zcashd/qa/rpc-tests/remove_sprout_shielding.py

148 lines
6.3 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (c) 2020 The Zcash developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
from decimal import Decimal
from test_framework.authproxy import JSONRPCException
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_message,
start_nodes, get_coinbase_address,
wait_and_assert_operationid_status,
nuparams,
BLOSSOM_BRANCH_ID,
HEARTWOOD_BRANCH_ID,
CANOPY_BRANCH_ID,
NU5_BRANCH_ID,
)
import logging
HAS_CANOPY = [
'-minrelaytxfee=0',
'-nurejectoldversions=false',
'-anchorconfirmations=1',
nuparams(BLOSSOM_BRANCH_ID, 205),
nuparams(HEARTWOOD_BRANCH_ID, 210),
nuparams(CANOPY_BRANCH_ID, 220),
nuparams(NU5_BRANCH_ID, 225),
'-allowdeprecated=getnewaddress',
'-allowdeprecated=z_getnewaddress',
'-allowdeprecated=z_getbalance',
]
class RemoveSproutShieldingTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.cache_behavior = 'sprout'
def setup_nodes(self):
return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[HAS_CANOPY] * self.num_nodes)
def run_test(self):
# Generate blocks up to Heartwood activation
logging.info("Generating initial blocks. Current height is 200, advance to 210 (activate Heartwood but not Canopy)")
self.nodes[0].generate(10)
self.sync_all()
n0_sprout_addr0 = self.nodes[0].listaddresses()[0]['sprout']['addresses'][0]
# Attempt to shield coinbase to Sprout on node 0. Should fail;
# transfers to Sprout are no longer supported
try:
self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), n0_sprout_addr0, 0)['opid']
except JSONRPCException as e:
errorString = e.error['message'];
unsupported_sprout_msg = "Sending funds into the Sprout pool is no longer supported."
assert_equal(unsupported_sprout_msg, errorString)
self.nodes[0].generate(1)
self.sync_all()
# Check that we have the expected balance from the cached setup
assert_equal(self.nodes[0].z_getbalance(n0_sprout_addr0), Decimal('50'))
# Fund n0_taddr0 from previously existing Sprout funds on node 0
n0_taddr0 = self.nodes[0].getnewaddress()
for _ in range(3):
recipients = [{"address": n0_taddr0, "amount": Decimal('1')}]
myopid = self.nodes[0].z_sendmany(n0_sprout_addr0, recipients, 1, 0, 'AllowRevealedRecipients')
wait_and_assert_operationid_status(self.nodes[0], myopid)
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
assert_equal(self.nodes[0].z_getbalance(n0_taddr0), Decimal('3'))
# Create mergetoaddress taddr -> Sprout transaction, should fail
n1_sprout_addr0 = self.nodes[1].z_getnewaddress('sprout')
assert_raises_message(
JSONRPCException,
"Sending funds into the Sprout pool is no longer supported.",
self.nodes[0].z_mergetoaddress,
["ANY_TADDR"], n1_sprout_addr0, 0)
self.nodes[0].generate(1)
self.sync_all()
# Send some funds back to n0_taddr0
recipients = [{"address": n0_taddr0, "amount": Decimal('1')}]
myopid = self.nodes[0].z_sendmany(n0_sprout_addr0, recipients, 1, 0, 'AllowRevealedRecipients')
wait_and_assert_operationid_status(self.nodes[0], myopid)
# Mine to one block before Canopy activation on node 0; adding value
# to the Sprout pool will fail now since the transaction must be
# included in the next (or later) block, after Canopy has activated.
self.sync_all()
self.nodes[0].generate(4)
self.sync_all()
assert_equal(self.nodes[0].getblockchaininfo()['upgrades']['e9ff75a6']['status'], 'pending')
assert_equal(self.nodes[0].z_getbalance(n0_taddr0), Decimal('4'))
# Shield coinbase to Sprout on node 0. Should fail
n0_coinbase_taddr = get_coinbase_address(self.nodes[0])
n0_sprout_addr1 = self.nodes[0].z_getnewaddress('sprout')
assert_raises_message(
JSONRPCException,
"Sending funds into the Sprout pool is no longer supported.",
self.nodes[0].z_shieldcoinbase,
n0_coinbase_taddr, n0_sprout_addr1, 0)
print("taddr -> Sprout z_shieldcoinbase tx rejected at Canopy activation on node 0")
# Create taddr -> Sprout z_sendmany transaction on node 0. Should fail
n1_sprout_addr1 = self.nodes[1].z_getnewaddress('sprout')
recipients = [{"address": n1_sprout_addr1, "amount": Decimal('1')}]
myopid = self.nodes[0].z_sendmany(n0_taddr0, recipients, 1, 0)
wait_and_assert_operationid_status(self.nodes[0], myopid, "failed", unsupported_sprout_msg)
print("taddr -> Sprout z_sendmany tx rejected at Canopy activation on node 0")
# Create z_mergetoaddress [taddr, Sprout] -> Sprout transaction on node 0. Should fail
assert_raises_message(
JSONRPCException,
"Sending funds into the Sprout pool is no longer supported.",
self.nodes[0].z_mergetoaddress,
["ANY_TADDR", "ANY_SPROUT"], self.nodes[1].z_getnewaddress('sprout'))
# Activate Canopy
self.nodes[0].generate(1)
self.sync_all()
assert_equal(self.nodes[0].getblockchaininfo()['upgrades']['e9ff75a6']['status'], 'active')
# Generating a Sprout address should fail after Canopy.
assert_raises_message(
JSONRPCException,
"Invalid address type, \"sprout\" is not allowed after Canopy",
self.nodes[0].z_getnewaddress, 'sprout')
print("Sprout z_getnewaddress rejected at Canopy activation on node 0")
# Shield coinbase to Sapling on node 0. Should pass
sapling_addr = self.nodes[0].z_getnewaddress('sapling')
myopid = self.nodes[0].z_shieldcoinbase(get_coinbase_address(self.nodes[0]), sapling_addr, 0)['opid']
wait_and_assert_operationid_status(self.nodes[0], myopid)
print("taddr -> Sapling z_shieldcoinbase tx accepted after Canopy on node 0")
if __name__ == '__main__':
RemoveSproutShieldingTest().main()