mirror of
https://github.com/btcsuite/btcd.git
synced 2026-08-13 12:32:51 +02:00
netsync: change isSyncCandidate behavior to include pruned nodes
isSyncCandidate is now changed to return true even if the peer is a pruned node if and only if our chaintip is within 288 blocks of the peer. Rationale: Pruned nodes that signal NODE_NETWORK_LIMITED MUST serve 288 blocks from their chaintip. If our chaintip is within that range, this peer can be a sync candidate even if they aren't an archival node.
This commit is contained in:
parent
a09e7b224a
commit
b4992febff
2 changed files with 54 additions and 19 deletions
|
|
@ -397,20 +397,55 @@ func (sm *SyncManager) isSyncCandidate(peer *peerpkg.Peer) bool {
|
|||
if host != "127.0.0.1" && host != "localhost" {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
// The peer is not a candidate for sync if it's not a full
|
||||
// node. Additionally, if the segwit soft-fork package has
|
||||
// activated, then the peer must also be upgraded.
|
||||
segwitActive, err := sm.chain.IsDeploymentActive(chaincfg.DeploymentSegwit)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to query for segwit "+
|
||||
"soft-fork state: %v", err)
|
||||
}
|
||||
nodeServices := peer.Services()
|
||||
if nodeServices&wire.SFNodeNetwork != wire.SFNodeNetwork ||
|
||||
(segwitActive && !peer.IsWitnessEnabled()) {
|
||||
|
||||
// Candidate if all checks passed.
|
||||
return true
|
||||
}
|
||||
|
||||
// If the segwit soft-fork package has activated, then the peer must
|
||||
// also be upgraded.
|
||||
segwitActive, err := sm.chain.IsDeploymentActive(
|
||||
chaincfg.DeploymentSegwit,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to query for segwit soft-fork state: %v",
|
||||
err)
|
||||
}
|
||||
|
||||
if segwitActive && !peer.IsWitnessEnabled() {
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
nodeServices = peer.Services()
|
||||
fullNode = nodeServices.HasFlag(wire.SFNodeNetwork)
|
||||
prunedNode = nodeServices.HasFlag(wire.SFNodeNetworkLimited)
|
||||
)
|
||||
|
||||
switch {
|
||||
case fullNode:
|
||||
// Node is a sync candidate if it has all the blocks.
|
||||
|
||||
case prunedNode:
|
||||
// Even if the peer is pruned, if they have the node network
|
||||
// limited flag, they are able to serve 2 days worth of blocks
|
||||
// from the current tip. Therefore, check if our chaintip is
|
||||
// within that range.
|
||||
bestHeight := sm.chain.BestSnapshot().Height
|
||||
peerLastBlock := peer.LastBlock()
|
||||
|
||||
// bestHeight+1 as we need the peer to serve us the next block,
|
||||
// not the one we already have.
|
||||
if bestHeight+1 <=
|
||||
peerLastBlock-wire.NodeNetworkLimitedBlockThreshold {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
default:
|
||||
// If the peer isn't an archival node, and it's not signaling
|
||||
// NODE_NETWORK_LIMITED, we can't sync off of this node.
|
||||
return false
|
||||
}
|
||||
|
||||
// Candidate if all checks passed.
|
||||
|
|
@ -428,7 +463,7 @@ func (sm *SyncManager) handleNewPeerMsg(peer *peerpkg.Peer) {
|
|||
|
||||
log.Infof("New valid peer %s (%s)", peer, peer.UserAgent())
|
||||
|
||||
// Initialize the peer state
|
||||
// Initialize the peer state.
|
||||
isSyncCandidate := sm.isSyncCandidate(peer)
|
||||
sm.peerStates[peer] = &peerSyncState{
|
||||
syncCandidate: isSyncCandidate,
|
||||
|
|
|
|||
|
|
@ -60,6 +60,12 @@ const (
|
|||
AddrV2Version uint32 = 70016
|
||||
)
|
||||
|
||||
const (
|
||||
// NodeNetworkLimitedBlockThreshold is the number of blocks that a node
|
||||
// broadcasting SFNodeNetworkLimited MUST be able to serve from the tip.
|
||||
NodeNetworkLimitedBlockThreshold = 288
|
||||
)
|
||||
|
||||
// ServiceFlag identifies services supported by a bitcoin peer.
|
||||
type ServiceFlag uint64
|
||||
|
||||
|
|
@ -156,12 +162,6 @@ func (f ServiceFlag) String() string {
|
|||
return s
|
||||
}
|
||||
|
||||
const (
|
||||
// NodeNetworkLimitedBlockThreshold is the number of blocks that a node
|
||||
// broadcasting SFNodeNetworkLimited MUST be able to serve from the tip.
|
||||
NodeNetworkLimitedBlockThreshold = 288
|
||||
)
|
||||
|
||||
// BitcoinNet represents which bitcoin network a message belongs to.
|
||||
type BitcoinNet uint32
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue