diff --git a/test/functional/abc-miner-fund.py b/test/functional/abc-miner-fund.py --- a/test/functional/abc-miner-fund.py +++ b/test/functional/abc-miner-fund.py @@ -3,7 +3,11 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -from test_framework.blocktools import (create_block, create_coinbase) +from test_framework.blocktools import ( + create_block, + create_coinbase, + TIME_GENESIS_BLOCK, +) from test_framework.messages import ToHex from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( @@ -26,6 +30,7 @@ class MinerFundTest(BitcoinTestFramework): def set_test_params(self): + self.setup_clean_chain = True self.num_nodes = 1 self.extra_args = [ ['-enableminerfund', "-phononactivationtime={}".format(PHONON_ACTIVATION_TIME)]] @@ -38,6 +43,14 @@ node = self.nodes[0] address = node.get_deterministic_priv_key().address + self.log.info('Create some old blocks') + for t in range(TIME_GENESIS_BLOCK, + TIME_GENESIS_BLOCK + 200 * 600, 600): + # ten-minute steps from genesis block time + self.nodes[0].setmocktime(t) + self.nodes[0].generatetoaddress(1, address) + assert_equal(self.nodes[0].getblockchaininfo()['blocks'], 200) + # Get the vote started. node.setmocktime(1580000000) diff --git a/test/functional/feature_proxy.py b/test/functional/feature_proxy.py --- a/test/functional/feature_proxy.py +++ b/test/functional/feature_proxy.py @@ -50,6 +50,7 @@ class ProxyTest(BitcoinTestFramework): def set_test_params(self): self.num_nodes = 4 + self.setup_clean_chain = True def setup_nodes(self): self.have_ipv6 = test_ipv6_local() diff --git a/test/functional/mempool_accept.py b/test/functional/mempool_accept.py --- a/test/functional/mempool_accept.py +++ b/test/functional/mempool_accept.py @@ -25,7 +25,6 @@ from test_framework.util import ( assert_equal, assert_raises_rpc_error, - wait_until, ) @@ -34,7 +33,6 @@ self.num_nodes = 1 self.extra_args = [[ '-txindex', - '-reindex', # Need reindex for txindex '-acceptnonstdtxn=0', # Try to mimic main-net ]] * self.num_nodes @@ -53,7 +51,7 @@ self.log.info('Start with empty mempool, and 200 blocks') self.mempool_size = 0 - wait_until(lambda: node.getblockcount() == 200) + assert_equal(node.getblockcount(), 200) assert_equal(node.getmempoolinfo()['size'], self.mempool_size) coins = node.listunspent() diff --git a/test/functional/rpc_blockchain.py b/test/functional/rpc_blockchain.py --- a/test/functional/rpc_blockchain.py +++ b/test/functional/rpc_blockchain.py @@ -36,6 +36,7 @@ from test_framework.blocktools import ( create_block, create_coinbase, + TIME_GENESIS_BLOCK, ) from test_framework.messages import ( msg_block, @@ -48,9 +49,12 @@ class BlockchainTest(BitcoinTestFramework): def set_test_params(self): + self.setup_clean_chain = True self.num_nodes = 1 def run_test(self): + self.mine_chain() + # Set extra args with pruning after rescan is complete self.restart_node(0, extra_args=['-stopatheight=207', '-prune=1']) @@ -66,6 +70,16 @@ self._test_getblock() assert self.nodes[0].verifychain(4, 0) + def mine_chain(self): + self.log.info('Create some old blocks') + address = self.nodes[0].get_deterministic_priv_key().address + for t in range(TIME_GENESIS_BLOCK, + TIME_GENESIS_BLOCK + 200 * 600, 600): + # ten-minute steps from genesis block time + self.nodes[0].setmocktime(t) + self.nodes[0].generatetoaddress(1, address) + assert_equal(self.nodes[0].getblockchaininfo()['blocks'], 200) + def _test_getblockchaininfo(self): self.log.info("Test getblockchaininfo") @@ -403,9 +417,11 @@ def _test_getblock(self): # Checks for getblock verbose outputs node = self.nodes[0] - blockinfo = node.getblock(node.getblockhash(1), 2) + (blockhash, nextblockhash) = node.generate(2) + + blockinfo = node.getblock(blockhash, 2) transactioninfo = node.gettransaction(blockinfo['tx'][0]['txid']) - blockheaderinfo = node.getblockheader(node.getblockhash(1), True) + blockheaderinfo = node.getblockheader(blockhash, True) assert_equal(blockinfo['hash'], transactioninfo['blockhash']) assert_equal( @@ -429,6 +445,7 @@ assert_equal( blockinfo['previousblockhash'], blockheaderinfo['previousblockhash']) + assert_equal(blockinfo['nextblockhash'], nextblockhash) assert_equal( blockinfo['nextblockhash'], blockheaderinfo['nextblockhash']) diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -30,7 +30,6 @@ p2p_port, PortSeed, rpc_port, - set_node_times, sync_blocks, sync_mempools, ) @@ -79,7 +78,6 @@ self.setup_clean_chain = False self.nodes = [] self.network_thread = None - self.mocktime = 0 # Wait for up to 60 seconds for the RPC server to respond self.rpc_timeout = 60 self.supports_cli = False @@ -259,6 +257,19 @@ self.add_nodes(self.num_nodes, extra_args) self.start_nodes() self.import_deterministic_coinbase_privkeys() + if not self.setup_clean_chain: + for n in self.nodes: + assert_equal(n.getblockchaininfo()["blocks"], 199) + # To ensure that all nodes are out of IBD, the most recent block + # must have a timestamp not too old (see IsInitialBlockDownload()). + self.log.debug('Generate a block with current time') + block_hash = self.nodes[0].generate(1)[0] + block = self.nodes[0].getblock(blockhash=block_hash, verbosity=0) + for n in self.nodes: + n.submitblock(block) + chain_info = n.getblockchaininfo() + assert_equal(chain_info["blocks"], 200) + assert_equal(chain_info["initialblockdownload"], False) def import_deterministic_coinbase_privkeys(self): for n in self.nodes: @@ -307,7 +318,6 @@ timewait=self.rpc_timeout, bitcoind=binary[i], bitcoin_cli=self.options.bitcoincli, - mocktime=self.mocktime, coverage_dir=self.options.coveragedir, extra_conf=extra_confs[i], extra_args=extra_args[i], @@ -436,7 +446,7 @@ def _initialize_chain(self): """Initialize a pre-mined blockchain for use by the test. - Create a cache of a 200-block-long chain (with wallet) for MAX_NODES + Create a cache of a 199-block-long chain (with wallet) for MAX_NODES Afterward, create num_nodes copies from the cache.""" assert self.num_nodes <= MAX_NODES @@ -470,7 +480,6 @@ timewait=self.rpc_timeout, bitcoind=self.options.bitcoind, bitcoin_cli=self.options.bitcoincli, - mocktime=self.mocktime, coverage_dir=None, emulator=self.options.emulator, )) @@ -489,33 +498,23 @@ for node in self.nodes: node.wait_for_rpc_connection() - # For backward compatibility of the python scripts with previous - # versions of the cache, set mocktime to Jan 1, - # 2014 + (201 * 10 * 60) - self.mocktime = 1388534400 + (201 * 10 * 60) - - # Create a 200-block-long chain; each of the 4 first nodes + # Create a 199-block-long chain; each of the 4 first nodes # gets 25 mature blocks and 25 immature. - # Note: To preserve compatibility with older versions of - # initialize_chain, only 4 nodes will generate coins. - # - # blocks are created with timestamps 10 minutes apart - # starting from 2010 minutes in the past - block_time = self.mocktime - (201 * 10 * 60) - for i in range(2): - for peer in range(4): - for j in range(25): - set_node_times(self.nodes, block_time) - self.nodes[peer].generatetoaddress( - 1, self.nodes[peer].get_deterministic_priv_key().address) - block_time += 10 * 60 - # Must sync before next peer starts generating blocks - sync_blocks(self.nodes) + # The 4th node gets only 24 immature blocks so that the very last + # block in the cache does not age too much (have an old tip age). + # This is needed so that we are out of IBD when the test starts, + # see the tip age check in IsInitialBlockDownload(). + for i in range(8): + self.nodes[0].generatetoaddress( + 25 if i != 7 else 24, self.nodes[i % 4].get_deterministic_priv_key().address) + sync_blocks(self.nodes) + + for n in self.nodes: + assert_equal(n.getblockchaininfo()["blocks"], 199) # Shut them down, and clean up cache directories: self.stop_nodes() self.nodes = [] - self.mocktime = 0 def cache_path(n, *paths): return os.path.join(get_datadir_path( diff --git a/test/functional/test_framework/test_node.py b/test/functional/test_framework/test_node.py --- a/test/functional/test_framework/test_node.py +++ b/test/functional/test_framework/test_node.py @@ -58,7 +58,7 @@ be dispatched to the RPC connection.""" def __init__(self, i, datadir, *, chain, host, rpc_port, p2p_port, timewait, bitcoind, bitcoin_cli, - mocktime, coverage_dir, extra_conf=None, extra_args=None, use_cli=False, emulator=None): + coverage_dir, extra_conf=None, extra_args=None, use_cli=False, emulator=None): self.index = i self.datadir = datadir self.bitcoinconf = os.path.join(self.datadir, "bitcoin.conf") @@ -90,7 +90,6 @@ "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", - "-mocktime=" + str(mocktime), "-uacomment=" + self.name, "-noprinttoconsole", ] diff --git a/test/functional/wallet_create_tx.py b/test/functional/wallet_create_tx.py --- a/test/functional/wallet_create_tx.py +++ b/test/functional/wallet_create_tx.py @@ -7,17 +7,25 @@ from test_framework.util import ( assert_equal, ) +from test_framework.blocktools import ( + TIME_GENESIS_BLOCK, +) class CreateTxWalletTest(BitcoinTestFramework): def set_test_params(self): - self.setup_clean_chain = False + self.setup_clean_chain = True self.num_nodes = 1 def skip_test_if_missing_module(self): self.skip_if_no_wallet() def run_test(self): + self.log.info('Create some old blocks') + self.nodes[0].setmocktime(TIME_GENESIS_BLOCK) + self.nodes[0].generate(200) + self.nodes[0].setmocktime(0) + self.log.info( 'Check that we have some (old) blocks and that anti-fee-sniping is disabled') assert_equal(self.nodes[0].getblockchaininfo()['blocks'], 200) diff --git a/test/functional/wallet_txn_doublespend.py b/test/functional/wallet_txn_doublespend.py --- a/test/functional/wallet_txn_doublespend.py +++ b/test/functional/wallet_txn_doublespend.py @@ -36,6 +36,14 @@ def run_test(self): # All nodes should start with 1,250 BCH: starting_balance = 1250 + + # All nodes should be out of IBD. + # If the nodes are not all out of IBD, that can interfere with + # blockchain sync later in the test when nodes are connected, due to + # timing issues. + for n in self.nodes: + assert n.getblockchaininfo()["initialblockdownload"] is False + for i in range(4): assert_equal(self.nodes[i].getbalance(), starting_balance) # bug workaround, coins generated assigned to first getnewaddress!