package store import ( "context" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/ipfs/go-cid" "golang.org/x/xerrors" ) func ComputeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int, epoch abi.ChainEpoch) types.BigInt { // deta := gasLimitUsed/noOfBlocks - build.BlockGasTarget // change := baseFee * deta / BlockGasTarget // nextBaseFee = baseFee + change // nextBaseFee = max(nextBaseFee, build.MinimumBaseFee) var delta int64 if epoch > build.UpgradeSmokeHeight { delta = gasLimitUsed / int64(noOfBlocks) delta -= build.BlockGasTarget } else { delta = build.PackingEfficiencyDenom * gasLimitUsed / (int64(noOfBlocks) * build.PackingEfficiencyNum) 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 } 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 } func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi.TokenAmount, error) { if build.UpgradeBreezeHeight >= 0 && ts.Height() > build.UpgradeBreezeHeight && ts.Height() < build.UpgradeBreezeHeight+build.BreezeGasTampingDuration { return abi.NewTokenAmount(100), nil } zero := abi.NewTokenAmount(0) // totalLimit is sum of GasLimits of unique messages in a tipset totalLimit := int64(0) seen := make(map[cid.Cid]struct{}) 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 { c := m.Cid() if _, ok := seen[c]; !ok { totalLimit += m.GasLimit seen[c] = struct{}{} } } for _, m := range msg2 { c := m.Cid() if _, ok := seen[c]; !ok { totalLimit += m.Message.GasLimit seen[c] = struct{}{} } } } parentBaseFee := ts.Blocks()[0].ParentBaseFee return ComputeNextBaseFee(parentBaseFee, totalLimit, len(ts.Blocks()), ts.Height()), nil }