aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Dashjr <luke-jr+git@utopios.org>2012-08-26 21:10:06 +0000
committerLuke Dashjr <luke-jr+git@utopios.org>2012-08-26 21:10:06 +0000
commit689b878c33e41df0bd692ac3189a0e2089abf8bf (patch)
tree73de684c4dd8d6c660e49a1b8d69ee7a837a534b
parentb958999af17473300e5b3cd26bd16997e21dd644 (diff)
parent2d57b561c212a7587aed895792b506807d3923c3 (diff)
downloadbitcoin-689b878c33e41df0bd692ac3189a0e2089abf8bf.tar.xz
Merge branch '0.4.x' into 0.5.x
Conflicts: src/main.cpp
-rw-r--r--src/main.cpp39
-rw-r--r--src/main.h12
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