OSDN Git Service

Feat(BVM): change number mul op use uint256 and test (#1854)
authorxuexiansong <s.xue.xian.c@gmail.com>
Tue, 6 Apr 2021 07:14:05 +0000 (15:14 +0800)
committerGitHub <noreply@github.com>
Tue, 6 Apr 2021 07:14:05 +0000 (15:14 +0800)
protocol/vm/mocks/data.go
protocol/vm/numeric.go
protocol/vm/numeric_test.go
protocol/vm/vm_test.go

index 63f7287..2b52d29 100644 (file)
@@ -3,4 +3,5 @@ package mocks
 // mocks data
 var (
        U256NumNegative1 = []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
+       MaxU256          = []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
 )
index 1c9f9d8..ca76a08 100644 (file)
@@ -57,15 +57,22 @@ func op2Mul(vm *virtualMachine) error {
        if err != nil {
                return err
        }
-       n, err := vm.popInt64(true)
+
+       n, err := vm.popBigInt(true)
        if err != nil {
                return err
        }
-       res, ok := checked.MulInt64(n, 2)
+
+       num, ok := checked.NewUInt256("2")
        if !ok {
+               return ErrBadValue
+       }
+
+       if num.Mul(n, num); num.Sign() < 0 {
                return ErrRange
        }
-       return vm.pushInt64(res, true)
+
+       return vm.pushBigInt(num, true)
 }
 
 func op2Div(vm *virtualMachine) error {
index 2699768..baf5e01 100644 (file)
@@ -60,6 +60,27 @@ func TestNumericOps(t *testing.T) {
                        dataStack: [][]byte{{4}},
                },
        }, {
+               op: OP_2MUL,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
+               },
+               wantVM: &virtualMachine{
+                       runLimit:  49998,
+                       dataStack: [][]byte{{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
+               },
+       }, {
+               op: OP_2MUL,
+               startVM: &virtualMachine{
+                       runLimit:  50000,
+                       dataStack: [][]byte{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
+               },
+               wantVM: &virtualMachine{
+                       runLimit:     49998,
+                       deferredCost: 1,
+                       dataStack:    [][]byte{{0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
+               },
+       }, {
                op: OP_2DIV,
                startVM: &virtualMachine{
                        runLimit:  50000,
@@ -772,6 +793,75 @@ func TestNumCompare(t *testing.T) {
        }
 }
 
+func Test_op2Mul(t *testing.T) {
+       type args struct {
+               vm *virtualMachine
+       }
+       tests := []struct {
+               name    string
+               args    args
+               wantErr bool
+       }{
+               {
+                       name: "test normal mul op",
+                       args: args{
+                               vm: &virtualMachine{
+                                       runLimit:  50000,
+                                       dataStack: [][]byte{{2}},
+                               },
+                       },
+                       wantErr: false,
+               },
+               {
+                       name: "test normal mul op of big number",
+                       args: args{
+                               vm: &virtualMachine{
+                                       runLimit:  50000,
+                                       dataStack: [][]byte{{0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
+                               },
+                       },
+                       wantErr: false,
+               },
+               {
+                       name: "test error of mul op negative",
+                       args: args{
+                               vm: &virtualMachine{
+                                       runLimit:  50000,
+                                       dataStack: [][]byte{mocks.U256NumNegative1},
+                               },
+                       },
+                       wantErr: true,
+               },
+               {
+                       name: "test error of mul op out range",
+                       args: args{
+                               vm: &virtualMachine{
+                                       runLimit:  50000,
+                                       dataStack: [][]byte{mocks.MaxU256},
+                               },
+                       },
+                       wantErr: true,
+               },
+               {
+                       name: "test error of mul op out range which result is min number",
+                       args: args{
+                               vm: &virtualMachine{
+                                       runLimit:  50000,
+                                       dataStack: [][]byte{{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+                               },
+                       },
+                       wantErr: true,
+               },
+       }
+       for _, tt := range tests {
+               t.Run(tt.name, func(t *testing.T) {
+                       if err := op2Mul(tt.args.vm); (err != nil) != tt.wantErr {
+                               t.Errorf("op2Mul() error = %v, wantErr %v", err, tt.wantErr)
+                       }
+               })
+       }
+}
+
 func Test_op1Sub(t *testing.T) {
        type args struct {
                vm *virtualMachine
index a15d947..71b3f56 100644 (file)
@@ -60,7 +60,6 @@ func doOKNotOK(t *testing.T, expectOK bool) {
 
                {"2MUL 2 NUMEQUAL", [][]byte{Int64Bytes(1)}, false},
                {"2MUL 0 NUMEQUAL", [][]byte{Int64Bytes(0)}, false},
-               {"2MUL -2 NUMEQUAL", [][]byte{Int64Bytes(-1)}, false},
 
                {"2DIV 1 NUMEQUAL", [][]byte{Int64Bytes(2)}, false},
                {"2DIV 0 NUMEQUAL", [][]byte{Int64Bytes(1)}, false},