github.com/palcoin-project/palcd@v1.0.0/txscript/reference_test.go (about) 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 5 package txscript 6 7 import ( 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/palcoin-project/palcd/chaincfg/chainhash" 19 "github.com/palcoin-project/palcd/wire" 20 "github.com/palcoin-project/palcutil" 21 ) 22 23 // scriptTestName returns a descriptive test name for the given reference script 24 // test data. 25 func 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. 53 func 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. 62 func 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. 78 var 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 91 func 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. 153 func 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. 205 func 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. 296 func 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. 322 type 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. 330 func 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 palcutil.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 = palcutil.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. 484 func 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. 509 func 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. 515 func 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] 532 testloop: 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 := palcutil.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. 671 func 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] 688 testloop: 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 := palcutil.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 826 func 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 }