Skip to content

Commit

Permalink
txscript: Optimize ExtractPkScriptAddrs multisig.
Browse files Browse the repository at this point in the history
This continues the process of converting the ExtractPkScriptAddrs
function to use the optimized extraction functions recently introduced
as part of the typeOfScript conversion.

In particular, this converts the detection for multisig scripts.

Also, since the remaining slow path cases are all recursive calls,
the parsed opcodes are no longer used, so parsing is removed.
  • Loading branch information
davecgh authored and cfromknecht committed Feb 5, 2021
1 parent 76a2d2b commit 05388db
Showing 1 changed file with 16 additions and 20 deletions.
36 changes: 16 additions & 20 deletions txscript/standard.go
Original file line number Diff line number Diff line change
Expand Up @@ -860,11 +860,27 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
return PubKeyTy, addrs, 1, nil
}

// Check for multi-signature script.
const scriptVersion = 0
details := extractMultisigScriptDetails(scriptVersion, pkScript, true)
if details.valid {
// Convert the public keys while skipping any that are invalid.
addrs := make([]btcutil.Address, 0, len(details.pubKeys))
for _, pubkey := range details.pubKeys {
addr, err := btcutil.NewAddressPubKey(pubkey, chainParams)
if err == nil {
addrs = append(addrs, addr)
}
}
return MultiSigTy, addrs, details.requiredSigs, nil
}

// Fall back to slow path. Ultimately these are intended to be replaced by
// faster variants based on the unparsed raw scripts.

var addrs []btcutil.Address
var requiredSigs int
var err error

// No valid addresses or required signatures if the script doesn't
// parse.
Expand All @@ -873,7 +889,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
return NonStandardTy, nil, 0, err
}

const scriptVersion = 0
scriptClass := typeOfScript(scriptVersion, pkScript)

switch scriptClass {
Expand Down Expand Up @@ -901,25 +916,6 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
addrs = append(addrs, addr)
}

case MultiSigTy:
// A multi-signature script is of the form:
// <numsigs> <pubkey> <pubkey> <pubkey>... <numpubkeys> OP_CHECKMULTISIG
// Therefore the number of required signatures is the 1st item
// on the stack and the number of public keys is the 2nd to last
// item on the stack.
requiredSigs = asSmallInt(pops[0].opcode.value)
numPubKeys := asSmallInt(pops[len(pops)-2].opcode.value)

// Extract the public keys while skipping any that are invalid.
addrs = make([]btcutil.Address, 0, numPubKeys)
for i := 0; i < numPubKeys; i++ {
addr, err := btcutil.NewAddressPubKey(pops[i+1].data,
chainParams)
if err == nil {
addrs = append(addrs, addr)
}
}

case NullDataTy:
// Null data transactions have no addresses or required
// signatures.
Expand Down

0 comments on commit 05388db

Please sign in to comment.