txscript: Optimize CalcMultiSigStats.
This converts the CalcMultiSigStats function to make use of the new extractMultisigScriptDetails function instead of the far less efficient parseScript thereby significantly optimizing the function. The tests are also updated accordingly. The following is a before and after comparison of analyzing a standard multisig script: benchmark old ns/op new ns/op delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 972 79.5 -91.82% benchmark old allocs new allocs delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 1 0 -100.00% benchmark old bytes new bytes delta --------------------------------------------------------------- BenchmarkCalcMultiSigStats 2304 0 -100.00%
This commit is contained in:
parent
ea7b0e3816
commit
e0cafeb4ca
2 changed files with 12 additions and 22 deletions
|
@ -656,27 +656,21 @@ func CalcScriptInfo(sigScript, pkScript []byte, witness wire.TxWitness,
|
||||||
// CalcMultiSigStats returns the number of public keys and signatures from
|
// CalcMultiSigStats returns the number of public keys and signatures from
|
||||||
// a multi-signature transaction script. The passed script MUST already be
|
// a multi-signature transaction script. The passed script MUST already be
|
||||||
// known to be a multi-signature script.
|
// known to be a multi-signature script.
|
||||||
|
//
|
||||||
|
// NOTE: This function is only valid for version 0 scripts. Since the function
|
||||||
|
// does not accept a script version, the results are undefined for other script
|
||||||
|
// versions.
|
||||||
func CalcMultiSigStats(script []byte) (int, int, error) {
|
func CalcMultiSigStats(script []byte) (int, int, error) {
|
||||||
pops, err := parseScript(script)
|
// The public keys are not needed here, so pass false to avoid the extra
|
||||||
if err != nil {
|
// allocation.
|
||||||
return 0, 0, err
|
const scriptVersion = 0
|
||||||
}
|
details := extractMultisigScriptDetails(scriptVersion, script, false)
|
||||||
|
if !details.valid {
|
||||||
// A multi-signature script is of the pattern:
|
|
||||||
// NUM_SIGS PUBKEY PUBKEY PUBKEY... NUM_PUBKEYS OP_CHECKMULTISIG
|
|
||||||
// Therefore the number of signatures is the oldest item on the stack
|
|
||||||
// and the number of pubkeys is the 2nd to last. Also, the absolute
|
|
||||||
// minimum for a multi-signature script is 1 pubkey, so at least 4
|
|
||||||
// items must be on the stack per:
|
|
||||||
// OP_1 PUBKEY OP_1 OP_CHECKMULTISIG
|
|
||||||
if len(pops) < 4 {
|
|
||||||
str := fmt.Sprintf("script %x is not a multisig script", script)
|
str := fmt.Sprintf("script %x is not a multisig script", script)
|
||||||
return 0, 0, scriptError(ErrNotMultisigScript, str)
|
return 0, 0, scriptError(ErrNotMultisigScript, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
numSigs := asSmallInt(pops[0].opcode.value)
|
return details.numPubKeys, details.requiredSigs, nil
|
||||||
numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value)
|
|
||||||
return numPubKeys, numSigs, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// payToPubKeyHashScript creates a new script to pay a transaction
|
// payToPubKeyHashScript creates a new script to pay a transaction
|
||||||
|
|
|
@ -832,7 +832,7 @@ func TestCalcMultiSigStats(t *testing.T) {
|
||||||
name: "short script",
|
name: "short script",
|
||||||
script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" +
|
script: "0x046708afdb0fe5548271967f1a67130b7105cd6a828" +
|
||||||
"e03909a67962e0ea1f61d",
|
"e03909a67962e0ea1f61d",
|
||||||
err: scriptError(ErrMalformedPush, ""),
|
err: scriptError(ErrNotMultisigScript, ""),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "stack underflow",
|
name: "stack underflow",
|
||||||
|
@ -843,11 +843,7 @@ func TestCalcMultiSigStats(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "multisig script",
|
name: "multisig script",
|
||||||
script: "0 DATA_72 0x30450220106a3e4ef0b51b764a2887226" +
|
script: "1 DATA_33 0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" +
|
||||||
"2ffef55846514dacbdcbbdd652c849d395b4384022100" +
|
|
||||||
"e03ae554c3cbb40600d31dd46fc33f25e47bf8525b1fe" +
|
|
||||||
"07282e3b6ecb5f3bb2801 CODESEPARATOR 1 DATA_33 " +
|
|
||||||
"0x0232abdc893e7f0631364d7fd01cb33d24da45329a0" +
|
|
||||||
"0357b3a7886211ab414d55a 1 CHECKMULTISIG",
|
"0357b3a7886211ab414d55a 1 CHECKMULTISIG",
|
||||||
err: nil,
|
err: nil,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue