github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/tm2/pkg/p2p/transport_test.go (about) 1 package p2p 2 3 import ( 4 "fmt" 5 "math/rand" 6 "net" 7 "reflect" 8 "testing" 9 "time" 10 11 "github.com/gnolang/gno/tm2/pkg/amino" 12 "github.com/gnolang/gno/tm2/pkg/crypto/ed25519" 13 "github.com/gnolang/gno/tm2/pkg/p2p/conn" 14 "github.com/gnolang/gno/tm2/pkg/testutils" 15 ) 16 17 var defaultNodeName = "host_peer" 18 19 func emptyNodeInfo() NodeInfo { 20 return NodeInfo{} 21 } 22 23 // newMultiplexTransport returns a tcp connected multiplexed peer 24 // using the default MConnConfig. It's a convenience function used 25 // for testing. 26 func newMultiplexTransport( 27 nodeInfo NodeInfo, 28 nodeKey NodeKey, 29 ) *MultiplexTransport { 30 return NewMultiplexTransport( 31 nodeInfo, nodeKey, conn.DefaultMConnConfig(), 32 ) 33 } 34 35 func TestTransportMultiplexConnFilter(t *testing.T) { 36 t.Parallel() 37 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 := NewNetAddressFromString(NetAddressString(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 err, ok := err.(RejectedError); ok { 83 if !err.IsFiltered() { 84 t.Errorf("expected peer to be filtered") 85 } 86 } else { 87 t.Errorf("expected RejectedError") 88 } 89 } 90 91 func TestTransportMultiplexConnFilterTimeout(t *testing.T) { 92 t.Parallel() 93 94 mt := newMultiplexTransport( 95 emptyNodeInfo(), 96 NodeKey{ 97 PrivKey: ed25519.GenPrivKey(), 98 }, 99 ) 100 id := mt.nodeKey.ID() 101 102 MultiplexTransportFilterTimeout(5 * time.Millisecond)(mt) 103 MultiplexTransportConnFilters( 104 func(_ ConnSet, _ net.Conn, _ []net.IP) error { 105 time.Sleep(100 * time.Millisecond) 106 return nil 107 }, 108 )(mt) 109 110 addr, err := NewNetAddressFromString(NetAddressString(id, "127.0.0.1:0")) 111 if err != nil { 112 t.Fatal(err) 113 } 114 115 if err := mt.Listen(*addr); err != nil { 116 t.Fatal(err) 117 } 118 119 errc := make(chan error) 120 121 go func() { 122 addr := NewNetAddress(id, mt.listener.Addr()) 123 124 _, err := addr.Dial() 125 if err != nil { 126 errc <- err 127 return 128 } 129 130 close(errc) 131 }() 132 133 if err := <-errc; err != nil { 134 t.Errorf("connection failed: %v", err) 135 } 136 137 _, err = mt.Accept(peerConfig{}) 138 if _, ok := err.(FilterTimeoutError); !ok { 139 t.Errorf("expected FilterTimeoutError") 140 } 141 } 142 143 func TestTransportMultiplexAcceptMultiple(t *testing.T) { 144 t.Parallel() 145 146 mt := testSetupMultiplexTransport(t) 147 laddr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 148 149 var ( 150 seed = rand.New(rand.NewSource(time.Now().UnixNano())) 151 nDialers = seed.Intn(64) + 64 152 errc = make(chan error, nDialers) 153 ) 154 155 // Setup dialers. 156 for i := 0; i < nDialers; i++ { 157 go testDialer(*laddr, errc) 158 } 159 160 // Catch connection errors. 161 for i := 0; i < nDialers; i++ { 162 if err := <-errc; err != nil { 163 t.Fatal(err) 164 } 165 } 166 167 ps := []Peer{} 168 169 // Accept all peers. 170 for i := 0; i < cap(errc); i++ { 171 p, err := mt.Accept(peerConfig{}) 172 if err != nil { 173 t.Fatal(err) 174 } 175 176 if err := p.Start(); err != nil { 177 t.Fatal(err) 178 } 179 180 ps = append(ps, p) 181 } 182 183 if have, want := len(ps), cap(errc); have != want { 184 t.Errorf("have %v, want %v", have, want) 185 } 186 187 // Stop all peers. 188 for _, p := range ps { 189 if err := p.Stop(); err != nil { 190 t.Fatal(err) 191 } 192 } 193 194 if err := mt.Close(); err != nil { 195 t.Errorf("close errored: %v", err) 196 } 197 } 198 199 func testDialer(dialAddr NetAddress, errc chan error) { 200 var ( 201 pv = ed25519.GenPrivKey() 202 dialer = newMultiplexTransport( 203 testNodeInfo(pv.PubKey().Address().ID(), defaultNodeName), 204 NodeKey{ 205 PrivKey: pv, 206 }, 207 ) 208 ) 209 210 _, err := dialer.Dial(dialAddr, peerConfig{}) 211 if err != nil { 212 errc <- err 213 return 214 } 215 216 // Signal that the connection was established. 217 errc <- nil 218 } 219 220 func TestFlappyTransportMultiplexAcceptNonBlocking(t *testing.T) { 221 t.Parallel() 222 223 testutils.FilterStability(t, testutils.Flappy) 224 225 mt := testSetupMultiplexTransport(t) 226 227 var ( 228 fastNodePV = ed25519.GenPrivKey() 229 fastNodeInfo = testNodeInfo(fastNodePV.PubKey().Address().ID(), "fastnode") 230 errc = make(chan error) 231 fastc = make(chan struct{}) 232 slowc = make(chan struct{}) 233 ) 234 235 // Simulate slow Peer. 236 go func() { 237 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 238 239 c, err := addr.Dial() 240 if err != nil { 241 errc <- err 242 return 243 } 244 245 close(slowc) 246 247 select { 248 case <-fastc: 249 // Fast peer connected. 250 case <-time.After(100 * time.Millisecond): 251 // We error if the fast peer didn't succeed. 252 errc <- fmt.Errorf("Fast peer timed out") 253 } 254 255 sc, err := upgradeSecretConn(c, 100*time.Millisecond, ed25519.GenPrivKey()) 256 if err != nil { 257 errc <- err 258 return 259 } 260 261 _, err = handshake(sc, 100*time.Millisecond, 262 testNodeInfo( 263 ed25519.GenPrivKey().PubKey().Address().ID(), 264 "slow_peer", 265 )) 266 if err != nil { 267 errc <- err 268 return 269 } 270 }() 271 272 // Simulate fast Peer. 273 go func() { 274 <-slowc 275 276 dialer := newMultiplexTransport( 277 fastNodeInfo, 278 NodeKey{ 279 PrivKey: fastNodePV, 280 }, 281 ) 282 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 283 284 _, err := dialer.Dial(*addr, peerConfig{}) 285 if err != nil { 286 errc <- err 287 return 288 } 289 290 close(errc) 291 close(fastc) 292 }() 293 294 if err := <-errc; err != nil { 295 t.Errorf("connection failed: %v", err) 296 } 297 298 p, err := mt.Accept(peerConfig{}) 299 if err != nil { 300 t.Fatal(err) 301 } 302 303 if have, want := p.NodeInfo(), fastNodeInfo; !reflect.DeepEqual(have, want) { 304 t.Errorf("have %v, want %v", have, want) 305 } 306 } 307 308 func TestTransportMultiplexValidateNodeInfo(t *testing.T) { 309 t.Parallel() 310 311 mt := testSetupMultiplexTransport(t) 312 313 errc := make(chan error) 314 315 go func() { 316 var ( 317 pv = ed25519.GenPrivKey() 318 dialer = newMultiplexTransport( 319 testNodeInfo(pv.PubKey().Address().ID(), ""), // Should not be empty 320 NodeKey{ 321 PrivKey: pv, 322 }, 323 ) 324 ) 325 326 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 327 328 _, err := dialer.Dial(*addr, peerConfig{}) 329 if err != nil { 330 errc <- err 331 return 332 } 333 334 close(errc) 335 }() 336 337 if err := <-errc; err != nil { 338 t.Errorf("connection failed: %v", err) 339 } 340 341 _, err := mt.Accept(peerConfig{}) 342 if err, ok := err.(RejectedError); ok { 343 if !err.IsNodeInfoInvalid() { 344 t.Errorf("expected NodeInfo to be invalid") 345 } 346 } else { 347 t.Errorf("expected RejectedError") 348 } 349 } 350 351 func TestTransportMultiplexRejectMismatchID(t *testing.T) { 352 t.Parallel() 353 354 mt := testSetupMultiplexTransport(t) 355 356 errc := make(chan error) 357 358 go func() { 359 dialer := newMultiplexTransport( 360 testNodeInfo( 361 ed25519.GenPrivKey().PubKey().Address().ID(), "dialer", 362 ), 363 NodeKey{ 364 PrivKey: ed25519.GenPrivKey(), 365 }, 366 ) 367 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 368 369 _, err := dialer.Dial(*addr, peerConfig{}) 370 if err != nil { 371 errc <- err 372 return 373 } 374 375 close(errc) 376 }() 377 378 if err := <-errc; err != nil { 379 t.Errorf("connection failed: %v", err) 380 } 381 382 _, err := mt.Accept(peerConfig{}) 383 if err, ok := err.(RejectedError); ok { 384 if !err.IsAuthFailure() { 385 t.Errorf("expected auth failure") 386 } 387 } else { 388 t.Errorf("expected RejectedError") 389 } 390 } 391 392 func TestTransportMultiplexDialRejectWrongID(t *testing.T) { 393 t.Parallel() 394 395 mt := testSetupMultiplexTransport(t) 396 397 var ( 398 pv = ed25519.GenPrivKey() 399 dialer = newMultiplexTransport( 400 testNodeInfo(pv.PubKey().Address().ID(), ""), // Should not be empty 401 NodeKey{ 402 PrivKey: pv, 403 }, 404 ) 405 ) 406 407 wrongID := ed25519.GenPrivKey().PubKey().Address().ID() 408 addr := NewNetAddress(wrongID, mt.listener.Addr()) 409 410 _, err := dialer.Dial(*addr, peerConfig{}) 411 if err != nil { 412 t.Logf("connection failed: %v", err) 413 if err, ok := err.(RejectedError); ok { 414 if !err.IsAuthFailure() { 415 t.Errorf("expected auth failure") 416 } 417 } else { 418 t.Errorf("expected RejectedError") 419 } 420 } 421 } 422 423 func TestTransportMultiplexRejectIncompatible(t *testing.T) { 424 t.Parallel() 425 426 mt := testSetupMultiplexTransport(t) 427 428 errc := make(chan error) 429 430 go func() { 431 var ( 432 pv = ed25519.GenPrivKey() 433 dialer = newMultiplexTransport( 434 testNodeInfoWithNetwork(pv.PubKey().Address().ID(), "dialer", "incompatible-network"), 435 NodeKey{ 436 PrivKey: pv, 437 }, 438 ) 439 ) 440 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 441 442 _, err := dialer.Dial(*addr, peerConfig{}) 443 if err != nil { 444 errc <- err 445 return 446 } 447 448 close(errc) 449 }() 450 451 _, err := mt.Accept(peerConfig{}) 452 if err, ok := err.(RejectedError); ok { 453 if !err.IsIncompatible() { 454 t.Errorf("expected to reject incompatible") 455 } 456 } else { 457 t.Errorf("expected RejectedError") 458 } 459 } 460 461 func TestTransportMultiplexRejectSelf(t *testing.T) { 462 t.Parallel() 463 464 mt := testSetupMultiplexTransport(t) 465 466 errc := make(chan error) 467 468 go func() { 469 addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr()) 470 471 _, err := mt.Dial(*addr, peerConfig{}) 472 if err != nil { 473 errc <- err 474 return 475 } 476 477 close(errc) 478 }() 479 480 if err := <-errc; err != nil { 481 if err, ok := err.(RejectedError); ok { 482 if !err.IsSelf() { 483 t.Errorf("expected to reject self, got: %v", err) 484 } 485 } else { 486 t.Errorf("expected RejectedError") 487 } 488 } else { 489 t.Errorf("expected connection failure") 490 } 491 492 _, err := mt.Accept(peerConfig{}) 493 if err, ok := err.(RejectedError); ok { 494 if !err.IsSelf() { 495 t.Errorf("expected to reject self, got: %v", err) 496 } 497 } else { 498 t.Errorf("expected RejectedError") 499 } 500 } 501 502 func TestTransportConnDuplicateIPFilter(t *testing.T) { 503 t.Parallel() 504 505 filter := ConnDuplicateIPFilter() 506 507 if err := filter(nil, &testTransportConn{}, nil); err != nil { 508 t.Fatal(err) 509 } 510 511 var ( 512 c = &testTransportConn{} 513 cs = NewConnSet() 514 ) 515 516 cs.Set(c, []net.IP{ 517 {10, 0, 10, 1}, 518 {10, 0, 10, 2}, 519 {10, 0, 10, 3}, 520 }) 521 522 if err := filter(cs, c, []net.IP{ 523 {10, 0, 10, 2}, 524 }); err == nil { 525 t.Errorf("expected Peer to be rejected as duplicate") 526 } 527 } 528 529 func TestTransportHandshake(t *testing.T) { 530 t.Parallel() 531 532 ln, err := net.Listen("tcp", "127.0.0.1:0") 533 if err != nil { 534 t.Fatal(err) 535 } 536 537 var ( 538 peerPV = ed25519.GenPrivKey() 539 peerNodeInfo = testNodeInfo(peerPV.PubKey().Address().ID(), defaultNodeName) 540 ) 541 542 go func() { 543 c, err := net.Dial(ln.Addr().Network(), ln.Addr().String()) 544 if err != nil { 545 t.Error(err) 546 return 547 } 548 549 go func(c net.Conn) { 550 _, err := amino.MarshalSizedWriter(c, peerNodeInfo) 551 if err != nil { 552 t.Error(err) 553 } 554 }(c) 555 go func(c net.Conn) { 556 var ni NodeInfo 557 558 _, err := amino.UnmarshalSizedReader( 559 c, 560 &ni, 561 int64(MaxNodeInfoSize()), 562 ) 563 if err != nil { 564 t.Error(err) 565 } 566 }(c) 567 }() 568 569 c, err := ln.Accept() 570 if err != nil { 571 t.Fatal(err) 572 } 573 574 ni, err := handshake(c, 100*time.Millisecond, emptyNodeInfo()) 575 if err != nil { 576 t.Fatal(err) 577 } 578 579 if have, want := ni, peerNodeInfo; !reflect.DeepEqual(have, want) { 580 t.Errorf("have %v, want %v", have, want) 581 } 582 } 583 584 // create listener 585 func testSetupMultiplexTransport(t *testing.T) *MultiplexTransport { 586 t.Helper() 587 588 var ( 589 pv = ed25519.GenPrivKey() 590 id = pv.PubKey().Address().ID() 591 mt = newMultiplexTransport( 592 testNodeInfo( 593 id, "transport", 594 ), 595 NodeKey{ 596 PrivKey: pv, 597 }, 598 ) 599 ) 600 601 addr, err := NewNetAddressFromString(NetAddressString(id, "127.0.0.1:0")) 602 if err != nil { 603 t.Fatal(err) 604 } 605 606 if err := mt.Listen(*addr); err != nil { 607 t.Fatal(err) 608 } 609 610 return mt 611 } 612 613 type testTransportAddr struct{} 614 615 func (a *testTransportAddr) Network() string { return "tcp" } 616 func (a *testTransportAddr) String() string { return "test.local:1234" } 617 618 type testTransportConn struct{} 619 620 func (c *testTransportConn) Close() error { 621 return fmt.Errorf("Close() not implemented") 622 } 623 624 func (c *testTransportConn) LocalAddr() net.Addr { 625 return &testTransportAddr{} 626 } 627 628 func (c *testTransportConn) RemoteAddr() net.Addr { 629 return &testTransportAddr{} 630 } 631 632 func (c *testTransportConn) Read(_ []byte) (int, error) { 633 return -1, fmt.Errorf("Read() not implemented") 634 } 635 636 func (c *testTransportConn) SetDeadline(_ time.Time) error { 637 return fmt.Errorf("SetDeadline() not implemented") 638 } 639 640 func (c *testTransportConn) SetReadDeadline(_ time.Time) error { 641 return fmt.Errorf("SetReadDeadline() not implemented") 642 } 643 644 func (c *testTransportConn) SetWriteDeadline(_ time.Time) error { 645 return fmt.Errorf("SetWriteDeadline() not implemented") 646 } 647 648 func (c *testTransportConn) Write(_ []byte) (int, error) { 649 return -1, fmt.Errorf("Write() not implemented") 650 }