@@ -782,6 +782,24 @@ static RPCHelpMan getblock()
782782 };
783783}
784784
785+ // ! Return height of highest block that has been pruned, or std::nullopt if no blocks have been pruned
786+ std::optional<int > GetPruneHeight (const BlockManager& blockman, const CChain& chain) {
787+ AssertLockHeld (::cs_main);
788+
789+ const CBlockIndex* chain_tip{chain.Tip ()};
790+ if (!(chain_tip->nStatus & BLOCK_HAVE_DATA)) return chain_tip->nHeight ;
791+
792+ // Get first block with data, after the last block without data.
793+ // This is the start of the unpruned range of blocks.
794+ const auto & first_unpruned{*Assert (blockman.GetFirstBlock (*chain_tip, /* status_mask=*/ BLOCK_HAVE_DATA))};
795+ if (!first_unpruned.pprev ) {
796+ // No block before the first unpruned block means nothing is pruned.
797+ return std::nullopt ;
798+ }
799+ // Block before the first unpruned block is the last pruned block.
800+ return Assert (first_unpruned.pprev )->nHeight ;
801+ }
802+
785803static RPCHelpMan pruneblockchain ()
786804{
787805 return RPCHelpMan{" pruneblockchain" , " " ,
@@ -834,8 +852,7 @@ static RPCHelpMan pruneblockchain()
834852 }
835853
836854 PruneBlockFilesManual (active_chainstate, height);
837- const CBlockIndex& block{*CHECK_NONFATAL (active_chain.Tip ())};
838- return block.nStatus & BLOCK_HAVE_DATA ? active_chainstate.m_blockman .GetFirstStoredBlock (block)->nHeight - 1 : block.nHeight ;
855+ return GetPruneHeight (chainman.m_blockman , active_chain).value_or (-1 );
839856},
840857 };
841858}
@@ -1288,8 +1305,8 @@ RPCHelpMan getblockchaininfo()
12881305 obj.pushKV (" size_on_disk" , chainman.m_blockman .CalculateCurrentUsage ());
12891306 obj.pushKV (" pruned" , chainman.m_blockman .IsPruneMode ());
12901307 if (chainman.m_blockman .IsPruneMode ()) {
1291- bool has_tip_data = tip. nStatus & BLOCK_HAVE_DATA ;
1292- obj.pushKV (" pruneheight" , has_tip_data ? chainman. m_blockman . GetFirstStoredBlock (tip)-> nHeight : tip. nHeight + 1 );
1308+ const auto prune_height{ GetPruneHeight (chainman. m_blockman , active_chainstate. m_chain )} ;
1309+ obj.pushKV (" pruneheight" , prune_height ? prune_height. value () + 1 : 0 );
12931310
12941311 const bool automatic_pruning{chainman.m_blockman .GetPruneTarget () != BlockManager::PRUNE_TARGET_MANUAL};
12951312 obj.pushKV (" automatic_pruning" , automatic_pruning);
0 commit comments