From 0a4f228dd10296da4c06484577112bf0411e7fff Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Wed, 13 Mar 2019 01:12:19 -0500 Subject: [PATCH] txscript: Optimize PushedData. This converts the PushedData function to make use of the new tokenizer instead of the far less efficient parseScript thereby significantly optimizing the function. Also, the comment is modified to explicitly call out the script version semantics. The following is a before and after comparison of extracting the data from a very large script: benchmark old ns/op new ns/op delta BenchmarkPushedData-8 64837 1790 -97.24% benchmark old allocs new allocs delta BenchmarkPushedData-8 7 6 -14.29% benchmark old bytes new bytes delta BenchmarkPushedData-8 312816 1520 -99.51% --- txscript/standard.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/txscript/standard.go b/txscript/standard.go index 3bb12b9a..0607b305 100644 --- a/txscript/standard.go +++ b/txscript/standard.go @@ -791,20 +791,25 @@ func MultiSigScript(pubkeys []*btcutil.AddressPubKey, nrequired int) ([]byte, er // PushedData returns an array of byte slices containing any pushed data found // in the passed script. This includes OP_0, but not OP_1 - OP_16. +// +// 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 PushedData(script []byte) ([][]byte, error) { - pops, err := parseScript(script) - if err != nil { - return nil, err - } + const scriptVersion = 0 var data [][]byte - for _, pop := range pops { - if pop.data != nil { - data = append(data, pop.data) - } else if pop.opcode.value == OP_0 { + tokenizer := MakeScriptTokenizer(scriptVersion, script) + for tokenizer.Next() { + if tokenizer.Data() != nil { + data = append(data, tokenizer.Data()) + } else if tokenizer.Opcode() == OP_0 { data = append(data, nil) } } + if err := tokenizer.Err(); err != nil { + return nil, err + } return data, nil }