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.
This commit is contained in:
Austin Roberts 2021-06-25 22:38:04 -05:00
parent 091a2f4884
commit 03808de29a
10 changed files with 283 additions and 256 deletions

View File

@ -324,7 +324,7 @@ func geth(ctx *cli.Context) error {
prepare(ctx) prepare(ctx)
stack, backend := makeFullNode(ctx) stack, backend := makeFullNode(ctx)
defer stack.Close() defer stack.Close()
stack.RegisterAPIs(plugins.GetAPIs(stack, backend)) stack.RegisterAPIs(pluginGetAPIs(stack, backend))
startNode(ctx, stack, backend) startNode(ctx, stack, backend)
stack.Wait() stack.Wait()

102
cmd/geth/plugin_hooks.go Normal file
View File

@ -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)
}

62
core/plugin_hooks.go Normal file
View File

@ -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)
}
}
}

View File

@ -27,7 +27,6 @@ import (
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/plugins"
) )
// StateProcessor is a basic Processor, which takes care of transitioning // 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) blockContext := NewEVMBlockContext(header, p.bc, nil)
vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg) vmenv := vm.NewEVM(blockContext, vm.TxContext{}, statedb, p.config, cfg)
// Iterate over and process the individual transactions // Iterate over and process the individual transactions
plugins.PreProcessBlock(block) pluginPreProcessBlock(block)
for i, tx := range block.Transactions() { for i, tx := range block.Transactions() {
msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee) msg, err := tx.AsMessage(types.MakeSigner(p.config, header.Number), header.BaseFee)
if err != nil { 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) 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) 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) receipt, err := applyTransaction(msg, p.config, p.bc, nil, gp, statedb, header, tx, usedGas, vmenv)
if err != nil { 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) 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) receipts = append(receipts, receipt)
allLogs = append(allLogs, receipt.Logs...) allLogs = append(allLogs, receipt.Logs...)
} }
// Finalize the block, applying any consensus engine specific extras (e.g. block rewards) // Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles()) p.engine.Finalize(p.bc, header, statedb, block.Transactions(), block.Uncles())
plugins.PostProcessBlock(block) pluginPostProcessBlock(block)
return receipts, allLogs, *usedGas, nil return receipts, allLogs, *usedGas, nil
} }

View File

@ -53,7 +53,6 @@ import (
"github.com/ethereum/go-ethereum/p2p/dnsdisc" "github.com/ethereum/go-ethereum/p2p/dnsdisc"
"github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/plugins"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/rpc"
) )
@ -146,7 +145,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
chainDb: chainDb, chainDb: chainDb,
eventMux: stack.EventMux(), eventMux: stack.EventMux(),
accountManager: stack.AccountManager(), accountManager: stack.AccountManager(),
engine: plugins.CreateConsensusEngine(stack, chainConfig, &ethashConfig, config.Miner.Notify, config.Miner.Noverify, chainDb), engine: pluginCreateConsensusEngine(stack, chainConfig, &ethashConfig, config.Miner.Notify, config.Miner.Noverify, chainDb),
closeBloomHandler: make(chan struct{}), closeBloomHandler: make(chan struct{}),
networkID: config.NetworkId, networkID: config.NetworkId,
gasPrice: config.Miner.GasPrice, gasPrice: config.Miner.GasPrice,
@ -191,7 +190,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) {
Preimages: config.Preimages, Preimages: config.Preimages,
} }
) )
plugins.UpdateBlockchainVMConfig(&vmConfig) pluginUpdateBlockchainVMConfig(&vmConfig)
eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit) eth.blockchain, err = core.NewBlockChain(chainDb, cacheConfig, chainConfig, eth.engine, vmConfig, eth.shouldPreserve, &config.TxLookupLimit)
if err != nil { if err != nil {
return nil, err return nil, err

52
eth/plugin_hooks.go Normal file
View File

@ -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
// }
// }

View File

@ -40,7 +40,6 @@ import (
"github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/internal/ethapi"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/plugins"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/rpc" "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 // 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) tracer = tr(statedb)
} else { } else {
// Constuct the JavaScript tracer to execute with // 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()), StructLogs: ethapi.FormatLogs(tracer.StructLogs()),
}, nil }, nil
case plugins.TracerResult: case TracerResult:
return tracer.GetResult() return tracer.GetResult()
case *Tracer: case *Tracer:

View File

@ -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
}

View File

@ -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)
}

View File

@ -2,15 +2,8 @@ package plugins
import ( import (
"plugin" "plugin"
"github.com/ethereum/go-ethereum/node"
"github.com/ethereum/go-ethereum/log" "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/vm"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/params"
"gopkg.in/urfave/cli.v1" "gopkg.in/urfave/cli.v1"
"flag" "flag"
"io/ioutil" "io/ioutil"
@ -29,19 +22,32 @@ type TracerResult interface {
type PluginLoader struct{ type PluginLoader struct{
Plugins []plugin.Plugin Plugins []*plugin.Plugin
Tracers map[string]func(StateDB)TracerResult
StateHooks []interface{} // TODO: Set interface
// RPCPlugins []APILoader
Subcommands map[string]Subcommand Subcommands map[string]Subcommand
Flags []*flag.FlagSet Flags []*flag.FlagSet
CreateConsensusEngine func(stack *node.Node, chainConfig *params.ChainConfig, config *ethash.Config, notify []string, noverify bool, db ethdb.Database) consensus.Engine LookupCache map[string][]interface{}
UpdateBlockchainVMConfig func(*vm.Config) }
PreProcessBlockList []func(*types.Block)
PreProcessTransactionList []func(*types.Transaction, *types.Block, int) func (pl *PluginLoader) Lookup(name string, validate func(interface{}) bool) []interface{} {
BlockProcessingErrorList []func(*types.Transaction, *types.Block, error) if v, ok := pl.LookupCache[name]; ok { return v }
PostProcessTransactionList []func(*types.Transaction, *types.Block, int, *types.Receipt) results := []interface{}{}
PostProcessBlockList []func(*types.Block) 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) { func NewPluginLoader(target string) (*PluginLoader, error) {
pl := &PluginLoader{ pl := &PluginLoader{
Plugins: []plugin.Plugin, Plugins: []*plugin.Plugin{},
// RPCPlugins: []APILoader{}, // RPCPlugins: []APILoader{},
Subcommands: make(map[string]Subcommand), Subcommands: make(map[string]Subcommand),
Tracers: make(map[string]func(StateDB)TracerResult),
Flags: []*flag.FlagSet{}, Flags: []*flag.FlagSet{},
LookupCache: make(map[string][]interface{}),
// CreateConsensusEngine: ethconfig.CreateConsensusEngine, // CreateConsensusEngine: ethconfig.CreateConsensusEngine,
UpdateBlockchainVMConfig: func(cfg *vm.Config) {}, // UpdateBlockchainVMConfig: func(cfg *vm.Config) {},
} }
files, err := ioutil.ReadDir(target) files, err := ioutil.ReadDir(target)
if err != nil { if err != nil {
log.Warn("Could not load plugins directory. Skipping.", "path", target) log.Warn("Could not load plugins directory. Skipping.", "path", target)
return pl, nil return pl, nil
} }
setConsensus := false
setUpdateBCVMCfg := false
for _, file := range files { for _, file := range files {
fpath := path.Join(target, file.Name()) fpath := path.Join(target, file.Name())
if !strings.HasSuffix(file.Name(), ".so") { if !strings.HasSuffix(file.Name(), ".so") {
@ -100,97 +104,7 @@ func NewPluginLoader(target string) (*PluginLoader, error) {
} }
} }
} }
tr, err := plug.Lookup("Tracers") pl.Plugins = append(pl.Plugins, plug)
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)
}
}
} }
return pl, nil return pl, nil
} }
@ -227,94 +141,3 @@ func ParseFlags(args []string) bool {
} }
return DefaultPluginLoader.ParseFlags(args) 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)
}