aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Barbosa <joao.paulo.barbosa@gmail.com>2018-01-11 22:23:19 +0000
committerJoão Barbosa <joao.paulo.barbosa@gmail.com>2018-09-09 18:02:24 +0100
commitb9f226b41f989f5c07fe57801701a39c14a6e173 (patch)
tree948a78b3718a6bbddeb367bff7ff7e1270544ac9
parent343b98cbcd52854ffffaca7ada72f5522117ac7f (diff)
rpc: Remove cs_main lock from blockToJSON and blockHeaderToJSON
-rw-r--r--src/rest.cpp17
-rw-r--r--src/rpc/blockchain.cpp34
-rw-r--r--src/rpc/blockchain.h4
3 files changed, 27 insertions, 28 deletions
diff --git a/src/rest.cpp b/src/rest.cpp
index 6ba15172fa..42d9a26195 100644
--- a/src/rest.cpp
+++ b/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);
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
index abab731ea7..75677a722b 100644
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -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
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
index add335eb8a..529132d033 100644
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -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);