From 4574b4bb59c2d06a14a71a0ef5f15b0c2e3e8356 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Thu, 15 May 2025 14:46:35 +0200 Subject: [PATCH 01/13] Revert "Revert "EIP-7892: Blob Parameter Only Hardforks (#14843)" (#14912)" This reverts commit 3035271086fc6fce11184e61961c7a025a64020a. --- cmd/devnet/networks/devnet_bor.go | 6 +- cmd/integration/commands/stages.go | 14 +- cmd/integration/commands/state_stages.go | 2 +- core/block_validator_test.go | 4 +- core/genesis_write.go | 4 +- erigon-lib/chain/chain_config.go | 182 +++++++++--------- erigon-lib/chain/chain_config_test.go | 176 +++++++++++++++-- erigon-lib/chain/params/protocol.go | 27 +++ erigon-lib/common/collections.go | 13 ++ eth/backend.go | 18 +- eth/stagedsync/chain_reader.go | 4 +- eth/stagedsync/stage_bodies.go | 4 +- eth/stagedsync/stage_bor_heimdall.go | 4 +- eth/stagedsync/stage_headers.go | 6 +- eth/stagedsync/stage_mining_create_block.go | 8 +- eth/stagedsync/stage_mining_exec.go | 24 +-- eth/stagedsync/stage_mining_finish.go | 4 +- eth/stagedsync/stage_snapshots.go | 8 +- .../stagedsynctest/chain_configs.go | 5 +- eth/stagedsync/stagedsynctest/harness.go | 2 +- execution/consensus/clique/snapshot_test.go | 7 +- execution/consensus/misc/eip1559_test.go | 5 +- go.mod | 1 + go.sum | 2 + params/config.go | 3 +- params/config_test.go | 45 +++-- polygon/bor/borcfg/bor_config.go | 8 +- tests/init_test.go | 15 +- turbo/snapshotsync/freezeblocks/dump_test.go | 13 +- turbo/stages/mock/mock_sentry.go | 18 +- turbo/stages/stageloop.go | 22 +-- .../block_building_integration_test.go | 5 +- txnprovider/txpool/assemble.go | 3 +- txnprovider/txpool/pool.go | 19 +- txnprovider/txpool/pool_fuzz_test.go | 5 +- txnprovider/txpool/pool_test.go | 41 ++-- 36 files changed, 459 insertions(+), 268 deletions(-) diff --git a/cmd/devnet/networks/devnet_bor.go b/cmd/devnet/networks/devnet_bor.go index 4b4ee85f50e..206c5adc27c 100644 --- a/cmd/devnet/networks/devnet_bor.go +++ b/cmd/devnet/networks/devnet_bor.go @@ -20,6 +20,9 @@ import ( "strconv" "time" + "github.com/jinzhu/copier" + + "github.com/erigontech/erigon-lib/chain" "github.com/erigontech/erigon-lib/chain/networkname" "github.com/erigontech/erigon-lib/log/v3" "github.com/erigontech/erigon-lib/types" @@ -230,7 +233,8 @@ func NewBorDevnetWithLocalHeimdall( consoleLogLevel log.Lvl, dirLogLevel log.Lvl, ) devnet.Devnet { - config := *params.BorDevnetChainConfig + var config chain.Config + copier.Copy(&config, params.BorDevnetChainConfig) borConfig := config.Bor.(*borcfg.BorConfig) if sprintSize > 0 { borConfig.Sprint = map[string]uint64{"0": sprintSize} diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 2c4a1bd94ba..1eb4f024bc1 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -771,7 +771,7 @@ func stageBorHeimdall(db kv.TemporalRwDB, ctx context.Context, unwindTypes []str } unwindState := sync.NewUnwindState(stages.BorHeimdall, stageState.BlockNumber-unwind, stageState.BlockNumber, true, false) - cfg := stagedsync.StageBorHeimdallCfg(db, nil, miningState, *chainConfig, nil, heimdallStore, bridgeStore, nil, nil, nil, nil, nil, false, unwindTypes) + cfg := stagedsync.StageBorHeimdallCfg(db, nil, miningState, chainConfig, nil, heimdallStore, bridgeStore, nil, nil, nil, nil, nil, false, unwindTypes) if err := stagedsync.BorHeimdallUnwind(unwindState, ctx, stageState, nil, cfg); err != nil { return err } @@ -800,7 +800,7 @@ func stageBorHeimdall(db kv.TemporalRwDB, ctx context.Context, unwindTypes []str recents = bor.Recents signatures = bor.Signatures } - cfg := stagedsync.StageBorHeimdallCfg(db, snapDb, miningState, *chainConfig, heimdallClient, heimdallStore, bridgeStore, blockReader, nil, nil, recents, signatures, false, unwindTypes) + cfg := stagedsync.StageBorHeimdallCfg(db, snapDb, miningState, chainConfig, heimdallClient, heimdallStore, bridgeStore, blockReader, nil, nil, recents, signatures, false, unwindTypes) stageState := stage(sync, nil, db, stages.BorHeimdall) if err := stagedsync.BorHeimdallForward(stageState, sync, ctx, nil, cfg, logger); err != nil { @@ -830,7 +830,7 @@ func stageBodies(db kv.TemporalRwDB, ctx context.Context, logger log.Logger) err } u := sync.NewUnwindState(stages.Bodies, s.BlockNumber-unwind, s.BlockNumber, true, false) - cfg := stagedsync.StageBodiesCfg(db, nil, nil, nil, nil, 0, *chainConfig, br, bw) + cfg := stagedsync.StageBodiesCfg(db, nil, nil, nil, nil, 0, chainConfig, br, bw) if err := stagedsync.UnwindBodiesStage(u, tx, cfg, ctx); err != nil { return err } @@ -1506,8 +1506,8 @@ func newSync(ctx context.Context, db kv.TemporalRwDB, miningConfig *params.Minin miningSync := stagedsync.New( cfg.Sync, stagedsync.MiningStages(ctx, - stagedsync.StageMiningCreateBlockCfg(db, miner, *chainConfig, engine, nil, dirs.Tmp, blockReader), - stagedsync.StageBorHeimdallCfg(db, snapDb, miner, *chainConfig, heimdallClient, heimdallStore, bridgeStore, blockReader, nil, nil, recents, signatures, false, unwindTypes), + stagedsync.StageMiningCreateBlockCfg(db, miner, chainConfig, engine, nil, dirs.Tmp, blockReader), + stagedsync.StageBorHeimdallCfg(db, snapDb, miner, chainConfig, heimdallClient, heimdallStore, bridgeStore, blockReader, nil, nil, recents, signatures, false, unwindTypes), stagedsync.StageExecuteBlocksCfg( db, cfg.Prune, @@ -1526,8 +1526,8 @@ func newSync(ctx context.Context, db kv.TemporalRwDB, miningConfig *params.Minin nil, ), stagedsync.StageSendersCfg(db, sentryControlServer.ChainConfig, cfg.Sync, false, dirs.Tmp, cfg.Prune, blockReader, sentryControlServer.Hd), - stagedsync.StageMiningExecCfg(db, miner, events, *chainConfig, engine, &vm.Config{}, dirs.Tmp, nil, 0, nil, blockReader), - stagedsync.StageMiningFinishCfg(db, *chainConfig, engine, miner, miningCancel, blockReader, builder.NewLatestBlockBuiltStore()), + stagedsync.StageMiningExecCfg(db, miner, events, chainConfig, engine, &vm.Config{}, dirs.Tmp, nil, 0, nil, blockReader), + stagedsync.StageMiningFinishCfg(db, chainConfig, engine, miner, miningCancel, blockReader, builder.NewLatestBlockBuiltStore()), false, ), stagedsync.MiningUnwindOrder, diff --git a/cmd/integration/commands/state_stages.go b/cmd/integration/commands/state_stages.go index 1f51a43dcaf..446ab750bb2 100644 --- a/cmd/integration/commands/state_stages.go +++ b/cmd/integration/commands/state_stages.go @@ -305,7 +305,7 @@ func syncBySmallSteps(db kv.TemporalRwDB, miningConfig params.MiningConfig, ctx miner.MiningConfig.ExtraData = nextBlock.Extra() miningStages.MockExecFunc(stages.MiningCreateBlock, func(badBlockUnwind bool, s *stagedsync.StageState, u stagedsync.Unwinder, txc wrap.TxContainer, logger log.Logger) error { err = stagedsync.SpawnMiningCreateBlockStage(s, txc, - stagedsync.StageMiningCreateBlockCfg(db, miner, *chainConfig, engine, nil, dirs.Tmp, br), + stagedsync.StageMiningCreateBlockCfg(db, miner, chainConfig, engine, nil, dirs.Tmp, br), quit, logger) if err != nil { return err diff --git a/core/block_validator_test.go b/core/block_validator_test.go index 64146b41420..1a3b261cf7a 100644 --- a/core/block_validator_test.go +++ b/core/block_validator_test.go @@ -56,7 +56,7 @@ func TestHeaderVerification(t *testing.T) { if err := m.DB.View(context.Background(), func(tx kv.Tx) error { for j, valid := range []bool{true, false} { chainReader := stagedsync.ChainReader{ - Cfg: *libchain.TestChainConfig, + Cfg: libchain.TestChainConfig, Db: tx, BlockReader: m.BlockReader, Logger: logger, @@ -106,7 +106,7 @@ func TestHeaderWithSealVerification(t *testing.T) { if err := m.DB.View(context.Background(), func(tx kv.Tx) error { for j, valid := range []bool{true, false} { chainReader := stagedsync.ChainReader{ - Cfg: *libchain.TestChainAuraConfig, + Cfg: libchain.TestChainAuraConfig, Db: tx, BlockReader: m.BlockReader, Logger: logger, diff --git a/core/genesis_write.go b/core/genesis_write.go index 680bc55ba79..2648f3f58c7 100644 --- a/core/genesis_write.go +++ b/core/genesis_write.go @@ -31,6 +31,7 @@ import ( "github.com/c2h5oh/datasize" "github.com/holiman/uint256" + "github.com/jinzhu/copier" "golang.org/x/sync/errgroup" "github.com/erigontech/erigon-db/rawdb" @@ -448,7 +449,8 @@ var DevnetSignKey = func(address common.Address) *ecdsa.PrivateKey { // DeveloperGenesisBlock returns the 'geth --dev' genesis block. func DeveloperGenesisBlock(period uint64, faucet common.Address) *types.Genesis { // Override the default period to the user requested one - config := *params2.AllCliqueProtocolChanges + var config chain.Config + copier.Copy(&config, params2.AllCliqueProtocolChanges) config.Clique.Period = period // Assemble and return the genesis with the precompiles and faucet pre-funded diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 803597ac276..6140f58c1c7 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -21,10 +21,12 @@ import ( "fmt" "math/big" "strconv" + "sync" "time" "github.com/erigontech/erigon-lib/chain/params" "github.com/erigontech/erigon-lib/common" + "github.com/erigontech/erigon-lib/common/generics" ) // Config is the core config which determines the blockchain settings. @@ -32,6 +34,8 @@ import ( // Config is stored in the database on a per block basis. This means // that any network, identified by its genesis block, can have its own // set of configuration options. +// +// Config must be copied only with jinzhu/copier since it contains a sync.Once. type Config struct { ChainName string `json:"chainName"` // chain name, eg: mainnet, sepolia, bor-mainnet ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection @@ -70,9 +74,11 @@ type Config struct { PragueTime *big.Int `json:"pragueTime,omitempty"` OsakaTime *big.Int `json:"osakaTime,omitempty"` - // Optional EIP-4844 parameters (see also EIP-7691 & EIP-7840) - MinBlobGasPrice *uint64 `json:"minBlobGasPrice,omitempty"` - BlobSchedule *BlobSchedule `json:"blobSchedule,omitempty"` + // Optional EIP-4844 parameters (see also EIP-7691, EIP-7840, EIP-7892) + MinBlobGasPrice *uint64 `json:"minBlobGasPrice,omitempty"` + BlobSchedule map[string]*params.BlobConfig `json:"blobSchedule,omitempty"` + parseBlobScheduleOnce sync.Once `copier:"-"` + parsedBlobSchedule map[uint64]*params.BlobConfig // (Optional) governance contract where EIP-1559 fees will be sent to, which otherwise would be burnt since the London fork. // A key corresponds to the block number, starting from which the fees are sent to the address (map value). @@ -112,6 +118,26 @@ var ( Ethash: new(EthashConfig), } + TestChainConfigCancun = &Config{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + TangerineWhistleBlock: big.NewInt(0), + SpuriousDragonBlock: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + GrayGlacierBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + TerminalTotalDifficultyPassed: true, + ShanghaiTime: big.NewInt(0), + CancunTime: big.NewInt(0), + } + TestChainAuraConfig = &Config{ ChainID: big.NewInt(1), Consensus: AuRaConsensus, @@ -129,57 +155,6 @@ var ( } ) -type BlobConfig struct { - Target *uint64 `json:"target,omitempty"` - Max *uint64 `json:"max,omitempty"` - BaseFeeUpdateFraction *uint64 `json:"baseFeeUpdateFraction,omitempty"` -} - -// See EIP-7840: Add blob schedule to EL config files -type BlobSchedule struct { - Cancun *BlobConfig `json:"cancun,omitempty"` - Prague *BlobConfig `json:"prague,omitempty"` -} - -func (b *BlobSchedule) TargetBlobsPerBlock(isPrague bool) uint64 { - if isPrague { - if b != nil && b.Prague != nil && b.Prague.Target != nil { - return *b.Prague.Target - } - return 6 // EIP-7691 - } - if b != nil && b.Cancun != nil && b.Cancun.Target != nil { - return *b.Cancun.Target - } - return 3 // EIP-4844 -} - -func (b *BlobSchedule) MaxBlobsPerBlock(isPrague bool) uint64 { - if isPrague { - if b != nil && b.Prague != nil && b.Prague.Max != nil { - return *b.Prague.Max - } - return 9 // EIP-7691 - } - if b != nil && b.Cancun != nil && b.Cancun.Max != nil { - return *b.Cancun.Max - } - return 6 // EIP-4844 -} - -func (b *BlobSchedule) BaseFeeUpdateFraction(isPrague bool) uint64 { - if isPrague { - if b != nil && b.Prague != nil && b.Prague.BaseFeeUpdateFraction != nil { - return *b.Prague.BaseFeeUpdateFraction - } - return 5007716 // EIP-7691 - } - if b != nil && b.Cancun != nil && b.Cancun.BaseFeeUpdateFraction != nil { - return *b.Cancun.BaseFeeUpdateFraction - } - return 3338477 // EIP-4844 -} - type BorConfig interface { fmt.Stringer IsAgra(num uint64) bool @@ -344,7 +319,7 @@ func (c *Config) GetBurntContract(num uint64) *common.Address { if len(c.BurntContract) == 0 { return nil } - addr := ConfigValueLookup(c.BurntContract, num) + addr := ConfigValueLookup(common.ParseMapKeysIntoUint64(c.BurntContract), num) return &addr } @@ -355,32 +330,64 @@ func (c *Config) GetMinBlobGasPrice() uint64 { return 1 // MIN_BLOB_GASPRICE (EIP-4844) } -func (c *Config) GetMaxBlobGasPerBlock(t uint64) uint64 { - return c.GetMaxBlobsPerBlock(t) * params.BlobGasPerBlob +func (c *Config) getBlobConfig(time uint64) *params.BlobConfig { + c.parseBlobScheduleOnce.Do(func() { + // Populate with default values + c.parsedBlobSchedule = map[uint64]*params.BlobConfig{ + 0: {}, + } + if c.CancunTime != nil { + c.parsedBlobSchedule[c.CancunTime.Uint64()] = ¶ms.DefaultCancunBlobConfig + } + if c.PragueTime != nil { + c.parsedBlobSchedule[c.PragueTime.Uint64()] = ¶ms.DefaultPragueBlobConfig + } + if c.OsakaTime != nil { + c.parsedBlobSchedule[c.OsakaTime.Uint64()] = ¶ms.DefaultOsakaBlobConfig + } + + // Override with supplied values + for key, val := range c.BlobSchedule { + switch { + case key == "cancun": + if c.CancunTime != nil { + c.parsedBlobSchedule[c.CancunTime.Uint64()] = val + } + case key == "prague": + if c.PragueTime != nil { + c.parsedBlobSchedule[c.PragueTime.Uint64()] = val + } + case key == "osaka": + if c.OsakaTime != nil { + c.parsedBlobSchedule[c.OsakaTime.Uint64()] = val + } + default: + keyU64, err := strconv.ParseUint(key, 10, 64) + if err != nil { + panic(err) + } + c.parsedBlobSchedule[keyU64] = val + } + } + }) + + return ConfigValueLookup(c.parsedBlobSchedule, time) } func (c *Config) GetMaxBlobsPerBlock(time uint64) uint64 { - var b *BlobSchedule - if c != nil { - b = c.BlobSchedule - } - return b.MaxBlobsPerBlock(c.IsPrague(time)) + return c.getBlobConfig(time).Max } -func (c *Config) GetTargetBlobGasPerBlock(t uint64) uint64 { - var b *BlobSchedule - if c != nil { - b = c.BlobSchedule - } - return b.TargetBlobsPerBlock(c.IsPrague(t)) * params.BlobGasPerBlob +func (c *Config) GetMaxBlobGasPerBlock(time uint64) uint64 { + return c.getBlobConfig(time).Max * params.BlobGasPerBlob } -func (c *Config) GetBlobGasPriceUpdateFraction(t uint64) uint64 { - var b *BlobSchedule - if c != nil { - b = c.BlobSchedule - } - return b.BaseFeeUpdateFraction(c.IsPrague(t)) +func (c *Config) GetTargetBlobGasPerBlock(time uint64) uint64 { + return c.getBlobConfig(time).Target * params.BlobGasPerBlob +} + +func (c *Config) GetBlobGasPriceUpdateFraction(time uint64) uint64 { + return c.getBlobConfig(time).BaseFeeUpdateFraction } func (c *Config) SecondsPerSlot() uint64 { @@ -588,28 +595,21 @@ func (c *CliqueConfig) String() string { // Looks up a config value as of a given block number (or time). // The assumption here is that config is a càdlàg map of starting_from_block -> value. -// For example, config of {"0": "0xA", "10": "0xB", "20": "0xC"} -// means that the config value is 0xA for blocks 0–9, -// 0xB for blocks 10–19, and 0xC for block 20 and above. -func ConfigValueLookup[T uint64 | common.Address](field map[string]T, number uint64) T { - fieldUint := make(map[uint64]T) - for k, v := range field { - keyUint, err := strconv.ParseUint(k, 10, 64) - if err != nil { - panic(err) - } - fieldUint[keyUint] = v +// For example, config of {5: "A", 10: "B", 20: "C"} +// means that the config value is "A" for blocks 5–9, +// "B" for blocks 10–19, and "C" for block 20 and above. +// For blocks 0–4 an empty string will be returned. +func ConfigValueLookup[T any](field map[uint64]T, number uint64) T { + keys := common.SortedKeys(field) + if number < keys[0] { + return generics.Zero[T]() } - - keys := common.SortedKeys(fieldUint) - for i := 0; i < len(keys)-1; i++ { if number >= keys[i] && number < keys[i+1] { - return fieldUint[keys[i]] + return field[keys[i]] } } - - return fieldUint[keys[len(keys)-1]] + return field[keys[len(keys)-1]] } // Rules is syntactic sugar over Config. It can be used for functions diff --git a/erigon-lib/chain/chain_config_test.go b/erigon-lib/chain/chain_config_test.go index 7bf3bf11274..b3b75820c92 100644 --- a/erigon-lib/chain/chain_config_test.go +++ b/erigon-lib/chain/chain_config_test.go @@ -17,18 +17,35 @@ package chain import ( + "math/big" + "strconv" "testing" "github.com/stretchr/testify/assert" + "github.com/erigontech/erigon-lib/chain/params" "github.com/erigontech/erigon-lib/common" ) func TestConfigValueLookup(t *testing.T) { - backupMultiplier := map[string]uint64{ - "0": 2, - "25275000": 5, - "29638656": 2, + foo := map[uint64]string{5: "A", 10: "B", 20: "C"} + assert.Equal(t, "", ConfigValueLookup(foo, 0)) + assert.Equal(t, "", ConfigValueLookup(foo, 4)) + assert.Equal(t, "A", ConfigValueLookup(foo, 5)) + assert.Equal(t, "A", ConfigValueLookup(foo, 9)) + assert.Equal(t, "B", ConfigValueLookup(foo, 10)) + assert.Equal(t, "B", ConfigValueLookup(foo, 11)) + assert.Equal(t, "B", ConfigValueLookup(foo, 15)) + assert.Equal(t, "B", ConfigValueLookup(foo, 19)) + assert.Equal(t, "C", ConfigValueLookup(foo, 20)) + assert.Equal(t, "C", ConfigValueLookup(foo, 21)) + assert.Equal(t, "C", ConfigValueLookup(foo, 100)) + assert.Equal(t, "C", ConfigValueLookup(foo, 1_000_000_000_000)) + + backupMultiplier := map[uint64]uint64{ + 0: 2, + 25275000: 5, + 29638656: 2, } assert.Equal(t, uint64(2), ConfigValueLookup(backupMultiplier, 0)) assert.Equal(t, uint64(2), ConfigValueLookup(backupMultiplier, 1)) @@ -39,10 +56,10 @@ func TestConfigValueLookup(t *testing.T) { assert.Equal(t, uint64(2), ConfigValueLookup(backupMultiplier, 29638656)) assert.Equal(t, uint64(2), ConfigValueLookup(backupMultiplier, 29638656+1)) - config := map[string]uint64{ - "0": 1, - "90000000": 2, - "100000000": 3, + config := map[uint64]uint64{ + 0: 1, + 90000000: 2, + 100000000: 3, } assert.Equal(t, uint64(1), ConfigValueLookup(config, 0)) assert.Equal(t, uint64(1), ConfigValueLookup(config, 1)) @@ -56,10 +73,11 @@ func TestConfigValueLookup(t *testing.T) { address1 := common.HexToAddress("0x70bcA57F4579f58670aB2d18Ef16e02C17553C38") address2 := common.HexToAddress("0x617b94CCCC2511808A3C9478ebb96f455CF167aA") - burntContract := map[string]common.Address{ - "22640000": address1, - "41874000": address2, + burntContract := map[uint64]common.Address{ + 22640000: address1, + 41874000: address2, } + assert.Equal(t, common.Address{}, ConfigValueLookup(burntContract, 10000000)) assert.Equal(t, address1, ConfigValueLookup(burntContract, 22640000)) assert.Equal(t, address1, ConfigValueLookup(burntContract, 22640000+1)) assert.Equal(t, address1, ConfigValueLookup(burntContract, 41874000-1)) @@ -68,17 +86,135 @@ func TestConfigValueLookup(t *testing.T) { } func TestNilBlobSchedule(t *testing.T) { - var b *BlobSchedule + var c Config + c.CancunTime = big.NewInt(1) + c.PragueTime = big.NewInt(2) + + // Everything should be 0 before Cancun + assert.Equal(t, uint64(0), c.GetTargetBlobGasPerBlock(0)) + assert.Equal(t, uint64(0), c.GetMaxBlobsPerBlock(0)) + assert.Equal(t, uint64(0), c.GetBlobGasPriceUpdateFraction(0)) // Original EIP-4844 values - isPrague := false - assert.Equal(t, uint64(3), b.TargetBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(6), b.MaxBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(3338477), b.BaseFeeUpdateFraction(isPrague)) + assert.Equal(t, 3*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(1)) + assert.Equal(t, uint64(6), c.GetMaxBlobsPerBlock(1)) + assert.Equal(t, uint64(3338477), c.GetBlobGasPriceUpdateFraction(1)) // EIP-7691: Blob throughput increase - isPrague = true - assert.Equal(t, uint64(6), b.TargetBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(9), b.MaxBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(5007716), b.BaseFeeUpdateFraction(isPrague)) + assert.Equal(t, 6*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(2)) + assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(2)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(2)) +} + +// EIP-7892 +func TestBlobParameterOnlyHardforks(t *testing.T) { + cancunTime := uint64(1710338135) + pragueTime := uint64(1746612311) + timeA := uint64(1775065900) + timeB := uint64(1785952240) + + var c Config + c.CancunTime = big.NewInt(int64(cancunTime)) + c.PragueTime = big.NewInt(int64(pragueTime)) + + c.BlobSchedule = map[string]*params.BlobConfig{ + "cancun": { + Target: 3, + Max: 6, + BaseFeeUpdateFraction: 3338477, + }, + "prague": { + Target: 6, + Max: 9, + BaseFeeUpdateFraction: 5007716, + }, + strconv.FormatUint(timeA, 10): { + Target: 24, + Max: 48, + BaseFeeUpdateFraction: 5007716, + }, + strconv.FormatUint(timeB, 10): { + Target: 36, + Max: 56, + BaseFeeUpdateFraction: 5007716, + }, + } + + time := uint64(0) + assert.Equal(t, uint64(0), c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(0), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(0), c.GetBlobGasPriceUpdateFraction(time)) + + time = cancunTime + assert.Equal(t, 3*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(6), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(3338477), c.GetBlobGasPriceUpdateFraction(time)) + + time = (cancunTime + pragueTime) / 2 + assert.Equal(t, 3*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(6), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(3338477), c.GetBlobGasPriceUpdateFraction(time)) + + time = pragueTime + assert.Equal(t, 6*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) + + time = (pragueTime + timeA) / 2 + assert.Equal(t, 6*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) + + time = timeA + assert.Equal(t, 24*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(48), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) + + time = (timeA + timeB) / 2 + assert.Equal(t, 24*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(48), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) + + time = timeB + assert.Equal(t, 36*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(56), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) + + time = timeB * 2 + assert.Equal(t, 36*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(56), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) +} + +func TestBlobParameterInactiveHardfork(t *testing.T) { + cancunTime := uint64(1710338135) + pragueTime := uint64(1746612311) + + var c Config + c.CancunTime = big.NewInt(int64(cancunTime)) + c.PragueTime = big.NewInt(int64(pragueTime)) + // Osaka is not activated yet + + c.BlobSchedule = map[string]*params.BlobConfig{ + "cancun": { + Target: 3, + Max: 6, + BaseFeeUpdateFraction: 3338477, + }, + "prague": { + Target: 6, + Max: 9, + BaseFeeUpdateFraction: 5007716, + }, + "osaka": { + Target: 12, + Max: 24, + BaseFeeUpdateFraction: 3338477, + }, + } + + time := pragueTime * 2 + assert.Equal(t, 6*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) } diff --git a/erigon-lib/chain/params/protocol.go b/erigon-lib/chain/params/protocol.go index 890cc14b64f..6c68f0b0f5f 100644 --- a/erigon-lib/chain/params/protocol.go +++ b/erigon-lib/chain/params/protocol.go @@ -219,3 +219,30 @@ var ( MinimumDifficulty = big.NewInt(131072) // The minimum that the difficulty may ever be. DurationLimit = big.NewInt(13) // The decision boundary on the blocktime duration used to determine whether difficulty should go up or not. ) + +// See EIP-7840: Add blob schedule to EL config files +// and EIP-7892: Blob Parameter Only Hardforks +type BlobConfig struct { + Target uint64 `json:"target"` + Max uint64 `json:"max"` + BaseFeeUpdateFraction uint64 `json:"baseFeeUpdateFraction"` +} + +var DefaultCancunBlobConfig = BlobConfig{ + Target: 3, + Max: 6, + BaseFeeUpdateFraction: 3338477, +} + +var DefaultPragueBlobConfig = BlobConfig{ + Target: 6, + Max: 9, + BaseFeeUpdateFraction: 5007716, +} + +// TODO(yperbasis): update when Fusaka's blob config is decided +var DefaultOsakaBlobConfig = BlobConfig{ + Target: 6, + Max: 9, + BaseFeeUpdateFraction: 5007716, +} diff --git a/erigon-lib/common/collections.go b/erigon-lib/common/collections.go index 77d0a04b8d3..d1289d5540d 100644 --- a/erigon-lib/common/collections.go +++ b/erigon-lib/common/collections.go @@ -18,6 +18,7 @@ package common import ( "math/rand" + "strconv" ) func SliceMap[T any, U any](s []T, mapFunc func(T) U) []U { @@ -41,3 +42,15 @@ func SliceTakeLast[T any](s []T, count int) []T { } return s } + +func ParseMapKeysIntoUint64[T any](m map[string]T) map[uint64]T { + res := make(map[uint64]T) + for k, v := range m { + keyU64, err := strconv.ParseUint(k, 10, 64) + if err != nil { + panic(err) + } + res[keyU64] = v + } + return res +} diff --git a/eth/backend.go b/eth/backend.go index edc7be275e6..e53c6c6c4cd 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -849,12 +849,12 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger mining := stagedsync.New( config.Sync, stagedsync.MiningStages(backend.sentryCtx, - stagedsync.StageMiningCreateBlockCfg(backend.chainDB, miner, *backend.chainConfig, backend.engine, nil, tmpdir, backend.blockReader), + stagedsync.StageMiningCreateBlockCfg(backend.chainDB, miner, backend.chainConfig, backend.engine, nil, tmpdir, backend.blockReader), stagedsync.StageBorHeimdallCfg( backend.chainDB, snapDb, miner, - *backend.chainConfig, + backend.chainConfig, heimdallClient, heimdallStore, bridgeStore, @@ -883,8 +883,8 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger stages2.SilkwormForExecutionStage(backend.silkworm, config), ), stagedsync.StageSendersCfg(backend.chainDB, chainConfig, config.Sync, false, dirs.Tmp, config.Prune, blockReader, backend.sentriesClient.Hd), - stagedsync.StageMiningExecCfg(backend.chainDB, miner, backend.notifications.Events, *backend.chainConfig, backend.engine, &vm.Config{}, tmpdir, nil, 0, txnProvider, blockReader), - stagedsync.StageMiningFinishCfg(backend.chainDB, *backend.chainConfig, backend.engine, miner, backend.miningSealingQuit, backend.blockReader, latestBlockBuiltStore), + stagedsync.StageMiningExecCfg(backend.chainDB, miner, backend.notifications.Events, backend.chainConfig, backend.engine, &vm.Config{}, tmpdir, nil, 0, txnProvider, blockReader), + stagedsync.StageMiningFinishCfg(backend.chainDB, backend.chainConfig, backend.engine, miner, backend.miningSealingQuit, backend.blockReader, latestBlockBuiltStore), astridEnabled, ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, logger, stages.ModeBlockProduction) @@ -896,12 +896,12 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger proposingSync := stagedsync.New( config.Sync, stagedsync.MiningStages(backend.sentryCtx, - stagedsync.StageMiningCreateBlockCfg(backend.chainDB, miningStatePos, *backend.chainConfig, backend.engine, param, tmpdir, backend.blockReader), + stagedsync.StageMiningCreateBlockCfg(backend.chainDB, miningStatePos, backend.chainConfig, backend.engine, param, tmpdir, backend.blockReader), stagedsync.StageBorHeimdallCfg( backend.chainDB, snapDb, miningStatePos, - *backend.chainConfig, + backend.chainConfig, heimdallClient, heimdallStore, bridgeStore, @@ -930,8 +930,8 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger stages2.SilkwormForExecutionStage(backend.silkworm, config), ), stagedsync.StageSendersCfg(backend.chainDB, chainConfig, config.Sync, false, dirs.Tmp, config.Prune, blockReader, backend.sentriesClient.Hd), - stagedsync.StageMiningExecCfg(backend.chainDB, miningStatePos, backend.notifications.Events, *backend.chainConfig, backend.engine, &vm.Config{}, tmpdir, interrupt, param.PayloadId, txnProvider, blockReader), - stagedsync.StageMiningFinishCfg(backend.chainDB, *backend.chainConfig, backend.engine, miningStatePos, backend.miningSealingQuit, backend.blockReader, latestBlockBuiltStore), + stagedsync.StageMiningExecCfg(backend.chainDB, miningStatePos, backend.notifications.Events, backend.chainConfig, backend.engine, &vm.Config{}, tmpdir, interrupt, param.PayloadId, txnProvider, blockReader), + stagedsync.StageMiningFinishCfg(backend.chainDB, backend.chainConfig, backend.engine, miningStatePos, backend.miningSealingQuit, backend.blockReader, latestBlockBuiltStore), astridEnabled, ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, logger, stages.ModeBlockProduction) // We start the mining step @@ -1161,7 +1161,7 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger } backend.polygonDownloadSync = stagedsync.New(backend.config.Sync, stagedsync.DownloadSyncStages( backend.sentryCtx, stagedsync.StageSnapshotsCfg( - backend.chainDB, *backend.sentriesClient.ChainConfig, config.Sync, dirs, blockRetire, backend.downloaderClient, + backend.chainDB, backend.sentriesClient.ChainConfig, config.Sync, dirs, blockRetire, backend.downloaderClient, blockReader, backend.notifications, false, false, false, backend.silkworm, config.Prune, )), nil, nil, backend.logger, stages.ModeApplyingBlocks) diff --git a/eth/stagedsync/chain_reader.go b/eth/stagedsync/chain_reader.go index 725cb809b8a..7c84b90d949 100644 --- a/eth/stagedsync/chain_reader.go +++ b/eth/stagedsync/chain_reader.go @@ -33,7 +33,7 @@ import ( // ChainReader implements consensus.ChainReader type ChainReader struct { - Cfg chain.Config + Cfg *chain.Config Db kv.Tx BlockReader services.FullBlockReader Logger log.Logger @@ -41,7 +41,7 @@ type ChainReader struct { // Config retrieves the blockchain's chain configuration. func (cr ChainReader) Config() *chain.Config { - return &cr.Cfg + return cr.Cfg } // CurrentHeader retrieves the current header from the local chain. diff --git a/eth/stagedsync/stage_bodies.go b/eth/stagedsync/stage_bodies.go index 55a0628151e..b4ef938382b 100644 --- a/eth/stagedsync/stage_bodies.go +++ b/eth/stagedsync/stage_bodies.go @@ -48,7 +48,7 @@ type BodiesCfg struct { penalise func(context.Context, []headerdownload.PenaltyItem) blockPropagator adapter.BlockPropagator timeout int - chanConfig chain.Config + chanConfig *chain.Config blockReader services.FullBlockReader blockWriter *blockio.BlockWriter } @@ -56,7 +56,7 @@ type BodiesCfg struct { func StageBodiesCfg(db kv.RwDB, bd *bodydownload.BodyDownload, bodyReqSend func(context.Context, *bodydownload.BodyRequest) ([64]byte, bool), penalise func(context.Context, []headerdownload.PenaltyItem), blockPropagator adapter.BlockPropagator, timeout int, - chanConfig chain.Config, + chanConfig *chain.Config, blockReader services.FullBlockReader, blockWriter *blockio.BlockWriter, ) BodiesCfg { diff --git a/eth/stagedsync/stage_bor_heimdall.go b/eth/stagedsync/stage_bor_heimdall.go index bfaf1e4e442..ee2aae994e8 100644 --- a/eth/stagedsync/stage_bor_heimdall.go +++ b/eth/stagedsync/stage_bor_heimdall.go @@ -78,7 +78,7 @@ func StageBorHeimdallCfg( db kv.RwDB, snapDb kv.RwDB, miningState MiningState, - chainConfig chain.Config, + chainConfig *chain.Config, heimdallClient heimdall.Client, heimdallStore heimdall.Store, bridgeStore bridge.Store, @@ -104,7 +104,7 @@ func StageBorHeimdallCfg( db: db, snapDb: snapDb, miningState: &miningState, - chainConfig: &chainConfig, + chainConfig: chainConfig, borConfig: borConfig, heimdallClient: heimdallClient, heimdallStore: heimdallStore, diff --git a/eth/stagedsync/stage_headers.go b/eth/stagedsync/stage_headers.go index 1fe6f78ca1c..dc9e2d4611b 100644 --- a/eth/stagedsync/stage_headers.go +++ b/eth/stagedsync/stage_headers.go @@ -55,7 +55,7 @@ type HeadersCfg struct { db kv.RwDB hd *headerdownload.HeaderDownload bodyDownload *bodydownload.BodyDownload - chainConfig chain.Config + chainConfig *chain.Config headerReqSend func(context.Context, *headerdownload.HeaderRequest) ([64]byte, bool) announceNewHashes func(context.Context, []headerdownload.Announce) penalize func(context.Context, []headerdownload.PenaltyItem) @@ -74,7 +74,7 @@ func StageHeadersCfg( db kv.RwDB, headerDownload *headerdownload.HeaderDownload, bodyDownload *bodydownload.BodyDownload, - chainConfig chain.Config, + chainConfig *chain.Config, syncConfig ethconfig.Sync, headerReqSend func(context.Context, *headerdownload.HeaderRequest) ([64]byte, bool), announceNewHashes func(context.Context, []headerdownload.Announce), @@ -177,7 +177,7 @@ func HeadersPOW(s *StageState, u Unwinder, ctx context.Context, tx kv.RwTx, cfg headerInserter := headerdownload.NewHeaderInserter(logPrefix, localTd, startProgress, cfg.blockReader) cfg.hd.SetHeaderReader(&ChainReaderImpl{ - config: &cfg.chainConfig, + config: cfg.chainConfig, tx: tx, blockReader: cfg.blockReader, logger: logger, diff --git a/eth/stagedsync/stage_mining_create_block.go b/eth/stagedsync/stage_mining_create_block.go index 00fb965528e..8b774595069 100644 --- a/eth/stagedsync/stage_mining_create_block.go +++ b/eth/stagedsync/stage_mining_create_block.go @@ -72,7 +72,7 @@ func NewMiningState(cfg *params.MiningConfig) MiningState { type MiningCreateBlockCfg struct { db kv.RwDB miner MiningState - chainConfig chain.Config + chainConfig *chain.Config engine consensus.Engine tmpdir string blockBuilderParameters *core.BlockBuilderParameters @@ -82,7 +82,7 @@ type MiningCreateBlockCfg struct { func StageMiningCreateBlockCfg( db kv.RwDB, miner MiningState, - chainConfig chain.Config, + chainConfig *chain.Config, engine consensus.Engine, blockBuilderParameters *core.BlockBuilderParameters, tmpdir string, @@ -177,13 +177,13 @@ func SpawnMiningCreateBlockStage(s *StageState, txc wrap.TxContainer, cfg Mining uncles mapset.Set[common.Hash] // uncle set } env := &envT{ - signer: types.MakeSigner(&cfg.chainConfig, blockNum, timestamp), + signer: types.MakeSigner(cfg.chainConfig, blockNum, timestamp), ancestors: mapset.NewSet[common.Hash](), family: mapset.NewSet[common.Hash](), uncles: mapset.NewSet[common.Hash](), } - header := core.MakeEmptyHeader(parent, &cfg.chainConfig, timestamp, &cfg.miner.MiningConfig.GasLimit) + header := core.MakeEmptyHeader(parent, cfg.chainConfig, timestamp, &cfg.miner.MiningConfig.GasLimit) if err := misc.VerifyGaslimit(parent.GasLimit, header.GasLimit); err != nil { logger.Warn("Failed to verify gas limit given by the validator, defaulting to parent gas limit", "err", err) header.GasLimit = parent.GasLimit diff --git a/eth/stagedsync/stage_mining_exec.go b/eth/stagedsync/stage_mining_exec.go index 31fd4ad3aad..697b1d933e1 100644 --- a/eth/stagedsync/stage_mining_exec.go +++ b/eth/stagedsync/stage_mining_exec.go @@ -53,7 +53,7 @@ type MiningExecCfg struct { db kv.RwDB miningState MiningState notifier ChainEventNotifier - chainConfig chain.Config + chainConfig *chain.Config engine consensus.Engine blockReader services.FullBlockReader vmConfig *vm.Config @@ -67,7 +67,7 @@ func StageMiningExecCfg( db kv.RwDB, miningState MiningState, notifier ChainEventNotifier, - chainConfig chain.Config, + chainConfig *chain.Config, engine consensus.Engine, vmConfig *vm.Config, tmpdir string, @@ -189,7 +189,7 @@ func SpawnMiningExecStage(s *StageState, txc wrap.TxContainer, cfg MiningExecCfg if current.Receipts == nil { current.Receipts = types.Receipts{} } - chainReader := ChainReaderImpl{config: &cfg.chainConfig, tx: txc.Tx, blockReader: cfg.blockReader, logger: logger} + chainReader := ChainReaderImpl{config: cfg.chainConfig, tx: txc.Tx, blockReader: cfg.blockReader, logger: logger} if err := cfg.engine.Prepare(chainReader, current.Header, ibs); err != nil { return err @@ -197,7 +197,7 @@ func SpawnMiningExecStage(s *StageState, txc wrap.TxContainer, cfg MiningExecCfg var err error var block *types.Block - block, current.Txns, current.Receipts, current.Requests, err = core.FinalizeBlockExecution(cfg.engine, stateReader, current.Header, current.Txns, current.Uncles, &state.NoopWriter{}, &cfg.chainConfig, ibs, current.Receipts, current.Withdrawals, chainReader, true, logger, nil) + block, current.Txns, current.Receipts, current.Requests, err = core.FinalizeBlockExecution(cfg.engine, stateReader, current.Header, current.Txns, current.Uncles, &state.NoopWriter{}, cfg.chainConfig, ibs, current.Receipts, current.Withdrawals, chainReader, true, logger, nil) if err != nil { return fmt.Errorf("cannot finalize block execution: %s", err) } @@ -291,7 +291,7 @@ func getNextTransactions( return txns, nil } -func filterBadTransactions(transactions []types.Transaction, chainID *uint256.Int, config chain.Config, blockNumber uint64, header *types.Header, simStateReader state.StateReader, simStateWriter state.StateWriter, logger log.Logger) ([]types.Transaction, error) { +func filterBadTransactions(transactions []types.Transaction, chainID *uint256.Int, config *chain.Config, blockNumber uint64, header *types.Header, simStateReader state.StateReader, simStateWriter state.StateWriter, logger log.Logger) ([]types.Transaction, error) { initialCnt := len(transactions) var filtered []types.Transaction gasBailout := false @@ -421,7 +421,7 @@ func addTransactionsToMiningBlock( ctx context.Context, logPrefix string, current *MiningBlock, - chainConfig chain.Config, + chainConfig *chain.Config, vmConfig *vm.Config, getHeader func(hash common.Hash, number uint64) *types.Header, engine consensus.Engine, @@ -438,12 +438,12 @@ func addTransactionsToMiningBlock( if header.BlobGasUsed != nil { gasPool.AddBlobGas(chainConfig.GetMaxBlobGasPerBlock(header.Time) - *header.BlobGasUsed) } - signer := types.MakeSigner(&chainConfig, header.Number.Uint64(), header.Time) + signer := types.MakeSigner(chainConfig, header.Number.Uint64(), header.Time) var coalescedLogs types.Logs noop := state.NewNoopWriter() - var miningCommitTx = func(txn types.Transaction, coinbase common.Address, vmConfig *vm.Config, chainConfig chain.Config, ibs *state.IntraBlockState, current *MiningBlock) ([]*types.Log, error) { + var miningCommitTx = func(txn types.Transaction, coinbase common.Address, vmConfig *vm.Config, chainConfig *chain.Config, ibs *state.IntraBlockState, current *MiningBlock) ([]*types.Log, error) { ibs.SetTxContext(txnIdx) gasSnap := gasPool.Gas() blobGasSnap := gasPool.BlobGas() @@ -451,9 +451,9 @@ func addTransactionsToMiningBlock( if txn.Type() == types.AccountAbstractionTxType { aaTxn := txn.(*types.AccountAbstractionTransaction) - blockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, &coinbase, &chainConfig) - evm := vm.NewEVM(blockContext, evmtypes.TxContext{}, ibs, &chainConfig, *vmConfig) - paymasterContext, validationGasUsed, err := aa.ValidateAATransaction(aaTxn, ibs, gasPool, header, evm, &chainConfig) + blockContext := core.NewEVMBlockContext(header, core.GetHashFn(header, getHeader), engine, &coinbase, chainConfig) + evm := vm.NewEVM(blockContext, evmtypes.TxContext{}, ibs, chainConfig, *vmConfig) + paymasterContext, validationGasUsed, err := aa.ValidateAATransaction(aaTxn, ibs, gasPool, header, evm, chainConfig) if err != nil { ibs.RevertToSnapshot(snap) gasPool = new(core.GasPool).AddGas(gasSnap).AddBlobGas(blobGasSnap) // restore gasPool as well as ibs @@ -476,7 +476,7 @@ func addTransactionsToMiningBlock( return receipt.Logs, nil } - receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, header.BlobGasUsed, *vmConfig) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, header.BlobGasUsed, *vmConfig) if err != nil { ibs.RevertToSnapshot(snap) gasPool = new(core.GasPool).AddGas(gasSnap).AddBlobGas(blobGasSnap) // restore gasPool as well as ibs diff --git a/eth/stagedsync/stage_mining_finish.go b/eth/stagedsync/stage_mining_finish.go index 627d1f4e9a7..279e12d6a13 100644 --- a/eth/stagedsync/stage_mining_finish.go +++ b/eth/stagedsync/stage_mining_finish.go @@ -30,7 +30,7 @@ import ( type MiningFinishCfg struct { db kv.RwDB - chainConfig chain.Config + chainConfig *chain.Config engine consensus.Engine sealCancel chan struct{} miningState MiningState @@ -40,7 +40,7 @@ type MiningFinishCfg struct { func StageMiningFinishCfg( db kv.RwDB, - chainConfig chain.Config, + chainConfig *chain.Config, engine consensus.Engine, miningState MiningState, sealCancel chan struct{}, diff --git a/eth/stagedsync/stage_snapshots.go b/eth/stagedsync/stage_snapshots.go index d3b10ae7bc7..10df1bea412 100644 --- a/eth/stagedsync/stage_snapshots.go +++ b/eth/stagedsync/stage_snapshots.go @@ -84,7 +84,7 @@ const ( type SnapshotsCfg struct { db kv.TemporalRwDB - chainConfig chain.Config + chainConfig *chain.Config dirs datadir.Dirs blockRetire services.BlockRetire @@ -102,7 +102,7 @@ type SnapshotsCfg struct { } func StageSnapshotsCfg(db kv.TemporalRwDB, - chainConfig chain.Config, + chainConfig *chain.Config, syncConfig ethconfig.Sync, dirs datadir.Dirs, blockRetire services.BlockRetire, @@ -277,7 +277,7 @@ func DownloadAndIndexSnapshotsIfNeed(s *StageState, ctx context.Context, tx kv.R diagnostics.Send(diagnostics.CurrentSyncSubStage{SubStage: "Download header-chain"}) agg := cfg.db.(*temporal.DB).Agg().(*state2.Aggregator) // Download only the snapshots that are for the header chain. - if err := snapshotsync.WaitForDownloader(ctx, s.LogPrefix(), cfg.dirs, true, cfg.blobs, cfg.caplinState, cfg.prune, cstate, agg, tx, cfg.blockReader, &cfg.chainConfig, cfg.snapshotDownloader, cfg.syncConfig); err != nil { + if err := snapshotsync.WaitForDownloader(ctx, s.LogPrefix(), cfg.dirs, true, cfg.blobs, cfg.caplinState, cfg.prune, cstate, agg, tx, cfg.blockReader, cfg.chainConfig, cfg.snapshotDownloader, cfg.syncConfig); err != nil { return err } @@ -286,7 +286,7 @@ func DownloadAndIndexSnapshotsIfNeed(s *StageState, ctx context.Context, tx kv.R } diagnostics.Send(diagnostics.CurrentSyncSubStage{SubStage: "Download snapshots"}) - if err := snapshotsync.WaitForDownloader(ctx, s.LogPrefix(), cfg.dirs, false, cfg.blobs, cfg.caplinState, cfg.prune, cstate, agg, tx, cfg.blockReader, &cfg.chainConfig, cfg.snapshotDownloader, cfg.syncConfig); err != nil { + if err := snapshotsync.WaitForDownloader(ctx, s.LogPrefix(), cfg.dirs, false, cfg.blobs, cfg.caplinState, cfg.prune, cstate, agg, tx, cfg.blockReader, cfg.chainConfig, cfg.snapshotDownloader, cfg.syncConfig); err != nil { return err } diff --git a/eth/stagedsync/stagedsynctest/chain_configs.go b/eth/stagedsync/stagedsynctest/chain_configs.go index db27a30a7c2..fb2a7fe11e6 100644 --- a/eth/stagedsync/stagedsynctest/chain_configs.go +++ b/eth/stagedsync/stagedsynctest/chain_configs.go @@ -17,6 +17,8 @@ package stagedsynctest import ( + "github.com/jinzhu/copier" + "github.com/erigontech/erigon-lib/chain" "github.com/erigontech/erigon/params" "github.com/erigontech/erigon/polygon/bor/borcfg" @@ -24,7 +26,8 @@ import ( func BorDevnetChainConfigWithNoBlockSealDelays() *chain.Config { // take care not to mutate global var (shallow copy) - chainConfigCopy := *params.BorDevnetChainConfig + var chainConfigCopy chain.Config + copier.Copy(&chainConfigCopy, params.BorDevnetChainConfig) borConfigCopy := *chainConfigCopy.Bor.(*borcfg.BorConfig) borConfigCopy.Period = map[string]uint64{ "0": 0, diff --git a/eth/stagedsync/stagedsynctest/harness.go b/eth/stagedsync/stagedsynctest/harness.go index f0739409f94..08da041fdfd 100644 --- a/eth/stagedsync/stagedsynctest/harness.go +++ b/eth/stagedsync/stagedsynctest/harness.go @@ -73,7 +73,7 @@ func InitHarness(ctx context.Context, t *testing.T, cfg HarnessCfg) Harness { chainDataDB, borConsensusDB, miningState, - *cfg.ChainConfig, + cfg.ChainConfig, heimdallClient, heimdallStore, bridgeStore, diff --git a/execution/consensus/clique/snapshot_test.go b/execution/consensus/clique/snapshot_test.go index 1b9c2486da0..3a605d1dda1 100644 --- a/execution/consensus/clique/snapshot_test.go +++ b/execution/consensus/clique/snapshot_test.go @@ -26,6 +26,8 @@ import ( "sort" "testing" + "github.com/jinzhu/copier" + "github.com/erigontech/erigon-lib/chain" "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/length" @@ -425,7 +427,8 @@ func TestClique(t *testing.T) { } // Assemble a chain of headers from the cast votes - config := *params.AllCliqueProtocolChanges + var config chain.Config + copier.Copy(&config, params.AllCliqueProtocolChanges) config.Clique = &chain.CliqueConfig{ Period: 1, Epoch: tt.epoch, @@ -519,7 +522,7 @@ func TestClique(t *testing.T) { var snap *clique.Snapshot if err := m.DB.View(context.Background(), func(tx kv.Tx) error { chainReader := stagedsync.ChainReader{ - Cfg: config, + Cfg: &config, Db: tx, BlockReader: m.BlockReader, Logger: logger, diff --git a/execution/consensus/misc/eip1559_test.go b/execution/consensus/misc/eip1559_test.go index bc5e426d45e..a9ad7bb0aca 100644 --- a/execution/consensus/misc/eip1559_test.go +++ b/execution/consensus/misc/eip1559_test.go @@ -23,6 +23,8 @@ import ( "math/big" "testing" + "github.com/jinzhu/copier" + "github.com/erigontech/erigon-lib/chain" "github.com/erigontech/erigon-lib/chain/params" "github.com/erigontech/erigon-lib/common" @@ -32,7 +34,8 @@ import ( // copyConfig does a _shallow_ copy of a given config. Safe to set new values, but // do not use e.g. SetInt() on the numbers. For testing only func copyConfig(original *chain.Config) *chain.Config { - copy := *original + var copy chain.Config + copier.Copy(©, original) return © } diff --git a/go.mod b/go.mod index a682a2624e7..6a9c0e30ccd 100644 --- a/go.mod +++ b/go.mod @@ -68,6 +68,7 @@ require ( github.com/huin/goupnp v1.3.0 github.com/jackpal/go-nat-pmp v1.0.2 github.com/jedib0t/go-pretty/v6 v6.5.9 + github.com/jinzhu/copier v0.4.0 github.com/json-iterator/go v1.1.12 github.com/julienschmidt/httprouter v1.3.0 github.com/klauspost/compress v1.18.0 diff --git a/go.sum b/go.sum index 32fef37ea54..1f269ebcd82 100644 --- a/go.sum +++ b/go.sum @@ -505,6 +505,8 @@ github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPw github.com/jedib0t/go-pretty/v6 v6.5.9 h1:ACteMBRrrmm1gMsXe9PSTOClQ63IXDUt03H5U+UV8OU= github.com/jedib0t/go-pretty/v6 v6.5.9/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= diff --git a/params/config.go b/params/config.go index 8522bdb9803..2cdcfea1928 100644 --- a/params/config.go +++ b/params/config.go @@ -29,9 +29,8 @@ import ( "github.com/erigontech/erigon-lib/chain" "github.com/erigontech/erigon-lib/chain/networkname" "github.com/erigontech/erigon-lib/common" - "github.com/erigontech/erigon/polygon/bor/borcfg" - "github.com/erigontech/erigon-lib/common/paths" + "github.com/erigontech/erigon/polygon/bor/borcfg" ) //go:embed chainspecs diff --git a/params/config_test.go b/params/config_test.go index d58503e45f6..791978f1b48 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/require" "github.com/erigontech/erigon-lib/chain" + "github.com/erigontech/erigon-lib/chain/params" "github.com/erigontech/erigon-lib/common" ) @@ -143,37 +144,35 @@ func TestGetBurntContract(t *testing.T) { } func TestMainnetBlobSchedule(t *testing.T) { + c := MainnetChainConfig // Original EIP-4844 values - assert.Equal(t, uint64(6), MainnetChainConfig.GetMaxBlobsPerBlock(0)) - assert.Equal(t, uint64(786432), MainnetChainConfig.GetMaxBlobGasPerBlock(0)) - assert.Equal(t, uint64(393216), MainnetChainConfig.GetTargetBlobGasPerBlock(0)) - assert.Equal(t, uint64(3338477), MainnetChainConfig.GetBlobGasPriceUpdateFraction(0)) - - b := MainnetChainConfig.BlobSchedule - isPrague := false - assert.Equal(t, uint64(3), b.TargetBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(6), b.MaxBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(3338477), b.BaseFeeUpdateFraction(isPrague)) + time := c.CancunTime.Uint64() + assert.Equal(t, uint64(6), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, 6*params.BlobGasPerBlob, c.GetMaxBlobGasPerBlock(time)) + assert.Equal(t, 3*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(3338477), c.GetBlobGasPriceUpdateFraction(time)) // EIP-7691: Blob throughput increase - isPrague = true - assert.Equal(t, uint64(6), b.TargetBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(9), b.MaxBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(5007716), b.BaseFeeUpdateFraction(isPrague)) + time = c.PragueTime.Uint64() + assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, 9*params.BlobGasPerBlob, c.GetMaxBlobGasPerBlock(time)) + assert.Equal(t, 6*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) } func TestGnosisBlobSchedule(t *testing.T) { - b := GnosisChainConfig.BlobSchedule + c := GnosisChainConfig // Cancun values - isPrague := false - assert.Equal(t, uint64(1), b.TargetBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(2), b.MaxBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(1112826), b.BaseFeeUpdateFraction(isPrague)) + time := c.CancunTime.Uint64() + assert.Equal(t, uint64(2), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, 2*params.BlobGasPerBlob, c.GetMaxBlobGasPerBlock(time)) + assert.Equal(t, 1*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(1112826), c.GetBlobGasPriceUpdateFraction(time)) // should remain the same in Pectra for Gnosis - isPrague = true - assert.Equal(t, uint64(1), b.TargetBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(2), b.MaxBlobsPerBlock(isPrague)) - assert.Equal(t, uint64(1112826), b.BaseFeeUpdateFraction(isPrague)) + assert.Equal(t, uint64(2), c.GetMaxBlobsPerBlock(time)) + assert.Equal(t, 2*params.BlobGasPerBlob, c.GetMaxBlobGasPerBlock(time)) + assert.Equal(t, 1*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) + assert.Equal(t, uint64(1112826), c.GetBlobGasPriceUpdateFraction(time)) } diff --git a/polygon/bor/borcfg/bor_config.go b/polygon/bor/borcfg/bor_config.go index 1ad3629744b..86c0fc2722f 100644 --- a/polygon/bor/borcfg/bor_config.go +++ b/polygon/bor/borcfg/bor_config.go @@ -54,7 +54,7 @@ func (c *BorConfig) String() string { } func (c *BorConfig) CalculateProducerDelay(number uint64) uint64 { - return chain.ConfigValueLookup(c.ProducerDelay, number) + return chain.ConfigValueLookup(common.ParseMapKeysIntoUint64(c.ProducerDelay), number) } func (c *BorConfig) IsSprintStart(number uint64) bool { @@ -112,11 +112,11 @@ func (c *BorConfig) CalculateSprintNumber(number uint64) uint64 { } func (c *BorConfig) CalculateBackupMultiplier(number uint64) uint64 { - return chain.ConfigValueLookup(c.BackupMultiplier, number) + return chain.ConfigValueLookup(common.ParseMapKeysIntoUint64(c.BackupMultiplier), number) } func (c *BorConfig) CalculatePeriod(number uint64) uint64 { - return chain.ConfigValueLookup(c.Period, number) + return chain.ConfigValueLookup(common.ParseMapKeysIntoUint64(c.Period), number) } // isForked returns whether a fork scheduled at block s is active at the given head block. @@ -169,7 +169,7 @@ func (c *BorConfig) GetAhmedabadBlock() *big.Int { } func (c *BorConfig) CalculateStateSyncDelay(number uint64) uint64 { - return chain.ConfigValueLookup(c.StateSyncConfirmationDelay, number) + return chain.ConfigValueLookup(common.ParseMapKeysIntoUint64(c.StateSyncConfirmationDelay), number) } func (c *BorConfig) StateReceiverContractAddress() common.Address { diff --git a/tests/init_test.go b/tests/init_test.go index 27bbcda2ea1..7b0e8c5606f 100644 --- a/tests/init_test.go +++ b/tests/init_test.go @@ -99,7 +99,7 @@ type testMatcher struct { type testConfig struct { p *regexp.Regexp - config chain.Config + config *chain.Config } type testFailure struct { @@ -130,7 +130,7 @@ func (tm *testMatcher) whitelist(pattern string) { } // config defines chain config for tests matching the pattern. -func (tm *testMatcher) config(pattern string, cfg chain.Config) { +func (tm *testMatcher) config(pattern string, cfg *chain.Config) { tm.configpat = append(tm.configpat, testConfig{regexp.MustCompile(pattern), cfg}) } @@ -155,17 +155,6 @@ func (tm *testMatcher) findSkip(name string) (reason string, skipload bool) { return "", false } -// findConfig returns the chain config matching defined patterns. -func (tm *testMatcher) findConfig(name string) *chain.Config { - // TODO(fjl): name can be derived from testing.T when min Go version is 1.8 - for _, m := range tm.configpat { - if m.p.MatchString(name) { - return &m.config - } - } - return new(chain.Config) -} - func (tm *testMatcher) checkFailure(t *testing.T, err error) error { return tm.checkFailureWithName(t, t.Name(), err) } diff --git a/turbo/snapshotsync/freezeblocks/dump_test.go b/turbo/snapshotsync/freezeblocks/dump_test.go index 55c6374ced7..6d538f271e8 100644 --- a/turbo/snapshotsync/freezeblocks/dump_test.go +++ b/turbo/snapshotsync/freezeblocks/dump_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/holiman/uint256" + "github.com/jinzhu/copier" "github.com/stretchr/testify/require" "github.com/erigontech/erigon-lib/chain" @@ -75,11 +76,13 @@ func TestDump(t *testing.T) { chainSize int } - withConfig := func(config chain.Config, sprints map[string]uint64) *chain.Config { + withConfig := func(config *chain.Config, sprints map[string]uint64) *chain.Config { + var copy chain.Config + copier.Copy(©, config) bor := *config.Bor.(*borcfg.BorConfig) bor.Sprint = sprints - config.Bor = &bor - return &config + copy.Bor = &bor + return © } tests := []test{ @@ -101,7 +104,7 @@ func TestDump(t *testing.T) { }, { chainSize: 1000, - chainConfig: withConfig(*params.BorDevnetChainConfig, + chainConfig: withConfig(params.BorDevnetChainConfig, map[string]uint64{ "0": 64, "800": 16, @@ -110,7 +113,7 @@ func TestDump(t *testing.T) { }, { chainSize: 2000, - chainConfig: withConfig(*params.BorDevnetChainConfig, + chainConfig: withConfig(params.BorDevnetChainConfig, map[string]uint64{ "0": 64, "800": 16, diff --git a/turbo/stages/mock/mock_sentry.go b/turbo/stages/mock/mock_sentry.go index 49046f2a74e..66f8316de47 100644 --- a/turbo/stages/mock/mock_sentry.go +++ b/turbo/stages/mock/mock_sentry.go @@ -485,8 +485,8 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK proposingSync := stagedsync.New( cfg.Sync, stagedsync.MiningStages(mock.Ctx, - stagedsync.StageMiningCreateBlockCfg(mock.DB, miner, *mock.ChainConfig, mock.Engine, nil, dirs.Tmp, mock.BlockReader), - stagedsync.StageBorHeimdallCfg(mock.DB, snapDb, miningStatePos, *mock.ChainConfig, nil, nil, nil, mock.BlockReader, nil, nil, recents, signatures, false, nil), + stagedsync.StageMiningCreateBlockCfg(mock.DB, miner, mock.ChainConfig, mock.Engine, nil, dirs.Tmp, mock.BlockReader), + stagedsync.StageBorHeimdallCfg(mock.DB, snapDb, miningStatePos, mock.ChainConfig, nil, nil, nil, mock.BlockReader, nil, nil, recents, signatures, false, nil), stagedsync.StageExecuteBlocksCfg( mock.DB, prune, @@ -505,8 +505,8 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK nil, ), stagedsync.StageSendersCfg(mock.DB, mock.ChainConfig, cfg.Sync, false, dirs.Tmp, prune, mock.BlockReader, mock.sentriesClient.Hd), - stagedsync.StageMiningExecCfg(mock.DB, miner, nil, *mock.ChainConfig, mock.Engine, &vm.Config{}, dirs.Tmp, nil, 0, mock.TxPool, mock.BlockReader), - stagedsync.StageMiningFinishCfg(mock.DB, *mock.ChainConfig, mock.Engine, miner, miningCancel, mock.BlockReader, latestBlockBuiltStore), + stagedsync.StageMiningExecCfg(mock.DB, miner, nil, mock.ChainConfig, mock.Engine, &vm.Config{}, dirs.Tmp, nil, 0, mock.TxPool, mock.BlockReader), + stagedsync.StageMiningFinishCfg(mock.DB, mock.ChainConfig, mock.Engine, miner, miningCancel, mock.BlockReader, latestBlockBuiltStore), false, ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, logger, stages.ModeBlockProduction) @@ -521,7 +521,7 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK blockRetire := freezeblocks.NewBlockRetire(1, dirs, mock.BlockReader, blockWriter, mock.DB, nil, nil, mock.ChainConfig, &cfg, mock.Notifications.Events, nil, logger) mock.Sync = stagedsync.New( cfg.Sync, - stagedsync.DefaultStages(mock.Ctx, stagedsync.StageSnapshotsCfg(mock.DB, *mock.ChainConfig, cfg.Sync, dirs, blockRetire, snapDownloader, mock.BlockReader, mock.Notifications, false, false, false, nil, prune), stagedsync.StageHeadersCfg(mock.DB, mock.sentriesClient.Hd, mock.sentriesClient.Bd, *mock.ChainConfig, cfg.Sync, sendHeaderRequest, propagateNewBlockHashes, penalize, cfg.BatchSize, false, mock.BlockReader, blockWriter, dirs.Tmp, mock.Notifications), stagedsync.StageBorHeimdallCfg(mock.DB, snapDb, stagedsync.MiningState{}, *mock.ChainConfig, nil, nil, nil, mock.BlockReader, nil, nil, recents, signatures, false, nil), stagedsync.StageBlockHashesCfg(mock.DB, mock.Dirs.Tmp, mock.ChainConfig, blockWriter), stagedsync.StageBodiesCfg(mock.DB, mock.sentriesClient.Bd, sendBodyRequest, penalize, blockPropagator, cfg.Sync.BodyDownloadTimeoutSeconds, *mock.ChainConfig, mock.BlockReader, blockWriter), stagedsync.StageSendersCfg(mock.DB, mock.ChainConfig, cfg.Sync, false, dirs.Tmp, prune, mock.BlockReader, mock.sentriesClient.Hd), stagedsync.StageExecuteBlocksCfg( + stagedsync.DefaultStages(mock.Ctx, stagedsync.StageSnapshotsCfg(mock.DB, mock.ChainConfig, cfg.Sync, dirs, blockRetire, snapDownloader, mock.BlockReader, mock.Notifications, false, false, false, nil, prune), stagedsync.StageHeadersCfg(mock.DB, mock.sentriesClient.Hd, mock.sentriesClient.Bd, mock.ChainConfig, cfg.Sync, sendHeaderRequest, propagateNewBlockHashes, penalize, cfg.BatchSize, false, mock.BlockReader, blockWriter, dirs.Tmp, mock.Notifications), stagedsync.StageBorHeimdallCfg(mock.DB, snapDb, stagedsync.MiningState{}, mock.ChainConfig, nil, nil, nil, mock.BlockReader, nil, nil, recents, signatures, false, nil), stagedsync.StageBlockHashesCfg(mock.DB, mock.Dirs.Tmp, mock.ChainConfig, blockWriter), stagedsync.StageBodiesCfg(mock.DB, mock.sentriesClient.Bd, sendBodyRequest, penalize, blockPropagator, cfg.Sync.BodyDownloadTimeoutSeconds, mock.ChainConfig, mock.BlockReader, blockWriter), stagedsync.StageSendersCfg(mock.DB, mock.ChainConfig, cfg.Sync, false, dirs.Tmp, prune, mock.BlockReader, mock.sentriesClient.Hd), stagedsync.StageExecuteBlocksCfg( mock.DB, prune, cfg.BatchSize, @@ -563,8 +563,8 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK mock.MiningSync = stagedsync.New( cfg.Sync, stagedsync.MiningStages(mock.Ctx, - stagedsync.StageMiningCreateBlockCfg(mock.DB, miner, *mock.ChainConfig, mock.Engine, nil, dirs.Tmp, mock.BlockReader), - stagedsync.StageBorHeimdallCfg(mock.DB, snapDb, miner, *mock.ChainConfig, nil, nil, nil, mock.BlockReader, nil, nil, recents, signatures, false, nil), + stagedsync.StageMiningCreateBlockCfg(mock.DB, miner, mock.ChainConfig, mock.Engine, nil, dirs.Tmp, mock.BlockReader), + stagedsync.StageBorHeimdallCfg(mock.DB, snapDb, miner, mock.ChainConfig, nil, nil, nil, mock.BlockReader, nil, nil, recents, signatures, false, nil), stagedsync.StageExecuteBlocksCfg( mock.DB, prune, @@ -583,8 +583,8 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK nil, ), stagedsync.StageSendersCfg(mock.DB, mock.ChainConfig, cfg.Sync, false, dirs.Tmp, prune, mock.BlockReader, mock.sentriesClient.Hd), - stagedsync.StageMiningExecCfg(mock.DB, miner, nil, *mock.ChainConfig, mock.Engine, &vm.Config{}, dirs.Tmp, nil, 0, mock.TxPool, mock.BlockReader), - stagedsync.StageMiningFinishCfg(mock.DB, *mock.ChainConfig, mock.Engine, miner, miningCancel, mock.BlockReader, latestBlockBuiltStore), + stagedsync.StageMiningExecCfg(mock.DB, miner, nil, mock.ChainConfig, mock.Engine, &vm.Config{}, dirs.Tmp, nil, 0, mock.TxPool, mock.BlockReader), + stagedsync.StageMiningFinishCfg(mock.DB, mock.ChainConfig, mock.Engine, miner, miningCancel, mock.BlockReader, latestBlockBuiltStore), false, ), stagedsync.MiningUnwindOrder, diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index 7a454c32a6a..88eea95a187 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -699,11 +699,11 @@ func NewDefaultStages(ctx context.Context, runInTestMode := cfg.ImportMode return stagedsync.DefaultStages(ctx, - stagedsync.StageSnapshotsCfg(db, *controlServer.ChainConfig, cfg.Sync, dirs, blockRetire, snapDownloader, blockReader, notifications, cfg.InternalCL && cfg.CaplinConfig.ArchiveBlocks, cfg.CaplinConfig.ArchiveBlobs, cfg.CaplinConfig.ArchiveStates, silkworm, cfg.Prune), - stagedsync.StageHeadersCfg(db, controlServer.Hd, controlServer.Bd, *controlServer.ChainConfig, cfg.Sync, controlServer.SendHeaderRequest, controlServer.PropagateNewBlockHashes, controlServer.Penalize, cfg.BatchSize, p2pCfg.NoDiscovery, blockReader, blockWriter, dirs.Tmp, notifications), - stagedsync.StageBorHeimdallCfg(db, snapDb, stagedsync.MiningState{}, *controlServer.ChainConfig, heimdallClient, heimdallStore, bridgeStore, blockReader, controlServer.Hd, controlServer.Penalize, recents, signatures, cfg.WithHeimdallWaypointRecording, nil), + stagedsync.StageSnapshotsCfg(db, controlServer.ChainConfig, cfg.Sync, dirs, blockRetire, snapDownloader, blockReader, notifications, cfg.InternalCL && cfg.CaplinConfig.ArchiveBlocks, cfg.CaplinConfig.ArchiveBlobs, cfg.CaplinConfig.ArchiveStates, silkworm, cfg.Prune), + stagedsync.StageHeadersCfg(db, controlServer.Hd, controlServer.Bd, controlServer.ChainConfig, cfg.Sync, controlServer.SendHeaderRequest, controlServer.PropagateNewBlockHashes, controlServer.Penalize, cfg.BatchSize, p2pCfg.NoDiscovery, blockReader, blockWriter, dirs.Tmp, notifications), + stagedsync.StageBorHeimdallCfg(db, snapDb, stagedsync.MiningState{}, controlServer.ChainConfig, heimdallClient, heimdallStore, bridgeStore, blockReader, controlServer.Hd, controlServer.Penalize, recents, signatures, cfg.WithHeimdallWaypointRecording, nil), stagedsync.StageBlockHashesCfg(db, dirs.Tmp, controlServer.ChainConfig, blockWriter), - stagedsync.StageBodiesCfg(db, controlServer.Bd, controlServer.SendBodyRequest, controlServer.Penalize, controlServer.BroadcastNewBlock, cfg.Sync.BodyDownloadTimeoutSeconds, *controlServer.ChainConfig, blockReader, blockWriter), + stagedsync.StageBodiesCfg(db, controlServer.Bd, controlServer.SendBodyRequest, controlServer.Penalize, controlServer.BroadcastNewBlock, cfg.Sync.BodyDownloadTimeoutSeconds, controlServer.ChainConfig, blockReader, blockWriter), stagedsync.StageSendersCfg(db, controlServer.ChainConfig, cfg.Sync, false, dirs.Tmp, cfg.Prune, blockReader, controlServer.Hd), stagedsync.StageExecuteBlocksCfg(db, cfg.Prune, cfg.BatchSize, controlServer.ChainConfig, controlServer.Engine, &vm.Config{Tracer: tracingHooks}, notifications, cfg.StateStream, false, dirs, blockReader, controlServer.Hd, cfg.Genesis, cfg.Sync, SilkwormForExecutionStage(silkworm, cfg)), stagedsync.StageTxLookupCfg(db, cfg.Prune, dirs.Tmp, controlServer.ChainConfig.Bor, blockReader), @@ -744,7 +744,7 @@ func NewPipelineStages(ctx context.Context, if len(cfg.Sync.UploadLocation) == 0 { return stagedsync.PipelineStages(ctx, - stagedsync.StageSnapshotsCfg(db, *controlServer.ChainConfig, cfg.Sync, dirs, blockRetire, snapDownloader, blockReader, notifications, cfg.InternalCL && cfg.CaplinConfig.ArchiveBlocks, cfg.CaplinConfig.ArchiveBlobs, cfg.CaplinConfig.ArchiveStates, silkworm, cfg.Prune), + stagedsync.StageSnapshotsCfg(db, controlServer.ChainConfig, cfg.Sync, dirs, blockRetire, snapDownloader, blockReader, notifications, cfg.InternalCL && cfg.CaplinConfig.ArchiveBlocks, cfg.CaplinConfig.ArchiveBlobs, cfg.CaplinConfig.ArchiveStates, silkworm, cfg.Prune), stagedsync.StageBlockHashesCfg(db, dirs.Tmp, controlServer.ChainConfig, blockWriter), stagedsync.StageSendersCfg(db, controlServer.ChainConfig, cfg.Sync, false, dirs.Tmp, cfg.Prune, blockReader, controlServer.Hd), stagedsync.StageExecuteBlocksCfg(db, cfg.Prune, cfg.BatchSize, controlServer.ChainConfig, controlServer.Engine, &vm.Config{Tracer: tracingHooks}, notifications, cfg.StateStream, false, dirs, blockReader, controlServer.Hd, cfg.Genesis, cfg.Sync, SilkwormForExecutionStage(silkworm, cfg)), @@ -753,11 +753,11 @@ func NewPipelineStages(ctx context.Context, } return stagedsync.UploaderPipelineStages(ctx, - stagedsync.StageSnapshotsCfg(db, *controlServer.ChainConfig, cfg.Sync, dirs, blockRetire, snapDownloader, blockReader, notifications, cfg.InternalCL && cfg.CaplinConfig.ArchiveBlocks, cfg.CaplinConfig.ArchiveBlobs, cfg.CaplinConfig.ArchiveStates, silkworm, cfg.Prune), - stagedsync.StageHeadersCfg(db, controlServer.Hd, controlServer.Bd, *controlServer.ChainConfig, cfg.Sync, controlServer.SendHeaderRequest, controlServer.PropagateNewBlockHashes, controlServer.Penalize, cfg.BatchSize, p2pCfg.NoDiscovery, blockReader, blockWriter, dirs.Tmp, notifications), + stagedsync.StageSnapshotsCfg(db, controlServer.ChainConfig, cfg.Sync, dirs, blockRetire, snapDownloader, blockReader, notifications, cfg.InternalCL && cfg.CaplinConfig.ArchiveBlocks, cfg.CaplinConfig.ArchiveBlobs, cfg.CaplinConfig.ArchiveStates, silkworm, cfg.Prune), + stagedsync.StageHeadersCfg(db, controlServer.Hd, controlServer.Bd, controlServer.ChainConfig, cfg.Sync, controlServer.SendHeaderRequest, controlServer.PropagateNewBlockHashes, controlServer.Penalize, cfg.BatchSize, p2pCfg.NoDiscovery, blockReader, blockWriter, dirs.Tmp, notifications), stagedsync.StageBlockHashesCfg(db, dirs.Tmp, controlServer.ChainConfig, blockWriter), stagedsync.StageSendersCfg(db, controlServer.ChainConfig, cfg.Sync, false, dirs.Tmp, cfg.Prune, blockReader, controlServer.Hd), - stagedsync.StageBodiesCfg(db, controlServer.Bd, controlServer.SendBodyRequest, controlServer.Penalize, controlServer.BroadcastNewBlock, cfg.Sync.BodyDownloadTimeoutSeconds, *controlServer.ChainConfig, blockReader, blockWriter), + stagedsync.StageBodiesCfg(db, controlServer.Bd, controlServer.SendBodyRequest, controlServer.Penalize, controlServer.BroadcastNewBlock, cfg.Sync.BodyDownloadTimeoutSeconds, controlServer.ChainConfig, blockReader, blockWriter), stagedsync.StageExecuteBlocksCfg(db, cfg.Prune, cfg.BatchSize, controlServer.ChainConfig, controlServer.Engine, &vm.Config{Tracer: tracingHooks}, notifications, cfg.StateStream, false, dirs, blockReader, controlServer.Hd, cfg.Genesis, cfg.Sync, SilkwormForExecutionStage(silkworm, cfg)), stagedsync.StageTxLookupCfg(db, cfg.Prune, dirs.Tmp, controlServer.ChainConfig.Bor, blockReader), stagedsync.StageFinishCfg(db, dirs.Tmp, forkValidator), runInTestMode) } @@ -767,8 +767,8 @@ func NewInMemoryExecution(ctx context.Context, db kv.RwDB, cfg *ethconfig.Config silkworm *silkworm.Silkworm, logger log.Logger) *stagedsync.Sync { return stagedsync.New( cfg.Sync, - stagedsync.StateStages(ctx, stagedsync.StageHeadersCfg(db, controlServer.Hd, controlServer.Bd, *controlServer.ChainConfig, cfg.Sync, controlServer.SendHeaderRequest, controlServer.PropagateNewBlockHashes, controlServer.Penalize, cfg.BatchSize, false, blockReader, blockWriter, dirs.Tmp, nil), - stagedsync.StageBodiesCfg(db, controlServer.Bd, controlServer.SendBodyRequest, controlServer.Penalize, controlServer.BroadcastNewBlock, cfg.Sync.BodyDownloadTimeoutSeconds, *controlServer.ChainConfig, blockReader, blockWriter), stagedsync.StageBlockHashesCfg(db, dirs.Tmp, controlServer.ChainConfig, blockWriter), stagedsync.StageSendersCfg(db, controlServer.ChainConfig, cfg.Sync, true, dirs.Tmp, cfg.Prune, blockReader, controlServer.Hd), + stagedsync.StateStages(ctx, stagedsync.StageHeadersCfg(db, controlServer.Hd, controlServer.Bd, controlServer.ChainConfig, cfg.Sync, controlServer.SendHeaderRequest, controlServer.PropagateNewBlockHashes, controlServer.Penalize, cfg.BatchSize, false, blockReader, blockWriter, dirs.Tmp, nil), + stagedsync.StageBodiesCfg(db, controlServer.Bd, controlServer.SendBodyRequest, controlServer.Penalize, controlServer.BroadcastNewBlock, cfg.Sync.BodyDownloadTimeoutSeconds, controlServer.ChainConfig, blockReader, blockWriter), stagedsync.StageBlockHashesCfg(db, dirs.Tmp, controlServer.ChainConfig, blockWriter), stagedsync.StageSendersCfg(db, controlServer.ChainConfig, cfg.Sync, true, dirs.Tmp, cfg.Prune, blockReader, controlServer.Hd), stagedsync.StageExecuteBlocksCfg(db, cfg.Prune, cfg.BatchSize, controlServer.ChainConfig, controlServer.Engine, &vm.Config{}, notifications, cfg.StateStream, true, cfg.Dirs, blockReader, controlServer.Hd, cfg.Genesis, cfg.Sync, SilkwormForExecutionStage(silkworm, cfg))), stagedsync.StateUnwindOrder, nil, /* pruneOrder */ @@ -810,7 +810,7 @@ func NewPolygonSyncStages( ctx, stagedsync.StageSnapshotsCfg( db, - *chainConfig, + chainConfig, config.Sync, config.Dirs, blockRetire, diff --git a/txnprovider/shutter/block_building_integration_test.go b/txnprovider/shutter/block_building_integration_test.go index 36225bb5d38..d5472f5cc0f 100644 --- a/txnprovider/shutter/block_building_integration_test.go +++ b/txnprovider/shutter/block_building_integration_test.go @@ -30,10 +30,12 @@ import ( "time" "github.com/holiman/uint256" + "github.com/jinzhu/copier" libp2pcrypto "github.com/libp2p/go-libp2p/core/crypto" "github.com/libp2p/go-libp2p/core/peer" "github.com/stretchr/testify/require" + "github.com/erigontech/erigon-lib/chain" params2 "github.com/erigontech/erigon-lib/chain/params" "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/datadir" @@ -324,7 +326,8 @@ func initBlockBuildingUniverse(ctx context.Context, t *testing.T) blockBuildingU } t.Cleanup(cleanNode(ethNode)) - chainConfig := *params.ChiadoChainConfig + var chainConfig chain.Config + copier.Copy(&chainConfig, params.ChiadoChainConfig) chainConfig.ChainName = "shutter-devnet" chainConfig.ChainID = chainId chainConfig.TerminalTotalDifficulty = big.NewInt(0) diff --git a/txnprovider/txpool/assemble.go b/txnprovider/txpool/assemble.go index 8262bde1ec7..9e4933d2373 100644 --- a/txnprovider/txpool/assemble.go +++ b/txnprovider/txpool/assemble.go @@ -78,12 +78,11 @@ func Assemble( chainDB.(kv.TemporalRwDB), cfg, cache, - *chainID, + chainConfig, shanghaiTime, agraBlock, cancunTime, pragueTime, - chainConfig.BlobSchedule, sentryClients, stateChangesClient, builderNotifyNewTxns, diff --git a/txnprovider/txpool/pool.go b/txnprovider/txpool/pool.go index 0b99cb0370c..2fbf938172a 100644 --- a/txnprovider/txpool/pool.go +++ b/txnprovider/txpool/pool.go @@ -127,6 +127,7 @@ type TxPool struct { promoted Announcements cfg txpoolcfg.Config chainID uint256.Int + chainConfig *chain.Config lastSeenBlock atomic.Uint64 lastSeenCond *sync.Cond lastFinalizedBlock atomic.Uint64 @@ -143,7 +144,6 @@ type TxPool struct { isPostCancun atomic.Bool pragueTime *uint64 isPostPrague atomic.Bool - blobSchedule *chain.BlobSchedule feeCalculator FeeCalculator p2pFetcher *Fetch p2pSender *Send @@ -173,12 +173,11 @@ func New( chainDB kv.TemporalRoDB, cfg txpoolcfg.Config, cache kvcache.Cache, - chainID uint256.Int, + chainConfig *chain.Config, shanghaiTime *big.Int, agraBlock *big.Int, cancunTime *big.Int, pragueTime *big.Int, - blobSchedule *chain.BlobSchedule, sentryClients []sentryproto.SentryClient, stateChangesClient StateChangesClient, builderNotifyNewTxns func(), @@ -208,6 +207,11 @@ func New( tracedSenders[common.BytesToAddress([]byte(sender))] = struct{}{} } + configChainID, overflow := uint256.FromBig(chainConfig.ChainID) + if overflow { + return nil, errors.New("chainID overflow") + } + lock := &sync.Mutex{} res := &TxPool{ @@ -227,12 +231,12 @@ func New( poolDB: poolDB, _chainDB: chainDB, cfg: cfg, - chainID: chainID, + chainID: *configChainID, + chainConfig: chainConfig, unprocessedRemoteTxns: &TxnSlots{}, unprocessedRemoteByHash: map[string]int{}, minedBlobTxnsByBlock: map[uint64][]*metaTxn{}, minedBlobTxnsByHash: map[string]*metaTxn{}, - blobSchedule: blobSchedule, feeCalculator: options.feeCalculator, ethBackend: ethBackend, builderNotifyNewTxns: builderNotifyNewTxns, @@ -274,7 +278,7 @@ func New( res.pragueTime = &pragueTimeU64 } - res.p2pFetcher = NewFetch(ctx, sentryClients, res, stateChangesClient, poolDB, chainID, logger, opts...) + res.p2pFetcher = NewFetch(ctx, sentryClients, res, stateChangesClient, poolDB, res.chainID, logger, opts...) res.p2pSender = NewSend(ctx, sentryClients, logger, opts...) return res, nil @@ -1181,7 +1185,8 @@ func (p *TxPool) isPrague() bool { } func (p *TxPool) GetMaxBlobsPerBlock() uint64 { - return p.blobSchedule.MaxBlobsPerBlock(p.isPrague()) + now := time.Now().Unix() + return p.chainConfig.GetMaxBlobsPerBlock(uint64(now)) } // Check that the serialized txn should not exceed a certain max size diff --git a/txnprovider/txpool/pool_fuzz_test.go b/txnprovider/txpool/pool_fuzz_test.go index adb3793a6fd..36efd95efe5 100644 --- a/txnprovider/txpool/pool_fuzz_test.go +++ b/txnprovider/txpool/pool_fuzz_test.go @@ -28,6 +28,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/erigontech/erigon-lib/chain" "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/datadir" "github.com/erigontech/erigon-lib/common/u256" @@ -328,7 +329,7 @@ func FuzzOnNewBlocks(f *testing.F) { cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) err = pool.start(ctx) @@ -554,7 +555,7 @@ func FuzzOnNewBlocks(f *testing.F) { check(p2pReceived, TxnSlots{}, "after_flush") checkNotify(p2pReceived, TxnSlots{}, "after_flush") - p2, err := New(ctx, ch, db, coreDB, txpoolcfg.DefaultConfig, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + p2, err := New(ctx, ch, db, coreDB, txpoolcfg.DefaultConfig, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) p2.senders = pool.senders // senders are not persisted diff --git a/txnprovider/txpool/pool_test.go b/txnprovider/txpool/pool_test.go index 860e024c4b6..3ea2cd0ce00 100644 --- a/txnprovider/txpool/pool_test.go +++ b/txnprovider/txpool/pool_test.go @@ -26,16 +26,13 @@ import ( "github.com/holiman/uint256" "github.com/stretchr/testify/assert" - - "github.com/erigontech/erigon-lib/chain/params" - "github.com/erigontech/erigon-lib/state" - "github.com/stretchr/testify/require" + "github.com/erigontech/erigon-lib/chain" + "github.com/erigontech/erigon-lib/chain/params" "github.com/erigontech/erigon-lib/common" "github.com/erigontech/erigon-lib/common/datadir" "github.com/erigontech/erigon-lib/common/length" - "github.com/erigontech/erigon-lib/common/u256" "github.com/erigontech/erigon-lib/crypto" "github.com/erigontech/erigon-lib/crypto/kzg" "github.com/erigontech/erigon-lib/gointerfaces" @@ -46,6 +43,7 @@ import ( "github.com/erigontech/erigon-lib/kv/temporal/temporaltest" "github.com/erigontech/erigon-lib/log/v3" "github.com/erigontech/erigon-lib/rlp" + "github.com/erigontech/erigon-lib/state" "github.com/erigontech/erigon-lib/types" accounts3 "github.com/erigontech/erigon-lib/types/accounts" "github.com/erigontech/erigon/txnprovider/txpool/txpoolcfg" @@ -60,7 +58,7 @@ func TestNonceFromAddress(t *testing.T) { db := memdb.NewTestPoolDB(t) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -186,7 +184,7 @@ func TestMultipleAuthorizations(t *testing.T) { cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, common.Big0 /* shanghaiTime */, nil /* agraBlock */, common.Big0 /* cancunTime */, common.Big0 /* pragueTime */, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, common.Big0 /* shanghaiTime */, nil /* agraBlock */, common.Big0 /* cancunTime */, common.Big0 /* pragueTime */, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(t, err) require.NotEqual(t, pool, nil) @@ -441,7 +439,7 @@ func TestReplaceWithHigherFee(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotNil(pool) var stateVersionID uint64 = 0 @@ -564,7 +562,7 @@ func TestReverseNonces(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -694,7 +692,7 @@ func TestTxnPoke(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -931,7 +929,7 @@ func TestShanghaiValidateTxn(t *testing.T) { asrt.NoError(err) defer sd.Close() cache := kvcache.NewDummy() - pool, err := New(ctx, ch, nil, coreDB, cfg, cache, *u256.N1, shanghaiTime, nil /* agraBlock */, nil /* cancunTime */, nil, nil, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) + pool, err := New(ctx, ch, nil, coreDB, cfg, cache, chain.TestChainConfig, shanghaiTime, nil /* agraBlock */, nil /* cancunTime */, nil, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) asrt.NoError(err) sndr := accounts3.Account{Nonce: 0, Balance: *uint256.NewInt(math.MaxUint64)} @@ -977,7 +975,7 @@ func TestTooHighGasLimitTxnValidation(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -1039,11 +1037,12 @@ func TestSetCodeTxnValidationWithLargeAuthorizationValues(t *testing.T) { ch := make(chan Announcements, 1) coreDB := temporaltest.NewTestDB(t, datadir.New(t.TempDir())) cfg := txpoolcfg.DefaultConfig - chainID := *maxUint256 + chainConfig := new(chain.Config) + chainConfig.ChainID = maxUint256.ToBig() cache := kvcache.NewDummy() logger := log.New() - pool, err := New(ctx, ch, nil, coreDB, cfg, cache, chainID, common.Big0 /* shanghaiTime */, nil, /* agraBlock */ - common.Big0 /* cancunTime */, common.Big0 /* pragueTime */, nil, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) + pool, err := New(ctx, ch, nil, coreDB, cfg, cache, chain.TestChainConfigCancun, common.Big0 /* shanghaiTime */, nil, /* agraBlock */ + common.Big0 /* cancunTime */, common.Big0 /* pragueTime */, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) require.NoError(t, err) pool.blockGasLimit.Store(30_000_000) tx, err := coreDB.BeginTemporalRw(ctx) @@ -1093,7 +1092,7 @@ func TestBlobTxnReplacement(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, common.Big0, nil, common.Big0, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfigCancun, common.Big0, nil, common.Big0, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) @@ -1277,7 +1276,7 @@ func TestDropRemoteAtNoGossip(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) - txnPool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) + txnPool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(txnPool, nil) @@ -1388,7 +1387,7 @@ func TestBlobSlots(t *testing.T) { cfg.TotalBlobPoolLimit = 20 sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, common.Big0, nil, common.Big0, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfigCancun, common.Big0, nil, common.Big0, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -1471,7 +1470,7 @@ func TestGetBlobsV1(t *testing.T) { cfg.TotalBlobPoolLimit = 20 sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, common.Big0, nil, common.Big0, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfigCancun, common.Big0, nil, common.Big0, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) pool.blockGasLimit.Store(30000000) @@ -1546,7 +1545,7 @@ func TestGasLimitChanged(t *testing.T) { db := memdb.NewTestPoolDB(t) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -1630,7 +1629,7 @@ func BenchmarkProcessRemoteTxns(b *testing.B) { b.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, *u256.N1, nil, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) From 3138bc322e5ecc8bf1bda11ddbf2013cd1d4bc79 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Fri, 16 May 2025 13:04:34 +0200 Subject: [PATCH 02/13] accept EEST encoding --- erigon-lib/chain/chain_config.go | 16 ++++--- erigon-lib/chain/chain_config_test.go | 49 ++++++++++++++++++++ erigon-lib/chain/params/protocol.go | 7 +-- erigon-lib/common/hexutil/errors.go | 1 + erigon-lib/common/hexutil/json.go | 65 ++++++++++++++++++++++----- 5 files changed, 116 insertions(+), 22 deletions(-) diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 6140f58c1c7..23bb6c1d241 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -21,6 +21,7 @@ import ( "fmt" "math/big" "strconv" + "strings" "sync" "time" @@ -348,16 +349,17 @@ func (c *Config) getBlobConfig(time uint64) *params.BlobConfig { // Override with supplied values for key, val := range c.BlobSchedule { + k := strings.ToLower(key) switch { - case key == "cancun": + case k == "cancun": if c.CancunTime != nil { c.parsedBlobSchedule[c.CancunTime.Uint64()] = val } - case key == "prague": + case k == "prague": if c.PragueTime != nil { c.parsedBlobSchedule[c.PragueTime.Uint64()] = val } - case key == "osaka": + case k == "osaka": if c.OsakaTime != nil { c.parsedBlobSchedule[c.OsakaTime.Uint64()] = val } @@ -375,19 +377,19 @@ func (c *Config) getBlobConfig(time uint64) *params.BlobConfig { } func (c *Config) GetMaxBlobsPerBlock(time uint64) uint64 { - return c.getBlobConfig(time).Max + return uint64(c.getBlobConfig(time).Max) } func (c *Config) GetMaxBlobGasPerBlock(time uint64) uint64 { - return c.getBlobConfig(time).Max * params.BlobGasPerBlob + return uint64(c.getBlobConfig(time).Max) * params.BlobGasPerBlob } func (c *Config) GetTargetBlobGasPerBlock(time uint64) uint64 { - return c.getBlobConfig(time).Target * params.BlobGasPerBlob + return uint64(c.getBlobConfig(time).Target) * params.BlobGasPerBlob } func (c *Config) GetBlobGasPriceUpdateFraction(time uint64) uint64 { - return c.getBlobConfig(time).BaseFeeUpdateFraction + return uint64(c.getBlobConfig(time).BaseFeeUpdateFraction) } func (c *Config) SecondsPerSlot() uint64 { diff --git a/erigon-lib/chain/chain_config_test.go b/erigon-lib/chain/chain_config_test.go index b3b75820c92..4ee835de2a6 100644 --- a/erigon-lib/chain/chain_config_test.go +++ b/erigon-lib/chain/chain_config_test.go @@ -17,11 +17,13 @@ package chain import ( + "encoding/json" "math/big" "strconv" "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/erigontech/erigon-lib/chain/params" "github.com/erigontech/erigon-lib/common" @@ -218,3 +220,50 @@ func TestBlobParameterInactiveHardfork(t *testing.T) { assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) } + +// See how blob schedule is rendered in EEST fixtures, e.g. from +// https://github.com/ethereum/execution-spec-tests/releases/tag/v4.5.0 +func TestEestBlobConfigParsing(t *testing.T) { + blobConfigJson := `{ + "Cancun": { + "target": "0x01", + "max": "0x02", + "baseFeeUpdateFraction": "0x100000" + } + }` + blobSchedule := make(map[string]*params.BlobConfig) + require.NoError(t, json.Unmarshal([]byte(blobConfigJson), &blobSchedule)) + + c := Config{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + TangerineWhistleBlock: big.NewInt(0), + SpuriousDragonBlock: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + GrayGlacierBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + TerminalTotalDifficultyPassed: true, + ShanghaiTime: big.NewInt(0), + CancunTime: big.NewInt(1), + BlobSchedule: blobSchedule, + } + + assert.Equal(t, uint64(0), c.GetTargetBlobGasPerBlock(0)) + assert.Equal(t, uint64(0), c.GetMaxBlobsPerBlock(0)) + assert.Equal(t, uint64(0), c.GetBlobGasPriceUpdateFraction(0)) + + assert.Equal(t, 1*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(1)) + assert.Equal(t, uint64(2), c.GetMaxBlobsPerBlock(1)) + assert.Equal(t, uint64(0x100000), c.GetBlobGasPriceUpdateFraction(1)) + + assert.Equal(t, 1*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(2)) + assert.Equal(t, uint64(2), c.GetMaxBlobsPerBlock(2)) + assert.Equal(t, uint64(0x100000), c.GetBlobGasPriceUpdateFraction(2)) +} diff --git a/erigon-lib/chain/params/protocol.go b/erigon-lib/chain/params/protocol.go index 6c68f0b0f5f..36b31d46994 100644 --- a/erigon-lib/chain/params/protocol.go +++ b/erigon-lib/chain/params/protocol.go @@ -23,6 +23,7 @@ import ( "math/big" "github.com/erigontech/erigon-lib/common" + "github.com/erigontech/erigon-lib/common/hexutil" ) const ( @@ -223,9 +224,9 @@ var ( // See EIP-7840: Add blob schedule to EL config files // and EIP-7892: Blob Parameter Only Hardforks type BlobConfig struct { - Target uint64 `json:"target"` - Max uint64 `json:"max"` - BaseFeeUpdateFraction uint64 `json:"baseFeeUpdateFraction"` + Target hexutil.FlexibleUint64 `json:"target"` + Max hexutil.FlexibleUint64 `json:"max"` + BaseFeeUpdateFraction hexutil.FlexibleUint64 `json:"baseFeeUpdateFraction"` } var DefaultCancunBlobConfig = BlobConfig{ diff --git a/erigon-lib/common/hexutil/errors.go b/erigon-lib/common/hexutil/errors.go index 07d0a7963e7..9872d32a7ff 100644 --- a/erigon-lib/common/hexutil/errors.go +++ b/erigon-lib/common/hexutil/errors.go @@ -31,6 +31,7 @@ var ( ErrBig256Range = &decError{"hex number > 256 bits"} ErrTooBigHexString = &decError{"hex string too long, want at most 32 bytes"} ErrHexStringInvalid = &decError{"hex string invalid"} + ErrDecUintInvalid = &decError{"invalid unsigned decimal integer"} ) type decError struct{ msg string } diff --git a/erigon-lib/common/hexutil/json.go b/erigon-lib/common/hexutil/json.go index 0e61bccf9f5..edf489829ae 100644 --- a/erigon-lib/common/hexutil/json.go +++ b/erigon-lib/common/hexutil/json.go @@ -30,9 +30,10 @@ import ( ) var ( - bigT = reflect.TypeOf((*Big)(nil)) - uintT = reflect.TypeOf(Uint(0)) - uint64T = reflect.TypeOf(Uint64(0)) + bigT = reflect.TypeOf((*Big)(nil)) + uintT = reflect.TypeOf(Uint(0)) + uint64T = reflect.TypeOf(Uint64(0)) + flexibleUint64T = reflect.TypeOf(FlexibleUint64(0)) ) // UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The @@ -79,7 +80,7 @@ func (b *Big) UnmarshalJSON(input []byte) error { // UnmarshalText implements encoding.TextUnmarshaler func (b *Big) UnmarshalText(input []byte) error { - raw, err := checkNumberText(input) + raw, err := checkNumberText(input, false) if err != nil { return err } @@ -145,24 +146,32 @@ func (b *Uint64) UnmarshalJSON(input []byte) error { // UnmarshalText implements encoding.TextUnmarshaler func (b *Uint64) UnmarshalText(input []byte) error { - raw, err := checkNumberText(input) + dec, err := unmarshalHexAsUint64(input, false) if err != nil { return err } + *b = Uint64(dec) + return nil +} + +func unmarshalHexAsUint64(input []byte, allowLeadingZeros bool) (uint64, error) { + raw, err := checkNumberText(input, allowLeadingZeros) + if err != nil { + return 0, err + } if len(raw) > 16 { - return ErrUint64Range + return 0, ErrUint64Range } var dec uint64 for _, byte := range raw { nib := decodeNibble(byte) if nib == badNibble { - return ErrSyntax + return 0, ErrSyntax } dec *= 16 dec += nib } - *b = Uint64(dec) - return nil + return dec, nil } // String returns the hex encoding of b. @@ -209,11 +218,43 @@ func (b Uint) String() string { return EncodeUint64(uint64(b)) } +// FlexibleUint64 marshals its value as a JSON integer +// and can unmarshal a JSON decimal integer or a hex string with 0x prefix. +type FlexibleUint64 uint64 + +// UnmarshalJSON implements json.Unmarshaler. +func (b *FlexibleUint64) UnmarshalJSON(input []byte) error { + var dec uint64 + var err error + if isString(input) { + // hex string + input = input[1 : len(input)-1] + dec, err = unmarshalHexAsUint64(input, true) + } else { + // decimal integer + dec, err = strconv.ParseUint(string(input), 10, 64) + } + if err != nil { + return wrapTypeError(ErrDecUintInvalid, flexibleUint64T) + } + *b = FlexibleUint64(dec) + return nil +} + +// String returns the decimal encoding of b. +func (b FlexibleUint64) String() string { + return strconv.FormatUint(uint64(b), 10) +} + +func (b FlexibleUint64) Uint64() uint64 { + return (uint64)(b) +} + func isString(input []byte) bool { return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' } -func checkNumberText(input []byte) (raw []byte, err error) { +func checkNumberText(input []byte, allowLeadingZeros bool) (raw []byte, err error) { if len(input) == 0 { return nil, nil // empty strings are allowed } @@ -224,14 +265,14 @@ func checkNumberText(input []byte) (raw []byte, err error) { if len(input) == 0 { return nil, ErrEmptyNumber } - if len(input) > 1 && input[0] == '0' { + if !allowLeadingZeros && len(input) > 1 && input[0] == '0' { return nil, ErrLeadingZero } return input, nil } func wrapTypeError(err error, typ reflect.Type) error { - // keeping compatiblity with go ethereum tests + // keeping compatibility with go ethereum tests // nolint:errorlint //if _, ok := err.(*decError); ok { // return &json.UnmarshalTypeError{Value: err.Error(), Type: typ} From 1151e36dc468c9349309bb0acc35ee42725e22d1 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 21 May 2025 12:42:57 +0200 Subject: [PATCH 03/13] Revert "accept EEST encoding" This reverts commit 3138bc322e5ecc8bf1bda11ddbf2013cd1d4bc79. --- erigon-lib/chain/chain_config.go | 16 +++---- erigon-lib/chain/chain_config_test.go | 49 -------------------- erigon-lib/chain/params/protocol.go | 7 ++- erigon-lib/common/hexutil/errors.go | 1 - erigon-lib/common/hexutil/json.go | 65 +++++---------------------- 5 files changed, 22 insertions(+), 116 deletions(-) diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 23bb6c1d241..6140f58c1c7 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -21,7 +21,6 @@ import ( "fmt" "math/big" "strconv" - "strings" "sync" "time" @@ -349,17 +348,16 @@ func (c *Config) getBlobConfig(time uint64) *params.BlobConfig { // Override with supplied values for key, val := range c.BlobSchedule { - k := strings.ToLower(key) switch { - case k == "cancun": + case key == "cancun": if c.CancunTime != nil { c.parsedBlobSchedule[c.CancunTime.Uint64()] = val } - case k == "prague": + case key == "prague": if c.PragueTime != nil { c.parsedBlobSchedule[c.PragueTime.Uint64()] = val } - case k == "osaka": + case key == "osaka": if c.OsakaTime != nil { c.parsedBlobSchedule[c.OsakaTime.Uint64()] = val } @@ -377,19 +375,19 @@ func (c *Config) getBlobConfig(time uint64) *params.BlobConfig { } func (c *Config) GetMaxBlobsPerBlock(time uint64) uint64 { - return uint64(c.getBlobConfig(time).Max) + return c.getBlobConfig(time).Max } func (c *Config) GetMaxBlobGasPerBlock(time uint64) uint64 { - return uint64(c.getBlobConfig(time).Max) * params.BlobGasPerBlob + return c.getBlobConfig(time).Max * params.BlobGasPerBlob } func (c *Config) GetTargetBlobGasPerBlock(time uint64) uint64 { - return uint64(c.getBlobConfig(time).Target) * params.BlobGasPerBlob + return c.getBlobConfig(time).Target * params.BlobGasPerBlob } func (c *Config) GetBlobGasPriceUpdateFraction(time uint64) uint64 { - return uint64(c.getBlobConfig(time).BaseFeeUpdateFraction) + return c.getBlobConfig(time).BaseFeeUpdateFraction } func (c *Config) SecondsPerSlot() uint64 { diff --git a/erigon-lib/chain/chain_config_test.go b/erigon-lib/chain/chain_config_test.go index 4ee835de2a6..b3b75820c92 100644 --- a/erigon-lib/chain/chain_config_test.go +++ b/erigon-lib/chain/chain_config_test.go @@ -17,13 +17,11 @@ package chain import ( - "encoding/json" "math/big" "strconv" "testing" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/erigontech/erigon-lib/chain/params" "github.com/erigontech/erigon-lib/common" @@ -220,50 +218,3 @@ func TestBlobParameterInactiveHardfork(t *testing.T) { assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) } - -// See how blob schedule is rendered in EEST fixtures, e.g. from -// https://github.com/ethereum/execution-spec-tests/releases/tag/v4.5.0 -func TestEestBlobConfigParsing(t *testing.T) { - blobConfigJson := `{ - "Cancun": { - "target": "0x01", - "max": "0x02", - "baseFeeUpdateFraction": "0x100000" - } - }` - blobSchedule := make(map[string]*params.BlobConfig) - require.NoError(t, json.Unmarshal([]byte(blobConfigJson), &blobSchedule)) - - c := Config{ - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - TangerineWhistleBlock: big.NewInt(0), - SpuriousDragonBlock: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - GrayGlacierBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0), - TerminalTotalDifficultyPassed: true, - ShanghaiTime: big.NewInt(0), - CancunTime: big.NewInt(1), - BlobSchedule: blobSchedule, - } - - assert.Equal(t, uint64(0), c.GetTargetBlobGasPerBlock(0)) - assert.Equal(t, uint64(0), c.GetMaxBlobsPerBlock(0)) - assert.Equal(t, uint64(0), c.GetBlobGasPriceUpdateFraction(0)) - - assert.Equal(t, 1*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(1)) - assert.Equal(t, uint64(2), c.GetMaxBlobsPerBlock(1)) - assert.Equal(t, uint64(0x100000), c.GetBlobGasPriceUpdateFraction(1)) - - assert.Equal(t, 1*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(2)) - assert.Equal(t, uint64(2), c.GetMaxBlobsPerBlock(2)) - assert.Equal(t, uint64(0x100000), c.GetBlobGasPriceUpdateFraction(2)) -} diff --git a/erigon-lib/chain/params/protocol.go b/erigon-lib/chain/params/protocol.go index 36b31d46994..6c68f0b0f5f 100644 --- a/erigon-lib/chain/params/protocol.go +++ b/erigon-lib/chain/params/protocol.go @@ -23,7 +23,6 @@ import ( "math/big" "github.com/erigontech/erigon-lib/common" - "github.com/erigontech/erigon-lib/common/hexutil" ) const ( @@ -224,9 +223,9 @@ var ( // See EIP-7840: Add blob schedule to EL config files // and EIP-7892: Blob Parameter Only Hardforks type BlobConfig struct { - Target hexutil.FlexibleUint64 `json:"target"` - Max hexutil.FlexibleUint64 `json:"max"` - BaseFeeUpdateFraction hexutil.FlexibleUint64 `json:"baseFeeUpdateFraction"` + Target uint64 `json:"target"` + Max uint64 `json:"max"` + BaseFeeUpdateFraction uint64 `json:"baseFeeUpdateFraction"` } var DefaultCancunBlobConfig = BlobConfig{ diff --git a/erigon-lib/common/hexutil/errors.go b/erigon-lib/common/hexutil/errors.go index 9872d32a7ff..07d0a7963e7 100644 --- a/erigon-lib/common/hexutil/errors.go +++ b/erigon-lib/common/hexutil/errors.go @@ -31,7 +31,6 @@ var ( ErrBig256Range = &decError{"hex number > 256 bits"} ErrTooBigHexString = &decError{"hex string too long, want at most 32 bytes"} ErrHexStringInvalid = &decError{"hex string invalid"} - ErrDecUintInvalid = &decError{"invalid unsigned decimal integer"} ) type decError struct{ msg string } diff --git a/erigon-lib/common/hexutil/json.go b/erigon-lib/common/hexutil/json.go index edf489829ae..0e61bccf9f5 100644 --- a/erigon-lib/common/hexutil/json.go +++ b/erigon-lib/common/hexutil/json.go @@ -30,10 +30,9 @@ import ( ) var ( - bigT = reflect.TypeOf((*Big)(nil)) - uintT = reflect.TypeOf(Uint(0)) - uint64T = reflect.TypeOf(Uint64(0)) - flexibleUint64T = reflect.TypeOf(FlexibleUint64(0)) + bigT = reflect.TypeOf((*Big)(nil)) + uintT = reflect.TypeOf(Uint(0)) + uint64T = reflect.TypeOf(Uint64(0)) ) // UnmarshalFixedUnprefixedText decodes the input as a string with optional 0x prefix. The @@ -80,7 +79,7 @@ func (b *Big) UnmarshalJSON(input []byte) error { // UnmarshalText implements encoding.TextUnmarshaler func (b *Big) UnmarshalText(input []byte) error { - raw, err := checkNumberText(input, false) + raw, err := checkNumberText(input) if err != nil { return err } @@ -146,32 +145,24 @@ func (b *Uint64) UnmarshalJSON(input []byte) error { // UnmarshalText implements encoding.TextUnmarshaler func (b *Uint64) UnmarshalText(input []byte) error { - dec, err := unmarshalHexAsUint64(input, false) + raw, err := checkNumberText(input) if err != nil { return err } - *b = Uint64(dec) - return nil -} - -func unmarshalHexAsUint64(input []byte, allowLeadingZeros bool) (uint64, error) { - raw, err := checkNumberText(input, allowLeadingZeros) - if err != nil { - return 0, err - } if len(raw) > 16 { - return 0, ErrUint64Range + return ErrUint64Range } var dec uint64 for _, byte := range raw { nib := decodeNibble(byte) if nib == badNibble { - return 0, ErrSyntax + return ErrSyntax } dec *= 16 dec += nib } - return dec, nil + *b = Uint64(dec) + return nil } // String returns the hex encoding of b. @@ -218,43 +209,11 @@ func (b Uint) String() string { return EncodeUint64(uint64(b)) } -// FlexibleUint64 marshals its value as a JSON integer -// and can unmarshal a JSON decimal integer or a hex string with 0x prefix. -type FlexibleUint64 uint64 - -// UnmarshalJSON implements json.Unmarshaler. -func (b *FlexibleUint64) UnmarshalJSON(input []byte) error { - var dec uint64 - var err error - if isString(input) { - // hex string - input = input[1 : len(input)-1] - dec, err = unmarshalHexAsUint64(input, true) - } else { - // decimal integer - dec, err = strconv.ParseUint(string(input), 10, 64) - } - if err != nil { - return wrapTypeError(ErrDecUintInvalid, flexibleUint64T) - } - *b = FlexibleUint64(dec) - return nil -} - -// String returns the decimal encoding of b. -func (b FlexibleUint64) String() string { - return strconv.FormatUint(uint64(b), 10) -} - -func (b FlexibleUint64) Uint64() uint64 { - return (uint64)(b) -} - func isString(input []byte) bool { return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' } -func checkNumberText(input []byte, allowLeadingZeros bool) (raw []byte, err error) { +func checkNumberText(input []byte) (raw []byte, err error) { if len(input) == 0 { return nil, nil // empty strings are allowed } @@ -265,14 +224,14 @@ func checkNumberText(input []byte, allowLeadingZeros bool) (raw []byte, err erro if len(input) == 0 { return nil, ErrEmptyNumber } - if !allowLeadingZeros && len(input) > 1 && input[0] == '0' { + if len(input) > 1 && input[0] == '0' { return nil, ErrLeadingZero } return input, nil } func wrapTypeError(err error, typ reflect.Type) error { - // keeping compatibility with go ethereum tests + // keeping compatiblity with go ethereum tests // nolint:errorlint //if _, ok := err.(*decError); ok { // return &json.UnmarshalTypeError{Value: err.Error(), Type: typ} From 9b89438480c8775ccf0ab3eaf137481bb6a355a6 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 21 May 2025 14:50:15 +0200 Subject: [PATCH 04/13] move Forks to execution --- cmd/evm/internal/t8ntool/flags.go | 4 ++-- tests/init.go => execution/testutil/forks.go | 2 +- tests/block_test_util.go | 5 +++-- tests/difficulty_test.go | 6 ++++-- tests/state_test_util.go | 13 ++++++------ tests/transaction_test_util.go | 21 ++++++++++---------- 6 files changed, 28 insertions(+), 23 deletions(-) rename tests/init.go => execution/testutil/forks.go (99%) diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go index 333678b0584..acfbb9a3716 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -26,7 +26,7 @@ import ( "github.com/urfave/cli/v2" "github.com/erigontech/erigon/core/vm" - "github.com/erigontech/erigon/tests" + "github.com/erigontech/erigon/execution/testutil" ) var ( @@ -100,7 +100,7 @@ var ( "\n\tAvailable extra eips:"+ "\n\t %v"+ "\n\tSyntax (+ExtraEip)", - strings.Join(tests.AvailableForks(), "\n\t "), + strings.Join(testutil.AvailableForks(), "\n\t "), strings.Join(vm.ActivateableEips(), ", ")), Value: "Merge", } diff --git a/tests/init.go b/execution/testutil/forks.go similarity index 99% rename from tests/init.go rename to execution/testutil/forks.go index 91741430471..6f65b58f667 100644 --- a/tests/init.go +++ b/execution/testutil/forks.go @@ -17,7 +17,7 @@ // You should have received a copy of the GNU Lesser General Public License // along with Erigon. If not, see . -package tests +package testutil import ( "fmt" diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 3df90223186..5b43325811f 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -45,6 +45,7 @@ import ( "github.com/erigontech/erigon/core" "github.com/erigontech/erigon/core/state" "github.com/erigontech/erigon/eth/ethconsensusconfig" + "github.com/erigontech/erigon/execution/testutil" "github.com/erigontech/erigon/turbo/services" "github.com/erigontech/erigon/turbo/stages/mock" ) @@ -117,9 +118,9 @@ type btHeaderMarshaling struct { } func (bt *BlockTest) Run(t *testing.T, checkStateRoot bool) error { - config, ok := Forks[bt.json.Network] + config, ok := testutil.Forks[bt.json.Network] if !ok { - return UnsupportedForkError{bt.json.Network} + return testutil.UnsupportedForkError{bt.json.Network} } engine := ethconsensusconfig.CreateConsensusEngineBareBones(context.Background(), config, log.New()) diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go index 966727e5bdf..78a180d275c 100644 --- a/tests/difficulty_test.go +++ b/tests/difficulty_test.go @@ -23,6 +23,8 @@ import ( "encoding/json" "fmt" "testing" + + "github.com/erigontech/erigon/execution/testutil" ) func TestDifficulty(t *testing.T) { @@ -43,9 +45,9 @@ func TestDifficulty(t *testing.T) { continue } - cfg, ok := Forks[fork] + cfg, ok := testutil.Forks[fork] if !ok { - t.Error(UnsupportedForkError{fork}) + t.Error(testutil.UnsupportedForkError{fork}) continue } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 745c9f7e04b..32c13d71cc8 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -51,6 +51,7 @@ import ( "github.com/erigontech/erigon/core/tracing" "github.com/erigontech/erigon/core/vm" "github.com/erigontech/erigon/execution/consensus/misc" + "github.com/erigontech/erigon/execution/testutil" "github.com/erigontech/erigon/rpc/rpchelper" ) @@ -139,8 +140,8 @@ func GetChainConfig(forkString string) (baseConfig *chain.Config, eips []int, er ok bool baseName, eipsStrings = splitForks[0], splitForks[1:] ) - if baseConfig, ok = Forks[baseName]; !ok { - return nil, nil, UnsupportedForkError{baseName} + if baseConfig, ok = testutil.Forks[baseName]; !ok { + return nil, nil, testutil.UnsupportedForkError{baseName} } for _, eip := range eipsStrings { if eipNum, err := strconv.Atoi(eip); err != nil { @@ -188,12 +189,12 @@ func (t *StateTest) Run(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Config, di func (t *StateTest) RunNoVerify(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Config, dirs datadir.Dirs) (*state.IntraBlockState, common.Hash, error) { config, eips, err := GetChainConfig(subtest.Fork) if err != nil { - return nil, common.Hash{}, UnsupportedForkError{subtest.Fork} + return nil, common.Hash{}, testutil.UnsupportedForkError{subtest.Fork} } vmconfig.ExtraEips = eips block, _, err := core.GenesisToBlock(t.genesis(config), dirs, log.Root()) if err != nil { - return nil, common.Hash{}, UnsupportedForkError{subtest.Fork} + return nil, common.Hash{}, testutil.UnsupportedForkError{subtest.Fork} } readBlockNr := block.NumberU64() @@ -201,13 +202,13 @@ func (t *StateTest) RunNoVerify(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Co _, err = MakePreState(&chain.Rules{}, tx, t.json.Pre, readBlockNr) if err != nil { - return nil, common.Hash{}, UnsupportedForkError{subtest.Fork} + return nil, common.Hash{}, testutil.UnsupportedForkError{subtest.Fork} } txc := wrap.NewTxContainer(tx, nil) domains, err := state2.NewSharedDomains(txc.Ttx, log.New()) if err != nil { - return nil, common.Hash{}, UnsupportedForkError{subtest.Fork} + return nil, common.Hash{}, testutil.UnsupportedForkError{subtest.Fork} } defer domains.Close() txc.Doms = domains diff --git a/tests/transaction_test_util.go b/tests/transaction_test_util.go index 64e8d24e7ff..47d439c912c 100644 --- a/tests/transaction_test_util.go +++ b/tests/transaction_test_util.go @@ -33,6 +33,7 @@ import ( "github.com/erigontech/erigon-lib/common/math" "github.com/erigontech/erigon-lib/types" "github.com/erigontech/erigon/core" + "github.com/erigontech/erigon/execution/testutil" ) // TransactionTest checks RLP decoding and sender derivation of transactions. @@ -117,16 +118,16 @@ func (tt *TransactionTest) Run(chainID *big.Int) error { fork ttFork config *chain.Config }{ - {"Frontier", types.MakeFrontierSigner(), tt.Forks.Frontier, Forks["Frontier"]}, - {"Homestead", types.LatestSignerForChainID(nil), tt.Forks.Homestead, Forks["Homestead"]}, - {"EIP150", types.LatestSignerForChainID(nil), tt.Forks.EIP150, Forks["EIP150"]}, - {"EIP158", types.LatestSignerForChainID(chainID), tt.Forks.EIP158, Forks["EIP158"]}, - {"Byzantium", types.LatestSignerForChainID(chainID), tt.Forks.Byzantium, Forks["Byzantium"]}, - {"Constantinople", types.LatestSignerForChainID(chainID), tt.Forks.Constantinople, Forks["Constantinople"]}, - {"ConstantinopleFix", types.LatestSignerForChainID(chainID), tt.Forks.ConstantinopleFix, Forks["ConstantinopleFix"]}, - {"Istanbul", types.LatestSignerForChainID(chainID), tt.Forks.Istanbul, Forks["Istanbul"]}, - {"Berlin", types.LatestSignerForChainID(chainID), tt.Forks.Berlin, Forks["Berlin"]}, - {"London", types.LatestSignerForChainID(chainID), tt.Forks.London, Forks["London"]}, + {"Frontier", types.MakeFrontierSigner(), tt.Forks.Frontier, testutil.Forks["Frontier"]}, + {"Homestead", types.LatestSignerForChainID(nil), tt.Forks.Homestead, testutil.Forks["Homestead"]}, + {"EIP150", types.LatestSignerForChainID(nil), tt.Forks.EIP150, testutil.Forks["EIP150"]}, + {"EIP158", types.LatestSignerForChainID(chainID), tt.Forks.EIP158, testutil.Forks["EIP158"]}, + {"Byzantium", types.LatestSignerForChainID(chainID), tt.Forks.Byzantium, testutil.Forks["Byzantium"]}, + {"Constantinople", types.LatestSignerForChainID(chainID), tt.Forks.Constantinople, testutil.Forks["Constantinople"]}, + {"ConstantinopleFix", types.LatestSignerForChainID(chainID), tt.Forks.ConstantinopleFix, testutil.Forks["ConstantinopleFix"]}, + {"Istanbul", types.LatestSignerForChainID(chainID), tt.Forks.Istanbul, testutil.Forks["Istanbul"]}, + {"Berlin", types.LatestSignerForChainID(chainID), tt.Forks.Berlin, testutil.Forks["Berlin"]}, + {"London", types.LatestSignerForChainID(chainID), tt.Forks.London, testutil.Forks["London"]}, } { sender, txhash, intrinsicGas, err := validateTx(tt.RLP, *testcase.signer, testcase.config.Rules(0, 0)) From 241e4b0b1cfaf162807e57cda04e2bc817d2af2b Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 21 May 2025 15:06:00 +0200 Subject: [PATCH 05/13] Simplify txpool.New --- cmd/utils/flags.go | 1 - erigon-lib/chain/chain_config.go | 20 ------------- txnprovider/txpool/assemble.go | 16 ---------- txnprovider/txpool/pool.go | 36 +++++++++++------------ txnprovider/txpool/pool_fuzz_test.go | 4 +-- txnprovider/txpool/pool_test.go | 35 +++++++++++----------- txnprovider/txpool/txpoolcfg/txpoolcfg.go | 2 -- 7 files changed, 36 insertions(+), 78 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f17597d7911..4cca0fd3a3c 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2071,7 +2071,6 @@ func SetEthConfig(ctx *cli.Context, nodeConfig *nodecfg.Config, cfg *ethconfig.C if ctx.IsSet(OverridePragueFlag.Name) { cfg.OverridePragueTime = flags.GlobalBig(ctx, OverridePragueFlag.Name) - cfg.TxPool.OverridePragueTime = cfg.OverridePragueTime } if clparams.EmbeddedSupported(cfg.NetworkID) || cfg.CaplinConfig.IsDevnet() { diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 6140f58c1c7..727bf369609 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -118,26 +118,6 @@ var ( Ethash: new(EthashConfig), } - TestChainConfigCancun = &Config{ - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - TangerineWhistleBlock: big.NewInt(0), - SpuriousDragonBlock: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - ArrowGlacierBlock: big.NewInt(0), - GrayGlacierBlock: big.NewInt(0), - TerminalTotalDifficulty: big.NewInt(0), - TerminalTotalDifficultyPassed: true, - ShanghaiTime: big.NewInt(0), - CancunTime: big.NewInt(0), - } - TestChainAuraConfig = &Config{ ChainID: big.NewInt(1), Consensus: AuRaConsensus, diff --git a/txnprovider/txpool/assemble.go b/txnprovider/txpool/assemble.go index 9e4933d2373..b63bd6cb5b0 100644 --- a/txnprovider/txpool/assemble.go +++ b/txnprovider/txpool/assemble.go @@ -18,7 +18,6 @@ package txpool import ( "context" - "math/big" "github.com/c2h5oh/datasize" "github.com/holiman/uint256" @@ -58,17 +57,6 @@ func Assemble( chainID, _ := uint256.FromBig(chainConfig.ChainID) - shanghaiTime := chainConfig.ShanghaiTime - var agraBlock *big.Int - if chainConfig.Bor != nil { - agraBlock = chainConfig.Bor.GetAgraBlock() - } - cancunTime := chainConfig.CancunTime - pragueTime := chainConfig.PragueTime - if cfg.OverridePragueTime != nil { - pragueTime = cfg.OverridePragueTime - } - newTxns := make(chan Announcements, 1024) newSlotsStreams := &NewSlotsStreams{} pool, err := New( @@ -79,10 +67,6 @@ func Assemble( cfg, cache, chainConfig, - shanghaiTime, - agraBlock, - cancunTime, - pragueTime, sentryClients, stateChangesClient, builderNotifyNewTxns, diff --git a/txnprovider/txpool/pool.go b/txnprovider/txpool/pool.go index 2203ad9bcc4..ea6d1ea27ab 100644 --- a/txnprovider/txpool/pool.go +++ b/txnprovider/txpool/pool.go @@ -24,7 +24,6 @@ import ( "errors" "fmt" "math" - "math/big" "sync" "sync/atomic" "time" @@ -174,10 +173,6 @@ func New( cfg txpoolcfg.Config, cache kvcache.Cache, chainConfig *chain.Config, - shanghaiTime *big.Int, - agraBlock *big.Int, - cancunTime *big.Int, - pragueTime *big.Int, sentryClients []sentryproto.SentryClient, stateChangesClient StateChangesClient, builderNotifyNewTxns func(), @@ -249,32 +244,35 @@ func New( }), } - if shanghaiTime != nil { - if !shanghaiTime.IsUint64() { + if chainConfig.ShanghaiTime != nil { + if !chainConfig.ShanghaiTime.IsUint64() { return nil, errors.New("shanghaiTime overflow") } - shanghaiTimeU64 := shanghaiTime.Uint64() + shanghaiTimeU64 := chainConfig.ShanghaiTime.Uint64() res.shanghaiTime = &shanghaiTimeU64 } - if agraBlock != nil { - if !agraBlock.IsUint64() { - return nil, errors.New("agraBlock overflow") + if chainConfig.Bor != nil { + agraBlock := chainConfig.Bor.GetAgraBlock() + if agraBlock != nil { + if !agraBlock.IsUint64() { + return nil, errors.New("agraBlock overflow") + } + agraBlockU64 := agraBlock.Uint64() + res.agraBlock = &agraBlockU64 } - agraBlockU64 := agraBlock.Uint64() - res.agraBlock = &agraBlockU64 } - if cancunTime != nil { - if !cancunTime.IsUint64() { + if chainConfig.CancunTime != nil { + if !chainConfig.CancunTime.IsUint64() { return nil, errors.New("cancunTime overflow") } - cancunTimeU64 := cancunTime.Uint64() + cancunTimeU64 := chainConfig.CancunTime.Uint64() res.cancunTime = &cancunTimeU64 } - if pragueTime != nil { - if !pragueTime.IsUint64() { + if chainConfig.PragueTime != nil { + if !chainConfig.PragueTime.IsUint64() { return nil, errors.New("pragueTime overflow") } - pragueTimeU64 := pragueTime.Uint64() + pragueTimeU64 := chainConfig.PragueTime.Uint64() res.pragueTime = &pragueTimeU64 } diff --git a/txnprovider/txpool/pool_fuzz_test.go b/txnprovider/txpool/pool_fuzz_test.go index 36efd95efe5..d6f1a8f1d95 100644 --- a/txnprovider/txpool/pool_fuzz_test.go +++ b/txnprovider/txpool/pool_fuzz_test.go @@ -329,7 +329,7 @@ func FuzzOnNewBlocks(f *testing.F) { cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) err = pool.start(ctx) @@ -555,7 +555,7 @@ func FuzzOnNewBlocks(f *testing.F) { check(p2pReceived, TxnSlots{}, "after_flush") checkNotify(p2pReceived, TxnSlots{}, "after_flush") - p2, err := New(ctx, ch, db, coreDB, txpoolcfg.DefaultConfig, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + p2, err := New(ctx, ch, db, coreDB, txpoolcfg.DefaultConfig, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) p2.senders = pool.senders // senders are not persisted diff --git a/txnprovider/txpool/pool_test.go b/txnprovider/txpool/pool_test.go index 89786f25413..78a388309fc 100644 --- a/txnprovider/txpool/pool_test.go +++ b/txnprovider/txpool/pool_test.go @@ -21,7 +21,6 @@ import ( "context" "fmt" "math" - "math/big" "testing" "github.com/holiman/uint256" @@ -46,6 +45,7 @@ import ( "github.com/erigontech/erigon-lib/state" "github.com/erigontech/erigon-lib/types" accounts3 "github.com/erigontech/erigon-lib/types/accounts" + "github.com/erigontech/erigon/execution/testutil" "github.com/erigontech/erigon/txnprovider/txpool/txpoolcfg" ) @@ -58,7 +58,7 @@ func TestNonceFromAddress(t *testing.T) { db := memdb.NewTestPoolDB(t) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -312,7 +312,7 @@ func TestMultipleAuthorizations(t *testing.T) { cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, common.Big0 /* shanghaiTime */, nil /* agraBlock */, common.Big0 /* cancunTime */, common.Big0 /* pragueTime */, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, testutil.Forks["Prague"], nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(t, err) require.NotEqual(t, pool, nil) @@ -437,7 +437,7 @@ func TestReplaceWithHigherFee(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotNil(pool) var stateVersionID uint64 = 0 @@ -560,7 +560,7 @@ func TestReverseNonces(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -690,7 +690,7 @@ func TestTxnPoke(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -913,9 +913,9 @@ func TestShanghaiValidateTxn(t *testing.T) { cfg := txpoolcfg.DefaultConfig - var shanghaiTime *big.Int + chainConfig := testutil.Forks["Paris"] if test.isShanghai { - shanghaiTime = big.NewInt(0) + chainConfig = testutil.Forks["Shanghai"] } ctx, cancel := context.WithCancel(context.Background()) @@ -927,7 +927,7 @@ func TestShanghaiValidateTxn(t *testing.T) { asrt.NoError(err) defer sd.Close() cache := kvcache.NewDummy() - pool, err := New(ctx, ch, nil, coreDB, cfg, cache, chain.TestChainConfig, shanghaiTime, nil /* agraBlock */, nil /* cancunTime */, nil, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) + pool, err := New(ctx, ch, nil, coreDB, cfg, cache, chainConfig, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) asrt.NoError(err) sndr := accounts3.Account{Nonce: 0, Balance: *uint256.NewInt(math.MaxUint64)} @@ -973,7 +973,7 @@ func TestTooHighGasLimitTxnValidation(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -1039,8 +1039,7 @@ func TestSetCodeTxnValidationWithLargeAuthorizationValues(t *testing.T) { chainConfig.ChainID = maxUint256.ToBig() cache := kvcache.NewDummy() logger := log.New() - pool, err := New(ctx, ch, nil, coreDB, cfg, cache, chain.TestChainConfigCancun, common.Big0 /* shanghaiTime */, nil, /* agraBlock */ - common.Big0 /* cancunTime */, common.Big0 /* pragueTime */, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) + pool, err := New(ctx, ch, nil, coreDB, cfg, cache, testutil.Forks["Prague"], nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) require.NoError(t, err) pool.blockGasLimit.Store(30_000_000) tx, err := coreDB.BeginTemporalRw(ctx) @@ -1089,7 +1088,7 @@ func TestBlobTxnReplacement(t *testing.T) { t.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfigCancun, common.Big0, nil, common.Big0, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, testutil.Forks["Cancun"], nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) @@ -1273,7 +1272,7 @@ func TestDropRemoteAtNoGossip(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) t.Cleanup(cancel) - txnPool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) + txnPool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, testutil.Forks["Shanghai"], nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(txnPool, nil) @@ -1384,7 +1383,7 @@ func TestBlobSlots(t *testing.T) { cfg.TotalBlobPoolLimit = 20 sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfigCancun, common.Big0, nil, common.Big0, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, testutil.Forks["Cancun"], nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -1467,7 +1466,7 @@ func TestGetBlobsV1(t *testing.T) { cfg.TotalBlobPoolLimit = 20 sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfigCancun, common.Big0, nil, common.Big0, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, testutil.Forks["Cancun"], nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) pool.blockGasLimit.Store(30000000) @@ -1542,7 +1541,7 @@ func TestGasLimitChanged(t *testing.T) { db := memdb.NewTestPoolDB(t) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) var stateVersionID uint64 = 0 @@ -1626,7 +1625,7 @@ func BenchmarkProcessRemoteTxns(b *testing.B) { b.Cleanup(cancel) cfg := txpoolcfg.DefaultConfig sendersCache := kvcache.New(kvcache.DefaultCoherentConfig) - pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, nil, nil, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) + pool, err := New(ctx, ch, db, coreDB, cfg, sendersCache, chain.TestChainConfig, nil, nil, func() {}, nil, nil, log.New(), WithFeeCalculator(nil)) require.NoError(err) require.NotEqual(pool, nil) diff --git a/txnprovider/txpool/txpoolcfg/txpoolcfg.go b/txnprovider/txpool/txpoolcfg/txpoolcfg.go index 2c0b6d23dfd..06c27815dd7 100644 --- a/txnprovider/txpool/txpoolcfg/txpoolcfg.go +++ b/txnprovider/txpool/txpoolcfg/txpoolcfg.go @@ -18,7 +18,6 @@ package txpoolcfg import ( "fmt" - "math/big" "time" "github.com/c2h5oh/datasize" @@ -42,7 +41,6 @@ type Config struct { TotalBlobPoolLimit uint64 // Total number of blobs (not txns) allowed within the txpool PriceBump uint64 // Price bump percentage to replace an already existing transaction BlobPriceBump uint64 //Price bump percentage to replace an existing 4844 blob txn (type-3) - OverridePragueTime *big.Int // regular batch tasks processing SyncToNewPeersEvery time.Duration From 15674b17efc87454bffbe41ea1b294cc2d007fda Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 21 May 2025 15:26:22 +0200 Subject: [PATCH 06/13] Switch to BPO forks --- erigon-lib/chain/chain_config.go | 34 +++++++++++++++++++++------ erigon-lib/chain/chain_config_test.go | 21 +++++++++-------- 2 files changed, 38 insertions(+), 17 deletions(-) diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 727bf369609..37cd3941ea1 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -20,7 +20,6 @@ import ( "encoding/json" "fmt" "math/big" - "strconv" "sync" "time" @@ -79,6 +78,11 @@ type Config struct { BlobSchedule map[string]*params.BlobConfig `json:"blobSchedule,omitempty"` parseBlobScheduleOnce sync.Once `copier:"-"` parsedBlobSchedule map[uint64]*params.BlobConfig + Bpo1Time *big.Int `json:"bpo1Time,omitempty"` + Bpo2Time *big.Int `json:"bpo2Time,omitempty"` + Bpo3Time *big.Int `json:"bpo3Time,omitempty"` + Bpo4Time *big.Int `json:"bpo4Time,omitempty"` + Bpo5Time *big.Int `json:"bpo5Time,omitempty"` // (Optional) governance contract where EIP-1559 fees will be sent to, which otherwise would be burnt since the London fork. // A key corresponds to the block number, starting from which the fees are sent to the address (map value). @@ -169,13 +173,15 @@ func (c *Config) String() string { ) } - return fmt.Sprintf("{ChainID: %v, Terminal Total Difficulty: %v, Shapella: %v, Dencun: %v, Pectra: %v, Fusaka: %v, Engine: %v}", + return fmt.Sprintf("{ChainID: %v, Terminal Total Difficulty: %v, Shapella: %v, Dencun: %v, Pectra: %v, Fusaka: %v, BPO1: %v, BPO2: %v, Engine: %v}", c.ChainID, c.TerminalTotalDifficulty, timestampToTime(c.ShanghaiTime), timestampToTime(c.CancunTime), timestampToTime(c.PragueTime), timestampToTime(c.OsakaTime), + timestampToTime(c.Bpo1Time), + timestampToTime(c.Bpo2Time), engine, ) } @@ -341,12 +347,26 @@ func (c *Config) getBlobConfig(time uint64) *params.BlobConfig { if c.OsakaTime != nil { c.parsedBlobSchedule[c.OsakaTime.Uint64()] = val } - default: - keyU64, err := strconv.ParseUint(key, 10, 64) - if err != nil { - panic(err) + case key == "bpo1": + if c.Bpo1Time != nil { + c.parsedBlobSchedule[c.Bpo1Time.Uint64()] = val + } + case key == "bpo2": + if c.Bpo2Time != nil { + c.parsedBlobSchedule[c.Bpo2Time.Uint64()] = val + } + case key == "bpo3": + if c.Bpo3Time != nil { + c.parsedBlobSchedule[c.Bpo3Time.Uint64()] = val + } + case key == "bpo4": + if c.Bpo4Time != nil { + c.parsedBlobSchedule[c.Bpo4Time.Uint64()] = val + } + case key == "bpo5": + if c.Bpo5Time != nil { + c.parsedBlobSchedule[c.Bpo5Time.Uint64()] = val } - c.parsedBlobSchedule[keyU64] = val } } }) diff --git a/erigon-lib/chain/chain_config_test.go b/erigon-lib/chain/chain_config_test.go index b3b75820c92..9f843226896 100644 --- a/erigon-lib/chain/chain_config_test.go +++ b/erigon-lib/chain/chain_config_test.go @@ -18,7 +18,6 @@ package chain import ( "math/big" - "strconv" "testing" "github.com/stretchr/testify/assert" @@ -110,12 +109,14 @@ func TestNilBlobSchedule(t *testing.T) { func TestBlobParameterOnlyHardforks(t *testing.T) { cancunTime := uint64(1710338135) pragueTime := uint64(1746612311) - timeA := uint64(1775065900) - timeB := uint64(1785952240) + bpo1time := uint64(1775065900) + bpo2time := uint64(1785952240) var c Config c.CancunTime = big.NewInt(int64(cancunTime)) c.PragueTime = big.NewInt(int64(pragueTime)) + c.Bpo1Time = big.NewInt(int64(bpo1time)) + c.Bpo2Time = big.NewInt(int64(bpo2time)) c.BlobSchedule = map[string]*params.BlobConfig{ "cancun": { @@ -128,12 +129,12 @@ func TestBlobParameterOnlyHardforks(t *testing.T) { Max: 9, BaseFeeUpdateFraction: 5007716, }, - strconv.FormatUint(timeA, 10): { + "bpo1": { Target: 24, Max: 48, BaseFeeUpdateFraction: 5007716, }, - strconv.FormatUint(timeB, 10): { + "bpo2": { Target: 36, Max: 56, BaseFeeUpdateFraction: 5007716, @@ -160,27 +161,27 @@ func TestBlobParameterOnlyHardforks(t *testing.T) { assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) - time = (pragueTime + timeA) / 2 + time = (pragueTime + bpo1time) / 2 assert.Equal(t, 6*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) - time = timeA + time = bpo1time assert.Equal(t, 24*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) assert.Equal(t, uint64(48), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) - time = (timeA + timeB) / 2 + time = (bpo1time + bpo2time) / 2 assert.Equal(t, 24*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) assert.Equal(t, uint64(48), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) - time = timeB + time = bpo2time assert.Equal(t, 36*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) assert.Equal(t, uint64(56), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) - time = timeB * 2 + time = bpo2time * 2 assert.Equal(t, 36*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(time)) assert.Equal(t, uint64(56), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) From 9f683e42e534c16d919e599c0752fa6bf3ed58d3 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 21 May 2025 15:38:58 +0200 Subject: [PATCH 07/13] fix TestSetCodeTxnValidationWithLargeAuthorizationValues --- erigon-lib/chain/params/protocol.go | 1 - txnprovider/txpool/pool_test.go | 6 ++++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/erigon-lib/chain/params/protocol.go b/erigon-lib/chain/params/protocol.go index 6c68f0b0f5f..5b0e182cf75 100644 --- a/erigon-lib/chain/params/protocol.go +++ b/erigon-lib/chain/params/protocol.go @@ -221,7 +221,6 @@ var ( ) // See EIP-7840: Add blob schedule to EL config files -// and EIP-7892: Blob Parameter Only Hardforks type BlobConfig struct { Target uint64 `json:"target"` Max uint64 `json:"max"` diff --git a/txnprovider/txpool/pool_test.go b/txnprovider/txpool/pool_test.go index 78a388309fc..9e6bed8ef12 100644 --- a/txnprovider/txpool/pool_test.go +++ b/txnprovider/txpool/pool_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/holiman/uint256" + "github.com/jinzhu/copier" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -1035,11 +1036,12 @@ func TestSetCodeTxnValidationWithLargeAuthorizationValues(t *testing.T) { ch := make(chan Announcements, 1) coreDB := temporaltest.NewTestDB(t, datadir.New(t.TempDir())) cfg := txpoolcfg.DefaultConfig - chainConfig := new(chain.Config) + var chainConfig chain.Config + copier.Copy(&chainConfig, testutil.Forks["Prague"]) chainConfig.ChainID = maxUint256.ToBig() cache := kvcache.NewDummy() logger := log.New() - pool, err := New(ctx, ch, nil, coreDB, cfg, cache, testutil.Forks["Prague"], nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) + pool, err := New(ctx, ch, nil, coreDB, cfg, cache, &chainConfig, nil, nil, func() {}, nil, nil, logger, WithFeeCalculator(nil)) require.NoError(t, err) pool.blockGasLimit.Store(30_000_000) tx, err := coreDB.BeginTemporalRw(ctx) From 05ca14005f46999c94aadce1e48d882b753ce23a Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 21 May 2025 18:16:26 +0200 Subject: [PATCH 08/13] fixed iteration order --- erigon-lib/chain/chain_config.go | 66 +++++++++++++++----------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 37cd3941ea1..c9b1444d0a5 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -333,41 +333,37 @@ func (c *Config) getBlobConfig(time uint64) *params.BlobConfig { } // Override with supplied values - for key, val := range c.BlobSchedule { - switch { - case key == "cancun": - if c.CancunTime != nil { - c.parsedBlobSchedule[c.CancunTime.Uint64()] = val - } - case key == "prague": - if c.PragueTime != nil { - c.parsedBlobSchedule[c.PragueTime.Uint64()] = val - } - case key == "osaka": - if c.OsakaTime != nil { - c.parsedBlobSchedule[c.OsakaTime.Uint64()] = val - } - case key == "bpo1": - if c.Bpo1Time != nil { - c.parsedBlobSchedule[c.Bpo1Time.Uint64()] = val - } - case key == "bpo2": - if c.Bpo2Time != nil { - c.parsedBlobSchedule[c.Bpo2Time.Uint64()] = val - } - case key == "bpo3": - if c.Bpo3Time != nil { - c.parsedBlobSchedule[c.Bpo3Time.Uint64()] = val - } - case key == "bpo4": - if c.Bpo4Time != nil { - c.parsedBlobSchedule[c.Bpo4Time.Uint64()] = val - } - case key == "bpo5": - if c.Bpo5Time != nil { - c.parsedBlobSchedule[c.Bpo5Time.Uint64()] = val - } - } + val, ok := c.BlobSchedule["cancun"] + if ok && c.CancunTime != nil { + c.parsedBlobSchedule[c.CancunTime.Uint64()] = val + } + val, ok = c.BlobSchedule["prague"] + if ok && c.PragueTime != nil { + c.parsedBlobSchedule[c.PragueTime.Uint64()] = val + } + val, ok = c.BlobSchedule["osaka"] + if ok && c.OsakaTime != nil { + c.parsedBlobSchedule[c.OsakaTime.Uint64()] = val + } + val, ok = c.BlobSchedule["bpo1"] + if ok && c.Bpo1Time != nil { + c.parsedBlobSchedule[c.Bpo1Time.Uint64()] = val + } + val, ok = c.BlobSchedule["bpo2"] + if ok && c.Bpo2Time != nil { + c.parsedBlobSchedule[c.Bpo2Time.Uint64()] = val + } + val, ok = c.BlobSchedule["bpo3"] + if ok && c.Bpo3Time != nil { + c.parsedBlobSchedule[c.Bpo3Time.Uint64()] = val + } + val, ok = c.BlobSchedule["bpo4"] + if ok && c.Bpo4Time != nil { + c.parsedBlobSchedule[c.Bpo4Time.Uint64()] = val + } + val, ok = c.BlobSchedule["bpo5"] + if ok && c.Bpo5Time != nil { + c.parsedBlobSchedule[c.Bpo5Time.Uint64()] = val } }) From 7142cf590162de0d01f659312ced4a4b4427b90b Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 21 May 2025 20:35:06 +0200 Subject: [PATCH 09/13] TestBlobParameterDencunAndPectraAtGenesis --- erigon-lib/chain/chain_config_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/erigon-lib/chain/chain_config_test.go b/erigon-lib/chain/chain_config_test.go index 9f843226896..24dbeaaa2ea 100644 --- a/erigon-lib/chain/chain_config_test.go +++ b/erigon-lib/chain/chain_config_test.go @@ -219,3 +219,27 @@ func TestBlobParameterInactiveHardfork(t *testing.T) { assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(time)) assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(time)) } + +func TestBlobParameterDencunAndPectraAtGenesis(t *testing.T) { + var c Config + c.CancunTime = big.NewInt(0) + c.PragueTime = big.NewInt(0) + + c.BlobSchedule = map[string]*params.BlobConfig{ + "cancun": { + Target: 3, + Max: 6, + BaseFeeUpdateFraction: 3338477, + }, + "prague": { + Target: 6, + Max: 9, + BaseFeeUpdateFraction: 5007716, + }, + } + + // Prague should take priority + assert.Equal(t, 6*params.BlobGasPerBlob, c.GetTargetBlobGasPerBlock(0)) + assert.Equal(t, uint64(9), c.GetMaxBlobsPerBlock(0)) + assert.Equal(t, uint64(5007716), c.GetBlobGasPriceUpdateFraction(0)) +} From b807495d38bee4f3d8f67ec2f32911bbc1eb7523 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Thu, 22 May 2025 14:18:45 +0200 Subject: [PATCH 10/13] lint --- tests/block_test_util.go | 2 +- tests/state_test_util.go | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 5b43325811f..792424b02c4 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -120,7 +120,7 @@ type btHeaderMarshaling struct { func (bt *BlockTest) Run(t *testing.T, checkStateRoot bool) error { config, ok := testutil.Forks[bt.json.Network] if !ok { - return testutil.UnsupportedForkError{bt.json.Network} + return testutil.UnsupportedForkError{Name: bt.json.Network} } engine := ethconsensusconfig.CreateConsensusEngineBareBones(context.Background(), config, log.New()) diff --git a/tests/state_test_util.go b/tests/state_test_util.go index 32c13d71cc8..baa658f57a8 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -141,7 +141,7 @@ func GetChainConfig(forkString string) (baseConfig *chain.Config, eips []int, er baseName, eipsStrings = splitForks[0], splitForks[1:] ) if baseConfig, ok = testutil.Forks[baseName]; !ok { - return nil, nil, testutil.UnsupportedForkError{baseName} + return nil, nil, testutil.UnsupportedForkError{Name: baseName} } for _, eip := range eipsStrings { if eipNum, err := strconv.Atoi(eip); err != nil { @@ -189,12 +189,12 @@ func (t *StateTest) Run(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Config, di func (t *StateTest) RunNoVerify(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Config, dirs datadir.Dirs) (*state.IntraBlockState, common.Hash, error) { config, eips, err := GetChainConfig(subtest.Fork) if err != nil { - return nil, common.Hash{}, testutil.UnsupportedForkError{subtest.Fork} + return nil, common.Hash{}, testutil.UnsupportedForkError{Name: subtest.Fork} } vmconfig.ExtraEips = eips block, _, err := core.GenesisToBlock(t.genesis(config), dirs, log.Root()) if err != nil { - return nil, common.Hash{}, testutil.UnsupportedForkError{subtest.Fork} + return nil, common.Hash{}, testutil.UnsupportedForkError{Name: subtest.Fork} } readBlockNr := block.NumberU64() @@ -202,13 +202,13 @@ func (t *StateTest) RunNoVerify(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Co _, err = MakePreState(&chain.Rules{}, tx, t.json.Pre, readBlockNr) if err != nil { - return nil, common.Hash{}, testutil.UnsupportedForkError{subtest.Fork} + return nil, common.Hash{}, testutil.UnsupportedForkError{Name: subtest.Fork} } txc := wrap.NewTxContainer(tx, nil) domains, err := state2.NewSharedDomains(txc.Ttx, log.New()) if err != nil { - return nil, common.Hash{}, testutil.UnsupportedForkError{subtest.Fork} + return nil, common.Hash{}, testutil.UnsupportedForkError{Name: subtest.Fork} } defer domains.Close() txc.Doms = domains From 6a1eca56c12a0eac438095f5e8886ab707106a80 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Thu, 22 May 2025 14:31:37 +0200 Subject: [PATCH 11/13] more lint --- tests/difficulty_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/difficulty_test.go b/tests/difficulty_test.go index 78a180d275c..1ac5e61e04d 100644 --- a/tests/difficulty_test.go +++ b/tests/difficulty_test.go @@ -47,7 +47,7 @@ func TestDifficulty(t *testing.T) { cfg, ok := testutil.Forks[fork] if !ok { - t.Error(testutil.UnsupportedForkError{fork}) + t.Error(testutil.UnsupportedForkError{Name: fork}) continue } From a15937b09230fcd11c01d3c46d04add370d4c46a Mon Sep 17 00:00:00 2001 From: yperbasis Date: Wed, 28 May 2025 13:15:03 +0200 Subject: [PATCH 12/13] print all BPO times --- erigon-lib/chain/chain_config.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index d56e84c39dd..006035d7c12 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -198,7 +198,7 @@ func (c *Config) String() string { ) } - return fmt.Sprintf("{ChainID: %v, Terminal Total Difficulty: %v, Shapella: %v, Dencun: %v, Pectra: %v, Fusaka: %v, BPO1: %v, BPO2: %v, Engine: %v}", + return fmt.Sprintf("{ChainID: %v, Terminal Total Difficulty: %v, Shapella: %v, Dencun: %v, Pectra: %v, Fusaka: %v, BPO1: %v, BPO2: %v, BPO3: %v, BPO4: %v, BPO5: %v, Engine: %v}", c.ChainID, c.TerminalTotalDifficulty, timestampToTime(c.ShanghaiTime), @@ -207,6 +207,9 @@ func (c *Config) String() string { timestampToTime(c.OsakaTime), timestampToTime(c.Bpo1Time), timestampToTime(c.Bpo2Time), + timestampToTime(c.Bpo3Time), + timestampToTime(c.Bpo4Time), + timestampToTime(c.Bpo5Time), engine, ) } From 7fc59bfc9830f2e5e182d2fdaa62b182168e3715 Mon Sep 17 00:00:00 2001 From: yperbasis Date: Thu, 29 May 2025 10:57:56 +0200 Subject: [PATCH 13/13] cosmetics --- erigon-lib/chain/chain_config.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index d53d06915b2..aeb4d10be1d 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -76,13 +76,13 @@ type Config struct { // Optional EIP-4844 parameters (see also EIP-7691, EIP-7840, EIP-7892) MinBlobGasPrice *uint64 `json:"minBlobGasPrice,omitempty"` BlobSchedule map[string]*params.BlobConfig `json:"blobSchedule,omitempty"` + Bpo1Time *big.Int `json:"bpo1Time,omitempty"` + Bpo2Time *big.Int `json:"bpo2Time,omitempty"` + Bpo3Time *big.Int `json:"bpo3Time,omitempty"` + Bpo4Time *big.Int `json:"bpo4Time,omitempty"` + Bpo5Time *big.Int `json:"bpo5Time,omitempty"` parseBlobScheduleOnce sync.Once `copier:"-"` parsedBlobSchedule map[uint64]*params.BlobConfig - Bpo1Time *big.Int `json:"bpo1Time,omitempty"` - Bpo2Time *big.Int `json:"bpo2Time,omitempty"` - Bpo3Time *big.Int `json:"bpo3Time,omitempty"` - Bpo4Time *big.Int `json:"bpo4Time,omitempty"` - Bpo5Time *big.Int `json:"bpo5Time,omitempty"` // (Optional) governance contract where EIP-1559 fees will be sent to, which otherwise would be burnt since the London fork. // A key corresponds to the block number, starting from which the fees are sent to the address (map value).