mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 18:53:23 -03:00
rpc: Avoid useless mempool query in gettxoutproof
This commit is contained in:
parent
fa1f7f28cb
commit
fa5979d12f
4 changed files with 62 additions and 38 deletions
36
src/rest.cpp
36
src/rest.cpp
|
@ -67,14 +67,33 @@ static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string me
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the node context.
|
||||
*
|
||||
* @param[in] req The HTTP request, whose status code will be set if node
|
||||
* context is not found.
|
||||
* @returns Pointer to the node context or nullptr if not found.
|
||||
*/
|
||||
static NodeContext* GetNodeContext(const util::Ref& context, HTTPRequest* req)
|
||||
{
|
||||
NodeContext* node = context.Has<NodeContext>() ? &context.Get<NodeContext>() : nullptr;
|
||||
if (!node) {
|
||||
RESTERR(req, HTTP_INTERNAL_SERVER_ERROR,
|
||||
strprintf("%s:%d (%s)\n"
|
||||
"Internal bug detected: Node context not found!\n"
|
||||
"You may report this issue here: %s\n",
|
||||
__FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
|
||||
return nullptr;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the node context mempool.
|
||||
*
|
||||
* Set the HTTP error and return nullptr if node context
|
||||
* mempool is not found.
|
||||
*
|
||||
* @param[in] req the HTTP request
|
||||
* return pointer to the mempool or nullptr if no mempool found
|
||||
* @param[in] req The HTTP request, whose status code will be set if node
|
||||
* context mempool is not found.
|
||||
* @returns Pointer to the mempool or nullptr if no mempool found.
|
||||
*/
|
||||
static CTxMemPool* GetMemPool(const util::Ref& context, HTTPRequest* req)
|
||||
{
|
||||
|
@ -371,10 +390,13 @@ static bool rest_tx(const util::Ref& context, HTTPRequest* req, const std::strin
|
|||
g_txindex->BlockUntilSyncedToCurrentChain();
|
||||
}
|
||||
|
||||
CTransactionRef tx;
|
||||
const NodeContext* const node = GetNodeContext(context, req);
|
||||
if (!node) return false;
|
||||
uint256 hashBlock = uint256();
|
||||
if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock))
|
||||
const CTransactionRef tx = GetTransaction(/* block_index */ nullptr, node->mempool, hash, Params().GetConsensus(), hashBlock);
|
||||
if (!tx) {
|
||||
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
|
||||
}
|
||||
|
||||
switch (rf) {
|
||||
case RetFormat::BINARY: {
|
||||
|
|
|
@ -157,6 +157,8 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
|
|||
},
|
||||
}.Check(request);
|
||||
|
||||
const NodeContext& node = EnsureNodeContext(request.context);
|
||||
|
||||
bool in_active_chain = true;
|
||||
uint256 hash = ParseHashV(request.params[0], "parameter 1");
|
||||
CBlockIndex* blockindex = nullptr;
|
||||
|
@ -188,9 +190,9 @@ static UniValue getrawtransaction(const JSONRPCRequest& request)
|
|||
f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
|
||||
}
|
||||
|
||||
CTransactionRef tx;
|
||||
uint256 hash_block;
|
||||
if (!GetTransaction(hash, tx, Params().GetConsensus(), hash_block, blockindex)) {
|
||||
const CTransactionRef tx = GetTransaction(blockindex, node.mempool, hash, Params().GetConsensus(), hash_block);
|
||||
if (!tx) {
|
||||
std::string errmsg;
|
||||
if (blockindex) {
|
||||
if (!(blockindex->nStatus & BLOCK_HAVE_DATA)) {
|
||||
|
@ -283,9 +285,10 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
|
|||
LOCK(cs_main);
|
||||
|
||||
if (pblockindex == nullptr) {
|
||||
CTransactionRef tx;
|
||||
if (!GetTransaction(oneTxid, tx, Params().GetConsensus(), hashBlock) || hashBlock.IsNull())
|
||||
const CTransactionRef tx = GetTransaction(/* block_index */ nullptr, /* mempool */ nullptr, oneTxid, Params().GetConsensus(), hashBlock);
|
||||
if (!tx || hashBlock.IsNull()) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
|
||||
}
|
||||
pblockindex = LookupBlockIndex(hashBlock);
|
||||
if (!pblockindex) {
|
||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Transaction index corrupt");
|
||||
|
|
|
@ -1089,45 +1089,33 @@ bool AcceptToMemoryPool(CTxMemPool& pool, TxValidationState &state, const CTrans
|
|||
return AcceptToMemoryPoolWithTime(chainparams, pool, state, tx, GetTime(), plTxnReplaced, bypass_limits, nAbsurdFee, test_accept);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock.
|
||||
* If blockIndex is provided, the transaction is fetched from the corresponding block.
|
||||
*/
|
||||
bool GetTransaction(const uint256& hash, CTransactionRef& txOut, const Consensus::Params& consensusParams, uint256& hashBlock, const CBlockIndex* const block_index)
|
||||
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock)
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
if (!block_index) {
|
||||
CTransactionRef ptx = mempool.get(hash);
|
||||
if (ptx) {
|
||||
txOut = ptx;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (g_txindex) {
|
||||
return g_txindex->FindTx(hash, hashBlock, txOut);
|
||||
}
|
||||
} else {
|
||||
if (block_index) {
|
||||
CBlock block;
|
||||
if (ReadBlockFromDisk(block, block_index, consensusParams)) {
|
||||
for (const auto& tx : block.vtx) {
|
||||
if (tx->GetHash() == hash) {
|
||||
txOut = tx;
|
||||
hashBlock = block_index->GetBlockHash();
|
||||
return true;
|
||||
return tx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return false;
|
||||
if (mempool) {
|
||||
CTransactionRef ptx = mempool->get(hash);
|
||||
if (ptx) return ptx;
|
||||
}
|
||||
if (g_txindex) {
|
||||
CTransactionRef tx;
|
||||
if (g_txindex->FindTx(hash, hashBlock, tx)) return tx;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CBlock and CBlockIndex
|
||||
|
|
|
@ -164,8 +164,19 @@ bool LoadGenesisBlock(const CChainParams& chainparams);
|
|||
void UnloadBlockIndex();
|
||||
/** Run an instance of the script checking thread */
|
||||
void ThreadScriptCheck(int worker_num);
|
||||
/** Retrieve a transaction (from memory pool, or from disk, if possible) */
|
||||
bool GetTransaction(const uint256& hash, CTransactionRef& tx, const Consensus::Params& params, uint256& hashBlock, const CBlockIndex* const blockIndex = nullptr);
|
||||
/**
|
||||
* Return transaction from the block at block_index.
|
||||
* If block_index is not provided, fall back to mempool.
|
||||
* If mempool is not provided or the tx couldn't be found in mempool, fall back to g_txindex.
|
||||
*
|
||||
* @param[in] block_index The block to read from disk, or nullptr
|
||||
* @param[in] mempool If block_index is not provided, look in the mempool, if provided
|
||||
* @param[in] hash The txid
|
||||
* @param[in] consensusParams The params
|
||||
* @param[out] hashBlock The hash of block_index, if the tx was found via block_index
|
||||
* @returns The tx if found, otherwise nullptr
|
||||
*/
|
||||
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock);
|
||||
/**
|
||||
* Find the best known block, and make it the tip of the block chain
|
||||
*
|
||||
|
|
Loading…
Add table
Reference in a new issue