Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Commit

Permalink
evm: fix iterator on deeply nested cache contexts (#617)
Browse files Browse the repository at this point in the history
* Problem: iterator on deeply nested cache contexts is extremely slow

Closes: #616

Solution:
- flatten cache contexts before doing `GetTxLogsTransient`

* Update x/evm/keeper/context_stack.go

* changelog

Co-authored-by: Federico Kunze Küllmer <[email protected]>
Co-authored-by: Federico Kunze <[email protected]>
  • Loading branch information
3 people committed Oct 7, 2021
1 parent 386943f commit b8798d7
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,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.
Expand Down
21 changes: 21 additions & 0 deletions x/evm/keeper/context_stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
3 changes: 3 additions & 0 deletions x/evm/keeper/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit b8798d7

Please sign in to comment.