Commit Graph

13 Commits

Author SHA1 Message Date
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
Olaoluwa Osuntokun
98cae74275 BIP0143+txscript: add segwit sighash, signing, and HashCache integration
This commit implements most of BIP0143 by adding logic to implement the
new sighash calculation, signing, and additionally introduces the
HashCache optimization which eliminates the O(N^2) computational
complexity for the SIGHASH_ALL sighash type.

The HashCache struct is the equivalent to the existing SigCache struct,
but for caching the reusable midstate for transactions which are
spending segwitty outputs.
2017-08-13 23:17:40 -05:00
Dave Collins
f6ad7eb2c9
wire: Make NewMsgTx accept the tx version.
This modifies the NewMsgTx function to accept the transaction version as
a parameter and updates all callers.

The reason for this change is so the transaction version can be bumped
in wire without breaking existing tests and to provide the caller with
the flexibility to create the specific transaction version they desire.
2016-10-27 14:09:29 -05:00
Dave Collins
bd4e64d1d4 chainhash: Abstract hash logic to new package. (#729)
This is mostly a backport of some of the same modifications made in
Decred along with a few additional things cleaned up.  In particular,
this updates the code to make use of the new chainhash package.

Also, since this required API changes anyways and the hash algorithm is
no longer tied specifically to SHA, all other functions throughout the
code base which had "Sha" in their name have been changed to Hash so
they are not incorrectly implying the hash algorithm.

The following is an overview of the changes:

- Remove the wire.ShaHash type
- Update all references to wire.ShaHash to the new chainhash.Hash type
- Rename the following functions and update all references:
  - wire.BlockHeader.BlockSha -> BlockHash
  - wire.MsgBlock.BlockSha -> BlockHash
  - wire.MsgBlock.TxShas -> TxHashes
  - wire.MsgTx.TxSha -> TxHash
  - blockchain.ShaHashToBig -> HashToBig
  - peer.ShaFunc -> peer.HashFunc
- Rename all variables that included sha in their name to include hash
  instead
- Update for function name changes in other dependent packages such as
  btcutil
- Update copyright dates on all modified files
- Update glide.lock file to use the required version of btcutil
2016-08-08 14:04:33 -05:00
Olaoluwa Osuntokun
0029905d43 Integrate a valid ECDSA signature cache into btcd
Introduce an ECDSA signature verification into btcd in order to
mitigate a certain DoS attack and as a performance optimization.

The benefits of SigCache are two fold. Firstly, usage of SigCache
mitigates a DoS attack wherein an attacker causes a victim's client to
hang due to worst-case behavior triggered while processing attacker
crafted invalid transactions. A detailed description of the mitigated
DoS attack can be found here: https://bitslog.wordpress.com/2013/01/23/fixed-bitcoin-vulnerability-explanation-why-the-signature-cache-is-a-dos-protection/
Secondly, usage of the SigCache introduces a signature verification
optimization which speeds up the validation of transactions within a
block, if they've already been seen and verified within the mempool.

The server itself manages the sigCache instance. The blockManager and
txMempool respectively now receive pointers to the created sigCache
instance. All read (sig triplet existence) operations on the sigCache
will not block unless a separate goroutine is adding an entry (writing)
to the sigCache. GetBlockTemplate generation now also utilizes the
sigCache in order to avoid unnecessarily double checking signatures
when generating a template after previously accepting a txn to the
mempool. Consequently, the CPU miner now also employs the same
optimization.

The maximum number of entries for the sigCache has been introduced as a
config parameter in order to allow users to configure the amount of
memory consumed by this new additional caching.
2015-10-08 17:31:42 -07:00
Dave Collins
6e402deb35 Relicense to the btcsuite developers.
This commit relicenses all code in this repository to the btcsuite
developers.
2015-05-01 12:00:56 -05:00
Dave Collins
8dd7412a84 txscript: Rename Script to Engine.
This commit renames the Script type to Engine to better reflect its
purpose.  It also renames the NewScript function to NewEngine to match.

This is being done because name Script for the engine is confusing since
it implies it is an actual script rather than the execution environment
for the script.  It also paves the way for eventually supplying a
ParsedScript type which will be less likely to be confused with the
execution environment.

While moving the code, some additional variable names and comments have
been updated to better match the style used throughout the rest of the
code base.  In addition, an attempt has been made to use consistent naming
of the engine as 'vm' instead of using different variables names as it was
previously.

Finally, the relevant engine code has been moved into a new file named
engine.go and related tests moved to engine_test.go.
2015-04-20 15:31:23 -05:00
Dave Collins
bec90e253c txscript: Remove unneeded param from NewScript.
This commit removes the unnecessary sigScript parameter from the
txscript.NewScript function.  This has bothered me for a while because it
can and really should be obtained from the provided transaction and input
index.  The way it was, the passed script could technically be different
than what is in the transaction.  Obviously that would be an improper use
of the API, but it's safer and more convenient to simply pull it from the
provided transaction and index.

Also, since the function signature is changing anyways, make the input
index parameter come after the transaction which it references.
2015-04-20 13:46:11 -05:00
Dave Collins
a4a52ae24f wire: Remove errs from BlockHeader/MsgBlock/MsgTx.
This commit removes the error returns from the BlockHeader.BlockSha,
MsgBlock.BlockSha, and MsgTx.TxSha functions since they can never fail and
end up causing a lot of unneeded error checking throughout the code base.

It also updates all call sites for the change.
2015-04-17 01:27:12 -05:00
David Hill
f79c72f18a txscript: Remove ScriptCanonicalSignatures
Remove ScriptCanonicalSignatures and use the new
ScriptVerifyDERSignatures flag.  The ScriptVerifyDERSignatures
flag accomplishes the same functionality.
2015-02-23 22:04:15 -05:00
Dave Collins
f82f7b6663 txscript: Add example for manully signing a txout.
This commit adds a new example to the txscript package that demonstrates
creating a new transaction which redeems funds and signing the referenced
transaction output the SignTxOutput function.
2015-02-09 13:07:56 -06:00
Dave Collins
c6bc8ac1eb Update btcnet path import paths to new location. 2015-02-05 23:24:53 -06:00
Dave Collins
cbda064842 Import btcscript repo into txscript directory.
This commit contains the entire btcscript repository along with several
changes needed to move all of the files into the txscript directory in
order to prepare it for merging.  This does NOT update btcd or any of the
other packages to use the new location as that will be done separately.

- All import paths in the old btcscript test files have been changed to the
  new location
- All references to btcscript as the package name have been chagned to
  txscript

This is ongoing work toward #214.
2015-01-30 10:30:16 -06:00