reference_test.go raw

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