stack_test.go raw

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