2019-12-04 07:29:16 -08:00
|
|
|
#!/usr/bin/env python3
|
2018-08-28 17:16:04 -07:00
|
|
|
# Copyright (c) 2018 The Zcash developers
|
|
|
|
# Distributed under the MIT software license, see the accompanying
|
2019-07-18 07:16:09 -07:00
|
|
|
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
2018-08-28 17:16:04 -07:00
|
|
|
|
|
|
|
from test_framework.test_framework import BitcoinTestFramework
|
2018-03-10 02:19:44 -08:00
|
|
|
from test_framework.util import (
|
|
|
|
assert_equal,
|
|
|
|
get_coinbase_address,
|
|
|
|
wait_and_assert_operationid_status,
|
|
|
|
)
|
2018-08-28 17:16:04 -07:00
|
|
|
|
|
|
|
from decimal import Decimal
|
|
|
|
|
2018-09-28 22:11:05 -07:00
|
|
|
# Test wallet z_listunspent behaviour across network upgrades
|
2018-08-28 17:16:04 -07:00
|
|
|
class WalletListNotes(BitcoinTestFramework):
|
|
|
|
|
|
|
|
def run_test(self):
|
2019-07-19 05:10:13 -07:00
|
|
|
# Current height = 200
|
2018-09-11 13:51:38 -07:00
|
|
|
assert_equal(200, self.nodes[0].getblockcount())
|
2018-08-28 17:16:04 -07:00
|
|
|
sproutzaddr = self.nodes[0].z_getnewaddress('sprout')
|
|
|
|
saplingzaddr = self.nodes[0].z_getnewaddress('sapling')
|
2018-09-11 13:51:38 -07:00
|
|
|
|
|
|
|
# we've got lots of coinbase (taddr) but no shielded funds yet
|
|
|
|
assert_equal(0, Decimal(self.nodes[0].z_gettotalbalance()['private']))
|
2019-07-19 05:10:13 -07:00
|
|
|
|
|
|
|
# Set current height to 201
|
2018-08-28 17:16:04 -07:00
|
|
|
self.nodes[0].generate(1)
|
|
|
|
self.sync_all()
|
2018-09-11 13:51:38 -07:00
|
|
|
assert_equal(201, self.nodes[0].getblockcount())
|
|
|
|
|
2019-07-19 05:10:13 -07:00
|
|
|
# Shield coinbase funds (must be a multiple of 10, no change allowed)
|
2018-09-11 13:51:38 -07:00
|
|
|
receive_amount_10 = Decimal('10.0') - Decimal('0.0001')
|
|
|
|
recipients = [{"address":sproutzaddr, "amount":receive_amount_10}]
|
2019-01-28 10:45:48 -08:00
|
|
|
myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients)
|
2018-08-28 17:16:04 -07:00
|
|
|
txid_1 = wait_and_assert_operationid_status(self.nodes[0], myopid)
|
2018-09-11 13:51:38 -07:00
|
|
|
self.sync_all()
|
2018-08-28 17:16:04 -07:00
|
|
|
|
2018-09-11 13:51:38 -07:00
|
|
|
# No funds (with (default) one or more confirmations) in sproutzaddr yet
|
|
|
|
assert_equal(0, len(self.nodes[0].z_listunspent()))
|
|
|
|
assert_equal(0, len(self.nodes[0].z_listunspent(1)))
|
2018-08-28 17:16:04 -07:00
|
|
|
|
2018-09-11 13:51:38 -07:00
|
|
|
# no private balance because no confirmations yet
|
|
|
|
assert_equal(0, Decimal(self.nodes[0].z_gettotalbalance()['private']))
|
2018-08-28 17:16:04 -07:00
|
|
|
|
2018-09-11 13:51:38 -07:00
|
|
|
# list private unspent, this time allowing 0 confirmations
|
2018-08-28 17:16:04 -07:00
|
|
|
unspent_cb = self.nodes[0].z_listunspent(0)
|
2018-09-11 13:51:38 -07:00
|
|
|
assert_equal(1, len(unspent_cb))
|
|
|
|
assert_equal(False, unspent_cb[0]['change'])
|
|
|
|
assert_equal(txid_1, unspent_cb[0]['txid'])
|
|
|
|
assert_equal(True, unspent_cb[0]['spendable'])
|
|
|
|
assert_equal(sproutzaddr, unspent_cb[0]['address'])
|
|
|
|
assert_equal(receive_amount_10, unspent_cb[0]['amount'])
|
|
|
|
|
|
|
|
# list unspent, filtering by address, should produce same result
|
|
|
|
unspent_cb_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr])
|
2018-08-28 17:16:04 -07:00
|
|
|
assert_equal(unspent_cb, unspent_cb_filter)
|
|
|
|
|
2018-09-11 13:51:38 -07:00
|
|
|
# Generate a block to confirm shield coinbase tx
|
2018-08-28 17:16:04 -07:00
|
|
|
self.nodes[0].generate(1)
|
|
|
|
self.sync_all()
|
2019-07-19 05:10:13 -07:00
|
|
|
|
|
|
|
# Current height = 202
|
2018-09-11 13:51:38 -07:00
|
|
|
assert_equal(202, self.nodes[0].getblockcount())
|
|
|
|
|
|
|
|
# Send 1.0 (actually 0.9999) from sproutzaddr to a new zaddr
|
2018-11-16 14:22:23 -08:00
|
|
|
sproutzaddr2 = self.nodes[0].z_getnewaddress('sprout')
|
2018-09-11 13:51:38 -07:00
|
|
|
receive_amount_1 = Decimal('1.0') - Decimal('0.0001')
|
|
|
|
change_amount_9 = receive_amount_10 - Decimal('1.0')
|
|
|
|
assert_equal('sprout', self.nodes[0].z_validateaddress(sproutzaddr2)['type'])
|
|
|
|
recipients = [{"address": sproutzaddr2, "amount":receive_amount_1}]
|
2018-08-28 17:16:04 -07:00
|
|
|
myopid = self.nodes[0].z_sendmany(sproutzaddr, recipients)
|
|
|
|
txid_2 = wait_and_assert_operationid_status(self.nodes[0], myopid)
|
2018-09-11 13:51:38 -07:00
|
|
|
self.sync_all()
|
2018-08-28 17:16:04 -07:00
|
|
|
|
|
|
|
# list unspent, allowing 0conf txs
|
|
|
|
unspent_tx = self.nodes[0].z_listunspent(0)
|
|
|
|
assert_equal(len(unspent_tx), 2)
|
2018-09-11 13:51:38 -07:00
|
|
|
# sort low-to-high by amount (order of returned entries is not guaranteed)
|
|
|
|
unspent_tx = sorted(unspent_tx, key=lambda k: k['amount'])
|
|
|
|
assert_equal(False, unspent_tx[0]['change'])
|
|
|
|
assert_equal(txid_2, unspent_tx[0]['txid'])
|
|
|
|
assert_equal(True, unspent_tx[0]['spendable'])
|
|
|
|
assert_equal(sproutzaddr2, unspent_tx[0]['address'])
|
|
|
|
assert_equal(receive_amount_1, unspent_tx[0]['amount'])
|
|
|
|
|
|
|
|
assert_equal(True, unspent_tx[1]['change'])
|
|
|
|
assert_equal(txid_2, unspent_tx[1]['txid'])
|
|
|
|
assert_equal(True, unspent_tx[1]['spendable'])
|
|
|
|
assert_equal(sproutzaddr, unspent_tx[1]['address'])
|
|
|
|
assert_equal(change_amount_9, unspent_tx[1]['amount'])
|
|
|
|
|
|
|
|
unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr2])
|
|
|
|
assert_equal(1, len(unspent_tx_filter))
|
|
|
|
assert_equal(unspent_tx[0], unspent_tx_filter[0])
|
|
|
|
|
|
|
|
unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [sproutzaddr])
|
|
|
|
assert_equal(1, len(unspent_tx_filter))
|
|
|
|
assert_equal(unspent_tx[1], unspent_tx_filter[0])
|
2019-07-19 05:10:13 -07:00
|
|
|
|
2018-09-11 13:51:38 -07:00
|
|
|
# No funds in saplingzaddr yet
|
|
|
|
assert_equal(0, len(self.nodes[0].z_listunspent(0, 9999, False, [saplingzaddr])))
|
|
|
|
|
|
|
|
# Send 0.9999 to our sapling zaddr
|
|
|
|
# (sending from a sprout zaddr to a sapling zaddr is disallowed,
|
|
|
|
# so send from coin base)
|
|
|
|
receive_amount_2 = Decimal('2.0') - Decimal('0.0001')
|
|
|
|
recipients = [{"address": saplingzaddr, "amount":receive_amount_2}]
|
2019-01-28 10:45:48 -08:00
|
|
|
myopid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients)
|
2018-09-11 13:51:38 -07:00
|
|
|
txid_3 = wait_and_assert_operationid_status(self.nodes[0], myopid)
|
|
|
|
self.sync_all()
|
|
|
|
unspent_tx = self.nodes[0].z_listunspent(0)
|
|
|
|
assert_equal(3, len(unspent_tx))
|
|
|
|
|
|
|
|
# low-to-high in amount
|
|
|
|
unspent_tx = sorted(unspent_tx, key=lambda k: k['amount'])
|
|
|
|
|
|
|
|
assert_equal(False, unspent_tx[0]['change'])
|
|
|
|
assert_equal(txid_2, unspent_tx[0]['txid'])
|
|
|
|
assert_equal(True, unspent_tx[0]['spendable'])
|
|
|
|
assert_equal(sproutzaddr2, unspent_tx[0]['address'])
|
|
|
|
assert_equal(receive_amount_1, unspent_tx[0]['amount'])
|
|
|
|
|
|
|
|
assert_equal(False, unspent_tx[1]['change'])
|
|
|
|
assert_equal(txid_3, unspent_tx[1]['txid'])
|
|
|
|
assert_equal(True, unspent_tx[1]['spendable'])
|
|
|
|
assert_equal(saplingzaddr, unspent_tx[1]['address'])
|
|
|
|
assert_equal(receive_amount_2, unspent_tx[1]['amount'])
|
|
|
|
|
|
|
|
assert_equal(True, unspent_tx[2]['change'])
|
|
|
|
assert_equal(txid_2, unspent_tx[2]['txid'])
|
|
|
|
assert_equal(True, unspent_tx[2]['spendable'])
|
|
|
|
assert_equal(sproutzaddr, unspent_tx[2]['address'])
|
|
|
|
assert_equal(change_amount_9, unspent_tx[2]['amount'])
|
|
|
|
|
|
|
|
unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False, [saplingzaddr])
|
|
|
|
assert_equal(1, len(unspent_tx_filter))
|
|
|
|
assert_equal(unspent_tx[1], unspent_tx_filter[0])
|
|
|
|
|
|
|
|
# test that pre- and post-sapling can be filtered in a single call
|
|
|
|
unspent_tx_filter = self.nodes[0].z_listunspent(0, 9999, False,
|
|
|
|
[sproutzaddr, saplingzaddr])
|
|
|
|
assert_equal(2, len(unspent_tx_filter))
|
|
|
|
unspent_tx_filter = sorted(unspent_tx_filter, key=lambda k: k['amount'])
|
|
|
|
assert_equal(unspent_tx[1], unspent_tx_filter[0])
|
|
|
|
assert_equal(unspent_tx[2], unspent_tx_filter[1])
|
|
|
|
|
|
|
|
# so far, this node has no watchonly addresses, so results are the same
|
|
|
|
unspent_tx_watchonly = self.nodes[0].z_listunspent(0, 9999, True)
|
|
|
|
unspent_tx_watchonly = sorted(unspent_tx_watchonly, key=lambda k: k['amount'])
|
|
|
|
assert_equal(unspent_tx, unspent_tx_watchonly)
|
|
|
|
|
|
|
|
# TODO: use z_exportviewingkey, z_importviewingkey to test includeWatchonly
|
|
|
|
# but this requires Sapling support for those RPCs
|
2018-08-28 17:16:04 -07:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2018-09-11 13:51:38 -07:00
|
|
|
WalletListNotes().main()
|