bc14d12fd7
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.
125 lines
3.3 KiB
Go
125 lines
3.3 KiB
Go
package main
|
|
|
|
import (
|
|
"github.com/ethereum/go-ethereum/log"
|
|
"github.com/ethereum/go-ethereum/node"
|
|
"github.com/ethereum/go-ethereum/rpc"
|
|
|
|
"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"
|
|
)
|
|
|
|
func apiTranslate(apis []core.API) []rpc.API {
|
|
result := make([]rpc.API, len(apis))
|
|
for i, api := range apis {
|
|
result[i] = rpc.API{
|
|
Namespace: api.Namespace,
|
|
Version: api.Version,
|
|
Service: api.Service,
|
|
Public: api.Public,
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func GetAPIsFromLoader(pl *plugins.PluginLoader, stack *node.Node, backend restricted.Backend) []rpc.API {
|
|
result := []core.API{}
|
|
fnList := pl.Lookup("GetAPIs", func(item interface{}) bool {
|
|
switch item.(type) {
|
|
case func(core.Node, restricted.Backend) []core.API:
|
|
return true
|
|
case func(core.Node, core.Backend) []core.API:
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
})
|
|
for _, fni := range fnList {
|
|
switch fn := fni.(type) {
|
|
case func(core.Node, restricted.Backend) []core.API:
|
|
result = append(result, fn(wrappers.NewNode(stack), backend)...)
|
|
case func(core.Node, core.Backend) []core.API:
|
|
result = append(result, fn(wrappers.NewNode(stack), backend)...)
|
|
default:
|
|
}
|
|
}
|
|
return apiTranslate(result)
|
|
}
|
|
|
|
func pluginGetAPIs(stack *node.Node, backend restricted.Backend) []rpc.API {
|
|
if plugins.DefaultPluginLoader == nil {
|
|
log.Warn("Attempting GetAPIs, but default PluginLoader has not been initialized")
|
|
return []rpc.API{}
|
|
}
|
|
return GetAPIsFromLoader(plugins.DefaultPluginLoader, stack, backend)
|
|
}
|
|
|
|
func InitializeNode(pl *plugins.PluginLoader, stack *node.Node, backend restricted.Backend) {
|
|
fnList := pl.Lookup("InitializeNode", func(item interface{}) bool {
|
|
switch item.(type) {
|
|
case func(core.Node, restricted.Backend):
|
|
return true
|
|
case func(core.Node, core.Backend):
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
})
|
|
for _, fni := range fnList {
|
|
switch fn := fni.(type) {
|
|
case func(core.Node, restricted.Backend):
|
|
fn(wrappers.NewNode(stack), backend)
|
|
case func(core.Node, core.Backend):
|
|
fn(wrappers.NewNode(stack), backend)
|
|
default:
|
|
}
|
|
}
|
|
}
|
|
|
|
func pluginsInitializeNode(stack *node.Node, backend restricted.Backend) {
|
|
if plugins.DefaultPluginLoader == nil {
|
|
log.Warn("Attempting InitializeNode, but default PluginLoader has not been initialized")
|
|
return
|
|
}
|
|
InitializeNode(plugins.DefaultPluginLoader, stack, backend)
|
|
}
|
|
|
|
func OnShutdown(pl *plugins.PluginLoader) {
|
|
fnList := pl.Lookup("OnShutdown", func(item interface{}) bool {
|
|
_, ok := item.(func())
|
|
return ok
|
|
})
|
|
for _, fni := range fnList {
|
|
fni.(func())()
|
|
}
|
|
}
|
|
|
|
func pluginsOnShutdown() {
|
|
if plugins.DefaultPluginLoader == nil {
|
|
log.Warn("Attempting OnShutdown, but default PluginLoader has not been initialized")
|
|
return
|
|
}
|
|
OnShutdown(plugins.DefaultPluginLoader)
|
|
}
|
|
|
|
func BlockChain(pl *plugins.PluginLoader) {
|
|
fnList := pl.Lookup("BlockChain", func(item interface{}) bool {
|
|
_, ok := item.(func())
|
|
return ok
|
|
})
|
|
for _, fni := range fnList {
|
|
fni.(func())()
|
|
}
|
|
}
|
|
|
|
func pluginBlockChain() {
|
|
if plugins.DefaultPluginLoader == nil {
|
|
log.Warn("Attempting BlockChain, but default PluginLoader has not been initialized")
|
|
return
|
|
}
|
|
BlockChain(plugins.DefaultPluginLoader)
|
|
}
|