script: (refactor) prepare for introducing sighash midstate cache

This commit is contained in:
Pieter Wuille
2025-04-25 13:11:30 -04:00
parent 9014d4016a
commit 8f3ddb0bcc

View File

@@ -1569,6 +1569,18 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
{ {
assert(nIn < txTo.vin.size()); assert(nIn < txTo.vin.size());
if (sigversion != SigVersion::WITNESS_V0) {
// Check for invalid use of SIGHASH_SINGLE
if ((nHashType & 0x1f) == SIGHASH_SINGLE) {
if (nIn >= txTo.vout.size()) {
// nOut out of range
return uint256::ONE;
}
}
}
HashWriter ss{};
if (sigversion == SigVersion::WITNESS_V0) { if (sigversion == SigVersion::WITNESS_V0) {
uint256 hashPrevouts; uint256 hashPrevouts;
uint256 hashSequence; uint256 hashSequence;
@@ -1583,16 +1595,14 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
hashSequence = cacheready ? cache->hashSequence : SHA256Uint256(GetSequencesSHA256(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 : SHA256Uint256(GetOutputsSHA256(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()) {
HashWriter ss{}; HashWriter inner_ss{};
ss << txTo.vout[nIn]; inner_ss << txTo.vout[nIn];
hashOutputs = ss.GetHash(); hashOutputs = inner_ss.GetHash();
} }
HashWriter ss{};
// Version // Version
ss << txTo.version; ss << txTo.version;
// Input prevouts/nSequence (none/all, depending on flags) // Input prevouts/nSequence (none/all, depending on flags)
@@ -1609,26 +1619,16 @@ uint256 SignatureHash(const CScript& scriptCode, const T& txTo, unsigned int nIn
ss << hashOutputs; ss << hashOutputs;
// Locktime // Locktime
ss << txTo.nLockTime; ss << txTo.nLockTime;
// Sighash type } else {
ss << nHashType; // Wrapper to serialize only the necessary parts of the transaction being signed
CTransactionSignatureSerializer<T> txTmp(txTo, scriptCode, nIn, nHashType);
return ss.GetHash(); // Serialize
ss << txTmp;
} }
// Check for invalid use of SIGHASH_SINGLE // Add sighash type and hash.
if ((nHashType & 0x1f) == SIGHASH_SINGLE) { ss << nHashType;
if (nIn >= txTo.vout.size()) {
// nOut out of range
return uint256::ONE;
}
}
// Wrapper to serialize only the necessary parts of the transaction being signed
CTransactionSignatureSerializer<T> txTmp(txTo, scriptCode, nIn, nHashType);
// Serialize and hash
HashWriter ss{};
ss << txTmp << nHashType;
return ss.GetHash(); return ss.GetHash();
} }