Skip to content

Commit cb82f14

Browse files
committed
merge bitcoin#19589: Avoid useless mempool query in gettxoutproof
1 parent 6378759 commit cb82f14

18 files changed

+152
-120
lines changed

src/governance/object.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -533,12 +533,10 @@ bool CGovernanceObject::IsCollateralValid(std::string& strError, bool& fMissingC
533533
fMissingConfirmations = false;
534534
uint256 nExpectedHash = GetHash();
535535

536-
CTransactionRef txCollateral;
537-
uint256 nBlockHash;
538-
539536
// RETRIEVE TRANSACTION IN QUESTION
540-
541-
if (!GetTransaction(nCollateralHash, txCollateral, Params().GetConsensus(), nBlockHash)) {
537+
uint256 nBlockHash;
538+
CTransactionRef txCollateral = GetTransaction(/* block_index */ nullptr, /* mempool */ nullptr, nCollateralHash, Params().GetConsensus(), nBlockHash);
539+
if (!txCollateral) {
542540
strError = strprintf("Can't find collateral tx %s", nCollateralHash.ToString());
543541
LogPrintf("CGovernanceObject::IsCollateralValid -- %s\n", strError);
544542
return false;

src/init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2001,7 +2001,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
20012001
llmq::quorumSnapshotManager.reset();
20022002
llmq::quorumSnapshotManager.reset(new llmq::CQuorumSnapshotManager(*evoDb));
20032003

2004-
llmq::InitLLMQSystem(*evoDb, *node.connman, false, fReset || fReindexChainState);
2004+
llmq::InitLLMQSystem(*evoDb, *node.mempool, *node.connman, false, fReset || fReindexChainState);
20052005

20062006
if (fReset) {
20072007
pblocktree->WriteReindexing(true);

src/llmq/chainlocks.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ namespace llmq
2323
{
2424
CChainLocksHandler* chainLocksHandler;
2525

26-
CChainLocksHandler::CChainLocksHandler(CConnman& _connman) :
26+
CChainLocksHandler::CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman) :
2727
scheduler(std::make_unique<CScheduler>()),
28-
connman(_connman)
28+
mempool(_mempool), connman(_connman)
2929
{
3030
CScheduler::Function serviceLoop = std::bind(&CScheduler::serviceQueue, scheduler.get());
3131
scheduler_thread = std::make_unique<std::thread>(std::bind(&TraceThread<CScheduler::Function>, "cl-schdlr", serviceLoop));
@@ -647,9 +647,9 @@ void CChainLocksHandler::Cleanup()
647647
}
648648
}
649649
for (auto it = txFirstSeenTime.begin(); it != txFirstSeenTime.end(); ) {
650-
CTransactionRef tx;
651650
uint256 hashBlock;
652-
if (!GetTransaction(it->first, tx, Params().GetConsensus(), hashBlock)) {
651+
CTransactionRef tx = GetTransaction(/* block_index */ nullptr, &mempool, it->first, Params().GetConsensus(), hashBlock);
652+
if (!tx) {
653653
// tx has vanished, probably due to conflicts
654654
it = txFirstSeenTime.erase(it);
655655
} else if (!hashBlock.IsNull()) {

src/llmq/chainlocks.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
class CConnman;
2323
class CBlockIndex;
2424
class CScheduler;
25+
class CTxMemPool;
2526

2627
namespace llmq
2728
{
@@ -36,6 +37,7 @@ class CChainLocksHandler : public CRecoveredSigsListener
3637

3738
private:
3839
CConnman& connman;
40+
CTxMemPool& mempool;
3941
std::unique_ptr<CScheduler> scheduler;
4042
std::unique_ptr<std::thread> scheduler_thread;
4143
mutable CCriticalSection cs;
@@ -68,7 +70,7 @@ class CChainLocksHandler : public CRecoveredSigsListener
6870
int64_t lastCleanupTime GUARDED_BY(cs) {0};
6971

7072
public:
71-
explicit CChainLocksHandler(CConnman& _connman);
73+
explicit CChainLocksHandler(CTxMemPool& _mempool, CConnman& _connman);
7274
~CChainLocksHandler();
7375

7476
void Start();

src/llmq/init.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace llmq
2323

2424
CBLSWorker* blsWorker;
2525

26-
void InitLLMQSystem(CEvoDB& evoDb, CConnman& connman, bool unitTests, bool fWipe)
26+
void InitLLMQSystem(CEvoDB& evoDb, CTxMemPool& mempool, CConnman& connman, bool unitTests, bool fWipe)
2727
{
2828
blsWorker = new CBLSWorker();
2929

@@ -33,8 +33,8 @@ void InitLLMQSystem(CEvoDB& evoDb, CConnman& connman, bool unitTests, bool fWipe
3333
quorumManager = new CQuorumManager(evoDb, connman, *blsWorker, *quorumDKGSessionManager);
3434
quorumSigSharesManager = new CSigSharesManager(connman);
3535
quorumSigningManager = new CSigningManager(connman, unitTests, fWipe);
36-
chainLocksHandler = new CChainLocksHandler(connman);
37-
quorumInstantSendManager = new CInstantSendManager(connman, unitTests, fWipe);
36+
chainLocksHandler = new CChainLocksHandler(mempool, connman);
37+
quorumInstantSendManager = new CInstantSendManager(mempool, connman, unitTests, fWipe);
3838

3939
// NOTE: we use this only to wipe the old db, do NOT use it for anything else
4040
// TODO: remove it in some future version

src/llmq/init.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88
class CConnman;
99
class CDBWrapper;
1010
class CEvoDB;
11+
class CTxMemPool;
1112

1213
namespace llmq
1314
{
1415

1516
// Init/destroy LLMQ globals
16-
void InitLLMQSystem(CEvoDB& evoDb, CConnman& connman, bool unitTests, bool fWipe = false);
17+
void InitLLMQSystem(CEvoDB& evoDb, CTxMemPool& mempool, CConnman& connman, bool unitTests, bool fWipe = false);
1718
void DestroyLLMQSystem();
1819

1920
// Manage scheduled tasks, threads, listeners etc.

src/llmq/instantsend.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ void CInstantSendDb::Upgrade()
6464
if (!db->Read(DB_VERSION, v) || v < CInstantSendDb::CURRENT_VERSION) {
6565
CDBBatch batch(*db);
6666
CInstantSendLock islock;
67-
CTransactionRef tx;
68-
uint256 hashBlock;
6967

7068
auto it = std::unique_ptr<CDBIterator>(db->NewIterator());
7169
auto firstKey = std::make_tuple(DB_ISLOCK_BY_HASH, uint256());
@@ -76,7 +74,9 @@ void CInstantSendDb::Upgrade()
7674
if (!it->GetKey(curKey) || std::get<0>(curKey) != DB_ISLOCK_BY_HASH) {
7775
break;
7876
}
79-
if (it->GetValue(islock) && !GetTransaction(islock.txid, tx, Params().GetConsensus(), hashBlock)) {
77+
uint256 hashBlock;
78+
CTransactionRef tx = GetTransaction(/* block_index */ nullptr, /* mempool */ nullptr, islock.txid, Params().GetConsensus(), hashBlock);
79+
if (it->GetValue(islock) && !tx) {
8080
// Drop locks for unknown txes
8181
batch.Erase(std::make_tuple(DB_HASH_BY_TXID, islock.txid));
8282
for (auto& in : islock.inputs) {
@@ -603,10 +603,10 @@ bool CInstantSendManager::CheckCanLock(const COutPoint& outpoint, bool printDebu
603603
return false;
604604
}
605605

606-
CTransactionRef tx;
607606
uint256 hashBlock;
607+
CTransactionRef tx = GetTransaction(/* block_index */ nullptr, &mempool, outpoint.hash, params, hashBlock);
608608
// this relies on enabled txindex and won't work if we ever try to remove the requirement for txindex for masternodes
609-
if (!GetTransaction(outpoint.hash, tx, params, hashBlock)) {
609+
if (!tx) {
610610
if (printDebug) {
611611
LogPrint(BCLog::INSTANTSEND, "CInstantSendManager::%s -- txid=%s: failed to find parent TX %s\n", __func__,
612612
txHash.ToString(), outpoint.hash.ToString());
@@ -661,9 +661,9 @@ void CInstantSendManager::HandleNewInputLockRecoveredSig(const CRecoveredSig& re
661661
g_txindex->BlockUntilSyncedToCurrentChain();
662662
}
663663

664-
CTransactionRef tx;
665664
uint256 hashBlock;
666-
if (!GetTransaction(txid, tx, Params().GetConsensus(), hashBlock)) {
665+
CTransactionRef tx = GetTransaction(/* block_index */ nullptr, &mempool, txid, Params().GetConsensus(), hashBlock);
666+
if (!tx) {
667667
return;
668668
}
669669

@@ -1048,11 +1048,11 @@ void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& has
10481048
return;
10491049
}
10501050

1051-
CTransactionRef tx;
10521051
uint256 hashBlock;
1052+
CTransactionRef tx = GetTransaction(/* block_index */ nullptr, &mempool, islock->txid, Params().GetConsensus(), hashBlock);
10531053
const CBlockIndex* pindexMined{nullptr};
10541054
// we ignore failure here as we must be able to propagate the lock even if we don't have the TX locally
1055-
if (GetTransaction(islock->txid, tx, Params().GetConsensus(), hashBlock) && !hashBlock.IsNull()) {
1055+
if (tx && !hashBlock.IsNull()) {
10561056
pindexMined = WITH_LOCK(cs_main, return LookupBlockIndex(hashBlock));
10571057

10581058
// Let's see if the TX that was locked by this islock is already mined in a ChainLocked block. If yes,

src/llmq/instantsend.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <dbwrapper.h>
1414
#include <primitives/transaction.h>
1515
#include <threadinterrupt.h>
16+
#include <txmempool.h>
1617

1718
#include <unordered_map>
1819
#include <unordered_set>
@@ -194,6 +195,7 @@ class CInstantSendManager : public CRecoveredSigsListener
194195
private:
195196
CInstantSendDb db;
196197
CConnman& connman;
198+
CTxMemPool& mempool;
197199

198200
std::atomic<bool> fUpgradedDB{false};
199201

@@ -241,7 +243,7 @@ class CInstantSendManager : public CRecoveredSigsListener
241243
std::unordered_set<uint256, StaticSaltedHasher> pendingRetryTxs GUARDED_BY(cs_pendingRetry);
242244

243245
public:
244-
explicit CInstantSendManager(CConnman& _connman, bool unitTests, bool fWipe) : db(unitTests, fWipe), connman(_connman) { workInterrupt.reset(); }
246+
explicit CInstantSendManager(CTxMemPool& _mempool, CConnman& _connman, bool unitTests, bool fWipe) : db(unitTests, fWipe), mempool(_mempool), connman(_connman) { workInterrupt.reset(); }
245247
~CInstantSendManager() = default;
246248

247249
void Start();

src/rest.cpp

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,32 @@ static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string me
6868
}
6969

7070
/**
71-
* Get the node context mempool.
71+
* Get the node context.
7272
*
73-
* Set the HTTP error and return nullptr if node context
74-
* mempool is not found.
73+
* @param[in] req The HTTP request, whose status code will be set if node
74+
* context is not found.
75+
* @returns Pointer to the node context or nullptr if not found.
76+
*/
77+
static NodeContext* GetNodeContext(const util::Ref& context, HTTPRequest* req)
78+
{
79+
NodeContext* node = context.Has<NodeContext>() ? &context.Get<NodeContext>() : nullptr;
80+
if (!node) {
81+
RESTERR(req, HTTP_INTERNAL_SERVER_ERROR,
82+
strprintf("%s:%d (%s)\n"
83+
"Internal bug detected: Node context not found!\n"
84+
"You may report this issue here: %s\n",
85+
__FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
86+
return nullptr;
87+
}
88+
return node;
89+
}
90+
91+
/**
92+
* Get the node context mempool.
7593
*
76-
* @param[in] req the HTTP request
77-
* return pointer to the mempool or nullptr if no mempool found
94+
* @param[in] req The HTTP request, whose status code will be set if node
95+
* context mempool is not found.
96+
* @returns Pointer to the mempool or nullptr if no mempool found.
7897
*/
7998
static CTxMemPool* GetMemPool(const util::Ref& context, HTTPRequest* req)
8099
{
@@ -371,10 +390,13 @@ static bool rest_tx(const util::Ref& context, HTTPRequest* req, const std::strin
371390
g_txindex->BlockUntilSyncedToCurrentChain();
372391
}
373392

374-
CTransactionRef tx;
393+
const NodeContext* const node = GetNodeContext(context, req);
394+
if (!node) return false;
375395
uint256 hashBlock = uint256();
376-
if (!GetTransaction(hash, tx, Params().GetConsensus(), hashBlock))
396+
const CTransactionRef tx = GetTransaction(/* block_index */ nullptr, node->mempool, hash, Params().GetConsensus(), hashBlock);
397+
if (!tx) {
377398
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
399+
}
378400

379401
switch (rf) {
380402
case RetFormat::BINARY: {

src/rpc/masternode.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,15 +416,15 @@ static UniValue masternode_payments(const JSONRPCRequest& request)
416416
// Note: we have to actually calculate block reward from scratch instead of simply querying coinbase vout
417417
// because miners might collect less coins than they potentially could and this would break our calculations.
418418
CAmount nBlockFees{0};
419+
NodeContext& node = EnsureNodeContext(request.context);
419420
for (const auto& tx : block.vtx) {
420421
if (tx->IsCoinBase()) {
421422
continue;
422423
}
423424
CAmount nValueIn{0};
424425
for (const auto& txin : tx->vin) {
425-
CTransactionRef txPrev;
426426
uint256 blockHashTmp;
427-
GetTransaction(txin.prevout.hash, txPrev, Params().GetConsensus(), blockHashTmp);
427+
CTransactionRef txPrev = GetTransaction(/* block_index */ nullptr, node.mempool, txin.prevout.hash, Params().GetConsensus(), blockHashTmp);
428428
nValueIn += txPrev->vout[txin.prevout.n].nValue;
429429
}
430430
nBlockFees += nValueIn - tx->GetValueOut();

0 commit comments

Comments
 (0)