Merge #8391: Consensus: Remove ISM

122786d Consensus: Remove ISM (NicolasDorier)
This commit is contained in:
Wladimir J. van der Laan 2016-08-04 11:55:25 +02:00
commit 37d83bb0a9
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
7 changed files with 84 additions and 108 deletions

View File

@ -71,9 +71,9 @@ class BIP65Test(ComparisonTestFramework):
self.nodeaddress = self.nodes[0].getnewaddress() self.nodeaddress = self.nodes[0].getnewaddress()
self.last_block_time = int(time.time()) self.last_block_time = int(time.time())
''' 98 more version 3 blocks ''' ''' 398 more version 3 blocks '''
test_blocks = [] test_blocks = []
for i in range(98): for i in range(398):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3 block.nVersion = 3
block.rehash() block.rehash()
@ -118,24 +118,6 @@ class BIP65Test(ComparisonTestFramework):
height += 1 height += 1
yield TestInstance([[block, True]]) yield TestInstance([[block, True]])
'''
Check that the new CLTV rules are enforced in the 751st version 4
block.
'''
spendtx = self.create_transaction(self.nodes[0],
self.coinbase_blocks[1], self.nodeaddress, 1.0)
cltv_invalidate(spendtx)
spendtx.rehash()
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 4
block.vtx.append(spendtx)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
self.last_block_time += 1
yield TestInstance([[block, False]])
''' Mine 199 new version blocks on last valid tip ''' ''' Mine 199 new version blocks on last valid tip '''
test_blocks = [] test_blocks = []
for i in range(199): for i in range(199):
@ -169,6 +151,24 @@ class BIP65Test(ComparisonTestFramework):
height += 1 height += 1
yield TestInstance([[block, True]]) yield TestInstance([[block, True]])
'''
Check that the new CLTV rules are enforced in the 951st version 4
block.
'''
spendtx = self.create_transaction(self.nodes[0],
self.coinbase_blocks[1], self.nodeaddress, 1.0)
cltv_invalidate(spendtx)
spendtx.rehash()
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 4
block.vtx.append(spendtx)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
self.last_block_time += 1
yield TestInstance([[block, False]])
''' Mine 1 old version block, should be invalid ''' ''' Mine 1 old version block, should be invalid '''
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3 block.nVersion = 3

View File

@ -30,7 +30,8 @@ class BIP65Test(BitcoinTestFramework):
cnt = self.nodes[0].getblockcount() cnt = self.nodes[0].getblockcount()
# Mine some old-version blocks # Mine some old-version blocks
self.nodes[1].generate(100) self.nodes[1].generate(200)
cnt += 100
self.sync_all() self.sync_all()
if (self.nodes[0].getblockcount() != cnt + 100): if (self.nodes[0].getblockcount() != cnt + 100):
raise AssertionError("Failed to mine 100 version=3 blocks") raise AssertionError("Failed to mine 100 version=3 blocks")

View File

@ -79,9 +79,9 @@ class BIP66Test(ComparisonTestFramework):
self.nodeaddress = self.nodes[0].getnewaddress() self.nodeaddress = self.nodes[0].getnewaddress()
self.last_block_time = int(time.time()) self.last_block_time = int(time.time())
''' 98 more version 2 blocks ''' ''' 298 more version 2 blocks '''
test_blocks = [] test_blocks = []
for i in range(98): for i in range(298):
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 2 block.nVersion = 2
block.rehash() block.rehash()
@ -126,24 +126,6 @@ class BIP66Test(ComparisonTestFramework):
height += 1 height += 1
yield TestInstance([[block, True]]) yield TestInstance([[block, True]])
'''
Check that the new DERSIG rules are enforced in the 751st version 3
block.
'''
spendtx = self.create_transaction(self.nodes[0],
self.coinbase_blocks[1], self.nodeaddress, 1.0)
unDERify(spendtx)
spendtx.rehash()
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3
block.vtx.append(spendtx)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
self.last_block_time += 1
yield TestInstance([[block, False]])
''' Mine 199 new version blocks on last valid tip ''' ''' Mine 199 new version blocks on last valid tip '''
test_blocks = [] test_blocks = []
for i in range(199): for i in range(199):
@ -177,6 +159,24 @@ class BIP66Test(ComparisonTestFramework):
height += 1 height += 1
yield TestInstance([[block, True]]) yield TestInstance([[block, True]])
'''
Check that the new DERSIG rules are enforced in the 951st version 3
block.
'''
spendtx = self.create_transaction(self.nodes[0],
self.coinbase_blocks[1], self.nodeaddress, 1.0)
unDERify(spendtx)
spendtx.rehash()
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 3
block.vtx.append(spendtx)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()
self.last_block_time += 1
yield TestInstance([[block, False]])
''' Mine 1 old version block, should be invalid ''' ''' Mine 1 old version block, should be invalid '''
block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1) block = create_block(self.tip, create_coinbase(height), self.last_block_time + 1)
block.nVersion = 2 block.nVersion = 2

View File

@ -71,11 +71,10 @@ public:
CMainParams() { CMainParams() {
strNetworkID = "main"; strNetworkID = "main";
consensus.nSubsidyHalvingInterval = 210000; consensus.nSubsidyHalvingInterval = 210000;
consensus.nMajorityEnforceBlockUpgrade = 750;
consensus.nMajorityRejectBlockOutdated = 950;
consensus.nMajorityWindow = 1000;
consensus.BIP34Height = 227931; consensus.BIP34Height = 227931;
consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"); consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8");
consensus.BIP65Height = 388381; // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0
consensus.BIP66Height = 363725; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60; consensus.nPowTargetSpacing = 10 * 60;
@ -167,11 +166,10 @@ public:
CTestNetParams() { CTestNetParams() {
strNetworkID = "test"; strNetworkID = "test";
consensus.nSubsidyHalvingInterval = 210000; consensus.nSubsidyHalvingInterval = 210000;
consensus.nMajorityEnforceBlockUpgrade = 51;
consensus.nMajorityRejectBlockOutdated = 75;
consensus.nMajorityWindow = 100;
consensus.BIP34Height = 21111; consensus.BIP34Height = 21111;
consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8"); consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8");
consensus.BIP65Height = 581885; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6
consensus.BIP66Height = 330776; // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182
consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60; consensus.nPowTargetSpacing = 10 * 60;
@ -247,11 +245,10 @@ public:
CRegTestParams() { CRegTestParams() {
strNetworkID = "regtest"; strNetworkID = "regtest";
consensus.nSubsidyHalvingInterval = 150; consensus.nSubsidyHalvingInterval = 150;
consensus.nMajorityEnforceBlockUpgrade = 750; consensus.BIP34Height = 100000000; // BIP34 has not activated on regtest (far in the future so block v1 are not rejected in tests)
consensus.nMajorityRejectBlockOutdated = 950;
consensus.nMajorityWindow = 1000;
consensus.BIP34Height = -1; // BIP34 has not necessarily activated on regtest
consensus.BIP34Hash = uint256(); consensus.BIP34Hash = uint256();
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks
consensus.nPowTargetSpacing = 10 * 60; consensus.nPowTargetSpacing = 10 * 60;

View File

@ -39,13 +39,13 @@ struct BIP9Deployment {
struct Params { struct Params {
uint256 hashGenesisBlock; uint256 hashGenesisBlock;
int nSubsidyHalvingInterval; int nSubsidyHalvingInterval;
/** Used to check majorities for block version upgrade */
int nMajorityEnforceBlockUpgrade;
int nMajorityRejectBlockOutdated;
int nMajorityWindow;
/** Block height and hash at which BIP34 becomes active */ /** Block height and hash at which BIP34 becomes active */
int BIP34Height; int BIP34Height;
uint256 BIP34Hash; uint256 BIP34Hash;
/** Block height at which BIP65 becomes active */
int BIP65Height;
/** Block height at which BIP66 becomes active */
int BIP66Height;
/** /**
* Minimum blocks including miner confirmation of the total of 2016 blocks in a retargetting period, * Minimum blocks including miner confirmation of the total of 2016 blocks in a retargetting period,
* (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments. * (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments.

View File

@ -106,11 +106,6 @@ map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(cs_main);
map<COutPoint, set<map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main); map<COutPoint, set<map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(cs_main);
void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main); void EraseOrphansFor(NodeId peer) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/**
* Returns true if there are nRequired or more blocks of minVersion or above
* in the last Consensus::Params::nMajorityWindow blocks, starting at pstart and going backwards.
*/
static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams);
static void CheckBlockIndex(const Consensus::Params& consensusParams); static void CheckBlockIndex(const Consensus::Params& consensusParams);
/** Constant stuff for coinbase transactions we create: */ /** Constant stuff for coinbase transactions we create: */
@ -2372,15 +2367,13 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE; unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
// Start enforcing the DERSIG (BIP66) rules, for block.nVersion=3 blocks, // Start enforcing the DERSIG (BIP66) rule
// when 75% of the network has upgraded: if (pindex->nHeight >= chainparams.GetConsensus().BIP66Height) {
if (block.nVersion >= 3 && IsSuperMajority(3, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) {
flags |= SCRIPT_VERIFY_DERSIG; flags |= SCRIPT_VERIFY_DERSIG;
} }
// Start enforcing CHECKLOCKTIMEVERIFY, (BIP65) for block.nVersion=4 // Start enforcing CHECKLOCKTIMEVERIFY (BIP65) rule
// blocks, when 75% of the network has upgraded: if (pindex->nHeight >= chainparams.GetConsensus().BIP65Height) {
if (block.nVersion >= 4 && IsSuperMajority(4, pindex->pprev, chainparams.GetConsensus().nMajorityEnforceBlockUpgrade, chainparams.GetConsensus())) {
flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; flags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY;
} }
@ -3504,6 +3497,7 @@ std::vector<unsigned char> GenerateCoinbaseCommitment(CBlock& block, const CBloc
bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int64_t nAdjustedTime) bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, const Consensus::Params& consensusParams, const CBlockIndex* pindexPrev, int64_t nAdjustedTime)
{ {
const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1;
// Check proof of work // Check proof of work
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work"); return state.DoS(100, false, REJECT_INVALID, "bad-diffbits", false, "incorrect proof of work");
@ -3517,10 +3511,12 @@ bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& sta
return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future"); return state.Invalid(false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future");
// Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded: // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded:
for (int32_t version = 2; version < 5; ++version) // check for version 2, 3 and 4 upgrades // check for version 2, 3 and 4 upgrades
if (block.nVersion < version && IsSuperMajority(version, pindexPrev, consensusParams.nMajorityRejectBlockOutdated, consensusParams)) if((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) ||
return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", version - 1), (block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) ||
strprintf("rejected nVersion=0x%08x block", version - 1)); (block.nVersion < 4 && nHeight >= consensusParams.BIP65Height))
return state.Invalid(false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", block.nVersion),
strprintf("rejected nVersion=0x%08x block", block.nVersion));
return true; return true;
} }
@ -3546,9 +3542,8 @@ bool ContextualCheckBlock(const CBlock& block, CValidationState& state, const Co
} }
} }
// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height // Enforce rule that the coinbase starts with serialized block height
// if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): if (nHeight >= consensusParams.BIP34Height)
if (block.nVersion >= 2 && IsSuperMajority(2, pindexPrev, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))
{ {
CScript expect = CScript() << nHeight; CScript expect = CScript() << nHeight;
if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || if (block.vtx[0].vin[0].scriptSig.size() < expect.size() ||
@ -3722,19 +3717,6 @@ static bool AcceptBlock(const CBlock& block, CValidationState& state, const CCha
return true; return true;
} }
static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned nRequired, const Consensus::Params& consensusParams)
{
unsigned int nFound = 0;
for (int i = 0; i < consensusParams.nMajorityWindow && nFound < nRequired && pstart != NULL; i++)
{
if (pstart->nVersion >= minVersion)
++nFound;
pstart = pstart->pprev;
}
return (nFound >= nRequired);
}
bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp) bool ProcessNewBlock(CValidationState& state, const CChainParams& chainparams, CNode* pfrom, const CBlock* pblock, bool fForceProcessing, const CDiskBlockPos* dbp)
{ {
{ {

View File

@ -817,22 +817,23 @@ UniValue verifychain(const UniValue& params, bool fHelp)
} }
/** Implementation of IsSuperMajority with better feedback */ /** Implementation of IsSuperMajority with better feedback */
static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams) static UniValue SoftForkMajorityDesc(int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
{ {
int nFound = 0;
CBlockIndex* pstart = pindex;
for (int i = 0; i < consensusParams.nMajorityWindow && pstart != NULL; i++)
{
if (pstart->nVersion >= minVersion)
++nFound;
pstart = pstart->pprev;
}
UniValue rv(UniValue::VOBJ); UniValue rv(UniValue::VOBJ);
rv.push_back(Pair("status", nFound >= nRequired)); bool activated = false;
rv.push_back(Pair("found", nFound)); switch(version)
rv.push_back(Pair("required", nRequired)); {
rv.push_back(Pair("window", consensusParams.nMajorityWindow)); case 2:
activated = pindex->nHeight >= consensusParams.BIP34Height;
break;
case 3:
activated = pindex->nHeight >= consensusParams.BIP66Height;
break;
case 4:
activated = pindex->nHeight >= consensusParams.BIP65Height;
break;
}
rv.push_back(Pair("status", activated));
return rv; return rv;
} }
@ -841,8 +842,7 @@ static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex*
UniValue rv(UniValue::VOBJ); UniValue rv(UniValue::VOBJ);
rv.push_back(Pair("id", name)); rv.push_back(Pair("id", name));
rv.push_back(Pair("version", version)); rv.push_back(Pair("version", version));
rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))); rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams)));
rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityRejectBlockOutdated, consensusParams)));
return rv; return rv;
} }
@ -897,13 +897,9 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp)
" {\n" " {\n"
" \"id\": \"xxxx\", (string) name of softfork\n" " \"id\": \"xxxx\", (string) name of softfork\n"
" \"version\": xx, (numeric) block version\n" " \"version\": xx, (numeric) block version\n"
" \"enforce\": { (object) progress toward enforcing the softfork rules for new-version blocks\n" " \"reject\": { (object) progress toward rejecting pre-softfork blocks\n"
" \"status\": xx, (boolean) true if threshold reached\n" " \"status\": xx, (boolean) true if threshold reached\n"
" \"found\": xx, (numeric) number of blocks with the new version found\n"
" \"required\": xx, (numeric) number of blocks required to trigger\n"
" \"window\": xx, (numeric) maximum size of examined window of recent blocks\n"
" },\n" " },\n"
" \"reject\": { ... } (object) progress toward rejecting pre-softfork blocks (same fields as \"enforce\")\n"
" }, ...\n" " }, ...\n"
" ],\n" " ],\n"
" \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n" " \"bip9_softforks\": { (object) status of BIP9 softforks in progress\n"