|
|
@ -2018,52 +2018,51 @@ bool CBlock::AcceptBlock(CDiskBlockPos *dbp) |
|
|
|
CBlockIndex* pindexPrev = NULL; |
|
|
|
CBlockIndex* pindexPrev = NULL; |
|
|
|
int nHeight = 0; |
|
|
|
int nHeight = 0; |
|
|
|
if (hash != hashGenesisBlock) { |
|
|
|
if (hash != hashGenesisBlock) { |
|
|
|
|
|
|
|
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); |
|
|
|
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock); |
|
|
|
if (mi == mapBlockIndex.end()) |
|
|
|
if (mi == mapBlockIndex.end()) |
|
|
|
return DoS(10, error("AcceptBlock() : prev block not found")); |
|
|
|
return DoS(10, error("AcceptBlock() : prev block not found")); |
|
|
|
pindexPrev = (*mi).second; |
|
|
|
pindexPrev = (*mi).second; |
|
|
|
nHeight = pindexPrev->nHeight+1; |
|
|
|
nHeight = pindexPrev->nHeight+1; |
|
|
|
|
|
|
|
|
|
|
|
// Check proof of work
|
|
|
|
// Check proof of work
|
|
|
|
if (nBits != GetNextWorkRequired(pindexPrev, this)) |
|
|
|
if (nBits != GetNextWorkRequired(pindexPrev, this)) |
|
|
|
return DoS(100, error("AcceptBlock() : incorrect proof of work")); |
|
|
|
return DoS(100, error("AcceptBlock() : incorrect proof of work")); |
|
|
|
|
|
|
|
|
|
|
|
// Check timestamp against prev
|
|
|
|
// Check timestamp against prev
|
|
|
|
if (GetBlockTime() <= pindexPrev->GetMedianTimePast()) |
|
|
|
if (GetBlockTime() <= pindexPrev->GetMedianTimePast()) |
|
|
|
return error("AcceptBlock() : block's timestamp is too early"); |
|
|
|
return error("AcceptBlock() : block's timestamp is too early"); |
|
|
|
|
|
|
|
|
|
|
|
// Check that all transactions are finalized
|
|
|
|
// Check that all transactions are finalized
|
|
|
|
BOOST_FOREACH(const CTransaction& tx, vtx) |
|
|
|
BOOST_FOREACH(const CTransaction& tx, vtx) |
|
|
|
if (!tx.IsFinal(nHeight, GetBlockTime())) |
|
|
|
if (!tx.IsFinal(nHeight, GetBlockTime())) |
|
|
|
return DoS(10, error("AcceptBlock() : contains a non-final transaction")); |
|
|
|
return DoS(10, error("AcceptBlock() : contains a non-final transaction")); |
|
|
|
|
|
|
|
|
|
|
|
// Check that the block chain matches the known block chain up to a checkpoint
|
|
|
|
// Check that the block chain matches the known block chain up to a checkpoint
|
|
|
|
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:
|
|
|
|
// Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded:
|
|
|
|
if (nVersion < 2) |
|
|
|
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"); |
|
|
|
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
|
|
|
|
// Enforce block.nVersion=2 rule that the coinbase starts with serialized block height
|
|
|
|
if (nVersion >= 2) |
|
|
|
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 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet):
|
|
|
|
if (!std::equal(expect.begin(), expect.end(), vtx[0].vin[0].scriptSig.begin())) |
|
|
|
if ((!fTestNet && CBlockIndex::IsSuperMajority(2, pindexPrev, 750, 1000)) || |
|
|
|
return DoS(100, error("AcceptBlock() : block height mismatch in coinbase")); |
|
|
|
(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
|
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION); |
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION); |
|
|
|