multi: Modify CFHeaders message to have a PrevFilterHeader field.
This commit is contained in:
parent
7a53a05878
commit
175af18043
3 changed files with 75 additions and 16 deletions
52
server.go
52
server.go
|
@ -788,13 +788,28 @@ func (sp *serverPeer) OnGetCFHeaders(_ *peer.Peer, msg *wire.MsgGetCFHeaders) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startHeight := int32(msg.StartHeight)
|
||||||
|
maxResults := wire.MaxCFHeadersPerMsg
|
||||||
|
|
||||||
|
// If StartHeight is positive, fetch the predecessor block hash so we can
|
||||||
|
// populate the PrevFilterHeader field.
|
||||||
|
if msg.StartHeight > 0 {
|
||||||
|
startHeight--
|
||||||
|
maxResults++
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch the hashes from the block index.
|
// Fetch the hashes from the block index.
|
||||||
hashList, err := sp.server.chain.HeightToHashRange(int32(msg.StartHeight),
|
hashList, err := sp.server.chain.HeightToHashRange(startHeight,
|
||||||
&msg.StopHash, wire.MaxCFHeadersPerMsg)
|
&msg.StopHash, maxResults)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
peerLog.Debugf("Invalid getcfheaders request: %v", err)
|
peerLog.Debugf("Invalid getcfheaders request: %v", err)
|
||||||
}
|
}
|
||||||
if len(hashList) == 0 {
|
|
||||||
|
// This is possible if StartHeight is one greater that the height of
|
||||||
|
// StopHash, and we pull a valid range of hashes including the previous
|
||||||
|
// filter header.
|
||||||
|
if len(hashList) == 0 || (msg.StartHeight > 0 && len(hashList) == 1) {
|
||||||
|
peerLog.Debug("No results for getcfheaders request")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -815,6 +830,37 @@ func (sp *serverPeer) OnGetCFHeaders(_ *peer.Peer, msg *wire.MsgGetCFHeaders) {
|
||||||
|
|
||||||
// Generate cfheaders message and send it.
|
// Generate cfheaders message and send it.
|
||||||
headersMsg := wire.NewMsgCFHeaders()
|
headersMsg := wire.NewMsgCFHeaders()
|
||||||
|
|
||||||
|
// Populate the PrevFilterHeader field.
|
||||||
|
if msg.StartHeight > 0 {
|
||||||
|
prevBlockHash := &hashList[0]
|
||||||
|
|
||||||
|
// Fetch the raw committed filter header bytes from the
|
||||||
|
// database.
|
||||||
|
headerBytes, err := sp.server.cfIndex.FilterHeaderByBlockHash(
|
||||||
|
prevBlockHash, msg.FilterType)
|
||||||
|
if err != nil {
|
||||||
|
peerLog.Errorf("Error retrieving CF header: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(headerBytes) == 0 {
|
||||||
|
peerLog.Warnf("Could not obtain CF header for %v", prevBlockHash)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deserialize the hash into PrevFilterHeader.
|
||||||
|
err = headersMsg.PrevFilterHeader.SetBytes(headerBytes)
|
||||||
|
if err != nil {
|
||||||
|
peerLog.Warnf("Committed filter header deserialize "+
|
||||||
|
"failed: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
hashList = hashList[1:]
|
||||||
|
filterHeaders = filterHeaders[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate HeaderHashes.
|
||||||
for i, headerBytes := range filterHeaders {
|
for i, headerBytes := range filterHeaders {
|
||||||
if len(headerBytes) == 0 {
|
if len(headerBytes) == 0 {
|
||||||
peerLog.Warnf("Could not obtain CF header for %v", hashList[i])
|
peerLog.Warnf("Could not obtain CF header for %v", hashList[i])
|
||||||
|
|
|
@ -106,7 +106,7 @@ func TestMessage(t *testing.T) {
|
||||||
{msgGetCFilters, msgGetCFilters, pver, MainNet, 61},
|
{msgGetCFilters, msgGetCFilters, pver, MainNet, 61},
|
||||||
{msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61},
|
{msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61},
|
||||||
{msgCFilter, msgCFilter, pver, MainNet, 65},
|
{msgCFilter, msgCFilter, pver, MainNet, 65},
|
||||||
{msgCFHeaders, msgCFHeaders, pver, MainNet, 58},
|
{msgCFHeaders, msgCFHeaders, pver, MainNet, 90},
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Logf("Running %d tests", len(tests))
|
t.Logf("Running %d tests", len(tests))
|
||||||
|
|
|
@ -27,9 +27,10 @@ const (
|
||||||
// of committed filter headers per message is currently 2000. See
|
// of committed filter headers per message is currently 2000. See
|
||||||
// MsgGetCFHeaders for details on requesting the headers.
|
// MsgGetCFHeaders for details on requesting the headers.
|
||||||
type MsgCFHeaders struct {
|
type MsgCFHeaders struct {
|
||||||
StopHash chainhash.Hash
|
FilterType FilterType
|
||||||
FilterType FilterType
|
StopHash chainhash.Hash
|
||||||
HeaderHashes []*chainhash.Hash
|
PrevFilterHeader chainhash.Hash
|
||||||
|
HeaderHashes []*chainhash.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddCFHeader adds a new committed filter header to the message.
|
// AddCFHeader adds a new committed filter header to the message.
|
||||||
|
@ -47,14 +48,20 @@ func (msg *MsgCFHeaders) AddCFHeader(headerHash *chainhash.Hash) error {
|
||||||
// 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 *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
|
func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
|
||||||
// Read stop hash
|
// Read filter type
|
||||||
err := readElement(r, &msg.StopHash)
|
err := readElement(r, &msg.FilterType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read filter type
|
// Read stop hash
|
||||||
err = readElement(r, &msg.FilterType)
|
err = readElement(r, &msg.StopHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read prev filter header
|
||||||
|
err = readElement(r, &msg.PrevFilterHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -91,14 +98,20 @@ func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding)
|
||||||
// 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 *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
|
func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
|
||||||
// Write stop hash
|
// Write filter type
|
||||||
err := writeElement(w, msg.StopHash)
|
err := writeElement(w, msg.FilterType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write filter type
|
// Write stop hash
|
||||||
err = writeElement(w, msg.FilterType)
|
err = writeElement(w, msg.StopHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write prev filter header
|
||||||
|
err = writeElement(w, msg.PrevFilterHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -154,7 +167,7 @@ func (msg *MsgCFHeaders) Command() string {
|
||||||
func (msg *MsgCFHeaders) MaxPayloadLength(pver uint32) uint32 {
|
func (msg *MsgCFHeaders) MaxPayloadLength(pver uint32) uint32 {
|
||||||
// Hash size + filter type + num headers (varInt) +
|
// Hash size + filter type + num headers (varInt) +
|
||||||
// (header size * max headers).
|
// (header size * max headers).
|
||||||
return chainhash.HashSize + 1 + MaxVarIntPayload +
|
return 1 + chainhash.HashSize + chainhash.HashSize + MaxVarIntPayload +
|
||||||
(MaxCFHeaderPayload * MaxCFHeadersPerMsg)
|
(MaxCFHeaderPayload * MaxCFHeadersPerMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue