WIP: next hard fork #5

Draft
BrannonKing wants to merge 178 commits from WIP-HF-2022 into master
Showing only changes of commit a4a21c0b08 - Show all commits

View file

@ -864,44 +864,44 @@ func finalOpcodeData(scriptVersion uint16, script []byte) []byte {
// Pay-To-Script-Hash script in order to find the precise number of signature // Pay-To-Script-Hash script in order to find the precise number of signature
// operations in the transaction. If the script fails to parse, then the count // operations in the transaction. If the script fails to parse, then the count
// up to the point of failure is returned. // up to the point of failure is returned.
func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) int { //
// Don't check error since parseScript returns the parsed-up-to-error // WARNING: This function always treats the passed script as version 0. Great
// list of pops. // care must be taken if introducing a new script version because it is used in
pops, _ := parseScript(scriptPubKey) // consensus which, unfortunately as of the time of this writing, does not check
// script versions before counting their signature operations which means nodes
// on existing rules will count new version scripts as if they were version 0.
//
// The third parameter is DEPRECATED and is unused.
func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, _ bool) int {
const scriptVersion = 0
// Treat non P2SH transactions as normal. // Treat non P2SH transactions as normal. Note that signature operation
if !(bip16 && isScriptHash(pops)) { // counting includes all operations up to the first parse failure.
return getSigOpCount(pops, true) if !isScriptHashScript(scriptPubKey) {
} return countSigOpsV0(scriptPubKey, true)
// The public key script is a pay-to-script-hash, so parse the signature
// script to get the final item. Scripts that fail to fully parse count
// as 0 signature operations.
sigPops, err := parseScript(scriptSig)
if err != nil {
return 0
} }
// The signature script must only push data to the stack for P2SH to be // The signature script must only push data to the stack for P2SH to be
// a valid pair, so the signature operation count is 0 when that is not // a valid pair, so the signature operation count is 0 when that is not
// the case. // the case.
if !isPushOnly(sigPops) || len(sigPops) == 0 { if len(scriptSig) == 0 || !IsPushOnlyScript(scriptSig) {
return 0 return 0
} }
// The P2SH script is the last item the signature script pushes to the // The P2SH script is the last item the signature script pushes to the
// stack. When the script is empty, there are no signature operations. // stack. When the script is empty, there are no signature operations.
shScript := sigPops[len(sigPops)-1].data //
if len(shScript) == 0 { // Notice that signature scripts that fail to fully parse count as 0
// signature operations unlike public key and redeem scripts.
redeemScript := finalOpcodeData(scriptVersion, scriptSig)
if len(redeemScript) == 0 {
return 0 return 0
} }
// Parse the P2SH script and don't check the error since parseScript // Return the more precise sigops count for the redeem script. Note that
// returns the parsed-up-to-error list of pops and the consensus rules // signature operation counting includes all operations up to the first
// dictate signature operations are counted up to the first parse // parse failure.
// failure. return countSigOpsV0(redeemScript, true)
shPops, _ := parseScript(shScript)
return getSigOpCount(shPops, true)
} }
// GetWitnessSigOpCount returns the number of signature operations generated by // GetWitnessSigOpCount returns the number of signature operations generated by