Add DumpMempool and LoadMempool

pull/308/head
Pieter Wuille 8 years ago
parent ced7c949e8
commit 3f78562df5

@ -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

@ -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:

@ -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)

Loading…
Cancel
Save