From b9919a572ad6574790a37adde07b255591cc34a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Mon, 27 May 2024 19:44:40 +0300 Subject: [PATCH 1/8] fix: make consensus engine wait for a bit before giving up on worker (#774) and if it happens despite the wait, let worker retry --- consensus/clique/clique.go | 4 +++- miner/scroll_worker.go | 6 +++++- params/version.go | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 8c0505f760de..bd92b525b980 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -648,6 +648,8 @@ func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, res // Wait until sealing is terminated or delay timeout. log.Trace("Waiting for slot to sign and propagate", "delay", common.PrettyDuration(delay)) go func() { + defer close(results) + select { case <-stop: return @@ -656,7 +658,7 @@ func (c *Clique) Seal(chain consensus.ChainHeaderReader, block *types.Block, res select { case results <- block.WithSeal(header): - default: + case <-time.After(time.Second): log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header)) } }() diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index c5614c59810d..9b7a1b63a6a4 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -651,8 +651,12 @@ func (w *worker) commit(res *pipeline.Result) error { if err := w.engine.Seal(w.chain, block, resultCh, stopCh); err != nil { return err } - + // Clique.Seal() will only wait for a second before giving up on us. So make sure there is nothing computational heavy + // or a call that blocks between the call to Seal and the line below block = <-resultCh + if block == nil { + return errors.New("missed seal response from consensus engine") + } // verify the generated block with local consensus engine to make sure everything is as expected if err = w.engine.VerifyHeader(w.chain, block.Header(), true); err != nil { diff --git a/params/version.go b/params/version.go index 145c4bf1b27f..9f991beae3f2 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 3 // Minor version component of the current release - VersionPatch = 23 // Patch version component of the current release + VersionPatch = 24 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) From 89ff451c775e9e476dcb29ab8dcb0e1ca619b254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Tue, 28 May 2024 12:54:36 +0300 Subject: [PATCH 2/8] fix: make sure building of pending blocks don't have any lasting sideaffects (#779) --- miner/scroll_worker.go | 20 ++++++++++++-------- params/version.go | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index 9b7a1b63a6a4..bb8da0658c22 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -556,6 +556,14 @@ func (w *worker) startNewPipeline(timestamp int64) { } func (w *worker) handlePipelineResult(res *pipeline.Result) error { + if !w.isRunning() { + if res != nil && res.FinalBlock != nil { + w.updateSnapshot(res.FinalBlock) + } + w.currentPipeline = nil + return nil + } + if res != nil && res.OverflowingTx != nil { if res.FinalBlock == nil { // first txn overflowed the circuit, skip @@ -602,14 +610,6 @@ func (w *worker) handlePipelineResult(res *pipeline.Result) error { } } - if !w.isRunning() { - if res != nil && res.FinalBlock != nil { - w.updateSnapshot(res.FinalBlock) - } - w.currentPipeline = nil - return nil - } - var commitError error if res != nil && res.FinalBlock != nil { if commitError = w.commit(res); commitError == nil { @@ -747,6 +747,10 @@ func (w *worker) postSideBlock(event core.ChainSideEvent) { } func (w *worker) onTxFailingInPipeline(txIndex int, tx *types.Transaction, err error) bool { + if !w.isRunning() { + return false + } + writeTrace := func() { var trace *types.BlockTrace var errWithTrace *pipeline.ErrorWithTrace diff --git a/params/version.go b/params/version.go index 9f991beae3f2..4146d57d012f 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 3 // Minor version component of the current release - VersionPatch = 24 // Patch version component of the current release + VersionPatch = 25 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) From 9f961ddc71145c28fdfd4568528961f7d996d290 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20Faruk=20Irmak?= Date: Tue, 28 May 2024 13:57:18 +0300 Subject: [PATCH 3/8] feat: reduce the number of samples in lifetimeTimer (#777) --- params/version.go | 2 +- rollup/pipeline/pipeline.go | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/params/version.go b/params/version.go index 4146d57d012f..326c7b339ce4 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 3 // Minor version component of the current release - VersionPatch = 25 // Patch version component of the current release + VersionPatch = 26 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) diff --git a/rollup/pipeline/pipeline.go b/rollup/pipeline/pipeline.go index fffdd21a12a5..3c7089cf60e5 100644 --- a/rollup/pipeline/pipeline.go +++ b/rollup/pipeline/pipeline.go @@ -33,7 +33,11 @@ var ( ErrApplyStageDone = errors.New("apply stage is done") ErrUnexpectedL1MessageIndex = errors.New("unexpected L1 message index") - lifetimeTimer = metrics.NewRegisteredTimer("pipeline/lifetime", nil) + lifetimeTimer = func() metrics.Timer { + t := metrics.NewCustomTimer(metrics.NewHistogram(metrics.NewExpDecaySample(128, 0.015)), metrics.NewMeter()) + metrics.DefaultRegistry.Register("pipeline/lifetime", t) + return t + }() applyTimer = metrics.NewRegisteredTimer("pipeline/apply", nil) applyIdleTimer = metrics.NewRegisteredTimer("pipeline/apply_idle", nil) applyStallTimer = metrics.NewRegisteredTimer("pipeline/apply_stall", nil) From bfe803001be452e90e4f9208d8a1cc24e5c44ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Garamv=C3=B6lgyi?= Date: Tue, 28 May 2024 14:12:39 +0200 Subject: [PATCH 4/8] feat: update L1 data fee in Curie hard fork (#755) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update fee calculation * add missing GPO slots to trace * add placeholder for contract update logic * nit * update fee calculation * update formula * update GPO slots * update L1GPO bytecode * apply Curie in new worker * move bytecode to config * create an empty block for curie hard fork * initialize L1GasPriceOracle storage slots * add comments * add test * add IsCurie to traces and tests * group GPO storage slots into a struct * update unit test * chore: auto version bump [bot] * trigger ci * update bytecode * remove leading 0x * update comments * include rollup fee tests in CI --------- Co-authored-by: Ömer Faruk Irmak Co-authored-by: Thegaram --- Makefile | 2 +- accounts/abi/bind/backends/simulated.go | 2 +- cmd/evm/internal/t8ntool/execution.go | 6 +- consensus/misc/curie.go | 23 ++++++ core/blockchain_test.go | 77 ++++++++++++++++++ core/chain_makers.go | 3 + core/state_prefetcher.go | 2 +- core/state_processor.go | 6 +- core/tx_list.go | 7 +- core/tx_list_test.go | 4 +- core/tx_pool.go | 14 ++-- eth/state_accessor.go | 2 +- eth/tracers/api.go | 14 ++-- eth/tracers/api_test.go | 2 +- .../internal/tracetest/calltrace_test.go | 6 +- eth/tracers/tracers_test.go | 2 +- ethclient/ethclient_test.go | 10 ++- ethclient/gethclient/gethclient_test.go | 10 ++- internal/ethapi/api.go | 4 +- les/odr_test.go | 4 +- les/state_accessor.go | 2 +- light/odr_test.go | 2 +- light/txpool.go | 15 +++- miner/scroll_worker.go | 26 ++++++ miner/worker.go | 7 ++ params/version.go | 2 +- rollup/fees/rollup_fee.go | 80 +++++++++++++++---- rollup/fees/rollup_fee_test.go | 21 ++++- rollup/pipeline/pipeline.go | 2 +- rollup/rcfg/config.go | 19 +++++ rollup/tracing/tracing.go | 8 +- tests/state_test_util.go | 2 +- 32 files changed, 316 insertions(+), 70 deletions(-) create mode 100644 consensus/misc/curie.go diff --git a/Makefile b/Makefile index 2a0c148d569e..77500dfa5c66 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,7 @@ test: all # genesis test cd ${PWD}/cmd/geth; go test -test.run TestCustomGenesis # module test - $(GORUN) build/ci.go test ./consensus ./core ./eth ./miner ./node ./trie + $(GORUN) build/ci.go test ./consensus ./core ./eth ./miner ./node ./trie ./rollup/fees lint: ## Run linters. $(GORUN) build/ci.go lint diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index febabccc2b08..949210ae0b3d 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -640,7 +640,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true}) gasPool := new(core.GasPool).AddGas(math.MaxUint64) signer := types.MakeSigner(b.blockchain.Config(), head.Number) - l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, head.BaseFee, b.blockchain.Config().ChainID, signer, stateDB) + l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, head.BaseFee, b.blockchain.Config(), signer, stateDB, head.Number) if err != nil { return nil, err } diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index 6e8cb9f44620..b1f5c13ea0ff 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -148,6 +148,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, chainConfig.DAOForkBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 { misc.ApplyDAOHardFork(statedb) } + // Apply Curie hard fork + if chainConfig.CurieBlock != nil && chainConfig.CurieBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 { + misc.ApplyCurieHardFork(statedb) + } for i, tx := range txs { msg, err := tx.AsMessage(signer, pre.Env.BaseFee) @@ -167,7 +171,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, snapshot := statedb.Snapshot() evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, chainConfig, new(big.Int).SetUint64(pre.Env.Number)) if err != nil { log.Info("rejected tx due to fees.CalculateL1DataFee", "index", i, "hash", tx.Hash(), "from", msg.From(), "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) diff --git a/consensus/misc/curie.go b/consensus/misc/curie.go new file mode 100644 index 000000000000..e1668b25dc33 --- /dev/null +++ b/consensus/misc/curie.go @@ -0,0 +1,23 @@ +package misc + +import ( + "github.com/scroll-tech/go-ethereum/common" + "github.com/scroll-tech/go-ethereum/core/state" + "github.com/scroll-tech/go-ethereum/log" + "github.com/scroll-tech/go-ethereum/rollup/rcfg" +) + +// ApplyCurieHardFork modifies the state database according to the Curie hard-fork rules, +// updating the bytecode and storage of the L1GasPriceOracle contract. +func ApplyCurieHardFork(statedb *state.StateDB) { + log.Info("Applying Curie hard fork") + + // update contract byte code + statedb.SetCode(rcfg.L1GasPriceOracleAddress, rcfg.CurieL1GasPriceOracleBytecode) + + // initialize new storage slots + statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.IsCurieSlot, common.BytesToHash([]byte{1})) + statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.L1BlobBaseFeeSlot, common.BytesToHash([]byte{1})) + statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.CommitScalarSlot, common.BigToHash(rcfg.InitialCommitScalar)) + statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.BlobScalarSlot, common.BigToHash(rcfg.InitialBlobScalar)) +} diff --git a/core/blockchain_test.go b/core/blockchain_test.go index b0f601f45585..87e7b01b5eb7 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -17,6 +17,7 @@ package core import ( + "encoding/json" "errors" "fmt" "io/ioutil" @@ -39,6 +40,7 @@ import ( "github.com/scroll-tech/go-ethereum/crypto" "github.com/scroll-tech/go-ethereum/ethdb" "github.com/scroll-tech/go-ethereum/params" + "github.com/scroll-tech/go-ethereum/rollup/rcfg" "github.com/scroll-tech/go-ethereum/trie" ) @@ -3712,3 +3714,78 @@ func TestTransientStorageReset(t *testing.T) { t.Fatalf("Unexpected dirty storage slot") } } + +func TestCurieTransition(t *testing.T) { + // Set fork blocks in config + // (we make a deep copy to avoid interference with other tests) + var config *params.ChainConfig + b, _ := json.Marshal(params.AllEthashProtocolChanges) + json.Unmarshal(b, &config) + config.CurieBlock = big.NewInt(2) + config.DescartesBlock = nil + + var ( + db = rawdb.NewMemoryDatabase() + gspec = &Genesis{Config: config} + genesis = gspec.MustCommit(db) + ) + + blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil) + defer blockchain.Stop() + blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, nil) + + if _, err := blockchain.InsertChain(blocks); err != nil { + t.Fatal(err) + } + + latestBlock := uint64(4) + assert.Equal(t, latestBlock, blockchain.CurrentHeader().Number.Uint64()) + + for ii := uint64(0); ii <= latestBlock; ii++ { + block := blockchain.GetBlockByNumber(ii) + + number := block.Number().Uint64() + baseFee := block.BaseFee() + + statedb, _ := state.New(block.Root(), state.NewDatabase(db), nil) + + code := statedb.GetCode(rcfg.L1GasPriceOracleAddress) + codeSize := statedb.GetCodeSize(rcfg.L1GasPriceOracleAddress) + keccakCodeHash := statedb.GetKeccakCodeHash(rcfg.L1GasPriceOracleAddress) + poseidonCodeHash := statedb.GetPoseidonCodeHash(rcfg.L1GasPriceOracleAddress) + + l1BlobBaseFee := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.L1BlobBaseFeeSlot) + commitScalar := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.CommitScalarSlot) + blobScalar := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.BlobScalarSlot) + isCurie := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.IsCurieSlot) + + if number < config.CurieBlock.Uint64() { + assert.Nil(t, baseFee, "Expected zero base fee before Curie") + + // we don't have predeploys configured in this test, + // so there is no gas oracle deployed before Curie + assert.Nil(t, code) + assert.Equal(t, uint64(0), codeSize) + assert.Equal(t, common.Hash{}, keccakCodeHash) + assert.Equal(t, common.Hash{}, poseidonCodeHash) + + assert.Equal(t, common.Hash{}, l1BlobBaseFee) + assert.Equal(t, common.Hash{}, commitScalar) + assert.Equal(t, common.Hash{}, blobScalar) + assert.Equal(t, common.Hash{}, isCurie) + } else { + assert.NotNil(t, baseFee, "Expected nonzero base fee after Curie") + + // all gas oracle entries updated + assert.NotNil(t, code) + assert.NotEqual(t, uint64(0), codeSize) + assert.NotEqual(t, common.Hash{}, keccakCodeHash) + assert.NotEqual(t, common.Hash{}, poseidonCodeHash) + + assert.NotEqual(t, common.Hash{}, l1BlobBaseFee) + assert.NotEqual(t, common.Hash{}, commitScalar) + assert.NotEqual(t, common.Hash{}, blobScalar) + assert.NotEqual(t, common.Hash{}, isCurie) + } + } +} diff --git a/core/chain_makers.go b/core/chain_makers.go index 143dbb005918..b79d92bf71e4 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -240,6 +240,9 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 { misc.ApplyDAOHardFork(statedb) } + if config.CurieBlock != nil && config.CurieBlock.Cmp(b.header.Number) == 0 { + misc.ApplyCurieHardFork(statedb) + } // Execute any user modifications to the block if gen != nil { gen(i, b) diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index 1fc7e02893ab..962f43a3ec91 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -71,7 +71,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c } statedb.SetTxContext(tx.Hash(), i) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, p.config, block.Number()) if err != nil { return } diff --git a/core/state_processor.go b/core/state_processor.go index 95952a4c19aa..8b4671d76768 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -86,6 +86,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { misc.ApplyDAOHardFork(statedb) } + // Apply Curie hard fork + if p.config.CurieBlock != nil && p.config.CurieBlock.Cmp(block.Number()) == 0 { + misc.ApplyCurieHardFork(statedb) + } blockContext := NewEVMBlockContext(header, p.bc, p.config, nil) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) processorBlockTransactionGauge.Update(int64(block.Transactions().Len())) @@ -120,7 +124,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon txContext := NewEVMTxContext(msg) evm.Reset(txContext, statedb) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, config, blockNumber) if err != nil { return nil, err } diff --git a/core/tx_list.go b/core/tx_list.go index 3742d7416e21..f219264260bb 100644 --- a/core/tx_list.go +++ b/core/tx_list.go @@ -29,6 +29,7 @@ import ( "github.com/scroll-tech/go-ethereum/core/state" "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/rollup/fees" ) @@ -281,7 +282,7 @@ func (l *txList) Overlaps(tx *types.Transaction) bool { // // If the new transaction is accepted into the list, the lists' cost and gas // thresholds are also potentially updated. -func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint64) (bool, *types.Transaction) { +func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint64, chainconfig *params.ChainConfig, blockNumber *big.Int) (bool, *types.Transaction) { // If there's an older better transaction, abort old := l.txs.Get(tx.Nonce()) if old != nil { @@ -307,9 +308,9 @@ func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint } // Otherwise overwrite the old transaction with the current one l1DataFee := big.NewInt(0) - if state != nil { + if state != nil && chainconfig != nil { var err error - l1DataFee, err = fees.CalculateL1DataFee(tx, state) + l1DataFee, err = fees.CalculateL1DataFee(tx, state, chainconfig, blockNumber) if err != nil { log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx) return false, nil diff --git a/core/tx_list_test.go b/core/tx_list_test.go index bd3fee86d8f8..9b1cab4c406b 100644 --- a/core/tx_list_test.go +++ b/core/tx_list_test.go @@ -38,7 +38,7 @@ func TestStrictTxListAdd(t *testing.T) { // Insert the transactions in a random order list := newTxList(true) for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump) + list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump, nil, nil) } // Verify internal state if len(list.txs.items) != len(txs) { @@ -65,7 +65,7 @@ func BenchmarkTxListAdd(b *testing.B) { for i := 0; i < b.N; i++ { list := newTxList(true) for _, v := range rand.Perm(len(txs)) { - list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump) + list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump, nil, nil) list.Filter(priceLimit, DefaultTxPoolConfig.PriceBump) } } diff --git a/core/tx_pool.go b/core/tx_pool.go index a8454204abf0..7e6bdd58a128 100644 --- a/core/tx_pool.go +++ b/core/tx_pool.go @@ -248,6 +248,7 @@ type TxPool struct { shanghai bool // Fork indicator whether we are in the Shanghai stage. currentState *state.StateDB // Current state in the blockchain head + currentHead *big.Int // Current blockchain head pendingNonces *txNoncer // Pending state tracking virtual nonces currentMaxGas uint64 // Current gas limit for transaction caps @@ -664,7 +665,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error { // 2. If FeeVault is enabled, perform an additional check for L1 data fees. if pool.chainconfig.Scroll.FeeVaultEnabled() { // Get L1 data fee in current state - l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState) + l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState, pool.chainconfig, pool.currentHead) if err != nil { return fmt.Errorf("failed to calculate L1 data fee, err: %w", err) } @@ -751,7 +752,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (replaced bool, err e from, _ := types.Sender(pool.signer, tx) // already validated if list := pool.pending[from]; list != nil && list.Overlaps(tx) { // Nonce already pending, check if required price bump is met - inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump) + inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead) if !inserted { pendingDiscardMeter.Mark(1) return false, ErrReplaceUnderpriced @@ -802,7 +803,7 @@ func (pool *TxPool) enqueueTx(hash common.Hash, tx *types.Transaction, local boo pool.queue[from] = newTxList(false) } - inserted, old := pool.queue[from].Add(tx, pool.currentState, pool.config.PriceBump) + inserted, old := pool.queue[from].Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead) if !inserted { // An older transaction was better, discard this queuedDiscardMeter.Mark(1) @@ -856,7 +857,7 @@ func (pool *TxPool) promoteTx(addr common.Address, hash common.Hash, tx *types.T } list := pool.pending[addr] - inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump) + inserted, old := list.Add(tx, pool.currentState, pool.config.PriceBump, pool.chainconfig, pool.currentHead) if !inserted { // An older transaction was better, discard this pool.all.Remove(hash) @@ -1357,6 +1358,9 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { pool.eip2718 = pool.chainconfig.IsCurie(next) pool.eip1559 = pool.chainconfig.IsCurie(next) pool.shanghai = pool.chainconfig.IsShanghai(next) + + // Update current head + pool.currentHead = next } // promoteExecutables moves transactions that have become processable from the @@ -1435,7 +1439,7 @@ func (pool *TxPool) executableTxFilter(costLimit *big.Int) func(tx *types.Transa if pool.chainconfig.Scroll.FeeVaultEnabled() { // recheck L1 data fee, as the oracle price may have changed - l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState) + l1DataFee, err := fees.CalculateL1DataFee(tx, pool.currentState, pool.chainconfig, pool.currentHead) if err != nil { log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx) return false diff --git a/eth/state_accessor.go b/eth/state_accessor.go index 11eaa365b60c..48e31bb6a72c 100644 --- a/eth/state_accessor.go +++ b/eth/state_accessor.go @@ -192,7 +192,7 @@ func (eth *Ethereum) stateAtTransaction(block *types.Block, txIndex int, reexec // Not yet the searched for transaction, execute on top of the current state vmenv := vm.NewEVM(context, txContext, statedb, eth.blockchain.Config(), vm.Config{}) statedb.SetTxContext(tx.Hash(), idx) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, eth.blockchain.Config(), block.Number()) if err != nil { return nil, vm.BlockContext{}, nil, err } diff --git a/eth/tracers/api.go b/eth/tracers/api.go index e4c3957c603d..d9171f4efd85 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -285,7 +285,7 @@ func (api *API) traceChain(ctx context.Context, start, end *types.Block, config TxHash: tx.Hash(), } - l1DataFee, err := fees.CalculateL1DataFee(tx, task.statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, task.statedb, api.backend.ChainConfig(), task.block.Number()) if err != nil { // though it's not a "tracing error", we still need to put it here task.results[i] = &txTraceResult{Error: err.Error()} @@ -545,7 +545,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config ) statedb.SetTxContext(tx.Hash(), i) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number()) if err != nil { log.Warn("Tracing intermediate roots did not complete due to fees.CalculateL1DataFee", "txindex", i, "txhash", tx.Hash(), "err", err) return nil, err @@ -626,7 +626,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac TxHash: txs[task.index].Hash(), } - l1DataFee, err := fees.CalculateL1DataFee(txs[task.index], task.statedb) + l1DataFee, err := fees.CalculateL1DataFee(txs[task.index], task.statedb, api.backend.ChainConfig(), block.Number()) if err != nil { // though it's not a "tracing error", we still need to put it here results[task.index] = &txTraceResult{Error: err.Error()} @@ -651,7 +651,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac msg, _ := tx.AsMessage(signer, block.BaseFee()) statedb.SetTxContext(tx.Hash(), i) vmenv := vm.NewEVM(blockCtx, core.NewEVMTxContext(msg), statedb, api.backend.ChainConfig(), vm.Config{}) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number()) if err != nil { failed = err break @@ -769,7 +769,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block // Execute the transaction and flush any traces to disk vmenv := vm.NewEVM(vmctx, txContext, statedb, chainConfig, vmConf) statedb.SetTxContext(tx.Hash(), i) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number()) if err == nil { _, err = core.ApplyMessage(vmenv, msg, new(core.GasPool).AddGas(msg.Gas()), l1DataFee) } @@ -834,7 +834,7 @@ func (api *API) TraceTransaction(ctx context.Context, hash common.Hash, config * TxIndex: int(index), TxHash: hash, } - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, api.backend.ChainConfig(), block.Number()) if err != nil { return nil, err } @@ -894,7 +894,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc } signer := types.MakeSigner(api.backend.ChainConfig(), block.Number()) - l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, block.BaseFee(), api.backend.ChainConfig().ChainID, signer, statedb) + l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, block.BaseFee(), api.backend.ChainConfig(), signer, statedb, block.Number()) if err != nil { return nil, err } diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 3a209c752b5a..e9928434a981 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -173,7 +173,7 @@ func (b *testBackend) StateAtTransaction(ctx context.Context, block *types.Block return msg, context, statedb, nil } vmenv := vm.NewEVM(context, txContext, statedb, b.chainConfig, vm.Config{}) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, b.chainConfig, block.Number()) if err != nil { return nil, vm.BlockContext{}, nil, err } diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index 7fc405b75004..8ef0b653017e 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -193,7 +193,7 @@ func testCallTracer(tracerName string, dirPath string, t *testing.T) { if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber) if err != nil { t.Fatalf("failed to calculate l1DataFee: %v", err) } @@ -308,7 +308,7 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { } evm := vm.NewEVM(context, txContext, statedb, test.Genesis.Config, vm.Config{Debug: true, Tracer: tracer}) snap := statedb.Snapshot() - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, test.Genesis.Config, context.BlockNumber) if err != nil { b.Fatalf("failed to calculate l1DataFee: %v", err) } @@ -381,7 +381,7 @@ func TestZeroValueToNotExitCall(t *testing.T) { if err != nil { t.Fatalf("failed to prepare transaction for tracing: %v", err) } - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, params.MainnetChainConfig, context.BlockNumber) if err != nil { t.Fatalf("failed to calculate l1DataFee: %v", err) } diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index 7b64f78eeac2..4a18a9245c73 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -112,7 +112,7 @@ func BenchmarkTransactionTrace(b *testing.B) { for i := 0; i < b.N; i++ { snap := statedb.Snapshot() - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, params.AllEthashProtocolChanges, context.BlockNumber) if err != nil { b.Fatal(err) } diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index d89bbcb50a6e..6e1e1393d6b6 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -197,9 +197,13 @@ var genesis = &core.Genesis{ rcfg.L1GasPriceOracleAddress: { Balance: big.NewInt(0), Storage: map[common.Hash]common.Hash{ - rcfg.L1BaseFeeSlot: common.BigToHash(big.NewInt(10000)), - rcfg.OverheadSlot: common.BigToHash(big.NewInt(10000)), - rcfg.ScalarSlot: common.BigToHash(big.NewInt(10000)), + rcfg.L1BaseFeeSlot: common.BigToHash(big.NewInt(10000)), + rcfg.OverheadSlot: common.BigToHash(big.NewInt(10000)), + rcfg.ScalarSlot: common.BigToHash(big.NewInt(10000)), + rcfg.L1BlobBaseFeeSlot: common.BigToHash(big.NewInt(10000)), + rcfg.CommitScalarSlot: common.BigToHash(big.NewInt(10000)), + rcfg.BlobScalarSlot: common.BigToHash(big.NewInt(10000)), + rcfg.IsCurieSlot: common.BytesToHash([]byte{1}), }, }, }, diff --git a/ethclient/gethclient/gethclient_test.go b/ethclient/gethclient/gethclient_test.go index 04a498d0f9e5..32f16e8c035b 100644 --- a/ethclient/gethclient/gethclient_test.go +++ b/ethclient/gethclient/gethclient_test.go @@ -81,9 +81,13 @@ func generateTestChain() (*core.Genesis, []*types.Block) { rcfg.L1GasPriceOracleAddress: { Balance: big.NewInt(0), Storage: map[common.Hash]common.Hash{ - rcfg.L1BaseFeeSlot: common.BigToHash(big.NewInt(10000)), - rcfg.OverheadSlot: common.BigToHash(big.NewInt(10000)), - rcfg.ScalarSlot: common.BigToHash(big.NewInt(10000)), + rcfg.L1BaseFeeSlot: common.BigToHash(big.NewInt(10000)), + rcfg.OverheadSlot: common.BigToHash(big.NewInt(10000)), + rcfg.ScalarSlot: common.BigToHash(big.NewInt(10000)), + rcfg.L1BlobBaseFeeSlot: common.BigToHash(big.NewInt(10000)), + rcfg.CommitScalarSlot: common.BigToHash(big.NewInt(10000)), + rcfg.BlobScalarSlot: common.BigToHash(big.NewInt(10000)), + rcfg.IsCurieSlot: common.BytesToHash([]byte{1}), }, }, }, diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index b41bd33fd84d..b4cf9539ce76 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -952,7 +952,7 @@ func EstimateL1MsgFee(ctx context.Context, b Backend, args TransactionArgs, bloc }() signer := types.MakeSigner(config, header.Number) - return fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config.ChainID, signer, evm.StateDB) + return fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, evm.StateDB, header.Number) } func DoCall(ctx context.Context, b Backend, args TransactionArgs, blockNrOrHash rpc.BlockNumberOrHash, overrides *StateOverride, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { @@ -1496,7 +1496,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH return nil, 0, nil, err } signer := types.MakeSigner(b.ChainConfig(), header.Number) - l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, b.ChainConfig().ChainID, signer, statedb) + l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, b.ChainConfig(), signer, statedb, header.Number) if err != nil { return nil, 0, nil, fmt.Errorf("failed to apply transaction: %v err: %v", args.toTransaction().Hash(), err) } diff --git a/les/odr_test.go b/les/odr_test.go index 6878e3479ec6..11f254ffd535 100644 --- a/les/odr_test.go +++ b/les/odr_test.go @@ -145,7 +145,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai //vmenv := core.NewEnv(statedb, config, bc, msg, header, vm.Config{}) gp := new(core.GasPool).AddGas(math.MaxUint64) signer := types.MakeSigner(config, header.Number) - l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config.ChainID, signer, statedb) + l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, statedb, header.Number) result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee) res = append(res, result.Return()...) } @@ -159,7 +159,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, config *params.Chai vmenv := vm.NewEVM(context, txContext, state, config, vm.Config{NoBaseFee: true}) gp := new(core.GasPool).AddGas(math.MaxUint64) signer := types.MakeSigner(config, header.Number) - l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config.ChainID, signer, state) + l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, state, header.Number) result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee) if state.Error() == nil { res = append(res, result.Return()...) diff --git a/les/state_accessor.go b/les/state_accessor.go index 80cfbac936f8..9378aefff110 100644 --- a/les/state_accessor.go +++ b/les/state_accessor.go @@ -65,7 +65,7 @@ func (leth *LightEthereum) stateAtTransaction(ctx context.Context, block *types. } // Not yet the searched for transaction, execute on top of the current state vmenv := vm.NewEVM(context, txContext, statedb, leth.blockchain.Config(), vm.Config{}) - l1DataFee, err := fees.CalculateL1DataFee(tx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, leth.blockchain.Config(), block.Number()) if err != nil { return nil, vm.BlockContext{}, nil, fmt.Errorf("transaction %#x failed: %v", tx.Hash(), err) } diff --git a/light/odr_test.go b/light/odr_test.go index 41c6c48901b5..7dd448535a97 100644 --- a/light/odr_test.go +++ b/light/odr_test.go @@ -201,7 +201,7 @@ func odrContractCall(ctx context.Context, db ethdb.Database, bc *core.BlockChain vmenv := vm.NewEVM(context, txContext, st, config, vm.Config{NoBaseFee: true}) gp := new(core.GasPool).AddGas(math.MaxUint64) signer := types.MakeSigner(config, header.Number) - l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config.ChainID, signer, st) + l1DataFee, _ := fees.EstimateL1DataFeeForMessage(msg, header.BaseFee, config, signer, st, header.Number) result, _ := core.ApplyMessage(vmenv, msg, gp, l1DataFee) res = append(res, result.Return()...) if st.Error() != nil { diff --git a/light/txpool.go b/light/txpool.go index d6b697fcbe9b..ca3158a78dc9 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -72,6 +72,8 @@ type TxPool struct { istanbul bool // Fork indicator whether we are in the istanbul stage. eip2718 bool // Fork indicator whether we are in the eip2718 stage. shanghai bool // Fork indicator whether we are in the shanghai stage. + + currentHead *big.Int // Current blockchain head } // TxRelayBackend provides an interface to the mechanism that forwards transacions @@ -79,10 +81,13 @@ type TxPool struct { // // Send instructs backend to forward new transactions // NewHead notifies backend about a new head after processed by the tx pool, -// including mined and rolled back transactions since the last event +// +// including mined and rolled back transactions since the last event +// // Discard notifies backend about transactions that should be discarded either -// because they have been replaced by a re-send or because they have been mined -// long ago and no rollback is expected +// +// because they have been replaced by a re-send or because they have been mined +// long ago and no rollback is expected type TxRelayBackend interface { Send(txs types.Transactions) NewHead(head common.Hash, mined []common.Hash, rollback []common.Hash) @@ -319,6 +324,8 @@ func (pool *TxPool) setNewHead(head *types.Header) { pool.istanbul = pool.config.IsIstanbul(next) pool.eip2718 = pool.config.IsBerlin(next) pool.shanghai = pool.config.IsShanghai(next) + + pool.currentHead = next } // Stop stops the light transaction pool @@ -387,7 +394,7 @@ func (pool *TxPool) validateTx(ctx context.Context, tx *types.Transaction) error // 2. If FeeVault is enabled, perform an additional check for L1 data fees. if pool.config.Scroll.FeeVaultEnabled() { // Get L1 data fee in current state - l1DataFee, err := fees.CalculateL1DataFee(tx, currentState) + l1DataFee, err := fees.CalculateL1DataFee(tx, currentState, pool.config, pool.currentHead) if err != nil { return fmt.Errorf("failed to calculate L1 data fee, err: %w", err) } diff --git a/miner/scroll_worker.go b/miner/scroll_worker.go index bb8da0658c22..3982396e2373 100644 --- a/miner/scroll_worker.go +++ b/miner/scroll_worker.go @@ -461,6 +461,32 @@ func (w *worker) startNewPipeline(timestamp int64) { return } + // Apply special state transition at Curie block + if w.chainConfig.CurieBlock != nil && w.chainConfig.CurieBlock.Cmp(header.Number) == 0 { + misc.ApplyCurieHardFork(parentState) + + // zkEVM requirement: Curie transition block contains 0 transactions, bypass pipeline. + err = w.commit(&pipeline.Result{ + // Note: Signer nodes will not store CCC results for empty blocks in their database. + // In practice, this is acceptable, since this block will never overflow, and follower + // nodes will still store CCC results. + Rows: &types.RowConsumption{}, + FinalBlock: &pipeline.BlockCandidate{ + Header: header, + State: parentState, + Txs: types.Transactions{}, + Receipts: types.Receipts{}, + CoalescedLogs: []*types.Log{}, + }, + }) + + if err != nil { + log.Error("failed to commit Curie fork block", "reason", err) + } + + return + } + // fetch l1Txs var l1Messages []types.L1MessageTx if w.chainConfig.Scroll.ShouldIncludeL1Messages() { diff --git a/miner/worker.go b/miner/worker.go index 40292c3d1d8d..7cef7e3e5c02 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -1411,6 +1411,13 @@ func (w *worker) commitNewWork(interrupt *int32, noempty bool, timestamp int64) if w.chainConfig.DAOForkSupport && w.chainConfig.DAOForkBlock != nil && w.chainConfig.DAOForkBlock.Cmp(header.Number) == 0 { misc.ApplyDAOHardFork(env.state) } + if w.chainConfig.CurieBlock != nil && w.chainConfig.CurieBlock.Cmp(header.Number) == 0 { + misc.ApplyCurieHardFork(env.state) + + // zkEVM requirement: Curie transition block has 0 transactions + w.commit(nil, w.fullTaskHook, true, tstart) + return + } // Accumulate the uncles for the current block uncles := make([]*types.Header, 0, 2) commitUncles := func(blocks map[common.Hash]*types.Block) { diff --git a/params/version.go b/params/version.go index 326c7b339ce4..3b8faf29d972 100644 --- a/params/version.go +++ b/params/version.go @@ -24,7 +24,7 @@ import ( const ( VersionMajor = 5 // Major version component of the current release VersionMinor = 3 // Minor version component of the current release - VersionPatch = 26 // Patch version component of the current release + VersionPatch = 27 // Patch version component of the current release VersionMeta = "mainnet" // Version metadata to append to the version string ) diff --git a/rollup/fees/rollup_fee.go b/rollup/fees/rollup_fee.go index 312471a1af6a..7eb110939420 100644 --- a/rollup/fees/rollup_fee.go +++ b/rollup/fees/rollup_fee.go @@ -43,12 +43,21 @@ type StateDB interface { GetBalance(addr common.Address) *big.Int } -func EstimateL1DataFeeForMessage(msg Message, baseFee, chainID *big.Int, signer types.Signer, state StateDB) (*big.Int, error) { +type gpoState struct { + l1BaseFee *big.Int + overhead *big.Int + scalar *big.Int + l1BlobBaseFee *big.Int + commitScalar *big.Int + blobScalar *big.Int +} + +func EstimateL1DataFeeForMessage(msg Message, baseFee *big.Int, config *params.ChainConfig, signer types.Signer, state StateDB, blockNumber *big.Int) (*big.Int, error) { if msg.IsL1MessageTx() { return big.NewInt(0), nil } - unsigned := asUnsignedTx(msg, baseFee, chainID) + unsigned := asUnsignedTx(msg, baseFee, config.ChainID) // with v=1 tx, err := unsigned.WithSignature(signer, append(bytes.Repeat([]byte{0xff}, crypto.SignatureLength-1), 0x01)) if err != nil { @@ -60,8 +69,16 @@ func EstimateL1DataFeeForMessage(msg Message, baseFee, chainID *big.Int, signer return nil, err } - l1BaseFee, overhead, scalar := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state) - l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar) + gpoState := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state) + + var l1DataFee *big.Int + + if !config.IsCurie(blockNumber) { + l1DataFee = calculateEncodedL1DataFee(raw, gpoState.overhead, gpoState.l1BaseFee, gpoState.scalar) + } else { + l1DataFee = calculateEncodedL1DataFeeCurie(raw, gpoState.l1BaseFee, gpoState.l1BlobBaseFee, gpoState.commitScalar, gpoState.blobScalar) + } + return l1DataFee, nil } @@ -126,25 +143,46 @@ func rlpEncode(tx *types.Transaction) ([]byte, error) { return raw.Bytes(), nil } -func readGPOStorageSlots(addr common.Address, state StateDB) (*big.Int, *big.Int, *big.Int) { - l1BaseFee := state.GetState(addr, rcfg.L1BaseFeeSlot) - overhead := state.GetState(addr, rcfg.OverheadSlot) - scalar := state.GetState(addr, rcfg.ScalarSlot) - return l1BaseFee.Big(), overhead.Big(), scalar.Big() +func readGPOStorageSlots(addr common.Address, state StateDB) gpoState { + var gpoState gpoState + gpoState.l1BaseFee = state.GetState(addr, rcfg.L1BaseFeeSlot).Big() + gpoState.overhead = state.GetState(addr, rcfg.OverheadSlot).Big() + gpoState.scalar = state.GetState(addr, rcfg.ScalarSlot).Big() + gpoState.l1BlobBaseFee = state.GetState(addr, rcfg.L1BlobBaseFeeSlot).Big() + gpoState.commitScalar = state.GetState(addr, rcfg.CommitScalarSlot).Big() + gpoState.blobScalar = state.GetState(addr, rcfg.BlobScalarSlot).Big() + return gpoState } // calculateEncodedL1DataFee computes the L1 fee for an RLP-encoded tx -func calculateEncodedL1DataFee(data []byte, overhead, l1GasPrice *big.Int, scalar *big.Int) *big.Int { - l1GasUsed := CalculateL1GasUsed(data, overhead) - l1DataFee := new(big.Int).Mul(l1GasUsed, l1GasPrice) +func calculateEncodedL1DataFee(data []byte, overhead, l1BaseFee *big.Int, scalar *big.Int) *big.Int { + l1GasUsed := calculateL1GasUsed(data, overhead) + l1DataFee := new(big.Int).Mul(l1GasUsed, l1BaseFee) return mulAndScale(l1DataFee, scalar, rcfg.Precision) } -// CalculateL1GasUsed computes the L1 gas used based on the calldata and +// calculateEncodedL1DataFeeCurie computes the L1 fee for an RLP-encoded tx, post Curie +func calculateEncodedL1DataFeeCurie(data []byte, l1BaseFee *big.Int, l1BlobBaseFee *big.Int, commitScalar *big.Int, blobScalar *big.Int) *big.Int { + // calldata component of commit fees (calldata gas + execution) + calldataGas := new(big.Int).Mul(commitScalar, l1BaseFee) + + // blob component of commit fees + blobGas := big.NewInt(int64(len(data))) + blobGas = new(big.Int).Mul(blobGas, l1BlobBaseFee) + blobGas = new(big.Int).Mul(blobGas, blobScalar) + + // combined + l1DataFee := new(big.Int).Add(calldataGas, blobGas) + l1DataFee = new(big.Int).Quo(l1DataFee, rcfg.Precision) + + return l1DataFee +} + +// calculateL1GasUsed computes the L1 gas used based on the calldata and // constant sized overhead. The overhead can be decreased as the cost of the // batch submission goes down via contract optimizations. This will not overflow // under standard network conditions. -func CalculateL1GasUsed(data []byte, overhead *big.Int) *big.Int { +func calculateL1GasUsed(data []byte, overhead *big.Int) *big.Int { zeroes, ones := zeroesAndOnes(data) zeroesGas := zeroes * params.TxDataZeroGas onesGas := (ones + txExtraDataBytes) * params.TxDataNonZeroGasEIP2028 @@ -173,7 +211,7 @@ func mulAndScale(x *big.Int, y *big.Int, precision *big.Int) *big.Int { return new(big.Int).Quo(z, precision) } -func CalculateL1DataFee(tx *types.Transaction, state StateDB) (*big.Int, error) { +func CalculateL1DataFee(tx *types.Transaction, state StateDB, config *params.ChainConfig, blockNumber *big.Int) (*big.Int, error) { if tx.IsL1MessageTx() { return big.NewInt(0), nil } @@ -183,8 +221,16 @@ func CalculateL1DataFee(tx *types.Transaction, state StateDB) (*big.Int, error) return nil, err } - l1BaseFee, overhead, scalar := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state) - l1DataFee := calculateEncodedL1DataFee(raw, overhead, l1BaseFee, scalar) + gpoState := readGPOStorageSlots(rcfg.L1GasPriceOracleAddress, state) + + var l1DataFee *big.Int + + if !config.IsCurie(blockNumber) { + l1DataFee = calculateEncodedL1DataFee(raw, gpoState.overhead, gpoState.l1BaseFee, gpoState.scalar) + } else { + l1DataFee = calculateEncodedL1DataFeeCurie(raw, gpoState.l1BaseFee, gpoState.l1BlobBaseFee, gpoState.commitScalar, gpoState.blobScalar) + } + return l1DataFee, nil } diff --git a/rollup/fees/rollup_fee_test.go b/rollup/fees/rollup_fee_test.go index 54b77eeb151c..b35d8cd9bf55 100644 --- a/rollup/fees/rollup_fee_test.go +++ b/rollup/fees/rollup_fee_test.go @@ -7,14 +7,27 @@ import ( "github.com/stretchr/testify/assert" ) -func TestCalculateEncodedL1DataFee(t *testing.T) { +func TestL1DataFeeBeforeCurie(t *testing.T) { l1BaseFee := new(big.Int).SetUint64(15000000) - - data := []byte{0, 10, 1, 0} overhead := new(big.Int).SetUint64(100) scalar := new(big.Int).SetUint64(10) - expected := new(big.Int).SetUint64(184) // 184.2 + data := []byte{0, 10, 1, 0} + + expected := new(big.Int).SetUint64(30) // 30.6 actual := calculateEncodedL1DataFee(data, overhead, l1BaseFee, scalar) assert.Equal(t, expected, actual) } + +func TestL1DataFeeAfterCurie(t *testing.T) { + l1BaseFee := new(big.Int).SetUint64(1500000000) + l1BlobBaseFee := new(big.Int).SetUint64(150000000) + commitScalar := new(big.Int).SetUint64(10) + blobScalar := new(big.Int).SetUint64(10) + + data := []byte{0, 10, 1, 0} + + expected := new(big.Int).SetUint64(21) + actual := calculateEncodedL1DataFeeCurie(data, l1BaseFee, l1BlobBaseFee, commitScalar, blobScalar) + assert.Equal(t, expected, actual) +} diff --git a/rollup/pipeline/pipeline.go b/rollup/pipeline/pipeline.go index 3c7089cf60e5..0cfad6ad5759 100644 --- a/rollup/pipeline/pipeline.go +++ b/rollup/pipeline/pipeline.go @@ -51,7 +51,7 @@ type Pipeline struct { parent *types.Block start time.Time - // accumalators + // accumulators ccc *circuitcapacitychecker.CircuitCapacityChecker Header types.Header state *state.StateDB diff --git a/rollup/rcfg/config.go b/rollup/rcfg/config.go index 3e0e00ce041e..005ca7d08833 100644 --- a/rollup/rcfg/config.go +++ b/rollup/rcfg/config.go @@ -29,4 +29,23 @@ var ( L1BaseFeeSlot = common.BigToHash(big.NewInt(1)) OverheadSlot = common.BigToHash(big.NewInt(2)) ScalarSlot = common.BigToHash(big.NewInt(3)) + + // New fields added in the Curie hard fork + L1BlobBaseFeeSlot = common.BigToHash(big.NewInt(5)) + CommitScalarSlot = common.BigToHash(big.NewInt(6)) + BlobScalarSlot = common.BigToHash(big.NewInt(7)) + IsCurieSlot = common.BigToHash(big.NewInt(8)) + + InitialCommitScalar = big.NewInt(230759955285) + InitialBlobScalar = big.NewInt(417565260) + + // CurieL1GasPriceOracleBytecode is the new (blob-enabled) gas price oracle after + // the Curie hard fork. Run these commands in the monorepo to verify this bytecode: + // + // git checkout 7059ad0ed465201287e06625dd4058c8ae9682b8 + // cd contracts + // yarn + // FOUNDRY_EVM_VERSION="cancun" forge build + // cat artifacts/src/L1GasPriceOracle.sol/L1GasPriceOracle.json | jq -r .deployedBytecode.object + CurieL1GasPriceOracleBytecode = common.Hex2Bytes("608060405234801561000f575f80fd5b5060043610610132575f3560e01c8063715018a6116100b4578063a911d77f11610079578063a911d77f1461024c578063bede39b514610254578063de26c4a114610267578063e88a60ad1461027a578063f2fde38b1461028d578063f45e65d8146102a0575f80fd5b8063715018a6146101eb57806384189161146101f35780638da5cb5b146101fc57806393e59dc114610226578063944b247f14610239575f80fd5b80633d0f963e116100fa5780633d0f963e146101a057806349948e0e146101b3578063519b4bd3146101c65780636a5e67e5146101cf57806370465597146101d8575f80fd5b80630c18c1621461013657806313dad5be1461015257806323e524ac1461016f5780633577afc51461017857806339455d3a1461018d575b5f80fd5b61013f60025481565b6040519081526020015b60405180910390f35b60085461015f9060ff1681565b6040519015158152602001610149565b61013f60065481565b61018b6101863660046109c3565b6102a9565b005b61018b61019b3660046109da565b61033b565b61018b6101ae3660046109fa565b610438565b61013f6101c1366004610a3b565b6104bb565b61013f60015481565b61013f60075481565b61018b6101e63660046109c3565b6104e0565b61018b61056e565b61013f60055481565b5f5461020e906001600160a01b031681565b6040516001600160a01b039091168152602001610149565b60045461020e906001600160a01b031681565b61018b6102473660046109c3565b6105a2565b61018b610636565b61018b6102623660046109c3565b610692565b61013f610275366004610a3b565b61074f565b61018b6102883660046109c3565b61076c565b61018b61029b3660046109fa565b610800565b61013f60035481565b5f546001600160a01b031633146102db5760405162461bcd60e51b81526004016102d290610ae6565b60405180910390fd5b621c9c388111156102ff57604051635742c80560e11b815260040160405180910390fd5b60028190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa158015610382573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103a69190610b1d565b6103c3576040516326b3506d60e11b815260040160405180910390fd5b600182905560058190556040518281527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c449060200160405180910390a16040518181527f9a14bfb5d18c4c3cf14cae19c23d7cf1bcede357ea40ca1f75cd49542c71c214906020015b60405180910390a15050565b5f546001600160a01b031633146104615760405162461bcd60e51b81526004016102d290610ae6565b600480546001600160a01b038381166001600160a01b031983168117909355604080519190921680825260208201939093527f22d1c35fe072d2e42c3c8f9bd4a0d34aa84a0101d020a62517b33fdb3174e5f7910161042c565b6008545f9060ff16156104d7576104d18261088b565b92915050565b6104d1826108d1565b5f546001600160a01b031633146105095760405162461bcd60e51b81526004016102d290610ae6565b610519633b9aca006103e8610b50565b81111561053957604051631e44fdeb60e11b815260040160405180910390fd5b60038190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a90602001610330565b5f546001600160a01b031633146105975760405162461bcd60e51b81526004016102d290610ae6565b6105a05f610914565b565b5f546001600160a01b031633146105cb5760405162461bcd60e51b81526004016102d290610ae6565b6105e1633b9aca00670de0b6b3a7640000610b50565b8111156106015760405163874f603160e01b815260040160405180910390fd5b60068190556040518181527f2ab3f5a4ebbcbf3c24f62f5454f52f10e1a8c9dcc5acac8f19199ce881a6a10890602001610330565b5f546001600160a01b0316331461065f5760405162461bcd60e51b81526004016102d290610ae6565b60085460ff1615610683576040516379f9c57560e01b815260040160405180910390fd5b6008805460ff19166001179055565b6004805460405163efc7840160e01b815233928101929092526001600160a01b03169063efc7840190602401602060405180830381865afa1580156106d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106fd9190610b1d565b61071a576040516326b3506d60e11b815260040160405180910390fd5b60018190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c4490602001610330565b6008545f9060ff161561076357505f919050565b6104d182610963565b5f546001600160a01b031633146107955760405162461bcd60e51b81526004016102d290610ae6565b6107ab633b9aca00670de0b6b3a7640000610b50565b8111156107cb5760405163f37ec21560e01b815260040160405180910390fd5b60078190556040518181527f6b332a036d8c3ead57dcb06c87243bd7a2aed015ddf2d0528c2501dae56331aa90602001610330565b5f546001600160a01b031633146108295760405162461bcd60e51b81526004016102d290610ae6565b6001600160a01b03811661087f5760405162461bcd60e51b815260206004820152601d60248201527f6e6577206f776e657220697320746865207a65726f206164647265737300000060448201526064016102d2565b61088881610914565b50565b5f633b9aca0060055483516007546108a39190610b50565b6108ad9190610b50565b6001546006546108bd9190610b50565b6108c79190610b67565b6104d19190610b7a565b5f806108dc83610963565b90505f600154826108ed9190610b50565b9050633b9aca00600354826109029190610b50565b61090c9190610b7a565b949350505050565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80515f908190815b818110156109b45784818151811061098557610985610b99565b01602001516001600160f81b0319165f036109a5576004830192506109ac565b6010830192505b60010161096b565b50506002540160400192915050565b5f602082840312156109d3575f80fd5b5035919050565b5f80604083850312156109eb575f80fd5b50508035926020909101359150565b5f60208284031215610a0a575f80fd5b81356001600160a01b0381168114610a20575f80fd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b5f60208284031215610a4b575f80fd5b813567ffffffffffffffff80821115610a62575f80fd5b818401915084601f830112610a75575f80fd5b813581811115610a8757610a87610a27565b604051601f8201601f19908116603f01168101908382118183101715610aaf57610aaf610a27565b81604052828152876020848701011115610ac7575f80fd5b826020860160208301375f928101602001929092525095945050505050565b60208082526017908201527f63616c6c6572206973206e6f7420746865206f776e6572000000000000000000604082015260600190565b5f60208284031215610b2d575f80fd5b81518015158114610a20575f80fd5b634e487b7160e01b5f52601160045260245ffd5b80820281158282048414176104d1576104d1610b3c565b808201808211156104d1576104d1610b3c565b5f82610b9457634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffdfea26469706673582212206579d545ea4839464c2fd4ba9a7e6a4f4fee1cc1b51182da675c0f0c05fc161964736f6c63430008180033") ) diff --git a/rollup/tracing/tracing.go b/rollup/tracing/tracing.go index 321b3885ecc9..f83e419c64ae 100644 --- a/rollup/tracing/tracing.go +++ b/rollup/tracing/tracing.go @@ -229,7 +229,7 @@ func (env *TraceEnv) GetBlockTrace(block *types.Block) (*types.BlockTrace, error msg, _ := tx.AsMessage(env.signer, block.BaseFee()) env.state.SetTxContext(tx.Hash(), i) vmenv := vm.NewEVM(env.blockCtx, core.NewEVMTxContext(msg), env.state, env.chainConfig, vm.Config{}) - l1DataFee, err := fees.CalculateL1DataFee(tx, env.state) + l1DataFee, err := fees.CalculateL1DataFee(tx, env.state, env.chainConfig, block.Number()) if err != nil { failed = err break @@ -335,7 +335,7 @@ func (env *TraceEnv) getTxResult(state *state.StateDB, index int, block *types.B state.SetTxContext(txctx.TxHash, txctx.TxIndex) // Computes the new state by applying the given message. - l1DataFee, err := fees.CalculateL1DataFee(tx, state) + l1DataFee, err := fees.CalculateL1DataFee(tx, state, env.chainConfig, block.Number()) if err != nil { return err } @@ -530,6 +530,10 @@ func (env *TraceEnv) fillBlockTrace(block *types.Block) (*types.BlockTrace, erro rcfg.L1BaseFeeSlot, rcfg.OverheadSlot, rcfg.ScalarSlot, + rcfg.L1BlobBaseFeeSlot, + rcfg.CommitScalarSlot, + rcfg.BlobScalarSlot, + rcfg.IsCurieSlot, }, } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 01ff828b8817..959c513d05c7 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -227,7 +227,7 @@ func (t *StateTest) RunNoVerify(subtest StateSubtest, vmconfig vm.Config, snapsh gaspool := new(core.GasPool) gaspool.AddGas(block.GasLimit()) - l1DataFee, err := fees.CalculateL1DataFee(&ttx, statedb) + l1DataFee, err := fees.CalculateL1DataFee(&ttx, statedb, config, block.Number()) if err != nil { return nil, nil, common.Hash{}, err } From 760f234a1ab050224ba245dbac3116f6a17d02ca Mon Sep 17 00:00:00 2001 From: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com> Date: Tue, 28 May 2024 22:07:38 +0800 Subject: [PATCH 5/8] trie: fix two issues in trie iterator (#24539) (#778) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * trie: fix two issues in trie iterator (#24539) * trie: fix memory leak in trie iterator In the trie iterator, live nodes are tracked in a stack while iterating. Popped node states should be explictly set to nil in order to get garbage-collected. * trie: fix empty trie iterator * fix lint * chore: auto version bump [bot] --------- Co-authored-by: rjl493456442 Co-authored-by: HAOYUatHZ --- trie/iterator.go | 14 +++++++++----- trie/iterator_test.go | 13 +++++++++++++ trie/trie.go | 4 ---- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/trie/iterator.go b/trie/iterator.go index af787aa7b520..d2c01662ca6b 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -151,8 +151,11 @@ func (e seekError) Error() string { } func newNodeIterator(trie *Trie, start []byte) NodeIterator { - if trie.Hash() == emptyState { - return new(nodeIterator) + if trie.Hash() == emptyRoot { + return &nodeIterator{ + trie: trie, + err: errIteratorEnd, + } } it := &nodeIterator{trie: trie} it.err = it.seek(start) @@ -402,7 +405,7 @@ func findChild(n *fullNode, index int, path []byte, ancestor common.Hash) (node, func (it *nodeIterator) nextChild(parent *nodeIteratorState, ancestor common.Hash) (*nodeIteratorState, []byte, bool) { switch node := parent.node.(type) { case *fullNode: - //Full node, move to the first non-nil child. + // Full node, move to the first non-nil child. if child, state, path, index := findChild(node, parent.index+1, it.path, ancestor); child != nil { parent.index = index - 1 return state, path, true @@ -480,8 +483,9 @@ func (it *nodeIterator) push(state *nodeIteratorState, parentIndex *int, path [] } func (it *nodeIterator) pop() { - parent := it.stack[len(it.stack)-1] - it.path = it.path[:parent.pathlen] + last := it.stack[len(it.stack)-1] + it.path = it.path[:last.pathlen] + it.stack[len(it.stack)-1] = nil it.stack = it.stack[:len(it.stack)-1] } diff --git a/trie/iterator_test.go b/trie/iterator_test.go index 46920e9541fa..761d812bdfcc 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -29,6 +29,19 @@ import ( "github.com/scroll-tech/go-ethereum/ethdb/memorydb" ) +func TestEmptyIterator(t *testing.T) { + trie := newEmpty() + iter := trie.NodeIterator(nil) + + seen := make(map[string]struct{}) + for iter.Next(true) { + seen[string(iter.Path())] = struct{}{} + } + if len(seen) != 0 { + t.Fatal("Unexpected trie node iterated") + } +} + func TestIterator(t *testing.T) { trie := newEmpty() vals := []struct{ k, v string }{ diff --git a/trie/trie.go b/trie/trie.go index 1befc0145e1e..81cdd1627745 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -25,7 +25,6 @@ import ( "github.com/scroll-tech/go-ethereum/common" "github.com/scroll-tech/go-ethereum/core/types" - "github.com/scroll-tech/go-ethereum/crypto" "github.com/scroll-tech/go-ethereum/log" "github.com/scroll-tech/go-ethereum/rlp" ) @@ -33,9 +32,6 @@ import ( var ( // emptyRoot is the known root hash of an empty trie. emptyRoot = common.HexToHash("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421") - - // emptyState is the known hash of an empty state trie entry. - emptyState = crypto.Keccak256Hash(nil) ) // LeafCallback is a callback type invoked when a trie operation reaches a leaf From 4f9d34b3a488dc4689e599d7f6b730603de305fa Mon Sep 17 00:00:00 2001 From: "semgrep.dev on behalf of @spilehchiha" Date: Tue, 28 May 2024 18:57:42 +0000 Subject: [PATCH 6/8] Add Semgrep CI --- .github/workflows/semgrep.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/semgrep.yml diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml new file mode 100644 index 000000000000..6d7663154a85 --- /dev/null +++ b/.github/workflows/semgrep.yml @@ -0,0 +1,24 @@ +on: + workflow_dispatch: {} + pull_request: {} + push: + branches: + - main + - master + paths: + - .github/workflows/semgrep.yml + schedule: + # random HH:MM to avoid a load spike on GitHub Actions at 00:00 + - cron: 20 19 * * * +name: Semgrep +jobs: + semgrep: + name: semgrep/ci + runs-on: ubuntu-20.04 + env: + SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} + container: + image: returntocorp/semgrep + steps: + - uses: actions/checkout@v3 + - run: semgrep ci From d81a5387b4dc858fb403923cc60c5ca6ed253188 Mon Sep 17 00:00:00 2001 From: "semgrep.dev on behalf of @spilehchiha" Date: Tue, 28 May 2024 19:08:07 +0000 Subject: [PATCH 7/8] Add Semgrep CI --- .github/workflows/semgrep.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index 6d7663154a85..d74d68d0ec1c 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -14,7 +14,7 @@ name: Semgrep jobs: semgrep: name: semgrep/ci - runs-on: ubuntu-20.04 + runs-on: self-hosted env: SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} container: From 34162effbcc1c4050ca209ad5505205fca5db257 Mon Sep 17 00:00:00 2001 From: "semgrep.dev on behalf of @spilehchiha" Date: Tue, 28 May 2024 20:46:11 +0000 Subject: [PATCH 8/8] Add Semgrep CI --- .github/workflows/semgrep.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml index d74d68d0ec1c..6d7663154a85 100644 --- a/.github/workflows/semgrep.yml +++ b/.github/workflows/semgrep.yml @@ -14,7 +14,7 @@ name: Semgrep jobs: semgrep: name: semgrep/ci - runs-on: self-hosted + runs-on: ubuntu-20.04 env: SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }} container: