Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 2,499 Lines • ▼ Show 20 Lines | do { | ||||
bool fInvalidAncestor = false; | bool fInvalidAncestor = false; | ||||
while (pindexTest && !chainActive.Contains(pindexTest)) { | while (pindexTest && !chainActive.Contains(pindexTest)) { | ||||
assert(pindexTest->nChainTx || pindexTest->nHeight == 0); | assert(pindexTest->nChainTx || pindexTest->nHeight == 0); | ||||
// Pruned nodes may have entries in setBlockIndexCandidates for | // Pruned nodes may have entries in setBlockIndexCandidates for | ||||
// which block files have been deleted. Remove those as candidates | // which block files have been deleted. Remove those as candidates | ||||
// for the most work chain if we come across them; we can't switch | // for the most work chain if we come across them; we can't switch | ||||
// to a chain unless we have all the non-active-chain parent blocks. | // to a chain unless we have all the non-active-chain parent blocks. | ||||
bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK; | bool fFailedChain = pindexTest->nStatus & BLOCK_FAILED_MASK || | ||||
pindexTest->nStatus & BLOCK_EXCESSIVE; | |||||
deadalnix: I think it is worth adding a new mask for that one. | |||||
bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA); | bool fMissingData = !(pindexTest->nStatus & BLOCK_HAVE_DATA); | ||||
if (fFailedChain || fMissingData) { | if (fFailedChain || fMissingData) { | ||||
// Candidate chain is not usable (either invalid or missing | // Candidate chain is not usable (either invalid or missing | ||||
// data) | // data) | ||||
if (fFailedChain && | if (fFailedChain && | ||||
(pindexBestInvalid == nullptr || | (pindexBestInvalid == nullptr || | ||||
pindexNew->nChainWork > pindexBestInvalid->nChainWork)) | pindexNew->nChainWork > pindexBestInvalid->nChainWork)) | ||||
pindexBestInvalid = pindexNew; | pindexBestInvalid = pindexNew; | ||||
▲ Show 20 Lines • Show All 621 Lines • ▼ Show 20 Lines | if (block.vtx.empty()) { | ||||
"first tx is not coinbase"); | "first tx is not coinbase"); | ||||
} | } | ||||
// Size limits. | // Size limits. | ||||
auto nMaxBlockSize = config.GetMaxBlockSize(); | auto nMaxBlockSize = config.GetMaxBlockSize(); | ||||
// Bail early if there is no way this block is of reasonable size. | // Bail early if there is no way this block is of reasonable size. | ||||
if ((block.vtx.size() * MIN_TRANSACTION_SIZE) > nMaxBlockSize) { | if ((block.vtx.size() * MIN_TRANSACTION_SIZE) > nMaxBlockSize) { | ||||
return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, | return state.Excessive(100, false, REJECT_INVALID, "bad-blk-length", | ||||
"size limits failed"); | false, "size limits failed"); | ||||
deadalnixUnsubmitted Not Done Inline ActionsIf we are going to increase ban score for excessive blocks, we need to make sure we have some automatic way to decrement ban score. Also 100 seems excessive (!). deadalnix: If we are going to increase ban score for excessive blocks, we need to make sure we have some… | |||||
hanchonUnsubmitted Not Done Inline ActionsI reduced the score to 10, but it may need to be lower. It should allow a node to send enough big blocks to activate EC but without attacking the node. When the select best chain algorithm is ready, this score should be easier to determinate. hanchon: I reduced the score to 10, but it may need to be lower. It should allow a node to send enough… | |||||
deadalnixUnsubmitted Not Done Inline ActionsI'd say the best strategy here is probably to have a way to decrease the ban score of a node if the node doesn't misbehave for a while. But that is somewhat different from what is done here, so just doing 10 is fine, IMO. deadalnix: I'd say the best strategy here is probably to have a way to decrease the ban score of a node if… | |||||
} | } | ||||
auto currentBlockSize = | auto currentBlockSize = | ||||
::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); | ::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION); | ||||
if (currentBlockSize > nMaxBlockSize) { | if (currentBlockSize > nMaxBlockSize) { | ||||
return state.DoS(100, false, REJECT_INVALID, "bad-blk-length", false, | return state.Excessive(100, false, REJECT_INVALID, "bad-blk-length", | ||||
"size limits failed"); | false, "size limits failed"); | ||||
deadalnixUnsubmitted Done Inline Actionsdito deadalnix: dito | |||||
} | } | ||||
// And a valid coinbase. | // And a valid coinbase. | ||||
if (!CheckCoinbase(*block.vtx[0], state, false)) { | if (!CheckCoinbase(*block.vtx[0], state, false)) { | ||||
return state.Invalid(false, state.GetRejectCode(), | return state.Invalid(false, state.GetRejectCode(), | ||||
state.GetRejectReason(), | state.GetRejectReason(), | ||||
strprintf("Coinbase check failed (txid %s) %s", | strprintf("Coinbase check failed (txid %s) %s", | ||||
block.vtx[0]->GetId().ToString(), | block.vtx[0]->GetId().ToString(), | ||||
▲ Show 20 Lines • Show All 381 Lines • ▼ Show 20 Lines | static bool AcceptBlock(const Config &config, | ||||
const CChainParams &chainparams = config.GetChainParams(); | const CChainParams &chainparams = config.GetChainParams(); | ||||
if (!CheckBlock(config, block, state, chainparams.GetConsensus()) || | if (!CheckBlock(config, block, state, chainparams.GetConsensus()) || | ||||
!ContextualCheckBlock(config, block, state, chainparams.GetConsensus(), | !ContextualCheckBlock(config, block, state, chainparams.GetConsensus(), | ||||
pindex->pprev)) { | pindex->pprev)) { | ||||
if (state.IsInvalid() && !state.CorruptionPossible()) { | if (state.IsInvalid() && !state.CorruptionPossible()) { | ||||
pindex->nStatus |= BLOCK_FAILED_VALID; | pindex->nStatus |= BLOCK_FAILED_VALID; | ||||
setDirtyBlockIndex.insert(pindex); | setDirtyBlockIndex.insert(pindex); | ||||
} else if (state.IsExcessive() && !state.CorruptionPossible()) { | |||||
pindex->nStatus |= BLOCK_EXCESSIVE; | |||||
setDirtyBlockIndex.insert(pindex); | |||||
} | } | ||||
return error("%s: %s (block %s)", __func__, FormatStateMessage(state), | return error("%s: %s (block %s)", __func__, FormatStateMessage(state), | ||||
block.GetHash().ToString()); | block.GetHash().ToString()); | ||||
} | } | ||||
// Header is valid/has work, merkle tree and segwit merkle tree are | // Header is valid/has work, merkle tree and segwit merkle tree are | ||||
// good...RELAY NOW (but if it does not build on our best tip, let the | // good...RELAY NOW (but if it does not build on our best tip, let the | ||||
// SendMessages loop relay it) | // SendMessages loop relay it) | ||||
▲ Show 20 Lines • Show All 1,403 Lines • Show Last 20 Lines |
I think it is worth adding a new mask for that one.