github.com/neatio-net/neatio@v1.7.3-0.20231114194659-f4d7a2226baa/network/p2p/dial_test.go (about) 1 package p2p 2 3 import ( 4 "encoding/binary" 5 "net" 6 "reflect" 7 "testing" 8 "time" 9 10 "github.com/davecgh/go-spew/spew" 11 "github.com/neatio-net/neatio/network/p2p/discover" 12 "github.com/neatio-net/neatio/network/p2p/netutil" 13 ) 14 15 func init() { 16 spew.Config.Indent = "\t" 17 } 18 19 type dialtest struct { 20 init *dialstate 21 rounds []round 22 } 23 24 type round struct { 25 peers []*Peer 26 done []task 27 new []task 28 } 29 30 func runDialTest(t *testing.T, test dialtest) { 31 var ( 32 vtime time.Time 33 running int 34 ) 35 pm := func(ps []*Peer) map[discover.NodeID]*Peer { 36 m := make(map[discover.NodeID]*Peer) 37 for _, p := range ps { 38 m[p.rw.id] = p 39 } 40 return m 41 } 42 for i, round := range test.rounds { 43 for _, task := range round.done { 44 running-- 45 if running < 0 { 46 panic("running task counter underflow") 47 } 48 test.init.taskDone(task, vtime) 49 } 50 51 new := test.init.newTasks(running, pm(round.peers), vtime) 52 if !sametasks(new, round.new) { 53 t.Errorf("round %d: new tasks mismatch:\ngot %v\nwant %v\nstate: %v\nrunning: %v\n", 54 i, spew.Sdump(new), spew.Sdump(round.new), spew.Sdump(test.init), spew.Sdump(running)) 55 } 56 57 vtime = vtime.Add(16 * time.Second) 58 running += len(new) 59 } 60 } 61 62 type fakeTable []*discover.Node 63 64 func (t fakeTable) Self() *discover.Node { return new(discover.Node) } 65 func (t fakeTable) Close() {} 66 func (t fakeTable) Lookup(discover.NodeID) []*discover.Node { return nil } 67 func (t fakeTable) Resolve(discover.NodeID) *discover.Node { return nil } 68 func (t fakeTable) ReadRandomNodes(buf []*discover.Node) int { return copy(buf, t) } 69 70 func TestDialStateDynDial(t *testing.T) { 71 runDialTest(t, dialtest{ 72 init: newDialState(nil, nil, fakeTable{}, 5, nil), 73 rounds: []round{ 74 75 { 76 peers: []*Peer{ 77 {rw: &conn{flags: staticDialedConn, id: uintID(0)}}, 78 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 79 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 80 }, 81 new: []task{&discoverTask{}}, 82 }, 83 84 { 85 peers: []*Peer{ 86 {rw: &conn{flags: staticDialedConn, id: uintID(0)}}, 87 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 88 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 89 }, 90 done: []task{ 91 &discoverTask{results: []*discover.Node{ 92 {ID: uintID(2)}, 93 {ID: uintID(3)}, 94 {ID: uintID(4)}, 95 {ID: uintID(5)}, 96 {ID: uintID(6)}, 97 {ID: uintID(7)}, 98 }}, 99 }, 100 new: []task{ 101 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}}, 102 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 103 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 104 }, 105 }, 106 107 { 108 peers: []*Peer{ 109 {rw: &conn{flags: staticDialedConn, id: uintID(0)}}, 110 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 111 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 112 {rw: &conn{flags: dynDialedConn, id: uintID(3)}}, 113 {rw: &conn{flags: dynDialedConn, id: uintID(4)}}, 114 }, 115 done: []task{ 116 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}}, 117 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 118 }, 119 }, 120 121 { 122 peers: []*Peer{ 123 {rw: &conn{flags: staticDialedConn, id: uintID(0)}}, 124 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 125 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 126 {rw: &conn{flags: dynDialedConn, id: uintID(3)}}, 127 {rw: &conn{flags: dynDialedConn, id: uintID(4)}}, 128 {rw: &conn{flags: dynDialedConn, id: uintID(5)}}, 129 }, 130 done: []task{ 131 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 132 }, 133 new: []task{ 134 &waitExpireTask{Duration: 14 * time.Second}, 135 }, 136 }, 137 138 { 139 peers: []*Peer{ 140 {rw: &conn{flags: staticDialedConn, id: uintID(0)}}, 141 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 142 {rw: &conn{flags: dynDialedConn, id: uintID(3)}}, 143 {rw: &conn{flags: dynDialedConn, id: uintID(4)}}, 144 {rw: &conn{flags: dynDialedConn, id: uintID(5)}}, 145 }, 146 new: []task{ 147 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(6)}}, 148 }, 149 }, 150 151 { 152 peers: []*Peer{ 153 {rw: &conn{flags: staticDialedConn, id: uintID(0)}}, 154 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 155 {rw: &conn{flags: dynDialedConn, id: uintID(5)}}, 156 }, 157 done: []task{ 158 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(6)}}, 159 }, 160 new: []task{ 161 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(7)}}, 162 &discoverTask{}, 163 }, 164 }, 165 166 { 167 peers: []*Peer{ 168 {rw: &conn{flags: staticDialedConn, id: uintID(0)}}, 169 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 170 {rw: &conn{flags: dynDialedConn, id: uintID(5)}}, 171 {rw: &conn{flags: dynDialedConn, id: uintID(7)}}, 172 }, 173 done: []task{ 174 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(7)}}, 175 }, 176 }, 177 178 { 179 peers: []*Peer{ 180 {rw: &conn{flags: staticDialedConn, id: uintID(0)}}, 181 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 182 {rw: &conn{flags: dynDialedConn, id: uintID(5)}}, 183 {rw: &conn{flags: dynDialedConn, id: uintID(7)}}, 184 }, 185 done: []task{ 186 &discoverTask{}, 187 }, 188 new: []task{ 189 &discoverTask{}, 190 }, 191 }, 192 }, 193 }) 194 } 195 196 func TestDialStateDynDialBootnode(t *testing.T) { 197 bootnodes := []*discover.Node{ 198 {ID: uintID(1)}, 199 {ID: uintID(2)}, 200 {ID: uintID(3)}, 201 } 202 table := fakeTable{ 203 {ID: uintID(4)}, 204 {ID: uintID(5)}, 205 {ID: uintID(6)}, 206 {ID: uintID(7)}, 207 {ID: uintID(8)}, 208 } 209 runDialTest(t, dialtest{ 210 init: newDialState(nil, bootnodes, table, 5, nil), 211 rounds: []round{ 212 213 { 214 new: []task{ 215 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 216 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 217 &discoverTask{}, 218 }, 219 }, 220 221 { 222 done: []task{ 223 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 224 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 225 }, 226 }, 227 228 {}, 229 230 { 231 new: []task{ 232 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}}, 233 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 234 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 235 }, 236 }, 237 238 { 239 done: []task{ 240 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}}, 241 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 242 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 243 }, 244 new: []task{ 245 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(2)}}, 246 }, 247 }, 248 249 { 250 done: []task{ 251 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(2)}}, 252 }, 253 new: []task{ 254 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}}, 255 }, 256 }, 257 258 { 259 done: []task{ 260 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}}, 261 }, 262 new: []task{ 263 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}}, 264 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 265 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 266 }, 267 }, 268 269 { 270 peers: []*Peer{ 271 {rw: &conn{flags: dynDialedConn, id: uintID(4)}}, 272 }, 273 done: []task{ 274 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}}, 275 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 276 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 277 }, 278 }, 279 }, 280 }) 281 } 282 283 func TestDialStateDynDialFromTable(t *testing.T) { 284 285 table := fakeTable{ 286 {ID: uintID(1)}, 287 {ID: uintID(2)}, 288 {ID: uintID(3)}, 289 {ID: uintID(4)}, 290 {ID: uintID(5)}, 291 {ID: uintID(6)}, 292 {ID: uintID(7)}, 293 {ID: uintID(8)}, 294 } 295 296 runDialTest(t, dialtest{ 297 init: newDialState(nil, nil, table, 10, nil), 298 rounds: []round{ 299 300 { 301 new: []task{ 302 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}}, 303 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(2)}}, 304 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}}, 305 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 306 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 307 &discoverTask{}, 308 }, 309 }, 310 311 { 312 peers: []*Peer{ 313 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 314 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 315 }, 316 done: []task{ 317 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(1)}}, 318 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(2)}}, 319 &discoverTask{results: []*discover.Node{ 320 {ID: uintID(10)}, 321 {ID: uintID(11)}, 322 {ID: uintID(12)}, 323 }}, 324 }, 325 new: []task{ 326 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(10)}}, 327 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(11)}}, 328 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(12)}}, 329 &discoverTask{}, 330 }, 331 }, 332 333 { 334 peers: []*Peer{ 335 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 336 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 337 {rw: &conn{flags: dynDialedConn, id: uintID(10)}}, 338 {rw: &conn{flags: dynDialedConn, id: uintID(11)}}, 339 {rw: &conn{flags: dynDialedConn, id: uintID(12)}}, 340 }, 341 done: []task{ 342 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(3)}}, 343 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(4)}}, 344 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(5)}}, 345 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(10)}}, 346 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(11)}}, 347 &dialTask{flags: dynDialedConn, dest: &discover.Node{ID: uintID(12)}}, 348 }, 349 }, 350 351 { 352 peers: []*Peer{ 353 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 354 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 355 {rw: &conn{flags: dynDialedConn, id: uintID(10)}}, 356 {rw: &conn{flags: dynDialedConn, id: uintID(11)}}, 357 {rw: &conn{flags: dynDialedConn, id: uintID(12)}}, 358 }, 359 }, 360 361 { 362 peers: []*Peer{ 363 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 364 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 365 {rw: &conn{flags: dynDialedConn, id: uintID(10)}}, 366 {rw: &conn{flags: dynDialedConn, id: uintID(11)}}, 367 {rw: &conn{flags: dynDialedConn, id: uintID(12)}}, 368 }, 369 }, 370 }, 371 }) 372 } 373 374 func TestDialStateNetRestrict(t *testing.T) { 375 376 table := fakeTable{ 377 {ID: uintID(1), IP: net.ParseIP("127.0.0.1")}, 378 {ID: uintID(2), IP: net.ParseIP("127.0.0.2")}, 379 {ID: uintID(3), IP: net.ParseIP("127.0.0.3")}, 380 {ID: uintID(4), IP: net.ParseIP("127.0.0.4")}, 381 {ID: uintID(5), IP: net.ParseIP("127.0.2.5")}, 382 {ID: uintID(6), IP: net.ParseIP("127.0.2.6")}, 383 {ID: uintID(7), IP: net.ParseIP("127.0.2.7")}, 384 {ID: uintID(8), IP: net.ParseIP("127.0.2.8")}, 385 } 386 restrict := new(netutil.Netlist) 387 restrict.Add("127.0.2.0/24") 388 389 runDialTest(t, dialtest{ 390 init: newDialState(nil, nil, table, 10, restrict), 391 rounds: []round{ 392 { 393 new: []task{ 394 &dialTask{flags: dynDialedConn, dest: table[4]}, 395 &discoverTask{}, 396 }, 397 }, 398 }, 399 }) 400 } 401 402 func TestDialStateStaticDial(t *testing.T) { 403 wantStatic := []*discover.Node{ 404 {ID: uintID(1)}, 405 {ID: uintID(2)}, 406 {ID: uintID(3)}, 407 {ID: uintID(4)}, 408 {ID: uintID(5)}, 409 } 410 411 runDialTest(t, dialtest{ 412 init: newDialState(wantStatic, nil, fakeTable{}, 0, nil), 413 rounds: []round{ 414 415 { 416 peers: []*Peer{ 417 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 418 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 419 }, 420 new: []task{ 421 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}}, 422 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(4)}}, 423 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(5)}}, 424 }, 425 }, 426 427 { 428 peers: []*Peer{ 429 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 430 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 431 {rw: &conn{flags: staticDialedConn, id: uintID(3)}}, 432 }, 433 done: []task{ 434 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}}, 435 }, 436 }, 437 438 { 439 peers: []*Peer{ 440 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 441 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 442 {rw: &conn{flags: staticDialedConn, id: uintID(3)}}, 443 {rw: &conn{flags: staticDialedConn, id: uintID(4)}}, 444 {rw: &conn{flags: staticDialedConn, id: uintID(5)}}, 445 }, 446 done: []task{ 447 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(4)}}, 448 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(5)}}, 449 }, 450 new: []task{ 451 &waitExpireTask{Duration: 14 * time.Second}, 452 }, 453 }, 454 455 { 456 peers: []*Peer{ 457 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 458 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 459 {rw: &conn{flags: staticDialedConn, id: uintID(3)}}, 460 {rw: &conn{flags: staticDialedConn, id: uintID(4)}}, 461 {rw: &conn{flags: staticDialedConn, id: uintID(5)}}, 462 }, 463 }, 464 465 { 466 peers: []*Peer{ 467 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 468 {rw: &conn{flags: staticDialedConn, id: uintID(3)}}, 469 {rw: &conn{flags: staticDialedConn, id: uintID(5)}}, 470 }, 471 new: []task{ 472 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(2)}}, 473 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(4)}}, 474 }, 475 }, 476 }, 477 }) 478 } 479 480 func TestDialStaticAfterReset(t *testing.T) { 481 wantStatic := []*discover.Node{ 482 {ID: uintID(1)}, 483 {ID: uintID(2)}, 484 } 485 486 rounds := []round{ 487 488 { 489 peers: nil, 490 new: []task{ 491 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(1)}}, 492 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(2)}}, 493 }, 494 }, 495 496 { 497 peers: []*Peer{ 498 {rw: &conn{flags: staticDialedConn, id: uintID(1)}}, 499 {rw: &conn{flags: staticDialedConn, id: uintID(2)}}, 500 }, 501 done: []task{ 502 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(1)}}, 503 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(2)}}, 504 }, 505 new: []task{ 506 &waitExpireTask{Duration: 30 * time.Second}, 507 }, 508 }, 509 } 510 dTest := dialtest{ 511 init: newDialState(wantStatic, nil, fakeTable{}, 0, nil), 512 rounds: rounds, 513 } 514 runDialTest(t, dTest) 515 for _, n := range wantStatic { 516 dTest.init.removeStatic(n) 517 dTest.init.addStatic(n) 518 } 519 520 runDialTest(t, dTest) 521 } 522 523 func TestDialStateCache(t *testing.T) { 524 wantStatic := []*discover.Node{ 525 {ID: uintID(1)}, 526 {ID: uintID(2)}, 527 {ID: uintID(3)}, 528 } 529 530 runDialTest(t, dialtest{ 531 init: newDialState(wantStatic, nil, fakeTable{}, 0, nil), 532 rounds: []round{ 533 534 { 535 peers: nil, 536 new: []task{ 537 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(1)}}, 538 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(2)}}, 539 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}}, 540 }, 541 }, 542 543 { 544 peers: []*Peer{ 545 {rw: &conn{flags: staticDialedConn, id: uintID(1)}}, 546 {rw: &conn{flags: staticDialedConn, id: uintID(2)}}, 547 }, 548 done: []task{ 549 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(1)}}, 550 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(2)}}, 551 }, 552 }, 553 554 { 555 peers: []*Peer{ 556 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 557 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 558 }, 559 done: []task{ 560 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}}, 561 }, 562 new: []task{ 563 &waitExpireTask{Duration: 14 * time.Second}, 564 }, 565 }, 566 567 { 568 peers: []*Peer{ 569 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 570 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 571 }, 572 }, 573 574 { 575 peers: []*Peer{ 576 {rw: &conn{flags: dynDialedConn, id: uintID(1)}}, 577 {rw: &conn{flags: dynDialedConn, id: uintID(2)}}, 578 }, 579 new: []task{ 580 &dialTask{flags: staticDialedConn, dest: &discover.Node{ID: uintID(3)}}, 581 }, 582 }, 583 }, 584 }) 585 } 586 587 func TestDialResolve(t *testing.T) { 588 resolved := discover.NewNode(uintID(1), net.IP{127, 0, 55, 234}, 3333, 4444) 589 table := &resolveMock{answer: resolved} 590 state := newDialState(nil, nil, table, 0, nil) 591 592 dest := discover.NewNode(uintID(1), nil, 0, 0) 593 state.addStatic(dest) 594 tasks := state.newTasks(0, nil, time.Time{}) 595 if !reflect.DeepEqual(tasks, []task{&dialTask{flags: staticDialedConn, dest: dest}}) { 596 t.Fatalf("expected dial task, got %#v", tasks) 597 } 598 599 config := Config{Dialer: TCPDialer{&net.Dialer{Deadline: time.Now().Add(-5 * time.Minute)}}} 600 srv := &Server{ntab: table, Config: config} 601 tasks[0].Do(srv) 602 if !reflect.DeepEqual(table.resolveCalls, []discover.NodeID{dest.ID}) { 603 t.Fatalf("wrong resolve calls, got %v", table.resolveCalls) 604 } 605 606 state.taskDone(tasks[0], time.Now()) 607 if state.static[uintID(1)].dest != resolved { 608 t.Fatalf("state.dest not updated") 609 } 610 } 611 612 func sametasks(a, b []task) bool { 613 if len(a) != len(b) { 614 return false 615 } 616 next: 617 for _, ta := range a { 618 for _, tb := range b { 619 if reflect.DeepEqual(ta, tb) { 620 continue next 621 } 622 } 623 return false 624 } 625 return true 626 } 627 628 func uintID(i uint32) discover.NodeID { 629 var id discover.NodeID 630 binary.BigEndian.PutUint32(id[:], i) 631 return id 632 } 633 634 type resolveMock struct { 635 resolveCalls []discover.NodeID 636 answer *discover.Node 637 } 638 639 func (t *resolveMock) Resolve(id discover.NodeID) *discover.Node { 640 t.resolveCalls = append(t.resolveCalls, id) 641 return t.answer 642 } 643 644 func (t *resolveMock) Self() *discover.Node { return new(discover.Node) } 645 func (t *resolveMock) Close() {} 646 func (t *resolveMock) Bootstrap([]*discover.Node) {} 647 func (t *resolveMock) Lookup(discover.NodeID) []*discover.Node { return nil } 648 func (t *resolveMock) ReadRandomNodes(buf []*discover.Node) int { return 0 }