Official Go implementation of the Bytom protocol
Revision | 50a700d08c595b12bdce603eb294dea889054d0c (tree) |
---|---|
Time | 2021-04-08 15:33:01 |
Author | songxuexian <s.xue.xian.c@gmai...> |
Commiter | songxuexian |
Feat(BVM): change op mod
@@ -250,30 +250,22 @@ func opMod(vm *virtualMachine) error { | ||
250 | 250 | if err != nil { |
251 | 251 | return err |
252 | 252 | } |
253 | - y, err := vm.popInt64(true) | |
253 | + | |
254 | + y, err := vm.popBigInt(true) | |
254 | 255 | if err != nil { |
255 | 256 | return err |
256 | 257 | } |
257 | - x, err := vm.popInt64(true) | |
258 | + | |
259 | + x, err := vm.popBigInt(true) | |
258 | 260 | if err != nil { |
259 | 261 | return err |
260 | 262 | } |
261 | - if y == 0 { | |
262 | - return ErrDivZero | |
263 | - } | |
264 | 263 | |
265 | - res, ok := checked.ModInt64(x, y) | |
266 | - if !ok { | |
267 | - return ErrRange | |
268 | - } | |
269 | - | |
270 | - // Go's modulus operator produces the wrong result for mixed-sign | |
271 | - // operands | |
272 | - if res != 0 && (x >= 0) != (y >= 0) { | |
273 | - res += y | |
264 | + if y.IsZero() { | |
265 | + return ErrDivZero | |
274 | 266 | } |
275 | 267 | |
276 | - return vm.pushInt64(res, true) | |
268 | + return vm.pushBigInt(x.Mod(x, y), true) | |
277 | 269 | } |
278 | 270 | |
279 | 271 | func opLshift(vm *virtualMachine) error { |
@@ -209,17 +209,6 @@ func TestNumericOps(t *testing.T) { | ||
209 | 209 | op: OP_MOD, |
210 | 210 | startVM: &virtualMachine{ |
211 | 211 | runLimit: 50000, |
212 | - dataStack: [][]byte{Int64Bytes(-12), {10}}, | |
213 | - }, | |
214 | - wantVM: &virtualMachine{ | |
215 | - runLimit: 49992, | |
216 | - deferredCost: -16, | |
217 | - dataStack: [][]byte{{8}}, | |
218 | - }, | |
219 | - }, { | |
220 | - op: OP_MOD, | |
221 | - startVM: &virtualMachine{ | |
222 | - runLimit: 50000, | |
223 | 212 | dataStack: [][]byte{{2}, {0}}, |
224 | 213 | }, |
225 | 214 | wantErr: ErrDivZero, |
@@ -1257,3 +1246,107 @@ func Test_opAdd(t *testing.T) { | ||
1257 | 1246 | }) |
1258 | 1247 | } |
1259 | 1248 | } |
1249 | + | |
1250 | +func Test_opMod(t *testing.T) { | |
1251 | + type args struct { | |
1252 | + vm *virtualMachine | |
1253 | + } | |
1254 | + tests := []struct { | |
1255 | + name string | |
1256 | + args args | |
1257 | + want [][]byte | |
1258 | + wantErr bool | |
1259 | + }{ | |
1260 | + { | |
1261 | + name: "Test 2 mod 2 = 0", | |
1262 | + args: args{ | |
1263 | + vm: &virtualMachine{ | |
1264 | + runLimit: 50000, | |
1265 | + dataStack: [][]byte{{0x02},{0x02}}, | |
1266 | + }, | |
1267 | + }, | |
1268 | + want: [][]byte{{}}, | |
1269 | + wantErr: false, | |
1270 | + }, | |
1271 | + { | |
1272 | + name: "Test 2 mod 1 = 0", | |
1273 | + args: args{ | |
1274 | + vm: &virtualMachine{ | |
1275 | + runLimit: 50000, | |
1276 | + dataStack: [][]byte{{0x02},{0x01}}, | |
1277 | + }, | |
1278 | + }, | |
1279 | + want: [][]byte{{}}, | |
1280 | + wantErr: false, | |
1281 | + }, | |
1282 | + { | |
1283 | + name: "Test 255 mod 4 = 3", | |
1284 | + args: args{ | |
1285 | + vm: &virtualMachine{ | |
1286 | + runLimit: 50000, | |
1287 | + dataStack: [][]byte{{0xff},{0x04}}, | |
1288 | + }, | |
1289 | + }, | |
1290 | + want: [][]byte{{0x03}}, | |
1291 | + wantErr: false, | |
1292 | + }, | |
1293 | + { | |
1294 | + name: "Test that two bytes number become one byte number", | |
1295 | + args: args{ | |
1296 | + vm: &virtualMachine{ | |
1297 | + runLimit: 50000, | |
1298 | + dataStack: [][]byte{{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},{0x03}}, | |
1299 | + }, | |
1300 | + }, | |
1301 | + want: [][]byte{{0x01}}, | |
1302 | + wantErr: false, | |
1303 | + }, | |
1304 | + { | |
1305 | + name: "Test for 0 mod 2 got 0", | |
1306 | + args: args{ | |
1307 | + vm: &virtualMachine{ | |
1308 | + runLimit: 50000, | |
1309 | + dataStack: [][]byte{{},{0x02}}, | |
1310 | + }, | |
1311 | + }, | |
1312 | + want: [][]byte{{}}, | |
1313 | + wantErr: false, | |
1314 | + }, | |
1315 | + { | |
1316 | + name: "Test for -1 div 2 got error", | |
1317 | + args: args{ | |
1318 | + vm: &virtualMachine{ | |
1319 | + runLimit: 50000, | |
1320 | + dataStack: [][]byte{mocks.U256NumNegative1,{0x02}}, | |
1321 | + }, | |
1322 | + }, | |
1323 | + want: nil, | |
1324 | + wantErr: true, | |
1325 | + }, | |
1326 | + { | |
1327 | + name: "Test for 1 div 0 got error", | |
1328 | + args: args{ | |
1329 | + vm: &virtualMachine{ | |
1330 | + runLimit: 50000, | |
1331 | + dataStack: [][]byte{{0x01},{}}, | |
1332 | + }, | |
1333 | + }, | |
1334 | + want: nil, | |
1335 | + wantErr: true, | |
1336 | + }, | |
1337 | + } | |
1338 | + for _, tt := range tests { | |
1339 | + t.Run(tt.name, func(t *testing.T) { | |
1340 | + if err := opMod(tt.args.vm); err != nil { | |
1341 | + if !tt.wantErr { | |
1342 | + t.Errorf("opMod() error = %v, wantErr %v", err, tt.wantErr) | |
1343 | + } else { | |
1344 | + return | |
1345 | + } | |
1346 | + } | |
1347 | + if !testutil.DeepEqual(tt.args.vm.dataStack, tt.want) { | |
1348 | + t.Errorf("opMod() error, got %v and wantErr %v", tt.args.vm.dataStack, tt.want) | |
1349 | + } | |
1350 | + }) | |
1351 | + } | |
1352 | +} |
@@ -67,10 +67,6 @@ func doOKNotOK(t *testing.T, expectOK bool) { | ||
67 | 67 | {"2DIV -1 NUMEQUAL", [][]byte{Int64Bytes(-1)}, true}, |
68 | 68 | {"2DIV -1 NUMEQUAL", [][]byte{Int64Bytes(-2)}, true}, |
69 | 69 | |
70 | - {"NEGATE -1 NUMEQUAL", [][]byte{Int64Bytes(1)}, false}, | |
71 | - {"NEGATE 1 NUMEQUAL", [][]byte{Int64Bytes(-1)}, false}, | |
72 | - {"NEGATE 0 NUMEQUAL", [][]byte{Int64Bytes(0)}, false}, | |
73 | - | |
74 | 70 | {"ABS 1 NUMEQUAL", [][]byte{Int64Bytes(1)}, false}, |
75 | 71 | {"ABS 1 NUMEQUAL", [][]byte{Int64Bytes(-1)}, false}, |
76 | 72 | {"ABS 0 NUMEQUAL", [][]byte{Int64Bytes(0)}, false}, |
@@ -87,13 +83,7 @@ func doOKNotOK(t *testing.T, expectOK bool) { | ||
87 | 83 | {"DIV 2 NUMEQUAL", [][]byte{Int64Bytes(6), Int64Bytes(3)}, false}, |
88 | 84 | |
89 | 85 | {"MOD 0 NUMEQUAL", [][]byte{Int64Bytes(6), Int64Bytes(2)}, false}, |
90 | - {"MOD 0 NUMEQUAL", [][]byte{Int64Bytes(-6), Int64Bytes(2)}, false}, | |
91 | - {"MOD 0 NUMEQUAL", [][]byte{Int64Bytes(6), Int64Bytes(-2)}, false}, | |
92 | - {"MOD 0 NUMEQUAL", [][]byte{Int64Bytes(-6), Int64Bytes(-2)}, false}, | |
93 | 86 | {"MOD 2 NUMEQUAL", [][]byte{Int64Bytes(12), Int64Bytes(10)}, false}, |
94 | - {"MOD 8 NUMEQUAL", [][]byte{Int64Bytes(-12), Int64Bytes(10)}, false}, | |
95 | - {"MOD -8 NUMEQUAL", [][]byte{Int64Bytes(12), Int64Bytes(-10)}, false}, | |
96 | - {"MOD -2 NUMEQUAL", [][]byte{Int64Bytes(-12), Int64Bytes(-10)}, false}, | |
97 | 87 | |
98 | 88 | {"LSHIFT 2 NUMEQUAL", [][]byte{Int64Bytes(1), Int64Bytes(1)}, false}, |
99 | 89 | {"LSHIFT 4 NUMEQUAL", [][]byte{Int64Bytes(1), Int64Bytes(2)}, false}, |