Merge pull request #14718 from holiman/gascalc_fix
core/vm: fix overflow in gas calculation formula
This commit is contained in:
commit
dfd076244d
@ -17,7 +17,6 @@
|
|||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
gmath "math"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
@ -28,15 +27,20 @@ import (
|
|||||||
// memoryGasCosts calculates the quadratic gas for memory expansion. It does so
|
// memoryGasCosts calculates the quadratic gas for memory expansion. It does so
|
||||||
// only for the memory region that is expanded, not the total memory.
|
// only for the memory region that is expanded, not the total memory.
|
||||||
func memoryGasCost(mem *Memory, newMemSize uint64) (uint64, error) {
|
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.
|
|
||||||
if newMemSize > gmath.MaxUint64-32 {
|
|
||||||
return 0, errGasUintOverflow
|
|
||||||
}
|
|
||||||
|
|
||||||
if newMemSize == 0 {
|
if newMemSize == 0 {
|
||||||
return 0, nil
|
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 0x7ffffffff will cause the square operation
|
||||||
|
// to overflow.
|
||||||
|
// The constant 0xffffffffe0 is the highest number that can be used without
|
||||||
|
// overflowing the gas calculation
|
||||||
|
if newMemSize > 0xffffffffe0 {
|
||||||
|
return 0, errGasUintOverflow
|
||||||
|
}
|
||||||
|
|
||||||
newMemSizeWords := toWordSize(newMemSize)
|
newMemSizeWords := toWordSize(newMemSize)
|
||||||
newMemSize = newMemSizeWords * 32
|
newMemSize = newMemSizeWords * 32
|
||||||
|
@ -16,24 +16,20 @@
|
|||||||
|
|
||||||
package vm
|
package vm
|
||||||
|
|
||||||
import (
|
import "testing"
|
||||||
"math"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestMemoryGasCost(t *testing.T) {
|
func TestMemoryGasCost(t *testing.T) {
|
||||||
size := uint64(math.MaxUint64 - 64)
|
//size := uint64(math.MaxUint64 - 64)
|
||||||
_, err := memoryGasCost(&Memory{}, size)
|
size := uint64(0xffffffffe0)
|
||||||
|
v, err := memoryGasCost(&Memory{}, size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("didn't expect error:", err)
|
t.Error("didn't expect error:", err)
|
||||||
}
|
}
|
||||||
|
if v != 36028899963961341 {
|
||||||
_, err = memoryGasCost(&Memory{}, size+32)
|
t.Errorf("Expected: 36028899963961341, got %d", v)
|
||||||
if err != nil {
|
|
||||||
t.Error("didn't expect error:", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = memoryGasCost(&Memory{}, size+33)
|
_, err = memoryGasCost(&Memory{}, size+1)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error")
|
t.Error("expected error")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user