@@ -1564,8 +1564,35 @@ bool SignatureHashSchnorr(uint256& hash_out, ScriptExecutionData& execdata, cons
1564
1564
return true ;
1565
1565
}
1566
1566
1567
+ int SigHashCache::CacheIndex (int32_t hash_type) const noexcept
1568
+ {
1569
+ // Note that we do not distinguish between BASE and WITNESS_V0 to determine the cache index,
1570
+ // because no input can simultaneously use both.
1571
+ return 3 * !!(hash_type & SIGHASH_ANYONECANPAY) +
1572
+ 2 * ((hash_type & 0x1f ) == SIGHASH_SINGLE) +
1573
+ 1 * ((hash_type & 0x1f ) == SIGHASH_NONE);
1574
+ }
1575
+
1576
+ bool SigHashCache::Load (int32_t hash_type, const CScript& script_code, HashWriter& writer) const noexcept
1577
+ {
1578
+ auto & entry = m_cache_entries[CacheIndex (hash_type)];
1579
+ if (entry.has_value ()) {
1580
+ if (script_code == entry->first ) {
1581
+ writer = HashWriter (entry->second );
1582
+ return true ;
1583
+ }
1584
+ }
1585
+ return false ;
1586
+ }
1587
+
1588
+ void SigHashCache::Store (int32_t hash_type, const CScript& script_code, const HashWriter& writer) noexcept
1589
+ {
1590
+ auto & entry = m_cache_entries[CacheIndex (hash_type)];
1591
+ entry.emplace (script_code, writer);
1592
+ }
1593
+
1567
1594
template <class T >
1568
- uint256 SignatureHash (const CScript& scriptCode, const T& txTo, unsigned int nIn, int32_t nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache)
1595
+ uint256 SignatureHash (const CScript& scriptCode, const T& txTo, unsigned int nIn, int32_t nHashType, const CAmount& amount, SigVersion sigversion, const PrecomputedTransactionData* cache, SigHashCache* sighash_cache )
1569
1596
{
1570
1597
assert (nIn < txTo.vin .size ());
1571
1598
@@ -1581,6 +1608,13 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
1581
1608
1582
1609
HashWriter ss{};
1583
1610
1611
+ // Try to compute using cached SHA256 midstate.
1612
+ if (sighash_cache && sighash_cache->Load (nHashType, scriptCode, ss)) {
1613
+ // Add sighash type and hash.
1614
+ ss << nHashType;
1615
+ return ss.GetHash ();
1616
+ }
1617
+
1584
1618
if (sigversion == SigVersion::WITNESS_V0) {
1585
1619
uint256 hashPrevouts;
1586
1620
uint256 hashSequence;
@@ -1627,6 +1661,11 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
1627
1661
ss << txTmp;
1628
1662
}
1629
1663
1664
+ // If a cache object was provided, store the midstate there.
1665
+ if (sighash_cache != nullptr ) {
1666
+ sighash_cache->Store (nHashType, scriptCode, ss);
1667
+ }
1668
+
1630
1669
// Add sighash type and hash.
1631
1670
ss << nHashType;
1632
1671
return ss.GetHash ();
@@ -1661,7 +1700,7 @@ bool GenericTransactionSignatureChecker<T>::CheckECDSASignature(const std::vecto
1661
1700
// Witness sighashes need the amount.
1662
1701
if (sigversion == SigVersion::WITNESS_V0 && amount < 0 ) return HandleMissingData (m_mdb);
1663
1702
1664
- uint256 sighash = SignatureHash (scriptCode, *txTo, nIn, nHashType, amount, sigversion, this ->txdata );
1703
+ uint256 sighash = SignatureHash (scriptCode, *txTo, nIn, nHashType, amount, sigversion, this ->txdata , &m_sighash_cache );
1665
1704
1666
1705
if (!VerifyECDSASignature (vchSig, pubkey, sighash))
1667
1706
return false ;
0 commit comments