From f51b175e3c9f7326267ca0eef0dd8ae2f28b4fad Mon Sep 17 00:00:00 2001 From: Philip Kaufmann Date: Fri, 17 Aug 2012 10:35:51 +0200 Subject: [PATCH 1/4] fix a compiler sign warning in OpenBlockFile() --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index ef59d31f9a8..9e1b228b2ad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1705,7 +1705,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; From d710ed5b637ab8a4fca433b9b6d331c1e4b97908 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 27 Jun 2012 12:43:19 -0400 Subject: [PATCH 2/4] Add CBlock::CURRENT_VERSION and CTransaction::CURRENT_VERSION constants. Partial of upstream dae3e10a5abe93833c57183b7c00f1db9200f46e --- src/main.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main.h b/src/main.h index 4edea5ed46e..8f9e07f7a82 100644 --- a/src/main.h +++ b/src/main.h @@ -396,6 +396,7 @@ typedef std::map > MapPrevTx; class CTransaction { public: + static const int CURRENT_VERSION=1; int nVersion; std::vector vin; std::vector vout; @@ -418,7 +419,7 @@ public: void SetNull() { - nVersion = 1; + nVersion = CTransaction::CURRENT_VERSION; vin.clear(); vout.clear(); nLockTime = 0; @@ -830,6 +831,7 @@ class CBlock { public: // header + static const int CURRENT_VERSION=1; int nVersion; uint256 hashPrevBlock; uint256 hashMerkleRoot; @@ -868,7 +870,7 @@ public: void SetNull() { - nVersion = 1; + nVersion = CBlock::CURRENT_VERSION; hashPrevBlock = 0; hashMerkleRoot = 0; nTime = 0; From 9adab76e0ae07d33d661c7b51b8f89cbfb119870 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Wed, 27 Jun 2012 19:30:39 -0400 Subject: [PATCH 3/4] 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. --- src/main.cpp | 28 +++++++++++++++++++++++++++- src/main.h | 8 +++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9e1b228b2ad..fc57713129b 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 8f9e07f7a82..8ca1afe6330 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 From 2d57b561c212a7587aed895792b506807d3923c3 Mon Sep 17 00:00:00 2001 From: Gavin Andresen Date: Thu, 5 Jul 2012 21:22:16 -0400 Subject: [PATCH 4/4] Reject block.nVersion<=1 blocks if network has upgraded to version=2 If 950 of the last 1,000 blocks are nVersion=2, reject nVersion=1 (or zero, but no bitcoin release has created block.nVersion=0) blocks -- 75 of last 100 on testnet3. This rule is being put in place now so that we don't have to go through another "express support" process to get what we really want, which is for every single new block to include the block height in the coinbase. --- src/main.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index fc57713129b..1821576dc55 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1554,8 +1554,17 @@ bool CBlock::AcceptBlock() if (!Checkpoints::CheckBlock(nHeight, hash)) return 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 > 1) + 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)) ||