aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2017-02-15 00:59:00 +0800
committerGitHub <noreply@github.com>2017-02-15 00:59:00 +0800
commita973d1d5233bbd36cbaed0b7235311d4cd529580 (patch)
tree61ed1bd31a9c2a2e6a052a122a737deaee70c6cb /common
parent15a609d5d6613e37e819975ceba01cb5ba735242 (diff)
parentc12f4df910e2da1cc5dd28c5c4bbe2d8721e1057 (diff)
downloaddexon-a973d1d5233bbd36cbaed0b7235311d4cd529580.tar
dexon-a973d1d5233bbd36cbaed0b7235311d4cd529580.tar.gz
dexon-a973d1d5233bbd36cbaed0b7235311d4cd529580.tar.bz2
dexon-a973d1d5233bbd36cbaed0b7235311d4cd529580.tar.lz
dexon-a973d1d5233bbd36cbaed0b7235311d4cd529580.tar.xz
dexon-a973d1d5233bbd36cbaed0b7235311d4cd529580.tar.zst
dexon-a973d1d5233bbd36cbaed0b7235311d4cd529580.zip
Merge pull request #3674 from obscuren/gaz64
params: core, core/vm, miner: 64bit gas instructions
Diffstat (limited to 'common')
-rw-r--r--common/math/integer.go25
-rw-r--r--common/math/integer_test.go50
2 files changed, 75 insertions, 0 deletions
diff --git a/common/math/integer.go b/common/math/integer.go
new file mode 100644
index 000000000..8162b1985
--- /dev/null
+++ b/common/math/integer.go
@@ -0,0 +1,25 @@
+package math
+
+import gmath "math"
+
+/*
+ * NOTE: The following methods need to be optimised using either bit checking or asm
+ */
+
+// SafeSub returns subtraction result and whether overflow occurred.
+func SafeSub(x, y uint64) (uint64, bool) {
+ return x - y, x < y
+}
+
+// SafeAdd returns the result and whether overflow occurred.
+func SafeAdd(x, y uint64) (uint64, bool) {
+ return x + y, y > gmath.MaxUint64-x
+}
+
+// SafeMul returns multiplication result and whether overflow occurred.
+func SafeMul(x, y uint64) (uint64, bool) {
+ if x == 0 {
+ return 0, false
+ }
+ return x * y, x != 0 && y != 0 && y > gmath.MaxUint64/x
+}
diff --git a/common/math/integer_test.go b/common/math/integer_test.go
new file mode 100644
index 000000000..198114e5e
--- /dev/null
+++ b/common/math/integer_test.go
@@ -0,0 +1,50 @@
+package math
+
+import (
+ gmath "math"
+ "testing"
+)
+
+type operation byte
+
+const (
+ sub operation = iota
+ add
+ mul
+)
+
+func TestOverflow(t *testing.T) {
+ for i, test := range []struct {
+ x uint64
+ y uint64
+ overflow bool
+ op operation
+ }{
+ // add operations
+ {gmath.MaxUint64, 1, true, add},
+ {gmath.MaxUint64 - 1, 1, false, add},
+
+ // sub operations
+ {0, 1, true, sub},
+ {0, 0, false, sub},
+
+ // mul operations
+ {10, 10, false, mul},
+ {gmath.MaxUint64, 2, true, mul},
+ {gmath.MaxUint64, 1, false, mul},
+ } {
+ var overflows bool
+ switch test.op {
+ case sub:
+ _, overflows = SafeSub(test.x, test.y)
+ case add:
+ _, overflows = SafeAdd(test.x, test.y)
+ case mul:
+ _, overflows = SafeMul(test.x, test.y)
+ }
+
+ if test.overflow != overflows {
+ t.Errorf("%d failed. Expected test to be %v, got %v", i, test.overflow, overflows)
+ }
+ }
+}