@@ -11,6 +11,7 @@ import (
11
11
"fmt"
12
12
"math/big"
13
13
"sort"
14
+ "time"
14
15
15
16
"github.com/decred/dcrd/chaincfg/chainhash"
16
17
"github.com/decred/dcrd/dcrec/secp256k1/v4"
@@ -20,6 +21,8 @@ import (
20
21
"github.com/decred/dcrd/wire"
21
22
)
22
23
24
+ var errBlameFailed = errors .New ("blame failed" )
25
+
23
26
// blamedIdentities identifies detected misbehaving peers.
24
27
//
25
28
// If a run returns a blamedIdentities error, these peers are immediately
@@ -48,7 +51,7 @@ func (e blamedIdentities) String() string {
48
51
}
49
52
50
53
func (c * Client ) blame (ctx context.Context , sesRun * sessionRun ) (err error ) {
51
- c .logf ("Blaming for sid=%x" , sesRun . sid [:] )
54
+ sesRun .logf ("running blame assignment" )
52
55
53
56
mp := c .mixpool
54
57
prs := sesRun .prs
@@ -65,14 +68,11 @@ func (c *Client) blame(ctx context.Context, sesRun *sessionRun) (err error) {
65
68
}
66
69
}()
67
70
68
- err = c .sendLocalPeerMsgs (ctx , sesRun , true , func (p * peer ) mixing.Message {
69
- // Send initial secrets messages from any peers who detected
70
- // misbehavior.
71
- if ! p .triggeredBlame {
72
- return nil
73
- }
74
- return p .rs
75
- })
71
+ deadline := time .Now ().Add (timeoutDuration )
72
+
73
+ // Send initial secrets messages from any peers who detected
74
+ // misbehavior.
75
+ err = c .sendLocalPeerMsgs (ctx , deadline , sesRun , 0 )
76
76
if err != nil {
77
77
return err
78
78
}
@@ -87,15 +87,17 @@ func (c *Client) blame(ctx context.Context, sesRun *sessionRun) (err error) {
87
87
rsHashes = append (rsHashes , rs .Hash ())
88
88
}
89
89
90
- // Send remaining secrets messages.
91
- err = c .sendLocalPeerMsgs (ctx , sesRun , true , func (p * peer ) mixing.Message {
92
- if p .triggeredBlame {
93
- p .triggeredBlame = false
94
- return nil
90
+ // Send remaining secrets messages with observed RS hashes from the
91
+ // initial peers who published secrets.
92
+ c .forLocalPeers (ctx , sesRun , func (p * peer ) error {
93
+ if ! p .triggeredBlame {
94
+ if p .rs != nil {
95
+ p .rs .SeenSecrets = rsHashes
96
+ }
95
97
}
96
- p .rs .SeenSecrets = rsHashes
97
- return p .rs
98
+ return nil
98
99
})
100
+ err = c .sendLocalPeerMsgs (ctx , deadline , sesRun , msgRS )
99
101
if err != nil {
100
102
return err
101
103
}
@@ -113,14 +115,14 @@ func (c *Client) blame(ctx context.Context, sesRun *sessionRun) (err error) {
113
115
}
114
116
if len (rss ) != len (sesRun .peers ) {
115
117
// Blame peers who did not send secrets
116
- c .logf ("received %d RSs for %d peers; blaming unresponsive peers" ,
118
+ sesRun .logf ("received %d RSs for %d peers; blaming unresponsive peers" ,
117
119
len (rss ), len (sesRun .peers ))
118
120
119
121
for _ , p := range sesRun .peers {
120
122
if p .rs != nil {
121
123
continue
122
124
}
123
- c .logf ("blaming %x for RS timeout" , p .id [:])
125
+ sesRun .logf ("blaming %x for RS timeout" , p .id [:])
124
126
blamed = append (blamed , * p .id )
125
127
}
126
128
return blamed
@@ -142,10 +144,14 @@ func (c *Client) blame(ctx context.Context, sesRun *sessionRun) (err error) {
142
144
continue
143
145
}
144
146
id := & rs .Identity
145
- c .logf ("blaming %x for false failure accusation" , id [:])
147
+ sesRun .logf ("blaming %x for false failure accusation" , id [:])
146
148
blamed = append (blamed , * id )
147
149
}
148
- err = blamed
150
+ if len (blamed ) > 0 {
151
+ err = blamed
152
+ } else {
153
+ err = errBlameFailed
154
+ }
149
155
}()
150
156
151
157
defer c .mu .Unlock ()
@@ -159,7 +165,7 @@ func (c *Client) blame(ctx context.Context, sesRun *sessionRun) (err error) {
159
165
KELoop:
160
166
for _ , p := range sesRun .peers {
161
167
if p .ke == nil {
162
- c .logf ("blaming %x for missing messages" , p .id [:])
168
+ sesRun .logf ("blaming %x for missing messages" , p .id [:])
163
169
blamed = append (blamed , * p .id )
164
170
continue
165
171
}
@@ -169,15 +175,15 @@ KELoop:
169
175
cm := p .rs .Commitment (c .blake256Hasher )
170
176
c .blake256HasherMu .Unlock ()
171
177
if cm != p .ke .Commitment {
172
- c .logf ("blaming %x for false commitment, got %x want %x" ,
178
+ sesRun .logf ("blaming %x for false commitment, got %x want %x" ,
173
179
p .id [:], cm [:], p .ke .Commitment [:])
174
180
blamed = append (blamed , * p .id )
175
181
continue
176
182
}
177
183
178
184
// Blame peers whose seed is not the correct length (will panic chacha20prng).
179
185
if len (p .rs .Seed ) != chacha20prng .SeedSize {
180
- c .logf ("blaming %x for bad seed size in RS message" , p .id [:])
186
+ sesRun .logf ("blaming %x for bad seed size in RS message" , p .id [:])
181
187
blamed = append (blamed , * p .id )
182
188
continue
183
189
}
@@ -187,7 +193,7 @@ KELoop:
187
193
if mixing .InField (scratch .SetBytes (m )) {
188
194
continue
189
195
}
190
- c .logf ("blaming %x for SR message outside field" , p .id [:])
196
+ sesRun .logf ("blaming %x for SR message outside field" , p .id [:])
191
197
blamed = append (blamed , * p .id )
192
198
continue KELoop
193
199
}
@@ -199,7 +205,7 @@ KELoop:
199
205
// Recover derived key exchange from PRNG.
200
206
p .kx , err = mixing .NewKX (p .prng )
201
207
if err != nil {
202
- c .logf ("blaming %x for bad KX" , p .id [:])
208
+ sesRun .logf ("blaming %x for bad KX" , p .id [:])
203
209
blamed = append (blamed , * p .id )
204
210
continue
205
211
}
@@ -210,14 +216,14 @@ KELoop:
210
216
case ! bytes .Equal (p .ke .ECDH [:], p .kx .ECDHPublicKey .SerializeCompressed ()):
211
217
fallthrough
212
218
case ! bytes .Equal (p .ke .PQPK [:], p .kx .PQPublicKey [:]):
213
- c .logf ("blaming %x for KE public keys not derived from their PRNG" ,
219
+ sesRun .logf ("blaming %x for KE public keys not derived from their PRNG" ,
214
220
p .id [:])
215
221
blamed = append (blamed , * p .id )
216
222
continue KELoop
217
223
}
218
224
publishedECDHPub , err := secp256k1 .ParsePubKey (p .ke .ECDH [:])
219
225
if err != nil {
220
- c .logf ("blaming %x for unparsable pubkey" )
226
+ sesRun .logf ("blaming %x for unparsable pubkey" )
221
227
blamed = append (blamed , * p .id )
222
228
continue
223
229
}
@@ -229,7 +235,7 @@ KELoop:
229
235
start += mcount
230
236
231
237
if uint32 (len (p .rs .SlotReserveMsgs )) != mcount || uint32 (len (p .rs .DCNetMsgs )) != mcount {
232
- c .logf ("blaming %x for bad message count" , p .id [:])
238
+ sesRun .logf ("blaming %x for bad message count" , p .id [:])
233
239
blamed = append (blamed , * p .id )
234
240
continue
235
241
}
@@ -261,19 +267,19 @@ KELoop:
261
267
// from their PRNG.
262
268
for i , p := range sesRun .peers {
263
269
if p .ct == nil {
264
- c .logf ("blaming %x for missing messages" , p .id [:])
270
+ sesRun .logf ("blaming %x for missing messages" , p .id [:])
265
271
blamed = append (blamed , * p .id )
266
272
continue
267
273
}
268
274
if len (recoveredCTs [i ]) != len (p .ct .Ciphertexts ) {
269
- c .logf ("blaming %x for different ciphertexts count %d != %d" ,
275
+ sesRun .logf ("blaming %x for different ciphertexts count %d != %d" ,
270
276
p .id [:], len (recoveredCTs [i ]), len (p .ct .Ciphertexts ))
271
277
blamed = append (blamed , * p .id )
272
278
continue
273
279
}
274
280
for j := range p .ct .Ciphertexts {
275
281
if ! bytes .Equal (p .ct .Ciphertexts [j ][:], recoveredCTs [i ][j ][:]) {
276
- c .logf ("blaming %x for different ciphertexts" , p .id [:])
282
+ sesRun .logf ("blaming %x for different ciphertexts" , p .id [:])
277
283
blamed = append (blamed , * p .id )
278
284
break
279
285
}
@@ -294,7 +300,7 @@ KELoop:
294
300
for _ , pids := range shared {
295
301
if len (pids ) > 1 {
296
302
for i := range pids {
297
- c .logf ("blaming %x for shared SR message" , pids [i ][:])
303
+ sesRun .logf ("blaming %x for shared SR message" , pids [i ][:])
298
304
}
299
305
blamed = append (blamed , pids ... )
300
306
}
@@ -306,7 +312,7 @@ KELoop:
306
312
SRLoop:
307
313
for i , p := range sesRun .peers {
308
314
if p .sr == nil {
309
- c .logf ("blaming %x for missing messages" , p .id [:])
315
+ sesRun .logf ("blaming %x for missing messages" , p .id [:])
310
316
blamed = append (blamed , * p .id )
311
317
continue
312
318
}
@@ -325,7 +331,7 @@ SRLoop:
325
331
var decapErr * mixing.DecapsulateError
326
332
if errors .As (err , & decapErr ) {
327
333
submittingID := p .id
328
- c .logf ("blaming %x for unrecoverable secrets" , submittingID [:])
334
+ sesRun .logf ("blaming %x for unrecoverable secrets" , submittingID [:])
329
335
blamed = append (blamed , * submittingID )
330
336
continue
331
337
}
@@ -343,7 +349,7 @@ SRLoop:
343
349
// Blame when committed mix does not match provided.
344
350
for k := range srMix {
345
351
if srMix [k ].Cmp (scratch .SetBytes (p .sr .DCMix [j ][k ])) != 0 {
346
- c .logf ("blaming %x for bad SR mix" , p .id [:])
352
+ sesRun .logf ("blaming %x for bad SR mix" , p .id [:])
347
353
blamed = append (blamed , * p .id )
348
354
continue SRLoop
349
355
}
@@ -376,7 +382,7 @@ DCLoop:
376
382
// deferred function) if no peers could be assigned blame is
377
383
// not likely to be seen under this situation.
378
384
if p .dc == nil {
379
- c .logf ("blaming %x for missing messages" , p .id [:])
385
+ sesRun .logf ("blaming %x for missing messages" , p .id [:])
380
386
blamed = append (blamed , * p .id )
381
387
continue
382
388
}
@@ -386,7 +392,7 @@ DCLoop:
386
392
// message, and there must be mcount DC-net vectors.
387
393
mcount := p .pr .MessageCount
388
394
if uint32 (len (p .dc .DCNet )) != mcount {
389
- c .logf ("blaming %x for missing DC mix vectors" , p .id [:])
395
+ sesRun .logf ("blaming %x for missing DC mix vectors" , p .id [:])
390
396
blamed = append (blamed , * p .id )
391
397
continue
392
398
}
@@ -406,7 +412,7 @@ DCLoop:
406
412
// Blame when committed mix does not match provided.
407
413
for k := 0 ; k < len (dcMix ); k ++ {
408
414
if ! dcMix .Equals (mixing .Vec (p .dc .DCNet [j ])) {
409
- c .logf ("blaming %x for bad DC mix" , p .id [:])
415
+ sesRun .logf ("blaming %x for bad DC mix" , p .id [:])
410
416
blamed = append (blamed , * p .id )
411
417
continue DCLoop
412
418
}
0 commit comments