gas: Add tests to median premium math
This commit is contained in:
parent
2aba16e2c9
commit
f695c0c164
@ -2,16 +2,15 @@ package full
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"math"
|
|
||||||
"math/rand"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"math"
|
||||||
|
"math/rand"
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"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
|
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,
|
func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64,
|
||||||
sender address.Address, gaslimit int64, _ types.TipSetKey) (types.BigInt, error) {
|
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
|
nblocksincl = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
type gasMeta struct {
|
|
||||||
price big.Int
|
|
||||||
limit int64
|
|
||||||
}
|
|
||||||
|
|
||||||
var prices []gasMeta
|
var prices []gasMeta
|
||||||
var blocks int
|
var blocks int
|
||||||
|
|
||||||
@ -92,25 +115,7 @@ func (a *GasAPI) GasEstimateGasPremium(ctx context.Context, nblocksincl uint64,
|
|||||||
ts = pts
|
ts = pts
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Slice(prices, func(i, j int) bool {
|
premium := medianGasPremium(prices, blocks)
|
||||||
// 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))
|
|
||||||
}
|
|
||||||
|
|
||||||
if types.BigCmp(premium, types.NewInt(MinGasPremium)) < 0 {
|
if types.BigCmp(premium, types.NewInt(MinGasPremium)) < 0 {
|
||||||
switch nblocksincl {
|
switch nblocksincl {
|
||||||
|
40
node/impl/full/gas_test.go
Normal file
40
node/impl/full/gas_test.go
Normal file
@ -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))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user