Skip to content
This repository has been archived by the owner on Apr 4, 2024. It is now read-only.

Problem: traceTransaction fails for succesful tx #720

Merged
merged 32 commits into from
Nov 9, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7233abb
Problem: traceTransaction fails for succesful tx
yihuang Nov 5, 2021
1b27db1
changelog
yihuang Nov 5, 2021
f1c7d55
fix build
yihuang Nov 5, 2021
f5e0a6c
fix lint
yihuang Nov 6, 2021
2f9197c
refactor traceBlock
crypto-facs Nov 6, 2021
eeb7d22
update protobuf
crypto-facs Nov 6, 2021
346105b
fix Predecessors
yihuang Nov 8, 2021
e1ff8fd
traceBlock refactor
crypto-facs Nov 8, 2021
84b6e27
Merge branch 'fix-tracetx-context' of github.com:yihuang/ethermint in…
crypto-facs Nov 8, 2021
8034d60
refactor traceBlock response
crypto-facs Nov 8, 2021
fa47b90
Update proto/ethermint/evm/v1/tx.proto
crypto-facs Nov 8, 2021
bb7c8cb
Update proto/ethermint/evm/v1/query.proto
crypto-facs Nov 8, 2021
042c4df
Update proto/ethermint/evm/v1/query.proto
crypto-facs Nov 8, 2021
4e99b42
Update proto/ethermint/evm/v1/query.proto
crypto-facs Nov 8, 2021
fb9cb2f
Update proto/ethermint/evm/v1/query.proto
crypto-facs Nov 8, 2021
28946cb
Update proto/ethermint/evm/v1/query.proto
crypto-facs Nov 8, 2021
5826910
fix conflicts
crypto-facs Nov 9, 2021
e55fa23
check tx index is not out of bound
crypto-facs Nov 9, 2021
2468ec8
fix build
crypto-facs Nov 9, 2021
0a3ee7d
Update rpc/ethereum/namespaces/debug/api.go
crypto-facs Nov 9, 2021
40e9675
Update rpc/ethereum/namespaces/debug/api.go
crypto-facs Nov 9, 2021
4f3f827
Update rpc/ethereum/namespaces/debug/api.go
crypto-facs Nov 9, 2021
3d1ea65
Update rpc/ethereum/namespaces/debug/api.go
crypto-facs Nov 9, 2021
f493ccf
remove prealloc
crypto-facs Nov 9, 2021
0567e8f
add traceBlock test
crypto-facs Nov 9, 2021
74b491a
Update x/evm/keeper/grpc_query.go
crypto-facs Nov 9, 2021
805d2e4
Merge branch 'fix-tracetx-context' of github.com:yihuang/ethermint in…
crypto-facs Nov 9, 2021
2c9c9f2
use bytes2Hex
crypto-facs Nov 9, 2021
14203f8
fix error message
crypto-facs Nov 9, 2021
1ea5970
add comment
crypto-facs Nov 9, 2021
417624a
Apply suggestions from code review
fedekunze Nov 9, 2021
5cd28c3
Update rpc/ethereum/namespaces/debug/api.go
fedekunze Nov 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,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, 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
* (rpc) [tharsis#720](https://github.com/tharsis/ethermint/pull/720) Fix `debug_traceTransaction` failure

### Improvements

Expand Down
4 changes: 4 additions & 0 deletions docs/api/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,10 @@ QueryTraceTxRequest defines TraceTx request
| `msg` | [MsgEthereumTx](#ethermint.evm.v1.MsgEthereumTx) | | msgEthereumTx for the requested transaction |
| `tx_index` | [uint64](#uint64) | | transaction index |
| `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_hash` | [string](#string) | | |
| `block_time` | [int64](#int64) | | |



Expand Down
6 changes: 6 additions & 0 deletions proto/ethermint/evm/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@ message QueryTraceTxRequest {
uint64 tx_index = 2;
// TraceConfig holds extra parameters to trace functions.
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;
int64 block_number = 5;
string block_hash = 6;
int64 block_time = 7;
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
}

// QueryTraceTxResponse defines TraceTx response
Expand Down
56 changes: 49 additions & 7 deletions rpc/ethereum/namespaces/debug/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"time"

"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"

Expand Down Expand Up @@ -81,6 +81,28 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (
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
}

predecessors := []*evmtypes.MsgEthereumTx{}
for _, txBz := range blk.Block.Txs[:transaction.Index] {
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
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)
if err != nil {
a.logger.Debug("tx not found", "hash", hash)
Expand All @@ -94,15 +116,25 @@ func (a *API) TraceTransaction(hash common.Hash, config *evmtypes.TraceConfig) (
}

traceTxRequest := evmtypes.QueryTraceTxRequest{
Msg: ethMessage,
TxIndex: uint64(transaction.Index),
Msg: ethMessage,
TxIndex: uint64(transaction.Index),
Predecessors: predecessors,
BlockNumber: blk.Block.Height,
BlockTime: blk.Block.Time.Unix(),
BlockHash: blk.BlockID.Hash.String(),
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
}

if config != nil {
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 {
return nil, err
}
Expand Down Expand Up @@ -131,13 +163,14 @@ func (a *API) TraceBlockByNumber(height rpctypes.BlockNumber, config *evmtypes.T
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
// executes all the transactions contained within. The return value will be one item
// 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)

if txsLength == 0 {
Expand All @@ -156,7 +189,13 @@ func (a API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConfi
threads = txsLength
}

ctxWithHeight := rpctypes.ContextWithHeight(int64(height))
// minus one to get the context at the begining of the block
contextHeight := height - 1
if contextHeight < 1 {
// 0 is a special value for `ContextWithHeight`.
contextHeight = 1
}
ctxWithHeight := rpctypes.ContextWithHeight(int64(contextHeight))

wg.Add(threads)
for th := 0; th < threads; th++ {
Expand Down Expand Up @@ -185,6 +224,9 @@ func (a API) traceBlock(height rpctypes.BlockNumber, config *evmtypes.TraceConfi
Msg: ethMessage,
TxIndex: uint64(task.Index),
TraceConfig: config,
BlockNumber: block.Block.Height,
BlockTime: block.Block.Time.Unix(),
BlockHash: block.BlockID.Hash.String(),
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
}

res, err := a.queryClient.TraceTx(ctxWithHeight, traceTxRequest)
Expand Down
20 changes: 19 additions & 1 deletion x/evm/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,14 +360,32 @@ func (k Keeper) TraceTx(c context.Context, req *types.QueryTraceTxRequest) (*typ
}

ctx := sdk.UnwrapSDKContext(c)
ctx = ctx.WithBlockHeight(req.BlockNumber)
ctx = ctx.WithBlockTime(time.Unix(req.BlockTime, 0))
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()))
tx := req.Msg.AsTransaction()
baseFee := k.feeMarketKeeper.GetBaseFee(ctx)

for i, tx := range req.Predecessors {
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
ethTx := tx.AsTransaction()
msg, err := ethTx.AsMessage(signer)
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this error should be logged

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^

continue
}
k.SetTxHashTransient(ethTx.Hash())
k.SetTxIndexTransient(uint64(i))

_, err = k.ApplyMessage(msg, types.NewNoOpTracer(), true)
if err != nil {
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
continue
}
}

tx := req.Msg.AsTransaction()
result, err := k.traceTx(ctx, signer, req.TxIndex, ethCfg, tx, baseFee, req.TraceConfig)
if err != nil {
return nil, err
crypto-facs marked this conversation as resolved.
Show resolved Hide resolved
Expand Down