Skip to content

Commit 036f4c0

Browse files
committed
Update L2 base fee calculation to account for Feynman
1 parent cdd77c1 commit 036f4c0

File tree

6 files changed

+91
-5
lines changed

6 files changed

+91
-5
lines changed

consensus/misc/eip1559.go

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,66 @@ func CalcBaseFee(config *params.ChainConfig, parent *types.Header, parentL1BaseF
108108
}
109109

110110
scalar, overhead := ReadL2BaseFeeCoefficients()
111-
return calcBaseFee(scalar, overhead, parentL1BaseFee)
111+
if !config.IsFeynman(big.NewInt(0).Add(parent.Number, common.Big1)) {
112+
return calcBaseFee(scalar, overhead, parentL1BaseFee)
113+
}
114+
baseFeeEIP1559 := calcBaseFeeEIP1559(config, parent, scalar, overhead)
115+
return calcBaseFee(scalar, overhead, baseFeeEIP1559)
116+
}
117+
118+
// CalcBaseFee calculates the basefee of the header.
119+
func calcBaseFeeEIP1559(config *params.ChainConfig, parent *types.Header, scalar *big.Int, overhead *big.Int) *big.Int {
120+
// If the current block is the first EIP-1559 block, return the InitialBaseFee.
121+
if !config.IsFeynman(parent.Number) {
122+
return new(big.Int).SetUint64(params.InitialBaseFee)
123+
}
124+
125+
parentBaseFeeEIP1559 := extractBaseFeeEIP1559(parent.BaseFee, scalar, overhead)
126+
parentGasTarget := parent.GasLimit / config.ElasticityMultiplier()
127+
// If the parent gasUsed is the same as the target, the baseFee remains unchanged.
128+
if parent.GasUsed == parentGasTarget {
129+
return new(big.Int).Set(parentBaseFeeEIP1559)
130+
}
131+
132+
var (
133+
num = new(big.Int)
134+
denom = new(big.Int)
135+
)
136+
137+
if parent.GasUsed > parentGasTarget {
138+
// If the parent block used more gas than its target, the baseFee should increase.
139+
// max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
140+
num.SetUint64(parent.GasUsed - parentGasTarget)
141+
num.Mul(num, parentBaseFeeEIP1559)
142+
num.Div(num, denom.SetUint64(parentGasTarget))
143+
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
144+
if num.Cmp(common.Big1) < 0 {
145+
return num.Add(parentBaseFeeEIP1559, common.Big1)
146+
}
147+
return num.Add(parentBaseFeeEIP1559, num)
148+
} else {
149+
// Otherwise if the parent block used less gas than its target, the baseFee should decrease.
150+
// max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
151+
num.SetUint64(parentGasTarget - parent.GasUsed)
152+
num.Mul(num, parentBaseFeeEIP1559)
153+
num.Div(num, denom.SetUint64(parentGasTarget))
154+
num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
155+
156+
baseFee := num.Sub(parentBaseFeeEIP1559, num)
157+
if baseFee.Cmp(common.Big0) < 0 {
158+
baseFee = common.Big0
159+
}
160+
return baseFee
161+
}
162+
}
163+
164+
func extractBaseFeeEIP1559(baseFee *big.Int, scalar *big.Int, overhead *big.Int) *big.Int {
165+
baseFeeEIP := new(big.Int).Set(baseFee)
166+
baseFeeEIP.Sub(baseFeeEIP, overhead)
167+
baseFeeEIP.Mul(baseFeeEIP, BaseFeePrecision)
168+
baseFeeEIP.Div(baseFeeEIP, scalar)
169+
170+
return baseFeeEIP
112171
}
113172

114173
// MinBaseFee calculates the minimum L2 base fee based on the current coefficients.

params/config.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -988,6 +988,11 @@ func (c *ChainConfig) IsEuclidV2(now uint64) bool {
988988
return isForkedTime(now, c.EuclidV2Time)
989989
}
990990

991+
// IsFeynman returns whether time is either equal to the Feyman fork time or greater.
992+
func (c *ChainConfig) IsFeynman(num *big.Int) bool {
993+
return false // placeholder
994+
}
995+
991996
// IsTerminalPoWBlock returns whether the given block is the last block of PoW stage.
992997
func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *big.Int) bool {
993998
if c.TerminalTotalDifficulty == nil {
@@ -1014,6 +1019,16 @@ func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *Confi
10141019
return lasterr
10151020
}
10161021

1022+
// BaseFeeChangeDenominator bounds the amount the base fee can change between blocks.
1023+
func (c *ChainConfig) BaseFeeChangeDenominator() uint64 {
1024+
return DefaultBaseFeeChangeDenominator
1025+
}
1026+
1027+
// ElasticityMultiplier bounds the maximum gas limit an EIP-1559 block may have.
1028+
func (c *ChainConfig) ElasticityMultiplier() uint64 {
1029+
return DefaultElasticityMultiplier
1030+
}
1031+
10171032
// CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
10181033
// to guarantee that forks can be implemented in a different order than on official networks
10191034
func (c *ChainConfig) CheckConfigForkOrder() error {

params/protocol_params.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,9 @@ const (
121121
// Introduced in Tangerine Whistle (Eip 150)
122122
CreateBySelfdestructGas uint64 = 25000
123123

124-
BaseFeeChangeDenominator = 8 // Bounds the amount the base fee can change between blocks.
125-
ElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have.
126-
InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks.
124+
DefaultBaseFeeChangeDenominator = 8 // Bounds the amount the base fee can change between blocks.
125+
DefaultElasticityMultiplier = 2 // Bounds the maximum gas limit an EIP-1559 block may have.
126+
InitialBaseFee = 1000000000 // Initial base fee for EIP-1559 blocks.
127127

128128
MaxCodeSize = 24576 // Maximum bytecode to permit for a contract
129129
MaxInitCodeSize = 2 * MaxCodeSize // Maximum initcode to permit in a creation transaction and create instructions

params/version.go

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

rollup/da_syncer/blob_client/blob_scan_client.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ func (c *BlobScanClient) GetBlobByVersionedHashAndBlockTime(ctx context.Context,
6464
if err != nil {
6565
return nil, fmt.Errorf("failed to decode result into struct, err: %w", err)
6666
}
67+
68+
// check that blob data is not empty
69+
if len(result.Data) < 2 {
70+
return nil, fmt.Errorf("blob data is too short to be valid, expected at least 2 characters, got: %s, versioned hash: %s", result.Data, versionedHash.String())
71+
}
72+
6773
blobBytes, err := hex.DecodeString(result.Data[2:])
6874
if err != nil {
6975
return nil, fmt.Errorf("failed to decode data to bytes, err: %w", err)

rollup/da_syncer/blob_client/block_native_client.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ func (c *BlockNativeClient) GetBlobByVersionedHashAndBlockTime(ctx context.Conte
5959
if err != nil {
6060
return nil, fmt.Errorf("failed to decode result into struct, err: %w", err)
6161
}
62+
63+
// check that blob data is not empty
64+
if len(result.Blob.Data) < 2 {
65+
return nil, fmt.Errorf("blob data is too short to be valid, expected at least 2 characters, got: %s, versioned hash: %s", result.Blob.Data, versionedHash.String())
66+
}
67+
6268
blobBytes, err := hex.DecodeString(result.Blob.Data[2:])
6369
if err != nil {
6470
return nil, fmt.Errorf("failed to decode data to bytes, err: %w", err)

0 commit comments

Comments
 (0)