mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 14:16:44 +00:00
feat: update base fee via contract (#1189)
* Revert "feat: update base fee via cli (#1183)"
This reverts commit 0b6f8f1889.
* feat: update l2 base fee via system contract
* nit
* bump version
* fix tests
* update contract abi
* init coefficients on startup
* nil check
* update test
* update txpool gas price
* init with default value
* update scroll sepolia and mainnet contract addresses
* nit
* update txpool min price during startup
* print stack trace for worker panic
* fix event parsing
* fix log
* improve txpool update logic
* move initializeL2BaseFeeCoefficients to misc package
* bump version
* add API to query L2 base fee coefficients via console
* fix code review suggestion
This commit is contained in:
parent
d8f4932bf2
commit
cdd77c1659
18 changed files with 338 additions and 104 deletions
|
|
@ -29,6 +29,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/accounts/keystore"
|
"github.com/scroll-tech/go-ethereum/accounts/keystore"
|
||||||
"github.com/scroll-tech/go-ethereum/cmd/utils"
|
"github.com/scroll-tech/go-ethereum/cmd/utils"
|
||||||
"github.com/scroll-tech/go-ethereum/common"
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
|
"github.com/scroll-tech/go-ethereum/consensus/misc"
|
||||||
"github.com/scroll-tech/go-ethereum/console/prompt"
|
"github.com/scroll-tech/go-ethereum/console/prompt"
|
||||||
"github.com/scroll-tech/go-ethereum/eth"
|
"github.com/scroll-tech/go-ethereum/eth"
|
||||||
"github.com/scroll-tech/go-ethereum/eth/downloader"
|
"github.com/scroll-tech/go-ethereum/eth/downloader"
|
||||||
|
|
@ -185,8 +186,6 @@ var (
|
||||||
utils.DARecoverySignBlocksFlag,
|
utils.DARecoverySignBlocksFlag,
|
||||||
utils.DARecoveryL2EndBlockFlag,
|
utils.DARecoveryL2EndBlockFlag,
|
||||||
utils.DARecoveryProduceBlocksFlag,
|
utils.DARecoveryProduceBlocksFlag,
|
||||||
utils.L2BaseFeeScalarFlag,
|
|
||||||
utils.L2BaseFeeOverheadFlag,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcFlags = []cli.Flag{
|
rpcFlags = []cli.Flag{
|
||||||
|
|
@ -455,8 +454,9 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) {
|
||||||
utils.Fatalf("Ethereum service not running")
|
utils.Fatalf("Ethereum service not running")
|
||||||
}
|
}
|
||||||
// Set the gas price to the limits from the CLI and start mining
|
// Set the gas price to the limits from the CLI and start mining
|
||||||
gasprice := utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
|
// gasprice := utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
|
||||||
ethBackend.TxPool().SetGasPrice(gasprice)
|
// ethBackend.TxPool().SetGasPrice(gasprice)
|
||||||
|
ethBackend.TxPool().SetGasPrice(misc.MinBaseFee()) // override configured min gas price
|
||||||
ethBackend.TxPool().SetIsMiner(true)
|
ethBackend.TxPool().SetIsMiner(true)
|
||||||
// start mining
|
// start mining
|
||||||
threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name)
|
threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name)
|
||||||
|
|
|
||||||
|
|
@ -236,8 +236,6 @@ var AppHelpFlagGroups = []flags.FlagGroup{
|
||||||
utils.L1DeploymentBlockFlag,
|
utils.L1DeploymentBlockFlag,
|
||||||
utils.L1DisableMessageQueueV2Flag,
|
utils.L1DisableMessageQueueV2Flag,
|
||||||
utils.RollupVerifyEnabledFlag,
|
utils.RollupVerifyEnabledFlag,
|
||||||
utils.L2BaseFeeScalarFlag,
|
|
||||||
utils.L2BaseFeeOverheadFlag,
|
|
||||||
utils.DASyncEnabledFlag,
|
utils.DASyncEnabledFlag,
|
||||||
utils.DABlobScanAPIEndpointFlag,
|
utils.DABlobScanAPIEndpointFlag,
|
||||||
utils.DABlockNativeAPIEndpointFlag,
|
utils.DABlockNativeAPIEndpointFlag,
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,6 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/consensus"
|
"github.com/scroll-tech/go-ethereum/consensus"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/clique"
|
"github.com/scroll-tech/go-ethereum/consensus/clique"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/ethash"
|
"github.com/scroll-tech/go-ethereum/consensus/ethash"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/misc"
|
|
||||||
"github.com/scroll-tech/go-ethereum/core"
|
"github.com/scroll-tech/go-ethereum/core"
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
"github.com/scroll-tech/go-ethereum/core/vm"
|
"github.com/scroll-tech/go-ethereum/core/vm"
|
||||||
|
|
@ -935,18 +934,6 @@ var (
|
||||||
Name: "da.recovery.produceblocks",
|
Name: "da.recovery.produceblocks",
|
||||||
Usage: "Produce unsigned blocks after L1 recovery for permissionless batch submission",
|
Usage: "Produce unsigned blocks after L1 recovery for permissionless batch submission",
|
||||||
}
|
}
|
||||||
|
|
||||||
// L2 base fee settings
|
|
||||||
L2BaseFeeScalarFlag = BigFlag{
|
|
||||||
Name: "basefee.scalar",
|
|
||||||
Usage: "Scalar used in the l2 base fee formula. Signer nodes will use this for computing the next block's base fee. Follower nodes will use this in RPC.",
|
|
||||||
Value: misc.DefaultBaseFeeScalar,
|
|
||||||
}
|
|
||||||
L2BaseFeeOverheadFlag = BigFlag{
|
|
||||||
Name: "basefee.overhead",
|
|
||||||
Usage: "Overhead used in the l2 base fee formula. Signer nodes will use this for computing the next block's base fee. Follower nodes will use this in RPC.",
|
|
||||||
Value: misc.DefaultBaseFeeOverhead,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MakeDataDir retrieves the currently requested data directory, terminating
|
// MakeDataDir retrieves the currently requested data directory, terminating
|
||||||
|
|
@ -1722,29 +1709,6 @@ func setDA(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setBaseFee(ctx *cli.Context, cfg *ethconfig.Config) {
|
|
||||||
cfg.BaseFeeScalar = misc.DefaultBaseFeeScalar
|
|
||||||
if ctx.GlobalIsSet(L2BaseFeeScalarFlag.Name) {
|
|
||||||
cfg.BaseFeeScalar = GlobalBig(ctx, L2BaseFeeScalarFlag.Name)
|
|
||||||
}
|
|
||||||
cfg.BaseFeeOverhead = misc.DefaultBaseFeeOverhead
|
|
||||||
if ctx.GlobalIsSet(L2BaseFeeOverheadFlag.Name) {
|
|
||||||
cfg.BaseFeeOverhead = GlobalBig(ctx, L2BaseFeeOverheadFlag.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("L2 base fee coefficients", "scalar", cfg.BaseFeeScalar, "overhead", cfg.BaseFeeOverhead)
|
|
||||||
|
|
||||||
var minBaseFee uint64
|
|
||||||
if fee := misc.MinBaseFee(cfg.BaseFeeScalar, cfg.BaseFeeOverhead); fee.IsUint64() {
|
|
||||||
minBaseFee = fee.Uint64()
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.TxPool.PriceLimit < minBaseFee {
|
|
||||||
log.Warn("Updating txpool price limit to min L2 base fee", "provided", cfg.TxPool.PriceLimit, "updated", minBaseFee)
|
|
||||||
cfg.TxPool.PriceLimit = minBaseFee
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func setMaxBlockRange(ctx *cli.Context, cfg *ethconfig.Config) {
|
func setMaxBlockRange(ctx *cli.Context, cfg *ethconfig.Config) {
|
||||||
if ctx.GlobalIsSet(MaxBlockRangeFlag.Name) {
|
if ctx.GlobalIsSet(MaxBlockRangeFlag.Name) {
|
||||||
cfg.MaxBlockRange = ctx.GlobalInt64(MaxBlockRangeFlag.Name)
|
cfg.MaxBlockRange = ctx.GlobalInt64(MaxBlockRangeFlag.Name)
|
||||||
|
|
@ -1821,7 +1785,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
|
||||||
setCircuitCapacityCheck(ctx, cfg)
|
setCircuitCapacityCheck(ctx, cfg)
|
||||||
setEnableRollupVerify(ctx, cfg)
|
setEnableRollupVerify(ctx, cfg)
|
||||||
setDA(ctx, cfg)
|
setDA(ctx, cfg)
|
||||||
setBaseFee(ctx, cfg)
|
|
||||||
setMaxBlockRange(ctx, cfg)
|
setMaxBlockRange(ctx, cfg)
|
||||||
if ctx.GlobalIsSet(ShadowforkPeersFlag.Name) {
|
if ctx.GlobalIsSet(ShadowforkPeersFlag.Name) {
|
||||||
cfg.ShadowForkPeerIDs = ctx.GlobalStringSlice(ShadowforkPeersFlag.Name)
|
cfg.ShadowForkPeerIDs = ctx.GlobalStringSlice(ShadowforkPeersFlag.Name)
|
||||||
|
|
|
||||||
|
|
@ -19,25 +19,67 @@ package misc
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
"github.com/scroll-tech/go-ethereum/core/types"
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
|
"github.com/scroll-tech/go-ethereum/rollup/rcfg"
|
||||||
|
"github.com/scroll-tech/go-ethereum/rpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
// Protocol-enforced maximum L2 base fee.
|
// Protocol-enforced maximum L2 base fee.
|
||||||
// We would only go above this if L1 base fee hits 2931 Gwei.
|
// We would only go above this if L1 base fee hits 2931 Gwei.
|
||||||
const MaximumL2BaseFee = 10000000000
|
MaximumL2BaseFee = 10000000000
|
||||||
|
|
||||||
|
// L2 base fee fallback values, in case the L2 system contract
|
||||||
|
// is not deployed on not configured yet.
|
||||||
|
DefaultBaseFeeOverhead = 15680000
|
||||||
|
DefaultBaseFeeScalar = 34000000000000
|
||||||
|
)
|
||||||
|
|
||||||
// L2 base fee formula constants and defaults.
|
// L2 base fee formula constants and defaults.
|
||||||
// l2BaseFee = (l1BaseFee * scalar) / PRECISION + overhead.
|
// l2BaseFee = (l1BaseFee * scalar) / PRECISION + overhead.
|
||||||
// `scalar` accounts for finalization costs. `overhead` accounts for sequencing and proving costs.
|
// `scalar` accounts for finalization costs. `overhead` accounts for sequencing and proving costs.
|
||||||
// we use 1e18 for precision to match the contract implementation.
|
|
||||||
var (
|
var (
|
||||||
|
// We use 1e18 for precision to match the contract implementation.
|
||||||
BaseFeePrecision = new(big.Int).SetUint64(1e18)
|
BaseFeePrecision = new(big.Int).SetUint64(1e18)
|
||||||
DefaultBaseFeeScalar = new(big.Int).SetUint64(34000000000000)
|
|
||||||
DefaultBaseFeeOverhead = new(big.Int).SetUint64(15680000)
|
// scalar and overhead are updated automatically in `Blockchain.writeBlockWithState`.
|
||||||
|
baseFeeScalar = big.NewInt(0)
|
||||||
|
baseFeeOverhead = big.NewInt(0)
|
||||||
|
|
||||||
|
lock sync.RWMutex
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func ReadL2BaseFeeCoefficients() (scalar *big.Int, overhead *big.Int) {
|
||||||
|
lock.RLock()
|
||||||
|
defer lock.RUnlock()
|
||||||
|
return new(big.Int).Set(baseFeeScalar), new(big.Int).Set(baseFeeOverhead)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateL2BaseFeeOverhead(newOverhead *big.Int) {
|
||||||
|
if newOverhead == nil {
|
||||||
|
log.Error("Failed to set L2 base fee overhead, new value is <nil>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
baseFeeOverhead.Set(newOverhead)
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateL2BaseFeeScalar(newScalar *big.Int) {
|
||||||
|
if newScalar == nil {
|
||||||
|
log.Error("Failed to set L2 base fee scalar, new value is <nil>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
baseFeeScalar.Set(newScalar)
|
||||||
|
}
|
||||||
|
|
||||||
// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559,
|
// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559,
|
||||||
// - gas limit check
|
// - gas limit check
|
||||||
// - basefee check
|
// - basefee check
|
||||||
|
|
@ -65,20 +107,13 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header, parentL1BaseF
|
||||||
return big.NewInt(10000000) // 0.01 Gwei
|
return big.NewInt(10000000) // 0.01 Gwei
|
||||||
}
|
}
|
||||||
|
|
||||||
scalar := config.Scroll.BaseFeeScalar
|
scalar, overhead := ReadL2BaseFeeCoefficients()
|
||||||
if scalar == nil {
|
|
||||||
scalar = DefaultBaseFeeScalar
|
|
||||||
}
|
|
||||||
overhead := config.Scroll.BaseFeeOverhead
|
|
||||||
if overhead == nil {
|
|
||||||
overhead = DefaultBaseFeeOverhead
|
|
||||||
}
|
|
||||||
|
|
||||||
return calcBaseFee(scalar, overhead, parentL1BaseFee)
|
return calcBaseFee(scalar, overhead, parentL1BaseFee)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MinBaseFee calculates the minimum L2 base fee based on the configured coefficients.
|
// MinBaseFee calculates the minimum L2 base fee based on the current coefficients.
|
||||||
func MinBaseFee(scalar, overhead *big.Int) *big.Int {
|
func MinBaseFee() *big.Int {
|
||||||
|
scalar, overhead := ReadL2BaseFeeCoefficients()
|
||||||
return calcBaseFee(scalar, overhead, big.NewInt(0))
|
return calcBaseFee(scalar, overhead, big.NewInt(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,3 +129,60 @@ func calcBaseFee(scalar, overhead, parentL1BaseFee *big.Int) *big.Int {
|
||||||
|
|
||||||
return baseFee
|
return baseFee
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type State interface {
|
||||||
|
GetState(addr common.Address, hash common.Hash) common.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitializeL2BaseFeeCoefficients(chainConfig *params.ChainConfig, state State) error {
|
||||||
|
overhead := common.Big0
|
||||||
|
scalar := common.Big0
|
||||||
|
|
||||||
|
if l2SystemConfig := chainConfig.Scroll.L2SystemConfigAddress(); l2SystemConfig != (common.Address{}) {
|
||||||
|
overhead = state.GetState(l2SystemConfig, rcfg.L2BaseFeeOverheadSlot).Big()
|
||||||
|
scalar = state.GetState(l2SystemConfig, rcfg.L2BaseFeeScalarSlot).Big()
|
||||||
|
} else {
|
||||||
|
log.Warn("L2SystemConfig address is not configured")
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback to default if contract is not deployed or configured yet
|
||||||
|
if overhead.Cmp(common.Big0) == 0 {
|
||||||
|
overhead = big.NewInt(DefaultBaseFeeOverhead)
|
||||||
|
}
|
||||||
|
if scalar.Cmp(common.Big0) == 0 {
|
||||||
|
scalar = big.NewInt(DefaultBaseFeeScalar)
|
||||||
|
}
|
||||||
|
|
||||||
|
// update local view of coefficients
|
||||||
|
lock.Lock()
|
||||||
|
defer lock.Unlock()
|
||||||
|
baseFeeOverhead.Set(overhead)
|
||||||
|
baseFeeScalar.Set(scalar)
|
||||||
|
log.Info("Initialized L2 base fee coefficients", "overhead", overhead, "scalar", scalar)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type API struct{}
|
||||||
|
|
||||||
|
type L2BaseFeeConfig struct {
|
||||||
|
Scalar *big.Int `json:"scalar,omitempty"`
|
||||||
|
Overhead *big.Int `json:"overhead,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api *API) GetL2BaseFeeConfig() *L2BaseFeeConfig {
|
||||||
|
scalar, overhead := ReadL2BaseFeeCoefficients()
|
||||||
|
|
||||||
|
return &L2BaseFeeConfig{
|
||||||
|
Scalar: scalar,
|
||||||
|
Overhead: overhead,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func APIs() []rpc.API {
|
||||||
|
return []rpc.API{{
|
||||||
|
Namespace: "scroll",
|
||||||
|
Version: "1.0",
|
||||||
|
Service: &API{},
|
||||||
|
Public: false,
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,8 +122,8 @@ func TestCalcBaseFee(t *testing.T) {
|
||||||
}
|
}
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
config := config()
|
config := config()
|
||||||
config.Scroll.BaseFeeScalar = big.NewInt(10000000)
|
UpdateL2BaseFeeScalar(big.NewInt(10000000))
|
||||||
config.Scroll.BaseFeeOverhead = big.NewInt(1)
|
UpdateL2BaseFeeOverhead(big.NewInt(1))
|
||||||
if have, want := CalcBaseFee(config, nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 {
|
if have, want := CalcBaseFee(config, nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 {
|
||||||
t.Errorf("test %d: have %d want %d, ", i, have, want)
|
t.Errorf("test %d: have %d want %d, ", i, have, want)
|
||||||
}
|
}
|
||||||
|
|
@ -142,6 +142,8 @@ func TestCalcBaseFee(t *testing.T) {
|
||||||
{644149677419355, 10000000000}, // cap at max L2 base fee
|
{644149677419355, 10000000000}, // cap at max L2 base fee
|
||||||
}
|
}
|
||||||
for i, test := range testsWithDefaults {
|
for i, test := range testsWithDefaults {
|
||||||
|
UpdateL2BaseFeeScalar(big.NewInt(34000000000000))
|
||||||
|
UpdateL2BaseFeeOverhead(big.NewInt(15680000))
|
||||||
if have, want := CalcBaseFee(config(), nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 {
|
if have, want := CalcBaseFee(config(), nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 {
|
||||||
t.Errorf("test %d: have %d want %d, ", i, have, want)
|
t.Errorf("test %d: have %d want %d, ", i, have, want)
|
||||||
}
|
}
|
||||||
|
|
@ -150,11 +152,15 @@ func TestCalcBaseFee(t *testing.T) {
|
||||||
|
|
||||||
// TestMinBaseFee assumes all blocks are 1559-blocks
|
// TestMinBaseFee assumes all blocks are 1559-blocks
|
||||||
func TestMinBaseFee(t *testing.T) {
|
func TestMinBaseFee(t *testing.T) {
|
||||||
if have, want := MinBaseFee(DefaultBaseFeeScalar, DefaultBaseFeeOverhead), big.NewInt(15680000); have.Cmp(want) != 0 {
|
UpdateL2BaseFeeScalar(big.NewInt(34000000000000))
|
||||||
|
UpdateL2BaseFeeOverhead(big.NewInt(15680000))
|
||||||
|
if have, want := MinBaseFee(), big.NewInt(15680000); have.Cmp(want) != 0 {
|
||||||
t.Errorf("have %d want %d, ", have, want)
|
t.Errorf("have %d want %d, ", have, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
if have, want := MinBaseFee(big.NewInt(10000000), big.NewInt(1)), big.NewInt(1); have.Cmp(want) != 0 {
|
UpdateL2BaseFeeScalar(big.NewInt(10000000))
|
||||||
|
UpdateL2BaseFeeOverhead(big.NewInt(1))
|
||||||
|
if have, want := MinBaseFee(), big.NewInt(1); have.Cmp(want) != 0 {
|
||||||
t.Errorf("have %d want %d, ", have, want)
|
t.Errorf("have %d want %d, ", have, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/common/mclock"
|
"github.com/scroll-tech/go-ethereum/common/mclock"
|
||||||
"github.com/scroll-tech/go-ethereum/common/prque"
|
"github.com/scroll-tech/go-ethereum/common/prque"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus"
|
"github.com/scroll-tech/go-ethereum/consensus"
|
||||||
|
"github.com/scroll-tech/go-ethereum/consensus/misc"
|
||||||
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
"github.com/scroll-tech/go-ethereum/core/rawdb"
|
||||||
"github.com/scroll-tech/go-ethereum/core/state"
|
"github.com/scroll-tech/go-ethereum/core/state"
|
||||||
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
"github.com/scroll-tech/go-ethereum/core/state/snapshot"
|
||||||
|
|
@ -45,6 +46,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/log"
|
"github.com/scroll-tech/go-ethereum/log"
|
||||||
"github.com/scroll-tech/go-ethereum/metrics"
|
"github.com/scroll-tech/go-ethereum/metrics"
|
||||||
"github.com/scroll-tech/go-ethereum/params"
|
"github.com/scroll-tech/go-ethereum/params"
|
||||||
|
"github.com/scroll-tech/go-ethereum/rollup/l2_system_config"
|
||||||
"github.com/scroll-tech/go-ethereum/trie"
|
"github.com/scroll-tech/go-ethereum/trie"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -56,6 +58,7 @@ var (
|
||||||
headL1MessageGauge = metrics.NewRegisteredGauge("chain/head/l1msg", nil)
|
headL1MessageGauge = metrics.NewRegisteredGauge("chain/head/l1msg", nil)
|
||||||
|
|
||||||
l2BaseFeeGauge = metrics.NewRegisteredGauge("chain/fees/l2basefee", nil)
|
l2BaseFeeGauge = metrics.NewRegisteredGauge("chain/fees/l2basefee", nil)
|
||||||
|
l2BaseFeeUpdateTimer = metrics.NewRegisteredTimer("chain/fees/updates", nil)
|
||||||
|
|
||||||
accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil)
|
accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil)
|
||||||
accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil)
|
accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil)
|
||||||
|
|
@ -161,6 +164,39 @@ func updateHeadL1msgGauge(block *types.Block) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updateL2BaseFeeCoefficients updates the global L2 base fee coefficients.
|
||||||
|
// Coefficient updates are written into L2 state and emit an event.
|
||||||
|
// We could use either here; we read from the event to avoid state reads.
|
||||||
|
// In the future, if the base fee setting becomes part of block validation,
|
||||||
|
// reading from state will be more appropriate.
|
||||||
|
func updateL2BaseFeeCoefficients(l2SystemConfigAddress common.Address, logs []*types.Log) {
|
||||||
|
defer func(start time.Time) { l2BaseFeeUpdateTimer.Update(time.Since(start)) }(time.Now())
|
||||||
|
|
||||||
|
for _, l := range logs {
|
||||||
|
if l.Address != l2SystemConfigAddress {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
switch l.Topics[0] {
|
||||||
|
case l2_system_config.BaseFeeOverheadUpdatedTopic:
|
||||||
|
event, err := l2_system_config.UnpackBaseFeeOverheadUpdatedEvent(*l)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to unpack base fee overhead updated event log", "err", err, "log", *l)
|
||||||
|
break // break from switch, continue loop
|
||||||
|
}
|
||||||
|
misc.UpdateL2BaseFeeOverhead(event.NewBaseFeeOverhead)
|
||||||
|
log.Info("Updated L2 base fee overhead", "blockNumber", l.BlockNumber, "blockHash", l.BlockHash.Hex(), "old", event.OldBaseFeeOverhead, "new", event.NewBaseFeeOverhead)
|
||||||
|
case l2_system_config.BaseFeeScalarUpdatedTopic:
|
||||||
|
event, err := l2_system_config.UnpackBaseFeeScalarUpdatedEvent(*l)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to unpack base fee scalar updated event log", "err", err, "log", *l)
|
||||||
|
break // break from switch, continue loop
|
||||||
|
}
|
||||||
|
misc.UpdateL2BaseFeeScalar(event.NewBaseFeeScalar)
|
||||||
|
log.Info("Updated L2 base fee scalar", "blockNumber", l.BlockNumber, "blockHash", l.BlockHash.Hex(), "old", event.OldBaseFeeScalar, "new", event.NewBaseFeeScalar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BlockChain represents the canonical chain given a database with a genesis
|
// BlockChain represents the canonical chain given a database with a genesis
|
||||||
// block. The Blockchain manages chain imports, reverts, chain reorganisations.
|
// block. The Blockchain manages chain imports, reverts, chain reorganisations.
|
||||||
//
|
//
|
||||||
|
|
@ -1272,6 +1308,9 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||||
// Note the latest relayed L1 message queue index (if any)
|
// Note the latest relayed L1 message queue index (if any)
|
||||||
updateHeadL1msgGauge(block)
|
updateHeadL1msgGauge(block)
|
||||||
|
|
||||||
|
// Execute L2 base fee coefficient updates (if any)
|
||||||
|
updateL2BaseFeeCoefficients(bc.Config().Scroll.L2SystemConfigAddress(), logs)
|
||||||
|
|
||||||
parent := bc.GetHeaderByHash(block.ParentHash())
|
parent := bc.GetHeaderByHash(block.ParentHash())
|
||||||
// block.Time is guaranteed to be larger than parent.Time,
|
// block.Time is guaranteed to be larger than parent.Time,
|
||||||
// and the time gap should fit into int64.
|
// and the time gap should fit into int64.
|
||||||
|
|
@ -1302,7 +1341,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
|
||||||
if queueIndex == nil {
|
if queueIndex == nil {
|
||||||
// We expect that we only insert contiguous chain segments,
|
// We expect that we only insert contiguous chain segments,
|
||||||
// so the parent will always be inserted first.
|
// so the parent will always be inserted first.
|
||||||
log.Crit("Queue index in DB is nil", "parent", block.ParentHash(), "hash", block.Hash())
|
log.Crit("Queue index in DB is nil", "parent", block.ParentHash().Hex(), "hash", block.Hash().Hex())
|
||||||
}
|
}
|
||||||
numProcessed := uint64(block.NumL1MessagesProcessed(*queueIndex))
|
numProcessed := uint64(block.NumL1MessagesProcessed(*queueIndex))
|
||||||
// do not overwrite the index written by the miner worker
|
// do not overwrite the index written by the miner worker
|
||||||
|
|
|
||||||
|
|
@ -389,13 +389,13 @@ func TestStateProcessorErrors(t *testing.T) {
|
||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicCreationTx(0, 500000, common.Big0, misc.CalcBaseFee(config, genesis.Header(), parentL1BaseFee), tooBigInitCode[:]),
|
mkDynamicCreationTx(0, 500000, common.Big0, misc.CalcBaseFee(config, genesis.Header(), parentL1BaseFee), tooBigInitCode[:]),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0x9fff9d187a68f9dce9664475ed9a01a5178992f15b44ce88ee7b1129a183e6af]: max initcode size exceeded: code size 49153 limit 49152",
|
want: "could not apply tx 0 [0x7b33776d375660694a23ef992c090265682f3687607e0099b14503fdb65d73e3]: max initcode size exceeded: code size 49153 limit 49152",
|
||||||
},
|
},
|
||||||
{ // ErrIntrinsicGas: Not enough gas to cover init code
|
{ // ErrIntrinsicGas: Not enough gas to cover init code
|
||||||
txs: []*types.Transaction{
|
txs: []*types.Transaction{
|
||||||
mkDynamicCreationTx(0, 54299, common.Big0, misc.CalcBaseFee(config, genesis.Header(), parentL1BaseFee), smallInitCode[:]),
|
mkDynamicCreationTx(0, 54299, common.Big0, misc.CalcBaseFee(config, genesis.Header(), parentL1BaseFee), smallInitCode[:]),
|
||||||
},
|
},
|
||||||
want: "could not apply tx 0 [0x272eefb0eeb3b973e933ae5dba17e7ecf6bfded5ce358f2a78426153c247f677]: intrinsic gas too low: have 54299, want 54300",
|
want: "could not apply tx 0 [0x98e54c5ecfa7986a66480d65ba32f2c6a2a6aedc3a67abb91b1e118b0717ed2d]: intrinsic gas too low: have 54299, want 54300",
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
|
block := GenerateBadBlock(genesis, ethash.NewFaker(), tt.txs, gspec.Config)
|
||||||
|
|
|
||||||
|
|
@ -424,6 +424,8 @@ func (pool *TxPool) loop() {
|
||||||
journal = time.NewTicker(pool.config.Rejournal)
|
journal = time.NewTicker(pool.config.Rejournal)
|
||||||
// Track the previous head headers for transaction reorgs
|
// Track the previous head headers for transaction reorgs
|
||||||
head = pool.chain.CurrentBlock()
|
head = pool.chain.CurrentBlock()
|
||||||
|
// Track the min L2 base fee
|
||||||
|
minBaseFee = big.NewInt(0)
|
||||||
)
|
)
|
||||||
defer report.Stop()
|
defer report.Stop()
|
||||||
defer evict.Stop()
|
defer evict.Stop()
|
||||||
|
|
@ -443,6 +445,13 @@ func (pool *TxPool) loop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
newMinBaseFee := misc.MinBaseFee()
|
||||||
|
if minBaseFee.Cmp(newMinBaseFee) != 0 {
|
||||||
|
log.Debug("Updating min base fee in txpool", "old", minBaseFee, "new", newMinBaseFee)
|
||||||
|
minBaseFee = newMinBaseFee
|
||||||
|
pool.SetGasPrice(minBaseFee)
|
||||||
|
}
|
||||||
|
|
||||||
// System shutdown.
|
// System shutdown.
|
||||||
case <-pool.chainHeadSub.Err():
|
case <-pool.chainHeadSub.Err():
|
||||||
close(pool.reorgShutdownCh)
|
close(pool.reorgShutdownCh)
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,8 @@ func (api *PrivateMinerAPI) SetGasPrice(gasPrice hexutil.Big) bool {
|
||||||
api.e.gasPrice = (*big.Int)(&gasPrice)
|
api.e.gasPrice = (*big.Int)(&gasPrice)
|
||||||
api.e.lock.Unlock()
|
api.e.lock.Unlock()
|
||||||
|
|
||||||
|
// This will override the min base fee configuration.
|
||||||
|
// That is fine, it only happens if we explicitly set gas price via the console.
|
||||||
api.e.txPool.SetGasPrice((*big.Int)(&gasPrice))
|
api.e.txPool.SetGasPrice((*big.Int)(&gasPrice))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import (
|
||||||
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus"
|
"github.com/scroll-tech/go-ethereum/consensus"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/clique"
|
"github.com/scroll-tech/go-ethereum/consensus/clique"
|
||||||
|
"github.com/scroll-tech/go-ethereum/consensus/misc"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/system_contract"
|
"github.com/scroll-tech/go-ethereum/consensus/system_contract"
|
||||||
"github.com/scroll-tech/go-ethereum/consensus/wrapper"
|
"github.com/scroll-tech/go-ethereum/consensus/wrapper"
|
||||||
"github.com/scroll-tech/go-ethereum/core"
|
"github.com/scroll-tech/go-ethereum/core"
|
||||||
|
|
@ -148,13 +149,6 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client l1.Client) (*Ether
|
||||||
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
||||||
return nil, genesisErr
|
return nil, genesisErr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hacky workaround:
|
|
||||||
// It's hard to pass these fields to `CalcBaseFee`, etc.
|
|
||||||
// So pass them as part of the genesis config instead.
|
|
||||||
chainConfig.Scroll.BaseFeeScalar = config.BaseFeeScalar
|
|
||||||
chainConfig.Scroll.BaseFeeOverhead = config.BaseFeeOverhead
|
|
||||||
|
|
||||||
log.Info("Initialised chain configuration", "config", chainConfig)
|
log.Info("Initialised chain configuration", "config", chainConfig)
|
||||||
|
|
||||||
if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil {
|
if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil {
|
||||||
|
|
@ -220,6 +214,12 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client l1.Client) (*Ether
|
||||||
eth.blockchain.Validator().WithAsyncValidator(eth.asyncChecker.Check)
|
eth.blockchain.Validator().WithAsyncValidator(eth.asyncChecker.Check)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
state, err := eth.blockchain.State()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
misc.InitializeL2BaseFeeCoefficients(chainConfig, state)
|
||||||
|
|
||||||
// Rewind the chain in case of an incompatible config upgrade.
|
// Rewind the chain in case of an incompatible config upgrade.
|
||||||
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
|
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
|
||||||
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
|
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
|
||||||
|
|
@ -232,6 +232,7 @@ func New(stack *node.Node, config *ethconfig.Config, l1Client l1.Client) (*Ether
|
||||||
config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
|
config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
|
||||||
}
|
}
|
||||||
eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain)
|
eth.txPool = core.NewTxPool(config.TxPool, chainConfig, eth.blockchain)
|
||||||
|
eth.txPool.SetGasPrice(misc.MinBaseFee())
|
||||||
|
|
||||||
// Initialize and start DA syncing pipeline before SyncService as SyncService is blocking until all L1 messages are loaded.
|
// Initialize and start DA syncing pipeline before SyncService as SyncService is blocking until all L1 messages are loaded.
|
||||||
// We need SyncService to load the L1 messages for DA syncing, but since both sync from last known L1 state, we can
|
// We need SyncService to load the L1 messages for DA syncing, but since both sync from last known L1 state, we can
|
||||||
|
|
@ -361,6 +362,9 @@ func (s *Ethereum) APIs() []rpc.API {
|
||||||
// Append any APIs exposed explicitly by the consensus engine
|
// Append any APIs exposed explicitly by the consensus engine
|
||||||
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
apis = append(apis, s.engine.APIs(s.BlockChain())...)
|
||||||
|
|
||||||
|
// Append L2 base fee APIs.
|
||||||
|
apis = append(apis, misc.APIs()...)
|
||||||
|
|
||||||
if !s.config.EnableDASyncing {
|
if !s.config.EnableDASyncing {
|
||||||
apis = append(apis, rpc.API{
|
apis = append(apis, rpc.API{
|
||||||
Namespace: "eth",
|
Namespace: "eth",
|
||||||
|
|
@ -527,10 +531,11 @@ func (s *Ethereum) StartMining(threads int) error {
|
||||||
// If the miner was not running, initialize it
|
// If the miner was not running, initialize it
|
||||||
if !s.IsMining() {
|
if !s.IsMining() {
|
||||||
// Propagate the initial price point to the transaction pool
|
// Propagate the initial price point to the transaction pool
|
||||||
s.lock.RLock()
|
// Disabled, we now update min gas price automatically via L2 base fee.
|
||||||
price := s.gasPrice
|
// s.lock.RLock()
|
||||||
s.lock.RUnlock()
|
// price := s.gasPrice
|
||||||
s.txPool.SetGasPrice(price)
|
// s.lock.RUnlock()
|
||||||
|
// s.txPool.SetGasPrice(price)
|
||||||
|
|
||||||
// Configure the local mining address
|
// Configure the local mining address
|
||||||
eb, err := s.Etherbase()
|
eb, err := s.Etherbase()
|
||||||
|
|
|
||||||
|
|
@ -230,10 +230,6 @@ type Config struct {
|
||||||
|
|
||||||
// DA syncer options
|
// DA syncer options
|
||||||
DA da_syncer.Config
|
DA da_syncer.Config
|
||||||
|
|
||||||
// L2 base fee coefficients for the formula: `l2BaseFee = (l1BaseFee * scalar) / PRECISION + overhead`.
|
|
||||||
BaseFeeScalar *big.Int
|
|
||||||
BaseFeeOverhead *big.Int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateConsensusEngine creates a consensus engine for the given chain configuration.
|
// CreateConsensusEngine creates a consensus engine for the given chain configuration.
|
||||||
|
|
|
||||||
|
|
@ -998,6 +998,10 @@ web3._extend({
|
||||||
name: 'localSigner',
|
name: 'localSigner',
|
||||||
getter: 'scroll_getLocalSigner',
|
getter: 'scroll_getLocalSigner',
|
||||||
}),
|
}),
|
||||||
|
new web3._extend.Property({
|
||||||
|
name: 'l2BaseFeeConfig',
|
||||||
|
getter: 'scroll_getL2BaseFeeConfig',
|
||||||
|
}),
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"runtime/debug"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -341,6 +342,7 @@ func (w *worker) mainLoop() {
|
||||||
p := recover()
|
p := recover()
|
||||||
if p != nil {
|
if p != nil {
|
||||||
log.Error("worker mainLoop panic", "panic", p)
|
log.Error("worker mainLoop panic", "panic", p)
|
||||||
|
fmt.Println("stacktrace from panic: \n" + string(debug.Stack()))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -351,6 +351,7 @@ var (
|
||||||
L1MessageQueueV2DeploymentBlock: 7773746,
|
L1MessageQueueV2DeploymentBlock: 7773746,
|
||||||
NumL1MessagesPerBlock: 10,
|
NumL1MessagesPerBlock: 10,
|
||||||
ScrollChainAddress: common.HexToAddress("0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0"),
|
ScrollChainAddress: common.HexToAddress("0x2D567EcE699Eabe5afCd141eDB7A4f2D0D6ce8a0"),
|
||||||
|
L2SystemConfigAddress: common.HexToAddress("0xF444cF06A3E3724e20B35c2989d3942ea8b59124"),
|
||||||
},
|
},
|
||||||
GenesisStateRoot: &ScrollSepoliaGenesisState,
|
GenesisStateRoot: &ScrollSepoliaGenesisState,
|
||||||
},
|
},
|
||||||
|
|
@ -401,6 +402,7 @@ var (
|
||||||
L1MessageQueueV2DeploymentBlock: 22088276,
|
L1MessageQueueV2DeploymentBlock: 22088276,
|
||||||
NumL1MessagesPerBlock: 10,
|
NumL1MessagesPerBlock: 10,
|
||||||
ScrollChainAddress: common.HexToAddress("0xa13BAF47339d63B743e7Da8741db5456DAc1E556"),
|
ScrollChainAddress: common.HexToAddress("0xa13BAF47339d63B743e7Da8741db5456DAc1E556"),
|
||||||
|
L2SystemConfigAddress: common.HexToAddress("0x331A873a2a85219863d80d248F9e2978fE88D0Ea"),
|
||||||
},
|
},
|
||||||
GenesisStateRoot: &ScrollMainnetGenesisState,
|
GenesisStateRoot: &ScrollMainnetGenesisState,
|
||||||
},
|
},
|
||||||
|
|
@ -704,11 +706,6 @@ type ScrollConfig struct {
|
||||||
|
|
||||||
// Genesis State Root for MPT clients
|
// Genesis State Root for MPT clients
|
||||||
GenesisStateRoot *common.Hash `json:"genesisStateRoot,omitempty"`
|
GenesisStateRoot *common.Hash `json:"genesisStateRoot,omitempty"`
|
||||||
|
|
||||||
// L2 base fee coefficients for the formula: `l2BaseFee = (l1BaseFee * scalar) / PRECISION + overhead`.
|
|
||||||
// These fields are populated from configuration flags, and passed to `CalcBaseFee`.
|
|
||||||
BaseFeeScalar *big.Int `json:"-"`
|
|
||||||
BaseFeeOverhead *big.Int `json:"-"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// L1Config contains the l1 parameters needed to sync l1 contract events (e.g., l1 messages, commit/revert/finalize batches) in the sequencer
|
// L1Config contains the l1 parameters needed to sync l1 contract events (e.g., l1 messages, commit/revert/finalize batches) in the sequencer
|
||||||
|
|
@ -719,6 +716,7 @@ type L1Config struct {
|
||||||
L1MessageQueueV2DeploymentBlock uint64 `json:"l1MessageQueueV2DeploymentBlock,omitempty"`
|
L1MessageQueueV2DeploymentBlock uint64 `json:"l1MessageQueueV2DeploymentBlock,omitempty"`
|
||||||
NumL1MessagesPerBlock uint64 `json:"numL1MessagesPerBlock,string,omitempty"`
|
NumL1MessagesPerBlock uint64 `json:"numL1MessagesPerBlock,string,omitempty"`
|
||||||
ScrollChainAddress common.Address `json:"scrollChainAddress,omitempty"`
|
ScrollChainAddress common.Address `json:"scrollChainAddress,omitempty"`
|
||||||
|
L2SystemConfigAddress common.Address `json:"l2SystemConfigAddress,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *L1Config) String() string {
|
func (c *L1Config) String() string {
|
||||||
|
|
@ -726,8 +724,8 @@ func (c *L1Config) String() string {
|
||||||
return "<nil>"
|
return "<nil>"
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("{l1ChainId: %v, l1MessageQueueAddress: %v, l1MessageQueueV2Address: %v, l1MessageQueueV2DeploymentBlock: %v, numL1MessagesPerBlock: %v, ScrollChainAddress: %v}",
|
return fmt.Sprintf("{l1ChainId: %v, l1MessageQueueAddress: %v, l1MessageQueueV2Address: %v, l1MessageQueueV2DeploymentBlock: %v, numL1MessagesPerBlock: %v, ScrollChainAddress: %v, L2SystemConfigAddress: %v}",
|
||||||
c.L1ChainId, c.L1MessageQueueAddress.Hex(), c.L1MessageQueueV2Address.Hex(), c.L1MessageQueueV2DeploymentBlock, c.NumL1MessagesPerBlock, c.ScrollChainAddress.Hex())
|
c.L1ChainId, c.L1MessageQueueAddress.Hex(), c.L1MessageQueueV2Address.Hex(), c.L1MessageQueueV2DeploymentBlock, c.NumL1MessagesPerBlock, c.ScrollChainAddress.Hex(), c.L2SystemConfigAddress.Hex())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s ScrollConfig) FeeVaultEnabled() bool {
|
func (s ScrollConfig) FeeVaultEnabled() bool {
|
||||||
|
|
@ -758,18 +756,8 @@ func (s ScrollConfig) String() string {
|
||||||
genesisStateRoot = fmt.Sprintf("%v", *s.GenesisStateRoot)
|
genesisStateRoot = fmt.Sprintf("%v", *s.GenesisStateRoot)
|
||||||
}
|
}
|
||||||
|
|
||||||
baseFeeScalar := "<nil>"
|
return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: %v, MaxTxPayloadBytesPerBlock: %v, feeVaultAddress: %v, l1Config: %v, genesisStateRoot: %v}",
|
||||||
if s.BaseFeeScalar != nil {
|
s.UseZktrie, maxTxPerBlock, maxTxPayloadBytesPerBlock, s.FeeVaultAddress, s.L1Config.String(), genesisStateRoot)
|
||||||
baseFeeScalar = s.BaseFeeScalar.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
baseFeeOverhead := "<nil>"
|
|
||||||
if s.BaseFeeOverhead != nil {
|
|
||||||
baseFeeOverhead = s.BaseFeeOverhead.String()
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("{useZktrie: %v, maxTxPerBlock: %v, MaxTxPayloadBytesPerBlock: %v, feeVaultAddress: %v, l1Config: %v, genesisStateRoot: %v, baseFeeScalar: %v, baseFeeOverhead: %v}",
|
|
||||||
s.UseZktrie, maxTxPerBlock, maxTxPayloadBytesPerBlock, s.FeeVaultAddress, s.L1Config.String(), genesisStateRoot, baseFeeScalar, baseFeeOverhead)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsValidTxCount returns whether the given block's transaction count is below the limit.
|
// IsValidTxCount returns whether the given block's transaction count is below the limit.
|
||||||
|
|
@ -788,6 +776,14 @@ func (s ScrollConfig) IsValidBlockSizeForMining(size common.StorageSize) bool {
|
||||||
return s.IsValidBlockSize(size * (1.0 / 0.95))
|
return s.IsValidBlockSize(size * (1.0 / 0.95))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// L2SystemConfigAddress returns the configured l2 system config address, or the zero address if it is not configured.
|
||||||
|
func (s ScrollConfig) L2SystemConfigAddress() common.Address {
|
||||||
|
if s.L1Config == nil {
|
||||||
|
return common.Address{} // only in tests
|
||||||
|
}
|
||||||
|
return s.L1Config.L2SystemConfigAddress
|
||||||
|
}
|
||||||
|
|
||||||
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
||||||
type EthashConfig struct{}
|
type EthashConfig struct{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import (
|
||||||
const (
|
const (
|
||||||
VersionMajor = 5 // Major version component of the current release
|
VersionMajor = 5 // Major version component of the current release
|
||||||
VersionMinor = 8 // Minor version component of the current release
|
VersionMinor = 8 // Minor version component of the current release
|
||||||
VersionPatch = 50 // Patch version component of the current release
|
VersionPatch = 51 // Patch version component of the current release
|
||||||
VersionMeta = "mainnet" // Version metadata to append to the version string
|
VersionMeta = "mainnet" // Version metadata to append to the version string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
54
rollup/l2_system_config/abi.go
Normal file
54
rollup/l2_system_config/abi.go
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
package l2_system_config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/scroll-tech/go-ethereum/accounts/abi"
|
||||||
|
"github.com/scroll-tech/go-ethereum/accounts/abi/bind"
|
||||||
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
|
"github.com/scroll-tech/go-ethereum/rollup/l1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
l2SystemConfigABI *abi.ABI
|
||||||
|
|
||||||
|
baseFeeOverheadUpdatedEventName = "BaseFeeOverheadUpdated"
|
||||||
|
baseFeeScalarUpdatedEventName = "BaseFeeScalarUpdated"
|
||||||
|
|
||||||
|
BaseFeeOverheadUpdatedTopic common.Hash
|
||||||
|
BaseFeeScalarUpdatedTopic common.Hash
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
l2SystemConfigABI, _ = l2SystemConfigMetaData.GetAbi()
|
||||||
|
|
||||||
|
BaseFeeOverheadUpdatedTopic = l2SystemConfigABI.Events[baseFeeOverheadUpdatedEventName].ID
|
||||||
|
BaseFeeScalarUpdatedTopic = l2SystemConfigABI.Events[baseFeeScalarUpdatedEventName].ID
|
||||||
|
}
|
||||||
|
|
||||||
|
var l2SystemConfigMetaData = &bind.MetaData{
|
||||||
|
ABI: "[{\"type\":\"event\",\"name\":\"BaseFeeOverheadUpdated\",\"inputs\":[{\"name\":\"oldBaseFeeOverhead\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newBaseFeeOverhead\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false},{\"type\":\"event\",\"name\":\"BaseFeeScalarUpdated\",\"inputs\":[{\"name\":\"oldBaseFeeScalar\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"},{\"name\":\"newBaseFeeScalar\",\"type\":\"uint256\",\"indexed\":false,\"internalType\":\"uint256\"}],\"anonymous\":false}]",
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseFeeOverheadUpdatedEventUnpacked struct {
|
||||||
|
OldBaseFeeOverhead *big.Int
|
||||||
|
NewBaseFeeOverhead *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
type BaseFeeScalarUpdatedEventUnpacked struct {
|
||||||
|
OldBaseFeeScalar *big.Int
|
||||||
|
NewBaseFeeScalar *big.Int
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnpackBaseFeeOverheadUpdatedEvent(log types.Log) (*BaseFeeOverheadUpdatedEventUnpacked, error) {
|
||||||
|
event := &BaseFeeOverheadUpdatedEventUnpacked{}
|
||||||
|
err := l1.UnpackLog(l2SystemConfigABI, event, baseFeeOverheadUpdatedEventName, log)
|
||||||
|
return event, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnpackBaseFeeScalarUpdatedEvent(log types.Log) (*BaseFeeScalarUpdatedEventUnpacked, error) {
|
||||||
|
event := &BaseFeeScalarUpdatedEventUnpacked{}
|
||||||
|
err := l1.UnpackLog(l2SystemConfigABI, event, baseFeeScalarUpdatedEventName, log)
|
||||||
|
return event, err
|
||||||
|
}
|
||||||
51
rollup/l2_system_config/abi_test.go
Normal file
51
rollup/l2_system_config/abi_test.go
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
package l2_system_config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/scroll-tech/go-ethereum/common"
|
||||||
|
"github.com/scroll-tech/go-ethereum/core/types"
|
||||||
|
"github.com/scroll-tech/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEventSignatures(t *testing.T) {
|
||||||
|
assert.Equal(t, crypto.Keccak256Hash([]byte("BaseFeeOverheadUpdated(uint256,uint256)")), BaseFeeOverheadUpdatedTopic)
|
||||||
|
assert.Equal(t, crypto.Keccak256Hash([]byte("BaseFeeScalarUpdated(uint256,uint256)")), BaseFeeScalarUpdatedTopic)
|
||||||
|
}
|
||||||
|
|
||||||
|
func bigToBytesPadded(num *big.Int) []byte {
|
||||||
|
return common.BigToHash(num).Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnpackBaseFeeOverheadUpdatedLog(t *testing.T) {
|
||||||
|
old := common.Big1
|
||||||
|
new := common.Big2
|
||||||
|
|
||||||
|
log := types.Log{
|
||||||
|
Topics: []common.Hash{BaseFeeOverheadUpdatedTopic},
|
||||||
|
Data: append(bigToBytesPadded(old), bigToBytesPadded(new)...),
|
||||||
|
}
|
||||||
|
|
||||||
|
event, err := UnpackBaseFeeOverheadUpdatedEvent(log)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.Big1, event.OldBaseFeeOverhead)
|
||||||
|
assert.Equal(t, common.Big2, event.NewBaseFeeOverhead)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUnpackBaseFeeScalarUpdatedLog(t *testing.T) {
|
||||||
|
old := common.Big32
|
||||||
|
new := common.Big256
|
||||||
|
|
||||||
|
log := types.Log{
|
||||||
|
Topics: []common.Hash{BaseFeeScalarUpdatedTopic},
|
||||||
|
Data: append(bigToBytesPadded(old), bigToBytesPadded(new)...),
|
||||||
|
}
|
||||||
|
|
||||||
|
event, err := UnpackBaseFeeScalarUpdatedEvent(log)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, common.Big32, event.OldBaseFeeScalar)
|
||||||
|
assert.Equal(t, common.Big256, event.NewBaseFeeScalar)
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue