rpc, evm: remove tx Receipt (#81)

* rpc, evm: remove tc receipt

* rm receipt from gRPC query service

* update eth block

* update tx service response

* rpc tx fixes

* update bloom

* fix

* more fixes

* c++
This commit is contained in:
Federico Kunze 2021-06-08 07:11:37 -04:00 committed by GitHub
parent e3270aee5d
commit 6eadc8fdf8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 458 additions and 1820 deletions

View File

@ -39,11 +39,16 @@ Ref: https://keepachangelog.com/en/1.0.0/
### State Machine Breaking ### State Machine Breaking
* (rpc, evm) [tharsis#81](https://github.com/tharsis/ethermint/pull/81) Remove tx `Receipt` from store and replace it with fields obtained from the Tendermint RPC client.
* (evm) [tharsis#72](https://github.com/tharsis/ethermint/issues/72) Update `AccessList` to use `TransientStore` instead of map. * (evm) [tharsis#72](https://github.com/tharsis/ethermint/issues/72) Update `AccessList` to use `TransientStore` instead of map.
* (evm) [tharsis#68](https://github.com/tharsis/ethermint/issues/68) Replace block hash storage map to use staking `HistoricalInfo`. * (evm) [tharsis#68](https://github.com/tharsis/ethermint/issues/68) Replace block hash storage map to use staking `HistoricalInfo`.
### API Breaking ### API Breaking
* (proto, evm) [tharsis#81](https://github.com/tharsis/ethermint/pull/81) gRPC Query and Tx service changes:
* The `TxReceipt`, `TxReceiptsByBlockHeight` endpoints have been removed from the Query service.
* The `ContractAddress`, `Bloom` have been removed from the `MsgEthereumTxResponse` and the
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. * (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.
### Improvements ### Improvements
@ -53,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
### Bug Fixes ### Bug Fixes
* (rpc) [tharsis#81](https://github.com/tharsis/ethermint/pull/81) Fix transaction hashing and decoding on `eth_sendTransaction`.
* (rpc) [tharsis#45](https://github.com/tharsis/ethermint/pull/45) Use `EmptyUncleHash` and `EmptyRootHash` for empty ethereum `Header` fields. * (rpc) [tharsis#45](https://github.com/tharsis/ethermint/pull/45) Use `EmptyUncleHash` and `EmptyRootHash` for empty ethereum `Header` fields.
## [v0.4.1] - 2021-03-01 ## [v0.4.1] - 2021-03-01

View File

@ -45,10 +45,6 @@
- [QueryStorageResponse](#ethermint.evm.v1alpha1.QueryStorageResponse) - [QueryStorageResponse](#ethermint.evm.v1alpha1.QueryStorageResponse)
- [QueryTxLogsRequest](#ethermint.evm.v1alpha1.QueryTxLogsRequest) - [QueryTxLogsRequest](#ethermint.evm.v1alpha1.QueryTxLogsRequest)
- [QueryTxLogsResponse](#ethermint.evm.v1alpha1.QueryTxLogsResponse) - [QueryTxLogsResponse](#ethermint.evm.v1alpha1.QueryTxLogsResponse)
- [QueryTxReceiptRequest](#ethermint.evm.v1alpha1.QueryTxReceiptRequest)
- [QueryTxReceiptResponse](#ethermint.evm.v1alpha1.QueryTxReceiptResponse)
- [QueryTxReceiptsByBlockHeightRequest](#ethermint.evm.v1alpha1.QueryTxReceiptsByBlockHeightRequest)
- [QueryTxReceiptsByBlockHeightResponse](#ethermint.evm.v1alpha1.QueryTxReceiptsByBlockHeightResponse)
- [Query](#ethermint.evm.v1alpha1.Query) - [Query](#ethermint.evm.v1alpha1.Query)
@ -708,61 +704,6 @@ QueryTxLogs is the response type for the Query/TxLogs RPC method.
<a name="ethermint.evm.v1alpha1.QueryTxReceiptRequest"></a>
### QueryTxReceiptRequest
QueryTxReceiptRequest is the request type for the Query/TxReceipt RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `hash` | [string](#string) | | hash is the ethereum transaction hex hash to query the receipt for. |
<a name="ethermint.evm.v1alpha1.QueryTxReceiptResponse"></a>
### QueryTxReceiptResponse
QueryTxReceiptResponse is the response type for the Query/TxReceipt RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `receipt` | [TxReceipt](#ethermint.evm.v1alpha1.TxReceipt) | | receipt represents the ethereum receipt for the given transaction. |
<a name="ethermint.evm.v1alpha1.QueryTxReceiptsByBlockHeightRequest"></a>
### QueryTxReceiptsByBlockHeightRequest
QueryTxReceiptsByBlockHeightRequest is the request type for the Query/TxReceiptsByBlockHeight RPC method.
<a name="ethermint.evm.v1alpha1.QueryTxReceiptsByBlockHeightResponse"></a>
### QueryTxReceiptsByBlockHeightResponse
QueryTxReceiptsByBlockHeightResponse is the response type for the Query/TxReceiptsByBlockHeight RPC method.
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `receipts` | [TxReceipt](#ethermint.evm.v1alpha1.TxReceipt) | repeated | tx receipts list for the block |
<!-- end messages --> <!-- end messages -->
<!-- end enums --> <!-- end enums -->
@ -783,8 +724,6 @@ Query defines the gRPC querier service.
| `Storage` | [QueryStorageRequest](#ethermint.evm.v1alpha1.QueryStorageRequest) | [QueryStorageResponse](#ethermint.evm.v1alpha1.QueryStorageResponse) | Storage queries the balance of all coins for a single account. | GET|/ethermint/evm/v1alpha1/storage/{address}/{key}| | `Storage` | [QueryStorageRequest](#ethermint.evm.v1alpha1.QueryStorageRequest) | [QueryStorageResponse](#ethermint.evm.v1alpha1.QueryStorageResponse) | Storage queries the balance of all coins for a single account. | GET|/ethermint/evm/v1alpha1/storage/{address}/{key}|
| `Code` | [QueryCodeRequest](#ethermint.evm.v1alpha1.QueryCodeRequest) | [QueryCodeResponse](#ethermint.evm.v1alpha1.QueryCodeResponse) | Code queries the balance of all coins for a single account. | GET|/ethermint/evm/v1alpha1/codes/{address}| | `Code` | [QueryCodeRequest](#ethermint.evm.v1alpha1.QueryCodeRequest) | [QueryCodeResponse](#ethermint.evm.v1alpha1.QueryCodeResponse) | Code queries the balance of all coins for a single account. | GET|/ethermint/evm/v1alpha1/codes/{address}|
| `TxLogs` | [QueryTxLogsRequest](#ethermint.evm.v1alpha1.QueryTxLogsRequest) | [QueryTxLogsResponse](#ethermint.evm.v1alpha1.QueryTxLogsResponse) | TxLogs queries ethereum logs from a transaction. | GET|/ethermint/evm/v1alpha1/tx_logs/{hash}| | `TxLogs` | [QueryTxLogsRequest](#ethermint.evm.v1alpha1.QueryTxLogsRequest) | [QueryTxLogsResponse](#ethermint.evm.v1alpha1.QueryTxLogsResponse) | TxLogs queries ethereum logs from a transaction. | GET|/ethermint/evm/v1alpha1/tx_logs/{hash}|
| `TxReceipt` | [QueryTxReceiptRequest](#ethermint.evm.v1alpha1.QueryTxReceiptRequest) | [QueryTxReceiptResponse](#ethermint.evm.v1alpha1.QueryTxReceiptResponse) | TxReceipt queries a receipt by a transaction hash. | GET|/ethermint/evm/v1alpha1/tx_receipt/{hash}|
| `TxReceiptsByBlockHeight` | [QueryTxReceiptsByBlockHeightRequest](#ethermint.evm.v1alpha1.QueryTxReceiptsByBlockHeightRequest) | [QueryTxReceiptsByBlockHeightResponse](#ethermint.evm.v1alpha1.QueryTxReceiptsByBlockHeightResponse) | TxReceiptsByBlockHeight queries tx receipts by a block height. | GET|/ethermint/evm/v1alpha1/tx_receipts_block|
| `BlockLogs` | [QueryBlockLogsRequest](#ethermint.evm.v1alpha1.QueryBlockLogsRequest) | [QueryBlockLogsResponse](#ethermint.evm.v1alpha1.QueryBlockLogsResponse) | BlockLogs queries all the ethereum logs for a given block hash. | GET|/ethermint/evm/v1alpha1/block_logs/{hash}| | `BlockLogs` | [QueryBlockLogsRequest](#ethermint.evm.v1alpha1.QueryBlockLogsRequest) | [QueryBlockLogsResponse](#ethermint.evm.v1alpha1.QueryBlockLogsResponse) | BlockLogs queries all the ethereum logs for a given block hash. | GET|/ethermint/evm/v1alpha1/block_logs/{hash}|
| `BlockBloom` | [QueryBlockBloomRequest](#ethermint.evm.v1alpha1.QueryBlockBloomRequest) | [QueryBlockBloomResponse](#ethermint.evm.v1alpha1.QueryBlockBloomResponse) | BlockBloom queries the block bloom filter bytes at a given height. | GET|/ethermint/evm/v1alpha1/block_bloom| | `BlockBloom` | [QueryBlockBloomRequest](#ethermint.evm.v1alpha1.QueryBlockBloomRequest) | [QueryBlockBloomResponse](#ethermint.evm.v1alpha1.QueryBlockBloomResponse) | BlockBloom queries the block bloom filter bytes at a given height. | GET|/ethermint/evm/v1alpha1/block_bloom|
| `Params` | [QueryParamsRequest](#ethermint.evm.v1alpha1.QueryParamsRequest) | [QueryParamsResponse](#ethermint.evm.v1alpha1.QueryParamsResponse) | Params queries the parameters of x/evm module. | GET|/ethermint/evm/v1alpha1/params| | `Params` | [QueryParamsRequest](#ethermint.evm.v1alpha1.QueryParamsRequest) | [QueryParamsResponse](#ethermint.evm.v1alpha1.QueryParamsResponse) | Params queries the parameters of x/evm module. | GET|/ethermint/evm/v1alpha1/params|
@ -849,10 +788,9 @@ MsgEthereumTxResponse defines the Msg/EthereumTx response type.
| Field | Type | Label | Description | | Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- | | ----- | ---- | ----- | ----------- |
| `contract_address` | [string](#string) | | contract_address contains the ethereum address of the created contract (if any). If the state transition is an evm.Call, the contract address will be empty. | | `hash` | [string](#string) | | ethereum transaction hash in hex format. This hash differs from the Tendermint sha256 hash of the transaction bytes. See https://github.com/tendermint/tendermint/issues/6539 for reference |
| `bloom` | [bytes](#bytes) | | bloom represents the bloom filter bytes | | `logs` | [Log](#ethermint.evm.v1alpha1.Log) | repeated | logs contains the transaction hash and the proto-compatible ethereum logs. |
| `tx_logs` | [TransactionLogs](#ethermint.evm.v1alpha1.TransactionLogs) | | tx_logs contains the transaction hash and the proto-compatible ethereum logs. | | `ret` | [bytes](#bytes) | | returned data from evm function (result or data supplied with revert opcode) |
| `ret` | [bytes](#bytes) | | ret defines the bytes from the execution. |
| `reverted` | [bool](#bool) | | reverted flag is set to true when the call has been reverted | | `reverted` | [bool](#bool) | | reverted flag is set to true when the call has been reverted |

View File

@ -133,43 +133,44 @@ func (e *EVMBackend) EthBlockFromTendermint(
fullTx bool, fullTx bool,
) (map[string]interface{}, error) { ) (map[string]interface{}, error) {
req := &evmtypes.QueryTxReceiptsByBlockHeightRequest{} gasUsed := uint64(0)
txReceiptsResp, err := queryClient.TxReceiptsByBlockHeight(types.ContextWithHeight(block.Height), req)
if err != nil {
e.logger.WithError(err).Debugln("TxReceiptsByBlockHeight failed")
}
gasUsed := big.NewInt(0)
ethRPCTxs := []interface{}{} ethRPCTxs := []interface{}{}
if txReceiptsResp != nil { for i, txBz := range block.Txs {
// TODO: use msg.AsTransaction.Hash() for txHash once hashing is fixed on Tendermint
// https://github.com/tendermint/tendermint/issues/6539
hash := common.BytesToHash(txBz.Hash())
tx, gas := types.DecodeTx(e.clientCtx, txBz)
gasUsed += gas
msg, isEthTx := tx.(*evmtypes.MsgEthereumTx)
for _, receipt := range txReceiptsResp.Receipts {
hash := common.HexToHash(receipt.Hash)
if fullTx { if fullTx {
// full txs from receipts if !isEthTx {
tx, err := types.NewTransactionFromData( // TODO: eventually support Cosmos txs in the block
receipt.Data,
common.HexToAddress(receipt.From),
hash,
common.HexToHash(receipt.BlockHash),
receipt.BlockHeight,
receipt.Index,
)
if err != nil {
e.logger.WithError(err).Warningf("NewTransactionFromData for receipt %s failed", hash)
continue continue
} }
tx, err := types.NewTransactionFromData(
msg.Data,
common.HexToAddress(msg.From),
hash,
common.BytesToHash(block.Hash()),
uint64(block.Height),
uint64(i),
)
ethRPCTxs = append(ethRPCTxs, tx) ethRPCTxs = append(ethRPCTxs, tx)
gasUsed.Add(gasUsed, new(big.Int).SetUint64(receipt.Result.GasUsed))
} else { if err != nil {
// simply hashes e.logger.WithError(err).Debugln("NewTransactionFromData for receipt failed", "hash", hash.Hex)
ethRPCTxs = append(ethRPCTxs, hash) continue
} }
} else {
ethRPCTxs = append(ethRPCTxs, hash)
} }
} }
@ -181,7 +182,7 @@ func (e *EVMBackend) EthBlockFromTendermint(
} }
bloom := ethtypes.BytesToBloom(blockBloomResp.Bloom) bloom := ethtypes.BytesToBloom(blockBloomResp.Bloom)
formattedBlock := types.FormatBlock(block.Header, block.Size(), ethermint.DefaultRPCGasLimit, gasUsed, ethRPCTxs, bloom) formattedBlock := types.FormatBlock(block.Header, block.Size(), ethermint.DefaultRPCGasLimit, new(big.Int).SetUint64(gasUsed), ethRPCTxs, bloom)
e.logger.Infoln(formattedBlock) e.logger.Infoln(formattedBlock)
return formattedBlock, nil return formattedBlock, nil

View File

@ -21,13 +21,13 @@ import (
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/tmhash" tmtypes "github.com/tendermint/tendermint/types"
"github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/common/hexutil"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/crypto"
"github.com/cosmos/ethermint/crypto/hd" "github.com/cosmos/ethermint/crypto/hd"
rpctypes "github.com/cosmos/ethermint/ethereum/rpc/types" rpctypes "github.com/cosmos/ethermint/ethereum/rpc/types"
@ -391,10 +391,14 @@ func (e *PublicEthAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, e
txEncoder := e.clientCtx.TxConfig.TxEncoder() txEncoder := e.clientCtx.TxConfig.TxEncoder()
txBytes, err := txEncoder(tx) txBytes, err := txEncoder(tx)
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to encode eth tx using default encoder")
return common.Hash{}, err return common.Hash{}, err
} }
txHash := common.BytesToHash(txBytes) // TODO: use msg.AsTransaction.Hash() for txHash once hashing is fixed on Tendermint
// https://github.com/tendermint/tendermint/issues/6539
tmTx := tmtypes.Tx(txBytes)
txHash := common.BytesToHash(tmTx.Hash())
// Broadcast transaction in sync mode (default) // Broadcast transaction in sync mode (default)
// NOTE: If error is encountered on the node, the broadcast will not return an error // NOTE: If error is encountered on the node, the broadcast will not return an error
@ -411,16 +415,21 @@ func (e *PublicEthAPI) SendTransaction(args rpctypes.SendTxArgs) (common.Hash, e
// SendRawTransaction send a raw Ethereum transaction. // SendRawTransaction send a raw Ethereum transaction.
func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) { func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
e.logger.Debugln("eth_sendRawTransaction", "data_len", len(data)) e.logger.Debugln("eth_sendRawTransaction", "data_len", len(data))
ethereumTx := new(evmtypes.MsgEthereumTx)
// RLP decode raw transaction bytes // RLP decode raw transaction bytes
if err := rlp.DecodeBytes(data, ethereumTx); err != nil { tx, err := e.clientCtx.TxConfig.TxDecoder()(data)
e.logger.WithError(err).Errorln("transaction RLP decode failed") if err != nil {
e.logger.WithError(err).Errorln("transaction decoding failed")
// Return nil is for when gasLimit overflows uint64
return common.Hash{}, err return common.Hash{}, err
} }
ethereumTx, isEthTx := tx.(*evmtypes.MsgEthereumTx)
if !isEthTx {
e.logger.Debugln("invalid transaction type", "type", fmt.Sprintf("%T", tx))
return common.Hash{}, fmt.Errorf("invalid transaction type %T", tx)
}
builder, ok := e.clientCtx.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder) builder, ok := e.clientCtx.TxConfig.NewTxBuilder().(authtx.ExtensionOptionsTxBuilder)
if !ok { if !ok {
e.logger.Panicln("clientCtx.TxConfig.NewTxBuilder returns unsupported builder") e.logger.Panicln("clientCtx.TxConfig.NewTxBuilder returns unsupported builder")
@ -432,7 +441,7 @@ func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, erro
} }
builder.SetExtensionOptions(option) builder.SetExtensionOptions(option)
err = builder.SetMsgs(ethereumTx.GetMsgs()...) err = builder.SetMsgs(tx.GetMsgs()...)
if err != nil { if err != nil {
e.logger.WithError(err).Panicln("builder.SetMsgs failed") e.logger.WithError(err).Panicln("builder.SetMsgs failed")
} }
@ -444,15 +453,19 @@ func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, erro
// Encode transaction by default Tx encoder // Encode transaction by default Tx encoder
txBytes, err := e.clientCtx.TxConfig.TxEncoder()(builder.GetTx()) txBytes, err := e.clientCtx.TxConfig.TxEncoder()(builder.GetTx())
if err != nil { if err != nil {
e.logger.WithError(err).Errorln("failed to encode Eth tx using default encoder") e.logger.WithError(err).Errorln("failed to encode eth tx using default encoder")
return common.Hash{}, err return common.Hash{}, err
} }
txHash := common.BytesToHash(tmhash.Sum(txBytes)) // TODO: use msg.AsTransaction.Hash() for txHash once hashing is fixed on Tendermint
// https://github.com/tendermint/tendermint/issues/6539
tmTx := tmtypes.Tx(txBytes)
txHash := common.BytesToHash(tmTx.Hash())
asyncCtx := e.clientCtx.WithBroadcastMode(flags.BroadcastAsync) asyncCtx := e.clientCtx.WithBroadcastMode(flags.BroadcastAsync)
if _, err := asyncCtx.BroadcastTx(txBytes); err != nil { if _, err := asyncCtx.BroadcastTx(txBytes); err != nil {
e.logger.WithError(err).Errorln("failed to broadcast Eth tx") e.logger.WithError(err).Errorln("failed to broadcast eth tx")
return txHash, err return txHash, err
} }
@ -461,7 +474,7 @@ func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, erro
// Call performs a raw contract call. // Call performs a raw contract call.
func (e *PublicEthAPI) Call(args rpctypes.CallArgs, blockNr rpctypes.BlockNumber, _ *rpctypes.StateOverride) (hexutil.Bytes, error) { func (e *PublicEthAPI) Call(args rpctypes.CallArgs, blockNr rpctypes.BlockNumber, _ *rpctypes.StateOverride) (hexutil.Bytes, error) {
//e.logger.Debugln("eth_call", "args", args, "block number", blockNr) e.logger.Debugln("eth_call", "args", args, "block number", blockNr)
simRes, err := e.doCall(args, blockNr, big.NewInt(ethermint.DefaultRPCGasLimit)) simRes, err := e.doCall(args, blockNr, big.NewInt(ethermint.DefaultRPCGasLimit))
if err != nil { if err != nil {
return []byte{}, err return []byte{}, err
@ -561,8 +574,8 @@ func (e *PublicEthAPI) doCall(
txBuilder.SetFeeAmount(fees) txBuilder.SetFeeAmount(fees)
txBuilder.SetGasLimit(gas) txBuilder.SetGasLimit(gas)
//doc about generate and transform tx into json, protobuf bytes // doc about generate and transform tx into json, protobuf bytes
//https://github.com/cosmos/cosmos-sdk/blob/master/docs/run-node/txs.md // https://github.com/cosmos/cosmos-sdk/blob/master/docs/run-node/txs.md
txBytes, err := e.clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx()) txBytes, err := e.clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
if err != nil { if err != nil {
return nil, err return nil, err
@ -636,79 +649,125 @@ func (e *PublicEthAPI) GetBlockByNumber(ethBlockNum rpctypes.BlockNumber, fullTx
func (e *PublicEthAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransaction, error) { func (e *PublicEthAPI) GetTransactionByHash(hash common.Hash) (*rpctypes.RPCTransaction, error) {
e.logger.Debugln("eth_getTransactionByHash", "hash", hash.Hex()) e.logger.Debugln("eth_getTransactionByHash", "hash", hash.Hex())
resp, err := e.queryClient.TxReceipt(e.ctx, &evmtypes.QueryTxReceiptRequest{ res, err := e.clientCtx.Client.Tx(e.ctx, hash.Bytes(), false)
Hash: hash.Hex(),
})
if err != nil { if err != nil {
e.logger.Debugf("failed to get tx info for %s: %s", hash.Hex(), err.Error()) e.logger.WithError(err).Debugln("tx not found", "hash", hash.Hex())
return nil, nil return nil, nil
} }
resBlock, err := e.clientCtx.Client.Block(e.ctx, &res.Height)
if err != nil {
e.logger.WithError(err).Debugln("block not found", "height", res.Height)
return nil, nil
}
tx, err := e.clientCtx.TxConfig.TxDecoder()(res.Tx)
if err != nil {
e.logger.WithError(err).Debugln("decoding failed")
return nil, fmt.Errorf("failed to decode tx: %w", err)
}
msg, ok := tx.(*evmtypes.MsgEthereumTx)
if !ok {
e.logger.Debugln("invalid tx")
return nil, fmt.Errorf("invalid tx type: %T", tx)
}
// TODO: use msg.AsTransaction.Hash() for txHash once hashing is fixed on Tendermint
// https://github.com/tendermint/tendermint/issues/6539
return rpctypes.NewTransactionFromData( return rpctypes.NewTransactionFromData(
resp.Receipt.Data, msg.Data,
common.HexToAddress(resp.Receipt.From), common.HexToAddress(msg.From),
common.HexToHash(resp.Receipt.Hash), hash,
common.HexToHash(resp.Receipt.BlockHash), common.BytesToHash(resBlock.Block.Hash()),
resp.Receipt.BlockHeight, uint64(res.Height),
resp.Receipt.Index, uint64(res.Index),
) )
} }
// GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index. // GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index.
func (e *PublicEthAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { func (e *PublicEthAPI) GetTransactionByBlockHashAndIndex(hash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
e.logger.Debugln("eth_getTransactionByHashAndIndex", "hash", hash.Hex(), "index", idx) e.logger.Debugln("eth_getTransactionByBlockHashAndIndex", "hash", hash.Hex(), "index", idx)
header, err := e.backend.HeaderByHash(hash) resBlock, err := e.clientCtx.Client.BlockByHash(e.ctx, hash.Bytes())
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "failed retrieve block from hash") e.logger.WithError(err).Debugln("block not found", "hash", hash.Hex())
return nil, nil
} }
resp, err := e.queryClient.TxReceiptsByBlockHeight(rpctypes.ContextWithHeight(header.Number.Int64()), &evmtypes.QueryTxReceiptsByBlockHeightRequest{}) i := int(idx)
if err != nil { if i >= len(resBlock.Block.Txs) {
return nil, errors.Wrap(err, "failed to query tx receipts by block height") e.logger.Debugln("block txs index out of bound", "index", i)
return nil, nil
} }
return e.getReceiptByIndex(resp.Receipts, hash, idx) txBz := resBlock.Block.Txs[i]
tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil {
e.logger.WithError(err).Debugln("decoding failed")
return nil, fmt.Errorf("failed to decode tx: %w", err)
}
msg, ok := tx.(*evmtypes.MsgEthereumTx)
if !ok {
e.logger.Debugln("invalid tx")
return nil, fmt.Errorf("invalid tx type: %T", tx)
}
// TODO: use msg.AsTransaction.Hash() for txHash once hashing is fixed on Tendermint
// https://github.com/tendermint/tendermint/issues/6539
txHash := common.BytesToHash(txBz.Hash())
return rpctypes.NewTransactionFromData(
msg.Data,
common.HexToAddress(msg.From),
txHash,
hash,
uint64(resBlock.Block.Height),
uint64(idx),
)
} }
// GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index. // GetTransactionByBlockNumberAndIndex returns the transaction identified by number and index.
func (e *PublicEthAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) { func (e *PublicEthAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
e.logger.Debugln("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx) e.logger.Debugln("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx)
req := &evmtypes.QueryTxReceiptsByBlockHeightRequest{} resBlock, err := e.clientCtx.Client.Block(e.ctx, blockNum.TmHeight())
resp, err := e.queryClient.TxReceiptsByBlockHeight(rpctypes.ContextWithHeight(blockNum.Int64()), req)
if err != nil { if err != nil {
err = errors.Wrap(err, "failed to query tx receipts by block height") e.logger.WithError(err).Debugln("block not found", "height", blockNum.Int64())
return nil, err
}
return e.getReceiptByIndex(resp.Receipts, common.Hash{}, idx)
}
func (e *PublicEthAPI) getReceiptByIndex(receipts []*evmtypes.TxReceipt, blockHash common.Hash, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
// return if index out of bounds
if uint64(idx) >= uint64(len(receipts)) {
return nil, nil return nil, nil
} }
receipt := receipts[idx] i := int(idx)
if i >= len(resBlock.Block.Txs) {
e.logger.Debugln("block txs index out of bound", "index", i)
return nil, nil
}
if (blockHash != common.Hash{}) { txBz := resBlock.Block.Txs[i]
hexBlockHash := blockHash.Hex() tx, err := e.clientCtx.TxConfig.TxDecoder()(txBz)
if receipt.BlockHash != hexBlockHash { if err != nil {
return nil, errors.Errorf("receipt found but block hashes don't match %s != %s", e.logger.WithError(err).Debugln("decoding failed")
receipt.BlockHash, return nil, fmt.Errorf("failed to decode tx: %w", err)
hexBlockHash,
)
} }
msg, ok := tx.(*evmtypes.MsgEthereumTx)
if !ok {
e.logger.Debugln("invalid tx")
return nil, fmt.Errorf("invalid tx type: %T", tx)
} }
// TODO: use msg.AsTransaction.Hash() for txHash once hashing is fixed on Tendermint
// https://github.com/tendermint/tendermint/issues/6539
txHash := common.BytesToHash(txBz.Hash())
return rpctypes.NewTransactionFromData( return rpctypes.NewTransactionFromData(
receipt.Data, msg.Data,
common.HexToAddress(receipt.From), common.HexToAddress(msg.From),
common.HexToHash(receipt.Hash), txHash,
blockHash, common.BytesToHash(resBlock.Block.Hash()),
receipt.BlockHeight, uint64(resBlock.Block.Height),
uint64(idx), uint64(idx),
) )
} }
@ -717,64 +776,97 @@ func (e *PublicEthAPI) getReceiptByIndex(receipts []*evmtypes.TxReceipt, blockHa
func (e *PublicEthAPI) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) { func (e *PublicEthAPI) GetTransactionReceipt(hash common.Hash) (map[string]interface{}, error) {
e.logger.Debugln("eth_getTransactionReceipt", "hash", hash.Hex()) e.logger.Debugln("eth_getTransactionReceipt", "hash", hash.Hex())
ctx := rpctypes.ContextWithHeight(int64(0)) res, err := e.clientCtx.Client.Tx(e.ctx, hash.Bytes(), false)
tx, err := e.queryClient.TxReceipt(ctx, &evmtypes.QueryTxReceiptRequest{
Hash: hash.Hex(),
})
if err != nil { if err != nil {
e.logger.Debugf("failed to get tx receipt for %s: %s", hash.Hex(), err.Error()) e.logger.WithError(err).Debugln("tx not found", "hash", hash.Hex())
return nil, nil return nil, nil
} }
// Query block for consensus hash resBlock, err := e.clientCtx.Client.Block(e.ctx, &res.Height)
height := int64(tx.Receipt.BlockHeight)
block, err := e.clientCtx.Client.Block(e.ctx, &height)
if err != nil { if err != nil {
e.logger.Warningln("didnt find block for tx height", height) e.logger.WithError(err).Debugln("block not found", "height", res.Height)
return nil, err return nil, nil
} }
cumulativeGasUsed := tx.Receipt.Result.GasUsed tx, err := e.clientCtx.TxConfig.TxDecoder()(res.Tx)
if tx.Receipt.Index != 0 { if err != nil {
cumulativeGasUsed += rpctypes.GetBlockCumulativeGas(e.clientCtx, block.Block, int(tx.Receipt.Index)) e.logger.WithError(err).Debugln("decoding failed")
return nil, fmt.Errorf("failed to decode tx: %w", err)
}
msg, ok := tx.(*evmtypes.MsgEthereumTx)
if !ok {
e.logger.Debugln("invalid tx")
return nil, fmt.Errorf("invalid tx type: %T", tx)
}
cumulativeGasUsed := uint64(0)
blockRes, err := e.clientCtx.Client.BlockResults(e.ctx, &res.Height)
if err != nil {
e.logger.WithError(err).Debugln("failed to retrieve block results", "height", res.Height)
return nil, nil
}
for i := 0; i <= int(res.Index) && i < len(blockRes.TxsResults); i++ {
cumulativeGasUsed += uint64(blockRes.TxsResults[i].GasUsed)
} }
var status hexutil.Uint var status hexutil.Uint
if tx.Receipt.Result.Reverted {
status = hexutil.Uint(0) // NOTE: Response{Deliver/Check}Tx Code from Tendermint and the Ethereum receipt status are switched:
// | | Tendermint | Ethereum |
// | ------- | ---------- | -------- |
// | Success | 0 | 1 |
// | Fail | 1 | 0 |
if res.TxResult.Code == 0 {
status = hexutil.Uint(ethtypes.ReceiptStatusSuccessful)
} else { } else {
status = hexutil.Uint(1) status = hexutil.Uint(ethtypes.ReceiptStatusFailed)
} }
toHex := common.Address{} from := common.HexToAddress(msg.From)
if len(tx.Receipt.Data.To) > 0 {
toHex = common.HexToAddress(tx.Receipt.Data.To) resLogs, err := e.queryClient.TxLogs(e.ctx, &evmtypes.QueryTxLogsRequest{Hash: hash.Hex()})
if err != nil {
e.logger.WithError(err).Debugln("logs not found", "hash", hash.Hex())
resLogs = &evmtypes.QueryTxLogsResponse{Logs: []*evmtypes.Log{}}
} }
contractAddress := common.HexToAddress(tx.Receipt.Result.ContractAddress) logs := evmtypes.LogsToEthereum(resLogs.Logs)
logsBloom := hexutil.Encode(ethtypes.BytesToBloom(tx.Receipt.Result.Bloom).Bytes())
receipt := map[string]interface{}{ receipt := map[string]interface{}{
// Consensus fields: These fields are defined by the Yellow Paper // Consensus fields: These fields are defined by the Yellow Paper
"status": status, "status": status,
"cumulativeGasUsed": hexutil.Uint64(cumulativeGasUsed), "cumulativeGasUsed": hexutil.Uint64(cumulativeGasUsed),
"logsBloom": logsBloom, "logsBloom": ethtypes.BytesToBloom(ethtypes.LogsBloom(logs)),
"logs": tx.Receipt.Result.TxLogs.EthLogs(), "logs": logs,
// Implementation fields: These fields are added by geth when processing a transaction. // Implementation fields: These fields are added by geth when processing a transaction.
// They are stored in the chain database. // They are stored in the chain database.
"transactionHash": hash.Hex(), "transactionHash": hash,
"contractAddress": contractAddress.Hex(), "contractAddress": nil,
"gasUsed": hexutil.Uint64(tx.Receipt.Result.GasUsed), "gasUsed": hexutil.Uint64(res.TxResult.GasUsed),
"type": hexutil.Uint(ethtypes.AccessListTxType), // TODO: support legacy type
// Inclusion information: These fields provide information about the inclusion of the // Inclusion information: These fields provide information about the inclusion of the
// transaction corresponding to this receipt. // transaction corresponding to this receipt.
"blockHash": common.BytesToHash(block.Block.Header.Hash()).Hex(), "blockHash": common.BytesToHash(resBlock.Block.Header.Hash()).Hex(),
"blockNumber": hexutil.Uint64(tx.Receipt.BlockHeight), "blockNumber": hexutil.Uint64(res.Height),
"transactionIndex": hexutil.Uint64(tx.Receipt.Index), "transactionIndex": hexutil.Uint64(res.Index),
// sender and receiver (contract or EOA) addreses // sender and receiver (contract or EOA) addreses
"from": common.HexToAddress(tx.Receipt.From), "from": from,
"to": toHex, "to": msg.To(),
}
if logs == nil {
receipt["logs"] = [][]*ethtypes.Log{}
}
// If the ContractAddress is 20 0x0 bytes, assume it is not a contract creation
if msg.To() == nil {
receipt["contractAddress"] = crypto.CreateAddress(from, msg.Data.Nonce)
} }
return receipt, nil return receipt, nil

View File

@ -371,7 +371,7 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit filters.FilterCriteri
return return
} }
logs := filterLogs(txResponse.TxLogs.EthLogs(), crit.FromBlock, crit.ToBlock, crit.Addresses, crit.Topics) logs := filterLogs(evmtypes.LogsToEthereum(txResponse.Logs), crit.FromBlock, crit.ToBlock, crit.Addresses, crit.Topics)
for _, log := range logs { for _, log := range logs {
err = notifier.Notify(rpcSub.ID, log) err = notifier.Notify(rpcSub.ID, log)
@ -448,7 +448,7 @@ func (api *PublicFilterAPI) NewFilter(criteria filters.FilterCriteria) (rpc.ID,
return return
} }
logs := filterLogs(txResponse.TxLogs.EthLogs(), criteria.FromBlock, criteria.ToBlock, criteria.Addresses, criteria.Topics) logs := filterLogs(evmtypes.LogsToEthereum(txResponse.Logs), criteria.FromBlock, criteria.ToBlock, criteria.Addresses, criteria.Topics)
api.filtersMu.Lock() api.filtersMu.Lock()
if f, found := api.filters[filterID]; found { if f, found := api.filters[filterID]; found {

View File

@ -25,8 +25,8 @@ import (
) )
// RawTxToEthTx returns a evm MsgEthereum transaction from raw tx bytes. // RawTxToEthTx returns a evm MsgEthereum transaction from raw tx bytes.
func RawTxToEthTx(clientCtx client.Context, bz []byte) (*evmtypes.MsgEthereumTx, error) { func RawTxToEthTx(clientCtx client.Context, txBz tmtypes.Tx) (*evmtypes.MsgEthereumTx, error) {
tx, err := clientCtx.TxConfig.TxDecoder()(bz) tx, err := clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
} }
@ -246,28 +246,23 @@ func BuildEthereumTx(clientCtx client.Context, msg *evmtypes.MsgEthereumTx, accN
return txBytes, nil return txBytes, nil
} }
// GetBlockCumulativeGas returns the cumulative gas used on a block up to a given func DecodeTx(clientCtx client.Context, txBz tmtypes.Tx) (sdk.Tx, uint64) {
// transaction index. The returned gas used includes the gas from both the SDK and
// EVM module transactions.
func GetBlockCumulativeGas(clientCtx client.Context, block *tmtypes.Block, idx int) uint64 {
var gasUsed uint64 var gasUsed uint64
txDecoder := clientCtx.TxConfig.TxDecoder() txDecoder := clientCtx.TxConfig.TxDecoder()
for i := 0; i < idx && i < len(block.Txs); i++ { tx, err := txDecoder(txBz)
txi, err := txDecoder(block.Txs[i])
if err != nil { if err != nil {
continue return nil, 0
} }
switch tx := txi.(type) { switch tx := tx.(type) {
case *evmtypes.MsgEthereumTx: case *evmtypes.MsgEthereumTx:
gasUsed += tx.GetGas() gasUsed = tx.GetGas() // NOTE: this doesn't include the gas refunded
case sdk.FeeTx: case sdk.FeeTx:
// TODO: add internal txns gasUsed = tx.GetGas()
gasUsed += tx.GetGas()
} }
}
return gasUsed return tx, gasUsed
} }
type DataError interface { type DataError interface {

View File

@ -604,7 +604,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
return return
} }
logs := filterLogs(txResponse.TxLogs.EthLogs(), crit.FromBlock, crit.ToBlock, crit.Addresses, crit.Topics) logs := filterLogs(evmtypes.LogsToEthereum(txResponse.Logs), crit.FromBlock, crit.ToBlock, crit.Addresses, crit.Topics)
if len(logs) == 0 { if len(logs) == 0 {
continue continue
} }

2
go.mod
View File

@ -46,7 +46,7 @@ require (
github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2 github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2
github.com/xlab/suplog v1.3.0 github.com/xlab/suplog v1.3.0
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a
google.golang.org/genproto v0.0.0-20210524171403-669157292da3 google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae
google.golang.org/grpc v1.38.0 google.golang.org/grpc v1.38.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect

16
go.sum
View File

@ -876,6 +876,7 @@ github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:
github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= github.com/xtaci/kcp-go v5.4.5+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8=
github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= github.com/zondax/hid v0.9.0/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
@ -945,7 +946,7 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@ -991,8 +992,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1062,9 +1063,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -1119,6 +1119,7 @@ golang.org/x/tools v0.0.0-20200110213125-a7a6caa82ab2/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -1168,8 +1169,8 @@ google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201111145450-ac7456db90a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201119123407-9b1e624d6bc4/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210114201628-6edceaf6022f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210524171403-669157292da3 h1:xFyh6GBb+NO1L0xqb978I3sBPQpk6FrKO0jJGRvdj/0= google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae h1:2dB4bZ/B7RJdKuvHk3mKTzL2xwrikb+Y/QQy7WdyBPk=
google.golang.org/genproto v0.0.0-20210524171403-669157292da3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@ -1191,7 +1192,6 @@ google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=

View File

@ -102,7 +102,7 @@ message ChainConfig {
(gogoproto.moretags) = "yaml:\"muir_glacier_block\"", (gogoproto.moretags) = "yaml:\"muir_glacier_block\"",
(gogoproto.nullable) = false (gogoproto.nullable) = false
]; ];
// Berlin switch block (< 0 = no fork, 0 = already on berlin) // Berlin switch block (< 0 = no fork, 0 = already on berlin)
string berlin_block = 13 [ string berlin_block = 13 [
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int", (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.moretags) = "yaml:\"berlin_block\"", (gogoproto.moretags) = "yaml:\"berlin_block\"",
@ -216,10 +216,7 @@ message TxData {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
// destination EVM chain ID // destination EVM chain ID
bytes chain_id = 1 [ bytes chain_id = 1 [(gogoproto.customname) = "ChainID", (gogoproto.jsontag) = "chainID"];
(gogoproto.customname) = "ChainID",
(gogoproto.jsontag) = "chainID"
];
// nonce corresponds to the account nonce (transaction sequence). // nonce corresponds to the account nonce (transaction sequence).
uint64 nonce = 2; uint64 nonce = 2;
// price defines the unsigned integer value of the gas price in bytes. // price defines the unsigned integer value of the gas price in bytes.
@ -232,11 +229,8 @@ message TxData {
bytes value = 6 [(gogoproto.customname) = "Amount"]; bytes value = 6 [(gogoproto.customname) = "Amount"];
// input defines the data payload bytes of the transaction. // input defines the data payload bytes of the transaction.
bytes input = 7; bytes input = 7;
repeated AccessTuple accesses = 8 [ repeated AccessTuple accesses = 8
(gogoproto.castrepeated) = "AccessList", [(gogoproto.castrepeated) = "AccessList", (gogoproto.jsontag) = "accessList", (gogoproto.nullable) = false];
(gogoproto.jsontag) = "accessList",
(gogoproto.nullable) = false
];
// v defines the signature value // v defines the signature value
bytes v = 9; bytes v = 9;
// r defines the signature value // r defines the signature value

View File

@ -41,16 +41,6 @@ service Query {
option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_logs/{hash}"; option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_logs/{hash}";
} }
// TxReceipt queries a receipt by a transaction hash.
rpc TxReceipt(QueryTxReceiptRequest) returns (QueryTxReceiptResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_receipt/{hash}";
}
// TxReceiptsByBlockHeight queries tx receipts by a block height.
rpc TxReceiptsByBlockHeight(QueryTxReceiptsByBlockHeightRequest) returns (QueryTxReceiptsByBlockHeightResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/tx_receipts_block";
}
// BlockLogs queries all the ethereum logs for a given block hash. // BlockLogs queries all the ethereum logs for a given block hash.
rpc BlockLogs(QueryBlockLogsRequest) returns (QueryBlockLogsResponse) { rpc BlockLogs(QueryBlockLogsRequest) returns (QueryBlockLogsResponse) {
option (google.api.http).get = "/ethermint/evm/v1alpha1/block_logs/{hash}"; option (google.api.http).get = "/ethermint/evm/v1alpha1/block_logs/{hash}";
@ -175,31 +165,6 @@ message QueryTxLogsResponse {
repeated Log logs = 1; repeated Log logs = 1;
} }
// QueryTxReceiptRequest is the request type for the Query/TxReceipt RPC method.
message QueryTxReceiptRequest {
option (gogoproto.equal) = false;
option (gogoproto.goproto_getters) = false;
// hash is the ethereum transaction hex hash to query the receipt for.
string hash = 1;
}
// QueryTxReceiptResponse is the response type for the Query/TxReceipt RPC method.
message QueryTxReceiptResponse {
// receipt represents the ethereum receipt for the given transaction.
TxReceipt receipt = 1;
}
// QueryTxReceiptsByBlockHeightRequest is the request type for the Query/TxReceiptsByBlockHeight RPC method.
message QueryTxReceiptsByBlockHeightRequest {
}
// QueryTxReceiptsByBlockHeightResponse is the response type for the Query/TxReceiptsByBlockHeight RPC method.
message QueryTxReceiptsByBlockHeightResponse {
// tx receipts list for the block
repeated TxReceipt receipts = 1;
}
// QueryBlockLogsRequest is the request type for the Query/BlockLogs RPC method. // QueryBlockLogsRequest is the request type for the Query/BlockLogs RPC method.
message QueryBlockLogsRequest { message QueryBlockLogsRequest {
option (gogoproto.equal) = false; option (gogoproto.equal) = false;
@ -221,7 +186,7 @@ message QueryBlockLogsResponse {
// QueryBlockBloomRequest is the request type for the Query/BlockBloom RPC // QueryBlockBloomRequest is the request type for the Query/BlockBloom RPC
// method. // method.
message QueryBlockBloomRequest { } message QueryBlockBloomRequest {}
// QueryBlockBloomResponse is the response type for the Query/BlockBloom RPC // QueryBlockBloomResponse is the response type for the Query/BlockBloom RPC
// method. // method.

View File

@ -42,34 +42,14 @@ message ExtensionOptionsWeb3Tx {
message MsgEthereumTxResponse { message MsgEthereumTxResponse {
option (gogoproto.goproto_getters) = false; option (gogoproto.goproto_getters) = false;
// contract_address contains the ethereum address of the created contract (if // ethereum transaction hash in hex format. This hash differs from the Tendermint sha256 hash of the transaction
// any). If the state transition is an evm.Call, the contract address will be // bytes. See https://github.com/tendermint/tendermint/issues/6539 for reference
// empty. string hash = 1;
string contract_address = 1 [(gogoproto.moretags) = "yaml:\"contract_address\""]; // logs contains the transaction hash and the proto-compatible ethereum
// bloom represents the bloom filter bytes
bytes bloom = 2;
// tx_logs contains the transaction hash and the proto-compatible ethereum
// logs. // logs.
TransactionLogs tx_logs = 3 [(gogoproto.moretags) = "yaml:\"tx_logs\"", (gogoproto.nullable) = false]; repeated Log logs = 2;
// ret defines the bytes from the execution. // returned data from evm function (result or data supplied with revert opcode)
bytes ret = 4; bytes ret = 3;
// reverted flag is set to true when the call has been reverted // reverted flag is set to true when the call has been reverted
bool reverted = 5; bool reverted = 4;
} }
// // SigCache is used to cache the derived sender and contains the signer used
// // to derive it.
// message SigCache {
// option (gogoproto.goproto_getters) = false;
// EIP155Signer signer = 1;
// bytes address = 2;
// }
// // EIP155Transaction implements Signer using the EIP155 rules.
// message EIP155Signer {
// option (gogoproto.goproto_getters) = false;
// bytes chain_id = 1 [(gogoproto.customname) = "chainId"];
// bytes chain_id_mul = 2 [(gogoproto.customname) = "chainIdMul"];
// }

View File

@ -1,14 +1,12 @@
package evm package evm
import ( import (
"fmt"
"runtime/debug" "runtime/debug"
log "github.com/xlab/suplog" log "github.com/xlab/suplog"
sdk "github.com/cosmos/cosmos-sdk/types" sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
ethcmn "github.com/ethereum/go-ethereum/common"
"github.com/cosmos/ethermint/x/evm/keeper" "github.com/cosmos/ethermint/x/evm/keeper"
"github.com/cosmos/ethermint/x/evm/types" "github.com/cosmos/ethermint/x/evm/types"
@ -25,42 +23,7 @@ func NewHandler(k *keeper.Keeper) sdk.Handler {
case *types.MsgEthereumTx: case *types.MsgEthereumTx:
// execute state transition // execute state transition
res, err := k.EthereumTx(sdk.WrapSDKContext(ctx), msg) res, err := k.EthereumTx(sdk.WrapSDKContext(ctx), msg)
if err != nil {
return sdk.WrapServiceResult(ctx, res, err) return sdk.WrapServiceResult(ctx, res, err)
} else if result, err = sdk.WrapServiceResult(ctx, res, nil); err != nil {
return nil, err
}
// log state transition result
var recipientLog string
if res.ContractAddress != "" {
recipientLog = fmt.Sprintf("contract address %s", res.ContractAddress)
} else {
var recipient string
if to := msg.To(); to != nil {
recipient = to.Hex()
}
recipientLog = fmt.Sprintf("recipient address %s", recipient)
}
sender := ethcmn.BytesToAddress(msg.GetFrom().Bytes())
if res.Reverted {
result.Log = "transaction reverted"
log := fmt.Sprintf(
"reverted EVM state transition; sender address %s; %s", sender.Hex(), recipientLog,
)
k.Logger(ctx).Info(log)
} else {
log := fmt.Sprintf(
"executed EVM state transition; sender address %s; %s", sender.Hex(), recipientLog,
)
result.Log = log
k.Logger(ctx).Info(log)
}
return result, nil
default: default:
err := sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg) err := sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)

View File

@ -14,6 +14,7 @@ import (
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types" ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/cosmos-sdk/crypto/keyring" "github.com/cosmos/cosmos-sdk/crypto/keyring"
@ -98,7 +99,7 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
"insufficient balance", "insufficient balance",
func() { func() {
tx = types.NewMsgEthereumTxContract(suite.chainID, 0, big.NewInt(100), 0, big.NewInt(10000), nil, nil) tx = types.NewMsgEthereumTxContract(suite.chainID, 0, big.NewInt(100), 0, big.NewInt(10000), nil, nil)
tx.From = suite.from.Hex()
// sign transaction // sign transaction
err := tx.Sign(suite.ethSigner, suite.signer) err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err) suite.Require().NoError(err)
@ -184,48 +185,17 @@ func (suite *EvmTestSuite) TestHandlerLogs() {
txResponse, err := types.DecodeTxResponse(result.Data) txResponse, err := types.DecodeTxResponse(result.Data)
suite.Require().NoError(err, "failed to decode result data") suite.Require().NoError(err, "failed to decode result data")
suite.Require().Equal(len(txResponse.TxLogs.Logs), 1) suite.Require().Equal(len(txResponse.Logs), 1)
suite.Require().Equal(len(txResponse.TxLogs.Logs[0].Topics), 2) suite.Require().Equal(len(txResponse.Logs[0].Topics), 2)
hash := []byte{1} hash := []byte{1}
err = suite.app.EvmKeeper.CommitStateDB.SetLogs(ethcmn.BytesToHash(hash), txResponse.TxLogs.EthLogs()) err = suite.app.EvmKeeper.CommitStateDB.SetLogs(ethcmn.BytesToHash(hash), types.LogsToEthereum(txResponse.Logs))
suite.Require().NoError(err) suite.Require().NoError(err)
logs, err := suite.app.EvmKeeper.CommitStateDB.GetLogs(ethcmn.BytesToHash(hash)) logs, err := suite.app.EvmKeeper.CommitStateDB.GetLogs(ethcmn.BytesToHash(hash))
suite.Require().NoError(err, "failed to get logs") suite.Require().NoError(err, "failed to get logs")
suite.Require().Equal(logs, txResponse.TxLogs.Logs) suite.Require().Equal(logs, txResponse.Logs)
}
func (suite *EvmTestSuite) TestQueryTxLogs() {
gasLimit := uint64(100000)
gasPrice := big.NewInt(1000000)
// send contract deployment transaction with an event in the constructor
bytecode := common.FromHex("0x6080604052348015600f57600080fd5b5060117f775a94827b8fd9b519d36cd827093c664f93347070a554f65e4a6f56cd73889860405160405180910390a2603580604b6000396000f3fe6080604052600080fdfea165627a7a723058206cab665f0f557620554bb45adf266708d2bd349b8a4314bdff205ee8440e3c240029")
tx := types.NewMsgEthereumTx(suite.chainID, 1, nil, big.NewInt(0), gasLimit, gasPrice, bytecode, nil)
tx.From = suite.from.String()
err := tx.Sign(suite.ethSigner, suite.signer)
suite.Require().NoError(err)
result, err := suite.handler(suite.ctx, tx)
suite.Require().NoError(err)
suite.Require().NotNil(result)
txResponse, err := types.DecodeTxResponse(result.Data)
suite.Require().NoError(err, "failed to decode result data")
suite.Require().Equal(len(txResponse.TxLogs.Logs), 1)
suite.Require().Equal(len(txResponse.TxLogs.Logs[0].Topics), 2)
// get logs by tx hash
hash := txResponse.TxLogs.Hash
logs, err := suite.app.EvmKeeper.CommitStateDB.GetLogs(ethcmn.HexToHash(hash))
suite.Require().NoError(err, "failed to get logs")
suite.Require().Equal(logs, txResponse.TxLogs.EthLogs())
} }
func (suite *EvmTestSuite) TestDeployAndCallContract() { func (suite *EvmTestSuite) TestDeployAndCallContract() {
@ -303,7 +273,7 @@ func (suite *EvmTestSuite) TestDeployAndCallContract() {
// store - changeOwner // store - changeOwner
gasLimit = uint64(100000000000) gasLimit = uint64(100000000000)
gasPrice = big.NewInt(100) gasPrice = big.NewInt(100)
receiver := common.HexToAddress(txResponse.ContractAddress) receiver := crypto.CreateAddress(suite.from, 1)
storeAddr := "0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424" storeAddr := "0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424"
bytecode = common.FromHex(storeAddr) bytecode = common.FromHex(storeAddr)

View File

@ -203,44 +203,6 @@ func (k Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types
}, nil }, nil
} }
// TxReceipt implements the Query/TxReceipt gRPC method
func (k Keeper) TxReceipt(c context.Context, req *types.QueryTxReceiptRequest) (*types.QueryTxReceiptResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if ethermint.IsEmptyHash(req.Hash) {
return nil, status.Error(
codes.InvalidArgument,
types.ErrEmptyHash.Error(),
)
}
ctx := sdk.UnwrapSDKContext(c)
hash := ethcmn.HexToHash(req.Hash)
receipt, found := k.GetTxReceiptFromHash(ctx, hash)
if !found {
return nil, status.Errorf(
codes.NotFound, "%s: %s", types.ErrTxReceiptNotFound.Error(), req.Hash,
)
}
return &types.QueryTxReceiptResponse{
Receipt: receipt,
}, nil
}
// TxReceiptsByBlockHeight implements the Query/TxReceiptsByBlockHeight gRPC method
func (k Keeper) TxReceiptsByBlockHeight(c context.Context, _ *types.QueryTxReceiptsByBlockHeightRequest) (*types.QueryTxReceiptsByBlockHeightResponse, error) {
ctx := sdk.UnwrapSDKContext(c)
receipts := k.GetTxReceiptsByBlockHeight(ctx, uint64(ctx.BlockHeight()))
return &types.QueryTxReceiptsByBlockHeightResponse{
Receipts: receipts,
}, nil
}
// BlockLogs implements the Query/BlockLogs gRPC method // BlockLogs implements the Query/BlockLogs gRPC method
func (k Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (*types.QueryBlockLogsResponse, error) { func (k Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (*types.QueryBlockLogsResponse, error) {
if req == nil { if req == nil {

View File

@ -517,136 +517,6 @@ func (suite *KeeperTestSuite) TestQueryBlockLogs() {
} }
} }
func (suite *KeeperTestSuite) TestQueryTxReceipt() {
var (
req *types.QueryTxReceiptRequest
expRes *types.QueryTxReceiptResponse
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty hash",
func() {
req = &types.QueryTxReceiptRequest{}
},
false,
},
{"tx receipt not found for hash",
func() {
hash := ethcmn.BytesToHash([]byte("thash"))
req = &types.QueryTxReceiptRequest{
Hash: hash.Hex(),
}
},
false,
},
{"success",
func() {
hash := ethcmn.BytesToHash([]byte("thash"))
receipt := &types.TxReceipt{
Hash: hash.Hex(),
From: suite.address.Hex(),
BlockHeight: uint64(suite.ctx.BlockHeight()),
BlockHash: ethcmn.BytesToHash(suite.ctx.BlockHeader().DataHash).Hex(),
}
suite.app.EvmKeeper.SetTxReceiptToHash(suite.ctx, hash, receipt)
req = &types.QueryTxReceiptRequest{
Hash: hash.Hex(),
}
expRes = &types.QueryTxReceiptResponse{
Receipt: receipt,
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
res, err := suite.queryClient.TxReceipt(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expRes, res)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryTxReceiptByBlockHeight() {
var (
req = &types.QueryTxReceiptsByBlockHeightRequest{}
expRes *types.QueryTxReceiptsByBlockHeightResponse
)
testCases := []struct {
msg string
malleate func()
expPass bool
}{
{"empty response",
func() {
expRes = &types.QueryTxReceiptsByBlockHeightResponse{
Receipts: nil,
}
},
true,
},
{"success",
func() {
hash := ethcmn.BytesToHash([]byte("thash"))
receipt := &types.TxReceipt{
Hash: hash.Hex(),
From: suite.address.Hex(),
BlockHeight: uint64(suite.ctx.BlockHeight()),
BlockHash: ethcmn.BytesToHash(suite.ctx.BlockHeader().DataHash).Hex(),
}
suite.app.EvmKeeper.AddTxHashToBlock(suite.ctx, suite.ctx.BlockHeight(), hash)
suite.app.EvmKeeper.SetTxReceiptToHash(suite.ctx, hash, receipt)
expRes = &types.QueryTxReceiptsByBlockHeightResponse{
Receipts: []*types.TxReceipt{receipt},
}
},
true,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
suite.SetupTest() // reset
tc.malleate()
ctx := sdk.WrapSDKContext(suite.ctx)
ctx = metadata.AppendToOutgoingContext(ctx, grpctypes.GRPCBlockHeightHeader, fmt.Sprintf("%d", suite.ctx.BlockHeight()))
res, err := suite.queryClient.TxReceiptsByBlockHeight(ctx, req)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)
suite.Require().Equal(expRes, res)
} else {
suite.Require().Error(err)
}
})
}
}
func (suite *KeeperTestSuite) TestQueryBlockBloom() { func (suite *KeeperTestSuite) TestQueryBlockBloom() {
var ( var (
req *types.QueryBlockBloomRequest req *types.QueryBlockBloomRequest

View File

@ -144,20 +144,6 @@ func (k Keeper) SetBlockBloomTransient(bloom *big.Int) {
store.Set(types.KeyPrefixTransientBloom, bloom.Bytes()) store.Set(types.KeyPrefixTransientBloom, bloom.Bytes())
} }
// ----------------------------------------------------------------------------
// Block
// ----------------------------------------------------------------------------
// SetTxReceiptToHash sets the mapping from tx hash to tx receipt
func (k Keeper) SetTxReceiptToHash(ctx sdk.Context, hash common.Hash, receipt *types.TxReceipt) {
ctx = ctx.WithGasMeter(sdk.NewInfiniteGasMeter())
data := k.cdc.MustMarshalBinaryBare(receipt)
store := ctx.KVStore(k.storeKey)
store.Set(types.KeyHashTxReceipt(hash), data)
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Tx // Tx
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -187,85 +173,6 @@ func (k Keeper) ResetRefundTransient(ctx sdk.Context) {
store.Delete(types.KeyPrefixTransientRefund) store.Delete(types.KeyPrefixTransientRefund)
} }
// GetTxReceiptFromHash gets tx receipt by tx hash.
func (k Keeper) GetTxReceiptFromHash(ctx sdk.Context, hash common.Hash) (*types.TxReceipt, bool) {
store := ctx.KVStore(k.storeKey)
data := store.Get(types.KeyHashTxReceipt(hash))
if len(data) == 0 {
return nil, false
}
var receipt types.TxReceipt
k.cdc.MustUnmarshalBinaryBare(data, &receipt)
return &receipt, true
}
// AddTxHashToBlock stores tx hash in the list of tx for the block.
func (k Keeper) AddTxHashToBlock(ctx sdk.Context, blockHeight int64, txHash common.Hash) {
key := types.KeyBlockHeightTxs(uint64(blockHeight))
list := types.BytesList{}
store := ctx.KVStore(k.storeKey)
data := store.Get(key)
if len(data) > 0 {
k.cdc.MustUnmarshalBinaryBare(data, &list)
}
list.Bytes = append(list.Bytes, txHash.Bytes())
data = k.cdc.MustMarshalBinaryBare(&list)
store.Set(key, data)
}
// GetTxsFromBlock returns list of tx hash in the block by height.
func (k Keeper) GetTxsFromBlock(ctx sdk.Context, blockHeight uint64) []common.Hash {
key := types.KeyBlockHeightTxs(blockHeight)
store := ctx.KVStore(k.storeKey)
data := store.Get(key)
if len(data) > 0 {
list := types.BytesList{}
k.cdc.MustUnmarshalBinaryBare(data, &list)
txs := make([]common.Hash, 0, len(list.Bytes))
for _, b := range list.Bytes {
txs = append(txs, common.BytesToHash(b))
}
return txs
}
return nil
}
// GetTxReceiptsByBlockHeight gets tx receipts by block height.
func (k Keeper) GetTxReceiptsByBlockHeight(ctx sdk.Context, blockHeight uint64) []*types.TxReceipt {
txs := k.GetTxsFromBlock(ctx, blockHeight)
if len(txs) == 0 {
return nil
}
store := ctx.KVStore(k.storeKey)
receipts := make([]*types.TxReceipt, 0, len(txs))
for idx, txHash := range txs {
data := store.Get(types.KeyHashTxReceipt(txHash))
if len(data) == 0 {
continue
}
var receipt types.TxReceipt
k.cdc.MustUnmarshalBinaryBare(data, &receipt)
receipt.Index = uint64(idx)
receipts = append(receipts, &receipt)
}
return receipts
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Log // Log
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -8,6 +8,7 @@ import (
"github.com/armon/go-metrics" "github.com/armon/go-metrics"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/core/vm"
tmtypes "github.com/tendermint/tendermint/types" tmtypes "github.com/tendermint/tendermint/types"
@ -55,6 +56,9 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
txHash := tmtypes.Tx(ctx.TxBytes()).Hash() txHash := tmtypes.Tx(ctx.TxBytes()).Hash()
ethHash := ethcmn.BytesToHash(txHash) ethHash := ethcmn.BytesToHash(txHash)
// Ethereum formatted tx hash
etherumTxHash := msg.AsTransaction().Hash()
st := &types.StateTransition{ st := &types.StateTransition{
Message: ethMsg, Message: ethMsg,
Csdb: k.CommitStateDB.WithContext(ctx), Csdb: k.CommitStateDB.WithContext(ctx),
@ -77,25 +81,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
if errors.Is(err, vm.ErrExecutionReverted) && executionResult != nil { if errors.Is(err, vm.ErrExecutionReverted) && executionResult != nil {
// keep the execution result for revert reason // keep the execution result for revert reason
executionResult.Response.Reverted = true executionResult.Response.Reverted = true
if !st.Simulate {
k.SetTxReceiptToHash(ctx, ethHash, &types.TxReceipt{
Hash: ethHash.Hex(),
From: sender.Hex(),
Data: msg.Data,
BlockHeight: uint64(ctx.BlockHeight()),
BlockHash: k.headerHash.Hex(),
Result: &types.TxResult{
ContractAddress: executionResult.Response.ContractAddress,
Bloom: executionResult.Response.Bloom,
TxLogs: executionResult.Response.TxLogs,
Ret: executionResult.Response.Ret,
Reverted: executionResult.Response.Reverted,
GasUsed: executionResult.GasInfo.GasConsumed,
},
})
}
return executionResult.Response, nil return executionResult.Response, nil
} }
@ -108,33 +93,9 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
bloom = big.NewInt(0) bloom = big.NewInt(0)
} }
// update block bloom filter // update block bloom filter
bloom = bloom.Or(bloom, executionResult.Bloom) logsBloom := ethtypes.LogsBloom(executionResult.Logs)
bloom = bloom.Or(bloom, new(big.Int).SetBytes(logsBloom))
k.SetBlockBloomTransient(bloom) k.SetBlockBloomTransient(bloom)
// update transaction logs in KVStore
err = k.CommitStateDB.SetLogs(ethHash, executionResult.Logs)
if err != nil {
panic(err)
}
k.SetTxReceiptToHash(ctx, ethHash, &types.TxReceipt{
Hash: ethHash.Hex(),
From: sender.Hex(),
Data: msg.Data,
Index: uint64(st.Csdb.TxIndex()),
BlockHeight: uint64(ctx.BlockHeight()),
BlockHash: k.headerHash.Hex(),
Result: &types.TxResult{
ContractAddress: executionResult.Response.ContractAddress,
Bloom: executionResult.Response.Bloom,
TxLogs: executionResult.Response.TxLogs,
Ret: executionResult.Response.Ret,
Reverted: executionResult.Response.Reverted,
GasUsed: executionResult.GasInfo.GasConsumed,
},
})
k.AddTxHashToBlock(ctx, ctx.BlockHeight(), ethHash)
} }
defer func() { defer func() {
@ -155,6 +116,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
attrs := []sdk.Attribute{ attrs := []sdk.Attribute{
sdk.NewAttribute(sdk.AttributeKeyAmount, st.Message.Value().String()), sdk.NewAttribute(sdk.AttributeKeyAmount, st.Message.Value().String()),
sdk.NewAttribute(types.AttributeKeyTxHash, ethcmn.BytesToHash(txHash).Hex()), sdk.NewAttribute(types.AttributeKeyTxHash, ethcmn.BytesToHash(txHash).Hex()),
sdk.NewAttribute(types.AttributeKeyEthereumTxHash, etherumTxHash.Hex()),
} }
if len(msg.Data.To) > 0 { if len(msg.Data.To) > 0 {
@ -174,5 +136,6 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
), ),
}) })
executionResult.Response.Hash = etherumTxHash.Hex()
return executionResult.Response, nil return executionResult.Response, nil
} }

View File

@ -146,8 +146,6 @@ func (k *Keeper) TransitionDb(msg core.Message) (*types.ExecutionResult, error)
func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionResult, error) { func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionResult, error) {
var ( var (
ret []byte // return bytes from evm execution ret []byte // return bytes from evm execution
contract common.Address
contractAddr string
vmErr, err error // vm errors do not effect consensus and are therefore not assigned to err vmErr, err error // vm errors do not effect consensus and are therefore not assigned to err
) )
@ -174,8 +172,7 @@ func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionRe
} }
if contractCreation { if contractCreation {
ret, contract, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value()) ret, _, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value())
contractAddr = contract.Hex()
} else { } else {
ret, leftoverGas, vmErr = evm.Call(sender, *msg.To(), msg.Data(), leftoverGas, msg.Value()) ret, leftoverGas, vmErr = evm.Call(sender, *msg.To(), msg.Data(), leftoverGas, msg.Value())
} }
@ -198,7 +195,6 @@ func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionRe
return &types.ExecutionResult{ return &types.ExecutionResult{
Response: &types.MsgEthereumTxResponse{ Response: &types.MsgEthereumTxResponse{
ContractAddress: contractAddr,
Ret: ret, Ret: ret,
}, },
GasInfo: types.GasInfo{ GasInfo: types.GasInfo{

View File

@ -7,6 +7,7 @@ const (
AttributeKeyContractAddress = "contract" AttributeKeyContractAddress = "contract"
AttributeKeyRecipient = "recipient" AttributeKeyRecipient = "recipient"
AttributeKeyTxHash = "txHash" AttributeKeyTxHash = "txHash"
AttributeKeyEthereumTxHash = "ethereumTxHash"
AttributeValueCategory = ModuleName AttributeValueCategory = ModuleName
MetricKeyTransitionDB = "transition_db" MetricKeyTransitionDB = "transition_db"

View File

@ -20,14 +20,9 @@ func NewTransactionLogs(hash ethcmn.Hash, logs []*Log) TransactionLogs { // noli
// NewTransactionLogsFromEth creates a new NewTransactionLogs instance using []*ethtypes.Log. // NewTransactionLogsFromEth creates a new NewTransactionLogs instance using []*ethtypes.Log.
func NewTransactionLogsFromEth(hash ethcmn.Hash, ethlogs []*ethtypes.Log) TransactionLogs { // nolint: interfacer func NewTransactionLogsFromEth(hash ethcmn.Hash, ethlogs []*ethtypes.Log) TransactionLogs { // nolint: interfacer
logs := make([]*Log, len(ethlogs))
for i := range ethlogs {
logs[i] = NewLogFromEth(ethlogs[i])
}
return TransactionLogs{ return TransactionLogs{
Hash: hash.String(), Hash: hash.String(),
Logs: logs, Logs: NewLogsFromEth(ethlogs),
} }
} }
@ -93,6 +88,15 @@ func (log *Log) ToEthereum() *ethtypes.Log {
} }
} }
func NewLogsFromEth(ethlogs []*ethtypes.Log) []*Log {
var logs []*Log
for _, ethlog := range ethlogs {
logs = append(logs, NewLogFromEth(ethlog))
}
return logs
}
// LogsToEthereum casts the Ethermint Logs to a slice of Ethereum Logs. // LogsToEthereum casts the Ethermint Logs to a slice of Ethereum Logs.
func LogsToEthereum(logs []*Log) []*ethtypes.Log { func LogsToEthereum(logs []*Log) []*ethtypes.Log {
var ethLogs []*ethtypes.Log // nolint: prealloc var ethLogs []*ethtypes.Log // nolint: prealloc

View File

@ -113,6 +113,7 @@ func (msg *MsgEthereumTx) FromEthereumTx(tx *ethtypes.Transaction) {
} }
msg.Size_ = float64(tx.Size()) msg.Size_ = float64(tx.Size())
msg.Hash = tx.Hash().Hex()
} }
// Route returns the route value of an MsgEthereumTx. // Route returns the route value of an MsgEthereumTx.

File diff suppressed because it is too large Load Diff

View File

@ -377,78 +377,6 @@ func local_request_Query_TxLogs_0(ctx context.Context, marshaler runtime.Marshal
} }
func request_Query_TxReceipt_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryTxReceiptRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["hash"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "hash")
}
protoReq.Hash, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "hash", err)
}
msg, err := client.TxReceipt(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_TxReceipt_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryTxReceiptRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["hash"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "hash")
}
protoReq.Hash, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "hash", err)
}
msg, err := server.TxReceipt(ctx, &protoReq)
return msg, metadata, err
}
func request_Query_TxReceiptsByBlockHeight_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryTxReceiptsByBlockHeightRequest
var metadata runtime.ServerMetadata
msg, err := client.TxReceiptsByBlockHeight(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_TxReceiptsByBlockHeight_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryTxReceiptsByBlockHeightRequest
var metadata runtime.ServerMetadata
msg, err := server.TxReceiptsByBlockHeight(ctx, &protoReq)
return msg, metadata, err
}
var ( var (
filter_Query_BlockLogs_0 = &utilities.DoubleArray{Encoding: map[string]int{"hash": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} filter_Query_BlockLogs_0 = &utilities.DoubleArray{Encoding: map[string]int{"hash": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}}
) )
@ -719,46 +647,6 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
}) })
mux.Handle("GET", pattern_Query_TxReceipt_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_TxReceipt_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_TxReceipt_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_TxReceiptsByBlockHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Query_TxReceiptsByBlockHeight_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_TxReceiptsByBlockHeight_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_BlockLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle("GET", pattern_Query_BlockLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
@ -1000,46 +888,6 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
}) })
mux.Handle("GET", pattern_Query_TxReceipt_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_TxReceipt_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_TxReceipt_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_TxReceiptsByBlockHeight_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Query_TxReceiptsByBlockHeight_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Query_TxReceiptsByBlockHeight_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Query_BlockLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { mux.Handle("GET", pattern_Query_BlockLogs_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context()) ctx, cancel := context.WithCancel(req.Context())
defer cancel() defer cancel()
@ -1136,10 +984,6 @@ var (
pattern_Query_TxLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"ethermint", "evm", "v1alpha1", "tx_logs", "hash"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_TxLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"ethermint", "evm", "v1alpha1", "tx_logs", "hash"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Query_TxReceipt_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"ethermint", "evm", "v1alpha1", "tx_receipt", "hash"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Query_TxReceiptsByBlockHeight_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1alpha1", "tx_receipts_block"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Query_BlockLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"ethermint", "evm", "v1alpha1", "block_logs", "hash"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_BlockLogs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 1, 0, 4, 1, 5, 4}, []string{"ethermint", "evm", "v1alpha1", "block_logs", "hash"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Query_BlockBloom_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1alpha1", "block_bloom"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_BlockBloom_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1alpha1", "block_bloom"}, "", runtime.AssumeColonVerbOpt(true)))
@ -1162,10 +1006,6 @@ var (
forward_Query_TxLogs_0 = runtime.ForwardResponseMessage forward_Query_TxLogs_0 = runtime.ForwardResponseMessage
forward_Query_TxReceipt_0 = runtime.ForwardResponseMessage
forward_Query_TxReceiptsByBlockHeight_0 = runtime.ForwardResponseMessage
forward_Query_BlockLogs_0 = runtime.ForwardResponseMessage forward_Query_BlockLogs_0 = runtime.ForwardResponseMessage
forward_Query_BlockBloom_0 = runtime.ForwardResponseMessage forward_Query_BlockBloom_0 = runtime.ForwardResponseMessage

View File

@ -242,11 +242,7 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re
// Resets nonce to value pre state transition // Resets nonce to value pre state transition
csdb.SetNonce(st.Message.From(), currentNonce) csdb.SetNonce(st.Message.From(), currentNonce)
// Generate bloom filter to be saved in tx receipt data
bloomInt := big.NewInt(0)
var ( var (
bloomFilter ethtypes.Bloom
logs []*ethtypes.Log logs []*ethtypes.Log
) )
@ -256,9 +252,6 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re
err = errors.Wrap(err, "failed to get logs") err = errors.Wrap(err, "failed to get logs")
return nil, err return nil, err
} }
bloomInt = big.NewInt(0).SetBytes(ethtypes.LogsBloom(logs))
bloomFilter = ethtypes.BytesToBloom(bloomInt.Bytes())
} }
if !st.Simulate { if !st.Simulate {
@ -270,17 +263,11 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re
} }
resp.Logs = logs resp.Logs = logs
resp.Bloom = bloomInt
resp.Response = &MsgEthereumTxResponse{ resp.Response = &MsgEthereumTxResponse{
Bloom: bloomFilter.Bytes(), Logs: NewLogsFromEth(logs),
TxLogs: NewTransactionLogsFromEth(*st.TxHash, logs),
Ret: ret, Ret: ret,
} }
if contractCreation {
resp.Response.ContractAddress = contractAddress.String()
}
// TODO: Refund unused gas here, if intended in future // TODO: Refund unused gas here, if intended in future
// Consume gas from evm execution // Consume gas from evm execution

View File

@ -150,19 +150,16 @@ var xxx_messageInfo_ExtensionOptionsWeb3Tx proto.InternalMessageInfo
// MsgEthereumTxResponse defines the Msg/EthereumTx response type. // MsgEthereumTxResponse defines the Msg/EthereumTx response type.
type MsgEthereumTxResponse struct { type MsgEthereumTxResponse struct {
// contract_address contains the ethereum address of the created contract (if // ethereum transaction hash in hex format. This hash differs from the Tendermint sha256 hash of the transaction
// any). If the state transition is an evm.Call, the contract address will be // bytes. See https://github.com/tendermint/tendermint/issues/6539 for reference
// empty. Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty" yaml:"contract_address"` // logs contains the transaction hash and the proto-compatible ethereum
// bloom represents the bloom filter bytes
Bloom []byte `protobuf:"bytes,2,opt,name=bloom,proto3" json:"bloom,omitempty"`
// tx_logs contains the transaction hash and the proto-compatible ethereum
// logs. // logs.
TxLogs TransactionLogs `protobuf:"bytes,3,opt,name=tx_logs,json=txLogs,proto3" json:"tx_logs" yaml:"tx_logs"` Logs []*Log `protobuf:"bytes,2,rep,name=logs,proto3" json:"logs,omitempty"`
// ret defines the bytes from the execution. // returned data from evm function (result or data supplied with revert opcode)
Ret []byte `protobuf:"bytes,4,opt,name=ret,proto3" json:"ret,omitempty"` Ret []byte `protobuf:"bytes,3,opt,name=ret,proto3" json:"ret,omitempty"`
// reverted flag is set to true when the call has been reverted // reverted flag is set to true when the call has been reverted
Reverted bool `protobuf:"varint,5,opt,name=reverted,proto3" json:"reverted,omitempty"` Reverted bool `protobuf:"varint,4,opt,name=reverted,proto3" json:"reverted,omitempty"`
} }
func (m *MsgEthereumTxResponse) Reset() { *m = MsgEthereumTxResponse{} } func (m *MsgEthereumTxResponse) Reset() { *m = MsgEthereumTxResponse{} }
@ -208,37 +205,33 @@ func init() {
func init() { proto.RegisterFile("ethermint/evm/v1alpha1/tx.proto", fileDescriptor_6a305e80b084ab0e) } func init() { proto.RegisterFile("ethermint/evm/v1alpha1/tx.proto", fileDescriptor_6a305e80b084ab0e) }
var fileDescriptor_6a305e80b084ab0e = []byte{ var fileDescriptor_6a305e80b084ab0e = []byte{
// 476 bytes of a gzipped FileDescriptorProto // 404 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3f, 0x6f, 0xd3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x31, 0x6b, 0xdb, 0x40,
0x18, 0xc6, 0x7d, 0x8d, 0xd3, 0x3f, 0x97, 0x02, 0xd5, 0xa9, 0x04, 0x63, 0x24, 0xdb, 0xb2, 0x84, 0x1c, 0xc5, 0x75, 0x96, 0xda, 0xba, 0xe7, 0x16, 0xca, 0xd1, 0x1a, 0x55, 0x85, 0x93, 0x10, 0x94,
0x9a, 0x25, 0xb6, 0x9a, 0x6e, 0xd9, 0x6a, 0x51, 0x26, 0x2a, 0xa4, 0x53, 0x25, 0x10, 0x4b, 0x75, 0x6a, 0xb1, 0x84, 0xe5, 0xcd, 0x5b, 0x4d, 0xbd, 0xd5, 0x14, 0x0e, 0x43, 0xa1, 0x9b, 0x64, 0x5f,
0x76, 0x0e, 0xdb, 0x92, 0xed, 0xb3, 0xee, 0xae, 0x91, 0xcb, 0xca, 0xc2, 0xc8, 0xca, 0xc6, 0xc7, 0x25, 0x81, 0xa5, 0x13, 0xba, 0xb3, 0x50, 0xf2, 0x09, 0x32, 0x7a, 0xcd, 0x96, 0x8f, 0x93, 0xd1,
0xe9, 0xd8, 0x91, 0xc9, 0x42, 0xc9, 0xc6, 0x98, 0x4f, 0x80, 0x7c, 0x6e, 0x52, 0x1a, 0x11, 0xa9, 0x63, 0x26, 0x13, 0xec, 0x2d, 0x63, 0x3e, 0x41, 0xd0, 0x39, 0xb6, 0xe3, 0x10, 0x43, 0xb6, 0xbf,
0xdb, 0x7b, 0xef, 0xfb, 0xf3, 0xf9, 0x79, 0x9e, 0x7b, 0xa1, 0x4d, 0x65, 0x42, 0x79, 0x9e, 0x16, 0xf4, 0xff, 0xdd, 0xbd, 0xf7, 0x8e, 0x07, 0x4d, 0x2a, 0x62, 0x5a, 0xa4, 0x49, 0x26, 0x3c, 0x5a,
0xd2, 0xa7, 0xd3, 0xdc, 0x9f, 0x1e, 0x93, 0xac, 0x4c, 0xc8, 0xb1, 0x2f, 0x2b, 0xaf, 0xe4, 0x4c, 0xa6, 0x5e, 0xd9, 0x0d, 0x66, 0x79, 0x1c, 0x74, 0x3d, 0x51, 0xb9, 0x79, 0xc1, 0x04, 0x43, 0xed,
0x32, 0xd4, 0x5f, 0x01, 0x1e, 0x9d, 0xe6, 0xde, 0x12, 0x30, 0x0f, 0x63, 0x16, 0x33, 0x85, 0xf8, 0x3d, 0xe0, 0xd2, 0x32, 0x75, 0x77, 0x80, 0xf1, 0x39, 0x62, 0x11, 0x93, 0x88, 0x57, 0x4f, 0x5b,
0x4d, 0xd5, 0xd2, 0xa6, 0xb3, 0xe1, 0xba, 0xe6, 0x53, 0x45, 0xb8, 0x3f, 0x00, 0x7c, 0x72, 0x2e, 0xda, 0xb0, 0x4e, 0x5c, 0x57, 0x1f, 0x95, 0x84, 0x7d, 0x09, 0xe0, 0xc7, 0x11, 0x8f, 0x86, 0x35,
0xe2, 0xb3, 0x86, 0xa3, 0x57, 0xf9, 0x45, 0x85, 0x46, 0x50, 0x9f, 0x10, 0x49, 0x0c, 0xe0, 0x80, 0x47, 0xe7, 0xe9, 0xb8, 0x42, 0x3e, 0xd4, 0xa6, 0x81, 0x08, 0x74, 0x60, 0x01, 0xa7, 0xe5, 0x63,
0x41, 0x6f, 0x64, 0x79, 0xff, 0xff, 0xa1, 0x77, 0x51, 0xbd, 0x21, 0x92, 0x60, 0xc5, 0xa2, 0x97, 0xf7, 0x65, 0x41, 0x77, 0x5c, 0xfd, 0x0a, 0x44, 0x40, 0x24, 0x8b, 0xbe, 0x42, 0x8d, 0x27, 0xe7,
0x50, 0x17, 0xe9, 0x17, 0x6a, 0x6c, 0x39, 0x60, 0x00, 0x82, 0xee, 0x9f, 0xda, 0x06, 0x43, 0xac, 0x54, 0x6f, 0x58, 0xc0, 0x01, 0x83, 0x37, 0x77, 0x2b, 0x13, 0x74, 0x88, 0xfc, 0x85, 0x4c, 0xa8,
0x5a, 0xc8, 0x86, 0x7a, 0x42, 0x44, 0x62, 0x74, 0x1c, 0x30, 0xd8, 0x0b, 0x7a, 0x8b, 0xda, 0xde, 0xc5, 0x01, 0x8f, 0x75, 0xd5, 0x02, 0xce, 0xfb, 0x41, 0xeb, 0x7e, 0x65, 0xbe, 0x2b, 0x66, 0x79,
0xe1, 0x59, 0x39, 0x76, 0x87, 0x2e, 0x56, 0x03, 0x84, 0xa0, 0xfe, 0x99, 0xb3, 0xdc, 0xd0, 0x1b, 0xdf, 0xee, 0xd8, 0x44, 0x2e, 0x10, 0x82, 0xda, 0xff, 0x82, 0xa5, 0xba, 0x56, 0x03, 0x44, 0xce,
0x00, 0xab, 0x7a, 0xac, 0x7f, 0xfb, 0x69, 0x6b, 0xae, 0x0b, 0xcd, 0xb3, 0x4a, 0xd2, 0x42, 0xa4, 0x7d, 0xed, 0xe2, 0xca, 0x54, 0x6c, 0x1b, 0x1a, 0xc3, 0x4a, 0xd0, 0x8c, 0x27, 0x2c, 0xfb, 0x93,
0xac, 0x78, 0x5f, 0xca, 0x94, 0x15, 0xe2, 0x5e, 0xe7, 0x1d, 0x63, 0xc1, 0xfe, 0x3a, 0xf3, 0x81, 0x8b, 0x84, 0x65, 0xfc, 0xe0, 0xf3, 0x91, 0xc1, 0xb0, 0xfd, 0x9c, 0xf9, 0x4b, 0xc3, 0xde, 0x7e,
0x86, 0x27, 0xab, 0xf9, 0xd7, 0x2d, 0xf8, 0xfc, 0x81, 0x3f, 0x4c, 0x45, 0xc9, 0x0a, 0x41, 0xd1, 0xbf, 0x00, 0xf0, 0xcb, 0x51, 0x3e, 0x42, 0x79, 0xce, 0x32, 0x4e, 0x6b, 0x5d, 0x69, 0x0c, 0x6c,
0x5b, 0x78, 0x10, 0xb1, 0x42, 0x72, 0x12, 0xc9, 0x4b, 0x32, 0x99, 0x70, 0x2a, 0x84, 0xf2, 0xbc, 0x75, 0xa5, 0x17, 0x0f, 0x6a, 0x33, 0x16, 0x71, 0xbd, 0x61, 0xa9, 0x4e, 0xcb, 0xff, 0x76, 0x2a,
0x17, 0xbc, 0x5a, 0xd4, 0xf6, 0x8b, 0x6b, 0x92, 0x67, 0x63, 0x77, 0x9d, 0x70, 0xf1, 0xb3, 0x65, 0xfb, 0x6f, 0x16, 0x11, 0x09, 0xa2, 0x4f, 0x50, 0x2d, 0xa8, 0x90, 0xe1, 0x3e, 0x90, 0x7a, 0x44,
0xeb, 0xb4, 0xed, 0xa0, 0x43, 0xd8, 0x0d, 0x33, 0xc6, 0x72, 0x65, 0x7e, 0x1f, 0xb7, 0x07, 0xf4, 0x06, 0x6c, 0x16, 0xb4, 0xa4, 0x85, 0xa0, 0x53, 0x19, 0xa9, 0x49, 0xf6, 0xdf, 0x5b, 0x4b, 0x7e,
0x11, 0xee, 0xc8, 0xea, 0x32, 0x63, 0xb1, 0x50, 0xce, 0x7b, 0xa3, 0xa3, 0x8d, 0x41, 0x72, 0x52, 0x02, 0xd5, 0x11, 0x8f, 0x50, 0x08, 0xe1, 0x93, 0x57, 0xff, 0x7e, 0x4a, 0xeb, 0xc8, 0xbc, 0xd1,
0x08, 0x12, 0x35, 0xd2, 0xdf, 0xb1, 0x58, 0x04, 0xfd, 0x9b, 0xda, 0xd6, 0x16, 0xb5, 0xfd, 0xb4, 0x79, 0x15, 0xb6, 0xcb, 0x38, 0xf8, 0x79, 0xbd, 0xc6, 0x60, 0xb9, 0xc6, 0xe0, 0x76, 0x8d, 0xc1,
0x55, 0x70, 0x77, 0x8b, 0x8b, 0xb7, 0x65, 0xd5, 0xcc, 0xd1, 0x01, 0xec, 0x70, 0x2a, 0x55, 0x5c, 0x62, 0x83, 0x95, 0xe5, 0x06, 0x2b, 0x37, 0x1b, 0xac, 0xfc, 0xfb, 0x11, 0x25, 0x22, 0x9e, 0x87,
0xfb, 0xb8, 0x29, 0x91, 0x09, 0x77, 0x39, 0x9d, 0x52, 0x2e, 0xe9, 0xc4, 0xe8, 0x3a, 0x60, 0xb0, 0xee, 0x84, 0xa5, 0xde, 0x84, 0xf1, 0x94, 0x71, 0xef, 0xd0, 0x95, 0x4a, 0xb6, 0x45, 0x9c, 0xe5,
0x8b, 0x57, 0xe7, 0x36, 0x85, 0x51, 0x0a, 0x3b, 0xe7, 0x22, 0x46, 0x21, 0x84, 0xff, 0x3c, 0xf4, 0x94, 0x87, 0x6f, 0x65, 0x4f, 0x7a, 0x0f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x61, 0x2c, 0xf2,
0xeb, 0x4d, 0x8a, 0x1e, 0xe4, 0x65, 0x0e, 0x1f, 0x85, 0x2d, 0x63, 0x0d, 0x4e, 0x6f, 0x66, 0x16, 0x9a, 0x02, 0x00, 0x00,
0xb8, 0x9d, 0x59, 0xe0, 0xf7, 0xcc, 0x02, 0xdf, 0xe7, 0x96, 0x76, 0x3b, 0xb7, 0xb4, 0x5f, 0x73,
0x4b, 0xfb, 0x74, 0x14, 0xa7, 0x32, 0xb9, 0x0a, 0xbd, 0x88, 0xe5, 0x7e, 0xc4, 0x44, 0xce, 0x84,
0x7f, 0xbf, 0x9e, 0x95, 0x5a, 0x50, 0x79, 0x5d, 0x52, 0x11, 0x6e, 0xab, 0xd5, 0x3c, 0xf9, 0x1b,
0x00, 0x00, 0xff, 0xff, 0x74, 0xe0, 0xdf, 0x68, 0x0d, 0x03, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -452,17 +445,19 @@ func (m *MsgEthereumTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
dAtA[i] = 0 dAtA[i] = 0
} }
i-- i--
dAtA[i] = 0x28 dAtA[i] = 0x20
} }
if len(m.Ret) > 0 { if len(m.Ret) > 0 {
i -= len(m.Ret) i -= len(m.Ret)
copy(dAtA[i:], m.Ret) copy(dAtA[i:], m.Ret)
i = encodeVarintTx(dAtA, i, uint64(len(m.Ret))) i = encodeVarintTx(dAtA, i, uint64(len(m.Ret)))
i-- i--
dAtA[i] = 0x22 dAtA[i] = 0x1a
} }
if len(m.Logs) > 0 {
for iNdEx := len(m.Logs) - 1; iNdEx >= 0; iNdEx-- {
{ {
size, err := m.TxLogs.MarshalToSizedBuffer(dAtA[:i]) size, err := m.Logs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -470,18 +465,13 @@ func (m *MsgEthereumTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i = encodeVarintTx(dAtA, i, uint64(size)) i = encodeVarintTx(dAtA, i, uint64(size))
} }
i-- i--
dAtA[i] = 0x1a
if len(m.Bloom) > 0 {
i -= len(m.Bloom)
copy(dAtA[i:], m.Bloom)
i = encodeVarintTx(dAtA, i, uint64(len(m.Bloom)))
i--
dAtA[i] = 0x12 dAtA[i] = 0x12
} }
if len(m.ContractAddress) > 0 { }
i -= len(m.ContractAddress) if len(m.Hash) > 0 {
copy(dAtA[i:], m.ContractAddress) i -= len(m.Hash)
i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddress))) copy(dAtA[i:], m.Hash)
i = encodeVarintTx(dAtA, i, uint64(len(m.Hash)))
i-- i--
dAtA[i] = 0xa dAtA[i] = 0xa
} }
@ -547,16 +537,16 @@ func (m *MsgEthereumTxResponse) Size() (n int) {
} }
var l int var l int
_ = l _ = l
l = len(m.ContractAddress) l = len(m.Hash)
if l > 0 { if l > 0 {
n += 1 + l + sovTx(uint64(l)) n += 1 + l + sovTx(uint64(l))
} }
l = len(m.Bloom) if len(m.Logs) > 0 {
if l > 0 { for _, e := range m.Logs {
l = e.Size()
n += 1 + l + sovTx(uint64(l)) n += 1 + l + sovTx(uint64(l))
} }
l = m.TxLogs.Size() }
n += 1 + l + sovTx(uint64(l))
l = len(m.Ret) l = len(m.Ret)
if l > 0 { if l > 0 {
n += 1 + l + sovTx(uint64(l)) n += 1 + l + sovTx(uint64(l))
@ -874,7 +864,7 @@ func (m *MsgEthereumTxResponse) Unmarshal(dAtA []byte) error {
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ContractAddress", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType)
} }
var stringLen uint64 var stringLen uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -902,45 +892,11 @@ func (m *MsgEthereumTxResponse) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.ContractAddress = string(dAtA[iNdEx:postIndex]) m.Hash = string(dAtA[iNdEx:postIndex])
iNdEx = postIndex iNdEx = postIndex
case 2: case 2:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Bloom", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Logs", wireType)
}
var byteLen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTx
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
byteLen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if byteLen < 0 {
return ErrInvalidLengthTx
}
postIndex := iNdEx + byteLen
if postIndex < 0 {
return ErrInvalidLengthTx
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
m.Bloom = append(m.Bloom[:0], dAtA[iNdEx:postIndex]...)
if m.Bloom == nil {
m.Bloom = []byte{}
}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field TxLogs", wireType)
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
@ -967,11 +923,12 @@ func (m *MsgEthereumTxResponse) Unmarshal(dAtA []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
if err := m.TxLogs.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { m.Logs = append(m.Logs, &Log{})
if err := m.Logs[len(m.Logs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 4: case 3:
if wireType != 2 { if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field Ret", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Ret", wireType)
} }
@ -1005,7 +962,7 @@ func (m *MsgEthereumTxResponse) Unmarshal(dAtA []byte) error {
m.Ret = []byte{} m.Ret = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 5: case 4:
if wireType != 0 { if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Reverted", wireType) return fmt.Errorf("proto: wrong wireType = %d for field Reverted", wireType)
} }

View File

@ -8,7 +8,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
ethcmn "github.com/ethereum/go-ethereum/common" ethcmn "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
ethcrypto "github.com/ethereum/go-ethereum/crypto" ethcrypto "github.com/ethereum/go-ethereum/crypto"
) )
@ -23,20 +22,13 @@ func GenerateEthAddress() ethcmn.Address {
} }
func TestEvmDataEncoding(t *testing.T) { func TestEvmDataEncoding(t *testing.T) {
addr := "0x5dE8a020088a2D6d0a23c204FFbeD02790466B49"
bloom := ethtypes.BytesToBloom([]byte{0x1, 0x3})
ret := []byte{0x5, 0x8} ret := []byte{0x5, 0x8}
data := &MsgEthereumTxResponse{ data := &MsgEthereumTxResponse{
ContractAddress: addr,
Bloom: bloom.Bytes(),
TxLogs: TransactionLogs{
Hash: ethcmn.BytesToHash([]byte{1, 2, 3, 4}).String(),
Logs: []*Log{{ Logs: []*Log{{
Data: []byte{1, 2, 3, 4}, Data: []byte{1, 2, 3, 4},
BlockNumber: 17, BlockNumber: 17,
}}, }},
},
Ret: ret, Ret: ret,
} }
@ -46,8 +38,6 @@ func TestEvmDataEncoding(t *testing.T) {
res, err := DecodeTxResponse(enc) res, err := DecodeTxResponse(enc)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res)
require.Equal(t, addr, res.ContractAddress) require.Equal(t, data.Logs, res.Logs)
require.Equal(t, bloom.Bytes(), res.Bloom)
require.Equal(t, data.TxLogs, res.TxLogs)
require.Equal(t, ret, res.Ret) require.Equal(t, ret, res.Ret)
} }