Add MissingDataBehavior and make TransactionSignatureChecker handle it
This allows specifying how *TransactionSignatureChecker will behave when presented with missing transaction data such as amounts spent, BIP341 data, or spent outputs. As all call sites still (implicitly) use MissingDataBehavior::ASSERT_FAIL, this commit introduces no change in behavior.
This commit is contained in:
1 parent
4ba1bab443
commit
b77b0cc507
2 files changed
+29
-5
No files matched your search
@@ -1488,8 +1488,20 @@ static const CHashWriter HASHER_TAPLEAF = TaggedHash("TapLeaf");
|
|||||||
static const CHashWriter HASHER_TAPBRANCH = TaggedHash("TapBranch");
|
static const CHashWriter HASHER_TAPBRANCH = TaggedHash("TapBranch");
|
||||||
static const CHashWriter HASHER_TAPTWEAK = TaggedHash("TapTweak");
|
static const CHashWriter HASHER_TAPTWEAK = TaggedHash("TapTweak");
|
||||||
|
|
||||||
|
static bool HandleMissingData(MissingDataBehavior mdb)
|
||||||
|
{
|
||||||
|
switch (mdb) {
|
||||||
|
case MissingDataBehavior::ASSERT_FAIL:
|
||||||
|
assert(!"Missing data");
|
||||||
|
break;
|
||||||
|
case MissingDataBehavior::FAIL:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assert(!"Unknown MissingDataBehavior value");
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache)
|
bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata, const T& tx_to, uint32_t in_pos, uint8_t hash_type, SigVersion sigversion, const PrecomputedTransactionData& cache, MissingDataBehavior mdb)
|
||||||
{
|
{
|
||||||
uint8_t ext_flag, key_version;
|
uint8_t ext_flag, key_version;
|
||||||
switch (sigversion) {
|
switch (sigversion) {
|
||||||
@@ -1509,7 +1521,9 @@ bool SignatureHashSchnorr(uint256& hash_out, const ScriptExecutionData& execdata
|
|||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
assert(in_pos < tx_to.vin.size());
|
assert(in_pos < tx_to.vin.size());
|
||||||
assert(cache.m_bip341_taproot_ready && cache.m_spent_outputs_ready);
|
if (!(cache.m_bip341_taproot_ready && cache.m_spent_outputs_ready)) {
|
||||||
|
return HandleMissingData(mdb);
|
||||||
|
}
|
||||||
|
|
||||||
CHashWriter ss = HASHER_TAPSIGHASH;
|
CHashWriter ss = HASHER_TAPSIGHASH;
|
||||||
|
|
||||||
@@ -1696,7 +1710,7 @@ bool GenericTransactionSignatureChecker<T>::CheckSchnorrSignature(Span<const uns
|
|||||||
}
|
}
|
||||||
uint256 sighash;
|
uint256 sighash;
|
||||||
assert(this->txdata);
|
assert(this->txdata);
|
||||||
if (!SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, *this->txdata)) {
|
if (!SignatureHashSchnorr(sighash, execdata, *txTo, nIn, hashtype, sigversion, *this->txdata, m_mdb)) {
|
||||||
return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_HASHTYPE);
|
return set_error(serror, SCRIPT_ERR_SCHNORR_SIG_HASHTYPE);
|
||||||
}
|
}
|
||||||
if (!VerifySchnorrSignature(sig, pubkey, sighash)) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG);
|
if (!VerifySchnorrSignature(sig, pubkey, sighash)) return set_error(serror, SCRIPT_ERR_SCHNORR_SIG);
|
||||||
|
|||||||
@@ -247,11 +247,21 @@ public:
|
|||||||
virtual ~BaseSignatureChecker() {}
|
virtual ~BaseSignatureChecker() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Enum to specify what *TransactionSignatureChecker's behavior should be
|
||||||
|
* when dealing with missing transaction data.
|
||||||
|
*/
|
||||||
|
enum class MissingDataBehavior
|
||||||
|
{
|
||||||
|
ASSERT_FAIL, //!< Abort execution through assertion failure (for consensus code)
|
||||||
|
FAIL, //!< Just act as if the signature was invalid
|
||||||
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class GenericTransactionSignatureChecker : public BaseSignatureChecker
|
class GenericTransactionSignatureChecker : public BaseSignatureChecker
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
const T* txTo;
|
const T* txTo;
|
||||||
|
const MissingDataBehavior m_mdb;
|
||||||
unsigned int nIn;
|
unsigned int nIn;
|
||||||
const CAmount amount;
|
const CAmount amount;
|
||||||
const PrecomputedTransactionData* txdata;
|
const PrecomputedTransactionData* txdata;
|
||||||
@@ -261,8 +271,8 @@ protected:
|
|||||||
virtual bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const;
|
virtual bool VerifySchnorrSignature(Span<const unsigned char> sig, const XOnlyPubKey& pubkey, const uint256& sighash) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
|
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, MissingDataBehavior mdb = MissingDataBehavior::ASSERT_FAIL) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(nullptr) {}
|
||||||
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn) : txTo(txToIn), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
|
GenericTransactionSignatureChecker(const T* txToIn, unsigned int nInIn, const CAmount& amountIn, const PrecomputedTransactionData& txdataIn, MissingDataBehavior mdb = MissingDataBehavior::ASSERT_FAIL) : txTo(txToIn), m_mdb(mdb), nIn(nInIn), amount(amountIn), txdata(&txdataIn) {}
|
||||||
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override;
|
bool CheckECDSASignature(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode, SigVersion sigversion) const override;
|
||||||
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
|
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, const ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
|
||||||
bool CheckLockTime(const CScriptNum& nLockTime) const override;
|
bool CheckLockTime(const CScriptNum& nLockTime) const override;
|
||||||
|
|||||||
Reference in new issue
Block a user