This converts SignTxOutput and supporting funcs, namely sign,
mergeScripts and mergeMultiSig, to make use of the new tokenizer as well
as some recently added funcs that deal with raw scripts in order to
remove the reliance on parsed opcodes as a step towards utlimately
removing them altogether and updates the comments to explicitly call out
the script version semantics.
It is worth noting that this has the side effect of optimizing the
function as well, however, since this change is not focused on the
optimization aspects, no benchmarks are provided.
This moves the function definition for mergeMultiSig so it is more
consistent with the preferred order used through the codebase. In
particular, the functions are defined before they're first used and
generally as close as possible to the first use when they're defined in
the same file.
This completes the process of converting the ExtractPkScriptAddr
function to use the optimized extraction functions recently introduced
as part of the typeOfScript conversion.
In particular, this cleans up the final remaining case for non-standard
transactions. The method now returns NonStandardTy direclty if no other
branch was taken.
The following is a before and after comparison of attempting to extract
pkscript addrs from a very large, non-standard script.
benchmark old ns/op new ns/op delta
BenchmarkExtractPkScriptAddrsLarge-8 60713 17.0 -99.97%
BenchmarkExtractPkScriptAddrs-8 289 17.0 -94.12%
benchmark old allocs new allocs delta
BenchmarkExtractPkScriptAddrsLarge-8 1 0 -100.00%
BenchmarkExtractPkScriptAddrs-8 1 0 -100.00%
benchmark old bytes new bytes delta
BenchmarkExtractPkScriptAddrsLarge-8 311299 0 -100.00%
BenchmarkExtractPkScriptAddrs-8 768 0 -100.00%
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 extract of witness-pay-to-script-hash
scripts.
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 extraction for witness-pubkey-hash
scripts.
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 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.
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 pay-to-pubkey scripts.
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 pay-to-pubkey-hash
scripts.
This begins the process of converting the ExtractPkScriptAddrs function
to use the optimized extraction functions recently introduced as part of
the typeOfScript conversion.
In order to ease the review process, the detection of each script type
will be converted in a separate commit such that the script is only
parsed as a fallback for the cases that are not already converted to
more efficient variants.
In particular, this converts the detection for pay-to-script-hash
scripts.
This converts the ExtractAtomicSwapDataPushes function to make use of
the new tokenizer instead of the far less efficient parseScript thereby
significantly optimizing the function.
The new implementation is designed such that it should be fairly easy to
move the function into the atomic swap tools where it more naturally
belongs now that the tokenizer makes it possible to analyze scripts
outside of the txscript module. Consequently, this also deprecates the
function.
The following is a before and after comparison of attempting to extract
from both a typical atomic swap script and a very large non-atomic swap
script:
benchmark old ns/op new ns/op delta
BenchmarkExtractAtomicSwapDataPushesLarge-8 61332 44.4 -99.93%
BenchmarkExtractAtomicSwapDataPushes-8 990 260 -73.74%
benchmark old allocs new allocs delta
BenchmarkExtractAtomicSwapDataPushesLarge-8 1 0 -100.00%
BenchmarkExtractAtomicSwapDataPushes-8 2 1 -50.00%
benchmark old bytes new bytes delta
BenchmarkExtractAtomicSwapDataPushesLarge-8 311299 0 -100.00%
BenchmarkExtractAtomicSwapDataPushes-8 3168 96 -96.97%
This renames the canonicalPush function to isCanonicalPush and converts
it to accept an opcode as a byte and the associate data as a byte slice
instead of the internal parse opcode data struct in order to make it
more flexible for raw script analysis.
It also updates all callers and tests accordingly.
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%
This converts the CalcMultiSigStats function to make use of the new
extractMultisigScriptDetails function instead of the far less efficient
parseScript thereby significantly optimizing the function.
The tests are also updated accordingly.
The following is a before and after comparison of analyzing a standard
multisig script:
benchmark old ns/op new ns/op delta
---------------------------------------------------------------
BenchmarkCalcMultiSigStats 972 79.5 -91.82%
benchmark old allocs new allocs delta
---------------------------------------------------------------
BenchmarkCalcMultiSigStats 1 0 -100.00%
benchmark old bytes new bytes delta
---------------------------------------------------------------
BenchmarkCalcMultiSigStats 2304 0 -100.00%
This converts CalcScriptInfo and dependent expectedInputs to make use of
the new script tokenizer as well as several of the other recently added
raw script analysis functions in order to remove the reliance on parsed
opcodes as a step towards utlimately removing them altogether.
It is worth noting that this has the side effect of significantly
optimizing the function as well, however, since it is deprecated, no
benchmarks are provided.
This concludes the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.
In particular, it converts the detection of witness script hash scripts
to use raw script analysis and the new tokenizer.
With all of the limbs now useing optimized variants, the following is a
before an after comparison of calling GetScriptClass on a large script:
benchmark old ns/op new ns/op delta
BenchmarkGetScriptClass-8 61515 15.3 -99.98%
benchmark old allocs new allocs delta
BenchmarkGetScriptClass-8 1 0 -100.00%
benchmark old bytes new bytes delta
BenchmarkGetScriptClass-8 311299 0 -100.00%
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.
In particular, it converts the detection of witness pubkey hash scripts
to use raw script analysis and the new tokenizer.
The following is a before and after comparison of analyzing a large
script:
benchmark old ns/op new ns/op delta
BenchmarkIsWitnessPubKeyHash-8 61688 62839 +1.87%
benchmark old allocs new allocs delta
BenchmarkIsWitnessPubKeyHash-8 1 1 +0.00%
benchmark old bytes new bytes delta
BenchmarkIsWitnessPubKeyHash-8 311299 311299 +0.00%
This continues the process of converting the typeOfScript function to
use a combination of raw script analysize and the tokenizer instead of
parsed opcode, with the intent of significanty optimizing the function.
In particular, it converts the detection of null data scripts to use raw
script analysis.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.
In particular, it converts the detection of pay-to-pubkey-hash scripts
to use raw script analysis.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the face less efficient parsed opcodes, with the intent of
significantly optimizing the function.
In particular, it converts the detection of pay-to-pubkey scripts to use
raw script analysis.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.
In particular, for this commit, since the ability to detect multisig
scripts via the new tokenizer is now available, the function is simply
updated to make use of it.
This begins the process of converting the typeOfScript function to use a
combination of raw script analysis and the new tokenizer instead of the
far less efficient parsed opcodes with the intent of significantly
optimizing the function.
In order to ease the review process, each script type will be converted
in a separate commit and the typeOfScript function will be updated such
that the script is only parsed as a fallback for the cases that are not
already converted to more efficient raw script variants.
In particular, for this commit, since the ability to detect
pay-to-script-hash via raw script analysis is now available, the
function is simply updated to make use of it.
This converts the typeOfScript function to accept a script version and
raw script instead of an array of internal parsed opcodes in order to
make it more flexible for raw script analysis.
Also, this adds a comment to CalcScriptInfo to call out the specific
version semantics and deprecates the function since nothing currently
uses it, and the relevant information can now be obtained by callers
more directly through the use of the new script tokenizer.
All other callers are updated accordingly.
This converts the GetWitnessSigOpCount function to use a combination of
raw script analysis and the new tokenizer instead of the far less
efficeint parseScript, thereby significantly optimizing the funciton.
In particular, it use the recently added countSigOpsv0 in precise mode
to avoid calling paseScript.
This converts the GetPreciseSigOpCount function to use a combination of
raw script analysis and the new tokenizer instead of the far less
efficient parseScript thereby significantly optimizing the function.
In particular it uses the recently converted isScriptHashScript,
IsPushOnlyScript, and countSigOpsV0 functions along with the recently
added finalOpcodeData functions.
It also modifies the comment to explicitly call out the script version
semantics.
The following is a before and after comparison of analyzing a large
script:
benchmark old ns/op new ns/op delta
BenchmarkGetPreciseSigOpCount-8 130223 742 -99.43%
benchmark old allocs new allocs delta
BenchmarkGetPreciseSigOpCount-8 3 0 -100.00%
benchmark old bytes new bytes delta
BenchmarkGetPreciseSigOpCount-8 623367 0 -100.00%
This converts the GetSigOpCount function to make use of the new
tokenizer instead of the far less efficient parseScript thereby
significantly optimizing the function.
A new function named countSigOpsV0 which accepts the raw script is
introduced to perform the bulk of the work so it can be reused for
precise signature operation counting as well in a later commit. It
retains the same semantics in terms of counting the number of signature
operations either up to the first parse error or the end of the script
in the case it parses successfully as required by consensus.
Finally, this also deprecates the getSigOpCount function that requires
opcodes in favor of the new function and modifies the comment on
GetSigOpCount to explicitly call out the script version semantics.
The following is a before and after comparison of analyzing a large
script:
benchmark old ns/op new ns/op delta
BenchmarkGetSigOpCount-8 61051 677 -98.89%
benchmark old allocs new allocs delta
BenchmarkGetSigOpCount-8 1 0 -100.00%
benchmark old bytes new bytes delta
BenchmarkGetSigOpCount-8 311299 0 -100.00%
This moves the check for non push-only pay-to-script-hash signature
scripts before the script parsing logic when creating a new engine
instance to avoid the extra overhead in the error case.