aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2016-10-30 23:53:38 -0700
committerPieter Wuille <pieter.wuille@gmail.com>2016-10-31 00:10:36 -0700
commit3f78562df5e86a2a0a21812047fc3a7db8cee988 (patch)
tree44ef06335547c3314542061669a18ebe7bef29c4 /src
parentced7c949e8648b727c05adccdc2a977f129ca2cd (diff)
downloadbitcoin-3f78562df5e86a2a0a21812047fc3a7db8cee988.tar.xz
Add DumpMempool and LoadMempool
Diffstat (limited to 'src')
-rw-r--r--src/init.cpp3
-rw-r--r--src/main.cpp113
-rw-r--r--src/main.h6
3 files changed, 122 insertions, 0 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 84b0108ea8..efaf821f4f 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -207,6 +207,7 @@ void Shutdown()
StopTorControl();
UnregisterNodeSignals(GetNodeSignals());
+ DumpMempool();
if (fFeeEstimatesInitialized)
{
@@ -659,6 +660,8 @@ void ThreadImport(std::vector<boost::filesystem::path> vImportFiles)
LogPrintf("Stopping after block import\n");
StartShutdown();
}
+
+ LoadMempool();
}
/** Sanity checks
diff --git a/src/main.cpp b/src/main.cpp
index ccf7efcf0d..11abc0d175 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -6935,6 +6935,119 @@ int VersionBitsTipStateSinceHeight(const Consensus::Params& params, Consensus::D
return VersionBitsStateSinceHeight(chainActive.Tip(), params, pos, versionbitscache);
}
+static const uint64_t MEMPOOL_DUMP_VERSION = 1;
+
+bool LoadMempool(void)
+{
+ int64_t nExpiryTimeout = GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60;
+ FILE* filestr = fopen((GetDataDir() / "mempool.dat").string().c_str(), "r");
+ 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 skipped = 0;
+ int64_t failed = 0;
+ int64_t nNow = GetTime();
+
+ try {
+ uint64_t version;
+ file >> version;
+ if (version != MEMPOOL_DUMP_VERSION) {
+ return false;
+ }
+ uint64_t num;
+ file >> num;
+ double prioritydummy = 0;
+ while (num--) {
+ CTransaction tx;
+ int64_t nTime;
+ int64_t nFeeDelta;
+ file >> tx;
+ file >> nTime;
+ file >> nFeeDelta;
+
+ CAmount amountdelta = nFeeDelta;
+ if (amountdelta) {
+ mempool.PrioritiseTransaction(tx.GetHash(), tx.GetHash().ToString(), prioritydummy, amountdelta);
+ }
+ CValidationState state;
+ if (nTime + nExpiryTimeout > nNow) {
+ LOCK(cs_main);
+ AcceptToMemoryPoolWithTime(mempool, state, tx, true, NULL, nTime);
+ if (state.IsValid()) {
+ ++count;
+ } else {
+ ++failed;
+ }
+ } else {
+ ++skipped;
+ }
+ }
+ std::map<uint256, CAmount> mapDeltas;
+ file >> mapDeltas;
+
+ for (const auto& i : mapDeltas) {
+ mempool.PrioritiseTransaction(i.first, i.first.ToString(), prioritydummy, i.second);
+ }
+ } 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 successes, %i failed, %i expired\n", count, failed, skipped);
+ return true;
+}
+
+void DumpMempool(void)
+{
+ int64_t start = GetTimeMicros();
+
+ std::map<uint256, CAmount> mapDeltas;
+ std::vector<TxMempoolInfo> vinfo;
+
+ {
+ LOCK(mempool.cs);
+ for (const auto &i : mempool.mapDeltas) {
+ mapDeltas[i.first] = i.second.first;
+ }
+ vinfo = mempool.infoAll();
+ }
+
+ int64_t mid = GetTimeMicros();
+
+ try {
+ FILE* filestr = fopen((GetDataDir() / "mempool.dat.new").string().c_str(), "w");
+ if (!filestr) {
+ return;
+ }
+
+ 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)i.nTime;
+ file << (int64_t)i.nFeeDelta;
+ mapDeltas.erase(i.tx->GetHash());
+ }
+
+ file << mapDeltas;
+ FileCommit(file.Get());
+ file.fclose();
+ RenameOver(GetDataDir() / "mempool.dat.new", GetDataDir() / "mempool.dat");
+ int64_t last = GetTimeMicros();
+ LogPrintf("Dumped mempool: %gs to copy, %gs to dump\n", (mid-start)*0.000001, (last-mid)*0.000001);
+ } catch (const std::exception& e) {
+ LogPrintf("Failed to dump mempool: %s. Continuing anyway.\n", e.what());
+ }
+}
+
class CMainCleanup
{
public:
diff --git a/src/main.h b/src/main.h
index 5a3af52fed..4c6af95142 100644
--- a/src/main.h
+++ b/src/main.h
@@ -533,6 +533,12 @@ static const unsigned int REJECT_ALREADY_KNOWN = 0x101;
/** Transaction conflicts with a transaction already known */
static const unsigned int REJECT_CONFLICT = 0x102;
+/** Dump the mempool to disk. */
+void DumpMempool();
+
+/** Load the mempool from disk. */
+bool LoadMempool();
+
// The following things handle network-processing logic
// (and should be moved to a separate file)