Skip to content

Commit 58b2f7b

Browse files
JeremyRubinRob1Ham
authored andcommitted
Add StandardTemplateHash definition
and associated SignatureChecker method. (cherry picked from commit 0cf7d5c)
1 parent bdd7a81 commit 58b2f7b

File tree

2 files changed

+65
-21
lines changed

2 files changed

+65
-21
lines changed

src/script/interpreter.cpp

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,18 @@ uint256 GetSpentAmountsSHA256(const std::vector<CTxOut>& outputs_spent)
14121412
HashWriter ss{};
14131413
for (const auto& txout : outputs_spent) {
14141414
ss << txout.nValue;
1415+
1416+
}
1417+
return ss.GetSHA256();
1418+
}
1419+
1420+
/** Compute the (single) SHA256 of the concatenation of all scriptSigs in a tx. */
1421+
template <class T>
1422+
uint256 GetScriptSigsSHA256(const T& txTo)
1423+
{
1424+
HashWriter ss{};
1425+
for (const auto& in : txTo.vin) {
1426+
ss << in.scriptSig;
14151427
}
14161428
return ss.GetSHA256();
14171429
}
@@ -1426,6 +1438,38 @@ uint256 GetSpentScriptsSHA256(const std::vector<CTxOut>& outputs_spent)
14261438
return ss.GetSHA256();
14271439
}
14281440

1441+
template<typename TxType>
1442+
uint256 GetDefaultCheckTemplateVerifyHashWithScript(
1443+
const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1444+
const uint256& scriptSig_hash, const uint32_t input_index)
1445+
{
1446+
auto h = HashWriter{}
1447+
<< tx.version
1448+
<< tx.nLockTime
1449+
<< scriptSig_hash
1450+
<< uint32_t(tx.vin.size())
1451+
<< sequences_hash
1452+
<< uint32_t(tx.vout.size())
1453+
<< outputs_hash
1454+
<< input_index;
1455+
return h.GetSHA256();
1456+
}
1457+
1458+
template<typename TxType>
1459+
uint256 GetDefaultCheckTemplateVerifyHashEmptyScript(
1460+
const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
1461+
const uint32_t input_index)
1462+
{
1463+
auto h = HashWriter{}
1464+
<< tx.version
1465+
<< tx.nLockTime
1466+
<< uint32_t(tx.vin.size())
1467+
<< sequences_hash
1468+
<< uint32_t(tx.vout.size())
1469+
<< outputs_hash
1470+
<< input_index;
1471+
return h.GetSHA256();
1472+
}
14291473

14301474
} // namespace
14311475

@@ -1434,16 +1478,12 @@ uint256 GetDefaultCheckTemplateVerifyHash(const TxType& tx, uint32_t input_index
14341478
return GetDefaultCheckTemplateVerifyHash(tx, GetOutputsSHA256(tx), GetSequencesSHA256(tx), input_index);
14351479
}
14361480

1437-
template<typename TxType>
1438-
static bool NoScriptSigs(const TxType& tx)
1439-
{
1440-
return std::all_of(tx.vin.begin(), tx.vin.end(), [](const CTxIn& c) { return c.scriptSig.empty(); });
1441-
}
1442-
14431481
template<typename TxType>
14441482
uint256 GetDefaultCheckTemplateVerifyHash(
14451483
const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash, const uint32_t input_index) {
1446-
return NoScriptSigs(tx) ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) :
1484+
bool skip_scriptSigs = std::find_if(tx.vin.begin(), tx.vin.end(),
1485+
[](const CTxIn& c) { return c.scriptSig != CScript(); }) == tx.vin.end();
1486+
return skip_scriptSigs ? GetDefaultCheckTemplateVerifyHashEmptyScript(tx, outputs_hash, sequences_hash, input_index) :
14471487
GetDefaultCheckTemplateVerifyHashWithScript(tx, outputs_hash, sequences_hash, GetScriptSigsSHA256(tx), input_index);
14481488
}
14491489

@@ -1856,20 +1896,13 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
18561896
}
18571897

18581898
template <class T>
1859-
bool GenericTransactionSignatureChecker<T>::CheckDefaultCheckTemplateVerifyHash(const std::span<const unsigned char>& hash) const
1899+
bool GenericTransactionSignatureChecker<T>::CheckDefaultCheckTemplateVerifyHash(const std::vector<unsigned char>& hash) const
18601900
{
18611901
// Should already be checked before calling...
18621902
assert(hash.size() == 32);
1863-
if (txdata && txdata->m_bip119_ctv_ready) {
1864-
assert(txTo != nullptr);
1865-
uint256 hash_tmpl = txdata->m_scriptSigs_single_hash.IsNull() ?
1866-
GetDefaultCheckTemplateVerifyHashEmptyScript(*txTo, txdata->m_outputs_single_hash, txdata->m_sequences_single_hash, nIn) :
1867-
GetDefaultCheckTemplateVerifyHashWithScript(*txTo, txdata->m_outputs_single_hash, txdata->m_sequences_single_hash,
1868-
txdata->m_scriptSigs_single_hash, nIn);
1869-
return std::equal(hash_tmpl.begin(), hash_tmpl.end(), hash.data());
1870-
} else {
1871-
return HandleMissingData(m_mdb);
1872-
}
1903+
assert(txTo != nullptr);
1904+
uint256 hash_tmpl = GetDefaultCheckTemplateVerifyHash(*txTo, nIn);
1905+
return std::equal(hash_tmpl.begin(), hash_tmpl.end(), hash.data());
18731906
}
18741907
// explicit instantiation
18751908
template class GenericTransactionSignatureChecker<CTransaction>;

src/script/interpreter.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,17 @@ struct PrecomputedTransactionData
209209
explicit PrecomputedTransactionData(const T& tx);
210210
};
211211

212+
/**
213+
* Compute the default template hash for OP_CHECKTEMPLATEVERIFY using some precomputed
214+
* hash inputs.
215+
*
216+
* (This exported interface is only used in tests.)
217+
*/
218+
template<typename TxType>
219+
uint256 GetDefaultCheckTemplateVerifyHash(
220+
const TxType& tx, const uint256& outputs_hash, const uint256& sequences_hash,
221+
const uint32_t input_index);
222+
212223
enum class SigVersion
213224
{
214225
BASE = 0, //!< Bare scripts and BIP16 P2SH-wrapped redeemscripts
@@ -287,9 +298,9 @@ class BaseSignatureChecker
287298
return false;
288299
}
289300

290-
virtual bool CheckDefaultCheckTemplateVerifyHash(const std::span<const unsigned char>& hash) const
301+
virtual bool CheckDefaultCheckTemplateVerifyHash(const std::vector<unsigned char>& hash) const
291302
{
292-
return false;
303+
return false;
293304
}
294305

295306
virtual ~BaseSignatureChecker() = default;
@@ -328,7 +339,7 @@ class GenericTransactionSignatureChecker : public BaseSignatureChecker
328339
bool CheckSchnorrSignature(Span<const unsigned char> sig, Span<const unsigned char> pubkey, SigVersion sigversion, ScriptExecutionData& execdata, ScriptError* serror = nullptr) const override;
329340
bool CheckLockTime(const CScriptNum& nLockTime) const override;
330341
bool CheckSequence(const CScriptNum& nSequence) const override;
331-
bool CheckDefaultCheckTemplateVerifyHash(const std::span<const unsigned char>& hash) const override;
342+
bool CheckDefaultCheckTemplateVerifyHash(const std::vector<unsigned char>& hash) const override;
332343
};
333344

334345
using TransactionSignatureChecker = GenericTransactionSignatureChecker<CTransaction>;

0 commit comments

Comments
 (0)