forked from cerc-io/laconicd-deprecated
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:
parent
e3270aee5d
commit
6eadc8fdf8
@ -39,11 +39,16 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
### 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#68](https://github.com/tharsis/ethermint/issues/68) Replace block hash storage map to use staking `HistoricalInfo`.
|
||||
|
||||
### 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.
|
||||
|
||||
### Improvements
|
||||
@ -53,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
|
||||
|
||||
### 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.
|
||||
|
||||
## [v0.4.1] - 2021-03-01
|
||||
|
@ -45,10 +45,6 @@
|
||||
- [QueryStorageResponse](#ethermint.evm.v1alpha1.QueryStorageResponse)
|
||||
- [QueryTxLogsRequest](#ethermint.evm.v1alpha1.QueryTxLogsRequest)
|
||||
- [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)
|
||||
|
||||
@ -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 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}|
|
||||
| `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}|
|
||||
| `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}|
|
||||
| `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|
|
||||
@ -849,10 +788,9 @@ MsgEthereumTxResponse defines the Msg/EthereumTx response type.
|
||||
|
||||
| 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. |
|
||||
| `bloom` | [bytes](#bytes) | | bloom represents the bloom filter bytes |
|
||||
| `tx_logs` | [TransactionLogs](#ethermint.evm.v1alpha1.TransactionLogs) | | tx_logs contains the transaction hash and the proto-compatible ethereum logs. |
|
||||
| `ret` | [bytes](#bytes) | | ret defines the bytes from the execution. |
|
||||
| `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 |
|
||||
| `logs` | [Log](#ethermint.evm.v1alpha1.Log) | repeated | 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) |
|
||||
| `reverted` | [bool](#bool) | | reverted flag is set to true when the call has been reverted |
|
||||
|
||||
|
||||
|
@ -133,43 +133,44 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
||||
fullTx bool,
|
||||
) (map[string]interface{}, error) {
|
||||
|
||||
req := &evmtypes.QueryTxReceiptsByBlockHeightRequest{}
|
||||
|
||||
txReceiptsResp, err := queryClient.TxReceiptsByBlockHeight(types.ContextWithHeight(block.Height), req)
|
||||
if err != nil {
|
||||
e.logger.WithError(err).Debugln("TxReceiptsByBlockHeight failed")
|
||||
}
|
||||
|
||||
gasUsed := big.NewInt(0)
|
||||
gasUsed := uint64(0)
|
||||
|
||||
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())
|
||||
|
||||
for _, receipt := range txReceiptsResp.Receipts {
|
||||
hash := common.HexToHash(receipt.Hash)
|
||||
if fullTx {
|
||||
// full txs from receipts
|
||||
tx, err := types.NewTransactionFromData(
|
||||
receipt.Data,
|
||||
common.HexToAddress(receipt.From),
|
||||
hash,
|
||||
common.HexToHash(receipt.BlockHash),
|
||||
receipt.BlockHeight,
|
||||
receipt.Index,
|
||||
)
|
||||
tx, gas := types.DecodeTx(e.clientCtx, txBz)
|
||||
|
||||
if err != nil {
|
||||
e.logger.WithError(err).Warningf("NewTransactionFromData for receipt %s failed", hash)
|
||||
continue
|
||||
}
|
||||
gasUsed += gas
|
||||
|
||||
ethRPCTxs = append(ethRPCTxs, tx)
|
||||
gasUsed.Add(gasUsed, new(big.Int).SetUint64(receipt.Result.GasUsed))
|
||||
} else {
|
||||
// simply hashes
|
||||
ethRPCTxs = append(ethRPCTxs, hash)
|
||||
msg, isEthTx := tx.(*evmtypes.MsgEthereumTx)
|
||||
|
||||
if fullTx {
|
||||
if !isEthTx {
|
||||
// TODO: eventually support Cosmos txs in the block
|
||||
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)
|
||||
|
||||
if err != nil {
|
||||
e.logger.WithError(err).Debugln("NewTransactionFromData for receipt failed", "hash", hash.Hex)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
ethRPCTxs = append(ethRPCTxs, hash)
|
||||
}
|
||||
}
|
||||
|
||||
@ -181,7 +182,7 @@ func (e *EVMBackend) EthBlockFromTendermint(
|
||||
}
|
||||
|
||||
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)
|
||||
return formattedBlock, nil
|
||||
|
@ -21,13 +21,13 @@ import (
|
||||
authtypes "github.com/cosmos/cosmos-sdk/x/auth/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/common"
|
||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||
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"
|
||||
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()
|
||||
txBytes, err := txEncoder(tx)
|
||||
if err != nil {
|
||||
e.logger.WithError(err).Errorln("failed to encode eth tx using default encoder")
|
||||
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)
|
||||
// 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.
|
||||
func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, error) {
|
||||
e.logger.Debugln("eth_sendRawTransaction", "data_len", len(data))
|
||||
ethereumTx := new(evmtypes.MsgEthereumTx)
|
||||
|
||||
// RLP decode raw transaction bytes
|
||||
if err := rlp.DecodeBytes(data, ethereumTx); err != nil {
|
||||
e.logger.WithError(err).Errorln("transaction RLP decode failed")
|
||||
tx, err := e.clientCtx.TxConfig.TxDecoder()(data)
|
||||
if err != nil {
|
||||
e.logger.WithError(err).Errorln("transaction decoding failed")
|
||||
|
||||
// Return nil is for when gasLimit overflows uint64
|
||||
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)
|
||||
if !ok {
|
||||
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)
|
||||
err = builder.SetMsgs(ethereumTx.GetMsgs()...)
|
||||
err = builder.SetMsgs(tx.GetMsgs()...)
|
||||
if err != nil {
|
||||
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
|
||||
txBytes, err := e.clientCtx.TxConfig.TxEncoder()(builder.GetTx())
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -461,7 +474,7 @@ func (e *PublicEthAPI) SendRawTransaction(data hexutil.Bytes) (common.Hash, erro
|
||||
|
||||
// Call performs a raw contract call.
|
||||
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))
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
@ -561,8 +574,8 @@ func (e *PublicEthAPI) doCall(
|
||||
txBuilder.SetFeeAmount(fees)
|
||||
txBuilder.SetGasLimit(gas)
|
||||
|
||||
//doc about generate and transform tx into json, protobuf bytes
|
||||
//https://github.com/cosmos/cosmos-sdk/blob/master/docs/run-node/txs.md
|
||||
// doc about generate and transform tx into json, protobuf bytes
|
||||
// https://github.com/cosmos/cosmos-sdk/blob/master/docs/run-node/txs.md
|
||||
txBytes, err := e.clientCtx.TxConfig.TxEncoder()(txBuilder.GetTx())
|
||||
if err != nil {
|
||||
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) {
|
||||
e.logger.Debugln("eth_getTransactionByHash", "hash", hash.Hex())
|
||||
|
||||
resp, err := e.queryClient.TxReceipt(e.ctx, &evmtypes.QueryTxReceiptRequest{
|
||||
Hash: hash.Hex(),
|
||||
})
|
||||
res, err := e.clientCtx.Client.Tx(e.ctx, hash.Bytes(), false)
|
||||
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
|
||||
}
|
||||
|
||||
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(
|
||||
resp.Receipt.Data,
|
||||
common.HexToAddress(resp.Receipt.From),
|
||||
common.HexToHash(resp.Receipt.Hash),
|
||||
common.HexToHash(resp.Receipt.BlockHash),
|
||||
resp.Receipt.BlockHeight,
|
||||
resp.Receipt.Index,
|
||||
msg.Data,
|
||||
common.HexToAddress(msg.From),
|
||||
hash,
|
||||
common.BytesToHash(resBlock.Block.Hash()),
|
||||
uint64(res.Height),
|
||||
uint64(res.Index),
|
||||
)
|
||||
}
|
||||
|
||||
// GetTransactionByBlockHashAndIndex returns the transaction identified by hash and index.
|
||||
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 {
|
||||
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{})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to query tx receipts by block height")
|
||||
i := int(idx)
|
||||
if i >= len(resBlock.Block.Txs) {
|
||||
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.
|
||||
func (e *PublicEthAPI) GetTransactionByBlockNumberAndIndex(blockNum rpctypes.BlockNumber, idx hexutil.Uint) (*rpctypes.RPCTransaction, error) {
|
||||
e.logger.Debugln("eth_getTransactionByBlockNumberAndIndex", "number", blockNum, "index", idx)
|
||||
|
||||
req := &evmtypes.QueryTxReceiptsByBlockHeightRequest{}
|
||||
resp, err := e.queryClient.TxReceiptsByBlockHeight(rpctypes.ContextWithHeight(blockNum.Int64()), req)
|
||||
resBlock, err := e.clientCtx.Client.Block(e.ctx, blockNum.TmHeight())
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "failed to query tx receipts by block height")
|
||||
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)) {
|
||||
e.logger.WithError(err).Debugln("block not found", "height", blockNum.Int64())
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
receipt := receipts[idx]
|
||||
|
||||
if (blockHash != common.Hash{}) {
|
||||
hexBlockHash := blockHash.Hex()
|
||||
if receipt.BlockHash != hexBlockHash {
|
||||
return nil, errors.Errorf("receipt found but block hashes don't match %s != %s",
|
||||
receipt.BlockHash,
|
||||
hexBlockHash,
|
||||
)
|
||||
}
|
||||
i := int(idx)
|
||||
if i >= len(resBlock.Block.Txs) {
|
||||
e.logger.Debugln("block txs index out of bound", "index", i)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
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(
|
||||
receipt.Data,
|
||||
common.HexToAddress(receipt.From),
|
||||
common.HexToHash(receipt.Hash),
|
||||
blockHash,
|
||||
receipt.BlockHeight,
|
||||
msg.Data,
|
||||
common.HexToAddress(msg.From),
|
||||
txHash,
|
||||
common.BytesToHash(resBlock.Block.Hash()),
|
||||
uint64(resBlock.Block.Height),
|
||||
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) {
|
||||
e.logger.Debugln("eth_getTransactionReceipt", "hash", hash.Hex())
|
||||
|
||||
ctx := rpctypes.ContextWithHeight(int64(0))
|
||||
tx, err := e.queryClient.TxReceipt(ctx, &evmtypes.QueryTxReceiptRequest{
|
||||
Hash: hash.Hex(),
|
||||
})
|
||||
res, err := e.clientCtx.Client.Tx(e.ctx, hash.Bytes(), false)
|
||||
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
|
||||
}
|
||||
|
||||
// Query block for consensus hash
|
||||
height := int64(tx.Receipt.BlockHeight)
|
||||
block, err := e.clientCtx.Client.Block(e.ctx, &height)
|
||||
resBlock, err := e.clientCtx.Client.Block(e.ctx, &res.Height)
|
||||
if err != nil {
|
||||
e.logger.Warningln("didnt find block for tx height", height)
|
||||
return nil, err
|
||||
e.logger.WithError(err).Debugln("block not found", "height", res.Height)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
cumulativeGasUsed := tx.Receipt.Result.GasUsed
|
||||
if tx.Receipt.Index != 0 {
|
||||
cumulativeGasUsed += rpctypes.GetBlockCumulativeGas(e.clientCtx, block.Block, int(tx.Receipt.Index))
|
||||
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)
|
||||
}
|
||||
|
||||
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
|
||||
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 {
|
||||
status = hexutil.Uint(1)
|
||||
status = hexutil.Uint(ethtypes.ReceiptStatusFailed)
|
||||
}
|
||||
|
||||
toHex := common.Address{}
|
||||
if len(tx.Receipt.Data.To) > 0 {
|
||||
toHex = common.HexToAddress(tx.Receipt.Data.To)
|
||||
from := common.HexToAddress(msg.From)
|
||||
|
||||
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)
|
||||
logsBloom := hexutil.Encode(ethtypes.BytesToBloom(tx.Receipt.Result.Bloom).Bytes())
|
||||
logs := evmtypes.LogsToEthereum(resLogs.Logs)
|
||||
|
||||
receipt := map[string]interface{}{
|
||||
// Consensus fields: These fields are defined by the Yellow Paper
|
||||
"status": status,
|
||||
"cumulativeGasUsed": hexutil.Uint64(cumulativeGasUsed),
|
||||
"logsBloom": logsBloom,
|
||||
"logs": tx.Receipt.Result.TxLogs.EthLogs(),
|
||||
"logsBloom": ethtypes.BytesToBloom(ethtypes.LogsBloom(logs)),
|
||||
"logs": logs,
|
||||
|
||||
// Implementation fields: These fields are added by geth when processing a transaction.
|
||||
// They are stored in the chain database.
|
||||
"transactionHash": hash.Hex(),
|
||||
"contractAddress": contractAddress.Hex(),
|
||||
"gasUsed": hexutil.Uint64(tx.Receipt.Result.GasUsed),
|
||||
"transactionHash": hash,
|
||||
"contractAddress": nil,
|
||||
"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
|
||||
// transaction corresponding to this receipt.
|
||||
"blockHash": common.BytesToHash(block.Block.Header.Hash()).Hex(),
|
||||
"blockNumber": hexutil.Uint64(tx.Receipt.BlockHeight),
|
||||
"transactionIndex": hexutil.Uint64(tx.Receipt.Index),
|
||||
"blockHash": common.BytesToHash(resBlock.Block.Header.Hash()).Hex(),
|
||||
"blockNumber": hexutil.Uint64(res.Height),
|
||||
"transactionIndex": hexutil.Uint64(res.Index),
|
||||
|
||||
// sender and receiver (contract or EOA) addreses
|
||||
"from": common.HexToAddress(tx.Receipt.From),
|
||||
"to": toHex,
|
||||
"from": from,
|
||||
"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
|
||||
|
@ -371,7 +371,7 @@ func (api *PublicFilterAPI) Logs(ctx context.Context, crit filters.FilterCriteri
|
||||
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 {
|
||||
err = notifier.Notify(rpcSub.ID, log)
|
||||
@ -448,7 +448,7 @@ func (api *PublicFilterAPI) NewFilter(criteria filters.FilterCriteria) (rpc.ID,
|
||||
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()
|
||||
if f, found := api.filters[filterID]; found {
|
||||
|
@ -25,8 +25,8 @@ import (
|
||||
)
|
||||
|
||||
// RawTxToEthTx returns a evm MsgEthereum transaction from raw tx bytes.
|
||||
func RawTxToEthTx(clientCtx client.Context, bz []byte) (*evmtypes.MsgEthereumTx, error) {
|
||||
tx, err := clientCtx.TxConfig.TxDecoder()(bz)
|
||||
func RawTxToEthTx(clientCtx client.Context, txBz tmtypes.Tx) (*evmtypes.MsgEthereumTx, error) {
|
||||
tx, err := clientCtx.TxConfig.TxDecoder()(txBz)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
@ -246,28 +246,23 @@ func BuildEthereumTx(clientCtx client.Context, msg *evmtypes.MsgEthereumTx, accN
|
||||
return txBytes, nil
|
||||
}
|
||||
|
||||
// GetBlockCumulativeGas returns the cumulative gas used on a block up to a given
|
||||
// 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 {
|
||||
func DecodeTx(clientCtx client.Context, txBz tmtypes.Tx) (sdk.Tx, uint64) {
|
||||
var gasUsed uint64
|
||||
txDecoder := clientCtx.TxConfig.TxDecoder()
|
||||
|
||||
for i := 0; i < idx && i < len(block.Txs); i++ {
|
||||
txi, err := txDecoder(block.Txs[i])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
switch tx := txi.(type) {
|
||||
case *evmtypes.MsgEthereumTx:
|
||||
gasUsed += tx.GetGas()
|
||||
case sdk.FeeTx:
|
||||
// TODO: add internal txns
|
||||
gasUsed += tx.GetGas()
|
||||
}
|
||||
tx, err := txDecoder(txBz)
|
||||
if err != nil {
|
||||
return nil, 0
|
||||
}
|
||||
return gasUsed
|
||||
|
||||
switch tx := tx.(type) {
|
||||
case *evmtypes.MsgEthereumTx:
|
||||
gasUsed = tx.GetGas() // NOTE: this doesn't include the gas refunded
|
||||
case sdk.FeeTx:
|
||||
gasUsed = tx.GetGas()
|
||||
}
|
||||
|
||||
return tx, gasUsed
|
||||
}
|
||||
|
||||
type DataError interface {
|
||||
|
@ -604,7 +604,7 @@ func (api *pubSubAPI) subscribeLogs(wsConn *wsConn, extra interface{}) (rpc.ID,
|
||||
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 {
|
||||
continue
|
||||
}
|
||||
|
2
go.mod
2
go.mod
@ -46,7 +46,7 @@ require (
|
||||
github.com/xlab/closer v0.0.0-20190328110542-03326addb7c2
|
||||
github.com/xlab/suplog v1.3.0
|
||||
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
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
|
16
go.sum
16
go.sum
@ -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/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.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/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM=
|
||||
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-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-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-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
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-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-20210316092652-d523dce5a7f4 h1:b0LrWgu8+q7z4J+0Y3Umo5q1dL7NXBkKBWkaVkAq17E=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
|
||||
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-20190226205417-e64efc72b421/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-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-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-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-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE=
|
||||
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-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.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-20191011141410-1b5146add898/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-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-20210524171403-669157292da3 h1:xFyh6GBb+NO1L0xqb978I3sBPQpk6FrKO0jJGRvdj/0=
|
||||
google.golang.org/genproto v0.0.0-20210524171403-669157292da3/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
|
||||
google.golang.org/genproto v0.0.0-20210607140030-00d4fb20b1ae h1:2dB4bZ/B7RJdKuvHk3mKTzL2xwrikb+Y/QQy7WdyBPk=
|
||||
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.19.0/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.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
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.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
|
@ -102,12 +102,12 @@ message ChainConfig {
|
||||
(gogoproto.moretags) = "yaml:\"muir_glacier_block\"",
|
||||
(gogoproto.nullable) = false
|
||||
];
|
||||
// Berlin switch block (< 0 = no fork, 0 = already on berlin)
|
||||
string berlin_block = 13 [
|
||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
||||
(gogoproto.moretags) = "yaml:\"berlin_block\"",
|
||||
(gogoproto.nullable) = false
|
||||
];
|
||||
// Berlin switch block (< 0 = no fork, 0 = already on berlin)
|
||||
string berlin_block = 13 [
|
||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
||||
(gogoproto.moretags) = "yaml:\"berlin_block\"",
|
||||
(gogoproto.nullable) = false
|
||||
];
|
||||
// YOLO v3: Gas repricings
|
||||
string yolo_v3_block = 14 [
|
||||
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
|
||||
@ -180,13 +180,13 @@ message Log {
|
||||
message TxReceipt {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
string hash = 1;
|
||||
string from = 2;
|
||||
TxData data = 3;
|
||||
TxResult result = 4;
|
||||
uint64 index = 5;
|
||||
string hash = 1;
|
||||
string from = 2;
|
||||
TxData data = 3;
|
||||
TxResult result = 4;
|
||||
uint64 index = 5;
|
||||
uint64 block_height = 6;
|
||||
string block_hash = 7;
|
||||
string block_hash = 7;
|
||||
}
|
||||
|
||||
// TxResult stores results of Tx execution.
|
||||
@ -216,10 +216,7 @@ message TxData {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// destination EVM chain ID
|
||||
bytes chain_id = 1 [
|
||||
(gogoproto.customname) = "ChainID",
|
||||
(gogoproto.jsontag) = "chainID"
|
||||
];
|
||||
bytes chain_id = 1 [(gogoproto.customname) = "ChainID", (gogoproto.jsontag) = "chainID"];
|
||||
// nonce corresponds to the account nonce (transaction sequence).
|
||||
uint64 nonce = 2;
|
||||
// price defines the unsigned integer value of the gas price in bytes.
|
||||
@ -227,16 +224,13 @@ message TxData {
|
||||
// gas defines the gas limit defined for the transaction.
|
||||
uint64 gas = 4 [(gogoproto.customname) = "GasLimit"];
|
||||
// hex formatted address of the recipient
|
||||
string to = 5;
|
||||
string to = 5;
|
||||
// value defines the unsigned integer value of the transaction amount.
|
||||
bytes value = 6 [(gogoproto.customname) = "Amount"];
|
||||
// input defines the data payload bytes of the transaction.
|
||||
bytes input = 7;
|
||||
repeated AccessTuple accesses = 8 [
|
||||
(gogoproto.castrepeated) = "AccessList",
|
||||
(gogoproto.jsontag) = "accessList",
|
||||
(gogoproto.nullable) = false
|
||||
];
|
||||
bytes input = 7;
|
||||
repeated AccessTuple accesses = 8
|
||||
[(gogoproto.castrepeated) = "AccessList", (gogoproto.jsontag) = "accessList", (gogoproto.nullable) = false];
|
||||
// v defines the signature value
|
||||
bytes v = 9;
|
||||
// r defines the signature value
|
||||
@ -256,7 +250,7 @@ message AccessTuple {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// hex formatted ethereum address
|
||||
string address = 1;
|
||||
string address = 1;
|
||||
// hex formatted hashes of the storage keys
|
||||
repeated string storage_keys = 2 [(gogoproto.jsontag) = "storageKeys"];
|
||||
repeated string storage_keys = 2 [(gogoproto.jsontag) = "storageKeys"];
|
||||
}
|
@ -41,16 +41,6 @@ service Query {
|
||||
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.
|
||||
rpc BlockLogs(QueryBlockLogsRequest) returns (QueryBlockLogsResponse) {
|
||||
option (google.api.http).get = "/ethermint/evm/v1alpha1/block_logs/{hash}";
|
||||
@ -175,31 +165,6 @@ message QueryTxLogsResponse {
|
||||
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.
|
||||
message QueryBlockLogsRequest {
|
||||
option (gogoproto.equal) = false;
|
||||
@ -221,7 +186,7 @@ message QueryBlockLogsResponse {
|
||||
|
||||
// QueryBlockBloomRequest is the request type for the Query/BlockBloom RPC
|
||||
// method.
|
||||
message QueryBlockBloomRequest { }
|
||||
message QueryBlockBloomRequest {}
|
||||
|
||||
// QueryBlockBloomResponse is the response type for the Query/BlockBloom RPC
|
||||
// method.
|
||||
|
@ -42,34 +42,14 @@ message ExtensionOptionsWeb3Tx {
|
||||
message MsgEthereumTxResponse {
|
||||
option (gogoproto.goproto_getters) = false;
|
||||
|
||||
// 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.
|
||||
string contract_address = 1 [(gogoproto.moretags) = "yaml:\"contract_address\""];
|
||||
// bloom represents the bloom filter bytes
|
||||
bytes bloom = 2;
|
||||
// tx_logs contains the transaction hash and the proto-compatible ethereum
|
||||
// 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
|
||||
string hash = 1;
|
||||
// logs contains the transaction hash and the proto-compatible ethereum
|
||||
// logs.
|
||||
TransactionLogs tx_logs = 3 [(gogoproto.moretags) = "yaml:\"tx_logs\"", (gogoproto.nullable) = false];
|
||||
// ret defines the bytes from the execution.
|
||||
bytes ret = 4;
|
||||
repeated Log logs = 2;
|
||||
// returned data from evm function (result or data supplied with revert opcode)
|
||||
bytes ret = 3;
|
||||
// reverted flag is set to true when the call has been reverted
|
||||
bool reverted = 5;
|
||||
}
|
||||
|
||||
// // 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"];
|
||||
// }
|
||||
bool reverted = 4;
|
||||
}
|
@ -1,14 +1,12 @@
|
||||
package evm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
|
||||
log "github.com/xlab/suplog"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
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/types"
|
||||
@ -25,42 +23,7 @@ func NewHandler(k *keeper.Keeper) sdk.Handler {
|
||||
case *types.MsgEthereumTx:
|
||||
// execute state transition
|
||||
res, err := k.EthereumTx(sdk.WrapSDKContext(ctx), msg)
|
||||
if err != nil {
|
||||
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
|
||||
return sdk.WrapServiceResult(ctx, res, err)
|
||||
|
||||
default:
|
||||
err := sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", types.ModuleName, msg)
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"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/crypto"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/crypto/keyring"
|
||||
@ -98,7 +99,7 @@ func (suite *EvmTestSuite) TestHandleMsgEthereumTx() {
|
||||
"insufficient balance",
|
||||
func() {
|
||||
tx = types.NewMsgEthereumTxContract(suite.chainID, 0, big.NewInt(100), 0, big.NewInt(10000), nil, nil)
|
||||
|
||||
tx.From = suite.from.Hex()
|
||||
// sign transaction
|
||||
err := tx.Sign(suite.ethSigner, suite.signer)
|
||||
suite.Require().NoError(err)
|
||||
@ -184,48 +185,17 @@ func (suite *EvmTestSuite) TestHandlerLogs() {
|
||||
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)
|
||||
suite.Require().Equal(len(txResponse.Logs), 1)
|
||||
suite.Require().Equal(len(txResponse.Logs[0].Topics), 2)
|
||||
|
||||
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)
|
||||
|
||||
logs, err := suite.app.EvmKeeper.CommitStateDB.GetLogs(ethcmn.BytesToHash(hash))
|
||||
suite.Require().NoError(err, "failed to get logs")
|
||||
|
||||
suite.Require().Equal(logs, txResponse.TxLogs.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())
|
||||
suite.Require().Equal(logs, txResponse.Logs)
|
||||
}
|
||||
|
||||
func (suite *EvmTestSuite) TestDeployAndCallContract() {
|
||||
@ -303,7 +273,7 @@ func (suite *EvmTestSuite) TestDeployAndCallContract() {
|
||||
// store - changeOwner
|
||||
gasLimit = uint64(100000000000)
|
||||
gasPrice = big.NewInt(100)
|
||||
receiver := common.HexToAddress(txResponse.ContractAddress)
|
||||
receiver := crypto.CreateAddress(suite.from, 1)
|
||||
|
||||
storeAddr := "0xa6f9dae10000000000000000000000006a82e4a67715c8412a9114fbd2cbaefbc8181424"
|
||||
bytecode = common.FromHex(storeAddr)
|
||||
|
@ -203,44 +203,6 @@ func (k Keeper) TxLogs(c context.Context, req *types.QueryTxLogsRequest) (*types
|
||||
}, 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
|
||||
func (k Keeper) BlockLogs(c context.Context, req *types.QueryBlockLogsRequest) (*types.QueryBlockLogsResponse, error) {
|
||||
if req == nil {
|
||||
|
@ -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() {
|
||||
var (
|
||||
req *types.QueryBlockBloomRequest
|
||||
|
@ -144,20 +144,6 @@ func (k Keeper) SetBlockBloomTransient(bloom *big.Int) {
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -187,85 +173,6 @@ func (k Keeper) ResetRefundTransient(ctx sdk.Context) {
|
||||
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
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/armon/go-metrics"
|
||||
ethcmn "github.com/ethereum/go-ethereum/common"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
|
||||
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()
|
||||
ethHash := ethcmn.BytesToHash(txHash)
|
||||
|
||||
// Ethereum formatted tx hash
|
||||
etherumTxHash := msg.AsTransaction().Hash()
|
||||
|
||||
st := &types.StateTransition{
|
||||
Message: ethMsg,
|
||||
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 {
|
||||
// keep the execution result for revert reason
|
||||
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
|
||||
}
|
||||
|
||||
@ -108,33 +93,9 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
|
||||
bloom = big.NewInt(0)
|
||||
}
|
||||
// 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)
|
||||
|
||||
// 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() {
|
||||
@ -155,6 +116,7 @@ func (k *Keeper) EthereumTx(goCtx context.Context, msg *types.MsgEthereumTx) (*t
|
||||
attrs := []sdk.Attribute{
|
||||
sdk.NewAttribute(sdk.AttributeKeyAmount, st.Message.Value().String()),
|
||||
sdk.NewAttribute(types.AttributeKeyTxHash, ethcmn.BytesToHash(txHash).Hex()),
|
||||
sdk.NewAttribute(types.AttributeKeyEthereumTxHash, etherumTxHash.Hex()),
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -145,10 +145,8 @@ func (k *Keeper) TransitionDb(msg core.Message) (*types.ExecutionResult, error)
|
||||
|
||||
func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionResult, error) {
|
||||
var (
|
||||
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
|
||||
ret []byte // return bytes from evm execution
|
||||
vmErr, err error // vm errors do not effect consensus and are therefore not assigned to err
|
||||
)
|
||||
|
||||
sender := vm.AccountRef(msg.From())
|
||||
@ -174,8 +172,7 @@ func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionRe
|
||||
}
|
||||
|
||||
if contractCreation {
|
||||
ret, contract, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value())
|
||||
contractAddr = contract.Hex()
|
||||
ret, _, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value())
|
||||
} else {
|
||||
ret, leftoverGas, vmErr = evm.Call(sender, *msg.To(), msg.Data(), leftoverGas, msg.Value())
|
||||
}
|
||||
@ -198,8 +195,7 @@ func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message) (*types.ExecutionRe
|
||||
|
||||
return &types.ExecutionResult{
|
||||
Response: &types.MsgEthereumTxResponse{
|
||||
ContractAddress: contractAddr,
|
||||
Ret: ret,
|
||||
Ret: ret,
|
||||
},
|
||||
GasInfo: types.GasInfo{
|
||||
GasLimit: k.ctx.GasMeter().Limit(),
|
||||
|
@ -7,6 +7,7 @@ const (
|
||||
AttributeKeyContractAddress = "contract"
|
||||
AttributeKeyRecipient = "recipient"
|
||||
AttributeKeyTxHash = "txHash"
|
||||
AttributeKeyEthereumTxHash = "ethereumTxHash"
|
||||
AttributeValueCategory = ModuleName
|
||||
|
||||
MetricKeyTransitionDB = "transition_db"
|
||||
|
@ -20,14 +20,9 @@ func NewTransactionLogs(hash ethcmn.Hash, logs []*Log) TransactionLogs { // noli
|
||||
|
||||
// NewTransactionLogsFromEth creates a new NewTransactionLogs instance using []*ethtypes.Log.
|
||||
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{
|
||||
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.
|
||||
func LogsToEthereum(logs []*Log) []*ethtypes.Log {
|
||||
var ethLogs []*ethtypes.Log // nolint: prealloc
|
||||
|
@ -113,6 +113,7 @@ func (msg *MsgEthereumTx) FromEthereumTx(tx *ethtypes.Transaction) {
|
||||
}
|
||||
|
||||
msg.Size_ = float64(tx.Size())
|
||||
msg.Hash = tx.Hash().Hex()
|
||||
}
|
||||
|
||||
// Route returns the route value of an MsgEthereumTx.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 (
|
||||
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) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
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) {
|
||||
ctx, cancel := context.WithCancel(req.Context())
|
||||
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_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_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_TxReceipt_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_TxReceiptsByBlockHeight_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_BlockLogs_0 = runtime.ForwardResponseMessage
|
||||
|
||||
forward_Query_BlockBloom_0 = runtime.ForwardResponseMessage
|
||||
|
@ -242,12 +242,8 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re
|
||||
// Resets nonce to value pre state transition
|
||||
csdb.SetNonce(st.Message.From(), currentNonce)
|
||||
|
||||
// Generate bloom filter to be saved in tx receipt data
|
||||
bloomInt := big.NewInt(0)
|
||||
|
||||
var (
|
||||
bloomFilter ethtypes.Bloom
|
||||
logs []*ethtypes.Log
|
||||
logs []*ethtypes.Log
|
||||
)
|
||||
|
||||
if st.TxHash != nil && !st.Simulate {
|
||||
@ -256,9 +252,6 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re
|
||||
err = errors.Wrap(err, "failed to get logs")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bloomInt = big.NewInt(0).SetBytes(ethtypes.LogsBloom(logs))
|
||||
bloomFilter = ethtypes.BytesToBloom(bloomInt.Bytes())
|
||||
}
|
||||
|
||||
if !st.Simulate {
|
||||
@ -270,15 +263,9 @@ func (st *StateTransition) TransitionDb(ctx sdk.Context, config ChainConfig) (re
|
||||
}
|
||||
|
||||
resp.Logs = logs
|
||||
resp.Bloom = bloomInt
|
||||
resp.Response = &MsgEthereumTxResponse{
|
||||
Bloom: bloomFilter.Bytes(),
|
||||
TxLogs: NewTransactionLogsFromEth(*st.TxHash, logs),
|
||||
Ret: ret,
|
||||
}
|
||||
|
||||
if contractCreation {
|
||||
resp.Response.ContractAddress = contractAddress.String()
|
||||
Logs: NewLogsFromEth(logs),
|
||||
Ret: ret,
|
||||
}
|
||||
|
||||
// TODO: Refund unused gas here, if intended in future
|
||||
|
@ -150,19 +150,16 @@ var xxx_messageInfo_ExtensionOptionsWeb3Tx proto.InternalMessageInfo
|
||||
|
||||
// MsgEthereumTxResponse defines the Msg/EthereumTx response type.
|
||||
type MsgEthereumTxResponse struct {
|
||||
// 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.
|
||||
ContractAddress string `protobuf:"bytes,1,opt,name=contract_address,json=contractAddress,proto3" json:"contract_address,omitempty" yaml:"contract_address"`
|
||||
// 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
|
||||
// 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
|
||||
Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"`
|
||||
// logs contains the transaction hash and the proto-compatible ethereum
|
||||
// logs.
|
||||
TxLogs TransactionLogs `protobuf:"bytes,3,opt,name=tx_logs,json=txLogs,proto3" json:"tx_logs" yaml:"tx_logs"`
|
||||
// ret defines the bytes from the execution.
|
||||
Ret []byte `protobuf:"bytes,4,opt,name=ret,proto3" json:"ret,omitempty"`
|
||||
Logs []*Log `protobuf:"bytes,2,rep,name=logs,proto3" json:"logs,omitempty"`
|
||||
// returned data from evm function (result or data supplied with revert opcode)
|
||||
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 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{} }
|
||||
@ -208,37 +205,33 @@ func init() {
|
||||
func init() { proto.RegisterFile("ethermint/evm/v1alpha1/tx.proto", fileDescriptor_6a305e80b084ab0e) }
|
||||
|
||||
var fileDescriptor_6a305e80b084ab0e = []byte{
|
||||
// 476 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x3f, 0x6f, 0xd3, 0x40,
|
||||
0x18, 0xc6, 0x7d, 0x8d, 0xd3, 0x3f, 0x97, 0x02, 0xd5, 0xa9, 0x04, 0x63, 0x24, 0xdb, 0xb2, 0x84,
|
||||
0x9a, 0x25, 0xb6, 0x9a, 0x6e, 0xd9, 0x6a, 0x51, 0x26, 0x2a, 0xa4, 0x53, 0x25, 0x10, 0x4b, 0x75,
|
||||
0x76, 0x0e, 0xdb, 0x92, 0xed, 0xb3, 0xee, 0xae, 0x91, 0xcb, 0xca, 0xc2, 0xc8, 0xca, 0xc6, 0xc7,
|
||||
0xe9, 0xd8, 0x91, 0xc9, 0x42, 0xc9, 0xc6, 0x98, 0x4f, 0x80, 0x7c, 0x6e, 0x52, 0x1a, 0x11, 0xa9,
|
||||
0xdb, 0x7b, 0xef, 0xfb, 0xf3, 0xf9, 0x79, 0x9e, 0x7b, 0xa1, 0x4d, 0x65, 0x42, 0x79, 0x9e, 0x16,
|
||||
0xd2, 0xa7, 0xd3, 0xdc, 0x9f, 0x1e, 0x93, 0xac, 0x4c, 0xc8, 0xb1, 0x2f, 0x2b, 0xaf, 0xe4, 0x4c,
|
||||
0x32, 0xd4, 0x5f, 0x01, 0x1e, 0x9d, 0xe6, 0xde, 0x12, 0x30, 0x0f, 0x63, 0x16, 0x33, 0x85, 0xf8,
|
||||
0x4d, 0xd5, 0xd2, 0xa6, 0xb3, 0xe1, 0xba, 0xe6, 0x53, 0x45, 0xb8, 0x3f, 0x00, 0x7c, 0x72, 0x2e,
|
||||
0xe2, 0xb3, 0x86, 0xa3, 0x57, 0xf9, 0x45, 0x85, 0x46, 0x50, 0x9f, 0x10, 0x49, 0x0c, 0xe0, 0x80,
|
||||
0x41, 0x6f, 0x64, 0x79, 0xff, 0xff, 0xa1, 0x77, 0x51, 0xbd, 0x21, 0x92, 0x60, 0xc5, 0xa2, 0x97,
|
||||
0x50, 0x17, 0xe9, 0x17, 0x6a, 0x6c, 0x39, 0x60, 0x00, 0x82, 0xee, 0x9f, 0xda, 0x06, 0x43, 0xac,
|
||||
0x5a, 0xc8, 0x86, 0x7a, 0x42, 0x44, 0x62, 0x74, 0x1c, 0x30, 0xd8, 0x0b, 0x7a, 0x8b, 0xda, 0xde,
|
||||
0xe1, 0x59, 0x39, 0x76, 0x87, 0x2e, 0x56, 0x03, 0x84, 0xa0, 0xfe, 0x99, 0xb3, 0xdc, 0xd0, 0x1b,
|
||||
0x00, 0xab, 0x7a, 0xac, 0x7f, 0xfb, 0x69, 0x6b, 0xae, 0x0b, 0xcd, 0xb3, 0x4a, 0xd2, 0x42, 0xa4,
|
||||
0xac, 0x78, 0x5f, 0xca, 0x94, 0x15, 0xe2, 0x5e, 0xe7, 0x1d, 0x63, 0xc1, 0xfe, 0x3a, 0xf3, 0x81,
|
||||
0x86, 0x27, 0xab, 0xf9, 0xd7, 0x2d, 0xf8, 0xfc, 0x81, 0x3f, 0x4c, 0x45, 0xc9, 0x0a, 0x41, 0xd1,
|
||||
0x5b, 0x78, 0x10, 0xb1, 0x42, 0x72, 0x12, 0xc9, 0x4b, 0x32, 0x99, 0x70, 0x2a, 0x84, 0xf2, 0xbc,
|
||||
0x17, 0xbc, 0x5a, 0xd4, 0xf6, 0x8b, 0x6b, 0x92, 0x67, 0x63, 0x77, 0x9d, 0x70, 0xf1, 0xb3, 0x65,
|
||||
0xeb, 0xb4, 0xed, 0xa0, 0x43, 0xd8, 0x0d, 0x33, 0xc6, 0x72, 0x65, 0x7e, 0x1f, 0xb7, 0x07, 0xf4,
|
||||
0x11, 0xee, 0xc8, 0xea, 0x32, 0x63, 0xb1, 0x50, 0xce, 0x7b, 0xa3, 0xa3, 0x8d, 0x41, 0x72, 0x52,
|
||||
0x08, 0x12, 0x35, 0xd2, 0xdf, 0xb1, 0x58, 0x04, 0xfd, 0x9b, 0xda, 0xd6, 0x16, 0xb5, 0xfd, 0xb4,
|
||||
0x55, 0x70, 0x77, 0x8b, 0x8b, 0xb7, 0x65, 0xd5, 0xcc, 0xd1, 0x01, 0xec, 0x70, 0x2a, 0x55, 0x5c,
|
||||
0xfb, 0xb8, 0x29, 0x91, 0x09, 0x77, 0x39, 0x9d, 0x52, 0x2e, 0xe9, 0xc4, 0xe8, 0x3a, 0x60, 0xb0,
|
||||
0x8b, 0x57, 0xe7, 0x36, 0x85, 0x51, 0x0a, 0x3b, 0xe7, 0x22, 0x46, 0x21, 0x84, 0xff, 0x3c, 0xf4,
|
||||
0xeb, 0x4d, 0x8a, 0x1e, 0xe4, 0x65, 0x0e, 0x1f, 0x85, 0x2d, 0x63, 0x0d, 0x4e, 0x6f, 0x66, 0x16,
|
||||
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,
|
||||
// 404 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x92, 0x31, 0x6b, 0xdb, 0x40,
|
||||
0x1c, 0xc5, 0x75, 0x96, 0xda, 0xba, 0xe7, 0x16, 0xca, 0xd1, 0x1a, 0x55, 0x85, 0x93, 0x10, 0x94,
|
||||
0x6a, 0xb1, 0x84, 0xe5, 0xcd, 0x5b, 0x4d, 0xbd, 0xd5, 0x14, 0x0e, 0x43, 0xa1, 0x9b, 0x64, 0x5f,
|
||||
0x25, 0x81, 0xa5, 0x13, 0xba, 0xb3, 0x50, 0xf2, 0x09, 0x32, 0x7a, 0xcd, 0x96, 0x8f, 0x93, 0xd1,
|
||||
0x63, 0x26, 0x13, 0xec, 0x2d, 0x63, 0x3e, 0x41, 0xd0, 0x39, 0xb6, 0xe3, 0x10, 0x43, 0xb6, 0xbf,
|
||||
0xf4, 0xff, 0xdd, 0xbd, 0xf7, 0x8e, 0x07, 0x4d, 0x2a, 0x62, 0x5a, 0xa4, 0x49, 0x26, 0x3c, 0x5a,
|
||||
0xa6, 0x5e, 0xd9, 0x0d, 0x66, 0x79, 0x1c, 0x74, 0x3d, 0x51, 0xb9, 0x79, 0xc1, 0x04, 0x43, 0xed,
|
||||
0x3d, 0xe0, 0xd2, 0x32, 0x75, 0x77, 0x80, 0xf1, 0x39, 0x62, 0x11, 0x93, 0x88, 0x57, 0x4f, 0x5b,
|
||||
0xda, 0xb0, 0x4e, 0x5c, 0x57, 0x1f, 0x95, 0x84, 0x7d, 0x09, 0xe0, 0xc7, 0x11, 0x8f, 0x86, 0x35,
|
||||
0x47, 0xe7, 0xe9, 0xb8, 0x42, 0x3e, 0xd4, 0xa6, 0x81, 0x08, 0x74, 0x60, 0x01, 0xa7, 0xe5, 0x63,
|
||||
0xf7, 0x65, 0x41, 0x77, 0x5c, 0xfd, 0x0a, 0x44, 0x40, 0x24, 0x8b, 0xbe, 0x42, 0x8d, 0x27, 0xe7,
|
||||
0x54, 0x6f, 0x58, 0xc0, 0x01, 0x83, 0x37, 0x77, 0x2b, 0x13, 0x74, 0x88, 0xfc, 0x85, 0x4c, 0xa8,
|
||||
0xc5, 0x01, 0x8f, 0x75, 0xd5, 0x02, 0xce, 0xfb, 0x41, 0xeb, 0x7e, 0x65, 0xbe, 0x2b, 0x66, 0x79,
|
||||
0xdf, 0xee, 0xd8, 0x44, 0x2e, 0x10, 0x82, 0xda, 0xff, 0x82, 0xa5, 0xba, 0x56, 0x03, 0x44, 0xce,
|
||||
0x7d, 0xed, 0xe2, 0xca, 0x54, 0x6c, 0x1b, 0x1a, 0xc3, 0x4a, 0xd0, 0x8c, 0x27, 0x2c, 0xfb, 0x93,
|
||||
0x8b, 0x84, 0x65, 0xfc, 0xe0, 0xf3, 0x91, 0xc1, 0xb0, 0xfd, 0x9c, 0xf9, 0x4b, 0xc3, 0xde, 0x7e,
|
||||
0xbf, 0x00, 0xf0, 0xcb, 0x51, 0x3e, 0x42, 0x79, 0xce, 0x32, 0x4e, 0x6b, 0x5d, 0x69, 0x0c, 0x6c,
|
||||
0x75, 0xa5, 0x17, 0x0f, 0x6a, 0x33, 0x16, 0x71, 0xbd, 0x61, 0xa9, 0x4e, 0xcb, 0xff, 0x76, 0x2a,
|
||||
0xfb, 0x6f, 0x16, 0x11, 0x09, 0xa2, 0x4f, 0x50, 0x2d, 0xa8, 0x90, 0xe1, 0x3e, 0x90, 0x7a, 0x44,
|
||||
0x06, 0x6c, 0x16, 0xb4, 0xa4, 0x85, 0xa0, 0x53, 0x19, 0xa9, 0x49, 0xf6, 0xdf, 0x5b, 0x4b, 0x7e,
|
||||
0x02, 0xd5, 0x11, 0x8f, 0x50, 0x08, 0xe1, 0x93, 0x57, 0xff, 0x7e, 0x4a, 0xeb, 0xc8, 0xbc, 0xd1,
|
||||
0x79, 0x15, 0xb6, 0xcb, 0x38, 0xf8, 0x79, 0xbd, 0xc6, 0x60, 0xb9, 0xc6, 0xe0, 0x76, 0x8d, 0xc1,
|
||||
0x62, 0x83, 0x95, 0xe5, 0x06, 0x2b, 0x37, 0x1b, 0xac, 0xfc, 0xfb, 0x11, 0x25, 0x22, 0x9e, 0x87,
|
||||
0xee, 0x84, 0xa5, 0xde, 0x84, 0xf1, 0x94, 0x71, 0xef, 0xd0, 0x95, 0x4a, 0xb6, 0x45, 0x9c, 0xe5,
|
||||
0x94, 0x87, 0x6f, 0x65, 0x4f, 0x7a, 0x0f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x9c, 0x61, 0x2c, 0xf2,
|
||||
0x9a, 0x02, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@ -452,36 +445,33 @@ func (m *MsgEthereumTxResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
dAtA[i] = 0
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x28
|
||||
dAtA[i] = 0x20
|
||||
}
|
||||
if len(m.Ret) > 0 {
|
||||
i -= len(m.Ret)
|
||||
copy(dAtA[i:], m.Ret)
|
||||
i = encodeVarintTx(dAtA, i, uint64(len(m.Ret)))
|
||||
i--
|
||||
dAtA[i] = 0x22
|
||||
dAtA[i] = 0x1a
|
||||
}
|
||||
{
|
||||
size, err := m.TxLogs.MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
if len(m.Logs) > 0 {
|
||||
for iNdEx := len(m.Logs) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
size, err := m.Logs[iNdEx].MarshalToSizedBuffer(dAtA[:i])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintTx(dAtA, i, uint64(size))
|
||||
}
|
||||
i--
|
||||
dAtA[i] = 0x12
|
||||
}
|
||||
i -= size
|
||||
i = encodeVarintTx(dAtA, i, uint64(size))
|
||||
}
|
||||
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
|
||||
}
|
||||
if len(m.ContractAddress) > 0 {
|
||||
i -= len(m.ContractAddress)
|
||||
copy(dAtA[i:], m.ContractAddress)
|
||||
i = encodeVarintTx(dAtA, i, uint64(len(m.ContractAddress)))
|
||||
if len(m.Hash) > 0 {
|
||||
i -= len(m.Hash)
|
||||
copy(dAtA[i:], m.Hash)
|
||||
i = encodeVarintTx(dAtA, i, uint64(len(m.Hash)))
|
||||
i--
|
||||
dAtA[i] = 0xa
|
||||
}
|
||||
@ -547,16 +537,16 @@ func (m *MsgEthereumTxResponse) Size() (n int) {
|
||||
}
|
||||
var l int
|
||||
_ = l
|
||||
l = len(m.ContractAddress)
|
||||
l = len(m.Hash)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
}
|
||||
l = len(m.Bloom)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
if len(m.Logs) > 0 {
|
||||
for _, e := range m.Logs {
|
||||
l = e.Size()
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
}
|
||||
}
|
||||
l = m.TxLogs.Size()
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
l = len(m.Ret)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
@ -874,7 +864,7 @@ func (m *MsgEthereumTxResponse) Unmarshal(dAtA []byte) error {
|
||||
switch fieldNum {
|
||||
case 1:
|
||||
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
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
@ -902,45 +892,11 @@ func (m *MsgEthereumTxResponse) Unmarshal(dAtA []byte) error {
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.ContractAddress = string(dAtA[iNdEx:postIndex])
|
||||
m.Hash = string(dAtA[iNdEx:postIndex])
|
||||
iNdEx = postIndex
|
||||
case 2:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Bloom", 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)
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Logs", wireType)
|
||||
}
|
||||
var msglen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
@ -967,11 +923,12 @@ func (m *MsgEthereumTxResponse) Unmarshal(dAtA []byte) error {
|
||||
if postIndex > l {
|
||||
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
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 4:
|
||||
case 3:
|
||||
if wireType != 2 {
|
||||
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{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
case 4:
|
||||
if wireType != 0 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field Reverted", wireType)
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
ethcmn "github.com/ethereum/go-ethereum/common"
|
||||
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||
ethcrypto "github.com/ethereum/go-ethereum/crypto"
|
||||
)
|
||||
|
||||
@ -23,20 +22,13 @@ func GenerateEthAddress() ethcmn.Address {
|
||||
}
|
||||
|
||||
func TestEvmDataEncoding(t *testing.T) {
|
||||
addr := "0x5dE8a020088a2D6d0a23c204FFbeD02790466B49"
|
||||
bloom := ethtypes.BytesToBloom([]byte{0x1, 0x3})
|
||||
ret := []byte{0x5, 0x8}
|
||||
|
||||
data := &MsgEthereumTxResponse{
|
||||
ContractAddress: addr,
|
||||
Bloom: bloom.Bytes(),
|
||||
TxLogs: TransactionLogs{
|
||||
Hash: ethcmn.BytesToHash([]byte{1, 2, 3, 4}).String(),
|
||||
Logs: []*Log{{
|
||||
Data: []byte{1, 2, 3, 4},
|
||||
BlockNumber: 17,
|
||||
}},
|
||||
},
|
||||
Logs: []*Log{{
|
||||
Data: []byte{1, 2, 3, 4},
|
||||
BlockNumber: 17,
|
||||
}},
|
||||
Ret: ret,
|
||||
}
|
||||
|
||||
@ -46,8 +38,6 @@ func TestEvmDataEncoding(t *testing.T) {
|
||||
res, err := DecodeTxResponse(enc)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, res)
|
||||
require.Equal(t, addr, res.ContractAddress)
|
||||
require.Equal(t, bloom.Bytes(), res.Bloom)
|
||||
require.Equal(t, data.TxLogs, res.TxLogs)
|
||||
require.Equal(t, data.Logs, res.Logs)
|
||||
require.Equal(t, ret, res.Ret)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user