15 #include <txmempool.h> 22 #include <util/time.h> 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());
std::shared_ptr< const CTransaction > CTransactionRef
std::vector< B > randbytes(size_t len) noexcept
Generate random bytes.
void AddUnbroadcastTx(const Txid &txid)
Adds a transaction to the unbroadcast set.
constexpr int64_t count_seconds(std::chrono::seconds t)
std::vector< TxMempoolInfo > infoAll() const
CTransactionRef get(const Txid &hash) const
static const uint64_t MEMPOOL_DUMP_VERSION_NO_XOR_KEY
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.
std::chrono::seconds expiry
Non-refcounted RAII wrapper for FILE*.
static constexpr size_t KEY_SIZE
void PrioritiseTransaction(const Txid &hash, const CAmount &nFeeDelta)
Affect CreateNewBlock prioritisation of transactions.
std::set< Txid > GetUnbroadcastTxs() const
Returns transactions in unbroadcast set.
const util::SignalInterrupt & m_interrupt
bool DumpMempool(const CTxMemPool &pool, const fs::path &dump_path, FopenFn mockable_fopen_function, bool skip_file_commit)
bool RenameOver(fs::path src, fs::path dest)
Rename src to dest.
std::string SysErrorString(int err)
Return system error string from errno value.
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.
int64_t CAmount
Amount in satoshis (Can be negative)
std::function< FILE *(const fs::path &, const char *)> FopenFn
ChainstateManager & m_chainman
The chainstate manager that owns this chainstate.
Chainstate stores and provides an API to update our local knowledge of the current best chain...
bool exists(const Txid &txid) const
static const uint64_t MEMPOOL_DUMP_VERSION
static time_point now() noexcept
Return current system time or mocked time, if set.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
static std::string PathToString(const path &path)
Convert path object to a byte string.
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it...
static constexpr TransactionSerParams TX_WITH_WITNESS