diff options
author | Luke Dashjr <luke-jr+git@utopios.org> | 2012-08-26 21:10:06 +0000 |
---|---|---|
committer | Luke Dashjr <luke-jr+git@utopios.org> | 2012-08-26 21:10:06 +0000 |
commit | 689b878c33e41df0bd692ac3189a0e2089abf8bf (patch) | |
tree | 73de684c4dd8d6c660e49a1b8d69ee7a837a534b | |
parent | b958999af17473300e5b3cd26bd16997e21dd644 (diff) | |
parent | 2d57b561c212a7587aed895792b506807d3923c3 (diff) | |
download | bitcoin-689b878c33e41df0bd692ac3189a0e2089abf8bf.tar.xz |
Merge branch '0.4.x' into 0.5.x
Conflicts:
src/main.cpp
-rw-r--r-- | src/main.cpp | 39 | ||||
-rw-r--r-- | src/main.h | 12 |
2 files changed, 47 insertions, 4 deletions
diff --git a/src/main.cpp b/src/main.cpp index c06eb88887..e9577ed27f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1574,6 +1574,28 @@ bool CBlock::AcceptBlock() if (!Checkpoints::CheckBlock(nHeight, hash)) return DoS(100, error("AcceptBlock() : rejected by checkpoint lockin at %d", nHeight)); + // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: + if (nVersion < 2) + { + if ((!fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 950, 1000)) || + (fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 75, 100))) + { + return error("AcceptBlock() : rejected nVersion=1 block"); + } + } + // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height + if (nVersion >= 2) + { + // 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"); @@ -1595,6 +1617,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 ProcessBlock(CNode* pfrom, CBlock* pblock) { // Check for duplicate @@ -1729,7 +1763,7 @@ FILE* AppendBlockFile(unsigned int& nFileRet) if (fseek(file, 0, SEEK_END) != 0) return NULL; // FAT32 file size max 4GB, fseek and ftell max 2GB, so we must stay under 2GB - if (ftell(file) < 0x7F000000 - MAX_SIZE) + if (ftell(file) < (long)(0x7F000000 - MAX_SIZE)) { nFileRet = nCurrentBlockFile; return file; @@ -3191,7 +3225,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 13931d077a..7a8e2d45cf 100644 --- a/src/main.h +++ b/src/main.h @@ -398,6 +398,7 @@ typedef std::map<uint256, std::pair<CTxIndex, CTransaction> > MapPrevTx; class CTransaction { public: + static const int CURRENT_VERSION=1; int nVersion; std::vector<CTxIn> vin; std::vector<CTxOut> vout; @@ -423,7 +424,7 @@ public: void SetNull() { - nVersion = 1; + nVersion = CTransaction::CURRENT_VERSION; vin.clear(); vout.clear(); nLockTime = 0; @@ -836,6 +837,7 @@ class CBlock { public: // header + static const int CURRENT_VERSION=2; int nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; @@ -877,7 +879,7 @@ public: void SetNull() { - nVersion = 1; + nVersion = CBlock::CURRENT_VERSION; hashPrevBlock = 0; hashMerkleRoot = 0; nTime = 0; @@ -1206,6 +1208,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 |