github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/txscript/stack_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 7 8 import ( 9 "bytes" 10 "errors" 11 "fmt" 12 "testing" 13 ) 14 15 // TestStack tests that all of the stack operations work as expected. 16 func TestStack(t *testing.T) { 17 t.Parallel() 18 19 tests := []struct { 20 name string 21 before [][]byte 22 operation func(*stack) error 23 expectedReturn error 24 after [][]byte 25 }{ 26 { 27 "noop", 28 [][]byte{{1}, {2}, {3}, {4}, {5}}, 29 func(s *stack) error { 30 return nil 31 }, 32 nil, 33 [][]byte{{1}, {2}, {3}, {4}, {5}}, 34 }, 35 { 36 "peek underflow (byte)", 37 [][]byte{{1}, {2}, {3}, {4}, {5}}, 38 func(s *stack) error { 39 _, err := s.PeekByteArray(5) 40 return err 41 }, 42 ErrStackUnderflow, 43 nil, 44 }, 45 { 46 "peek underflow (int)", 47 [][]byte{{1}, {2}, {3}, {4}, {5}}, 48 func(s *stack) error { 49 _, err := s.PeekInt(5) 50 return err 51 }, 52 ErrStackUnderflow, 53 nil, 54 }, 55 { 56 "peek underflow (bool)", 57 [][]byte{{1}, {2}, {3}, {4}, {5}}, 58 func(s *stack) error { 59 _, err := s.PeekBool(5) 60 return err 61 }, 62 ErrStackUnderflow, 63 nil, 64 }, 65 { 66 "pop", 67 [][]byte{{1}, {2}, {3}, {4}, {5}}, 68 func(s *stack) error { 69 val, err := s.PopByteArray() 70 if err != nil { 71 return err 72 } 73 if !bytes.Equal(val, []byte{5}) { 74 return errors.New("not equal") 75 } 76 return err 77 }, 78 nil, 79 [][]byte{{1}, {2}, {3}, {4}}, 80 }, 81 { 82 "pop everything", 83 [][]byte{{1}, {2}, {3}, {4}, {5}}, 84 func(s *stack) error { 85 for i := 0; i < 5; i++ { 86 _, err := s.PopByteArray() 87 if err != nil { 88 return err 89 } 90 } 91 return nil 92 }, 93 nil, 94 nil, 95 }, 96 { 97 "pop underflow", 98 [][]byte{{1}, {2}, {3}, {4}, {5}}, 99 func(s *stack) error { 100 for i := 0; i < 6; i++ { 101 _, err := s.PopByteArray() 102 if err != nil { 103 return err 104 } 105 } 106 return nil 107 }, 108 ErrStackUnderflow, 109 nil, 110 }, 111 { 112 "pop bool", 113 [][]byte{nil}, 114 func(s *stack) error { 115 val, err := s.PopBool() 116 if err != nil { 117 return err 118 } 119 120 if val != false { 121 return errors.New("unexpected value") 122 } 123 return nil 124 }, 125 nil, 126 nil, 127 }, 128 { 129 "pop bool", 130 [][]byte{{1}}, 131 func(s *stack) error { 132 val, err := s.PopBool() 133 if err != nil { 134 return err 135 } 136 137 if val != true { 138 return errors.New("unexpected value") 139 } 140 return nil 141 }, 142 nil, 143 nil, 144 }, 145 { 146 "pop bool", 147 nil, 148 func(s *stack) error { 149 _, err := s.PopBool() 150 if err != nil { 151 return err 152 } 153 154 return nil 155 }, 156 ErrStackUnderflow, 157 nil, 158 }, 159 { 160 "popInt 0", 161 [][]byte{{0x0}}, 162 func(s *stack) error { 163 v, err := s.PopInt() 164 if err != nil { 165 return err 166 } 167 if v != 0 { 168 return errors.New("0 != 0 on popInt") 169 } 170 return nil 171 }, 172 nil, 173 nil, 174 }, 175 { 176 "popInt -0", 177 [][]byte{{0x80}}, 178 func(s *stack) error { 179 v, err := s.PopInt() 180 if err != nil { 181 return err 182 } 183 if v != 0 { 184 return errors.New("-0 != 0 on popInt") 185 } 186 return nil 187 }, 188 nil, 189 nil, 190 }, 191 { 192 "popInt 1", 193 [][]byte{{0x01}}, 194 func(s *stack) error { 195 v, err := s.PopInt() 196 if err != nil { 197 return err 198 } 199 if v != 1 { 200 return errors.New("1 != 1 on popInt") 201 } 202 return nil 203 }, 204 nil, 205 nil, 206 }, 207 { 208 "popInt 1 leading 0", 209 [][]byte{{0x01, 0x00, 0x00, 0x00}}, 210 func(s *stack) error { 211 v, err := s.PopInt() 212 if err != nil { 213 return err 214 } 215 if v != 1 { 216 fmt.Printf("%v != %v\n", v, 1) 217 return errors.New("1 != 1 on popInt") 218 } 219 return nil 220 }, 221 nil, 222 nil, 223 }, 224 { 225 "popInt -1", 226 [][]byte{{0x81}}, 227 func(s *stack) error { 228 v, err := s.PopInt() 229 if err != nil { 230 return err 231 } 232 if v != -1 { 233 return errors.New("-1 != -1 on popInt") 234 } 235 return nil 236 }, 237 nil, 238 nil, 239 }, 240 { 241 "popInt -1 leading 0", 242 [][]byte{{0x01, 0x00, 0x00, 0x80}}, 243 func(s *stack) error { 244 v, err := s.PopInt() 245 if err != nil { 246 return err 247 } 248 if v != -1 { 249 fmt.Printf("%v != %v\n", v, -1) 250 return errors.New("-1 != -1 on popInt") 251 } 252 return nil 253 }, 254 nil, 255 nil, 256 }, 257 // Triggers the multibyte case in asInt 258 { 259 "popInt -513", 260 [][]byte{{0x1, 0x82}}, 261 func(s *stack) error { 262 v, err := s.PopInt() 263 if err != nil { 264 return err 265 } 266 if v != -513 { 267 fmt.Printf("%v != %v\n", v, -513) 268 return errors.New("1 != 1 on popInt") 269 } 270 return nil 271 }, 272 nil, 273 nil, 274 }, 275 // Confirm that the asInt code doesn't modify the base data. 276 { 277 "peekint nomodify -1", 278 [][]byte{{0x01, 0x00, 0x00, 0x80}}, 279 func(s *stack) error { 280 v, err := s.PeekInt(0) 281 if err != nil { 282 return err 283 } 284 if v != -1 { 285 fmt.Printf("%v != %v\n", v, -1) 286 return errors.New("-1 != -1 on popInt") 287 } 288 return nil 289 }, 290 nil, 291 [][]byte{{0x01, 0x00, 0x00, 0x80}}, 292 }, 293 { 294 "PushInt 0", 295 nil, 296 func(s *stack) error { 297 s.PushInt(scriptNum(0)) 298 return nil 299 }, 300 nil, 301 [][]byte{{}}, 302 }, 303 { 304 "PushInt 1", 305 nil, 306 func(s *stack) error { 307 s.PushInt(scriptNum(1)) 308 return nil 309 }, 310 nil, 311 [][]byte{{0x1}}, 312 }, 313 { 314 "PushInt -1", 315 nil, 316 func(s *stack) error { 317 s.PushInt(scriptNum(-1)) 318 return nil 319 }, 320 nil, 321 [][]byte{{0x81}}, 322 }, 323 { 324 "PushInt two bytes", 325 nil, 326 func(s *stack) error { 327 s.PushInt(scriptNum(256)) 328 return nil 329 }, 330 nil, 331 // little endian.. *sigh* 332 [][]byte{{0x00, 0x01}}, 333 }, 334 { 335 "PushInt leading zeros", 336 nil, 337 func(s *stack) error { 338 // this will have the highbit set 339 s.PushInt(scriptNum(128)) 340 return nil 341 }, 342 nil, 343 [][]byte{{0x80, 0x00}}, 344 }, 345 { 346 "dup", 347 [][]byte{{1}}, 348 func(s *stack) error { 349 err := s.DupN(1) 350 if err != nil { 351 return err 352 } 353 354 return nil 355 }, 356 nil, 357 [][]byte{{1}, {1}}, 358 }, 359 { 360 "dup2", 361 [][]byte{{1}, {2}}, 362 func(s *stack) error { 363 err := s.DupN(2) 364 if err != nil { 365 return err 366 } 367 368 return nil 369 }, 370 nil, 371 [][]byte{{1}, {2}, {1}, {2}}, 372 }, 373 { 374 "dup3", 375 [][]byte{{1}, {2}, {3}}, 376 func(s *stack) error { 377 err := s.DupN(3) 378 if err != nil { 379 return err 380 } 381 382 return nil 383 }, 384 nil, 385 [][]byte{{1}, {2}, {3}, {1}, {2}, {3}}, 386 }, 387 { 388 "dup0", 389 [][]byte{{1}}, 390 func(s *stack) error { 391 err := s.DupN(0) 392 if err != nil { 393 return err 394 } 395 396 return nil 397 }, 398 ErrStackInvalidArgs, 399 nil, 400 }, 401 { 402 "dup-1", 403 [][]byte{{1}}, 404 func(s *stack) error { 405 err := s.DupN(-1) 406 if err != nil { 407 return err 408 } 409 410 return nil 411 }, 412 ErrStackInvalidArgs, 413 nil, 414 }, 415 { 416 "dup too much", 417 [][]byte{{1}}, 418 func(s *stack) error { 419 err := s.DupN(2) 420 if err != nil { 421 return err 422 } 423 424 return nil 425 }, 426 ErrStackUnderflow, 427 nil, 428 }, 429 { 430 "PushBool true", 431 nil, 432 func(s *stack) error { 433 s.PushBool(true) 434 435 return nil 436 }, 437 nil, 438 [][]byte{{1}}, 439 }, 440 { 441 "PushBool false", 442 nil, 443 func(s *stack) error { 444 s.PushBool(false) 445 446 return nil 447 }, 448 nil, 449 [][]byte{nil}, 450 }, 451 { 452 "PushBool PopBool", 453 nil, 454 func(s *stack) error { 455 s.PushBool(true) 456 val, err := s.PopBool() 457 if err != nil { 458 return err 459 } 460 if val != true { 461 return errors.New("unexpected value") 462 } 463 464 return nil 465 }, 466 nil, 467 nil, 468 }, 469 { 470 "PushBool PopBool 2", 471 nil, 472 func(s *stack) error { 473 s.PushBool(false) 474 val, err := s.PopBool() 475 if err != nil { 476 return err 477 } 478 if val != false { 479 return errors.New("unexpected value") 480 } 481 482 return nil 483 }, 484 nil, 485 nil, 486 }, 487 { 488 "PushInt PopBool", 489 nil, 490 func(s *stack) error { 491 s.PushInt(scriptNum(1)) 492 val, err := s.PopBool() 493 if err != nil { 494 return err 495 } 496 if val != true { 497 return errors.New("unexpected value") 498 } 499 500 return nil 501 }, 502 nil, 503 nil, 504 }, 505 { 506 "PushInt PopBool 2", 507 nil, 508 func(s *stack) error { 509 s.PushInt(scriptNum(0)) 510 val, err := s.PopBool() 511 if err != nil { 512 return err 513 } 514 if val != false { 515 return errors.New("unexpected value") 516 } 517 518 return nil 519 }, 520 nil, 521 nil, 522 }, 523 { 524 "Nip top", 525 [][]byte{{1}, {2}, {3}}, 526 func(s *stack) error { 527 return s.NipN(0) 528 }, 529 nil, 530 [][]byte{{1}, {2}}, 531 }, 532 { 533 "Nip middle", 534 [][]byte{{1}, {2}, {3}}, 535 func(s *stack) error { 536 return s.NipN(1) 537 }, 538 nil, 539 [][]byte{{1}, {3}}, 540 }, 541 { 542 "Nip low", 543 [][]byte{{1}, {2}, {3}}, 544 func(s *stack) error { 545 return s.NipN(2) 546 }, 547 nil, 548 [][]byte{{2}, {3}}, 549 }, 550 { 551 "Nip too much", 552 [][]byte{{1}, {2}, {3}}, 553 func(s *stack) error { 554 // bite off more than we can chew 555 return s.NipN(3) 556 }, 557 ErrStackUnderflow, 558 [][]byte{{2}, {3}}, 559 }, 560 { 561 "keep on tucking", 562 [][]byte{{1}, {2}, {3}}, 563 func(s *stack) error { 564 return s.Tuck() 565 }, 566 nil, 567 [][]byte{{1}, {3}, {2}, {3}}, 568 }, 569 { 570 "a little tucked up", 571 [][]byte{{1}}, // too few arguments for tuck 572 func(s *stack) error { 573 return s.Tuck() 574 }, 575 ErrStackUnderflow, 576 nil, 577 }, 578 { 579 "all tucked up", 580 nil, // too few arguments for tuck 581 func(s *stack) error { 582 return s.Tuck() 583 }, 584 ErrStackUnderflow, 585 nil, 586 }, 587 { 588 "drop 1", 589 [][]byte{{1}, {2}, {3}, {4}}, 590 func(s *stack) error { 591 return s.DropN(1) 592 }, 593 nil, 594 [][]byte{{1}, {2}, {3}}, 595 }, 596 { 597 "drop 2", 598 [][]byte{{1}, {2}, {3}, {4}}, 599 func(s *stack) error { 600 return s.DropN(2) 601 }, 602 nil, 603 [][]byte{{1}, {2}}, 604 }, 605 { 606 "drop 3", 607 [][]byte{{1}, {2}, {3}, {4}}, 608 func(s *stack) error { 609 return s.DropN(3) 610 }, 611 nil, 612 [][]byte{{1}}, 613 }, 614 { 615 "drop 4", 616 [][]byte{{1}, {2}, {3}, {4}}, 617 func(s *stack) error { 618 return s.DropN(4) 619 }, 620 nil, 621 nil, 622 }, 623 { 624 "drop 4/5", 625 [][]byte{{1}, {2}, {3}, {4}}, 626 func(s *stack) error { 627 return s.DropN(5) 628 }, 629 ErrStackUnderflow, 630 nil, 631 }, 632 { 633 "drop invalid", 634 [][]byte{{1}, {2}, {3}, {4}}, 635 func(s *stack) error { 636 return s.DropN(0) 637 }, 638 ErrStackInvalidArgs, 639 nil, 640 }, 641 { 642 "Rot1", 643 [][]byte{{1}, {2}, {3}, {4}}, 644 func(s *stack) error { 645 return s.RotN(1) 646 }, 647 nil, 648 [][]byte{{1}, {3}, {4}, {2}}, 649 }, 650 { 651 "Rot2", 652 [][]byte{{1}, {2}, {3}, {4}, {5}, {6}}, 653 func(s *stack) error { 654 return s.RotN(2) 655 }, 656 nil, 657 [][]byte{{3}, {4}, {5}, {6}, {1}, {2}}, 658 }, 659 { 660 "Rot too little", 661 [][]byte{{1}, {2}}, 662 func(s *stack) error { 663 return s.RotN(1) 664 }, 665 ErrStackUnderflow, 666 nil, 667 }, 668 { 669 "Rot0", 670 [][]byte{{1}, {2}, {3}}, 671 func(s *stack) error { 672 return s.RotN(0) 673 }, 674 ErrStackInvalidArgs, 675 nil, 676 }, 677 { 678 "Swap1", 679 [][]byte{{1}, {2}, {3}, {4}}, 680 func(s *stack) error { 681 return s.SwapN(1) 682 }, 683 nil, 684 [][]byte{{1}, {2}, {4}, {3}}, 685 }, 686 { 687 "Swap2", 688 [][]byte{{1}, {2}, {3}, {4}}, 689 func(s *stack) error { 690 return s.SwapN(2) 691 }, 692 nil, 693 [][]byte{{3}, {4}, {1}, {2}}, 694 }, 695 { 696 "Swap too little", 697 [][]byte{{1}}, 698 func(s *stack) error { 699 return s.SwapN(1) 700 }, 701 ErrStackUnderflow, 702 nil, 703 }, 704 { 705 "Swap0", 706 [][]byte{{1}, {2}, {3}}, 707 func(s *stack) error { 708 return s.SwapN(0) 709 }, 710 ErrStackInvalidArgs, 711 nil, 712 }, 713 { 714 "Over1", 715 [][]byte{{1}, {2}, {3}, {4}}, 716 func(s *stack) error { 717 return s.OverN(1) 718 }, 719 nil, 720 [][]byte{{1}, {2}, {3}, {4}, {3}}, 721 }, 722 { 723 "Over2", 724 [][]byte{{1}, {2}, {3}, {4}}, 725 func(s *stack) error { 726 return s.OverN(2) 727 }, 728 nil, 729 [][]byte{{1}, {2}, {3}, {4}, {1}, {2}}, 730 }, 731 { 732 "Over too little", 733 [][]byte{{1}}, 734 func(s *stack) error { 735 return s.OverN(1) 736 }, 737 ErrStackUnderflow, 738 nil, 739 }, 740 { 741 "Over0", 742 [][]byte{{1}, {2}, {3}}, 743 func(s *stack) error { 744 return s.OverN(0) 745 }, 746 ErrStackInvalidArgs, 747 nil, 748 }, 749 { 750 "Pick1", 751 [][]byte{{1}, {2}, {3}, {4}}, 752 func(s *stack) error { 753 return s.PickN(1) 754 }, 755 nil, 756 [][]byte{{1}, {2}, {3}, {4}, {3}}, 757 }, 758 { 759 "Pick2", 760 [][]byte{{1}, {2}, {3}, {4}}, 761 func(s *stack) error { 762 return s.PickN(2) 763 }, 764 nil, 765 [][]byte{{1}, {2}, {3}, {4}, {2}}, 766 }, 767 { 768 "Pick too little", 769 [][]byte{{1}}, 770 func(s *stack) error { 771 return s.PickN(1) 772 }, 773 ErrStackUnderflow, 774 nil, 775 }, 776 { 777 "Roll1", 778 [][]byte{{1}, {2}, {3}, {4}}, 779 func(s *stack) error { 780 return s.RollN(1) 781 }, 782 nil, 783 [][]byte{{1}, {2}, {4}, {3}}, 784 }, 785 { 786 "Roll2", 787 [][]byte{{1}, {2}, {3}, {4}}, 788 func(s *stack) error { 789 return s.RollN(2) 790 }, 791 nil, 792 [][]byte{{1}, {3}, {4}, {2}}, 793 }, 794 { 795 "Roll too little", 796 [][]byte{{1}}, 797 func(s *stack) error { 798 return s.RollN(1) 799 }, 800 ErrStackUnderflow, 801 nil, 802 }, 803 { 804 "Peek bool", 805 [][]byte{{1}}, 806 func(s *stack) error { 807 // Peek bool is otherwise pretty well tested, 808 // just check it works. 809 val, err := s.PeekBool(0) 810 if err != nil { 811 return err 812 } 813 if val != true { 814 return errors.New("invalid result") 815 } 816 return nil 817 }, 818 nil, 819 [][]byte{{1}}, 820 }, 821 { 822 "Peek bool 2", 823 [][]byte{nil}, 824 func(s *stack) error { 825 // Peek bool is otherwise pretty well tested, 826 // just check it works. 827 val, err := s.PeekBool(0) 828 if err != nil { 829 return err 830 } 831 if val != false { 832 return errors.New("invalid result") 833 } 834 return nil 835 }, 836 nil, 837 [][]byte{nil}, 838 }, 839 { 840 "Peek int", 841 [][]byte{{1}}, 842 func(s *stack) error { 843 // Peek int is otherwise pretty well tested, 844 // just check it works. 845 val, err := s.PeekInt(0) 846 if err != nil { 847 return err 848 } 849 if val != 1 { 850 return errors.New("invalid result") 851 } 852 return nil 853 }, 854 nil, 855 [][]byte{{1}}, 856 }, 857 { 858 "Peek int 2", 859 [][]byte{{0}}, 860 func(s *stack) error { 861 // Peek int is otherwise pretty well tested, 862 // just check it works. 863 val, err := s.PeekInt(0) 864 if err != nil { 865 return err 866 } 867 if val != 0 { 868 return errors.New("invalid result") 869 } 870 return nil 871 }, 872 nil, 873 [][]byte{{0}}, 874 }, 875 { 876 "pop int", 877 nil, 878 func(s *stack) error { 879 s.PushInt(scriptNum(1)) 880 // Peek int is otherwise pretty well tested, 881 // just check it works. 882 val, err := s.PopInt() 883 if err != nil { 884 return err 885 } 886 if val != 1 { 887 return errors.New("invalid result") 888 } 889 return nil 890 }, 891 nil, 892 nil, 893 }, 894 { 895 "pop empty", 896 nil, 897 func(s *stack) error { 898 // Peek int is otherwise pretty well tested, 899 // just check it works. 900 _, err := s.PopInt() 901 return err 902 }, 903 ErrStackUnderflow, 904 nil, 905 }, 906 } 907 908 for _, test := range tests { 909 s := stack{} 910 911 for i := range test.before { 912 s.PushByteArray(test.before[i]) 913 } 914 err := test.operation(&s) 915 if err != test.expectedReturn { 916 t.Errorf("%s: operation return not what expected: %v "+ 917 "vs %v", test.name, err, test.expectedReturn) 918 } 919 if err != nil { 920 continue 921 } 922 923 if int32(len(test.after)) != s.Depth() { 924 t.Errorf("%s: stack depth doesn't match expected: %v "+ 925 "vs %v", test.name, len(test.after), 926 s.Depth()) 927 } 928 929 for i := range test.after { 930 val, err := s.PeekByteArray(s.Depth() - int32(i) - 1) 931 if err != nil { 932 t.Errorf("%s: can't peek %dth stack entry: %v", 933 test.name, i, err) 934 break 935 } 936 937 if !bytes.Equal(val, test.after[i]) { 938 t.Errorf("%s: %dth stack entry doesn't match "+ 939 "expected: %v vs %v", test.name, i, val, 940 test.after[i]) 941 break 942 } 943 } 944 } 945 }