diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 20f53a60d7..2a94034a57 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -417,10 +417,10 @@ class CCustomParams : public CRegTestParams { consensus.nSubsidyHalvingInterval = args.GetArg("-con_nsubsidyhalvinginterval", consensus.nSubsidyHalvingInterval); consensus.BIP16Exception = uint256S(args.GetArg("-con_bip16exception", "0x0")); - consensus.BIP34Height = args.GetArg("-con_bip34height", consensus.BIP34Height); + consensus.BIP34Height = args.GetArg("-con_bip34height", 0); consensus.BIP34Hash = uint256S(args.GetArg("-con_bip34hash", "0x0")); - consensus.BIP65Height = args.GetArg("-con_bip65height", consensus.BIP65Height); - consensus.BIP66Height = args.GetArg("-con_bip66height", consensus.BIP66Height); + consensus.BIP65Height = args.GetArg("-con_bip65height", 0); + consensus.BIP66Height = args.GetArg("-con_bip66height", 0); consensus.powLimit = uint256S(args.GetArg("-con_powlimit", "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); consensus.nPowTargetTimespan = args.GetArg("-con_npowtargettimespan", consensus.nPowTargetTimespan); consensus.nPowTargetSpacing = args.GetArg("-con_npowtargetspacing", consensus.nPowTargetSpacing); diff --git a/test/bitcoin_functional/functional/test_framework/util.py b/test/bitcoin_functional/functional/test_framework/util.py index 9b2129cd67..145f8ceabe 100644 --- a/test/bitcoin_functional/functional/test_framework/util.py +++ b/test/bitcoin_functional/functional/test_framework/util.py @@ -309,6 +309,9 @@ def initialize_datadir(dirname, n, chain): f.write("con_connect_coinbase=0\n") f.write("anyonecanspendaremine=0\n") f.write("con_blockheightinheader=0\n") + f.write("con_bip34height=100000000\n") + f.write("con_bip65height=1351\n") + f.write("con_bip66height=1251\n") os.makedirs(os.path.join(datadir, 'stderr'), exist_ok=True) os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True) return datadir diff --git a/test/functional/feature_block_v4.py b/test/functional/feature_block_v4.py new file mode 100755 index 0000000000..0f5ace0cd0 --- /dev/null +++ b/test/functional/feature_block_v4.py @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2018 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +"""Test BIP 34, 65, 66 activation at block 0""" + +from test_framework.blocktools import create_coinbase, create_block, create_transaction +from test_framework.messages import msg_block +from test_framework.mininode import mininode_lock, P2PInterface +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import assert_equal, wait_until + +from feature_cltv import cltv_validate, REJECT_OBSOLETE + +class BlockV4Test(BitcoinTestFramework): + def set_test_params(self): + self.num_nodes = 1 + self.extra_args = [['-whitelist=127.0.0.1', '-con_bip34height=0', '-con_bip65height=0', '-con_bip66height=0']] + self.setup_clean_chain = True + + def run_test(self): + self.nodes[0].add_p2p_connection(P2PInterface()) + + self.nodeaddress = self.nodes[0].getnewaddress() + + self.log.info("Test that blocks past the genesis block must be at least version 4") + + # Create a v3 block + tip = self.nodes[0].getbestblockhash() + block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 + block = create_block(int(tip, 16), create_coinbase(1), block_time) + block.nVersion = 3 + block.solve() + + # Send it to the node + self.nodes[0].p2p.send_and_ping(msg_block(block)) + + # The best block should not have changed, because... + assert_equal(self.nodes[0].getbestblockhash(), tip) + + # ... we rejected it because it is v3 + wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock) + with mininode_lock: + assert_equal(self.nodes[0].p2p.last_message["reject"].code, REJECT_OBSOLETE) + assert_equal(self.nodes[0].p2p.last_message["reject"].reason, b'bad-version(0x00000003)') + assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256) + del self.nodes[0].p2p.last_message["reject"] + + self.log.info("Test that a version 4 block with a valid-according-to-CLTV transaction is accepted") + + # Generate 100 blocks so that first coinbase matures + generated_blocks = self.nodes[0].generate(100) + spendable_coinbase_txid = self.nodes[0].getblock(generated_blocks[0])['tx'][0] + tip = generated_blocks[-1] + + # Construct a v4 block + block_time = self.nodes[0].getblockheader(tip)['mediantime'] + 1 + block = create_block(int(tip, 16), create_coinbase(len(generated_blocks) + 1), block_time) + block.nVersion = 4 + + # Create a CLTV transaction + spendtx = create_transaction(self.nodes[0], spendable_coinbase_txid, + self.nodeaddress, amount=1.0) + spendtx = cltv_validate(self.nodes[0], spendtx, 1) + spendtx.rehash() + + # Add the CLTV transaction and prepare for sending + block.vtx.append(spendtx) + block.hashMerkleRoot = block.calc_merkle_root() + block.solve() + + # Send block and check that it becomes new best block + self.nodes[0].p2p.send_and_ping(msg_block(block)) + assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.sha256) + +if __name__ == '__main__': + BlockV4Test().main() diff --git a/test/functional/test_framework/util.py b/test/functional/test_framework/util.py index 7630e32266..d250fd117d 100644 --- a/test/functional/test_framework/util.py +++ b/test/functional/test_framework/util.py @@ -308,6 +308,9 @@ def initialize_datadir(dirname, n, chain): f.write("con_blocksubsidy=5000000000\n") f.write("con_connect_coinbase=0\n") f.write("anyonecanspendaremine=0\n") + f.write("con_bip34height=100000000\n") + f.write("con_bip65height=1351\n") + f.write("con_bip66height=1251\n") os.makedirs(os.path.join(datadir, 'stderr'), exist_ok=True) os.makedirs(os.path.join(datadir, 'stdout'), exist_ok=True) return datadir diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py index d709ddbdbc..ea821d2223 100755 --- a/test/functional/test_runner.py +++ b/test/functional/test_runner.py @@ -170,6 +170,7 @@ 'feature_mandatory_coinbase.py', 'feature_block_subsidy.py', 'feature_connect_coinbase.py', + 'feature_block_v4.py' # Don't append tests at the end to avoid merge conflicts # Put them in a random line within the section that fits their approximate run-time ]