github.com/pure-x-eth/consensus_tm@v0.0.0-20230502163723-e3c2ff987250/p2p/transport_test.go (about) 1 package p2p 2 3 import ( 4 "fmt" 5 "math/rand" 6 "net" 7 "reflect" 8 "runtime" 9 "strings" 10 "testing" 11 "time" 12 13 "github.com/pure-x-eth/consensus_tm/crypto/ed25519" 14 "github.com/pure-x-eth/consensus_tm/libs/protoio" 15 "github.com/pure-x-eth/consensus_tm/p2p/conn" 16 tmp2p "github.com/pure-x-eth/consensus_tm/proto/tendermint/p2p" 17 ) 18 19 var defaultNodeName = "host_peer" 20 21 func emptyNodeInfo() NodeInfo { 22 return DefaultNodeInfo{} 23 } 24 25 // newMultiplexTransport returns a tcp connected multiplexed peer 26 // using the default MConnConfig. It's a convenience function used 27 // for testing. 28 func newMultiplexTransport( 29 nodeInfo NodeInfo, 30 nodeKey NodeKey, 31 ) *MultiplexTransport { 32 return NewMultiplexTransport( 33 nodeInfo, nodeKey, conn.DefaultMConnConfig(), 34 ) 35 } 36 37 func TestTransportMultiplexConnFilter(t *testing.T) { 38 mt := newMultiplexTransport( 39 emptyNodeInfo(), 40 NodeKey{ 41 PrivKey: ed25519.GenPrivKey(), 42 }, 43 ) 44 id := mt.nodeKey.ID() 45 46 MultiplexTransportConnFilters( 47 func(_ ConnSet, _ net.Conn, _ []net.IP) error { return nil }, 48 func(_ ConnSet, _ net.Conn, _ []net.IP) error { return nil }, 49 func(_ ConnSet, _ net.Conn, _ []net.IP) error { 50 return fmt.Errorf("rejected") 51 }, 52 )(mt) 53 54 addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0")) 55 if err != nil { 56 t.Fatal(err) 57 } 58 59 if err := mt.Listen(*addr); err != nil { 60 t.Fatal(err) 61 } 62 63 errc := make(chan error) 64 65 go func() { 66 addr := NewNetAddress(id, mt.listener.Addr()) 67 68 _, err := addr.Dial() 69 if err != nil { 70 errc <- err 71 return 72 } 73 74 close(errc) 75 }() 76 77 if err := <-errc; err != nil { 78 t.Errorf("connection failed: %v", err) 79 } 80 81 _, err = mt.Accept(peerConfig{}) 82 if e, ok := err.(ErrRejected); ok { 83 if !e.IsFiltered() { 84 t.Errorf("expected peer to be filtered, got %v", err) 85 } 86 } else { 87 t.Errorf("expected ErrRejected, got %v", err) 88 } 89 } 90 91 func TestTransportMultiplexConnFilterTimeout(t *testing.T) { 92 mt := newMultiplexTransport( 93 emptyNodeInfo(), 94 NodeKey{ 95 PrivKey: ed25519.GenPrivKey(), 96 }, 97 ) 98 id := mt.nodeKey.ID() 99 100 MultiplexTransportFilterTimeout(5 * time.Millisecond)(mt) 101 MultiplexTransportConnFilters( 102 func(_ ConnSet, _ net.Conn, _ []net.IP) error { 103 time.Sleep(1 * time.Second) 104 return nil 105 }, 106 )(mt) 107 108 addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0")) 109 if err != nil { 110 t.Fatal(err) 111 } 112 113 if err := mt.Listen(*addr); err != nil { 114 t.Fatal(err) 115 } 116 117 errc := make(chan error) 118 go func() { 119 addr := NewNetAddress(id, mt.listener.Addr()) 120 121 _, err := addr.Dial() 122 if err != nil { 123 errc <- err 124 return 125 } 126 127 close(errc) 128 }() 129 130 if err := <-errc; err != nil { 131 t.Errorf("connection failed: %v", err) 132 } 133 134 _, err = mt.Accept(peerConfig{}) 135 if _, ok := err.(ErrFilterTimeout); !ok { 136 t.Errorf("expected ErrFilterTimeout, got %v", err) 137 } 138 } 139 140 func TestTransportMultiplexMaxIncomingConnections(t *testing.T) { 141 pv := ed25519.GenPrivKey() 142 id := PubKeyToID(pv.PubKey()) 143 mt := newMultiplexTransport( 144 testNodeInfo( 145 id, "transport", 146 ), 147 NodeKey{ 148 PrivKey: pv, 149 }, 150 ) 151 152 MultiplexTransportMaxIncomingConnections(0)(mt) 153 154 addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0")) 155 if err != nil { 156 t.Fatal(err) 157 } 158 const maxIncomingConns = 2 159 MultiplexTransportMaxIncomingConnections(maxIncomingConns)(mt) 160 if err := mt.Listen(*addr); err != nil { 161 t.Fatal(err) 162 } 163 164 laddr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 165 166 // Connect more peers than max 167 for i := 0; i <= maxIncomingConns; i++ { 168 errc := make(chan error) 169 go testDialer(*laddr, errc) 170 171 err = <-errc 172 if i < maxIncomingConns { 173 if err != nil { 174 t.Errorf("dialer connection failed: %v", err) 175 } 176 _, err = mt.Accept(peerConfig{}) 177 if err != nil { 178 t.Errorf("connection failed: %v", err) 179 } 180 } else if err == nil || !strings.Contains(err.Error(), "i/o timeout") { 181 // mt actually blocks forever on trying to accept a new peer into a full channel so 182 // expect the dialer to encounter a timeout error. Calling mt.Accept will block until 183 // mt is closed. 184 t.Errorf("expected i/o timeout error, got %v", err) 185 } 186 } 187 } 188 189 func TestTransportMultiplexAcceptMultiple(t *testing.T) { 190 mt := testSetupMultiplexTransport(t) 191 laddr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 192 193 var ( 194 seed = rand.New(rand.NewSource(time.Now().UnixNano())) 195 nDialers = seed.Intn(64) + 64 196 errc = make(chan error, nDialers) 197 ) 198 199 // Setup dialers. 200 for i := 0; i < nDialers; i++ { 201 go testDialer(*laddr, errc) 202 } 203 204 // Catch connection errors. 205 for i := 0; i < nDialers; i++ { 206 if err := <-errc; err != nil { 207 t.Fatal(err) 208 } 209 } 210 211 ps := []Peer{} 212 213 // Accept all peers. 214 for i := 0; i < cap(errc); i++ { 215 p, err := mt.Accept(peerConfig{}) 216 if err != nil { 217 t.Fatal(err) 218 } 219 220 if err := p.Start(); err != nil { 221 t.Fatal(err) 222 } 223 224 ps = append(ps, p) 225 } 226 227 if have, want := len(ps), cap(errc); have != want { 228 t.Errorf("have %v, want %v", have, want) 229 } 230 231 // Stop all peers. 232 for _, p := range ps { 233 if err := p.Stop(); err != nil { 234 t.Fatal(err) 235 } 236 } 237 238 if err := mt.Close(); err != nil { 239 t.Errorf("close errored: %v", err) 240 } 241 } 242 243 func testDialer(dialAddr NetAddress, errc chan error) { 244 var ( 245 pv = ed25519.GenPrivKey() 246 dialer = newMultiplexTransport( 247 testNodeInfo(PubKeyToID(pv.PubKey()), defaultNodeName), 248 NodeKey{ 249 PrivKey: pv, 250 }, 251 ) 252 ) 253 254 _, err := dialer.Dial(dialAddr, peerConfig{}) 255 if err != nil { 256 errc <- err 257 return 258 } 259 260 // Signal that the connection was established. 261 errc <- nil 262 } 263 264 func TestTransportMultiplexAcceptNonBlocking(t *testing.T) { 265 mt := testSetupMultiplexTransport(t) 266 267 var ( 268 fastNodePV = ed25519.GenPrivKey() 269 fastNodeInfo = testNodeInfo(PubKeyToID(fastNodePV.PubKey()), "fastnode") 270 errc = make(chan error) 271 fastc = make(chan struct{}) 272 slowc = make(chan struct{}) 273 slowdonec = make(chan struct{}) 274 ) 275 276 // Simulate slow Peer. 277 go func() { 278 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 279 280 c, err := addr.Dial() 281 if err != nil { 282 errc <- err 283 return 284 } 285 286 close(slowc) 287 defer func() { 288 close(slowdonec) 289 }() 290 291 // Make sure we switch to fast peer goroutine. 292 runtime.Gosched() 293 294 select { 295 case <-fastc: 296 // Fast peer connected. 297 case <-time.After(200 * time.Millisecond): 298 // We error if the fast peer didn't succeed. 299 errc <- fmt.Errorf("fast peer timed out") 300 } 301 302 sc, err := upgradeSecretConn(c, 200*time.Millisecond, ed25519.GenPrivKey()) 303 if err != nil { 304 errc <- err 305 return 306 } 307 308 _, err = handshake(sc, 200*time.Millisecond, 309 testNodeInfo( 310 PubKeyToID(ed25519.GenPrivKey().PubKey()), 311 "slow_peer", 312 )) 313 if err != nil { 314 errc <- err 315 } 316 }() 317 318 // Simulate fast Peer. 319 go func() { 320 <-slowc 321 322 var ( 323 dialer = newMultiplexTransport( 324 fastNodeInfo, 325 NodeKey{ 326 PrivKey: fastNodePV, 327 }, 328 ) 329 ) 330 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 331 332 _, err := dialer.Dial(*addr, peerConfig{}) 333 if err != nil { 334 errc <- err 335 return 336 } 337 338 close(fastc) 339 <-slowdonec 340 close(errc) 341 }() 342 343 if err := <-errc; err != nil { 344 t.Logf("connection failed: %v", err) 345 } 346 347 p, err := mt.Accept(peerConfig{}) 348 if err != nil { 349 t.Fatal(err) 350 } 351 352 if have, want := p.NodeInfo(), fastNodeInfo; !reflect.DeepEqual(have, want) { 353 t.Errorf("have %v, want %v", have, want) 354 } 355 } 356 357 func TestTransportMultiplexValidateNodeInfo(t *testing.T) { 358 mt := testSetupMultiplexTransport(t) 359 360 errc := make(chan error) 361 362 go func() { 363 var ( 364 pv = ed25519.GenPrivKey() 365 dialer = newMultiplexTransport( 366 testNodeInfo(PubKeyToID(pv.PubKey()), ""), // Should not be empty 367 NodeKey{ 368 PrivKey: pv, 369 }, 370 ) 371 ) 372 373 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 374 375 _, err := dialer.Dial(*addr, peerConfig{}) 376 if err != nil { 377 errc <- err 378 return 379 } 380 381 close(errc) 382 }() 383 384 if err := <-errc; err != nil { 385 t.Errorf("connection failed: %v", err) 386 } 387 388 _, err := mt.Accept(peerConfig{}) 389 if e, ok := err.(ErrRejected); ok { 390 if !e.IsNodeInfoInvalid() { 391 t.Errorf("expected NodeInfo to be invalid, got %v", err) 392 } 393 } else { 394 t.Errorf("expected ErrRejected, got %v", err) 395 } 396 } 397 398 func TestTransportMultiplexRejectMissmatchID(t *testing.T) { 399 mt := testSetupMultiplexTransport(t) 400 401 errc := make(chan error) 402 403 go func() { 404 dialer := newMultiplexTransport( 405 testNodeInfo( 406 PubKeyToID(ed25519.GenPrivKey().PubKey()), "dialer", 407 ), 408 NodeKey{ 409 PrivKey: ed25519.GenPrivKey(), 410 }, 411 ) 412 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 413 414 _, err := dialer.Dial(*addr, peerConfig{}) 415 if err != nil { 416 errc <- err 417 return 418 } 419 420 close(errc) 421 }() 422 423 if err := <-errc; err != nil { 424 t.Errorf("connection failed: %v", err) 425 } 426 427 _, err := mt.Accept(peerConfig{}) 428 if e, ok := err.(ErrRejected); ok { 429 if !e.IsAuthFailure() { 430 t.Errorf("expected auth failure, got %v", err) 431 } 432 } else { 433 t.Errorf("expected ErrRejected, got %v", err) 434 } 435 } 436 437 func TestTransportMultiplexDialRejectWrongID(t *testing.T) { 438 mt := testSetupMultiplexTransport(t) 439 440 var ( 441 pv = ed25519.GenPrivKey() 442 dialer = newMultiplexTransport( 443 testNodeInfo(PubKeyToID(pv.PubKey()), ""), // Should not be empty 444 NodeKey{ 445 PrivKey: pv, 446 }, 447 ) 448 ) 449 450 wrongID := PubKeyToID(ed25519.GenPrivKey().PubKey()) 451 addr := NewNetAddress(wrongID, mt.listener.Addr()) 452 453 _, err := dialer.Dial(*addr, peerConfig{}) 454 if err != nil { 455 t.Logf("connection failed: %v", err) 456 if e, ok := err.(ErrRejected); ok { 457 if !e.IsAuthFailure() { 458 t.Errorf("expected auth failure, got %v", err) 459 } 460 } else { 461 t.Errorf("expected ErrRejected, got %v", err) 462 } 463 } 464 } 465 466 func TestTransportMultiplexRejectIncompatible(t *testing.T) { 467 mt := testSetupMultiplexTransport(t) 468 469 errc := make(chan error) 470 471 go func() { 472 var ( 473 pv = ed25519.GenPrivKey() 474 dialer = newMultiplexTransport( 475 testNodeInfoWithNetwork(PubKeyToID(pv.PubKey()), "dialer", "incompatible-network"), 476 NodeKey{ 477 PrivKey: pv, 478 }, 479 ) 480 ) 481 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 482 483 _, err := dialer.Dial(*addr, peerConfig{}) 484 if err != nil { 485 errc <- err 486 return 487 } 488 489 close(errc) 490 }() 491 492 _, err := mt.Accept(peerConfig{}) 493 if e, ok := err.(ErrRejected); ok { 494 if !e.IsIncompatible() { 495 t.Errorf("expected to reject incompatible, got %v", err) 496 } 497 } else { 498 t.Errorf("expected ErrRejected, got %v", err) 499 } 500 } 501 502 func TestTransportMultiplexRejectSelf(t *testing.T) { 503 mt := testSetupMultiplexTransport(t) 504 505 errc := make(chan error) 506 507 go func() { 508 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 509 510 _, err := mt.Dial(*addr, peerConfig{}) 511 if err != nil { 512 errc <- err 513 return 514 } 515 516 close(errc) 517 }() 518 519 if err := <-errc; err != nil { 520 if e, ok := err.(ErrRejected); ok { 521 if !e.IsSelf() { 522 t.Errorf("expected to reject self, got: %v", err) 523 } 524 } else { 525 t.Errorf("expected ErrRejected, got %v", err) 526 } 527 } else { 528 t.Errorf("expected connection failure") 529 } 530 531 _, err := mt.Accept(peerConfig{}) 532 if e, ok := err.(ErrRejected); ok { 533 if !e.IsSelf() { 534 t.Errorf("expected to reject self, got: %v", err) 535 } 536 } else { 537 t.Errorf("expected ErrRejected, got %v", nil) 538 } 539 } 540 541 func TestTransportConnDuplicateIPFilter(t *testing.T) { 542 filter := ConnDuplicateIPFilter() 543 544 if err := filter(nil, &testTransportConn{}, nil); err != nil { 545 t.Fatal(err) 546 } 547 548 var ( 549 c = &testTransportConn{} 550 cs = NewConnSet() 551 ) 552 553 cs.Set(c, []net.IP{ 554 {10, 0, 10, 1}, 555 {10, 0, 10, 2}, 556 {10, 0, 10, 3}, 557 }) 558 559 if err := filter(cs, c, []net.IP{ 560 {10, 0, 10, 2}, 561 }); err == nil { 562 t.Errorf("expected Peer to be rejected as duplicate") 563 } 564 } 565 566 func TestTransportHandshake(t *testing.T) { 567 ln, err := net.Listen("tcp", "127.0.0.1:0") 568 if err != nil { 569 t.Fatal(err) 570 } 571 572 var ( 573 peerPV = ed25519.GenPrivKey() 574 peerNodeInfo = testNodeInfo(PubKeyToID(peerPV.PubKey()), defaultNodeName) 575 ) 576 577 go func() { 578 c, err := net.Dial(ln.Addr().Network(), ln.Addr().String()) 579 if err != nil { 580 t.Error(err) 581 return 582 } 583 584 go func(c net.Conn) { 585 _, err := protoio.NewDelimitedWriter(c).WriteMsg(peerNodeInfo.(DefaultNodeInfo).ToProto()) 586 if err != nil { 587 t.Error(err) 588 } 589 }(c) 590 go func(c net.Conn) { 591 var ( 592 // ni DefaultNodeInfo 593 pbni tmp2p.DefaultNodeInfo 594 ) 595 596 protoReader := protoio.NewDelimitedReader(c, MaxNodeInfoSize()) 597 _, err := protoReader.ReadMsg(&pbni) 598 if err != nil { 599 t.Error(err) 600 } 601 602 _, err = DefaultNodeInfoFromToProto(&pbni) 603 if err != nil { 604 t.Error(err) 605 } 606 }(c) 607 }() 608 609 c, err := ln.Accept() 610 if err != nil { 611 t.Fatal(err) 612 } 613 614 ni, err := handshake(c, 20*time.Millisecond, emptyNodeInfo()) 615 if err != nil { 616 t.Fatal(err) 617 } 618 619 if have, want := ni, peerNodeInfo; !reflect.DeepEqual(have, want) { 620 t.Errorf("have %v, want %v", have, want) 621 } 622 } 623 624 func TestTransportAddChannel(t *testing.T) { 625 mt := newMultiplexTransport( 626 emptyNodeInfo(), 627 NodeKey{ 628 PrivKey: ed25519.GenPrivKey(), 629 }, 630 ) 631 testChannel := byte(0x01) 632 633 mt.AddChannel(testChannel) 634 if !mt.nodeInfo.(DefaultNodeInfo).HasChannel(testChannel) { 635 t.Errorf("missing added channel %v. Got %v", testChannel, mt.nodeInfo.(DefaultNodeInfo).Channels) 636 } 637 } 638 639 // create listener 640 func testSetupMultiplexTransport(t *testing.T) *MultiplexTransport { 641 var ( 642 pv = ed25519.GenPrivKey() 643 id = PubKeyToID(pv.PubKey()) 644 mt = newMultiplexTransport( 645 testNodeInfo( 646 id, "transport", 647 ), 648 NodeKey{ 649 PrivKey: pv, 650 }, 651 ) 652 ) 653 654 addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0")) 655 if err != nil { 656 t.Fatal(err) 657 } 658 659 if err := mt.Listen(*addr); err != nil { 660 t.Fatal(err) 661 } 662 663 // give the listener some time to get ready 664 time.Sleep(20 * time.Millisecond) 665 666 return mt 667 } 668 669 type testTransportAddr struct{} 670 671 func (a *testTransportAddr) Network() string { return "tcp" } 672 func (a *testTransportAddr) String() string { return "test.local:1234" } 673 674 type testTransportConn struct{} 675 676 func (c *testTransportConn) Close() error { 677 return fmt.Errorf("close() not implemented") 678 } 679 680 func (c *testTransportConn) LocalAddr() net.Addr { 681 return &testTransportAddr{} 682 } 683 684 func (c *testTransportConn) RemoteAddr() net.Addr { 685 return &testTransportAddr{} 686 } 687 688 func (c *testTransportConn) Read(_ []byte) (int, error) { 689 return -1, fmt.Errorf("read() not implemented") 690 } 691 692 func (c *testTransportConn) SetDeadline(_ time.Time) error { 693 return fmt.Errorf("setDeadline() not implemented") 694 } 695 696 func (c *testTransportConn) SetReadDeadline(_ time.Time) error { 697 return fmt.Errorf("setReadDeadline() not implemented") 698 } 699 700 func (c *testTransportConn) SetWriteDeadline(_ time.Time) error { 701 return fmt.Errorf("setWriteDeadline() not implemented") 702 } 703 704 func (c *testTransportConn) Write(_ []byte) (int, error) { 705 return -1, fmt.Errorf("write() not implemented") 706 }