github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/protocol/vm/pushdata_test.go (about)

     1  package vm
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/bytom/bytom/testutil"
     8  )
     9  
    10  func TestPushdataOps(t *testing.T) {
    11  	type testStruct struct {
    12  		op      Op
    13  		startVM *virtualMachine
    14  		wantErr error
    15  		wantVM  *virtualMachine
    16  	}
    17  	cases := []testStruct{{
    18  		op: OP_FALSE,
    19  		startVM: &virtualMachine{
    20  			runLimit:  50000,
    21  			dataStack: [][]byte{},
    22  		},
    23  		wantVM: &virtualMachine{
    24  			runLimit:  49991,
    25  			dataStack: [][]byte{{}},
    26  		},
    27  	}, {
    28  		op: OP_FALSE,
    29  		startVM: &virtualMachine{
    30  			runLimit:  1,
    31  			dataStack: [][]byte{},
    32  		},
    33  		wantErr: ErrRunLimitExceeded,
    34  	}, {
    35  		op: OP_1NEGATE,
    36  		startVM: &virtualMachine{
    37  			runLimit:  50000,
    38  			dataStack: [][]byte{},
    39  		},
    40  		wantVM: &virtualMachine{
    41  			runLimit:  49983,
    42  			dataStack: [][]byte{Int64Bytes(-1)},
    43  		},
    44  	}, {
    45  		op: OP_1NEGATE,
    46  		startVM: &virtualMachine{
    47  			runLimit:  1,
    48  			dataStack: [][]byte{},
    49  		},
    50  		wantErr: ErrRunLimitExceeded,
    51  	}}
    52  
    53  	pushdataops := []Op{OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4}
    54  	for i := 1; i <= 75; i++ {
    55  		pushdataops = append(pushdataops, Op(i))
    56  	}
    57  	for _, op := range pushdataops {
    58  		cases = append(cases, testStruct{
    59  			op: op,
    60  			startVM: &virtualMachine{
    61  				runLimit:  50000,
    62  				dataStack: [][]byte{},
    63  				data:      []byte("data"),
    64  			},
    65  			wantVM: &virtualMachine{
    66  				runLimit:  49987,
    67  				dataStack: [][]byte{[]byte("data")},
    68  				data:      []byte("data"),
    69  			},
    70  		}, testStruct{
    71  			op: op,
    72  			startVM: &virtualMachine{
    73  				runLimit:  1,
    74  				dataStack: [][]byte{},
    75  				data:      []byte("data"),
    76  			},
    77  			wantErr: ErrRunLimitExceeded,
    78  		})
    79  	}
    80  
    81  	pushops := append(pushdataops, OP_FALSE, OP_1NEGATE, OP_NOP)
    82  	for _, op := range pushops {
    83  		cases = append(cases, testStruct{
    84  			op: op,
    85  			startVM: &virtualMachine{
    86  				runLimit:  0,
    87  				dataStack: [][]byte{},
    88  			},
    89  			wantErr: ErrRunLimitExceeded,
    90  		})
    91  	}
    92  
    93  	for i, c := range cases {
    94  		err := ops[c.op].fn(c.startVM)
    95  
    96  		if err != c.wantErr {
    97  			t.Errorf("case %d, op %s: got err = %v want %v", i, ops[c.op].name, err, c.wantErr)
    98  			continue
    99  		}
   100  		if c.wantErr != nil {
   101  			continue
   102  		}
   103  
   104  		if !testutil.DeepEqual(c.startVM, c.wantVM) {
   105  			t.Errorf("case %d, op %s: unexpected vm result\n\tgot:  %+v\n\twant: %+v\n", i, ops[c.op].name, c.startVM, c.wantVM)
   106  		}
   107  	}
   108  }
   109  
   110  func TestPushDataBytes(t *testing.T) {
   111  	type test struct {
   112  		data []byte
   113  		want []byte
   114  	}
   115  	cases := []test{{
   116  		data: nil,
   117  		want: []byte{byte(OP_0)},
   118  	}, {
   119  		data: make([]byte, 255),
   120  		want: append([]byte{byte(OP_PUSHDATA1), 0xff}, make([]byte, 255)...),
   121  	}, {
   122  		data: make([]byte, 1<<8),
   123  		want: append([]byte{byte(OP_PUSHDATA2), 0, 1}, make([]byte, 1<<8)...),
   124  	}, {
   125  		data: make([]byte, 1<<16),
   126  		want: append([]byte{byte(OP_PUSHDATA4), 0, 0, 1, 0}, make([]byte, 1<<16)...),
   127  	}}
   128  
   129  	for i := 1; i <= 75; i++ {
   130  		cases = append(cases, test{
   131  			data: make([]byte, i),
   132  			want: append([]byte{byte(OP_DATA_1) - 1 + byte(i)}, make([]byte, i)...),
   133  		})
   134  	}
   135  
   136  	for _, c := range cases {
   137  		got := PushdataBytes(c.data)
   138  
   139  		dl := len(c.data)
   140  		if dl > 10 {
   141  			dl = 10
   142  		}
   143  		if !bytes.Equal(got, c.want) {
   144  			t.Errorf("PushdataBytes(%x...) = %x...[%d] want %x...[%d]", c.data[:dl], got[:dl], len(got), c.want[:dl], len(c.want))
   145  		}
   146  	}
   147  }
   148  
   149  func TestPushdataInt64(t *testing.T) {
   150  	type test struct {
   151  		num  int64
   152  		want []byte
   153  	}
   154  	cases := []test{{
   155  		num:  0,
   156  		want: []byte{byte(OP_0)},
   157  	}, {
   158  		num:  17,
   159  		want: []byte{byte(OP_DATA_1), 0x11},
   160  	}, {
   161  		num:  255,
   162  		want: []byte{byte(OP_DATA_1), 0xff},
   163  	}, {
   164  		num:  256,
   165  		want: []byte{byte(OP_DATA_2), 0x00, 0x01},
   166  	}, {
   167  		num:  -1,
   168  		want: []byte{byte(OP_DATA_8), 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
   169  	}, {
   170  		num:  -2,
   171  		want: []byte{byte(OP_DATA_8), 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
   172  	}}
   173  
   174  	for i := 1; i <= 16; i++ {
   175  		cases = append(cases, test{
   176  			num:  int64(i),
   177  			want: []byte{byte(OP_1) - 1 + byte(i)},
   178  		})
   179  	}
   180  
   181  	for _, c := range cases {
   182  		got := PushdataInt64(c.num)
   183  
   184  		if !bytes.Equal(got, c.want) {
   185  			t.Errorf("PushdataInt64(%d) = %x want %x", c.num, got, c.want)
   186  		}
   187  	}
   188  }