Skip to content

Commit 6d772a3

Browse files
author
Jim Posen
committed
[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.
1 parent a03f804 commit 6d772a3

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

src/rest.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <chain.h>
77
#include <chainparams.h>
88
#include <core_io.h>
9+
#include <index/txindex.h>
910
#include <primitives/block.h>
1011
#include <primitives/transaction.h>
1112
#include <validation.h>
@@ -350,6 +351,10 @@ static bool rest_tx(HTTPRequest* req, const std::string& strURIPart)
350351
if (!ParseHashStr(hashStr, hash))
351352
return RESTERR(req, HTTP_BAD_REQUEST, "Invalid hash: " + hashStr);
352353

354+
if (g_txindex) {
355+
g_txindex->BlockUntilSyncedToCurrentChain();
356+
}
357+
353358
CTransactionRef tx;
354359
uint256 hashBlock = uint256();
355360
if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock, true))

src/rpc/blockchain.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ static std::mutex cs_blockchange;
4747
static std::condition_variable cond_blockchange;
4848
static CUpdatedBlock latestblock;
4949

50-
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
51-
5250
/* Calculate the difficulty for a given block index,
5351
* or the block index of the given chain.
5452
*/

src/rpc/rawtransaction.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
4848
TxToUniv(tx, uint256(), entry, true, RPCSerializationFlags());
4949

5050
if (!hashBlock.IsNull()) {
51+
LOCK(cs_main);
52+
5153
entry.pushKV("blockhash", hashBlock.GetHex());
5254
CBlockIndex* pindex = LookupBlockIndex(hashBlock);
5355
if (pindex) {
@@ -142,8 +144,6 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
142144
+ HelpExampleCli("getrawtransaction", "\"mytxid\" true \"myblockhash\"")
143145
);
144146

145-
LOCK(cs_main);
146-
147147
bool in_active_chain = true;
148148
uint256 hash = ParseHashV(request.params[0], "parameter 1");
149149
CBlockIndex* blockindex = nullptr;
@@ -160,6 +160,8 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
160160
}
161161

162162
if (!request.params[2].isNull()) {
163+
LOCK(cs_main);
164+
163165
uint256 blockhash = ParseHashV(request.params[2], "parameter 3");
164166
blockindex = LookupBlockIndex(blockhash);
165167
if (!blockindex) {
@@ -168,6 +170,11 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
168170
in_active_chain = chainActive.Contains(blockindex);
169171
}
170172

173+
bool f_txindex_ready = false;
174+
if (g_txindex && !blockindex) {
175+
f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
176+
}
177+
171178
CTransactionRef tx;
172179
uint256 hash_block;
173180
if (!GetTransaction(hash, tx, Params().GetConsensus(), hash_block, true, blockindex)) {
@@ -179,6 +186,8 @@ UniValue getrawtransaction(const JSONRPCRequest& request)
179186
errmsg = "No such transaction found in the provided block";
180187
} else if (!g_txindex) {
181188
errmsg = "No such mempool transaction. Use -txindex to enable blockchain transaction queries";
189+
} else if (!f_txindex_ready) {
190+
errmsg = "No such mempool transaction. Blockchain transactions are still in the process of being indexed";
182191
} else {
183192
errmsg = "No such mempool or blockchain transaction";
184193
}
@@ -230,19 +239,18 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
230239
oneTxid = hash;
231240
}
232241

233-
LOCK(cs_main);
234-
235242
CBlockIndex* pblockindex = nullptr;
236-
237243
uint256 hashBlock;
238-
if (!request.params[1].isNull())
239-
{
244+
if (!request.params[1].isNull()) {
245+
LOCK(cs_main);
240246
hashBlock = uint256S(request.params[1].get_str());
241247
pblockindex = LookupBlockIndex(hashBlock);
242248
if (!pblockindex) {
243249
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
244250
}
245251
} else {
252+
LOCK(cs_main);
253+
246254
// Loop through txids and try to find which block they're in. Exit loop once a block is found.
247255
for (const auto& tx : setTxids) {
248256
const Coin& coin = AccessByTxid(*pcoinsTip, tx);
@@ -253,6 +261,14 @@ UniValue gettxoutproof(const JSONRPCRequest& request)
253261
}
254262
}
255263

264+
265+
// Allow txindex to catch up if we need to query it and before we acquire cs_main.
266+
if (g_txindex && !pblockindex) {
267+
g_txindex->BlockUntilSyncedToCurrentChain();
268+
}
269+
270+
LOCK(cs_main);
271+
256272
if (pblockindex == nullptr)
257273
{
258274
CTransactionRef tx;

0 commit comments

Comments
 (0)