From 997c9879dbb45057ab223410bfb3591caeb4d4c2 Mon Sep 17 00:00:00 2001 From: HuangYi Date: Sun, 3 Oct 2021 20:38:15 +0800 Subject: [PATCH] Problem: iterator on deeply nested cache contexts is extremely slow Closes: #616 Solution: - flatten cache contexts before doing `GetTxLogsTransient` --- x/evm/keeper/context_stack.go | 21 +++++++++++++++++++++ x/evm/keeper/state_transition.go | 3 +++ 2 files changed, 24 insertions(+) diff --git a/x/evm/keeper/context_stack.go b/x/evm/keeper/context_stack.go index 9d1bc68cab..530283a056 100644 --- a/x/evm/keeper/context_stack.go +++ b/x/evm/keeper/context_stack.go @@ -60,6 +60,27 @@ func (cs *ContextStack) Commit() { cs.cachedContexts = []cachedContext{} } +// CommitToRevision flatter multiple layers of cache contexts into one layer, +// to improve efficiency of db operations. +func (cs *ContextStack) CommitToRevision(target int) { + if target < 0 || target >= len(cs.cachedContexts) { + panic(fmt.Errorf("snapshot index %d out of bound [%d..%d)", target, 0, len(cs.cachedContexts))) + } + + targetCtx := cs.cachedContexts[target].ctx + // commit in order from top to bottom + for i := len(cs.cachedContexts) - 1; i > target; i-- { + // keep all the cosmos events + targetCtx.EventManager().EmitEvents(cs.cachedContexts[i].ctx.EventManager().Events()) + if cs.cachedContexts[i].commit == nil { + panic(fmt.Sprintf("commit function at index %d should not be nil", i)) + } else { + cs.cachedContexts[i].commit() + } + } + cs.cachedContexts = cs.cachedContexts[0 : target+1] +} + // Snapshot pushes a new cached context to the stack, // and returns the index of it. func (cs *ContextStack) Snapshot() int { diff --git a/x/evm/keeper/state_transition.go b/x/evm/keeper/state_transition.go index bece935210..f20a58853f 100644 --- a/x/evm/keeper/state_transition.go +++ b/x/evm/keeper/state_transition.go @@ -191,6 +191,9 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT return nil, stacktrace.Propagate(err, "failed to apply ethereum core message") } + // flatten the cache contexts to improve efficiency of following db operations + k.ctxStack.CommitToRevision(revision) + k.IncreaseTxIndexTransient() res.Hash = txHash.Hex()