1// Copyright (c) 2013-2017 The btcsuite developers
2// Use of this source code is governed by an ISC
3// license that can be found in the LICENSE file.
4
5package txscript
6
7import (
8	"bytes"
9	"encoding/hex"
10	"encoding/json"
11	"errors"
12	"fmt"
13	"io/ioutil"
14	"strconv"
15	"strings"
16	"testing"
17
18	"github.com/btcsuite/btcd/chaincfg/chainhash"
19	"github.com/btcsuite/btcd/wire"
20	"github.com/btcsuite/btcutil"
21)
22
23// scriptTestName returns a descriptive test name for the given reference script
24// test data.
25func scriptTestName(test []interface{}) (string, error) {
26	// Account for any optional leading witness data.
27	var witnessOffset int
28	if _, ok := test[0].([]interface{}); ok {
29		witnessOffset++
30	}
31
32	// In addition to the optional leading witness data, the test must
33	// consist of at least a signature script, public key script, flags,
34	// and expected error.  Finally, it may optionally contain a comment.
35	if len(test) < witnessOffset+4 || len(test) > witnessOffset+5 {
36		return "", fmt.Errorf("invalid test length %d", len(test))
37	}
38
39	// Use the comment for the test name if one is specified, otherwise,
40	// construct the name based on the signature script, public key script,
41	// and flags.
42	var name string
43	if len(test) == witnessOffset+5 {
44		name = fmt.Sprintf("test (%s)", test[witnessOffset+4])
45	} else {
46		name = fmt.Sprintf("test ([%s, %s, %s])", test[witnessOffset],
47			test[witnessOffset+1], test[witnessOffset+2])
48	}
49	return name, nil
50}
51
52// parse hex string into a []byte.
53func parseHex(tok string) ([]byte, error) {
54	if !strings.HasPrefix(tok, "0x") {
55		return nil, errors.New("not a hex number")
56	}
57	return hex.DecodeString(tok[2:])
58}
59
60// parseWitnessStack parses a json array of witness items encoded as hex into a
61// slice of witness elements.
62func parseWitnessStack(elements []interface{}) ([][]byte, error) {
63	witness := make([][]byte, len(elements))
64	for i, e := range elements {
65		witElement, err := hex.DecodeString(e.(string))
66		if err != nil {
67			return nil, err
68		}
69
70		witness[i] = witElement
71	}
72
73	return witness, nil
74}
75
76// shortFormOps holds a map of opcode names to values for use in short form
77// parsing.  It is declared here so it only needs to be created once.
78var shortFormOps map[string]byte
79
80// parseShortForm parses a string as as used in the Bitcoin Core reference tests
81// into the script it came from.
82//
83// The format used for these tests is pretty simple if ad-hoc:
84//   - Opcodes other than the push opcodes and unknown are present as
85//     either OP_NAME or just NAME
86//   - Plain numbers are made into push operations
87//   - Numbers beginning with 0x are inserted into the []byte as-is (so
88//     0x14 is OP_DATA_20)
89//   - Single quoted strings are pushed as data
90//   - Anything else is an error
91func parseShortForm(script string) ([]byte, error) {
92	// Only create the short form opcode map once.
93	if shortFormOps == nil {
94		ops := make(map[string]byte)
95		for opcodeName, opcodeValue := range OpcodeByName {
96			if strings.Contains(opcodeName, "OP_UNKNOWN") {
97				continue
98			}
99			ops[opcodeName] = opcodeValue
100
101			// The opcodes named OP_# can't have the OP_ prefix
102			// stripped or they would conflict with the plain
103			// numbers.  Also, since OP_FALSE and OP_TRUE are
104			// aliases for the OP_0, and OP_1, respectively, they
105			// have the same value, so detect those by name and
106			// allow them.
107			if (opcodeName == "OP_FALSE" || opcodeName == "OP_TRUE") ||
108				(opcodeValue != OP_0 && (opcodeValue < OP_1 ||
109					opcodeValue > OP_16)) {
110
111				ops[strings.TrimPrefix(opcodeName, "OP_")] = opcodeValue
112			}
113		}
114		shortFormOps = ops
115	}
116
117	// Split only does one separator so convert all \n and tab into  space.
118	script = strings.Replace(script, "\n", " ", -1)
119	script = strings.Replace(script, "\t", " ", -1)
120	tokens := strings.Split(script, " ")
121	builder := NewScriptBuilder()
122
123	for _, tok := range tokens {
124		if len(tok) == 0 {
125			continue
126		}
127		// if parses as a plain number
128		if num, err := strconv.ParseInt(tok, 10, 64); err == nil {
129			builder.AddInt64(num)
130			continue
131		} else if bts, err := parseHex(tok); err == nil {
132			// Concatenate the bytes manually since the test code
133			// intentionally creates scripts that are too large and
134			// would cause the builder to error otherwise.
135			if builder.err == nil {
136				builder.script = append(builder.script, bts...)
137			}
138		} else if len(tok) >= 2 &&
139			tok[0] == '\'' && tok[len(tok)-1] == '\'' {
140			builder.AddFullData([]byte(tok[1 : len(tok)-1]))
141		} else if opcode, ok := shortFormOps[tok]; ok {
142			builder.AddOp(opcode)
143		} else {
144			return nil, fmt.Errorf("bad token %q", tok)
145		}
146
147	}
148	return builder.Script()
149}
150
151// parseScriptFlags parses the provided flags string from the format used in the
152// reference tests into ScriptFlags suitable for use in the script engine.
153func parseScriptFlags(flagStr string) (ScriptFlags, error) {
154	var flags ScriptFlags
155
156	sFlags := strings.Split(flagStr, ",")
157	for _, flag := range sFlags {
158		switch flag {
159		case "":
160			// Nothing.
161		case "CHECKLOCKTIMEVERIFY":
162			flags |= ScriptVerifyCheckLockTimeVerify
163		case "CHECKSEQUENCEVERIFY":
164			flags |= ScriptVerifyCheckSequenceVerify
165		case "CLEANSTACK":
166			flags |= ScriptVerifyCleanStack
167		case "DERSIG":
168			flags |= ScriptVerifyDERSignatures
169		case "DISCOURAGE_UPGRADABLE_NOPS":
170			flags |= ScriptDiscourageUpgradableNops
171		case "LOW_S":
172			flags |= ScriptVerifyLowS
173		case "MINIMALDATA":
174			flags |= ScriptVerifyMinimalData
175		case "NONE":
176			// Nothing.
177		case "NULLDUMMY":
178			flags |= ScriptStrictMultiSig
179		case "NULLFAIL":
180			flags |= ScriptVerifyNullFail
181		case "P2SH":
182			flags |= ScriptBip16
183		case "SIGPUSHONLY":
184			flags |= ScriptVerifySigPushOnly
185		case "STRICTENC":
186			flags |= ScriptVerifyStrictEncoding
187		case "WITNESS":
188			flags |= ScriptVerifyWitness
189		case "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM":
190			flags |= ScriptVerifyDiscourageUpgradeableWitnessProgram
191		case "MINIMALIF":
192			flags |= ScriptVerifyMinimalIf
193		case "WITNESS_PUBKEYTYPE":
194			flags |= ScriptVerifyWitnessPubKeyType
195		default:
196			return flags, fmt.Errorf("invalid flag: %s", flag)
197		}
198	}
199	return flags, nil
200}
201
202// parseExpectedResult parses the provided expected result string into allowed
203// script error codes.  An error is returned if the expected result string is
204// not supported.
205func parseExpectedResult(expected string) ([]ErrorCode, error) {
206	switch expected {
207	case "OK":
208		return nil, nil
209	case "UNKNOWN_ERROR":
210		return []ErrorCode{ErrNumberTooBig, ErrMinimalData}, nil
211	case "PUBKEYTYPE":
212		return []ErrorCode{ErrPubKeyType}, nil
213	case "SIG_DER":
214		return []ErrorCode{ErrSigTooShort, ErrSigTooLong,
215			ErrSigInvalidSeqID, ErrSigInvalidDataLen, ErrSigMissingSTypeID,
216			ErrSigMissingSLen, ErrSigInvalidSLen,
217			ErrSigInvalidRIntID, ErrSigZeroRLen, ErrSigNegativeR,
218			ErrSigTooMuchRPadding, ErrSigInvalidSIntID,
219			ErrSigZeroSLen, ErrSigNegativeS, ErrSigTooMuchSPadding,
220			ErrInvalidSigHashType}, nil
221	case "EVAL_FALSE":
222		return []ErrorCode{ErrEvalFalse, ErrEmptyStack}, nil
223	case "EQUALVERIFY":
224		return []ErrorCode{ErrEqualVerify}, nil
225	case "NULLFAIL":
226		return []ErrorCode{ErrNullFail}, nil
227	case "SIG_HIGH_S":
228		return []ErrorCode{ErrSigHighS}, nil
229	case "SIG_HASHTYPE":
230		return []ErrorCode{ErrInvalidSigHashType}, nil
231	case "SIG_NULLDUMMY":
232		return []ErrorCode{ErrSigNullDummy}, nil
233	case "SIG_PUSHONLY":
234		return []ErrorCode{ErrNotPushOnly}, nil
235	case "CLEANSTACK":
236		return []ErrorCode{ErrCleanStack}, nil
237	case "BAD_OPCODE":
238		return []ErrorCode{ErrReservedOpcode, ErrMalformedPush}, nil
239	case "UNBALANCED_CONDITIONAL":
240		return []ErrorCode{ErrUnbalancedConditional,
241			ErrInvalidStackOperation}, nil
242	case "OP_RETURN":
243		return []ErrorCode{ErrEarlyReturn}, nil
244	case "VERIFY":
245		return []ErrorCode{ErrVerify}, nil
246	case "INVALID_STACK_OPERATION", "INVALID_ALTSTACK_OPERATION":
247		return []ErrorCode{ErrInvalidStackOperation}, nil
248	case "DISABLED_OPCODE":
249		return []ErrorCode{ErrDisabledOpcode}, nil
250	case "DISCOURAGE_UPGRADABLE_NOPS":
251		return []ErrorCode{ErrDiscourageUpgradableNOPs}, nil
252	case "PUSH_SIZE":
253		return []ErrorCode{ErrElementTooBig}, nil
254	case "OP_COUNT":
255		return []ErrorCode{ErrTooManyOperations}, nil
256	case "STACK_SIZE":
257		return []ErrorCode{ErrStackOverflow}, nil
258	case "SCRIPT_SIZE":
259		return []ErrorCode{ErrScriptTooBig}, nil
260	case "PUBKEY_COUNT":
261		return []ErrorCode{ErrInvalidPubKeyCount}, nil
262	case "SIG_COUNT":
263		return []ErrorCode{ErrInvalidSignatureCount}, nil
264	case "MINIMALDATA":
265		return []ErrorCode{ErrMinimalData}, nil
266	case "NEGATIVE_LOCKTIME":
267		return []ErrorCode{ErrNegativeLockTime}, nil
268	case "UNSATISFIED_LOCKTIME":
269		return []ErrorCode{ErrUnsatisfiedLockTime}, nil
270	case "MINIMALIF":
271		return []ErrorCode{ErrMinimalIf}, nil
272	case "DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM":
273		return []ErrorCode{ErrDiscourageUpgradableWitnessProgram}, nil
274	case "WITNESS_PROGRAM_WRONG_LENGTH":
275		return []ErrorCode{ErrWitnessProgramWrongLength}, nil
276	case "WITNESS_PROGRAM_WITNESS_EMPTY":
277		return []ErrorCode{ErrWitnessProgramEmpty}, nil
278	case "WITNESS_PROGRAM_MISMATCH":
279		return []ErrorCode{ErrWitnessProgramMismatch}, nil
280	case "WITNESS_MALLEATED":
281		return []ErrorCode{ErrWitnessMalleated}, nil
282	case "WITNESS_MALLEATED_P2SH":
283		return []ErrorCode{ErrWitnessMalleatedP2SH}, nil
284	case "WITNESS_UNEXPECTED":
285		return []ErrorCode{ErrWitnessUnexpected}, nil
286	case "WITNESS_PUBKEYTYPE":
287		return []ErrorCode{ErrWitnessPubKeyType}, nil
288	}
289
290	return nil, fmt.Errorf("unrecognized expected result in test data: %v",
291		expected)
292}
293
294// createSpendTx generates a basic spending transaction given the passed
295// signature, witness and public key scripts.
296func createSpendingTx(witness [][]byte, sigScript, pkScript []byte,
297	outputValue int64) *wire.MsgTx {
298
299	coinbaseTx := wire.NewMsgTx(wire.TxVersion)
300
301	outPoint := wire.NewOutPoint(&chainhash.Hash{}, ^uint32(0))
302	txIn := wire.NewTxIn(outPoint, []byte{OP_0, OP_0}, nil)
303	txOut := wire.NewTxOut(outputValue, pkScript)
304	coinbaseTx.AddTxIn(txIn)
305	coinbaseTx.AddTxOut(txOut)
306
307	spendingTx := wire.NewMsgTx(wire.TxVersion)
308	coinbaseTxSha := coinbaseTx.TxHash()
309	outPoint = wire.NewOutPoint(&coinbaseTxSha, 0)
310	txIn = wire.NewTxIn(outPoint, sigScript, witness)
311	txOut = wire.NewTxOut(outputValue, nil)
312
313	spendingTx.AddTxIn(txIn)
314	spendingTx.AddTxOut(txOut)
315
316	return spendingTx
317}
318
319// scriptWithInputVal wraps a target pkScript with the value of the output in
320// which it is contained. The inputVal is necessary in order to properly
321// validate inputs which spend nested, or native witness programs.
322type scriptWithInputVal struct {
323	inputVal int64
324	pkScript []byte
325}
326
327// testScripts ensures all of the passed script tests execute with the expected
328// results with or without using a signature cache, as specified by the
329// parameter.
330func testScripts(t *testing.T, tests [][]interface{}, useSigCache bool) {
331	// Create a signature cache to use only if requested.
332	var sigCache *SigCache
333	if useSigCache {
334		sigCache = NewSigCache(10)
335	}
336
337	for i, test := range tests {
338		// "Format is: [[wit..., amount]?, scriptSig, scriptPubKey,
339		//    flags, expected_scripterror, ... comments]"
340
341		// Skip single line comments.
342		if len(test) == 1 {
343			continue
344		}
345
346		// Construct a name for the test based on the comment and test
347		// data.
348		name, err := scriptTestName(test)
349		if err != nil {
350			t.Errorf("TestScripts: invalid test #%d: %v", i, err)
351			continue
352		}
353
354		var (
355			witness  wire.TxWitness
356			inputAmt btcutil.Amount
357		)
358
359		// When the first field of the test data is a slice it contains
360		// witness data and everything else is offset by 1 as a result.
361		witnessOffset := 0
362		if witnessData, ok := test[0].([]interface{}); ok {
363			witnessOffset++
364
365			// If this is a witness test, then the final element
366			// within the slice is the input amount, so we ignore
367			// all but the last element in order to parse the
368			// witness stack.
369			strWitnesses := witnessData[:len(witnessData)-1]
370			witness, err = parseWitnessStack(strWitnesses)
371			if err != nil {
372				t.Errorf("%s: can't parse witness; %v", name, err)
373				continue
374			}
375
376			inputAmt, err = btcutil.NewAmount(witnessData[len(witnessData)-1].(float64))
377			if err != nil {
378				t.Errorf("%s: can't parse input amt: %v",
379					name, err)
380				continue
381			}
382
383		}
384
385		// Extract and parse the signature script from the test fields.
386		scriptSigStr, ok := test[witnessOffset].(string)
387		if !ok {
388			t.Errorf("%s: signature script is not a string", name)
389			continue
390		}
391		scriptSig, err := parseShortForm(scriptSigStr)
392		if err != nil {
393			t.Errorf("%s: can't parse signature script: %v", name,
394				err)
395			continue
396		}
397
398		// Extract and parse the public key script from the test fields.
399		scriptPubKeyStr, ok := test[witnessOffset+1].(string)
400		if !ok {
401			t.Errorf("%s: public key script is not a string", name)
402			continue
403		}
404		scriptPubKey, err := parseShortForm(scriptPubKeyStr)
405		if err != nil {
406			t.Errorf("%s: can't parse public key script: %v", name,
407				err)
408			continue
409		}
410
411		// Extract and parse the script flags from the test fields.
412		flagsStr, ok := test[witnessOffset+2].(string)
413		if !ok {
414			t.Errorf("%s: flags field is not a string", name)
415			continue
416		}
417		flags, err := parseScriptFlags(flagsStr)
418		if err != nil {
419			t.Errorf("%s: %v", name, err)
420			continue
421		}
422
423		// Extract and parse the expected result from the test fields.
424		//
425		// Convert the expected result string into the allowed script
426		// error codes.  This is necessary because txscript is more
427		// fine grained with its errors than the reference test data, so
428		// some of the reference test data errors map to more than one
429		// possibility.
430		resultStr, ok := test[witnessOffset+3].(string)
431		if !ok {
432			t.Errorf("%s: result field is not a string", name)
433			continue
434		}
435		allowedErrorCodes, err := parseExpectedResult(resultStr)
436		if err != nil {
437			t.Errorf("%s: %v", name, err)
438			continue
439		}
440
441		// Generate a transaction pair such that one spends from the
442		// other and the provided signature and public key scripts are
443		// used, then create a new engine to execute the scripts.
444		tx := createSpendingTx(witness, scriptSig, scriptPubKey,
445			int64(inputAmt))
446		vm, err := NewEngine(scriptPubKey, tx, 0, flags, sigCache, nil,
447			int64(inputAmt))
448		if err == nil {
449			err = vm.Execute()
450		}
451
452		// Ensure there were no errors when the expected result is OK.
453		if resultStr == "OK" {
454			if err != nil {
455				t.Errorf("%s failed to execute: %v", name, err)
456			}
457			continue
458		}
459
460		// At this point an error was expected so ensure the result of
461		// the execution matches it.
462		success := false
463		for _, code := range allowedErrorCodes {
464			if IsErrorCode(err, code) {
465				success = true
466				break
467			}
468		}
469		if !success {
470			if serr, ok := err.(Error); ok {
471				t.Errorf("%s: want error codes %v, got %v", name,
472					allowedErrorCodes, serr.ErrorCode)
473				continue
474			}
475			t.Errorf("%s: want error codes %v, got err: %v (%T)",
476				name, allowedErrorCodes, err, err)
477			continue
478		}
479	}
480}
481
482// TestScripts ensures all of the tests in script_tests.json execute with the
483// expected results as defined in the test data.
484func TestScripts(t *testing.T) {
485	file, err := ioutil.ReadFile("data/script_tests.json")
486	if err != nil {
487		t.Fatalf("TestScripts: %v\n", err)
488	}
489
490	var tests [][]interface{}
491	err = json.Unmarshal(file, &tests)
492	if err != nil {
493		t.Fatalf("TestScripts couldn't Unmarshal: %v", err)
494	}
495
496	// Run all script tests with and without the signature cache.
497	testScripts(t, tests, true)
498	testScripts(t, tests, false)
499}
500
501// testVecF64ToUint32 properly handles conversion of float64s read from the JSON
502// test data to unsigned 32-bit integers.  This is necessary because some of the
503// test data uses -1 as a shortcut to mean max uint32 and direct conversion of a
504// negative float to an unsigned int is implementation dependent and therefore
505// doesn't result in the expected value on all platforms.  This function woks
506// around that limitation by converting to a 32-bit signed integer first and
507// then to a 32-bit unsigned integer which results in the expected behavior on
508// all platforms.
509func testVecF64ToUint32(f float64) uint32 {
510	return uint32(int32(f))
511}
512
513// TestTxInvalidTests ensures all of the tests in tx_invalid.json fail as
514// expected.
515func TestTxInvalidTests(t *testing.T) {
516	file, err := ioutil.ReadFile("data/tx_invalid.json")
517	if err != nil {
518		t.Fatalf("TestTxInvalidTests: %v\n", err)
519	}
520
521	var tests [][]interface{}
522	err = json.Unmarshal(file, &tests)
523	if err != nil {
524		t.Fatalf("TestTxInvalidTests couldn't Unmarshal: %v\n", err)
525	}
526
527	// form is either:
528	//   ["this is a comment "]
529	// or:
530	//   [[[previous hash, previous index, previous scriptPubKey]...,]
531	//	serializedTransaction, verifyFlags]
532testloop:
533	for i, test := range tests {
534		inputs, ok := test[0].([]interface{})
535		if !ok {
536			continue
537		}
538
539		if len(test) != 3 {
540			t.Errorf("bad test (bad length) %d: %v", i, test)
541			continue
542
543		}
544		serializedhex, ok := test[1].(string)
545		if !ok {
546			t.Errorf("bad test (arg 2 not string) %d: %v", i, test)
547			continue
548		}
549		serializedTx, err := hex.DecodeString(serializedhex)
550		if err != nil {
551			t.Errorf("bad test (arg 2 not hex %v) %d: %v", err, i,
552				test)
553			continue
554		}
555
556		tx, err := btcutil.NewTxFromBytes(serializedTx)
557		if err != nil {
558			t.Errorf("bad test (arg 2 not msgtx %v) %d: %v", err,
559				i, test)
560			continue
561		}
562
563		verifyFlags, ok := test[2].(string)
564		if !ok {
565			t.Errorf("bad test (arg 3 not string) %d: %v", i, test)
566			continue
567		}
568
569		flags, err := parseScriptFlags(verifyFlags)
570		if err != nil {
571			t.Errorf("bad test %d: %v", i, err)
572			continue
573		}
574
575		prevOuts := make(map[wire.OutPoint]scriptWithInputVal)
576		for j, iinput := range inputs {
577			input, ok := iinput.([]interface{})
578			if !ok {
579				t.Errorf("bad test (%dth input not array)"+
580					"%d: %v", j, i, test)
581				continue testloop
582			}
583
584			if len(input) < 3 || len(input) > 4 {
585				t.Errorf("bad test (%dth input wrong length)"+
586					"%d: %v", j, i, test)
587				continue testloop
588			}
589
590			previoustx, ok := input[0].(string)
591			if !ok {
592				t.Errorf("bad test (%dth input hash not string)"+
593					"%d: %v", j, i, test)
594				continue testloop
595			}
596
597			prevhash, err := chainhash.NewHashFromStr(previoustx)
598			if err != nil {
599				t.Errorf("bad test (%dth input hash not hash %v)"+
600					"%d: %v", j, err, i, test)
601				continue testloop
602			}
603
604			idxf, ok := input[1].(float64)
605			if !ok {
606				t.Errorf("bad test (%dth input idx not number)"+
607					"%d: %v", j, i, test)
608				continue testloop
609			}
610			idx := testVecF64ToUint32(idxf)
611
612			oscript, ok := input[2].(string)
613			if !ok {
614				t.Errorf("bad test (%dth input script not "+
615					"string) %d: %v", j, i, test)
616				continue testloop
617			}
618
619			script, err := parseShortForm(oscript)
620			if err != nil {
621				t.Errorf("bad test (%dth input script doesn't "+
622					"parse %v) %d: %v", j, err, i, test)
623				continue testloop
624			}
625
626			var inputValue float64
627			if len(input) == 4 {
628				inputValue, ok = input[3].(float64)
629				if !ok {
630					t.Errorf("bad test (%dth input value not int) "+
631						"%d: %v", j, i, test)
632					continue
633				}
634			}
635
636			v := scriptWithInputVal{
637				inputVal: int64(inputValue),
638				pkScript: script,
639			}
640			prevOuts[*wire.NewOutPoint(prevhash, idx)] = v
641		}
642
643		for k, txin := range tx.MsgTx().TxIn {
644			prevOut, ok := prevOuts[txin.PreviousOutPoint]
645			if !ok {
646				t.Errorf("bad test (missing %dth input) %d:%v",
647					k, i, test)
648				continue testloop
649			}
650			// These are meant to fail, so as soon as the first
651			// input fails the transaction has failed. (some of the
652			// test txns have good inputs, too..
653			vm, err := NewEngine(prevOut.pkScript, tx.MsgTx(), k,
654				flags, nil, nil, prevOut.inputVal)
655			if err != nil {
656				continue testloop
657			}
658
659			err = vm.Execute()
660			if err != nil {
661				continue testloop
662			}
663
664		}
665		t.Errorf("test (%d:%v) succeeded when should fail",
666			i, test)
667	}
668}
669
670// TestTxValidTests ensures all of the tests in tx_valid.json pass as expected.
671func TestTxValidTests(t *testing.T) {
672	file, err := ioutil.ReadFile("data/tx_valid.json")
673	if err != nil {
674		t.Fatalf("TestTxValidTests: %v\n", err)
675	}
676
677	var tests [][]interface{}
678	err = json.Unmarshal(file, &tests)
679	if err != nil {
680		t.Fatalf("TestTxValidTests couldn't Unmarshal: %v\n", err)
681	}
682
683	// form is either:
684	//   ["this is a comment "]
685	// or:
686	//   [[[previous hash, previous index, previous scriptPubKey, input value]...,]
687	//	serializedTransaction, verifyFlags]
688testloop:
689	for i, test := range tests {
690		inputs, ok := test[0].([]interface{})
691		if !ok {
692			continue
693		}
694
695		if len(test) != 3 {
696			t.Errorf("bad test (bad length) %d: %v", i, test)
697			continue
698		}
699		serializedhex, ok := test[1].(string)
700		if !ok {
701			t.Errorf("bad test (arg 2 not string) %d: %v", i, test)
702			continue
703		}
704		serializedTx, err := hex.DecodeString(serializedhex)
705		if err != nil {
706			t.Errorf("bad test (arg 2 not hex %v) %d: %v", err, i,
707				test)
708			continue
709		}
710
711		tx, err := btcutil.NewTxFromBytes(serializedTx)
712		if err != nil {
713			t.Errorf("bad test (arg 2 not msgtx %v) %d: %v", err,
714				i, test)
715			continue
716		}
717
718		verifyFlags, ok := test[2].(string)
719		if !ok {
720			t.Errorf("bad test (arg 3 not string) %d: %v", i, test)
721			continue
722		}
723
724		flags, err := parseScriptFlags(verifyFlags)
725		if err != nil {
726			t.Errorf("bad test %d: %v", i, err)
727			continue
728		}
729
730		prevOuts := make(map[wire.OutPoint]scriptWithInputVal)
731		for j, iinput := range inputs {
732			input, ok := iinput.([]interface{})
733			if !ok {
734				t.Errorf("bad test (%dth input not array)"+
735					"%d: %v", j, i, test)
736				continue
737			}
738
739			if len(input) < 3 || len(input) > 4 {
740				t.Errorf("bad test (%dth input wrong length)"+
741					"%d: %v", j, i, test)
742				continue
743			}
744
745			previoustx, ok := input[0].(string)
746			if !ok {
747				t.Errorf("bad test (%dth input hash not string)"+
748					"%d: %v", j, i, test)
749				continue
750			}
751
752			prevhash, err := chainhash.NewHashFromStr(previoustx)
753			if err != nil {
754				t.Errorf("bad test (%dth input hash not hash %v)"+
755					"%d: %v", j, err, i, test)
756				continue
757			}
758
759			idxf, ok := input[1].(float64)
760			if !ok {
761				t.Errorf("bad test (%dth input idx not number)"+
762					"%d: %v", j, i, test)
763				continue
764			}
765			idx := testVecF64ToUint32(idxf)
766
767			oscript, ok := input[2].(string)
768			if !ok {
769				t.Errorf("bad test (%dth input script not "+
770					"string) %d: %v", j, i, test)
771				continue
772			}
773
774			script, err := parseShortForm(oscript)
775			if err != nil {
776				t.Errorf("bad test (%dth input script doesn't "+
777					"parse %v) %d: %v", j, err, i, test)
778				continue
779			}
780
781			var inputValue float64
782			if len(input) == 4 {
783				inputValue, ok = input[3].(float64)
784				if !ok {
785					t.Errorf("bad test (%dth input value not int) "+
786						"%d: %v", j, i, test)
787					continue
788				}
789			}
790
791			v := scriptWithInputVal{
792				inputVal: int64(inputValue),
793				pkScript: script,
794			}
795			prevOuts[*wire.NewOutPoint(prevhash, idx)] = v
796		}
797
798		for k, txin := range tx.MsgTx().TxIn {
799			prevOut, ok := prevOuts[txin.PreviousOutPoint]
800			if !ok {
801				t.Errorf("bad test (missing %dth input) %d:%v",
802					k, i, test)
803				continue testloop
804			}
805			vm, err := NewEngine(prevOut.pkScript, tx.MsgTx(), k,
806				flags, nil, nil, prevOut.inputVal)
807			if err != nil {
808				t.Errorf("test (%d:%v:%d) failed to create "+
809					"script: %v", i, test, k, err)
810				continue
811			}
812
813			err = vm.Execute()
814			if err != nil {
815				t.Errorf("test (%d:%v:%d) failed to execute: "+
816					"%v", i, test, k, err)
817				continue
818			}
819		}
820	}
821}
822
823// TestCalcSignatureHash runs the Bitcoin Core signature hash calculation tests
824// in sighash.json.
825// https://github.com/bitcoin/bitcoin/blob/master/src/test/data/sighash.json
826func TestCalcSignatureHash(t *testing.T) {
827	file, err := ioutil.ReadFile("data/sighash.json")
828	if err != nil {
829		t.Fatalf("TestCalcSignatureHash: %v\n", err)
830	}
831
832	var tests [][]interface{}
833	err = json.Unmarshal(file, &tests)
834	if err != nil {
835		t.Fatalf("TestCalcSignatureHash couldn't Unmarshal: %v\n",
836			err)
837	}
838
839	for i, test := range tests {
840		if i == 0 {
841			// Skip first line -- contains comments only.
842			continue
843		}
844		if len(test) != 5 {
845			t.Fatalf("TestCalcSignatureHash: Test #%d has "+
846				"wrong length.", i)
847		}
848		var tx wire.MsgTx
849		rawTx, _ := hex.DecodeString(test[0].(string))
850		err := tx.Deserialize(bytes.NewReader(rawTx))
851		if err != nil {
852			t.Errorf("TestCalcSignatureHash failed test #%d: "+
853				"Failed to parse transaction: %v", i, err)
854			continue
855		}
856
857		subScript, _ := hex.DecodeString(test[1].(string))
858		parsedScript, err := parseScript(subScript)
859		if err != nil {
860			t.Errorf("TestCalcSignatureHash failed test #%d: "+
861				"Failed to parse sub-script: %v", i, err)
862			continue
863		}
864
865		hashType := SigHashType(testVecF64ToUint32(test[3].(float64)))
866		hash := calcSignatureHash(parsedScript, hashType, &tx,
867			int(test[2].(float64)))
868
869		expectedHash, _ := chainhash.NewHashFromStr(test[4].(string))
870		if !bytes.Equal(hash, expectedHash[:]) {
871			t.Errorf("TestCalcSignatureHash failed test #%d: "+
872				"Signature hash mismatch.", i)
873		}
874	}
875}
876