mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-12 11:19:08 -05:00
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
This commit is contained in:
parent
aa30676541
commit
cb3e9a1e3f
11 changed files with 238 additions and 158 deletions
|
@ -41,6 +41,7 @@ if [ "${RUN_TIDY}" = "true" ]; then
|
||||||
CI_EXEC "python3 ${DIR_IWYU}/include-what-you-use/iwyu_tool.py"\
|
CI_EXEC "python3 ${DIR_IWYU}/include-what-you-use/iwyu_tool.py"\
|
||||||
" src/compat"\
|
" src/compat"\
|
||||||
" src/init"\
|
" src/init"\
|
||||||
|
" src/kernel/mempool_persist.cpp"\
|
||||||
" src/policy/feerate.cpp"\
|
" src/policy/feerate.cpp"\
|
||||||
" src/policy/packages.cpp"\
|
" src/policy/packages.cpp"\
|
||||||
" src/policy/settings.cpp"\
|
" src/policy/settings.cpp"\
|
||||||
|
|
|
@ -3,4 +3,5 @@
|
||||||
{ include: [ "<bits/termios-c_lflag.h>", private, "<termios.h>", public ] },
|
{ include: [ "<bits/termios-c_lflag.h>", private, "<termios.h>", public ] },
|
||||||
{ include: [ "<bits/termios-struct.h>", private, "<termios.h>", public ] },
|
{ include: [ "<bits/termios-struct.h>", private, "<termios.h>", public ] },
|
||||||
{ include: [ "<bits/termios-tcflow.h>", private, "<termios.h>", public ] },
|
{ include: [ "<bits/termios-tcflow.h>", private, "<termios.h>", public ] },
|
||||||
|
{ include: [ "<bits/chrono.h>", private, "<chrono>", public ] },
|
||||||
]
|
]
|
||||||
|
|
|
@ -177,6 +177,7 @@ BITCOIN_CORE_H = \
|
||||||
kernel/context.h \
|
kernel/context.h \
|
||||||
kernel/mempool_limits.h \
|
kernel/mempool_limits.h \
|
||||||
kernel/mempool_options.h \
|
kernel/mempool_options.h \
|
||||||
|
kernel/mempool_persist.h \
|
||||||
key.h \
|
key.h \
|
||||||
key_io.h \
|
key_io.h \
|
||||||
logging.h \
|
logging.h \
|
||||||
|
@ -368,6 +369,7 @@ libbitcoin_node_a_SOURCES = \
|
||||||
kernel/checks.cpp \
|
kernel/checks.cpp \
|
||||||
kernel/coinstats.cpp \
|
kernel/coinstats.cpp \
|
||||||
kernel/context.cpp \
|
kernel/context.cpp \
|
||||||
|
kernel/mempool_persist.cpp \
|
||||||
mapport.cpp \
|
mapport.cpp \
|
||||||
mempool_args.cpp \
|
mempool_args.cpp \
|
||||||
net.cpp \
|
net.cpp \
|
||||||
|
@ -884,6 +886,7 @@ libbitcoinkernel_la_SOURCES = \
|
||||||
kernel/checks.cpp \
|
kernel/checks.cpp \
|
||||||
kernel/coinstats.cpp \
|
kernel/coinstats.cpp \
|
||||||
kernel/context.cpp \
|
kernel/context.cpp \
|
||||||
|
kernel/mempool_persist.cpp \
|
||||||
key.cpp \
|
key.cpp \
|
||||||
logging.cpp \
|
logging.cpp \
|
||||||
node/blockstorage.cpp \
|
node/blockstorage.cpp \
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
|
||||||
#include <kernel/checks.h>
|
#include <kernel/checks.h>
|
||||||
|
#include <kernel/mempool_persist.h>
|
||||||
|
|
||||||
#include <addrman.h>
|
#include <addrman.h>
|
||||||
#include <banman.h>
|
#include <banman.h>
|
||||||
|
@ -104,6 +105,8 @@
|
||||||
#include <zmq/zmqrpc.h>
|
#include <zmq/zmqrpc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using kernel::DumpMempool;
|
||||||
|
|
||||||
using node::CacheSizes;
|
using node::CacheSizes;
|
||||||
using node::CalculateCacheSizes;
|
using node::CalculateCacheSizes;
|
||||||
using node::ChainstateLoadVerifyError;
|
using node::ChainstateLoadVerifyError;
|
||||||
|
|
189
src/kernel/mempool_persist.cpp
Normal file
189
src/kernel/mempool_persist.cpp
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
// Copyright (c) 2022 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <kernel/mempool_persist.h>
|
||||||
|
|
||||||
|
#include <clientversion.h>
|
||||||
|
#include <consensus/amount.h>
|
||||||
|
#include <fs.h>
|
||||||
|
#include <logging.h>
|
||||||
|
#include <primitives/transaction.h>
|
||||||
|
#include <serialize.h>
|
||||||
|
#include <shutdown.h>
|
||||||
|
#include <streams.h>
|
||||||
|
#include <sync.h>
|
||||||
|
#include <txmempool.h>
|
||||||
|
#include <uint256.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
#include <util/time.h>
|
||||||
|
#include <validation.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <exception>
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
using fsbridge::FopenFn;
|
||||||
|
|
||||||
|
namespace kernel {
|
||||||
|
|
||||||
|
static const uint64_t MEMPOOL_DUMP_VERSION = 1;
|
||||||
|
|
||||||
|
bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, CChainState& active_chainstate, FopenFn mockable_fopen_function)
|
||||||
|
{
|
||||||
|
if (load_path.empty()) return false;
|
||||||
|
|
||||||
|
FILE* filestr{mockable_fopen_function(load_path, "rb")};
|
||||||
|
CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
|
||||||
|
if (file.IsNull()) {
|
||||||
|
LogPrintf("Failed to open mempool file from disk. Continuing anyway.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t count = 0;
|
||||||
|
int64_t expired = 0;
|
||||||
|
int64_t failed = 0;
|
||||||
|
int64_t already_there = 0;
|
||||||
|
int64_t unbroadcast = 0;
|
||||||
|
auto now = NodeClock::now();
|
||||||
|
|
||||||
|
try {
|
||||||
|
uint64_t version;
|
||||||
|
file >> version;
|
||||||
|
if (version != MEMPOOL_DUMP_VERSION) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
uint64_t num;
|
||||||
|
file >> num;
|
||||||
|
while (num) {
|
||||||
|
--num;
|
||||||
|
CTransactionRef tx;
|
||||||
|
int64_t nTime;
|
||||||
|
int64_t nFeeDelta;
|
||||||
|
file >> tx;
|
||||||
|
file >> nTime;
|
||||||
|
file >> nFeeDelta;
|
||||||
|
|
||||||
|
CAmount amountdelta = nFeeDelta;
|
||||||
|
if (amountdelta) {
|
||||||
|
pool.PrioritiseTransaction(tx->GetHash(), amountdelta);
|
||||||
|
}
|
||||||
|
if (nTime > TicksSinceEpoch<std::chrono::seconds>(now - pool.m_expiry)) {
|
||||||
|
LOCK(cs_main);
|
||||||
|
const auto& accepted = AcceptToMemoryPool(active_chainstate, tx, nTime, /*bypass_limits=*/false, /*test_accept=*/false);
|
||||||
|
if (accepted.m_result_type == MempoolAcceptResult::ResultType::VALID) {
|
||||||
|
++count;
|
||||||
|
} else {
|
||||||
|
// mempool may contain the transaction already, e.g. from
|
||||||
|
// wallet(s) having loaded it while we were processing
|
||||||
|
// mempool transactions; consider these as valid, instead of
|
||||||
|
// failed, but mark them as 'already there'
|
||||||
|
if (pool.exists(GenTxid::Txid(tx->GetHash()))) {
|
||||||
|
++already_there;
|
||||||
|
} else {
|
||||||
|
++failed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
++expired;
|
||||||
|
}
|
||||||
|
if (ShutdownRequested())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::map<uint256, CAmount> mapDeltas;
|
||||||
|
file >> mapDeltas;
|
||||||
|
|
||||||
|
for (const auto& i : mapDeltas) {
|
||||||
|
pool.PrioritiseTransaction(i.first, i.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<uint256> unbroadcast_txids;
|
||||||
|
file >> unbroadcast_txids;
|
||||||
|
unbroadcast = unbroadcast_txids.size();
|
||||||
|
for (const auto& txid : unbroadcast_txids) {
|
||||||
|
// Ensure transactions were accepted to mempool then add to
|
||||||
|
// unbroadcast set.
|
||||||
|
if (pool.get(txid) != nullptr) pool.AddUnbroadcastTx(txid);
|
||||||
|
}
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
LogPrintf("Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path, FopenFn mockable_fopen_function, bool skip_file_commit)
|
||||||
|
{
|
||||||
|
auto start = SteadyClock::now();
|
||||||
|
|
||||||
|
std::map<uint256, CAmount> mapDeltas;
|
||||||
|
std::vector<TxMempoolInfo> vinfo;
|
||||||
|
std::set<uint256> unbroadcast_txids;
|
||||||
|
|
||||||
|
static Mutex dump_mutex;
|
||||||
|
LOCK(dump_mutex);
|
||||||
|
|
||||||
|
{
|
||||||
|
LOCK(pool.cs);
|
||||||
|
for (const auto &i : pool.mapDeltas) {
|
||||||
|
mapDeltas[i.first] = i.second;
|
||||||
|
}
|
||||||
|
vinfo = pool.infoAll();
|
||||||
|
unbroadcast_txids = pool.GetUnbroadcastTxs();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto mid = SteadyClock::now();
|
||||||
|
|
||||||
|
try {
|
||||||
|
FILE* filestr{mockable_fopen_function(dump_path + ".new", "wb")};
|
||||||
|
if (!filestr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
|
||||||
|
|
||||||
|
uint64_t version = MEMPOOL_DUMP_VERSION;
|
||||||
|
file << version;
|
||||||
|
|
||||||
|
file << (uint64_t)vinfo.size();
|
||||||
|
for (const auto& i : vinfo) {
|
||||||
|
file << *(i.tx);
|
||||||
|
file << int64_t{count_seconds(i.m_time)};
|
||||||
|
file << int64_t{i.nFeeDelta};
|
||||||
|
mapDeltas.erase(i.tx->GetHash());
|
||||||
|
}
|
||||||
|
|
||||||
|
file << mapDeltas;
|
||||||
|
|
||||||
|
LogPrintf("Writing %d unbroadcast transactions to disk.\n", unbroadcast_txids.size());
|
||||||
|
file << unbroadcast_txids;
|
||||||
|
|
||||||
|
if (!skip_file_commit && !FileCommit(file.Get()))
|
||||||
|
throw std::runtime_error("FileCommit failed");
|
||||||
|
file.fclose();
|
||||||
|
if (!RenameOver(dump_path + ".new", dump_path)) {
|
||||||
|
throw std::runtime_error("Rename failed");
|
||||||
|
}
|
||||||
|
auto last = SteadyClock::now();
|
||||||
|
|
||||||
|
LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n",
|
||||||
|
Ticks<SecondsDouble>(mid - start),
|
||||||
|
Ticks<SecondsDouble>(last - mid));
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace kernel
|
28
src/kernel/mempool_persist.h
Normal file
28
src/kernel/mempool_persist.h
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright (c) 2022 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_KERNEL_MEMPOOL_PERSIST_H
|
||||||
|
#define BITCOIN_KERNEL_MEMPOOL_PERSIST_H
|
||||||
|
|
||||||
|
#include <fs.h>
|
||||||
|
|
||||||
|
class CChainState;
|
||||||
|
class CTxMemPool;
|
||||||
|
|
||||||
|
namespace kernel {
|
||||||
|
|
||||||
|
/** Dump the mempool to disk. */
|
||||||
|
bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path,
|
||||||
|
fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen,
|
||||||
|
bool skip_file_commit = false);
|
||||||
|
|
||||||
|
/** Load the mempool from disk. */
|
||||||
|
bool LoadMempool(CTxMemPool& pool, const fs::path& load_path,
|
||||||
|
CChainState& active_chainstate,
|
||||||
|
fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen);
|
||||||
|
|
||||||
|
} // namespace kernel
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BITCOIN_KERNEL_MEMPOOL_PERSIST_H
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <rpc/blockchain.h>
|
#include <rpc/blockchain.h>
|
||||||
|
|
||||||
|
#include <kernel/mempool_persist.h>
|
||||||
|
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
|
@ -19,6 +21,8 @@
|
||||||
#include <univalue.h>
|
#include <univalue.h>
|
||||||
#include <util/moneystr.h>
|
#include <util/moneystr.h>
|
||||||
|
|
||||||
|
using kernel::DumpMempool;
|
||||||
|
|
||||||
using node::DEFAULT_MAX_RAW_TX_FEE_RATE;
|
using node::DEFAULT_MAX_RAW_TX_FEE_RATE;
|
||||||
using node::MempoolPath;
|
using node::MempoolPath;
|
||||||
using node::ShouldPersistMempool;
|
using node::ShouldPersistMempool;
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <kernel/mempool_persist.h>
|
||||||
|
|
||||||
#include <chainparamsbase.h>
|
#include <chainparamsbase.h>
|
||||||
#include <mempool_args.h>
|
#include <mempool_args.h>
|
||||||
#include <node/mempool_persist_args.h>
|
#include <node/mempool_persist_args.h>
|
||||||
|
@ -17,6 +19,8 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
using kernel::DumpMempool;
|
||||||
|
|
||||||
using node::MempoolPath;
|
using node::MempoolPath;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
|
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
|
||||||
|
#include <kernel/coinstats.h>
|
||||||
|
#include <kernel/mempool_persist.h>
|
||||||
|
|
||||||
#include <arith_uint256.h>
|
#include <arith_uint256.h>
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
@ -19,7 +22,6 @@
|
||||||
#include <flatfile.h>
|
#include <flatfile.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <kernel/coinstats.h>
|
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <logging/timer.h>
|
#include <logging/timer.h>
|
||||||
#include <node/blockstorage.h>
|
#include <node/blockstorage.h>
|
||||||
|
@ -64,6 +66,7 @@
|
||||||
using kernel::CCoinsStats;
|
using kernel::CCoinsStats;
|
||||||
using kernel::CoinStatsHashType;
|
using kernel::CoinStatsHashType;
|
||||||
using kernel::ComputeUTXOStats;
|
using kernel::ComputeUTXOStats;
|
||||||
|
using kernel::LoadMempool;
|
||||||
|
|
||||||
using fsbridge::FopenFn;
|
using fsbridge::FopenFn;
|
||||||
using node::BLOCKFILE_CHUNK_SIZE;
|
using node::BLOCKFILE_CHUNK_SIZE;
|
||||||
|
@ -4640,157 +4643,6 @@ bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint64_t MEMPOOL_DUMP_VERSION = 1;
|
|
||||||
|
|
||||||
bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, CChainState& active_chainstate, FopenFn mockable_fopen_function)
|
|
||||||
{
|
|
||||||
if (load_path.empty()) return false;
|
|
||||||
|
|
||||||
FILE* filestr{mockable_fopen_function(load_path, "rb")};
|
|
||||||
CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
|
|
||||||
if (file.IsNull()) {
|
|
||||||
LogPrintf("Failed to open mempool file from disk. Continuing anyway.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t count = 0;
|
|
||||||
int64_t expired = 0;
|
|
||||||
int64_t failed = 0;
|
|
||||||
int64_t already_there = 0;
|
|
||||||
int64_t unbroadcast = 0;
|
|
||||||
auto now = NodeClock::now();
|
|
||||||
|
|
||||||
try {
|
|
||||||
uint64_t version;
|
|
||||||
file >> version;
|
|
||||||
if (version != MEMPOOL_DUMP_VERSION) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
uint64_t num;
|
|
||||||
file >> num;
|
|
||||||
while (num) {
|
|
||||||
--num;
|
|
||||||
CTransactionRef tx;
|
|
||||||
int64_t nTime;
|
|
||||||
int64_t nFeeDelta;
|
|
||||||
file >> tx;
|
|
||||||
file >> nTime;
|
|
||||||
file >> nFeeDelta;
|
|
||||||
|
|
||||||
CAmount amountdelta = nFeeDelta;
|
|
||||||
if (amountdelta) {
|
|
||||||
pool.PrioritiseTransaction(tx->GetHash(), amountdelta);
|
|
||||||
}
|
|
||||||
if (nTime > TicksSinceEpoch<std::chrono::seconds>(now - pool.m_expiry)) {
|
|
||||||
LOCK(cs_main);
|
|
||||||
const auto& accepted = AcceptToMemoryPool(active_chainstate, tx, nTime, /*bypass_limits=*/false, /*test_accept=*/false);
|
|
||||||
if (accepted.m_result_type == MempoolAcceptResult::ResultType::VALID) {
|
|
||||||
++count;
|
|
||||||
} else {
|
|
||||||
// mempool may contain the transaction already, e.g. from
|
|
||||||
// wallet(s) having loaded it while we were processing
|
|
||||||
// mempool transactions; consider these as valid, instead of
|
|
||||||
// failed, but mark them as 'already there'
|
|
||||||
if (pool.exists(GenTxid::Txid(tx->GetHash()))) {
|
|
||||||
++already_there;
|
|
||||||
} else {
|
|
||||||
++failed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
++expired;
|
|
||||||
}
|
|
||||||
if (ShutdownRequested())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::map<uint256, CAmount> mapDeltas;
|
|
||||||
file >> mapDeltas;
|
|
||||||
|
|
||||||
for (const auto& i : mapDeltas) {
|
|
||||||
pool.PrioritiseTransaction(i.first, i.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::set<uint256> unbroadcast_txids;
|
|
||||||
file >> unbroadcast_txids;
|
|
||||||
unbroadcast = unbroadcast_txids.size();
|
|
||||||
for (const auto& txid : unbroadcast_txids) {
|
|
||||||
// Ensure transactions were accepted to mempool then add to
|
|
||||||
// unbroadcast set.
|
|
||||||
if (pool.get(txid) != nullptr) pool.AddUnbroadcastTx(txid);
|
|
||||||
}
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
LogPrintf("Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path, FopenFn mockable_fopen_function, bool skip_file_commit)
|
|
||||||
{
|
|
||||||
auto start = SteadyClock::now();
|
|
||||||
|
|
||||||
std::map<uint256, CAmount> mapDeltas;
|
|
||||||
std::vector<TxMempoolInfo> vinfo;
|
|
||||||
std::set<uint256> unbroadcast_txids;
|
|
||||||
|
|
||||||
static Mutex dump_mutex;
|
|
||||||
LOCK(dump_mutex);
|
|
||||||
|
|
||||||
{
|
|
||||||
LOCK(pool.cs);
|
|
||||||
for (const auto &i : pool.mapDeltas) {
|
|
||||||
mapDeltas[i.first] = i.second;
|
|
||||||
}
|
|
||||||
vinfo = pool.infoAll();
|
|
||||||
unbroadcast_txids = pool.GetUnbroadcastTxs();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto mid = SteadyClock::now();
|
|
||||||
|
|
||||||
try {
|
|
||||||
FILE* filestr{mockable_fopen_function(dump_path + ".new", "wb")};
|
|
||||||
if (!filestr) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAutoFile file(filestr, SER_DISK, CLIENT_VERSION);
|
|
||||||
|
|
||||||
uint64_t version = MEMPOOL_DUMP_VERSION;
|
|
||||||
file << version;
|
|
||||||
|
|
||||||
file << (uint64_t)vinfo.size();
|
|
||||||
for (const auto& i : vinfo) {
|
|
||||||
file << *(i.tx);
|
|
||||||
file << int64_t{count_seconds(i.m_time)};
|
|
||||||
file << int64_t{i.nFeeDelta};
|
|
||||||
mapDeltas.erase(i.tx->GetHash());
|
|
||||||
}
|
|
||||||
|
|
||||||
file << mapDeltas;
|
|
||||||
|
|
||||||
LogPrintf("Writing %d unbroadcast transactions to disk.\n", unbroadcast_txids.size());
|
|
||||||
file << unbroadcast_txids;
|
|
||||||
|
|
||||||
if (!skip_file_commit && !FileCommit(file.Get()))
|
|
||||||
throw std::runtime_error("FileCommit failed");
|
|
||||||
file.fclose();
|
|
||||||
if (!RenameOver(dump_path + ".new", dump_path)) {
|
|
||||||
throw std::runtime_error("Rename failed");
|
|
||||||
}
|
|
||||||
auto last = SteadyClock::now();
|
|
||||||
|
|
||||||
LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n",
|
|
||||||
Ticks<SecondsDouble>(mid - start),
|
|
||||||
Ticks<SecondsDouble>(last - mid));
|
|
||||||
} catch (const std::exception& e) {
|
|
||||||
LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Guess how far we are in the verification process at the given block index
|
//! Guess how far we are in the verification process at the given block index
|
||||||
//! require cs_main if pindex has not been validated yet (because nChainTx might be unset)
|
//! require cs_main if pindex has not been validated yet (because nChainTx might be unset)
|
||||||
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) {
|
double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) {
|
||||||
|
|
|
@ -1012,12 +1012,6 @@ bool DeploymentEnabled(const ChainstateManager& chainman, DEP dep)
|
||||||
return DeploymentEnabled(chainman.GetConsensus(), dep);
|
return DeploymentEnabled(chainman.GetConsensus(), dep);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Dump the mempool to disk. */
|
|
||||||
bool DumpMempool(const CTxMemPool& pool, const fs::path& dump_path, fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen, bool skip_file_commit = false);
|
|
||||||
|
|
||||||
/** Load the mempool from disk. */
|
|
||||||
bool LoadMempool(CTxMemPool& pool, const fs::path& load_path, CChainState& active_chainstate, fsbridge::FopenFn mockable_fopen_function = fsbridge::fopen);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the expected assumeutxo value for a given height, if one exists.
|
* Return the expected assumeutxo value for a given height, if one exists.
|
||||||
*
|
*
|
||||||
|
|
|
@ -22,6 +22,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES = (
|
||||||
"wallet/fees -> wallet/wallet -> wallet/fees",
|
"wallet/fees -> wallet/wallet -> wallet/fees",
|
||||||
"wallet/wallet -> wallet/walletdb -> wallet/wallet",
|
"wallet/wallet -> wallet/walletdb -> wallet/wallet",
|
||||||
"kernel/coinstats -> validation -> kernel/coinstats",
|
"kernel/coinstats -> validation -> kernel/coinstats",
|
||||||
|
"kernel/mempool_persist -> validation -> kernel/mempool_persist",
|
||||||
)
|
)
|
||||||
|
|
||||||
CODE_DIR = "src"
|
CODE_DIR = "src"
|
||||||
|
|
Loading…
Add table
Reference in a new issue