Skip to content

Commit 622e79e

Browse files
committed
Merge bitcoin#29021: refactor: rpc: Pass CBlockIndex by reference instead of pointer
fa5989d refactor: rpc: Pass CBlockIndex by reference instead of pointer (MarcoFalke) fa604eb refactor: Use reference instead of pointer in IsBlockPruned (MarcoFalke) Pull request description: Follow-up to bitcoin#29003 (comment) ACKs for top commit: TheCharlatan: ACK fa5989d pablomartin4btc: tACK fa5989d dergoegge: Code review ACK fa5989d Tree-SHA512: 7449de3e3bb435dcbf438df88df343bb70f6edc3228ee7c0078f912ffb415e951ba30f8ecad916765f8cf896f0d784fe30535c5cf997e303cf5af257ade69773
2 parents d5e5810 + fa5989d commit 622e79e

File tree

9 files changed

+58
-62
lines changed

9 files changed

+58
-62
lines changed

src/bench/rpc_blockchain.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static void BlockToJsonVerbose(benchmark::Bench& bench)
4141
{
4242
TestBlockAndIndex data;
4343
bench.run([&] {
44-
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, &data.blockindex, &data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
44+
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
4545
ankerl::nanobench::doNotOptimizeAway(univalue);
4646
});
4747
}
@@ -51,7 +51,7 @@ BENCHMARK(BlockToJsonVerbose, benchmark::PriorityLevel::HIGH);
5151
static void BlockToJsonVerboseWrite(benchmark::Bench& bench)
5252
{
5353
TestBlockAndIndex data;
54-
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, &data.blockindex, &data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
54+
auto univalue = blockToJSON(data.testing_setup->m_node.chainman->m_blockman, data.block, data.blockindex, data.blockindex, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
5555
bench.run([&] {
5656
auto str = univalue.write();
5757
ankerl::nanobench::doNotOptimizeAway(str);

src/node/blockstorage.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -582,10 +582,10 @@ const CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
582582
return nullptr;
583583
}
584584

585-
bool BlockManager::IsBlockPruned(const CBlockIndex* pblockindex)
585+
bool BlockManager::IsBlockPruned(const CBlockIndex& block)
586586
{
587587
AssertLockHeld(::cs_main);
588-
return (m_have_pruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0);
588+
return m_have_pruned && !(block.nStatus & BLOCK_HAVE_DATA) && (block.nTx > 0);
589589
}
590590

591591
const CBlockIndex* BlockManager::GetFirstStoredBlock(const CBlockIndex& upper_block, const CBlockIndex* lower_block)

src/node/blockstorage.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ class BlockManager
344344
bool m_have_pruned = false;
345345

346346
//! Check whether the block associated with this index entry is pruned or not.
347-
bool IsBlockPruned(const CBlockIndex* pblockindex) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
347+
bool IsBlockPruned(const CBlockIndex& block) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
348348

349349
//! Create or update a prune lock identified by its name
350350
void UpdatePruneLock(const std::string& name, const PruneLockInfo& lock_info) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);

src/rest.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ static bool rest_headers(const std::any& context,
264264
case RESTResponseFormat::JSON: {
265265
UniValue jsonHeaders(UniValue::VARR);
266266
for (const CBlockIndex *pindex : headers) {
267-
jsonHeaders.push_back(blockheaderToJSON(tip, pindex));
267+
jsonHeaders.push_back(blockheaderToJSON(*tip, *pindex));
268268
}
269269
std::string strJSON = jsonHeaders.write() + "\n";
270270
req->WriteHeader("Content-Type", "application/json");
@@ -304,10 +304,9 @@ static bool rest_block(const std::any& context,
304304
if (!pblockindex) {
305305
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
306306
}
307-
308-
if (chainman.m_blockman.IsBlockPruned(pblockindex))
307+
if (chainman.m_blockman.IsBlockPruned(*pblockindex)) {
309308
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not available (pruned data)");
310-
309+
}
311310
}
312311

313312
if (!chainman.m_blockman.ReadBlockFromDisk(block, *pblockindex)) {
@@ -334,7 +333,7 @@ static bool rest_block(const std::any& context,
334333
}
335334

336335
case RESTResponseFormat::JSON: {
337-
UniValue objBlock = blockToJSON(chainman.m_blockman, block, tip, pblockindex, tx_verbosity);
336+
UniValue objBlock = blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity);
338337
std::string strJSON = objBlock.write() + "\n";
339338
req->WriteHeader("Content-Type", "application/json");
340339
req->WriteReply(HTTP_OK, strJSON);

src/rpc/blockchain.cpp

Lines changed: 41 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,11 @@ static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange);
7373

7474
/* Calculate the difficulty for a given block index.
7575
*/
76-
double GetDifficulty(const CBlockIndex* blockindex)
76+
double GetDifficulty(const CBlockIndex& blockindex)
7777
{
78-
CHECK_NONFATAL(blockindex);
79-
80-
int nShift = (blockindex->nBits >> 24) & 0xff;
78+
int nShift = (blockindex.nBits >> 24) & 0xff;
8179
double dDiff =
82-
(double)0x0000ffff / (double)(blockindex->nBits & 0x00ffffff);
80+
(double)0x0000ffff / (double)(blockindex.nBits & 0x00ffffff);
8381

8482
while (nShift < 29)
8583
{
@@ -95,14 +93,14 @@ double GetDifficulty(const CBlockIndex* blockindex)
9593
return dDiff;
9694
}
9795

98-
static int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next)
96+
static int ComputeNextBlockAndDepth(const CBlockIndex& tip, const CBlockIndex& blockindex, const CBlockIndex*& next)
9997
{
100-
next = tip->GetAncestor(blockindex->nHeight + 1);
101-
if (next && next->pprev == blockindex) {
102-
return tip->nHeight - blockindex->nHeight + 1;
98+
next = tip.GetAncestor(blockindex.nHeight + 1);
99+
if (next && next->pprev == &blockindex) {
100+
return tip.nHeight - blockindex.nHeight + 1;
103101
}
104102
next = nullptr;
105-
return blockindex == tip ? 1 : -1;
103+
return &blockindex == &tip ? 1 : -1;
106104
}
107105

108106
static const CBlockIndex* ParseHashOrHeight(const UniValue& param, ChainstateManager& chainman)
@@ -133,36 +131,36 @@ static const CBlockIndex* ParseHashOrHeight(const UniValue& param, ChainstateMan
133131
}
134132
}
135133

136-
UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex)
134+
UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex)
137135
{
138136
// Serialize passed information without accessing chain state of the active chain!
139137
AssertLockNotHeld(cs_main); // For performance reasons
140138

141139
UniValue result(UniValue::VOBJ);
142-
result.pushKV("hash", blockindex->GetBlockHash().GetHex());
140+
result.pushKV("hash", blockindex.GetBlockHash().GetHex());
143141
const CBlockIndex* pnext;
144142
int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
145143
result.pushKV("confirmations", confirmations);
146-
result.pushKV("height", blockindex->nHeight);
147-
result.pushKV("version", blockindex->nVersion);
148-
result.pushKV("versionHex", strprintf("%08x", blockindex->nVersion));
149-
result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex());
150-
result.pushKV("time", (int64_t)blockindex->nTime);
151-
result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast());
152-
result.pushKV("nonce", (uint64_t)blockindex->nNonce);
153-
result.pushKV("bits", strprintf("%08x", blockindex->nBits));
144+
result.pushKV("height", blockindex.nHeight);
145+
result.pushKV("version", blockindex.nVersion);
146+
result.pushKV("versionHex", strprintf("%08x", blockindex.nVersion));
147+
result.pushKV("merkleroot", blockindex.hashMerkleRoot.GetHex());
148+
result.pushKV("time", blockindex.nTime);
149+
result.pushKV("mediantime", blockindex.GetMedianTimePast());
150+
result.pushKV("nonce", blockindex.nNonce);
151+
result.pushKV("bits", strprintf("%08x", blockindex.nBits));
154152
result.pushKV("difficulty", GetDifficulty(blockindex));
155-
result.pushKV("chainwork", blockindex->nChainWork.GetHex());
156-
result.pushKV("nTx", (uint64_t)blockindex->nTx);
153+
result.pushKV("chainwork", blockindex.nChainWork.GetHex());
154+
result.pushKV("nTx", blockindex.nTx);
157155

158-
if (blockindex->pprev)
159-
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
156+
if (blockindex.pprev)
157+
result.pushKV("previousblockhash", blockindex.pprev->GetBlockHash().GetHex());
160158
if (pnext)
161159
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
162160
return result;
163161
}
164162

165-
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, TxVerbosity verbosity)
163+
UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity)
166164
{
167165
UniValue result = blockheaderToJSON(tip, blockindex);
168166

@@ -182,7 +180,7 @@ UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIn
182180
case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:
183181
CBlockUndo blockUndo;
184182
const bool is_not_pruned{WITH_LOCK(::cs_main, return !blockman.IsBlockPruned(blockindex))};
185-
const bool have_undo{is_not_pruned && blockman.UndoReadFromDisk(blockUndo, *blockindex)};
183+
const bool have_undo{is_not_pruned && blockman.UndoReadFromDisk(blockUndo, blockindex)};
186184

187185
for (size_t i = 0; i < block.vtx.size(); ++i) {
188186
const CTransactionRef& tx = block.vtx.at(i);
@@ -418,7 +416,7 @@ static RPCHelpMan getdifficulty()
418416
{
419417
ChainstateManager& chainman = EnsureAnyChainman(request.context);
420418
LOCK(cs_main);
421-
return GetDifficulty(chainman.ActiveChain().Tip());
419+
return GetDifficulty(*CHECK_NONFATAL(chainman.ActiveChain().Tip()));
422420
},
423421
};
424422
}
@@ -571,22 +569,22 @@ static RPCHelpMan getblockheader()
571569
return strHex;
572570
}
573571

574-
return blockheaderToJSON(tip, pblockindex);
572+
return blockheaderToJSON(*tip, *pblockindex);
575573
},
576574
};
577575
}
578576

579-
static CBlock GetBlockChecked(BlockManager& blockman, const CBlockIndex* pblockindex)
577+
static CBlock GetBlockChecked(BlockManager& blockman, const CBlockIndex& blockindex)
580578
{
581579
CBlock block;
582580
{
583581
LOCK(cs_main);
584-
if (blockman.IsBlockPruned(pblockindex)) {
582+
if (blockman.IsBlockPruned(blockindex)) {
585583
throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)");
586584
}
587585
}
588586

589-
if (!blockman.ReadBlockFromDisk(block, *pblockindex)) {
587+
if (!blockman.ReadBlockFromDisk(block, blockindex)) {
590588
// Block not found on disk. This could be because we have the block
591589
// header in our index but not yet have the block or did not accept the
592590
// block. Or if the block was pruned right after we released the lock above.
@@ -596,21 +594,21 @@ static CBlock GetBlockChecked(BlockManager& blockman, const CBlockIndex* pblocki
596594
return block;
597595
}
598596

599-
static CBlockUndo GetUndoChecked(BlockManager& blockman, const CBlockIndex* pblockindex)
597+
static CBlockUndo GetUndoChecked(BlockManager& blockman, const CBlockIndex& blockindex)
600598
{
601599
CBlockUndo blockUndo;
602600

603601
// The Genesis block does not have undo data
604-
if (pblockindex->nHeight == 0) return blockUndo;
602+
if (blockindex.nHeight == 0) return blockUndo;
605603

606604
{
607605
LOCK(cs_main);
608-
if (blockman.IsBlockPruned(pblockindex)) {
606+
if (blockman.IsBlockPruned(blockindex)) {
609607
throw JSONRPCError(RPC_MISC_ERROR, "Undo data not available (pruned data)");
610608
}
611609
}
612610

613-
if (!blockman.UndoReadFromDisk(blockUndo, *pblockindex)) {
611+
if (!blockman.UndoReadFromDisk(blockUndo, blockindex)) {
614612
throw JSONRPCError(RPC_MISC_ERROR, "Can't read undo data from disk");
615613
}
616614

@@ -736,7 +734,7 @@ static RPCHelpMan getblock()
736734
}
737735
}
738736

739-
const CBlock block{GetBlockChecked(chainman.m_blockman, pblockindex)};
737+
const CBlock block{GetBlockChecked(chainman.m_blockman, *pblockindex)};
740738

741739
if (verbosity <= 0)
742740
{
@@ -755,7 +753,7 @@ static RPCHelpMan getblock()
755753
tx_verbosity = TxVerbosity::SHOW_DETAILS_AND_PREVOUT;
756754
}
757755

758-
return blockToJSON(chainman.m_blockman, block, tip, pblockindex, tx_verbosity);
756+
return blockToJSON(chainman.m_blockman, block, *tip, *pblockindex, tx_verbosity);
759757
},
760758
};
761759
}
@@ -1257,7 +1255,7 @@ RPCHelpMan getblockchaininfo()
12571255
obj.pushKV("blocks", height);
12581256
obj.pushKV("headers", chainman.m_best_header ? chainman.m_best_header->nHeight : -1);
12591257
obj.pushKV("bestblockhash", tip.GetBlockHash().GetHex());
1260-
obj.pushKV("difficulty", GetDifficulty(&tip));
1258+
obj.pushKV("difficulty", GetDifficulty(tip));
12611259
obj.pushKV("time", tip.GetBlockTime());
12621260
obj.pushKV("mediantime", tip.GetMedianTimePast());
12631261
obj.pushKV("verificationprogress", GuessVerificationProgress(chainman.GetParams().TxData(), &tip));
@@ -1815,8 +1813,8 @@ static RPCHelpMan getblockstats()
18151813
}
18161814
}
18171815

1818-
const CBlock& block = GetBlockChecked(chainman.m_blockman, &pindex);
1819-
const CBlockUndo& blockUndo = GetUndoChecked(chainman.m_blockman, &pindex);
1816+
const CBlock& block = GetBlockChecked(chainman.m_blockman, pindex);
1817+
const CBlockUndo& blockUndo = GetUndoChecked(chainman.m_blockman, pindex);
18201818

18211819
const bool do_all = stats.size() == 0; // Calculate everything if nothing selected (default)
18221820
const bool do_mediantxsize = do_all || stats.count("mediantxsize") != 0;
@@ -2275,8 +2273,8 @@ class BlockFiltersScanReserver
22752273

22762274
static bool CheckBlockFilterMatches(BlockManager& blockman, const CBlockIndex& blockindex, const GCSFilter::ElementSet& needles)
22772275
{
2278-
const CBlock block{GetBlockChecked(blockman, &blockindex)};
2279-
const CBlockUndo block_undo{GetUndoChecked(blockman, &blockindex)};
2276+
const CBlock block{GetBlockChecked(blockman, blockindex)};
2277+
const CBlockUndo block_undo{GetUndoChecked(blockman, blockindex)};
22802278

22812279
// Check if any of the outputs match the scriptPubKey
22822280
for (const auto& tx : block.vtx) {
@@ -2845,7 +2843,7 @@ return RPCHelpMan{
28452843

28462844
data.pushKV("blocks", (int)chain.Height());
28472845
data.pushKV("bestblockhash", tip->GetBlockHash().GetHex());
2848-
data.pushKV("difficulty", (double)GetDifficulty(tip));
2846+
data.pushKV("difficulty", GetDifficulty(*tip));
28492847
data.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
28502848
data.pushKV("coins_db_cache_bytes", cs.m_coinsdb_cache_size_bytes);
28512849
data.pushKV("coins_tip_cache_bytes", cs.m_coinstip_cache_size_bytes);

src/rpc/blockchain.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ static constexpr int NUM_GETBLOCKSTATS_PERCENTILES = 5;
3232
* @return A floating point number that is a multiple of the main net minimum
3333
* difficulty (4295032833 hashes).
3434
*/
35-
double GetDifficulty(const CBlockIndex* blockindex);
35+
double GetDifficulty(const CBlockIndex& blockindex);
3636

3737
/** Callback for when block tip changed. */
3838
void RPCNotifyBlockChange(const CBlockIndex*);
3939

4040
/** Block description to JSON */
41-
UniValue blockToJSON(node::BlockManager& blockman, const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, TxVerbosity verbosity) LOCKS_EXCLUDED(cs_main);
41+
UniValue blockToJSON(node::BlockManager& blockman, const CBlock& block, const CBlockIndex& tip, const CBlockIndex& blockindex, TxVerbosity verbosity) LOCKS_EXCLUDED(cs_main);
4242

4343
/** Block header to JSON */
44-
UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex) LOCKS_EXCLUDED(cs_main);
44+
UniValue blockheaderToJSON(const CBlockIndex& tip, const CBlockIndex& blockindex) LOCKS_EXCLUDED(cs_main);
4545

4646
/** Used by getblockstats to get feerates at different percentiles by weight */
4747
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);

src/rpc/mining.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ static RPCHelpMan getmininginfo()
441441
obj.pushKV("blocks", active_chain.Height());
442442
if (BlockAssembler::m_last_block_weight) obj.pushKV("currentblockweight", *BlockAssembler::m_last_block_weight);
443443
if (BlockAssembler::m_last_block_num_txs) obj.pushKV("currentblocktx", *BlockAssembler::m_last_block_num_txs);
444-
obj.pushKV("difficulty", (double)GetDifficulty(active_chain.Tip()));
444+
obj.pushKV("difficulty", GetDifficulty(*CHECK_NONFATAL(active_chain.Tip())));
445445
obj.pushKV("networkhashps", getnetworkhashps().HandleRequest(request));
446446
obj.pushKV("pooledtx", (uint64_t)mempool.size());
447447
obj.pushKV("chain", chainman.GetParams().GetChainTypeString());

src/rpc/rawtransaction.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,18 +394,17 @@ static RPCHelpMan getrawtransaction()
394394
// If request is verbosity >= 1 but no blockhash was given, then look up the blockindex
395395
if (request.params[2].isNull()) {
396396
LOCK(cs_main);
397-
blockindex = chainman.m_blockman.LookupBlockIndex(hash_block);
397+
blockindex = chainman.m_blockman.LookupBlockIndex(hash_block); // May be nullptr for mempool transactions
398398
}
399-
if (verbosity == 1 || !blockindex) {
399+
if (verbosity == 1) {
400400
TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
401401
return result;
402402
}
403403

404404
CBlockUndo blockUndo;
405405
CBlock block;
406-
const bool is_block_pruned{WITH_LOCK(cs_main, return chainman.m_blockman.IsBlockPruned(blockindex))};
407406

408-
if (tx->IsCoinBase() || is_block_pruned ||
407+
if (tx->IsCoinBase() || !blockindex || WITH_LOCK(::cs_main, return chainman.m_blockman.IsBlockPruned(*blockindex)) ||
409408
!(chainman.m_blockman.UndoReadFromDisk(blockUndo, *blockindex) && chainman.m_blockman.ReadBlockFromDisk(block, *blockindex))) {
410409
TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
411410
return result;

src/test/blockchain_tests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ static void RejectDifficultyMismatch(double difficulty, double expected_difficul
4141
static void TestDifficulty(uint32_t nbits, double expected_difficulty)
4242
{
4343
CBlockIndex* block_index = CreateBlockIndexWithNbits(nbits);
44-
double difficulty = GetDifficulty(block_index);
44+
double difficulty = GetDifficulty(*block_index);
4545
delete block_index;
4646

4747
RejectDifficultyMismatch(difficulty, expected_difficulty);

0 commit comments

Comments
 (0)