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
This commit is contained in:
Dave Collins 2015-05-02 14:56:55 -05:00
parent 9a658c2689
commit 927a0e9c37
9 changed files with 4626 additions and 6500 deletions

View file

@ -54,7 +54,7 @@ func TestBadPC(t *testing.T) {
TxOut: []*wire.TxOut{ TxOut: []*wire.TxOut{
{ {
Value: 1000000000, Value: 1000000000,
PkScript: []byte{}, PkScript: nil,
}, },
}, },
LockTime: 0, LockTime: 0,
@ -114,7 +114,7 @@ func TestCheckErrorCondition(t *testing.T) {
TxOut: []*wire.TxOut{ TxOut: []*wire.TxOut{
{ {
Value: 1000000000, Value: 1000000000,
PkScript: []byte{}, PkScript: nil,
}, },
}, },
LockTime: 0, LockTime: 0,
@ -171,3 +171,284 @@ func TestCheckErrorCondition(t *testing.T) {
t.Errorf("unexpected error %v on final check", err) t.Errorf("unexpected error %v on final check", err)
} }
} }
// TestInvalidFlagCombinations ensures the script engine returns the expected
// error when disallowed flag combinations are specified.
func TestInvalidFlagCombinations(t *testing.T) {
t.Parallel()
tests := []txscript.ScriptFlags{
txscript.ScriptVerifyCleanStack,
}
// tx with almost empty scripts.
tx := &wire.MsgTx{
Version: 1,
TxIn: []*wire.TxIn{
{
PreviousOutPoint: wire.OutPoint{
Hash: wire.ShaHash([32]byte{
0xc9, 0x97, 0xa5, 0xe5,
0x6e, 0x10, 0x41, 0x02,
0xfa, 0x20, 0x9c, 0x6a,
0x85, 0x2d, 0xd9, 0x06,
0x60, 0xa2, 0x0b, 0x2d,
0x9c, 0x35, 0x24, 0x23,
0xed, 0xce, 0x25, 0x85,
0x7f, 0xcd, 0x37, 0x04,
}),
Index: 0,
},
SignatureScript: []uint8{txscript.OP_NOP},
Sequence: 4294967295,
},
},
TxOut: []*wire.TxOut{
{
Value: 1000000000,
PkScript: nil,
},
},
LockTime: 0,
}
pkScript := []byte{txscript.OP_NOP}
for i, test := range tests {
_, err := txscript.NewEngine(pkScript, tx, 0, test)
if err != txscript.ErrInvalidFlags {
t.Fatalf("TestInvalidFlagCombinations #%d unexpected "+
"error: %v", i, err)
}
}
}
// TestCheckPubKeyEncoding ensures the internal checkPubKeyEncoding function
// works as expected.
func TestCheckPubKeyEncoding(t *testing.T) {
t.Parallel()
tests := []struct {
name string
key []byte
isValid bool
}{
{
name: "uncompressed ok",
key: decodeHex("0411db93e1dcdb8a016b49840f8c53bc1eb68" +
"a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf" +
"9744464f82e160bfa9b8b64f9d4c03f999b8643f656b" +
"412a3"),
isValid: true,
},
{
name: "compressed ok",
key: decodeHex("02ce0b14fb842b1ba549fdd675c98075f12e9" +
"c510f8ef52bd021a9a1f4809d3b4d"),
isValid: true,
},
{
name: "compressed ok",
key: decodeHex("032689c7c2dab13309fb143e0e8fe39634252" +
"1887e976690b6b47f5b2a4b7d448e"),
isValid: true,
},
{
name: "hybrid",
key: decodeHex("0679be667ef9dcbbac55a06295ce870b07029" +
"bfcdb2dce28d959f2815b16f81798483ada7726a3c46" +
"55da4fbfc0e1108a8fd17b448a68554199c47d08ffb1" +
"0d4b8"),
isValid: false,
},
{
name: "empty",
key: nil,
isValid: false,
},
}
flags := txscript.ScriptVerifyStrictEncoding
for _, test := range tests {
err := txscript.TstCheckPubKeyEncoding(test.key, flags)
if err != nil && test.isValid {
t.Errorf("checkSignatureEncoding test '%s' failed "+
"when it should have succeeded: %v", test.name,
err)
} else if err == nil && !test.isValid {
t.Errorf("checkSignatureEncooding test '%s' succeeded "+
"when it should have failed", test.name)
}
}
}
// TestCheckSignatureEncoding ensures the internal checkSignatureEncoding
// function works as expected.
func TestCheckSignatureEncoding(t *testing.T) {
t.Parallel()
tests := []struct {
name string
sig []byte
isValid bool
}{
{
name: "valid signature",
sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: true,
},
{
name: "empty.",
sig: nil,
isValid: false,
},
{
name: "bad magic",
sig: decodeHex("314402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "bad 1st int marker magic",
sig: decodeHex("304403204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "bad 2nd int marker",
sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41032018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "short len",
sig: decodeHex("304302204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "long len",
sig: decodeHex("304502204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "long X",
sig: decodeHex("304402424e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "long Y",
sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022118152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "short Y",
sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41021918152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "trailing crap",
sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d0901"),
isValid: false,
},
{
name: "X == N ",
sig: decodeHex("30440220fffffffffffffffffffffffffffff" +
"ffebaaedce6af48a03bbfd25e8cd0364141022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "X == N ",
sig: decodeHex("30440220fffffffffffffffffffffffffffff" +
"ffebaaedce6af48a03bbfd25e8cd0364142022018152" +
"2ec8eca07de4860a4acdd12909d831cc56cbbac46220" +
"82221a8768d1d09"),
isValid: false,
},
{
name: "Y == N",
sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd410220fffff" +
"ffffffffffffffffffffffffffebaaedce6af48a03bb" +
"fd25e8cd0364141"),
isValid: false,
},
{
name: "Y > N",
sig: decodeHex("304402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd410220fffff" +
"ffffffffffffffffffffffffffebaaedce6af48a03bb" +
"fd25e8cd0364142"),
isValid: false,
},
{
name: "0 len X",
sig: decodeHex("302402000220181522ec8eca07de4860a4acd" +
"d12909d831cc56cbbac4622082221a8768d1d09"),
isValid: false,
},
{
name: "0 len Y",
sig: decodeHex("302402204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd410200"),
isValid: false,
},
{
name: "extra R padding",
sig: decodeHex("30450221004e45e16932b8af514961a1d3a1a" +
"25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181" +
"522ec8eca07de4860a4acdd12909d831cc56cbbac462" +
"2082221a8768d1d09"),
isValid: false,
},
{
name: "extra S padding",
sig: decodeHex("304502204e45e16932b8af514961a1d3a1a25" +
"fdf3f4f7732e9d624c6c61548ab5fb8cd41022100181" +
"522ec8eca07de4860a4acdd12909d831cc56cbbac462" +
"2082221a8768d1d09"),
isValid: false,
},
}
flags := txscript.ScriptVerifyStrictEncoding
for _, test := range tests {
err := txscript.TstCheckSignatureEncoding(test.sig, flags)
if err != nil && test.isValid {
t.Errorf("checkSignatureEncoding test '%s' failed "+
"when it should have succeeded: %v", test.name,
err)
} else if err == nil && !test.isValid {
t.Errorf("checkSignatureEncooding test '%s' succeeded "+
"when it should have failed", test.name)
}
}
}

View file

@ -2,6 +2,13 @@
// Use of this source code is governed by an ISC // Use of this source code is governed by an ISC
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
/*
This test file is part of the txscript package rather than than the
txscript_test package so it can bridge access to the internals to properly test
cases which are either not possible or can't reliably be tested via the public
interface. The functions are only exported while the tests are being run.
*/
package txscript package txscript
import "testing" import "testing"
@ -18,339 +25,37 @@ var TstHasCanonicalPushes = canonicalPush
// test package. // test package.
var TstParseScript = parseScript var TstParseScript = parseScript
// this file is present to export some internal interfaces so that we can // TstConcatRawScript makes the ability to add the pass script directly to
// test them reliably. // an existing script to the test package. This differs from AddData since it
// doesn't add a push data opcode.
func TestCheckPubKeyEncoding(t *testing.T) { func (b *ScriptBuilder) TstConcatRawScript(data []byte) *ScriptBuilder {
t.Parallel() if b.err != nil {
return b
tests := []struct {
name string
key []byte
isValid bool
}{
{
name: "uncompressed ok",
key: []byte{0x04, 0x11, 0xdb, 0x93, 0xe1, 0xdc, 0xdb, 0x8a,
0x01, 0x6b, 0x49, 0x84, 0x0f, 0x8c, 0x53, 0xbc, 0x1e,
0xb6, 0x8a, 0x38, 0x2e, 0x97, 0xb1, 0x48, 0x2e, 0xca,
0xd7, 0xb1, 0x48, 0xa6, 0x90, 0x9a, 0x5c, 0xb2, 0xe0,
0xea, 0xdd, 0xfb, 0x84, 0xcc, 0xf9, 0x74, 0x44, 0x64,
0xf8, 0x2e, 0x16, 0x0b, 0xfa, 0x9b, 0x8b, 0x64, 0xf9,
0xd4, 0xc0, 0x3f, 0x99, 0x9b, 0x86, 0x43, 0xf6, 0x56,
0xb4, 0x12, 0xa3,
},
isValid: true,
},
{
name: "compressed ok",
key: []byte{0x02, 0xce, 0x0b, 0x14, 0xfb, 0x84, 0x2b, 0x1b,
0xa5, 0x49, 0xfd, 0xd6, 0x75, 0xc9, 0x80, 0x75, 0xf1,
0x2e, 0x9c, 0x51, 0x0f, 0x8e, 0xf5, 0x2b, 0xd0, 0x21,
0xa9, 0xa1, 0xf4, 0x80, 0x9d, 0x3b, 0x4d,
},
isValid: true,
},
{
name: "compressed ok",
key: []byte{0x03, 0x26, 0x89, 0xc7, 0xc2, 0xda, 0xb1, 0x33,
0x09, 0xfb, 0x14, 0x3e, 0x0e, 0x8f, 0xe3, 0x96, 0x34,
0x25, 0x21, 0x88, 0x7e, 0x97, 0x66, 0x90, 0xb6, 0xb4,
0x7f, 0x5b, 0x2a, 0x4b, 0x7d, 0x44, 0x8e,
},
isValid: true,
},
{
name: "hybrid",
key: []byte{0x06, 0x79, 0xbe, 0x66, 0x7e, 0xf9, 0xdc, 0xbb,
0xac, 0x55, 0xa0, 0x62, 0x95, 0xce, 0x87, 0x0b, 0x07,
0x02, 0x9b, 0xfc, 0xdb, 0x2d, 0xce, 0x28, 0xd9, 0x59,
0xf2, 0x81, 0x5b, 0x16, 0xf8, 0x17, 0x98, 0x48, 0x3a,
0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb,
0xfc, 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48,
0xa6, 0x85, 0x54, 0x19, 0x9c, 0x47, 0xd0, 0x8f, 0xfb,
0x10, 0xd4, 0xb8,
},
isValid: false,
},
{
name: "empty.",
key: []byte{},
isValid: false,
},
}
vm := Engine{flags: ScriptVerifyStrictEncoding}
for _, test := range tests {
err := vm.checkPubKeyEncoding(test.key)
if err != nil && test.isValid {
t.Errorf("checkSignatureEncoding test '%s' failed "+
"when it should have succeeded: %v", test.name,
err)
} else if err == nil && !test.isValid {
t.Errorf("checkSignatureEncooding test '%s' succeeded "+
"when it should have failed", test.name)
}
} }
b.script = append(b.script, data...)
return b
} }
func TestCheckSignatureEncoding(t *testing.T) { // TstCheckPubKeyEncoding makes the internal checkPubKeyEncoding function
t.Parallel() // available to the test package. Since it only really needs from the engine
// for the flags, just accept the flags and create a new engine skeleton.
tests := []struct { func TstCheckPubKeyEncoding(pubKey []byte, flags ScriptFlags) error {
name string vm := Engine{flags: flags}
sig []byte return vm.checkPubKeyEncoding(pubKey)
isValid bool
}{
{
name: "valid signature.",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: true,
},
{
name: "empty.",
sig: []byte{},
isValid: false,
},
{
name: "bad magic.",
sig: []byte{0x31, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "bad 1st int marker magic.",
sig: []byte{0x30, 0x44, 0x03, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "bad 2nd int marker.",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x03, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "short len",
sig: []byte{0x30, 0x43, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "long len",
sig: []byte{0x30, 0x45, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "long X",
sig: []byte{0x30, 0x44, 0x02, 0x42, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "long Y",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x21, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "short Y",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x19, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "trailing crap.",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09, 0x01,
},
isValid: false,
},
{
name: "X == N ",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48,
0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "X == N ",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48,
0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41,
0x42, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "Y == N",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41,
},
isValid: false,
},
{
name: "Y > N",
sig: []byte{0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x42,
},
isValid: false,
},
{
name: "0 len X.",
sig: []byte{0x30, 0x24, 0x02, 0x00, 0x02, 0x20, 0x18, 0x15,
0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60, 0xa4,
0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c, 0xc5, 0x6c,
0xbb, 0xac, 0x46, 0x22, 0x08, 0x22, 0x21, 0xa8, 0x76,
0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "0 len Y.",
sig: []byte{0x30, 0x24, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x00,
},
isValid: false,
},
{
name: "extra R padding.",
sig: []byte{0x30, 0x45, 0x02, 0x21, 0x00, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x20, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
{
name: "extra S padding.",
sig: []byte{0x30, 0x45, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3, 0xa1,
0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32, 0xe9, 0xd6,
0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab, 0x5f, 0xb8, 0xcd,
0x41, 0x02, 0x21, 0x00, 0x18, 0x15, 0x22, 0xec, 0x8e, 0xca,
0x07, 0xde, 0x48, 0x60, 0xa4, 0xac, 0xdd, 0x12, 0x90,
0x9d, 0x83, 0x1c, 0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22,
0x08, 0x22, 0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
},
isValid: false,
},
} }
vm := Engine{flags: ScriptVerifyStrictEncoding} // TstCheckSignatureEncoding makes the internal checkSignatureEncoding function
for _, test := range tests { // available to the test package. Since it only really needs from the engine
err := vm.checkSignatureEncoding(test.sig) // for the flags, just accept the flags and create a new engine skeleton with
if err != nil && test.isValid { // them.
t.Errorf("checkSignatureEncoding test '%s' failed "+ func TstCheckSignatureEncoding(sig []byte, flags ScriptFlags) error {
"when it should have succeeded: %v", test.name, vm := Engine{flags: flags}
err) return vm.checkSignatureEncoding(sig)
} else if err == nil && !test.isValid {
t.Errorf("checkSignatureEncooding test '%s' succeeded "+
"when it should have failed", test.name)
}
}
} }
// TstRemoveOpcode makes the internal removeOpcode function available to the
// test package.
func TstRemoveOpcode(pkscript []byte, opcode byte) ([]byte, error) { func TstRemoveOpcode(pkscript []byte, opcode byte) ([]byte, error) {
pops, err := parseScript(pkscript) pops, err := parseScript(pkscript)
if err != nil { if err != nil {
@ -360,6 +65,8 @@ func TstRemoveOpcode(pkscript []byte, opcode byte) ([]byte, error) {
return unparseScript(pops) return unparseScript(pops)
} }
// TstRemoveOpcodeByData makes the internal removeOpcodeByData function
// available to the test package.
func TstRemoveOpcodeByData(pkscript []byte, data []byte) ([]byte, error) { func TstRemoveOpcodeByData(pkscript []byte, data []byte) ([]byte, error) {
pops, err := parseScript(pkscript) pops, err := parseScript(pkscript)
if err != nil { if err != nil {
@ -376,15 +83,15 @@ func (vm *Engine) TstSetPC(script, off int) {
vm.scriptOff = off vm.scriptOff = off
} }
// Internal tests for opcodde parsing with bad data templates. // Internal tests for opcode parsing with bad data templates.
func TestParseOpcode(t *testing.T) { func TestParseOpcode(t *testing.T) {
// Deep copy the array. // Deep copy the array and make one of the opcodes invalid by setting it
// to the wrong length.
fakeArray := opcodeArray fakeArray := opcodeArray
// wrong length -8.
fakeArray[OP_PUSHDATA4] = opcode{value: OP_PUSHDATA4, fakeArray[OP_PUSHDATA4] = opcode{value: OP_PUSHDATA4,
name: "OP_PUSHDATA4", length: -8, opfunc: opcodePushData} name: "OP_PUSHDATA4", length: -8, opfunc: opcodePushData}
// this script would be fine if -8 was a valid length. // This script would be fine if -8 was a valid length.
_, err := parseScriptTemplate([]byte{OP_PUSHDATA4, 0x1, 0x00, 0x00, _, err := parseScriptTemplate([]byte{OP_PUSHDATA4, 0x1, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00}, &fakeArray) 0x00, 0x00, 0x00, 0x00, 0x00}, &fakeArray)
if err == nil { if err == nil {
@ -392,13 +99,12 @@ func TestParseOpcode(t *testing.T) {
} }
} }
type popTest struct { func TestUnparsingInvalidOpcodes(t *testing.T) {
tests := []struct {
name string name string
pop *parsedOpcode pop *parsedOpcode
expectedErr error expectedErr error
} }{
var popTests = []popTest{
{ {
name: "OP_FALSE", name: "OP_FALSE",
pop: &parsedOpcode{ pop: &parsedOpcode{
@ -4033,8 +3739,7 @@ var popTests = []popTest{
}, },
} }
func TestUnparsingInvalidOpcodes(t *testing.T) { for _, test := range tests {
for _, test := range popTests {
_, err := test.pop.bytes() _, err := test.pop.bytes()
if err != test.expectedErr { if err != test.expectedErr {
t.Errorf("Parsed Opcode test '%s' failed", test.name) t.Errorf("Parsed Opcode test '%s' failed", test.name)

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by an ISC // Use of this source code is governed by an ISC
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package txscript package txscript_test
import ( import (
"encoding/hex" "encoding/hex"
@ -14,6 +14,7 @@ import (
"strings" "strings"
"testing" "testing"
. "github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
) )
@ -43,30 +44,46 @@ func parseHex(tok string) ([]byte, error) {
return hex.DecodeString(tok[2:]) return hex.DecodeString(tok[2:])
} }
// shortFormOps holds a map of opcode names to values for use in short form
// parsing. It is declared here so it only needs to be created once.
var shortFormOps map[string]byte
// parseShortForm parses a string as as used in the Bitcoin Core reference tests // parseShortForm parses a string as as used in the Bitcoin Core reference tests
// into the script it came from. // into the script it came from.
func parseShortForm(script string) ([]byte, error) { //
ops := make(map[string]byte) // The format used for these tests is pretty simple if ad-hoc:
// - Opcodes other than the push opcodes and unknown are present as
// the format used for these tests is pretty simple if ad-hoc:
// - opcodes other than the push opcodes and unknown are present as
// either OP_NAME or just NAME // either OP_NAME or just NAME
// - plain numbers are made into push operations // - Plain numbers are made into push operations
// - numbers beginning with 0x are inserted into the []byte as-is (so // - Numbers beginning with 0x are inserted into the []byte as-is (so
// 0x14 is OP_DATA_20) // 0x14 is OP_DATA_20)
// - single quoted strings are pushed as data. // - Single quoted strings are pushed as data
// - anything else is an error. // - Anything else is an error
func parseShortForm(script string) ([]byte, error) {
// Only create the short form opcode map once.
if shortFormOps == nil {
ops := make(map[string]byte)
for opcodeName, opcodeValue := range OpcodeByName { for opcodeName, opcodeValue := range OpcodeByName {
if opcodeValue < OP_NOP && opcodeValue != OP_RESERVED {
continue
}
if strings.Contains(opcodeName, "OP_UNKNOWN") { if strings.Contains(opcodeName, "OP_UNKNOWN") {
continue continue
} }
ops[opcodeName] = opcodeValue ops[opcodeName] = opcodeValue
// The opcodes named OP_# can't have the OP_ prefix
// stripped or they would conflict with the plain
// numbers. Also, since OP_FALSE and OP_TRUE are
// aliases for the OP_0, and OP_1, respectively, they
// have the same value, so detect those by name and
// allow them.
if (opcodeName == "OP_FALSE" || opcodeName == "OP_TRUE") ||
(opcodeValue != OP_0 && (opcodeValue < OP_1 ||
opcodeValue > OP_16)) {
ops[strings.TrimPrefix(opcodeName, "OP_")] = opcodeValue ops[strings.TrimPrefix(opcodeName, "OP_")] = opcodeValue
} }
// do once, build map. }
shortFormOps = ops
}
// Split only does one separator so convert all \n and tab into space. // Split only does one separator so convert all \n and tab into space.
script = strings.Replace(script, "\n", " ", -1) script = strings.Replace(script, "\n", " ", -1)
@ -83,12 +100,11 @@ func parseShortForm(script string) ([]byte, error) {
builder.AddInt64(num) builder.AddInt64(num)
continue continue
} else if bts, err := parseHex(tok); err == nil { } else if bts, err := parseHex(tok); err == nil {
// naughty... builder.TstConcatRawScript(bts)
builder.script = append(builder.script, bts...)
} else if len(tok) >= 2 && } else if len(tok) >= 2 &&
tok[0] == '\'' && tok[len(tok)-1] == '\'' { tok[0] == '\'' && tok[len(tok)-1] == '\'' {
builder.AddFullData([]byte(tok[1 : len(tok)-1])) builder.AddFullData([]byte(tok[1 : len(tok)-1]))
} else if opcode, ok := ops[tok]; ok { } else if opcode, ok := shortFormOps[tok]; ok {
builder.AddOp(opcode) builder.AddOp(opcode)
} else { } else {
return nil, fmt.Errorf("bad token \"%s\"", tok) return nil, fmt.Errorf("bad token \"%s\"", tok)

File diff suppressed because it is too large Load diff

View file

@ -141,7 +141,7 @@ func TestScriptBuilderAddData(t *testing.T) {
useFull bool // use AddFullData instead of AddData. useFull bool // use AddFullData instead of AddData.
}{ }{
// BIP0062: Pushing an empty byte sequence must use OP_0. // BIP0062: Pushing an empty byte sequence must use OP_0.
{name: "push empty byte sequence", data: []byte{}, expected: []byte{txscript.OP_0}}, {name: "push empty byte sequence", data: nil, expected: []byte{txscript.OP_0}},
{name: "push 1 byte 0x00", data: []byte{0x00}, expected: []byte{txscript.OP_0}}, {name: "push 1 byte 0x00", data: []byte{0x00}, expected: []byte{txscript.OP_0}},
// BIP0062: Pushing a 1-byte sequence of byte 0x01 through 0x10 must use OP_n. // BIP0062: Pushing a 1-byte sequence of byte 0x01 through 0x10 must use OP_n.
@ -213,17 +213,17 @@ func TestScriptBuilderAddData(t *testing.T) {
{ {
name: "push data len 521", name: "push data len 521",
data: bytes.Repeat([]byte{0x49}, 521), data: bytes.Repeat([]byte{0x49}, 521),
expected: []byte{}, expected: nil,
}, },
{ {
name: "push data len 32767 (canonical)", name: "push data len 32767 (canonical)",
data: bytes.Repeat([]byte{0x49}, 32767), data: bytes.Repeat([]byte{0x49}, 32767),
expected: []byte{}, expected: nil,
}, },
{ {
name: "push data len 65536 (canonical)", name: "push data len 65536 (canonical)",
data: bytes.Repeat([]byte{0x49}, 65536), data: bytes.Repeat([]byte{0x49}, 65536),
expected: []byte{}, expected: nil,
}, },
// Additional tests for the PushFullData function that // Additional tests for the PushFullData function that

View file

@ -78,7 +78,7 @@ func signAndCheck(msg string, tx *wire.MsgTx, idx int, pkScript []byte,
previousScript []byte) error { previousScript []byte) error {
sigScript, err := txscript.SignTxOutput(&chaincfg.TestNet3Params, tx, sigScript, err := txscript.SignTxOutput(&chaincfg.TestNet3Params, tx,
idx, pkScript, hashType, kdb, sdb, []byte{}) idx, pkScript, hashType, kdb, sdb, nil)
if err != nil { if err != nil {
return fmt.Errorf("failed to sign output %s: %v", msg, err) return fmt.Errorf("failed to sign output %s: %v", msg, err)
} }
@ -170,7 +170,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType, if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{ mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(nil), []byte{}); err != nil { }), mkGetScript(nil), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -208,7 +208,7 @@ func TestSignTxOutput(t *testing.T) {
&chaincfg.TestNet3Params, tx, i, pkScript, &chaincfg.TestNet3Params, tx, i, pkScript,
hashType, mkGetKey(map[string]addressToKey{ hashType, mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(nil), []byte{}) }), mkGetScript(nil), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -268,7 +268,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType, if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{ mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(nil), []byte{}); err != nil { }), mkGetScript(nil), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -307,7 +307,7 @@ func TestSignTxOutput(t *testing.T) {
&chaincfg.TestNet3Params, tx, i, pkScript, &chaincfg.TestNet3Params, tx, i, pkScript,
hashType, mkGetKey(map[string]addressToKey{ hashType, mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(nil), []byte{}) }), mkGetScript(nil), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -367,7 +367,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType, if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{ mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(nil), []byte{}); err != nil { }), mkGetScript(nil), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -406,7 +406,7 @@ func TestSignTxOutput(t *testing.T) {
&chaincfg.TestNet3Params, tx, i, pkScript, &chaincfg.TestNet3Params, tx, i, pkScript,
hashType, mkGetKey(map[string]addressToKey{ hashType, mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(nil), []byte{}) }), mkGetScript(nil), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -466,7 +466,7 @@ func TestSignTxOutput(t *testing.T) {
if err := signAndCheck(msg, tx, i, pkScript, hashType, if err := signAndCheck(msg, tx, i, pkScript, hashType,
mkGetKey(map[string]addressToKey{ mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(nil), []byte{}); err != nil { }), mkGetScript(nil), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -505,7 +505,7 @@ func TestSignTxOutput(t *testing.T) {
&chaincfg.TestNet3Params, tx, i, pkScript, &chaincfg.TestNet3Params, tx, i, pkScript,
hashType, mkGetKey(map[string]addressToKey{ hashType, mkGetKey(map[string]addressToKey{
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(nil), []byte{}) }), mkGetScript(nil), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -585,7 +585,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}); err != nil { }), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -642,7 +642,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -657,7 +657,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s a "+ t.Errorf("failed to sign output %s a "+
"second time: %v", msg, err) "second time: %v", msg, err)
@ -723,7 +723,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}); err != nil { }), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -780,7 +780,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -795,7 +795,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s a "+ t.Errorf("failed to sign output %s a "+
"second time: %v", msg, err) "second time: %v", msg, err)
@ -861,7 +861,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}); err != nil { }), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -918,7 +918,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -933,7 +933,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, false}, address.EncodeAddress(): {key, false},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s a "+ t.Errorf("failed to sign output %s a "+
"second time: %v", msg, err) "second time: %v", msg, err)
@ -999,7 +999,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}); err != nil { }), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -1056,7 +1056,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -1071,7 +1071,7 @@ func TestSignTxOutput(t *testing.T) {
address.EncodeAddress(): {key, true}, address.EncodeAddress(): {key, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s a "+ t.Errorf("failed to sign output %s a "+
"second time: %v", msg, err) "second time: %v", msg, err)
@ -1157,7 +1157,7 @@ func TestSignTxOutput(t *testing.T) {
address2.EncodeAddress(): {key2, true}, address2.EncodeAddress(): {key2, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}); err != nil { }), nil); err != nil {
t.Error(err) t.Error(err)
break break
} }
@ -1233,7 +1233,7 @@ func TestSignTxOutput(t *testing.T) {
address1.EncodeAddress(): {key1, true}, address1.EncodeAddress(): {key1, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)
@ -1340,7 +1340,7 @@ func TestSignTxOutput(t *testing.T) {
address1.EncodeAddress(): {key1, true}, address1.EncodeAddress(): {key1, true},
}), mkGetScript(map[string][]byte{ }), mkGetScript(map[string][]byte{
scriptAddr.EncodeAddress(): pkScript, scriptAddr.EncodeAddress(): pkScript,
}), []byte{}) }), nil)
if err != nil { if err != nil {
t.Errorf("failed to sign output %s: %v", msg, t.Errorf("failed to sign output %s: %v", msg,
err) err)

View file

@ -39,7 +39,7 @@ func TestStack(t *testing.T) {
return err return err
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"peek underflow (int)", "peek underflow (int)",
@ -49,7 +49,7 @@ func TestStack(t *testing.T) {
return err return err
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"peek underflow (bool)", "peek underflow (bool)",
@ -59,7 +59,7 @@ func TestStack(t *testing.T) {
return err return err
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"pop", "pop",
@ -106,7 +106,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"pop underflow", "pop underflow",
@ -121,7 +121,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"pop bool", "pop bool",
@ -138,7 +138,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"pop bool", "pop bool",
@ -155,11 +155,11 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"pop bool", "pop bool",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
_, err := s.PopBool() _, err := s.PopBool()
if err != nil { if err != nil {
@ -169,7 +169,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"popInt 0", "popInt 0",
@ -185,7 +185,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"popInt -0", "popInt -0",
@ -201,7 +201,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"popInt 1", "popInt 1",
@ -217,7 +217,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"popInt 1 leading 0", "popInt 1 leading 0",
@ -234,7 +234,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"popInt -1", "popInt -1",
@ -250,7 +250,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"popInt -1 leading 0", "popInt -1 leading 0",
@ -267,7 +267,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
// Triggers the multibyte case in asInt // Triggers the multibyte case in asInt
{ {
@ -285,7 +285,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
// Confirm that the asInt code doesn't modify the base data. // Confirm that the asInt code doesn't modify the base data.
{ {
@ -307,7 +307,7 @@ func TestStack(t *testing.T) {
}, },
{ {
"PushInt 0", "PushInt 0",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushInt(scriptNum(0)) s.PushInt(scriptNum(0))
return nil return nil
@ -317,7 +317,7 @@ func TestStack(t *testing.T) {
}, },
{ {
"PushInt 1", "PushInt 1",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushInt(scriptNum(1)) s.PushInt(scriptNum(1))
return nil return nil
@ -327,7 +327,7 @@ func TestStack(t *testing.T) {
}, },
{ {
"PushInt -1", "PushInt -1",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushInt(scriptNum(-1)) s.PushInt(scriptNum(-1))
return nil return nil
@ -337,7 +337,7 @@ func TestStack(t *testing.T) {
}, },
{ {
"PushInt two bytes", "PushInt two bytes",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushInt(scriptNum(256)) s.PushInt(scriptNum(256))
return nil return nil
@ -348,7 +348,7 @@ func TestStack(t *testing.T) {
}, },
{ {
"PushInt leading zeros", "PushInt leading zeros",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
// this will have the highbit set // this will have the highbit set
s.PushInt(scriptNum(128)) s.PushInt(scriptNum(128))
@ -411,7 +411,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
ErrStackInvalidArgs, ErrStackInvalidArgs,
[][]byte{}, nil,
}, },
{ {
"dup-1", "dup-1",
@ -425,7 +425,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
ErrStackInvalidArgs, ErrStackInvalidArgs,
[][]byte{}, nil,
}, },
{ {
"dup too much", "dup too much",
@ -439,7 +439,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"dup-1", "dup-1",
@ -453,11 +453,11 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
ErrStackInvalidArgs, ErrStackInvalidArgs,
[][]byte{}, nil,
}, },
{ {
"PushBool true", "PushBool true",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushBool(true) s.PushBool(true)
@ -468,7 +468,7 @@ func TestStack(t *testing.T) {
}, },
{ {
"PushBool false", "PushBool false",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushBool(false) s.PushBool(false)
@ -479,7 +479,7 @@ func TestStack(t *testing.T) {
}, },
{ {
"PushBool PopBool", "PushBool PopBool",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushBool(true) s.PushBool(true)
val, err := s.PopBool() val, err := s.PopBool()
@ -493,11 +493,11 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"PushBool PopBool 2", "PushBool PopBool 2",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushBool(false) s.PushBool(false)
val, err := s.PopBool() val, err := s.PopBool()
@ -511,11 +511,11 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"PushInt PopBool", "PushInt PopBool",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushInt(scriptNum(1)) s.PushInt(scriptNum(1))
val, err := s.PopBool() val, err := s.PopBool()
@ -529,11 +529,11 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"PushInt PopBool 2", "PushInt PopBool 2",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushInt(scriptNum(0)) s.PushInt(scriptNum(0))
val, err := s.PopBool() val, err := s.PopBool()
@ -547,11 +547,11 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"PushInt PopBool 2", "PushInt PopBool 2",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushInt(scriptNum(0)) s.PushInt(scriptNum(0))
val, err := s.PopBool() val, err := s.PopBool()
@ -565,7 +565,7 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"Nip top", "Nip top",
@ -620,16 +620,16 @@ func TestStack(t *testing.T) {
return s.Tuck() return s.Tuck()
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"all tucked up", "all tucked up",
[][]byte{}, // too few arguments for tuck nil, // too few arguments for tuck
func(s *stack) error { func(s *stack) error {
return s.Tuck() return s.Tuck()
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"drop 1", "drop 1",
@ -665,7 +665,7 @@ func TestStack(t *testing.T) {
return s.DropN(4) return s.DropN(4)
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"drop 4/5", "drop 4/5",
@ -674,7 +674,7 @@ func TestStack(t *testing.T) {
return s.DropN(5) return s.DropN(5)
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"drop invalid", "drop invalid",
@ -683,7 +683,7 @@ func TestStack(t *testing.T) {
return s.DropN(0) return s.DropN(0)
}, },
ErrStackInvalidArgs, ErrStackInvalidArgs,
[][]byte{}, nil,
}, },
{ {
"Rot1", "Rot1",
@ -710,7 +710,7 @@ func TestStack(t *testing.T) {
return s.RotN(1) return s.RotN(1)
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"Rot0", "Rot0",
@ -719,7 +719,7 @@ func TestStack(t *testing.T) {
return s.RotN(0) return s.RotN(0)
}, },
ErrStackInvalidArgs, ErrStackInvalidArgs,
[][]byte{}, nil,
}, },
{ {
"Swap1", "Swap1",
@ -746,7 +746,7 @@ func TestStack(t *testing.T) {
return s.SwapN(1) return s.SwapN(1)
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"Swap0", "Swap0",
@ -755,7 +755,7 @@ func TestStack(t *testing.T) {
return s.SwapN(0) return s.SwapN(0)
}, },
ErrStackInvalidArgs, ErrStackInvalidArgs,
[][]byte{}, nil,
}, },
{ {
"Over1", "Over1",
@ -782,7 +782,7 @@ func TestStack(t *testing.T) {
return s.OverN(1) return s.OverN(1)
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"Over0", "Over0",
@ -791,7 +791,7 @@ func TestStack(t *testing.T) {
return s.OverN(0) return s.OverN(0)
}, },
ErrStackInvalidArgs, ErrStackInvalidArgs,
[][]byte{}, nil,
}, },
{ {
"Pick1", "Pick1",
@ -818,7 +818,7 @@ func TestStack(t *testing.T) {
return s.PickN(1) return s.PickN(1)
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"Roll1", "Roll1",
@ -845,7 +845,7 @@ func TestStack(t *testing.T) {
return s.RollN(1) return s.RollN(1)
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
{ {
"Peek bool", "Peek bool",
@ -921,7 +921,7 @@ func TestStack(t *testing.T) {
}, },
{ {
"pop int", "pop int",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
s.PushInt(scriptNum(1)) s.PushInt(scriptNum(1))
// Peek int is otherwise pretty well tested, // Peek int is otherwise pretty well tested,
@ -936,11 +936,11 @@ func TestStack(t *testing.T) {
return nil return nil
}, },
nil, nil,
[][]byte{}, nil,
}, },
{ {
"pop empty", "pop empty",
[][]byte{}, nil,
func(s *stack) error { func(s *stack) error {
// Peek int is otherwise pretty well tested, // Peek int is otherwise pretty well tested,
// just check it works. // just check it works.
@ -948,7 +948,7 @@ func TestStack(t *testing.T) {
return err return err
}, },
ErrStackUnderflow, ErrStackUnderflow,
[][]byte{}, nil,
}, },
} }

View file

@ -372,7 +372,7 @@ func PushedData(script []byte) ([][]byte, error) {
if pop.data != nil { if pop.data != nil {
data = append(data, pop.data) data = append(data, pop.data)
} else if pop.opcode.value == OP_0 { } else if pop.opcode.value == OP_0 {
data = append(data, []byte{}) data = append(data, nil)
} }
} }
return data, nil return data, nil

File diff suppressed because it is too large Load diff