Merge pull request #1526 from gavinandresen/heightincoinbase
Transition to requiring block height in block coinbases
This commit is contained in:
commit
af3b5ea569
3 changed files with 44 additions and 2 deletions
37
src/main.cpp
37
src/main.cpp
|
@ -1826,6 +1826,28 @@ bool CBlock::AcceptBlock()
|
||||||
if (!Checkpoints::CheckBlock(nHeight, hash))
|
if (!Checkpoints::CheckBlock(nHeight, hash))
|
||||||
return DoS(100, error("AcceptBlock() : rejected by checkpoint lock-in at %d", nHeight));
|
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
|
// Write block to history file
|
||||||
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION)))
|
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION)))
|
||||||
return error("AcceptBlock() : out of disk space");
|
return error("AcceptBlock() : out of disk space");
|
||||||
|
@ -1849,6 +1871,18 @@ bool CBlock::AcceptBlock()
|
||||||
return true;
|
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)
|
bool ProcessBlock(CNode* pfrom, CBlock* pblock)
|
||||||
{
|
{
|
||||||
// Check for duplicate
|
// Check for duplicate
|
||||||
|
@ -3663,7 +3697,8 @@ void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int&
|
||||||
hashPrevBlock = pblock->hashPrevBlock;
|
hashPrevBlock = pblock->hashPrevBlock;
|
||||||
}
|
}
|
||||||
++nExtraNonce;
|
++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);
|
assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100);
|
||||||
|
|
||||||
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
pblock->hashMerkleRoot = pblock->BuildMerkleTree();
|
||||||
|
|
|
@ -820,7 +820,7 @@ class CBlock
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// header
|
// header
|
||||||
static const int CURRENT_VERSION=1;
|
static const int CURRENT_VERSION=2;
|
||||||
int nVersion;
|
int nVersion;
|
||||||
uint256 hashPrevBlock;
|
uint256 hashPrevBlock;
|
||||||
uint256 hashMerkleRoot;
|
uint256 hashMerkleRoot;
|
||||||
|
@ -1164,6 +1164,12 @@ public:
|
||||||
return pindex->GetMedianTimePast();
|
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
|
std::string ToString() const
|
||||||
|
|
|
@ -62,6 +62,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
||||||
std::vector<CTransaction*>txFirst;
|
std::vector<CTransaction*>txFirst;
|
||||||
for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i)
|
for (unsigned int i = 0; i < sizeof(blockinfo)/sizeof(*blockinfo); ++i)
|
||||||
{
|
{
|
||||||
|
pblock->nVersion = 1;
|
||||||
pblock->nTime = pindexBest->GetMedianTimePast()+1;
|
pblock->nTime = pindexBest->GetMedianTimePast()+1;
|
||||||
pblock->vtx[0].vin[0].scriptSig = CScript();
|
pblock->vtx[0].vin[0].scriptSig = CScript();
|
||||||
pblock->vtx[0].vin[0].scriptSig.push_back(blockinfo[i].extranonce);
|
pblock->vtx[0].vin[0].scriptSig.push_back(blockinfo[i].extranonce);
|
||||||
|
|
Loading…
Reference in a new issue