Browse Source

[wallet] fix zapwallettxes interaction with persistent mempool

zapwallettxes previously did not interact well with persistent mempool.
zapwallettxes would cause wallet transactions to be zapped, but they
would then be reloaded from the mempool on startup. This commit softsets
persistmempool to false if zapwallettxes is enabled so transactions are
actually zapped.
0.15
John Newbery 8 years ago
parent
commit
e7a2181b49
  1. 5
      src/wallet/wallet.cpp
  2. 78
      test/functional/zapwallettxes.py

5
src/wallet/wallet.cpp

@ -4043,6 +4043,11 @@ bool CWallet::ParameterInteraction()
} }
} }
// -zapwallettx implies dropping the mempool on startup
if (GetBoolArg("-zapwallettxes", false) && SoftSetBoolArg("-persistmempool", false)) {
LogPrintf("%s: parameter interaction: -zapwallettxes=<mode> -> setting -persistmempool=0\n", __func__);
}
// -zapwallettx implies a rescan // -zapwallettx implies a rescan
if (GetBoolArg("-zapwallettxes", false)) { if (GetBoolArg("-zapwallettxes", false)) {
if (is_multiwallet) { if (is_multiwallet) {

78
test/functional/zapwallettxes.py

@ -4,20 +4,19 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php. # file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test the zapwallettxes functionality. """Test the zapwallettxes functionality.
- start three bitcoind nodes - start two bitcoind nodes
- create four transactions on node 0 - two are confirmed and two are - create two transactions on node 0 - one is confirmed and one is unconfirmed.
unconfirmed. - restart node 0 and verify that both the confirmed and the unconfirmed
- restart node 1 and verify that both the confirmed and the unconfirmed
transactions are still available. transactions are still available.
- restart node 0 and verify that the confirmed transactions are still - restart node 0 with zapwallettxes and persistmempool, and verify that both
available, but that the unconfirmed transaction has been zapped. the confirmed and the unconfirmed transactions are still available.
- restart node 0 with just zapwallettxed and verify that the confirmed
transactions are still available, but that the unconfirmed transaction has
been zapped.
""" """
from test_framework.test_framework import BitcoinTestFramework from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (assert_equal, from test_framework.util import (assert_equal,
assert_raises, assert_raises_jsonrpc,
bitcoind_processes,
connect_nodes_bi,
JSONRPCException,
) )
class ZapWalletTXesTest (BitcoinTestFramework): class ZapWalletTXesTest (BitcoinTestFramework):
@ -25,60 +24,53 @@ class ZapWalletTXesTest (BitcoinTestFramework):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.setup_clean_chain = True self.setup_clean_chain = True
self.num_nodes = 3 self.num_nodes = 2
def setup_network(self):
super().setup_network()
connect_nodes_bi(self.nodes, 0, 2)
def run_test(self): def run_test(self):
self.log.info("Mining blocks...") self.log.info("Mining blocks...")
self.nodes[0].generate(1) self.nodes[0].generate(1)
self.sync_all() self.sync_all()
self.nodes[1].generate(101) self.nodes[1].generate(100)
self.sync_all() self.sync_all()
assert_equal(self.nodes[0].getbalance(), 50) # This transaction will be confirmed
txid1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 10)
txid0 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11)
txid1 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10)
self.sync_all()
self.nodes[0].generate(1) self.nodes[0].generate(1)
self.sync_all() self.sync_all()
txid2 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) # This transaction will not be confirmed
txid3 = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) txid2 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 20)
tx0 = self.nodes[0].gettransaction(txid0)
assert_equal(tx0['txid'], txid0) # tx0 must be available (confirmed)
tx1 = self.nodes[0].gettransaction(txid1) # Confirmed and unconfirmed transactions are now in the wallet.
assert_equal(tx1['txid'], txid1) # tx1 must be available (confirmed) assert_equal(self.nodes[0].gettransaction(txid1)['txid'], txid1)
assert_equal(self.nodes[0].gettransaction(txid2)['txid'], txid2)
tx2 = self.nodes[0].gettransaction(txid2) # Stop-start node0. Both confirmed and unconfirmed transactions remain in the wallet.
assert_equal(tx2['txid'], txid2) # tx2 must be available (unconfirmed)
tx3 = self.nodes[0].gettransaction(txid3)
assert_equal(tx3['txid'], txid3) # tx3 must be available (unconfirmed)
#restart bitcoind
self.stop_node(0) self.stop_node(0)
self.nodes[0] = self.start_node(0,self.options.tmpdir) self.nodes[0] = self.start_node(0, self.options.tmpdir)
tx3 = self.nodes[0].gettransaction(txid3) assert_equal(self.nodes[0].gettransaction(txid1)['txid'], txid1)
assert_equal(tx3['txid'], txid3) # tx must be available (unconfirmed) assert_equal(self.nodes[0].gettransaction(txid2)['txid'], txid2)
# Stop node0 and restart with zapwallettxes and persistmempool. The unconfirmed
# transaction is zapped from the wallet, but is re-added when the mempool is reloaded.
self.stop_node(0) self.stop_node(0)
self.nodes[0] = self.start_node(0, self.options.tmpdir, ["-persistmempool=1", "-zapwallettxes=2"])
#restart bitcoind with zapwallettxes assert_equal(self.nodes[0].gettransaction(txid1)['txid'], txid1)
self.nodes[0] = self.start_node(0,self.options.tmpdir, ["-zapwallettxes=1"]) assert_equal(self.nodes[0].gettransaction(txid2)['txid'], txid2)
assert_raises(JSONRPCException, self.nodes[0].gettransaction, [txid3]) # Stop node0 and restart with zapwallettxes, but not persistmempool.
# there must be an exception because the unconfirmed wallettx0 must be gone by now # The unconfirmed transaction is zapped and is no longer in the wallet.
self.stop_node(0)
self.nodes[0] = self.start_node(0, self.options.tmpdir, ["-zapwallettxes=2"])
tx0 = self.nodes[0].gettransaction(txid0) # tx1 is still be available because it was confirmed
assert_equal(tx0['txid'], txid0) # tx0 (confirmed) must still be available because it was confirmed assert_equal(self.nodes[0].gettransaction(txid1)['txid'], txid1)
# This will raise an exception because the unconfirmed transaction has been zapped
assert_raises_jsonrpc(-5, 'Invalid or non-wallet transaction id', self.nodes[0].gettransaction, txid2)
if __name__ == '__main__': if __name__ == '__main__':
ZapWalletTXesTest().main() ZapWalletTXesTest().main()

Loading…
Cancel
Save