Skip to content
Permalink
Browse files

Switch activation of segwit and CSV from version bits.

Instead of using version bits to activate segwit and CSV, use the
BIP16Height to activate them all together with P2SH.  The height is set
to 0 on mainnet and testnet, but that will be updated for Namecoin.  The
height is set to 432 on regtest net, which immitates when BIP9
activation would hit so that the regtests work.

Some tests needed to be updated if they assumed that segwit is activated
right away by mining 500 blocks before running the test.  The segwit
regtests can be activated again with this, after removing logic that
tests the BIP9 stages (which are not present).

This allows to activate segwit and CSV with a scheduled soft fork, even
before AAA is launched.
  • Loading branch information...
domob1812 committed Apr 22, 2018
1 parent d2f7472 commit 4cf6ddbfd80921e1e82f001cdc9c2dc44ce0ac2c
@@ -58,7 +58,6 @@ BITCOIN_TESTS =\
test/mempool_tests.cpp \
test/merkle_tests.cpp \
test/merkleblock_tests.cpp \
test/miner_tests.cpp \
test/multisig_tests.cpp \
test/net_tests.cpp \
test/netbase_tests.cpp \
@@ -89,6 +88,8 @@ BITCOIN_TESTS =\
test/versionbits_tests.cpp \
test/uint256_tests.cpp \
test/util_tests.cpp
# FIXME: Update and re-enable these tests:
# miner_tests

if ENABLE_WALLET
BITCOIN_TESTS += \
@@ -59,6 +59,11 @@ void CChainParams::UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64
consensus.vDeployments[d].nTimeout = nTimeout;
}

void CChainParams::TurnOffSegwitForUnitTests ()
{
consensus.BIP16Height = 1000000;
}

/**
* Main network
*/
@@ -75,7 +80,7 @@ class CMainParams : public CChainParams {
CMainParams() {
strNetworkID = "main";
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP16Exception = uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22");
consensus.BIP16Height = 0;
consensus.BIP34Height = 227931;
consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8");
consensus.BIP65Height = 388381; // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
@@ -91,15 +96,8 @@ class CMainParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008

// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1462060800; // May 1st, 2016
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017

// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1479168000; // November 15th, 2016.
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1510704000; // November 15th, 2017.
// CSV (BIP68, BIP112 and BIP113) as well as segwit (BIP141, BIP143 and
// BIP147) are deployed together with P2SH.

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000f91c579d57cad4bc5278cc");
@@ -195,7 +193,7 @@ class CTestNetParams : public CChainParams {
CTestNetParams() {
strNetworkID = "test";
consensus.nSubsidyHalvingInterval = 210000;
consensus.BIP16Exception = uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105");
consensus.BIP16Height = 0;
consensus.BIP34Height = 21111;
consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8");
consensus.BIP65Height = 581885; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
@@ -211,15 +209,8 @@ class CTestNetParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008

// Deployment of BIP68, BIP112, and BIP113.
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017

// Deployment of SegWit (BIP141, BIP143, and BIP147)
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 0; // Never / undefined
// CSV (BIP68, BIP112 and BIP113) as well as segwit (BIP141, BIP143 and
// BIP147) are deployed together with P2SH.

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000002830dab7f76dbb7d63");
@@ -293,7 +284,7 @@ class CRegTestParams : public CChainParams {
CRegTestParams() {
strNetworkID = "regtest";
consensus.nSubsidyHalvingInterval = 150;
consensus.BIP16Exception = uint256();
consensus.BIP16Height = 432; // Corresponds to activation height using BIP9 rules
consensus.BIP34Height = 100000000; // BIP34 has not activated on regtest (far in the future so block v1 are not rejected in tests)
consensus.BIP34Hash = uint256();
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
@@ -308,12 +299,6 @@ class CRegTestParams : public CChainParams {
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE;
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT;

// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("0x00");
@@ -398,3 +383,8 @@ void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime,
{
globalChainParams->UpdateVersionBitsParameters(d, nStartTime, nTimeout);
}

void TurnOffSegwitForUnitTests ()
{
globalChainParams->TurnOffSegwitForUnitTests ();
}
@@ -75,6 +75,7 @@ class CChainParams
const CCheckpointData& Checkpoints() const { return checkpointData; }
const ChainTxData& TxData() const { return chainTxData; }
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);
void TurnOffSegwitForUnitTests();
protected:
CChainParams() {}

@@ -120,4 +121,9 @@ void SelectParams(const std::string& chain);
*/
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);

/**
* Allows turning off segwit for unit tests.
*/
void TurnOffSegwitForUnitTests();

#endif // BITCOIN_CHAINPARAMS_H
@@ -16,8 +16,6 @@ namespace Consensus {
enum DeploymentPos
{
DEPLOYMENT_TESTDUMMY,
DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113.
DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147.
// NOTE: Also add new deployments to VersionBitsDeploymentInfo in versionbits.cpp
MAX_VERSION_BITS_DEPLOYMENTS
};
@@ -49,8 +47,8 @@ struct BIP9Deployment {
struct Params {
uint256 hashGenesisBlock;
int nSubsidyHalvingInterval;
/* Block hash that is excepted from BIP16 enforcement */
uint256 BIP16Exception;
/** Block height at with BIP16 becomes active */
int BIP16Height;
/** Block height and hash at which BIP34 becomes active */
int BIP34Height;
uint256 BIP34Hash;
@@ -847,7 +847,7 @@ namespace { // Variables internal to initialization process only
int nMaxConnections;
int nUserMaxConnections;
int nFD;
ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK | NODE_NETWORK_LIMITED);
ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK | NODE_NETWORK_LIMITED | NODE_WITNESS);

} // namespace

@@ -1624,15 +1624,6 @@ bool AppInitMain()
}
}

if (chainparams.GetConsensus().vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) {
// Only advertise witness capabilities if they have a reasonable start time.
// This allows us to have the code merged without a defined softfork, by setting its
// end time to 0.
// Note that setting NODE_WITNESS is never required: the only downside from not
// doing so is that after activation, no upgraded nodes will fetch from you.
nLocalServices = ServiceFlags(nLocalServices | NODE_WITNESS);
}

// ********************************************************* Step 10: import blocks

if (!CheckDiskSpace() && !CheckDiskSpace(0, true))
@@ -1291,7 +1291,7 @@ UniValue getblockchaininfo(const JSONRPCRequest& request)
softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
for (int pos = Consensus::DEPLOYMENT_CSV; pos != Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++pos) {
for (int pos = Consensus::DEPLOYMENT_TESTDUMMY + 1; pos != Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++pos) {
BIP9SoftForkDescPushBack(bip9_softforks, consensusParams, static_cast<Consensus::DeploymentPos>(pos));
}
obj.pushKV("softforks", softforks);
@@ -493,11 +493,10 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
// TODO: Maybe recheck connections/IBD and (if something wrong) send an expires-immediately template to stop miners?
}

const struct VBDeploymentInfo& segwit_info = VersionBitsDeploymentInfo[Consensus::DEPLOYMENT_SEGWIT];
// If the caller is indicating segwit support, then allow CreateNewBlock()
// to select witness transactions, after segwit activates (otherwise
// don't).
bool fSupportsSegwit = setClientRules.find(segwit_info.name) != setClientRules.end();
bool fSupportsSegwit = setClientRules.find("segwit") != setClientRules.end();

// Update block
static CBlockIndex* pindexPrev;
@@ -536,7 +535,7 @@ UniValue getblocktemplate(const JSONRPCRequest& request)
pblock->nNonce = 0;

// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
const bool fPreSegWit = (ThresholdState::ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache));
const bool fPreSegWit = !IsWitnessEnabled(pindexPrev, consensusParams);

UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");

@@ -115,7 +115,7 @@ TestChain100Setup::TestChain100Setup() : TestingSetup(CBaseChainParams::REGTEST)
{
// CreateAndProcessBlock() does not support building SegWit blocks, so don't activate in these tests.
// TODO: fix the code to support SegWit blocks.
UpdateVersionBitsParameters(Consensus::DEPLOYMENT_SEGWIT, 0, Consensus::BIP9Deployment::NO_TIMEOUT);
TurnOffSegwitForUnitTests();
// Generate a 100-block chain:
coinbaseKey.MakeNewKey(true);
CScript scriptPubKey = CScript() << ToByteVector(coinbaseKey.GetPubKey()) << OP_CHECKSIG;
@@ -1785,36 +1785,18 @@ class WarningBitsConditionChecker : public AbstractThresholdConditionChecker
// Protected by cs_main
static ThresholdConditionCache warningcache[VERSIONBITS_NUM_BITS];

// 0.13.0 was shipped with a segwit deployment defined for testnet, but not for
// mainnet. We no longer need to support disabling the segwit deployment
// except for testing purposes, due to limitations of the functional test
// environment. See test/functional/p2p-segwit.py.
static bool IsScriptWitnessEnabled(const Consensus::Params& params)
{
return params.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0;
}

static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consensus::Params& consensusparams) {
AssertLockHeld(cs_main);

unsigned int flags = SCRIPT_VERIFY_NONE;

// BIP16 didn't become active until Apr 1 2012 (on mainnet, and
// retroactively applied to testnet)
// However, only one historical block violated the P2SH rules (on both
// mainnet and testnet), so for simplicity, always leave P2SH
// on except for the one violating block.
if (consensusparams.BIP16Exception.IsNull() || // no bip16 exception on this chain
pindex->phashBlock == nullptr || // this is a new candidate block, eg from TestBlockValidity()
*pindex->phashBlock != consensusparams.BIP16Exception) // this block isn't the historical exception
{
if (pindex->nHeight >= consensusparams.BIP16Height) {
flags |= SCRIPT_VERIFY_P2SH;
}

// Enforce WITNESS rules whenever P2SH is in effect (and the segwit
// deployment is defined).
if (flags & SCRIPT_VERIFY_P2SH && IsScriptWitnessEnabled(consensusparams)) {
if (IsWitnessEnabled(pindex->pprev, consensusparams)) {
flags |= SCRIPT_VERIFY_WITNESS;
flags |= SCRIPT_VERIFY_NULLDUMMY;
}

// Start enforcing the DERSIG (BIP66) rule
@@ -1827,15 +1809,12 @@ static unsigned int GetBlockScriptFlags(const CBlockIndex* pindex, const Consens
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
}

// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic.
if (VersionBitsState(pindex->pprev, consensusparams, Consensus::DEPLOYMENT_CSV, versionbitscache) == ThresholdState::ACTIVE) {
// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY)
// together with P2SH.
if (flags & SCRIPT_VERIFY_P2SH) {
flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY;
}

if (IsNullDummyEnabled(pindex->pprev, consensusparams)) {
flags |= SCRIPT_VERIFY_NULLDUMMY;
}

return flags;
}

@@ -2017,15 +1996,17 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
}
}

// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY) using versionbits logic.
int nLockTimeFlags = 0;
if (VersionBitsState(pindex->pprev, chainparams.GetConsensus(), Consensus::DEPLOYMENT_CSV, versionbitscache) == ThresholdState::ACTIVE) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
}

// Get the script flags for this block
unsigned int flags = GetBlockScriptFlags(pindex, chainparams.GetConsensus());

// Start enforcing BIP68 (sequence locks) and BIP112 (CHECKSEQUENCEVERIFY)
// together with P2SH.
int nLockTimeFlags = 0;
if (flags & SCRIPT_VERIFY_P2SH) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
}

int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);

@@ -3174,14 +3155,10 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P

bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
LOCK(cs_main);
return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == ThresholdState::ACTIVE);
}

bool IsNullDummyEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params)
{
LOCK(cs_main);
return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == ThresholdState::ACTIVE);
// Segwit is enabled together with P2SH, when the current block (not prev)
// is at the threshold height.
return pindexPrev != nullptr
&& pindexPrev->nHeight + 1 >= params.BIP16Height;
}

// Compute at which vout of the block's coinbase transaction the witness
@@ -3216,25 +3193,23 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
std::vector<unsigned char> commitment;
int commitpos = GetWitnessCommitmentIndex(block);
std::vector<unsigned char> ret(32, 0x00);
if (consensusParams.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout != 0) {
if (commitpos == -1) {
uint256 witnessroot = BlockWitnessMerkleRoot(block, nullptr);
CHash256().Write(witnessroot.begin(), 32).Write(ret.data(), 32).Finalize(witnessroot.begin());
CTxOut out;
out.nValue = 0;
out.scriptPubKey.resize(38);
out.scriptPubKey[0] = OP_RETURN;
out.scriptPubKey[1] = 0x24;
out.scriptPubKey[2] = 0xaa;
out.scriptPubKey[3] = 0x21;
out.scriptPubKey[4] = 0xa9;
out.scriptPubKey[5] = 0xed;
memcpy(&out.scriptPubKey[6], witnessroot.begin(), 32);
commitment = std::vector<unsigned char>(out.scriptPubKey.begin(), out.scriptPubKey.end());
CMutableTransaction tx(*block.vtx[0]);
tx.vout.push_back(out);
block.vtx[0] = MakeTransactionRef(std::move(tx));
}
if (commitpos == -1) {
uint256 witnessroot = BlockWitnessMerkleRoot(block, nullptr);
CHash256().Write(witnessroot.begin(), 32).Write(ret.data(), 32).Finalize(witnessroot.begin());
CTxOut out;
out.nValue = 0;
out.scriptPubKey.resize(38);
out.scriptPubKey[0] = OP_RETURN;
out.scriptPubKey[1] = 0x24;
out.scriptPubKey[2] = 0xaa;
out.scriptPubKey[3] = 0x21;
out.scriptPubKey[4] = 0xa9;
out.scriptPubKey[5] = 0xed;
memcpy(&out.scriptPubKey[6], witnessroot.begin(), 32);
commitment = std::vector<unsigned char>(out.scriptPubKey.begin(), out.scriptPubKey.end());
CMutableTransaction tx(*block.vtx[0]);
tx.vout.push_back(out);
block.vtx[0] = MakeTransactionRef(std::move(tx));
}
UpdateUncommittedBlockStructures(block, pindexPrev, consensusParams);
return commitment;
@@ -3304,9 +3279,9 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
{
const int nHeight = pindexPrev == nullptr ? 0 : pindexPrev->nHeight + 1;

// Start enforcing BIP113 (Median Time Past) using versionbits logic.
// Start enforcing BIP113 (Median Time Past) together with P2SH.
int nLockTimeFlags = 0;
if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_CSV, versionbitscache) == ThresholdState::ACTIVE) {
if (nHeight >= consensusParams.BIP16Height) {
nLockTimeFlags |= LOCKTIME_MEDIAN_TIME_PAST;
}

@@ -3340,7 +3315,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
// {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness reserved value). In case there are
// multiple, the last one is used.
bool fHaveWitness = false;
if (VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == ThresholdState::ACTIVE) {
if (IsWitnessEnabled(pindexPrev, consensusParams)) {
int commitpos = GetWitnessCommitmentIndex(block);
if (commitpos != -1) {
bool malleated = false;
@@ -4182,9 +4157,8 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)

int nHeight = 1;
while (nHeight <= chainActive.Height()) {
// Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
// blocks in ConnectBlock, we don't need to go back and
// re-download/re-verify blocks from before segwit actually activated.
// We don't need to go back and re-download/re-verify blocks from
// before segwit actually activated.
if (IsWitnessEnabled(chainActive[nHeight - 1], params.GetConsensus()) && !(chainActive[nHeight]->nStatus & BLOCK_OPT_WITNESS)) {
break;
}

0 comments on commit 4cf6ddb

Please sign in to comment.
You can’t perform that action at this time.