From 157f09e5b64bd4ba8a579c4719cf504d68f4b925 Mon Sep 17 00:00:00 2001 From: Liang Ma Date: Thu, 28 Mar 2019 21:04:31 +0000 Subject: [PATCH 1/2] core/vm: Correct the Memory Gas Overflow condition previous overflow condition is too big to use. 0x7FFFFFFFF squre operation is overflowed uint64. 0x7FFFFFFFF^2 = 0x3F FFFF FFF0 0000 0001 --- core/vm/gas_table.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 6400c1324..8b034a0e7 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -32,11 +32,11 @@ func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) { // The maximum that will fit in a uint64 is max_word_count - 1 // anything above that will result in an overflow. // Additionally, a newMemSize which results in a - // newMemSizeWords larger than 0x7ffffffff will cause the square operation + // newMemSizeWords larger than 0xFFFFFFFF will cause the square operation // to overflow. - // The constant 0xffffffffe0 is the highest number that can be used without + // The constant 0x1FFFFFFFE0 is the highest number that can be used without // overflowing the gas calculation - if newMemSize > 0xffffffffe0 { + if newMemSize > 0x1FFFFFFFE0 { return 0, errGasUintOverflow } From 9294b8f10f1fceb662a06f9d45aaf7a6b2492f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Mon, 1 Apr 2019 14:56:43 +0300 Subject: [PATCH 2/2] core/vm: polish gas PR, fix tests, make table driven --- core/vm/gas_table.go | 14 +++++--------- core/vm/gas_table_test.go | 27 +++++++++++++++------------ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index 8b034a0e7..8270300ba 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -25,21 +25,17 @@ import ( // memoryGasCost calculates the quadratic gas for memory expansion. It does so // only for the memory region that is expanded, not the total memory. func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) { - if newMemSize == 0 { return 0, nil } - // The maximum that will fit in a uint64 is max_word_count - 1 - // anything above that will result in an overflow. - // Additionally, a newMemSize which results in a - // newMemSizeWords larger than 0xFFFFFFFF will cause the square operation - // to overflow. - // The constant 0x1FFFFFFFE0 is the highest number that can be used without - // overflowing the gas calculation + // The maximum that will fit in a uint64 is max_word_count - 1. Anything above + // that will result in an overflow. Additionally, a newMemSize which results in + // a newMemSizeWords larger than 0xFFFFFFFF will cause the square operation to + // overflow. The constant 0x1FFFFFFFE0 is the highest number that can be used + // without overflowing the gas calculation. if newMemSize > 0x1FFFFFFFE0 { return 0, errGasUintOverflow } - newMemSizeWords := toWordSize(newMemSize) newMemSize = newMemSizeWords * 32 diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index 1b91aee56..2c1e11894 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -19,18 +19,21 @@ package vm import "testing" func TestMemoryGasCost(t *testing.T) { - //size := uint64(math.MaxUint64 - 64) - size := uint64(0xffffffffe0) - v, err := memoryGasCost(&Memory{}, size) - if err != nil { - t.Error("didn't expect error:", err) + tests := []struct { + size uint64 + cost uint64 + overflow bool + }{ + {0x1fffffffe0, 36028809887088637, false}, + {0x1fffffffe1, 0, true}, } - if v != 36028899963961341 { - t.Errorf("Expected: 36028899963961341, got %d", v) - } - - _, err = memoryGasCost(&Memory{}, size+1) - if err == nil { - t.Error("expected error") + for i, tt := range tests { + v, err := memoryGasCost(&Memory{}, tt.size) + if (err == errGasUintOverflow) != tt.overflow { + t.Errorf("test %d: overflow mismatch: have %v, want %v", i, err == errGasUintOverflow, tt.overflow) + } + if v != tt.cost { + t.Errorf("test %d: gas cost mismatch: have %v, want %v", i, v, tt.cost) + } } }