Skip to content

Commit bfe8030

Browse files
Thegaramomerfirmak
andauthored
feat: update L1 data fee in Curie hard fork (#755)
* 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 <[email protected]> Co-authored-by: Thegaram <[email protected]>
1 parent 9f961dd commit bfe8030

File tree

32 files changed

+316
-70
lines changed

32 files changed

+316
-70
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ test: all
4040
# genesis test
4141
cd ${PWD}/cmd/geth; go test -test.run TestCustomGenesis
4242
# module test
43-
$(GORUN) build/ci.go test ./consensus ./core ./eth ./miner ./node ./trie
43+
$(GORUN) build/ci.go test ./consensus ./core ./eth ./miner ./node ./trie ./rollup/fees
4444

4545
lint: ## Run linters.
4646
$(GORUN) build/ci.go lint

accounts/abi/bind/backends/simulated.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
640640
vmEnv := vm.NewEVM(evmContext, txContext, stateDB, b.config, vm.Config{NoBaseFee: true})
641641
gasPool := new(core.GasPool).AddGas(math.MaxUint64)
642642
signer := types.MakeSigner(b.blockchain.Config(), head.Number)
643-
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, head.BaseFee, b.blockchain.Config().ChainID, signer, stateDB)
643+
l1DataFee, err := fees.EstimateL1DataFeeForMessage(msg, head.BaseFee, b.blockchain.Config(), signer, stateDB, head.Number)
644644
if err != nil {
645645
return nil, err
646646
}

cmd/evm/internal/t8ntool/execution.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
148148
chainConfig.DAOForkBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 {
149149
misc.ApplyDAOHardFork(statedb)
150150
}
151+
// Apply Curie hard fork
152+
if chainConfig.CurieBlock != nil && chainConfig.CurieBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 {
153+
misc.ApplyCurieHardFork(statedb)
154+
}
151155

152156
for i, tx := range txs {
153157
msg, err := tx.AsMessage(signer, pre.Env.BaseFee)
@@ -167,7 +171,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
167171
snapshot := statedb.Snapshot()
168172
evm := vm.NewEVM(vmContext, txContext, statedb, chainConfig, vmConfig)
169173

170-
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
174+
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, chainConfig, new(big.Int).SetUint64(pre.Env.Number))
171175
if err != nil {
172176
log.Info("rejected tx due to fees.CalculateL1DataFee", "index", i, "hash", tx.Hash(), "from", msg.From(), "error", err)
173177
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})

consensus/misc/curie.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package misc
2+
3+
import (
4+
"github.com/scroll-tech/go-ethereum/common"
5+
"github.com/scroll-tech/go-ethereum/core/state"
6+
"github.com/scroll-tech/go-ethereum/log"
7+
"github.com/scroll-tech/go-ethereum/rollup/rcfg"
8+
)
9+
10+
// ApplyCurieHardFork modifies the state database according to the Curie hard-fork rules,
11+
// updating the bytecode and storage of the L1GasPriceOracle contract.
12+
func ApplyCurieHardFork(statedb *state.StateDB) {
13+
log.Info("Applying Curie hard fork")
14+
15+
// update contract byte code
16+
statedb.SetCode(rcfg.L1GasPriceOracleAddress, rcfg.CurieL1GasPriceOracleBytecode)
17+
18+
// initialize new storage slots
19+
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.IsCurieSlot, common.BytesToHash([]byte{1}))
20+
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.L1BlobBaseFeeSlot, common.BytesToHash([]byte{1}))
21+
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.CommitScalarSlot, common.BigToHash(rcfg.InitialCommitScalar))
22+
statedb.SetState(rcfg.L1GasPriceOracleAddress, rcfg.BlobScalarSlot, common.BigToHash(rcfg.InitialBlobScalar))
23+
}

core/blockchain_test.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package core
1818

1919
import (
20+
"encoding/json"
2021
"errors"
2122
"fmt"
2223
"io/ioutil"
@@ -39,6 +40,7 @@ import (
3940
"github.com/scroll-tech/go-ethereum/crypto"
4041
"github.com/scroll-tech/go-ethereum/ethdb"
4142
"github.com/scroll-tech/go-ethereum/params"
43+
"github.com/scroll-tech/go-ethereum/rollup/rcfg"
4244
"github.com/scroll-tech/go-ethereum/trie"
4345
)
4446

@@ -3712,3 +3714,78 @@ func TestTransientStorageReset(t *testing.T) {
37123714
t.Fatalf("Unexpected dirty storage slot")
37133715
}
37143716
}
3717+
3718+
func TestCurieTransition(t *testing.T) {
3719+
// Set fork blocks in config
3720+
// (we make a deep copy to avoid interference with other tests)
3721+
var config *params.ChainConfig
3722+
b, _ := json.Marshal(params.AllEthashProtocolChanges)
3723+
json.Unmarshal(b, &config)
3724+
config.CurieBlock = big.NewInt(2)
3725+
config.DescartesBlock = nil
3726+
3727+
var (
3728+
db = rawdb.NewMemoryDatabase()
3729+
gspec = &Genesis{Config: config}
3730+
genesis = gspec.MustCommit(db)
3731+
)
3732+
3733+
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
3734+
defer blockchain.Stop()
3735+
blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, nil)
3736+
3737+
if _, err := blockchain.InsertChain(blocks); err != nil {
3738+
t.Fatal(err)
3739+
}
3740+
3741+
latestBlock := uint64(4)
3742+
assert.Equal(t, latestBlock, blockchain.CurrentHeader().Number.Uint64())
3743+
3744+
for ii := uint64(0); ii <= latestBlock; ii++ {
3745+
block := blockchain.GetBlockByNumber(ii)
3746+
3747+
number := block.Number().Uint64()
3748+
baseFee := block.BaseFee()
3749+
3750+
statedb, _ := state.New(block.Root(), state.NewDatabase(db), nil)
3751+
3752+
code := statedb.GetCode(rcfg.L1GasPriceOracleAddress)
3753+
codeSize := statedb.GetCodeSize(rcfg.L1GasPriceOracleAddress)
3754+
keccakCodeHash := statedb.GetKeccakCodeHash(rcfg.L1GasPriceOracleAddress)
3755+
poseidonCodeHash := statedb.GetPoseidonCodeHash(rcfg.L1GasPriceOracleAddress)
3756+
3757+
l1BlobBaseFee := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.L1BlobBaseFeeSlot)
3758+
commitScalar := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.CommitScalarSlot)
3759+
blobScalar := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.BlobScalarSlot)
3760+
isCurie := statedb.GetState(rcfg.L1GasPriceOracleAddress, rcfg.IsCurieSlot)
3761+
3762+
if number < config.CurieBlock.Uint64() {
3763+
assert.Nil(t, baseFee, "Expected zero base fee before Curie")
3764+
3765+
// we don't have predeploys configured in this test,
3766+
// so there is no gas oracle deployed before Curie
3767+
assert.Nil(t, code)
3768+
assert.Equal(t, uint64(0), codeSize)
3769+
assert.Equal(t, common.Hash{}, keccakCodeHash)
3770+
assert.Equal(t, common.Hash{}, poseidonCodeHash)
3771+
3772+
assert.Equal(t, common.Hash{}, l1BlobBaseFee)
3773+
assert.Equal(t, common.Hash{}, commitScalar)
3774+
assert.Equal(t, common.Hash{}, blobScalar)
3775+
assert.Equal(t, common.Hash{}, isCurie)
3776+
} else {
3777+
assert.NotNil(t, baseFee, "Expected nonzero base fee after Curie")
3778+
3779+
// all gas oracle entries updated
3780+
assert.NotNil(t, code)
3781+
assert.NotEqual(t, uint64(0), codeSize)
3782+
assert.NotEqual(t, common.Hash{}, keccakCodeHash)
3783+
assert.NotEqual(t, common.Hash{}, poseidonCodeHash)
3784+
3785+
assert.NotEqual(t, common.Hash{}, l1BlobBaseFee)
3786+
assert.NotEqual(t, common.Hash{}, commitScalar)
3787+
assert.NotEqual(t, common.Hash{}, blobScalar)
3788+
assert.NotEqual(t, common.Hash{}, isCurie)
3789+
}
3790+
}
3791+
}

core/chain_makers.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
240240
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(b.header.Number) == 0 {
241241
misc.ApplyDAOHardFork(statedb)
242242
}
243+
if config.CurieBlock != nil && config.CurieBlock.Cmp(b.header.Number) == 0 {
244+
misc.ApplyCurieHardFork(statedb)
245+
}
243246
// Execute any user modifications to the block
244247
if gen != nil {
245248
gen(i, b)

core/state_prefetcher.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
7171
}
7272
statedb.SetTxContext(tx.Hash(), i)
7373

74-
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
74+
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, p.config, block.Number())
7575
if err != nil {
7676
return
7777
}

core/state_processor.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
8686
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
8787
misc.ApplyDAOHardFork(statedb)
8888
}
89+
// Apply Curie hard fork
90+
if p.config.CurieBlock != nil && p.config.CurieBlock.Cmp(block.Number()) == 0 {
91+
misc.ApplyCurieHardFork(statedb)
92+
}
8993
blockContext := NewEVMBlockContext(header, p.bc, p.config, nil)
9094
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
9195
processorBlockTransactionGauge.Update(int64(block.Transactions().Len()))
@@ -120,7 +124,7 @@ func applyTransaction(msg types.Message, config *params.ChainConfig, bc ChainCon
120124
txContext := NewEVMTxContext(msg)
121125
evm.Reset(txContext, statedb)
122126

123-
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb)
127+
l1DataFee, err := fees.CalculateL1DataFee(tx, statedb, config, blockNumber)
124128
if err != nil {
125129
return nil, err
126130
}

core/tx_list.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/scroll-tech/go-ethereum/core/state"
3030
"github.com/scroll-tech/go-ethereum/core/types"
3131
"github.com/scroll-tech/go-ethereum/log"
32+
"github.com/scroll-tech/go-ethereum/params"
3233
"github.com/scroll-tech/go-ethereum/rollup/fees"
3334
)
3435

@@ -281,7 +282,7 @@ func (l *txList) Overlaps(tx *types.Transaction) bool {
281282
//
282283
// If the new transaction is accepted into the list, the lists' cost and gas
283284
// thresholds are also potentially updated.
284-
func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint64) (bool, *types.Transaction) {
285+
func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint64, chainconfig *params.ChainConfig, blockNumber *big.Int) (bool, *types.Transaction) {
285286
// If there's an older better transaction, abort
286287
old := l.txs.Get(tx.Nonce())
287288
if old != nil {
@@ -307,9 +308,9 @@ func (l *txList) Add(tx *types.Transaction, state *state.StateDB, priceBump uint
307308
}
308309
// Otherwise overwrite the old transaction with the current one
309310
l1DataFee := big.NewInt(0)
310-
if state != nil {
311+
if state != nil && chainconfig != nil {
311312
var err error
312-
l1DataFee, err = fees.CalculateL1DataFee(tx, state)
313+
l1DataFee, err = fees.CalculateL1DataFee(tx, state, chainconfig, blockNumber)
313314
if err != nil {
314315
log.Error("Failed to calculate L1 data fee", "err", err, "tx", tx)
315316
return false, nil

core/tx_list_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestStrictTxListAdd(t *testing.T) {
3838
// Insert the transactions in a random order
3939
list := newTxList(true)
4040
for _, v := range rand.Perm(len(txs)) {
41-
list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump)
41+
list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump, nil, nil)
4242
}
4343
// Verify internal state
4444
if len(list.txs.items) != len(txs) {
@@ -65,7 +65,7 @@ func BenchmarkTxListAdd(b *testing.B) {
6565
for i := 0; i < b.N; i++ {
6666
list := newTxList(true)
6767
for _, v := range rand.Perm(len(txs)) {
68-
list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump)
68+
list.Add(txs[v], nil, DefaultTxPoolConfig.PriceBump, nil, nil)
6969
list.Filter(priceLimit, DefaultTxPoolConfig.PriceBump)
7070
}
7171
}

0 commit comments

Comments
 (0)