Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1388,7 +1388,7 @@ void PeerManagerImpl::FindNextBlocksToDownload(const Peer& peer, unsigned int co
// We can't reorg to this chain due to missing undo data until the background sync has finished,
// so downloading blocks from it would be futile.
const CBlockIndex* snap_base{m_chainman.GetSnapshotBaseBlock()};
if (snap_base && state->pindexBestKnownBlock->GetAncestor(snap_base->nHeight) != snap_base) {
if (snap_base && !m_chainman.IsSnapshotValidated() && state->pindexBestKnownBlock->GetAncestor(snap_base->nHeight) != snap_base) {
LogDebug(BCLog::NET, "Not downloading blocks from peer=%d, which doesn't have the snapshot block in its best chain.\n", peer.m_id);
return;
}
Expand Down
25 changes: 25 additions & 0 deletions test/functional/feature_assumeutxo.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,29 @@ def test_sync_from_assumeutxo_node(self, snapshot):
assert 'NETWORK' in ibd_node.getpeerinfo()[0]['servicesnames']
self.sync_blocks(nodes=(ibd_node, snapshot_node))

def test_sync_to_most_work_chain_after_background_validation(self):
"""
After background validation completes, node should be able
to download and process blocks from peers without the snapshot block in their chain.
"""
self.log.info("Testing sync to the most-work chain without the snapshot block after background validation")

miner = self.nodes[0]
snapshot_node = self.nodes[2] # Has already completed background validation

self.log.info("Miner switches to an alternative chain that forks one block before the snapshot block")
fork_point = SNAPSHOT_BASE_HEIGHT - 1
miner_old_height = miner.getblockcount()
miner_old_chainwork = int(miner.getblockchaininfo()['chainwork'], 16)
miner.invalidateblock(miner.getblockhash(fork_point + 1))

self.log.info("Mine one more block than original chain to make the new chain have most work")
self.generate(miner, nblocks=(miner_old_height - fork_point) + 1, sync_fun=self.no_op)
assert int(miner.getblockchaininfo()['chainwork'], 16) > miner_old_chainwork

self.log.info("Snapshot node should reorg to the most-work chain without the snapshot block")
self.sync_blocks(nodes=(snapshot_node, miner))

def assert_only_network_limited_service(self, node):
node_services = node.getnetworkinfo()['localservicesnames']
assert 'NETWORK' not in node_services
Expand Down Expand Up @@ -775,6 +798,8 @@ def check_tx_counts(final: bool) -> None:
# The following test cleans node2 and node3 chain directories.
self.test_sync_from_assumeutxo_node(snapshot=dump_output)

self.test_sync_to_most_work_chain_after_background_validation()

@dataclass
class Block:
hash: str
Expand Down
Loading