diff --git a/peer/peer_test.go b/peer/peer_test.go index 8f80dfb7..cddf7aa3 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -544,7 +544,7 @@ func TestPeerListeners(t *testing.T) { }, { "OnCFilter", - wire.NewMsgCFilter([]byte("payload")), + wire.NewMsgCFilter(&chainhash.Hash{}, []byte("payload")), }, { "OnCFHeaders", diff --git a/server.go b/server.go index a237b31b..1827f2c8 100644 --- a/server.go +++ b/server.go @@ -756,7 +756,7 @@ func (sp *serverPeer) OnGetCFilter(_ *peer.Peer, msg *wire.MsgGetCFilter) { err) } - filterMsg := wire.NewMsgCFilter(filterBytes) + filterMsg := wire.NewMsgCFilter(&msg.BlockHash, filterBytes) sp.QueueMessage(filterMsg, nil) } @@ -806,6 +806,7 @@ func (sp *serverPeer) OnGetCFHeaders(_ *peer.Peer, msg *wire.MsgGetCFHeaders) { headersMsg := wire.NewMsgCFHeaders() headersMsg.AddCFHeader(&header) + headersMsg.StopHash = msg.HashStop sp.QueueMessage(headersMsg, nil) return } @@ -862,6 +863,7 @@ func (sp *serverPeer) OnGetCFHeaders(_ *peer.Peer, msg *wire.MsgGetCFHeaders) { headersMsg.AddCFHeader(&header) } + headersMsg.StopHash = hashList[len(hashList)-1] sp.QueueMessage(headersMsg, nil) } diff --git a/wire/message_test.go b/wire/message_test.go index 2b5e41ef..3a657704 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -71,7 +71,7 @@ func TestMessage(t *testing.T) { msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block") msgGetCFilter := NewMsgGetCFilter(&chainhash.Hash{}, false) msgGetCFHeaders := NewMsgGetCFHeaders() - msgCFilter := NewMsgCFilter([]byte("payload")) + msgCFilter := NewMsgCFilter(&chainhash.Hash{}, []byte("payload")) msgCFHeaders := NewMsgCFHeaders() tests := []struct { @@ -104,8 +104,8 @@ func TestMessage(t *testing.T) { {msgReject, msgReject, pver, MainNet, 79}, {msgGetCFilter, msgGetCFilter, pver, MainNet, 57}, {msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 62}, - {msgCFilter, msgCFilter, pver, MainNet, 32}, - {msgCFHeaders, msgCFHeaders, pver, MainNet, 25}, + {msgCFilter, msgCFilter, pver, MainNet, 64}, + {msgCFHeaders, msgCFHeaders, pver, MainNet, 57}, } t.Logf("Running %d tests", len(tests)) diff --git a/wire/msgcfheaders.go b/wire/msgcfheaders.go index 3b9266b1..615fb3f5 100644 --- a/wire/msgcfheaders.go +++ b/wire/msgcfheaders.go @@ -27,6 +27,7 @@ const ( // of committed filter headers per message is currently 2000. See // MsgGetCFHeaders for details on requesting the headers. type MsgCFHeaders struct { + StopHash chainhash.Hash HeaderHashes []*chainhash.Hash } @@ -45,6 +46,12 @@ func (msg *MsgCFHeaders) AddCFHeader(headerHash *chainhash.Hash) error { // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error { + // Read stop hash + err := readElement(r, &msg.StopHash) + if err != nil { + return err + } + count, err := ReadVarInt(r, pver) if err != nil { return err @@ -76,6 +83,12 @@ func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32) error { // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // This is part of the Message interface implementation. func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32) error { + // Write stop hash + err := writeElement(w, msg.StopHash) + if err != nil { + return err + } + // Limit to max committed headers per message. count := len(msg.HeaderHashes) if count > MaxCFHeadersPerMsg { @@ -85,7 +98,7 @@ func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32) error { return messageError("MsgCFHeaders.BtcEncode", str) } - err := WriteVarInt(w, pver, uint64(count)) + err = WriteVarInt(w, pver, uint64(count)) if err != nil { return err } @@ -125,8 +138,9 @@ func (msg *MsgCFHeaders) Command() string { // MaxPayloadLength returns the maximum length the payload can be for the // receiver. This is part of the Message interface implementation. func (msg *MsgCFHeaders) MaxPayloadLength(pver uint32) uint32 { - // Num headers (varInt) + (header size * max allowed headers). - return MaxVarIntPayload + (MaxCFHeaderPayload * MaxBlockHeadersPerMsg) + // Hash size + num headers (varInt) + (header size * max headers). + return chainhash.HashSize + MaxVarIntPayload + + (MaxCFHeaderPayload * MaxCFHeadersPerMsg) } // NewMsgCFHeaders returns a new bitcoin cfheaders message that conforms to diff --git a/wire/msgcfilter.go b/wire/msgcfilter.go index bd600036..a1d1b0fb 100644 --- a/wire/msgcfilter.go +++ b/wire/msgcfilter.go @@ -7,22 +7,27 @@ package wire import ( "fmt" "io" + + "github.com/btcsuite/btcd/chaincfg/chainhash" ) const ( // MaxCFilterDataSize is the maximum byte size of a committed filter. - MaxCFilterDataSize = 65536 + MaxCFilterDataSize = 262144 ) + type MsgCFilter struct { - Data []byte + BlockHash chainhash.Hash + Data []byte } // BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // This is part of the Message interface implementation. func (msg *MsgCFilter) BtcDecode(r io.Reader, pver uint32) error { var err error + err = readElement(r, &msg.BlockHash) msg.Data, err = ReadVarBytes(r, pver, MaxCFilterDataSize, - "cfilter data") + "cfilter data") return err } @@ -36,6 +41,11 @@ func (msg *MsgCFilter) BtcEncode(w io.Writer, pver uint32) error { return messageError("MsgCFilter.BtcEncode", str) } + err := writeElement(w, msg.BlockHash) + if err != nil { + return err + } + return WriteVarBytes(w, pver, msg.Data) } @@ -65,13 +75,14 @@ func (msg *MsgCFilter) Command() string { // receiver. This is part of the Message interface implementation. func (msg *MsgCFilter) MaxPayloadLength(pver uint32) uint32 { return uint32(VarIntSerializeSize(MaxCFilterDataSize)) + - MaxCFilterDataSize + MaxCFilterDataSize } -// NewMsgFilterAdd returns a new bitcoin filteradd message that conforms to the +// NewMsgCFilter returns a new bitcoin cfilter message that conforms to the // Message interface. See MsgCFilter for details. -func NewMsgCFilter(data []byte) *MsgCFilter { +func NewMsgCFilter(blockHash *chainhash.Hash, data []byte) *MsgCFilter { return &MsgCFilter{ - Data: data, + BlockHash: *blockHash, + Data: data, } }