From 2aba16e2c9de358bf1aab4113321eeecc8227305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 9 Sep 2020 11:41:02 +0200 Subject: [PATCH 1/3] gas: Fix median calc --- node/impl/full/gas.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 2aa8a39ca..a3496cbd7 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -102,8 +102,8 @@ func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64, for _, price := range prices { prev1, prev2 = price.price, prev1 at -= price.limit - if at > 0 { - continue + if at < 0 { + break } } From f695c0c164313d62bc60f4d7d15f434f63172808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 9 Sep 2020 12:03:02 +0200 Subject: [PATCH 2/3] gas: Add tests to median premium math --- node/impl/full/gas.go | 61 +++++++++++++++++++++----------------- node/impl/full/gas_test.go | 40 +++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 node/impl/full/gas_test.go diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index a3496cbd7..4f29188c8 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -2,16 +2,15 @@ package full import ( "context" - "math" - "math/rand" - "sort" - "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" + "math" + "math/rand" + "sort" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" @@ -50,6 +49,35 @@ func (a *GasAPI) GasEstimateFeeCap(ctx context.Context, msg *types.Message, maxq return out, nil } +type gasMeta struct { + price big.Int + limit int64 +} + +func medianGasPremium(prices []gasMeta, blocks int) abi.TokenAmount { + sort.Slice(prices, func(i, j int) bool { + // sort desc by price + return prices[i].price.GreaterThan(prices[j].price) + }) + + at := build.BlockGasTarget * int64(blocks) / 2 + prev1, prev2 := big.Zero(), big.Zero() + for _, price := range prices { + prev1, prev2 = price.price, prev1 + at -= price.limit + if at < 0 { + break + } + } + + premium := prev1 + if prev2.Sign() != 0 { + premium = big.Div(types.BigAdd(prev1, prev2), types.NewInt(2)) + } + + return premium +} + func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64, sender address.Address, gaslimit int64, _ types.TipSetKey) (types.BigInt, error) { @@ -57,11 +85,6 @@ func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64, nblocksincl = 1 } - type gasMeta struct { - price big.Int - limit int64 - } - var prices []gasMeta var blocks int @@ -92,25 +115,7 @@ func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64, ts = pts } - sort.Slice(prices, func(i, j int) bool { - // sort desc by price - return prices[i].price.GreaterThan(prices[j].price) - }) - - at := build.BlockGasTarget * int64(blocks) / 2 - prev1, prev2 := big.Zero(), big.Zero() - for _, price := range prices { - prev1, prev2 = price.price, prev1 - at -= price.limit - if at < 0 { - break - } - } - - premium := prev1 - if prev2.Sign() != 0 { - premium = big.Div(types.BigAdd(prev1, prev2), types.NewInt(2)) - } + premium := medianGasPremium(prices, blocks) if types.BigCmp(premium, types.NewInt(MinGasPremium)) < 0 { switch nblocksincl { diff --git a/node/impl/full/gas_test.go b/node/impl/full/gas_test.go new file mode 100644 index 000000000..2452ab807 --- /dev/null +++ b/node/impl/full/gas_test.go @@ -0,0 +1,40 @@ +package full + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" +) + +func TestMedian(t *testing.T) { + require.Equal(t, types.NewInt(5), medianGasPremium([]gasMeta{ + {big.NewInt(5), build.BlockGasTarget}, + }, 1)) + + require.Equal(t, types.NewInt(10), medianGasPremium([]gasMeta{ + {big.NewInt(5), build.BlockGasTarget}, + {big.NewInt(10), build.BlockGasTarget}, + }, 1)) + + require.Equal(t, types.NewInt(15), medianGasPremium([]gasMeta{ + {big.NewInt(10), build.BlockGasTarget / 2}, + {big.NewInt(20), build.BlockGasTarget / 2}, + }, 1)) + + require.Equal(t, types.NewInt(25), medianGasPremium([]gasMeta{ + {big.NewInt(10), build.BlockGasTarget / 2}, + {big.NewInt(20), build.BlockGasTarget / 2}, + {big.NewInt(30), build.BlockGasTarget / 2}, + }, 1)) + + require.Equal(t, types.NewInt(15), medianGasPremium([]gasMeta{ + {big.NewInt(10), build.BlockGasTarget / 2}, + {big.NewInt(20), build.BlockGasTarget / 2}, + {big.NewInt(30), build.BlockGasTarget / 2}, + }, 2)) +} From e91ee9f62a43b4942772bb4bb414c31e661e7df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 9 Sep 2020 12:18:02 +0200 Subject: [PATCH 3/3] Fix lint --- node/impl/full/gas.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/node/impl/full/gas.go b/node/impl/full/gas.go index 4f29188c8..40ab88b6b 100644 --- a/node/impl/full/gas.go +++ b/node/impl/full/gas.go @@ -2,24 +2,25 @@ package full import ( "context" - "github.com/filecoin-project/lotus/api" - "github.com/filecoin-project/lotus/build" - "github.com/filecoin-project/lotus/chain/messagepool" - "github.com/filecoin-project/lotus/chain/stmgr" - "github.com/filecoin-project/lotus/chain/store" - "github.com/filecoin-project/lotus/chain/types" "math" "math/rand" "sort" + "go.uber.org/fx" + "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/specs-actors/actors/builtin" - "go.uber.org/fx" - "golang.org/x/xerrors" + "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/messagepool" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/store" + "github.com/filecoin-project/lotus/chain/types" ) type GasAPI struct {