peer: Implement sendheaders support (BIP0130).
This modifies the peer package to add support for the sendheaders protocol message introduced by BIP0030. NOTE: This does not add support to btcd itself. That requires the server and sync code to make use of the new functionality exposed by these changes. As a result, btcd will still be using protocol version 70011.
This commit is contained in:
parent
c1861bc8fa
commit
8a58f8cf3a
3 changed files with 44 additions and 11 deletions
45
peer/peer.go
45
peer/peer.go
|
@ -26,7 +26,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// MaxProtocolVersion is the max protocol version the peer supports.
|
// MaxProtocolVersion is the max protocol version the peer supports.
|
||||||
MaxProtocolVersion = 70011
|
MaxProtocolVersion = wire.SendHeadersVersion
|
||||||
|
|
||||||
// outputBufferSize is the number of elements the output channels use.
|
// outputBufferSize is the number of elements the output channels use.
|
||||||
outputBufferSize = 50
|
outputBufferSize = 50
|
||||||
|
@ -175,6 +175,10 @@ type MessageListeners struct {
|
||||||
// OnReject is invoked when a peer receives a reject bitcoin message.
|
// OnReject is invoked when a peer receives a reject bitcoin message.
|
||||||
OnReject func(p *Peer, msg *wire.MsgReject)
|
OnReject func(p *Peer, msg *wire.MsgReject)
|
||||||
|
|
||||||
|
// OnSendHeaders is invoked when a peer receives a sendheaders bitcoin
|
||||||
|
// message.
|
||||||
|
OnSendHeaders func(p *Peer, msg *wire.MsgSendHeaders)
|
||||||
|
|
||||||
// OnRead is invoked when a peer receives a bitcoin message. It
|
// OnRead is invoked when a peer receives a bitcoin message. It
|
||||||
// consists of the number of bytes read, the message, and whether or not
|
// consists of the number of bytes read, the message, and whether or not
|
||||||
// an error in the read occurred. Typically, callers will opt to use
|
// an error in the read occurred. Typically, callers will opt to use
|
||||||
|
@ -401,15 +405,16 @@ type Peer struct {
|
||||||
cfg Config
|
cfg Config
|
||||||
inbound bool
|
inbound bool
|
||||||
|
|
||||||
flagsMtx sync.Mutex // protects the peer flags below
|
flagsMtx sync.Mutex // protects the peer flags below
|
||||||
na *wire.NetAddress
|
na *wire.NetAddress
|
||||||
id int32
|
id int32
|
||||||
userAgent string
|
userAgent string
|
||||||
services wire.ServiceFlag
|
services wire.ServiceFlag
|
||||||
versionKnown bool
|
versionKnown bool
|
||||||
protocolVersion uint32
|
protocolVersion uint32
|
||||||
versionSent bool
|
sendHeadersPreferred bool // peer sent a sendheaders message
|
||||||
verAckReceived bool
|
versionSent bool
|
||||||
|
verAckReceived bool
|
||||||
|
|
||||||
knownInventory *mruInventoryMap
|
knownInventory *mruInventoryMap
|
||||||
prevGetBlocksMtx sync.Mutex
|
prevGetBlocksMtx sync.Mutex
|
||||||
|
@ -725,6 +730,17 @@ func (p *Peer) StartingHeight() int32 {
|
||||||
return p.startingHeight
|
return p.startingHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WantsHeaders returns if the peer wants header messages instead of
|
||||||
|
// inventory vectors for blocks.
|
||||||
|
//
|
||||||
|
// This function is safe for concurrent access.
|
||||||
|
func (p *Peer) WantsHeaders() bool {
|
||||||
|
p.flagsMtx.Lock()
|
||||||
|
defer p.flagsMtx.Unlock()
|
||||||
|
|
||||||
|
return p.sendHeadersPreferred
|
||||||
|
}
|
||||||
|
|
||||||
// pushVersionMsg sends a version message to the connected peer using the
|
// pushVersionMsg sends a version message to the connected peer using the
|
||||||
// current state.
|
// current state.
|
||||||
func (p *Peer) pushVersionMsg() error {
|
func (p *Peer) pushVersionMsg() error {
|
||||||
|
@ -1634,6 +1650,15 @@ out:
|
||||||
p.cfg.Listeners.OnReject(p, msg)
|
p.cfg.Listeners.OnReject(p, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case *wire.MsgSendHeaders:
|
||||||
|
p.flagsMtx.Lock()
|
||||||
|
p.sendHeadersPreferred = true
|
||||||
|
p.flagsMtx.Unlock()
|
||||||
|
|
||||||
|
if p.cfg.Listeners.OnSendHeaders != nil {
|
||||||
|
p.cfg.Listeners.OnSendHeaders(p, msg)
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log.Debugf("Received unhandled message of type %v:",
|
log.Debugf("Received unhandled message of type %v:",
|
||||||
rmsg.Command())
|
rmsg.Command())
|
||||||
|
|
|
@ -379,6 +379,9 @@ func TestPeerListeners(t *testing.T) {
|
||||||
OnReject: func(p *peer.Peer, msg *wire.MsgReject) {
|
OnReject: func(p *peer.Peer, msg *wire.MsgReject) {
|
||||||
ok <- msg
|
ok <- msg
|
||||||
},
|
},
|
||||||
|
OnSendHeaders: func(p *peer.Peer, msg *wire.MsgSendHeaders) {
|
||||||
|
ok <- msg
|
||||||
|
},
|
||||||
},
|
},
|
||||||
UserAgentName: "peer",
|
UserAgentName: "peer",
|
||||||
UserAgentVersion: "1.0",
|
UserAgentVersion: "1.0",
|
||||||
|
@ -496,9 +499,13 @@ func TestPeerListeners(t *testing.T) {
|
||||||
// only one version message is allowed
|
// only one version message is allowed
|
||||||
// only one verack message is allowed
|
// only one verack message is allowed
|
||||||
{
|
{
|
||||||
"OnMsgReject",
|
"OnReject",
|
||||||
wire.NewMsgReject("block", wire.RejectDuplicate, "dupe block"),
|
wire.NewMsgReject("block", wire.RejectDuplicate, "dupe block"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"OnSendHeaders",
|
||||||
|
wire.NewMsgSendHeaders(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
t.Logf("Running %d tests", len(tests))
|
t.Logf("Running %d tests", len(tests))
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
|
|
|
@ -1453,6 +1453,7 @@ func newPeerConfig(sp *serverPeer) *peer.Config {
|
||||||
ChainParams: sp.server.chainParams,
|
ChainParams: sp.server.chainParams,
|
||||||
Services: sp.server.services,
|
Services: sp.server.services,
|
||||||
DisableRelayTx: false,
|
DisableRelayTx: false,
|
||||||
|
ProtocolVersion: 70011,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue