@@ -4474,6 +4474,9 @@ void Chainstate::LoadExternalBlockFile(
4474
4474
// next block, but it's still possible to rewind to the start of the current block (without a disk read).
4475
4475
nRewind = nBlockPos + nSize;
4476
4476
blkdat.SkipTo (nRewind);
4477
+
4478
+ std::shared_ptr<CBlock> pblock{}; // needs to remain available after the cs_main lock is released to avoid duplicate reads from disk
4479
+
4477
4480
{
4478
4481
LOCK (cs_main);
4479
4482
// detect out of order blocks, and store them for later
@@ -4491,7 +4494,7 @@ void Chainstate::LoadExternalBlockFile(
4491
4494
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0 ) {
4492
4495
// This block can be processed immediately; rewind to its start, read and deserialize it.
4493
4496
blkdat.SetPos (nBlockPos);
4494
- std::shared_ptr<CBlock> pblock{ std::make_shared<CBlock>()} ;
4497
+ pblock = std::make_shared<CBlock>();
4495
4498
blkdat >> *pblock;
4496
4499
nRewind = blkdat.GetPos ();
4497
4500
@@ -4515,6 +4518,21 @@ void Chainstate::LoadExternalBlockFile(
4515
4518
}
4516
4519
}
4517
4520
4521
+ if (m_blockman.IsPruneMode () && !fReindex && pblock) {
4522
+ // must update the tip for pruning to work while importing with -loadblock.
4523
+ // this is a tradeoff to conserve disk space at the expense of time
4524
+ // spent updating the tip to be able to prune.
4525
+ // otherwise, ActivateBestChain won't be called by the import process
4526
+ // until after all of the block files are loaded. ActivateBestChain can be
4527
+ // called by concurrent network message processing. but, that is not
4528
+ // reliable for the purpose of pruning while importing.
4529
+ BlockValidationState state;
4530
+ if (!ActivateBestChain (state, pblock)) {
4531
+ LogPrint (BCLog::REINDEX, " failed to activate chain (%s)\n " , state.ToString ());
4532
+ break ;
4533
+ }
4534
+ }
4535
+
4518
4536
NotifyHeaderTip (*this );
4519
4537
4520
4538
if (!blocks_with_unknown_parent) continue ;
0 commit comments