2020-08-06 17:09:03 +00:00
|
|
|
package store
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/lotus/build"
|
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
|
|
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
2020-08-18 13:19:24 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
2020-08-06 17:09:03 +00:00
|
|
|
"golang.org/x/xerrors"
|
|
|
|
)
|
|
|
|
|
2020-08-07 01:34:50 +00:00
|
|
|
func computeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int) types.BigInt {
|
2020-08-18 13:19:24 +00:00
|
|
|
// deta := 1/PackingEfficiency * gasLimitUsed/noOfBlocks - build.BlockGasTarget
|
|
|
|
// change := baseFee * deta / BlockGasTarget / BaseFeeMaxChangeDenom
|
|
|
|
// nextBaseFee = baseFee + change
|
|
|
|
// nextBaseFee = max(nextBaseFee, build.MinimumBaseFee)
|
|
|
|
|
2020-08-18 15:40:53 +00:00
|
|
|
delta := build.PackingEfficiencyDenom * gasLimitUsed / (int64(noOfBlocks) * build.PackingEfficiencyNum)
|
2020-08-18 13:19:24 +00:00
|
|
|
delta -= build.BlockGasTarget
|
|
|
|
|
|
|
|
// cap change at 12.5% (BaseFeeMaxChangeDenom) by capping delta
|
|
|
|
if delta > build.BlockGasTarget {
|
|
|
|
delta = build.BlockGasTarget
|
|
|
|
}
|
|
|
|
if delta < -build.BlockGasTarget {
|
|
|
|
delta = -build.BlockGasTarget
|
|
|
|
}
|
2020-08-07 01:34:50 +00:00
|
|
|
|
|
|
|
change := big.Mul(baseFee, big.NewInt(delta))
|
|
|
|
change = big.Div(change, big.NewInt(build.BlockGasTarget))
|
|
|
|
change = big.Div(change, big.NewInt(build.BaseFeeMaxChangeDenom))
|
|
|
|
|
|
|
|
nextBaseFee := big.Add(baseFee, change)
|
|
|
|
if big.Cmp(nextBaseFee, big.NewInt(build.MinimumBaseFee)) < 0 {
|
|
|
|
nextBaseFee = big.NewInt(build.MinimumBaseFee)
|
|
|
|
}
|
|
|
|
return nextBaseFee
|
|
|
|
}
|
|
|
|
|
2020-08-06 17:09:03 +00:00
|
|
|
func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi.TokenAmount, error) {
|
|
|
|
zero := abi.NewTokenAmount(0)
|
2020-08-18 13:19:24 +00:00
|
|
|
|
|
|
|
// totalLimit is sum of GasLimits of unique messages in a tipset
|
2020-08-06 17:09:03 +00:00
|
|
|
totalLimit := int64(0)
|
2020-08-18 13:19:24 +00:00
|
|
|
|
|
|
|
seen := make(map[cid.Cid]struct{})
|
|
|
|
|
2020-08-06 17:09:03 +00:00
|
|
|
for _, b := range ts.Blocks() {
|
|
|
|
msg1, msg2, err := cs.MessagesForBlock(b)
|
|
|
|
if err != nil {
|
|
|
|
return zero, xerrors.Errorf("error getting messages for: %s: %w", b.Cid(), err)
|
|
|
|
}
|
|
|
|
for _, m := range msg1 {
|
2020-08-18 13:19:24 +00:00
|
|
|
c := m.Cid()
|
|
|
|
if _, ok := seen[c]; !ok {
|
|
|
|
totalLimit += m.GasLimit
|
|
|
|
seen[c] = struct{}{}
|
|
|
|
}
|
2020-08-06 17:09:03 +00:00
|
|
|
}
|
|
|
|
for _, m := range msg2 {
|
2020-08-18 13:19:24 +00:00
|
|
|
c := m.Cid()
|
|
|
|
if _, ok := seen[c]; !ok {
|
|
|
|
totalLimit += m.Message.GasLimit
|
|
|
|
seen[c] = struct{}{}
|
|
|
|
}
|
2020-08-06 17:09:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
parentBaseFee := ts.Blocks()[0].ParentBaseFee
|
|
|
|
|
2020-08-07 01:34:50 +00:00
|
|
|
return computeNextBaseFee(parentBaseFee, totalLimit, len(ts.Blocks())), nil
|
2020-08-06 17:09:03 +00:00
|
|
|
}
|