[validation] Remove useless ret parameter from Invalid()

ValidationState::Invalid() takes a parameter `ret` which is returned to
the caller. All call sites set this to false. Remove the `ret` parameter
and just return false always.
This commit is contained in:
John Newbery
2019-04-28 15:40:01 -05:00
parent 1a37de4b31
commit 7204c6434b
4 changed files with 74 additions and 74 deletions

View File

@@ -11,24 +11,24 @@ bool CheckTransaction(const CTransaction& tx, TxValidationState& state)
{ {
// Basic checks that don't depend on any context // Basic checks that don't depend on any context
if (tx.vin.empty()) if (tx.vin.empty())
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-vin-empty"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vin-empty");
if (tx.vout.empty()) if (tx.vout.empty())
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-vout-empty"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-empty");
// Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability) // Size limits (this doesn't take the witness into account, as that hasn't been checked for malleability)
if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-oversize"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-oversize");
// Check for negative or overflow output values (see CVE-2010-5139) // Check for negative or overflow output values (see CVE-2010-5139)
CAmount nValueOut = 0; CAmount nValueOut = 0;
for (const auto& txout : tx.vout) for (const auto& txout : tx.vout)
{ {
if (txout.nValue < 0) if (txout.nValue < 0)
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-vout-negative"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-negative");
if (txout.nValue > MAX_MONEY) if (txout.nValue > MAX_MONEY)
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-vout-toolarge"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-vout-toolarge");
nValueOut += txout.nValue; nValueOut += txout.nValue;
if (!MoneyRange(nValueOut)) if (!MoneyRange(nValueOut))
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-txouttotal-toolarge"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-txouttotal-toolarge");
} }
// Check for duplicate inputs (see CVE-2018-17144) // Check for duplicate inputs (see CVE-2018-17144)
@@ -39,19 +39,19 @@ bool CheckTransaction(const CTransaction& tx, TxValidationState& state)
std::set<COutPoint> vInOutPoints; std::set<COutPoint> vInOutPoints;
for (const auto& txin : tx.vin) { for (const auto& txin : tx.vin) {
if (!vInOutPoints.insert(txin.prevout).second) if (!vInOutPoints.insert(txin.prevout).second)
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-inputs-duplicate"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputs-duplicate");
} }
if (tx.IsCoinBase()) if (tx.IsCoinBase())
{ {
if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100) if (tx.vin[0].scriptSig.size() < 2 || tx.vin[0].scriptSig.size() > 100)
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-cb-length"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-cb-length");
} }
else else
{ {
for (const auto& txin : tx.vin) for (const auto& txin : tx.vin)
if (txin.prevout.IsNull()) if (txin.prevout.IsNull())
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-prevout-null"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-prevout-null");
} }
return true; return true;

View File

@@ -160,7 +160,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state,
{ {
// are the actual inputs available? // are the actual inputs available?
if (!inputs.HaveInputs(tx)) { if (!inputs.HaveInputs(tx)) {
return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, false, "bad-txns-inputs-missingorspent", return state.Invalid(TxValidationResult::TX_MISSING_INPUTS, "bad-txns-inputs-missingorspent",
strprintf("%s: inputs missing/spent", __func__)); strprintf("%s: inputs missing/spent", __func__));
} }
@@ -172,27 +172,27 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state,
// If prev is coinbase, check that it's matured // If prev is coinbase, check that it's matured
if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) { if (coin.IsCoinBase() && nSpendHeight - coin.nHeight < COINBASE_MATURITY) {
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, false, "bad-txns-premature-spend-of-coinbase", return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "bad-txns-premature-spend-of-coinbase",
strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight)); strprintf("tried to spend coinbase at depth %d", nSpendHeight - coin.nHeight));
} }
// Check for negative or overflow input values // Check for negative or overflow input values
nValueIn += coin.out.nValue; nValueIn += coin.out.nValue;
if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) { if (!MoneyRange(coin.out.nValue) || !MoneyRange(nValueIn)) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-inputvalues-outofrange"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-inputvalues-outofrange");
} }
} }
const CAmount value_out = tx.GetValueOut(); const CAmount value_out = tx.GetValueOut();
if (nValueIn < value_out) { if (nValueIn < value_out) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-in-belowout", return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-in-belowout",
strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out))); strprintf("value in (%s) < value out (%s)", FormatMoney(nValueIn), FormatMoney(value_out)));
} }
// Tally transaction fees // Tally transaction fees
const CAmount txfee_aux = nValueIn - value_out; const CAmount txfee_aux = nValueIn - value_out;
if (!MoneyRange(txfee_aux)) { if (!MoneyRange(txfee_aux)) {
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-fee-outofrange"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-fee-outofrange");
} }
txfee = txfee_aux; txfee = txfee_aux;

View File

@@ -121,13 +121,13 @@ class TxValidationState : public ValidationState {
private: private:
TxValidationResult m_result; TxValidationResult m_result;
public: public:
bool Invalid(TxValidationResult result, bool ret = false, bool Invalid(TxValidationResult result,
const std::string &reject_reason="", const std::string &reject_reason="",
const std::string &debug_message="") const std::string &debug_message="")
{ {
m_result = result; m_result = result;
ValidationState::Invalid(reject_reason, debug_message); ValidationState::Invalid(reject_reason, debug_message);
return ret; return false;
} }
TxValidationResult GetResult() const { return m_result; } TxValidationResult GetResult() const { return m_result; }
}; };
@@ -136,12 +136,12 @@ class BlockValidationState : public ValidationState {
private: private:
BlockValidationResult m_result; BlockValidationResult m_result;
public: public:
bool Invalid(BlockValidationResult result, bool ret = false, bool Invalid(BlockValidationResult result,
const std::string &reject_reason="", const std::string &reject_reason="",
const std::string &debug_message="") { const std::string &debug_message="") {
m_result = result; m_result = result;
ValidationState::Invalid(reject_reason, debug_message); ValidationState::Invalid(reject_reason, debug_message);
return ret; return false;
} }
BlockValidationResult GetResult() const { return m_result; } BlockValidationResult GetResult() const { return m_result; }
}; };

View File

@@ -506,11 +506,11 @@ private:
{ {
CAmount mempoolRejectFee = m_pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(package_size); CAmount mempoolRejectFee = m_pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(package_size);
if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) { if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee)); return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee));
} }
if (package_fee < ::minRelayTxFee.GetFee(package_size)) { if (package_fee < ::minRelayTxFee.GetFee(package_size)) {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "min relay fee not met", strprintf("%d < %d", package_fee, ::minRelayTxFee.GetFee(package_size))); return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "min relay fee not met", strprintf("%d < %d", package_fee, ::minRelayTxFee.GetFee(package_size)));
} }
return true; return true;
} }
@@ -563,29 +563,29 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// Coinbase is only valid in a block, not as a loose transaction // Coinbase is only valid in a block, not as a loose transaction
if (tx.IsCoinBase()) if (tx.IsCoinBase())
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "coinbase"); return state.Invalid(TxValidationResult::TX_CONSENSUS, "coinbase");
// Rather not work on nonstandard transactions (unless -testnet/-regtest) // Rather not work on nonstandard transactions (unless -testnet/-regtest)
std::string reason; std::string reason;
if (fRequireStandard && !IsStandardTx(tx, reason)) if (fRequireStandard && !IsStandardTx(tx, reason))
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, false, reason); return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason);
// Do not work on transactions that are too small. // Do not work on transactions that are too small.
// A transaction with 1 segwit input and 1 P2WPHK output has non-witness size of 82 bytes. // A transaction with 1 segwit input and 1 P2WPHK output has non-witness size of 82 bytes.
// Transactions smaller than this are not relayed to mitigate CVE-2017-12842 by not relaying // Transactions smaller than this are not relayed to mitigate CVE-2017-12842 by not relaying
// 64-byte transactions. // 64-byte transactions.
if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) < MIN_STANDARD_TX_NONWITNESS_SIZE) if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) < MIN_STANDARD_TX_NONWITNESS_SIZE)
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, false, "tx-size-small"); return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "tx-size-small");
// 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.
if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS)) if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, false, "non-final"); return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-final");
// is it already in the memory pool? // is it already in the memory pool?
if (m_pool.exists(hash)) { if (m_pool.exists(hash)) {
return state.Invalid(TxValidationResult::TX_CONFLICT, false, "txn-already-in-mempool"); return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-already-in-mempool");
} }
// Check for conflicts with in-memory transactions // Check for conflicts with in-memory transactions
@@ -617,7 +617,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
} }
} }
if (fReplacementOptOut) { if (fReplacementOptOut) {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "txn-mempool-conflict"); return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "txn-mempool-conflict");
} }
setConflicts.insert(ptxConflicting->GetHash()); setConflicts.insert(ptxConflicting->GetHash());
@@ -643,7 +643,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
for (size_t out = 0; out < tx.vout.size(); out++) { for (size_t out = 0; out < tx.vout.size(); out++) {
// Optimistically just do efficient check of cache for outputs // Optimistically just do efficient check of cache for outputs
if (coins_cache.HaveCoinInCache(COutPoint(hash, out))) { if (coins_cache.HaveCoinInCache(COutPoint(hash, out))) {
return state.Invalid(TxValidationResult::TX_CONFLICT, false, "txn-already-known"); return state.Invalid(TxValidationResult::TX_CONFLICT, "txn-already-known");
} }
} }
// Otherwise assume this might be an orphan tx for which we just haven't seen parents yet // Otherwise assume this might be an orphan tx for which we just haven't seen parents yet
@@ -668,7 +668,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// Must keep pool.cs for this unless we change CheckSequenceLocks to take a // Must keep pool.cs for this unless we change CheckSequenceLocks to take a
// CoinsViewCache instead of create its own // CoinsViewCache instead of create its own
if (!CheckSequenceLocks(m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp)) if (!CheckSequenceLocks(m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, false, "non-BIP68-final"); return state.Invalid(TxValidationResult::TX_PREMATURE_SPEND, "non-BIP68-final");
CAmount nFees = 0; CAmount nFees = 0;
if (!Consensus::CheckTxInputs(tx, state, m_view, GetSpendHeight(m_view), nFees)) { if (!Consensus::CheckTxInputs(tx, state, m_view, GetSpendHeight(m_view), nFees)) {
@@ -677,11 +677,11 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// Check for non-standard pay-to-script-hash in inputs // Check for non-standard pay-to-script-hash in inputs
if (fRequireStandard && !AreInputsStandard(tx, m_view)) if (fRequireStandard && !AreInputsStandard(tx, m_view))
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, false, "bad-txns-nonstandard-inputs"); return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "bad-txns-nonstandard-inputs");
// Check for non-standard witness in P2WSH // Check for non-standard witness in P2WSH
if (tx.HasWitness() && fRequireStandard && !IsWitnessStandard(tx, m_view)) if (tx.HasWitness() && fRequireStandard && !IsWitnessStandard(tx, m_view))
return state.Invalid(TxValidationResult::TX_WITNESS_MUTATED, false, "bad-witness-nonstandard"); return state.Invalid(TxValidationResult::TX_WITNESS_MUTATED, "bad-witness-nonstandard");
int64_t nSigOpsCost = GetTransactionSigOpCost(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS); int64_t nSigOpsCost = GetTransactionSigOpCost(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS);
@@ -705,7 +705,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
unsigned int nSize = entry->GetTxSize(); unsigned int nSize = entry->GetTxSize();
if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST) if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST)
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, false, "bad-txns-too-many-sigops", return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "bad-txns-too-many-sigops",
strprintf("%d", nSigOpsCost)); strprintf("%d", nSigOpsCost));
// No transactions are allowed below minRelayTxFee except from disconnected // No transactions are allowed below minRelayTxFee except from disconnected
@@ -713,7 +713,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
if (!bypass_limits && !CheckFeeRate(nSize, nModifiedFees, state)) return false; if (!bypass_limits && !CheckFeeRate(nSize, nModifiedFees, state)) return false;
if (nAbsurdFee && nFees > nAbsurdFee) if (nAbsurdFee && nFees > nAbsurdFee)
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, false, return state.Invalid(TxValidationResult::TX_NOT_STANDARD,
"absurdly-high-fee", strprintf("%d > %d", nFees, nAbsurdFee)); "absurdly-high-fee", strprintf("%d > %d", nFees, nAbsurdFee));
const CTxMemPool::setEntries setIterConflicting = m_pool.GetIterSet(setConflicts); const CTxMemPool::setEntries setIterConflicting = m_pool.GetIterSet(setConflicts);
@@ -771,7 +771,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// this, see https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-November/016518.html // this, see https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-November/016518.html
if (nSize > EXTRA_DESCENDANT_TX_SIZE_LIMIT || if (nSize > EXTRA_DESCENDANT_TX_SIZE_LIMIT ||
!m_pool.CalculateMemPoolAncestors(*entry, setAncestors, 2, m_limit_ancestor_size, m_limit_descendants + 1, m_limit_descendant_size + EXTRA_DESCENDANT_TX_SIZE_LIMIT, dummy_err_string)) { !m_pool.CalculateMemPoolAncestors(*entry, setAncestors, 2, m_limit_ancestor_size, m_limit_descendants + 1, m_limit_descendant_size + EXTRA_DESCENDANT_TX_SIZE_LIMIT, dummy_err_string)) {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "too-long-mempool-chain", errString); return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "too-long-mempool-chain", errString);
} }
} }
@@ -784,7 +784,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
const uint256 &hashAncestor = ancestorIt->GetTx().GetHash(); const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
if (setConflicts.count(hashAncestor)) if (setConflicts.count(hashAncestor))
{ {
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, "bad-txns-spends-conflicting-tx", return state.Invalid(TxValidationResult::TX_CONSENSUS, "bad-txns-spends-conflicting-tx",
strprintf("%s spends conflicting transaction %s", strprintf("%s spends conflicting transaction %s",
hash.ToString(), hash.ToString(),
hashAncestor.ToString())); hashAncestor.ToString()));
@@ -824,7 +824,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize()); CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
if (newFeeRate <= oldFeeRate) if (newFeeRate <= oldFeeRate)
{ {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "insufficient fee", return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "insufficient fee",
strprintf("rejecting replacement %s; new feerate %s <= old feerate %s", strprintf("rejecting replacement %s; new feerate %s <= old feerate %s",
hash.ToString(), hash.ToString(),
newFeeRate.ToString(), newFeeRate.ToString(),
@@ -852,7 +852,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
nConflictingSize += it->GetTxSize(); nConflictingSize += it->GetTxSize();
} }
} else { } else {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "too many potential replacements", return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "too many potential replacements",
strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n", strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
hash.ToString(), hash.ToString(),
nConflictingCount, nConflictingCount,
@@ -876,7 +876,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// it's cheaper to just check if the new input refers to a // it's cheaper to just check if the new input refers to a
// tx that's in the mempool. // tx that's in the mempool.
if (m_pool.exists(tx.vin[j].prevout.hash)) { if (m_pool.exists(tx.vin[j].prevout.hash)) {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "replacement-adds-unconfirmed", return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "replacement-adds-unconfirmed",
strprintf("replacement %s adds unconfirmed input, idx %d", strprintf("replacement %s adds unconfirmed input, idx %d",
hash.ToString(), j)); hash.ToString(), j));
} }
@@ -888,7 +888,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
// transactions would not be paid for. // transactions would not be paid for.
if (nModifiedFees < nConflictingFees) if (nModifiedFees < nConflictingFees)
{ {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "insufficient fee", return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "insufficient fee",
strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s", strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s",
hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees))); hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)));
} }
@@ -898,7 +898,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
CAmount nDeltaFees = nModifiedFees - nConflictingFees; CAmount nDeltaFees = nModifiedFees - nConflictingFees;
if (nDeltaFees < ::incrementalRelayFee.GetFee(nSize)) if (nDeltaFees < ::incrementalRelayFee.GetFee(nSize))
{ {
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "insufficient fee", return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "insufficient fee",
strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s", strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s",
hash.ToString(), hash.ToString(),
FormatMoney(nDeltaFees), FormatMoney(nDeltaFees),
@@ -926,7 +926,7 @@ bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, Workspace& ws, Precompute
if (!tx.HasWitness() && CheckInputs(tx, state_dummy, m_view, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, false, txdata) && if (!tx.HasWitness() && CheckInputs(tx, state_dummy, m_view, scriptVerifyFlags & ~(SCRIPT_VERIFY_WITNESS | SCRIPT_VERIFY_CLEANSTACK), true, false, txdata) &&
!CheckInputs(tx, state_dummy, m_view, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, false, txdata)) { !CheckInputs(tx, state_dummy, m_view, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, false, txdata)) {
// Only the witness is missing, so the transaction itself may be fine. // Only the witness is missing, so the transaction itself may be fine.
state.Invalid(TxValidationResult::TX_WITNESS_MUTATED, false, state.Invalid(TxValidationResult::TX_WITNESS_MUTATED,
state.GetRejectReason(), state.GetDebugMessage()); state.GetRejectReason(), state.GetDebugMessage());
} }
return false; // state filled in by CheckInputs return false; // state filled in by CheckInputs
@@ -1009,7 +1009,7 @@ bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
if (!bypass_limits) { if (!bypass_limits) {
LimitMempoolSize(m_pool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, std::chrono::hours{gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)}); LimitMempoolSize(m_pool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, std::chrono::hours{gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
if (!m_pool.exists(hash)) if (!m_pool.exists(hash))
return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, false, "mempool full"); return state.Invalid(TxValidationResult::TX_MEMPOOL_POLICY, "mempool full");
} }
return true; return true;
} }
@@ -1544,7 +1544,7 @@ bool CheckInputs(const CTransaction& tx, TxValidationState &state, const CCoinsV
CScriptCheck check2(coin.out, tx, i, CScriptCheck check2(coin.out, tx, i,
flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata); flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
if (check2()) if (check2())
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, false, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError()))); return state.Invalid(TxValidationResult::TX_NOT_STANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(check.GetScriptError())));
} }
// MANDATORY flag failures correspond to // MANDATORY flag failures correspond to
// TxValidationResult::TX_CONSENSUS. Because CONSENSUS // TxValidationResult::TX_CONSENSUS. Because CONSENSUS
@@ -1555,7 +1555,7 @@ bool CheckInputs(const CTransaction& tx, TxValidationState &state, const CCoinsV
// support, to avoid splitting the network (but this // support, to avoid splitting the network (but this
// depends on the details of how net_processing handles // depends on the details of how net_processing handles
// such errors). // such errors).
return state.Invalid(TxValidationResult::TX_CONSENSUS, false, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError()))); return state.Invalid(TxValidationResult::TX_CONSENSUS, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(check.GetScriptError())));
} }
} }
@@ -2058,7 +2058,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
for (size_t o = 0; o < tx->vout.size(); o++) { for (size_t o = 0; o < tx->vout.size(); o++) {
if (view.HaveCoin(COutPoint(tx->GetHash(), o))) { if (view.HaveCoin(COutPoint(tx->GetHash(), o))) {
LogPrintf("ERROR: ConnectBlock(): tried to overwrite transaction\n"); LogPrintf("ERROR: ConnectBlock(): tried to overwrite transaction\n");
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-txns-BIP30"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-BIP30");
} }
} }
} }
@@ -2099,14 +2099,14 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
TxValidationState tx_state; TxValidationState tx_state;
if (!Consensus::CheckTxInputs(tx, tx_state, view, pindex->nHeight, txfee)) { if (!Consensus::CheckTxInputs(tx, tx_state, view, pindex->nHeight, txfee)) {
// Any transaction validation failure in ConnectBlock is a block consensus failure // Any transaction validation failure in ConnectBlock is a block consensus failure
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
tx_state.GetRejectReason(), tx_state.GetDebugMessage()); tx_state.GetRejectReason(), tx_state.GetDebugMessage());
return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state)); return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
} }
nFees += txfee; nFees += txfee;
if (!MoneyRange(nFees)) { if (!MoneyRange(nFees)) {
LogPrintf("ERROR: %s: accumulated fee in the block out of range.\n", __func__); LogPrintf("ERROR: %s: accumulated fee in the block out of range.\n", __func__);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-txns-accumulated-fee-outofrange"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-accumulated-fee-outofrange");
} }
// Check that transaction is BIP68 final // Check that transaction is BIP68 final
@@ -2119,7 +2119,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) { if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {
LogPrintf("ERROR: %s: contains a non-BIP68-final transaction\n", __func__); LogPrintf("ERROR: %s: contains a non-BIP68-final transaction\n", __func__);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-txns-nonfinal"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-nonfinal");
} }
} }
@@ -2130,7 +2130,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
nSigOpsCost += GetTransactionSigOpCost(tx, view, flags); nSigOpsCost += GetTransactionSigOpCost(tx, view, flags);
if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST) { if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST) {
LogPrintf("ERROR: ConnectBlock(): too many sigops\n"); LogPrintf("ERROR: ConnectBlock(): too many sigops\n");
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-blk-sigops"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-sigops");
} }
txdata.emplace_back(tx); txdata.emplace_back(tx);
@@ -2141,7 +2141,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
TxValidationState tx_state; TxValidationState tx_state;
if (fScriptChecks && !CheckInputs(tx, tx_state, view, flags, fCacheResults, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : nullptr)) { if (fScriptChecks && !CheckInputs(tx, tx_state, view, flags, fCacheResults, fCacheResults, txdata[i], nScriptCheckThreads ? &vChecks : nullptr)) {
// Any transaction validation failure in ConnectBlock is a block consensus failure // Any transaction validation failure in ConnectBlock is a block consensus failure
state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, state.Invalid(BlockValidationResult::BLOCK_CONSENSUS,
tx_state.GetRejectReason(), tx_state.GetDebugMessage()); tx_state.GetRejectReason(), tx_state.GetDebugMessage());
return error("ConnectBlock(): CheckInputs on %s failed with %s", return error("ConnectBlock(): CheckInputs on %s failed with %s",
tx.GetHash().ToString(), FormatStateMessage(state)); tx.GetHash().ToString(), FormatStateMessage(state));
@@ -2161,12 +2161,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
if (block.vtx[0]->GetValueOut() > blockReward) { if (block.vtx[0]->GetValueOut() > blockReward) {
LogPrintf("ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.vtx[0]->GetValueOut(), blockReward); LogPrintf("ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.vtx[0]->GetValueOut(), blockReward);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-cb-amount"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-amount");
} }
if (!control.Wait()) { if (!control.Wait()) {
LogPrintf("ERROR: %s: CheckQueue failed\n", __func__); LogPrintf("ERROR: %s: CheckQueue failed\n", __func__);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "block-validation-failed"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "block-validation-failed");
} }
int64_t nTime4 = GetTimeMicros(); nTimeVerify += nTime4 - nTime2; int64_t nTime4 = GetTimeMicros(); nTimeVerify += nTime4 - nTime2;
LogPrint(BCLog::BENCH, " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1, MILLI * (nTime4 - nTime2), nInputs <= 1 ? 0 : MILLI * (nTime4 - nTime2) / (nInputs-1), nTimeVerify * MICRO, nTimeVerify * MILLI / nBlocksTotal); LogPrint(BCLog::BENCH, " - Verify %u txins: %.2fms (%.3fms/txin) [%.2fs (%.2fms/blk)]\n", nInputs - 1, MILLI * (nTime4 - nTime2), nInputs <= 1 ? 0 : MILLI * (nTime4 - nTime2) / (nInputs-1), nTimeVerify * MICRO, nTimeVerify * MILLI / nBlocksTotal);
@@ -3244,7 +3244,7 @@ static bool CheckBlockHeader(const CBlockHeader& block, BlockValidationState& st
{ {
// Check proof of work matches claimed amount // Check proof of work matches claimed amount
if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) if (fCheckPOW && !CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, false, "high-hash", "proof of work failed"); return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "high-hash", "proof of work failed");
return true; return true;
} }
@@ -3266,13 +3266,13 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
bool mutated; bool mutated;
uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated); uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated);
if (block.hashMerkleRoot != hashMerkleRoot2) if (block.hashMerkleRoot != hashMerkleRoot2)
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, false, "bad-txnmrklroot", "hashMerkleRoot mismatch"); return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-txnmrklroot", "hashMerkleRoot mismatch");
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences // Check for merkle tree malleability (CVE-2012-2459): repeating sequences
// of transactions in a block without affecting the merkle root of a block, // of transactions in a block without affecting the merkle root of a block,
// while still invalidating it. // while still invalidating it.
if (mutated) if (mutated)
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, false, "bad-txns-duplicate", "duplicate transaction"); return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-txns-duplicate", "duplicate transaction");
} }
// All potential-corruption validation must be done before we do any // All potential-corruption validation must be done before we do any
@@ -3283,14 +3283,14 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
// Size limits // Size limits
if (block.vtx.empty() || block.vtx.size() * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT || ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT) if (block.vtx.empty() || block.vtx.size() * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT || ::GetSerializeSize(block, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) * WITNESS_SCALE_FACTOR > MAX_BLOCK_WEIGHT)
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-blk-length", "size limits failed"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-length", "size limits failed");
// 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.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-cb-missing", "first tx is not coinbase"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-missing", "first tx is not coinbase");
for (unsigned int i = 1; i < block.vtx.size(); i++) for (unsigned int i = 1; i < block.vtx.size(); i++)
if (block.vtx[i]->IsCoinBase()) if (block.vtx[i]->IsCoinBase())
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-cb-multiple", "more than one coinbase"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-multiple", "more than one coinbase");
// Check transactions // Check transactions
// Must check for duplicate inputs (see CVE-2018-17144) // Must check for duplicate inputs (see CVE-2018-17144)
@@ -3300,7 +3300,7 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
// CheckBlock() does context-free validation checks. The only // CheckBlock() does context-free validation checks. The only
// possible failures are consensus failures. // possible failures are consensus failures.
assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS); assert(tx_state.GetResult() == TxValidationResult::TX_CONSENSUS);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, tx_state.GetRejectReason(), return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, tx_state.GetRejectReason(),
strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), tx_state.GetDebugMessage())); strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), tx_state.GetDebugMessage()));
} }
} }
@@ -3310,7 +3310,7 @@ bool CheckBlock(const CBlock& block, BlockValidationState& state, const Consensu
nSigOps += GetLegacySigOpCount(*tx); nSigOps += GetLegacySigOpCount(*tx);
} }
if (nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST) if (nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST)
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-blk-sigops", "out-of-bounds SigOpCount"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-sigops", "out-of-bounds SigOpCount");
if (fCheckPOW && fCheckMerkleRoot) if (fCheckPOW && fCheckMerkleRoot)
block.fChecked = true; block.fChecked = true;
@@ -3411,7 +3411,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
// Check proof of work // Check proof of work
const Consensus::Params& consensusParams = params.GetConsensus(); const Consensus::Params& consensusParams = params.GetConsensus();
if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams)) if (block.nBits != GetNextWorkRequired(pindexPrev, &block, consensusParams))
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, false, "bad-diffbits", "incorrect proof of work"); return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "bad-diffbits", "incorrect proof of work");
// Check against checkpoints // Check against checkpoints
if (fCheckpointsEnabled) { if (fCheckpointsEnabled) {
@@ -3421,24 +3421,24 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, BlockValidatio
CBlockIndex* pcheckpoint = GetLastCheckpoint(params.Checkpoints()); CBlockIndex* pcheckpoint = GetLastCheckpoint(params.Checkpoints());
if (pcheckpoint && nHeight < pcheckpoint->nHeight) { if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight); LogPrintf("ERROR: %s: forked chain older than last checkpoint (height %d)\n", __func__, nHeight);
return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, false, "bad-fork-prior-to-checkpoint"); return state.Invalid(BlockValidationResult::BLOCK_CHECKPOINT, "bad-fork-prior-to-checkpoint");
} }
} }
// Check timestamp against prev // Check timestamp against prev
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, false, "time-too-old", "block's timestamp is too early"); return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, "time-too-old", "block's timestamp is too early");
// Check timestamp // Check timestamp
if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME) if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, false, "time-too-new", "block timestamp too far in the future"); return state.Invalid(BlockValidationResult::BLOCK_TIME_FUTURE, "time-too-new", "block timestamp too far in the future");
// Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded: // Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded:
// check for version 2, 3 and 4 upgrades // check for version 2, 3 and 4 upgrades
if((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) || if((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) ||
(block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) || (block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) ||
(block.nVersion < 4 && nHeight >= consensusParams.BIP65Height)) (block.nVersion < 4 && nHeight >= consensusParams.BIP65Height))
return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, false, strprintf("bad-version(0x%08x)", block.nVersion), return state.Invalid(BlockValidationResult::BLOCK_INVALID_HEADER, 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;
@@ -3468,7 +3468,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
// Check that all transactions are finalized // Check that all transactions are finalized
for (const auto& tx : block.vtx) { for (const auto& tx : block.vtx) {
if (!IsFinalTx(*tx, nHeight, nLockTimeCutoff)) { if (!IsFinalTx(*tx, nHeight, nLockTimeCutoff)) {
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-txns-nonfinal", "non-final transaction"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-txns-nonfinal", "non-final transaction");
} }
} }
@@ -3478,7 +3478,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
CScript expect = CScript() << nHeight; CScript expect = CScript() << nHeight;
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() || if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
!std::equal(expect.begin(), expect.end(), block.vtx[0]->vin[0].scriptSig.begin())) { !std::equal(expect.begin(), expect.end(), block.vtx[0]->vin[0].scriptSig.begin())) {
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-cb-height", "block height mismatch in coinbase"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-height", "block height mismatch in coinbase");
} }
} }
@@ -3500,11 +3500,11 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
// already does not permit it, it is impossible to trigger in the // already does not permit it, it is impossible to trigger in the
// witness tree. // witness tree.
if (block.vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) { if (block.vtx[0]->vin[0].scriptWitness.stack.size() != 1 || block.vtx[0]->vin[0].scriptWitness.stack[0].size() != 32) {
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, false, "bad-witness-nonce-size", strprintf("%s : invalid witness reserved value size", __func__)); return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-witness-nonce-size", strprintf("%s : invalid witness reserved value size", __func__));
} }
CHash256().Write(hashWitness.begin(), 32).Write(&block.vtx[0]->vin[0].scriptWitness.stack[0][0], 32).Finalize(hashWitness.begin()); CHash256().Write(hashWitness.begin(), 32).Write(&block.vtx[0]->vin[0].scriptWitness.stack[0][0], 32).Finalize(hashWitness.begin());
if (memcmp(hashWitness.begin(), &block.vtx[0]->vout[commitpos].scriptPubKey[6], 32)) { if (memcmp(hashWitness.begin(), &block.vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, false, "bad-witness-merkle-match", strprintf("%s : witness merkle commitment mismatch", __func__)); return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "bad-witness-merkle-match", strprintf("%s : witness merkle commitment mismatch", __func__));
} }
fHaveWitness = true; fHaveWitness = true;
} }
@@ -3514,7 +3514,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
if (!fHaveWitness) { if (!fHaveWitness) {
for (const auto& tx : block.vtx) { for (const auto& tx : block.vtx) {
if (tx->HasWitness()) { if (tx->HasWitness()) {
return state.Invalid(BlockValidationResult::BLOCK_MUTATED, false, "unexpected-witness", strprintf("%s : unexpected witness data found", __func__)); return state.Invalid(BlockValidationResult::BLOCK_MUTATED, "unexpected-witness", strprintf("%s : unexpected witness data found", __func__));
} }
} }
} }
@@ -3526,7 +3526,7 @@ static bool ContextualCheckBlock(const CBlock& block, BlockValidationState& stat
// the block hash, so we couldn't mark the block as permanently // the block hash, so we couldn't mark the block as permanently
// failed). // failed).
if (GetBlockWeight(block) > MAX_BLOCK_WEIGHT) { if (GetBlockWeight(block) > MAX_BLOCK_WEIGHT) {
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, false, "bad-blk-weight", strprintf("%s : weight limit failed", __func__)); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-blk-weight", strprintf("%s : weight limit failed", __func__));
} }
return true; return true;
@@ -3547,7 +3547,7 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
*ppindex = pindex; *ppindex = pindex;
if (pindex->nStatus & BLOCK_FAILED_MASK) { if (pindex->nStatus & BLOCK_FAILED_MASK) {
LogPrintf("ERROR: %s: block %s is marked invalid\n", __func__, hash.ToString()); LogPrintf("ERROR: %s: block %s is marked invalid\n", __func__, hash.ToString());
return state.Invalid(BlockValidationResult::BLOCK_CACHED_INVALID, false, "duplicate"); return state.Invalid(BlockValidationResult::BLOCK_CACHED_INVALID, "duplicate");
} }
return true; return true;
} }
@@ -3560,12 +3560,12 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
BlockMap::iterator mi = m_block_index.find(block.hashPrevBlock); BlockMap::iterator mi = m_block_index.find(block.hashPrevBlock);
if (mi == m_block_index.end()) { if (mi == m_block_index.end()) {
LogPrintf("ERROR: %s: prev block not found\n", __func__); LogPrintf("ERROR: %s: prev block not found\n", __func__);
return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, false, "prev-blk-not-found"); return state.Invalid(BlockValidationResult::BLOCK_MISSING_PREV, "prev-blk-not-found");
} }
pindexPrev = (*mi).second; pindexPrev = (*mi).second;
if (pindexPrev->nStatus & BLOCK_FAILED_MASK) { if (pindexPrev->nStatus & BLOCK_FAILED_MASK) {
LogPrintf("ERROR: %s: prev block invalid\n", __func__); LogPrintf("ERROR: %s: prev block invalid\n", __func__);
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, false, "bad-prevblk"); return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
} }
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime())) if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime()))
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state)); return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
@@ -3604,7 +3604,7 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, BlockValidationS
invalid_walk = invalid_walk->pprev; invalid_walk = invalid_walk->pprev;
} }
LogPrintf("ERROR: %s: prev block invalid\n", __func__); LogPrintf("ERROR: %s: prev block invalid\n", __func__);
return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, false, "bad-prevblk"); return state.Invalid(BlockValidationResult::BLOCK_INVALID_PREV, "bad-prevblk");
} }
} }
} }