aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorGavin Andresen <gavinandresen@gmail.com>2012-06-27 19:30:39 -0400
committerLuke Dashjr <luke-jr+git@utopios.org>2012-08-26 21:06:26 +0000
commit9adab76e0ae07d33d661c7b51b8f89cbfb119870 (patch)
treec9fbc9a4db9c85e36424ebb451610b6220f390b5 /src/main.cpp
parentd710ed5b637ab8a4fca433b9b6d331c1e4b97908 (diff)
downloadbitcoin-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.
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp28
1 files changed, 27 insertions, 1 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();
}