rpc: debug_traceTransaction fails for succesful tx (#720)

* Problem: traceTransaction fails for succesful tx

Solution:
- Change the context to the begining of the block, rather than the end
  of it, while override block context to correct one

pass predecessors

pass current block information to grpc query

* changelog

* fix build

* fix lint

* refactor traceBlock

* update protobuf

* fix Predecessors

* traceBlock refactor

* refactor traceBlock response

* Update proto/ethermint/evm/v1/tx.proto

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* Update proto/ethermint/evm/v1/query.proto

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* Update proto/ethermint/evm/v1/query.proto

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* Update proto/ethermint/evm/v1/query.proto

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* Update proto/ethermint/evm/v1/query.proto

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* Update proto/ethermint/evm/v1/query.proto

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* check tx index is not out of bound

* fix build

* Update rpc/ethereum/namespaces/debug/api.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* Update rpc/ethereum/namespaces/debug/api.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* Update rpc/ethereum/namespaces/debug/api.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* Update rpc/ethereum/namespaces/debug/api.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* remove prealloc

* add traceBlock test

* Update x/evm/keeper/grpc_query.go

Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>

* use bytes2Hex

* fix error message

* add comment

* Apply suggestions from code review

Co-authored-by: Freddy Caceres <freddy.caceres@crypto.com>
Co-authored-by: crypto-facs <84574577+crypto-facs@users.noreply.github.com>
Co-authored-by: Federico Kunze Küllmer <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
yihuang 2021-11-10 02:38:22 +08:00 committed by GitHub
parent 7c7f3f02bb
commit 2a205e561a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 3314 additions and 347 deletions

View File

@ -57,6 +57,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* (evm) [tharsis#660](https://github.com/tharsis/ethermint/pull/660) Fix `nil` pointer panic in `ApplyNativeMessage`. * (evm) [tharsis#660](https://github.com/tharsis/ethermint/pull/660) Fix `nil` pointer panic in `ApplyNativeMessage`.
* (evm, test) [tharsis#649](https://github.com/tharsis/ethermint/pull/649) Test DynamicFeeTx. * (evm, test) [tharsis#649](https://github.com/tharsis/ethermint/pull/649) Test DynamicFeeTx.
* (evm) [tharsis#702](https://github.com/tharsis/ethermint/pull/702) Fix panic in web3 RPC handlers * (evm) [tharsis#702](https://github.com/tharsis/ethermint/pull/702) Fix panic in web3 RPC handlers
* (rpc) [tharsis#720](https://github.com/tharsis/ethermint/pull/720) Fix `debug_traceTransaction` failure
### Improvements ### Improvements

File diff suppressed because it is too large Load Diff

View File

@ -47,6 +47,8 @@
- [QueryParamsResponse](#ethermint.evm.v1.QueryParamsResponse) - [QueryParamsResponse](#ethermint.evm.v1.QueryParamsResponse)
- [QueryStorageRequest](#ethermint.evm.v1.QueryStorageRequest) - [QueryStorageRequest](#ethermint.evm.v1.QueryStorageRequest)
- [QueryStorageResponse](#ethermint.evm.v1.QueryStorageResponse) - [QueryStorageResponse](#ethermint.evm.v1.QueryStorageResponse)
- [QueryTraceBlockRequest](#ethermint.evm.v1.QueryTraceBlockRequest)
- [QueryTraceBlockResponse](#ethermint.evm.v1.QueryTraceBlockResponse)
- [QueryTraceTxRequest](#ethermint.evm.v1.QueryTraceTxRequest) - [QueryTraceTxRequest](#ethermint.evm.v1.QueryTraceTxRequest)
- [QueryTraceTxResponse](#ethermint.evm.v1.QueryTraceTxResponse) - [QueryTraceTxResponse](#ethermint.evm.v1.QueryTraceTxResponse)
- [QueryTxLogsRequest](#ethermint.evm.v1.QueryTxLogsRequest) - [QueryTxLogsRequest](#ethermint.evm.v1.QueryTxLogsRequest)
@ -508,7 +510,7 @@ Msg defines the evm Msg service.
| Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint | | Method Name | Request Type | Response Type | Description | HTTP Verb | Endpoint |
| ----------- | ------------ | ------------- | ------------| ------- | -------- | | ----------- | ------------ | ------------- | ------------| ------- | -------- |
| `EthereumTx` | [MsgEthereumTx](#ethermint.evm.v1.MsgEthereumTx) | [MsgEthereumTxResponse](#ethermint.evm.v1.MsgEthereumTxResponse) | EthereumTx defines a method submitting Ethereum transactions. | | | `EthereumTx` | [MsgEthereumTx](#ethermint.evm.v1.MsgEthereumTx) | [MsgEthereumTxResponse](#ethermint.evm.v1.MsgEthereumTxResponse) | EthereumTx defines a method submitting Ethereum transactions. | POST|/ethermint/evm/v1/ethereum_tx|
<!-- end services --> <!-- end services -->
@ -736,6 +738,40 @@ method.
<a name="ethermint.evm.v1.QueryTraceBlockRequest"></a>
### QueryTraceBlockRequest
QueryTraceBlockRequest defines TraceTx request
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `txs` | [MsgEthereumTx](#ethermint.evm.v1.MsgEthereumTx) | repeated | txs messages in the block |
| `trace_config` | [TraceConfig](#ethermint.evm.v1.TraceConfig) | | TraceConfig holds extra parameters to trace functions. |
| `block_number` | [int64](#int64) | | block number |
| `block_hash` | [string](#string) | | block hex hash |
| `block_time` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | block time |
<a name="ethermint.evm.v1.QueryTraceBlockResponse"></a>
### QueryTraceBlockResponse
QueryTraceBlockResponse defines TraceBlock response
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `data` | [bytes](#bytes) | | |
<a name="ethermint.evm.v1.QueryTraceTxRequest"></a> <a name="ethermint.evm.v1.QueryTraceTxRequest"></a>
### QueryTraceTxRequest ### QueryTraceTxRequest
@ -747,6 +783,10 @@ QueryTraceTxRequest defines TraceTx request
| `msg` | [MsgEthereumTx](#ethermint.evm.v1.MsgEthereumTx) | | msgEthereumTx for the requested transaction | | `msg` | [MsgEthereumTx](#ethermint.evm.v1.MsgEthereumTx) | | msgEthereumTx for the requested transaction |
| `tx_index` | [uint64](#uint64) | | transaction index | | `tx_index` | [uint64](#uint64) | | transaction index |
| `trace_config` | [TraceConfig](#ethermint.evm.v1.TraceConfig) | | TraceConfig holds extra parameters to trace functions. | | `trace_config` | [TraceConfig](#ethermint.evm.v1.TraceConfig) | | TraceConfig holds extra parameters to trace functions. |
| `predecessors` | [MsgEthereumTx](#ethermint.evm.v1.MsgEthereumTx) | repeated | the predecessor transactions included in the same block need to be replayed first to get correct context for tracing. |
| `block_number` | [int64](#int64) | | block number of requested transaction |
| `block_hash` | [string](#string) | | block hex hash of requested transaction |
| `block_time` | [google.protobuf.Timestamp](#google.protobuf.Timestamp) | | block time of requested transaction |
@ -857,6 +897,7 @@ Query defines the gRPC querier service.
| `EthCall` | [EthCallRequest](#ethermint.evm.v1.EthCallRequest) | [MsgEthereumTxResponse](#ethermint.evm.v1.MsgEthereumTxResponse) | EthCall implements the `eth_call` rpc api | GET|/ethermint/evm/v1/eth_call| | `EthCall` | [EthCallRequest](#ethermint.evm.v1.EthCallRequest) | [MsgEthereumTxResponse](#ethermint.evm.v1.MsgEthereumTxResponse) | EthCall implements the `eth_call` rpc api | GET|/ethermint/evm/v1/eth_call|
| `EstimateGas` | [EthCallRequest](#ethermint.evm.v1.EthCallRequest) | [EstimateGasResponse](#ethermint.evm.v1.EstimateGasResponse) | EstimateGas implements the `eth_estimateGas` rpc api | GET|/ethermint/evm/v1/estimate_gas| | `EstimateGas` | [EthCallRequest](#ethermint.evm.v1.EthCallRequest) | [EstimateGasResponse](#ethermint.evm.v1.EstimateGasResponse) | EstimateGas implements the `eth_estimateGas` rpc api | GET|/ethermint/evm/v1/estimate_gas|
| `TraceTx` | [QueryTraceTxRequest](#ethermint.evm.v1.QueryTraceTxRequest) | [QueryTraceTxResponse](#ethermint.evm.v1.QueryTraceTxResponse) | TraceTx implements the `debug_traceTransaction` rpc api | GET|/ethermint/evm/v1/trace_tx| | `TraceTx` | [QueryTraceTxRequest](#ethermint.evm.v1.QueryTraceTxRequest) | [QueryTraceTxResponse](#ethermint.evm.v1.QueryTraceTxResponse) | TraceTx implements the `debug_traceTransaction` rpc api | GET|/ethermint/evm/v1/trace_tx|
| `TraceBlock` | [QueryTraceBlockRequest](#ethermint.evm.v1.QueryTraceBlockRequest) | [QueryTraceBlockResponse](#ethermint.evm.v1.QueryTraceBlockResponse) | TraceBlock implements the `debug_traceBlockByNumber` and `debug_traceBlockByHash` rpc api | GET|/ethermint/evm/v1/trace_block|
<!-- end services --> <!-- end services -->

9
go.mod
View File

@ -8,6 +8,7 @@ require (
github.com/cosmos/cosmos-sdk v0.44.3 github.com/cosmos/cosmos-sdk v0.44.3
github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/go-bip39 v1.0.0
github.com/cosmos/ibc-go/v2 v2.0.0-rc0 github.com/cosmos/ibc-go/v2 v2.0.0-rc0
github.com/davecgh/go-spew v1.1.1
github.com/ethereum/go-ethereum v1.10.11 github.com/ethereum/go-ethereum v1.10.11
github.com/gogo/protobuf v1.3.3 github.com/gogo/protobuf v1.3.3
github.com/golang/protobuf v1.5.2 github.com/golang/protobuf v1.5.2
@ -34,14 +35,13 @@ require (
github.com/tendermint/tm-db v0.6.4 github.com/tendermint/tm-db v0.6.4
github.com/tyler-smith/go-bip39 v1.1.0 github.com/tyler-smith/go-bip39 v1.1.0
go.etcd.io/bbolt v1.3.6 // indirect go.etcd.io/bbolt v1.3.6 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa // indirect
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247
google.golang.org/grpc v1.41.0 google.golang.org/grpc v1.41.0
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
require github.com/davecgh/go-spew v1.1.1
require ( require (
filippo.io/edwards25519 v1.0.0-beta.2 // indirect filippo.io/edwards25519 v1.0.0-beta.2 // indirect
github.com/99designs/keyring v1.1.6 // indirect github.com/99designs/keyring v1.1.6 // indirect
@ -138,7 +138,6 @@ require (
golang.org/x/sys v0.0.0-20211025112917-711f33c9992c // indirect golang.org/x/sys v0.0.0-20211025112917-711f33c9992c // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
golang.org/x/text v0.3.7 // indirect golang.org/x/text v0.3.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/ini.v1 v1.63.2 // indirect gopkg.in/ini.v1 v1.63.2 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6 // indirect

8
go.sum
View File

@ -1293,8 +1293,8 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa h1:idItI2DDfCokpg0N51B2VtiLdJ4vAuXC9fnCb2gACo4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1759,8 +1759,8 @@ google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKr
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c h1:FqrtZMB5Wr+/RecOM3uPJNPfWR8Upb5hAPnt7PU6i4k= google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247 h1:ZONpjmFT5e+I/0/xE3XXbG5OIvX2hRYzol04MhKBl2E=
google.golang.org/genproto v0.0.0-20211021150943-2b146023228c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211104193956-4c6863e31247/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o= google.golang.org/grpc v1.33.2 h1:EQyQC3sa8M+p6Ulc8yy9SWSS2GVwyRc83gAbG8lrl4o=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=

View File

@ -6,6 +6,7 @@ import "cosmos/base/query/v1beta1/pagination.proto";
import "google/api/annotations.proto"; import "google/api/annotations.proto";
import "ethermint/evm/v1/evm.proto"; import "ethermint/evm/v1/evm.proto";
import "ethermint/evm/v1/tx.proto"; import "ethermint/evm/v1/tx.proto";
import "google/protobuf/timestamp.proto";
option go_package = "github.com/tharsis/ethermint/x/evm/types"; option go_package = "github.com/tharsis/ethermint/x/evm/types";
@ -65,6 +66,11 @@ service Query {
rpc TraceTx(QueryTraceTxRequest) returns (QueryTraceTxResponse) { rpc TraceTx(QueryTraceTxRequest) returns (QueryTraceTxResponse) {
option (google.api.http).get = "/ethermint/evm/v1/trace_tx"; option (google.api.http).get = "/ethermint/evm/v1/trace_tx";
} }
// TraceBlock implements the `debug_traceBlockByNumber` and `debug_traceBlockByHash` rpc api
rpc TraceBlock(QueryTraceBlockRequest) returns (QueryTraceBlockResponse) {
option (google.api.http).get = "/ethermint/evm/v1/trace_block";
}
} }
// QueryAccountRequest is the request type for the Query/Account RPC method. // QueryAccountRequest is the request type for the Query/Account RPC method.
@ -228,6 +234,15 @@ message QueryTraceTxRequest {
uint64 tx_index = 2; uint64 tx_index = 2;
// TraceConfig holds extra parameters to trace functions. // TraceConfig holds extra parameters to trace functions.
TraceConfig trace_config = 3; TraceConfig trace_config = 3;
// the predecessor transactions included in the same block
// need to be replayed first to get correct context for tracing.
repeated MsgEthereumTx predecessors = 4;
// block number of requested transaction
int64 block_number = 5;
// block hex hash of requested transaction
string block_hash = 6;
// block time of requested transaction
google.protobuf.Timestamp block_time = 7 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
} }
// QueryTraceTxResponse defines TraceTx response // QueryTraceTxResponse defines TraceTx response
@ -235,3 +250,23 @@ message QueryTraceTxResponse {
// response serialized in bytes // response serialized in bytes
bytes data = 1; bytes data = 1;
} }
// QueryTraceBlockRequest defines TraceTx request
message QueryTraceBlockRequest {
// txs messages in the block
repeated MsgEthereumTx txs = 1;
// TraceConfig holds extra parameters to trace functions.
TraceConfig trace_config = 3;
// block number
int64 block_number = 5;
// block hex hash
string block_hash = 6;
// block time
google.protobuf.Timestamp block_time = 7 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
// QueryTraceBlockResponse defines TraceBlock response
message QueryTraceBlockResponse {
bytes data = 1;
}

View File

@ -13,7 +13,7 @@ option go_package = "github.com/tharsis/ethermint/x/evm/types";
service Msg { service Msg {
// EthereumTx defines a method submitting Ethereum transactions. // EthereumTx defines a method submitting Ethereum transactions.
rpc EthereumTx(MsgEthereumTx) returns (MsgEthereumTxResponse) { rpc EthereumTx(MsgEthereumTx) returns (MsgEthereumTxResponse) {
option (google.api.http).get = "/ethermint/evm/v1/ethereum_tx"; option (google.api.http).post = "/ethermint/evm/v1/ethereum_tx";
}; };
} }

View File

@ -14,7 +14,7 @@ import (
"time" "time"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"github.com/tendermint/tendermint/types" tmrpctypes "github.com/tendermint/tendermint/rpc/core/types"
evmtypes "github.com/tharsis/ethermint/x/evm/types" evmtypes "github.com/tharsis/ethermint/x/evm/types"
@ -81,6 +81,35 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (
return nil, errors.New("genesis is not traceable") return nil, errors.New("genesis is not traceable")
} }
blk, err := a.backend.GetTendermintBlockByNumber(rpctypes.BlockNumber(transaction.Height))
if err != nil {
a.logger.Debug("block not found", "height", transaction.Height)
return nil, err
}
// check tx index is not out of bound
if uint32(len(blk.Block.Txs)) < transaction.Index {
a.logger.Debug("tx index out of bounds", "index", transaction.Index, "hash", hash.String(), "height", blk.Block.Height)
return nil, fmt.Errorf("transaction not included in block %v", blk.Block.Height)
}
// nolint: prealloc
var predecessors []*evmtypes.MsgEthereumTx
for _, txBz := range blk.Block.Txs[:transaction.Index] {
tx, err := a.clientCtx.TxConfig.TxDecoder()(txBz)
if err != nil {
a.logger.Debug("failed to decode transaction in block", "height", blk.Block.Height, "error", err.Error())
continue
}
msg := tx.GetMsgs()[0]
ethMsg, ok := msg.(*evmtypes.MsgEthereumTx)
if !ok {
continue
}
predecessors = append(predecessors, ethMsg)
}
tx, err := a.clientCtx.TxConfig.TxDecoder()(transaction.Tx) tx, err := a.clientCtx.TxConfig.TxDecoder()(transaction.Tx)
if err != nil { if err != nil {
a.logger.Debug("tx not found", "hash", hash) a.logger.Debug("tx not found", "hash", hash)
@ -96,13 +125,23 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (
traceTxRequest := evmtypes.QueryTraceTxRequest{ traceTxRequest := evmtypes.QueryTraceTxRequest{
Msg: ethMessage, Msg: ethMessage,
TxIndex: uint64(transaction.Index), TxIndex: uint64(transaction.Index),
Predecessors: predecessors,
BlockNumber: blk.Block.Height,
BlockTime: blk.Block.Time,
BlockHash: common.Bytes2Hex(blk.BlockID.Hash),
} }
if config != nil { if config != nil {
traceTxRequest.TraceConfig = config traceTxRequest.TraceConfig = config
} }
traceResult, err := a.queryClient.TraceTx(rpctypes.ContextWithHeight(transaction.Height), &traceTxRequest) // minus one to get the context of block beginning
contextHeight := transaction.Height - 1
if contextHeight < 1 {
// 0 is a special value in `ContextWithHeight`
contextHeight = 1
}
traceResult, err := a.queryClient.TraceTx(rpctypes.ContextWithHeight(contextHeight), &traceTxRequest)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -131,13 +170,14 @@ func (a *API) TraceBlockByNumber(height rpctypes.BlockNumber, config *evmtypes.T
return nil, err return nil, err
} }
return a.traceBlock(height, config, resBlock.Block.Txs) return a.traceBlock(height, config, resBlock)
} }
// traceBlock configures a new tracer according to the provided configuration, and // traceBlock configures a new tracer according to the provided configuration, and
// executes all the transactions contained within. The return value will be one item // executes all the transactions contained within. The return value will be one item
// per transaction, dependent on the requested tracer. // per transaction, dependent on the requested tracer.
func (a API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConfig, txs types.Txs) ([]*evmtypes.TxTraceResult, error) { func (a *API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConfig, block *tmrpctypes.ResultBlock) ([]*evmtypes.TxTraceResult, error) {
txs := block.Block.Txs
txsLength := len(txs) txsLength := len(txs)
if txsLength == 0 { if txsLength == 0 {
@ -145,33 +185,18 @@ func (a API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConfi
return []*evmtypes.TxTraceResult{}, nil return []*evmtypes.TxTraceResult{}, nil
} }
var (
results = make([]*evmtypes.TxTraceResult, txsLength)
wg = new(sync.WaitGroup)
jobs = make(chan *evmtypes.TxTraceTask, txsLength)
)
threads := runtime.NumCPU()
if threads > txsLength {
threads = txsLength
}
ctxWithHeight := rpctypes.ContextWithHeight(int64(height))
wg.Add(threads)
for th := 0; th < threads; th++ {
go func() {
defer wg.Done()
txDecoder := a.clientCtx.TxConfig.TxDecoder() txDecoder := a.clientCtx.TxConfig.TxDecoder()
// Fetch and execute the next transaction trace tasks
for task := range jobs { // nolint: prealloc
tx, err := txDecoder(txs[task.Index]) var txsMessages []*evmtypes.MsgEthereumTx
for i, tx := range txs {
decodedTx, err := txDecoder(tx)
if err != nil { if err != nil {
a.logger.Error("failed to decode transaction", "hash", txs[task.Index].Hash(), "error", err.Error()) a.logger.Error("failed to decode transaction", "hash", txs[i].Hash(), "error", err.Error())
continue continue
} }
messages := tx.GetMsgs() messages := decodedTx.GetMsgs()
if len(messages) == 0 { if len(messages) == 0 {
continue continue
} }
@ -180,38 +205,36 @@ func (a API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConfi
// Just considers Ethereum transactions // Just considers Ethereum transactions
continue continue
} }
txsMessages = append(txsMessages, ethMessage)
}
traceTxRequest := &evmtypes.QueryTraceTxRequest{ // minus one to get the context at the beginning of the block
Msg: ethMessage, contextHeight := height - 1
TxIndex: uint64(task.Index), if contextHeight < 1 {
// 0 is a special value for `ContextWithHeight`.
contextHeight = 1
}
ctxWithHeight := rpctypes.ContextWithHeight(int64(contextHeight))
traceBlockRequest := &evmtypes.QueryTraceBlockRequest{
Txs: txsMessages,
TraceConfig: config, TraceConfig: config,
BlockNumber: block.Block.Height,
BlockTime: block.Block.Time,
BlockHash: common.Bytes2Hex(block.BlockID.Hash),
} }
res, err := a.queryClient.TraceTx(ctxWithHeight, traceTxRequest) res, err := a.queryClient.TraceBlock(ctxWithHeight, traceBlockRequest)
if err != nil { if err != nil {
results[task.Index] = &evmtypes.TxTraceResult{Error: err.Error()} return nil, err
continue
}
// Response format is unknown due to custom tracer config param
// More information can be found here https://geth.ethereum.org/docs/dapp/tracing-filtered
var decodedResult interface{}
if err := json.Unmarshal(res.Data, &decodedResult); err != nil {
results[task.Index] = &evmtypes.TxTraceResult{Error: err.Error()}
continue
}
results[task.Index] = &evmtypes.TxTraceResult{Result: decodedResult}
}
}()
} }
for i := range txs { decodedResults := make([]*evmtypes.TxTraceResult, txsLength)
jobs <- &evmtypes.TxTraceTask{Index: i} if err := json.Unmarshal(res.Data, &decodedResults); err != nil {
return nil, err
} }
close(jobs) return decodedResults, nil
wg.Wait()
return results, nil
} }
// BlockProfile turns on goroutine profiling for nsec seconds and writes profile data to // BlockProfile turns on goroutine profiling for nsec seconds and writes profile data to

View File

@ -360,16 +360,34 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
} }
ctx := sdk.UnwrapSDKContext(c) ctx := sdk.UnwrapSDKContext(c)
ctx = ctx.WithBlockHeight(req.BlockNumber)
ctx = ctx.WithBlockTime(req.BlockTime)
ctx = ctx.WithHeaderHash(common.Hex2Bytes(req.BlockHash))
k.WithContext(ctx) k.WithContext(ctx)
params := k.GetParams(ctx) params := k.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID) ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight())) signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
tx := req.Msg.AsTransaction()
baseFee := k.feeMarketKeeper.GetBaseFee(ctx) baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
result, err := k.traceTx(ctx, signer, req.TxIndex, ethCfg, tx, baseFee, req.TraceConfig) for i, tx := range req.Predecessors {
ethTx := tx.AsTransaction()
msg, err := ethTx.AsMessage(signer, baseFee)
if err != nil { if err != nil {
continue
}
k.SetTxHashTransient(ethTx.Hash())
k.SetTxIndexTransient(uint64(i))
if _, err := k.ApplyMessage(msg, types.NewNoOpTracer(), true); err != nil {
continue
}
}
tx := req.Msg.AsTransaction()
result, err := k.traceTx(ctx, signer, req.TxIndex, ethCfg, tx, baseFee, req.TraceConfig, false)
if err != nil {
// error will be returned with detail status from traceTx
return nil, err return nil, err
} }
@ -383,6 +401,54 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
}, nil }, nil
} }
// TraceBlock configures a new tracer according to the provided configuration, and
// executes the given message in the provided environment for all the transactions in the queried block.
// The return value will be tracer dependent.
func (k Keeper) TraceBlock(c context.Context, req *types.QueryTraceBlockRequest) (*types.QueryTraceBlockResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}
if req.TraceConfig != nil && req.TraceConfig.Limit < 0 {
return nil, status.Errorf(codes.InvalidArgument, "output limit cannot be negative, got %d", req.TraceConfig.Limit)
}
ctx := sdk.UnwrapSDKContext(c)
ctx = ctx.WithBlockHeight(req.BlockNumber)
ctx = ctx.WithBlockTime(req.BlockTime)
ctx = ctx.WithHeaderHash(common.Hex2Bytes(req.BlockHash))
k.WithContext(ctx)
params := k.GetParams(ctx)
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)
txsLength := len(req.Txs)
results := make([]*types.TxTraceResult, 0, txsLength)
for i, tx := range req.Txs {
result := types.TxTraceResult{}
ethTx := tx.AsTransaction()
traceResult, err := k.traceTx(ctx, signer, uint64(i), ethCfg, ethTx, baseFee, req.TraceConfig, true)
if err != nil {
result.Error = err.Error()
continue
}
result.Result = traceResult
results = append(results, &result)
}
resultData, err := json.Marshal(results)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return &types.QueryTraceBlockResponse{
Data: resultData,
}, nil
}
func (k *Keeper) traceTx( func (k *Keeper) traceTx(
ctx sdk.Context, ctx sdk.Context,
signer ethtypes.Signer, signer ethtypes.Signer,
@ -391,6 +457,7 @@ func (k *Keeper) traceTx(
tx *ethtypes.Transaction, tx *ethtypes.Transaction,
baseFee *big.Int, baseFee *big.Int,
traceConfig *types.TraceConfig, traceConfig *types.TraceConfig,
commitMessage bool,
) (*interface{}, error) { ) (*interface{}, error) {
// Assemble the structured logger or the JavaScript tracer // Assemble the structured logger or the JavaScript tracer
var ( var (
@ -462,7 +529,7 @@ func (k *Keeper) traceTx(
k.SetTxHashTransient(txHash) k.SetTxHashTransient(txHash)
k.SetTxIndexTransient(txIndex) k.SetTxIndexTransient(txIndex)
res, err := k.ApplyMessage(msg, tracer, false) res, err := k.ApplyMessage(msg, tracer, commitMessage)
if err != nil { if err != nil {
return nil, status.Error(codes.Internal, err.Error()) return nil, status.Error(codes.Internal, err.Error())
} }

View File

@ -598,6 +598,8 @@ func (suite *KeeperTestSuite) TestTraceTx() {
var ( var (
txMsg *types.MsgEthereumTx txMsg *types.MsgEthereumTx
traceConfig *types.TraceConfig traceConfig *types.TraceConfig
txIndex uint64
predecessors []*types.MsgEthereumTx
) )
testCases := []struct { testCases := []struct {
@ -610,16 +612,20 @@ func (suite *KeeperTestSuite) TestTraceTx() {
{ {
msg: "default trace", msg: "default trace",
malleate: func() { malleate: func() {
txIndex = 0
traceConfig = nil traceConfig = nil
predecessors = []*types.MsgEthereumTx{}
}, },
expPass: true, expPass: true,
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d}, traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d},
}, { }, {
msg: "javascript tracer", msg: "javascript tracer",
malleate: func() { malleate: func() {
txIndex = 0
traceConfig = &types.TraceConfig{ traceConfig = &types.TraceConfig{
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}", Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
} }
predecessors = []*types.MsgEthereumTx{}
}, },
expPass: true, expPass: true,
traceResponse: []byte{0x5b, 0x5d}, traceResponse: []byte{0x5b, 0x5d},
@ -627,7 +633,9 @@ func (suite *KeeperTestSuite) TestTraceTx() {
{ {
msg: "default trace with dynamicTxFee", msg: "default trace with dynamicTxFee",
malleate: func() { malleate: func() {
txIndex = 0
traceConfig = nil traceConfig = nil
predecessors = []*types.MsgEthereumTx{}
}, },
expPass: true, expPass: true,
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d}, traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d},
@ -635,14 +643,35 @@ func (suite *KeeperTestSuite) TestTraceTx() {
}, { }, {
msg: "javascript tracer with dynamicTxFee", msg: "javascript tracer with dynamicTxFee",
malleate: func() { malleate: func() {
txIndex = 0
traceConfig = &types.TraceConfig{ traceConfig = &types.TraceConfig{
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}", Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
} }
predecessors = []*types.MsgEthereumTx{}
}, },
expPass: true, expPass: true,
traceResponse: []byte{0x5b, 0x5d}, traceResponse: []byte{0x5b, 0x5d},
dynamicTxFee: true, dynamicTxFee: true,
}, },
{
msg: "default tracer with predecessors",
malleate: func() {
txIndex = 1
traceConfig = nil
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
suite.Commit()
// Generate token transfer transaction
firstTx := suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
txMsg = suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
suite.Commit()
predecessors = append(predecessors, firstTx)
},
expPass: true,
traceResponse: []byte{0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d},
dynamicTxFee: false,
},
} }
for _, tc := range testCases { for _, tc := range testCases {
@ -660,7 +689,8 @@ func (suite *KeeperTestSuite) TestTraceTx() {
traceReq := types.QueryTraceTxRequest{ traceReq := types.QueryTraceTxRequest{
Msg: txMsg, Msg: txMsg,
TraceConfig: traceConfig, TraceConfig: traceConfig,
TxIndex: 1, // Can be hardcoded as this will be the only tx included in the block TxIndex: txIndex,
Predecessors: predecessors,
} }
res, err := suite.queryClient.TraceTx(ctx, &traceReq) res, err := suite.queryClient.TraceTx(ctx, &traceReq)
@ -675,3 +705,121 @@ func (suite *KeeperTestSuite) TestTraceTx() {
suite.dynamicTxFee = false // reset flag suite.dynamicTxFee = false // reset flag
} }
func (suite *KeeperTestSuite) TestTraceBlock() {
ctx := sdk.WrapSDKContext(suite.ctx)
var (
txs []*types.MsgEthereumTx
traceConfig *types.TraceConfig
)
testCases := []struct {
msg string
malleate func()
expPass bool
traceResponse []byte
dynamicTxFee bool
}{
{
msg: "default trace",
malleate: func() {
traceConfig = nil
},
expPass: true,
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x5d},
},
{
msg: "filtered trace",
malleate: func() {
traceConfig = &types.TraceConfig{
DisableStack: true,
DisableStorage: true,
EnableMemory: false,
}
},
expPass: true,
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x5d},
}, {
msg: "javascript tracer",
malleate: func() {
traceConfig = &types.TraceConfig{
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
}
},
expPass: true,
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x5d},
},
{
msg: "default trace with dynamicTxFee and filtered return",
malleate: func() {
traceConfig = &types.TraceConfig{
DisableStack: true,
DisableStorage: true,
EnableMemory: false,
}
},
expPass: true,
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x5d},
dynamicTxFee: true,
}, {
msg: "javascript tracer with dynamicTxFee",
malleate: func() {
traceConfig = &types.TraceConfig{
Tracer: "{data: [], fault: function(log) {}, step: function(log) { if(log.op.toString() == \"CALL\") this.data.push(log.stack.peek(0)); }, result: function() { return this.data; }}",
}
},
expPass: true,
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x5d},
dynamicTxFee: true,
},
{
msg: "tracer with multiple transactions",
malleate: func() {
traceConfig = nil
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
suite.Commit()
// create multiple transactions in the same block
firstTx := suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
secondTx := suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
suite.Commit()
// overwrite txs to include only the ones on new block
txs = append([]*types.MsgEthereumTx{}, firstTx, secondTx)
},
expPass: true,
traceResponse: []byte{0x5b, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x34, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x2c, 0x7b, 0x22, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x3a, 0x7b, 0x22, 0x67, 0x61, 0x73, 0x22, 0x3a, 0x33, 0x30, 0x38, 0x32, 0x38, 0x2c, 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x3a, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x2c, 0x22, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x4c, 0x6f, 0x67, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x7d, 0x5d},
dynamicTxFee: false,
},
}
for _, tc := range testCases {
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
txs = []*types.MsgEthereumTx{}
suite.dynamicTxFee = tc.dynamicTxFee
suite.SetupTest()
// Deploy contract
contractAddr := suite.DeployTestContract(suite.T(), suite.address, sdk.NewIntWithDecimal(1000, 18).BigInt())
suite.Commit()
// Generate token transfer transaction
txMsg := suite.TransferERC20Token(suite.T(), contractAddr, suite.address, common.HexToAddress("0x378c50D9264C63F3F92B806d4ee56E9D86FfB3Ec"), sdk.NewIntWithDecimal(1, 18).BigInt())
suite.Commit()
txs = append(txs, txMsg)
tc.malleate()
traceReq := types.QueryTraceBlockRequest{
Txs: txs,
TraceConfig: traceConfig,
}
res, err := suite.queryClient.TraceBlock(ctx, &traceReq)
if tc.expPass {
suite.Require().NoError(err)
suite.Require().Equal(tc.traceResponse, res.Data)
} else {
suite.Require().Error(err)
}
})
}
suite.dynamicTxFee = false // reset flag
}

View File

@ -6,5 +6,19 @@ import (
// UnpackInterfaces implements UnpackInterfacesMesssage.UnpackInterfaces // UnpackInterfaces implements UnpackInterfacesMesssage.UnpackInterfaces
func (m QueryTraceTxRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error { func (m QueryTraceTxRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
for _, msg := range m.Predecessors {
if err := msg.UnpackInterfaces(unpacker); err != nil {
return err
}
}
return m.Msg.UnpackInterfaces(unpacker) return m.Msg.UnpackInterfaces(unpacker)
} }
func (m QueryTraceBlockRequest) UnpackInterfaces(unpacker codectypes.AnyUnpacker) error {
for _, msg := range m.Txs {
if err := msg.UnpackInterfaces(unpacker); err != nil {
return err
}
}
return nil
}

957
x/evm/types/query.pb.go generated

File diff suppressed because it is too large Load Diff

View File

@ -503,6 +503,42 @@ func local_request_Query_TraceTx_0(ctx context.Context, marshaler runtime.Marsha
} }
var (
filter_Query_TraceBlock_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_Query_TraceBlock_0(ctx context.Context, marshaler runtime.Marshaler, client QueryClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryTraceBlockRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_TraceBlock_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.TraceBlock(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Query_TraceBlock_0(ctx context.Context, marshaler runtime.Marshaler, server QueryServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq QueryTraceBlockRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Query_TraceBlock_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.TraceBlock(ctx, &protoReq)
return msg, metadata, err
}
// RegisterQueryHandlerServer registers the http handlers for service Query to "mux". // RegisterQueryHandlerServer registers the http handlers for service Query to "mux".
// UnaryRPC :call QueryServer directly. // UnaryRPC :call QueryServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@ -709,6 +745,26 @@ func RegisterQueryHandlerServer(ctx context.Context, mux *runtime.ServeMux, serv
}) })
mux.Handle("GET", pattern_Query_TraceBlock_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_TraceBlock_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_TraceBlock_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil return nil
} }
@ -950,6 +1006,26 @@ func RegisterQueryHandlerClient(ctx context.Context, mux *runtime.ServeMux, clie
}) })
mux.Handle("GET", pattern_Query_TraceBlock_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_TraceBlock_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_TraceBlock_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil return nil
} }
@ -973,6 +1049,8 @@ var (
pattern_Query_EstimateGas_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1", "estimate_gas"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_EstimateGas_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1", "estimate_gas"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Query_TraceTx_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1", "trace_tx"}, "", runtime.AssumeColonVerbOpt(true))) pattern_Query_TraceTx_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1", "trace_tx"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Query_TraceBlock_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1", "trace_block"}, "", runtime.AssumeColonVerbOpt(true)))
) )
var ( var (
@ -995,4 +1073,6 @@ var (
forward_Query_EstimateGas_0 = runtime.ForwardResponseMessage forward_Query_EstimateGas_0 = runtime.ForwardResponseMessage
forward_Query_TraceTx_0 = runtime.ForwardResponseMessage forward_Query_TraceTx_0 = runtime.ForwardResponseMessage
forward_Query_TraceBlock_0 = runtime.ForwardResponseMessage
) )

109
x/evm/types/tx.pb.go generated
View File

@ -13,6 +13,7 @@ import (
grpc1 "github.com/gogo/protobuf/grpc" grpc1 "github.com/gogo/protobuf/grpc"
proto "github.com/gogo/protobuf/proto" proto "github.com/gogo/protobuf/proto"
_ "github.com/regen-network/cosmos-proto" _ "github.com/regen-network/cosmos-proto"
_ "google.golang.org/genproto/googleapis/api/annotations"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes" codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status" status "google.golang.org/grpc/status"
@ -351,59 +352,61 @@ func init() {
func init() { proto.RegisterFile("ethermint/evm/v1/tx.proto", fileDescriptor_f75ac0a12d075f21) } func init() { proto.RegisterFile("ethermint/evm/v1/tx.proto", fileDescriptor_f75ac0a12d075f21) }
var fileDescriptor_f75ac0a12d075f21 = []byte{ var fileDescriptor_f75ac0a12d075f21 = []byte{
// 818 bytes of a gzipped FileDescriptorProto // 853 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x55, 0x3f, 0x6f, 0xdb, 0x46, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x55, 0x31, 0x8f, 0xe3, 0x44,
0x14, 0x17, 0x25, 0x4a, 0xa4, 0x4e, 0xaa, 0x61, 0x10, 0x36, 0x40, 0x09, 0xa8, 0x28, 0x68, 0x68, 0x14, 0xce, 0x24, 0x4e, 0xec, 0x4c, 0xc2, 0xe9, 0x64, 0xed, 0x49, 0x4e, 0xc4, 0xc5, 0x91, 0x25,
0xd5, 0x02, 0x22, 0x61, 0xb7, 0x93, 0xa7, 0x9a, 0xfe, 0x07, 0x1b, 0x32, 0x5a, 0x10, 0x6a, 0x87, 0x20, 0x20, 0xc5, 0xd6, 0x2d, 0x54, 0x5b, 0xb1, 0xbe, 0xdd, 0x3b, 0xdd, 0x29, 0x27, 0x90, 0x15,
0x1a, 0x85, 0x70, 0xa6, 0xce, 0x14, 0x51, 0x91, 0x47, 0xf0, 0x4e, 0x84, 0xd4, 0x4f, 0xd0, 0x2d, 0x1a, 0xae, 0x88, 0x66, 0x9d, 0x59, 0x67, 0x44, 0xec, 0xb1, 0x3c, 0x13, 0xcb, 0x41, 0xa2, 0x41,
0xf9, 0x08, 0x19, 0x32, 0x65, 0x4d, 0x3e, 0x40, 0x46, 0x8f, 0x46, 0xa6, 0x20, 0x03, 0x13, 0xc8, 0x14, 0x74, 0x20, 0xf1, 0x07, 0x28, 0xa8, 0x68, 0xe1, 0x07, 0x50, 0x5e, 0x79, 0x82, 0x06, 0x51,
0x9b, 0xb7, 0xe4, 0x13, 0x04, 0x77, 0xa4, 0x2c, 0x2b, 0x82, 0x9c, 0xc4, 0x71, 0x90, 0x49, 0xef, 0x18, 0x94, 0xa5, 0xda, 0x0e, 0x7e, 0x01, 0x9a, 0xb1, 0xb3, 0x9b, 0x10, 0xe5, 0x80, 0xe3, 0x10,
0xf1, 0xbd, 0x7b, 0xff, 0x7e, 0x3f, 0xbd, 0x07, 0x2a, 0x88, 0xf6, 0x51, 0xe8, 0xb9, 0x3e, 0x35, 0x55, 0xe6, 0xf9, 0x7b, 0xf3, 0xe6, 0xbd, 0xf7, 0x7d, 0x79, 0x0f, 0x76, 0x30, 0x9f, 0xe1, 0x24,
0x50, 0xe4, 0x19, 0xd1, 0x86, 0x41, 0x47, 0x7a, 0x10, 0x62, 0x8a, 0x95, 0xd5, 0x6b, 0x93, 0x8e, 0x24, 0x11, 0x77, 0x70, 0x1a, 0x3a, 0xe9, 0x1d, 0x87, 0x67, 0x76, 0x9c, 0x50, 0x4e, 0xf5, 0x9b,
0x22, 0x4f, 0x8f, 0x36, 0xaa, 0x6b, 0x0e, 0x76, 0x30, 0x37, 0x1a, 0x4c, 0x4a, 0xfc, 0xaa, 0x15, 0x57, 0x90, 0x8d, 0xd3, 0xd0, 0x4e, 0xef, 0x74, 0x0f, 0x02, 0x1a, 0x50, 0x09, 0x3a, 0xe2, 0x54,
0x07, 0x63, 0x67, 0x80, 0x0c, 0xae, 0x9d, 0x0e, 0xcf, 0x0c, 0xe8, 0x8f, 0xa7, 0x26, 0x1b, 0x13, 0xf8, 0x75, 0x5f, 0x0e, 0x28, 0x0d, 0xe6, 0xd8, 0x41, 0x31, 0x71, 0x50, 0x14, 0x51, 0x8e, 0x38,
0x0f, 0x93, 0x6e, 0xf2, 0x26, 0x51, 0x52, 0x53, 0x75, 0x21, 0x31, 0x4b, 0xc2, 0x6d, 0x8d, 0x07, 0xa1, 0x11, 0x2b, 0xd1, 0x4e, 0x89, 0x4a, 0xeb, 0x6c, 0x71, 0xee, 0xa0, 0x68, 0xb9, 0x86, 0x7c,
0x02, 0xf8, 0xee, 0x98, 0x38, 0x7b, 0xcc, 0x03, 0x0d, 0xbd, 0xce, 0x48, 0x69, 0x02, 0xb1, 0x07, 0xca, 0x42, 0xca, 0x26, 0x45, 0xc4, 0xc2, 0x28, 0xa1, 0xee, 0x4e, 0x5a, 0x22, 0x05, 0x89, 0x59,
0x29, 0x54, 0x85, 0xba, 0xd0, 0x2c, 0x6d, 0xae, 0xe9, 0x49, 0x4a, 0x7d, 0x9a, 0x52, 0xdf, 0xf6, 0x9f, 0x01, 0xf8, 0xd2, 0x23, 0x16, 0x9c, 0x0a, 0x0f, 0xbc, 0x08, 0xc7, 0x99, 0x3e, 0x80, 0xca,
0xc7, 0x16, 0xf7, 0x50, 0x2a, 0x40, 0x24, 0xee, 0x7f, 0x48, 0xcd, 0xd6, 0x85, 0xa6, 0x60, 0xe6, 0x14, 0x71, 0x64, 0x80, 0x3e, 0x18, 0xb4, 0x0e, 0x0f, 0xec, 0xe2, 0x49, 0x7b, 0xfd, 0xa4, 0x7d,
0xaf, 0x62, 0x4d, 0x68, 0x59, 0xfc, 0x93, 0xa2, 0x01, 0xb1, 0x0f, 0x49, 0x5f, 0xcd, 0xd5, 0x85, 0x1c, 0x2d, 0x3d, 0xe9, 0xa1, 0x77, 0xa0, 0xc2, 0xc8, 0x87, 0xd8, 0xa8, 0xf6, 0xc1, 0x00, 0xb8,
0x66, 0xd1, 0x2c, 0xbd, 0x8b, 0x35, 0x29, 0x1c, 0x04, 0x5b, 0x8d, 0x56, 0xc3, 0xe2, 0x06, 0x45, 0xf5, 0xcb, 0xdc, 0x04, 0x43, 0x4f, 0x7e, 0xd2, 0x4d, 0xa8, 0xcc, 0x10, 0x9b, 0x19, 0xb5, 0x3e,
0x01, 0xe2, 0x59, 0x88, 0x3d, 0x55, 0x64, 0x0e, 0x16, 0x97, 0xb7, 0xc4, 0xff, 0x1f, 0x69, 0x99, 0x18, 0x34, 0xdd, 0xd6, 0xef, 0xb9, 0xa9, 0x26, 0xf3, 0xf8, 0xc8, 0x1a, 0x5a, 0x9e, 0x04, 0x74,
0xc6, 0xd3, 0x2c, 0x90, 0xdb, 0xc8, 0x81, 0xf6, 0xb8, 0x33, 0x52, 0xd6, 0x40, 0xde, 0xc7, 0xbe, 0x1d, 0x2a, 0xe7, 0x09, 0x0d, 0x0d, 0x45, 0x38, 0x78, 0xf2, 0x7c, 0xa4, 0x7c, 0xfa, 0xa5, 0x59,
0x8d, 0x78, 0x35, 0xa2, 0x95, 0x28, 0xca, 0x01, 0x28, 0x3a, 0x90, 0xb5, 0xea, 0xda, 0x49, 0xf6, 0xb1, 0xbe, 0xa9, 0x42, 0x6d, 0x84, 0x03, 0xe4, 0x2f, 0xc7, 0x99, 0x7e, 0x00, 0xeb, 0x11, 0x8d,
0xa2, 0xf9, 0xf3, 0xab, 0x58, 0xfb, 0xc1, 0x71, 0x69, 0x7f, 0x78, 0xaa, 0xdb, 0xd8, 0x4b, 0x07, 0x7c, 0x2c, 0xb3, 0x51, 0xbc, 0xc2, 0xd0, 0xef, 0xc3, 0x66, 0x80, 0x44, 0xa9, 0xc4, 0x2f, 0x5e,
0x90, 0xfe, 0xb4, 0x48, 0xef, 0x5f, 0x83, 0x8e, 0x03, 0x44, 0xf4, 0x43, 0x9f, 0x5a, 0xb2, 0x03, 0x6f, 0xba, 0x6f, 0xfc, 0x94, 0x9b, 0xaf, 0x06, 0x84, 0xcf, 0x16, 0x67, 0xb6, 0x4f, 0xc3, 0xb2,
0xc9, 0x1f, 0xec, 0xad, 0x52, 0x03, 0x39, 0x07, 0x12, 0x5e, 0xa5, 0x68, 0x96, 0x27, 0xb1, 0x26, 0x01, 0xe5, 0xcf, 0x90, 0x4d, 0x3f, 0x70, 0xf8, 0x32, 0xc6, 0xcc, 0x7e, 0x10, 0x71, 0x4f, 0x0b,
0x1f, 0x40, 0xd2, 0x76, 0x3d, 0x97, 0x5a, 0xcc, 0xa0, 0xac, 0x80, 0x2c, 0xc5, 0x69, 0x8d, 0x59, 0x10, 0x7b, 0x57, 0xdc, 0xd5, 0x7b, 0xb0, 0x16, 0x20, 0x26, 0xb3, 0x54, 0xdc, 0xf6, 0x2a, 0x37,
0x8a, 0x95, 0x23, 0x90, 0x8f, 0xe0, 0x60, 0x88, 0xd4, 0x3c, 0x4f, 0xfa, 0xeb, 0xa7, 0x27, 0x9d, 0xb5, 0xfb, 0x88, 0x8d, 0x48, 0x48, 0xb8, 0x27, 0x00, 0xfd, 0x06, 0xac, 0x72, 0x5a, 0xe6, 0x58,
0xc4, 0x5a, 0x61, 0xdb, 0xc3, 0x43, 0x9f, 0x5a, 0x49, 0x08, 0x36, 0x01, 0x3e, 0xe7, 0x42, 0x5d, 0xe5, 0x54, 0x7f, 0x08, 0xeb, 0x29, 0x9a, 0x2f, 0xb0, 0x51, 0x97, 0x8f, 0xbe, 0xf5, 0xf7, 0x1f,
0x68, 0x96, 0xd3, 0x89, 0x96, 0x81, 0x10, 0xa9, 0x12, 0xff, 0x20, 0x44, 0x4c, 0x0b, 0x55, 0x39, 0x5d, 0xe5, 0x66, 0xe3, 0x38, 0xa4, 0x8b, 0x88, 0x7b, 0x45, 0x08, 0xd1, 0x01, 0xd9, 0xe7, 0x46,
0xd1, 0x42, 0xa6, 0x11, 0xb5, 0x98, 0x68, 0x64, 0x6b, 0x85, 0xcd, 0xea, 0xc5, 0xb3, 0x56, 0xa1, 0x1f, 0x0c, 0xda, 0x65, 0x47, 0xdb, 0x10, 0xa4, 0x86, 0x2a, 0x3f, 0x80, 0x54, 0x58, 0x89, 0xa1,
0x33, 0xda, 0x85, 0x14, 0x36, 0xde, 0xe6, 0x40, 0x79, 0xdb, 0xb6, 0x11, 0x21, 0x6d, 0x97, 0xd0, 0x15, 0x56, 0x22, 0x2c, 0x66, 0x34, 0x0b, 0x8b, 0x1d, 0xdd, 0x10, 0xbd, 0xfa, 0xfe, 0xdb, 0x61,
0xce, 0x48, 0x39, 0x01, 0xb2, 0xdd, 0x87, 0xae, 0xdf, 0x75, 0x7b, 0x7c, 0x78, 0x45, 0xf3, 0xb7, 0x63, 0x9c, 0x9d, 0x20, 0x8e, 0xac, 0xdf, 0x6a, 0xb0, 0x7d, 0xec, 0xfb, 0x98, 0xb1, 0x11, 0x61,
0xcf, 0xaa, 0x56, 0xda, 0x61, 0xaf, 0x0f, 0x77, 0xaf, 0x62, 0x4d, 0xb2, 0x13, 0xd1, 0x4a, 0x85, 0x7c, 0x9c, 0xe9, 0x8f, 0xa1, 0xe6, 0xcf, 0x10, 0x89, 0x26, 0x64, 0x2a, 0x9b, 0xd7, 0x74, 0xdf,
0xde, 0x0c, 0x96, 0xec, 0x52, 0x58, 0x72, 0x5f, 0x0e, 0x8b, 0x78, 0x3b, 0x2c, 0xf9, 0x45, 0x58, 0xfe, 0x47, 0xd9, 0xaa, 0x77, 0xc5, 0xed, 0x07, 0x27, 0x97, 0xb9, 0xa9, 0xfa, 0xc5, 0xd1, 0x2b,
0x0a, 0xf7, 0x07, 0x8b, 0x74, 0x03, 0x96, 0x13, 0x20, 0x43, 0x3e, 0x5b, 0x44, 0x54, 0xb9, 0x9e, 0x0f, 0xd3, 0x6b, 0x5a, 0xaa, 0x7b, 0x69, 0xa9, 0xfd, 0x7b, 0x5a, 0x94, 0x67, 0xd3, 0x52, 0xdf,
0x6b, 0x96, 0x36, 0xbf, 0xd7, 0x3f, 0xfc, 0xc7, 0xea, 0xc9, 0xf4, 0x3b, 0xc3, 0x60, 0x80, 0xcc, 0xa5, 0xa5, 0xf1, 0xe2, 0x68, 0x51, 0x37, 0x68, 0x79, 0x0c, 0x35, 0x24, 0x7b, 0x8b, 0x99, 0xa1,
0xfa, 0x79, 0xac, 0x65, 0xae, 0x62, 0x0d, 0xc0, 0x6b, 0x48, 0x9e, 0xbc, 0xd6, 0xc0, 0x0c, 0x20, 0xf5, 0x6b, 0x83, 0xd6, 0xe1, 0x6d, 0xfb, 0xcf, 0xff, 0x67, 0xbb, 0xe8, 0xfe, 0x78, 0x11, 0xcf,
0xeb, 0x3a, 0x60, 0x82, 0x79, 0x71, 0x0e, 0x73, 0x30, 0x87, 0x79, 0x69, 0x19, 0xe6, 0xcf, 0x45, 0xb1, 0xdb, 0x7f, 0x92, 0x9b, 0x95, 0xcb, 0xdc, 0x84, 0xe8, 0x8a, 0x92, 0xaf, 0x7f, 0x36, 0xe1,
0x50, 0xde, 0x1d, 0xfb, 0xd0, 0x73, 0xed, 0x7d, 0x84, 0xbe, 0x0d, 0xe6, 0x47, 0xa0, 0xc4, 0x30, 0x35, 0x41, 0xde, 0x55, 0xc0, 0x82, 0xf3, 0xe6, 0x16, 0xe7, 0x70, 0x8b, 0xf3, 0xd6, 0x3e, 0xce,
0xa7, 0x6e, 0xd0, 0xb5, 0x61, 0x70, 0x07, 0xd4, 0x19, 0x65, 0x3a, 0x6e, 0xb0, 0x03, 0x83, 0x69, 0xbf, 0x53, 0x60, 0xfb, 0x64, 0x19, 0xa1, 0x90, 0xf8, 0xf7, 0x30, 0xfe, 0x7f, 0x38, 0x7f, 0x08,
0xac, 0x33, 0x84, 0x78, 0x2c, 0xf1, 0x4e, 0xb1, 0xf6, 0x11, 0x62, 0xb1, 0x52, 0x0a, 0xe5, 0x6f, 0x5b, 0x82, 0x73, 0x4e, 0xe2, 0x89, 0x8f, 0xe2, 0xe7, 0x60, 0x5d, 0x48, 0x66, 0x4c, 0xe2, 0xbb,
0xa7, 0x50, 0x61, 0x91, 0x42, 0xd2, 0xfd, 0x51, 0x48, 0x5e, 0x42, 0xa1, 0xe2, 0x57, 0xa1, 0x10, 0x28, 0x5e, 0xc7, 0x3a, 0xc7, 0x58, 0xc6, 0x52, 0x9e, 0x2b, 0xd6, 0x3d, 0x8c, 0x45, 0xac, 0x52,
0x98, 0xa3, 0x50, 0x69, 0x8e, 0x42, 0xe5, 0x65, 0x14, 0x6a, 0x80, 0xea, 0xde, 0x88, 0x22, 0x9f, 0x42, 0xf5, 0x67, 0x4b, 0xa8, 0xb1, 0x2b, 0x21, 0xf5, 0xc5, 0x49, 0x48, 0xdb, 0x23, 0xa1, 0xe6,
0xb8, 0xd8, 0xff, 0x3d, 0xa0, 0x2e, 0xf6, 0xc9, 0xec, 0x14, 0xa4, 0x0b, 0xf9, 0xb1, 0x00, 0xd6, 0x7f, 0x22, 0x21, 0xb8, 0x25, 0xa1, 0xd6, 0x96, 0x84, 0xda, 0xfb, 0x24, 0x64, 0xc1, 0xee, 0x69,
0xe7, 0x4e, 0x84, 0x85, 0x48, 0x80, 0x7d, 0xc2, 0x1b, 0xe5, 0x5b, 0x5e, 0x48, 0x96, 0x38, 0x5f, 0xc6, 0x71, 0xc4, 0x08, 0x8d, 0xde, 0x89, 0xe5, 0xaa, 0xb9, 0x5e, 0x05, 0xe5, 0x40, 0xfe, 0x0a,
0xec, 0x3f, 0x01, 0x71, 0x80, 0x1d, 0xa2, 0x66, 0x79, 0x93, 0xeb, 0x8b, 0x4d, 0xb6, 0xb1, 0x63, 0xc0, 0x5b, 0x5b, 0x2b, 0xc2, 0xc3, 0x2c, 0xa6, 0x11, 0x93, 0x85, 0xca, 0x29, 0x0f, 0x8a, 0x21,
0x71, 0x17, 0x65, 0x15, 0xe4, 0x42, 0x44, 0x39, 0x67, 0xca, 0x16, 0x13, 0x95, 0x0a, 0x90, 0x23, 0x2e, 0x07, 0xfb, 0xeb, 0x50, 0x99, 0xd3, 0x80, 0x19, 0x55, 0x59, 0xe4, 0xad, 0xdd, 0x22, 0x47,
0xaf, 0x8b, 0xc2, 0x10, 0x87, 0xe9, 0xd6, 0x95, 0x22, 0x6f, 0x8f, 0xa9, 0xcc, 0xc4, 0xc8, 0x31, 0x34, 0xf0, 0xa4, 0x8b, 0x7e, 0x13, 0xd6, 0x12, 0xcc, 0xa5, 0x66, 0xda, 0x9e, 0x38, 0xea, 0x1d,
0x24, 0xa8, 0x97, 0xa0, 0x6a, 0x49, 0x0e, 0x24, 0x7f, 0x12, 0xd4, 0x4b, 0xca, 0xdc, 0xfc, 0x07, 0xa8, 0xa5, 0xe1, 0x04, 0x27, 0x09, 0x4d, 0xca, 0xa9, 0xab, 0xa6, 0xe1, 0xa9, 0x30, 0x05, 0x24,
0xe4, 0x8e, 0x89, 0xa3, 0xfc, 0x05, 0xc0, 0x8d, 0x63, 0xa6, 0x2d, 0xe6, 0x9f, 0x6b, 0xa5, 0xfa, 0xc4, 0xb1, 0x60, 0x78, 0x5a, 0xb0, 0xea, 0xa9, 0x01, 0x62, 0xef, 0x31, 0x3c, 0x2d, 0xd2, 0x3c,
0xe3, 0x47, 0x1c, 0xa6, 0xbd, 0x9a, 0xe6, 0xf9, 0xa4, 0x26, 0x5c, 0x4c, 0x6a, 0xc2, 0x9b, 0x49, 0xfc, 0x04, 0xc0, 0xda, 0x23, 0x16, 0xe8, 0x1f, 0x41, 0xb8, 0xb1, 0xcd, 0xcc, 0xdd, 0x04, 0xb6,
0x4d, 0x78, 0x78, 0x59, 0xcb, 0x5c, 0x5c, 0xd6, 0x32, 0x2f, 0x2f, 0x6b, 0x99, 0xbf, 0x9b, 0x37, 0x6a, 0xe9, 0xbe, 0xf6, 0x17, 0x0e, 0xeb, 0x62, 0xad, 0x57, 0x3e, 0xfe, 0xe1, 0xd7, 0x2f, 0xaa,
0x78, 0x42, 0xfb, 0x30, 0x24, 0x2e, 0x31, 0x66, 0x17, 0x77, 0xc4, 0x6f, 0x2e, 0x67, 0xcb, 0x69, 0xa6, 0x75, 0xdb, 0xd9, 0x5d, 0xa7, 0xa5, 0xf7, 0x84, 0x67, 0xae, 0xfb, 0x64, 0xd5, 0x03, 0x4f,
0x81, 0x1f, 0xd1, 0x5f, 0xde, 0x07, 0x00, 0x00, 0xff, 0xff, 0x03, 0xe3, 0x68, 0xe8, 0x0a, 0x08, 0x57, 0x3d, 0xf0, 0xcb, 0xaa, 0x07, 0x3e, 0xbf, 0xe8, 0x55, 0x9e, 0x5e, 0xf4, 0x2a, 0x3f, 0x5e,
0x00, 0x00, 0xf4, 0x2a, 0xef, 0x0f, 0x36, 0xf4, 0xc4, 0x67, 0x28, 0x61, 0x84, 0x6d, 0x84, 0xca, 0x64, 0x30,
0xa9, 0xaa, 0xb3, 0x86, 0x5c, 0xb6, 0x6f, 0xfe, 0x11, 0x00, 0x00, 0xff, 0xff, 0x4a, 0x54, 0xa7,
0x4c, 0x50, 0x08, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.

166
x/evm/types/tx.pb.gw.go generated Normal file
View File

@ -0,0 +1,166 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: ethermint/evm/v1/tx.proto
/*
Package types is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package types
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
var (
filter_Msg_EthereumTx_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_Msg_EthereumTx_0(ctx context.Context, marshaler runtime.Marshaler, client MsgClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq MsgEthereumTx
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_EthereumTx_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.EthereumTx(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Msg_EthereumTx_0(ctx context.Context, marshaler runtime.Marshaler, server MsgServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq MsgEthereumTx
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Msg_EthereumTx_0); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.EthereumTx(ctx, &protoReq)
return msg, metadata, err
}
// RegisterMsgHandlerServer registers the http handlers for service Msg to "mux".
// UnaryRPC :call MsgServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features (such as grpc.SendHeader, etc) to stop working. Consider using RegisterMsgHandlerFromEndpoint instead.
func RegisterMsgHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MsgServer) error {
mux.Handle("POST", pattern_Msg_EthereumTx_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_Msg_EthereumTx_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Msg_EthereumTx_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterMsgHandlerFromEndpoint is same as RegisterMsgHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterMsgHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterMsgHandler(ctx, mux, conn)
}
// RegisterMsgHandler registers the http handlers for service Msg to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterMsgHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterMsgHandlerClient(ctx, mux, NewMsgClient(conn))
}
// RegisterMsgHandlerClient registers the http handlers for service Msg
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MsgClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MsgClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "MsgClient" to call the correct interceptors.
func RegisterMsgHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MsgClient) error {
mux.Handle("POST", pattern_Msg_EthereumTx_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_Msg_EthereumTx_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Msg_EthereumTx_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Msg_EthereumTx_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"ethermint", "evm", "v1", "ethereum_tx"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
forward_Msg_EthereumTx_0 = runtime.ForwardResponseMessage
)