2 # Copyright (c) 2018 The Zcash developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 from test_framework.test_framework import BitcoinTestFramework
7 from test_framework.util import (
8 assert_equal, assert_true,
9 start_nodes, stop_nodes,
10 initialize_chain_clean, connect_nodes_bi, wait_bitcoinds,
11 wait_and_assert_operationid_status
13 from decimal import Decimal
15 class WalletPersistenceTest (BitcoinTestFramework):
17 def setup_chain(self):
18 print("Initializing test directory " + self.options.tmpdir)
19 initialize_chain_clean(self.options.tmpdir, 3)
21 def setup_network(self, split=False):
22 self.nodes = start_nodes(3, self.options.tmpdir,
24 '-nuparams=5ba81b19:100', # Overwinter
25 '-nuparams=76b809bb:201', # Sapling
27 connect_nodes_bi(self.nodes,0,1)
28 connect_nodes_bi(self.nodes,1,2)
29 self.is_network_split=False
33 # Sanity-check the test harness
34 self.nodes[0].generate(200)
35 assert_equal(self.nodes[0].getblockcount(), 200)
38 # Verify Sapling address is persisted in wallet (even when Sapling is not yet active)
39 sapling_addr = self.nodes[0].z_getnewaddress('sapling')
41 # Make sure the node has the addresss
42 addresses = self.nodes[0].z_listaddresses()
43 assert_true(sapling_addr in addresses, "Should contain address before restart")
46 stop_nodes(self.nodes)
50 # Make sure we still have the address after restarting
51 addresses = self.nodes[0].z_listaddresses()
52 assert_true(sapling_addr in addresses, "Should contain address after restart")
55 self.nodes[0].generate(1)
58 # Node 0 shields funds to Sapling address
59 taddr0 = self.nodes[0].getnewaddress()
61 recipients.append({"address": sapling_addr, "amount": Decimal('20')})
62 myopid = self.nodes[0].z_sendmany(taddr0, recipients, 1, 0)
63 wait_and_assert_operationid_status(self.nodes[0], myopid)
66 self.nodes[0].generate(1)
69 # Verify shielded balance
70 assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('20'))
73 stop_nodes(self.nodes)
77 # Node 0 sends some shielded funds to Node 1
78 dest_addr = self.nodes[1].z_getnewaddress('sapling')
80 recipients.append({"address": dest_addr, "amount": Decimal('15')})
81 myopid = self.nodes[0].z_sendmany(sapling_addr, recipients, 1, 0)
82 wait_and_assert_operationid_status(self.nodes[0], myopid)
85 self.nodes[0].generate(1)
89 assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('5'))
90 assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('15'))
93 stop_nodes(self.nodes)
98 assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('5'))
99 assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('15'))
101 # Verify importing a spending key will update and persist the nullifiers and witnesses correctly
102 sk0 = self.nodes[0].z_exportkey(sapling_addr)
103 self.nodes[2].z_importkey(sk0, "yes")
104 assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('5'))
107 stop_nodes(self.nodes)
111 # Verify nullifiers persisted correctly by checking balance
112 # Prior to PR #3590, there will be an error as spent notes are considered unspent:
113 # Assertion failed: expected: <25.00000000> but was: <5>
114 assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('5'))
116 # Verity witnesses persisted correctly by sending shielded funds
118 recipients.append({"address": dest_addr, "amount": Decimal('1')})
119 myopid = self.nodes[2].z_sendmany(sapling_addr, recipients, 1, 0)
120 wait_and_assert_operationid_status(self.nodes[2], myopid)
123 self.nodes[0].generate(1)
127 assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('4'))
128 assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('16'))
130 if __name__ == '__main__':
131 WalletPersistenceTest().main()