Skip to content

Commit dbf8815

Browse files
committed
add blob config set for blob fee calc
1 parent 7f2a108 commit dbf8815

File tree

4 files changed

+263
-4
lines changed

4 files changed

+263
-4
lines changed

go-ethereum

Submodule go-ethereum updated 265 files

tx-submitter/services/rollup.go

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import (
1515
"github.com/morph-l2/go-ethereum"
1616
"github.com/morph-l2/go-ethereum/accounts/abi"
1717
"github.com/morph-l2/go-ethereum/common"
18-
"github.com/morph-l2/go-ethereum/consensus/misc/eip4844"
1918
"github.com/morph-l2/go-ethereum/core"
2019
ethtypes "github.com/morph-l2/go-ethereum/core/types"
2120
"github.com/morph-l2/go-ethereum/crypto"
@@ -82,6 +81,8 @@ type Rollup struct {
8281
bm *l1checker.BlockMonitor
8382
eventInfoStorage *event.EventInfoStorage
8483
reorgDetector iface.IReorgDetector
84+
85+
ChainConfigMap types.ChainBlobConfigs
8586
}
8687

8788
func NewRollup(
@@ -126,6 +127,7 @@ func NewRollup(
126127
bm: bm,
127128
eventInfoStorage: eventInfoStorage,
128129
reorgDetector: reorgDetector,
130+
ChainConfigMap: types.ChainConfigMap,
129131
}
130132
return r
131133
}
@@ -298,7 +300,7 @@ func (r *Rollup) ProcessTx() error {
298300
// Helper function to detect reorgs with retry
299301
func (r *Rollup) detectReorgWithRetry() (bool, uint64, error) {
300302
var lastErr error
301-
for i := range 3 { // Try up to 3 times
303+
for i := 0; i < 3; i++ { // Try up to 3 times
302304
hasReorg, depth, err := r.reorgDetector.DetectReorg(r.ctx)
303305
if err == nil {
304306
return hasReorg, depth, nil
@@ -1279,7 +1281,10 @@ func (r *Rollup) GetGasTipAndCap() (*big.Int, *big.Int, *big.Int, error) {
12791281
// calc blob fee cap
12801282
var blobFee *big.Int
12811283
if head.ExcessBlobGas != nil {
1282-
blobFee = eip4844.CalcBlobFee(*head.ExcessBlobGas, params.BlobTxBlobGaspriceUpdateFraction)
1284+
log.Info("market blob fee info", "excess blob gas", *head.ExcessBlobGas)
1285+
blobConfig := r.ChainConfigMap[r.chainId]
1286+
blobFeeDenominator := types.GetBlobFeeDenominator(blobConfig, head.Time)
1287+
blobFee = fakeExponential(types.MinBlobGasPrice, new(big.Int).SetUint64(uint64(*head.ExcessBlobGas)), blobFeeDenominator)
12831288
// Set to 3x to handle blob market congestion
12841289
blobFee = new(big.Int).Mul(blobFee, big.NewInt(3))
12851290
}
@@ -1902,3 +1907,20 @@ func (r *Rollup) CancelTx(tx *ethtypes.Transaction) (*ethtypes.Transaction, erro
19021907

19031908
return newTx, nil
19041909
}
1910+
1911+
// fakeExponential approximates factor * e ** (numerator / denominator) using
1912+
// Taylor expansion.
1913+
func fakeExponential(factor, numerator, denominator *big.Int) *big.Int {
1914+
var (
1915+
output = new(big.Int)
1916+
accum = new(big.Int).Mul(factor, denominator)
1917+
)
1918+
for i := 1; accum.Sign() > 0; i++ {
1919+
output.Add(output, accum)
1920+
1921+
accum.Mul(accum, numerator)
1922+
accum.Div(accum, denominator)
1923+
accum.Div(accum, big.NewInt(int64(i)))
1924+
}
1925+
return output.Div(output, denominator)
1926+
}

tx-submitter/types/blob_config.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package types
2+
3+
import (
4+
"math/big"
5+
6+
"github.com/morph-l2/go-ethereum/log"
7+
)
8+
9+
// BlobFeeConfig is used to configure blob fee calculation parameters.
10+
type BlobFeeConfig struct {
11+
ChainID *big.Int
12+
13+
// LondonBlock is the London block number (used for time determination).
14+
LondonBlock *big.Int
15+
16+
// Timestamps for each EIP upgrade (Unix timestamp, seconds).
17+
CancunTime *uint64 // EIP-4844 (Cancun)
18+
PragueTime *uint64 // Prague
19+
OsakaTime *uint64 // Osaka
20+
BPO1Time *uint64 // BPO1
21+
BPO2Time *uint64 // BPO2
22+
BPO3Time *uint64 // BPO3
23+
BPO4Time *uint64 // BPO4
24+
BPO5Time *uint64 // BPO5
25+
26+
// BlobConfig corresponding to each EIP.
27+
Cancun *BlobConfig
28+
Prague *BlobConfig
29+
Osaka *BlobConfig
30+
BPO1 *BlobConfig
31+
BPO2 *BlobConfig
32+
BPO3 *BlobConfig
33+
BPO4 *BlobConfig
34+
BPO5 *BlobConfig
35+
36+
Default *BlobConfig
37+
}
38+
39+
// BlobConfig contains the parameters required for blob fee calculation.
40+
type BlobConfig struct {
41+
// UpdateFraction is the denominator in the fakeExponential function.
42+
UpdateFraction uint64
43+
}
44+
45+
// Time determination methods (referencing go-ethereum logic).
46+
// IsCancun returns whether time is either equal to the Cancun fork time or greater.
47+
func (c *BlobFeeConfig) IsCancun(num *big.Int, time uint64) bool {
48+
return c.IsLondon(num) && isTimestampForked(c.CancunTime, time)
49+
}
50+
51+
// IsPrague returns whether time is either equal to the Prague fork time or greater.
52+
func (c *BlobFeeConfig) IsPrague(num *big.Int, time uint64) bool {
53+
return c.IsLondon(num) && isTimestampForked(c.PragueTime, time)
54+
}
55+
56+
// IsOsaka returns whether time is either equal to the Osaka fork time or greater.
57+
func (c *BlobFeeConfig) IsOsaka(num *big.Int, time uint64) bool {
58+
return c.IsLondon(num) && isTimestampForked(c.OsakaTime, time)
59+
}
60+
61+
// IsBPO1 returns whether time is either equal to the BPO1 fork time or greater.
62+
func (c *BlobFeeConfig) IsBPO1(num *big.Int, time uint64) bool {
63+
return c.IsLondon(num) && isTimestampForked(c.BPO1Time, time)
64+
}
65+
66+
// IsBPO2 returns whether time is either equal to the BPO2 fork time or greater.
67+
func (c *BlobFeeConfig) IsBPO2(num *big.Int, time uint64) bool {
68+
return c.IsLondon(num) && isTimestampForked(c.BPO2Time, time)
69+
}
70+
71+
// IsBPO3 returns whether time is either equal to the BPO3 fork time or greater.
72+
func (c *BlobFeeConfig) IsBPO3(num *big.Int, time uint64) bool {
73+
return c.IsLondon(num) && isTimestampForked(c.BPO3Time, time)
74+
}
75+
76+
// IsBPO4 returns whether time is either equal to the BPO4 fork time or greater.
77+
func (c *BlobFeeConfig) IsBPO4(num *big.Int, time uint64) bool {
78+
return c.IsLondon(num) && isTimestampForked(c.BPO4Time, time)
79+
}
80+
81+
// IsBPO5 returns whether time is either equal to the BPO5 fork time or greater.
82+
func (c *BlobFeeConfig) IsBPO5(num *big.Int, time uint64) bool {
83+
return c.IsLondon(num) && isTimestampForked(c.BPO5Time, time)
84+
}
85+
86+
// IsLondon returns whether num is either equal to the London fork block or greater.
87+
func (c *BlobFeeConfig) IsLondon(num *big.Int) bool {
88+
return isBlockForked(c.LondonBlock, num)
89+
}
90+
91+
// GetBlobFeeDenominator returns the corresponding UpdateFraction based on the time.
92+
func GetBlobFeeDenominator(blobFeeConfig *BlobFeeConfig, blockTime uint64) *big.Int {
93+
if blobFeeConfig == nil {
94+
// If not configured, use default value.
95+
log.Warn("BlobFeeConfig not set, using default denominator",
96+
"default", DefaultOsakaBlobConfig)
97+
return new(big.Int).SetUint64(DefaultOsakaBlobConfig.UpdateFraction)
98+
}
99+
100+
cfg := blobFeeConfig
101+
londonBlock := cfg.LondonBlock // London block number for fork determination.
102+
103+
// Check in priority order from high to low (BPO5 -> BPO4 -> ... -> Cancun).
104+
var blobConfig *BlobConfig
105+
106+
// Check BPO5
107+
if cfg.BPO5Time != nil && cfg.IsBPO5(londonBlock, blockTime) && cfg.BPO5 != nil {
108+
blobConfig = cfg.BPO5
109+
} else if cfg.BPO4Time != nil && cfg.IsBPO4(londonBlock, blockTime) && cfg.BPO4 != nil {
110+
blobConfig = cfg.BPO4
111+
} else if cfg.BPO3Time != nil && cfg.IsBPO3(londonBlock, blockTime) && cfg.BPO3 != nil {
112+
blobConfig = cfg.BPO3
113+
} else if cfg.BPO2Time != nil && cfg.IsBPO2(londonBlock, blockTime) && cfg.BPO2 != nil {
114+
blobConfig = cfg.BPO2
115+
} else if cfg.BPO1Time != nil && cfg.IsBPO1(londonBlock, blockTime) && cfg.BPO1 != nil {
116+
blobConfig = cfg.BPO1
117+
} else if cfg.OsakaTime != nil && cfg.IsOsaka(londonBlock, blockTime) && cfg.Osaka != nil {
118+
blobConfig = cfg.Osaka
119+
} else if cfg.PragueTime != nil && cfg.IsPrague(londonBlock, blockTime) && cfg.Prague != nil {
120+
blobConfig = cfg.Prague
121+
} else if cfg.CancunTime != nil && cfg.IsCancun(londonBlock, blockTime) && cfg.Cancun != nil {
122+
blobConfig = cfg.Cancun
123+
} else if cfg.Default != nil {
124+
blobConfig = cfg.Default
125+
}
126+
127+
if blobConfig == nil {
128+
log.Warn("No blob config found for current time, using default",
129+
"blockTime", blockTime,
130+
"londonBlock", londonBlock,
131+
"default", DefaultOsakaBlobConfig)
132+
return new(big.Int).SetUint64(DefaultOsakaBlobConfig.UpdateFraction)
133+
}
134+
135+
return new(big.Int).SetUint64(blobConfig.UpdateFraction)
136+
}
137+
138+
// isBlockForked returns whether a fork scheduled at block s is active at the
139+
// given head block. Whilst this method is the same as isTimestampForked, they
140+
// are explicitly separate for clearer reading.
141+
func isBlockForked(s, head *big.Int) bool {
142+
if s == nil || head == nil {
143+
return false
144+
}
145+
return s.Cmp(head) <= 0
146+
}
147+
148+
// isTimestampForked returns whether a fork scheduled at timestamp s is active
149+
// at the given head timestamp. Whilst this method is the same as isBlockForked,
150+
// they are explicitly separate for clearer reading.
151+
func isTimestampForked(s *uint64, head uint64) bool {
152+
if s == nil {
153+
return false
154+
}
155+
return *s <= head
156+
}

tx-submitter/types/blob_params.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package types
2+
3+
import (
4+
"math/big"
5+
6+
"github.com/morph-l2/go-ethereum/params"
7+
)
8+
9+
var (
10+
MinBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice)
11+
12+
ChainConfigMap = ChainBlobConfigs{
13+
big.NewInt(1): MainnetChainConfig,
14+
big.NewInt(560048): HoodiChainConfig,
15+
}
16+
)
17+
18+
func newUint64(val uint64) *uint64 { return &val }
19+
20+
type ChainBlobConfigs map[*big.Int]*BlobFeeConfig
21+
22+
var (
23+
// MainnetChainConfig is the chain parameters to run a node on the main network.
24+
MainnetChainConfig = &BlobFeeConfig{
25+
ChainID: big.NewInt(1),
26+
LondonBlock: big.NewInt(12_965_000),
27+
CancunTime: newUint64(1710338135),
28+
PragueTime: newUint64(1746612311),
29+
Cancun: DefaultCancunBlobConfig,
30+
Prague: DefaultPragueBlobConfig,
31+
Default: DefaultOsakaBlobConfig,
32+
}
33+
34+
// HoodiChainConfig contains the chain parameters to run a node on the Hoodi test network.
35+
HoodiChainConfig = &BlobFeeConfig{
36+
ChainID: big.NewInt(560048),
37+
LondonBlock: big.NewInt(0),
38+
CancunTime: newUint64(0),
39+
PragueTime: newUint64(1742999832),
40+
OsakaTime: newUint64(1761677592),
41+
BPO1Time: newUint64(1762365720),
42+
BPO2Time: newUint64(1762955544),
43+
Cancun: DefaultCancunBlobConfig,
44+
Prague: DefaultPragueBlobConfig,
45+
Osaka: DefaultOsakaBlobConfig,
46+
BPO1: DefaultBPO1BlobConfig,
47+
BPO2: DefaultBPO2BlobConfig,
48+
Default: DefaultOsakaBlobConfig,
49+
}
50+
)
51+
52+
var (
53+
// DefaultCancunBlobConfig is the default blob configuration for the Cancun fork.
54+
DefaultCancunBlobConfig = &BlobConfig{
55+
UpdateFraction: 3338477,
56+
}
57+
// DefaultPragueBlobConfig is the default blob configuration for the Prague fork.
58+
DefaultPragueBlobConfig = &BlobConfig{
59+
UpdateFraction: 5007716,
60+
}
61+
// DefaultOsakaBlobConfig is the default blob configuration for the Osaka fork.
62+
DefaultOsakaBlobConfig = &BlobConfig{
63+
UpdateFraction: 5007716,
64+
}
65+
// DefaultBPO1BlobConfig is the default blob configuration for the BPO1 fork.
66+
DefaultBPO1BlobConfig = &BlobConfig{
67+
UpdateFraction: 8346193,
68+
}
69+
// DefaultBPO2BlobConfig is the default blob configuration for the BPO2 fork.
70+
DefaultBPO2BlobConfig = &BlobConfig{
71+
UpdateFraction: 11684671,
72+
}
73+
// DefaultBPO3BlobConfig is the default blob configuration for the BPO3 fork.
74+
DefaultBPO3BlobConfig = &BlobConfig{
75+
UpdateFraction: 20609697,
76+
}
77+
// DefaultBPO4BlobConfig is the default blob configuration for the BPO4 fork.
78+
DefaultBPO4BlobConfig = &BlobConfig{
79+
UpdateFraction: 13739630,
80+
}
81+
)

0 commit comments

Comments
 (0)