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 Olaoluwa Osuntokun
parent 0bc18254d4
commit 507a4dcc00
No known key found for this signature in database
GPG key ID: 3BBD59E99B280306

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 // signatures associated with the passed PkScript. Note that it only works for
// 'standard' transaction script types. Any data such as public keys which are // 'standard' transaction script types. Any data such as public keys which are
// invalid are omitted from the results. // 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) { 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. // Check for pay-to-pubkey-hash script.
if hash := extractPubKeyHash(pkScript); hash != nil { if hash := extractPubKeyHash(pkScript); hash != nil {
return PubKeyHashTy, pubKeyHashToAddrs(hash, chainParams), 1, 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 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 // Fall back to slow path. Ultimately these are intended to be replaced by
// faster variants based on the unparsed raw scripts. // faster variants based on the unparsed raw scripts.
@ -924,15 +931,13 @@ func ExtractPkScriptAddrs(pkScript []byte, chainParams *chaincfg.Params) (Script
addrs = append(addrs, addr) addrs = append(addrs, addr)
} }
case NullDataTy:
// Null data transactions have no addresses or required
// signatures.
case NonStandardTy: case NonStandardTy:
// Don't attempt to extract addresses or required signatures for // Don't attempt to extract addresses or required signatures for
// nonstandard transactions. // nonstandard transactions.
} }
// Don't attempt to extract addresses or required signatures for nonstandard
// transactions.
return scriptClass, addrs, requiredSigs, nil return scriptClass, addrs, requiredSigs, nil
} }