Skip to content

Commit cb3e9a1

Browse files
committed
Move {Load,Dump}Mempool to kernel namespace
Also: 1. Add the newly introduced kernel/mempool_persist.cpp to IWYU CI script 2. Add chrono mapping for iwyu
1 parent aa30676 commit cb3e9a1

File tree

11 files changed

+238
-158
lines changed

11 files changed

+238
-158
lines changed

ci/test/06_script_b.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ if [ "${RUN_TIDY}" = "true" ]; then
4141
CI_EXEC "python3 ${DIR_IWYU}/include-what-you-use/iwyu_tool.py"\
4242
" src/compat"\
4343
" src/init"\
44+
" src/kernel/mempool_persist.cpp"\
4445
" src/policy/feerate.cpp"\
4546
" src/policy/packages.cpp"\
4647
" src/policy/settings.cpp"\

contrib/devtools/iwyu/bitcoin.core.imp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
{ include: [ "<bits/termios-c_lflag.h>", private, "<termios.h>", public ] },
44
{ include: [ "<bits/termios-struct.h>", private, "<termios.h>", public ] },
55
{ include: [ "<bits/termios-tcflow.h>", private, "<termios.h>", public ] },
6+
{ include: [ "<bits/chrono.h>", private, "<chrono>", public ] },
67
]

src/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ BITCOIN_CORE_H = \
177177
kernel/context.h \
178178
kernel/mempool_limits.h \
179179
kernel/mempool_options.h \
180+
kernel/mempool_persist.h \
180181
key.h \
181182
key_io.h \
182183
logging.h \
@@ -368,6 +369,7 @@ libbitcoin_node_a_SOURCES = \
368369
kernel/checks.cpp \
369370
kernel/coinstats.cpp \
370371
kernel/context.cpp \
372+
kernel/mempool_persist.cpp \
371373
mapport.cpp \
372374
mempool_args.cpp \
373375
net.cpp \
@@ -884,6 +886,7 @@ libbitcoinkernel_la_SOURCES = \
884886
kernel/checks.cpp \
885887
kernel/coinstats.cpp \
886888
kernel/context.cpp \
889+
kernel/mempool_persist.cpp \
887890
key.cpp \
888891
logging.cpp \
889892
node/blockstorage.cpp \

src/init.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <init.h>
1111

1212
#include <kernel/checks.h>
13+
#include <kernel/mempool_persist.h>
1314

1415
#include <addrman.h>
1516
#include <banman.h>
@@ -104,6 +105,8 @@
104105
#include <zmq/zmqrpc.h>
105106
#endif
106107

108+
using kernel::DumpMempool;
109+
107110
using node::CacheSizes;
108111
using node::CalculateCacheSizes;
109112
using node::ChainstateLoadVerifyError;

src/kernel/mempool_persist.cpp

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <kernel/mempool_persist.h>
6+
7+
#include <clientversion.h>
8+
#include <consensus/amount.h>
9+
#include <fs.h>
10+
#include <logging.h>
11+
#include <primitives/transaction.h>
12+
#include <serialize.h>
13+
#include <shutdown.h>
14+
#include <streams.h>
15+
#include <sync.h>
16+
#include <txmempool.h>
17+
#include <uint256.h>
18+
#include <util/system.h>
19+
#include <util/time.h>
20+
#include <validation.h>
21+
22+
#include <chrono>
23+
#include <cstdint>
24+
#include <cstdio>
25+
#include <exception>
26+
#include <functional>
27+
#include <map>
28+
#include <memory>
29+
#include <set>
30+
#include <stdexcept>
31+
#include <utility>
32+
#include <vector>
33+
34+
using fsbridge::FopenFn;
35+
36+
namespace kernel {
37+
38+
static const uint64_t MEMPOOL_DUMP_VERSION = 1;
39+
40+
bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, CChainState& active_chainstate, FopenFn mockable_fopen_function)
41+
{
42+
if (load_path.empty()) return false;
43+
44+
FILE* filestr{mockable_fopen_function(load_path, "rb")};
45+
CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
46+
if (file.IsNull()) {
47+
LogPrintf("Failed to open mempool file from disk. Continuing anyway.\n");
48+
return false;
49+
}
50+
51+
int64_t count = 0;
52+
int64_t expired = 0;
53+
int64_t failed = 0;
54+
int64_t already_there = 0;
55+
int64_t unbroadcast = 0;
56+
auto now = NodeClock::now();
57+
58+
try {
59+
uint64_t version;
60+
file >> version;
61+
if (version != MEMPOOL_DUMP_VERSION) {
62+
return false;
63+
}
64+
uint64_t num;
65+
file >> num;
66+
while (num) {
67+
--num;
68+
CTransactionRef tx;
69+
int64_t nTime;
70+
int64_t nFeeDelta;
71+
file >> tx;
72+
file >> nTime;
73+
file >> nFeeDelta;
74+
75+
CAmount amountdelta = nFeeDelta;
76+
if (amountdelta) {
77+
pool.PrioritiseTransaction(tx->GetHash(), amountdelta);
78+
}
79+
if (nTime > TicksSinceEpoch<std::chrono::seconds>(now - pool.m_expiry)) {
80+
LOCK(cs_main);
81+
const auto& accepted = AcceptToMemoryPool(active_chainstate, tx, nTime, /*bypass_limits=*/false, /*test_accept=*/false);
82+
if (accepted.m_result_type == MempoolAcceptResult::ResultType::VALID) {
83+
++count;
84+
} else {
85+
// mempool may contain the transaction already, e.g. from
86+
// wallet(s) having loaded it while we were processing
87+
// mempool transactions; consider these as valid, instead of
88+
// failed, but mark them as 'already there'
89+
if (pool.exists(GenTxid::Txid(tx->GetHash()))) {
90+
++already_there;
91+
} else {
92+
++failed;
93+
}
94+
}
95+
} else {
96+
++expired;
97+
}
98+
if (ShutdownRequested())
99+
return false;
100+
}
101+
std::map<uint256, CAmount> mapDeltas;
102+
file >> mapDeltas;
103+
104+
for (const auto& i : mapDeltas) {
105+
pool.PrioritiseTransaction(i.first, i.second);
106+
}
107+
108+
std::set<uint256> unbroadcast_txids;
109+
file >> unbroadcast_txids;
110+
unbroadcast = unbroadcast_txids.size();
111+
for (const auto& txid : unbroadcast_txids) {
112+
// Ensure transactions were accepted to mempool then add to
113+
// unbroadcast set.
114+
if (pool.get(txid) != nullptr) pool.AddUnbroadcastTx(txid);
115+
}
116+
} catch (const std::exception& e) {
117+
LogPrintf("Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
118+
return false;
119+
}
120+
121+
LogPrintf("Imported mempool transactions from disk: %i succeeded, %i failed, %i expired, %i already there, %i waiting for initial broadcast\n", count, failed, expired, already_there, unbroadcast);
122+
return true;
123+
}
124+
125+
bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path, FopenFn mockable_fopen_function, bool skip_file_commit)
126+
{
127+
auto start = SteadyClock::now();
128+
129+
std::map<uint256, CAmount> mapDeltas;
130+
std::vector<TxMempoolInfo> vinfo;
131+
std::set<uint256> unbroadcast_txids;
132+
133+
static Mutex dump_mutex;
134+
LOCK(dump_mutex);
135+
136+
{
137+
LOCK(pool.cs);
138+
for (const auto &i : pool.mapDeltas) {
139+
mapDeltas[i.first] = i.second;
140+
}
141+
vinfo = pool.infoAll();
142+
unbroadcast_txids = pool.GetUnbroadcastTxs();
143+
}
144+
145+
auto mid = SteadyClock::now();
146+
147+
try {
148+
FILE* filestr{mockable_fopen_function(dump_path + ".new", "wb")};
149+
if (!filestr) {
150+
return false;
151+
}
152+
153+
CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
154+
155+
uint64_t version = MEMPOOL_DUMP_VERSION;
156+
file << version;
157+
158+
file << (uint64_t)vinfo.size();
159+
for (const auto& i : vinfo) {
160+
file << *(i.tx);
161+
file << int64_t{count_seconds(i.m_time)};
162+
file << int64_t{i.nFeeDelta};
163+
mapDeltas.erase(i.tx->GetHash());
164+
}
165+
166+
file << mapDeltas;
167+
168+
LogPrintf("Writing %d unbroadcast transactions to disk.\n", unbroadcast_txids.size());
169+
file << unbroadcast_txids;
170+
171+
if (!skip_file_commit && !FileCommit(file.Get()))
172+
throw std::runtime_error("FileCommit failed");
173+
file.fclose();
174+
if (!RenameOver(dump_path + ".new", dump_path)) {
175+
throw std::runtime_error("Rename failed");
176+
}
177+
auto last = SteadyClock::now();
178+
179+
LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n",
180+
Ticks<SecondsDouble>(mid - start),
181+
Ticks<SecondsDouble>(last - mid));
182+
} catch (const std::exception& e) {
183+
LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what());
184+
return false;
185+
}
186+
return true;
187+
}
188+
189+
} // namespace kernel

src/kernel/mempool_persist.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) 2022 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_KERNEL_MEMPOOL_PERSIST_H
6+
#define BITCOIN_KERNEL_MEMPOOL_PERSIST_H
7+
8+
#include <fs.h>
9+
10+
class CChainState;
11+
class CTxMemPool;
12+
13+
namespace kernel {
14+
15+
/** Dump the mempool to disk. */
16+
bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path,
17+
fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen,
18+
bool skip_file_commit = false);
19+
20+
/** Load the mempool from disk. */
21+
bool LoadMempool(CTxMemPool& pool, const fs::path& load_path,
22+
CChainState& active_chainstate,
23+
fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen);
24+
25+
} // namespace kernel
26+
27+
28+
#endif // BITCOIN_KERNEL_MEMPOOL_PERSIST_H

src/rpc/mempool.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
#include <rpc/blockchain.h>
77

8+
#include <kernel/mempool_persist.h>
9+
810
#include <chainparams.h>
911
#include <core_io.h>
1012
#include <fs.h>
@@ -19,6 +21,8 @@
1921
#include <univalue.h>
2022
#include <util/moneystr.h>
2123

24+
using kernel::DumpMempool;
25+
2226
using node::DEFAULT_MAX_RAW_TX_FEE_RATE;
2327
using node::MempoolPath;
2428
using node::ShouldPersistMempool;

src/test/fuzz/validation_load_mempool.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <kernel/mempool_persist.h>
6+
57
#include <chainparamsbase.h>
68
#include <mempool_args.h>
79
#include <node/mempool_persist_args.h>
@@ -17,6 +19,8 @@
1719
#include <cstdint>
1820
#include <vector>
1921

22+
using kernel::DumpMempool;
23+
2024
using node::MempoolPath;
2125

2226
namespace {

0 commit comments

Comments
 (0)