|
|
@ -2288,16 +2288,8 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) |
|
|
|
bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// These are checks that are independent of context
|
|
|
|
|
|
|
|
// that can be verified before saving an orphan block.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Size limits
|
|
|
|
|
|
|
|
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) |
|
|
|
|
|
|
|
return state.DoS(100, error("CheckBlock() : size limits failed"), |
|
|
|
|
|
|
|
REJECT_INVALID, "bad-blk-length"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check proof of work matches claimed amount
|
|
|
|
// Check proof of work matches claimed amount
|
|
|
|
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits)) |
|
|
|
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits)) |
|
|
|
return state.DoS(50, error("CheckBlock() : proof of work failed"), |
|
|
|
return state.DoS(50, error("CheckBlock() : proof of work failed"), |
|
|
@ -2308,6 +2300,22 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo |
|
|
|
return state.Invalid(error("CheckBlock() : block timestamp too far in the future"), |
|
|
|
return state.Invalid(error("CheckBlock() : block timestamp too far in the future"), |
|
|
|
REJECT_INVALID, "time-too-new"); |
|
|
|
REJECT_INVALID, "time-too-new"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bool fCheckMerkleRoot) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// These are checks that are independent of context
|
|
|
|
|
|
|
|
// that can be verified before saving an orphan block.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!CheckBlockHeader(block, state, fCheckPOW)) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Size limits
|
|
|
|
|
|
|
|
if (block.vtx.empty() || block.vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE) |
|
|
|
|
|
|
|
return state.DoS(100, error("CheckBlock() : size limits failed"), |
|
|
|
|
|
|
|
REJECT_INVALID, "bad-blk-length"); |
|
|
|
|
|
|
|
|
|
|
|
// First transaction must be coinbase, the rest must not be
|
|
|
|
// First transaction must be coinbase, the rest must not be
|
|
|
|
if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) |
|
|
|
if (block.vtx.empty() || !block.vtx[0].IsCoinBase()) |
|
|
|
return state.DoS(100, error("CheckBlock() : first tx is not coinbase"), |
|
|
|
return state.DoS(100, error("CheckBlock() : first tx is not coinbase"), |
|
|
|