@@ -1135,7 +1135,7 @@ std::string FormatStateMessage(const CValidationState &state)
1135
1135
}
1136
1136
1137
1137
bool AcceptToMemoryPoolWorker (CTxMemPool& pool, CValidationState& state, const CTransaction& tx, bool fLimitFree ,
1138
- bool * pfMissingInputs, bool fOverrideMempoolLimit , const CAmount& nAbsurdFee,
1138
+ bool * pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit , const CAmount& nAbsurdFee,
1139
1139
std::vector<uint256>& vHashTxnToUncache)
1140
1140
{
1141
1141
const uint256 hash = tx.GetHash ();
@@ -1308,7 +1308,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
1308
1308
}
1309
1309
}
1310
1310
1311
- CTxMemPoolEntry entry (tx, nFees, GetTime () , dPriority, chainActive.Height (), pool.HasNoInputsOf (tx), inChainInputValue, fSpendsCoinbase , nSigOpsCost, lp);
1311
+ CTxMemPoolEntry entry (tx, nFees, nAcceptTime , dPriority, chainActive.Height (), pool.HasNoInputsOf (tx), inChainInputValue, fSpendsCoinbase , nSigOpsCost, lp);
1312
1312
unsigned int nSize = entry.GetTxSize ();
1313
1313
1314
1314
// Check that the transaction doesn't have an excessive number of
@@ -1572,18 +1572,24 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C
1572
1572
return true ;
1573
1573
}
1574
1574
1575
- bool AcceptToMemoryPool (CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree ,
1576
- bool * pfMissingInputs, bool fOverrideMempoolLimit , const CAmount nAbsurdFee)
1575
+ bool AcceptToMemoryPoolWithTime (CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree ,
1576
+ bool * pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit , const CAmount nAbsurdFee)
1577
1577
{
1578
1578
std::vector<uint256> vHashTxToUncache;
1579
- bool res = AcceptToMemoryPoolWorker (pool, state, tx, fLimitFree , pfMissingInputs, fOverrideMempoolLimit , nAbsurdFee, vHashTxToUncache);
1579
+ bool res = AcceptToMemoryPoolWorker (pool, state, tx, fLimitFree , pfMissingInputs, nAcceptTime, fOverrideMempoolLimit , nAbsurdFee, vHashTxToUncache);
1580
1580
if (!res) {
1581
1581
BOOST_FOREACH (const uint256& hashTx, vHashTxToUncache)
1582
1582
pcoinsTip->Uncache (hashTx);
1583
1583
}
1584
1584
return res;
1585
1585
}
1586
1586
1587
+ bool AcceptToMemoryPool (CTxMemPool& pool, CValidationState &state, const CTransaction &tx, bool fLimitFree ,
1588
+ bool * pfMissingInputs, bool fOverrideMempoolLimit , const CAmount nAbsurdFee)
1589
+ {
1590
+ return AcceptToMemoryPoolWithTime (pool, state, tx, fLimitFree , pfMissingInputs, GetTime (), fOverrideMempoolLimit , nAbsurdFee);
1591
+ }
1592
+
1587
1593
/* * Return transaction in txOut, and if it was found inside a block, its hash is placed in hashBlock */
1588
1594
bool GetTransaction (const uint256 &hash, CTransaction &txOut, const Consensus::Params& consensusParams, uint256 &hashBlock, bool fAllowSlow )
1589
1595
{
@@ -6929,6 +6935,119 @@ int VersionBitsTipStateSinceHeight(const Consensus::Params& params, Consensus::D
6929
6935
return VersionBitsStateSinceHeight (chainActive.Tip (), params, pos, versionbitscache);
6930
6936
}
6931
6937
6938
+ static const uint64_t MEMPOOL_DUMP_VERSION = 1 ;
6939
+
6940
+ bool LoadMempool (void )
6941
+ {
6942
+ int64_t nExpiryTimeout = GetArg (" -mempoolexpiry" , DEFAULT_MEMPOOL_EXPIRY) * 60 * 60 ;
6943
+ FILE* filestr = fopen ((GetDataDir () / " mempool.dat" ).string ().c_str (), " r" );
6944
+ CAutoFile file (filestr, SER_DISK, CLIENT_VERSION);
6945
+ if (file.IsNull ()) {
6946
+ LogPrintf (" Failed to open mempool file from disk. Continuing anyway.\n " );
6947
+ return false ;
6948
+ }
6949
+
6950
+ int64_t count = 0 ;
6951
+ int64_t skipped = 0 ;
6952
+ int64_t failed = 0 ;
6953
+ int64_t nNow = GetTime ();
6954
+
6955
+ try {
6956
+ uint64_t version;
6957
+ file >> version;
6958
+ if (version != MEMPOOL_DUMP_VERSION) {
6959
+ return false ;
6960
+ }
6961
+ uint64_t num;
6962
+ file >> num;
6963
+ double prioritydummy = 0 ;
6964
+ while (num--) {
6965
+ CTransaction tx;
6966
+ int64_t nTime;
6967
+ int64_t nFeeDelta;
6968
+ file >> tx;
6969
+ file >> nTime;
6970
+ file >> nFeeDelta;
6971
+
6972
+ CAmount amountdelta = nFeeDelta;
6973
+ if (amountdelta) {
6974
+ mempool.PrioritiseTransaction (tx.GetHash (), tx.GetHash ().ToString (), prioritydummy, amountdelta);
6975
+ }
6976
+ CValidationState state;
6977
+ if (nTime + nExpiryTimeout > nNow) {
6978
+ LOCK (cs_main);
6979
+ AcceptToMemoryPoolWithTime (mempool, state, tx, true , NULL , nTime);
6980
+ if (state.IsValid ()) {
6981
+ ++count;
6982
+ } else {
6983
+ ++failed;
6984
+ }
6985
+ } else {
6986
+ ++skipped;
6987
+ }
6988
+ }
6989
+ std::map<uint256, CAmount> mapDeltas;
6990
+ file >> mapDeltas;
6991
+
6992
+ for (const auto & i : mapDeltas) {
6993
+ mempool.PrioritiseTransaction (i.first , i.first .ToString (), prioritydummy, i.second );
6994
+ }
6995
+ } catch (const std::exception& e) {
6996
+ LogPrintf (" Failed to deserialize mempool data on disk: %s. Continuing anyway.\n " , e.what ());
6997
+ return false ;
6998
+ }
6999
+
7000
+ LogPrintf (" Imported mempool transactions from disk: %i successes, %i failed, %i expired\n " , count, failed, skipped);
7001
+ return true ;
7002
+ }
7003
+
7004
+ void DumpMempool (void )
7005
+ {
7006
+ int64_t start = GetTimeMicros ();
7007
+
7008
+ std::map<uint256, CAmount> mapDeltas;
7009
+ std::vector<TxMempoolInfo> vinfo;
7010
+
7011
+ {
7012
+ LOCK (mempool.cs );
7013
+ for (const auto &i : mempool.mapDeltas ) {
7014
+ mapDeltas[i.first ] = i.second .first ;
7015
+ }
7016
+ vinfo = mempool.infoAll ();
7017
+ }
7018
+
7019
+ int64_t mid = GetTimeMicros ();
7020
+
7021
+ try {
7022
+ FILE* filestr = fopen ((GetDataDir () / " mempool.dat.new" ).string ().c_str (), " w" );
7023
+ if (!filestr) {
7024
+ return ;
7025
+ }
7026
+
7027
+ CAutoFile file (filestr, SER_DISK, CLIENT_VERSION);
7028
+
7029
+ uint64_t version = MEMPOOL_DUMP_VERSION;
7030
+ file << version;
7031
+
7032
+ file << (uint64_t )vinfo.size ();
7033
+ for (const auto & i : vinfo) {
7034
+ file << *(i.tx );
7035
+ file << (int64_t )i.nTime ;
7036
+ file << (int64_t )i.nFeeDelta ;
7037
+ mapDeltas.erase (i.tx ->GetHash ());
7038
+ }
7039
+
7040
+ file << mapDeltas;
7041
+ FileCommit (file.Get ());
7042
+ file.fclose ();
7043
+ RenameOver (GetDataDir () / " mempool.dat.new" , GetDataDir () / " mempool.dat" );
7044
+ int64_t last = GetTimeMicros ();
7045
+ LogPrintf (" Dumped mempool: %gs to copy, %gs to dump\n " , (mid-start)*0.000001 , (last-mid)*0.000001 );
7046
+ } catch (const std::exception& e) {
7047
+ LogPrintf (" Failed to dump mempool: %s. Continuing anyway.\n " , e.what ());
7048
+ }
7049
+ }
7050
+
6932
7051
class CMainCleanup
6933
7052
{
6934
7053
public:
0 commit comments