Auto merge of #3518 - str4d:3216-z_shieldcoinbase, r=str4d

Add Sapling support to z_shieldcoinbase

Part of #3216.
This commit is contained in:
Homu
2018-10-05 03:33:16 -07:00
11 changed files with 204 additions and 64 deletions

View File

@@ -18,7 +18,8 @@ testScripts=(
'wallet_changeindicator.py'
'wallet_import_export.py'
'wallet_protectcoinbase.py'
'wallet_shieldcoinbase.py'
'wallet_shieldcoinbase_sprout.py'
'wallet_shieldcoinbase_sapling.py'
'wallet_listreceived.py'
'wallet_mergetoaddress.py'
'wallet.py'

View File

@@ -12,9 +12,6 @@ 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')
@@ -95,7 +92,7 @@ class ListReceivedTest (BitcoinTestFramework):
def run_test(self):
self.run_test_release('sprout', no_memo, 200)
self.run_test_release('sapling', zero_memo, 204)
self.run_test_release('sapling', no_memo, 204)
if __name__ == '__main__':
ListReceivedTest().main()

View File

@@ -12,6 +12,9 @@ from test_framework.util import assert_equal, initialize_chain_clean, \
from decimal import Decimal
class WalletShieldCoinbaseTest (BitcoinTestFramework):
def __init__(self, addr_type):
super(WalletShieldCoinbaseTest, self).__init__()
self.addr_type = addr_type
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
@@ -19,10 +22,17 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
def setup_network(self, split=False):
args = ['-regtestprotectcoinbase', '-debug=zrpcunsafe']
args2 = ['-regtestprotectcoinbase', '-debug=zrpcunsafe', "-mempooltxinputlimit=7"]
if self.addr_type != 'sprout':
nu = [
'-nuparams=5ba81b19:0', # Overwinter
'-nuparams=76b809bb:1', # Sapling
]
args.extend(nu)
args2 = args
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, args))
self.nodes.append(start_node(1, self.options.tmpdir, args))
args2 = ['-regtestprotectcoinbase', '-debug=zrpcunsafe', "-mempooltxinputlimit=7"]
self.nodes.append(start_node(2, self.options.tmpdir, args2))
connect_nodes_bi(self.nodes,0,1)
connect_nodes_bi(self.nodes,1,2)
@@ -55,7 +65,7 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
# Prepare to send taddr->zaddr
mytaddr = self.nodes[0].getnewaddress()
myzaddr = self.nodes[0].z_getnewaddress()
myzaddr = self.nodes[0].z_getnewaddress(self.addr_type)
# Shielding will fail when trying to spend from watch-only address
self.nodes[2].importaddress(mytaddr)
@@ -135,26 +145,33 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
self.sync_all()
mytaddr = self.nodes[0].getnewaddress()
# Shielding the 800 utxos will occur over two transactions, since max tx size is 100,000 bytes.
# We don't verify shieldingValue as utxos are not selected in any specific order, so value can change on each test run.
# We set an unrealistically high limit parameter of 99999, to verify that max tx size will constrain the number of utxos.
result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 99999)
assert_equal(result["shieldingUTXOs"], Decimal('662'))
assert_equal(result["remainingUTXOs"], Decimal('138'))
remainingValue = result["remainingValue"]
opid1 = result['opid']
def verify_locking(first, second, limit):
result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, limit)
assert_equal(result["shieldingUTXOs"], Decimal(first))
assert_equal(result["remainingUTXOs"], Decimal(second))
remainingValue = result["remainingValue"]
opid1 = result['opid']
# Verify that utxos are locked (not available for selection) by queuing up another shielding operation
result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 0)
assert_equal(result["shieldingValue"], Decimal(remainingValue))
assert_equal(result["shieldingUTXOs"], Decimal('138'))
assert_equal(result["remainingValue"], Decimal('0'))
assert_equal(result["remainingUTXOs"], Decimal('0'))
opid2 = result['opid']
# Verify that utxos are locked (not available for selection) by queuing up another shielding operation
result = self.nodes[0].z_shieldcoinbase(mytaddr, myzaddr, 0, 0)
assert_equal(result["shieldingValue"], Decimal(remainingValue))
assert_equal(result["shieldingUTXOs"], Decimal(second))
assert_equal(result["remainingValue"], Decimal('0'))
assert_equal(result["remainingUTXOs"], Decimal('0'))
opid2 = result['opid']
# wait for both aysnc operations to complete
wait_and_assert_operationid_status(self.nodes[0], opid1)
wait_and_assert_operationid_status(self.nodes[0], opid2)
# wait for both aysnc operations to complete
wait_and_assert_operationid_status(self.nodes[0], opid1)
wait_and_assert_operationid_status(self.nodes[0], opid2)
if self.addr_type == 'sprout':
# Shielding the 800 utxos will occur over two transactions, since max tx size is 100,000 bytes.
# We don't verify shieldingValue as utxos are not selected in any specific order, so value can change on each test run.
# We set an unrealistically high limit parameter of 99999, to verify that max tx size will constrain the number of utxos.
verify_locking('662', '138', 99999)
else:
# Shield the 800 utxos over two transactions
verify_locking('500', '300', 500)
# sync_all() invokes sync_mempool() but node 2's mempool limit will cause tx1 and tx2 to be rejected.
# So instead, we sync on blocks and mempool for node 0 and node 1, and after a new block is generated
@@ -164,16 +181,17 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
self.nodes[1].generate(1)
self.sync_all()
# Verify maximum number of utxos which node 2 can shield is limited by option -mempooltxinputlimit
# This option is used when the limit parameter is set to 0.
mytaddr = self.nodes[2].getnewaddress()
result = self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 0)
assert_equal(result["shieldingUTXOs"], Decimal('7'))
assert_equal(result["remainingUTXOs"], Decimal('13'))
wait_and_assert_operationid_status(self.nodes[2], result['opid'])
self.sync_all()
self.nodes[1].generate(1)
self.sync_all()
if self.addr_type == 'sprout':
# Verify maximum number of utxos which node 2 can shield is limited by option -mempooltxinputlimit
# This option is used when the limit parameter is set to 0.
mytaddr = self.nodes[2].getnewaddress()
result = self.nodes[2].z_shieldcoinbase(mytaddr, myzaddr, Decimal('0.0001'), 0)
assert_equal(result["shieldingUTXOs"], Decimal('7'))
assert_equal(result["remainingUTXOs"], Decimal('13'))
wait_and_assert_operationid_status(self.nodes[2], result['opid'])
self.sync_all()
self.nodes[1].generate(1)
self.sync_all()
# Verify maximum number of utxos which node 0 can shield is set by default limit parameter of 50
self.nodes[0].generate(200)
@@ -194,6 +212,3 @@ class WalletShieldCoinbaseTest (BitcoinTestFramework):
sync_mempools(self.nodes[:2])
self.nodes[1].generate(1)
self.sync_all()
if __name__ == '__main__':
WalletShieldCoinbaseTest().main()

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env python2
import inspect
import os
# To keep pyflakes happy
WalletShieldCoinbaseTest = object
cwd = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
execfile(os.path.join(cwd, 'wallet_shieldcoinbase.py'))
class WalletShieldCoinbaseSapling(WalletShieldCoinbaseTest):
def __init__(self):
super(WalletShieldCoinbaseSapling, self).__init__('sapling')
if __name__ == '__main__':
WalletShieldCoinbaseSapling().main()

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env python2
import inspect
import os
# To keep pyflakes happy
WalletShieldCoinbaseTest = object
cwd = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
execfile(os.path.join(cwd, 'wallet_shieldcoinbase.py'))
class WalletShieldCoinbaseSprout(WalletShieldCoinbaseTest):
def __init__(self):
super(WalletShieldCoinbaseSprout, self).__init__('sprout')
if __name__ == '__main__':
WalletShieldCoinbaseSprout().main()