From bcfeb7e466ec802ceef03ad24ab33d7ce9cb8ee0 Mon Sep 17 00:00:00 2001 From: Harry Ngo <17699212+huyngopt1994@users.noreply.github.com> Date: Fri, 4 Oct 2024 17:21:53 +0700 Subject: [PATCH] all: remove trie cache journal (#595) --- cmd/devp2p/internal/ethtest/suite_test.go | 2 -- cmd/ronin/config.go | 4 +++ cmd/ronin/main.go | 4 +-- cmd/ronin/snapshot.go | 6 ++-- cmd/utils/flags.go | 18 ----------- cmd/utils/flags_legacy.go | 14 ++++++++ core/blockchain.go | 22 ------------- core/state/pruner/pruner.go | 39 ++++++++--------------- eth/backend.go | 4 +-- eth/ethconfig/config.go | 20 ++++++------ eth/ethconfig/gen_config.go | 12 ------- graphql/graphql_test.go | 12 +++---- trie/database.go | 29 +---------------- 13 files changed, 52 insertions(+), 134 deletions(-) diff --git a/cmd/devp2p/internal/ethtest/suite_test.go b/cmd/devp2p/internal/ethtest/suite_test.go index 50380b989c..55e386c4aa 100644 --- a/cmd/devp2p/internal/ethtest/suite_test.go +++ b/cmd/devp2p/internal/ethtest/suite_test.go @@ -91,8 +91,6 @@ func setupGeth(stack *node.Node) error { Genesis: &chain.genesis, NetworkId: chain.genesis.Config.ChainID.Uint64(), // 19763 DatabaseCache: 10, - TrieCleanCache: 10, - TrieCleanCacheJournal: "", TrieCleanCacheRejournal: 60 * time.Minute, TrieDirtyCache: 16, TrieTimeout: 60 * time.Minute, diff --git a/cmd/ronin/config.go b/cmd/ronin/config.go index cae2e3bc30..d3bf084fbb 100644 --- a/cmd/ronin/config.go +++ b/cmd/ronin/config.go @@ -287,6 +287,10 @@ func deprecated(field string) bool { return true case "ethconfig.Config.EWASMInterpreter": return true + case "ethconfig.Config.TrieCleanCacheJournal": + return true + case "ethconfig.Config.TrieCleanCacheRejournal": + return true default: return false } diff --git a/cmd/ronin/main.go b/cmd/ronin/main.go index 5144bc14a9..3e94098ab3 100644 --- a/cmd/ronin/main.go +++ b/cmd/ronin/main.go @@ -118,8 +118,8 @@ var ( utils.CacheFlag, utils.CacheDatabaseFlag, utils.CacheTrieFlag, - utils.CacheTrieJournalFlag, - utils.CacheTrieRejournalFlag, + utils.CacheTrieJournalFlag, // deprecated + utils.CacheTrieRejournalFlag, // deprecated utils.CacheGCFlag, utils.CacheSnapshotFlag, utils.CacheNoPrefetchFlag, diff --git a/cmd/ronin/snapshot.go b/cmd/ronin/snapshot.go index ce9b343b90..b61f32969f 100644 --- a/cmd/ronin/snapshot.go +++ b/cmd/ronin/snapshot.go @@ -66,7 +66,6 @@ var ( utils.SepoliaFlag, utils.RinkebyFlag, utils.GoerliFlag, - utils.CacheTrieJournalFlag, utils.BloomFilterSizeFlag, }, Description: ` @@ -187,11 +186,12 @@ block is used. ) func pruneState(ctx *cli.Context) error { - stack, config := makeConfigNode(ctx) + stack, _ := makeConfigNode(ctx) defer stack.Close() chaindb := utils.MakeChainDatabase(ctx, stack, false) - pruner, err := pruner.NewPruner(chaindb, stack.ResolvePath(""), stack.ResolvePath(config.Eth.TrieCleanCacheJournal), ctx.Uint64(utils.BloomFilterSizeFlag.Name)) + pruner, err := pruner.NewPruner(chaindb, stack.ResolvePath(""), + ctx.Uint64(utils.BloomFilterSizeFlag.Name)) if err != nil { log.Error("Failed to open snapshot tree", "err", err) return err diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 976c8191ce..806384adce 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -479,18 +479,6 @@ var ( Value: 15, Category: flags.PerfCategory, } - CacheTrieJournalFlag = &cli.StringFlag{ - Name: "cache.trie.journal", - Usage: "Disk journal directory for trie cache to survive node restarts", - Value: ethconfig.Defaults.TrieCleanCacheJournal, - Category: flags.PerfCategory, - } - CacheTrieRejournalFlag = &cli.DurationFlag{ - Name: "cache.trie.rejournal", - Usage: "Time interval to regenerate the trie cache journal", - Value: ethconfig.Defaults.TrieCleanCacheRejournal, - Category: flags.PerfCategory, - } CacheGCFlag = &cli.IntFlag{ Name: "cache.gc", Usage: "Percentage of cache memory allowance to use for trie pruning (default = 25% full mode, 0% archive mode)", @@ -1922,12 +1910,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheTrieFlag.Name) { cfg.TrieCleanCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheTrieFlag.Name) / 100 } - if ctx.IsSet(CacheTrieJournalFlag.Name) { - cfg.TrieCleanCacheJournal = ctx.String(CacheTrieJournalFlag.Name) - } - if ctx.IsSet(CacheTrieRejournalFlag.Name) { - cfg.TrieCleanCacheRejournal = ctx.Duration(CacheTrieRejournalFlag.Name) - } if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheGCFlag.Name) { cfg.TrieDirtyCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheGCFlag.Name) / 100 } diff --git a/cmd/utils/flags_legacy.go b/cmd/utils/flags_legacy.go index cafa07892d..63b6d64879 100644 --- a/cmd/utils/flags_legacy.go +++ b/cmd/utils/flags_legacy.go @@ -20,6 +20,7 @@ import ( "fmt" "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/internal/flags" "github.com/urfave/cli/v2" ) @@ -35,6 +36,8 @@ var ShowDeprecated = &cli.Command{ var DeprecatedFlags = []cli.Flag{ LegacyMinerGasTargetFlag, NoUSBFlag, + CacheTrieJournalFlag, + CacheTrieRejournalFlag, } var ( @@ -49,6 +52,17 @@ var ( Usage: "Target gas floor for mined blocks (deprecated)", Value: ethconfig.Defaults.Miner.GasFloor, } + // (Deprecated Oct 2024, shown in aliased flags section) + CacheTrieJournalFlag = &cli.StringFlag{ + Name: "cache.trie.journal", + Usage: "Disk journal directory for trie cache to survive node restarts", + Category: flags.PerfCategory, + } + CacheTrieRejournalFlag = &cli.DurationFlag{ + Name: "cache.trie.rejournal", + Usage: "Time interval to regenerate the trie cache journal", + Category: flags.PerfCategory, + } ) // showDeprecated displays deprecated flags that will be soon removed from the codebase. diff --git a/core/blockchain.go b/core/blockchain.go index 588ab667f9..2b7e82e2f7 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -132,8 +132,6 @@ const ( // that's resident in a blockchain. type CacheConfig struct { TrieCleanLimit int // Memory allowance (MB) to use for caching trie nodes in memory - TrieCleanJournal string // Disk journal for saving clean cache entries. - TrieCleanRejournal time.Duration // Time interval to dump clean cache to disk periodically TrieCleanNoPrefetch bool // Whether to disable heuristic state prefetching for followup blocks TrieDirtyLimit int // Memory limit (MB) at which to start flushing dirty trie nodes to disk TrieDirtyDisabled bool // Whether to disable trie write caching and GC altogether (archive node) @@ -269,7 +267,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis db, &trie.Config{ Cache: cacheConfig.TrieCleanLimit, - Journal: cacheConfig.TrieCleanJournal, Preimages: cacheConfig.Preimages, }) // Setup the genesis block, commit the provided genesis specification @@ -289,7 +286,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis triegc: prque.New(nil), stateCache: state.NewDatabaseWithConfig(db, &trie.Config{ Cache: cacheConfig.TrieCleanLimit, - Journal: cacheConfig.TrieCleanJournal, Preimages: cacheConfig.Preimages, }), quit: make(chan struct{}), @@ -456,19 +452,6 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis go bc.maintainTxIndex(txIndexBlock) } - // If periodic cache journal is required, spin it up. - if bc.cacheConfig.TrieCleanRejournal > 0 { - if bc.cacheConfig.TrieCleanRejournal < time.Minute { - log.Warn("Sanitizing invalid trie cache journal time", "provided", bc.cacheConfig.TrieCleanRejournal, "updated", time.Minute) - bc.cacheConfig.TrieCleanRejournal = time.Minute - } - bc.wg.Add(1) - go func() { - defer bc.wg.Done() - bc.triedb.SaveCachePeriodically(bc.cacheConfig.TrieCleanJournal, bc.cacheConfig.TrieCleanRejournal, bc.quit) - }() - } - // load the latest dirty accounts stored from last stop to cache bc.loadLatestDirtyAccounts() // Rewind the chain in case of an incompatible config upgrade. @@ -1037,11 +1020,6 @@ func (bc *BlockChain) Stop() { log.Error("Dangling trie nodes after full cleanup") } } - // Ensure all live cached entries be saved into disk, so that we can skip - // cache warmup when node restarts. - if bc.cacheConfig.TrieCleanJournal != "" { - bc.triedb.SaveCache(bc.cacheConfig.TrieCleanJournal) - } log.Info("Blockchain stopped") } diff --git a/core/state/pruner/pruner.go b/core/state/pruner/pruner.go index c46432ee68..f46eb66990 100644 --- a/core/state/pruner/pruner.go +++ b/core/state/pruner/pruner.go @@ -75,16 +75,15 @@ var ( // periodically in order to release the disk usage and improve the // disk read performance to some extent. type Pruner struct { - db ethdb.Database - stateBloom *stateBloom - datadir string - trieCachePath string - headHeader *types.Header - snaptree *snapshot.Tree + db ethdb.Database + stateBloom *stateBloom + datadir string + headHeader *types.Header + snaptree *snapshot.Tree } // NewPruner creates the pruner instance. -func NewPruner(db ethdb.Database, datadir, trieCachePath string, bloomSize uint64) (*Pruner, error) { +func NewPruner(db ethdb.Database, datadir string, bloomSize uint64) (*Pruner, error) { headBlock := rawdb.ReadHeadBlock(db) if headBlock == nil { return nil, errors.New("Failed to load head block") @@ -103,12 +102,11 @@ func NewPruner(db ethdb.Database, datadir, trieCachePath string, bloomSize uint6 return nil, err } return &Pruner{ - db: db, - stateBloom: stateBloom, - datadir: datadir, - trieCachePath: trieCachePath, - headHeader: headBlock.Header(), - snaptree: snaptree, + db: db, + stateBloom: stateBloom, + datadir: datadir, + headHeader: headBlock.Header(), + snaptree: snaptree, }, nil } @@ -241,7 +239,7 @@ func (p *Pruner) Prune(root common.Hash) error { return err } if stateBloomRoot != (common.Hash{}) { - return RecoverPruning(p.datadir, p.db, p.trieCachePath) + return RecoverPruning(p.datadir, p.db) } // If the target state root is not specified, use the HEAD-127 as the // target. The reason for picking it is: @@ -299,11 +297,6 @@ func (p *Pruner) Prune(root common.Hash) error { log.Info("Selecting user-specified state as the pruning target", "root", root) } } - // Before start the pruning, delete the clean trie cache first. - // It's necessary otherwise in the next restart we will hit the - // deleted state root in the "clean cache" so that the incomplete - // state is picked for usage. - deleteCleanTrieCache(p.trieCachePath) // All the state roots of the middle layer should be forcibly pruned, // otherwise the dangling state will be left. @@ -342,7 +335,7 @@ func (p *Pruner) Prune(root common.Hash) error { // pruning can be resumed. What's more if the bloom filter is constructed, the // pruning **has to be resumed**. Otherwise a lot of dangling nodes may be left // in the disk. -func RecoverPruning(datadir string, db ethdb.Database, trieCachePath string) error { +func RecoverPruning(datadir string, db ethdb.Database) error { stateBloomPath, stateBloomRoot, err := findBloomFilter(datadir) if err != nil { return err @@ -372,12 +365,6 @@ func RecoverPruning(datadir string, db ethdb.Database, trieCachePath string) err } log.Info("Loaded state bloom filter", "path", stateBloomPath) - // Before start the pruning, delete the clean trie cache first. - // It's necessary otherwise in the next restart we will hit the - // deleted state root in the "clean cache" so that the incomplete - // state is picked for usage. - deleteCleanTrieCache(trieCachePath) - // All the state roots of the middle layers should be forcibly pruned, // otherwise the dangling state will be left. var ( diff --git a/eth/backend.go b/eth/backend.go index 32e3f17331..3850b94458 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -141,7 +141,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { return nil, err } - if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb, stack.ResolvePath(config.TrieCleanCacheJournal)); err != nil { + if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb); err != nil { log.Error("Failed to recover state", "error", err) } eth := &Ethereum{ @@ -192,8 +192,6 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } cacheConfig = &core.CacheConfig{ TrieCleanLimit: config.TrieCleanCache, - TrieCleanJournal: stack.ResolvePath(config.TrieCleanCacheJournal), - TrieCleanRejournal: config.TrieCleanCacheRejournal, TrieCleanNoPrefetch: config.NoPrefetch, TrieDirtyLimit: config.TrieDirtyCache, TrieDirtyDisabled: config.NoPruning, diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 5e64069127..ac257d8a68 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -76,17 +76,15 @@ var Defaults = Config{ DatasetsOnDisk: 2, DatasetsLockMmap: false, }, - NetworkId: 1, - TxLookupLimit: 2350000, - LightPeers: 100, - UltraLightFraction: 75, - DatabaseCache: 512, - TrieCleanCache: 154, - TrieCleanCacheJournal: "triecache", - TrieCleanCacheRejournal: 60 * time.Minute, - TrieDirtyCache: 256, - TrieTimeout: 60 * time.Minute, - SnapshotCache: 102, + NetworkId: 1, + TxLookupLimit: 2350000, + LightPeers: 100, + UltraLightFraction: 75, + DatabaseCache: 512, + TrieCleanCache: 154, + TrieDirtyCache: 256, + TrieTimeout: 60 * time.Minute, + SnapshotCache: 102, Miner: miner.Config{ GasCeil: 8000000, GasPrice: big.NewInt(params.GWei), diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 6e1302bc88..0af7eeced0 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -43,8 +43,6 @@ func (c Config) MarshalTOML() (interface{}, error) { DatabaseCache int DatabaseFreezer string TrieCleanCache int - TrieCleanCacheJournal string `toml:",omitempty"` - TrieCleanCacheRejournal time.Duration `toml:",omitempty"` TrieDirtyCache int TrieTimeout time.Duration SnapshotCache int @@ -87,8 +85,6 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.DatabaseCache = c.DatabaseCache enc.DatabaseFreezer = c.DatabaseFreezer enc.TrieCleanCache = c.TrieCleanCache - enc.TrieCleanCacheJournal = c.TrieCleanCacheJournal - enc.TrieCleanCacheRejournal = c.TrieCleanCacheRejournal enc.TrieDirtyCache = c.TrieDirtyCache enc.TrieTimeout = c.TrieTimeout enc.SnapshotCache = c.SnapshotCache @@ -135,8 +131,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { DatabaseCache *int DatabaseFreezer *string TrieCleanCache *int - TrieCleanCacheJournal *string `toml:",omitempty"` - TrieCleanCacheRejournal *time.Duration `toml:",omitempty"` TrieDirtyCache *int TrieTimeout *time.Duration SnapshotCache *int @@ -230,12 +224,6 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.TrieCleanCache != nil { c.TrieCleanCache = *dec.TrieCleanCache } - if dec.TrieCleanCacheJournal != nil { - c.TrieCleanCacheJournal = *dec.TrieCleanCacheJournal - } - if dec.TrieCleanCacheRejournal != nil { - c.TrieCleanCacheRejournal = *dec.TrieCleanCacheRejournal - } if dec.TrieDirtyCache != nil { c.TrieDirtyCache = *dec.TrieDirtyCache } diff --git a/graphql/graphql_test.go b/graphql/graphql_test.go index 895e797535..767a37ae6f 100644 --- a/graphql/graphql_test.go +++ b/graphql/graphql_test.go @@ -245,13 +245,11 @@ func createGQLService(t *testing.T, stack *node.Node) { Ethash: ethash.Config{ PowMode: ethash.ModeFake, }, - NetworkId: 1337, - TrieCleanCache: 5, - TrieCleanCacheJournal: "triecache", - TrieCleanCacheRejournal: 60 * time.Minute, - TrieDirtyCache: 5, - TrieTimeout: 60 * time.Minute, - SnapshotCache: 5, + NetworkId: 1337, + TrieCleanCache: 5, + TrieDirtyCache: 5, + TrieTimeout: 60 * time.Minute, + SnapshotCache: 5, } ethBackend, err := eth.New(stack, ethConf) if err != nil { diff --git a/trie/database.go b/trie/database.go index 96d201aabe..c970383ad2 100644 --- a/trie/database.go +++ b/trie/database.go @@ -18,7 +18,6 @@ package trie import ( "errors" - "runtime" "time" "github.com/VictoriaMetrics/fastcache" @@ -91,11 +90,7 @@ type Database struct { func prepare(diskdb ethdb.Database, config *Config) *Database { var cleans *fastcache.Cache if config != nil && config.Cache > 0 { - if config.Journal == "" { - cleans = fastcache.New(config.Cache * 1024 * 1024) - } else { - cleans = fastcache.LoadFromFileOrNew(config.Journal, config.Cache*1024*1024) - } + cleans = fastcache.New(config.Cache * 1024 * 1024) } var preimages *preimageStore if config != nil && config.Preimages { @@ -219,28 +214,6 @@ func (db *Database) saveCache(dir string, threads int) error { return nil } -// SaveCache atomically saves fast cache data to the given dir using all -// available CPU cores. -func (db *Database) SaveCache(dir string) error { - return db.saveCache(dir, runtime.GOMAXPROCS(0)) -} - -// SaveCachePeriodically atomically saves fast cache data to the given dir with -// the specified interval. All dump operation will only use a single CPU core. -func (db *Database) SaveCachePeriodically(dir string, interval time.Duration, stopCh <-chan struct{}) { - ticker := time.NewTicker(interval) - defer ticker.Stop() - - for { - select { - case <-ticker.C: - db.saveCache(dir, 1) - case <-stopCh: - return - } - } -} - // Cap iteratively flushes old but still referenced trie nodes until the total // memory usage goes below the given threshold. The held pre-images accumulated // up to this point will be flushed in case the size exceeds the threshold.