zcashd/qa/rpc-tests/wallet_changeaddresses.py

94 lines
3.7 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (c) 2019 The Zcash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
connect_nodes_bi,
get_coinbase_address,
initialize_chain_clean,
start_node,
wait_and_assert_operationid_status,
)
from decimal import Decimal
# Test wallet change address behaviour
class WalletChangeAddressesTest(BitcoinTestFramework):
def setup_chain(self):
print("Initializing test directory " + self.options.tmpdir)
initialize_chain_clean(self.options.tmpdir, 2)
def setup_network(self):
args = [
'-nuparams=5ba81b19:1', # Overwinter
'-nuparams=76b809bb:1', # Sapling
'-txindex' # Avoid JSONRPC error: No information available about transaction
]
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, args))
self.nodes.append(start_node(1, self.options.tmpdir, args))
connect_nodes_bi(self.nodes,0,1)
self.is_network_split=False
self.sync_all()
def run_test(self):
self.nodes[0].generate(110)
# Obtain some transparent funds
midAddr = self.nodes[0].z_getnewaddress('sapling')
myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), midAddr, 0)['opid']
wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
self.nodes[1].generate(1)
self.sync_all()
taddrSource = self.nodes[0].getnewaddress()
for _ in range(6):
recipients = [{"address": taddrSource, "amount": Decimal('2')}]
myopid = self.nodes[0].z_sendmany(midAddr, recipients, 1, 0)
wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
self.nodes[1].generate(1)
self.sync_all()
def check_change_taddr_reuse(target):
recipients = [{"address": target, "amount": Decimal('1')}]
# Send funds to recipient address twice
myopid = self.nodes[0].z_sendmany(taddrSource, recipients, 1, 0)
txid1 = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.nodes[1].generate(1)
self.sync_all()
myopid = self.nodes[0].z_sendmany(taddrSource, recipients, 1, 0)
txid2 = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.nodes[1].generate(1)
self.sync_all()
# Verify that the two transactions used different change addresses
tx1 = self.nodes[0].getrawtransaction(txid1, 1)
tx2 = self.nodes[0].getrawtransaction(txid2, 1)
for i in range(len(tx1['vout'])):
tx1OutAddrs = tx1['vout'][i]['scriptPubKey']['addresses']
tx2OutAddrs = tx2['vout'][i]['scriptPubKey']['addresses']
if tx1OutAddrs != [target]:
print('Source address: %s' % taddrSource)
print('TX1 change address: %s' % tx1OutAddrs[0])
print('TX2 change address: %s' % tx2OutAddrs[0])
assert(tx1OutAddrs != tx2OutAddrs)
taddr = self.nodes[0].getnewaddress()
saplingAddr = self.nodes[0].z_getnewaddress('sapling')
print()
print('Checking z_sendmany(taddr->Sapling)')
check_change_taddr_reuse(saplingAddr)
print()
print('Checking z_sendmany(taddr->taddr)')
check_change_taddr_reuse(taddr)
if __name__ == '__main__':
WalletChangeAddressesTest().main()