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
|
||||
}
|
||||
|
||||
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.
|
||||
hashList, err := sp.server.chain.HeightToHashRange(int32(msg.StartHeight),
|
||||
&msg.StopHash, wire.MaxCFHeadersPerMsg)
|
||||
hashList, err := sp.server.chain.HeightToHashRange(startHeight,
|
||||
&msg.StopHash, maxResults)
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -815,6 +830,37 @@ func (sp *serverPeer) OnGetCFHeaders(_ *peer.Peer, msg *wire.MsgGetCFHeaders) {
|
|||
|
||||
// Generate cfheaders message and send it.
|
||||
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 {
|
||||
if len(headerBytes) == 0 {
|
||||
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},
|
||||
{msgGetCFHeaders, msgGetCFHeaders, pver, MainNet, 61},
|
||||
{msgCFilter, msgCFilter, pver, MainNet, 65},
|
||||
{msgCFHeaders, msgCFHeaders, pver, MainNet, 58},
|
||||
{msgCFHeaders, msgCFHeaders, pver, MainNet, 90},
|
||||
}
|
||||
|
||||
t.Logf("Running %d tests", len(tests))
|
||||
|
|
|
@ -27,9 +27,10 @@ const (
|
|||
// of committed filter headers per message is currently 2000. See
|
||||
// MsgGetCFHeaders for details on requesting the headers.
|
||||
type MsgCFHeaders struct {
|
||||
StopHash chainhash.Hash
|
||||
FilterType FilterType
|
||||
HeaderHashes []*chainhash.Hash
|
||||
FilterType FilterType
|
||||
StopHash chainhash.Hash
|
||||
PrevFilterHeader chainhash.Hash
|
||||
HeaderHashes []*chainhash.Hash
|
||||
}
|
||||
|
||||
// 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.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgCFHeaders) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
|
||||
// Read stop hash
|
||||
err := readElement(r, &msg.StopHash)
|
||||
// Read filter type
|
||||
err := readElement(r, &msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read filter type
|
||||
err = readElement(r, &msg.FilterType)
|
||||
// Read stop hash
|
||||
err = readElement(r, &msg.StopHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read prev filter header
|
||||
err = readElement(r, &msg.PrevFilterHeader)
|
||||
if err != nil {
|
||||
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.
|
||||
// This is part of the Message interface implementation.
|
||||
func (msg *MsgCFHeaders) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
|
||||
// Write stop hash
|
||||
err := writeElement(w, msg.StopHash)
|
||||
// Write filter type
|
||||
err := writeElement(w, msg.FilterType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write filter type
|
||||
err = writeElement(w, msg.FilterType)
|
||||
// Write stop hash
|
||||
err = writeElement(w, msg.StopHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Write prev filter header
|
||||
err = writeElement(w, msg.PrevFilterHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -154,7 +167,7 @@ func (msg *MsgCFHeaders) Command() string {
|
|||
func (msg *MsgCFHeaders) MaxPayloadLength(pver uint32) uint32 {
|
||||
// Hash size + filter type + num headers (varInt) +
|
||||
// (header size * max headers).
|
||||
return chainhash.HashSize + 1 + MaxVarIntPayload +
|
||||
return 1 + chainhash.HashSize + chainhash.HashSize + MaxVarIntPayload +
|
||||
(MaxCFHeaderPayload * MaxCFHeadersPerMsg)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue