From 03808de29a67877a3f32d9f523664c3160ed1ef7 Mon Sep 17 00:00:00 2001 From: Austin Roberts Date: Fri, 25 Jun 2021 22:38:04 -0500 Subject: [PATCH] Refactor plugin system When the plugin loader itself had to know the types in the arguments and return values of the plugin functions, it was very difficult to avoid import loops, given that the types were often defined in the same package that needed to invoke the plugins. Under this model, the plugin loader has much less knowledge of the plugins themselves, and within each package we define functions to interact with the plugins. --- cmd/geth/main.go | 2 +- cmd/geth/plugin_hooks.go | 102 ++++++++++++++++ core/plugin_hooks.go | 62 ++++++++++ core/state_processor.go | 13 +- eth/backend.go | 5 +- eth/plugin_hooks.go | 52 ++++++++ eth/tracers/api.go | 5 +- eth/tracers/plugin_hooks.go | 28 +++++ plugins/interface.go | 37 ------ plugins/plugin_loader.go | 233 +++++------------------------------- 10 files changed, 283 insertions(+), 256 deletions(-) create mode 100644 cmd/geth/plugin_hooks.go create mode 100644 core/plugin_hooks.go create mode 100644 eth/plugin_hooks.go create mode 100644 eth/tracers/plugin_hooks.go delete mode 100644 plugins/interface.go diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 91b251858..e2ef7c7ed 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -324,7 +324,7 @@ func geth(ctx *cli.Context) error { prepare(ctx) stack, backend := makeFullNode(ctx) defer stack.Close() - stack.RegisterAPIs(plugins.GetAPIs(stack, backend)) + stack.RegisterAPIs(pluginGetAPIs(stack, backend)) startNode(ctx, stack, backend) stack.Wait() diff --git a/cmd/geth/plugin_hooks.go b/cmd/geth/plugin_hooks.go new file mode 100644 index 000000000..ca837f690 --- /dev/null +++ b/cmd/geth/plugin_hooks.go @@ -0,0 +1,102 @@ +package main + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/eth/downloader" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/plugins" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/log" +) + +// Backend interface provides the common API services (that are provided by +// both full and light clients) with access to necessary functions. +type Backend interface { + // General Ethereum API + Downloader() *downloader.Downloader + SuggestGasTipCap(ctx context.Context) (*big.Int, error) + ChainDb() ethdb.Database + AccountManager() *accounts.Manager + ExtRPCEnabled() bool + RPCGasCap() uint64 // global gas cap for eth_call over rpc: DoS protection + RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs + UnprotectedAllowed() bool // allows only for EIP155 transactions. + + // Blockchain API + SetHead(number uint64) + HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) + HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) + HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) + CurrentHeader() *types.Header + CurrentBlock() *types.Block + BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) + BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) + BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) + StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) + StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) + GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) + GetTd(ctx context.Context, hash common.Hash) *big.Int + GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, cfg *vm.Config) (*vm.EVM, func() error, error) + SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription + SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription + SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription + + // Transaction pool API + SendTx(ctx context.Context, signedTx *types.Transaction) error + GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) + GetPoolTransactions() (types.Transactions, error) + GetPoolTransaction(txHash common.Hash) *types.Transaction + GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) + Stats() (pending int, queued int) + TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) + SubscribeNewTxsEvent(chan<- core.NewTxsEvent) event.Subscription + + // Filter API + BloomStatus() (uint64, uint64) + GetLogs(ctx context.Context, blockHash common.Hash) ([][]*types.Log, error) + ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) + SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription + SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription + SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription + + ChainConfig() *params.ChainConfig + Engine() consensus.Engine +} + + +type APILoader func(*node.Node, Backend) []rpc.API + +func GetAPIsFromLoader(pl *plugins.PluginLoader, stack *node.Node, backend Backend) []rpc.API { + result := []rpc.API{} + fnList := pl.Lookup("GetAPIs", func(item interface{}) bool { + _, ok := item.(func(*node.Node, Backend) []rpc.API) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(*node.Node, Backend) []rpc.API); ok { + result = append(result, fn(stack, backend)...) + } + } + return result +} + +func pluginGetAPIs(stack *node.Node, backend 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) +} diff --git a/core/plugin_hooks.go b/core/plugin_hooks.go new file mode 100644 index 000000000..ba5f5f662 --- /dev/null +++ b/core/plugin_hooks.go @@ -0,0 +1,62 @@ +package core + +import ( + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/plugins" +) + +func pluginPreProcessBlock(block *types.Block) { + fnList := plugins.Lookup("ProcessBlock", func(item interface{}) bool { + _, ok := item.(func(*types.Block)) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(*types.Block)); ok { + fn(block) + } + } +} +func pluginPreProcessTransaction(tx *types.Transaction, block *types.Block, i int) { + fnList := plugins.Lookup("ProcessTransaction", func(item interface{}) bool { + _, ok := item.(func(*types.Transaction, *types.Block, int)) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(*types.Transaction, *types.Block, int)); ok { + fn(tx, block, i) + } + } +} +func pluginBlockProcessingError(tx *types.Transaction, block *types.Block, err error) { + fnList := plugins.Lookup("ProcessingError", func(item interface{}) bool { + _, ok := item.(func(*types.Transaction, *types.Block, error)) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(*types.Transaction, *types.Block, error)); ok { + fn(tx, block, err) + } + } +} +func pluginPostProcessTransaction(tx *types.Transaction, block *types.Block, i int, receipt *types.Receipt) { + fnList := plugins.Lookup("ProcessTransaction", func(item interface{}) bool { + _, ok := item.(func(*types.Transaction, *types.Block, int, *types.Receipt)) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(*types.Transaction, *types.Block, int, *types.Receipt)); ok { + fn(tx, block, i, receipt) + } + } +} +func pluginPostProcessBlock(block *types.Block) { + fnList := plugins.Lookup("ProcessBlock", func(item interface{}) bool { + _, ok := item.(func(*types.Block)) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(*types.Block)); ok { + fn(block) + } + } +} diff --git a/core/state_processor.go b/core/state_processor.go index 4f0b79fe1..6d91b2db2 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -27,7 +27,6 @@ import ( "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/plugins" ) // StateProcessor is a basic Processor, which takes care of transitioning @@ -71,27 +70,27 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg blockContext := NewEVMBlockContext(header, p.bc, nil) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) // Iterate over and process the individual transactions - plugins.PreProcessBlock(block) + pluginPreProcessBlock(block) for i, tx := range block.Transactions() { msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee) if err != nil { - plugins.BlockProcessingError(tx, block, err) + pluginBlockProcessingError(tx, block, err) return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } statedb.Prepare(tx.Hash(), block.Hash(), i) - plugins.PreProcessTransaction(tx, block, i) + pluginPreProcessTransaction(tx, block, i) receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, header, tx, usedGas, vmenv) if err != nil { - plugins.BlockProcessingError(tx, block, err) + pluginBlockProcessingError(tx, block, err) return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err) } - plugins.PostProcessTransaction(tx, block, i, receipt) + pluginPostProcessTransaction(tx, block, i, receipt) receipts = append(receipts, receipt) allLogs = append(allLogs, receipt.Logs...) } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles()) - plugins.PostProcessBlock(block) + pluginPostProcessBlock(block) return receipts, allLogs, *usedGas, nil } diff --git a/eth/backend.go b/eth/backend.go index 3ef6baa5c..c2480b378 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -53,7 +53,6 @@ import ( "github.com/ethereum/go-ethereum/p2p/dnsdisc" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/plugins" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" ) @@ -146,7 +145,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { chainDb: chainDb, eventMux: stack.EventMux(), accountManager: stack.AccountManager(), - engine: plugins.CreateConsensusEngine(stack, chainConfig, ðashConfig, config.Miner.Notify, config.Miner.Noverify, chainDb), + engine: pluginCreateConsensusEngine(stack, chainConfig, ðashConfig, config.Miner.Notify, config.Miner.Noverify, chainDb), closeBloomHandler: make(chan struct{}), networkID: config.NetworkId, gasPrice: config.Miner.GasPrice, @@ -191,7 +190,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { Preimages: config.Preimages, } ) - plugins.UpdateBlockchainVMConfig(&vmConfig) + pluginUpdateBlockchainVMConfig(&vmConfig) eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit) if err != nil { return nil, err diff --git a/eth/plugin_hooks.go b/eth/plugin_hooks.go new file mode 100644 index 000000000..d3da88453 --- /dev/null +++ b/eth/plugin_hooks.go @@ -0,0 +1,52 @@ +package eth + +import ( + "github.com/ethereum/go-ethereum/plugins" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/ethdb" +) + + + func pluginCreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine { + fnList := plugins.Lookup("CreateConsensusEngine", func(item interface{}) bool { + _, ok := item.(func(*node.Node, *params.ChainConfig, *ethash.Config, []string, bool, ethdb.Database) consensus.Engine) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(*node.Node, *params.ChainConfig, *ethash.Config, []string, bool, ethdb.Database) consensus.Engine); ok { + return fn(stack, chainConfig, config, notify, noverify, db) + } + } + return ethconfig.CreateConsensusEngine(stack, chainConfig, config, notify, noverify, db) +} +func pluginUpdateBlockchainVMConfig(cfg *vm.Config) { + fnList := plugins.Lookup("UpdateBlockchainVMConfig", func(item interface{}) bool { + _, ok := item.(func(*vm.Config)) + return ok + }) + for _, fni := range fnList { + if fn, ok := fni.(func(*vm.Config)); ok { + fn(cfg) + return + } + } +} + +// ce, err := plug.Lookup("CreateConsensusEngine") +// if err == nil { +// cce, ok := ce.(func (stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine) +// if !ok { +// log.Warn("Could not cast plugin.CreateConsensusEngine to appropriate function", "file", fpath) +// } else { +// if setConsensus { +// log.Warn("CreateConsensusEngine redeclared", "file", fpath) +// } +// pl.CreateConsensusEngine = cce +// setConsensus = true +// } +// } diff --git a/eth/tracers/api.go b/eth/tracers/api.go index c9b414260..74ee4490d 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -40,7 +40,6 @@ import ( "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/plugins" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" ) @@ -801,7 +800,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTrac } } // Get the tracer from the plugin loader - if tr, ok := plugins.GetTracer(*config.Tracer); ok { + if tr, ok := getPluginTracer(*config.Tracer); ok { tracer = tr(statedb) } else { // Constuct the JavaScript tracer to execute with @@ -851,7 +850,7 @@ func (api *API) traceTx(ctx context.Context, message core.Message, txctx *txTrac StructLogs: ethapi.FormatLogs(tracer.StructLogs()), }, nil - case plugins.TracerResult: + case TracerResult: return tracer.GetResult() case *Tracer: diff --git a/eth/tracers/plugin_hooks.go b/eth/tracers/plugin_hooks.go new file mode 100644 index 000000000..3eaaeba7b --- /dev/null +++ b/eth/tracers/plugin_hooks.go @@ -0,0 +1,28 @@ +package tracers + +import ( + "github.com/ethereum/go-ethereum/plugins" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/core/state" +) + + +type TracerResult interface { + vm.Tracer + GetResult() (interface{}, error) +} + +func getPluginTracer(name string) (func(*state.StateDB)TracerResult, bool) { + tracers := plugins.Lookup("Tracers", func(item interface{}) bool { + _, ok := item.(map[string]func(*state.StateDB)TracerResult) + return ok + }) + for _, tmap := range tracers { + if tracerMap, ok := tmap.(map[string]func(*state.StateDB)TracerResult); ok { + if tracer, ok := tracerMap[name]; ok { + return tracer, true + } + } + } + return nil, false +} diff --git a/plugins/interface.go b/plugins/interface.go deleted file mode 100644 index 2c84f5d1f..000000000 --- a/plugins/interface.go +++ /dev/null @@ -1,37 +0,0 @@ -package plugins - -import ( - "context" - "math/big" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" -) - - -type StateDB interface { - Error() error - GetLogs(hash common.Hash) []*types.Log - Logs() []*types.Log - Preimages() map[common.Hash][]byte - Exist(addr common.Address) bool - Empty(addr common.Address) bool - GetBalance(addr common.Address) *big.Int - GetNonce(addr common.Address) uint64 - TxIndex() int - BlockHash() common.Hash - GetCode(addr common.Address) []byte - GetCodeSize(addr common.Address) int - GetCodeHash(addr common.Address) common.Hash - GetState(addr common.Address, hash common.Hash) common.Hash - GetProof(addr common.Address) ([][]byte, error) - GetProofByHash(addrHash common.Hash) ([][]byte, error) - GetStorageProof(a common.Address, key common.Hash) ([][]byte, error) - GetStorageProofByHash(a common.Address, key common.Hash) ([][]byte, error) - GetCommittedState(addr common.Address, hash common.Hash) common.Hash - HasSuicided(addr common.Address) bool - ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error - GetRefund() uint64 - AddressInAccessList(addr common.Address) bool - SlotInAccessList(addr common.Address, slot common.Hash) (addressPresent bool, slotPresent bool) -} diff --git a/plugins/plugin_loader.go b/plugins/plugin_loader.go index 4f3450193..b1017fbbd 100644 --- a/plugins/plugin_loader.go +++ b/plugins/plugin_loader.go @@ -2,15 +2,8 @@ package plugins import ( "plugin" - "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/consensus" - "github.com/ethereum/go-ethereum/consensus/ethash" - // "github.com/ethereum/go-ethereum/eth/ethconfig" - "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/params" "gopkg.in/urfave/cli.v1" "flag" "io/ioutil" @@ -29,19 +22,32 @@ type TracerResult interface { type PluginLoader struct{ - Plugins []plugin.Plugin - Tracers map[string]func(StateDB)TracerResult - StateHooks []interface{} // TODO: Set interface - // RPCPlugins []APILoader + Plugins []*plugin.Plugin Subcommands map[string]Subcommand Flags []*flag.FlagSet - CreateConsensusEngine func(stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine - UpdateBlockchainVMConfig func(*vm.Config) - PreProcessBlockList []func(*types.Block) - PreProcessTransactionList []func(*types.Transaction, *types.Block, int) - BlockProcessingErrorList []func(*types.Transaction, *types.Block, error) - PostProcessTransactionList []func(*types.Transaction, *types.Block, int, *types.Receipt) - PostProcessBlockList []func(*types.Block) + LookupCache map[string][]interface{} +} + +func (pl *PluginLoader) Lookup(name string, validate func(interface{}) bool) []interface{} { + if v, ok := pl.LookupCache[name]; ok { return v } + results := []interface{}{} + for _, plugin := range pl.Plugins { + if v, err := plugin.Lookup(name); err == nil { + if validate(v) { + results = append(results, v) + } + } + } + pl.LookupCache[name] = results + return results +} + +func Lookup(name string, validate func(interface{}) bool) []interface{} { + if DefaultPluginLoader == nil { + log.Warn("Lookup attempted, but PluginLoader is not initialized", "name", name) + return []interface{}{} + } + return DefaultPluginLoader.Lookup(name, validate) } @@ -50,21 +56,19 @@ var DefaultPluginLoader *PluginLoader func NewPluginLoader(target string) (*PluginLoader, error) { pl := &PluginLoader{ - Plugins: []plugin.Plugin, + Plugins: []*plugin.Plugin{}, // RPCPlugins: []APILoader{}, Subcommands: make(map[string]Subcommand), - Tracers: make(map[string]func(StateDB)TracerResult), Flags: []*flag.FlagSet{}, + LookupCache: make(map[string][]interface{}), // CreateConsensusEngine: ethconfig.CreateConsensusEngine, - UpdateBlockchainVMConfig: func(cfg *vm.Config) {}, + // UpdateBlockchainVMConfig: func(cfg *vm.Config) {}, } files, err := ioutil.ReadDir(target) if err != nil { log.Warn("Could not load plugins directory. Skipping.", "path", target) return pl, nil } - setConsensus := false - setUpdateBCVMCfg := false for _, file := range files { fpath := path.Join(target, file.Name()) if !strings.HasSuffix(file.Name(), ".so") { @@ -100,97 +104,7 @@ func NewPluginLoader(target string) (*PluginLoader, error) { } } } - tr, err := plug.Lookup("Tracers") - if err == nil { - tracers, ok := tr.(*map[string]func(StateDB)TracerResult) - if !ok { - log.Warn("Could not cast plugin.Tracers to `map[string]vm.Tracer`", "file", fpath) - } else { - for k, v := range *tracers { - if _, ok := pl.Tracers[k]; ok { - log.Warn("Tracer redeclared", "file", fpath, "tracer", k) - } - pl.Tracers[k] = v - } - } - } - ce, err := plug.Lookup("CreateConsensusEngine") - if err == nil { - cce, ok := ce.(func (stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine) - if !ok { - log.Warn("Could not cast plugin.CreateConsensusEngine to appropriate function", "file", fpath) - } else { - if setConsensus { - log.Warn("CreateConsensusEngine redeclared", "file", fpath) - } - pl.CreateConsensusEngine = cce - setConsensus = true - } - } - vmcfgu, err := plug.Lookup("UpdateBlockchainVMConfig") - if err == nil { - vmcfgfn, ok := vmcfgu.(func(*vm.Config)) - if !ok { - log.Warn("Could not cast plugin.UpdateBlockchainVMConfig to appropriate function", "file", fpath) - } else { - if setUpdateBCVMCfg { - log.Warn("UpdateBlockchainVMConfig redeclared", "file", fpath) - } - pl.UpdateBlockchainVMConfig = vmcfgfn - setUpdateBCVMCfg = true - } - } - - - prepb, err := plug.Lookup("PreProcessBlock") - if err == nil { - prepbfn, ok := prepb.(func(*types.Block)) - if !ok { - log.Warn("Could not cast plugin.PreProcessBlock to appropriate function", "file", fpath) - } else { - pl.PreProcessBlockList = append(pl.PreProcessBlockList, prepbfn) - } - } - prept, err := plug.Lookup("PreProcessTransaction") - if err == nil { - preptfn, ok := prept.(func(*types.Transaction, *types.Block, int)) - if !ok { - log.Warn("Could not cast plugin.PreProcessTransaction to appropriate function", "file", fpath) - } else { - pl.PreProcessTransactionList = append(pl.PreProcessTransactionList, preptfn) - } - } - bpe, err := plug.Lookup("BlockProcessingError") - if err == nil { - bpefn, ok := bpe.(func(*types.Transaction, *types.Block, error)) - if !ok { - log.Warn("Could not cast plugin.BlockProcessingError to appropriate function", "file", fpath) - } else { - pl.BlockProcessingErrorList = append(pl.BlockProcessingErrorList, bpefn) - } - } - prept, err := plug.Lookup("PostProcessTransaction") - if err == nil { - preptfn, ok := prept.(func(*types.Transaction, *types.Block, int, *types.Receipt)) - if !ok { - log.Warn("Could not cast plugin.PostProcessTransaction to appropriate function", "file", fpath) - } else { - pl.PostProcessTransactionList = append(pl.PostProcessTransactionList, preptfn) - } - } - prepb, err := plug.Lookup("PostProcessBlock") - if err == nil { - prepbfn, ok := prepb.(func(*types.Block)) - if !ok { - log.Warn("Could not cast plugin.PostProcessBlock to appropriate function", "file", fpath) - } else { - pl.PostProcessBlockList = append(pl.PostProcessBlockList, prepbfn) - } - } - - - - + pl.Plugins = append(pl.Plugins, plug) } return pl, nil } @@ -227,94 +141,3 @@ func ParseFlags(args []string) bool { } return DefaultPluginLoader.ParseFlags(args) } - -func (pl *PluginLoader) GetTracer(s string) (func(StateDB)TracerResult, bool) { - tr, ok := pl.Tracers[s] - return tr, ok -} - -func GetTracer(s string) (func(StateDB)TracerResult, bool) { - if DefaultPluginLoader == nil { - log.Warn("Attempting GetTracer, but default PluginLoader has not been initialized") - return nil, false - } - return DefaultPluginLoader.GetTracer(s) -} - -// func CreateConsensusEngine(stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine { -// if DefaultPluginLoader == nil { -// log.Warn("Attempting CreateConsensusEngine, but default PluginLoader has not been initialized") -// return ethconfig.CreateConsensusEngine(stack, chainConfig, config, notify, noverify, db) -// } -// return DefaultPluginLoader.CreateConsensusEngine(stack, chainConfig, config, notify, noverify, db) -// } - -func UpdateBlockchainVMConfig(cfg *vm.Config) { - if DefaultPluginLoader == nil { - log.Warn("Attempting UpdateBlockchainVMConfig, but default PluginLoader has not been initialized") - return - } - DefaultPluginLoader.UpdateBlockchainVMConfig(cfg) -} - - -func (pl *PluginLoader) PreProcessBlock(block *types.Block) { - for _, fn := range pl.PreProcessBlockList { - fn(block) - } -} -func PreProcessBlock(block *types.Block) { - if DefaultPluginLoader == nil { - log.Warn("Attempting PreProcessBlock, but default PluginLoader has not been initialized") - return - } - DefaultPluginLoader.PreProcessBlock(block) -} -func (pl *PluginLoader) PreProcessTransaction(tx *types.Transaction, block *types.Block, i int) { - for _, fn := range pl.PreProcessTransactionList { - fn(tx, block, i) - } -} -func PreProcessTransaction(tx *types.Transaction, block *types.Block, i int) { - if DefaultPluginLoader == nil { - log.Warn("Attempting PreProcessTransaction, but default PluginLoader has not been initialized") - return - } - DefaultPluginLoader.PreProcessTransaction(tx, block, i) -} -func (pl *PluginLoader) BlockProcessingError(tx *types.Transaction, block *types.Block, err error) { - for _, fn := range pl.BlockProcessingErrorList { - fn(tx, block, err) - } -} -func BlockProcessingError(tx *types.Transaction, block *types.Block, err error) { - if DefaultPluginLoader == nil { - log.Warn("Attempting BlockProcessingError, but default PluginLoader has not been initialized") - return - } - DefaultPluginLoader.BlockProcessingError(tx, block, err) -} -func (pl *PluginLoader) PostProcessTransaction(tx *types.Transaction, block *types.Block, i int, receipt *types.Receipt) { - for _, fn := range pl.PostProcessTransactionList { - fn(tx, block, i, receipt) - } -} -func PostProcessTransaction(tx *types.Transaction, block *types.Block, i int, receipt *types.Receipt) { - if DefaultPluginLoader == nil { - log.Warn("Attempting PostProcessTransaction, but default PluginLoader has not been initialized") - return - } - DefaultPluginLoader.PostProcessTransaction(tx, block, i, receipt) -} -func (pl *PluginLoader) PostProcessBlock(block *types.Block) { - for _, fn := range pl.PostProcessBlockList { - fn(block) - } -} -func PostProcessBlock(block *types.Block) { - if DefaultPluginLoader == nil { - log.Warn("Attempting PostProcessBlock, but default PluginLoader has not been initialized") - return - } - DefaultPluginLoader.PostProcessBlock(block) -}