github.com/palcoin-project/palcd@v1.0.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/palcoin-project/palcd/chaincfg"
    14  	"github.com/palcoin-project/palcd/peer"
    15  	"github.com/palcoin-project/palcd/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  }