From e9298934b97e5c49158150ce6ceebfdf52ccec53 Mon Sep 17 00:00:00 2001 From: pedro martelletto Date: Tue, 13 Dec 2016 11:40:30 +0000 Subject: [PATCH] Add a stub GetCBFilter message. Actual semantic and payload format yet to be defined. --- peer/peer.go | 12 +++++++++++ peer/peer_test.go | 7 ++++++ server.go | 12 +++++++++++ wire/message.go | 4 ++++ wire/msggetcbfilter.go | 49 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+) create mode 100644 wire/msggetcbfilter.go diff --git a/peer/peer.go b/peer/peer.go index 4075c4353..832331a00 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -144,6 +144,10 @@ type MessageListeners struct { // message. OnGetHeaders func(p *Peer, msg *wire.MsgGetHeaders) + // OnGetCBFilter is invoked when a peer receives a getcbfilter bitcoin + // message. + OnGetCBFilter func(p *Peer, msg *wire.MsgGetCBFilter) + // OnFeeFilter is invoked when a peer receives a feefilter bitcoin message. OnFeeFilter func(p *Peer, msg *wire.MsgFeeFilter) @@ -1280,6 +1284,9 @@ func (p *Peer) maybeAddDeadline(pendingResponses map[string]time.Time, msgCmd st // headers. deadline = time.Now().Add(stallResponseTimeout * 3) pendingResponses[wire.CmdHeaders] = deadline + + // XXX pedro: we may need to handle OnCBFilter here depending on the + // protocol behaviour defined. } } @@ -1579,6 +1586,11 @@ out: p.cfg.Listeners.OnGetHeaders(p, msg) } + case *wire.MsgGetCBFilter: + if p.cfg.Listeners.OnGetCBFilter != nil { + p.cfg.Listeners.OnGetCBFilter(p, msg) + } + case *wire.MsgFeeFilter: if p.cfg.Listeners.OnFeeFilter != nil { p.cfg.Listeners.OnFeeFilter(p, msg) diff --git a/peer/peer_test.go b/peer/peer_test.go index 590c95dc7..bbd4008df 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -399,6 +399,9 @@ func TestPeerListeners(t *testing.T) { OnGetHeaders: func(p *peer.Peer, msg *wire.MsgGetHeaders) { ok <- msg }, + OnGetCBFilter: func(p *peer.Peer, msg *wire.MsgGetCBFilter) { + ok <- msg + }, OnFeeFilter: func(p *peer.Peer, msg *wire.MsgFeeFilter) { ok <- msg }, @@ -522,6 +525,10 @@ func TestPeerListeners(t *testing.T) { "OnGetHeaders", wire.NewMsgGetHeaders(), }, + { + "OnGetCBFilter", + wire.NewMsgGetCBFilter(&chainhash.Hash{}), + }, { "OnFeeFilter", wire.NewMsgFeeFilter(15000), diff --git a/server.go b/server.go index 80fd0f42d..c180700da 100644 --- a/server.go +++ b/server.go @@ -738,6 +738,17 @@ func (sp *serverPeer) OnGetHeaders(_ *peer.Peer, msg *wire.MsgGetHeaders) { sp.QueueMessage(&wire.MsgHeaders{Headers: blockHeaders}, nil) } +// OnGetCBFilter is invoked when a peer receives a getcbfilter bitcoin message. +func (sp *serverPeer) OnGetCBFilter(_ *peer.Peer, msg *wire.MsgGetCBFilter) { + // Ignore getcbfilter requests if not in sync. + if !sp.server.blockManager.IsCurrent() { + return + } + + // XXX pedro: work in progress + peerLog.Warnf("received OnGetCBFilter") +} + // enforceNodeBloomFlag disconnects the peer if the server is not configured to // allow bloom filters. Additionally, if the peer has negotiated to a protocol // version that is high enough to observe the bloom filter service support bit, @@ -1585,6 +1596,7 @@ func newPeerConfig(sp *serverPeer) *peer.Config { OnGetData: sp.OnGetData, OnGetBlocks: sp.OnGetBlocks, OnGetHeaders: sp.OnGetHeaders, + OnGetCBFilter: sp.OnGetCBFilter, OnFeeFilter: sp.OnFeeFilter, OnFilterAdd: sp.OnFilterAdd, OnFilterClear: sp.OnFilterClear, diff --git a/wire/message.go b/wire/message.go index 80e9fe3cc..b49f7d3b8 100644 --- a/wire/message.go +++ b/wire/message.go @@ -51,6 +51,7 @@ const ( CmdReject = "reject" CmdSendHeaders = "sendheaders" CmdFeeFilter = "feefilter" + CmdGetCBFilter = "getcbfilter" ) // MessageEncoding represents the wire message encoding format to be used. @@ -156,6 +157,9 @@ func makeEmptyMessage(command string) (Message, error) { case CmdFeeFilter: msg = &MsgFeeFilter{} + case CmdGetCBFilter: + msg = &MsgGetCBFilter{} + default: return nil, fmt.Errorf("unhandled command [%s]", command) } diff --git a/wire/msggetcbfilter.go b/wire/msggetcbfilter.go new file mode 100644 index 000000000..ba6a13540 --- /dev/null +++ b/wire/msggetcbfilter.go @@ -0,0 +1,49 @@ +// Copyright (c) 2013-2016 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package wire + +import ( + "io" + + "github.com/btcsuite/btcd/chaincfg/chainhash" +) + +type MsgGetCBFilter struct { + ProtocolVersion uint32 + BlockHash chainhash.Hash +} + +func (msg *MsgGetCBFilter) BtcDecode(r io.Reader, pver uint32) error { + return readElement(r, &msg.BlockHash) +} + +// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. +// This is part of the Message interface implementation. +func (msg *MsgGetCBFilter) BtcEncode(w io.Writer, pver uint32) error { + return writeElement(w, &msg.BlockHash) +} + +// Command returns the protocol command string for the message. This is part +// of the Message interface implementation. +func (msg *MsgGetCBFilter) Command() string { + return CmdGetCBFilter +} + +// MaxPayloadLength returns the maximum length the payload can be for the +// receiver. This is part of the Message interface implementation. +func (msg *MsgGetCBFilter) MaxPayloadLength(pver uint32) uint32 { + // Protocol version 4 bytes + block hash. + return 4 + chainhash.HashSize +} + +// NewMsgGetCBFilter returns a new bitcoin getblocks message that conforms to +// the Message interface using the passed parameters and defaults for the +// remaining fields. +func NewMsgGetCBFilter(blockHash *chainhash.Hash) *MsgGetCBFilter { + return &MsgGetCBFilter{ + ProtocolVersion: ProtocolVersion, + BlockHash: *blockHash, + } +}