github.com/btcsuite/btcd@v0.24.0/peer/peer_test.go (about) 1 // Copyright (c) 2015-2016 The btcsuite developers 2 // Copyright (c) 2016-2018 The Decred developers 3 // Use of this source code is governed by an ISC 4 // license that can be found in the LICENSE file. 5 6 package peer_test 7 8 import ( 9 "errors" 10 "io" 11 "net" 12 "strconv" 13 "testing" 14 "time" 15 16 "github.com/btcsuite/btcd/chaincfg" 17 "github.com/btcsuite/btcd/chaincfg/chainhash" 18 "github.com/btcsuite/btcd/peer" 19 "github.com/btcsuite/btcd/wire" 20 "github.com/btcsuite/go-socks/socks" 21 ) 22 23 // conn mocks a network connection by implementing the net.Conn interface. It 24 // is used to test peer connection without actually opening a network 25 // connection. 26 type conn struct { 27 io.Reader 28 io.Writer 29 io.Closer 30 31 // local network, address for the connection. 32 lnet, laddr string 33 34 // remote network, address for the connection. 35 rnet, raddr string 36 37 // mocks socks proxy if true 38 proxy bool 39 } 40 41 // LocalAddr returns the local address for the connection. 42 func (c conn) LocalAddr() net.Addr { 43 return &addr{c.lnet, c.laddr} 44 } 45 46 // Remote returns the remote address for the connection. 47 func (c conn) RemoteAddr() net.Addr { 48 if !c.proxy { 49 return &addr{c.rnet, c.raddr} 50 } 51 host, strPort, _ := net.SplitHostPort(c.raddr) 52 port, _ := strconv.Atoi(strPort) 53 return &socks.ProxiedAddr{ 54 Net: c.rnet, 55 Host: host, 56 Port: port, 57 } 58 } 59 60 // Close handles closing the connection. 61 func (c conn) Close() error { 62 if c.Closer == nil { 63 return nil 64 } 65 return c.Closer.Close() 66 } 67 68 func (c conn) SetDeadline(t time.Time) error { return nil } 69 func (c conn) SetReadDeadline(t time.Time) error { return nil } 70 func (c conn) SetWriteDeadline(t time.Time) error { return nil } 71 72 // addr mocks a network address 73 type addr struct { 74 net, address string 75 } 76 77 func (m addr) Network() string { return m.net } 78 func (m addr) String() string { return m.address } 79 80 // pipe turns two mock connections into a full-duplex connection similar to 81 // net.Pipe to allow pipe's with (fake) addresses. 82 func pipe(c1, c2 *conn) (*conn, *conn) { 83 r1, w1 := io.Pipe() 84 r2, w2 := io.Pipe() 85 86 c1.Writer = w1 87 c1.Closer = w1 88 c2.Reader = r1 89 c1.Reader = r2 90 c2.Writer = w2 91 c2.Closer = w2 92 93 return c1, c2 94 } 95 96 // peerStats holds the expected peer stats used for testing peer. 97 type peerStats struct { 98 wantUserAgent string 99 wantServices wire.ServiceFlag 100 wantProtocolVersion uint32 101 wantConnected bool 102 wantVersionKnown bool 103 wantVerAckReceived bool 104 wantLastBlock int32 105 wantStartingHeight int32 106 wantLastPingTime time.Time 107 wantLastPingNonce uint64 108 wantLastPingMicros int64 109 wantTimeOffset int64 110 wantBytesSent uint64 111 wantBytesReceived uint64 112 wantWitnessEnabled bool 113 } 114 115 // testPeer tests the given peer's flags and stats 116 func testPeer(t *testing.T, p *peer.Peer, s peerStats) { 117 if p.UserAgent() != s.wantUserAgent { 118 t.Errorf("testPeer: wrong UserAgent - got %v, want %v", p.UserAgent(), s.wantUserAgent) 119 return 120 } 121 122 if p.Services() != s.wantServices { 123 t.Errorf("testPeer: wrong Services - got %v, want %v", p.Services(), s.wantServices) 124 return 125 } 126 127 if !p.LastPingTime().Equal(s.wantLastPingTime) { 128 t.Errorf("testPeer: wrong LastPingTime - got %v, want %v", p.LastPingTime(), s.wantLastPingTime) 129 return 130 } 131 132 if p.LastPingNonce() != s.wantLastPingNonce { 133 t.Errorf("testPeer: wrong LastPingNonce - got %v, want %v", p.LastPingNonce(), s.wantLastPingNonce) 134 return 135 } 136 137 if p.LastPingMicros() != s.wantLastPingMicros { 138 t.Errorf("testPeer: wrong LastPingMicros - got %v, want %v", p.LastPingMicros(), s.wantLastPingMicros) 139 return 140 } 141 142 if p.VerAckReceived() != s.wantVerAckReceived { 143 t.Errorf("testPeer: wrong VerAckReceived - got %v, want %v", p.VerAckReceived(), s.wantVerAckReceived) 144 return 145 } 146 147 if p.VersionKnown() != s.wantVersionKnown { 148 t.Errorf("testPeer: wrong VersionKnown - got %v, want %v", p.VersionKnown(), s.wantVersionKnown) 149 return 150 } 151 152 if p.ProtocolVersion() != s.wantProtocolVersion { 153 t.Errorf("testPeer: wrong ProtocolVersion - got %v, want %v", p.ProtocolVersion(), s.wantProtocolVersion) 154 return 155 } 156 157 if p.LastBlock() != s.wantLastBlock { 158 t.Errorf("testPeer: wrong LastBlock - got %v, want %v", p.LastBlock(), s.wantLastBlock) 159 return 160 } 161 162 // Allow for a deviation of 1s, as the second may tick when the message is 163 // in transit and the protocol doesn't support any further precision. 164 if p.TimeOffset() != s.wantTimeOffset && p.TimeOffset() != s.wantTimeOffset-1 { 165 t.Errorf("testPeer: wrong TimeOffset - got %v, want %v or %v", p.TimeOffset(), 166 s.wantTimeOffset, s.wantTimeOffset-1) 167 return 168 } 169 170 if p.BytesSent() != s.wantBytesSent { 171 t.Errorf("testPeer: wrong BytesSent - got %v, want %v", p.BytesSent(), s.wantBytesSent) 172 return 173 } 174 175 if p.BytesReceived() != s.wantBytesReceived { 176 t.Errorf("testPeer: wrong BytesReceived - got %v, want %v", p.BytesReceived(), s.wantBytesReceived) 177 return 178 } 179 180 if p.StartingHeight() != s.wantStartingHeight { 181 t.Errorf("testPeer: wrong StartingHeight - got %v, want %v", p.StartingHeight(), s.wantStartingHeight) 182 return 183 } 184 185 if p.Connected() != s.wantConnected { 186 t.Errorf("testPeer: wrong Connected - got %v, want %v", p.Connected(), s.wantConnected) 187 return 188 } 189 190 if p.IsWitnessEnabled() != s.wantWitnessEnabled { 191 t.Errorf("testPeer: wrong WitnessEnabled - got %v, want %v", 192 p.IsWitnessEnabled(), s.wantWitnessEnabled) 193 return 194 } 195 196 stats := p.StatsSnapshot() 197 198 if p.ID() != stats.ID { 199 t.Errorf("testPeer: wrong ID - got %v, want %v", p.ID(), stats.ID) 200 return 201 } 202 203 if p.Addr() != stats.Addr { 204 t.Errorf("testPeer: wrong Addr - got %v, want %v", p.Addr(), stats.Addr) 205 return 206 } 207 208 if p.LastSend() != stats.LastSend { 209 t.Errorf("testPeer: wrong LastSend - got %v, want %v", p.LastSend(), stats.LastSend) 210 return 211 } 212 213 if p.LastRecv() != stats.LastRecv { 214 t.Errorf("testPeer: wrong LastRecv - got %v, want %v", p.LastRecv(), stats.LastRecv) 215 return 216 } 217 } 218 219 // TestPeerConnection tests connection between inbound and outbound peers. 220 func TestPeerConnection(t *testing.T) { 221 verack := make(chan struct{}) 222 peer1Cfg := &peer.Config{ 223 Listeners: peer.MessageListeners{ 224 OnVerAck: func(p *peer.Peer, msg *wire.MsgVerAck) { 225 verack <- struct{}{} 226 }, 227 OnWrite: func(p *peer.Peer, bytesWritten int, msg wire.Message, 228 err error) { 229 if _, ok := msg.(*wire.MsgVerAck); ok { 230 verack <- struct{}{} 231 } 232 }, 233 }, 234 UserAgentName: "peer", 235 UserAgentVersion: "1.0", 236 UserAgentComments: []string{"comment"}, 237 ChainParams: &chaincfg.MainNetParams, 238 ProtocolVersion: wire.RejectVersion, // Configure with older version 239 Services: 0, 240 TrickleInterval: time.Second * 10, 241 AllowSelfConns: true, 242 } 243 peer2Cfg := &peer.Config{ 244 Listeners: peer1Cfg.Listeners, 245 UserAgentName: "peer", 246 UserAgentVersion: "1.0", 247 UserAgentComments: []string{"comment"}, 248 ChainParams: &chaincfg.MainNetParams, 249 Services: wire.SFNodeNetwork | wire.SFNodeWitness, 250 TrickleInterval: time.Second * 10, 251 AllowSelfConns: true, 252 } 253 254 wantStats1 := peerStats{ 255 wantUserAgent: wire.DefaultUserAgent + "peer:1.0(comment)/", 256 wantServices: 0, 257 wantProtocolVersion: wire.RejectVersion, 258 wantConnected: true, 259 wantVersionKnown: true, 260 wantVerAckReceived: true, 261 wantLastPingTime: time.Time{}, 262 wantLastPingNonce: uint64(0), 263 wantLastPingMicros: int64(0), 264 wantTimeOffset: int64(0), 265 wantBytesSent: 167, // 143 version + 24 verack 266 wantBytesReceived: 167, 267 wantWitnessEnabled: false, 268 } 269 wantStats2 := peerStats{ 270 wantUserAgent: wire.DefaultUserAgent + "peer:1.0(comment)/", 271 wantServices: wire.SFNodeNetwork | wire.SFNodeWitness, 272 wantProtocolVersion: wire.RejectVersion, 273 wantConnected: true, 274 wantVersionKnown: true, 275 wantVerAckReceived: true, 276 wantLastPingTime: time.Time{}, 277 wantLastPingNonce: uint64(0), 278 wantLastPingMicros: int64(0), 279 wantTimeOffset: int64(0), 280 wantBytesSent: 167, // 143 version + 24 verack 281 wantBytesReceived: 167, 282 wantWitnessEnabled: true, 283 } 284 285 tests := []struct { 286 name string 287 setup func() (*peer.Peer, *peer.Peer, error) 288 }{ 289 { 290 "basic handshake", 291 func() (*peer.Peer, *peer.Peer, error) { 292 inPeer := peer.NewInboundPeer(peer1Cfg) 293 outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:8333") 294 if err != nil { 295 return nil, nil, err 296 } 297 298 err = setupPeerConnection(inPeer, outPeer) 299 if err != nil { 300 return nil, nil, err 301 } 302 303 for i := 0; i < 4; i++ { 304 select { 305 case <-verack: 306 case <-time.After(time.Second): 307 return nil, nil, errors.New("verack timeout") 308 } 309 } 310 return inPeer, outPeer, nil 311 }, 312 }, 313 { 314 "socks proxy", 315 func() (*peer.Peer, *peer.Peer, error) { 316 inPeer := peer.NewInboundPeer(peer1Cfg) 317 outPeer, err := peer.NewOutboundPeer(peer2Cfg, "10.0.0.2:8333") 318 if err != nil { 319 return nil, nil, err 320 } 321 322 err = setupPeerConnection(inPeer, outPeer) 323 if err != nil { 324 return nil, nil, err 325 } 326 327 for i := 0; i < 4; i++ { 328 select { 329 case <-verack: 330 case <-time.After(time.Second): 331 return nil, nil, errors.New("verack timeout") 332 } 333 } 334 return inPeer, outPeer, nil 335 }, 336 }, 337 } 338 t.Logf("Running %d tests", len(tests)) 339 for i, test := range tests { 340 inPeer, outPeer, err := test.setup() 341 if err != nil { 342 t.Errorf("TestPeerConnection setup #%d: unexpected err %v", i, err) 343 return 344 } 345 testPeer(t, inPeer, wantStats2) 346 testPeer(t, outPeer, wantStats1) 347 348 inPeer.Disconnect() 349 outPeer.Disconnect() 350 inPeer.WaitForDisconnect() 351 outPeer.WaitForDisconnect() 352 } 353 } 354 355 // TestPeerListeners tests that the peer listeners are called as expected. 356 func TestPeerListeners(t *testing.T) { 357 verack := make(chan struct{}, 1) 358 ok := make(chan wire.Message, 22) 359 peerCfg := &peer.Config{ 360 Listeners: peer.MessageListeners{ 361 OnGetAddr: func(p *peer.Peer, msg *wire.MsgGetAddr) { 362 ok <- msg 363 }, 364 OnAddr: func(p *peer.Peer, msg *wire.MsgAddr) { 365 ok <- msg 366 }, 367 OnPing: func(p *peer.Peer, msg *wire.MsgPing) { 368 ok <- msg 369 }, 370 OnPong: func(p *peer.Peer, msg *wire.MsgPong) { 371 ok <- msg 372 }, 373 OnAlert: func(p *peer.Peer, msg *wire.MsgAlert) { 374 ok <- msg 375 }, 376 OnMemPool: func(p *peer.Peer, msg *wire.MsgMemPool) { 377 ok <- msg 378 }, 379 OnTx: func(p *peer.Peer, msg *wire.MsgTx) { 380 ok <- msg 381 }, 382 OnBlock: func(p *peer.Peer, msg *wire.MsgBlock, buf []byte) { 383 ok <- msg 384 }, 385 OnInv: func(p *peer.Peer, msg *wire.MsgInv) { 386 ok <- msg 387 }, 388 OnHeaders: func(p *peer.Peer, msg *wire.MsgHeaders) { 389 ok <- msg 390 }, 391 OnNotFound: func(p *peer.Peer, msg *wire.MsgNotFound) { 392 ok <- msg 393 }, 394 OnGetData: func(p *peer.Peer, msg *wire.MsgGetData) { 395 ok <- msg 396 }, 397 OnGetBlocks: func(p *peer.Peer, msg *wire.MsgGetBlocks) { 398 ok <- msg 399 }, 400 OnGetHeaders: func(p *peer.Peer, msg *wire.MsgGetHeaders) { 401 ok <- msg 402 }, 403 OnGetCFilters: func(p *peer.Peer, msg *wire.MsgGetCFilters) { 404 ok <- msg 405 }, 406 OnGetCFHeaders: func(p *peer.Peer, msg *wire.MsgGetCFHeaders) { 407 ok <- msg 408 }, 409 OnGetCFCheckpt: func(p *peer.Peer, msg *wire.MsgGetCFCheckpt) { 410 ok <- msg 411 }, 412 OnCFilter: func(p *peer.Peer, msg *wire.MsgCFilter) { 413 ok <- msg 414 }, 415 OnCFHeaders: func(p *peer.Peer, msg *wire.MsgCFHeaders) { 416 ok <- msg 417 }, 418 OnFeeFilter: func(p *peer.Peer, msg *wire.MsgFeeFilter) { 419 ok <- msg 420 }, 421 OnFilterAdd: func(p *peer.Peer, msg *wire.MsgFilterAdd) { 422 ok <- msg 423 }, 424 OnFilterClear: func(p *peer.Peer, msg *wire.MsgFilterClear) { 425 ok <- msg 426 }, 427 OnFilterLoad: func(p *peer.Peer, msg *wire.MsgFilterLoad) { 428 ok <- msg 429 }, 430 OnMerkleBlock: func(p *peer.Peer, msg *wire.MsgMerkleBlock) { 431 ok <- msg 432 }, 433 OnVersion: func(p *peer.Peer, msg *wire.MsgVersion) *wire.MsgReject { 434 ok <- msg 435 return nil 436 }, 437 OnVerAck: func(p *peer.Peer, msg *wire.MsgVerAck) { 438 verack <- struct{}{} 439 }, 440 OnReject: func(p *peer.Peer, msg *wire.MsgReject) { 441 ok <- msg 442 }, 443 OnSendHeaders: func(p *peer.Peer, msg *wire.MsgSendHeaders) { 444 ok <- msg 445 }, 446 OnSendAddrV2: func(p *peer.Peer, msg *wire.MsgSendAddrV2) { 447 ok <- msg 448 }, 449 OnAddrV2: func(p *peer.Peer, msg *wire.MsgAddrV2) { 450 ok <- msg 451 }, 452 }, 453 UserAgentName: "peer", 454 UserAgentVersion: "1.0", 455 UserAgentComments: []string{"comment"}, 456 ChainParams: &chaincfg.MainNetParams, 457 Services: wire.SFNodeBloom, 458 TrickleInterval: time.Second * 10, 459 AllowSelfConns: true, 460 } 461 inPeer := peer.NewInboundPeer(peerCfg) 462 463 peerCfg.Listeners = peer.MessageListeners{ 464 OnVerAck: func(p *peer.Peer, msg *wire.MsgVerAck) { 465 verack <- struct{}{} 466 }, 467 } 468 outPeer, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") 469 if err != nil { 470 t.Errorf("NewOutboundPeer: unexpected err %v\n", err) 471 return 472 } 473 474 err = setupPeerConnection(inPeer, outPeer) 475 if err != nil { 476 t.Errorf("setupPeerConnection: failed: %v\n", err) 477 return 478 } 479 480 for i := 0; i < 2; i++ { 481 select { 482 case <-verack: 483 case <-time.After(time.Second * 1): 484 t.Errorf("TestPeerListeners: verack timeout\n") 485 return 486 } 487 } 488 489 tests := []struct { 490 listener string 491 msg wire.Message 492 }{ 493 { 494 "OnGetAddr", 495 wire.NewMsgGetAddr(), 496 }, 497 { 498 "OnAddr", 499 wire.NewMsgAddr(), 500 }, 501 { 502 "OnPing", 503 wire.NewMsgPing(42), 504 }, 505 { 506 "OnPong", 507 wire.NewMsgPong(42), 508 }, 509 { 510 "OnAlert", 511 wire.NewMsgAlert([]byte("payload"), []byte("signature")), 512 }, 513 { 514 "OnMemPool", 515 wire.NewMsgMemPool(), 516 }, 517 { 518 "OnTx", 519 wire.NewMsgTx(wire.TxVersion), 520 }, 521 { 522 "OnBlock", 523 wire.NewMsgBlock(wire.NewBlockHeader(1, 524 &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), 525 }, 526 { 527 "OnInv", 528 wire.NewMsgInv(), 529 }, 530 { 531 "OnHeaders", 532 wire.NewMsgHeaders(), 533 }, 534 { 535 "OnNotFound", 536 wire.NewMsgNotFound(), 537 }, 538 { 539 "OnGetData", 540 wire.NewMsgGetData(), 541 }, 542 { 543 "OnGetBlocks", 544 wire.NewMsgGetBlocks(&chainhash.Hash{}), 545 }, 546 { 547 "OnGetHeaders", 548 wire.NewMsgGetHeaders(), 549 }, 550 { 551 "OnGetCFilters", 552 wire.NewMsgGetCFilters(wire.GCSFilterRegular, 0, &chainhash.Hash{}), 553 }, 554 { 555 "OnGetCFHeaders", 556 wire.NewMsgGetCFHeaders(wire.GCSFilterRegular, 0, &chainhash.Hash{}), 557 }, 558 { 559 "OnGetCFCheckpt", 560 wire.NewMsgGetCFCheckpt(wire.GCSFilterRegular, &chainhash.Hash{}), 561 }, 562 { 563 "OnCFilter", 564 wire.NewMsgCFilter(wire.GCSFilterRegular, &chainhash.Hash{}, 565 []byte("payload")), 566 }, 567 { 568 "OnCFHeaders", 569 wire.NewMsgCFHeaders(), 570 }, 571 { 572 "OnFeeFilter", 573 wire.NewMsgFeeFilter(15000), 574 }, 575 { 576 "OnFilterAdd", 577 wire.NewMsgFilterAdd([]byte{0x01}), 578 }, 579 { 580 "OnFilterClear", 581 wire.NewMsgFilterClear(), 582 }, 583 { 584 "OnFilterLoad", 585 wire.NewMsgFilterLoad([]byte{0x01}, 10, 0, wire.BloomUpdateNone), 586 }, 587 { 588 "OnMerkleBlock", 589 wire.NewMsgMerkleBlock(wire.NewBlockHeader(1, 590 &chainhash.Hash{}, &chainhash.Hash{}, 1, 1)), 591 }, 592 // only one version message is allowed 593 // only one verack message is allowed 594 { 595 "OnReject", 596 wire.NewMsgReject("block", wire.RejectDuplicate, "dupe block"), 597 }, 598 { 599 "OnSendHeaders", 600 wire.NewMsgSendHeaders(), 601 }, 602 { 603 "OnSendAddrV2", 604 wire.NewMsgSendAddrV2(), 605 }, 606 { 607 "OnAddrV2", 608 wire.NewMsgAddrV2(), 609 }, 610 } 611 t.Logf("Running %d tests", len(tests)) 612 for _, test := range tests { 613 // Queue the test message 614 outPeer.QueueMessage(test.msg, nil) 615 select { 616 case <-ok: 617 case <-time.After(time.Second * 1): 618 t.Errorf("TestPeerListeners: %s timeout", test.listener) 619 return 620 } 621 } 622 inPeer.Disconnect() 623 outPeer.Disconnect() 624 } 625 626 // TestOutboundPeer tests that the outbound peer works as expected. 627 func TestOutboundPeer(t *testing.T) { 628 629 peerCfg := &peer.Config{ 630 NewestBlock: func() (*chainhash.Hash, int32, error) { 631 return nil, 0, errors.New("newest block not found") 632 }, 633 UserAgentName: "peer", 634 UserAgentVersion: "1.0", 635 UserAgentComments: []string{"comment"}, 636 ChainParams: &chaincfg.MainNetParams, 637 Services: 0, 638 TrickleInterval: time.Second * 10, 639 AllowSelfConns: true, 640 } 641 642 r, w := io.Pipe() 643 c := &conn{raddr: "10.0.0.1:8333", Writer: w, Reader: r} 644 645 p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") 646 if err != nil { 647 t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) 648 return 649 } 650 651 // Test trying to connect twice. 652 p.AssociateConnection(c) 653 p.AssociateConnection(c) 654 655 disconnected := make(chan struct{}) 656 go func() { 657 p.WaitForDisconnect() 658 disconnected <- struct{}{} 659 }() 660 661 select { 662 case <-disconnected: 663 close(disconnected) 664 case <-time.After(time.Second): 665 t.Fatal("Peer did not automatically disconnect.") 666 } 667 668 if p.Connected() { 669 t.Fatalf("Should not be connected as NewestBlock produces error.") 670 } 671 672 // Test Queue Inv 673 fakeBlockHash := &chainhash.Hash{0: 0x00, 1: 0x01} 674 fakeInv := wire.NewInvVect(wire.InvTypeBlock, fakeBlockHash) 675 676 // Should be noops as the peer could not connect. 677 p.QueueInventory(fakeInv) 678 p.AddKnownInventory(fakeInv) 679 p.QueueInventory(fakeInv) 680 681 fakeMsg := wire.NewMsgVerAck() 682 p.QueueMessage(fakeMsg, nil) 683 done := make(chan struct{}) 684 p.QueueMessage(fakeMsg, done) 685 <-done 686 p.Disconnect() 687 688 // Test NewestBlock 689 var newestBlock = func() (*chainhash.Hash, int32, error) { 690 hashStr := "14a0810ac680a3eb3f82edc878cea25ec41d6b790744e5daeef" 691 hash, err := chainhash.NewHashFromStr(hashStr) 692 if err != nil { 693 return nil, 0, err 694 } 695 return hash, 234439, nil 696 } 697 698 peerCfg.NewestBlock = newestBlock 699 r1, w1 := io.Pipe() 700 c1 := &conn{raddr: "10.0.0.1:8333", Writer: w1, Reader: r1} 701 p1, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") 702 if err != nil { 703 t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) 704 return 705 } 706 p1.AssociateConnection(c1) 707 708 // Test update latest block 709 latestBlockHash, err := chainhash.NewHashFromStr("1a63f9cdff1752e6375c8c76e543a71d239e1a2e5c6db1aa679") 710 if err != nil { 711 t.Errorf("NewHashFromStr: unexpected err %v\n", err) 712 return 713 } 714 p1.UpdateLastAnnouncedBlock(latestBlockHash) 715 p1.UpdateLastBlockHeight(234440) 716 if p1.LastAnnouncedBlock() != latestBlockHash { 717 t.Errorf("LastAnnouncedBlock: wrong block - got %v, want %v", 718 p1.LastAnnouncedBlock(), latestBlockHash) 719 return 720 } 721 722 // Test Queue Inv after connection 723 p1.QueueInventory(fakeInv) 724 p1.Disconnect() 725 726 // Test regression 727 peerCfg.ChainParams = &chaincfg.RegressionNetParams 728 peerCfg.Services = wire.SFNodeBloom 729 r2, w2 := io.Pipe() 730 c2 := &conn{raddr: "10.0.0.1:8333", Writer: w2, Reader: r2} 731 p2, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") 732 if err != nil { 733 t.Errorf("NewOutboundPeer: unexpected err - %v\n", err) 734 return 735 } 736 p2.AssociateConnection(c2) 737 738 // Test PushXXX 739 var addrs []*wire.NetAddress 740 for i := 0; i < 5; i++ { 741 na := wire.NetAddress{} 742 addrs = append(addrs, &na) 743 } 744 if _, err := p2.PushAddrMsg(addrs); err != nil { 745 t.Errorf("PushAddrMsg: unexpected err %v\n", err) 746 return 747 } 748 if err := p2.PushGetBlocksMsg(nil, &chainhash.Hash{}); err != nil { 749 t.Errorf("PushGetBlocksMsg: unexpected err %v\n", err) 750 return 751 } 752 if err := p2.PushGetHeadersMsg(nil, &chainhash.Hash{}); err != nil { 753 t.Errorf("PushGetHeadersMsg: unexpected err %v\n", err) 754 return 755 } 756 757 p2.PushRejectMsg("block", wire.RejectMalformed, "malformed", nil, false) 758 p2.PushRejectMsg("block", wire.RejectInvalid, "invalid", nil, false) 759 760 // Test Queue Messages 761 p2.QueueMessage(wire.NewMsgGetAddr(), nil) 762 p2.QueueMessage(wire.NewMsgPing(1), nil) 763 p2.QueueMessage(wire.NewMsgMemPool(), nil) 764 p2.QueueMessage(wire.NewMsgGetData(), nil) 765 p2.QueueMessage(wire.NewMsgGetHeaders(), nil) 766 p2.QueueMessage(wire.NewMsgFeeFilter(20000), nil) 767 768 p2.Disconnect() 769 } 770 771 // Tests that the node disconnects from peers with an unsupported protocol 772 // version. 773 func TestUnsupportedVersionPeer(t *testing.T) { 774 peerCfg := &peer.Config{ 775 UserAgentName: "peer", 776 UserAgentVersion: "1.0", 777 UserAgentComments: []string{"comment"}, 778 ChainParams: &chaincfg.MainNetParams, 779 Services: 0, 780 TrickleInterval: time.Second * 10, 781 AllowSelfConns: true, 782 } 783 784 localNA := wire.NewNetAddressIPPort( 785 net.ParseIP("10.0.0.1"), 786 uint16(8333), 787 wire.SFNodeNetwork, 788 ) 789 remoteNA := wire.NewNetAddressIPPort( 790 net.ParseIP("10.0.0.2"), 791 uint16(8333), 792 wire.SFNodeNetwork, 793 ) 794 localConn, remoteConn := pipe( 795 &conn{laddr: "10.0.0.1:8333", raddr: "10.0.0.2:8333"}, 796 &conn{laddr: "10.0.0.2:8333", raddr: "10.0.0.1:8333"}, 797 ) 798 799 p, err := peer.NewOutboundPeer(peerCfg, "10.0.0.1:8333") 800 if err != nil { 801 t.Fatalf("NewOutboundPeer: unexpected err - %v\n", err) 802 } 803 p.AssociateConnection(localConn) 804 805 // Read outbound messages to peer into a channel 806 outboundMessages := make(chan wire.Message) 807 go func() { 808 for { 809 _, msg, _, err := wire.ReadMessageN( 810 remoteConn, 811 p.ProtocolVersion(), 812 peerCfg.ChainParams.Net, 813 ) 814 if err == io.EOF { 815 close(outboundMessages) 816 return 817 } 818 if err != nil { 819 t.Errorf("Error reading message from local node: %v\n", err) 820 return 821 } 822 823 outboundMessages <- msg 824 } 825 }() 826 827 // Read version message sent to remote peer 828 select { 829 case msg := <-outboundMessages: 830 if _, ok := msg.(*wire.MsgVersion); !ok { 831 t.Fatalf("Expected version message, got [%s]", msg.Command()) 832 } 833 case <-time.After(time.Second): 834 t.Fatal("Peer did not send version message") 835 } 836 837 // Remote peer writes version message advertising invalid protocol version 1 838 invalidVersionMsg := wire.NewMsgVersion(remoteNA, localNA, 0, 0) 839 invalidVersionMsg.ProtocolVersion = 1 840 841 _, err = wire.WriteMessageN( 842 remoteConn.Writer, 843 invalidVersionMsg, 844 uint32(invalidVersionMsg.ProtocolVersion), 845 peerCfg.ChainParams.Net, 846 ) 847 if err != nil { 848 t.Fatalf("wire.WriteMessageN: unexpected err - %v\n", err) 849 } 850 851 // Expect peer to disconnect automatically 852 disconnected := make(chan struct{}) 853 go func() { 854 p.WaitForDisconnect() 855 disconnected <- struct{}{} 856 }() 857 858 select { 859 case <-disconnected: 860 close(disconnected) 861 case <-time.After(time.Second): 862 t.Fatal("Peer did not automatically disconnect") 863 } 864 865 // Expect no further outbound messages from peer 866 select { 867 case msg, chanOpen := <-outboundMessages: 868 if chanOpen { 869 t.Fatalf("Expected no further messages, received [%s]", msg.Command()) 870 } 871 case <-time.After(time.Second): 872 t.Fatal("Timeout waiting for remote reader to close") 873 } 874 } 875 876 // TestDuplicateVersionMsg ensures that receiving a version message after one 877 // has already been received results in the peer being disconnected. 878 func TestDuplicateVersionMsg(t *testing.T) { 879 // Create a pair of peers that are connected to each other using a fake 880 // connection. 881 verack := make(chan struct{}) 882 peerCfg := &peer.Config{ 883 Listeners: peer.MessageListeners{ 884 OnVerAck: func(p *peer.Peer, msg *wire.MsgVerAck) { 885 verack <- struct{}{} 886 }, 887 }, 888 UserAgentName: "peer", 889 UserAgentVersion: "1.0", 890 ChainParams: &chaincfg.MainNetParams, 891 Services: 0, 892 AllowSelfConns: true, 893 } 894 outPeer, err := peer.NewOutboundPeer(peerCfg, "10.0.0.2:8333") 895 if err != nil { 896 t.Fatalf("NewOutboundPeer: unexpected err: %v\n", err) 897 } 898 inPeer := peer.NewInboundPeer(peerCfg) 899 900 err = setupPeerConnection(inPeer, outPeer) 901 if err != nil { 902 t.Fatalf("setupPeerConnection failed to connect: %v\n", err) 903 } 904 905 // Wait for the veracks from the initial protocol version negotiation. 906 for i := 0; i < 2; i++ { 907 select { 908 case <-verack: 909 case <-time.After(time.Second): 910 t.Fatal("verack timeout") 911 } 912 } 913 // Queue a duplicate version message from the outbound peer and wait until 914 // it is sent. 915 done := make(chan struct{}) 916 outPeer.QueueMessage(&wire.MsgVersion{}, done) 917 select { 918 case <-done: 919 case <-time.After(time.Second): 920 t.Fatal("send duplicate version timeout") 921 } 922 // Ensure the peer that is the recipient of the duplicate version closes the 923 // connection. 924 disconnected := make(chan struct{}, 1) 925 go func() { 926 inPeer.WaitForDisconnect() 927 disconnected <- struct{}{} 928 }() 929 select { 930 case <-disconnected: 931 case <-time.After(time.Second): 932 t.Fatal("peer did not disconnect") 933 } 934 } 935 936 // TestUpdateLastBlockHeight ensures the last block height is set properly 937 // during the initial version negotiation and is only allowed to advance to 938 // higher values via the associated update function. 939 func TestUpdateLastBlockHeight(t *testing.T) { 940 // Create a pair of peers that are connected to each other using a fake 941 // connection and the remote peer starting at height 100. 942 const remotePeerHeight = 100 943 verack := make(chan struct{}) 944 peerCfg := peer.Config{ 945 Listeners: peer.MessageListeners{ 946 OnVerAck: func(p *peer.Peer, msg *wire.MsgVerAck) { 947 verack <- struct{}{} 948 }, 949 }, 950 UserAgentName: "peer", 951 UserAgentVersion: "1.0", 952 ChainParams: &chaincfg.MainNetParams, 953 Services: 0, 954 AllowSelfConns: true, 955 } 956 remotePeerCfg := peerCfg 957 remotePeerCfg.NewestBlock = func() (*chainhash.Hash, int32, error) { 958 return &chainhash.Hash{}, remotePeerHeight, nil 959 } 960 localPeer, err := peer.NewOutboundPeer(&peerCfg, "10.0.0.2:8333") 961 if err != nil { 962 t.Fatalf("NewOutboundPeer: unexpected err: %v\n", err) 963 } 964 inPeer := peer.NewInboundPeer(&remotePeerCfg) 965 966 err = setupPeerConnection(inPeer, localPeer) 967 if err != nil { 968 t.Fatalf("setupPeerConnection failed to connect: %v\n", err) 969 } 970 971 // Wait for the veracks from the initial protocol version negotiation. 972 for i := 0; i < 2; i++ { 973 select { 974 case <-verack: 975 case <-time.After(time.Second): 976 t.Fatal("verack timeout") 977 } 978 } 979 980 // Ensure the latest block height starts at the value reported by the remote 981 // peer via its version message. 982 if height := localPeer.LastBlock(); height != remotePeerHeight { 983 t.Fatalf("wrong starting height - got %d, want %d", height, 984 remotePeerHeight) 985 } 986 987 // Ensure the latest block height is not allowed to go backwards. 988 localPeer.UpdateLastBlockHeight(remotePeerHeight - 1) 989 if height := localPeer.LastBlock(); height != remotePeerHeight { 990 t.Fatalf("height allowed to go backwards - got %d, want %d", height, 991 remotePeerHeight) 992 } 993 994 // Ensure the latest block height is allowed to advance. 995 localPeer.UpdateLastBlockHeight(remotePeerHeight + 1) 996 if height := localPeer.LastBlock(); height != remotePeerHeight+1 { 997 t.Fatalf("height not allowed to advance - got %d, want %d", height, 998 remotePeerHeight+1) 999 } 1000 } 1001 1002 // setupPeerConnection initiates a tcp connection between two peers. 1003 func setupPeerConnection(in, out *peer.Peer) error { 1004 // listenFunc is a function closure that listens for a tcp connection. 1005 // The tcp connection will be the one the inbound peer uses. This will 1006 // be run as a goroutine. 1007 listenFunc := func(l *net.TCPListener, errChan chan error, 1008 listenChan chan struct{}) { 1009 1010 listenChan <- struct{}{} 1011 1012 conn, err := l.Accept() 1013 if err != nil { 1014 errChan <- err 1015 return 1016 } 1017 1018 in.AssociateConnection(conn) 1019 errChan <- nil 1020 } 1021 1022 // dialFunc is a function closure that initiates the tcp connection. 1023 // The tcp connection will be the one the outbound peer uses. 1024 dialFunc := func(addr *net.TCPAddr) error { 1025 conn, err := net.Dial("tcp", addr.String()) 1026 if err != nil { 1027 return err 1028 } 1029 1030 out.AssociateConnection(conn) 1031 return nil 1032 } 1033 1034 listenAddr := "localhost:0" 1035 1036 addr, err := net.ResolveTCPAddr("tcp", listenAddr) 1037 if err != nil { 1038 return err 1039 } 1040 1041 l, err := net.ListenTCP("tcp", addr) 1042 if err != nil { 1043 return err 1044 } 1045 1046 errChan := make(chan error, 1) 1047 listenChan := make(chan struct{}, 1) 1048 1049 go listenFunc(l, errChan, listenChan) 1050 <-listenChan 1051 1052 if err := dialFunc(l.Addr().(*net.TCPAddr)); err != nil { 1053 return err 1054 } 1055 1056 select { 1057 case err = <-errChan: 1058 return err 1059 case <-time.After(time.Second * 2): 1060 return errors.New("failed to create connection") 1061 } 1062 } 1063 1064 // TestSendAddrV2Handshake tests that the version-verack handshake with the 1065 // addition of the sendaddrv2 message works as expected. 1066 func TestSendAddrV2Handshake(t *testing.T) { 1067 verack := make(chan struct{}, 2) 1068 sendaddr := make(chan struct{}, 2) 1069 peer1Cfg := &peer.Config{ 1070 Listeners: peer.MessageListeners{ 1071 OnVerAck: func(p *peer.Peer, msg *wire.MsgVerAck) { 1072 verack <- struct{}{} 1073 }, 1074 OnSendAddrV2: func(p *peer.Peer, 1075 msg *wire.MsgSendAddrV2) { 1076 1077 sendaddr <- struct{}{} 1078 }, 1079 }, 1080 AllowSelfConns: true, 1081 ChainParams: &chaincfg.MainNetParams, 1082 } 1083 1084 peer2Cfg := &peer.Config{ 1085 Listeners: peer1Cfg.Listeners, 1086 AllowSelfConns: true, 1087 ChainParams: &chaincfg.MainNetParams, 1088 } 1089 1090 verackErr := errors.New("verack timeout") 1091 1092 tests := []struct { 1093 name string 1094 expectsV2 bool 1095 setup func() (*peer.Peer, *peer.Peer, error) 1096 }{ 1097 { 1098 "successful sendaddrv2 handshake", 1099 true, 1100 func() (*peer.Peer, *peer.Peer, error) { 1101 inPeer := peer.NewInboundPeer(peer1Cfg) 1102 outPeer, err := peer.NewOutboundPeer( 1103 peer2Cfg, "10.0.0.2:8333", 1104 ) 1105 if err != nil { 1106 return nil, nil, err 1107 } 1108 1109 err = setupPeerConnection(inPeer, outPeer) 1110 if err != nil { 1111 return nil, nil, err 1112 } 1113 1114 for i := 0; i < 4; i++ { 1115 select { 1116 case <-sendaddr: 1117 case <-verack: 1118 case <-time.After(time.Second * 2): 1119 return nil, nil, verackErr 1120 } 1121 } 1122 1123 return inPeer, outPeer, nil 1124 }, 1125 }, 1126 { 1127 "handshake with legacy inbound peer", 1128 false, 1129 func() (*peer.Peer, *peer.Peer, error) { 1130 legacyVersion := wire.AddrV2Version - 1 1131 peer1Cfg.ProtocolVersion = legacyVersion 1132 inPeer := peer.NewInboundPeer(peer1Cfg) 1133 outPeer, err := peer.NewOutboundPeer( 1134 peer2Cfg, "10.0.0.2:8333", 1135 ) 1136 if err != nil { 1137 return nil, nil, err 1138 } 1139 1140 err = setupPeerConnection(inPeer, outPeer) 1141 if err != nil { 1142 return nil, nil, err 1143 } 1144 1145 for i := 0; i < 2; i++ { 1146 select { 1147 case <-verack: 1148 case <-time.After(time.Second * 2): 1149 return nil, nil, verackErr 1150 } 1151 } 1152 1153 return inPeer, outPeer, nil 1154 }, 1155 }, 1156 { 1157 "handshake with legacy outbound peer", 1158 false, 1159 func() (*peer.Peer, *peer.Peer, error) { 1160 inPeer := peer.NewInboundPeer(peer1Cfg) 1161 legacyVersion := wire.AddrV2Version - 1 1162 peer2Cfg.ProtocolVersion = legacyVersion 1163 outPeer, err := peer.NewOutboundPeer( 1164 peer2Cfg, "10.0.0.2:8333", 1165 ) 1166 if err != nil { 1167 return nil, nil, err 1168 } 1169 1170 err = setupPeerConnection(inPeer, outPeer) 1171 if err != nil { 1172 return nil, nil, err 1173 } 1174 1175 for i := 0; i < 2; i++ { 1176 select { 1177 case <-verack: 1178 case <-time.After(time.Second * 2): 1179 return nil, nil, verackErr 1180 } 1181 } 1182 1183 return inPeer, outPeer, nil 1184 }, 1185 }, 1186 } 1187 1188 t.Logf("Running %d tests", len(tests)) 1189 for i, test := range tests { 1190 inPeer, outPeer, err := test.setup() 1191 if err != nil { 1192 t.Fatalf("TestSendAddrV2Handshake setup #%d: "+ 1193 "unexpected err: %v", i, err) 1194 } 1195 1196 if inPeer.WantsAddrV2() != test.expectsV2 { 1197 t.Fatalf("TestSendAddrV2Handshake #%d expected "+ 1198 "wantsAddrV2 to be %v instead was %v", i, 1199 test.expectsV2, inPeer.WantsAddrV2()) 1200 } else if outPeer.WantsAddrV2() != test.expectsV2 { 1201 t.Fatalf("TestSendAddrV2Handshake #%d expected "+ 1202 "wantsAddrV2 to be %v instead was %v", i, 1203 test.expectsV2, outPeer.WantsAddrV2()) 1204 } 1205 1206 inPeer.Disconnect() 1207 outPeer.Disconnect() 1208 inPeer.WaitForDisconnect() 1209 outPeer.WaitForDisconnect() 1210 } 1211 }