Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 463 Lines • ▼ Show 20 Lines | if (fRequireStandard && !IsStandardTx(tx, reason)) { | ||||
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason); | return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason); | ||||
} | } | ||||
// Only accept nLockTime-using transactions that can be mined in the next | // Only accept nLockTime-using transactions that can be mined in the next | ||||
// block; we don't want our mempool filled up with transactions that can't | // block; we don't want our mempool filled up with transactions that can't | ||||
// be mined yet. | // be mined yet. | ||||
TxValidationState ctxState; | TxValidationState ctxState; | ||||
if (!ContextualCheckTransactionForCurrentBlock( | if (!ContextualCheckTransactionForCurrentBlock( | ||||
::ChainActive().Tip(), | |||||
args.m_config.GetChainParams().GetConsensus(), tx, ctxState, | args.m_config.GetChainParams().GetConsensus(), tx, ctxState, | ||||
STANDARD_LOCKTIME_VERIFY_FLAGS)) { | STANDARD_LOCKTIME_VERIFY_FLAGS)) { | ||||
// We copy the state from a dummy to ensure we don't increase the | // We copy the state from a dummy to ensure we don't increase the | ||||
// ban score of peer for transaction that could be valid in the future. | // ban score of peer for transaction that could be valid in the future. | ||||
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, | return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, | ||||
ctxState.GetRejectReason(), | ctxState.GetRejectReason(), | ||||
ctxState.GetDebugMessage()); | ctxState.GetDebugMessage()); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 3,455 Lines • ▼ Show 20 Lines | if ((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) || | ||||
BlockValidationResult::BLOCK_INVALID_HEADER, | BlockValidationResult::BLOCK_INVALID_HEADER, | ||||
strprintf("bad-version(0x%08x)", block.nVersion), | strprintf("bad-version(0x%08x)", block.nVersion), | ||||
strprintf("rejected nVersion=0x%08x block", block.nVersion)); | strprintf("rejected nVersion=0x%08x block", block.nVersion)); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool ContextualCheckTransactionForCurrentBlock(const Consensus::Params ¶ms, | bool ContextualCheckTransactionForCurrentBlock( | ||||
const CTransaction &tx, | const CBlockIndex *active_chain_tip, const Consensus::Params ¶ms, | ||||
TxValidationState &state, | const CTransaction &tx, TxValidationState &state, int flags) { | ||||
int flags) { | |||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
assert(std::addressof(*::ChainActive().Tip()) == | |||||
std::addressof(*active_chain_tip)); | |||||
// By convention a negative value for flags indicates that the current | // By convention a negative value for flags indicates that the current | ||||
// network-enforced consensus rules should be used. In a future soft-fork | // network-enforced consensus rules should be used. In a future soft-fork | ||||
// scenario that would mean checking which rules would be enforced for the | // scenario that would mean checking which rules would be enforced for the | ||||
// next block and setting the appropriate flags. At the present time no | // next block and setting the appropriate flags. At the present time no | ||||
// soft-forks are scheduled, so no flags are set. | // soft-forks are scheduled, so no flags are set. | ||||
flags = std::max(flags, 0); | flags = std::max(flags, 0); | ||||
// ContextualCheckTransactionForCurrentBlock() uses | // ContextualCheckTransactionForCurrentBlock() uses | ||||
// ::ChainActive().Height()+1 to evaluate nLockTime because when IsFinalTx() | // ::ChainActive().Height()+1 to evaluate nLockTime because when IsFinalTx() | ||||
// is called within CBlock::AcceptBlock(), the height of the block *being* | // is called within CBlock::AcceptBlock(), the height of the block *being* | ||||
// evaluated is what is used. Thus if we want to know if a transaction can | // evaluated is what is used. Thus if we want to know if a transaction can | ||||
// be part of the *next* block, we need to call ContextualCheckTransaction() | // be part of the *next* block, we need to call ContextualCheckTransaction() | ||||
// with one more than ::ChainActive().Height(). | // with one more than ::ChainActive().Height(). | ||||
const int nBlockHeight = ::ChainActive().Height() + 1; | const int nBlockHeight = active_chain_tip->nHeight + 1; | ||||
// BIP113 will require that time-locked transactions have nLockTime set to | // BIP113 will require that time-locked transactions have nLockTime set to | ||||
// less than the median time of the previous block they're contained in. | // less than the median time of the previous block they're contained in. | ||||
// When the next block is created its previous block will be the current | // When the next block is created its previous block will be the current | ||||
// chain tip, so we use that to calculate the median time passed to | // chain tip, so we use that to calculate the median time passed to | ||||
// ContextualCheckTransaction() if LOCKTIME_MEDIAN_TIME_PAST is set. | // ContextualCheckTransaction() if LOCKTIME_MEDIAN_TIME_PAST is set. | ||||
const int64_t nMedianTimePast = | const int64_t nMedianTimePast = | ||||
::ChainActive().Tip() == nullptr | active_chain_tip == nullptr ? 0 : active_chain_tip->GetMedianTimePast(); | ||||
? 0 | |||||
: ::ChainActive().Tip()->GetMedianTimePast(); | |||||
const int64_t nLockTimeCutoff = (flags & LOCKTIME_MEDIAN_TIME_PAST) | const int64_t nLockTimeCutoff = (flags & LOCKTIME_MEDIAN_TIME_PAST) | ||||
? nMedianTimePast | ? nMedianTimePast | ||||
: GetAdjustedTime(); | : GetAdjustedTime(); | ||||
return ContextualCheckTransaction(params, tx, state, nBlockHeight, | return ContextualCheckTransaction(params, tx, state, nBlockHeight, | ||||
nLockTimeCutoff, nMedianTimePast); | nLockTimeCutoff, nMedianTimePast); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,190 Lines • Show Last 20 Lines |