Rename CFilterHeader to CFHeader on P2P side; fix some bugs/tests

This commit is contained in:
Alex 2017-02-22 19:30:53 -07:00 committed by Olaoluwa Osuntokun
parent ba7b5f3308
commit 8ad7aa5d5d
9 changed files with 189 additions and 153 deletions

View file

@ -123,6 +123,13 @@ type MessageListeners struct {
// OnBlock is invoked when a peer receives a block bitcoin message. // OnBlock is invoked when a peer receives a block bitcoin message.
OnBlock func(p *Peer, msg *wire.MsgBlock, buf []byte) 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 is invoked when a peer receives an inv bitcoin message.
OnInv func(p *Peer, msg *wire.MsgInv) OnInv func(p *Peer, msg *wire.MsgInv)
@ -148,9 +155,9 @@ type MessageListeners struct {
// message. // message.
OnGetCFilter func(p *Peer, msg *wire.MsgGetCFilter) OnGetCFilter func(p *Peer, msg *wire.MsgGetCFilter)
// OnGetCFilterHeader is invoked when a peer receives a // OnGetCFHeader is invoked when a peer receives a getcfheader
// getcfilterheader bitcoin message. // bitcoin message.
OnGetCFilterHeader func(p *Peer, msg *wire.MsgGetCFilterHeader) OnGetCFHeader func(p *Peer, msg *wire.MsgGetCFHeader)
// OnFeeFilter is invoked when a peer receives a feefilter bitcoin message. // OnFeeFilter is invoked when a peer receives a feefilter bitcoin message.
OnFeeFilter func(p *Peer, msg *wire.MsgFeeFilter) OnFeeFilter func(p *Peer, msg *wire.MsgFeeFilter)
@ -1592,9 +1599,19 @@ out:
p.cfg.Listeners.OnGetCFilter(p, msg) p.cfg.Listeners.OnGetCFilter(p, msg)
} }
case *wire.MsgGetCFilterHeader: case *wire.MsgGetCFHeader:
if p.cfg.Listeners.OnGetCFilterHeader != nil { if p.cfg.Listeners.OnGetCFHeader != nil {
p.cfg.Listeners.OnGetCFilterHeader(p, msg) 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: case *wire.MsgFeeFilter:

View file

@ -402,7 +402,13 @@ func TestPeerListeners(t *testing.T) {
OnGetCFilter: func(p *peer.Peer, msg *wire.MsgGetCFilter) { OnGetCFilter: func(p *peer.Peer, msg *wire.MsgGetCFilter) {
ok <- msg 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 ok <- msg
}, },
OnFeeFilter: func(p *peer.Peer, msg *wire.MsgFeeFilter) { OnFeeFilter: func(p *peer.Peer, msg *wire.MsgFeeFilter) {
@ -530,11 +536,19 @@ func TestPeerListeners(t *testing.T) {
}, },
{ {
"OnGetCFilter", "OnGetCFilter",
wire.NewMsgGetCFilter(&chainhash.Hash{}), wire.NewMsgGetCFilter(&chainhash.Hash{}, false),
}, },
{ {
"OnGetCFilterHeader", "OnGetCFHeader",
wire.NewMsgGetCFilterHeader(&chainhash.Hash{}), wire.NewMsgGetCFHeader(&chainhash.Hash{}, false),
},
{
"OnCFilter",
wire.NewMsgCFilter([]byte("payload")),
},
{
"OnCFHeader",
wire.NewMsgCFHeader([]byte("payload")),
}, },
{ {
"OnFeeFilter", "OnFeeFilter",

View file

@ -760,9 +760,8 @@ func (sp *serverPeer) OnGetCFilter(_ *peer.Peer, msg *wire.MsgGetCFilter) {
sp.QueueMessage(filterMsg, nil) sp.QueueMessage(filterMsg, nil)
} }
// OnGetCFilterHeader is invoked when a peer receives a getcfilterheader bitcoin // OnGetCFHeader is invoked when a peer receives a getcfheader bitcoin message.
// message. func (sp *serverPeer) OnGetCFHeader(_ *peer.Peer, msg *wire.MsgGetCFHeader) {
func (sp *serverPeer) OnGetCFilterHeader(_ *peer.Peer, msg *wire.MsgGetCFilterHeader) {
// Ignore getcfilterheader requests if not in sync. // Ignore getcfilterheader requests if not in sync.
if !sp.server.blockManager.IsCurrent() { if !sp.server.blockManager.IsCurrent() {
return return
@ -778,7 +777,7 @@ func (sp *serverPeer) OnGetCFilterHeader(_ *peer.Peer, msg *wire.MsgGetCFilterHe
msg.BlockHash, err) msg.BlockHash, err)
} }
headerMsg := wire.NewMsgCFilterHeader(headerBytes) headerMsg := wire.NewMsgCFHeader(headerBytes)
sp.QueueMessage(headerMsg, nil) sp.QueueMessage(headerMsg, nil)
} }
@ -1620,25 +1619,25 @@ func disconnectPeer(peerList map[int32]*serverPeer, compareFunc func(*serverPeer
func newPeerConfig(sp *serverPeer) *peer.Config { func newPeerConfig(sp *serverPeer) *peer.Config {
return &peer.Config{ return &peer.Config{
Listeners: peer.MessageListeners{ Listeners: peer.MessageListeners{
OnVersion: sp.OnVersion, OnVersion: sp.OnVersion,
OnMemPool: sp.OnMemPool, OnMemPool: sp.OnMemPool,
OnTx: sp.OnTx, OnTx: sp.OnTx,
OnBlock: sp.OnBlock, OnBlock: sp.OnBlock,
OnInv: sp.OnInv, OnInv: sp.OnInv,
OnHeaders: sp.OnHeaders, OnHeaders: sp.OnHeaders,
OnGetData: sp.OnGetData, OnGetData: sp.OnGetData,
OnGetBlocks: sp.OnGetBlocks, OnGetBlocks: sp.OnGetBlocks,
OnGetHeaders: sp.OnGetHeaders, OnGetHeaders: sp.OnGetHeaders,
OnGetCFilter: sp.OnGetCFilter, OnGetCFilter: sp.OnGetCFilter,
OnGetCFilterHeader: sp.OnGetCFilterHeader, OnGetCFHeader: sp.OnGetCFHeader,
OnFeeFilter: sp.OnFeeFilter, OnFeeFilter: sp.OnFeeFilter,
OnFilterAdd: sp.OnFilterAdd, OnFilterAdd: sp.OnFilterAdd,
OnFilterClear: sp.OnFilterClear, OnFilterClear: sp.OnFilterClear,
OnFilterLoad: sp.OnFilterLoad, OnFilterLoad: sp.OnFilterLoad,
OnGetAddr: sp.OnGetAddr, OnGetAddr: sp.OnGetAddr,
OnAddr: sp.OnAddr, OnAddr: sp.OnAddr,
OnRead: sp.OnRead, OnRead: sp.OnRead,
OnWrite: sp.OnWrite, OnWrite: sp.OnWrite,
// Note: The reference client currently bans peers that send alerts // Note: The reference client currently bans peers that send alerts
// not signed with its key. We could verify against their key, but // not signed with its key. We could verify against their key, but

View file

@ -28,33 +28,33 @@ const MaxMessagePayload = (1024 * 1024 * 32) // 32MB
// Commands used in bitcoin message headers which describe the type of message. // Commands used in bitcoin message headers which describe the type of message.
const ( const (
CmdVersion = "version" CmdVersion = "version"
CmdVerAck = "verack" CmdVerAck = "verack"
CmdGetAddr = "getaddr" CmdGetAddr = "getaddr"
CmdAddr = "addr" CmdAddr = "addr"
CmdGetBlocks = "getblocks" CmdGetBlocks = "getblocks"
CmdInv = "inv" CmdInv = "inv"
CmdGetData = "getdata" CmdGetData = "getdata"
CmdNotFound = "notfound" CmdNotFound = "notfound"
CmdBlock = "block" CmdBlock = "block"
CmdTx = "tx" CmdTx = "tx"
CmdGetHeaders = "getheaders" CmdGetHeaders = "getheaders"
CmdHeaders = "headers" CmdHeaders = "headers"
CmdPing = "ping" CmdPing = "ping"
CmdPong = "pong" CmdPong = "pong"
CmdAlert = "alert" CmdAlert = "alert"
CmdMemPool = "mempool" CmdMemPool = "mempool"
CmdFilterAdd = "filteradd" CmdFilterAdd = "filteradd"
CmdFilterClear = "filterclear" CmdFilterClear = "filterclear"
CmdFilterLoad = "filterload" CmdFilterLoad = "filterload"
CmdMerkleBlock = "merkleblock" CmdMerkleBlock = "merkleblock"
CmdReject = "reject" CmdReject = "reject"
CmdSendHeaders = "sendheaders" CmdSendHeaders = "sendheaders"
CmdFeeFilter = "feefilter" CmdFeeFilter = "feefilter"
CmdGetCFilter = "getcfilter" CmdGetCFilter = "getcfilter"
CmdGetCFilterHeader = "getcfilterheader" CmdGetCFHeader = "getcfheader"
CmdCFilter = "cfilter" CmdCFilter = "cfilter"
CmdCFilterHeader = "cfilterheader" CmdCFHeader = "cfheader"
) )
// MessageEncoding represents the wire message encoding format to be used. // MessageEncoding represents the wire message encoding format to be used.
@ -163,14 +163,14 @@ func makeEmptyMessage(command string) (Message, error) {
case CmdGetCFilter: case CmdGetCFilter:
msg = &MsgGetCFilter{} msg = &MsgGetCFilter{}
case CmdGetCFilterHeader: case CmdGetCFHeader:
msg = &MsgGetCFilterHeader{} msg = &MsgGetCFHeader{}
case CmdCFilter: case CmdCFilter:
msg = &MsgCFilter{} msg = &MsgCFilter{}
case CmdCFilterHeader: case CmdCFHeader:
msg = &MsgCFilterHeader{} msg = &MsgCFHeader{}
default: default:
return nil, fmt.Errorf("unhandled command [%s]", command) return nil, fmt.Errorf("unhandled command [%s]", command)

View file

@ -69,6 +69,10 @@ func TestMessage(t *testing.T) {
bh := NewBlockHeader(1, &chainhash.Hash{}, &chainhash.Hash{}, 0, 0) bh := NewBlockHeader(1, &chainhash.Hash{}, &chainhash.Hash{}, 0, 0)
msgMerkleBlock := NewMsgMerkleBlock(bh) msgMerkleBlock := NewMsgMerkleBlock(bh)
msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block") 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 { tests := []struct {
in Message // Value to encode in Message // Value to encode
@ -98,6 +102,10 @@ func TestMessage(t *testing.T) {
{msgFilterLoad, msgFilterLoad, pver, MainNet, 35}, {msgFilterLoad, msgFilterLoad, pver, MainNet, 35},
{msgMerkleBlock, msgMerkleBlock, pver, MainNet, 110}, {msgMerkleBlock, msgMerkleBlock, pver, MainNet, 110},
{msgReject, msgReject, pver, MainNet, 79}, {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)) t.Logf("Running %d tests", len(tests))

View file

@ -6,36 +6,38 @@ package wire
import ( import (
"fmt" "fmt"
"github.com/btcsuite/fastsha256"
"io" "io"
"github.com/btcsuite/fastsha256"
) )
const ( const (
// MaxCFilterHeaderDataSize is the maximum byte size of a committed // MaxCFHeaderDataSize is the maximum byte size of a committed
// filter header. // filter header.
MaxCFilterHeaderDataSize = fastsha256.Size MaxCFHeaderDataSize = fastsha256.Size
) )
type MsgCFilterHeader struct {
type MsgCFHeader struct {
Data []byte Data []byte
} }
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation. // 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 var err error
msg.Data, err = ReadVarBytes(r, pver, MaxCFilterHeaderDataSize, msg.Data, err = ReadVarBytes(r, pver, MaxCFHeaderDataSize,
"cf header data") "cf header data")
return err return err
} }
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding. // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation. // 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) size := len(msg.Data)
if size > MaxCFilterHeaderDataSize { if size > MaxCFHeaderDataSize {
str := fmt.Sprintf("cf header size too large for message " + str := fmt.Sprintf("cf header size too large for message "+
"[size %v, max %v]", size, MaxCFilterHeaderDataSize) "[size %v, max %v]", size, MaxCFHeaderDataSize)
return messageError("MsgCFilterHeader.BtcEncode", str) return messageError("MsgCFHeader.BtcEncode", str)
} }
return WriteVarBytes(w, pver, msg.Data) 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 // 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 // instances, but there is a distinct difference and separating the two allows
// the API to be flexible enough to deal with changes. // 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 // 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 // and the stable long-term storage format. As a result, make use of
// BtcDecode. // 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 // Command returns the protocol command string for the message. This is part
// of the Message interface implementation. // of the Message interface implementation.
func (msg *MsgCFilterHeader) Command() string { func (msg *MsgCFHeader) Command() string {
return CmdCFilterHeader return CmdCFHeader
} }
// MaxPayloadLength returns the maximum length the payload can be for the // MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation. // receiver. This is part of the Message interface implementation.
func (msg *MsgCFilterHeader) MaxPayloadLength(pver uint32) uint32 { func (msg *MsgCFHeader) MaxPayloadLength(pver uint32) uint32 {
return uint32(VarIntSerializeSize(MaxCFilterHeaderDataSize)) + return uint32(VarIntSerializeSize(MaxCFHeaderDataSize)) +
MaxCFilterHeaderDataSize MaxCFHeaderDataSize
} }
// NewMsgFilterAdd returns a new bitcoin cfilterheader message that conforms to // NewMsgCFHeader returns a new bitcoin cfheader message that conforms to
// the Message interface. See MsgCFilterHeader for details. // the Message interface. See MsgCFHeader for details.
func NewMsgCFilterHeader(data []byte) *MsgCFilterHeader { func NewMsgCFHeader(data []byte) *MsgCFHeader {
return &MsgCFilterHeader{ return &MsgCFHeader{
Data: data, Data: data,
} }
} }

57
wire/msggetcfheader.go Normal file
View file

@ -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,
}
}

View file

@ -11,9 +11,8 @@ import (
) )
type MsgGetCFilter struct { type MsgGetCFilter struct {
ProtocolVersion uint32 BlockHash chainhash.Hash
BlockHash chainhash.Hash Extended bool
Extended bool
} }
func (msg *MsgGetCFilter) BtcDecode(r io.Reader, pver uint32) error { 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 { if err != nil {
return err return err
} }
return writeElement(w, &msg.Extended) return writeElement(w, msg.Extended)
} }
// Command returns the protocol command string for the message. This is part // 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 // MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation. // receiver. This is part of the Message interface implementation.
func (msg *MsgGetCFilter) MaxPayloadLength(pver uint32) uint32 { func (msg *MsgGetCFilter) MaxPayloadLength(pver uint32) uint32 {
// Protocol version 4 bytes + block hash + Extended flag. // Block hash + Extended flag.
return 4 + chainhash.HashSize + 1 return chainhash.HashSize + 1
} }
// NewMsgGetCFilter returns a new bitcoin getcfilter message that conforms to // NewMsgGetCFilter returns a new bitcoin getcfilter message that conforms to
@ -52,8 +51,7 @@ func (msg *MsgGetCFilter) MaxPayloadLength(pver uint32) uint32 {
// remaining fields. // remaining fields.
func NewMsgGetCFilter(blockHash *chainhash.Hash, extended bool) *MsgGetCFilter { func NewMsgGetCFilter(blockHash *chainhash.Hash, extended bool) *MsgGetCFilter {
return &MsgGetCFilter{ return &MsgGetCFilter{
ProtocolVersion: ProtocolVersion, BlockHash: *blockHash,
BlockHash: *blockHash, Extended: extended,
Extended: extended,
} }
} }

View file

@ -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,
}
}