Skip to content

Commit ccec84c

Browse files
authored
feat: re-enable EIP-1559 in Banach hard fork (#634)
* feat: re-enable EIP-1559 in Banach hard fork * enable BASEFEE opcode * do not double gas limit on Banach fork block * do not burn base fee * update base fee calculation logic * fix gas price oracle * fix ethapi backend * typo * reorder worker code * update genesis base fee * add MaximumL2BaseFee * add base fee metrics * handle nil base fee * revert state-transition change * bump version * remove TODO * update test * fix typo * fix typo * update traces * fix test * update london to banach * handle error * bump version * bump version
1 parent dab4354 commit ccec84c

32 files changed

+272
-229
lines changed

accounts/abi/bind/backends/simulated.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ func (b *SimulatedBackend) callContract(ctx context.Context, call ethereum.CallM
590590
return nil, errors.New("both gasPrice and (maxFeePerGas or maxPriorityFeePerGas) specified")
591591
}
592592
head := b.blockchain.CurrentHeader()
593-
if !b.blockchain.Config().IsLondon(head.Number) {
593+
if !b.blockchain.Config().IsBanach(head.Number) {
594594
// If there's no basefee, then it must be a non-1559 execution
595595
if call.GasPrice == nil {
596596
call.GasPrice = new(big.Int)

accounts/abi/bind/base.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ func (c *BoundContract) createDynamicTx(opts *TransactOpts, contract *common.Add
289289

290290
func (c *BoundContract) createLegacyTx(opts *TransactOpts, contract *common.Address, input []byte) (*types.Transaction, error) {
291291
if opts.GasFeeCap != nil || opts.GasTipCap != nil {
292-
return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but london is not active yet")
292+
return nil, errors.New("maxFeePerGas or maxPriorityFeePerGas specified but banach is not active yet")
293293
}
294294
// Normalize value
295295
value := opts.Value

cmd/evm/internal/t8ntool/transition.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ func Transition(ctx *cli.Context) error {
247247
return NewError(ErrorJson, fmt.Errorf("failed signing transactions: %v", err))
248248
}
249249
// Sanity check, to not `panic` in state_transition
250-
if chainConfig.IsLondon(big.NewInt(int64(prestate.Env.Number))) {
251-
if prestate.Env.BaseFee == nil && chainConfig.Scroll.BaseFeeEnabled() {
250+
if chainConfig.IsBanach(big.NewInt(int64(prestate.Env.Number))) {
251+
if prestate.Env.BaseFee == nil {
252252
return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section"))
253253
}
254254
}
@@ -321,8 +321,9 @@ func (t *txWithKey) UnmarshalJSON(input []byte) error {
321321
// signUnsignedTransactions converts the input txs to canonical transactions.
322322
//
323323
// The transactions can have two forms, either
324-
// 1. unsigned or
325-
// 2. signed
324+
// 1. unsigned or
325+
// 2. signed
326+
//
326327
// For (1), r, s, v, need so be zero, and the `secretKey` needs to be set.
327328
// If so, we sign it here and now, with the given `secretKey`
328329
// If the condition above is not met, then it's considered a signed transaction.

consensus/clique/clique.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ func (c *Clique) verifyCascadingFields(chain consensus.ChainHeaderReader, header
335335
if header.GasUsed > header.GasLimit {
336336
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
337337
}
338-
if !chain.Config().IsLondon(header.Number) {
338+
if !chain.Config().IsBanach(header.Number) {
339339
// Verify BaseFee not present before EIP-1559 fork.
340340
if header.BaseFee != nil {
341341
return fmt.Errorf("invalid baseFee before fork: have %d, want <nil>", header.BaseFee)

consensus/ethash/consensus.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa
291291
return fmt.Errorf("invalid gasUsed: have %d, gasLimit %d", header.GasUsed, header.GasLimit)
292292
}
293293
// Verify the block's gas usage and (if applicable) verify the base fee.
294-
if !chain.Config().IsLondon(header.Number) {
294+
if !chain.Config().IsBanach(header.Number) {
295295
// Verify BaseFee not present before EIP-1559 fork.
296296
if header.BaseFee != nil {
297297
return fmt.Errorf("invalid baseFee before fork: have %d, expected 'nil'", header.BaseFee)

consensus/misc/eip1559.go

+26-63
Original file line numberDiff line numberDiff line change
@@ -20,90 +20,53 @@ import (
2020
"fmt"
2121
"math/big"
2222

23-
"github.com/scroll-tech/go-ethereum/common"
24-
"github.com/scroll-tech/go-ethereum/common/math"
2523
"github.com/scroll-tech/go-ethereum/core/types"
2624
"github.com/scroll-tech/go-ethereum/params"
2725
)
2826

27+
// Protocol-enforced maximum L2 base fee.
28+
// We would only go above this if L1 base fee hits 700 Gwei.
29+
const MaximumL2BaseFee = 10000000000
30+
2931
// VerifyEip1559Header verifies some header attributes which were changed in EIP-1559,
3032
// - gas limit check
3133
// - basefee check
3234
func VerifyEip1559Header(config *params.ChainConfig, parent, header *types.Header) error {
3335
// Verify that the gas limit remains within allowed bounds
34-
parentGasLimit := parent.GasLimit
35-
if !config.IsLondon(parent.Number) {
36-
parentGasLimit = parent.GasLimit * params.ElasticityMultiplier
37-
}
38-
if err := VerifyGaslimit(parentGasLimit, header.GasLimit); err != nil {
36+
if err := VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil {
3937
return err
4038
}
4139
// Verify the header is not malformed
42-
if header.BaseFee == nil && config.Scroll.BaseFeeEnabled() {
43-
return fmt.Errorf("header is missing baseFee")
44-
}
45-
// Now BaseFee can be nil, because !config.Scroll.BaseFeeEnabled()
4640
if header.BaseFee == nil {
47-
return nil
48-
}
49-
// Verify the baseFee is correct based on the parent header.
50-
51-
var expectedBaseFee *big.Int
52-
53-
// compatible check with the logic in commitNewWork
54-
if config.Clique == nil || config.Scroll.BaseFeeEnabled() {
55-
expectedBaseFee = CalcBaseFee(config, parent)
56-
} else {
57-
expectedBaseFee = big.NewInt(0)
41+
return fmt.Errorf("header is missing baseFee")
5842
}
59-
60-
if header.BaseFee.Cmp(expectedBaseFee) != 0 {
61-
return fmt.Errorf("invalid baseFee: have %s, want %s, parentBaseFee %s, parentGasUsed %d",
62-
expectedBaseFee, header.BaseFee, parent.BaseFee, parent.GasUsed)
43+
// note: we do not verify L2 base fee, the sequencer has the
44+
// right to set any base fee below the maximum. L2 base fee
45+
// is not subject to L2 consensus or zk verification.
46+
if header.BaseFee.Cmp(big.NewInt(MaximumL2BaseFee)) > 0 {
47+
return fmt.Errorf("invalid baseFee: have %s, maximum %d", header.BaseFee, MaximumL2BaseFee)
6348
}
6449
return nil
6550
}
6651

6752
// CalcBaseFee calculates the basefee of the header.
68-
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
69-
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
70-
if !config.IsLondon(parent.Number) {
71-
return new(big.Int).SetUint64(params.InitialBaseFee)
72-
}
53+
func CalcBaseFee(config *params.ChainConfig, parent *types.Header, parentL1BaseFee *big.Int) *big.Int {
54+
l2SequencerFee := big.NewInt(10000000) // 0.01 Gwei
55+
provingFee := big.NewInt(140000000) // 0.14 Gwei
7356

74-
var (
75-
parentGasTarget = parent.GasLimit / params.ElasticityMultiplier
76-
parentGasTargetBig = new(big.Int).SetUint64(parentGasTarget)
77-
baseFeeChangeDenominator = new(big.Int).SetUint64(params.BaseFeeChangeDenominator)
78-
)
79-
if !config.Scroll.BaseFeeEnabled() {
80-
return nil
81-
}
82-
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
83-
if parent.GasUsed == parentGasTarget {
84-
return new(big.Int).Set(parent.BaseFee)
85-
}
86-
if parent.GasUsed > parentGasTarget {
87-
// If the parent block used more gas than its target, the baseFee should increase.
88-
gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed - parentGasTarget)
89-
x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta)
90-
y := x.Div(x, parentGasTargetBig)
91-
baseFeeDelta := math.BigMax(
92-
x.Div(y, baseFeeChangeDenominator),
93-
common.Big1,
94-
)
57+
// L1_base_fee * 0.014
58+
verificationFee := parentL1BaseFee
59+
verificationFee = new(big.Int).Mul(verificationFee, big.NewInt(14))
60+
verificationFee = new(big.Int).Div(verificationFee, big.NewInt(1000))
9561

96-
return x.Add(parent.BaseFee, baseFeeDelta)
97-
} else {
98-
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
99-
gasUsedDelta := new(big.Int).SetUint64(parentGasTarget - parent.GasUsed)
100-
x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta)
101-
y := x.Div(x, parentGasTargetBig)
102-
baseFeeDelta := x.Div(y, baseFeeChangeDenominator)
62+
baseFee := big.NewInt(0)
63+
baseFee.Add(baseFee, l2SequencerFee)
64+
baseFee.Add(baseFee, provingFee)
65+
baseFee.Add(baseFee, verificationFee)
10366

104-
return math.BigMax(
105-
x.Sub(parent.BaseFee, baseFeeDelta),
106-
common.Big0,
107-
)
67+
if baseFee.Cmp(big.NewInt(MaximumL2BaseFee)) > 0 {
68+
baseFee = big.NewInt(MaximumL2BaseFee)
10869
}
70+
71+
return baseFee
10972
}

consensus/misc/eip1559_test.go

+18-23
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"math/big"
2121
"testing"
2222

23-
"github.com/scroll-tech/go-ethereum/common"
2423
"github.com/scroll-tech/go-ethereum/core/types"
2524
"github.com/scroll-tech/go-ethereum/params"
2625
)
@@ -52,7 +51,8 @@ func copyConfig(original *params.ChainConfig) *params.ChainConfig {
5251

5352
func config() *params.ChainConfig {
5453
config := copyConfig(params.TestChainConfig)
55-
config.LondonBlock = big.NewInt(5)
54+
config.LondonBlock = big.NewInt(3)
55+
config.BanachBlock = big.NewInt(5)
5656
return config
5757
}
5858

@@ -67,13 +67,13 @@ func TestBlockGasLimits(t *testing.T) {
6767
gasLimit uint64
6868
ok bool
6969
}{
70-
// Transitions from non-london to london
71-
{10000000, 4, 20000000, true}, // No change
72-
{10000000, 4, 20019530, true}, // Upper limit
73-
{10000000, 4, 20019531, false}, // Upper +1
74-
{10000000, 4, 19980470, true}, // Lower limit
75-
{10000000, 4, 19980469, false}, // Lower limit -1
76-
// London to London
70+
// Transitions from non-banach to banach
71+
{10000000, 4, 10000000, true}, // No change
72+
{10000000, 4, 10009764, true}, // Upper limit
73+
{10000000, 4, 10009765, false}, // Upper +1
74+
{10000000, 4, 9990236, true}, // Lower limit
75+
{10000000, 4, 9990235, false}, // Lower limit -1
76+
// Banach to Banach
7777
{20000000, 5, 20000000, true},
7878
{20000000, 5, 20019530, true}, // Upper limit
7979
{20000000, 5, 20019531, false}, // Upper limit +1
@@ -109,23 +109,18 @@ func TestBlockGasLimits(t *testing.T) {
109109
// TestCalcBaseFee assumes all blocks are 1559-blocks
110110
func TestCalcBaseFee(t *testing.T) {
111111
tests := []struct {
112-
parentBaseFee int64
113-
parentGasLimit uint64
114-
parentGasUsed uint64
115-
expectedBaseFee int64
112+
parentL1BaseFee int64
113+
expectedL2BaseFee int64
116114
}{
117-
{params.InitialBaseFee, 20000000, 10000000, params.InitialBaseFee}, // usage == target
118-
{params.InitialBaseFee, 20000000, 9000000, 987500000}, // usage below target
119-
{params.InitialBaseFee, 20000000, 11000000, 1012500000}, // usage above target
115+
{0, 150000000},
116+
{1000000000, 164000000},
117+
{2000000000, 178000000},
118+
{100000000000, 1550000000},
119+
{111111111111, 1705555555},
120+
{1000000000000, 10000000000}, // cap at max L2 base fee
120121
}
121122
for i, test := range tests {
122-
parent := &types.Header{
123-
Number: common.Big32,
124-
GasLimit: test.parentGasLimit,
125-
GasUsed: test.parentGasUsed,
126-
BaseFee: big.NewInt(test.parentBaseFee),
127-
}
128-
if have, want := CalcBaseFee(config(), parent), big.NewInt(test.expectedBaseFee); have.Cmp(want) != 0 {
123+
if have, want := CalcBaseFee(config(), nil, big.NewInt(test.parentL1BaseFee)), big.NewInt(test.expectedL2BaseFee); have.Cmp(want) != 0 {
129124
t.Errorf("test %d: have %d want %d, ", i, have, want)
130125
}
131126
}

core/blockchain.go

+9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ var (
5454
headHeaderGauge = metrics.NewRegisteredGauge("chain/head/header", nil)
5555
headFastBlockGauge = metrics.NewRegisteredGauge("chain/head/receipt", nil)
5656

57+
l2BaseFeeGauge = metrics.NewRegisteredGauge("chain/fees/l2basefee", nil)
58+
5759
accountReadTimer = metrics.NewRegisteredTimer("chain/account/reads", nil)
5860
accountHashTimer = metrics.NewRegisteredTimer("chain/account/hashes", nil)
5961
accountUpdateTimer = metrics.NewRegisteredTimer("chain/account/updates", nil)
@@ -1246,6 +1248,13 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
12461248
return NonStatTy, errInsertionInterrupted
12471249
}
12481250

1251+
// Note latest seen L2 base fee
1252+
if block.BaseFee() != nil {
1253+
l2BaseFeeGauge.Update(block.BaseFee().Int64())
1254+
} else {
1255+
l2BaseFeeGauge.Update(0)
1256+
}
1257+
12491258
// Calculate the total difficulty of the block
12501259
ptd := bc.GetTd(block.ParentHash(), block.NumberU64()-1)
12511260
if ptd == nil {

core/blockchain_test.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ func TestFastVsFullChains(t *testing.T) {
607607
gendb = rawdb.NewMemoryDatabase()
608608
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
609609
address = crypto.PubkeyToAddress(key.PublicKey)
610-
funds = big.NewInt(1000000000000000)
610+
funds = big.NewInt(3000000000000000)
611611
gspec = &Genesis{
612612
Config: params.TestChainConfig,
613613
Alloc: GenesisAlloc{address: {Balance: funds}},
@@ -1704,6 +1704,7 @@ func TestInsertReceiptChainRollback(t *testing.T) {
17041704
t.Fatalf("failed to create temp freezer db: %v", err)
17051705
}
17061706
gspec := Genesis{Config: params.AllEthashProtocolChanges}
1707+
gspec.BaseFee = big.NewInt(params.InitialBaseFee)
17071708
gspec.MustCommit(ancientDb)
17081709
ancientChain, _ := NewBlockChain(ancientDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
17091710
defer ancientChain.Stop()
@@ -3171,7 +3172,10 @@ func TestFeeVault(t *testing.T) {
31713172

31723173
// Ensure that the fee vault received all tx fees
31733174
actual = state.GetBalance(*params.TestChainConfig.Scroll.FeeVaultAddress)
3174-
expected = new(big.Int).SetUint64(block.GasUsed() * block.Transactions()[0].GasTipCap().Uint64())
3175+
3176+
effectiveGasPrice := new(big.Int).Add(block.BaseFee(), block.Transactions()[0].GasTipCap())
3177+
gasUsed := new(big.Int).SetUint64(block.GasUsed())
3178+
expected = new(big.Int).Mul(gasUsed, effectiveGasPrice)
31753179

31763180
if actual.Cmp(expected) != 0 {
31773181
t.Fatalf("fee vault balance incorrect: expected %d, got %d", expected, actual)

core/chain_makers.go

+4-6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/scroll-tech/go-ethereum/core/vm"
2929
"github.com/scroll-tech/go-ethereum/ethdb"
3030
"github.com/scroll-tech/go-ethereum/params"
31+
"github.com/scroll-tech/go-ethereum/rollup/fees"
3132
)
3233

3334
// BlockGen creates blocks for testing.
@@ -275,12 +276,9 @@ func makeHeader(chain consensus.ChainReader, parent *types.Block, state *state.S
275276
Number: new(big.Int).Add(parent.Number(), common.Big1),
276277
Time: time,
277278
}
278-
if chain.Config().IsLondon(header.Number) {
279-
header.BaseFee = misc.CalcBaseFee(chain.Config(), parent.Header())
280-
if !chain.Config().IsLondon(parent.Number()) {
281-
parentGasLimit := parent.GasLimit() * params.ElasticityMultiplier
282-
header.GasLimit = CalcGasLimit(parentGasLimit, parentGasLimit)
283-
}
279+
if chain.Config().IsBanach(header.Number) {
280+
parentL1BaseFee := fees.GetL1BaseFee(state)
281+
header.BaseFee = misc.CalcBaseFee(chain.Config(), parent.Header(), parentL1BaseFee)
284282
}
285283
return header
286284
}

core/genesis.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"github.com/scroll-tech/go-ethereum/common"
2929
"github.com/scroll-tech/go-ethereum/common/hexutil"
3030
"github.com/scroll-tech/go-ethereum/common/math"
31+
"github.com/scroll-tech/go-ethereum/consensus/misc"
3132
"github.com/scroll-tech/go-ethereum/core/rawdb"
3233
"github.com/scroll-tech/go-ethereum/core/state"
3334
"github.com/scroll-tech/go-ethereum/core/types"
@@ -312,13 +313,11 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
312313
if g.Difficulty == nil {
313314
head.Difficulty = params.GenesisDifficulty
314315
}
315-
if g.Config != nil && g.Config.IsLondon(common.Big0) {
316+
if g.Config != nil && g.Config.IsBanach(common.Big0) {
316317
if g.BaseFee != nil {
317318
head.BaseFee = g.BaseFee
318-
} else if g.Config.Scroll.BaseFeeEnabled() {
319-
head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)
320319
} else {
321-
head.BaseFee = nil
320+
head.BaseFee = misc.CalcBaseFee(g.Config, nil, big.NewInt(0))
322321
}
323322
}
324323
statedb.Commit(false)

0 commit comments

Comments
 (0)