|
|
|
@ -1826,6 +1826,28 @@ bool CBlock::AcceptBlock()
@@ -1826,6 +1826,28 @@ bool CBlock::AcceptBlock()
|
|
|
|
|
if (!Checkpoints::CheckBlock(nHeight, hash)) |
|
|
|
|
return DoS(100, error("AcceptBlock() : rejected by checkpoint lock-in 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 DoS(100, error("AcceptBlock() : block height mismatch in coinbase")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Write block to history file
|
|
|
|
|
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION))) |
|
|
|
|
return error("AcceptBlock() : out of disk space"); |
|
|
|
@ -1849,6 +1871,18 @@ bool CBlock::AcceptBlock()
@@ -1849,6 +1871,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
|
|
|
|
@ -3663,7 +3697,8 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
@@ -3663,7 +3697,8 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
|
|
|
|
|
hashPrevBlock = pblock->hashPrevBlock; |
|
|
|
|
} |
|
|
|
|
++nExtraNonce; |
|
|
|
|
pblock->vtx[0].vin[0].scriptSig = (CScript() << pblock->nTime << CBigNum(nExtraNonce)) + COINBASE_FLAGS; |
|
|
|
|
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)) + COINBASE_FLAGS; |
|
|
|
|
assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100); |
|
|
|
|
|
|
|
|
|
pblock->hashMerkleRoot = pblock->BuildMerkleTree(); |
|
|
|
|