| 4980 | static const uint64_t MEMPOOL_DUMP_VERSION = 1; |
| 4981 | |
| 4982 | bool LoadMempool(CTxMemPool& pool, CChainState& active_chainstate, FopenFn mockable_fopen_function) |
| 4983 | { |
| 4984 | int64_t nExpiryTimeout = gArgs.GetIntArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60; |
| 4985 | FILE* filestr{mockable_fopen_function(gArgs.GetDataDirNet() / "mempool.dat", "rb")}; |
| 4986 | CAutoFile file(filestr, SER_DISK, CLIENT_VERSION); |
| 4987 | if (file.IsNull()) { |
| 4988 | LogPrintf("Failed to open mempool file from disk. Continuing anyway.\n"); |
| 4989 | return false; |
| 4990 | } |
| 4991 | |
| 4992 | int64_t count = 0; |
| 4993 | int64_t expired = 0; |
| 4994 | int64_t failed = 0; |
| 4995 | int64_t already_there = 0; |
| 4996 | int64_t unbroadcast = 0; |
| 4997 | int64_t nNow = GetTime(); |
| 4998 | |
| 4999 | try { |
| 5000 | uint64_t version; |
| 5001 | file >> version; |
| 5002 | if (version != MEMPOOL_DUMP_VERSION) { |
| 5003 | return false; |
| 5004 | } |
| 5005 | uint64_t num; |
| 5006 | file >> num; |
| 5007 | while (num) { |
| 5008 | --num; |
| 5009 | CTransactionRef tx; |
| 5010 | int64_t nTime; |
| 5011 | int64_t nFeeDelta; |
| 5012 | file >> tx; |
| 5013 | file >> nTime; |
| 5014 | file >> nFeeDelta; |
| 5015 | |
| 5016 | CAmount amountdelta = nFeeDelta; |
| 5017 | if (amountdelta) { |
| 5018 | pool.PrioritiseTransaction(tx->GetHash(), amountdelta); |
| 5019 | } |
| 5020 | if (nTime > nNow - nExpiryTimeout) { |
| 5021 | LOCK(cs_main); |
| 5022 | const auto& accepted = AcceptToMemoryPool(active_chainstate, tx, nTime, /*bypass_limits=*/false, /*test_accept=*/false); |
| 5023 | if (accepted.m_result_type == MempoolAcceptResult::ResultType::VALID) { |
| 5024 | ++count; |
| 5025 | } else { |
| 5026 | // mempool may contain the transaction already, e.g. from |
| 5027 | // wallet(s) having loaded it while we were processing |
| 5028 | // mempool transactions; consider these as valid, instead of |
| 5029 | // failed, but mark them as 'already there' |
| 5030 | if (pool.exists(GenTxid::Txid(tx->GetHash()))) { |
| 5031 | ++already_there; |
| 5032 | } else { |
| 5033 | ++failed; |
| 5034 | } |
| 5035 | } |
| 5036 | } else { |
| 5037 | ++expired; |
| 5038 | } |
| 5039 | if (ShutdownRequested()) |