Skip to content

Commit 223bf0c

Browse files
committed
feat: update base fee via cli
1 parent 3edb331 commit 223bf0c

File tree

9 files changed

+156
-14
lines changed

9 files changed

+156
-14
lines changed

cmd/geth/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ var (
185185
utils.DARecoverySignBlocksFlag,
186186
utils.DARecoveryL2EndBlockFlag,
187187
utils.DARecoveryProduceBlocksFlag,
188+
utils.L2BaseFeeScalarFlag,
189+
utils.L2BaseFeeOverheadFlag,
188190
}
189191

190192
rpcFlags = []cli.Flag{

cmd/geth/usage.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ var AppHelpFlagGroups = []flags.FlagGroup{
161161
utils.RPCGlobalEVMTimeoutFlag,
162162
utils.RPCGlobalTxFeeCapFlag,
163163
utils.AllowUnprotectedTxs,
164+
utils.MaxBlockRangeFlag,
164165
utils.JSpathFlag,
165166
utils.ExecFlag,
166167
utils.PreloadJSFlag,
@@ -227,6 +228,30 @@ var AppHelpFlagGroups = []flags.FlagGroup{
227228
Name: "METRICS AND STATS",
228229
Flags: metricsFlags,
229230
},
231+
{
232+
Name: "ROLLUP",
233+
Flags: []cli.Flag{
234+
utils.L1EndpointFlag,
235+
utils.L1ConfirmationsFlag,
236+
utils.L1DeploymentBlockFlag,
237+
utils.L1DisableMessageQueueV2Flag,
238+
utils.RollupVerifyEnabledFlag,
239+
utils.L2BaseFeeScalarFlag,
240+
utils.L2BaseFeeOverheadFlag,
241+
utils.DASyncEnabledFlag,
242+
utils.DABlobScanAPIEndpointFlag,
243+
utils.DABlockNativeAPIEndpointFlag,
244+
utils.DABeaconNodeAPIEndpointFlag,
245+
utils.DARecoveryModeFlag,
246+
utils.DARecoveryInitialL1BlockFlag,
247+
utils.DARecoveryInitialBatchFlag,
248+
utils.DARecoverySignBlocksFlag,
249+
utils.DARecoveryL2EndBlockFlag,
250+
utils.DARecoveryProduceBlocksFlag,
251+
utils.CircuitCapacityCheckEnabledFlag,
252+
utils.CircuitCapacityCheckWorkersFlag,
253+
},
254+
},
230255
{
231256
Name: "ALIASED (deprecated)",
232257
Flags: []cli.Flag{

cmd/utils/flags.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import (
4747
"github.com/scroll-tech/go-ethereum/consensus"
4848
"github.com/scroll-tech/go-ethereum/consensus/clique"
4949
"github.com/scroll-tech/go-ethereum/consensus/ethash"
50+
"github.com/scroll-tech/go-ethereum/consensus/misc"
5051
"github.com/scroll-tech/go-ethereum/core"
5152
"github.com/scroll-tech/go-ethereum/core/rawdb"
5253
"github.com/scroll-tech/go-ethereum/core/vm"
@@ -934,6 +935,18 @@ var (
934935
Name: "da.recovery.produceblocks",
935936
Usage: "Produce unsigned blocks after L1 recovery for permissionless batch submission",
936937
}
938+
939+
// L2 base fee settings
940+
L2BaseFeeScalarFlag = BigFlag{
941+
Name: "basefee.scalar",
942+
Usage: "Scalar used in l2 base fee formula. Signer nodes will use this for computing the next block's base fee. Follower nodes will use this in RPC.",
943+
Value: misc.DefaultBaseFeeScalar,
944+
}
945+
L2BaseFeeOverheadFlag = BigFlag{
946+
Name: "basefee.overhead",
947+
Usage: "Overhead used in l2 base fee formula. Signer nodes will use this for computing the next block's base fee. Follower nodes will use this in RPC.",
948+
Value: misc.DefaultBaseFeeOverhead,
949+
}
937950
)
938951

939952
// MakeDataDir retrieves the currently requested data directory, terminating
@@ -1709,6 +1722,29 @@ func setDA(ctx *cli.Context, cfg *ethconfig.Config) {
17091722
}
17101723
}
17111724

1725+
func setBaseFee(ctx *cli.Context, cfg *ethconfig.Config) {
1726+
cfg.BaseFeeScalar = misc.DefaultBaseFeeScalar
1727+
if ctx.GlobalIsSet(L2BaseFeeScalarFlag.Name) {
1728+
cfg.BaseFeeScalar = GlobalBig(ctx, L2BaseFeeScalarFlag.Name)
1729+
}
1730+
cfg.BaseFeeOverhead = misc.DefaultBaseFeeOverhead
1731+
if ctx.GlobalIsSet(L2BaseFeeOverheadFlag.Name) {
1732+
cfg.BaseFeeOverhead = GlobalBig(ctx, L2BaseFeeOverheadFlag.Name)
1733+
}
1734+
1735+
log.Info("L2 base fee coefficients", "scalar", cfg.BaseFeeScalar, "overhead", cfg.BaseFeeOverhead)
1736+
1737+
var minBaseFee uint64
1738+
if fee := misc.MinBaseFee(cfg.Genesis.Config); fee.IsUint64() {
1739+
minBaseFee = fee.Uint64()
1740+
}
1741+
1742+
if cfg.TxPool.PriceLimit < minBaseFee {
1743+
log.Warn("Updating txpool price limit to min L2 base fee", "provided", cfg.TxPool.PriceLimit, "updated", minBaseFee)
1744+
cfg.TxPool.PriceLimit = minBaseFee
1745+
}
1746+
}
1747+
17121748
func setMaxBlockRange(ctx *cli.Context, cfg *ethconfig.Config) {
17131749
if ctx.GlobalIsSet(MaxBlockRangeFlag.Name) {
17141750
cfg.MaxBlockRange = ctx.GlobalInt64(MaxBlockRangeFlag.Name)
@@ -1785,6 +1821,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
17851821
setCircuitCapacityCheck(ctx, cfg)
17861822
setEnableRollupVerify(ctx, cfg)
17871823
setDA(ctx, cfg)
1824+
setBaseFee(ctx, cfg)
17881825
setMaxBlockRange(ctx, cfg)
17891826
if ctx.GlobalIsSet(ShadowforkPeersFlag.Name) {
17901827
cfg.ShadowForkPeerIDs = ctx.GlobalStringSlice(ShadowforkPeersFlag.Name)

consensus/misc/eip1559.go

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ import (
2828
// We would only go above this if L1 base fee hits 2931 Gwei.
2929
const MaximumL2BaseFee = 10000000000
3030

31+
var (
32+
BaseFeePrecision = new(big.Int).SetUint64(1e18)
33+
DefaultBaseFeeScalar = new(big.Int).SetUint64(34000000000000)
34+
DefaultBaseFeeOverhead = new(big.Int).SetUint64(15680000)
35+
)
36+
3137
// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559,
3238
// - gas limit check
3339
// - basefee check
@@ -54,22 +60,34 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header, parentL1BaseF
5460
if config.Clique != nil && config.Clique.ShadowForkHeight != 0 && parent.Number.Uint64() >= config.Clique.ShadowForkHeight {
5561
return big.NewInt(10000000) // 0.01 Gwei
5662
}
57-
l2SequencerFee := big.NewInt(1000000) // 0.001 Gwei
58-
provingFee := big.NewInt(14680000) // 0.01468 Gwei
5963

60-
// L1_base_fee * 0.000034
61-
verificationFee := parentL1BaseFee
62-
verificationFee = new(big.Int).Mul(verificationFee, big.NewInt(34))
63-
verificationFee = new(big.Int).Div(verificationFee, big.NewInt(1000000))
64+
return calcBaseFee(config, parentL1BaseFee)
65+
}
66+
67+
// l2BaseFee = (l1BaseFee * scalar) / PRECISION + overhead
68+
func calcBaseFee(config *params.ChainConfig, parentL1BaseFee *big.Int) *big.Int {
69+
scalar := config.Scroll.BaseFeeScalar
70+
if scalar == nil {
71+
scalar = DefaultBaseFeeScalar
72+
}
73+
overhead := config.Scroll.BaseFeeOverhead
74+
if overhead == nil {
75+
overhead = DefaultBaseFeeOverhead
76+
}
6477

65-
baseFee := big.NewInt(0)
66-
baseFee.Add(baseFee, l2SequencerFee)
67-
baseFee.Add(baseFee, provingFee)
68-
baseFee.Add(baseFee, verificationFee)
78+
baseFee := parentL1BaseFee
79+
baseFee.Mul(baseFee, scalar)
80+
baseFee.Div(baseFee, BaseFeePrecision)
81+
baseFee.Add(baseFee, overhead)
6982

7083
if baseFee.Cmp(big.NewInt(MaximumL2BaseFee)) > 0 {
7184
baseFee = big.NewInt(MaximumL2BaseFee)
7285
}
7386

7487
return baseFee
7588
}
89+
90+
// MinBaseFee calculates the minimum L2 base fee based on the configured coefficients.
91+
func MinBaseFee(config *params.ChainConfig) *big.Int {
92+
return calcBaseFee(config, big.NewInt(0))
93+
}

consensus/misc/eip1559_test.go

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,27 @@ func TestCalcBaseFee(t *testing.T) {
111111
tests := []struct {
112112
parentL1BaseFee int64
113113
expectedL2BaseFee int64
114+
}{
115+
{0, 1},
116+
{1000000000, 1},
117+
{2000000000, 1},
118+
{100000000000, 2},
119+
{111111111111, 2},
120+
{2164000000000, 22},
121+
{644149677419355, 6442},
122+
}
123+
for i, test := range tests {
124+
config := config()
125+
config.Scroll.BaseFeeScalar = big.NewInt(10000000)
126+
config.Scroll.BaseFeeOverhead = big.NewInt(1)
127+
if have, want := CalcBaseFee(config, nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 {
128+
t.Errorf("test %d: have %d want %d, ", i, have, want)
129+
}
130+
}
131+
132+
testsWithDefaults := []struct {
133+
parentL1BaseFee int64
134+
expectedL2BaseFee int64
114135
}{
115136
{0, 15680000},
116137
{1000000000, 15714000},
@@ -120,9 +141,23 @@ func TestCalcBaseFee(t *testing.T) {
120141
{2164000000000, 89256000},
121142
{644149677419355, 10000000000}, // cap at max L2 base fee
122143
}
123-
for i, test := range tests {
144+
for i, test := range testsWithDefaults {
124145
if have, want := CalcBaseFee(config(), nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 {
125146
t.Errorf("test %d: have %d want %d, ", i, have, want)
126147
}
127148
}
128149
}
150+
151+
// TestMinBaseFee assumes all blocks are 1559-blocks
152+
func TestMinBaseFee(t *testing.T) {
153+
config := config()
154+
if have, want := MinBaseFee(config), big.NewInt(15680000); have.Cmp(want) != 0 {
155+
t.Errorf("have %d want %d, ", have, want)
156+
}
157+
158+
config.Scroll.BaseFeeScalar = big.NewInt(10000000)
159+
config.Scroll.BaseFeeOverhead = big.NewInt(1)
160+
if have, want := MinBaseFee(config), big.NewInt(1); have.Cmp(want) != 0 {
161+
t.Errorf("have %d want %d, ", have, want)
162+
}
163+
}

eth/backend.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client l1.Client) (*Ether
150150
}
151151
log.Info("Initialised chain configuration", "config", chainConfig)
152152

153+
// Hacky workaround:
154+
// It's hard to pass these fields to `CalcBaseFee`, etc.
155+
// So pass them as part of the genesis config instead.
156+
chainConfig.Scroll.BaseFeeScalar = config.BaseFeeScalar
157+
chainConfig.Scroll.BaseFeeOverhead = config.BaseFeeOverhead
158+
153159
if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil {
154160
log.Error("Failed to recover state", "error", err)
155161
}

eth/ethconfig/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@ type Config struct {
230230

231231
// DA syncer options
232232
DA da_syncer.Config
233+
234+
// L2 base fee coefficients for the formula: `l2BaseFee = (l1BaseFee * scalar) / PRECISION + overhead`.
235+
BaseFeeScalar *big.Int
236+
BaseFeeOverhead *big.Int
233237
}
234238

235239
// CreateConsensusEngine creates a consensus engine for the given chain configuration.

params/config.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,11 @@ type ScrollConfig struct {
704704

705705
// Genesis State Root for MPT clients
706706
GenesisStateRoot *common.Hash `json:"genesisStateRoot,omitempty"`
707+
708+
// L2 base fee coefficients for the formula: `l2BaseFee = (l1BaseFee * scalar) / PRECISION + overhead`.
709+
// These fields are populated from configuration flags, and passed to `CalcBaseFee`.
710+
BaseFeeScalar *big.Int `json:"-"`
711+
BaseFeeOverhead *big.Int `json:"-"`
707712
}
708713

709714
// L1Config contains the l1 parameters needed to sync l1 contract events (e.g., l1 messages, commit/revert/finalize batches) in the sequencer
@@ -753,8 +758,18 @@ func (s ScrollConfig) String() string {
753758
genesisStateRoot = fmt.Sprintf("%v", *s.GenesisStateRoot)
754759
}
755760

756-
return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: %v, MaxTxPayloadBytesPerBlock: %v, feeVaultAddress: %v, l1Config: %v, genesisStateRoot: %v}",
757-
s.UseZktrie, maxTxPerBlock, maxTxPayloadBytesPerBlock, s.FeeVaultAddress, s.L1Config.String(), genesisStateRoot)
761+
baseFeeScalar := "<nil>"
762+
if s.BaseFeeScalar != nil {
763+
baseFeeScalar = fmt.Sprintf("%v", *s.BaseFeeScalar)
764+
}
765+
766+
baseFeeOverhead := "<nil>"
767+
if s.BaseFeeOverhead != nil {
768+
baseFeeOverhead = fmt.Sprintf("%v", *s.BaseFeeOverhead)
769+
}
770+
771+
return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: %v, MaxTxPayloadBytesPerBlock: %v, feeVaultAddress: %v, l1Config: %v, genesisStateRoot: %v, baseFeeScalar: %v, baseFeeOverhead: %v}",
772+
s.UseZktrie, maxTxPerBlock, maxTxPayloadBytesPerBlock, s.FeeVaultAddress, s.L1Config.String(), genesisStateRoot, baseFeeScalar, baseFeeOverhead)
758773
}
759774

760775
// IsValidTxCount returns whether the given block's transaction count is below the limit.

params/version.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import (
2424
const (
2525
VersionMajor = 5 // Major version component of the current release
2626
VersionMinor = 8 // Minor version component of the current release
27-
VersionPatch = 44 // Patch version component of the current release
27+
VersionPatch = 45 // Patch version component of the current release
2828
VersionMeta = "mainnet" // Version metadata to append to the version string
2929
)
3030

0 commit comments

Comments
 (0)