From 336b18c584b8131564aa89c041ba91a21511f1b5 Mon Sep 17 00:00:00 2001 From: Jim Posen Date: Mon, 22 Jan 2018 13:56:27 -0800 Subject: [PATCH] wire: Define GetCFCheckpt message. --- peer/peer.go | 9 +++++ peer/peer_test.go | 7 ++++ wire/message.go | 4 +++ wire/message_test.go | 2 ++ wire/msggetcfcheckpt.go | 75 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 wire/msggetcfcheckpt.go diff --git a/peer/peer.go b/peer/peer.go index b9d802a4..4b1c3a53 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -159,6 +159,10 @@ type MessageListeners struct { // bitcoin message. OnGetCFHeaders func(p *Peer, msg *wire.MsgGetCFHeaders) + // OnGetCFCheckpt is invoked when a peer receives a getcfcheckpt + // bitcoin message. + OnGetCFCheckpt func(p *Peer, msg *wire.MsgGetCFCheckpt) + // OnFeeFilter is invoked when a peer receives a feefilter bitcoin message. OnFeeFilter func(p *Peer, msg *wire.MsgFeeFilter) @@ -1601,6 +1605,11 @@ out: p.cfg.Listeners.OnGetCFHeaders(p, msg) } + case *wire.MsgGetCFCheckpt: + if p.cfg.Listeners.OnGetCFCheckpt != nil { + p.cfg.Listeners.OnGetCFCheckpt(p, msg) + } + case *wire.MsgCFilter: if p.cfg.Listeners.OnCFilter != nil { p.cfg.Listeners.OnCFilter(p, msg) diff --git a/peer/peer_test.go b/peer/peer_test.go index cec2f5d2..34ab1144 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -405,6 +405,9 @@ func TestPeerListeners(t *testing.T) { OnGetCFHeaders: func(p *peer.Peer, msg *wire.MsgGetCFHeaders) { ok <- msg }, + OnGetCFCheckpt: func(p *peer.Peer, msg *wire.MsgGetCFCheckpt) { + ok <- msg + }, OnCFilter: func(p *peer.Peer, msg *wire.MsgCFilter) { ok <- msg }, @@ -542,6 +545,10 @@ func TestPeerListeners(t *testing.T) { "OnGetCFHeaders", wire.NewMsgGetCFHeaders(wire.GCSFilterRegular, 0, &chainhash.Hash{}), }, + { + "OnGetCFCheckpt", + wire.NewMsgGetCFCheckpt(wire.GCSFilterRegular, &chainhash.Hash{}), + }, { "OnCFilter", wire.NewMsgCFilter(wire.GCSFilterRegular, &chainhash.Hash{}, diff --git a/wire/message.go b/wire/message.go index f00267d7..f055801e 100644 --- a/wire/message.go +++ b/wire/message.go @@ -53,6 +53,7 @@ const ( CmdFeeFilter = "feefilter" CmdGetCFilters = "getcfilters" CmdGetCFHeaders = "getcfheaders" + CmdGetCFCheckpt = "getcfcheckpt" CmdCFilter = "cfilter" CmdCFHeaders = "cfheaders" ) @@ -166,6 +167,9 @@ func makeEmptyMessage(command string) (Message, error) { case CmdGetCFHeaders: msg = &MsgGetCFHeaders{} + case CmdGetCFCheckpt: + msg = &MsgGetCFCheckpt{} + case CmdCFilter: msg = &MsgCFilter{} diff --git a/wire/message_test.go b/wire/message_test.go index 806a196e..24a01cd8 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -71,6 +71,7 @@ func TestMessage(t *testing.T) { msgReject := NewMsgReject("block", RejectDuplicate, "duplicate block") msgGetCFilters := NewMsgGetCFilters(GCSFilterExtended, 0, &chainhash.Hash{}) msgGetCFHeaders := NewMsgGetCFHeaders(GCSFilterExtended, 0, &chainhash.Hash{}) + msgGetCFCheckpt := NewMsgGetCFCheckpt(GCSFilterExtended, &chainhash.Hash{}) msgCFilter := NewMsgCFilter(GCSFilterExtended, &chainhash.Hash{}, []byte("payload")) msgCFHeaders := NewMsgCFHeaders() @@ -105,6 +106,7 @@ func TestMessage(t *testing.T) { {msgReject, msgReject, pver, MainNet, 79}, {msgGetCFilters, msgGetCFilters, pver, MainNet, 61}, {msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61}, + {msgGetCFCheckpt, msgGetCFCheckpt, pver, MainNet, 57}, {msgCFilter, msgCFilter, pver, MainNet, 65}, {msgCFHeaders, msgCFHeaders, pver, MainNet, 90}, } diff --git a/wire/msggetcfcheckpt.go b/wire/msggetcfcheckpt.go new file mode 100644 index 00000000..12ecce4e --- /dev/null +++ b/wire/msggetcfcheckpt.go @@ -0,0 +1,75 @@ +// Copyright (c) 2018 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" +) + +// MsgGetCFCheckpt is a request for filter headers at evenly spaced intervals +// throughout the blockchain history. It allows to set the FilterType field to +// get headers in the chain of basic (0x00) or extended (0x01) headers. +type MsgGetCFCheckpt struct { + FilterType FilterType + StopHash chainhash.Hash +} + +// BtcDecode decodes r using the bitcoin protocol encoding into the receiver. +// This is part of the Message interface implementation. +func (msg *MsgGetCFCheckpt) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error { + err := readElement(r, &msg.FilterType) + 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 *MsgGetCFCheckpt) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error { + err := writeElement(w, msg.FilterType) + 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 *MsgGetCFCheckpt) Command() string { + return CmdGetCFCheckpt +} + +// MaxPayloadLength returns the maximum length the payload can be for the +// receiver. This is part of the Message interface implementation. +func (msg *MsgGetCFCheckpt) MaxPayloadLength(pver uint32) uint32 { + // Filter type + uint32 + block hash + return 1 + chainhash.HashSize +} + +// NewMsgGetCFCheckpt returns a new bitcoin getcfcheckpt message that conforms +// to the Message interface using the passed parameters and defaults for the +// remaining fields. +func NewMsgGetCFCheckpt(filterType FilterType, stopHash *chainhash.Hash, +) *MsgGetCFCheckpt { + return &MsgGetCFCheckpt{ + FilterType: filterType, + StopHash: *stopHash, + } +}