From eaab39235bbc5e1fa787ba6b5b69c6856504a5c0 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Thu, 15 Jun 2017 02:33:04 +0800 Subject: [PATCH 1/8] Override default confirmation window and threshold for SEGSIGNAL --- src/chainparams.cpp | 2 ++ src/consensus/params.h | 4 ++++ src/versionbits.cpp | 13 +++++++------ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index f5dfaf523326b..9cf3ce9d3fcd4 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -100,6 +100,8 @@ class CMainParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].bit = 4; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nStartTime = 1496275200; // June 1st, 2017. consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nTimeout = 1510704000; // November 15th, 2017. + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nOverrideMinerConfirmationWindow = 672; // ~4.67 days + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nOverrideRuleChangeActivationThreshold = 538; // 80% // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000003f94d1ad391682fe038bf5"); diff --git a/src/consensus/params.h b/src/consensus/params.h index 442ec07911f33..19c0b319cad41 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -32,6 +32,10 @@ struct BIP9Deployment { int64_t nStartTime; /** Timeout/expiry MedianTime for the deployment attempt. */ int64_t nTimeout; + /** Overriding the default threshold if not zero. */ + uint32_t nOverrideRuleChangeActivationThreshold = 0; + /** Overriding the default confirmation window if not zero . */ + uint32_t nOverrideMinerConfirmationWindow = 0; }; /** diff --git a/src/versionbits.cpp b/src/versionbits.cpp index bd02e03373dae..429300e0e3040 100644 --- a/src/versionbits.cpp +++ b/src/versionbits.cpp @@ -151,13 +151,14 @@ class VersionBitsConditionChecker : public AbstractThresholdConditionChecker { protected: int64_t BeginTime(const Consensus::Params& params) const { return params.vDeployments[id].nStartTime; } int64_t EndTime(const Consensus::Params& params) const { return params.vDeployments[id].nTimeout; } - int Period(const Consensus::Params& params) const { return params.nMinerConfirmationWindow; } + int Period(const Consensus::Params& params) const { + if (params.vDeployments[id].nOverrideMinerConfirmationWindow > 0) + return params.vDeployments[id].nOverrideMinerConfirmationWindow; + return params.nMinerConfirmationWindow; + } int Threshold(const Consensus::Params& params) const { - if (params.nRuleChangeActivationThreshold == 1916 && params.nMinerConfirmationWindow == 2016 && - params.vDeployments[id].bit == params.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].bit && - params.vDeployments[id].nStartTime == params.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nStartTime) { - return 1612; // 80% threshold for SEGWIT2X only - } + if (params.vDeployments[id].nOverrideRuleChangeActivationThreshold > 0) + return params.vDeployments[id].nOverrideRuleChangeActivationThreshold; return params.nRuleChangeActivationThreshold; } From 8031cfe331e1f3ae7423b9c35cc514e4b8acedf3 Mon Sep 17 00:00:00 2001 From: James Hilliard Date: Wed, 14 Jun 2017 18:05:21 -0500 Subject: [PATCH 2/8] Enforce BIP91 when locked in --- src/validation.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/validation.cpp b/src/validation.cpp index 9ebce7708c80c..c00f76b714982 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1852,7 +1852,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } // SEGWIT2X signalling. - if ( VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT2X, versionbitscache) == THRESHOLD_ACTIVE && + if ((VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT2X, versionbitscache) == THRESHOLD_ACTIVE || + VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT2X, versionbitscache) == THRESHOLD_LOCKED_IN) && !IsWitnessLockedIn(pindex->pprev, chainparams.GetConsensus()) && // Segwit is not locked in !IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus()) ) // and is not active. { From 25e59fe080a1989153c2427ed33e7e23425a0a96 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 16 Jun 2017 00:34:37 +0800 Subject: [PATCH 3/8] Add regtest parameters for SEGSIGNAL --- src/chainparams.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 9cf3ce9d3fcd4..adafa525f4d7e 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -297,6 +297,8 @@ class CRegTestParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].bit = 4; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nTimeout = 999999999999ULL; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nOverrideMinerConfirmationWindow = 48; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nOverrideRuleChangeActivationThreshold = 29; // 60% // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x00"); From b3b6cba9e6259498bd23c418d87d7052bee4467f Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 16 Jun 2017 00:38:37 +0800 Subject: [PATCH 4/8] Enforce SEGSIGNAL only when SEGWIT is in STARTED state bit 1 signaling is not required (and has no meaning) unless the state is STARTED --- src/validation.cpp | 9 +-------- src/validation.h | 3 --- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/validation.cpp b/src/validation.cpp index c00f76b714982..b884d842f5fe9 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1854,8 +1854,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // SEGWIT2X signalling. if ((VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT2X, versionbitscache) == THRESHOLD_ACTIVE || VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT2X, versionbitscache) == THRESHOLD_LOCKED_IN) && - !IsWitnessLockedIn(pindex->pprev, chainparams.GetConsensus()) && // Segwit is not locked in - !IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus()) ) // and is not active. + VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_STARTED) { bool fVersionBits = (pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS; bool fSegbit = (pindex->nVersion & VersionBitsMask(chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) != 0; @@ -2931,12 +2930,6 @@ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& pa return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE); } -// Check if Segregated Witness is Locked In -bool IsWitnessLockedIn(const CBlockIndex* pindexPrev, const Consensus::Params& params) -{ - LOCK(cs_main); - return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_LOCKED_IN); -} // Compute at which vout of the block's coinbase transaction the witness // commitment occurs, or -1 if not found. diff --git a/src/validation.h b/src/validation.h index f40baeed4cc4b..9c606f2419409 100644 --- a/src/validation.h +++ b/src/validation.h @@ -503,9 +503,6 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, /** Check whether witness commitments are required for block. */ bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params); -/** Check whether witness commitments are required for block. */ -bool IsWitnessLockedIn(const CBlockIndex* pindexPrev, const Consensus::Params& params); - /** When there are blocks in the active chain with missing data, rewind the chainstate and remove them from the block index */ bool RewindBlockIndex(const CChainParams& params); From 78002c278dcea47371dc948255794e4a3b1e6abe Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 16 Jun 2017 00:38:57 +0800 Subject: [PATCH 5/8] [qa] Add RPC test for SEGSIGNAL --- qa/rpc-tests/bip91.py | 176 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) create mode 100755 qa/rpc-tests/bip91.py diff --git a/qa/rpc-tests/bip91.py b/qa/rpc-tests/bip91.py new file mode 100755 index 0000000000000..ed574b18fe9ff --- /dev/null +++ b/qa/rpc-tests/bip91.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python3 +# Copyright (c) 2015-2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +from test_framework.test_framework import BitcoinTestFramework +from test_framework.util import * +from test_framework.mininode import NetworkThread +from test_framework.blocktools import create_coinbase, create_block +import time + +''' +This test is meant to exercise BIP91 +regtest lock-in with 108/144 for BIP141 and 29/48 for BIP91 +mine 143 blocks to transition from DEFINED to STARTED +mine 28 blocks signalling readiness and 20 not in order to fail to change state this period for BIP91 +mine 29 blocks signalling readiness and 19 blocks not signalling readiness for BIP91 (STARTED->LOCKED_IN) +bit 1 is mandatory for the following 192 blocks until BIP141 is locked_in +bit 1 is optional after BIP141 is locked_in +''' + +class BIP91Test(BitcoinTestFramework): + + def __init__(self): + super().__init__() + self.num_nodes = 2 + self.setup_clean_chain = True + + def setup_network(self): + self.nodes = [] + self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1"])) + self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-whitelist=127.0.0.1"])) # connect to a dummy node to allow getblocktemplate + connect_nodes(self.nodes[0], 1) + + def run_test(self): + NetworkThread().start() # Start up network handling in another thread + self.tip = int("0x" + self.nodes[0].getbestblockhash(), 0) + self.height = 1 # height of the next block to build + self.last_block_time = int(time.time()) + + assert_equal(self.get_bip9_status('segwit2x')['status'], 'defined') + assert_equal(self.get_bip9_status('segwit2x')['since'], 0) + assert_equal(self.get_bip9_status('segwit')['status'], 'defined') + assert_equal(self.get_bip9_status('segwit')['since'], 0) + + + # Test 1 + # Advance from DEFINED to STARTED + self.generate_blocks(1,4) + tmpl = self.nodes[0].getblocktemplate({}) + assert_equal(tmpl['version'], 0x20000000) + + self.generate_blocks(142, 4) + assert_equal(self.get_bip9_status('segwit2x')['status'], 'started') + assert_equal(self.get_bip9_status('segwit2x')['since'], 48) + assert_equal(self.get_bip9_status('segwit')['status'], 'started') + assert_equal(self.get_bip9_status('segwit')['since'], 144) + tmpl = self.nodes[0].getblocktemplate({}) + assert_equal(tmpl['version'], 0x10000001|0x20000012) # 0x10000001 are TESTDUMMY and CSV + + # Test 2 + # Fail to achieve LOCKED_IN 28 out of 48 signal bit 4 + self.generate_blocks(20, 0x20000010) # signalling bit 4 + self.generate_blocks(8, 0x20000012) # signalling bit 1 and 4 + self.generate_blocks(10, 0x20000002) # signalling bit 1 + self.generate_blocks(10, 4) # not signalling + assert_equal(self.get_bip9_status('segwit2x')['status'], 'started') + assert_equal(self.get_bip9_status('segwit2x')['since'], 48) + assert_equal(self.get_bip9_status('segwit')['status'], 'started') + assert_equal(self.get_bip9_status('segwit')['since'], 144) + tmpl = self.nodes[0].getblocktemplate({}) + assert_equal(tmpl['version'], 0x10000001|0x20000012) + + + # Test 3 + # 28 out of 48 signal bit 4 to achieve LOCKED_IN + self.generate_blocks(20, 0x20000010) # signalling bit 4 + self.generate_blocks(9, 0x20000012) # signalling bit 1 and 4 + self.generate_blocks(10, 0x20000002) # signalling bit 1 + self.generate_blocks(9, 4) # not signalling + assert_equal(self.get_bip9_status('segwit2x')['status'], 'locked_in') + assert_equal(self.get_bip9_status('segwit2x')['since'], 240) + assert_equal(self.get_bip9_status('segwit')['status'], 'started') + assert_equal(self.get_bip9_status('segwit')['since'], 144) + tmpl = self.nodes[0].getblocktemplate({}) + assert_equal(tmpl['version'], 0x10000001|0x20000012) + + # Test 4 + # bit 1 signalling becomes mandatory after bit 4 locked_in + self.generate_blocks(1, 4, 'bad-no-segwit') + self.generate_blocks(1, 0x20000000, 'bad-no-segwit') + self.generate_blocks(1, 0x20000010, 'bad-no-segwit') + self.generate_blocks(1, 0x40000002, 'bad-no-segwit') + self.generate_blocks(1, 0x60000002, 'bad-no-segwit') + self.generate_blocks(1, 0x12, 'bad-no-segwit') + self.generate_blocks(35, 0x20000002) + self.generate_blocks(35, 0x20000012) + self.generate_blocks(121, 0x20000102) + + assert_equal(self.get_bip9_status('segwit2x')['status'], 'active') + assert_equal(self.get_bip9_status('segwit2x')['since'], 288) + assert_equal(self.get_bip9_status('segwit')['status'], 'started') + assert_equal(self.get_bip9_status('segwit')['since'], 144) + tmpl = self.nodes[0].getblocktemplate({}) + assert_equal(tmpl['version'], 0x10000001|0x20000002) + + self.generate_blocks(1, 4, 'bad-no-segwit') + self.generate_blocks(1, 0x20000000, 'bad-no-segwit') + self.generate_blocks(1, 0x20000010, 'bad-no-segwit') + self.generate_blocks(1, 0x40000002, 'bad-no-segwit') + self.generate_blocks(1, 0x60000002, 'bad-no-segwit') + self.generate_blocks(1, 0x12, 'bad-no-segwit') + self.generate_blocks(1, 0x20000002) + + # Test 4 + # bit 1 signalling becomes optional after bit 1 locked_in + + assert_equal(self.get_bip9_status('segwit2x')['status'], 'active') + assert_equal(self.get_bip9_status('segwit2x')['since'], 288) + assert_equal(self.get_bip9_status('segwit')['status'], 'locked_in') + assert_equal(self.get_bip9_status('segwit')['since'], 432) + tmpl = self.nodes[0].getblocktemplate({}) + assert_equal(tmpl['version'], 0x10000001|0x20000002) + + self.generate_blocks(20, 0x20000002) + self.generate_blocks(20, 0x20000012) + self.generate_blocks(20, 0x20000102) + self.generate_blocks(20, 0x20000000) + self.generate_blocks(20, 0x20000010) + self.generate_blocks(20, 0x40000002) + self.generate_blocks(23, 0x60000002) + + + assert_equal(self.get_bip9_status('segwit2x')['status'], 'active') + assert_equal(self.get_bip9_status('segwit2x')['since'], 288) + assert_equal(self.get_bip9_status('segwit')['status'], 'locked_in') + assert_equal(self.get_bip9_status('segwit')['since'], 432) + + self.generate_blocks(1, 4) + + + assert_equal(self.get_bip9_status('segwit2x')['status'], 'active') + assert_equal(self.get_bip9_status('segwit2x')['since'], 288) + assert_equal(self.get_bip9_status('segwit')['status'], 'active') + assert_equal(self.get_bip9_status('segwit')['since'], 576) + tmpl = self.nodes[0].getblocktemplate({}) + assert_equal(tmpl['version'], 0x10000001|0x20000000) + + self.generate_blocks(1, 0x20000002) + self.generate_blocks(1, 0x20000012) + self.generate_blocks(1, 0x20000102) + self.generate_blocks(1, 0x20000000) + self.generate_blocks(1, 0x20000010) + self.generate_blocks(1, 0x40000002) + self.generate_blocks(1, 0x60000002) + self.generate_blocks(1, 4) + + def generate_blocks(self, number, version, error = None): + for i in range(number): + block = create_block(self.tip, create_coinbase(self.height), self.last_block_time + 1) + block.nVersion = version + block.rehash() + block.solve() + assert_equal(self.nodes[0].submitblock(bytes_to_hex_str(block.serialize())), error) + if (error == None): + self.last_block_time += 1 + self.tip = block.sha256 + self.height += 1 + + def get_bip9_status(self, key): + info = self.nodes[0].getblockchaininfo() + return info['bip9_softforks'][key] + + +if __name__ == '__main__': + BIP91Test().main() From f95bb7fc1d173497f8337126cc1efab10ace22fb Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 16 Jun 2017 12:48:12 +0800 Subject: [PATCH 6/8] [qa] Fix tests under SEGSIGNAL --- qa/rpc-tests/p2p-compactblocks.py | 2 +- qa/rpc-tests/p2p-versionbits-warning.py | 3 ++- qa/rpc-tests/sendheaders.py | 2 ++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/qa/rpc-tests/p2p-compactblocks.py b/qa/rpc-tests/p2p-compactblocks.py index 80d0db8d29671..dfc15be2c208d 100755 --- a/qa/rpc-tests/p2p-compactblocks.py +++ b/qa/rpc-tests/p2p-compactblocks.py @@ -123,7 +123,7 @@ def setup_network(self): # Start up node0 to be a version 1, pre-segwit node. self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, - [["-debug", "-logtimemicros=1", "-bip9params=segwit:0:0", "-bip9params=segwit2x:0:0"], + [["-debug", "-logtimemicros=1", "-bip9params=segwit:0:0", "-blockversion=536870915"], # signal segwit and csv ["-debug", "-logtimemicros", "-txindex"]]) connect_nodes(self.nodes[0], 1) diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/qa/rpc-tests/p2p-versionbits-warning.py index fc3eddddee17b..dbf8367926644 100755 --- a/qa/rpc-tests/p2p-versionbits-warning.py +++ b/qa/rpc-tests/p2p-versionbits-warning.py @@ -74,7 +74,8 @@ def setup_network(self): # Open and close to create zero-length file with open(self.alert_filename, 'w', encoding='utf8') as _: pass - self.extra_args = [["-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]] + self.extra_args = [["-blockversion=4", "-debug", "-logtimemicros=1", "-alertnotify=echo %s >> \"" + self.alert_filename + "\""]] + # Have to use version 4 as the default version will trigger BIP91 and make the subsequent tests fail self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args) # Send numblocks blocks via peer with nVersionToUse set. diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 37b98c576e837..2f82279fa3c5e 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -492,6 +492,7 @@ def run_test(self): # Create extra blocks for later for b in range(20): blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].nVersion = 0x20000002 blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 @@ -538,6 +539,7 @@ def run_test(self): # Create two more blocks. for j in range(2): blocks.append(create_block(tip, create_coinbase(height), block_time)) + blocks[-1].nVersion = 0x20000002 blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 From 340230c94695f03235cf7dc7e34f7a6184466cea Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 16 Jun 2017 13:17:24 +0800 Subject: [PATCH 7/8] Reduce the SEGSIGNAL signalling window to 336 blocks and enforce only when ACTIVE --- src/chainparams.cpp | 4 ++-- src/validation.cpp | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index adafa525f4d7e..1959b7128bd46 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -100,8 +100,8 @@ class CMainParams : public CChainParams { consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].bit = 4; consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nStartTime = 1496275200; // June 1st, 2017. consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nTimeout = 1510704000; // November 15th, 2017. - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nOverrideMinerConfirmationWindow = 672; // ~4.67 days - consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nOverrideRuleChangeActivationThreshold = 538; // 80% + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nOverrideMinerConfirmationWindow = 336; // ~2.33 days + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT2X].nOverrideRuleChangeActivationThreshold = 269; // 80% // The best chain should have at least this much work. consensus.nMinimumChainWork = uint256S("0x0000000000000000000000000000000000000000003f94d1ad391682fe038bf5"); diff --git a/src/validation.cpp b/src/validation.cpp index b884d842f5fe9..0a186461826db 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -1852,9 +1852,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } // SEGWIT2X signalling. - if ((VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT2X, versionbitscache) == THRESHOLD_ACTIVE || - VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT2X, versionbitscache) == THRESHOLD_LOCKED_IN) && - VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_STARTED) + if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT2X, versionbitscache) == THRESHOLD_ACTIVE && + VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_STARTED) { bool fVersionBits = (pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS; bool fSegbit = (pindex->nVersion & VersionBitsMask(chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) != 0; From dbfc931394eff6e5ddb0a51ef51614a0b49e6e15 Mon Sep 17 00:00:00 2001 From: Johnson Lau Date: Fri, 16 Jun 2017 13:20:25 +0800 Subject: [PATCH 8/8] [qa] fix tests for SEGSIGNAL LOCKED_IN --- qa/pull-tester/rpc-tests.py | 1 + qa/rpc-tests/bip91.py | 27 +++++++++++++++++++++++---- qa/rpc-tests/sendheaders.py | 2 -- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/qa/pull-tester/rpc-tests.py b/qa/pull-tester/rpc-tests.py index 20ab0fdd1de30..38b635bde852a 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/qa/pull-tester/rpc-tests.py @@ -155,6 +155,7 @@ 'rpcnamedargs.py', 'listsinceblock.py', 'p2p-leaktests.py', + 'bip91.py', ] if ENABLE_ZMQ: testScripts.append('zmq_test.py') diff --git a/qa/rpc-tests/bip91.py b/qa/rpc-tests/bip91.py index ed574b18fe9ff..484c749369af7 100755 --- a/qa/rpc-tests/bip91.py +++ b/qa/rpc-tests/bip91.py @@ -15,7 +15,8 @@ mine 143 blocks to transition from DEFINED to STARTED mine 28 blocks signalling readiness and 20 not in order to fail to change state this period for BIP91 mine 29 blocks signalling readiness and 19 blocks not signalling readiness for BIP91 (STARTED->LOCKED_IN) -bit 1 is mandatory for the following 192 blocks until BIP141 is locked_in +bit 1 is optional for the following 48 blocks when BIP91 is LOCKED_IN (LOCKED_IN->ACTIVE) +bit 1 is mandatory for the following 144 blocks until BIP141 is locked_in bit 1 is optional after BIP141 is locked_in ''' @@ -86,7 +87,25 @@ def run_test(self): assert_equal(tmpl['version'], 0x10000001|0x20000012) # Test 4 - # bit 1 signalling becomes mandatory after bit 4 locked_in + # No restriction when bit 4 is LOCKED_IN + self.generate_blocks(5, 4) + self.generate_blocks(5, 0x20000000) + self.generate_blocks(5, 0x20000010) + self.generate_blocks(5, 0x40000002) + self.generate_blocks(5, 0x60000002) + self.generate_blocks(5, 0x12) + self.generate_blocks(5, 0x20000002) + self.generate_blocks(5, 0x20000012) + self.generate_blocks(8, 0x20000102) + assert_equal(self.get_bip9_status('segwit2x')['status'], 'active') + assert_equal(self.get_bip9_status('segwit2x')['since'], 288) + assert_equal(self.get_bip9_status('segwit')['status'], 'started') + assert_equal(self.get_bip9_status('segwit')['since'], 144) + tmpl = self.nodes[0].getblocktemplate({}) + assert_equal(tmpl['version'], 0x10000001|0x20000002) + + # Test 5 + # bit 1 signalling becomes mandatory after bit 4 is ACTIVE self.generate_blocks(1, 4, 'bad-no-segwit') self.generate_blocks(1, 0x20000000, 'bad-no-segwit') self.generate_blocks(1, 0x20000010, 'bad-no-segwit') @@ -95,7 +114,7 @@ def run_test(self): self.generate_blocks(1, 0x12, 'bad-no-segwit') self.generate_blocks(35, 0x20000002) self.generate_blocks(35, 0x20000012) - self.generate_blocks(121, 0x20000102) + self.generate_blocks(73, 0x20000102) assert_equal(self.get_bip9_status('segwit2x')['status'], 'active') assert_equal(self.get_bip9_status('segwit2x')['since'], 288) @@ -112,7 +131,7 @@ def run_test(self): self.generate_blocks(1, 0x12, 'bad-no-segwit') self.generate_blocks(1, 0x20000002) - # Test 4 + # Test 6 # bit 1 signalling becomes optional after bit 1 locked_in assert_equal(self.get_bip9_status('segwit2x')['status'], 'active') diff --git a/qa/rpc-tests/sendheaders.py b/qa/rpc-tests/sendheaders.py index 2f82279fa3c5e..37b98c576e837 100755 --- a/qa/rpc-tests/sendheaders.py +++ b/qa/rpc-tests/sendheaders.py @@ -492,7 +492,6 @@ def run_test(self): # Create extra blocks for later for b in range(20): blocks.append(create_block(tip, create_coinbase(height), block_time)) - blocks[-1].nVersion = 0x20000002 blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1 @@ -539,7 +538,6 @@ def run_test(self): # Create two more blocks. for j in range(2): blocks.append(create_block(tip, create_coinbase(height), block_time)) - blocks[-1].nVersion = 0x20000002 blocks[-1].solve() tip = blocks[-1].sha256 block_time += 1