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