Refactor Get{Prevout,Sequence,Outputs}Hash to Get{Prevouts,Sequences,Outputs}SHA256.

Several proposals (Taproot, MuHash, CTV) require access to the single
hash.
This commit is contained in:
Jeremy Rubin 2020-02-05 12:31:20 -08:00
parent 6510d0ff41
commit 9ab4cafabd

View File

@ -1258,34 +1258,37 @@ public:
} }
}; };
/** Compute the (single) SHA256 of the concatenation of all prevouts of a tx. */
template <class T> template <class T>
uint256 GetPrevoutHash(const T& txTo) uint256 GetPrevoutsSHA256(const T& txTo)
{ {
CHashWriter ss(SER_GETHASH, 0); CHashWriter ss(SER_GETHASH, 0);
for (const auto& txin : txTo.vin) { for (const auto& txin : txTo.vin) {
ss << txin.prevout; ss << txin.prevout;
} }
return ss.GetHash(); return ss.GetSHA256();
} }
/** Compute the (single) SHA256 of the concatenation of all nSequences of a tx. */
template <class T> template <class T>
uint256 GetSequenceHash(const T& txTo) uint256 GetSequencesSHA256(const T& txTo)
{ {
CHashWriter ss(SER_GETHASH, 0); CHashWriter ss(SER_GETHASH, 0);
for (const auto& txin : txTo.vin) { for (const auto& txin : txTo.vin) {
ss << txin.nSequence; ss << txin.nSequence;
} }
return ss.GetHash(); return ss.GetSHA256();
} }
/** Compute the (single) SHA256 of the concatenation of all txouts of a tx. */
template <class T> template <class T>
uint256 GetOutputsHash(const T& txTo) uint256 GetOutputsSHA256(const T& txTo)
{ {
CHashWriter ss(SER_GETHASH, 0); CHashWriter ss(SER_GETHASH, 0);
for (const auto& txout : txTo.vout) { for (const auto& txout : txTo.vout) {
ss << txout; ss << txout;
} }
return ss.GetHash(); return ss.GetSHA256();
} }
} // namespace } // namespace
@ -1297,9 +1300,9 @@ void PrecomputedTransactionData::Init(const T& txTo)
// Cache is calculated only for transactions with witness // Cache is calculated only for transactions with witness
if (txTo.HasWitness()) { if (txTo.HasWitness()) {
hashPrevouts = GetPrevoutHash(txTo); hashPrevouts = SHA256Uint256(GetPrevoutsSHA256(txTo));
hashSequence = GetSequenceHash(txTo); hashSequence = SHA256Uint256(GetSequencesSHA256(txTo));
hashOutputs = GetOutputsHash(txTo); hashOutputs = SHA256Uint256(GetOutputsSHA256(txTo));
} }
m_ready = true; m_ready = true;
@ -1329,16 +1332,16 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
const bool cacheready = cache && cache->m_ready; const bool cacheready = cache && cache->m_ready;
if (!(nHashType & SIGHASH_ANYONECANPAY)) { if (!(nHashType & SIGHASH_ANYONECANPAY)) {
hashPrevouts = cacheready ? cache->hashPrevouts : GetPrevoutHash(txTo); hashPrevouts = cacheready ? cache->hashPrevouts : SHA256Uint256(GetPrevoutsSHA256(txTo));
} }
if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { if (!(nHashType & SIGHASH_ANYONECANPAY) && (nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
hashSequence = cacheready ? cache->hashSequence : GetSequenceHash(txTo); hashSequence = cacheready ? cache->hashSequence : SHA256Uint256(GetSequencesSHA256(txTo));
} }
if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) { if ((nHashType & 0x1f) != SIGHASH_SINGLE && (nHashType & 0x1f) != SIGHASH_NONE) {
hashOutputs = cacheready ? cache->hashOutputs : GetOutputsHash(txTo); hashOutputs = cacheready ? cache->hashOutputs : SHA256Uint256(GetOutputsSHA256(txTo));
} else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) { } else if ((nHashType & 0x1f) == SIGHASH_SINGLE && nIn < txTo.vout.size()) {
CHashWriter ss(SER_GETHASH, 0); CHashWriter ss(SER_GETHASH, 0);
ss << txTo.vout[nIn]; ss << txTo.vout[nIn];