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<std::string>& comments)
+std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& 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<std::string>& comments);
+std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& 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<std::string> 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>()),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<std::string>(), 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)