mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-06-15 02:26:40 +00:00
103 lines
2.7 KiB
Go
103 lines
2.7 KiB
Go
package p2p
|
|
|
|
import (
|
|
"github.com/daglabs/btcd/peer"
|
|
"github.com/daglabs/btcd/util/daghash"
|
|
"github.com/daglabs/btcd/wire"
|
|
)
|
|
|
|
// OnGetCFHeaders is invoked when a peer receives a getcfheader bitcoin message.
|
|
func (sp *Peer) OnGetCFHeaders(_ *peer.Peer, msg *wire.MsgGetCFHeaders) {
|
|
// Ignore getcfilterheader requests if not in sync.
|
|
if !sp.server.SyncManager.IsCurrent() {
|
|
return
|
|
}
|
|
|
|
startHeight := 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.DAG.HeightToHashRange(startHeight,
|
|
msg.StopHash, maxResults)
|
|
if err != nil {
|
|
peerLog.Debugf("Invalid getcfheaders request: %s", err)
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// Fetch the raw filter hash bytes from the database for all blocks.
|
|
filterHashes, err := sp.server.CfIndex.FilterHashesByBlockHashes(hashList,
|
|
msg.FilterType)
|
|
if err != nil {
|
|
peerLog.Errorf("Error retrieving cfilter hashes: %s", err)
|
|
return
|
|
}
|
|
|
|
// Generate cfheaders message and send it.
|
|
headersMsg := wire.NewMsgCFHeaders()
|
|
|
|
// Populate the PrevFilterHeader field.
|
|
if msg.StartHeight > 0 {
|
|
parentHash := hashList[0]
|
|
|
|
// Fetch the raw committed filter header bytes from the
|
|
// database.
|
|
headerBytes, err := sp.server.CfIndex.FilterHeaderByBlockHash(
|
|
parentHash, msg.FilterType)
|
|
if err != nil {
|
|
peerLog.Errorf("Error retrieving CF header: %s", err)
|
|
return
|
|
}
|
|
if len(headerBytes) == 0 {
|
|
peerLog.Warnf("Could not obtain CF header for %s", parentHash)
|
|
return
|
|
}
|
|
|
|
// Deserialize the hash into PrevFilterHeader.
|
|
err = headersMsg.PrevFilterHeader.SetBytes(headerBytes)
|
|
if err != nil {
|
|
peerLog.Warnf("Committed filter header deserialize "+
|
|
"failed: %s", err)
|
|
return
|
|
}
|
|
|
|
hashList = hashList[1:]
|
|
filterHashes = filterHashes[1:]
|
|
}
|
|
|
|
// Populate HeaderHashes.
|
|
for i, hashBytes := range filterHashes {
|
|
if len(hashBytes) == 0 {
|
|
peerLog.Warnf("Could not obtain CF hash for %s", hashList[i])
|
|
return
|
|
}
|
|
|
|
// Deserialize the hash.
|
|
filterHash, err := daghash.NewHash(hashBytes)
|
|
if err != nil {
|
|
peerLog.Warnf("Committed filter hash deserialize "+
|
|
"failed: %s", err)
|
|
return
|
|
}
|
|
|
|
headersMsg.AddCFHash(filterHash)
|
|
}
|
|
|
|
headersMsg.FilterType = msg.FilterType
|
|
headersMsg.StopHash = msg.StopHash
|
|
sp.QueueMessage(headersMsg, nil)
|
|
}
|