Skip to content

Commit 1aa97ee

Browse files
author
Lawrence Nahum
committed
Add savemempool RPC
1 parent 467cbbc commit 1aa97ee

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/rpc/blockchain.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,25 @@ UniValue getchaintxstats(const JSONRPCRequest& request)
15321532
return ret;
15331533
}
15341534

1535+
UniValue savemempool(const JSONRPCRequest& request)
1536+
{
1537+
if (request.fHelp || request.params.size() != 0) {
1538+
throw std::runtime_error(
1539+
"savemempool\n"
1540+
"\nDumps the mempool to disk.\n"
1541+
"\nExamples:\n"
1542+
+ HelpExampleCli("savemempool", "")
1543+
+ HelpExampleRpc("savemempool", "")
1544+
);
1545+
}
1546+
1547+
if (!DumpMempool()) {
1548+
throw JSONRPCError(RPC_MISC_ERROR, "Unable to dump mempool to disk");
1549+
}
1550+
1551+
return NullUniValue;
1552+
}
1553+
15351554
static const CRPCCommand commands[] =
15361555
{ // category name actor (function) argNames
15371556
// --------------------- ------------------------ ----------------------- ----------
@@ -1552,6 +1571,7 @@ static const CRPCCommand commands[] =
15521571
{ "blockchain", "gettxout", &gettxout, {"txid","n","include_mempool"} },
15531572
{ "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, {} },
15541573
{ "blockchain", "pruneblockchain", &pruneblockchain, {"height"} },
1574+
{ "blockchain", "savemempool", &savemempool, {} },
15551575
{ "blockchain", "verifychain", &verifychain, {"checklevel","nblocks"} },
15561576

15571577
{ "blockchain", "preciousblock", &preciousblock, {"blockhash"} },

test/functional/mempool_persist.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,14 @@
2828
- Restart node0 with -persistmempool. Verify that it has 5
2929
transactions in its mempool. This tests that -persistmempool=0
3030
does not overwrite a previously valid mempool stored on disk.
31+
- Remove node0 mempool.dat and verify savemempool RPC recreates it
32+
and verify that node1 can load it and has 5 transaction in its
33+
mempool.
34+
- Verify that savemempool throws when the RPC is called if
35+
node1 can't write to disk.
3136
3237
"""
38+
import os
3339
import time
3440

3541
from test_framework.test_framework import BitcoinTestFramework
@@ -78,5 +84,27 @@ def run_test(self):
7884
self.start_node(0)
7985
wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5)
8086

87+
mempooldat0 = os.path.join(self.options.tmpdir, 'node0', 'regtest', 'mempool.dat')
88+
mempooldat1 = os.path.join(self.options.tmpdir, 'node1', 'regtest', 'mempool.dat')
89+
self.log.debug("Remove the mempool.dat file. Verify that savemempool to disk via RPC re-creates it")
90+
os.remove(mempooldat0)
91+
self.nodes[0].savemempool()
92+
assert os.path.isfile(mempooldat0)
93+
94+
self.log.debug("Stop nodes, make node1 use mempool.dat from node0. Verify it has 5 transactions")
95+
os.rename(mempooldat0, mempooldat1)
96+
self.stop_nodes()
97+
self.start_node(1, extra_args=[])
98+
wait_until(lambda: len(self.nodes[1].getrawmempool()) == 5)
99+
100+
self.log.debug("Prevent bitcoind from writing mempool.dat to disk. Verify that `savemempool` fails")
101+
# to test the exception we are setting bad permissions on a tmp file called mempool.dat.new
102+
# which is an implementation detail that could change and break this test
103+
mempooldotnew1 = mempooldat1 + '.new'
104+
with os.fdopen(os.open(mempooldotnew1, os.O_CREAT, 0o000), 'w'):
105+
pass
106+
assert_raises_jsonrpc(-1, "Unable to dump mempool to disk", self.nodes[1].savemempool)
107+
os.remove(mempooldotnew1)
108+
81109
if __name__ == '__main__':
82110
MempoolPersistTest().main()

0 commit comments

Comments
 (0)