Commit graph

172 commits

Author SHA1 Message Date
Owain G. Ainsworth
8ec60d4678 Quick and dirty tests harnesses using some bitcoind test data.
Both the script tests (positive and negative) and tx texts (ditto) are
present.  Some of the tx tests in the negative section have been
replaced by a comment line explaining why that test is elided, to add in
diffing. The reasons were always that they test things handled by other
parts of the btcd stack (normally chain). For example MAX_MONEY, number
of outputs, coinbase sizes etc.

Much of the inital test logic from @dajohi using hand transcribed tables
for selected tests. The json parsers, script format parser and a lot of
cleaning up/bugfixing from your truly. @davecgh had some input too.
2014-03-19 01:06:19 +00:00
Owain G. Ainsworth
5f6de02eb8 use bytes.Repeat instead of my perlscript generated lists of zeros.
Pointed out by davec. I'd forgotten about it. Kills just over 10k lines
from the test file.
2014-03-19 00:43:21 +00:00
Owain G. Ainsworth
1b1fef7369 Make removeOpcodeByData only search canonical pushes.
Matches bitcoind behaviour. Pointed out by one of their tx_invalid tests.
2014-03-18 18:28:09 +00:00
Owain G. Ainsworth
76339baf6c Make removeOpcodeByData in line with bitcoind behaviour.
It should remove the opcode and data is the data is contained within the data
pushed, not just if it is equal to it. Found by bitcoind tx tests.
2014-03-18 00:49:24 +00:00
Owain G. Ainsworth
dab2a7cb0f Don't possibly dereference bad signatures in OP_CHECKMULTISIG.
We do all the preprocessing in one loop. Fixes a bug introduced a while ago to
handle invalid signatures. Found by more tests from bitcoind.
2014-03-17 17:46:56 +00:00
Dave Collins
c8332cc9a7 Correct num expected inputs calc for multisig.
This commit corrects the number of expected inputs for a multi-sig script
to include the additional item that is popped from the stack due to the
OP_CHECKMULTISIG consensus bug (which is required and properly performed).

Note this issue did NOT affect the consensus critical code and hence would
not cause a chain fork.  It did however, cause standard p2sh multisig txns
to be rejected from the mempool as nonstandard.

The tx rejected as non-standard which prompted this was spotted by
@mbelshe on IRC.

ok @owainga
2014-03-17 10:47:02 -05:00
Owain G. Ainsworth
9375c8dc48 move data extraction fof OP_PUSHDATA into main function.
This allows us to centralise the error checking to simplify things a bit.
2014-03-14 22:46:41 +00:00
Owain G. Ainsworth
02ee7762e4 AddData([]byte{}) is valid and should push empty to the stack.
Doing so is perfectly idiomatic.  Fixes the last of the valid bitcoind
script tests. (by fixing the script parser :)
2014-03-14 22:46:15 +00:00
Owain G. Ainsworth
299dcc2fad PushDataN with a 0 length is valid, we were too tight here.
Found by bitcoind positive tests. (but of course that is noncanonical
anyway, it should be OP_0 ;).
2014-03-14 22:46:14 +00:00
Owain G. Ainsworth
42f6576b02 Enforce max script length of 10000.
Detected by bitcoind negative script tests. Note that this length is only for
*executing* scripts, this is why it is in NewScript.
2014-03-14 22:45:14 +00:00
Owain G. Ainsworth
dec16d7ff2 Enforce a combined max stack depth of 1000 after every opcode.
This limit is for the sum of main and alt stacks. Found by bitcoind
negative tests.
2014-03-14 21:06:08 +00:00
Owain G. Ainsworth
d6d755e411 Always return reserved opcode for always-illegal ops. 2014-03-14 21:06:08 +00:00
Owain G. Ainsworth
8beb0dec54 Make opcode.Exec run a bunch of unconditional checks
Add push length and number of operations to this to match bitcoind behaviour.
found that we differed here by their negative tests.
2014-03-14 21:06:05 +00:00
Owain G. Ainsworth
f80c3255a3 PopInt now guarantees that number will be 32 bit.
So remove later checks that need this.
2014-03-14 21:05:29 +00:00
Owain G. Ainsworth
c7d5102954 Alt stack should be purged between scripts.
Found by bitcoind negative scripts.
2014-03-14 21:05:25 +00:00
Owain G. Ainsworth
a5e7e9ebb6 Disabled opcodes are `fail if pc passes' not fail if execute.
Detected by bitcoind negative tests.
2014-03-14 21:04:59 +00:00
Owain G. Ainsworth
c1a6e47f38 Conditionals must not straddle two scripts.
Found by tests dhill is working on. We checked that ifs were closed at the end
of execution but not at script switching time, we now move this to just after
finishing a single script.
2014-03-14 21:04:37 +00:00
Owain G. Ainsworth
8df0af32d6 Encountering OP_VERIF and OP_VERNOTIF in execution is always an error.
I honestly thought we already handled this, but some tests dhill is
working on shows that we didn't.
2014-03-14 20:28:23 +00:00
Owain G. Ainsworth
201d6651c9 Fix tests after IsForNet addition to btcutil.Address interface.
dhill pointed this out to me.
2014-03-13 17:20:45 +00:00
Dave Collins
da1fcc6dbd Tighten the check for pay-to-pubkey scripts.
This commit tightens the check for a pay-to-pubkey script by ensuring the
length of the pubkey is one of the two valid values of 33 or 65.  This
mirrors the checks in the multisig script type check as well.

ok @owainga
2014-02-21 12:18:43 -06:00
Dave Collins
982f282e10 Go fmt. 2014-02-21 02:10:38 -06:00
Owain G. Ainsworth
88f3c73ad1 Add MultiSigScript to provide a canonical script for a multisig transaction. 2014-02-21 00:20:24 +00:00
Owain G. Ainsworth
2b0b512a83 Add support for pay to pubkey addresses to PayToAddrScript
Based on some initial code from @davecgh, finished by me.
2014-02-20 19:26:34 +00:00
Owain G. Ainsworth
5171cb803c Convert builder.Push* to builder.Add* we think this is clearer.
Also, shorter!  Discussed with @davecgh.
2014-02-20 18:42:58 +00:00
Owain G. Ainsworth
1566366346 convert internal script generation to use ScriptBuilder.
Also, unexport the functions to generate script types. Everything should
(and is) be using PayToAddrScript() with an address type instead of
throwing bytes around.

discussed with #@davecgh
2014-02-20 17:52:46 +00:00
Dave Collins
cff7f9704b Fix a few comment typos. 2014-02-20 11:20:53 -06:00
Dave Collins
5a660e95f9 Add 100% test coverage for new ScriptBuilder code. 2014-02-20 02:47:52 -06:00
Dave Collins
50173b865b Allow push of 0 via new ScriptBuilder PushInt64.
Nothing was being pushed for 0 to the new ScriptBuilder due to the fact Go
big integers when set to 0 have no bytes.
2014-02-20 01:48:37 -06:00
David Hill
61d270957e Add HasCanonicalPushes
Closes #6.

ok @davecgh
2014-02-20 01:20:47 -06:00
Dave Collins
b8dc1b66e5 Add new ScriptBuilder for building custom scripts.
This commit adds a new ScriptBuilder interface that can be used to build
custom scripts.  It currently is fairly basic, but it allows you to push
raw opcodes, ints, and data while respecting canonical encoding.  These
primitives are sufficient to build any script.

This could be improved upon with quite a few things. One example would be
functions for certain opcodes that take properly typed parameters to make
it harder to create invalid scripts.

For now though, it is already quite useful since it handles all of the
opcode selection for canonical data pushes and integer encoding.

The initial discussion took place in #5.
2014-02-20 01:02:57 -06:00
Dave Collins
a6cdb8b844 Add tests for multisig with zero required sigs. 2014-02-19 16:52:11 -06:00
Dave Collins
37a45ec683 Allow multi-sig scripts with zero signatures.
This commit builds off the previous commit which fixed the execution of
multi-signature scripts with zero required signatures.

It introduces the concept of a "small int" which is one of OP_0 or OP_1 -
OP_16.  All areas of code that deal with multi-sig transactions now make
use of these to ensure consistent handling.

This fixes a few issues surrounding multi-sig zero required signature
transactions included proper detection as a multi-sig script, signature
counting for script statistics, and

ok @owainga
2014-02-19 16:34:50 -06:00
Dave Collins
1d360509f4 Correct handling for multi-sig zero signatures.
It is possible for a multisignature transaction to require zero
signatures.  For example, input 2 of testnet transaction
b2d93dfd0b2c1a380e55e76a8d9cb3075dec9f4474e9485be008c337fd62c1f7
in block number 185117.

Previously the code was pushing a false to the stack when no
valid signatures were found.  This commit remedies that by pushing true
when no valid signatures were found, but none are required.  Otherwise it
still pushes false when no valid signatures were found, but some are
required.

Fixes #7.

ok @owainga
2014-02-19 15:03:32 -06:00
Dave Collins
fcd73f75ea Correct log trace for failed script execution.
The function needs to be wrapped by a newLogClosure for the logger to be
able to log it.
2014-02-19 13:22:33 -06:00
David Hill
971fbf8b28 gofmt 2014-02-04 16:18:37 -05:00
Dave Collins
13ba8607f7 Gofmt. 2014-02-04 11:22:51 -06:00
Owain G. Ainsworth
e8881196d6 Fix a number of bugs in signature checking
When given badly formatted  signature or pubkeys like in block
0000000000000001e4241fd0b3469a713f41c5682605451c05d3033288fb2244, transaction
fd9b541d23f6e9bddb34ede15c7684eeec36231118796b691ae525f95578acf1 we could fail
on strange scripts because we returned an error instead of failing the
opcode and putting a FALSE on the stack.

Fixes chainfork issue on the aforementioned block.
2014-02-04 03:13:23 +00:00
Dave Collins
b11f1620e2 Remove warnings for errors that are returned.
ok @owainga.
2014-01-17 09:40:34 -06:00
Dave Collins
565f11409c Add 2014 to copyright dates. 2014-01-08 23:47:47 -06:00
Dave Collins
e50681264b Add 100% test coverage for ExtractPkScriptAddrs. 2014-01-07 18:09:48 -06:00
Dave Collins
6c8003b064 Refactor and improve address extraction code.
This commit significantly changes the address extraction code.  The
original code was written before some of the other newer code was written
and as a result essentially duplicated some of the logic for handling
standard scripts which is used elsewhere in the package.

The following is a summary of what has changed:

- CalcPkScriptAddrHashes, ScriptToAddrHash, and ScriptToAddrHashes have
  been replaced by ExtractPkScriptAddresses
- The ScriptType type has been removed in favor of the existing
  ScriptClass type
- The new function returns a slice of btcutil.Addresses instead of raw
  hashes that the caller then needs to figure out what to do with to
  convert them to proper addressses
- The new function makes use of the existing ScriptClass instead of an
  nearly duplicate ScriptType
- The new function hooks into the existing infrastructure for parsing
  scripts and identifying scripts of standard forms
- The new function only works with pkscripts to match the behavior of the
  reference implementation - do note that the redeeming script from a p2sh
  script is still considered a pkscript
- The logic combines extraction for all script types instead of using a
  separate function for multi-signature transactions
- The new function ignores addresses which are invalid for some reason
  such as invalid public keys
2014-01-07 17:48:18 -06:00
Dave Collins
126991b60b Make opcode disasm names match reference impl.
This commit modifies the names of opcdoes shown in the oneline script
disassembly to match the reference implementation.  In particular
OP_1NEGATE, and OP_0 through OP_16 are changed to the raw numbers
they represent when doing oneline disassembly.  When doing full
disassembly, the full opcode names are still shown.

ok @owainga.
2014-01-07 12:07:54 -06:00
Dave Collins
e2f14e2cfa Fix comment typo. 2014-01-06 12:14:43 -06:00
Dave Collins
2005fae908 Change OP_CHECK_MULTISIG -> OP_CHECKMULTISIG.
This change was made to match the reference implementation.
2014-01-04 15:23:51 -06:00
Dave Collins
b713590902 Group the StackErrX definitions.
This improves the godoc display and provides a cleaner separation of the
error definitions from other variables.
2014-01-04 09:58:22 -06:00
Dave Collins
eb4fc19b95 Modify DisasmString to return partial disassembly.
Rather than returning an empty string from DisasmString if a script fails
to parse, return the disassembly up to the point of the failure along with
[error] appended.  The error is still returned in case the caller wants
more information about the script parse failure.
2014-01-03 18:47:00 -06:00
Dave Collins
814c920c96 Add tests for new payment script creation funcs. 2014-01-03 13:42:22 -06:00
Dave Collins
3d60bac238 Add new funcs for creating payment scripts.
This commit adds two new functions named PayToScriptHashScript and
PayToAddrScript.  The first one creates and returns a public-key script
which pays to the provided script hash and conforms to BIP0016.

The second function takes the new btcutil.Address interface type and
returns an appropriate script to pay to the address type in the interface.
It currently works for btcutil.AddressPubKeyHash and
btcutil.AddressScriptHash.
2014-01-03 13:35:51 -06:00
Francis Lam
3a8ec0078b Added another multisig test with compressed pubkey 2014-01-02 13:50:22 -05:00
Francis Lam
3f52f559eb Added tests for multisig scripts and fixed comments
Fixed up bad function comment headers

Added a small set of tests for the ScriptToAddrHashes function to test
functionality of a couple real multisig cases as well as error checking
2014-01-02 13:31:00 -05:00