diff options
author | Andrew Chow <github@achow101.com> | 2023-05-03 17:49:07 -0400 |
---|---|---|
committer | Andrew Chow <github@achow101.com> | 2023-05-03 17:49:57 -0400 |
commit | aebcd18c654a1706954a9e2c9cbfe97dfe531357 (patch) | |
tree | c70b708191f9fc8521b6a4028a0480f9e45700b4 /src | |
parent | 1d7f1ada48083d27adda47e04fd0311cc3cd6816 (diff) | |
parent | c4981e7f63a3e0aeec1ef3dec040261e993dd724 (diff) |
Merge bitcoin/bitcoin#24957: prune, import: allow pruning to work during loadblock import
c4981e7f63a3e0aeec1ef3dec040261e993dd724 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 c4981e7f63a3e0aeec1ef3dec040261e993dd724
Tree-SHA512: d287c7753952c22f598ba782914c47f45ad44ce60b0fbce9561354e701f1a2a98bafaaaa106c8428690b814e281305ca3622b177ed3cb2eb7559f07c958ab537
Diffstat (limited to 'src')
-rw-r--r-- | src/validation.cpp | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/src/validation.cpp b/src/validation.cpp index b2f4283e16..0b46854902 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -4593,6 +4593,9 @@ void Chainstate::LoadExternalBlockFile( // next block, but it's still possible to rewind to the start of the current block (without a disk read). nRewind = nBlockPos + nSize; blkdat.SkipTo(nRewind); + + std::shared_ptr<CBlock> pblock{}; // needs to remain available after the cs_main lock is released to avoid duplicate reads from disk + { LOCK(cs_main); // detect out of order blocks, and store them for later @@ -4610,7 +4613,7 @@ void Chainstate::LoadExternalBlockFile( if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) { // This block can be processed immediately; rewind to its start, read and deserialize it. blkdat.SetPos(nBlockPos); - std::shared_ptr<CBlock> pblock{std::make_shared<CBlock>()}; + pblock = std::make_shared<CBlock>(); blkdat >> *pblock; nRewind = blkdat.GetPos(); @@ -4634,6 +4637,21 @@ void Chainstate::LoadExternalBlockFile( } } + if (m_blockman.IsPruneMode() && !fReindex && pblock) { + // must update the tip for pruning to work while importing with -loadblock. + // this is a tradeoff to conserve disk space at the expense of time + // spent updating the tip to be able to prune. + // otherwise, ActivateBestChain won't be called by the import process + // until after all of the block files are loaded. ActivateBestChain can be + // called by concurrent network message processing. but, that is not + // reliable for the purpose of pruning while importing. + BlockValidationState state; + if (!ActivateBestChain(state, pblock)) { + LogPrint(BCLog::REINDEX, "failed to activate chain (%s)\n", state.ToString()); + break; + } + } + NotifyHeaderTip(*this); if (!blocks_with_unknown_parent) continue; |