github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/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  
    36  	pushdataops := []Op{OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4}
    37  	for i := 1; i <= 75; i++ {
    38  		pushdataops = append(pushdataops, Op(i))
    39  	}
    40  	for _, op := range pushdataops {
    41  		cases = append(cases, testStruct{
    42  			op: op,
    43  			startVM: &virtualMachine{
    44  				runLimit:  50000,
    45  				dataStack: [][]byte{},
    46  				data:      []byte("data"),
    47  			},
    48  			wantVM: &virtualMachine{
    49  				runLimit:  49987,
    50  				dataStack: [][]byte{[]byte("data")},
    51  				data:      []byte("data"),
    52  			},
    53  		}, testStruct{
    54  			op: op,
    55  			startVM: &virtualMachine{
    56  				runLimit:  1,
    57  				dataStack: [][]byte{},
    58  				data:      []byte("data"),
    59  			},
    60  			wantErr: ErrRunLimitExceeded,
    61  		})
    62  	}
    63  
    64  	pushops := append(pushdataops, OP_FALSE, OP_NOP)
    65  	for _, op := range pushops {
    66  		cases = append(cases, testStruct{
    67  			op: op,
    68  			startVM: &virtualMachine{
    69  				runLimit:  0,
    70  				dataStack: [][]byte{},
    71  			},
    72  			wantErr: ErrRunLimitExceeded,
    73  		})
    74  	}
    75  
    76  	for i, c := range cases {
    77  		err := ops[c.op].fn(c.startVM)
    78  
    79  		if err != c.wantErr {
    80  			t.Errorf("case %d, op %s: got err = %v want %v", i, ops[c.op].name, err, c.wantErr)
    81  			continue
    82  		}
    83  		if c.wantErr != nil {
    84  			continue
    85  		}
    86  
    87  		if !testutil.DeepEqual(c.startVM, c.wantVM) {
    88  			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)
    89  		}
    90  	}
    91  }
    92  
    93  func TestPushDataBytes(t *testing.T) {
    94  	type test struct {
    95  		data []byte
    96  		want []byte
    97  	}
    98  	cases := []test{
    99  		{
   100  			data: nil,
   101  			want: []byte{byte(OP_0)},
   102  		},
   103  		{
   104  			data: make([]byte, 255),
   105  			want: append([]byte{byte(OP_PUSHDATA1), 0xff}, make([]byte, 255)...),
   106  		},
   107  		{
   108  			data: make([]byte, 1<<8),
   109  			want: append([]byte{byte(OP_PUSHDATA2), 0, 1}, make([]byte, 1<<8)...),
   110  		},
   111  		{
   112  			data: make([]byte, 1<<16),
   113  			want: append([]byte{byte(OP_PUSHDATA4), 0, 0, 1, 0}, make([]byte, 1<<16)...),
   114  		},
   115  		{
   116  			data: make([]byte, 1<<16),
   117  			want: append([]byte{byte(OP_PUSHDATA4), 0, 0, 1, 0}, make([]byte, 1<<16)...),
   118  		},
   119  	}
   120  
   121  	for i := 1; i <= 75; i++ {
   122  		cases = append(cases, test{
   123  			data: make([]byte, i),
   124  			want: append([]byte{byte(OP_DATA_1) - 1 + byte(i)}, make([]byte, i)...),
   125  		})
   126  	}
   127  
   128  	for _, c := range cases {
   129  		got := PushDataBytes(c.data)
   130  
   131  		dl := len(c.data)
   132  		if dl > 10 {
   133  			dl = 10
   134  		}
   135  		if !bytes.Equal(got, c.want) {
   136  			t.Errorf("PushDataBytes(%x...) = %x...[%d] want %x...[%d]", c.data[:dl], got[:dl], len(got), c.want[:dl], len(c.want))
   137  		}
   138  	}
   139  }
   140  
   141  func TestPushdataInt64(t *testing.T) {
   142  	type test struct {
   143  		num  uint64
   144  		want []byte
   145  	}
   146  	cases := []test{{
   147  		num:  0,
   148  		want: []byte{byte(OP_0)},
   149  	}, {
   150  		num:  17,
   151  		want: []byte{byte(OP_DATA_1), 0x11},
   152  	}, {
   153  		num:  255,
   154  		want: []byte{byte(OP_DATA_1), 0xff},
   155  	}, {
   156  		num:  256,
   157  		want: []byte{byte(OP_DATA_2), 0x00, 0x01},
   158  	}}
   159  
   160  	for i := 1; i <= 16; i++ {
   161  		cases = append(cases, test{
   162  			num:  uint64(i),
   163  			want: []byte{byte(OP_1) - 1 + byte(i)},
   164  		})
   165  	}
   166  
   167  	for _, c := range cases {
   168  		got := PushDataUint64(c.num)
   169  
   170  		if !bytes.Equal(got, c.want) {
   171  			t.Errorf("PushDataInt64(%d) = %x want %x", c.num, got, c.want)
   172  		}
   173  	}
   174  }