diff --git a/src/rest.cpp b/src/rest.cpp index aa51930265cbd..945ad66479a80 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -56,7 +56,7 @@ struct CCoin { } }; -extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const CBlockIndex* tip, const CBlockIndex* blockindex, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIndex* blockindex, bool txDetails = false); extern UniValue mempoolInfoToJSON(); extern UniValue mempoolToJSON(bool fVerbose = false); @@ -127,7 +127,7 @@ static bool rest_headers(HTTPRequest* req, if (!ParseHashStr(hashStr, hash)) return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); - const CBlockIndex* tip = nullptr; + const CBlockIndex* tip; std::vector headers; headers.reserve(count); { @@ -192,8 +192,8 @@ static bool rest_block(HTTPRequest* req, return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr); CBlock block; - CBlockIndex* pblockindex = nullptr; - CBlockIndex* tip = nullptr; + const CBlockIndex* pblockindex; + const CBlockIndex* tip; { LOCK(cs_main); tip = chainActive.Tip(); @@ -357,8 +357,15 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart) } case RF_JSON: { + const CBlockIndex* pblockindex; + const CBlockIndex* tip; + { + LOCK(cs_main); + tip = chainActive.Tip(); + pblockindex = LookupBlockIndex(hashBlock); + } UniValue objTx(UniValue::VOBJ); - WITH_LOCK(cs_main, TxToJSON(nullptr, *tx, hashBlock, objTx); ); + TxToJSON(nullptr, *tx, tip, pblockindex, objTx); std::string strJSON = objTx.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 517591d67db2e..68e90732709ab 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -43,7 +43,7 @@ static std::mutex cs_blockchange; static std::condition_variable cond_blockchange; static CUpdatedBlock latestblock; -extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +extern void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const CBlockIndex* tip, const CBlockIndex* blockindex, UniValue& entry); UniValue syncwithvalidationinterfacequeue(const JSONRPCRequest& request) { @@ -99,7 +99,7 @@ static UniValue ValuePoolDesc( return rv; } -static int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next) +int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next) { next = tip->GetAncestor(blockindex->nHeight + 1); if (next && next->pprev == blockindex) { @@ -153,7 +153,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* tip, const CBlockIn const CTransaction& tx = *txIn; if (txDetails) { UniValue objTx(UniValue::VOBJ); - TxToJSON(nullptr, tx, UINT256_ZERO, objTx); + TxToJSON(nullptr, tx, nullptr, nullptr, objTx); txs.push_back(objTx); } else txs.push_back(tx.GetHash().GetHex()); diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 50243d10e5d9e..d71763121b3b4 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -68,11 +68,17 @@ static void PayloadToJSON(const CTransaction& tx, UniValue& entry) } } -// pwallet can be nullptr. If not null, the json could include information available only to the wallet. -void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hashBlock, UniValue& entry) EXCLUSIVE_LOCKS_REQUIRED(cs_main) +extern int ComputeNextBlockAndDepth(const CBlockIndex* tip, const CBlockIndex* blockindex, const CBlockIndex*& next); + +static int ComputeConfirmations(const CBlockIndex* tip, const CBlockIndex* blockindex) { - AssertLockHeld(cs_main); + const CBlockIndex* next{nullptr}; + return ComputeNextBlockAndDepth(tip, blockindex, next); +} +// pwallet can be nullptr. If not null, the json could include information available only to the wallet. +void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const CBlockIndex* tip, const CBlockIndex* blockindex, UniValue& entry) +{ // Call into TxToUniv() in bitcoin-common to decode the transaction hex. // // Blockchain contextual information (confirmations and blocktime) is not @@ -99,17 +105,15 @@ void TxToJSON(CWallet* const pwallet, const CTransaction& tx, const uint256 hash PayloadToJSON(tx, entry); } - if (!hashBlock.IsNull()) { - entry.pushKV("blockhash", hashBlock.GetHex()); - CBlockIndex* pindex = LookupBlockIndex(hashBlock); - if (pindex) { - if (chainActive.Contains(pindex)) { - entry.pushKV("confirmations", 1 + chainActive.Height() - pindex->nHeight); - entry.pushKV("time", pindex->GetBlockTime()); - entry.pushKV("blocktime", pindex->GetBlockTime()); - } - else - entry.pushKV("confirmations", 0); + if (blockindex && tip) { + entry.pushKV("blockhash", blockindex->GetBlockHash().ToString()); + int confirmations = ComputeConfirmations(tip, blockindex); + if (confirmations != -1) { + entry.pushKV("confirmations", confirmations); + entry.pushKV("time", blockindex->GetBlockTime()); + entry.pushKV("blocktime", blockindex->GetBlockTime()); + } else { + entry.pushKV("confirmations", 0); } } } @@ -267,8 +271,9 @@ UniValue getrawtransaction(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); if (blockindex) result.pushKV("in_active_chain", in_active_chain); + else blockindex = LookupBlockIndex(hash_block); CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - TxToJSON(pwallet, *tx, hash_block, result); + TxToJSON(pwallet, *tx, chainActive.Tip(), blockindex, result); return result; } @@ -437,7 +442,7 @@ UniValue decoderawtransaction(const JSONRPCRequest& request) UniValue result(UniValue::VOBJ); CWallet * const pwallet = GetWalletForJSONRPCRequest(request); - TxToJSON(pwallet, CTransaction(std::move(mtx)), UINT256_ZERO, result); + TxToJSON(pwallet, CTransaction(std::move(mtx)), nullptr, nullptr, result); return result; }