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'))
72 # Verify size of shielded pools
73 pools = self.nodes[0].getblockchaininfo()['valuePools']
74 assert_equal(pools[0]['chainValue'], Decimal('0')) # Sprout
75 assert_equal(pools[1]['chainValue'], Decimal('20')) # Sapling
78 stop_nodes(self.nodes)
82 # Verify size of shielded pools
83 pools = self.nodes[0].getblockchaininfo()['valuePools']
84 assert_equal(pools[0]['chainValue'], Decimal('0')) # Sprout
85 assert_equal(pools[1]['chainValue'], Decimal('20')) # Sapling
87 # Node 0 sends some shielded funds to Node 1
88 dest_addr = self.nodes[1].z_getnewaddress('sapling')
90 recipients.append({"address": dest_addr, "amount": Decimal('15')})
91 myopid = self.nodes[0].z_sendmany(sapling_addr, recipients, 1, 0)
92 wait_and_assert_operationid_status(self.nodes[0], myopid)
95 self.nodes[0].generate(1)
99 assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('5'))
100 assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('15'))
103 stop_nodes(self.nodes)
108 assert_equal(self.nodes[0].z_getbalance(sapling_addr), Decimal('5'))
109 assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('15'))
111 # Verify importing a spending key will update and persist the nullifiers and witnesses correctly
112 sk0 = self.nodes[0].z_exportkey(sapling_addr)
113 self.nodes[2].z_importkey(sk0, "yes")
114 assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('5'))
117 stop_nodes(self.nodes)
121 # Verify nullifiers persisted correctly by checking balance
122 # Prior to PR #3590, there will be an error as spent notes are considered unspent:
123 # Assertion failed: expected: <25.00000000> but was: <5>
124 assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('5'))
126 # Verity witnesses persisted correctly by sending shielded funds
128 recipients.append({"address": dest_addr, "amount": Decimal('1')})
129 myopid = self.nodes[2].z_sendmany(sapling_addr, recipients, 1, 0)
130 wait_and_assert_operationid_status(self.nodes[2], myopid)
133 self.nodes[0].generate(1)
137 assert_equal(self.nodes[2].z_getbalance(sapling_addr), Decimal('4'))
138 assert_equal(self.nodes[1].z_getbalance(dest_addr), Decimal('16'))
140 if __name__ == '__main__':
141 WalletPersistenceTest().main()