rpc: Remove cs_main lock from blockToJSON and blockHeaderToJSON
This commit is contained in:
parent
343b98cbcd
commit
b9f226b41f
3 changed files with 27 additions and 28 deletions
17
src/rest.cpp
17
src/rest.cpp
|
@ -144,10 +144,12 @@ static bool rest_headers(HTTPRequest* req,
|
|||
if (!ParseHashStr(hashStr, hash))
|
||||
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
|
||||
|
||||
const CBlockIndex* tip = nullptr;
|
||||
std::vector<const CBlockIndex *> headers;
|
||||
headers.reserve(count);
|
||||
{
|
||||
LOCK(cs_main);
|
||||
tip = chainActive.Tip();
|
||||
const CBlockIndex* pindex = LookupBlockIndex(hash);
|
||||
while (pindex != nullptr && chainActive.Contains(pindex)) {
|
||||
headers.push_back(pindex);
|
||||
|
@ -178,11 +180,8 @@ static bool rest_headers(HTTPRequest* req,
|
|||
}
|
||||
case RetFormat::JSON: {
|
||||
UniValue jsonHeaders(UniValue::VARR);
|
||||
{
|
||||
LOCK(cs_main);
|
||||
for (const CBlockIndex *pindex : headers) {
|
||||
jsonHeaders.push_back(blockheaderToJSON(pindex));
|
||||
}
|
||||
for (const CBlockIndex *pindex : headers) {
|
||||
jsonHeaders.push_back(blockheaderToJSON(tip, pindex));
|
||||
}
|
||||
std::string strJSON = jsonHeaders.write() + "\n";
|
||||
req->WriteHeader("Content-Type", "application/json");
|
||||
|
@ -210,8 +209,10 @@ static bool rest_block(HTTPRequest* req,
|
|||
|
||||
CBlock block;
|
||||
CBlockIndex* pblockindex = nullptr;
|
||||
CBlockIndex* tip = nullptr;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
tip = chainActive.Tip();
|
||||
pblockindex = LookupBlockIndex(hash);
|
||||
if (!pblockindex) {
|
||||
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
|
||||
|
@ -243,11 +244,7 @@ static bool rest_block(HTTPRequest* req,
|
|||
}
|
||||
|
||||
case RetFormat::JSON: {
|
||||
UniValue objBlock;
|
||||
{
|
||||
LOCK(cs_main);
|
||||
objBlock = blockToJSON(block, pblockindex, showTxDetails);
|
||||
}
|
||||
UniValue objBlock = blockToJSON(block, tip, pblockindex, showTxDetails);
|
||||
std::string strJSON = objBlock.write() + "\n";
|
||||
req->WriteHeader("Content-Type", "application/json");
|
||||
req->WriteReply(HTTP_OK, strJSON);
|
||||
|
|
|
@ -78,15 +78,22 @@ double GetDifficulty(const CBlockIndex* blockindex)
|
|||
return dDiff;
|
||||
}
|
||||
|
||||
UniValue blockheaderToJSON(const CBlockIndex* blockindex)
|
||||
static int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next)
|
||||
{
|
||||
next = tip->GetAncestor(blockindex->nHeight + 1);
|
||||
if (next && next->pprev == blockindex) {
|
||||
return tip->nHeight - blockindex->nHeight + 1;
|
||||
}
|
||||
next = nullptr;
|
||||
return blockindex == tip ? 1 : -1;
|
||||
}
|
||||
|
||||
UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("hash", blockindex->GetBlockHash().GetHex());
|
||||
int confirmations = -1;
|
||||
// Only report confirmations if the block is on the main chain
|
||||
if (chainActive.Contains(blockindex))
|
||||
confirmations = chainActive.Height() - blockindex->nHeight + 1;
|
||||
const CBlockIndex* pnext;
|
||||
int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
|
||||
result.pushKV("confirmations", confirmations);
|
||||
result.pushKV("height", blockindex->nHeight);
|
||||
result.pushKV("version", blockindex->nVersion);
|
||||
|
@ -102,21 +109,17 @@ UniValue blockheaderToJSON(const CBlockIndex* blockindex)
|
|||
|
||||
if (blockindex->pprev)
|
||||
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
|
||||
CBlockIndex *pnext = chainActive.Next(blockindex);
|
||||
if (pnext)
|
||||
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
|
||||
return result;
|
||||
}
|
||||
|
||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails)
|
||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("hash", blockindex->GetBlockHash().GetHex());
|
||||
int confirmations = -1;
|
||||
// Only report confirmations if the block is on the main chain
|
||||
if (chainActive.Contains(blockindex))
|
||||
confirmations = chainActive.Height() - blockindex->nHeight + 1;
|
||||
const CBlockIndex* pnext;
|
||||
int confirmations = ComputeNextBlockAndDepth(tip, blockindex, pnext);
|
||||
result.pushKV("confirmations", confirmations);
|
||||
result.pushKV("strippedsize", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS));
|
||||
result.pushKV("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION));
|
||||
|
@ -148,7 +151,6 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx
|
|||
|
||||
if (blockindex->pprev)
|
||||
result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex());
|
||||
CBlockIndex *pnext = chainActive.Next(blockindex);
|
||||
if (pnext)
|
||||
result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex());
|
||||
return result;
|
||||
|
@ -744,7 +746,7 @@ static UniValue getblockheader(const JSONRPCRequest& request)
|
|||
return strHex;
|
||||
}
|
||||
|
||||
return blockheaderToJSON(pblockindex);
|
||||
return blockheaderToJSON(chainActive.Tip(), pblockindex);
|
||||
}
|
||||
|
||||
static CBlock GetBlockChecked(const CBlockIndex* pblockindex)
|
||||
|
@ -845,7 +847,7 @@ static UniValue getblock(const JSONRPCRequest& request)
|
|||
return strHex;
|
||||
}
|
||||
|
||||
return blockToJSON(block, pblockindex, verbosity >= 2);
|
||||
return blockToJSON(block, chainActive.Tip(), pblockindex, verbosity >= 2);
|
||||
}
|
||||
|
||||
struct CCoinsStats
|
||||
|
|
|
@ -27,7 +27,7 @@ double GetDifficulty(const CBlockIndex* blockindex);
|
|||
void RPCNotifyBlockChange(bool ibd, const CBlockIndex *);
|
||||
|
||||
/** Block description to JSON */
|
||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
|
||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails = false);
|
||||
|
||||
/** Mempool information to JSON */
|
||||
UniValue mempoolInfoToJSON();
|
||||
|
@ -36,7 +36,7 @@ UniValue mempoolInfoToJSON();
|
|||
UniValue mempoolToJSON(bool fVerbose = false);
|
||||
|
||||
/** Block header to JSON */
|
||||
UniValue blockheaderToJSON(const CBlockIndex* blockindex);
|
||||
UniValue blockheaderToJSON(const CBlockIndex* tip, const CBlockIndex* blockindex);
|
||||
|
||||
/** Used by getblockstats to get feerates at different percentiles by weight */
|
||||
void CalculatePercentilesByWeight(CAmount result[NUM_GETBLOCKSTATS_PERCENTILES], std::vector<std::pair<CAmount, int64_t>>& scores, int64_t total_weight);
|
||||
|
|
Loading…
Reference in a new issue