Skip to content

Commit 48d64d7

Browse files
author
MarcoFalke
committed
Merge #17564: rpc: Use mempool from node context instead of global
fa8e650 rest: Use mempool from node context instead of global (MarcoFalke) fa660d6 node: Use mempool from node context instead of global (MarcoFalke) facbaf0 rpc: Use mempool from node context instead of global (MarcoFalke) Pull request description: Currently they are identical, but in the future we might want to turn the mempool into a unique_ptr. Replacing the global with the mempool pointer from the node context simplifies this step. ACKs for top commit: jnewbery: Code review ACK fa8e650 ryanofsky: Code review ACK fa8e650, Only the discussed REST server changes since the last review. Tree-SHA512: 0836f3f39cf90306455962918446e5f8612e88c32072b92afc30929aea1f17430bbda0e2b3668d36c9d6b97d63a93cf4903185194571108642b7bf5a39b89125
2 parents 988eaf2 + fa8e650 commit 48d64d7

File tree

11 files changed

+68
-30
lines changed

11 files changed

+68
-30
lines changed

src/interfaces/chain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ class ChainImpl : public Chain
263263
}
264264
return true;
265265
}
266-
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(coins); }
266+
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
267267
double guessVerificationProgress(const uint256& block_hash) override
268268
{
269269
LOCK(cs_main);

src/interfaces/node.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,8 @@ class NodeImpl : public Node
167167
}
168168
int64_t getTotalBytesRecv() override { return m_context.connman ? m_context.connman->GetTotalBytesRecv() : 0; }
169169
int64_t getTotalBytesSent() override { return m_context.connman ? m_context.connman->GetTotalBytesSent() : 0; }
170-
size_t getMempoolSize() override { return ::mempool.size(); }
171-
size_t getMempoolDynamicUsage() override { return ::mempool.DynamicMemoryUsage(); }
170+
size_t getMempoolSize() override { return m_context.mempool ? m_context.mempool->size() : 0; }
171+
size_t getMempoolDynamicUsage() override { return m_context.mempool ? m_context.mempool->DynamicMemoryUsage() : 0; }
172172
bool getHeaderTip(int& height, int64_t& block_time) override
173173
{
174174
LOCK(::cs_main);

src/node/coin.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44

55
#include <node/coin.h>
66

7+
#include <node/context.h>
78
#include <txmempool.h>
89
#include <validation.h>
910

10-
void FindCoins(std::map<COutPoint, Coin>& coins)
11+
void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins)
1112
{
12-
LOCK2(cs_main, ::mempool.cs);
13+
assert(node.mempool);
14+
LOCK2(cs_main, node.mempool->cs);
1315
CCoinsViewCache& chain_view = ::ChainstateActive().CoinsTip();
14-
CCoinsViewMemPool mempool_view(&chain_view, ::mempool);
16+
CCoinsViewMemPool mempool_view(&chain_view, *node.mempool);
1517
for (auto& coin : coins) {
1618
if (!mempool_view.GetCoin(coin.first, coin.second)) {
1719
// Either the coin is not in the CCoinsViewCache or is spent. Clear it.

src/node/coin.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@
99

1010
class COutPoint;
1111
class Coin;
12+
struct NodeContext;
1213

1314
/**
1415
* Look up unspent output information. Returns coins in the mempool and in the
1516
* current chain UTXO set. Iterates through all the keys in the map and
1617
* populates the values.
1718
*
19+
* @param[in] node The node context to use for lookup
1820
* @param[in,out] coins map to fill
1921
*/
20-
void FindCoins(std::map<COutPoint, Coin>& coins);
22+
void FindCoins(const NodeContext& node, std::map<COutPoint, Coin>& coins);
2123

2224
#endif // BITCOIN_NODE_COIN_H

src/node/transaction.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
2020
// node.connman is assigned both before chain clients and before RPC server is accepting calls,
2121
// and reset after chain clients and RPC sever are stopped. node.connman should never be null here.
2222
assert(node.connman);
23+
assert(node.mempool);
2324
std::promise<void> promise;
2425
uint256 hashTx = tx->GetHash();
2526
bool callback_set = false;
@@ -35,10 +36,10 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
3536
// So if the output does exist, then this transaction exists in the chain.
3637
if (!existingCoin.IsSpent()) return TransactionError::ALREADY_IN_CHAIN;
3738
}
38-
if (!mempool.exists(hashTx)) {
39+
if (!node.mempool->exists(hashTx)) {
3940
// Transaction is not already in the mempool. Submit it.
4041
TxValidationState state;
41-
if (!AcceptToMemoryPool(mempool, state, std::move(tx),
42+
if (!AcceptToMemoryPool(*node.mempool, state, std::move(tx),
4243
nullptr /* plTxnReplaced */, false /* bypass_limits */, max_tx_fee)) {
4344
err_string = FormatStateMessage(state);
4445
if (state.IsInvalid()) {

src/qt/test/wallettests.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ void TestGUI(interfaces::Node& node)
134134
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
135135
}
136136
node.context()->connman = std::move(test.m_node.connman);
137+
node.context()->mempool = std::move(test.m_node.mempool);
137138
std::shared_ptr<CWallet> wallet = std::make_shared<CWallet>(node.context()->chain.get(), WalletLocation(), WalletDatabase::CreateMock());
138139
bool firstRun;
139140
wallet->LoadWallet(firstRun);

src/rest.cpp

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <core_io.h>
99
#include <httpserver.h>
1010
#include <index/txindex.h>
11+
#include <node/context.h>
1112
#include <primitives/block.h>
1213
#include <primitives/transaction.h>
1314
#include <rpc/blockchain.h>
@@ -16,6 +17,7 @@
1617
#include <streams.h>
1718
#include <sync.h>
1819
#include <txmempool.h>
20+
#include <util/check.h>
1921
#include <util/strencodings.h>
2022
#include <validation.h>
2123
#include <version.h>
@@ -69,6 +71,24 @@ static bool RESTERR(HTTPRequest* req, enum HTTPStatusCode status, std::string me
6971
return false;
7072
}
7173

74+
/**
75+
* Get the node context mempool.
76+
*
77+
* Set the HTTP error and return nullptr if node context
78+
* mempool is not found.
79+
*
80+
* @param[in] req the HTTP request
81+
* return pointer to the mempool or nullptr if no mempool found
82+
*/
83+
static CTxMemPool* GetMemPool(HTTPRequest* req)
84+
{
85+
if (!g_rpc_node || !g_rpc_node->mempool) {
86+
RESTERR(req, HTTP_NOT_FOUND, "Mempool disabled or instance not found");
87+
return nullptr;
88+
}
89+
return g_rpc_node->mempool;
90+
}
91+
7292
static RetFormat ParseDataFormat(std::string& param, const std::string& strReq)
7393
{
7494
const std::string::size_type pos = strReq.rfind('.');
@@ -295,12 +315,14 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
295315
{
296316
if (!CheckWarmup(req))
297317
return false;
318+
const CTxMemPool* mempool = GetMemPool(req);
319+
if (!mempool) return false;
298320
std::string param;
299321
const RetFormat rf = ParseDataFormat(param, strURIPart);
300322

301323
switch (rf) {
302324
case RetFormat::JSON: {
303-
UniValue mempoolInfoObject = MempoolInfoToJSON(::mempool);
325+
UniValue mempoolInfoObject = MempoolInfoToJSON(*mempool);
304326

305327
std::string strJSON = mempoolInfoObject.write() + "\n";
306328
req->WriteHeader("Content-Type", "application/json");
@@ -315,14 +337,15 @@ static bool rest_mempool_info(HTTPRequest* req, const std::string& strURIPart)
315337

316338
static bool rest_mempool_contents(HTTPRequest* req, const std::string& strURIPart)
317339
{
318-
if (!CheckWarmup(req))
319-
return false;
340+
if (!CheckWarmup(req)) return false;
341+
const CTxMemPool* mempool = GetMemPool(req);
342+
if (!mempool) return false;
320343
std::string param;
321344
const RetFormat rf = ParseDataFormat(param, strURIPart);
322345

323346
switch (rf) {
324347
case RetFormat::JSON: {
325-
UniValue mempoolObject = MempoolToJSON(::mempool, true);
348+
UniValue mempoolObject = MempoolToJSON(*mempool, true);
326349

327350
std::string strJSON = mempoolObject.write() + "\n";
328351
req->WriteHeader("Content-Type", "application/json");
@@ -500,11 +523,13 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
500523
};
501524

502525
if (fCheckMemPool) {
526+
const CTxMemPool* mempool = GetMemPool(req);
527+
if (!mempool) return false;
503528
// use db+mempool as cache backend in case user likes to query mempool
504-
LOCK2(cs_main, mempool.cs);
529+
LOCK2(cs_main, mempool->cs);
505530
CCoinsViewCache& viewChain = ::ChainstateActive().CoinsTip();
506-
CCoinsViewMemPool viewMempool(&viewChain, mempool);
507-
process_utxos(viewMempool, mempool);
531+
CCoinsViewMemPool viewMempool(&viewChain, *mempool);
532+
process_utxos(viewMempool, *mempool);
508533
} else {
509534
LOCK(cs_main); // no need to lock mempool!
510535
process_utxos(::ChainstateActive().CoinsTip(), CTxMemPool());

src/rpc/blockchain.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ static UniValue getrawmempool(const JSONRPCRequest& request)
528528
if (!request.params[0].isNull())
529529
fVerbose = request.params[0].get_bool();
530530

531-
return MempoolToJSON(::mempool, fVerbose);
531+
return MempoolToJSON(EnsureMemPool(), fVerbose);
532532
}
533533

534534
static UniValue getmempoolancestors(const JSONRPCRequest& request)
@@ -566,6 +566,7 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
566566

567567
uint256 hash = ParseHashV(request.params[0], "parameter 1");
568568

569+
const CTxMemPool& mempool = EnsureMemPool();
569570
LOCK(mempool.cs);
570571

571572
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -591,7 +592,7 @@ static UniValue getmempoolancestors(const JSONRPCRequest& request)
591592
const CTxMemPoolEntry &e = *ancestorIt;
592593
const uint256& _hash = e.GetTx().GetHash();
593594
UniValue info(UniValue::VOBJ);
594-
entryToJSON(::mempool, info, e);
595+
entryToJSON(mempool, info, e);
595596
o.pushKV(_hash.ToString(), info);
596597
}
597598
return o;
@@ -633,6 +634,7 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
633634

634635
uint256 hash = ParseHashV(request.params[0], "parameter 1");
635636

637+
const CTxMemPool& mempool = EnsureMemPool();
636638
LOCK(mempool.cs);
637639

638640
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -658,7 +660,7 @@ static UniValue getmempooldescendants(const JSONRPCRequest& request)
658660
const CTxMemPoolEntry &e = *descendantIt;
659661
const uint256& _hash = e.GetTx().GetHash();
660662
UniValue info(UniValue::VOBJ);
661-
entryToJSON(::mempool, info, e);
663+
entryToJSON(mempool, info, e);
662664
o.pushKV(_hash.ToString(), info);
663665
}
664666
return o;
@@ -685,6 +687,7 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)
685687

686688
uint256 hash = ParseHashV(request.params[0], "parameter 1");
687689

690+
const CTxMemPool& mempool = EnsureMemPool();
688691
LOCK(mempool.cs);
689692

690693
CTxMemPool::txiter it = mempool.mapTx.find(hash);
@@ -694,7 +697,7 @@ static UniValue getmempoolentry(const JSONRPCRequest& request)
694697

695698
const CTxMemPoolEntry &e = *it;
696699
UniValue info(UniValue::VOBJ);
697-
entryToJSON(::mempool, info, e);
700+
entryToJSON(mempool, info, e);
698701
return info;
699702
}
700703

@@ -1070,6 +1073,7 @@ UniValue gettxout(const JSONRPCRequest& request)
10701073
CCoinsViewCache* coins_view = &::ChainstateActive().CoinsTip();
10711074

10721075
if (fMempool) {
1076+
const CTxMemPool& mempool = EnsureMemPool();
10731077
LOCK(mempool.cs);
10741078
CCoinsViewMemPool view(coins_view, mempool);
10751079
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
@@ -1448,7 +1452,7 @@ static UniValue getmempoolinfo(const JSONRPCRequest& request)
14481452
},
14491453
}.Check(request);
14501454

1451-
return MempoolInfoToJSON(::mempool);
1455+
return MempoolInfoToJSON(EnsureMemPool());
14521456
}
14531457

14541458
static UniValue preciousblock(const JSONRPCRequest& request)
@@ -1964,11 +1968,13 @@ static UniValue savemempool(const JSONRPCRequest& request)
19641968
},
19651969
}.Check(request);
19661970

1967-
if (!::mempool.IsLoaded()) {
1971+
const CTxMemPool& mempool = EnsureMemPool();
1972+
1973+
if (!mempool.IsLoaded()) {
19681974
throw JSONRPCError(RPC_MISC_ERROR, "The mempool was not loaded yet");
19691975
}
19701976

1971-
if (!DumpMempool(::mempool)) {
1977+
if (!DumpMempool(mempool)) {
19721978
throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
19731979
}
19741980

src/rpc/mining.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ static UniValue getmininginfo(const JSONRPCRequest& request)
244244
}.Check(request);
245245

246246
LOCK(cs_main);
247+
const CTxMemPool& mempool = EnsureMemPool();
247248

248249
UniValue obj(UniValue::VOBJ);
249250
obj.pushKV("blocks", (int)::ChainActive().Height());
@@ -290,7 +291,7 @@ static UniValue prioritisetransaction(const JSONRPCRequest& request)
290291
throw JSONRPCError(RPC_INVALID_PARAMETER, "Priority is no longer supported, dummy argument to prioritisetransaction must be 0.");
291292
}
292293

293-
mempool.PrioritiseTransaction(hash, nAmount);
294+
EnsureMemPool().PrioritiseTransaction(hash, nAmount);
294295
return true;
295296
}
296297

@@ -476,6 +477,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
476477
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, PACKAGE_NAME " is in initial sync and waiting for blocks...");
477478

478479
static unsigned int nTransactionsUpdatedLast;
480+
const CTxMemPool& mempool = EnsureMemPool();
479481

480482
if (!lpval.isNull())
481483
{
@@ -510,7 +512,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
510512
if (g_best_block_cv.wait_until(lock, checktxtime) == std::cv_status::timeout)
511513
{
512514
// Timeout: Check transactions for update
513-
// without holding ::mempool.cs to avoid deadlocks
515+
// without holding the mempool lock to avoid deadlocks
514516
if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP)
515517
break;
516518
checktxtime += std::chrono::seconds(10);

src/rpc/rawtransaction.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
636636
CCoinsView viewDummy;
637637
CCoinsViewCache view(&viewDummy);
638638
{
639+
const CTxMemPool& mempool = EnsureMemPool();
639640
LOCK(cs_main);
640641
LOCK(mempool.cs);
641642
CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip();
@@ -758,7 +759,7 @@ static UniValue signrawtransactionwithkey(const JSONRPCRequest& request)
758759
for (const CTxIn& txin : mtx.vin) {
759760
coins[txin.prevout]; // Create empty map entry keyed by prevout.
760761
}
761-
FindCoins(coins);
762+
FindCoins(*g_rpc_node, coins);
762763

763764
// Parse the prevtxs array
764765
ParsePrevouts(request.params[2], &keystore, coins);
@@ -890,6 +891,7 @@ static UniValue testmempoolaccept(const JSONRPCRequest& request)
890891
max_raw_tx_fee_rate = CFeeRate(AmountFromValue(request.params[1]));
891892
}
892893

894+
CTxMemPool& mempool = EnsureMemPool();
893895
int64_t virtual_size = GetVirtualTransactionSize(*tx);
894896
CAmount max_raw_tx_fee = max_raw_tx_fee_rate.GetFee(virtual_size);
895897

@@ -1508,6 +1510,7 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
15081510
CCoinsView viewDummy;
15091511
CCoinsViewCache view(&viewDummy);
15101512
{
1513+
const CTxMemPool& mempool = EnsureMemPool();
15111514
LOCK2(cs_main, mempool.cs);
15121515
CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip();
15131516
CCoinsViewMemPool viewMempool(&viewChain, mempool);

0 commit comments

Comments
 (0)