dcrd/peer/example_test.go
Dave Collins 5473e7907f
peer: Deprecate dependency on chaincfg.
The only way the chain params are used by the peer is to ascertain the
network magic to use on the wire (the Net field), so rather than
requiring an entire chain params instance, it is desirable to reduce the
scope such that the caller only needs to specify the specific value the
module peer needs.

To that end, this introduces a new field named Net on the config struct
which the caller can optionally specify in the same vain as the chain
params could previously optionally be specified.

The ultimate goal is to remove the chaincfg dependency altogether,
however, since removing the public ChainParams field is a breaking API
change, the field is deprecated and, in order to maintain API
compatibility, some additional semantics around handling of the
optionalality of the new Net field are introduced.

In particular, the Net field is chosen as follows:

- Use the value specified by the caller directly when set
- Fallback to the network associated with the chain params when set
- Fallback to the test network if neither are set

Finally, it updates the example and tests to specify the network
directly and adds a new test which explicitly tests the new fallback
semantics.
2019-03-16 21:10:59 -05:00

110 lines
3.1 KiB
Go

// Copyright (c) 2015-2016 The btcsuite developers
// Copyright (c) 2016 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package peer_test
import (
"fmt"
"net"
"time"
"github.com/decred/dcrd/peer"
"github.com/decred/dcrd/wire"
)
// mockRemotePeer creates a basic inbound peer listening on the simnet port for
// use with Example_peerConnection. It does not return until the listner is
// active.
func mockRemotePeer() error {
// Configure peer to act as a simnet node that offers no services.
peerCfg := &peer.Config{
UserAgentName: "peer", // User agent name to advertise.
UserAgentVersion: "1.0.0", // User agent version to advertise.
Net: wire.SimNet,
}
// Accept connections on the simnet port.
listener, err := net.Listen("tcp", "127.0.0.1:18555")
if err != nil {
return err
}
go func() {
conn, err := listener.Accept()
if err != nil {
fmt.Printf("Accept: error %v\n", err)
return
}
// Create and start the inbound peer.
p := peer.NewInboundPeer(peerCfg)
p.AssociateConnection(conn)
}()
return nil
}
// This example demonstrates the basic process for initializing and creating an
// outbound peer. Peers negotiate by exchanging version and verack messages.
// For demonstration, a simple handler for version message is attached to the
// peer.
func Example_newOutboundPeer() {
// Ordinarily this will not be needed since the outbound peer will be
// connecting to a remote peer, however, since this example is executed
// and tested, a mock remote peer is needed to listen for the outbound
// peer.
if err := mockRemotePeer(); err != nil {
fmt.Printf("mockRemotePeer: unexpected error %v\n", err)
return
}
// Create an outbound peer that is configured to act as a simnet node
// that offers no services and has listeners for the version and verack
// messages. The verack listener is used here to signal the code below
// when the handshake has been finished by signalling a channel.
verack := make(chan struct{})
peerCfg := &peer.Config{
UserAgentName: "peer", // User agent name to advertise.
UserAgentVersion: "1.0.0", // User agent version to advertise.
Net: wire.SimNet,
Services: 0,
Listeners: peer.MessageListeners{
OnVersion: func(p *peer.Peer, msg *wire.MsgVersion) *wire.MsgReject {
fmt.Println("outbound: received version")
return nil
},
OnVerAck: func(p *peer.Peer, msg *wire.MsgVerAck) {
verack <- struct{}{}
},
},
}
p, err := peer.NewOutboundPeer(peerCfg, "127.0.0.1:18555")
if err != nil {
fmt.Printf("NewOutboundPeer: error %v\n", err)
return
}
// Establish the connection to the peer address and mark it connected.
conn, err := net.Dial("tcp", p.Addr())
if err != nil {
fmt.Printf("net.Dial: error %v\n", err)
return
}
p.AssociateConnection(conn)
// Wait for the verack message or timeout in case of failure.
select {
case <-verack:
case <-time.After(time.Second * 1):
fmt.Printf("Example_peerConnection: verack timeout")
}
// Disconnect the peer.
p.Disconnect()
p.WaitForDisconnect()
// Output:
// outbound: received version
}