Merge pull request #6040 from nuttycom/test/persisted_sprout_chain

Add persistent test data to avoid needing to create new Sprout outputs in RPC tests.
This commit is contained in:
Kris Nuttycombe 2022-07-18 11:35:57 -06:00 committed by GitHub
commit c1a18cab39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 190 additions and 227 deletions

View File

@ -46,7 +46,7 @@ class AddressIndexTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self):
# -insightexplorer causes addressindex to be enabled (fAddressIndex = true)

View File

@ -28,7 +28,6 @@ class BlockchainTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = False
self.num_nodes = 2
def setup_network(self, split=False):

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -22,7 +22,7 @@ class CoinbaseFundingStreamsTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def start_node_with(self, index, extra_args=[]):
args = [

View File

@ -16,7 +16,7 @@ class DecodeScriptTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 1
def setup_network(self, split=False):

View File

@ -16,7 +16,7 @@ class DisableWalletTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 1
def setup_network(self, split=False):

View File

@ -14,7 +14,7 @@ from test_framework.test_framework import BitcoinTestFramework
class LoggingTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def run_test(self):
# test default log file name

View File

@ -14,7 +14,7 @@ from test_framework.test_framework import BitcoinTestFramework
class WalletFileTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 1
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def run_test(self):
# test default wallet location

View File

@ -30,7 +30,7 @@ class Zip221Test(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_nodes(self):
return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[

View File

@ -3,6 +3,7 @@
# 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.mininode import (
NU5_PROTO_VERSION,
CInv,
@ -20,6 +21,7 @@ from test_framework.util import (
HEARTWOOD_BRANCH_ID,
CANOPY_BRANCH_ID,
NU5_BRANCH_ID,
DEFAULT_FEE,
assert_equal,
assert_false,
assert_true,
@ -27,7 +29,7 @@ from test_framework.util import (
hex_str_to_bytes,
nuparams,
p2p_port,
start_node,
start_nodes,
wait_and_assert_operationid_status,
)
from tx_expiry_helper import TestNode
@ -37,22 +39,19 @@ import time
# Test ZIP 239 behaviour before and after NU5.
class Zip239Test(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.cache_behavior = 'sprout'
def setup_nodes(self):
extra_args=[
# Enable Canopy at height 205 to allow shielding Sprout funds first.
return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[
# Enable Canopy at height 205
nuparams(BLOSSOM_BRANCH_ID, 205),
nuparams(HEARTWOOD_BRANCH_ID, 205),
nuparams(CANOPY_BRANCH_ID, 205),
nuparams(NU5_BRANCH_ID, 210),
"-preferredtxversion=5"
]
nodes = []
nodes.append(start_node(0, self.options.tmpdir, extra_args))
nodes.append(start_node(1, self.options.tmpdir, extra_args))
nodes.append(start_node(2, self.options.tmpdir, extra_args))
nodes.append(start_node(3, self.options.tmpdir, extra_args))
return nodes
]] * self.num_nodes)
def cinv_for(self, txid, authDigest=None):
if authDigest is not None:
@ -187,16 +186,12 @@ class Zip239Test(BitcoinTestFramework):
print("Node's block index is not NU5-aware, skipping remaining tests")
return
# Load funds into the Sprout address
sproutzaddr = self.nodes[0].z_getnewaddress('sprout')
result = self.nodes[2].z_shieldcoinbase("*", sproutzaddr, 0)
wait_and_assert_operationid_status(self.nodes[2], result['opid'])
self.sync_all()
self.nodes[1].generate(1)
self.sync_all()
# Look up the Sprout address that contains existing funds
sproutzaddr = self.nodes[0].listaddresses()[0]['sprout']['addresses'][0]
assert_equal(self.nodes[0].z_getbalance(sproutzaddr), Decimal('50'))
# Activate NU5. Block height after this is 210.
self.nodes[0].generate(9)
self.nodes[0].generate(10)
self.sync_all()
# Add v4 transaction to the mempool.
@ -204,7 +199,7 @@ class Zip239Test(BitcoinTestFramework):
opid = self.nodes[0].z_sendmany(sproutzaddr, [{
'address': node1_taddr,
'amount': 1,
}])
}], 1, DEFAULT_FEE, 'AllowRevealedRecipients')
v4_txid = uint256_from_str(hex_str_to_bytes(
wait_and_assert_operationid_status(self.nodes[0], opid)
)[::-1])

View File

@ -29,11 +29,12 @@ class FinalSaplingRootTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = True
self.cache_behavior = 'sprout'
def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[
'-txindex', # Avoid JSONRPC error: No information available about transaction
'-txindex', # Avoid JSONRPC error: No information available about transaction
'-reindex', # Required due to enabling -txindex
nuparams(NU5_BRANCH_ID, 210),
'-debug',
]] * self.num_nodes)
@ -42,9 +43,6 @@ class FinalSaplingRootTest(BitcoinTestFramework):
self.sync_all()
def run_test(self):
self.nodes[0].generate(200)
self.sync_all()
# Verify genesis block contains null field for what is now called the final sapling root field.
blk = self.nodes[0].getblock("0")
assert_equal(blk["finalsaplingroot"], NULL_FIELD)
@ -78,10 +76,10 @@ class FinalSaplingRootTest(BitcoinTestFramework):
assert_equal(treestate["height"], height)
assert_equal(treestate["hash"], self.nodes[0].getblockhash(height))
assert "skipHash" not in treestate["sprout"]
assert_equal(treestate["sprout"]["commitments"]["finalRoot"], SPROUT_TREE_EMPTY_ROOT)
assert_equal(treestate["sprout"]["commitments"]["finalState"], "000000")
if height < 100:
assert "skipHash" not in treestate["sprout"]
assert_equal(treestate["sprout"]["commitments"]["finalRoot"], SPROUT_TREE_EMPTY_ROOT)
assert_equal(treestate["sprout"]["commitments"]["finalState"], "000000")
assert "skipHash" not in treestate["sapling"]
assert_equal(treestate["sapling"]["commitments"]["finalRoot"], SAPLING_TREE_EMPTY_ROOT)
@ -94,7 +92,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
taddr0 = get_coinbase_address(self.nodes[0])
saplingAddr0 = self.nodes[0].z_getnewaddress('sapling')
recipients = []
recipients.append({"address": saplingAddr0, "amount": Decimal('20')})
recipients.append({"address": saplingAddr0, "amount": Decimal('10')})
myopid = self.nodes[0].z_sendmany(taddr0, recipients, 1, 0)
mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid)
@ -142,16 +140,18 @@ class FinalSaplingRootTest(BitcoinTestFramework):
assert_equal(root, self.nodes[0].getblock("203")["finalsaplingroot"])
# Mine a block with a Sprout shielded tx and verify the final Sapling root does not change
zaddr1 = self.nodes[1].z_getnewaddress('sprout')
result = self.nodes[0].z_shieldcoinbase(taddr0, zaddr1, 0, 1)
wait_and_assert_operationid_status(self.nodes[0], result['opid'])
zaddr0 = self.nodes[0].listaddresses()[0]['sprout']['addresses'][0]
assert_equal(self.nodes[0].z_getbalance(zaddr0), Decimal('50'))
recipients = [{"address": taddr0, "amount": Decimal('12.34')}]
opid = self.nodes[0].z_sendmany(zaddr0, recipients, 1, 0, 'AllowRevealedRecipients')
wait_and_assert_operationid_status(self.nodes[0], opid)
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
assert_equal(len(self.nodes[0].getblock("204")["tx"]), 2)
assert_equal(self.nodes[1].z_getbalance(zaddr1), Decimal("10"))
assert_equal(self.nodes[0].z_getbalance(zaddr0), Decimal("37.66"))
assert_equal(root, self.nodes[0].getblock("204")["finalsaplingroot"])
new_treestate = self.nodes[0].z_gettreestate(str(-1))
@ -160,13 +160,12 @@ class FinalSaplingRootTest(BitcoinTestFramework):
assert new_treestate["sprout"]["commitments"]["finalRoot"] != treestate["sprout"]["commitments"]["finalRoot"]
assert new_treestate["sprout"]["commitments"]["finalState"] != treestate["sprout"]["commitments"]["finalState"]
assert_equal(len(new_treestate["sprout"]["commitments"]["finalRoot"]), 64)
assert_equal(len(new_treestate["sprout"]["commitments"]["finalState"]), 134)
assert_equal(len(new_treestate["sprout"]["commitments"]["finalState"]), 204)
treestate = new_treestate
# Mine a block with a Sapling shielded recipient and verify the final Sapling root changes
saplingAddr1 = self.nodes[1].z_getnewaddress("sapling")
recipients = []
recipients.append({"address": saplingAddr1, "amount": Decimal('12.34')})
recipients = [{"address": saplingAddr1, "amount": Decimal('2.34')}]
myopid = self.nodes[0].z_sendmany(saplingAddr0, recipients, 1, 0)
mytxid = wait_and_assert_operationid_status(self.nodes[0], myopid)
@ -175,7 +174,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
self.sync_all()
assert_equal(len(self.nodes[0].getblock("205")["tx"]), 2)
assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal("12.34"))
assert_equal(self.nodes[1].z_getbalance(saplingAddr1), Decimal("2.34"))
assert root is not self.nodes[0].getblock("205")["finalsaplingroot"]
# Verify there is a Sapling output description (its commitment was added to tree)
@ -193,7 +192,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
# Mine a block with a Sapling shielded sender and transparent recipient and verify the final Sapling root doesn't change
taddr2 = self.nodes[0].getnewaddress()
recipients = []
recipients.append({"address": taddr2, "amount": Decimal('12.34')})
recipients.append({"address": taddr2, "amount": Decimal('2.34')})
myopid = self.nodes[1].z_sendmany(saplingAddr1, recipients, 1, 0)
mytxid = wait_and_assert_operationid_status(self.nodes[1], myopid)
@ -202,7 +201,7 @@ class FinalSaplingRootTest(BitcoinTestFramework):
self.sync_all()
assert_equal(len(self.nodes[0].getblock("206")["tx"]), 2)
assert_equal(self.nodes[0].z_getbalance(taddr2), Decimal("12.34"))
assert_equal(self.nodes[0].z_getbalance(taddr2), Decimal("2.34"))
blk = self.nodes[0].getblock("206")
root = blk["finalsaplingroot"]

View File

@ -18,7 +18,6 @@ class ForkNotifyTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = False
alert_filename = None # Set by setup_network

View File

@ -16,7 +16,7 @@ class FrameworkTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def start_node_with(self, index, extra_args=[]):
args = []

View File

@ -17,7 +17,7 @@ class RawTransactionsTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 4
def setup_network(self, split=False):

View File

@ -34,12 +34,12 @@ class GetBlockTemplateTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 1
self.setup_clean_chain = True
self.cache_behavior = 'sprout'
def setup_network(self, split=False):
args = [
nuparams(CANOPY_BRANCH_ID, 115),
nuparams(NU5_BRANCH_ID, 130),
nuparams(CANOPY_BRANCH_ID, 215),
nuparams(NU5_BRANCH_ID, 230),
]
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, [args] * self.num_nodes)
self.is_network_split = False
@ -128,22 +128,14 @@ class GetBlockTemplateTest(BitcoinTestFramework):
def run_test(self):
node = self.node
# Generate Sprout funds before Canopy activates; using the Sprout address will
# force the generation of v4 transactions from NU5.
print("Generating pre-Canopy blocks to create sprout funds")
# coinbase only becomes mature after 100 blocks, so make one mature.
node.generate(105)
self.sprout_addr = node.z_getnewaddress('sprout')
myopid = node.z_shieldcoinbase('*', self.sprout_addr)['opid']
wait_and_assert_operationid_status(node, myopid)
self.sprout_addr = node.listaddresses()[0]['sprout']['addresses'][0]
self.transparent_addr = node.getnewaddress()
account = node.z_getnewaccount()['account']
self.unified_addr = node.z_getaddressforaccount(account)['address']
node.generate(15)
node.generate(20)
# at height 120, NU5 is not active
# at height 220, NU5 is not active
assert_equal(node.getblockchaininfo()['upgrades'][nustr(NU5_BRANCH_ID)]['status'], 'pending')
print("Testing getblocktemplate for pre-NU5")

View File

@ -50,11 +50,6 @@ class GetBlockTemplateLPTest(BitcoinTestFramework):
Test longpolling with getblocktemplate.
'''
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = False
def run_test(self):
print("Warning: this test will take about 70 seconds in the best case. Be patient.")
self.nodes[0].generate(10)

View File

@ -99,7 +99,6 @@ class GetBlockTemplateProposalTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = False
def setup_network(self):
self.nodes = self.setup_nodes()

View File

@ -13,10 +13,6 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal
class GetChainTipsTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = False
def run_test (self):

View File

@ -15,7 +15,7 @@ class GetMiningInfoTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 1
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)

View File

@ -22,7 +22,7 @@ class GetrawtransactionTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 3
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self):
# -insightexplorer causes spentindex to be enabled (fSpentIndex = true)

View File

@ -18,7 +18,6 @@ class HTTPBasicsTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 3
self.setup_clean_chain = False
def setup_network(self):
self.nodes = self.setup_nodes()

View File

@ -17,7 +17,7 @@ import time
class InvalidateTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 3
def setup_network(self):

View File

@ -19,7 +19,7 @@ class KeyImportExportTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir )

View File

@ -87,7 +87,6 @@ class KeyPoolTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = False
self.num_nodes = 1
def setup_network(self):

View File

@ -32,10 +32,6 @@ def check_array_result(object_array, to_match, expected):
raise AssertionError("No objects matched %s"%(str(to_match)))
class ListTransactionsTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = False
def run_test(self):
# Simple send, 0 to 1:

View File

@ -88,7 +88,7 @@ class MaxBlocksInFlightTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 1
def setup_network(self):

View File

@ -40,7 +40,7 @@ class MempoolLimit(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 4
def run_test(self):

View File

@ -26,7 +26,7 @@ class MempoolUpgradeActivationTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self):
args = ["-checkmempool", "-debug=mempool", "-blockmaxsize=4000",

View File

@ -19,7 +19,6 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 2
self.setup_clean_chain = False
alert_filename = None # Set by setup_network

View File

@ -21,7 +21,6 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 1
self.setup_clean_chain = False
def setup_network(self):
# Just need one node for this test

View File

@ -26,7 +26,6 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 1
self.setup_clean_chain = False
def setup_network(self):
# Just need one node for this test

View File

@ -19,7 +19,7 @@ class MerkleBlockTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 4
def setup_network(self):

View File

@ -26,7 +26,7 @@ class ShieldCoinbaseTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def start_node_with(self, index, extra_args=[]):
args = [

View File

@ -19,7 +19,6 @@ class HTTPBasicsTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = False
self.num_nodes = 1
def setup_chain(self):

View File

@ -17,11 +17,6 @@ import urllib.parse
class NodeHandlingTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = False
def run_test(self):
###########################
# setban/listbanned tests #

View File

@ -27,7 +27,7 @@ class NuparamsTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 1
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self, split=False):
args = [[

View File

@ -28,7 +28,7 @@ class OrchardReorgTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_nodes(self):
return start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[

View File

@ -120,7 +120,7 @@ class AcceptBlockTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 2
def setup_network(self):

View File

@ -17,7 +17,7 @@ class TxExpiringSoonTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 3
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)

View File

@ -17,7 +17,7 @@ class TxExpiryDoSTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 1
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)

View File

@ -38,8 +38,6 @@ addnode connect to generic DNS name
class ProxyTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = False
self.have_ipv6 = test_ipv6_local()
# Create two proxies on different ports

View File

@ -27,7 +27,7 @@ class PruneTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 3
self.utxo = []

View File

@ -21,7 +21,7 @@ class RawTransactionsTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 3
def setup_network(self, split=False):

View File

@ -54,11 +54,6 @@ def check_array_result(object_array, to_match, expected, should_not_find = False
class ReceivedByTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = False
def run_test(self):
'''
listreceivedbyaddress Test

View File

@ -17,7 +17,7 @@ class ReindexTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 1
def setup_network(self):

View File

@ -53,7 +53,7 @@ class RESTTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 3
def setup_network(self, split=False):

View File

@ -18,7 +18,7 @@ class RewindBlockIndexTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 3
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self, split=False):
# Node 0 - Overwinter, then Sprout, then Overwinter again

View File

@ -29,7 +29,7 @@ class RPCBindTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 1
def setup_network(self):

View File

@ -45,7 +45,7 @@ class SaplingRewindTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 3
self.setup_clean_chain = True
self.cache_behavior = 'clean'
# This mirrors how the network was setup in the bash test
def setup_network(self, split=False):

View File

@ -17,7 +17,7 @@ class ShorterBlockTimes(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_nodes(self):
return start_nodes(self.num_nodes, self.options.tmpdir, [[

View File

@ -13,7 +13,7 @@ class SignRawTransactionsTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 1
def setup_network(self, split=False):

View File

@ -146,7 +146,6 @@ class EstimateFeeTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 3
self.setup_clean_chain = False
def setup_network(self):
'''

View File

@ -5,8 +5,8 @@
from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_true, get_coinbase_address, \
start_nodes, wait_and_assert_operationid_status, \
from test_framework.util import assert_equal, assert_true, \
start_nodes, \
wait_and_assert_operationid_status_result, DEFAULT_FEE
SAPLING_ADDR = 'zregtestsapling1ssqj3f3majnl270985gqcdqedd9t4nlttjqskccwevj2v20sc25deqspv3masufnwcdy67cydyy'
@ -52,7 +52,7 @@ class SproutSaplingMigration(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = True
self.cache_behavior = 'sprout'
def setup_nodes(self):
extra_args = [[
@ -67,17 +67,17 @@ class SproutSaplingMigration(BitcoinTestFramework):
assert_equal(0, len(extra_args[1]))
return start_nodes(self.num_nodes, self.options.tmpdir, extra_args)
def run_migration_test(self, node, sproutAddr, saplingAddr, target_height):
def run_migration_test(self, node, sproutAddr, saplingAddr, target_height, sprout_initial_balance):
# Make sure we are in a good state to run the test
assert_equal(102, node.getblockcount() % 500, "Should be at block 102 % 500")
assert_equal(node.z_getbalance(sproutAddr), Decimal('10'))
assert_equal(200, node.getblockcount() % 500, "Should be at block 200 % 500")
assert_equal(node.z_getbalance(sproutAddr), sprout_initial_balance)
assert_equal(node.z_getbalance(saplingAddr), Decimal('0'))
check_migration_status(node, saplingAddr, DISABLED_BEFORE_MIGRATION)
# Migrate
node.z_setmigration(True)
print("Mining to block 494 % 500...")
node.generate(392) # 102 % 500 -> 494 % 500
node.generate(294) # 200 % 500 -> 494 % 500
self.sync_all()
# At 494 % 500 we should have no async operations
@ -90,7 +90,7 @@ class SproutSaplingMigration(BitcoinTestFramework):
# At 495 % 500 we should have an async operation
operationstatus = node.z_getoperationstatus()
print("migration operation: {}".format(operationstatus))
assert_equal(1, len(operationstatus), "num async operations at 495 % 500")
assert_equal(1, len(operationstatus), "num async operations at 495 % 500")
assert_equal('saplingmigration', operationstatus[0]['method'])
assert_equal(target_height, operationstatus[0]['target_height'])
@ -109,7 +109,7 @@ class SproutSaplingMigration(BitcoinTestFramework):
# At 498 % 500 the mempool will be empty and no funds will have moved
assert_equal(0, len(node.getrawmempool()), "mempool size at 498 % 500")
assert_equal(node.z_getbalance(sproutAddr), Decimal('10'))
assert_equal(node.z_getbalance(sproutAddr), sprout_initial_balance)
assert_equal(node.z_getbalance(saplingAddr), Decimal('0'))
node.generate(1)
@ -125,7 +125,7 @@ class SproutSaplingMigration(BitcoinTestFramework):
# Check that unmigrated amount + unfinalized = starting balance - fee
status = node.z_getmigrationstatus()
print("status: {}".format(status))
assert_equal(Decimal('10.0') - DEFAULT_FEE, Decimal(status['unmigrated_amount']) + Decimal(status['unfinalized_migrated_amount']))
assert_equal(sprout_initial_balance - DEFAULT_FEE, Decimal(status['unmigrated_amount']) + Decimal(status['unfinalized_migrated_amount']))
# The transaction in the mempool should be the one listed in migration_txids,
# and it should expire at the next 450 % 500.
@ -142,9 +142,9 @@ class SproutSaplingMigration(BitcoinTestFramework):
sprout_balance = node.z_getbalance(sproutAddr)
sapling_balance = node.z_getbalance(saplingAddr)
print("sprout balance: {}, sapling balance: {}".format(sprout_balance, sapling_balance))
assert_true(sprout_balance < Decimal('10'), "Should have less Sprout funds")
assert_true(sprout_balance < sprout_initial_balance, "Should have less Sprout funds")
assert_true(sapling_balance > Decimal('0'), "Should have more Sapling funds")
assert_true(sprout_balance + sapling_balance, Decimal('10.0') - DEFAULT_FEE)
assert_true(sprout_balance + sapling_balance, sprout_initial_balance - DEFAULT_FEE)
check_migration_status(node, saplingAddr, DURING_MIGRATION)
# At 10 % 500 the transactions will be considered 'finalized'
@ -156,59 +156,34 @@ class SproutSaplingMigration(BitcoinTestFramework):
assert_equal(sprout_balance, Decimal(status['unmigrated_amount']))
assert_equal(sapling_balance, Decimal(status['finalized_migrated_amount']))
def send_to_sprout_zaddr(self, tAddr, sproutAddr):
# Send some ZEC to a Sprout address
result = self.nodes[0].z_shieldcoinbase(tAddr, sproutAddr, 0, 1)
wait_and_assert_operationid_status(self.nodes[0], result['opid'])
self.nodes[0].generate(1)
self.sync_all()
def run_test(self):
# Wallet RPCs that depend on accurate chain state are blocked while in IBD. This
# test starts from a clean chain state, so we need to mine a single block first to
# ensure that the chain tip's block time is within 24 hours of the current time.
#
# We mine 2 blocks because we need to make two transparent->Sprout spends below
# (to load Sprout addresses with funds), and `get_coinbase_address` only selects
# a coinbase address with spendable coins. If we only mined one block here and 100
# below, the selected coinbase address would only have one coin (due to the way
# the `generate` RPC uses one address per call).
print("Mining blocks...")
self.nodes[0].generate(2)
self.sync_all()
# Check enabling via '-migration' and disabling via rpc
check_migration_status(self.nodes[0], SAPLING_ADDR, ENABLED_NO_FUNDS)
check_migration_status(self.nodes[0], SAPLING_ADDR, ENABLED_BEFORE_MIGRATION)
self.nodes[0].z_setmigration(False)
check_migration_status(self.nodes[0], SAPLING_ADDR, DISABLED_NO_FUNDS)
check_migration_status(self.nodes[0], SAPLING_ADDR, DISABLED_BEFORE_MIGRATION)
print("Running test using '-migrationdestaddress'...")
# 1. Test using self.nodes[0] which has the parameter
print("Running test using '-migrationdestaddress'...")
self.nodes[0].generate(99)
self.sync_all()
tAddr = get_coinbase_address(self.nodes[0])
# Import a previously generated key to test '-migrationdestaddress'
self.nodes[0].z_importkey(SAPLING_KEY)
sproutAddr0 = self.nodes[0].z_getnewaddress('sprout')
sproutAddr0 = self.nodes[0].listaddresses()[0]['sprout']['addresses'][0]
self.send_to_sprout_zaddr(tAddr, sproutAddr0)
self.run_migration_test(self.nodes[0], sproutAddr0, SAPLING_ADDR, 500)
self.run_migration_test(self.nodes[0], sproutAddr0, SAPLING_ADDR, 500, Decimal('50'))
# Disable migration so only self.nodes[1] has a transaction in the mempool at block 999
self.nodes[0].z_setmigration(False)
# 2. Test using self.nodes[1] which will use the default Sapling address
print("Running test using default Sapling address...")
# Mine more blocks so we start at 102 % 500
# Mine more blocks so we start at 200 % 500
print("Mining blocks...")
self.nodes[1].generate(91) # 511 -> 602
self.nodes[1].generate(190) # 510 -> 700
self.sync_all()
sproutAddr1 = self.nodes[1].z_getnewaddress('sprout')
sproutAddr1 = self.nodes[1].listaddresses()[0]['sprout']['addresses'][0]
saplingAddr1 = self.nodes[1].z_getnewaddress('sapling')
self.send_to_sprout_zaddr(tAddr, sproutAddr1)
self.run_migration_test(self.nodes[1], sproutAddr1, saplingAddr1, 1000)
self.run_migration_test(self.nodes[1], sproutAddr1, saplingAddr1, 1000, Decimal('50'))
if __name__ == '__main__':

View File

@ -26,7 +26,6 @@ from .util import (
wait_bitcoinds,
enable_coverage,
check_json_precision,
initialize_chain_clean,
PortSeed,
)
@ -35,7 +34,7 @@ class BitcoinTestFramework(object):
def __init__(self):
self.num_nodes = 4
self.setup_clean_chain = False
self.cache_behavior = 'current'
self.nodes = None
def run_test(self):
@ -46,10 +45,7 @@ class BitcoinTestFramework(object):
def setup_chain(self):
print("Initializing test directory "+self.options.tmpdir)
if self.setup_clean_chain:
initialize_chain_clean(self.options.tmpdir, self.num_nodes)
else:
initialize_chain(self.options.tmpdir, self.num_nodes, self.options.cachedir)
initialize_chain(self.options.tmpdir, self.num_nodes, self.options.cachedir, self.cache_behavior)
def setup_nodes(self):
return start_nodes(self.num_nodes, self.options.tmpdir)
@ -192,7 +188,7 @@ class ComparisonTestFramework(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 1
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def add_options(self, parser):
parser.add_option("--testbinary", dest="testbinary",

View File

@ -20,6 +20,7 @@ import http.client
import random
import shutil
import subprocess
import tarfile
import tempfile
import time
import re
@ -170,7 +171,7 @@ def sync_mempools(rpc_connections, wait=0.5, timeout=60):
bitcoind_processes = {}
def initialize_datadir(dirname, n):
def initialize_datadir(dirname, n, clock_offset=0):
datadir = os.path.join(dirname, "node"+str(n))
if not os.path.isdir(datadir):
os.makedirs(datadir)
@ -183,6 +184,9 @@ def initialize_datadir(dirname, n):
f.write("port="+str(p2p_port(n))+"\n")
f.write("rpcport="+str(rpc_port(n))+"\n")
f.write("listenonion=0\n")
if clock_offset != 0:
f.write('clockoffset='+str(clock_offset)+'\n')
return datadir
def rpc_auth_pair(n):
@ -220,42 +224,30 @@ def wait_for_bitcoind_start(process, url, i):
raise # unknown JSON RPC exception
time.sleep(0.25)
def initialize_chain(test_dir, num_nodes, cachedir):
def initialize_chain(test_dir, num_nodes, cachedir, cache_behavior='current'):
"""
Create a cache of a 200-block-long chain (with wallet) for MAX_NODES
Afterward, create num_nodes copies from the cache
Create a set of node datadirs in `test_dir`, based upon the specified
`cache_behavior` value. The following values are recognized for
`cache_behavior`:
* 'current': create a 200-block-long chain (with wallet) for MAX_NODES
in `cachedir` if necessary. Afterward, create num_nodes copies in
`test_dir` from the cache. The resulting nodes will be configured to
use the -clockoffset config argument when starting to ensure that
the cached chain is not treated as being excessively out-of-date.
* 'sprout': use persisted chain data containing known amounts of Sprout
funds from the files in `qa/rpc-tests/cache/sprout`. This allows
testing of Sprout spends even though Sprout outputs can no longer
be created by zcashd software. The resulting nodes will be configured to
use the -clockoffset config argument when starting to ensure that
the cached chain is not treated as being excessively out-of-date.
* 'fresh': force re-creation of the cache, and then start as for `current`.
* 'clean': start the nodes without cached chain data, allowing the test
to take full control of chain setup.
"""
# Due to the consensus change fix for the timejacking attack, we need to
# ensure that the cache is pretty fresh. Specifically, we need the median
# time past of the chain tip of the cache to be no more than 90 minutes
# behind the current local time, or else mined blocks will be rejected by
# all nodes, halting the test. With Sapling active by default, this requires
# the chain tip itself to be no more than 75 minutes behind the current
# local time.
#
# We address this here, by regenerating the cache if it is more than 60
# minutes old. This gives 15 minutes of slack initially that an RPC test has
# to complete in, if it is started right at the oldest cache time. Within an
# individual test, the first five calls to `generate` will each advance the
# median time past of the chain tip by 2.5 minutes (with Sapling active by
# default). Therefore, if the logic between the completion of any two
# adjacent calls to `generate` within a test takes longer than 2.5 minutes,
# the excess will subtract from the slack.
if os.path.isdir(os.path.join(cachedir, "node0")):
if os.stat(cachedir).st_mtime + (60 * 60) < time.time():
print("initialize_chain(): Removing stale cache")
shutil.rmtree(cachedir)
assert num_nodes <= MAX_NODES
create_cache = False
for i in range(MAX_NODES):
if not os.path.isdir(os.path.join(cachedir, 'node'+str(i))):
create_cache = True
break
if create_cache:
def rebuild_cache():
#find and delete old cache directories if any exist
for i in range(MAX_NODES):
if os.path.isdir(os.path.join(cachedir,"node"+str(i))):
@ -264,7 +256,7 @@ def initialize_chain(test_dir, num_nodes, cachedir):
# Create cache directories, run bitcoinds:
block_time = int(time.time()) - (200 * PRE_BLOSSOM_BLOCK_TARGET_SPACING)
for i in range(MAX_NODES):
datadir=initialize_datadir(cachedir, i)
datadir = initialize_datadir(cachedir, i)
args = [ os.getenv("ZCASHD", ZCASHD_BINARY), "-keypool=1", "-datadir="+datadir, "-discover=0" ]
args.extend([
'-nuparams=5ba81b19:1', # Overwinter
@ -311,16 +303,70 @@ def initialize_chain(test_dir, num_nodes, cachedir):
stop_nodes(rpcs)
wait_bitcoinds()
for i in range(MAX_NODES):
# record the system time at which the cache was regenerated
with open(log_filename(cachedir, i, 'cache_config.json'), "w", encoding="utf8") as cache_conf_file:
cache_config = { "cache_time": time.time() }
cache_conf_json = json.dumps(cache_config, indent=4)
cache_conf_file.write(cache_conf_json)
os.remove(log_filename(cachedir, i, "debug.log"))
os.remove(log_filename(cachedir, i, "db.log"))
os.remove(log_filename(cachedir, i, "peers.dat"))
os.remove(log_filename(cachedir, i, "fee_estimates.dat"))
for i in range(num_nodes):
from_dir = os.path.join(cachedir, "node"+str(i))
to_dir = os.path.join(test_dir, "node"+str(i))
shutil.copytree(from_dir, to_dir)
initialize_datadir(test_dir, i) # Overwrite port/rpcport in zcash.conf
def init_from_cache():
for i in range(num_nodes):
from_dir = os.path.join(cachedir, "node"+str(i))
to_dir = os.path.join(test_dir, "node"+str(i))
shutil.copytree(from_dir, to_dir)
with open(os.path.join(to_dir, 'regtest', 'cache_config.json'), "r", encoding="utf8") as cache_conf_file:
cache_conf = json.load(cache_conf_file)
# obtain the clock offset as a negative number of seconds
offset = round(cache_conf['cache_time']) - round(time.time())
# overwrite port/rpcport and clock offset in zcash.conf
initialize_datadir(test_dir, i, clock_offset=offset)
def init_sprout():
assert num_nodes <= 4 # only 4 nodes with Sprout funds are supported
sprout_cache_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'cache', 'sprout')
for i in range(num_nodes):
to_dir = os.path.join(test_dir, "node"+str(i), "regtest")
os.makedirs(to_dir)
# Unzip the persisted Sprout config file
with tarfile.open(os.path.join(sprout_cache_path, "chain_cache.tar.gz"), "r:gz") as tgz:
tgz.extractall(path = to_dir)
with tarfile.open(os.path.join(sprout_cache_path, "node"+str(i)+"_wallet.tar.gz"), "r:gz") as tgz:
tgz.extractall(path = os.path.join(to_dir, "wallet.dat"))
with open(os.path.join(to_dir, 'cache_config.json'), "r", encoding="utf8") as cache_conf_file:
cache_conf = json.load(cache_conf_file)
# obtain the clock offset as a negative number of seconds
offset = round(cache_conf['cache_time']) - round(time.time())
# overwrite port/rpcport and clock offset in zcash.conf
initialize_datadir(test_dir, i, clock_offset=offset)
def cache_rebuild_required():
for i in range(MAX_NODES):
node_path = os.path.join(cachedir, 'node'+str(i))
if os.path.isdir(node_path):
if not os.path.isfile(log_filename(cachedir, i, 'cache_config.json')):
return True
else:
return True
return False
if cache_behavior == 'current':
if cache_rebuild_required(): rebuild_cache()
init_from_cache()
elif cache_behavior == 'sprout':
init_sprout()
elif cache_behavior == 'fresh':
rebuild_cache()
init_from_cache()
elif cache_behavior == 'clean':
initialize_chain_clean(test_dir, num_nodes)
else:
raise Exception('Cache behavior %s not recognized' % cache_behavior)
def initialize_chain_clean(test_dir, num_nodes):
"""

View File

@ -10,7 +10,7 @@ class ThreeOfThreeRestoreTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 4
def setup_network(self, split=False):

View File

@ -48,7 +48,7 @@ class TurnstileTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 3
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir)

View File

@ -15,11 +15,6 @@ from test_framework.util import assert_equal, connect_nodes, \
class TxnMallTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = False
def add_options(self, parser):
parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true",
help="Test double-spend of 1-confirmed transaction")

View File

@ -15,7 +15,7 @@ class WalletTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 4
def setup_network(self, split=False):

View File

@ -20,7 +20,7 @@ class WalletAddressesTest(BitcoinTestFramework):
super().__init__()
# need 2 nodes to import addresses
self.num_nodes = 2
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self):
self.nodes = start_nodes(

View File

@ -30,7 +30,7 @@ class ListReceivedTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 3
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self):
self.nodes = start_nodes(

View File

@ -22,7 +22,7 @@ class WalletOverwinterTxTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.num_nodes = 4
self.setup_clean_chain = True
self.cache_behavior = 'clean'
def setup_network(self, split=False):
self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, extra_args=[[

View File

@ -53,7 +53,7 @@ class WalletBackupTest(BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 4
# This mirrors how the network was setup in the bash test

View File

@ -14,7 +14,7 @@ class ZapWalletTXesTest (BitcoinTestFramework):
def __init__(self):
super().__init__()
self.setup_clean_chain = True
self.cache_behavior = 'clean'
self.num_nodes = 3
def setup_network(self, split=False):