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.
This commit is contained in:
parent
703c3b6b74
commit
bc14d12fd7
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -40,7 +40,9 @@ func (t *WrappedTrie) Hash() core.Hash {
|
||||
|
||||
func (t *WrappedTrie) NodeIterator(startKey []byte) core.NodeIterator {
|
||||
itr, err := t.t.NodeIterator(startKey)
|
||||
if err != nil {
|
||||
log.Error("Error returned from geth side NodeIterator", "err", err)
|
||||
}
|
||||
return &WrappedNodeIterator{itr}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user