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  }