23#include <validation.h>
45 if (load_path.empty())
return false;
47 AutoFile file{opts.mockable_fopen_function(load_path,
"rb")};
49 LogInfo(
"Failed to open mempool file. Continuing anyway.\n");
56 int64_t already_there = 0;
57 int64_t unbroadcast = 0;
65 file.SetObfuscation({});
69 file.SetObfuscation(obfuscation);
74 uint64_t total_txns_to_load;
75 file >> total_txns_to_load;
76 uint64_t txns_tried = 0;
77 LogInfo(
"Loading %u mempool transactions from file...\n", total_txns_to_load);
78 int next_tenth_to_report = 0;
79 while (txns_tried < total_txns_to_load) {
80 const int percentage_done(100.0 * txns_tried / total_txns_to_load);
81 if (next_tenth_to_report < percentage_done / 10) {
82 LogInfo(
"Progress loading mempool transactions from file: %d%% (tried %u, %u remaining)\n",
83 percentage_done, txns_tried, total_txns_to_load - txns_tried);
84 next_tenth_to_report = percentage_done / 10;
95 if (opts.use_current_time) {
96 nTime = TicksSinceEpoch<std::chrono::seconds>(now);
99 CAmount amountdelta = nFeeDelta;
100 if (amountdelta && opts.apply_fee_delta_priority) {
103 if (nTime > TicksSinceEpoch<std::chrono::seconds>(now - pool.
m_opts.
expiry)) {
105 const auto& accepted =
AcceptToMemoryPool(active_chainstate, tx, nTime,
false,
false);
113 if (pool.
exists(tx->GetHash())) {
125 std::map<Txid, CAmount> mapDeltas;
128 if (opts.apply_fee_delta_priority) {
129 for (
const auto& i : mapDeltas) {
134 std::set<Txid> unbroadcast_txids;
135 file >> unbroadcast_txids;
136 if (opts.apply_unbroadcast_set) {
137 unbroadcast = unbroadcast_txids.size();
138 for (
const auto& txid : unbroadcast_txids) {
144 }
catch (
const std::exception& e) {
145 LogInfo(
"Failed to deserialize mempool data on file: %s. Continuing anyway.\n", e.what());
149 LogInfo(
"Imported mempool transactions from file: %i succeeded, %i failed, %i expired, %i already there, %i waiting for initial broadcast\n",
count, failed, expired, already_there, unbroadcast);
155 auto start = SteadyClock::now();
157 std::map<Txid, CAmount> mapDeltas;
158 std::vector<TxMempoolInfo> vinfo;
159 std::set<Txid> unbroadcast_txids;
161 static Mutex dump_mutex;
166 for (
const auto &i : pool.mapDeltas) {
167 mapDeltas[i.first] = i.second;
173 auto mid = SteadyClock::now();
175 const fs::path file_fspath{dump_path +
".new"};
176 AutoFile file{mockable_fopen_function(file_fspath,
"wb")};
188 file.SetObfuscation(obfuscation);
190 file.SetObfuscation({});
193 uint64_t mempool_transactions_to_write(vinfo.size());
194 file << mempool_transactions_to_write;
195 LogInfo(
"Writing %u mempool transactions to file...\n", mempool_transactions_to_write);
196 for (
const auto& i : vinfo) {
199 file << int64_t{i.nFeeDelta};
200 mapDeltas.erase(i.tx->GetHash());
205 LogInfo(
"Writing %d unbroadcast transactions to file.\n", unbroadcast_txids.size());
206 file << unbroadcast_txids;
208 if (!skip_file_commit && !file.Commit()) {
210 throw std::runtime_error(
"Commit failed");
212 if (file.fclose() != 0) {
213 throw std::runtime_error(
216 if (!
RenameOver(dump_path +
".new", dump_path)) {
217 throw std::runtime_error(
"Rename failed");
219 auto last = SteadyClock::now();
221 LogInfo(
"Dumped mempool: %.3fs to copy, %.3fs to dump, %d bytes dumped to file\n",
222 Ticks<SecondsDouble>(mid - start),
223 Ticks<SecondsDouble>(last - mid),
224 fs::file_size(dump_path));
225 }
catch (
const std::exception& e) {
226 LogInfo(
"Failed to dump mempool: %s. Continuing anyway.\n", e.what());
int64_t CAmount
Amount in satoshis (Can be negative)
Non-refcounted RAII wrapper for FILE*.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
void PrioritiseTransaction(const Txid &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
CTransactionRef get(const Txid &hash) const
std::vector< TxMempoolInfo > infoAll() const
bool exists(const Txid &txid) const
void AddUnbroadcastTx(const Txid &txid)
Adds a transaction to the unbroadcast set.
std::set< Txid > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
Chainstate stores and provides an API to update our local knowledge of the current best chain.
ChainstateManager & m_chainman
The chainstate manager that owns this chainstate.
const util::SignalInterrupt & m_interrupt
static constexpr size_t KEY_SIZE
std::vector< B > randbytes(size_t len) noexcept
Generate random bytes.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
static std::string PathToString(const path &path)
Convert path object to a byte string.
bool RenameOver(fs::path src, fs::path dest)
Rename src to dest.
std::function< FILE *(const fs::path &, const char *)> FopenFn
static const uint64_t MEMPOOL_DUMP_VERSION_NO_XOR_KEY
static const uint64_t MEMPOOL_DUMP_VERSION
bool LoadMempool(CTxMemPool &pool, const fs::path &load_path, Chainstate &active_chainstate, ImportMempoolOptions &&opts)
Import the file and attempt to add its contents to the mempool.
bool DumpMempool(const CTxMemPool &pool, const fs::path &dump_path, FopenFn mockable_fopen_function, bool skip_file_commit)
static constexpr TransactionSerParams TX_WITH_WITNESS
std::shared_ptr< const CTransaction > CTransactionRef
static time_point now() noexcept
Return current system time or mocked time, if set.
std::chrono::seconds expiry
std::string SysErrorString(int err)
Return system error string from errno value.
constexpr int64_t count_seconds(std::chrono::seconds t)
MempoolAcceptResult AcceptToMemoryPool(Chainstate &active_chainstate, const CTransactionRef &tx, int64_t accept_time, bool bypass_limits, bool test_accept)
Try to add a transaction to the mempool.