github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/txscript/reference_test.go (about)

     1  // Copyright (c) 2013-2015 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package txscript_test
     7  
     8  import (
     9  	"bytes"
    10  	"encoding/hex"
    11  	"encoding/json"
    12  	"errors"
    13  	"fmt"
    14  	"io/ioutil"
    15  	"strconv"
    16  	"strings"
    17  	"testing"
    18  
    19  	. "github.com/dashpay/godash/txscript"
    20  	"github.com/dashpay/godash/wire"
    21  	"github.com/dashpay/godashutil"
    22  )
    23  
    24  // testName returns a descriptive test name for the given reference test data.
    25  func testName(test []string) (string, error) {
    26  	var name string
    27  
    28  	if len(test) < 3 || len(test) > 4 {
    29  		return name, fmt.Errorf("invalid test length %d", len(test))
    30  	}
    31  
    32  	if len(test) == 4 {
    33  		name = fmt.Sprintf("test (%s)", test[3])
    34  	} else {
    35  		name = fmt.Sprintf("test ([%s, %s, %s])", test[0], test[1],
    36  			test[2])
    37  	}
    38  	return name, nil
    39  }
    40  
    41  // parse hex string into a []byte.
    42  func parseHex(tok string) ([]byte, error) {
    43  	if !strings.HasPrefix(tok, "0x") {
    44  		return nil, errors.New("not a hex number")
    45  	}
    46  	return hex.DecodeString(tok[2:])
    47  }
    48  
    49  // shortFormOps holds a map of opcode names to values for use in short form
    50  // parsing.  It is declared here so it only needs to be created once.
    51  var shortFormOps map[string]byte
    52  
    53  // parseShortForm parses a string as as used in the Bitcoin Core reference tests
    54  // into the script it came from.
    55  //
    56  // The format used for these tests is pretty simple if ad-hoc:
    57  //   - Opcodes other than the push opcodes and unknown are present as
    58  //     either OP_NAME or just NAME
    59  //   - Plain numbers are made into push operations
    60  //   - Numbers beginning with 0x are inserted into the []byte as-is (so
    61  //     0x14 is OP_DATA_20)
    62  //   - Single quoted strings are pushed as data
    63  //   - Anything else is an error
    64  func parseShortForm(script string) ([]byte, error) {
    65  	// Only create the short form opcode map once.
    66  	if shortFormOps == nil {
    67  		ops := make(map[string]byte)
    68  		for opcodeName, opcodeValue := range OpcodeByName {
    69  			if strings.Contains(opcodeName, "OP_UNKNOWN") {
    70  				continue
    71  			}
    72  			ops[opcodeName] = opcodeValue
    73  
    74  			// The opcodes named OP_# can't have the OP_ prefix
    75  			// stripped or they would conflict with the plain
    76  			// numbers.  Also, since OP_FALSE and OP_TRUE are
    77  			// aliases for the OP_0, and OP_1, respectively, they
    78  			// have the same value, so detect those by name and
    79  			// allow them.
    80  			if (opcodeName == "OP_FALSE" || opcodeName == "OP_TRUE") ||
    81  				(opcodeValue != OP_0 && (opcodeValue < OP_1 ||
    82  					opcodeValue > OP_16)) {
    83  
    84  				ops[strings.TrimPrefix(opcodeName, "OP_")] = opcodeValue
    85  			}
    86  		}
    87  		shortFormOps = ops
    88  	}
    89  
    90  	// Split only does one separator so convert all \n and tab into  space.
    91  	script = strings.Replace(script, "\n", " ", -1)
    92  	script = strings.Replace(script, "\t", " ", -1)
    93  	tokens := strings.Split(script, " ")
    94  	builder := NewScriptBuilder()
    95  
    96  	for _, tok := range tokens {
    97  		if len(tok) == 0 {
    98  			continue
    99  		}
   100  		// if parses as a plain number
   101  		if num, err := strconv.ParseInt(tok, 10, 64); err == nil {
   102  			builder.AddInt64(num)
   103  			continue
   104  		} else if bts, err := parseHex(tok); err == nil {
   105  			builder.TstConcatRawScript(bts)
   106  		} else if len(tok) >= 2 &&
   107  			tok[0] == '\'' && tok[len(tok)-1] == '\'' {
   108  			builder.AddFullData([]byte(tok[1 : len(tok)-1]))
   109  		} else if opcode, ok := shortFormOps[tok]; ok {
   110  			builder.AddOp(opcode)
   111  		} else {
   112  			return nil, fmt.Errorf("bad token \"%s\"", tok)
   113  		}
   114  
   115  	}
   116  	return builder.Script()
   117  }
   118  
   119  // parseScriptFlags parses the provided flags string from the format used in the
   120  // reference tests into ScriptFlags suitable for use in the script engine.
   121  func parseScriptFlags(flagStr string) (ScriptFlags, error) {
   122  	var flags ScriptFlags
   123  
   124  	sFlags := strings.Split(flagStr, ",")
   125  	for _, flag := range sFlags {
   126  		switch flag {
   127  		case "":
   128  			// Nothing.
   129  		case "CHECKLOCKTIMEVERIFY":
   130  			flags |= ScriptVerifyCheckLockTimeVerify
   131  		case "CLEANSTACK":
   132  			flags |= ScriptVerifyCleanStack
   133  		case "DERSIG":
   134  			flags |= ScriptVerifyDERSignatures
   135  		case "DISCOURAGE_UPGRADABLE_NOPS":
   136  			flags |= ScriptDiscourageUpgradableNops
   137  		case "LOW_S":
   138  			flags |= ScriptVerifyLowS
   139  		case "MINIMALDATA":
   140  			flags |= ScriptVerifyMinimalData
   141  		case "NONE":
   142  			// Nothing.
   143  		case "NULLDUMMY":
   144  			flags |= ScriptStrictMultiSig
   145  		case "P2SH":
   146  			flags |= ScriptBip16
   147  		case "SIGPUSHONLY":
   148  			flags |= ScriptVerifySigPushOnly
   149  		case "STRICTENC":
   150  			flags |= ScriptVerifyStrictEncoding
   151  		default:
   152  			return flags, fmt.Errorf("invalid flag: %s", flag)
   153  		}
   154  	}
   155  	return flags, nil
   156  }
   157  
   158  // createSpendTx generates a basic spending transaction given the passed
   159  // signature and public key scripts.
   160  func createSpendingTx(sigScript, pkScript []byte) *wire.MsgTx {
   161  	coinbaseTx := wire.NewMsgTx()
   162  
   163  	outPoint := wire.NewOutPoint(&wire.ShaHash{}, ^uint32(0))
   164  	txIn := wire.NewTxIn(outPoint, []byte{OP_0, OP_0})
   165  	txOut := wire.NewTxOut(0, pkScript)
   166  	coinbaseTx.AddTxIn(txIn)
   167  	coinbaseTx.AddTxOut(txOut)
   168  
   169  	spendingTx := wire.NewMsgTx()
   170  	coinbaseTxSha := coinbaseTx.TxSha()
   171  	outPoint = wire.NewOutPoint(&coinbaseTxSha, 0)
   172  	txIn = wire.NewTxIn(outPoint, sigScript)
   173  	txOut = wire.NewTxOut(0, nil)
   174  
   175  	spendingTx.AddTxIn(txIn)
   176  	spendingTx.AddTxOut(txOut)
   177  
   178  	return spendingTx
   179  }
   180  
   181  // TestScriptInvalidTests ensures all of the tests in script_invalid.json fail
   182  // as expected.
   183  func TestScriptInvalidTests(t *testing.T) {
   184  	file, err := ioutil.ReadFile("data/script_invalid.json")
   185  	if err != nil {
   186  		t.Errorf("TestBitcoindInvalidTests: %v\n", err)
   187  		return
   188  	}
   189  
   190  	var tests [][]string
   191  	err = json.Unmarshal(file, &tests)
   192  	if err != nil {
   193  		t.Errorf("TestBitcoindInvalidTests couldn't Unmarshal: %v",
   194  			err)
   195  		return
   196  	}
   197  	sigCache := NewSigCache(10)
   198  
   199  	sigCacheToggle := []bool{true, false}
   200  	for _, useSigCache := range sigCacheToggle {
   201  		for i, test := range tests {
   202  			// Skip comments
   203  			if len(test) == 1 {
   204  				continue
   205  			}
   206  			name, err := testName(test)
   207  			if err != nil {
   208  				t.Errorf("TestBitcoindInvalidTests: invalid test #%d",
   209  					i)
   210  				continue
   211  			}
   212  			scriptSig, err := parseShortForm(test[0])
   213  			if err != nil {
   214  				t.Errorf("%s: can't parse scriptSig; %v", name, err)
   215  				continue
   216  			}
   217  			scriptPubKey, err := parseShortForm(test[1])
   218  			if err != nil {
   219  				t.Errorf("%s: can't parse scriptPubkey; %v", name, err)
   220  				continue
   221  			}
   222  			flags, err := parseScriptFlags(test[2])
   223  			if err != nil {
   224  				t.Errorf("%s: %v", name, err)
   225  				continue
   226  			}
   227  			tx := createSpendingTx(scriptSig, scriptPubKey)
   228  
   229  			var vm *Engine
   230  			if useSigCache {
   231  				vm, err = NewEngine(scriptPubKey, tx, 0, flags, sigCache)
   232  			} else {
   233  				vm, err = NewEngine(scriptPubKey, tx, 0, flags, nil)
   234  			}
   235  
   236  			if err == nil {
   237  				if err := vm.Execute(); err == nil {
   238  					t.Errorf("%s test succeeded when it "+
   239  						"should have failed\n", name)
   240  				}
   241  				continue
   242  			}
   243  		}
   244  	}
   245  }
   246  
   247  // TestScriptValidTests ensures all of the tests in script_valid.json pass as
   248  // expected.
   249  func TestScriptValidTests(t *testing.T) {
   250  	file, err := ioutil.ReadFile("data/script_valid.json")
   251  	if err != nil {
   252  		t.Errorf("TestBitcoinValidTests: %v\n", err)
   253  		return
   254  	}
   255  
   256  	var tests [][]string
   257  	err = json.Unmarshal(file, &tests)
   258  	if err != nil {
   259  		t.Errorf("TestBitcoindValidTests couldn't Unmarshal: %v",
   260  			err)
   261  		return
   262  	}
   263  
   264  	sigCache := NewSigCache(10)
   265  
   266  	sigCacheToggle := []bool{true, false}
   267  	for _, useSigCache := range sigCacheToggle {
   268  		for i, test := range tests {
   269  			// Skip comments
   270  			if len(test) == 1 {
   271  				continue
   272  			}
   273  			name, err := testName(test)
   274  			if err != nil {
   275  				t.Errorf("TestBitcoindValidTests: invalid test #%d",
   276  					i)
   277  				continue
   278  			}
   279  			scriptSig, err := parseShortForm(test[0])
   280  			if err != nil {
   281  				t.Errorf("%s: can't parse scriptSig; %v", name, err)
   282  				continue
   283  			}
   284  			scriptPubKey, err := parseShortForm(test[1])
   285  			if err != nil {
   286  				t.Errorf("%s: can't parse scriptPubkey; %v", name, err)
   287  				continue
   288  			}
   289  			flags, err := parseScriptFlags(test[2])
   290  			if err != nil {
   291  				t.Errorf("%s: %v", name, err)
   292  				continue
   293  			}
   294  			tx := createSpendingTx(scriptSig, scriptPubKey)
   295  
   296  			var vm *Engine
   297  			if useSigCache {
   298  				vm, err = NewEngine(scriptPubKey, tx, 0, flags, sigCache)
   299  			} else {
   300  				vm, err = NewEngine(scriptPubKey, tx, 0, flags, nil)
   301  			}
   302  
   303  			if err != nil {
   304  				t.Errorf("%s failed to create script: %v", name, err)
   305  				continue
   306  			}
   307  			err = vm.Execute()
   308  			if err != nil {
   309  				t.Errorf("%s failed to execute: %v", name, err)
   310  				continue
   311  			}
   312  		}
   313  	}
   314  }
   315  
   316  // testVecF64ToUint32 properly handles conversion of float64s read from the JSON
   317  // test data to unsigned 32-bit integers.  This is necessary because some of the
   318  // test data uses -1 as a shortcut to mean max uint32 and direct conversion of a
   319  // negative float to an unsigned int is implementation dependent and therefore
   320  // doesn't result in the expected value on all platforms.  This function woks
   321  // around that limitation by converting to a 32-bit signed integer first and
   322  // then to a 32-bit unsigned integer which results in the expected behavior on
   323  // all platforms.
   324  func testVecF64ToUint32(f float64) uint32 {
   325  	return uint32(int32(f))
   326  }
   327  
   328  // TestTxInvalidTests ensures all of the tests in tx_invalid.json fail as
   329  // expected.
   330  func TestTxInvalidTests(t *testing.T) {
   331  	file, err := ioutil.ReadFile("data/tx_invalid.json")
   332  	if err != nil {
   333  		t.Errorf("TestTxInvalidTests: %v\n", err)
   334  		return
   335  	}
   336  
   337  	var tests [][]interface{}
   338  	err = json.Unmarshal(file, &tests)
   339  	if err != nil {
   340  		t.Errorf("TestTxInvalidTests couldn't Unmarshal: %v\n", err)
   341  		return
   342  	}
   343  
   344  	// form is either:
   345  	//   ["this is a comment "]
   346  	// or:
   347  	//   [[[previous hash, previous index, previous scriptPubKey]...,]
   348  	//	serializedTransaction, verifyFlags]
   349  testloop:
   350  	for i, test := range tests {
   351  		inputs, ok := test[0].([]interface{})
   352  		if !ok {
   353  			continue
   354  		}
   355  
   356  		if len(test) != 3 {
   357  			t.Errorf("bad test (bad length) %d: %v", i, test)
   358  			continue
   359  
   360  		}
   361  		serializedhex, ok := test[1].(string)
   362  		if !ok {
   363  			t.Errorf("bad test (arg 2 not string) %d: %v", i, test)
   364  			continue
   365  		}
   366  		serializedTx, err := hex.DecodeString(serializedhex)
   367  		if err != nil {
   368  			t.Errorf("bad test (arg 2 not hex %v) %d: %v", err, i,
   369  				test)
   370  			continue
   371  		}
   372  
   373  		tx, err := godashutil.NewTxFromBytes(serializedTx)
   374  		if err != nil {
   375  			t.Errorf("bad test (arg 2 not msgtx %v) %d: %v", err,
   376  				i, test)
   377  			continue
   378  		}
   379  
   380  		verifyFlags, ok := test[2].(string)
   381  		if !ok {
   382  			t.Errorf("bad test (arg 3 not string) %d: %v", i, test)
   383  			continue
   384  		}
   385  
   386  		flags, err := parseScriptFlags(verifyFlags)
   387  		if err != nil {
   388  			t.Errorf("bad test %d: %v", i, err)
   389  			continue
   390  		}
   391  
   392  		prevOuts := make(map[wire.OutPoint][]byte)
   393  		for j, iinput := range inputs {
   394  			input, ok := iinput.([]interface{})
   395  			if !ok {
   396  				t.Errorf("bad test (%dth input not array)"+
   397  					"%d: %v", j, i, test)
   398  				continue testloop
   399  			}
   400  
   401  			if len(input) != 3 {
   402  				t.Errorf("bad test (%dth input wrong length)"+
   403  					"%d: %v", j, i, test)
   404  				continue testloop
   405  			}
   406  
   407  			previoustx, ok := input[0].(string)
   408  			if !ok {
   409  				t.Errorf("bad test (%dth input sha not string)"+
   410  					"%d: %v", j, i, test)
   411  				continue testloop
   412  			}
   413  
   414  			prevhash, err := wire.NewShaHashFromStr(previoustx)
   415  			if err != nil {
   416  				t.Errorf("bad test (%dth input sha not sha %v)"+
   417  					"%d: %v", j, err, i, test)
   418  				continue testloop
   419  			}
   420  
   421  			idxf, ok := input[1].(float64)
   422  			if !ok {
   423  				t.Errorf("bad test (%dth input idx not number)"+
   424  					"%d: %v", j, i, test)
   425  				continue testloop
   426  			}
   427  			idx := testVecF64ToUint32(idxf)
   428  
   429  			oscript, ok := input[2].(string)
   430  			if !ok {
   431  				t.Errorf("bad test (%dth input script not "+
   432  					"string) %d: %v", j, i, test)
   433  				continue testloop
   434  			}
   435  
   436  			script, err := parseShortForm(oscript)
   437  			if err != nil {
   438  				t.Errorf("bad test (%dth input script doesn't "+
   439  					"parse %v) %d: %v", j, err, i, test)
   440  				continue testloop
   441  			}
   442  
   443  			prevOuts[*wire.NewOutPoint(prevhash, idx)] = script
   444  		}
   445  
   446  		for k, txin := range tx.MsgTx().TxIn {
   447  			pkScript, ok := prevOuts[txin.PreviousOutPoint]
   448  			if !ok {
   449  				t.Errorf("bad test (missing %dth input) %d:%v",
   450  					k, i, test)
   451  				continue testloop
   452  			}
   453  			// These are meant to fail, so as soon as the first
   454  			// input fails the transaction has failed. (some of the
   455  			// test txns have good inputs, too..
   456  			vm, err := NewEngine(pkScript, tx.MsgTx(), k, flags, nil)
   457  			if err != nil {
   458  				continue testloop
   459  			}
   460  
   461  			err = vm.Execute()
   462  			if err != nil {
   463  				continue testloop
   464  			}
   465  
   466  		}
   467  		t.Errorf("test (%d:%v) succeeded when should fail",
   468  			i, test)
   469  	}
   470  }
   471  
   472  // TestTxValidTests ensures all of the tests in tx_valid.json pass as expected.
   473  func TestTxValidTests(t *testing.T) {
   474  	file, err := ioutil.ReadFile("data/tx_valid.json")
   475  	if err != nil {
   476  		t.Errorf("TestTxValidTests: %v\n", err)
   477  		return
   478  	}
   479  
   480  	var tests [][]interface{}
   481  	err = json.Unmarshal(file, &tests)
   482  	if err != nil {
   483  		t.Errorf("TestTxValidTests couldn't Unmarshal: %v\n", err)
   484  		return
   485  	}
   486  
   487  	// form is either:
   488  	//   ["this is a comment "]
   489  	// or:
   490  	//   [[[previous hash, previous index, previous scriptPubKey]...,]
   491  	//	serializedTransaction, verifyFlags]
   492  testloop:
   493  	for i, test := range tests {
   494  		inputs, ok := test[0].([]interface{})
   495  		if !ok {
   496  			continue
   497  		}
   498  
   499  		if len(test) != 3 {
   500  			t.Errorf("bad test (bad length) %d: %v", i, test)
   501  			continue
   502  		}
   503  		serializedhex, ok := test[1].(string)
   504  		if !ok {
   505  			t.Errorf("bad test (arg 2 not string) %d: %v", i, test)
   506  			continue
   507  		}
   508  		serializedTx, err := hex.DecodeString(serializedhex)
   509  		if err != nil {
   510  			t.Errorf("bad test (arg 2 not hex %v) %d: %v", err, i,
   511  				test)
   512  			continue
   513  		}
   514  
   515  		tx, err := godashutil.NewTxFromBytes(serializedTx)
   516  		if err != nil {
   517  			t.Errorf("bad test (arg 2 not msgtx %v) %d: %v", err,
   518  				i, test)
   519  			continue
   520  		}
   521  
   522  		verifyFlags, ok := test[2].(string)
   523  		if !ok {
   524  			t.Errorf("bad test (arg 3 not string) %d: %v", i, test)
   525  			continue
   526  		}
   527  
   528  		flags, err := parseScriptFlags(verifyFlags)
   529  		if err != nil {
   530  			t.Errorf("bad test %d: %v", i, err)
   531  			continue
   532  		}
   533  
   534  		prevOuts := make(map[wire.OutPoint][]byte)
   535  		for j, iinput := range inputs {
   536  			input, ok := iinput.([]interface{})
   537  			if !ok {
   538  				t.Errorf("bad test (%dth input not array)"+
   539  					"%d: %v", j, i, test)
   540  				continue
   541  			}
   542  
   543  			if len(input) != 3 {
   544  				t.Errorf("bad test (%dth input wrong length)"+
   545  					"%d: %v", j, i, test)
   546  				continue
   547  			}
   548  
   549  			previoustx, ok := input[0].(string)
   550  			if !ok {
   551  				t.Errorf("bad test (%dth input sha not string)"+
   552  					"%d: %v", j, i, test)
   553  				continue
   554  			}
   555  
   556  			prevhash, err := wire.NewShaHashFromStr(previoustx)
   557  			if err != nil {
   558  				t.Errorf("bad test (%dth input sha not sha %v)"+
   559  					"%d: %v", j, err, i, test)
   560  				continue
   561  			}
   562  
   563  			idxf, ok := input[1].(float64)
   564  			if !ok {
   565  				t.Errorf("bad test (%dth input idx not number)"+
   566  					"%d: %v", j, i, test)
   567  				continue
   568  			}
   569  			idx := testVecF64ToUint32(idxf)
   570  
   571  			oscript, ok := input[2].(string)
   572  			if !ok {
   573  				t.Errorf("bad test (%dth input script not "+
   574  					"string) %d: %v", j, i, test)
   575  				continue
   576  			}
   577  
   578  			script, err := parseShortForm(oscript)
   579  			if err != nil {
   580  				t.Errorf("bad test (%dth input script doesn't "+
   581  					"parse %v) %d: %v", j, err, i, test)
   582  				continue
   583  			}
   584  
   585  			prevOuts[*wire.NewOutPoint(prevhash, idx)] = script
   586  		}
   587  
   588  		for k, txin := range tx.MsgTx().TxIn {
   589  			pkScript, ok := prevOuts[txin.PreviousOutPoint]
   590  			if !ok {
   591  				t.Errorf("bad test (missing %dth input) %d:%v",
   592  					k, i, test)
   593  				continue testloop
   594  			}
   595  			vm, err := NewEngine(pkScript, tx.MsgTx(), k, flags, nil)
   596  			if err != nil {
   597  				t.Errorf("test (%d:%v:%d) failed to create "+
   598  					"script: %v", i, test, k, err)
   599  				continue
   600  			}
   601  
   602  			err = vm.Execute()
   603  			if err != nil {
   604  				t.Errorf("test (%d:%v:%d) failed to execute: "+
   605  					"%v", i, test, k, err)
   606  				continue
   607  			}
   608  		}
   609  	}
   610  }
   611  
   612  // TestCalcSignatureHash runs the Bitcoin Core signature hash calculation tests
   613  // in sighash.json.
   614  // https://github.com/bitcoin/bitcoin/blob/master/src/test/data/sighash.json
   615  func TestCalcSignatureHash(t *testing.T) {
   616  	file, err := ioutil.ReadFile("data/sighash.json")
   617  	if err != nil {
   618  		t.Errorf("TestCalcSignatureHash: %v\n", err)
   619  		return
   620  	}
   621  
   622  	var tests [][]interface{}
   623  	err = json.Unmarshal(file, &tests)
   624  	if err != nil {
   625  		t.Errorf("TestCalcSignatureHash couldn't Unmarshal: %v\n",
   626  			err)
   627  		return
   628  	}
   629  
   630  	for i, test := range tests {
   631  		if i == 0 {
   632  			// Skip first line -- contains comments only.
   633  			continue
   634  		}
   635  		if len(test) != 5 {
   636  			t.Fatalf("TestCalcSignatureHash: Test #%d has "+
   637  				"wrong length.", i)
   638  		}
   639  		tx := wire.NewMsgTx()
   640  		rawTx, _ := hex.DecodeString(test[0].(string))
   641  		err := tx.Deserialize(bytes.NewReader(rawTx))
   642  		if err != nil {
   643  			t.Errorf("TestCalcSignatureHash failed test #%d: "+
   644  				"Failed to parse transaction: %v", i, err)
   645  			continue
   646  		}
   647  
   648  		subScript, _ := hex.DecodeString(test[1].(string))
   649  		parsedScript, err := TstParseScript(subScript)
   650  		if err != nil {
   651  			t.Errorf("TestCalcSignatureHash failed test #%d: "+
   652  				"Failed to parse sub-script: %v", i, err)
   653  			continue
   654  		}
   655  
   656  		hashType := SigHashType(testVecF64ToUint32(test[3].(float64)))
   657  		hash := TstCalcSignatureHash(parsedScript, hashType, tx,
   658  			int(test[2].(float64)))
   659  
   660  		expectedHash, _ := wire.NewShaHashFromStr(test[4].(string))
   661  		if !bytes.Equal(hash, expectedHash.Bytes()) {
   662  			t.Errorf("TestCalcSignatureHash failed test #%d: "+
   663  				"Signature hash mismatch.", i)
   664  		}
   665  	}
   666  }