@@ -131,7 +131,7 @@ func waitForRevalidationPing(t *testing.T, transport *pingRecorder, tab *Table,
131
131
simclock := tab .cfg .Clock .(* mclock.Simulated )
132
132
maxAttempts := tab .len () * 8
133
133
for i := 0 ; i < maxAttempts ; i ++ {
134
- simclock .Run (tab .cfg .PingInterval )
134
+ simclock .Run (tab .cfg .PingInterval * slowRevalidationFactor )
135
135
p := transport .waitPing (2 * time .Second )
136
136
if p == nil {
137
137
t .Fatal ("Table did not send revalidation ping" )
@@ -275,7 +275,7 @@ func (*closeTest) Generate(rand *rand.Rand, size int) reflect.Value {
275
275
return reflect .ValueOf (t )
276
276
}
277
277
278
- func TestTable_addVerifiedNode (t * testing.T ) {
278
+ func TestTable_addInboundNode (t * testing.T ) {
279
279
tab , db := newTestTable (newPingRecorder (), Config {})
280
280
<- tab .initDone
281
281
defer db .Close ()
@@ -286,29 +286,26 @@ func TestTable_addVerifiedNode(t *testing.T) {
286
286
n2 := nodeAtDistance (tab .self ().ID (), 256 , net.IP {88 , 77 , 66 , 2 })
287
287
tab .addFoundNode (n1 )
288
288
tab .addFoundNode (n2 )
289
- bucket := tab . bucket ( n1 .ID () )
289
+ checkBucketContent ( t , tab , [] * enode. Node { n1 .Node , n2 . Node } )
290
290
291
- // Verify bucket content:
292
- bcontent := []* node {n1 , n2 }
293
- if ! reflect .DeepEqual (unwrapNodes (bucket .entries ), unwrapNodes (bcontent )) {
294
- t .Fatalf ("wrong bucket content: %v" , bucket .entries )
295
- }
296
-
297
- // Add a changed version of n2.
291
+ // Add a changed version of n2. The bucket should be updated.
298
292
newrec := n2 .Record ()
299
293
newrec .Set (enr.IP {99 , 99 , 99 , 99 })
300
- newn2 := wrapNode (enode .SignNull (newrec , n2 .ID ()))
301
- tab .addInboundNode (newn2 )
302
-
303
- // Check that bucket is updated correctly.
304
- newBcontent := []* node {n1 , newn2 }
305
- if ! reflect .DeepEqual (unwrapNodes (bucket .entries ), unwrapNodes (newBcontent )) {
306
- t .Fatalf ("wrong bucket content after update: %v" , bucket .entries )
307
- }
308
- checkIPLimitInvariant (t , tab )
294
+ n2v2 := enode .SignNull (newrec , n2 .ID ())
295
+ tab .addInboundNode (wrapNode (n2v2 ))
296
+ checkBucketContent (t , tab , []* enode.Node {n1 .Node , n2v2 })
297
+
298
+ // Try updating n2 without sequence number change. The update is accepted
299
+ // because it's inbound.
300
+ newrec = n2 .Record ()
301
+ newrec .Set (enr.IP {100 , 100 , 100 , 100 })
302
+ newrec .SetSeq (n2 .Seq ())
303
+ n2v3 := enode .SignNull (newrec , n2 .ID ())
304
+ tab .addInboundNode (wrapNode (n2v3 ))
305
+ checkBucketContent (t , tab , []* enode.Node {n1 .Node , n2v3 })
309
306
}
310
307
311
- func TestTable_addSeenNode (t * testing.T ) {
308
+ func TestTable_addFoundNode (t * testing.T ) {
312
309
tab , db := newTestTable (newPingRecorder (), Config {})
313
310
<- tab .initDone
314
311
defer db .Close ()
@@ -319,23 +316,84 @@ func TestTable_addSeenNode(t *testing.T) {
319
316
n2 := nodeAtDistance (tab .self ().ID (), 256 , net.IP {88 , 77 , 66 , 2 })
320
317
tab .addFoundNode (n1 )
321
318
tab .addFoundNode (n2 )
319
+ checkBucketContent (t , tab , []* enode.Node {n1 .Node , n2 .Node })
322
320
323
- // Verify bucket content:
324
- bcontent := []* node {n1 , n2 }
325
- if ! reflect .DeepEqual (tab .bucket (n1 .ID ()).entries , bcontent ) {
326
- t .Fatalf ("wrong bucket content: %v" , tab .bucket (n1 .ID ()).entries )
327
- }
328
-
329
- // Add a changed version of n2.
321
+ // Add a changed version of n2. The bucket should be updated.
330
322
newrec := n2 .Record ()
331
323
newrec .Set (enr.IP {99 , 99 , 99 , 99 })
332
- newn2 := wrapNode (enode .SignNull (newrec , n2 .ID ()))
333
- tab .addFoundNode (newn2 )
324
+ n2v2 := enode .SignNull (newrec , n2 .ID ())
325
+ tab .addFoundNode (wrapNode (n2v2 ))
326
+ checkBucketContent (t , tab , []* enode.Node {n1 .Node , n2v2 })
327
+
328
+ // Try updating n2 without a sequence number change.
329
+ // The update should not be accepted.
330
+ newrec = n2 .Record ()
331
+ newrec .Set (enr.IP {100 , 100 , 100 , 100 })
332
+ newrec .SetSeq (n2 .Seq ())
333
+ n2v3 := enode .SignNull (newrec , n2 .ID ())
334
+ tab .addFoundNode (wrapNode (n2v3 ))
335
+ checkBucketContent (t , tab , []* enode.Node {n1 .Node , n2v2 })
336
+ }
334
337
335
- // Check that bucket content is unchanged.
336
- if ! reflect .DeepEqual (tab .bucket (n1 .ID ()).entries , bcontent ) {
337
- t .Fatalf ("wrong bucket content after update: %v" , tab .bucket (n1 .ID ()).entries )
338
+ // This test checks that discv4 nodes can update their own endpoint via PING.
339
+ func TestTable_addInboundNodeUpdateV4Accept (t * testing.T ) {
340
+ tab , db := newTestTable (newPingRecorder (), Config {})
341
+ <- tab .initDone
342
+ defer db .Close ()
343
+ defer tab .close ()
344
+
345
+ // Add a v4 node.
346
+ key , _ := crypto .HexToECDSA ("dd3757a8075e88d0f2b1431e7d3c5b1562e1c0aab9643707e8cbfcc8dae5cfe3" )
347
+ n1 := enode .NewV4 (& key .PublicKey , net.IP {88 , 77 , 66 , 1 }, 9000 , 9000 )
348
+ tab .addInboundNode (wrapNode (n1 ))
349
+ checkBucketContent (t , tab , []* enode.Node {n1 })
350
+
351
+ // Add an updated version with changed IP.
352
+ // The update will be accepted because it is inbound.
353
+ n1v2 := enode .NewV4 (& key .PublicKey , net.IP {99 , 99 , 99 , 99 }, 9000 , 9000 )
354
+ tab .addInboundNode (wrapNode (n1v2 ))
355
+ checkBucketContent (t , tab , []* enode.Node {n1v2 })
356
+ }
357
+
358
+ // This test checks that discv4 node entries will NOT be updated when a
359
+ // changed record is found.
360
+ func TestTable_addFoundNodeV4UpdateReject (t * testing.T ) {
361
+ tab , db := newTestTable (newPingRecorder (), Config {})
362
+ <- tab .initDone
363
+ defer db .Close ()
364
+ defer tab .close ()
365
+
366
+ // Add a v4 node.
367
+ key , _ := crypto .HexToECDSA ("dd3757a8075e88d0f2b1431e7d3c5b1562e1c0aab9643707e8cbfcc8dae5cfe3" )
368
+ n1 := enode .NewV4 (& key .PublicKey , net.IP {88 , 77 , 66 , 1 }, 9000 , 9000 )
369
+ tab .addFoundNode (wrapNode (n1 ))
370
+ checkBucketContent (t , tab , []* enode.Node {n1 })
371
+
372
+ // Add an updated version with changed IP.
373
+ // The update won't be accepted because it isn't inbound.
374
+ n1v2 := enode .NewV4 (& key .PublicKey , net.IP {99 , 99 , 99 , 99 }, 9000 , 9000 )
375
+ tab .addFoundNode (wrapNode (n1v2 ))
376
+ checkBucketContent (t , tab , []* enode.Node {n1 })
377
+ }
378
+
379
+ func checkBucketContent (t * testing.T , tab * Table , nodes []* enode.Node ) {
380
+ t .Helper ()
381
+
382
+ b := tab .bucket (nodes [0 ].ID ())
383
+ if reflect .DeepEqual (unwrapNodes (b .entries ), nodes ) {
384
+ return
338
385
}
386
+ t .Log ("wrong bucket content. have nodes:" )
387
+ for _ , n := range b .entries {
388
+ t .Logf (" %v (seq=%v, ip=%v)" , n .ID (), n .Seq (), n .IP ())
389
+ }
390
+ t .Log ("want nodes:" )
391
+ for _ , n := range nodes {
392
+ t .Logf (" %v (seq=%v, ip=%v)" , n .ID (), n .Seq (), n .IP ())
393
+ }
394
+ t .FailNow ()
395
+
396
+ // Also check IP limits.
339
397
checkIPLimitInvariant (t , tab )
340
398
}
341
399
0 commit comments