mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
policy: make bare OP_CHECKTEMPLATEVERIFY standard
Co-authored-by: James O'Beirne <github@au92.org>
This commit is contained in:
parent
a0bd24e9cd
commit
d314cbb7ee
13 changed files with 42 additions and 1 deletions
|
@ -98,6 +98,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
|
|||
case TxoutType::MULTISIG:
|
||||
case TxoutType::NULL_DATA:
|
||||
case TxoutType::NONSTANDARD:
|
||||
case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY:
|
||||
addressRet = CNoDestination(scriptPubKey);
|
||||
return false;
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
|
|
|
@ -212,6 +212,11 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
|
|||
if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) {
|
||||
return false;
|
||||
}
|
||||
} else if (whichType == TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY) {
|
||||
// after activation, only allow bare with no scriptsig.
|
||||
// pre-activation disallowing enforced via discouraged logic in the
|
||||
// interpreter.
|
||||
if (tx.vin[i].scriptSig.size() != 0) return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,10 @@ static constexpr unsigned int STANDARD_SCRIPT_VERIFY_FLAGS{MANDATORY_SCRIPT_VERI
|
|||
SCRIPT_VERIFY_CONST_SCRIPTCODE |
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION |
|
||||
SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS |
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE};
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE |
|
||||
SCRIPT_VERIFY_DISCOURAGE_CHECKTEMPLATEVERIFY |
|
||||
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY |
|
||||
SCRIPT_VERIFY_CHECKTEMPLATEVERIFY};
|
||||
|
||||
/** For convenience, standard but not mandatory verify flags. */
|
||||
static constexpr unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS{STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS};
|
||||
|
|
|
@ -544,6 +544,8 @@ static RPCHelpMan decodescript()
|
|||
case TxoutType::WITNESS_UNKNOWN:
|
||||
case TxoutType::WITNESS_V1_TAPROOT:
|
||||
case TxoutType::ANCHOR:
|
||||
// don't wrap CTV because P2SH CTV is a hash cycle
|
||||
case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY:
|
||||
// Should not be wrapped
|
||||
return false;
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
|
@ -587,6 +589,8 @@ static RPCHelpMan decodescript()
|
|||
case TxoutType::WITNESS_V0_SCRIPTHASH:
|
||||
case TxoutType::WITNESS_V1_TAPROOT:
|
||||
case TxoutType::ANCHOR:
|
||||
// don't wrap CTV because P2SH CTV is a hash cycle
|
||||
case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY:
|
||||
// Should not be wrapped
|
||||
return false;
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
|
|
|
@ -221,6 +221,14 @@ bool CScript::IsPayToAnchor(int version, const std::vector<unsigned char>& progr
|
|||
program[1] == 0x73;
|
||||
}
|
||||
|
||||
bool CScript::IsPayToBareDefaultCheckTemplateVerifyHash() const
|
||||
{
|
||||
// Extra-fast test for pay-to-bare-default-check-template-verify-hash CScripts:
|
||||
return (this->size() == 34 &&
|
||||
(*this)[0] == 0x20 &&
|
||||
(*this)[33] == OP_CHECKTEMPLATEVERIFY);
|
||||
}
|
||||
|
||||
bool CScript::IsPayToScriptHash() const
|
||||
{
|
||||
// Extra-fast test for pay-to-script-hash CScripts:
|
||||
|
|
|
@ -553,6 +553,8 @@ public:
|
|||
*/
|
||||
static bool IsPayToAnchor(int version, const std::vector<unsigned char>& program);
|
||||
|
||||
bool IsPayToBareDefaultCheckTemplateVerifyHash() const;
|
||||
|
||||
bool IsPayToScriptHash() const;
|
||||
bool IsPayToWitnessScriptHash() const;
|
||||
bool IsWitnessProgram(int& version, std::vector<unsigned char>& program) const;
|
||||
|
|
|
@ -412,6 +412,7 @@ static bool SignStep(const SigningProvider& provider, const BaseSignatureCreator
|
|||
case TxoutType::NONSTANDARD:
|
||||
case TxoutType::NULL_DATA:
|
||||
case TxoutType::WITNESS_UNKNOWN:
|
||||
case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY:
|
||||
return false;
|
||||
case TxoutType::PUBKEY:
|
||||
if (!CreateSig(creator, sigdata, provider, sig, CPubKey(vSolutions[0]), scriptPubKey, sigversion)) return false;
|
||||
|
|
|
@ -29,6 +29,7 @@ std::string GetTxnOutputType(TxoutType t)
|
|||
case TxoutType::WITNESS_V0_SCRIPTHASH: return "witness_v0_scripthash";
|
||||
case TxoutType::WITNESS_V1_TAPROOT: return "witness_v1_taproot";
|
||||
case TxoutType::WITNESS_UNKNOWN: return "witness_unknown";
|
||||
case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY: return "bare_default_ctv_hash";
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
assert(false);
|
||||
}
|
||||
|
@ -151,6 +152,10 @@ TxoutType Solver(const CScript& scriptPubKey, std::vector<std::vector<unsigned c
|
|||
return TxoutType::SCRIPTHASH;
|
||||
}
|
||||
|
||||
if (scriptPubKey.IsPayToBareDefaultCheckTemplateVerifyHash()) {
|
||||
return TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY;
|
||||
}
|
||||
|
||||
int witnessversion;
|
||||
std::vector<unsigned char> witnessprogram;
|
||||
if (scriptPubKey.IsWitnessProgram(witnessversion, witnessprogram)) {
|
||||
|
|
|
@ -31,6 +31,7 @@ enum class TxoutType {
|
|||
WITNESS_V0_SCRIPTHASH,
|
||||
WITNESS_V0_KEYHASH,
|
||||
WITNESS_V1_TAPROOT,
|
||||
TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY,
|
||||
WITNESS_UNKNOWN, //!< Only for Witness versions not already defined above
|
||||
};
|
||||
|
||||
|
|
|
@ -76,6 +76,7 @@ FUZZ_TARGET(script, .init = initialize_script)
|
|||
assert(which_type == TxoutType::PUBKEY ||
|
||||
which_type == TxoutType::NONSTANDARD ||
|
||||
which_type == TxoutType::NULL_DATA ||
|
||||
which_type == TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY ||
|
||||
which_type == TxoutType::MULTISIG);
|
||||
}
|
||||
if (which_type == TxoutType::NONSTANDARD ||
|
||||
|
|
|
@ -70,6 +70,9 @@ static std::map<std::string, unsigned int> mapFlagNames = {
|
|||
{std::string("DISCOURAGE_UPGRADABLE_PUBKEYTYPE"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_PUBKEYTYPE},
|
||||
{std::string("DISCOURAGE_OP_SUCCESS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_OP_SUCCESS},
|
||||
{std::string("DISCOURAGE_UPGRADABLE_TAPROOT_VERSION"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_TAPROOT_VERSION},
|
||||
{std::string("DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_CHECKTEMPLATEVERIFY},
|
||||
{std::string("DISCOURAGE_CHECKTEMPLATEVERIFY"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_CHECKTEMPLATEVERIFY},
|
||||
{std::string("CHECKTEMPLATEVERIFY"), (unsigned int)SCRIPT_VERIFY_CHECKTEMPLATEVERIFY},
|
||||
};
|
||||
|
||||
unsigned int ParseScriptFlags(std::string strFlags)
|
||||
|
|
|
@ -912,6 +912,8 @@ static std::string RecurseImportData(const CScript& script, ImportData& import_d
|
|||
case TxoutType::WITNESS_V1_TAPROOT:
|
||||
case TxoutType::ANCHOR:
|
||||
return "unrecognized script";
|
||||
case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY:
|
||||
return "bare default CheckTemplateVerify hash";
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
NONFATAL_UNREACHABLE();
|
||||
}
|
||||
|
|
|
@ -208,6 +208,11 @@ IsMineResult IsMineInner(const LegacyDataSPKM& keystore, const CScript& scriptPu
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TxoutType::TX_BARE_DEFAULT_CHECKTEMPLATEVERIFY:
|
||||
{
|
||||
ret = IsMineResult::NO;
|
||||
break;
|
||||
}
|
||||
} // no default case, so the compiler can warn about missing cases
|
||||
|
||||
if (ret == IsMineResult::NO && keystore.HaveWatchOnly(scriptPubKey)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue