diff --git a/CHANGELOG.md b/CHANGELOG.md index c45ff43f..3654f8dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes +* (evm) [tharsis#616](https://github.com/tharsis/ethermint/issues/616) Fix halt on deeply nested stack of cache context. Stack is now flattened before iterating over the tx logs. * (rpc, evm) [tharsis#614](https://github.com/tharsis/ethermint/issues/614) Use JSON for (un)marshaling tx `Log`s from events. * (rpc) [tharsis#611](https://github.com/tharsis/ethermint/pull/611) Fix panic on JSON-RPC when querying for an invalid block height. * (cmd) [tharsis#483](https://github.com/tharsis/ethermint/pull/483) Use config values on genesis accounts. diff --git a/x/evm/keeper/context_stack.go b/x/evm/keeper/context_stack.go index 9d1bc68c..f2a41917 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 commit the cache after the target revision, +// 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 8cd0f605..d331f20e 100644 --- a/x/evm/keeper/state_transition.go +++ b/x/evm/keeper/state_transition.go @@ -198,6 +198,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()