From 1f9d2ca4a9db222ee34317177bafc2e88be5f965 Mon Sep 17 00:00:00 2001 From: Arya Lanjewar <102943033+AryaLanjewar3005@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:41:45 +0530 Subject: [PATCH 1/4] fix(vm): wire commit flag through DerivedEVMCallWithData to prevent unintended state persistence --- x/vm/keeper/call_evm.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x/vm/keeper/call_evm.go b/x/vm/keeper/call_evm.go index 341c30d359..c7f97b9d73 100644 --- a/x/vm/keeper/call_evm.go +++ b/x/vm/keeper/call_evm.go @@ -239,13 +239,12 @@ func (k Keeper) DerivedEVMCallWithData( // thus restricted to be used only inside `ApplyMessage`. tmpCtx, commitState := ctx.CacheContext() - // pass true to commit the StateDB - res, err := k.ApplyMessageWithConfig(tmpCtx, msg, nil, true, cfg, txConfig) + res, err := k.ApplyMessageWithConfig(tmpCtx, msg, nil, commit, cfg, txConfig) if err != nil { return nil, err } - if !res.Failed() { + if commit && !res.Failed() { commitState() } From 7cac8239441cfc91b29aa0d1f9449b1ad21954a5 Mon Sep 17 00:00:00 2001 From: Arya Lanjewar <102943033+AryaLanjewar3005@users.noreply.github.com> Date: Mon, 8 Jun 2026 15:59:55 +0530 Subject: [PATCH 2/4] fix(vm): gate tx log events and block bloom updates on successful derived EVM execution --- x/vm/keeper/call_evm.go | 49 +++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/x/vm/keeper/call_evm.go b/x/vm/keeper/call_evm.go index c7f97b9d73..fef91b5bb5 100644 --- a/x/vm/keeper/call_evm.go +++ b/x/vm/keeper/call_evm.go @@ -274,16 +274,6 @@ func (k Keeper) DerivedEVMCallWithData( attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyEthereumTxFailed, res.VmError)) } - txLogAttrs := make([]sdk.Attribute, len(res.Logs)) - for i, log := range res.Logs { - log.TxHash = ethTxHash - value, err := json.Marshal(log) - if err != nil { - return nil, errorsmod.Wrap(err, "failed to encode log") - } - txLogAttrs[i] = sdk.NewAttribute(types.AttributeKeyTxLog, string(value)) - } - // adding txData for more info in rpc methods in order to parse derived txs attrs = append(attrs, sdk.NewAttribute(types.AttributeKeyTxData, hexutil.Encode(msg.Data()))) // adding nonce for more info in rpc methods in order to parse derived txs @@ -294,10 +284,6 @@ func (k Keeper) DerivedEVMCallWithData( types.EventTypeEthereumTx, attrs..., ), - sdk.NewEvent( - types.EventTypeTxLog, - txLogAttrs..., - ), sdk.NewEvent( sdk.EventTypeMessage, sdk.NewAttribute(sdk.AttributeKeyModule, types.ModuleName), @@ -306,14 +292,33 @@ func (k Keeper) DerivedEVMCallWithData( ), }) - logs := types.LogsToEthereum(res.Logs) - var bloomReceipt ethtypes.Bloom - if len(logs) > 0 { - bloom := k.GetBlockBloomTransient(ctx) - bloom.Or(bloom, big.NewInt(0).SetBytes(ethtypes.LogsBloom(logs))) - bloomReceipt = ethtypes.BytesToBloom(bloom.Bytes()) - k.SetBlockBloomTransient(ctx, bloomReceipt.Big()) - k.SetLogSizeTransient(ctx, (k.GetLogSizeTransient(ctx))+uint64(len(logs))) + if !res.Failed() { + txLogAttrs := make([]sdk.Attribute, len(res.Logs)) + for i, log := range res.Logs { + log.TxHash = ethTxHash + value, err := json.Marshal(log) + if err != nil { + return nil, errorsmod.Wrap(err, "failed to encode log") + } + txLogAttrs[i] = sdk.NewAttribute(types.AttributeKeyTxLog, string(value)) + } + + ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeTxLog, + txLogAttrs..., + ), + }) + + logs := types.LogsToEthereum(res.Logs) + var bloomReceipt ethtypes.Bloom + if len(logs) > 0 { + bloom := k.GetBlockBloomTransient(ctx) + bloom.Or(bloom, big.NewInt(0).SetBytes(ethtypes.LogsBloom(logs))) + bloomReceipt = ethtypes.BytesToBloom(bloom.Bytes()) + k.SetBlockBloomTransient(ctx, bloomReceipt.Big()) + k.SetLogSizeTransient(ctx, (k.GetLogSizeTransient(ctx))+uint64(len(logs))) + } } } From 50a2dce8e1345de9e25cad42a7c856c4a15a5d5d Mon Sep 17 00:00:00 2001 From: Arya Lanjewar <102943033+AryaLanjewar3005@users.noreply.github.com> Date: Tue, 9 Jun 2026 14:56:55 +0530 Subject: [PATCH 3/4] fix(rpc): fallback to event-query reconstruction on KV indexer miss for derived transaction lookups --- rpc/backend/tx_info.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/rpc/backend/tx_info.go b/rpc/backend/tx_info.go index 1531c5a774..6f7428607a 100644 --- a/rpc/backend/tx_info.go +++ b/rpc/backend/tx_info.go @@ -410,10 +410,10 @@ func (b *Backend) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNum func (b *Backend) GetTxByEthHash(hash common.Hash) (*types.TxResult, *rpctypes.TxResultAdditionalFields, error) { if b.indexer != nil { txRes, err := b.indexer.GetByTxHash(hash) - if err != nil { - return nil, nil, err + if err == nil { + return txRes, nil, nil } - return txRes, nil, nil + // indexer miss or no derived-tx metadata — fall through to event-query reconstruction } // fallback to tendermint tx indexer @@ -430,10 +430,10 @@ func (b *Backend) GetTxByEthHash(hash common.Hash) (*types.TxResult, *rpctypes.T func (b *Backend) GetTxByEthHashAndMsgIndex(hash common.Hash, index int) (*types.TxResult, *rpctypes.TxResultAdditionalFields, error) { if b.indexer != nil { txRes, err := b.indexer.GetByTxHash(hash) - if err != nil { - return nil, nil, err + if err == nil { + return txRes, nil, nil } - return txRes, nil, nil + // indexer miss or no derived-tx metadata — fall through to event-query reconstruction } // fallback to tendermint tx indexer From 9321243ef6fa6f787014cb9bff714bde914d3185 Mon Sep 17 00:00:00 2001 From: Arya Lanjewar <102943033+AryaLanjewar3005@users.noreply.github.com> Date: Tue, 9 Jun 2026 15:23:15 +0530 Subject: [PATCH 4/4] fix(vm): replace hardcoded DerivedTxIndex with sequential transient counter for derived EVM executions --- x/vm/keeper/call_evm.go | 5 +++-- x/vm/types/events.go | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x/vm/keeper/call_evm.go b/x/vm/keeper/call_evm.go index fef91b5bb5..8cbadd6681 100644 --- a/x/vm/keeper/call_evm.go +++ b/x/vm/keeper/call_evm.go @@ -260,8 +260,7 @@ func (k Keeper) DerivedEVMCallWithData( sdk.NewAttribute(sdk.AttributeKeyAmount, value.String()), // add event for ethereum transaction hash format; sdk.NewAttribute(types.AttributeKeyEthereumTxHash, ethTxHash), - // add event for index of valid ethereum tx; NOTE: default txindex for derivedTx - sdk.NewAttribute(types.AttributeKeyTxIndex, strconv.FormatUint(types.DerivedTxIndex, 10)), + sdk.NewAttribute(types.AttributeKeyTxIndex, strconv.FormatUint(uint64(txConfig.TxIndex), 10)), // add event for eth tx gas used, we can't get it from cosmos tx result when it contains multiple eth tx msgs. sdk.NewAttribute(types.AttributeKeyTxGasUsed, strconv.FormatUint(gasUsed, 10)), }...) @@ -320,6 +319,8 @@ func (k Keeper) DerivedEVMCallWithData( k.SetLogSizeTransient(ctx, (k.GetLogSizeTransient(ctx))+uint64(len(logs))) } } + + k.SetTxIndexTransient(ctx, uint64(txConfig.TxIndex)+1) } if res.Failed() { diff --git a/x/vm/types/events.go b/x/vm/types/events.go index 489635e41d..15e5ddf046 100644 --- a/x/vm/types/events.go +++ b/x/vm/types/events.go @@ -30,6 +30,5 @@ const ( ) const ( - DerivedTxIndex = 9999 - DerivedTxType = 99 + DerivedTxType = 99 )