diff --git a/blockchain/indexers/cfindex.go b/blockchain/indexers/cfindex.go index 01523e7f..5152db30 100644 --- a/blockchain/indexers/cfindex.go +++ b/blockchain/indexers/cfindex.go @@ -171,11 +171,15 @@ func (idx *CfIndex) DisconnectBlock(dbTx database.Tx, block *btcutil.Block, return dbDeleteBasicEntry(dbTx, block.Hash()) } -func (idx *CfIndex) FilterByBlockHash(hash *chainhash.Hash) ([]byte, error) { +func (idx *CfIndex) FilterByBlockHash(hash *chainhash.Hash, extended bool) ([]byte, error) { var filterBytes []byte err := idx.db.View(func(dbTx database.Tx) error { var err error - filterBytes, err = dbFetchBasicEntry(dbTx, hash) + if extended { + filterBytes, err = dbFetchExtendedEntry(dbTx, hash) + } else { + filterBytes, err = dbFetchBasicEntry(dbTx, hash) + } return err }) return filterBytes, err diff --git a/btcjson/chainsvrcmds.go b/btcjson/chainsvrcmds.go index 90462762..9461ff8b 100644 --- a/btcjson/chainsvrcmds.go +++ b/btcjson/chainsvrcmds.go @@ -280,14 +280,16 @@ func NewGetBlockTemplateCmd(request *TemplateRequest) *GetBlockTemplateCmd { } // GetCFilterCmd defines the getcfilter JSON-RPC command. type GetCFilterCmd struct { - Hash string + Hash string + Extended bool } // NewGetCFilterCmd returns a new instance which can be used to issue a // getcfilter JSON-RPC command. -func NewGetCFilterCmd(hash string) *GetCFilterCmd { +func NewGetCFilterCmd(hash string, extended bool) *GetCFilterCmd { return &GetCFilterCmd{ - Hash: hash, + Hash: hash, + Extended: extended, } } diff --git a/btcjson/chainsvrcmds_test.go b/btcjson/chainsvrcmds_test.go index 0501bee5..a5b43b2d 100644 --- a/btcjson/chainsvrcmds_test.go +++ b/btcjson/chainsvrcmds_test.go @@ -320,12 +320,12 @@ func TestChainSvrCmds(t *testing.T) { { name: "getcfilter", newCmd: func() (interface{}, error) { - return btcjson.NewCmd("getcfilter", "123") + return btcjson.NewCmd("getcfilter", "123", false) }, staticCmd: func() interface{} { - return btcjson.NewGetCFilterCmd("123") + return btcjson.NewGetCFilterCmd("123", false) }, - marshalled: `{"jsonrpc":"1.0","method":"getcfilter","params":["123"],"id":1}`, + marshalled: `{"jsonrpc":"1.0","method":"getcfilter","params":["123",false],"id":1}`, unmarshalled: &btcjson.GetCFilterCmd{ Hash: "123", }, diff --git a/peer/peer.go b/peer/peer.go index ea0e3aa2..feefed6c 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -1284,9 +1284,6 @@ 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 OnCFilter here depending on the - // protocol behaviour defined. } } diff --git a/rpcserver.go b/rpcserver.go index 72f0f6a4..6654cd61 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -2154,7 +2154,7 @@ func handleGetCFilter(s *rpcServer, cmd interface{}, closeChan <-chan struct{}) return nil, rpcDecodeHexError(c.Hash) } - filterBytes, err := s.server.cfIndex.FilterByBlockHash(hash) + filterBytes, err := s.server.cfIndex.FilterByBlockHash(hash, c.Extended) if len(filterBytes) > 0 { rpcsLog.Debugf("Found committed filter for %v", hash) } else { diff --git a/server.go b/server.go index bcfcf752..56eae15f 100644 --- a/server.go +++ b/server.go @@ -746,7 +746,8 @@ func (sp *serverPeer) OnGetCFilter(_ *peer.Peer, msg *wire.MsgGetCFilter) { return } - filterBytes, err := sp.server.cfIndex.FilterByBlockHash(&msg.BlockHash) + filterBytes, err := sp.server.cfIndex.FilterByBlockHash(&msg.BlockHash, + msg.Extended) if len(filterBytes) > 0 { peerLog.Infof("Obtained CB filter for %v", msg.BlockHash) diff --git a/wire/msggetcfilter.go b/wire/msggetcfilter.go index 160fc5f1..5e3e8614 100644 --- a/wire/msggetcfilter.go +++ b/wire/msggetcfilter.go @@ -13,16 +13,25 @@ import ( type MsgGetCFilter struct { ProtocolVersion uint32 BlockHash chainhash.Hash + Extended bool } func (msg *MsgGetCFilter) BtcDecode(r io.Reader, pver uint32) error { - return readElement(r, &msg.BlockHash) + 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 *MsgGetCFilter) BtcEncode(w io.Writer, pver uint32) error { - return writeElement(w, &msg.BlockHash) + 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 @@ -34,16 +43,17 @@ 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. - return 4 + chainhash.HashSize + // Protocol version 4 bytes + block hash + Extended flag. + return 4 + chainhash.HashSize + 1 } // NewMsgGetCFilter returns a new bitcoin getblocks message that conforms to // the Message interface using the passed parameters and defaults for the // remaining fields. -func NewMsgGetCFilter(blockHash *chainhash.Hash) *MsgGetCFilter { +func NewMsgGetCFilter(blockHash *chainhash.Hash, extended bool) *MsgGetCFilter { return &MsgGetCFilter{ - ProtocolVersion: ProtocolVersion, + ProtocolVersion: ProtocolVersion, BlockHash: *blockHash, + Extended: extended, } }