From bc14d12fd78de4148c1242570154c79345a68c07 Mon Sep 17 00:00:00 2001 From: Austin Roberts Date: Wed, 6 Dec 2023 16:04:56 -0600 Subject: [PATCH] Use the statedb database to get Tries The old approach of getting state tries involved instantiating a new state database and using it to instantiate a trie. What we didn't realize was that state database needed to have Close() called on it, which we didn't offer a way for plugins to do, resulting in memory leaking. This approach reuses the primary trie database associated with the blockchain object, albeit a bit indirectly. This will allow access to recent tries that are stored in memory, where previously only tries that had been committed to disk were accessible. --- cmd/geth/main.go | 3 +- cmd/geth/plugin_hooks.go | 76 ------------------- .../wrappers/backendwrapper/backendwrapper.go | 18 +++-- .../wrappers/backendwrapper/triewrapper.go | 4 +- 4 files changed, 14 insertions(+), 87 deletions(-) diff --git a/cmd/geth/main.go b/cmd/geth/main.go index da143edec..3fab902c7 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -358,8 +358,7 @@ func geth(ctx *cli.Context) error { } stack, backend := makeFullNode(ctx) - trieCfg := plugethCaptureTrieConfig(ctx, stack, backend) - wrapperBackend := backendwrapper.NewBackend(backend, trieCfg) + wrapperBackend := backendwrapper.NewBackend(backend) pluginsInitializeNode(stack, wrapperBackend) if ok, err := plugins.RunSubcommand(ctx); ok { diff --git a/cmd/geth/plugin_hooks.go b/cmd/geth/plugin_hooks.go index d809cb382..9530fa09f 100644 --- a/cmd/geth/plugin_hooks.go +++ b/cmd/geth/plugin_hooks.go @@ -1,25 +1,15 @@ package main import ( - "github.com/ethereum/go-ethereum/cmd/utils" - gcore "github.com/ethereum/go-ethereum/core" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/eth/ethconfig" - "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/trie" - "github.com/ethereum/go-ethereum/trie/triedb/hashdb" - "github.com/ethereum/go-ethereum/trie/triedb/pathdb" "github.com/ethereum/go-ethereum/plugins" "github.com/ethereum/go-ethereum/plugins/wrappers" "github.com/openrelayxyz/plugeth-utils/core" "github.com/openrelayxyz/plugeth-utils/restricted" - - "github.com/urfave/cli/v2" ) func apiTranslate(apis []core.API) []rpc.API { @@ -132,69 +122,3 @@ func pluginBlockChain() { } BlockChain(plugins.DefaultPluginLoader) } - -func plugethCaptureTrieConfig(ctx *cli.Context, stack *node.Node, backend ethapi.Backend) *trie.Config { - - ethCfg := new(ethconfig.Config) - - if ctx.IsSet(utils.CacheFlag.Name) || ctx.IsSet(utils.CacheTrieFlag.Name) { - ethCfg.TrieCleanCache = ctx.Int(utils.CacheFlag.Name) * ctx.Int(utils.CacheTrieFlag.Name) / 100 - } - if ctx.IsSet(utils.CacheNoPrefetchFlag.Name) { - ethCfg.NoPrefetch = ctx.Bool(utils.CacheNoPrefetchFlag.Name) - } - if ctx.IsSet(utils.CacheFlag.Name) || ctx.IsSet(utils.CacheGCFlag.Name) { - ethCfg.TrieDirtyCache = ctx.Int(utils.CacheFlag.Name) * ctx.Int(utils.CacheGCFlag.Name) / 100 - } - if ctx.IsSet(utils.GCModeFlag.Name) { - ethCfg.NoPruning = ctx.String(utils.GCModeFlag.Name) == "archive" - } - if ctx.IsSet(utils.CacheFlag.Name) || ctx.IsSet(utils.CacheSnapshotFlag.Name) { - ethCfg.SnapshotCache = ctx.Int(utils.CacheFlag.Name) * ctx.Int(utils.CacheSnapshotFlag.Name) / 100 - } - ethCfg.Preimages = ctx.Bool(utils.CachePreimagesFlag.Name) - if ethCfg.NoPruning && !ethCfg.Preimages { - ethCfg.Preimages = true - log.Info("Enabling recording of key preimages since archive mode is used") - } - if ctx.IsSet(utils.StateHistoryFlag.Name) { - ethCfg.StateHistory = ctx.Uint64(utils.StateHistoryFlag.Name) - } - - chaindb := backend.ChainDb() - - scheme, err := rawdb.ParseStateScheme(ctx.String(utils.StateSchemeFlag.Name), chaindb) - if err != nil { - utils.Fatalf("%v", err) - } - - ethCfg.StateScheme = scheme - - cacheCfg := &gcore.CacheConfig{ - TrieCleanLimit: ethCfg.TrieCleanCache, - TrieCleanNoPrefetch: ethCfg.NoPrefetch, - TrieDirtyLimit: ethCfg.TrieDirtyCache, - TrieDirtyDisabled: ethCfg.NoPruning, - TrieTimeLimit: ethconfig.Defaults.TrieTimeout, - SnapshotLimit: ethCfg.SnapshotCache, - Preimages: ethCfg.Preimages, - StateHistory: ethCfg.StateHistory, - StateScheme: ethCfg.StateScheme, - } - - config := &trie.Config{Preimages: cacheCfg.Preimages} - if cacheCfg.StateScheme == rawdb.HashScheme { - config.HashDB = &hashdb.Config{ - CleanCacheSize: cacheCfg.TrieCleanLimit * 1024 * 1024, - } - } - if cacheCfg.StateScheme == rawdb.PathScheme { - config.PathDB = &pathdb.Config{ - StateHistory: cacheCfg.StateHistory, - CleanCacheSize: cacheCfg.TrieCleanLimit * 1024 * 1024, - DirtyCacheSize: cacheCfg.TrieDirtyLimit * 1024 * 1024, - } - } - - return config -} diff --git a/plugins/wrappers/backendwrapper/backendwrapper.go b/plugins/wrappers/backendwrapper/backendwrapper.go index a2f681ed9..6e8b54401 100644 --- a/plugins/wrappers/backendwrapper/backendwrapper.go +++ b/plugins/wrappers/backendwrapper/backendwrapper.go @@ -13,12 +13,10 @@ import ( gcore "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/event" gparams "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" @@ -29,6 +27,7 @@ import ( type Backend struct { b ethapi.Backend + db state.Database newTxsFeed event.Feed newTxsOnce sync.Once chainFeed event.Feed @@ -44,14 +43,17 @@ type Backend struct { removedLogsFeed event.Feed removedLogsOnce sync.Once chainConfig *params.ChainConfig - trieConfig *trie.Config } -func NewBackend(b ethapi.Backend, tc *trie.Config) *Backend { - +func NewBackend(b ethapi.Backend) *Backend { + state, _, err := b.StateAndHeaderByNumber(context.Background(), 0) + if err != nil { + panic(err.Error()) + } return &Backend{ b: b, - trieConfig: tc} + db: state.Database(), + } } func (b *Backend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { @@ -492,7 +494,7 @@ func CloneChainConfig(cf *gparams.ChainConfig) *params.ChainConfig { } func (b *Backend) GetTrie(h core.Hash) (core.Trie, error) { - tr, err := trie.NewStateTrie(trie.TrieID(common.Hash(h)), trie.NewDatabase(b.b.ChainDb(), b.trieConfig)) + tr, err := b.db.OpenTrie(common.Hash(h)) if err != nil { return nil, err } @@ -508,7 +510,7 @@ func (b *Backend) GetAccountTrie(stateRoot core.Hash, account core.Address) (cor if err != nil { return nil, err } - acTr, err := trie.NewStateTrie(trie.StorageTrieID(common.Hash(stateRoot), crypto.Keccak256Hash(account[:]), common.Hash(act.Root)), trie.NewDatabase(b.b.ChainDb(), b.trieConfig)) + acTr, err := b.db.OpenStorageTrie(common.Hash(stateRoot), common.Address(account), common.Hash(act.Root)) if err != nil { return nil, err } diff --git a/plugins/wrappers/backendwrapper/triewrapper.go b/plugins/wrappers/backendwrapper/triewrapper.go index d4e3b3c1d..133536733 100644 --- a/plugins/wrappers/backendwrapper/triewrapper.go +++ b/plugins/wrappers/backendwrapper/triewrapper.go @@ -40,7 +40,9 @@ func (t *WrappedTrie) Hash() core.Hash { func (t *WrappedTrie) NodeIterator(startKey []byte) core.NodeIterator { itr, err := t.t.NodeIterator(startKey) - log.Error("Error returned from geth side NodeIterator", "err", err) + if err != nil { + log.Error("Error returned from geth side NodeIterator", "err", err) + } return &WrappedNodeIterator{itr} }