mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-14 12:43:40 +02:00
Merge b688b859db into merged_master (Bitcoin PR #17004)
This commit is contained in:
commit
508fcb020d
19 changed files with 166 additions and 171 deletions
|
|
@ -524,11 +524,11 @@ private:
|
|||
{
|
||||
CAmount mempoolRejectFee = m_pool.GetMinFee(gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(package_size);
|
||||
if (mempoolRejectFee > 0 && package_fee < mempoolRejectFee) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee));
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "mempool min fee not met", strprintf("%d < %d", package_fee, mempoolRejectFee));
|
||||
}
|
||||
|
||||
if (package_fee < ::minRelayTxFee.GetFee(package_size)) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_INSUFFICIENTFEE, "min relay fee not met", strprintf("%d < %d", package_fee, ::minRelayTxFee.GetFee(package_size)));
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "min relay fee not met", strprintf("%d < %d", package_fee, ::minRelayTxFee.GetFee(package_size)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -583,17 +583,17 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
|
||||
// Coinbase is only valid in a block, not as a loose transaction
|
||||
if (tx.IsCoinBase())
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "coinbase");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "coinbase");
|
||||
|
||||
// Rather not work on nonstandard transactions (unless -testnet/-regtest)
|
||||
std::string reason;
|
||||
if (fRequireStandard && !IsStandardTx(tx, reason))
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, reason);
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, reason);
|
||||
|
||||
// And now do PAK checks. Filtered by next blocks' enforced list
|
||||
if (chainparams.GetEnforcePak()) {
|
||||
if (!IsPAKValidTx(tx, GetActivePAKList(::ChainActive().Tip(), chainparams.GetConsensus()), chainparams.ParentGenesisBlockHash(), chainparams.GetConsensus().pegged_asset)) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, "invalid-pegout-proof");
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, "invalid-pegout-proof");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -602,17 +602,17 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
// Transactions smaller than this are not relayed to mitigate CVE-2017-12842 by not relaying
|
||||
// 64-byte transactions.
|
||||
if (::GetSerializeSize(tx, PROTOCOL_VERSION | SERIALIZE_TRANSACTION_NO_WITNESS) < MIN_STANDARD_TX_NONWITNESS_SIZE)
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, "tx-size-small");
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, "tx-size-small");
|
||||
|
||||
// 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
|
||||
// be mined yet.
|
||||
if (!CheckFinalTx(tx, STANDARD_LOCKTIME_VERIFY_FLAGS))
|
||||
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_NONSTANDARD, "non-final");
|
||||
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, "non-final");
|
||||
|
||||
// is it already in the memory pool?
|
||||
if (m_pool.exists(hash)) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_CONFLICT, false, REJECT_DUPLICATE, "txn-already-in-mempool");
|
||||
return state.Invalid(ValidationInvalidReason::TX_CONFLICT, false, "txn-already-in-mempool");
|
||||
}
|
||||
|
||||
// Check for conflicts with in-memory transactions
|
||||
|
|
@ -644,7 +644,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
}
|
||||
}
|
||||
if (fReplacementOptOut) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_DUPLICATE, "txn-mempool-conflict");
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "txn-mempool-conflict");
|
||||
}
|
||||
|
||||
setConflicts.insert(ptxConflicting->GetHash());
|
||||
|
|
@ -662,7 +662,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
// Note that the witness vector must be size 0 or len(vin)
|
||||
if (!tx.witness.vtxinwit.empty() &&
|
||||
!tx.witness.vtxinwit[input_index].m_pegin_witness.IsNull()) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_WITNESS_MUTATED, false, REJECT_PEGIN, "extra-pegin-witness");
|
||||
return state.Invalid(ValidationInvalidReason::TX_WITNESS_MUTATED, false, "extra-pegin-witness");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -684,13 +684,13 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
std::string err_msg = "no peg-in witness attached";
|
||||
if (tx.witness.vtxinwit.size() != tx.vin.size() ||
|
||||
!IsValidPeginWitness(tx.witness.vtxinwit[i].m_pegin_witness, fedpegscripts, tx.vin[i].prevout, err_msg, false)) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_WITNESS_MUTATED, false, REJECT_INVALID, "pegin-no-witness", err_msg);
|
||||
return state.Invalid(ValidationInvalidReason::TX_WITNESS_MUTATED, false, "pegin-no-witness", err_msg);
|
||||
}
|
||||
|
||||
std::pair<uint256, COutPoint> pegin = std::make_pair(uint256(tx.witness.vtxinwit[i].m_pegin_witness.stack[2]), tx.vin[i].prevout);
|
||||
// This assumes non-null prevout and genesis block hash
|
||||
if (m_view.IsPeginSpent(pegin)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "pegin-already-claimed");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "pegin-already-claimed");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
|
@ -707,7 +707,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
for (size_t out = 0; out < tx.vout.size(); out++) {
|
||||
// Optimistically just do efficient check of cache for outputs
|
||||
if (coins_cache.HaveCoinInCache(COutPoint(hash, out))) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_CONFLICT, false, REJECT_DUPLICATE, "txn-already-known");
|
||||
return state.Invalid(ValidationInvalidReason::TX_CONFLICT, false, "txn-already-known");
|
||||
}
|
||||
}
|
||||
// Otherwise assume this might be an orphan tx for which we just haven't seen parents yet
|
||||
|
|
@ -732,7 +732,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
// Must keep pool.cs for this unless we change CheckSequenceLocks to take a
|
||||
// CoinsViewCache instead of create its own
|
||||
if (!CheckSequenceLocks(m_pool, tx, STANDARD_LOCKTIME_VERIFY_FLAGS, &lp))
|
||||
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, REJECT_NONSTANDARD, "non-BIP68-final");
|
||||
return state.Invalid(ValidationInvalidReason::TX_PREMATURE_SPEND, false, "non-BIP68-final");
|
||||
|
||||
CAmountMap fee_map;
|
||||
if (!Consensus::CheckTxInputs(tx, state, m_view, GetSpendHeight(m_view), fee_map, setPeginsSpent, NULL, true, true, fedpegscripts)) {
|
||||
|
|
@ -741,11 +741,11 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
|
||||
// Check for non-standard pay-to-script-hash in inputs
|
||||
if (fRequireStandard && !AreInputsStandard(tx, m_view))
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs");
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, "bad-txns-nonstandard-inputs");
|
||||
|
||||
// Check for non-standard witness in P2WSH
|
||||
if (tx.HasWitness() && fRequireStandard && !IsWitnessStandard(tx, m_view))
|
||||
return state.Invalid(ValidationInvalidReason::TX_WITNESS_MUTATED, false, REJECT_NONSTANDARD, "bad-witness-nonstandard");
|
||||
return state.Invalid(ValidationInvalidReason::TX_WITNESS_MUTATED, false, "bad-witness-nonstandard");
|
||||
|
||||
int64_t nSigOpsCost = GetTransactionSigOpCost(tx, m_view, STANDARD_SCRIPT_VERIFY_FLAGS);
|
||||
|
||||
|
|
@ -776,7 +776,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
unsigned int nSize = entry->GetTxSize();
|
||||
|
||||
if (nSigOpsCost > MAX_STANDARD_TX_SIGOPS_COST)
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, "bad-txns-too-many-sigops",
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, "bad-txns-too-many-sigops",
|
||||
strprintf("%d", nSigOpsCost));
|
||||
|
||||
// No transactions are allowed below minRelayTxFee except from disconnected
|
||||
|
|
@ -785,8 +785,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
|
||||
if (nAbsurdFee && nFees > nAbsurdFee)
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false,
|
||||
REJECT_HIGHFEE, "absurdly-high-fee",
|
||||
strprintf("%d > %d", nFees, nAbsurdFee));
|
||||
"absurdly-high-fee", strprintf("%d > %d", nFees, nAbsurdFee));
|
||||
|
||||
const CTxMemPool::setEntries setIterConflicting = m_pool.GetIterSet(setConflicts);
|
||||
// Calculate in-mempool ancestors, up to a limit.
|
||||
|
|
@ -843,7 +842,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
// this, see https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-November/016518.html
|
||||
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)) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_NONSTANDARD, "too-long-mempool-chain", errString);
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "too-long-mempool-chain", errString);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -856,7 +855,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
const uint256 &hashAncestor = ancestorIt->GetTx().GetHash();
|
||||
if (setConflicts.count(hashAncestor))
|
||||
{
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-txns-spends-conflicting-tx",
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-txns-spends-conflicting-tx",
|
||||
strprintf("%s spends conflicting transaction %s",
|
||||
hash.ToString(),
|
||||
hashAncestor.ToString()));
|
||||
|
|
@ -896,7 +895,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
CFeeRate oldFeeRate(mi->GetModifiedFee(), mi->GetTxSize());
|
||||
if (newFeeRate <= oldFeeRate)
|
||||
{
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_INSUFFICIENTFEE, "insufficient fee",
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "insufficient fee",
|
||||
strprintf("rejecting replacement %s; new feerate %s <= old feerate %s",
|
||||
hash.ToString(),
|
||||
newFeeRate.ToString(),
|
||||
|
|
@ -924,7 +923,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
nConflictingSize += it->GetTxSize();
|
||||
}
|
||||
} else {
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_NONSTANDARD, "too many potential replacements",
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "too many potential replacements",
|
||||
strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
|
||||
hash.ToString(),
|
||||
nConflictingCount,
|
||||
|
|
@ -948,7 +947,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
// it's cheaper to just check if the new input refers to a
|
||||
// tx that's in the mempool.
|
||||
if (m_pool.exists(tx.vin[j].prevout.hash)) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_NONSTANDARD, "replacement-adds-unconfirmed",
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "replacement-adds-unconfirmed",
|
||||
strprintf("replacement %s adds unconfirmed input, idx %d",
|
||||
hash.ToString(), j));
|
||||
}
|
||||
|
|
@ -960,7 +959,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
// transactions would not be paid for.
|
||||
if (nModifiedFees < nConflictingFees)
|
||||
{
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_INSUFFICIENTFEE, "insufficient fee",
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "insufficient fee",
|
||||
strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s",
|
||||
hash.ToString(), FormatMoney(nModifiedFees), FormatMoney(nConflictingFees)));
|
||||
}
|
||||
|
|
@ -970,7 +969,7 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
|
|||
CAmount nDeltaFees = nModifiedFees - nConflictingFees;
|
||||
if (nDeltaFees < ::incrementalRelayFee.GetFee(nSize))
|
||||
{
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_INSUFFICIENTFEE, "insufficient fee",
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "insufficient fee",
|
||||
strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s",
|
||||
hash.ToString(),
|
||||
FormatMoney(nDeltaFees),
|
||||
|
|
@ -999,7 +998,7 @@ bool MemPoolAccept::PolicyScriptChecks(ATMPArgs& args, Workspace& ws, Precompute
|
|||
!CheckInputs(tx, stateDummy, m_view, scriptVerifyFlags & ~SCRIPT_VERIFY_CLEANSTACK, true, false, txdata)) {
|
||||
// Only the witness is missing, so the transaction itself may be fine.
|
||||
state.Invalid(ValidationInvalidReason::TX_WITNESS_MUTATED, false,
|
||||
state.GetRejectCode(), state.GetRejectReason(), state.GetDebugMessage());
|
||||
state.GetRejectReason(), state.GetDebugMessage());
|
||||
}
|
||||
assert(IsTransactionReason(state.GetReason()));
|
||||
return false; // state filled in by CheckInputs
|
||||
|
|
@ -1082,7 +1081,7 @@ bool MemPoolAccept::Finalize(ATMPArgs& args, Workspace& ws)
|
|||
if (!bypass_limits) {
|
||||
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))
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, REJECT_INSUFFICIENTFEE, "mempool full");
|
||||
return state.Invalid(ValidationInvalidReason::TX_MEMPOOL_POLICY, false, "mempool full");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1636,7 +1635,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
|
|||
CScriptCheck check2(coin.out, tx, i,
|
||||
flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheSigStore, &txdata);
|
||||
if (check2()) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, REJECT_NONSTANDARD, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(serror)));
|
||||
return state.Invalid(ValidationInvalidReason::TX_NOT_STANDARD, false, strprintf("non-mandatory-script-verify-flag (%s)", ScriptErrorString(serror)));
|
||||
}
|
||||
}
|
||||
// MANDATORY flag failures correspond to
|
||||
|
|
@ -1648,7 +1647,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
|
|||
// support, to avoid splitting the network (but this
|
||||
// depends on the details of how net_processing handles
|
||||
// such errors).
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(serror)));
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, strprintf("mandatory-script-verify-flag-failed (%s)", ScriptErrorString(serror)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2080,7 +2079,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
bool mustPay = !txout.nValue.IsExplicit() || txout.nValue.GetAmount() != 0;
|
||||
if (mustPay && txout.scriptPubKey != mandatory_coinbase_destination) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): Coinbase outputs didn't match required scriptPubKey"),
|
||||
REJECT_INVALID, "bad-coinbase-txos");
|
||||
"bad-coinbase-txos");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2204,7 +2203,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
for (size_t o = 0; o < tx->vout.size(); o++) {
|
||||
if (view.HaveCoin(COutPoint(tx->GetHash(), o))) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): tried to overwrite transaction"),
|
||||
REJECT_INVALID, "bad-txns-BIP30");
|
||||
"bad-txns-BIP30");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2242,7 +2241,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
CPAKList paklist = GetActivePAKList(pindex->pprev, chainparams.GetConsensus());
|
||||
for (const auto& tx : block.vtx) {
|
||||
if (!IsPAKValidTx(*tx, paklist, chainparams.ParentGenesisBlockHash(), chainparams.GetConsensus().pegged_asset)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): Bad PAK transaction"), REJECT_INVALID, "bad-pak-tx");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): Bad PAK transaction"), "bad-pak-tx");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2272,14 +2271,14 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
// defined for a block, so we reset the reason flag to
|
||||
// CONSENSUS here.
|
||||
state.Invalid(ValidationInvalidReason::CONSENSUS, false,
|
||||
state.GetRejectCode(), state.GetRejectReason(), state.GetDebugMessage());
|
||||
state.GetRejectReason(), state.GetDebugMessage());
|
||||
}
|
||||
return error("%s: Consensus::CheckTxInputs: %s, %s", __func__, tx.GetHash().ToString(), FormatStateMessage(state));
|
||||
}
|
||||
control.Add(vChecks);
|
||||
|
||||
if (!MoneyRange(fee_map))
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): total block reward overflowed"), REJECT_INVALID, "bad-blockreward-outofrange");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): total block reward overflowed"), "bad-blockreward-outofrange");
|
||||
|
||||
// Check that transaction is BIP68 final
|
||||
// BIP68 lock checks (as opposed to nLockTime checks) must
|
||||
|
|
@ -2295,7 +2294,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
|
||||
if (!SequenceLocks(tx, nLockTimeFlags, &prevheights, *pindex)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("%s: contains a non-BIP68-final transaction", __func__),
|
||||
REJECT_INVALID, "bad-txns-nonfinal");
|
||||
"bad-txns-nonfinal");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2306,7 +2305,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
nSigOpsCost += GetTransactionSigOpCost(tx, view, flags);
|
||||
if (nSigOpsCost > MAX_BLOCK_SIGOPS_COST)
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): too many sigops"),
|
||||
REJECT_INVALID, "bad-blk-sigops");
|
||||
"bad-blk-sigops");
|
||||
|
||||
txdata.emplace_back(tx);
|
||||
if (!tx.IsCoinBase())
|
||||
|
|
@ -2322,7 +2321,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
// consider whether rewriting to CONSENSUS or
|
||||
// RECENT_CONSENSUS_CHANGE would be more appropriate.
|
||||
state.Invalid(ValidationInvalidReason::CONSENSUS, false,
|
||||
state.GetRejectCode(), state.GetRejectReason(), state.GetDebugMessage());
|
||||
state.GetRejectReason(), state.GetDebugMessage());
|
||||
}
|
||||
return error("ConnectBlock(): CheckInputs on %s failed with %s",
|
||||
tx.GetHash().ToString(), FormatStateMessage(state));
|
||||
|
|
@ -2343,14 +2342,14 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
CAmountMap block_reward = fee_map;
|
||||
block_reward[consensusParams.subsidy_asset] += GetBlockSubsidy(pindex->nHeight, consensusParams);
|
||||
if (!MoneyRange(block_reward))
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): total block reward overflowed"), REJECT_INVALID, "bad-blockreward-outofrange");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): total block reward overflowed"), "bad-blockreward-outofrange");
|
||||
if (!VerifyCoinbaseAmount(*(block.vtx[0]), block_reward)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("ConnectBlock(): coinbase pays too much (limit=%d)",
|
||||
block_reward[consensusParams.subsidy_asset]), REJECT_INVALID, "bad-cb-amount");
|
||||
block_reward[consensusParams.subsidy_asset]), "bad-cb-amount");
|
||||
}
|
||||
|
||||
if (!control.Wait())
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("%s: CheckQueue failed", __func__), REJECT_INVALID, "block-validation-failed");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, error("%s: CheckQueue failed", __func__), "block-validation-failed");
|
||||
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);
|
||||
|
||||
|
|
@ -2743,7 +2742,7 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp
|
|||
// or unseen Bitcoin blocks.
|
||||
// These blocks are later re-evaluated at an interval
|
||||
// set by `-recheckpeginblockinterval`.
|
||||
if (state.GetRejectCode() == REJECT_PEGIN) {
|
||||
if (state.GetRejectReason() == "bad-pegin-witness") {
|
||||
//Write queue of invalid blocks that
|
||||
//must be cleared to continue operation
|
||||
std::vector<uint256> vinvalidBlocks;
|
||||
|
|
@ -3461,7 +3460,7 @@ static bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state,
|
|||
// Check proof of work matches claimed amount
|
||||
if (fCheckPOW && block.GetHash() != consensusParams.hashGenesisBlock
|
||||
&& !CheckProof(block, consensusParams)) {
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, false, REJECT_INVALID, g_signed_blocks ? "block-proof-invalid" : "high-hash", "proof of work failed");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, false, g_signed_blocks ? "block-proof-invalid" : "high-hash", "proof of work failed");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3483,13 +3482,13 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
|
|||
bool mutated;
|
||||
uint256 hashMerkleRoot2 = BlockMerkleRoot(block, &mutated);
|
||||
if (block.hashMerkleRoot != hashMerkleRoot2)
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, REJECT_INVALID, "bad-txnmrklroot", "hashMerkleRoot mismatch");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, "bad-txnmrklroot", "hashMerkleRoot mismatch");
|
||||
|
||||
// Check for merkle tree malleability (CVE-2012-2459): repeating sequences
|
||||
// of transactions in a block without affecting the merkle root of a block,
|
||||
// while still invalidating it.
|
||||
if (mutated)
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, REJECT_INVALID, "bad-txns-duplicate", "duplicate transaction");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, "bad-txns-duplicate", "duplicate transaction");
|
||||
}
|
||||
|
||||
// All potential-corruption validation must be done before we do any
|
||||
|
|
@ -3500,20 +3499,20 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
|
|||
|
||||
// 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)
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-blk-length", "size limits failed");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-blk-length", "size limits failed");
|
||||
|
||||
// First transaction must be coinbase, the rest must not be
|
||||
if (block.vtx.empty() || !block.vtx[0]->IsCoinBase())
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-cb-missing", "first tx is not coinbase");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-cb-missing", "first tx is not coinbase");
|
||||
for (unsigned int i = 1; i < block.vtx.size(); i++)
|
||||
if (block.vtx[i]->IsCoinBase())
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-cb-multiple", "more than one coinbase");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-cb-multiple", "more than one coinbase");
|
||||
|
||||
// Check transactions
|
||||
// Must check for duplicate inputs (see CVE-2018-17144)
|
||||
for (const auto& tx : block.vtx)
|
||||
if (!CheckTransaction(*tx, state, true))
|
||||
return state.Invalid(state.GetReason(), false, state.GetRejectCode(), state.GetRejectReason(),
|
||||
return state.Invalid(state.GetReason(), false, state.GetRejectReason(),
|
||||
strprintf("Transaction check failed (tx hash %s) %s", tx->GetHash().ToString(), state.GetDebugMessage()));
|
||||
|
||||
unsigned int nSigOps = 0;
|
||||
|
|
@ -3522,7 +3521,7 @@ bool CheckBlock(const CBlock& block, CValidationState& state, const Consensus::P
|
|||
nSigOps += GetLegacySigOpCount(*tx);
|
||||
}
|
||||
if (nSigOps * WITNESS_SCALE_FACTOR > MAX_BLOCK_SIGOPS_COST)
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-blk-sigops", "out-of-bounds SigOpCount");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-blk-sigops", "out-of-bounds SigOpCount");
|
||||
|
||||
if (fCheckPOW && fCheckMerkleRoot)
|
||||
block.fChecked = true;
|
||||
|
|
@ -3624,19 +3623,19 @@ static bool ContextualCheckDynaFedHeader(const CBlockHeader& block, CValidationS
|
|||
|
||||
// Dynamic blocks must at least publish current signblockscript in full
|
||||
if (dynafed_params.m_current.IsNull()) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "invalid-dyna-fed", "dynamic block headers must have non-empty current signblockscript field");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "invalid-dyna-fed", "dynamic block headers must have non-empty current signblockscript field");
|
||||
}
|
||||
|
||||
// Make sure extension bits aren't active, reserved for future HF
|
||||
uint32_t reserved_mask = (1<<23) | (1<<24) | (1<<25) | (1<<26);
|
||||
if ((block.nVersion & reserved_mask) != 0) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "invalid-dyna-fed", "dynamic block header has unknown HF extension bits set");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "invalid-dyna-fed", "dynamic block header has unknown HF extension bits set");
|
||||
}
|
||||
|
||||
const DynaFedParamEntry expected_current_params = ComputeNextBlockCurrentParameters(pindexPrev, params.GetConsensus());
|
||||
|
||||
if (expected_current_params != dynafed_params.m_current) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "invalid-dyna-fed", "dynamic block header's current parameters do not match expected");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "invalid-dyna-fed", "dynamic block header's current parameters do not match expected");
|
||||
}
|
||||
|
||||
// Lastly, enforce rules on proposals.
|
||||
|
|
@ -3647,13 +3646,13 @@ static bool ContextualCheckDynaFedHeader(const CBlockHeader& block, CValidationS
|
|||
int block_version = 0;
|
||||
std::vector<unsigned char> block_program;
|
||||
if (!proposed.m_signblockscript.IsWitnessProgram(block_version, block_program)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "invalid-dyna-fed", "proposed signblockscript must be native segwit scriptPubkey");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "invalid-dyna-fed", "proposed signblockscript must be native segwit scriptPubkey");
|
||||
}
|
||||
|
||||
int fedpeg_version = 0;
|
||||
std::vector<unsigned char> fedpeg_program;
|
||||
if (!proposed.m_fedpeg_program.IsWitnessProgram(fedpeg_version, fedpeg_program)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "invalid-dyna-fed", "proposed fedpegs program must be native segwit scriptPubkey");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "invalid-dyna-fed", "proposed fedpegs program must be native segwit scriptPubkey");
|
||||
}
|
||||
|
||||
// for v0, fedpegscript's scriptPubKey must match. v1+ is unencumbered.
|
||||
|
|
@ -3662,7 +3661,7 @@ static bool ContextualCheckDynaFedHeader(const CBlockHeader& block, CValidationS
|
|||
CSHA256().Write(proposed.m_fedpegscript.data(), proposed.m_fedpegscript.size()).Finalize(fedpeg_program.begin());
|
||||
CScript computed_program = CScript() << OP_0 << ToByteVector(fedpeg_program);
|
||||
if (computed_program != proposed.m_fedpeg_program) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "invalid-dyna-fed", "proposed v0 segwit fedpegscript must match proposed fedpeg witness program");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "invalid-dyna-fed", "proposed v0 segwit fedpegscript must match proposed fedpeg witness program");
|
||||
}
|
||||
|
||||
// fedpegscript proposals *must not* start with OP_DEPTH
|
||||
|
|
@ -3671,7 +3670,7 @@ static bool ContextualCheckDynaFedHeader(const CBlockHeader& block, CValidationS
|
|||
// We don't encumber future segwit versions as opcodes may change.
|
||||
if (!proposed.m_fedpegscript.empty() &&
|
||||
proposed.m_fedpegscript.front() == OP_DEPTH) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "invalid-dyna-fed", "Proposed fedpegscript starts with OP_DEPTH, which is illegal");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "invalid-dyna-fed", "Proposed fedpegscript starts with OP_DEPTH, which is illegal");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3681,7 +3680,7 @@ static bool ContextualCheckDynaFedHeader(const CBlockHeader& block, CValidationS
|
|||
if (params.GetEnforcePak()) {
|
||||
if (!proposed.m_extension_space.empty() &&
|
||||
CreatePAKListFromExtensionSpace(proposed.m_extension_space).IsReject()) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "invalid-dyna-fed", "Extension space is not list of valid PAK entries");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "invalid-dyna-fed", "Extension space is not list of valid PAK entries");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3721,7 +3720,7 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
|
|||
// Check proof of work target or non-dynamic signblockscript if necessary
|
||||
const Consensus::Params& consensusParams = params.GetConsensus();
|
||||
if (!IsDynaFedEnabled(pindexPrev, consensusParams) && !CheckChallenge(block, *pindexPrev, consensusParams))
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, false, REJECT_INVALID, "bad-diffbits", "incorrect proof of work");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, false, "bad-diffbits", "incorrect proof of work");
|
||||
|
||||
// Check against checkpoints
|
||||
if (fCheckpointsEnabled) {
|
||||
|
|
@ -3730,28 +3729,28 @@ static bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationSta
|
|||
// g_blockman.m_block_index.
|
||||
CBlockIndex* pcheckpoint = GetLastCheckpoint(params.Checkpoints());
|
||||
if (pcheckpoint && nHeight < pcheckpoint->nHeight)
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_CHECKPOINT, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), REJECT_CHECKPOINT, "bad-fork-prior-to-checkpoint");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_CHECKPOINT, error("%s: forked chain older than last checkpoint (height %d)", __func__, nHeight), "bad-fork-prior-to-checkpoint");
|
||||
}
|
||||
|
||||
// Check timestamp against prev
|
||||
if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast())
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, false, REJECT_INVALID, "time-too-old", "block's timestamp is too early");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, false, "time-too-old", "block's timestamp is too early");
|
||||
|
||||
// Check height in header against prev
|
||||
if (g_con_blockheightinheader && (uint32_t)nHeight != block.block_height)
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, error("%s: block height in header is incorrect", __func__),
|
||||
REJECT_INVALID, "bad-header-height");
|
||||
"bad-header-height");
|
||||
|
||||
// Check timestamp
|
||||
if (block.GetBlockTime() > nAdjustedTime + MAX_FUTURE_BLOCK_TIME)
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_TIME_FUTURE, false, REJECT_INVALID, "time-too-new", "block timestamp too far in the future");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_TIME_FUTURE, false, "time-too-new", "block timestamp too far in the future");
|
||||
|
||||
// Reject outdated version blocks when 95% (75% on testnet) of the network has upgraded:
|
||||
// check for version 2, 3 and 4 upgrades
|
||||
if((block.nVersion < 2 && nHeight >= consensusParams.BIP34Height) ||
|
||||
(block.nVersion < 3 && nHeight >= consensusParams.BIP66Height) ||
|
||||
(block.nVersion < 4 && nHeight >= consensusParams.BIP65Height))
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, false, REJECT_OBSOLETE, strprintf("bad-version(0x%08x)", block.nVersion),
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_HEADER, false, strprintf("bad-version(0x%08x)", block.nVersion),
|
||||
strprintf("rejected nVersion=0x%08x block", block.nVersion));
|
||||
|
||||
if (!ContextualCheckDynaFedHeader(block, state, params, pindexPrev)) {
|
||||
|
|
@ -3785,7 +3784,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
|
|||
// Check that all transactions are finalized
|
||||
for (const auto& tx : block.vtx) {
|
||||
if (!IsFinalTx(*tx, nHeight, nLockTimeCutoff)) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-txns-nonfinal", "non-final transaction");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-txns-nonfinal", "non-final transaction");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3795,7 +3794,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
|
|||
CScript expect = CScript() << nHeight;
|
||||
if (block.vtx[0]->vin[0].scriptSig.size() < expect.size() ||
|
||||
!std::equal(expect.begin(), expect.end(), block.vtx[0]->vin[0].scriptSig.begin())) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-cb-height", "block height mismatch in coinbase");
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-cb-height", "block height mismatch in coinbase");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3805,7 +3804,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
|
|||
if (!inwit.vchIssuanceAmountRangeproof.empty() ||
|
||||
!inwit.vchInflationKeysRangeproof.empty() ||
|
||||
!inwit.m_pegin_witness.IsNull()) {
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, REJECT_INVALID, "bad-cb-witness", "Coinbase has invalid input witness data.");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, "bad-cb-witness", "Coinbase has invalid input witness data.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3829,12 +3828,12 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
|
|||
if ((block.vtx[0]->witness.vtxinwit.empty()) ||
|
||||
(block.vtx[0]->witness.vtxinwit[0].scriptWitness.stack.size() != 1) ||
|
||||
(block.vtx[0]->witness.vtxinwit[0].scriptWitness.stack[0].size() != 32)) {
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, REJECT_INVALID, "bad-witness-nonce-size", strprintf("%s : invalid witness reserved value size", __func__));
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, "bad-witness-nonce-size", strprintf("%s : invalid witness reserved value size", __func__));
|
||||
}
|
||||
CHash256().Write(hashWitness.begin(), 32).Write(&block.vtx[0]->witness.vtxinwit[0].scriptWitness.stack[0][0], 32).Finalize(hashWitness.begin());
|
||||
uint256 committedWitness(std::vector<unsigned char>(&block.vtx[0]->vout[commitpos].scriptPubKey[6], &block.vtx[0]->vout[commitpos].scriptPubKey[6+32]));
|
||||
if (memcmp(hashWitness.begin(), &block.vtx[0]->vout[commitpos].scriptPubKey[6], 32)) {
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, REJECT_INVALID, "bad-witness-merkle-match", strprintf("%s : witness merkle commitment mismatch", __func__));
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, "bad-witness-merkle-match", strprintf("%s : witness merkle commitment mismatch", __func__));
|
||||
}
|
||||
fHaveWitness = true;
|
||||
}
|
||||
|
|
@ -3844,7 +3843,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
|
|||
if (!fHaveWitness) {
|
||||
for (const auto& tx : block.vtx) {
|
||||
if (tx->HasWitness()) {
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, REJECT_INVALID, "unexpected-witness", strprintf("%s : unexpected witness data found", __func__));
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MUTATED, false, "unexpected-witness", strprintf("%s : unexpected witness data found", __func__));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3856,7 +3855,7 @@ static bool ContextualCheckBlock(const CBlock& block, CValidationState& state, c
|
|||
// the block hash, so we couldn't mark the block as permanently
|
||||
// failed).
|
||||
if (GetBlockWeight(block) > MAX_BLOCK_WEIGHT) {
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-blk-weight", strprintf("%s : weight limit failed", __func__));
|
||||
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, "bad-blk-weight", strprintf("%s : weight limit failed", __func__));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -3876,7 +3875,7 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, CValidationState
|
|||
if (ppindex)
|
||||
*ppindex = pindex;
|
||||
if (pindex->nStatus & BLOCK_FAILED_MASK)
|
||||
return state.Invalid(ValidationInvalidReason::CACHED_INVALID, error("%s: block %s is marked invalid", __func__, hash.ToString()), 0, "duplicate");
|
||||
return state.Invalid(ValidationInvalidReason::CACHED_INVALID, error("%s: block %s is marked invalid", __func__, hash.ToString()), "duplicate");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -3887,10 +3886,10 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, CValidationState
|
|||
CBlockIndex* pindexPrev = nullptr;
|
||||
BlockMap::iterator mi = m_block_index.find(block.hashPrevBlock);
|
||||
if (mi == m_block_index.end())
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MISSING_PREV, error("%s: prev block not found", __func__), 0, "prev-blk-not-found");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_MISSING_PREV, error("%s: prev block not found", __func__), "prev-blk-not-found");
|
||||
pindexPrev = (*mi).second;
|
||||
if (pindexPrev->nStatus & BLOCK_FAILED_MASK)
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_PREV, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_PREV, error("%s: prev block invalid", __func__), "bad-prevblk");
|
||||
if (!ContextualCheckBlockHeader(block, state, chainparams, pindexPrev, GetAdjustedTime()))
|
||||
return error("%s: Consensus::ContextualCheckBlockHeader: %s, %s", __func__, hash.ToString(), FormatStateMessage(state));
|
||||
|
||||
|
|
@ -3927,7 +3926,7 @@ bool BlockManager::AcceptBlockHeader(const CBlockHeader& block, CValidationState
|
|||
setDirtyBlockIndex.insert(invalid_walk);
|
||||
invalid_walk = invalid_walk->pprev;
|
||||
}
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_PREV, error("%s: prev block invalid", __func__), REJECT_INVALID, "bad-prevblk");
|
||||
return state.Invalid(ValidationInvalidReason::BLOCK_INVALID_PREV, error("%s: prev block invalid", __func__), "bad-prevblk");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue