Skip to content

Commit b9f226b

Browse files
committed
rpc: Remove cs_main lock from blockToJSON and blockHeaderToJSON
1 parent 343b98c commit b9f226b

File tree

3 files changed

+27
-28
lines changed

3 files changed

+27
-28
lines changed

src/rest.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,12 @@ static bool rest_headers(HTTPRequest* req,
144144
if (!ParseHashStr(hashStr, hash))
145145
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
146146

147+
const CBlockIndex* tip = nullptr;
147148
std::vector<const CBlockIndex *> headers;
148149
headers.reserve(count);
149150
{
150151
LOCK(cs_main);
152+
tip = chainActive.Tip();
151153
const CBlockIndex* pindex = LookupBlockIndex(hash);
152154
while (pindex != nullptr && chainActive.Contains(pindex)) {
153155
headers.push_back(pindex);
@@ -178,11 +180,8 @@ static bool rest_headers(HTTPRequest* req,
178180
}
179181
case RetFormat::JSON: {
180182
UniValue jsonHeaders(UniValue::VARR);
181-
{
182-
LOCK(cs_main);
183-
for (const CBlockIndex *pindex : headers) {
184-
jsonHeaders.push_back(blockheaderToJSON(pindex));
185-
}
183+
for (const CBlockIndex *pindex : headers) {
184+
jsonHeaders.push_back(blockheaderToJSON(tip, pindex));
186185
}
187186
std::string strJSON = jsonHeaders.write() + "\n";
188187
req->WriteHeader("Content-Type", "application/json");
@@ -210,8 +209,10 @@ static bool rest_block(HTTPRequest* req,
210209

211210
CBlock block;
212211
CBlockIndex* pblockindex = nullptr;
212+
CBlockIndex* tip = nullptr;
213213
{
214214
LOCK(cs_main);
215+
tip = chainActive.Tip();
215216
pblockindex = LookupBlockIndex(hash);
216217
if (!pblockindex) {
217218
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
@@ -243,11 +244,7 @@ static bool rest_block(HTTPRequest* req,
243244
}
244245

245246
case RetFormat::JSON: {
246-
UniValue objBlock;
247-
{
248-
LOCK(cs_main);
249-
objBlock = blockToJSON(block, pblockindex, showTxDetails);
250-
}
247+
UniValue objBlock = blockToJSON(block, tip, pblockindex, showTxDetails);
251248
std::string strJSON = objBlock.write() + "\n";
252249
req->WriteHeader("Content-Type", "application/json");
253250
req->WriteReply(HTTP_OK, strJSON);

src/rpc/blockchain.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,22 @@ double GetDifficulty(const CBlockIndex* blockindex)
7878
return dDiff;
7979
}
8080

81-
UniValue blockheaderToJSON(const CBlockIndex* blockindex)
81+
static int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next)
82+
{
83+
next = tip->GetAncestor(blockindex->nHeight + 1);
84+
if (next && next->pprev == blockindex) {
85+
return tip->nHeight - blockindex->nHeight + 1;
86+
}
87+
next = nullptr;
88+
return blockindex == tip ? 1 : -1;
89+
}
90+
91+
UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex)
8292
{
83-
AssertLockHeld(cs_main);
8493
UniValue result(UniValue::VOBJ);
8594
result.pushKV("hash", blockindex->GetBlockHash().GetHex());
86-
int confirmations = -1;
87-
// Only report confirmations if the block is on the main chain
88-
if (chainActive.Contains(blockindex))
89-
confirmations = chainActive.Height() - blockindex->nHeight + 1;
95+
const CBlockIndex* pnext;
96+
int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
9097
result.pushKV("confirmations", confirmations);
9198
result.pushKV("height", blockindex->nHeight);
9299
result.pushKV("version", blockindex->nVersion);
@@ -102,21 +109,17 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
102109

103110
if (blockindex->pprev)
104111
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
105-
CBlockIndex *pnext = chainActive.Next(blockindex);
106112
if (pnext)
107113
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
108114
return result;
109115
}
110116

111-
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
117+
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails)
112118
{
113-
AssertLockHeld(cs_main);
114119
UniValue result(UniValue::VOBJ);
115120
result.pushKV("hash", blockindex->GetBlockHash().GetHex());
116-
int confirmations = -1;
117-
// Only report confirmations if the block is on the main chain
118-
if (chainActive.Contains(blockindex))
119-
confirmations = chainActive.Height() - blockindex->nHeight + 1;
121+
const CBlockIndex* pnext;
122+
int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
120123
result.pushKV("confirmations", confirmations);
121124
result.pushKV("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS));
122125
result.pushKV("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION));
@@ -148,7 +151,6 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
148151

149152
if (blockindex->pprev)
150153
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
151-
CBlockIndex *pnext = chainActive.Next(blockindex);
152154
if (pnext)
153155
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
154156
return result;
@@ -744,7 +746,7 @@ static UniValue getblockheader(const JSONRPCRequest& request)
744746
return strHex;
745747
}
746748

747-
return blockheaderToJSON(pblockindex);
749+
return blockheaderToJSON(chainActive.Tip(), pblockindex);
748750
}
749751

750752
static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
@@ -845,7 +847,7 @@ static UniValue getblock(const JSONRPCRequest& request)
845847
return strHex;
846848
}
847849

848-
return blockToJSON(block, pblockindex, verbosity >= 2);
850+
return blockToJSON(block, chainActive.Tip(), pblockindex, verbosity >= 2);
849851
}
850852

851853
struct CCoinsStats

src/rpc/blockchain.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ double GetDifficulty(const CBlockIndex* blockindex);
2727
void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
2828

2929
/** Block description to JSON */
30-
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
30+
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails = false);
3131

3232
/** Mempool information to JSON */
3333
UniValue mempoolInfoToJSON();
@@ -36,7 +36,7 @@ UniValue mempoolInfoToJSON();
3636
UniValue mempoolToJSON(bool fVerbose = false);
3737

3838
/** Block header to JSON */
39-
UniValue blockheaderToJSON(const CBlockIndex* blockindex);
39+
UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex);
4040

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

0 commit comments

Comments
 (0)