txscript: Optimize ExtractPkScriptAddrs nulldata.

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 nulldata scripts, removes
the slow path fallback code since it is the final case, and modifies the
comment to call out the script version semantics.

The following is a before and after comparison of analyzing both a
typical standard script and a very large non-standard script:

benchmark                            old ns/op    new ns/op    delta
-----------------------------------------------------------------------
BenchmarkExtractPkScriptAddrsLarge   132400       44.4         -99.97%
BenchmarkExtractPkScriptAddrs        1265         231          -81.74%

benchmark                            old allocs   new allocs   delta
-----------------------------------------------------------------------
BenchmarkExtractPkScriptAddrsLarge   1            0            -100.00%
BenchmarkExtractPkScriptAddrs        5            2            -60.00%

benchmark                            old bytes    new bytes    delta
-----------------------------------------------------------------------
BenchmarkExtractPkScriptAddrsLarge   466944       0            -100.00%
BenchmarkExtractPkScriptAddrs        1600         48           -97.00%
This commit is contained in:
Dave Collins 2019-03-13 01:12:38 -05:00 committed by Roy Lee
parent 8a4da7690d
commit 45bdd26ac3

View file

@ -843,11 +843,12 @@ func scriptHashToAddrs(hash []byte, params *chaincfg.Params) []btcutil.Address {
// signatures associated with the passed PkScript. Note that it only works for
// 'standard' transaction script types. Any data such as public keys which are
// invalid are omitted from the results.
//
// NOTE: This function only attempts to identify version 0 scripts. The return
// value will indicate a nonstandard script type for other script versions along
// with an invalid script version error.
func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (ScriptClass, []btcutil.Address, int, error) {
// Avoid parsing the script for the cases that already have the able to
// work with raw scripts.
// Check for pay-to-pubkey-hash script.
if hash := extractPubKeyHash(pkScript); hash != nil {
return PubKeyHashTy, pubKeyHashToAddrs(hash, chainParams), 1, nil
@ -883,6 +884,12 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
return MultiSigTy, addrs, details.requiredSigs, nil
}
// Check for null data script.
if isNullDataScript(scriptVersion, pkScript) {
// Null data transactions have no addresses or required signatures.
return NullDataTy, nil, 0, nil
}
// Fall back to slow path. Ultimately these are intended to be replaced by
// faster variants based on the unparsed raw scripts.
@ -924,15 +931,13 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
addrs = append(addrs, addr)
}
case NullDataTy:
// Null data transactions have no addresses or required
// signatures.
case NonStandardTy:
// Don't attempt to extract addresses or required signatures for
// nonstandard transactions.
}
// Don't attempt to extract addresses or required signatures for nonstandard
// transactions.
return scriptClass, addrs, requiredSigs, nil
}