Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

Bad data may be generated due to insufficient gas during the execution of evm transactions #668

Closed
summerpro opened this issue Dec 22, 2020 · 2 comments · Fixed by #677
Closed

Comments

@summerpro
Copy link
Contributor

summerpro commented Dec 22, 2020

System info: [Include Ethermint commit, operating system name, and other relevant details]

  • development

Steps to reproduce:

  1. An evm transaction is executed, and the evm.Create or evm.Call method is successfully executed, the "storage" data and "code" data in CommitStateDB have been modified.
  2. Start to execute the function "csdb.Finalise". The function needs to set data to the Store (Keeper). Due to insufficient gas, panic is triggered and the transaction execution fails.
  3. The data set to Store (Keeper) will be rolled back, but the "storage" data and "code" data from CommitStateDB will remain in CommitStateDB.
    4.Then, the problem encountered is Similar to issue667issue669
@summerpro
Copy link
Contributor Author

summerpro commented Dec 29, 2020

solution 1

  • We can create a new snapshot of CommitStateDB before executing the handler, after panic occurs, catch panic through recover, and rollback Keeper.CommitStateDB to the old state
// NewHandler returns a handler for Ethermint type messages.
func NewHandler(k Keeper) sdk.Handler {
	return func(ctx sdk.Context, msg sdk.Msg) (result *sdk.Result, err error) {
		snapshotStateDB := k.CommitStateDB.Copy()
		defer func() {
			if r := recover(); r != nil {
				types.CopyCommitStateDB(snapshotStateDB, k.CommitStateDB)
				panic(r)
			}
		}()
		ctx = ctx.WithEventManager(sdk.NewEventManager())
		switch msg := msg.(type) {
		case types.MsgEthereumTx:
			return handleMsgEthereumTx(ctx, k, msg)
		case types.MsgEthermint:
			return handleMsgEthermint(ctx, k, msg)
		default:
			return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
		}
	}
}

@summerpro
Copy link
Contributor Author

The following is a detailed description:
If the gas is insufficient during the execution of the "handler",
panic will be thrown from the function "ConsumeGas" and finally
caught by the function "runTx" from Cosmos. The function "runTx"
will think that the execution of Msg has failed and the modified
data in the Store will not take effect.

Stacktrace:runTx->runMsgs->handler->...->gaskv.Store.Set->ConsumeGas

The problem is that when the modified data in the Store does not take
effect, the data in the modified CommitStateDB is not rolled back,
they take effect, and dirty data is generated.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant