From 507a4dcc005dea7bf3c1742498cd68de6977a9de Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:38 -0500 Subject: [PATCH] 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% --- txscript/standard.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index b187ac01..89c21966 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -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 }