Skip to content

Commit aebcd18

Browse files
committed
Merge bitcoin/bitcoin#24957: prune, import: allow pruning to work during loadblock import
c4981e7 prune, import: fixes #23852 (mruddy) Pull request description: Fixes #23852 This allows pruning to work during the `-loadblock` import process. An example use case is where you have a clean set of block files and you want to create a pruned node from them, but you don't want to alter the input set of block files. #23852 noted that pruning was not working reliably during the loadblock import process. The reason why the loadblock process was not pruning regularly as it progressed is that the pruning process (`BlockManager::FindFilesToPrune`) checks the tip height of the active chainstate, and `CChainState::ActivateBestChain` was not called (which updates that tip height) in `ThreadImport` until after all the import files were processed. An example bash command line that makes it easy to import a bunch of block files: ``` ./src/qt/bitcoin-qt -debug -logthreadnames -datadir=/tmp/btc -prune=550 -loadblock=/readonly/btc/main/blk{00000..00043}.dat ``` One interesting side note is that `CChainState::ActivateBestChain` can be called while the import process is running (in the `loadblk` thread) by concurrent network message processing activity in the `msghand` thread. For example, one way to reproduce this easily is with the `getblockfrompeer` RPC (requesting a block with height greater than 100000) run from a node connected to an importing node. There are other ways too, but this is an easy way. I only mention this to explain how the `max_prune_height=225719` log message in the original issue came to occur. ACKs for top commit: achow101: re-ACK c4981e7 Tree-SHA512: d287c7753952c22f598ba782914c47f45ad44ce60b0fbce9561354e701f1a2a98bafaaaa106c8428690b814e281305ca3622b177ed3cb2eb7559f07c958ab537
2 parents 1d7f1ad + c4981e7 commit aebcd18

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/validation.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4593,6 +4593,9 @@ void Chainstate::LoadExternalBlockFile(
45934593
// next block, but it's still possible to rewind to the start of the current block (without a disk read).
45944594
nRewind = nBlockPos + nSize;
45954595
blkdat.SkipTo(nRewind);
4596+
4597+
std::shared_ptr<CBlock> pblock{}; // needs to remain available after the cs_main lock is released to avoid duplicate reads from disk
4598+
45964599
{
45974600
LOCK(cs_main);
45984601
// detect out of order blocks, and store them for later
@@ -4610,7 +4613,7 @@ void Chainstate::LoadExternalBlockFile(
46104613
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
46114614
// This block can be processed immediately; rewind to its start, read and deserialize it.
46124615
blkdat.SetPos(nBlockPos);
4613-
std::shared_ptr<CBlock> pblock{std::make_shared<CBlock>()};
4616+
pblock = std::make_shared<CBlock>();
46144617
blkdat >> *pblock;
46154618
nRewind = blkdat.GetPos();
46164619

@@ -4634,6 +4637,21 @@ void Chainstate::LoadExternalBlockFile(
46344637
}
46354638
}
46364639

4640+
if (m_blockman.IsPruneMode() && !fReindex && pblock) {
4641+
// must update the tip for pruning to work while importing with -loadblock.
4642+
// this is a tradeoff to conserve disk space at the expense of time
4643+
// spent updating the tip to be able to prune.
4644+
// otherwise, ActivateBestChain won't be called by the import process
4645+
// until after all of the block files are loaded. ActivateBestChain can be
4646+
// called by concurrent network message processing. but, that is not
4647+
// reliable for the purpose of pruning while importing.
4648+
BlockValidationState state;
4649+
if (!ActivateBestChain(state, pblock)) {
4650+
LogPrint(BCLog::REINDEX, "failed to activate chain (%s)\n", state.ToString());
4651+
break;
4652+
}
4653+
}
4654+
46374655
NotifyHeaderTip(*this);
46384656

46394657
if (!blocks_with_unknown_parent) continue;

0 commit comments

Comments
 (0)