Commit graph

14 commits

Author SHA1 Message Date
Dave Collins
e4118c914f
txscript: Add benchmark for IsNullData 2021-11-16 18:46:21 -08:00
Conner Fromknecht
728ce1001d
txscript: Add benchmark for IsPayToWitnessScriptHash 2021-11-16 18:46:16 -08:00
Conner Fromknecht
e422d42d7f
txscript: Add benchmark IsPayToWitnessPubkeyHash 2021-11-16 18:46:11 -08:00
Dave Collins
ce1513df03
txscript: Add benchmark for IsPushOnlyScript. 2021-11-16 18:46:06 -08:00
Dave Collins
02dab1695f
txscript: Add benchmarks for IsMutlsigSigScript. 2021-11-16 18:46:01 -08:00
Dave Collins
4d31d1599d
txscript: Add benchmarks for IsMutlsigScript. 2021-11-16 18:45:57 -08:00
Dave Collins
665c29802e
txscript: Add benchmark for IsPayToScriptHash. 2021-11-16 18:45:52 -08:00
Conner Fromknecht
2d2608c34e
txscript: Add benchmark for IsPayToPubKeyHash 2021-11-16 18:45:47 -08:00
Dave Collins
05aa488a87
txscript: Add benchmark for IsPayToPubKey 2021-11-16 18:45:43 -08:00
Dave Collins
099784267e
txscript: Add benchmark for DisasmString. 2021-11-16 18:45:24 -08:00
Dave Collins
c997417978
txscript: Introduce zero-alloc script tokenizer.
This implements an efficient and zero-allocation script tokenizer that
is exported to both provide a new capability to tokenize scripts to
external consumers of the API as well as to serve as a base for
refactoring the existing highly inefficient internal code.

It is important to note that this tokenizer is intended to be used in
consensus critical code in the future, so it must exactly follow the
existing semantics.

The current script parsing mechanism used throughout the txscript module
is to fully tokenize the scripts into an array of internal parsed
opcodes which are then examined and passed around in order to implement
virtually everything related to scripts.

While that approach does simplify the analysis of certain scripts and
thus provide some nice properties in that regard, it is both extremely
inefficient in many cases, and makes it impossible for external
consumers of the API to implement any form of custom script analysis
without manually implementing a bunch of error prone tokenizing code or,
alternatively, the script engine exposing internal structures.

For example, as shown by profiling the total memory allocations of an
initial sync, the existing script parsing code allocates a total of
around 295.12GB, which equates to around 50% of all allocations
performed.  The zero-alloc tokenizer this introduces will allow that to
be reduced to virtually zero.

The following is a before and after comparison of tokenizing a large
script with a high opcode count using the existing code versus the
tokenizer this introduces for both speed and memory allocations:

benchmark                    old ns/op     new ns/op     delta
BenchmarkScriptParsing-8     63464         677           -98.93%

benchmark                    old allocs     new allocs     delta
BenchmarkScriptParsing-8     1              0              -100.00%

benchmark                    old bytes     new bytes     delta
BenchmarkScriptParsing-8     311299        0             -100.00%

The following is an overview of the changes:

- Introduce new error code ErrUnsupportedScriptVersion
- Implement zero-allocation script tokenizer
- Add a full suite of tests to ensure the tokenizer works as intended
  and follows the required consensus semantics
- Add an example of using the new tokenizer to count the number of
  opcodes in a script
- Update README.md to include the new example
- Update script parsing benchmark to use the new tokenizer
2021-11-16 18:45:22 -08:00
Dave Collins
bcb9643d39
txscript: Add benchmark for script parsing. 2021-11-16 18:45:19 -08:00
Conner Fromknecht
47806df63d
txscript: Add benchmark for CalcWitnessSigHash 2021-11-16 18:45:16 -08:00
Dave Collins
843d7607ef
txscript: Add benchmark for CalcSignatureHash 2021-11-16 18:45:14 -08:00