diff options
author | Gavin Andresen <gavinandresen@gmail.com> | 2012-06-27 19:30:39 -0400 |
---|---|---|
committer | Luke Dashjr <luke-jr+git@utopios.org> | 2012-08-26 21:06:26 +0000 |
commit | 9adab76e0ae07d33d661c7b51b8f89cbfb119870 (patch) | |
tree | c9fbc9a4db9c85e36424ebb451610b6220f390b5 | |
parent | d710ed5b637ab8a4fca433b9b6d331c1e4b97908 (diff) | |
download | bitcoin-9adab76e0ae07d33d661c7b51b8f89cbfb119870.tar.xz |
Block height in coinbase as a new block rule
"Version 2" blocks are blocks that have nVersion=2 and
have the block height as the first item in their coinbase.
Block-height-in-the-coinbase is strictly enforced when
version=2 blocks are a supermajority in the block chain
(750 of the last 1,000 blocks on main net, 51 of 100 for
testnet). This does not affect old clients/miners at all,
which will continue producing nVersion=1 blocks, and
which will continue to be valid.
-rw-r--r-- | src/main.cpp | 28 | ||||
-rw-r--r-- | src/main.h | 8 |
2 files changed, 34 insertions, 2 deletions
diff --git a/src/main.cpp b/src/main.cpp index 9e1b228b2a..fc57713129 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1554,6 +1554,19 @@ bool CBlock::AcceptBlock() if (!Checkpoints::CheckBlock(nHeight, hash)) return error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight); + // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height + if (nVersion > 1) + { + // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): + if ((!fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 750, 1000)) || + (fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 51, 100))) + { + CScript expect = CScript() << nHeight; + if (!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) + return error("AcceptBlock() : block height mismatch in coinbase"); + } + } + // Write block to history file if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK))) return error("AcceptBlock() : out of disk space"); @@ -1575,6 +1588,18 @@ bool CBlock::AcceptBlock() return true; } +bool CBlockIndex::IsSuperMajority(int minVersion, const CBlockIndex* pstart, unsigned int nRequired, unsigned int nToCheck) +{ + unsigned int nFound = 0; + for (unsigned int i = 0; i < nToCheck && nFound < nRequired && pstart != NULL; i++) + { + if (pstart->nVersion >= minVersion) + ++nFound; + pstart = pstart->pprev; + } + return (nFound >= nRequired); +} + bool static ProcessBlock(CNode* pfrom, CBlock* pblock) { // Check for duplicate @@ -3140,7 +3165,8 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& hashPrevBlock = pblock->hashPrevBlock; } ++nExtraNonce; - pblock->vtx[0].vin[0].scriptSig = CScript() << pblock->nTime << CBigNum(nExtraNonce); + unsigned int nHeight = pindexPrev->nHeight+1; // Height first in coinbase required for block.version=2 + pblock->vtx[0].vin[0].scriptSig = CScript() << nHeight << CBigNum(nExtraNonce); pblock->hashMerkleRoot = pblock->BuildMerkleTree(); } diff --git a/src/main.h b/src/main.h index 8f9e07f7a8..8ca1afe633 100644 --- a/src/main.h +++ b/src/main.h @@ -831,7 +831,7 @@ class CBlock { public: // header - static const int CURRENT_VERSION=1; + static const int CURRENT_VERSION=2; int nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; @@ -1198,6 +1198,12 @@ public: return pindex->GetMedianTimePast(); } + /** + * Returns true if there are nRequired or more blocks of minVersion or above + * in the last nToCheck blocks, starting at pstart and going backwards. + */ + static bool IsSuperMajority(int minVersion, const CBlockIndex* pstart, + unsigned int nRequired, unsigned int nToCheck); std::string ToString() const |