Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 981 Lines • ▼ Show 20 Lines | // Check for conflicts with in-memory transactions | ||||
entry, setAncestors, nLimitAncestors, nLimitAncestorSize, | entry, setAncestors, nLimitAncestors, nLimitAncestorSize, | ||||
nLimitDescendants, nLimitDescendantSize, errString)) { | nLimitDescendants, nLimitDescendantSize, errString)) { | ||||
return state.DoS(0, false, REJECT_NONSTANDARD, | return state.DoS(0, false, REJECT_NONSTANDARD, | ||||
"too-long-mempool-chain", false, errString); | "too-long-mempool-chain", false, errString); | ||||
} | } | ||||
// Set extraFlags as a set of flags that needs to be activated. | // Set extraFlags as a set of flags that needs to be activated. | ||||
uint32_t extraFlags = 0; | uint32_t extraFlags = 0; | ||||
if (hasMonolith) { | |||||
extraFlags |= SCRIPT_ENABLE_MONOLITH_OPCODES; | |||||
} | |||||
if (IsReplayProtectionEnabledForCurrentBlock(config)) { | if (IsReplayProtectionEnabledForCurrentBlock(config)) { | ||||
extraFlags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | extraFlags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | ||||
} | } | ||||
// Check inputs based on the set of flags we activate. | // Check inputs based on the set of flags we activate. | ||||
uint32_t scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; | uint32_t scriptVerifyFlags = STANDARD_SCRIPT_VERIFY_FLAGS; | ||||
if (!config.GetChainParams().RequireStandard()) { | if (!config.GetChainParams().RequireStandard()) { | ||||
scriptVerifyFlags = | scriptVerifyFlags = | ||||
Show All 30 Lines | // Check for conflicts with in-memory transactions | ||||
// transactions into the mempool can be exploited as a DoS attack. | // transactions into the mempool can be exploited as a DoS attack. | ||||
uint32_t currentBlockScriptVerifyFlags = | uint32_t currentBlockScriptVerifyFlags = | ||||
GetBlockScriptFlags(chainActive.Tip(), config); | GetBlockScriptFlags(chainActive.Tip(), config); | ||||
// We have an off by one error for flag activation. As a result, we need | // We have an off by one error for flag activation. As a result, we need | ||||
// to set the replay protection flag manually here until this is fixed. | // to set the replay protection flag manually here until this is fixed. | ||||
// FIXME: https://reviews.bitcoinabc.org/T288 | // FIXME: https://reviews.bitcoinabc.org/T288 | ||||
currentBlockScriptVerifyFlags |= extraFlags; | currentBlockScriptVerifyFlags |= extraFlags; | ||||
if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, | if (!CheckInputsFromMempoolAndCache(tx, state, view, pool, | ||||
currentBlockScriptVerifyFlags, true, | currentBlockScriptVerifyFlags, true, | ||||
txdata)) { | txdata)) { | ||||
// If we're using promiscuousmempoolflags, we may hit this normally. | // If we're using promiscuousmempoolflags, we may hit this normally. | ||||
// Check if current block has some flags that scriptVerifyFlags does | // Check if current block has some flags that scriptVerifyFlags does | ||||
// not before printing an ominous warning. | // not before printing an ominous warning. | ||||
if (!(~scriptVerifyFlags & currentBlockScriptVerifyFlags)) { | if (!(~scriptVerifyFlags & currentBlockScriptVerifyFlags)) { | ||||
return error( | return error( | ||||
▲ Show 20 Lines • Show All 513 Lines • ▼ Show 20 Lines | for (size_t i = 0; i < tx.vin.size(); i++) { | ||||
const Amount amount = coin.GetTxOut().nValue; | const Amount amount = coin.GetTxOut().nValue; | ||||
// Verify signature | // Verify signature | ||||
CScriptCheck check(scriptPubKey, amount, tx, i, flags, sigCacheStore, | CScriptCheck check(scriptPubKey, amount, tx, i, flags, sigCacheStore, | ||||
txdata); | txdata); | ||||
if (pvChecks) { | if (pvChecks) { | ||||
pvChecks->push_back(std::move(check)); | pvChecks->push_back(std::move(check)); | ||||
} else if (!check()) { | } else if (!check()) { | ||||
if (flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) { | const bool hasNonMandatoryFlags = | ||||
(flags & STANDARD_NOT_MANDATORY_VERIFY_FLAGS) != 0; | |||||
const bool doesNotHaveMonolith = | |||||
(flags & SCRIPT_ENABLE_MONOLITH_OPCODES) == 0; | |||||
if (hasNonMandatoryFlags || doesNotHaveMonolith) { | |||||
// Check whether the failure was caused by a non-mandatory | // Check whether the failure was caused by a non-mandatory | ||||
// script verification check, such as non-standard DER encodings | // script verification check, such as non-standard DER encodings | ||||
// or non-null dummy arguments; if so, don't trigger DoS | // or non-null dummy arguments; if so, don't trigger DoS | ||||
// protection to avoid splitting the network between upgraded | // protection to avoid splitting the network between upgraded | ||||
// and non-upgraded nodes. | // and non-upgraded nodes. | ||||
CScriptCheck check2(scriptPubKey, amount, tx, i, | // | ||||
flags & | // We also check activating the monolith opcodes as it is a | ||||
~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, | // strictly additive change and we would not like to ban some of | ||||
// our peer that are ahead of us and are considering the fork | |||||
// as activated. | |||||
CScriptCheck check2( | |||||
scriptPubKey, amount, tx, i, | |||||
(flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS) | | |||||
SCRIPT_ENABLE_MONOLITH_OPCODES, | |||||
sigCacheStore, txdata); | sigCacheStore, txdata); | ||||
if (check2()) { | if (check2()) { | ||||
return state.Invalid( | return state.Invalid( | ||||
false, REJECT_NONSTANDARD, | false, REJECT_NONSTANDARD, | ||||
strprintf("non-mandatory-script-verify-flag (%s)", | strprintf("non-mandatory-script-verify-flag (%s)", | ||||
ScriptErrorString(check.GetScriptError()))); | ScriptErrorString(check.GetScriptError()))); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 345 Lines • ▼ Show 20 Lines | static uint32_t GetBlockScriptFlags(const CBlockIndex *pindex, | ||||
// s in their signature. We also make sure that signature that are supposed | // s in their signature. We also make sure that signature that are supposed | ||||
// to fail (for instance in multisig or other forms of smart contracts) are | // to fail (for instance in multisig or other forms of smart contracts) are | ||||
// null. | // null. | ||||
if (IsDAAEnabled(config, pindex->pprev)) { | if (IsDAAEnabled(config, pindex->pprev)) { | ||||
flags |= SCRIPT_VERIFY_LOW_S; | flags |= SCRIPT_VERIFY_LOW_S; | ||||
flags |= SCRIPT_VERIFY_NULLFAIL; | flags |= SCRIPT_VERIFY_NULLFAIL; | ||||
} | } | ||||
// The monolith HF enable a set of opcodes. | |||||
if (IsMonolithEnabled(config, pindex->pprev)) { | |||||
flags |= SCRIPT_ENABLE_MONOLITH_OPCODES; | |||||
} | |||||
// We make sure this node will have replay protection during the next hard | // We make sure this node will have replay protection during the next hard | ||||
// fork. | // fork. | ||||
if (IsReplayProtectionEnabled(config, pindex->pprev)) { | if (IsReplayProtectionEnabled(config, pindex->pprev)) { | ||||
flags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | flags |= SCRIPT_ENABLE_REPLAY_PROTECTION; | ||||
} | } | ||||
return flags; | return flags; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 634 Lines • ▼ Show 20 Lines | if (!FlushStateToDisk(config.GetChainParams(), state, | ||||
FLUSH_STATE_IF_NEEDED)) { | FLUSH_STATE_IF_NEEDED)) { | ||||
return false; | return false; | ||||
} | } | ||||
// If this block was deactivating the replay protection, then we need to | // If this block was deactivating the replay protection, then we need to | ||||
// remove transactions that are replay protected from the mempool. There is | // remove transactions that are replay protected from the mempool. There is | ||||
// no easy way to do this so we'll just discard the whole mempool and then | // no easy way to do this so we'll just discard the whole mempool and then | ||||
// add the transaction of the block we just disconnected back. | // add the transaction of the block we just disconnected back. | ||||
if (IsReplayProtectionEnabled(config, pindexDelete) && | // | ||||
!IsReplayProtectionEnabled(config, pindexDelete->pprev)) { | // Samewise, if this block enabled the monolith opcodes, then we need to | ||||
// clear the mempool of any transaction using them. | |||||
if ((IsReplayProtectionEnabled(config, pindexDelete) && | |||||
!IsReplayProtectionEnabled(config, pindexDelete->pprev)) || | |||||
(IsMonolithEnabled(config, pindexDelete) && | |||||
!IsMonolithEnabled(config, pindexDelete->pprev))) { | |||||
mempool.clear(); | mempool.clear(); | ||||
// While not strictly necessary, clearing the disconnect pool is also | // While not strictly necessary, clearing the disconnect pool is also | ||||
// beneficial so we don't try to reuse its content at the end of the | // beneficial so we don't try to reuse its content at the end of the | ||||
// reorg, which we know will fail. | // reorg, which we know will fail. | ||||
if (disconnectpool) { | if (disconnectpool) { | ||||
disconnectpool->clear(); | disconnectpool->clear(); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,835 Lines • Show Last 20 Lines |