Latest Zcash updates and more CC for N@S

This commit is contained in:
miketout
2018-10-05 00:26:06 -07:00
26 changed files with 657 additions and 154 deletions

View File

@@ -20,6 +20,7 @@ testScripts=(
'wallet_import_export.py'
'wallet_protectcoinbase.py'
'wallet_shieldcoinbase.py'
'wallet_listreceived.py'
'wallet_mergetoaddress.py'
'wallet.py'
'wallet_overwintertx.py'
@@ -27,6 +28,7 @@ testScripts=(
'wallet_1941.py'
'wallet_addresses.py'
'wallet_sapling.py'
'wallet_listnotes.py'
'listtransactions.py'
'mempool_resurrect_test.py'
'txn_doublespend.py'
@@ -67,6 +69,7 @@ testScripts=(
'rewind_index.py'
'p2p_txexpiry_dos.py'
'p2p_node_bloom.py'
'regtest_signrawtransaction.py'
);
testScriptsExt=(
'getblocktemplate_longpoll.py'

View File

@@ -0,0 +1,34 @@
#!/usr/bin/env python2
# Copyright (c) 2018 The Zcash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import start_nodes, wait_and_assert_operationid_status
class RegtestSignrawtransactionTest (BitcoinTestFramework):
def setup_nodes(self):
return start_nodes(4, self.options.tmpdir, [[
"-nuparams=5ba81b19:200", # Overwinter
"-nuparams=76b809bb:204", # Sapling
]] * 4)
def run_test(self):
self.nodes[0].generate(1)
self.sync_all()
taddr = self.nodes[1].getnewaddress()
zaddr1 = self.nodes[1].z_getnewaddress('sprout')
self.nodes[0].sendtoaddress(taddr, 2.0)
self.nodes[0].generate(1)
self.sync_all()
# Create and sign Overwinter transaction.
# If the incorrect consensus branch id is selected, there will be a signing error.
opid = self.nodes[1].z_sendmany(taddr,
[{'address': zaddr1, 'amount': 1}])
wait_and_assert_operationid_status(self.nodes[1], opid)
if __name__ == '__main__':
RegtestSignrawtransactionTest().main()

View File

@@ -2,6 +2,7 @@
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_true, initialize_chain_clean, start_node
from test_framework.authproxy import JSONRPCException
class SignOfflineTest (BitcoinTestFramework):
# Setup Methods
@@ -36,7 +37,17 @@ class SignOfflineTest (BitcoinTestFramework):
create_hex = self.nodes[0].createrawtransaction(create_inputs, {taddr: 9.9999})
signed_tx = offline_node.signrawtransaction(create_hex, sign_inputs, privkeys)
# An offline regtest node does not rely on the approx release height of the software
# to determine the consensus rules to be used for signing.
try:
signed_tx = offline_node.signrawtransaction(create_hex, sign_inputs, privkeys)
self.nodes[0].sendrawtransaction(signed_tx['hex'])
assert(False)
except JSONRPCException:
pass
# Passing in the consensus branch id resolves the issue for offline regtest nodes.
signed_tx = offline_node.signrawtransaction(create_hex, sign_inputs, privkeys, "ALL", "5ba81b19")
# If we return the transaction hash, then we have have not thrown an error (success)
online_tx_hash = self.nodes[0].sendrawtransaction(signed_tx['hex'])

168
qa/rpc-tests/wallet_listnotes.py Executable file
View File

@@ -0,0 +1,168 @@
#!/usr/bin/env python2
# Copyright (c) 2018 The Zcash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, start_nodes, wait_and_assert_operationid_status
from decimal import Decimal
# Test wallet z_listunspent behaviour across network upgrades
class WalletListNotes(BitcoinTestFramework):
def setup_nodes(self):
return start_nodes(4, self.options.tmpdir, [[
'-nuparams=5ba81b19:202', # Overwinter
'-nuparams=76b809bb:204', # Sapling
]] * 4)
def run_test(self):
# Current height = 200 -> Sprout
assert_equal(200, self.nodes[0].getblockcount())
sproutzaddr = self.nodes[0].z_getnewaddress('sprout')
# test that we can create a sapling zaddr before sapling activates
saplingzaddr = self.nodes[0].z_getnewaddress('sapling')
# we've got lots of coinbase (taddr) but no shielded funds yet
assert_equal(0, Decimal(self.nodes[0].z_gettotalbalance()['private']))
# Set current height to 201 -> Sprout
self.nodes[0].generate(1)
self.sync_all()
assert_equal(201, self.nodes[0].getblockcount())
mining_addr = self.nodes[0].listunspent()[0]['address']
# Shield coinbase funds (must be a multiple of 10, no change allowed pre-sapling)
receive_amount_10 = Decimal('10.0') - Decimal('0.0001')
recipients = [{"address":sproutzaddr, "amount":receive_amount_10}]
myopid = self.nodes[0].z_sendmany(mining_addr, recipients)
txid_1 = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
# 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)))
# no private balance because no confirmations yet
assert_equal(0, Decimal(self.nodes[0].z_gettotalbalance()['private']))
# list private unspent, this time allowing 0 confirmations
unspent_cb = self.nodes[0].z_listunspent(0)
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])
assert_equal(unspent_cb, unspent_cb_filter)
# Generate a block to confirm shield coinbase tx
self.nodes[0].generate(1)
self.sync_all()
# Current height = 202 -> Overwinter. Default address type remains Sprout
assert_equal(202, self.nodes[0].getblockcount())
# Send 1.0 (actually 0.9999) from sproutzaddr to a new zaddr
sproutzaddr2 = self.nodes[0].z_getnewaddress()
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}]
myopid = self.nodes[0].z_sendmany(sproutzaddr, recipients)
txid_2 = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
# list unspent, allowing 0conf txs
unspent_tx = self.nodes[0].z_listunspent(0)
assert_equal(len(unspent_tx), 2)
# 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])
# Set current height to 204 -> Sapling
self.nodes[0].generate(2)
self.sync_all()
assert_equal(204, self.nodes[0].getblockcount())
# 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}]
myopid = self.nodes[0].z_sendmany(mining_addr, recipients)
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
if __name__ == '__main__':
WalletListNotes().main()

View File

@@ -0,0 +1,101 @@
#!/usr/bin/env python2
# Copyright (c) 2018 The Zcash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_true, assert_false
from test_framework.util import start_nodes, wait_and_assert_operationid_status
from decimal import Decimal
my_memo = 'c0ffee' # stay awake
my_memo = my_memo + '0'*(1024-len(my_memo))
no_memo = 'f6' + ('0'*1022) # see section 5.5 of the protocol spec
# sapling generates zero_memo, but this may be fixed soon (to no_memo)
# then this test can be simplified
zero_memo = '0'*1024
fee = Decimal('0.0001')
class ListReceivedTest (BitcoinTestFramework):
def setup_nodes(self):
return start_nodes(4, self.options.tmpdir, [[
"-nuparams=5ba81b19:201", # Overwinter
"-nuparams=76b809bb:204", # Sapling
]] * 4)
def generate_and_sync(self, new_height):
self.nodes[0].generate(1)
self.sync_all()
assert_equal(new_height, self.nodes[0].getblockcount())
def run_test_release(self, release, expected_memo, height):
self.generate_and_sync(height+1)
taddr = self.nodes[1].getnewaddress()
zaddr1 = self.nodes[1].z_getnewaddress(release)
self.nodes[0].sendtoaddress(taddr, 2.0)
self.generate_and_sync(height+2)
# Send 1 ZEC to zaddr1
opid = self.nodes[1].z_sendmany(taddr,
[{'address': zaddr1, 'amount': 1, 'memo': my_memo}])
txid = wait_and_assert_operationid_status(self.nodes[1], opid)
self.sync_all()
r = self.nodes[1].z_listreceivedbyaddress(zaddr1)
assert_equal(0, len(r), "Should have received no confirmed note")
# No confirmation required, one note should be present
r = self.nodes[1].z_listreceivedbyaddress(zaddr1, 0)
assert_equal(1, len(r), "Should have received one (unconfirmed) note")
assert_equal(txid, r[0]['txid'])
assert_equal(1, r[0]['amount'])
assert_false(r[0]['change'], "Note should not be change")
assert_equal(my_memo, r[0]['memo'])
# Confirm transaction (1 ZEC from taddr to zaddr1)
self.generate_and_sync(height+3)
# Require one confirmation, note should be present
assert_equal(r, self.nodes[1].z_listreceivedbyaddress(zaddr1))
# Generate some change by sending part of zaddr1 to zaddr2
zaddr2 = self.nodes[1].z_getnewaddress(release)
opid = self.nodes[1].z_sendmany(zaddr1,
[{'address': zaddr2, 'amount': 0.6, 'memo': my_memo}])
txid = wait_and_assert_operationid_status(self.nodes[1], opid)
self.sync_all()
self.generate_and_sync(height+4)
# zaddr1 should have a note with change
r = self.nodes[1].z_listreceivedbyaddress(zaddr1, 0)
r = sorted(r, key = lambda received: received['amount'])
assert_equal(2, len(r), "zaddr1 Should have received 2 notes")
assert_equal(txid, r[0]['txid'])
assert_equal(Decimal('0.4')-fee, r[0]['amount'])
assert_true(r[0]['change'], "Note valued at (0.4-fee) should be change")
assert_equal(expected_memo, r[0]['memo'])
# The old note still exists (it's immutable), even though it is spent
assert_equal(Decimal('1.0'), r[1]['amount'])
assert_false(r[1]['change'], "Note valued at 1.0 should not be change")
assert_equal(expected_memo, r[0]['memo'])
# zaddr2 should not have change
r = self.nodes[1].z_listreceivedbyaddress(zaddr2, 0)
r = sorted(r, key = lambda received: received['amount'])
assert_equal(1, len(r), "zaddr2 Should have received 1 notes")
assert_equal(txid, r[0]['txid'])
assert_equal(Decimal('0.6'), r[0]['amount'])
assert_false(r[0]['change'], "Note valued at 0.6 should not be change")
assert_equal(my_memo, r[0]['memo'])
def run_test(self):
self.run_test_release('sprout', no_memo, 200)
self.run_test_release('sapling', zero_memo, 204)
if __name__ == '__main__':
ListReceivedTest().main()

View File

@@ -53,9 +53,14 @@ class WalletSaplingTest(BitcoinTestFramework):
recipients = []
recipients.append({"address": saplingAddr0, "amount": Decimal('20')})
myopid = self.nodes[0].z_sendmany(taddr0, recipients, 1, 0)
wait_and_assert_operationid_status(self.nodes[0], myopid)
mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
# Verify priority of tx is MAX_PRIORITY, defined as 1E+16 (10000000000000000)
mempool = self.nodes[0].getrawmempool(True)
assert(Decimal(mempool[mytxid]['startingpriority']) == Decimal('1E+16'))
self.nodes[2].generate(1)
self.sync_all()
@@ -70,9 +75,14 @@ class WalletSaplingTest(BitcoinTestFramework):
recipients = []
recipients.append({"address": saplingAddr1, "amount": Decimal('15')})
myopid = self.nodes[0].z_sendmany(saplingAddr0, recipients, 1, 0)
wait_and_assert_operationid_status(self.nodes[0], myopid)
mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
# Verify priority of tx is MAX_PRIORITY, defined as 1E+16 (10000000000000000)
mempool = self.nodes[0].getrawmempool(True)
assert(Decimal(mempool[mytxid]['startingpriority']) == Decimal('1E+16'))
self.nodes[2].generate(1)
self.sync_all()
@@ -92,6 +102,11 @@ class WalletSaplingTest(BitcoinTestFramework):
mytxid = wait_and_assert_operationid_status(self.nodes[1], myopid)
self.sync_all()
# Verify priority of tx is MAX_PRIORITY, defined as 1E+16 (10000000000000000)
mempool = self.nodes[1].getrawmempool(True)
assert(Decimal(mempool[mytxid]['startingpriority']) == Decimal('1E+16'))
self.nodes[2].generate(1)
self.sync_all()