Avoid unnecessary RLP encoding

While looking for the source of a memory leak, I decided to optimize
the metatracer to avoid encoding values when there weren't any tracers
configured to received the encoded values.

I also avoided putting the EVM into debug mode when there weren't any
tracers configured.

None of these fixed the memory leak, but they still seem like good
practices. Memory leak fix is in the next commit.
This commit is contained in:
Austin Roberts 2022-01-07 11:34:07 -06:00
parent 13009f4c51
commit 1201e7c4f8
2 changed files with 13 additions and 6 deletions

View File

@ -190,6 +190,7 @@ type metaTracer struct {
} }
func (mt *metaTracer) PreProcessBlock(block *types.Block) { func (mt *metaTracer) PreProcessBlock(block *types.Block) {
if len(mt.tracers) == 0 { return }
blockHash := core.Hash(block.Hash()) blockHash := core.Hash(block.Hash())
blockNumber := block.NumberU64() blockNumber := block.NumberU64()
encoded, _ := rlp.EncodeToBytes(block) encoded, _ := rlp.EncodeToBytes(block)
@ -198,6 +199,7 @@ func (mt *metaTracer) PreProcessBlock(block *types.Block) {
} }
} }
func (mt *metaTracer) PreProcessTransaction(tx *types.Transaction, block *types.Block, i int) { func (mt *metaTracer) PreProcessTransaction(tx *types.Transaction, block *types.Block, i int) {
if len(mt.tracers) == 0 { return }
blockHash := core.Hash(block.Hash()) blockHash := core.Hash(block.Hash())
transactionHash := core.Hash(tx.Hash()) transactionHash := core.Hash(tx.Hash())
for _, tracer := range mt.tracers { for _, tracer := range mt.tracers {
@ -205,6 +207,7 @@ func (mt *metaTracer) PreProcessTransaction(tx *types.Transaction, block *types.
} }
} }
func (mt *metaTracer) BlockProcessingError(tx *types.Transaction, block *types.Block, err error) { func (mt *metaTracer) BlockProcessingError(tx *types.Transaction, block *types.Block, err error) {
if len(mt.tracers) == 0 { return }
blockHash := core.Hash(block.Hash()) blockHash := core.Hash(block.Hash())
transactionHash := core.Hash(tx.Hash()) transactionHash := core.Hash(tx.Hash())
for _, tracer := range mt.tracers { for _, tracer := range mt.tracers {
@ -212,6 +215,7 @@ func (mt *metaTracer) BlockProcessingError(tx *types.Transaction, block *types.B
} }
} }
func (mt *metaTracer) PostProcessTransaction(tx *types.Transaction, block *types.Block, i int, receipt *types.Receipt) { func (mt *metaTracer) PostProcessTransaction(tx *types.Transaction, block *types.Block, i int, receipt *types.Receipt) {
if len(mt.tracers) == 0 { return }
blockHash := core.Hash(block.Hash()) blockHash := core.Hash(block.Hash())
transactionHash := core.Hash(tx.Hash()) transactionHash := core.Hash(tx.Hash())
receiptBytes, _ := json.Marshal(receipt) receiptBytes, _ := json.Marshal(receipt)
@ -220,6 +224,7 @@ func (mt *metaTracer) PostProcessTransaction(tx *types.Transaction, block *types
} }
} }
func (mt *metaTracer) PostProcessBlock(block *types.Block) { func (mt *metaTracer) PostProcessBlock(block *types.Block) {
if len(mt.tracers) == 0 { return }
blockHash := core.Hash(block.Hash()) blockHash := core.Hash(block.Hash())
for _, tracer := range mt.tracers { for _, tracer := range mt.tracers {
tracer.PostProcessBlock(blockHash) tracer.PostProcessBlock(blockHash)
@ -258,7 +263,7 @@ func (mt *metaTracer) CaptureExit(output []byte, gasUsed uint64, err error) {
} }
} }
func PluginGetBlockTracer(pl *plugins.PluginLoader, hash common.Hash, statedb *state.StateDB) *metaTracer { func PluginGetBlockTracer(pl *plugins.PluginLoader, hash common.Hash, statedb *state.StateDB) (*metaTracer, bool) {
//look for a function that takes whatever the ctx provides and statedb and returns a core.blocktracer append into meta tracer //look for a function that takes whatever the ctx provides and statedb and returns a core.blocktracer append into meta tracer
tracerList := plugins.Lookup("GetLiveTracer", func(item interface{}) bool { tracerList := plugins.Lookup("GetLiveTracer", func(item interface{}) bool {
_, ok := item.(func(core.Hash, core.StateDB) core.BlockTracer) _, ok := item.(func(core.Hash, core.StateDB) core.BlockTracer)
@ -274,9 +279,9 @@ func PluginGetBlockTracer(pl *plugins.PluginLoader, hash common.Hash, statedb *s
} }
} }
} }
return mt return mt, (len(mt.tracers) > 0)
} }
func pluginGetBlockTracer(hash common.Hash, statedb *state.StateDB) *metaTracer { func pluginGetBlockTracer(hash common.Hash, statedb *state.StateDB) (*metaTracer, bool) {
if plugins.DefaultPluginLoader == nil { if plugins.DefaultPluginLoader == nil {
log.Warn("Attempting GetBlockTracer, but default PluginLoader has not been initialized") log.Warn("Attempting GetBlockTracer, but default PluginLoader has not been initialized")
return &metaTracer{} return &metaTracer{}

View File

@ -71,9 +71,11 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
misc.ApplyDAOHardFork(statedb) misc.ApplyDAOHardFork(statedb)
} }
blockContext := NewEVMBlockContext(header, p.bc, nil) blockContext := NewEVMBlockContext(header, p.bc, nil)
blockTracer := pluginGetBlockTracer(header.Hash(), statedb) blockTracer, ok := pluginGetBlockTracer(header.Hash(), statedb)
if ok {
cfg.Tracer = blockTracer cfg.Tracer = blockTracer
cfg.Debug = true cfg.Debug = true
}
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
pluginPreProcessBlock(block) pluginPreProcessBlock(block)