mirror of
https://github.com/btcsuite/btcd.git
synced 2025-03-27 02:37:10 +01:00
multi: Redefine GetCFilters to have StartHeight and StopHash.
This commit is contained in:
parent
3425d33506
commit
daac60675e
8 changed files with 152 additions and 106 deletions
10
peer/peer.go
10
peer/peer.go
|
@ -151,9 +151,9 @@ type MessageListeners struct {
|
|||
// message.
|
||||
OnGetHeaders func(p *Peer, msg *wire.MsgGetHeaders)
|
||||
|
||||
// OnGetCFilter is invoked when a peer receives a getcfilter bitcoin
|
||||
// OnGetCFilters is invoked when a peer receives a getcfilters bitcoin
|
||||
// message.
|
||||
OnGetCFilter func(p *Peer, msg *wire.MsgGetCFilter)
|
||||
OnGetCFilters func(p *Peer, msg *wire.MsgGetCFilters)
|
||||
|
||||
// OnGetCFHeaders is invoked when a peer receives a getcfheaders
|
||||
// bitcoin message.
|
||||
|
@ -1591,9 +1591,9 @@ out:
|
|||
p.cfg.Listeners.OnGetHeaders(p, msg)
|
||||
}
|
||||
|
||||
case *wire.MsgGetCFilter:
|
||||
if p.cfg.Listeners.OnGetCFilter != nil {
|
||||
p.cfg.Listeners.OnGetCFilter(p, msg)
|
||||
case *wire.MsgGetCFilters:
|
||||
if p.cfg.Listeners.OnGetCFilters != nil {
|
||||
p.cfg.Listeners.OnGetCFilters(p, msg)
|
||||
}
|
||||
|
||||
case *wire.MsgGetCFHeaders:
|
||||
|
|
|
@ -399,7 +399,7 @@ func TestPeerListeners(t *testing.T) {
|
|||
OnGetHeaders: func(p *peer.Peer, msg *wire.MsgGetHeaders) {
|
||||
ok <- msg
|
||||
},
|
||||
OnGetCFilter: func(p *peer.Peer, msg *wire.MsgGetCFilter) {
|
||||
OnGetCFilters: func(p *peer.Peer, msg *wire.MsgGetCFilters) {
|
||||
ok <- msg
|
||||
},
|
||||
OnGetCFHeaders: func(p *peer.Peer, msg *wire.MsgGetCFHeaders) {
|
||||
|
@ -535,9 +535,8 @@ func TestPeerListeners(t *testing.T) {
|
|||
wire.NewMsgGetHeaders(),
|
||||
},
|
||||
{
|
||||
"OnGetCFilter",
|
||||
wire.NewMsgGetCFilter(&chainhash.Hash{},
|
||||
wire.GCSFilterRegular),
|
||||
"OnGetCFilters",
|
||||
wire.NewMsgGetCFilters(wire.GCSFilterRegular, 0, &chainhash.Hash{}),
|
||||
},
|
||||
{
|
||||
"OnGetCFHeaders",
|
||||
|
@ -545,8 +544,8 @@ func TestPeerListeners(t *testing.T) {
|
|||
},
|
||||
{
|
||||
"OnCFilter",
|
||||
wire.NewMsgCFilter(&chainhash.Hash{},
|
||||
wire.GCSFilterRegular, []byte("payload")),
|
||||
wire.NewMsgCFilter(wire.GCSFilterRegular, &chainhash.Hash{},
|
||||
[]byte("payload")),
|
||||
},
|
||||
{
|
||||
"OnCFHeaders",
|
||||
|
|
46
server.go
46
server.go
|
@ -743,26 +743,42 @@ func (sp *serverPeer) OnGetHeaders(_ *peer.Peer, msg *wire.MsgGetHeaders) {
|
|||
sp.QueueMessage(&wire.MsgHeaders{Headers: blockHeaders}, nil)
|
||||
}
|
||||
|
||||
// OnGetCFilter is invoked when a peer receives a getcfilter bitcoin message.
|
||||
func (sp *serverPeer) OnGetCFilter(_ *peer.Peer, msg *wire.MsgGetCFilter) {
|
||||
// Ignore getcfilter requests if not in sync.
|
||||
// OnGetCFilters is invoked when a peer receives a getcfilters bitcoin message.
|
||||
func (sp *serverPeer) OnGetCFilters(_ *peer.Peer, msg *wire.MsgGetCFilters) {
|
||||
// Ignore getcfilters requests if not in sync.
|
||||
if !sp.server.syncManager.IsCurrent() {
|
||||
return
|
||||
}
|
||||
|
||||
filterBytes, err := sp.server.cfIndex.FilterByBlockHash(&msg.BlockHash,
|
||||
msg.FilterType)
|
||||
|
||||
if len(filterBytes) > 0 {
|
||||
peerLog.Tracef("Obtained CF for %v", msg.BlockHash)
|
||||
} else {
|
||||
peerLog.Warnf("Could not obtain CF for %v: %v", msg.BlockHash,
|
||||
err)
|
||||
hashes, err := sp.server.chain.HeightToHashRange(int32(msg.StartHeight),
|
||||
&msg.StopHash, wire.MaxGetCFiltersReqRange)
|
||||
if err != nil {
|
||||
peerLog.Debugf("Invalid getcfilters request: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
filterMsg := wire.NewMsgCFilter(&msg.BlockHash, msg.FilterType,
|
||||
filterBytes)
|
||||
sp.QueueMessage(filterMsg, nil)
|
||||
// Create []*chainhash.Hash from []chainhash.Hash to pass to
|
||||
// FiltersByBlockHashes.
|
||||
hashPtrs := make([]*chainhash.Hash, len(hashes))
|
||||
for i := range hashes {
|
||||
hashPtrs[i] = &hashes[i]
|
||||
}
|
||||
|
||||
filters, err := sp.server.cfIndex.FiltersByBlockHashes(hashPtrs,
|
||||
msg.FilterType)
|
||||
if err != nil {
|
||||
peerLog.Errorf("Error retrieving cfilters: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
for i, filterBytes := range filters {
|
||||
if len(filterBytes) == 0 {
|
||||
peerLog.Warnf("Could not obtain cfilter for %v", hashes[i])
|
||||
return
|
||||
}
|
||||
filterMsg := wire.NewMsgCFilter(msg.FilterType, &hashes[i], filterBytes)
|
||||
sp.QueueMessage(filterMsg, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// OnGetCFHeaders is invoked when a peer receives a getcfheader bitcoin message.
|
||||
|
@ -1724,7 +1740,7 @@ func newPeerConfig(sp *serverPeer) *peer.Config {
|
|||
OnGetData: sp.OnGetData,
|
||||
OnGetBlocks: sp.OnGetBlocks,
|
||||
OnGetHeaders: sp.OnGetHeaders,
|
||||
OnGetCFilter: sp.OnGetCFilter,
|
||||
OnGetCFilters: sp.OnGetCFilters,
|
||||
OnGetCFHeaders: sp.OnGetCFHeaders,
|
||||
OnFeeFilter: sp.OnFeeFilter,
|
||||
OnFilterAdd: sp.OnFilterAdd,
|
||||
|
|
|
@ -51,7 +51,7 @@ const (
|
|||
CmdReject = "reject"
|
||||
CmdSendHeaders = "sendheaders"
|
||||
CmdFeeFilter = "feefilter"
|
||||
CmdGetCFilter = "getcfilter"
|
||||
CmdGetCFilters = "getcfilters"
|
||||
CmdGetCFHeaders = "getcfheaders"
|
||||
CmdCFilter = "cfilter"
|
||||
CmdCFHeaders = "cfheaders"
|
||||
|
@ -160,8 +160,8 @@ func makeEmptyMessage(command string) (Message, error) {
|
|||
case CmdFeeFilter:
|
||||
msg = &MsgFeeFilter{}
|
||||
|
||||
case CmdGetCFilter:
|
||||
msg = &MsgGetCFilter{}
|
||||
case CmdGetCFilters:
|
||||
msg = &MsgGetCFilters{}
|
||||
|
||||
case CmdGetCFHeaders:
|
||||
msg = &MsgGetCFHeaders{}
|
||||
|
|
|
@ -69,9 +69,9 @@ 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{}, GCSFilterExtended)
|
||||
msgGetCFilters := NewMsgGetCFilters(GCSFilterExtended, 0, &chainhash.Hash{})
|
||||
msgGetCFHeaders := NewMsgGetCFHeaders()
|
||||
msgCFilter := NewMsgCFilter(&chainhash.Hash{}, GCSFilterExtended,
|
||||
msgCFilter := NewMsgCFilter(GCSFilterExtended, &chainhash.Hash{},
|
||||
[]byte("payload"))
|
||||
msgCFHeaders := NewMsgCFHeaders()
|
||||
|
||||
|
@ -103,7 +103,7 @@ 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},
|
||||
{msgGetCFilters, msgGetCFilters, pver, MainNet, 61},
|
||||
{msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 58},
|
||||
{msgCFilter, msgCFilter, pver, MainNet, 65},
|
||||
{msgCFHeaders, msgCFHeaders, pver, MainNet, 58},
|
||||
|
|
|
@ -30,26 +30,28 @@ const (
|
|||
|
||||
// MsgCFilter implements the Message interface and represents a bitcoin cfilter
|
||||
// message. It is used to deliver a committed filter in response to a
|
||||
// getcfilter (MsgGetCFilter) message.
|
||||
// getcfilters (MsgGetCFilters) message.
|
||||
type MsgCFilter struct {
|
||||
BlockHash chainhash.Hash
|
||||
FilterType FilterType
|
||||
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, _ MessageEncoding) error {
|
||||
// Read the hash of the filter's block
|
||||
err := readElement(r, &msg.BlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Read filter type
|
||||
err = readElement(r, &msg.FilterType)
|
||||
err := readElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read the hash of the filter's block
|
||||
err = readElement(r, &msg.BlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read filter data
|
||||
msg.Data, err = ReadVarBytes(r, pver, MaxCFilterDataSize,
|
||||
"cfilter data")
|
||||
|
@ -66,12 +68,12 @@ func (msg *MsgCFilter) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) er
|
|||
return messageError("MsgCFilter.BtcEncode", str)
|
||||
}
|
||||
|
||||
err := writeElement(w, msg.BlockHash)
|
||||
err := writeElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, msg.FilterType)
|
||||
err = writeElement(w, msg.BlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -110,11 +112,11 @@ func (msg *MsgCFilter) MaxPayloadLength(pver uint32) uint32 {
|
|||
|
||||
// NewMsgCFilter returns a new bitcoin cfilter message that conforms to the
|
||||
// Message interface. See MsgCFilter for details.
|
||||
func NewMsgCFilter(blockHash *chainhash.Hash, filterType FilterType,
|
||||
func NewMsgCFilter(filterType FilterType, blockHash *chainhash.Hash,
|
||||
data []byte) *MsgCFilter {
|
||||
return &MsgCFilter{
|
||||
BlockHash: *blockHash,
|
||||
FilterType: filterType,
|
||||
BlockHash: *blockHash,
|
||||
Data: data,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,62 +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"
|
||||
)
|
||||
|
||||
// MsgGetCFilter implements the Message interface and represents a bitcoin
|
||||
// getcfilter message. It is used to request a committed filter for a block.
|
||||
type MsgGetCFilter struct {
|
||||
BlockHash chainhash.Hash
|
||||
FilterType FilterType
|
||||
}
|
||||
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFilter) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
|
||||
err := readElement(r, &msg.BlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return readElement(r, &msg.FilterType)
|
||||
}
|
||||
|
||||
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFilter) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
|
||||
err := writeElement(w, &msg.BlockHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return writeElement(w, msg.FilterType)
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgGetCFilter) Command() string {
|
||||
return CmdGetCFilter
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// Block hash + filter type.
|
||||
return chainhash.HashSize + 1
|
||||
}
|
||||
|
||||
// NewMsgGetCFilter returns a new bitcoin getcfilter message that conforms to
|
||||
// the Message interface using the passed parameters and defaults for the
|
||||
// remaining fields.
|
||||
func NewMsgGetCFilter(blockHash *chainhash.Hash,
|
||||
filterType FilterType) *MsgGetCFilter {
|
||||
return &MsgGetCFilter{
|
||||
BlockHash: *blockHash,
|
||||
FilterType: filterType,
|
||||
}
|
||||
}
|
91
wire/msggetcfilters.go
Normal file
91
wire/msggetcfilters.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
// 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/roasbeef/btcd/chaincfg/chainhash"
|
||||
)
|
||||
|
||||
// MaxGetCFiltersReqRange the maximum number of filters that may be requested in
|
||||
// a getcfheaders message.
|
||||
const MaxGetCFiltersReqRange = 100
|
||||
|
||||
// MsgGetCFilters implements the Message interface and represents a bitcoin
|
||||
// getcfilters message. It is used to request committed filters for a range of
|
||||
// blocks.
|
||||
type MsgGetCFilters struct {
|
||||
FilterType FilterType
|
||||
StartHeight uint32
|
||||
StopHash chainhash.Hash
|
||||
}
|
||||
|
||||
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFilters) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
|
||||
err := readElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = readElement(r, &msg.StartHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = readElement(r, &msg.StopHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFilters) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
|
||||
err := writeElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, &msg.StartHeight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = writeElement(w, &msg.StopHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Command returns the protocol command string for the message. This is part
|
||||
// of the Message interface implementation.
|
||||
func (msg *MsgGetCFilters) Command() string {
|
||||
return CmdGetCFilters
|
||||
}
|
||||
|
||||
// MaxPayloadLength returns the maximum length the payload can be for the
|
||||
// receiver. This is part of the Message interface implementation.
|
||||
func (msg *MsgGetCFilters) MaxPayloadLength(pver uint32) uint32 {
|
||||
// Filter type + uint32 + block hash
|
||||
return 1 + 4 + chainhash.HashSize
|
||||
}
|
||||
|
||||
// NewMsgGetCFilters returns a new bitcoin getcfilters message that conforms to
|
||||
// the Message interface using the passed parameters and defaults for the
|
||||
// remaining fields.
|
||||
func NewMsgGetCFilters(filterType FilterType, startHeight uint32,
|
||||
stopHash *chainhash.Hash) *MsgGetCFilters {
|
||||
return &MsgGetCFilters{
|
||||
FilterType: filterType,
|
||||
StartHeight: startHeight,
|
||||
StopHash: *stopHash,
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue