diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 4af6f34c62..30f3b7c140 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -92,6 +92,11 @@ public: 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. + /** * The message start string is designed to be unlikely to occur in normal data. * The characters are rarely used upper ASCII, not valid as UTF-8, and produce @@ -185,6 +190,11 @@ public: 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 = 1462060800; // May 1st 2016 + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017 + pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; @@ -257,6 +267,9 @@ public: consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0; consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0; consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0; + consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL; pchMessageStart[0] = 0xfa; pchMessageStart[1] = 0xbf; diff --git a/src/clientversion.cpp b/src/clientversion.cpp index aae0569bba..15edb69a20 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -94,7 +94,7 @@ std::string FormatFullVersion() /** * Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki) */ -std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments) +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments, const bool fBaseNameOnly) { std::ostringstream ss; ss << "/"; @@ -108,5 +108,7 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const ss << ")"; } ss << "/"; + if (!fBaseNameOnly) + ss << "UASF-Segwit:0.3(BIP148)/"; return ss.str(); } diff --git a/src/clientversion.h b/src/clientversion.h index ab79da9b36..434d745787 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -63,7 +63,7 @@ extern const std::string CLIENT_DATE; std::string FormatFullVersion(); -std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments); +std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector& comments, bool fBaseNameOnly = false); #endif // WINDRES_PREPROC diff --git a/src/consensus/params.h b/src/consensus/params.h index 4f3480b89b..d7bbc22ee3 100644 --- a/src/consensus/params.h +++ b/src/consensus/params.h @@ -16,6 +16,7 @@ enum DeploymentPos { DEPLOYMENT_TESTDUMMY, DEPLOYMENT_CSV, // Deployment of BIP68, BIP112, and BIP113. + DEPLOYMENT_SEGWIT, // Deployment of BIP141, BIP143, and BIP147. MAX_VERSION_BITS_DEPLOYMENTS }; diff --git a/src/main.cpp b/src/main.cpp index f85ac33177..56789c7d66 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2307,6 +2307,20 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; } + // BIP148 mandatory segwit signalling. + int64_t nMedianTimePast = pindex->GetMedianTimePast(); + if ( (nMedianTimePast >= 1501545600) && // Tue 01 Aug 2017 00:00:00 UTC + (nMedianTimePast <= 1510704000) && // Wed 15 Nov 2017 00:00:00 UTC + (!IsWitnessLockedIn(pindex->pprev, chainparams.GetConsensus()) && // Segwit is not locked in + !IsWitnessEnabled(pindex->pprev, chainparams.GetConsensus())) ) // and is not active. + { + bool fVersionBits = (pindex->nVersion & VERSIONBITS_TOP_MASK) == VERSIONBITS_TOP_BITS; + bool fSegbit = (pindex->nVersion & VersionBitsMask(chainparams.GetConsensus(), Consensus::DEPLOYMENT_SEGWIT)) != 0; + if (!(fVersionBits && fSegbit)) { + return state.DoS(0, error("ConnectBlock(): relayed block must signal for segwit, please upgrade"), REJECT_INVALID, "bad-no-segwit"); + } + } + int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; LogPrint("bench", " - Fork checks: %.2fms [%.2fs]\n", 0.001 * (nTime2 - nTime1), nTimeForks * 0.000001); @@ -3300,6 +3314,18 @@ static bool CheckIndexAgainstCheckpoint(const CBlockIndex* pindexPrev, CValidati return true; } +bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params) +{ + LOCK(cs_main); + return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_ACTIVE); +} + +bool IsWitnessLockedIn(const CBlockIndex* pindexPrev, const Consensus::Params& params) +{ + LOCK(cs_main); + return (VersionBitsState(pindexPrev, params, Consensus::DEPLOYMENT_SEGWIT, versionbitscache) == THRESHOLD_LOCKED_IN); +} + bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) { const Consensus::Params& consensusParams = Params().GetConsensus(); diff --git a/src/main.h b/src/main.h index 1a696dcd91..5c9d481834 100644 --- a/src/main.h +++ b/src/main.h @@ -448,6 +448,11 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIn /** Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) */ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams, const CBlock& block, CBlockIndex* pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); +/** Check whether witness commitments are required for block. */ +bool IsWitnessEnabled(const CBlockIndex* pindexPrev, const Consensus::Params& params); + +/** Check if Segregated Witness is Locked In */ +bool IsWitnessLockedIn(const CBlockIndex* pindexPrev, const Consensus::Params& params); class CBlockFileInfo { diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 28cecfffaf..7f4180fe5a 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -414,9 +414,9 @@ BOOST_AUTO_TEST_CASE(test_FormatSubVersion) std::vector comments2; comments2.push_back(std::string("comment1")); comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014 - BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector()),std::string("/Test:0.9.99/")); - BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:0.9.99(comment1)/")); - BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; Comment2; .,_?@-; )/")); + BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector(), true),std::string("/Test:0.9.99/")); + BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments, true),std::string("/Test:0.9.99(comment1)/")); + BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2, true),std::string("/Test:0.9.99(comment1; Comment2; .,_?@-; )/")); } BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)