From 8ad7aa5d5d6f3b9d8067fa0ba7834f45e90a72be Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 22 Feb 2017 19:30:53 -0700 Subject: [PATCH] Rename CFilterHeader to CFHeader on P2P side; fix some bugs/tests --- peer/peer.go | 29 +++++++-- peer/peer_test.go | 22 +++++-- server.go | 45 +++++++------- wire/message.go | 62 ++++++++++---------- wire/message_test.go | 8 +++ wire/{msgcfilterheader.go => msgcfheader.go} | 44 +++++++------- wire/msggetcfheader.go | 57 ++++++++++++++++++ wire/msggetcfilter.go | 16 +++-- wire/msggetcfilterheader.go | 59 ------------------- 9 files changed, 189 insertions(+), 153 deletions(-) rename wire/{msgcfilterheader.go => msgcfheader.go} (62%) create mode 100644 wire/msggetcfheader.go delete mode 100644 wire/msggetcfilterheader.go diff --git a/peer/peer.go b/peer/peer.go index 488f3bcc..858e2fc6 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -123,6 +123,13 @@ type MessageListeners struct { // OnBlock is invoked when a peer receives a block bitcoin message. OnBlock func(p *Peer, msg *wire.MsgBlock, buf []byte) + // OnCFilter is invoked when a peer receives a cfilter bitcoin message. + OnCFilter func(p *Peer, msg *wire.MsgCFilter) + + // OnCFHeader is invoked when a peer receives a cfheader bitcoin + // message. + OnCFHeader func(p *Peer, msg *wire.MsgCFHeader) + // OnInv is invoked when a peer receives an inv bitcoin message. OnInv func(p *Peer, msg *wire.MsgInv) @@ -148,9 +155,9 @@ type MessageListeners struct { // message. OnGetCFilter func(p *Peer, msg *wire.MsgGetCFilter) - // OnGetCFilterHeader is invoked when a peer receives a - // getcfilterheader bitcoin message. - OnGetCFilterHeader func(p *Peer, msg *wire.MsgGetCFilterHeader) + // OnGetCFHeader is invoked when a peer receives a getcfheader + // bitcoin message. + OnGetCFHeader func(p *Peer, msg *wire.MsgGetCFHeader) // OnFeeFilter is invoked when a peer receives a feefilter bitcoin message. OnFeeFilter func(p *Peer, msg *wire.MsgFeeFilter) @@ -1592,9 +1599,19 @@ out: p.cfg.Listeners.OnGetCFilter(p, msg) } - case *wire.MsgGetCFilterHeader: - if p.cfg.Listeners.OnGetCFilterHeader != nil { - p.cfg.Listeners.OnGetCFilterHeader(p, msg) + case *wire.MsgGetCFHeader: + if p.cfg.Listeners.OnGetCFHeader != nil { + p.cfg.Listeners.OnGetCFHeader(p, msg) + } + + case *wire.MsgCFilter: + if p.cfg.Listeners.OnCFilter != nil { + p.cfg.Listeners.OnCFilter(p, msg) + } + + case *wire.MsgCFHeader: + if p.cfg.Listeners.OnCFHeader != nil { + p.cfg.Listeners.OnCFHeader(p, msg) } case *wire.MsgFeeFilter: diff --git a/peer/peer_test.go b/peer/peer_test.go index c913f79e..04e7b7bd 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -402,7 +402,13 @@ func TestPeerListeners(t *testing.T) { OnGetCFilter: func(p *peer.Peer, msg *wire.MsgGetCFilter) { ok <- msg }, - OnGetCFilterHeader: func(p *peer.Peer, msg *wire.MsgGetCFilterHeader) { + OnGetCFHeader: func(p *peer.Peer, msg *wire.MsgGetCFHeader) { + ok <- msg + }, + OnCFilter: func(p *peer.Peer, msg *wire.MsgCFilter) { + ok <- msg + }, + OnCFHeader: func(p *peer.Peer, msg *wire.MsgCFHeader) { ok <- msg }, OnFeeFilter: func(p *peer.Peer, msg *wire.MsgFeeFilter) { @@ -530,11 +536,19 @@ func TestPeerListeners(t *testing.T) { }, { "OnGetCFilter", - wire.NewMsgGetCFilter(&chainhash.Hash{}), + wire.NewMsgGetCFilter(&chainhash.Hash{}, false), }, { - "OnGetCFilterHeader", - wire.NewMsgGetCFilterHeader(&chainhash.Hash{}), + "OnGetCFHeader", + wire.NewMsgGetCFHeader(&chainhash.Hash{}, false), + }, + { + "OnCFilter", + wire.NewMsgCFilter([]byte("payload")), + }, + { + "OnCFHeader", + wire.NewMsgCFHeader([]byte("payload")), }, { "OnFeeFilter", diff --git a/server.go b/server.go index 91b614cb..c1880a9b 100644 --- a/server.go +++ b/server.go @@ -760,9 +760,8 @@ func (sp *serverPeer) OnGetCFilter(_ *peer.Peer, msg *wire.MsgGetCFilter) { sp.QueueMessage(filterMsg, nil) } -// OnGetCFilterHeader is invoked when a peer receives a getcfilterheader bitcoin -// message. -func (sp *serverPeer) OnGetCFilterHeader(_ *peer.Peer, msg *wire.MsgGetCFilterHeader) { +// OnGetCFHeader is invoked when a peer receives a getcfheader bitcoin message. +func (sp *serverPeer) OnGetCFHeader(_ *peer.Peer, msg *wire.MsgGetCFHeader) { // Ignore getcfilterheader requests if not in sync. if !sp.server.blockManager.IsCurrent() { return @@ -778,7 +777,7 @@ func (sp *serverPeer) OnGetCFilterHeader(_ *peer.Peer, msg *wire.MsgGetCFilterHe msg.BlockHash, err) } - headerMsg := wire.NewMsgCFilterHeader(headerBytes) + headerMsg := wire.NewMsgCFHeader(headerBytes) sp.QueueMessage(headerMsg, nil) } @@ -1620,25 +1619,25 @@ func disconnectPeer(peerList map[int32]*serverPeer, compareFunc func(*serverPeer func newPeerConfig(sp *serverPeer) *peer.Config { return &peer.Config{ Listeners: peer.MessageListeners{ - OnVersion: sp.OnVersion, - OnMemPool: sp.OnMemPool, - OnTx: sp.OnTx, - OnBlock: sp.OnBlock, - OnInv: sp.OnInv, - OnHeaders: sp.OnHeaders, - OnGetData: sp.OnGetData, - OnGetBlocks: sp.OnGetBlocks, - OnGetHeaders: sp.OnGetHeaders, - OnGetCFilter: sp.OnGetCFilter, - OnGetCFilterHeader: sp.OnGetCFilterHeader, - OnFeeFilter: sp.OnFeeFilter, - OnFilterAdd: sp.OnFilterAdd, - OnFilterClear: sp.OnFilterClear, - OnFilterLoad: sp.OnFilterLoad, - OnGetAddr: sp.OnGetAddr, - OnAddr: sp.OnAddr, - OnRead: sp.OnRead, - OnWrite: sp.OnWrite, + OnVersion: sp.OnVersion, + OnMemPool: sp.OnMemPool, + OnTx: sp.OnTx, + OnBlock: sp.OnBlock, + OnInv: sp.OnInv, + OnHeaders: sp.OnHeaders, + OnGetData: sp.OnGetData, + OnGetBlocks: sp.OnGetBlocks, + OnGetHeaders: sp.OnGetHeaders, + OnGetCFilter: sp.OnGetCFilter, + OnGetCFHeader: sp.OnGetCFHeader, + OnFeeFilter: sp.OnFeeFilter, + OnFilterAdd: sp.OnFilterAdd, + OnFilterClear: sp.OnFilterClear, + OnFilterLoad: sp.OnFilterLoad, + OnGetAddr: sp.OnGetAddr, + OnAddr: sp.OnAddr, + OnRead: sp.OnRead, + OnWrite: sp.OnWrite, // Note: The reference client currently bans peers that send alerts // not signed with its key. We could verify against their key, but diff --git a/wire/message.go b/wire/message.go index ade36386..377b9673 100644 --- a/wire/message.go +++ b/wire/message.go @@ -28,33 +28,33 @@ const MaxMessagePayload = (1024 * 1024 * 32) // 32MB // Commands used in bitcoin message headers which describe the type of message. const ( - CmdVersion = "version" - CmdVerAck = "verack" - CmdGetAddr = "getaddr" - CmdAddr = "addr" - CmdGetBlocks = "getblocks" - CmdInv = "inv" - CmdGetData = "getdata" - CmdNotFound = "notfound" - CmdBlock = "block" - CmdTx = "tx" - CmdGetHeaders = "getheaders" - CmdHeaders = "headers" - CmdPing = "ping" - CmdPong = "pong" - CmdAlert = "alert" - CmdMemPool = "mempool" - CmdFilterAdd = "filteradd" - CmdFilterClear = "filterclear" - CmdFilterLoad = "filterload" - CmdMerkleBlock = "merkleblock" - CmdReject = "reject" - CmdSendHeaders = "sendheaders" - CmdFeeFilter = "feefilter" - CmdGetCFilter = "getcfilter" - CmdGetCFilterHeader = "getcfilterheader" - CmdCFilter = "cfilter" - CmdCFilterHeader = "cfilterheader" + CmdVersion = "version" + CmdVerAck = "verack" + CmdGetAddr = "getaddr" + CmdAddr = "addr" + CmdGetBlocks = "getblocks" + CmdInv = "inv" + CmdGetData = "getdata" + CmdNotFound = "notfound" + CmdBlock = "block" + CmdTx = "tx" + CmdGetHeaders = "getheaders" + CmdHeaders = "headers" + CmdPing = "ping" + CmdPong = "pong" + CmdAlert = "alert" + CmdMemPool = "mempool" + CmdFilterAdd = "filteradd" + CmdFilterClear = "filterclear" + CmdFilterLoad = "filterload" + CmdMerkleBlock = "merkleblock" + CmdReject = "reject" + CmdSendHeaders = "sendheaders" + CmdFeeFilter = "feefilter" + CmdGetCFilter = "getcfilter" + CmdGetCFHeader = "getcfheader" + CmdCFilter = "cfilter" + CmdCFHeader = "cfheader" ) // MessageEncoding represents the wire message encoding format to be used. @@ -163,14 +163,14 @@ func makeEmptyMessage(command string) (Message, error) { case CmdGetCFilter: msg = &MsgGetCFilter{} - case CmdGetCFilterHeader: - msg = &MsgGetCFilterHeader{} + case CmdGetCFHeader: + msg = &MsgGetCFHeader{} case CmdCFilter: msg = &MsgCFilter{} - case CmdCFilterHeader: - msg = &MsgCFilterHeader{} + case CmdCFHeader: + msg = &MsgCFHeader{} default: return nil, fmt.Errorf("unhandled command [%s]", command) diff --git a/wire/message_test.go b/wire/message_test.go index 83005f4d..1aad5ef7 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -69,6 +69,10 @@ func TestMessage(t *testing.T) { bh := NewBlockHeader(1, &chainhash.Hash{}, &chainhash.Hash{}, 0, 0) msgMerkleBlock := NewMsgMerkleBlock(bh) msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block") + msgGetCFilter := NewMsgGetCFilter(&chainhash.Hash{}, false) + msgGetCFHeader := NewMsgGetCFHeader(&chainhash.Hash{}, false) + msgCFilter := NewMsgCFilter([]byte("payload")) + msgCFHeader := NewMsgCFHeader([]byte("payload")) tests := []struct { in Message // Value to encode @@ -98,6 +102,10 @@ func TestMessage(t *testing.T) { {msgFilterLoad, msgFilterLoad, pver, MainNet, 35}, {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 110}, {msgReject, msgReject, pver, MainNet, 79}, + {msgGetCFilter, msgGetCFilter, pver, MainNet, 57}, + {msgGetCFHeader, msgGetCFHeader, pver, MainNet, 57}, + {msgCFilter, msgCFilter, pver, MainNet, 32}, + {msgCFHeader, msgCFHeader, pver, MainNet, 32}, } t.Logf("Running %d tests", len(tests)) diff --git a/wire/msgcfilterheader.go b/wire/msgcfheader.go similarity index 62% rename from wire/msgcfilterheader.go rename to wire/msgcfheader.go index ca4908e9..f6945544 100644 --- a/wire/msgcfilterheader.go +++ b/wire/msgcfheader.go @@ -6,36 +6,38 @@ package wire import ( "fmt" - "github.com/btcsuite/fastsha256" "io" + + "github.com/btcsuite/fastsha256" ) const ( - // MaxCFilterHeaderDataSize is the maximum byte size of a committed + // MaxCFHeaderDataSize is the maximum byte size of a committed // filter header. - MaxCFilterHeaderDataSize = fastsha256.Size + MaxCFHeaderDataSize = fastsha256.Size ) -type MsgCFilterHeader struct { + +type MsgCFHeader struct { Data []byte } // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. -func (msg *MsgCFilterHeader) BtcDecode(r io.Reader, pver uint32) error { +func (msg *MsgCFHeader) BtcDecode(r io.Reader, pver uint32) error { var err error - msg.Data, err = ReadVarBytes(r, pver, MaxCFilterHeaderDataSize, + msg.Data, err = ReadVarBytes(r, pver, MaxCFHeaderDataSize, "cf header data") return err } // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. -func (msg *MsgCFilterHeader) BtcEncode(w io.Writer, pver uint32) error { +func (msg *MsgCFHeader) BtcEncode(w io.Writer, pver uint32) error { size := len(msg.Data) - if size > MaxCFilterHeaderDataSize { - str := fmt.Sprintf("cf header size too large for message " + - "[size %v, max %v]", size, MaxCFilterHeaderDataSize) - return messageError("MsgCFilterHeader.BtcEncode", str) + if size > MaxCFHeaderDataSize { + str := fmt.Sprintf("cf header size too large for message "+ + "[size %v, max %v]", size, MaxCFHeaderDataSize) + return messageError("MsgCFHeader.BtcEncode", str) } return WriteVarBytes(w, pver, msg.Data) @@ -50,7 +52,7 @@ func (msg *MsgCFilterHeader) BtcEncode(w io.Writer, pver uint32) error { // this comment was written, the encoded filter header is the same in both // instances, but there is a distinct difference and separating the two allows // the API to be flexible enough to deal with changes. -func (msg *MsgCFilterHeader) Deserialize(r io.Reader) error { +func (msg *MsgCFHeader) Deserialize(r io.Reader) error { // At the current time, there is no difference between the wire encoding // and the stable long-term storage format. As a result, make use of // BtcDecode. @@ -59,21 +61,21 @@ func (msg *MsgCFilterHeader) Deserialize(r io.Reader) error { // Command returns the protocol command string for the message. This is part // of the Message interface implementation. -func (msg *MsgCFilterHeader) Command() string { - return CmdCFilterHeader +func (msg *MsgCFHeader) Command() string { + return CmdCFHeader } // MaxPayloadLength returns the maximum length the payload can be for the // receiver. This is part of the Message interface implementation. -func (msg *MsgCFilterHeader) MaxPayloadLength(pver uint32) uint32 { - return uint32(VarIntSerializeSize(MaxCFilterHeaderDataSize)) + - MaxCFilterHeaderDataSize +func (msg *MsgCFHeader) MaxPayloadLength(pver uint32) uint32 { + return uint32(VarIntSerializeSize(MaxCFHeaderDataSize)) + + MaxCFHeaderDataSize } -// NewMsgFilterAdd returns a new bitcoin cfilterheader message that conforms to -// the Message interface. See MsgCFilterHeader for details. -func NewMsgCFilterHeader(data []byte) *MsgCFilterHeader { - return &MsgCFilterHeader{ +// NewMsgCFHeader returns a new bitcoin cfheader message that conforms to +// the Message interface. See MsgCFHeader for details. +func NewMsgCFHeader(data []byte) *MsgCFHeader { + return &MsgCFHeader{ Data: data, } } diff --git a/wire/msggetcfheader.go b/wire/msggetcfheader.go new file mode 100644 index 00000000..0295ca8d --- /dev/null +++ b/wire/msggetcfheader.go @@ -0,0 +1,57 @@ +// Copyright (c) 2017 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 MsgGetCFHeader struct { + BlockHash chainhash.Hash + Extended bool +} + +func (msg *MsgGetCFHeader) BtcDecode(r io.Reader, pver uint32) error { + err := readElement(r, &msg.BlockHash) + if err != nil { + return err + } + return readElement(r, &msg.Extended) +} + +// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. +// This is part of the Message interface implementation. +func (msg *MsgGetCFHeader) BtcEncode(w io.Writer, pver uint32) error { + err := writeElement(w, &msg.BlockHash) + if err != nil { + return err + } + return writeElement(w, msg.Extended) +} + +// Command returns the protocol command string for the message. This is part +// of the Message interface implementation. +func (msg *MsgGetCFHeader) Command() string { + return CmdGetCFHeader +} + +// MaxPayloadLength returns the maximum length the payload can be for the +// receiver. This is part of the Message interface implementation. +func (msg *MsgGetCFHeader) MaxPayloadLength(pver uint32) uint32 { + // Block hash + Extended flag. + return chainhash.HashSize + 1 +} + +// NewMsgGetCFHeader returns a new bitcoin getcfheader message that conforms to +// the Message interface using the passed parameters and defaults for the +// remaining fields. +func NewMsgGetCFHeader(blockHash *chainhash.Hash, extended bool) *MsgGetCFHeader { + return &MsgGetCFHeader{ + BlockHash: *blockHash, + Extended: extended, + } +} diff --git a/wire/msggetcfilter.go b/wire/msggetcfilter.go index 2b775103..f3ae5c91 100644 --- a/wire/msggetcfilter.go +++ b/wire/msggetcfilter.go @@ -11,9 +11,8 @@ import ( ) type MsgGetCFilter struct { - ProtocolVersion uint32 - BlockHash chainhash.Hash - Extended bool + BlockHash chainhash.Hash + Extended bool } func (msg *MsgGetCFilter) BtcDecode(r io.Reader, pver uint32) error { @@ -31,7 +30,7 @@ func (msg *MsgGetCFilter) BtcEncode(w io.Writer, pver uint32) error { if err != nil { return err } - return writeElement(w, &msg.Extended) + return writeElement(w, msg.Extended) } // Command returns the protocol command string for the message. This is part @@ -43,8 +42,8 @@ func (msg *MsgGetCFilter) Command() string { // MaxPayloadLength returns the maximum length the payload can be for the // receiver. This is part of the Message interface implementation. func (msg *MsgGetCFilter) MaxPayloadLength(pver uint32) uint32 { - // Protocol version 4 bytes + block hash + Extended flag. - return 4 + chainhash.HashSize + 1 + // Block hash + Extended flag. + return chainhash.HashSize + 1 } // NewMsgGetCFilter returns a new bitcoin getcfilter message that conforms to @@ -52,8 +51,7 @@ func (msg *MsgGetCFilter) MaxPayloadLength(pver uint32) uint32 { // remaining fields. func NewMsgGetCFilter(blockHash *chainhash.Hash, extended bool) *MsgGetCFilter { return &MsgGetCFilter{ - ProtocolVersion: ProtocolVersion, - BlockHash: *blockHash, - Extended: extended, + BlockHash: *blockHash, + Extended: extended, } } diff --git a/wire/msggetcfilterheader.go b/wire/msggetcfilterheader.go deleted file mode 100644 index d23e1d18..00000000 --- a/wire/msggetcfilterheader.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2017 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 MsgGetCFilterHeader struct { - ProtocolVersion uint32 - BlockHash chainhash.Hash - Extended bool -} - -func (msg *MsgGetCFilterHeader) BtcDecode(r io.Reader, pver uint32) error { - err := readElement(r, &msg.BlockHash) - if err != nil { - return err - } - return readElement(r, &msg.Extended) -} - -// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. -// This is part of the Message interface implementation. -func (msg *MsgGetCFilterHeader) BtcEncode(w io.Writer, pver uint32) error { - err := writeElement(w, &msg.BlockHash) - if err != nil { - return err - } - return writeElement(w, &msg.Extended) -} - -// Command returns the protocol command string for the message. This is part -// of the Message interface implementation. -func (msg *MsgGetCFilterHeader) Command() string { - return CmdGetCFilterHeader -} - -// MaxPayloadLength returns the maximum length the payload can be for the -// receiver. This is part of the Message interface implementation. -func (msg *MsgGetCFilterHeader) MaxPayloadLength(pver uint32) uint32 { - // Protocol version 4 bytes + block hash + Extended flag. - return 4 + chainhash.HashSize + 1 -} - -// NewMsgGetCFilterHeader returns a new bitcoin getcfilterheader message that -// conforms to the Message interface using the passed parameters and defaults -// for the remaining fields. -func NewMsgGetCFilterHeader(blockHash *chainhash.Hash, extended bool) *MsgGetCFilterHeader { - return &MsgGetCFilterHeader{ - ProtocolVersion: ProtocolVersion, - BlockHash: *blockHash, - Extended: extended, - } -}