Skip to content

Commit

Permalink
policy: Reject transactions with witness before SegWit activates
Browse files Browse the repository at this point in the history
  • Loading branch information
lateminer committed Jan 22, 2024
1 parent 5f77e59 commit 5facf3c
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 7 deletions.
9 changes: 5 additions & 4 deletions src/policy/policy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFeeIn)
return (txout.nValue < GetDustThreshold(txout, dustRelayFeeIn));
}

bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_datacarrier_bytes, TxoutType& whichType)
bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_datacarrier_bytes, TxoutType& whichType, const bool witnessEnabled)
{
std::vector<std::vector<unsigned char> > vSolutions;
whichType = Solver(scriptPubKey, vSolutions);
Expand All @@ -88,12 +88,13 @@ bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_
if (!max_datacarrier_bytes || scriptPubKey.size() > *max_datacarrier_bytes) {
return false;
}
} else if (!witnessEnabled && (whichType == TxoutType::WITNESS_V0_SCRIPTHASH || whichType == TxoutType::WITNESS_V0_KEYHASH || whichType == TxoutType::WITNESS_V1_TAPROOT || whichType == TxoutType::WITNESS_UNKNOWN)) {
return false;
}

return true;
}

bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason)
bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason, const bool witnessEnabled)
{
if ((!Params().GetConsensus().IsProtocolV3_1(tx.nTime ? (int64_t)tx.nTime : GetAdjustedTimeSeconds()) && (tx.nVersion > TX_MAX_STANDARD_VERSION-1)) || tx.nVersion > TX_MAX_STANDARD_VERSION || tx.nVersion < 1) {
reason = "version";
Expand Down Expand Up @@ -133,7 +134,7 @@ bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_dat
unsigned int nDataOut = 0;
TxoutType whichType;
for (const CTxOut& txout : tx.vout) {
if (!::IsStandard(txout.scriptPubKey, max_datacarrier_bytes, whichType)) {
if (!::IsStandard(txout.scriptPubKey, max_datacarrier_bytes, whichType, witnessEnabled)) {
reason = "scriptpubkey";
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ CAmount GetDustThreshold(const CTxOut& txout, const CFeeRate& dustRelayFee);

bool IsDust(const CTxOut& txout, const CFeeRate& dustRelayFee);

bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_datacarrier_bytes, TxoutType& whichType);
bool IsStandard(const CScript& scriptPubKey, const std::optional<unsigned>& max_datacarrier_bytes, TxoutType& whichType, const bool witnessEnabled = false);


// Changing the default transaction version requires a two step process: first
Expand All @@ -114,7 +114,7 @@ static constexpr decltype(CTransaction::nVersion) TX_MAX_STANDARD_VERSION{2};
* Check for standard transaction types
* @return True if all outputs (scriptPubKeys) use only standard transaction forms
*/
bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason);
bool IsStandardTx(const CTransaction& tx, const std::optional<unsigned>& max_datacarrier_bytes, bool permit_bare_multisig, const CFeeRate& dust_relay_fee, std::string& reason, const bool witnessEnabled = false);
/**
* Check for standard transaction types
* @param[in] mapInputs Map of previous transactions that have outputs we're spending
Expand Down
8 changes: 7 additions & 1 deletion src/validation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,9 +715,15 @@ bool MemPoolAccept::PreChecks(ATMPArgs& args, Workspace& ws)
if (m_pool.m_require_standard && tx.nVersion >= TX_MAX_STANDARD_VERSION && !Params().GetConsensus().IsProtocolV3_1(nTimeTx))
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "premature-version2-tx");

// Reject transactions with witness before segregated witness activates (override with -prematurewitness)
bool witnessEnabled = DeploymentActiveAfter(m_active_chainstate.m_chain.Tip(), m_active_chainstate.m_chainman, Consensus::DEPLOYMENT_SEGWIT);
if (!gArgs.GetBoolArg("-prematurewitness", false) && tx.HasWitness() && !witnessEnabled) {
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, "no-witness-yet");
}

// Rather not work on nonstandard transactions (unless -testnet/-regtest)
std::string reason;
if (m_pool.m_require_standard && !IsStandardTx(tx, m_pool.m_max_datacarrier_bytes, m_pool.m_permit_bare_multisig, m_pool.m_dust_relay_feerate, reason)) {
if (m_pool.m_require_standard && !IsStandardTx(tx, m_pool.m_max_datacarrier_bytes, m_pool.m_permit_bare_multisig, m_pool.m_dust_relay_feerate, reason, witnessEnabled)) {
return state.Invalid(TxValidationResult::TX_NOT_STANDARD, reason);
}

Expand Down

0 comments on commit 5facf3c

Please sign in to comment.