From a677b73e15a3f26830fbc2d92a72fc9763b7de42 Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Wed, 1 May 2024 12:59:30 +0200 Subject: [PATCH] Turn NoPruneContracts into DepositContract --- cmd/integration/commands/stages.go | 2 +- erigon-lib/chain/chain_config.go | 12 +++--- eth/stagedsync/stage_execute.go | 7 ++-- eth/stagedsync/stage_log_index.go | 51 ++++++++++++++------------ eth/stagedsync/stage_log_index_test.go | 3 +- params/chainspecs/chiado.json | 8 ++-- params/chainspecs/gnosis.json | 8 ++-- params/chainspecs/goerli.json | 4 +- params/chainspecs/holesky.json | 6 +-- params/chainspecs/mainnet.json | 6 +-- params/chainspecs/sepolia.json | 6 +-- turbo/stages/stageloop.go | 14 +++---- 12 files changed, 58 insertions(+), 69 deletions(-) diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 428903d3fab..2582c7c1478 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -1268,7 +1268,7 @@ func stageLogIndex(db kv.RwDB, ctx context.Context, logger log.Logger) error { logger.Info("Stage exec", "progress", execAt) logger.Info("Stage", "name", s.ID, "progress", s.BlockNumber) - cfg := stagedsync.StageLogIndexCfg(db, pm, dirs.Tmp, chainConfig.NoPruneContracts) + cfg := stagedsync.StageLogIndexCfg(db, pm, dirs.Tmp, chainConfig.DepositContract) if unwind > 0 { u := sync.NewUnwindState(stages.LogIndex, s.BlockNumber-unwind, s.BlockNumber) err = stagedsync.UnwindLogIndex(u, s, tx, cfg, ctx) diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 9c61e3cc351..adce07b9941 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -78,6 +78,10 @@ type Config struct { // (Optional) governance contract where EIP-1559 fees will be sent to that otherwise would be burnt since the London fork BurntContract map[string]common.Address `json:"burntContract,omitempty"` + // (Optional) deposit contract of PoS chains + // See also EIP-6110: Supply validator deposits on chain + DepositContract *common.Address `json:"depositContract,omitempty"` + // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty"` Clique *CliqueConfig `json:"clique,omitempty"` @@ -85,11 +89,6 @@ type Config struct { Bor BorConfig `json:"-"` BorJSON json.RawMessage `json:"bor,omitempty"` - - // For not pruning the logs of these contracts - // For deposit contract logs are needed by CL to validate/produce blocks. - // All logs should be available to a validating node through eth_getLogs - NoPruneContracts map[common.Address]bool `json:"noPruneContracts,omitempty"` } type BorConfig interface { @@ -104,7 +103,7 @@ type BorConfig interface { func (c *Config) String() string { engine := c.getEngine() - return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v, Prague: %v, Osaka: %v, Engine: %v, NoPruneContracts: %v}", + return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v, Prague: %v, Osaka: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -126,7 +125,6 @@ func (c *Config) String() string { c.PragueTime, c.OsakaTime, engine, - c.NoPruneContracts, ) } diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go index 1686e399c26..30f0343f476 100644 --- a/eth/stagedsync/stage_execute.go +++ b/eth/stagedsync/stage_execute.go @@ -204,17 +204,16 @@ func executeBlock( return nil } -// Filters out and keeps receipts of contracts that may be needed by CL, such as deposit contrac, -// The list of contracts to filter is config-specified +// Filters out and keeps receipts of the contracts that may be needed by CL, namely of the deposit contract. func gatherNoPruneReceipts(receipts *types.Receipts, chainCfg *chain.Config) bool { cr := types.Receipts{} for _, r := range *receipts { toStore := false - if chainCfg.NoPruneContracts != nil && chainCfg.NoPruneContracts[r.ContractAddress] { + if chainCfg.DepositContract != nil && *chainCfg.DepositContract == r.ContractAddress { toStore = true } else { for _, l := range r.Logs { - if chainCfg.NoPruneContracts != nil && chainCfg.NoPruneContracts[l.Address] { + if chainCfg.DepositContract != nil && *chainCfg.DepositContract == l.Address { toStore = true break } diff --git a/eth/stagedsync/stage_log_index.go b/eth/stagedsync/stage_log_index.go index 1628964167c..82cb3177602 100644 --- a/eth/stagedsync/stage_log_index.go +++ b/eth/stagedsync/stage_log_index.go @@ -9,17 +9,17 @@ import ( "slices" "time" - "github.com/ledgerwatch/erigon-lib/kv/dbutils" - "github.com/RoaringBitmap/roaring" "github.com/c2h5oh/datasize" + "github.com/ledgerwatch/log/v3" + libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/dbg" "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/etl" "github.com/ledgerwatch/erigon-lib/kv" "github.com/ledgerwatch/erigon-lib/kv/bitmapdb" - "github.com/ledgerwatch/log/v3" + "github.com/ledgerwatch/erigon-lib/kv/dbutils" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/ethdb/cbor" @@ -32,22 +32,25 @@ const ( ) type LogIndexCfg struct { - tmpdir string - db kv.RwDB - prune prune.Mode - bufLimit datasize.ByteSize - flushEvery time.Duration - noPruneContracts map[libcommon.Address]bool + tmpdir string + db kv.RwDB + prune prune.Mode + bufLimit datasize.ByteSize + flushEvery time.Duration + + // For not pruning the logs of this contract since deposit contract logs are needed by CL to validate/produce blocks. + // All logs should be available to a validating node through eth_getLogs + depositContract *libcommon.Address } -func StageLogIndexCfg(db kv.RwDB, prune prune.Mode, tmpDir string, noPruneContracts map[libcommon.Address]bool) LogIndexCfg { +func StageLogIndexCfg(db kv.RwDB, prune prune.Mode, tmpDir string, depositContract *libcommon.Address) LogIndexCfg { return LogIndexCfg{ - db: db, - prune: prune, - bufLimit: bitmapsBufLimit, - flushEvery: bitmapsFlushEvery, - tmpdir: tmpDir, - noPruneContracts: noPruneContracts, + db: db, + prune: prune, + bufLimit: bitmapsBufLimit, + flushEvery: bitmapsFlushEvery, + tmpdir: tmpDir, + depositContract: depositContract, } } @@ -106,7 +109,7 @@ func SpawnLogIndex(s *StageState, tx kv.RwTx, cfg LogIndexCfg, ctx context.Conte return nil } -// Add the topics and address index for logs, if not in prune range or addr in noPruneContracts +// Add the topics and address index for logs, if not in prune range or addr is the deposit contract func promoteLogIndex(logPrefix string, tx kv.RwTx, start uint64, endBlock uint64, pruneBlock uint64, cfg LogIndexCfg, ctx context.Context, logger log.Logger) error { quit := ctx.Done() logEvery := time.NewTicker(30 * time.Second) @@ -179,15 +182,15 @@ func promoteLogIndex(logPrefix string, tx kv.RwTx, start uint64, endBlock uint64 } toStore := true - // if pruning is enabled, and noPruneContracts isn't configured for the chain, don't index + // if pruning is enabled, and depositContract isn't configured for the chain, don't index if blockNum < pruneBlock { toStore = false - if cfg.noPruneContracts == nil { + if cfg.depositContract == nil { continue } for _, l := range ll { // if any of the log address is in noPrune, store and index all logs for this txId - if cfg.noPruneContracts[l.Address] { + if *cfg.depositContract == l.Address { toStore = true break } @@ -431,7 +434,7 @@ func PruneLogIndex(s *PruneState, tx kv.RwTx, cfg LogIndexCfg, ctx context.Conte } pruneTo := cfg.prune.Receipts.PruneTo(s.ForwardProgress) - if err = pruneLogIndex(logPrefix, tx, cfg.tmpdir, s.PruneProgress, pruneTo, ctx, logger, cfg.noPruneContracts); err != nil { + if err = pruneLogIndex(logPrefix, tx, cfg.tmpdir, s.PruneProgress, pruneTo, ctx, logger, cfg.depositContract); err != nil { return err } if err = s.DoneAt(tx, pruneTo); err != nil { @@ -447,7 +450,7 @@ func PruneLogIndex(s *PruneState, tx kv.RwTx, cfg LogIndexCfg, ctx context.Conte } // Prune log indexes as well as logs within the prune range -func pruneLogIndex(logPrefix string, tx kv.RwTx, tmpDir string, pruneFrom, pruneTo uint64, ctx context.Context, logger log.Logger, noPruneContracts map[libcommon.Address]bool) error { +func pruneLogIndex(logPrefix string, tx kv.RwTx, tmpDir string, pruneFrom, pruneTo uint64, ctx context.Context, logger log.Logger, depositContract *libcommon.Address) error { logEvery := time.NewTicker(logInterval) defer logEvery.Stop() @@ -490,8 +493,8 @@ func pruneLogIndex(logPrefix string, tx kv.RwTx, tmpDir string, pruneFrom, prune toPrune := true for _, l := range logs { // No logs (or sublogs) for this txId should be pruned - // if one of the logs belongs to noPruneContracts lis - if noPruneContracts != nil && noPruneContracts[l.Address] { + // if one of the logs belongs to the deposit contract + if depositContract != nil && *depositContract == l.Address { toPrune = false break } diff --git a/eth/stagedsync/stage_log_index_test.go b/eth/stagedsync/stage_log_index_test.go index b736d2254d3..3c465cd2bef 100644 --- a/eth/stagedsync/stage_log_index_test.go +++ b/eth/stagedsync/stage_log_index_test.go @@ -135,7 +135,8 @@ func TestPruneLogIndex(t *testing.T) { require.NoError(err) // Mode test - err = pruneLogIndex("", tx, tmpDir, 0, 45, ctx, logger, map[libcommon.Address]bool{{1}: true}) // using addr {1} from genReceipts + depositContract := libcommon.Address{1} // using addr {1} from genReceipts + err = pruneLogIndex("", tx, tmpDir, 0, 45, ctx, logger, &depositContract) require.NoError(err) { diff --git a/params/chainspecs/chiado.json b/params/chainspecs/chiado.json index 72b7a99682a..babff69f01d 100644 --- a/params/chainspecs/chiado.json +++ b/params/chainspecs/chiado.json @@ -11,9 +11,6 @@ "istanbulBlock": 0, "berlinBlock": 0, "londonBlock": 0, - "burntContract": { - "0": "0x1559000000000000000000000000000000000000" - }, "terminalTotalDifficulty": 231707791542740786049188744689299064356246512, "terminalTotalDifficultyPassed": true, "shanghaiTime": 1684934220, @@ -22,9 +19,10 @@ "maxBlobGasPerBlock": 262144, "targetBlobGasPerBlock": 131072, "blobGasPriceUpdateFraction": 1112826, - "noPruneContracts": { - "0xb97036A26259B7147018913bD58a774cf91acf25": true + "burntContract": { + "0": "0x1559000000000000000000000000000000000000" }, + "depositContract": "0xb97036A26259B7147018913bD58a774cf91acf25", "aura": { "stepDuration": 5, "blockReward": 0, diff --git a/params/chainspecs/gnosis.json b/params/chainspecs/gnosis.json index 834ed7e6dfd..bd42cebdd40 100644 --- a/params/chainspecs/gnosis.json +++ b/params/chainspecs/gnosis.json @@ -11,9 +11,6 @@ "istanbulBlock": 7298030, "berlinBlock": 16101500, "londonBlock": 19040000, - "burntContract": { - "19040000": "0x6BBe78ee9e474842Dbd4AB4987b3CeFE88426A92" - }, "terminalTotalDifficulty": 8626000000000000000000058750000000000000000000, "terminalTotalDifficultyPassed": true, "shanghaiTime": 1690889660, @@ -22,9 +19,10 @@ "maxBlobGasPerBlock": 262144, "targetBlobGasPerBlock": 131072, "blobGasPriceUpdateFraction": 1112826, - "noPruneContracts": { - "0x0B98057eA310F4d31F2a452B414647007d1645d9": true + "burntContract": { + "19040000": "0x6BBe78ee9e474842Dbd4AB4987b3CeFE88426A92" }, + "depositContract": "0x0B98057eA310F4d31F2a452B414647007d1645d9", "aura": { "stepDuration": 5, "blockReward": 0, diff --git a/params/chainspecs/goerli.json b/params/chainspecs/goerli.json index f8839fb6cd1..6823b1e9695 100644 --- a/params/chainspecs/goerli.json +++ b/params/chainspecs/goerli.json @@ -15,11 +15,9 @@ "terminalTotalDifficultyPassed": true, "shanghaiTime": 1678832736, "cancunTime": 1705473120, + "depositContract": "0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b", "clique": { "period": 15, "epoch": 30000 - }, - "noPruneContracts": { - "0xff50ed3d0ec03aC01D4C79aAd74928BFF48a7b2b": true } } diff --git a/params/chainspecs/holesky.json b/params/chainspecs/holesky.json index de44186a888..2473b1d6e70 100644 --- a/params/chainspecs/holesky.json +++ b/params/chainspecs/holesky.json @@ -15,7 +15,5 @@ "terminalTotalDifficultyPassed": true, "shanghaiTime": 1696000704, "cancunTime": 1707305664, - "noPruneContracts": { - "0x4242424242424242424242424242424242424242": true - } -} \ No newline at end of file + "depositContract": "0x4242424242424242424242424242424242424242" +} diff --git a/params/chainspecs/mainnet.json b/params/chainspecs/mainnet.json index 7d73ec6470b..c2c3fd3ea24 100644 --- a/params/chainspecs/mainnet.json +++ b/params/chainspecs/mainnet.json @@ -19,8 +19,6 @@ "terminalTotalDifficultyPassed": true, "shanghaiTime": 1681338455, "cancunTime": 1710338135, - "ethash": {}, - "noPruneContracts": { - "0x00000000219ab540356cBB839Cbe05303d7705Fa": true - } + "depositContract": "0x00000000219ab540356cBB839Cbe05303d7705Fa", + "ethash": {} } diff --git a/params/chainspecs/sepolia.json b/params/chainspecs/sepolia.json index e5ffd230325..949b12252df 100644 --- a/params/chainspecs/sepolia.json +++ b/params/chainspecs/sepolia.json @@ -17,8 +17,6 @@ "mergeNetsplitBlock": 1735371, "shanghaiTime": 1677557088, "cancunTime": 1706655072, - "ethash": {}, - "noPruneContracts": { - "0x7f02C3E3c98b133055B8B348B2Ac625669Ed295D": true - } + "depositContract": "0x7f02C3E3c98b133055B8B348B2Ac625669Ed295D", + "ethash": {} } diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index 1a025103159..a64ba51c0c6 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -491,9 +491,9 @@ func NewDefaultStages(ctx context.Context, } } - var noPruneContracts map[libcommon.Address]bool + var depositContract *libcommon.Address if cfg.Genesis != nil { - noPruneContracts = cfg.Genesis.Config.NoPruneContracts + depositContract = cfg.Genesis.Config.DepositContract } return stagedsync.DefaultStages(ctx, @@ -526,7 +526,7 @@ func NewDefaultStages(ctx context.Context, stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, true, true, false, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg), stagedsync.StageHistoryCfg(db, cfg.Prune, dirs.Tmp), - stagedsync.StageLogIndexCfg(db, cfg.Prune, dirs.Tmp, noPruneContracts), + stagedsync.StageLogIndexCfg(db, cfg.Prune, dirs.Tmp, depositContract), stagedsync.StageCallTracesCfg(db, cfg.Prune, 0, dirs.Tmp), stagedsync.StageTxLookupCfg(db, cfg.Prune, dirs.Tmp, controlServer.ChainConfig.Bor, blockReader), stagedsync.StageFinishCfg(db, dirs.Tmp, forkValidator), @@ -572,9 +572,9 @@ func NewPipelineStages(ctx context.Context, } } - var noPruneContracts map[libcommon.Address]bool + var depositContract *libcommon.Address if cfg.Genesis != nil { - noPruneContracts = cfg.Genesis.Config.NoPruneContracts + depositContract = cfg.Genesis.Config.DepositContract } if len(cfg.Sync.UploadLocation) == 0 { @@ -605,7 +605,7 @@ func NewPipelineStages(ctx context.Context, stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, checkStateRoot, true, false, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg), stagedsync.StageHistoryCfg(db, cfg.Prune, dirs.Tmp), - stagedsync.StageLogIndexCfg(db, cfg.Prune, dirs.Tmp, noPruneContracts), + stagedsync.StageLogIndexCfg(db, cfg.Prune, dirs.Tmp, depositContract), stagedsync.StageCallTracesCfg(db, cfg.Prune, 0, dirs.Tmp), stagedsync.StageTxLookupCfg(db, cfg.Prune, dirs.Tmp, controlServer.ChainConfig.Bor, blockReader), stagedsync.StageFinishCfg(db, dirs.Tmp, forkValidator), @@ -641,7 +641,7 @@ func NewPipelineStages(ctx context.Context, stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, checkStateRoot, true, false, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg), stagedsync.StageHistoryCfg(db, cfg.Prune, dirs.Tmp), - stagedsync.StageLogIndexCfg(db, cfg.Prune, dirs.Tmp, noPruneContracts), + stagedsync.StageLogIndexCfg(db, cfg.Prune, dirs.Tmp, depositContract), stagedsync.StageCallTracesCfg(db, cfg.Prune, 0, dirs.Tmp), stagedsync.StageTxLookupCfg(db, cfg.Prune, dirs.Tmp, controlServer.ChainConfig.Bor, blockReader), stagedsync.StageFinishCfg(db, dirs.Tmp, forkValidator),