Commit graph

52 commits

Author SHA1 Message Date
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
David Hill ce22159fb2 txscript: Change makeScriptNum to take a length argument
While current existing numeric opcodes are limited to 4 bytes, new
opcodes may need different limits.

This mimics Bitcoin Core commit 99088d60d8a7747c6d1a7fd5d8cd388be1b3e138
2015-10-05 19:48:55 -04:00
Dave Collins 064cc8e7c3 txscript: Optimize DisasmString function.
This commit modifies the DisasmString function to use a bytes buffer for
constructing the disassembled string instead of naive string
concatenation.  This makes a huge difference when disassembling scripts
with large numbers of opcodes.
2015-09-28 12:57:53 -05:00
Jonathan Gillham 27f7f82355 txscript: Make error strings idiomatic. 2015-08-09 14:06:36 +01:00
David Hill 3331d6098b txscript: New function IsUnspendable
IsUnspendable takes a public key script and returns whether it is
spendable.

Additionally, hook this into the mempool isDust function, since
unspendable outputs can't be spent.

This mimics Bitcoin Core commit 0aad1f13b2430165062bf9436036c1222a8724da
2015-08-03 10:10:23 -04:00
Jonathan Gillham b448a2b6bc Make PubKey variable names consistent. 2015-08-02 22:21:27 +01:00
Jonathan Gillham f8167ab36f txscript: Remove unneeded signature hash copies
These copies were likely left over from when MsgTx had no deep copy
functionality.
2015-07-28 11:31:43 +01:00
Bruno 4335ce828c switch maxDataCarrierSize to public const 2015-07-20 14:26:05 +08:00
Jonathan Gillham 8fcea82a56 Fixed erroneous txscript.KeyClosure documentation. 2015-07-19 16:15:29 +01:00
David Hill 9ffd96bf51 Revert "Move IsFinalizedTransaction to txscript."
This reverts commit 17da2ba7fa.

This was done prematurely.  This will be revisited when a code
restructure is more urgent.
2015-06-29 11:12:35 -04:00
David Hill 17da2ba7fa Move IsFinalizedTransaction to txscript.
This change moves IsFinalizedTransaction to txscript and also changes
the first argument to take a wire.MsgTx instead of btcutil.Tx.  This
is needed for an upcoming diff in which txscript will require
IsFinalizedTransaction and we do not want to import the btcd/blockchain.
2015-06-28 09:43:14 -04:00
David Hill 527f585463 txscript: Move lockTimeThreshold to txscript
Move lockTimeThreshold to txscript and export it.  This is a
consensus value which txscript will need in an upcoming diff.
2015-06-26 10:55:22 -04:00
Dave Collins edc0d15882 txscript: Consensus audit.
This commit contains fixes from the results of a thorough audit of
txscript to find any cases of script evaluation which doesn't match the
required consensus behavior.  These conditions are fairly obscure and
highly unlikely to happen in any real scripts, but they could have
nevertheless been used by a clever attacker with malicious intent to
cause a fork.

Test cases which exercise these conditions have been added to the
reference tests and will contributed upstream to improve the quality for
the entire ecosystem.
2015-05-06 09:41:50 -05:00
Dave Collins f284b9b394 txscript: Match Bitcoin Core OP_IFDUP behavior.
Unlike OP_IF and OP_NOTIF which interpret the top stack item as a
number, OP_IFDUP interprets it as a boolean.  This has important
consequences because numbers are imited to int32s while booleans can be
an arbitrary number of bytes.

The offending script was found and reported by Jonas Nick through the
use of fuzzing.
2015-05-05 15:06:20 -05:00
Dave Collins 927a0e9c37 txscript: Test consistency and cleanup.
- Move reference tests to test package since they are intended to
  exercise the engine as callers would
- Improve the short form script parsing to allow additional opcodes:
  DATA_#, OP_#, FALSE, TRUE
- Make use of a function to decode hex strings rather than manually
  defining byte slices
- Update the tests to make use of the short form script parsing logic
  rather than manually defining byte slices
- Consistently replace all []byte{} and [][]byte{} with nil
- Define tests only used in a specific function inside that func
- Move invalid flag combination test to engine_test since that is what
  it is testing
- Remove all redundant script tests in favor of the JSON-based tests in
  the data directory.
- Move several functions from internal_test.go to the test files
  associated with what the tests are checking
2015-05-04 16:04:29 -05:00
Dave Collins 005b540895 txscript: Separate code for standard scripts.
This commit moves all code related to standard scripts into a separate
file named standard.go as well as the associated tests into
standard_test.go.  Since the code in address.go and address_test.go is
only related to standard scripts, it has been combined into the new
files and the old files deleted.

The intent here is to make it clear that the code in standard.go is not
related to consensus.
2015-05-01 15:20:48 -05:00
Dave Collins b6e52fbd93 txscript: Convert to new scriptnum type.
This commit implements a new type, named scriptNum, for handling all
numeric values used in scripts and converts the code over to make use of
it.  This is being done for a few of reasons.

First, the consensus rules for handling numeric values in the scripts
require special handling with subtle semantics.  By encapsulating those
details into a type specifically dedicated to that purpose, it
simplifies the code and generally helps prevent improper usage.

Second, the new type is quite a bit more efficient than big.Ints which
are designed to be arbitrarily large and thus involve a lot of heap
allocations and additional multi-precision bookkeeping.  Because this
new type is based on an int64, it allows the numbers to be stack
allocated thereby eliminating a lot of GC and also eliminates the extra
multi-precision arithmetic bookkeeping.

The use of an int64 is possible because the consensus rules dictate that
when data is interpreted as a number, it is limited to an int32 even
though results outside of this range are allowed so long as they are not
interpreted as integers again themselves.   Thus, the maximum possible
result comes from multiplying a max int32 by itself which safely fits
into an int64 and can then still appropriately provide the serialization
of the larger number as required by consensus.

Finally, it more closely resembles the implementation used by Bitcoin
Core and thus makes is easier to compare the behavior between the two
implementations.

This commit also includes a full suite of tests with 100% coverage of
the semantics of the new type.
2015-05-01 13:15:08 -05: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 a8fe1ad5fe txscript: Code consistency and doco improvements.
This commit contains a lot of cleanup on the txscript code to make it
more consistent with the code throughout the rest of the project.  It
doesn't change any operational logic.

The following is an overview of the changes:

- Add a significant number of comments throughout in order to better
  explain what the code is doing
- Fix several comment typos
- Move a couple of constants only used by the engine to engine.go
- Move a variable only used by the engine to engine.go
- Fix a couple of format specifiers in the test prints
- Reorder functions so they're defined before/closer to use
- Make the code lint clean with the exception of the opcode definitions
2015-04-29 13:16:22 -05:00
Dave Collins 8ef68dcc6e txscript: Cleanup and improve opcode tests.
- Remove all redundant opcode tests in favor of the JSON-based tests
  in the data directory.
- Remove duplicate stack nip test
- Add new tests to data/script_invalid.json to exercise additional
  negative error paths
- Remove old unneeded pubkey trace code from opcodeCheckSig
- Simplify and improve the disassembly print function
- Add new tests to directly test all individual opcode disassembly
- Add new tests to directly test opcode disabled function which does not
  get invoked during ordinary execution
- Improve test coverage of opcode.go
2015-04-28 03:19:00 -05:00
Dave Collins 2e433b0eb3 txscript: Move opcode execution logic to engine
This commit moves the opcode execution logic from the opcode type to the
engine type because execution of an opcode modifies the engine state
(primarily the main and alternate data stacks) as opposed to the state
of the opcode.  Making the engine the receiver more clearly indicates
this fact.
2015-04-27 14:35:41 -05:00
Dave Collins c701477eaf txscript: Slight crypto hash optimizations.
This commit very slightly optimizes the cryptographic hashing performed
by the script opcodes by calling the hash sum routines directly (for
those that support it) rather than allocating a new generic hash.Hash
hasher instance for them.
2015-04-27 12:32:32 -05:00
Dave Collins 7411e65b1e txscript: Unexport Stack type.
This commit unexports the Stack type since it is only intended to be
used internally during script execution.  Further, the engine exposes
the {G,S}etStack and {G,S}etAltStack functions which return the items as
a slice of byte slices ([][]byte) for caller access while stepping.
2015-04-25 17:10:53 -05:00
Dave Collins d6105893af txscript: Improve conditional stack.
This commit improves the way the conditional execution stack is handled in
a few ways.

First, the current execution state is now pushed onto the end of the slice
rather than the front of it.  This has been done because it results in
fewer allocations and is therefore more efficient.

Second, the need for allocating and setting an initial true in the
conditional stack has been eliminated.  The vast majority of scripts don't
contain any conditionals, so there is no reason to allocate a slice when
it isn't needed.

Third, a new function has been added to the engine to determine if the
current conditional branch is executing named isBranchExecuting which
handles the fact the conditional execution stack can now be empty and
improves the readability of the code.

Finally, it removes a couple of TODOs which I have verified do not apply.
2015-04-23 02:45:27 -05:00
Dave Collins d66593bbfd txscript: Add exported opcode name to value map.
This commit exports a new map named OpcodeByName which can be used to
lookup an opcode value given a human-readable opcode name.

It also modifies the test function which does short form parsing to use
the new map instead of the internal array.

Closes #267.
2015-04-21 14:02:30 -05:00
Dave Collins d251208f1f txscript: Convert opcode map to an array.
This commit converts the opcode map to an array to improve performance.

Benchmark of executing a standard p2pk transaction:

New: BenchmarkExecute            2000            784349 ns/op
Old: BenchmarkExecute            2000            792600 ns/op

The time is dominated by the signature checking as expected, however there
is still an increase in speed.
2015-04-21 13:56:05 -05:00
Dave Collins d6f2b092c0 txscript: Define opcodes in hex and sync BC opcodes.
This commit modifies the definition of the opcodes to their hex
counterparts rather than decimal since it is far more common to see
scripts in hex.  This makes it easier when manually looking at script
dumps to correlate opcodes.  However, since there are also cases where it
is useful to see the decimal value of the opcode, the decimal value has
been left as a comment.  Obviously converting the numbers is trivial, but
it is handy when looking at the opcode definitions to already have it
there.

In addition, it syncs the opcodes with the latest Bitcoin Core internal
opcodes for completeness and modifies the tests accordingly.
2015-04-21 13:51:02 -05:00
Dave Collins 0baac03129 txscript: Store flags in instance versus bools.
Rather than storing a separate bool for whether or not each flag is set in
every script engine instance, store the flags and check if the relevant
flag is set from each specific location.

This reduces the memory needed by each script engine instance and means
future flags will not require new fields.
2015-04-21 13:49:25 -05:00
Dave Collins 43c053bbfe txscript: Move error definitions to error.go.
This is more consistent with the rest of the code base and also will make
it easier to improve the errors to provide more details at a later date.
2015-04-21 13:33:08 -05:00
Dave Collins 3fc2444309 txscript: Separate signing code.
This commit separate the transaction signing code into sign.go and the
related tests into sign_test.go.
2015-04-20 17:00:23 -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 0f8d90086a txscript: Separate reference tests into own file.
This commit separates the test functions and associated helper functions
which are used to execute the reference transaction and script tests from
Bitcoin Core into a separate file named reference_test.go.

Also, add a few comments and fix a couple of typos along the way.
2015-04-20 14:22:22 -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 abe74f1d4e txscript: sync Bitcoin Core tests.
From Bitcoin Core commit 437ada3e55df8ae6f801cb2aa2e79ec5bb5f1971
2015-04-09 12:24:12 -04:00
David Hill 369b352452 txscript: Add new flag ScriptVerifyLowS
The ScriptVerifyLowS flag defines that script signatures must
comply with the DER format as well as have an S value less than
or equal to the half order.
2015-03-14 13:40:03 -04:00
David Hill 9523345814 txscript: Add new flag ScriptVerifyCleanStack
The ScriptVerifyCleanStack flag requires that only a single
stack element remains after evaluation and that when interpreted
as a bool, it must be true.  This is BIP0062, rule 6.

This mimics Bitcoin Core commit b6e03cc59208305681745ad06f2056ffe6690597
2015-03-13 15:54:17 -04:00
David Hill 436fb8203c txscript: Increase maximum allowed nulldata bytes
This change increases the maximum allowed bytes allowed in pushed
data to be considered a nulldata transaction.  This matches the current
value the reference implementation uses by default.
2015-03-09 23:40:46 -04:00
Dave Collins a765bbff5a Update golang.org/x/crypto import paths to new location. 2015-03-03 21:10:38 -06:00
David Hill d9cba7ca6a txscript: export StandardVerifyFlags
By exporting StandardVerifyFlags, clients can ensure they create
transactions that btcd will accept into its mempool.

This flag doesn't belong in txscript.  It belongs in a
policy package.  However, this is currently the least worse place.
2015-02-26 15:21:12 -05:00
David Hill ff747f8eae Use ScriptVerifyMinimalData
Additionally, drop HasCanoncialPushes as ScriptVerifyMinimalData
offers more complete checks.
2015-02-26 13:13:16 -05:00
David Hill b3342510b7 txscript: sync Bitcoin Core tests. 2015-02-25 12:44:15 -05:00
David Hill 5a4312d9ca txscript: Add new flag ScriptVerifyMinimalData
The ScriptVerifyMinimalData enforces that all push operations use the
minimal data push required.  This is part of BIP0062.

This commit mimics Bitcoin Core commit
698c6abb25c1fbbc7fa4ba46b60e9f17d97332ef
2015-02-24 18:06:20 -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
David Hill 761381066d txscript: Add new verification flags.
This commit adds two new verification flags to txscript named
ScriptVerifyStrictEncoding and ScriptVerifyDerSignatures.

The ScriptVerifyStrictEncoding flag enforces signature scripts
and public keys to follow the strict encoding requirements.

The ScriptVerifyDerSignatures flag enforces signature scripts
to follow the strict encoding requirements.

These flags mimic Bitcoin Core's SCRIPT_VERIFY_STRICTENC and
SCRIPT_VERIFY_DERSIG flags and brings the Bitcoin Core test scripts up
to date.
2015-02-12 12:27:44 -05:00
Dave Collins a8a26aabb6 txscript: Correct OP_CHECKMULTSIG handling.
This commit corrects a case in the OP_CHECKMULTISIG handling where it was
possible to improperly validate a transaction that had a combination of
valid and malformed signatures.

It also adds a new test to ensure this case is properly handled and nukes
a superfluous comment.

Fixes #293.
2015-02-10 05:07:15 -06: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
Josh Rickmar 45dfa1a9cd txscript: Remove excessive error check. 2015-02-08 21:26:16 -05:00
Dave Collins e7c7c3399f Update btcec path import paths to new location. 2015-02-06 10:54:32 -06:00
Dave Collins c6bc8ac1eb Update btcnet path import paths to new location. 2015-02-05 23:24:53 -06:00