From aab793e7f4dee813e8798d7492299af1220e544e Mon Sep 17 00:00:00 2001 From: Thomas Nguy <81727899+thomas-nguy@users.noreply.github.com> Date: Wed, 14 Jul 2021 18:40:58 +0900 Subject: [PATCH] rpc: fix `BlockBloom` not found in header (#258) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix context index * return default bloom if cannot be found * fix blockbloom error * fix setting blockbloom transient in ctx * clean comments * remove unused method * update changelog * Update CHANGELOG.md Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com> --- CHANGELOG.md | 1 + ethereum/rpc/backend/backend.go | 12 ++++++------ ethereum/rpc/types/utils.go | 24 ------------------------ x/evm/keeper/state_transition.go | 16 ++++++++++------ 4 files changed, 17 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 37a03546..107dfa9a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ response now contains the ethereum-formatted `Hash` in hex format. * (eth) [\#845](https://github.com/cosmos/ethermint/pull/845) The `eth` namespace must be included in the list of API's as default to run the rpc server without error. * (evm) [#202](https://github.com/tharsis/ethermint/pull/202) Web3 api `SendTransaction`/`SendRawTransaction` returns ethereum compatible transaction hash, and query api `GetTransaction*` also accept that. +* (rpc) [tharsis#258](https://github.com/tharsis/ethermint/pull/258) Return empty `BloomFilter` instead of throwing an error when it cannot be found (`nil` or empty). ### Improvements diff --git a/ethereum/rpc/backend/backend.go b/ethereum/rpc/backend/backend.go index f98fad09..c3911bba 100644 --- a/ethereum/rpc/backend/backend.go +++ b/ethereum/rpc/backend/backend.go @@ -248,14 +248,14 @@ func (e *EVMBackend) HeaderByNumber(blockNum types.BlockNumber) (*ethtypes.Heade req := &evmtypes.QueryBlockBloomRequest{} - res, err := e.queryClient.BlockBloom(types.ContextWithHeight(resBlock.Block.Height), req) + blockBloomResp, err := e.queryClient.BlockBloom(types.ContextWithHeight(resBlock.Block.Height), req) if err != nil { e.logger.Debug("HeaderByNumber BlockBloom failed", "height", resBlock.Block.Height) - return nil, err + blockBloomResp = &evmtypes.QueryBlockBloomResponse{Bloom: ethtypes.Bloom{}.Bytes()} } ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header) - ethHeader.Bloom = ethtypes.BytesToBloom(res.Bloom) + ethHeader.Bloom = ethtypes.BytesToBloom(blockBloomResp.Bloom) return ethHeader, nil } @@ -269,14 +269,14 @@ func (e *EVMBackend) HeaderByHash(blockHash common.Hash) (*ethtypes.Header, erro req := &evmtypes.QueryBlockBloomRequest{} - res, err := e.queryClient.BlockBloom(types.ContextWithHeight(resBlock.Block.Height), req) + blockBloomResp, err := e.queryClient.BlockBloom(types.ContextWithHeight(resBlock.Block.Height), req) if err != nil { e.logger.Debug("HeaderByHash BlockBloom failed", "height", resBlock.Block.Height) - return nil, err + blockBloomResp = &evmtypes.QueryBlockBloomResponse{Bloom: ethtypes.Bloom{}.Bytes()} } ethHeader := types.EthHeaderFromTendermint(resBlock.Block.Header) - ethHeader.Bloom = ethtypes.BytesToBloom(res.Bloom) + ethHeader.Bloom = ethtypes.BytesToBloom(blockBloomResp.Bloom) return ethHeader, nil } diff --git a/ethereum/rpc/types/utils.go b/ethereum/rpc/types/utils.go index 21ed4e12..89ff1727 100644 --- a/ethereum/rpc/types/utils.go +++ b/ethereum/rpc/types/utils.go @@ -33,30 +33,6 @@ func RawTxToEthTx(clientCtx client.Context, txBz tmtypes.Tx) (*evmtypes.MsgEther return ethTx, nil } -// EthBlockFromTendermint returns a JSON-RPC compatible Ethereum blockfrom a given Tendermint block. -func EthBlockFromTendermint(clientCtx client.Context, queryClient *QueryClient, block *tmtypes.Block) (map[string]interface{}, error) { - gasLimit, err := BlockMaxGasFromConsensusParams(context.Background(), clientCtx) - if err != nil { - return nil, err - } - - transactions, gasUsed, err := EthTransactionsFromTendermint(clientCtx, block.Txs) - if err != nil { - return nil, err - } - - req := &evmtypes.QueryBlockBloomRequest{} - - res, err := queryClient.BlockBloom(ContextWithHeight(block.Height), req) - if err != nil { - return nil, err - } - - bloom := ethtypes.BytesToBloom(res.Bloom) - - return FormatBlock(block.Header, block.Size(), gasLimit, gasUsed, transactions, bloom), nil -} - // NewTransaction returns a transaction that will serialize to the RPC // representation, with the given location metadata set (if available). func NewTransaction(tx *ethtypes.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction { diff --git a/x/evm/keeper/state_transition.go b/x/evm/keeper/state_transition.go index 32c0a158..a90ce4c6 100644 --- a/x/evm/keeper/state_transition.go +++ b/x/evm/keeper/state_transition.go @@ -138,21 +138,25 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT txHash := tx.Hash() res.Hash = txHash.Hex() + logs := k.GetTxLogs(txHash) - // Set the bloom filter and commit only if transaction is NOT reverted + // Commit and switch to original context + if !res.Reverted { + commit() + } + k.ctx = originalCtx + + // Logs needs to be ignored when tx is reverted + // Set the log and bloom filter only when the tx is NOT REVERTED if !res.Reverted { - logs := k.GetTxLogs(txHash) res.Logs = types.NewLogsFromEth(logs) - // update block bloom filter + // Update block bloom filter in the original context because blockbloom is set in EndBlock bloom := k.GetBlockBloomTransient() bloom.Or(bloom, big.NewInt(0).SetBytes(ethtypes.LogsBloom(logs))) k.SetBlockBloomTransient(bloom) - - commit() } // refund gas prior to handling the vm error in order to set the updated gas meter - k.ctx = originalCtx leftoverGas := msg.Gas() - res.GasUsed leftoverGas, err = k.RefundGas(msg, leftoverGas) if err != nil {