Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 507 Lines • ▼ Show 20 Lines | for (const CTxIn &txin : tx.vin) { | ||||
bool fSpendsCoinbase = false; | bool fSpendsCoinbase = false; | ||||
for (const CTxIn &txin : tx.vin) { | for (const CTxIn &txin : tx.vin) { | ||||
const Coin &coin = view.AccessCoin(txin.prevout); | const Coin &coin = view.AccessCoin(txin.prevout); | ||||
if (coin.IsCoinBase()) { | if (coin.IsCoinBase()) { | ||||
fSpendsCoinbase = true; | fSpendsCoinbase = true; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
auto nSigOpsCount = | |||||
GetTransactionSigOpCount(tx, view, nextBlockScriptVerifyFlags); | |||||
// Check that the transaction doesn't have an excessive number of | |||||
// sigops. | |||||
static_assert(MAX_STANDARD_TX_SIGOPS <= MAX_TX_SIGOPS_COUNT, | |||||
"we don't want transactions we can't even mine"); | |||||
if (nSigOpsCount > MAX_STANDARD_TX_SIGOPS) { | |||||
return state.DoS(0, false, REJECT_NONSTANDARD, | |||||
"bad-txns-too-many-sigops", false, | |||||
strprintf("%d", nSigOpsCount)); | |||||
} | |||||
unsigned int nSize = tx.GetTotalSize(); | unsigned int nSize = tx.GetTotalSize(); | ||||
// No transactions are allowed below minRelayTxFee except from | // No transactions are allowed below minRelayTxFee except from | ||||
// disconnected blocks. | // disconnected blocks. | ||||
// Do not change this to use virtualsize without coordinating a network | // Do not change this to use virtualsize without coordinating a network | ||||
// policy upgrade. | // policy upgrade. | ||||
if (!bypass_limits && nModifiedFees < minRelayTxFee.GetFee(nSize)) { | if (!bypass_limits && nModifiedFees < minRelayTxFee.GetFee(nSize)) { | ||||
Show All 12 Lines | for (const CTxIn &txin : tx.vin) { | ||||
PrecomputedTransactionData txdata(tx); | PrecomputedTransactionData txdata(tx); | ||||
int nSigChecksStandard; | int nSigChecksStandard; | ||||
if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, false, | if (!CheckInputs(tx, state, view, true, scriptVerifyFlags, true, false, | ||||
txdata, nSigChecksStandard)) { | txdata, nSigChecksStandard)) { | ||||
// State filled in by CheckInputs. | // State filled in by CheckInputs. | ||||
return false; | return false; | ||||
} | } | ||||
// After the sigchecks activation we repurpose the 'sigops' tracking in | |||||
// mempool/mining to actually track sigchecks instead. (Proper SigOps | |||||
// will not need to be counted any more since it's getting deactivated.) | |||||
auto nSigChecksOrOps = | |||||
(nextBlockScriptVerifyFlags & SCRIPT_REPORT_SIGCHECKS) | |||||
? nSigChecksStandard | |||||
: nSigOpsCount; | |||||
CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, ::ChainActive().Height(), | CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, ::ChainActive().Height(), | ||||
fSpendsCoinbase, nSigChecksOrOps, lp); | fSpendsCoinbase, nSigChecksStandard, lp); | ||||
unsigned int nVirtualSize = entry.GetTxVirtualSize(); | unsigned int nVirtualSize = entry.GetTxVirtualSize(); | ||||
Amount mempoolRejectFee = | Amount mempoolRejectFee = | ||||
pool.GetMinFee( | pool.GetMinFee( | ||||
gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * | gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * | ||||
1000000) | 1000000) | ||||
.GetFee(nVirtualSize); | .GetFee(nVirtualSize); | ||||
▲ Show 20 Lines • Show All 1,187 Lines • ▼ Show 20 Lines | for (const auto &ptx : block.vtx) { | ||||
if (!MoneyRange(nFees)) { | if (!MoneyRange(nFees)) { | ||||
return state.DoS( | return state.DoS( | ||||
100, | 100, | ||||
error("%s: accumulated fee in the block out of range.", | error("%s: accumulated fee in the block out of range.", | ||||
__func__), | __func__), | ||||
REJECT_INVALID, "bad-txns-accumulated-fee-outofrange"); | REJECT_INVALID, "bad-txns-accumulated-fee-outofrange"); | ||||
} | } | ||||
// GetTransactionSigOpCount counts 2 types of sigops: | |||||
// * legacy (always) | |||||
// * p2sh (when P2SH enabled in flags and excludes coinbase) | |||||
auto txSigOpsCount = GetTransactionSigOpCount(tx, view, flags); | |||||
if (txSigOpsCount > MAX_TX_SIGOPS_COUNT) { | |||||
return state.DoS(100, false, REJECT_INVALID, "bad-txn-sigops"); | |||||
} | |||||
// The following checks do not apply to the coinbase. | // The following checks do not apply to the coinbase. | ||||
if (isCoinBase) { | if (isCoinBase) { | ||||
continue; | continue; | ||||
} | } | ||||
// Check that transaction is BIP68 final BIP68 lock checks (as | // Check that transaction is BIP68 final BIP68 lock checks (as | ||||
// opposed to nLockTime checks) must be in ConnectBlock because they | // opposed to nLockTime checks) must be in ConnectBlock because they | ||||
// require the UTXO set. | // require the UTXO set. | ||||
▲ Show 20 Lines • Show All 1,901 Lines • ▼ Show 20 Lines | static bool ContextualCheckBlock(const CBlock &block, CValidationState &state, | ||||
const int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) | const int64_t nLockTimeCutoff = (nLockTimeFlags & LOCKTIME_MEDIAN_TIME_PAST) | ||||
? nMedianTimePast | ? nMedianTimePast | ||||
: block.GetBlockTime(); | : block.GetBlockTime(); | ||||
const bool fIsMagneticAnomalyEnabled = | const bool fIsMagneticAnomalyEnabled = | ||||
IsMagneticAnomalyEnabled(params, pindexPrev); | IsMagneticAnomalyEnabled(params, pindexPrev); | ||||
// Note that pindexPrev may be null if reindexing genesis block. | |||||
const auto scriptFlags = pindexPrev | |||||
? GetNextBlockScriptFlags(params, pindexPrev) | |||||
: SCRIPT_VERIFY_NONE; | |||||
// Check transactions: | // Check transactions: | ||||
// - canonical ordering | // - canonical ordering | ||||
// - ensure they are finalized | // - ensure they are finalized | ||||
// - perform a preliminary block-sigops count (they will be recounted more | // - perform a preliminary block-sigops count (they will be recounted more | ||||
// strictly during ConnectBlock). | // strictly during ConnectBlock). | ||||
// - perform a transaction-sigops check (again, a more strict check will | // - perform a transaction-sigops check (again, a more strict check will | ||||
// happen in ConnectBlock). | // happen in ConnectBlock). | ||||
const CTransaction *prevTx = nullptr; | const CTransaction *prevTx = nullptr; | ||||
Show All 15 Lines | for (const auto &ptx : block.vtx) { | ||||
prevTx->GetId().ToString())); | prevTx->GetId().ToString())); | ||||
} | } | ||||
if (prevTx || !tx.IsCoinBase()) { | if (prevTx || !tx.IsCoinBase()) { | ||||
prevTx = &tx; | prevTx = &tx; | ||||
} | } | ||||
} | } | ||||
// Count the sigops for the current transaction. If the tx or total | |||||
// sigops counts are too high, then the block is invalid. | |||||
const auto txSigOps = GetSigOpCountWithoutP2SH(tx, scriptFlags); | |||||
if (txSigOps > MAX_TX_SIGOPS_COUNT) { | |||||
return state.DoS(100, false, REJECT_INVALID, "bad-txn-sigops", | |||||
false, "out-of-bounds SigOpCount"); | |||||
} | |||||
if (!ContextualCheckTransaction(params, tx, state, nHeight, | if (!ContextualCheckTransaction(params, tx, state, nHeight, | ||||
nLockTimeCutoff, nMedianTimePast)) { | nLockTimeCutoff, nMedianTimePast)) { | ||||
// state set by ContextualCheckTransaction. | // state set by ContextualCheckTransaction. | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
// Enforce rule that the coinbase starts with serialized block height | // Enforce rule that the coinbase starts with serialized block height | ||||
▲ Show 20 Lines • Show All 1,958 Lines • Show Last 20 Lines |