github.com/btcsuite/btcd@v0.24.0/peer/example_test.go (about) 1 // Copyright (c) 2015-2018 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 "fmt" 10 "net" 11 "time" 12 13 "github.com/btcsuite/btcd/chaincfg" 14 "github.com/btcsuite/btcd/peer" 15 "github.com/btcsuite/btcd/wire" 16 ) 17 18 // mockRemotePeer creates a basic inbound peer listening on the simnet port for 19 // use with Example_peerConnection. It does not return until the listner is 20 // active. 21 func mockRemotePeer() error { 22 // Configure peer to act as a simnet node that offers no services. 23 peerCfg := &peer.Config{ 24 UserAgentName: "peer", // User agent name to advertise. 25 UserAgentVersion: "1.0.0", // User agent version to advertise. 26 ChainParams: &chaincfg.SimNetParams, 27 TrickleInterval: time.Second * 10, 28 AllowSelfConns: true, 29 } 30 31 // Accept connections on the simnet port. 32 listener, err := net.Listen("tcp", "127.0.0.1:18555") 33 if err != nil { 34 return err 35 } 36 go func() { 37 conn, err := listener.Accept() 38 if err != nil { 39 fmt.Printf("Accept: error %v\n", err) 40 return 41 } 42 43 // Create and start the inbound peer. 44 p := peer.NewInboundPeer(peerCfg) 45 p.AssociateConnection(conn) 46 }() 47 48 return nil 49 } 50 51 // This example demonstrates the basic process for initializing and creating an 52 // outbound peer. Peers negotiate by exchanging version and verack messages. 53 // For demonstration, a simple handler for version message is attached to the 54 // peer. 55 func Example_newOutboundPeer() { 56 // Ordinarily this will not be needed since the outbound peer will be 57 // connecting to a remote peer, however, since this example is executed 58 // and tested, a mock remote peer is needed to listen for the outbound 59 // peer. 60 if err := mockRemotePeer(); err != nil { 61 fmt.Printf("mockRemotePeer: unexpected error %v\n", err) 62 return 63 } 64 65 // Create an outbound peer that is configured to act as a simnet node 66 // that offers no services and has listeners for the version and verack 67 // messages. The verack listener is used here to signal the code below 68 // when the handshake has been finished by signalling a channel. 69 verack := make(chan struct{}) 70 peerCfg := &peer.Config{ 71 UserAgentName: "peer", // User agent name to advertise. 72 UserAgentVersion: "1.0.0", // User agent version to advertise. 73 ChainParams: &chaincfg.SimNetParams, 74 Services: 0, 75 TrickleInterval: time.Second * 10, 76 Listeners: peer.MessageListeners{ 77 OnVersion: func(p *peer.Peer, msg *wire.MsgVersion) *wire.MsgReject { 78 fmt.Println("outbound: received version") 79 return nil 80 }, 81 OnVerAck: func(p *peer.Peer, msg *wire.MsgVerAck) { 82 verack <- struct{}{} 83 }, 84 }, 85 AllowSelfConns: true, 86 } 87 p, err := peer.NewOutboundPeer(peerCfg, "127.0.0.1:18555") 88 if err != nil { 89 fmt.Printf("NewOutboundPeer: error %v\n", err) 90 return 91 } 92 93 // Establish the connection to the peer address and mark it connected. 94 conn, err := net.Dial("tcp", p.Addr()) 95 if err != nil { 96 fmt.Printf("net.Dial: error %v\n", err) 97 return 98 } 99 p.AssociateConnection(conn) 100 101 // Wait for the verack message or timeout in case of failure. 102 select { 103 case <-verack: 104 case <-time.After(time.Second * 1): 105 fmt.Printf("Example_peerConnection: verack timeout") 106 } 107 108 // Disconnect the peer. 109 p.Disconnect() 110 p.WaitForDisconnect() 111 112 // Output: 113 // outbound: received version 114 }