From d91c8c799ef1f88920b92a800d0083f2c85c82a8 Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Fri, 24 Feb 2023 09:25:49 +0800 Subject: [PATCH] fix(l1fee): use int for `CalculateL1Fee` (#231) * fix(l1fee): use floor for `mulByFloat` * fix(l1fee): use int for `CalculateL1Fee` * fix(l1fee): use int for `CalculateL1Fee` * add `TestCalculateL1Fee` (#233) * update testcase --- rollup/fees/rollup_fee.go | 31 +++++++++---------------------- rollup/fees/rollup_fee_test.go | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 rollup/fees/rollup_fee_test.go diff --git a/rollup/fees/rollup_fee.go b/rollup/fees/rollup_fee.go index 7aa6829b4a..2d634be309 100644 --- a/rollup/fees/rollup_fee.go +++ b/rollup/fees/rollup_fee.go @@ -3,7 +3,6 @@ package fees import ( "bytes" "errors" - "math" "math/big" "github.com/scroll-tech/go-ethereum/common" @@ -93,27 +92,18 @@ func rlpEncode(tx *types.Transaction) ([]byte, error) { return b[:len(b)-3], nil } -func readGPOStorageSlots(addr common.Address, state StateDB) (*big.Int, *big.Int, *big.Float) { +func readGPOStorageSlots(addr common.Address, state StateDB) (*big.Int, *big.Int, *big.Int) { l1BaseFee := state.GetState(addr, rcfg.L1BaseFeeSlot) overhead := state.GetState(addr, rcfg.OverheadSlot) scalar := state.GetState(addr, rcfg.ScalarSlot) - scaled := ScalePrecision(scalar.Big(), rcfg.Precision) - return l1BaseFee.Big(), overhead.Big(), scaled -} - -// ScalePrecision will scale a value by precision -func ScalePrecision(scalar, precision *big.Int) *big.Float { - fscalar := new(big.Float).SetInt(scalar) - fdivisor := new(big.Float).SetInt(precision) - // fscalar / fdivisor - return new(big.Float).Quo(fscalar, fdivisor) + return l1BaseFee.Big(), overhead.Big(), scalar.Big() } // CalculateL1Fee computes the L1 fee -func CalculateL1Fee(data []byte, overhead, l1GasPrice *big.Int, scalar *big.Float) *big.Int { +func CalculateL1Fee(data []byte, overhead, l1GasPrice *big.Int, scalar *big.Int) *big.Int { l1GasUsed := CalculateL1GasUsed(data, overhead) l1Fee := new(big.Int).Mul(l1GasUsed, l1GasPrice) - return mulByFloat(l1Fee, scalar) + return mulAndScale(l1Fee, scalar, rcfg.Precision) } // CalculateL1GasUsed computes the L1 gas used based on the calldata and @@ -142,12 +132,9 @@ func zeroesAndOnes(data []byte) (uint64, uint64) { return zeroes, ones } -// mulByFloat multiplies a big.Int by a float and returns the -// big.Int rounded upwards -func mulByFloat(num *big.Int, float *big.Float) *big.Int { - n := new(big.Float).SetUint64(num.Uint64()) - product := n.Mul(n, float) - pfloat, _ := product.Float64() - rounded := math.Ceil(pfloat) - return new(big.Int).SetUint64(uint64(rounded)) +// mulAndScale multiplies a big.Int by a big.Int and then scale it by precision, +// rounded towards zero +func mulAndScale(x *big.Int, y *big.Int, precision *big.Int) *big.Int { + z := new(big.Int).Mul(x, y) + return new(big.Int).Quo(z, precision) } diff --git a/rollup/fees/rollup_fee_test.go b/rollup/fees/rollup_fee_test.go new file mode 100644 index 0000000000..d1bb2e9e74 --- /dev/null +++ b/rollup/fees/rollup_fee_test.go @@ -0,0 +1,20 @@ +package fees + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCalculateL1Fee(t *testing.T) { + l1BaseFee := new(big.Int).SetUint64(15000000) + + data := []byte{0, 10, 1, 0} + overhead := new(big.Int).SetUint64(100) + scalar := new(big.Int).SetUint64(10) + + expected := new(big.Int).SetUint64(184) // 184.2 + actual := CalculateL1Fee(data, overhead, l1BaseFee, scalar) + assert.Equal(t, expected, actual) +}