]> Git Repo - VerusCoin.git/blob - qa/rpc-tests/wallet_shieldcoinbase.py
Fix an issue where qa test wallet_shieldcoinbase could hang.
[VerusCoin.git] / qa / rpc-tests / wallet_shieldcoinbase.py
1 #!/usr/bin/env python2
2 # Copyright (c) 2017 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.
5
6 from test_framework.test_framework import BitcoinTestFramework
7 from test_framework.authproxy import JSONRPCException
8 from test_framework.util import assert_equal, initialize_chain_clean, \
9     start_node, connect_nodes_bi, sync_blocks, sync_mempools
10
11 import time
12 from decimal import Decimal
13
14 class WalletShieldCoinbaseTest (BitcoinTestFramework):
15
16     def setup_chain(self):
17         print("Initializing test directory "+self.options.tmpdir)
18         initialize_chain_clean(self.options.tmpdir, 4)
19
20     def setup_network(self, split=False):
21         args = ['-regtestprotectcoinbase', '-debug=zrpcunsafe']
22         self.nodes = []
23         self.nodes.append(start_node(0, self.options.tmpdir, args))
24         self.nodes.append(start_node(1, self.options.tmpdir, args))
25         args2 = ['-regtestprotectcoinbase', '-debug=zrpcunsafe', "-mempooltxinputlimit=7"]
26         self.nodes.append(start_node(2, self.options.tmpdir, args2))
27         connect_nodes_bi(self.nodes,0,1)
28         connect_nodes_bi(self.nodes,1,2)
29         connect_nodes_bi(self.nodes,0,2)
30         self.is_network_split=False
31         self.sync_all()
32
33     # Returns txid if operation was a success or None
34     def wait_and_assert_operationid_status(self, nodeid, myopid, in_status='success', in_errormsg=None):
35         print('waiting for async operation {}'.format(myopid))
36         opids = []
37         opids.append(myopid)
38         timeout = 300
39         status = None
40         errormsg = None
41         txid = None
42         for x in xrange(1, timeout):
43             results = self.nodes[nodeid].z_getoperationresult(opids)
44             if len(results)==0:
45                 time.sleep(1)
46             else:
47                 status = results[0]["status"]
48                 if status == "failed":
49                     errormsg = results[0]['error']['message']
50                 elif status == "success":
51                     txid = results[0]['result']['txid']
52                 break
53         print('...returned status: {}'.format(status))
54         assert_equal(in_status, status)
55         if errormsg is not None:
56             assert(in_errormsg is not None)
57             assert_equal(in_errormsg in errormsg, True)
58             print('...returned error: {}'.format(errormsg))
59         return txid
60
61     def run_test (self):
62         print "Mining blocks..."
63
64         self.nodes[0].generate(1)
65         do_not_shield_taddr = self.nodes[0].getnewaddress()
66
67         self.nodes[0].generate(4)
68         walletinfo = self.nodes[0].getwalletinfo()
69         assert_equal(walletinfo['immature_balance'], 50)
70         assert_equal(walletinfo['balance'], 0)
71         self.sync_all()
72         self.nodes[2].generate(1)
73         self.nodes[2].getnewaddress()
74         self.nodes[2].generate(1)
75         self.nodes[2].getnewaddress()
76         self.nodes[2].generate(1)
77         self.sync_all()
78         self.nodes[1].generate(101)
79         self.sync_all()
80         assert_equal(self.nodes[0].getbalance(), 50)
81         assert_equal(self.nodes[1].getbalance(), 10)
82         assert_equal(self.nodes[2].getbalance(), 30)
83
84         # Prepare to send taddr->zaddr
85         mytaddr = self.nodes[0].getnewaddress()
86         myzaddr = self.nodes[0].z_getnewaddress()
87
88         # Shielding will fail when trying to spend from watch-only address
89         self.nodes[2].importaddress(mytaddr)
90         try:
91             self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr)
92         except JSONRPCException,e:
93             errorString = e.error['message']
94         assert_equal("Could not find any coinbase funds to shield" in errorString, True)
95
96         # Shielding will fail because fee is negative
97         try:
98             self.nodes[0].z_shieldcoinbase("*", myzaddr, -1)
99         except JSONRPCException,e:
100             errorString = e.error['message']
101         assert_equal("Amount out of range" in errorString, True)
102
103         # Shielding will fail because fee is larger than MAX_MONEY
104         try:
105             self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('21000000.00000001'))
106         except JSONRPCException,e:
107             errorString = e.error['message']
108         assert_equal("Amount out of range" in errorString, True)
109
110         # Shielding will fail because fee is larger than sum of utxos
111         try:
112             self.nodes[0].z_shieldcoinbase("*", myzaddr, 999)
113         except JSONRPCException,e:
114             errorString = e.error['message']
115         assert_equal("Insufficient coinbase funds" in errorString, True)
116
117         # Shielding will fail because limit parameter must be at least 0
118         try:
119             self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('0.001'), -1)
120         except JSONRPCException,e:
121             errorString = e.error['message']
122         assert_equal("Limit on maximum number of utxos cannot be negative" in errorString, True)
123
124         # Shielding will fail because limit parameter is absurdly large
125         try:
126             self.nodes[0].z_shieldcoinbase("*", myzaddr, Decimal('0.001'), 99999999999999)
127         except JSONRPCException,e:
128             errorString = e.error['message']
129         assert_equal("JSON integer out of range" in errorString, True)
130
131         # Shield coinbase utxos from node 0 of value 40, standard fee of 0.00010000
132         result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr)
133         self.wait_and_assert_operationid_status(0, result['opid'])
134         self.sync_all()
135         self.nodes[1].generate(1)
136         self.sync_all()
137
138         # Confirm balances and that do_not_shield_taddr containing funds of 10 was left alone
139         assert_equal(self.nodes[0].getbalance(), 10)
140         assert_equal(self.nodes[0].z_getbalance(do_not_shield_taddr), Decimal('10.0'))
141         assert_equal(self.nodes[0].z_getbalance(myzaddr), Decimal('39.99990000'))
142         assert_equal(self.nodes[1].getbalance(), 20)
143         assert_equal(self.nodes[2].getbalance(), 30)
144
145         # Shield coinbase utxos from any node 2 taddr, and set fee to 0
146         result = self.nodes[2].z_shieldcoinbase("*", myzaddr, 0)
147         self.wait_and_assert_operationid_status(2, result['opid'])
148         self.sync_all()
149         self.nodes[1].generate(1)
150         self.sync_all()
151
152         assert_equal(self.nodes[0].getbalance(), 10)
153         assert_equal(self.nodes[0].z_getbalance(myzaddr), Decimal('69.99990000'))
154         assert_equal(self.nodes[1].getbalance(), 30)
155         assert_equal(self.nodes[2].getbalance(), 0)
156
157         # Generate 800 coinbase utxos on node 0, and 20 coinbase utxos on node 2
158         self.nodes[0].generate(800)
159         self.sync_all()
160         self.nodes[2].generate(20)
161         self.sync_all()
162         self.nodes[1].generate(100)
163         self.sync_all()
164         mytaddr = self.nodes[0].getnewaddress()
165
166         # Shielding the 800 utxos will occur over two transactions, since max tx size is 100,000 bytes.
167         # We don't verify shieldingValue as utxos are not selected in any specific order, so value can change on each test run.
168         # We set an unrealistically high limit parameter of 99999, to verify that max tx size will constrain the number of utxos.
169         result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 99999)
170         assert_equal(result["shieldingUTXOs"], Decimal('662'))
171         assert_equal(result["remainingUTXOs"], Decimal('138'))
172         remainingValue = result["remainingValue"]
173         opid1 = result['opid']
174
175         # Verify that utxos are locked (not available for selection) by queuing up another shielding operation
176         result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 0)
177         assert_equal(result["shieldingValue"], Decimal(remainingValue))
178         assert_equal(result["shieldingUTXOs"], Decimal('138'))
179         assert_equal(result["remainingValue"], Decimal('0'))
180         assert_equal(result["remainingUTXOs"], Decimal('0'))
181         opid2 = result['opid']
182
183         # wait for both aysnc operations to complete
184         self.wait_and_assert_operationid_status(0, opid1)
185         self.wait_and_assert_operationid_status(0, opid2)
186
187         # sync_all() invokes sync_mempool() but node 2's mempool limit will cause tx1 and tx2 to be rejected.
188         # So instead, we sync on blocks and mempool for node 0 and node 1, and after a new block is generated
189         # which mines tx1 and tx2, all nodes will have an empty mempool which can then be synced.
190         sync_blocks(self.nodes[:2])
191         sync_mempools(self.nodes[:2])
192         self.nodes[1].generate(1)
193         self.sync_all()
194
195         # Verify maximum number of utxos which node 2 can shield is limited by option -mempooltxinputlimit
196         # This option is used when the limit parameter is set to 0.
197         mytaddr = self.nodes[2].getnewaddress()
198         result = self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 0)
199         assert_equal(result["shieldingUTXOs"], Decimal('7'))
200         assert_equal(result["remainingUTXOs"], Decimal('13'))
201         self.wait_and_assert_operationid_status(2, result['opid'])
202         self.sync_all()
203         self.nodes[1].generate(1)
204         self.sync_all()
205
206         # Verify maximum number of utxos which node 0 can shield is set by default limit parameter of 50
207         self.nodes[0].generate(200)
208         self.sync_all()
209         mytaddr = self.nodes[0].getnewaddress()
210         result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'))
211         assert_equal(result["shieldingUTXOs"], Decimal('50'))
212         assert_equal(result["remainingUTXOs"], Decimal('50'))
213         self.wait_and_assert_operationid_status(0, result['opid'])
214
215         # Verify maximum number of utxos which node 0 can shield can be set by the limit parameter
216         result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 33)
217         assert_equal(result["shieldingUTXOs"], Decimal('33'))
218         assert_equal(result["remainingUTXOs"], Decimal('17'))
219         self.wait_and_assert_operationid_status(0, result['opid'])
220         # Don't sync node 2 which rejects the tx due to its mempooltxinputlimit
221         sync_blocks(self.nodes[:2])
222         sync_mempools(self.nodes[:2])
223         self.nodes[1].generate(1)
224         self.sync_all()
225
226 if __name__ == '__main__':
227     WalletShieldCoinbaseTest().main()
This page took 0.039217 seconds and 4 git commands to generate.