[rpc] Public interfaces to GetTransaction block until synced.
Now that the transaction index is updated asynchronously, in order to preserve the current behavior of public interfaces, the code blocks until the transaction index is caught up with the current state of the blockchain.
This commit is contained in:
parent
a03f804f2a
commit
6d772a3d44
3 changed files with 28 additions and 9 deletions
|
@ -6,6 +6,7 @@
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
|
#include <index/txindex.h>
|
||||||
#include <primitives/block.h>
|
#include <primitives/block.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
@ -350,6 +351,10 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
|
||||||
if (!ParseHashStr(hashStr, hash))
|
if (!ParseHashStr(hashStr, hash))
|
||||||
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
|
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
|
||||||
|
|
||||||
|
if (g_txindex) {
|
||||||
|
g_txindex->BlockUntilSyncedToCurrentChain();
|
||||||
|
}
|
||||||
|
|
||||||
CTransactionRef tx;
|
CTransactionRef tx;
|
||||||
uint256 hashBlock = uint256();
|
uint256 hashBlock = uint256();
|
||||||
if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
|
if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))
|
||||||
|
|
|
@ -47,8 +47,6 @@ static std::mutex cs_blockchange;
|
||||||
static std::condition_variable cond_blockchange;
|
static std::condition_variable cond_blockchange;
|
||||||
static CUpdatedBlock latestblock;
|
static CUpdatedBlock latestblock;
|
||||||
|
|
||||||
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
|
|
||||||
|
|
||||||
/* Calculate the difficulty for a given block index,
|
/* Calculate the difficulty for a given block index,
|
||||||
* or the block index of the given chain.
|
* or the block index of the given chain.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,6 +48,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
||||||
TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags());
|
TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags());
|
||||||
|
|
||||||
if (!hashBlock.IsNull()) {
|
if (!hashBlock.IsNull()) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
|
||||||
entry.pushKV("blockhash", hashBlock.GetHex());
|
entry.pushKV("blockhash", hashBlock.GetHex());
|
||||||
CBlockIndex* pindex = LookupBlockIndex(hashBlock);
|
CBlockIndex* pindex = LookupBlockIndex(hashBlock);
|
||||||
if (pindex) {
|
if (pindex) {
|
||||||
|
@ -142,8 +144,6 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
|
||||||
+ HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"")
|
+ HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"")
|
||||||
);
|
);
|
||||||
|
|
||||||
LOCK(cs_main);
|
|
||||||
|
|
||||||
bool in_active_chain = true;
|
bool in_active_chain = true;
|
||||||
uint256 hash = ParseHashV(request.params[0], "parameter 1");
|
uint256 hash = ParseHashV(request.params[0], "parameter 1");
|
||||||
CBlockIndex* blockindex = nullptr;
|
CBlockIndex* blockindex = nullptr;
|
||||||
|
@ -160,6 +160,8 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!request.params[2].isNull()) {
|
if (!request.params[2].isNull()) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
|
||||||
uint256 blockhash = ParseHashV(request.params[2], "parameter 3");
|
uint256 blockhash = ParseHashV(request.params[2], "parameter 3");
|
||||||
blockindex = LookupBlockIndex(blockhash);
|
blockindex = LookupBlockIndex(blockhash);
|
||||||
if (!blockindex) {
|
if (!blockindex) {
|
||||||
|
@ -168,6 +170,11 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
|
||||||
in_active_chain = chainActive.Contains(blockindex);
|
in_active_chain = chainActive.Contains(blockindex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool f_txindex_ready = false;
|
||||||
|
if (g_txindex && !blockindex) {
|
||||||
|
f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
|
||||||
|
}
|
||||||
|
|
||||||
CTransactionRef tx;
|
CTransactionRef tx;
|
||||||
uint256 hash_block;
|
uint256 hash_block;
|
||||||
if (!GetTransaction(hash, tx, Params().GetConsensus(), hash_block, true, blockindex)) {
|
if (!GetTransaction(hash, tx, Params().GetConsensus(), hash_block, true, blockindex)) {
|
||||||
|
@ -179,6 +186,8 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
|
||||||
errmsg = "No such transaction found in the provided block";
|
errmsg = "No such transaction found in the provided block";
|
||||||
} else if (!g_txindex) {
|
} else if (!g_txindex) {
|
||||||
errmsg = "No such mempool transaction. Use -txindex to enable blockchain transaction queries";
|
errmsg = "No such mempool transaction. Use -txindex to enable blockchain transaction queries";
|
||||||
|
} else if (!f_txindex_ready) {
|
||||||
|
errmsg = "No such mempool transaction. Blockchain transactions are still in the process of being indexed";
|
||||||
} else {
|
} else {
|
||||||
errmsg = "No such mempool or blockchain transaction";
|
errmsg = "No such mempool or blockchain transaction";
|
||||||
}
|
}
|
||||||
|
@ -230,19 +239,18 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
|
||||||
oneTxid = hash;
|
oneTxid = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCK(cs_main);
|
|
||||||
|
|
||||||
CBlockIndex* pblockindex = nullptr;
|
CBlockIndex* pblockindex = nullptr;
|
||||||
|
|
||||||
uint256 hashBlock;
|
uint256 hashBlock;
|
||||||
if (!request.params[1].isNull())
|
if (!request.params[1].isNull()) {
|
||||||
{
|
LOCK(cs_main);
|
||||||
hashBlock = uint256S(request.params[1].get_str());
|
hashBlock = uint256S(request.params[1].get_str());
|
||||||
pblockindex = LookupBlockIndex(hashBlock);
|
pblockindex = LookupBlockIndex(hashBlock);
|
||||||
if (!pblockindex) {
|
if (!pblockindex) {
|
||||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
LOCK(cs_main);
|
||||||
|
|
||||||
// Loop through txids and try to find which block they're in. Exit loop once a block is found.
|
// Loop through txids and try to find which block they're in. Exit loop once a block is found.
|
||||||
for (const auto& tx : setTxids) {
|
for (const auto& tx : setTxids) {
|
||||||
const Coin& coin = AccessByTxid(*pcoinsTip, tx);
|
const Coin& coin = AccessByTxid(*pcoinsTip, tx);
|
||||||
|
@ -253,6 +261,14 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Allow txindex to catch up if we need to query it and before we acquire cs_main.
|
||||||
|
if (g_txindex && !pblockindex) {
|
||||||
|
g_txindex->BlockUntilSyncedToCurrentChain();
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK(cs_main);
|
||||||
|
|
||||||
if (pblockindex == nullptr)
|
if (pblockindex == nullptr)
|
||||||
{
|
{
|
||||||
CTransactionRef tx;
|
CTransactionRef tx;
|
||||||
|
|
Loading…
Reference in a new issue