Skip to content

Commit

Permalink
Merge pull request #3503 from vitaliy-io/fix/trace-tx
Browse files Browse the repository at this point in the history
fix debug_traceTransaction bugs
  • Loading branch information
vitaliy-io authored Sep 17, 2024
2 parents cb4115a + 6125e44 commit 3a1b4c2
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 14 deletions.
61 changes: 55 additions & 6 deletions packages/evm/jsonrpc/jsonrpctest/jsonrpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -586,21 +586,62 @@ func TestRPCTraceTx(t *testing.T) {

require.Equal(t, creatorAddress, trace1.From)
require.Equal(t, contractAddress, *trace1.To)
require.Equal(t, big.NewInt(123), trace1.Value)
require.Equal(t, "0x7b", trace1.Value.String())
expectedInput, err := contractABI.Pack("sendTo", common.Address{0x1}, big.NewInt(1))
require.NoError(t, err)
require.Equal(t, expectedInput, trace1.Input)
require.Empty(t, trace1.Error)
require.Empty(t, trace1.RevertReason)
require.Equal(t, "0x0", trace1.Gas.String())
require.Equal(t, "0x0", trace1.GasUsed.String())

require.Len(t, trace1.Calls, 1)
trace2 := trace1.Calls[0]
require.Equal(t, contractAddress, trace2.From)
require.Equal(t, common.Address{0x1}, *trace2.To)
require.Equal(t, big.NewInt(1), trace2.Value)
require.Equal(t, "0x1", trace2.Value.String())
require.Empty(t, trace2.Input)
require.Empty(t, trace2.Error)
require.Empty(t, trace2.RevertReason)
require.Contains(t, trace2.Gas.String(), "0x")
require.Contains(t, trace2.GasUsed.String(), "0x")
}

func TestRPCTraceEvmDeposit(t *testing.T) {
env := newSoloTestEnv(t)
wallet, _ := env.solo.NewKeyPairWithFunds()
_, evmAddr := env.soloChain.NewEthereumAccountWithL2Funds()

err := env.soloChain.TransferAllowanceTo(
isc.NewAssetsBaseTokens(1000),
isc.NewEthereumAddressAgentID(env.soloChain.ChainID, evmAddr),
wallet)

block := env.BlockByNumber(nil)
require.NoError(t, err)
txs := block.Transactions()
tx := txs[0]

require.Equal(t, evmAddr, *tx.To())

rc, err := env.TxReceipt(txs[0].Hash())
require.NoError(t, err)
require.EqualValues(t, types.ReceiptStatusSuccessful, rc.Status)

var res1 json.RawMessage
err = env.RawClient.CallContext(
context.Background(),
&res1,
"debug_traceTransaction",
tx.Hash().Hex(),
tracers.TraceConfig{TracerConfig: []byte(`{"tracer": "callTracer"}`)},
)
require.NoError(t, err)

var trace1 []jsonrpc.CallFrame
err = json.Unmarshal(res1, &trace1)
require.NoError(t, err)
require.Len(t, trace1, 0)
}

func TestRPCTraceBlock(t *testing.T) {
Expand Down Expand Up @@ -681,39 +722,47 @@ func TestRPCTraceBlock(t *testing.T) {

require.Equal(t, creatorAddress, trace1.From)
require.Equal(t, contractAddress, *trace1.To)
require.Equal(t, big.NewInt(123), trace1.Value)
require.Equal(t, "0x7b", trace1.Value.String())
expectedInput, err := contractABI.Pack("sendTo", common.Address{0x1}, big.NewInt(2))
require.NoError(t, err)
require.Equal(t, expectedInput, trace1.Input)
require.Empty(t, trace1.Error)
require.Empty(t, trace1.RevertReason)
require.Equal(t, "0x0", trace1.Gas.String())
require.Equal(t, "0x0", trace1.GasUsed.String())

require.Len(t, trace1.Calls, 1)
innerCall1 := trace1.Calls[0]
require.Equal(t, contractAddress, innerCall1.From)
require.Equal(t, common.Address{0x1}, *innerCall1.To)
require.Equal(t, big.NewInt(2), innerCall1.Value)
require.Equal(t, "0x2", innerCall1.Value.String())
require.Empty(t, innerCall1.Input)
require.Empty(t, innerCall1.Error)
require.Empty(t, innerCall1.RevertReason)
require.Contains(t, innerCall1.Gas.String(), "0x")
require.Contains(t, innerCall1.GasUsed.String(), "0x")

require.Equal(t, creatorAddress2, trace2.From)
require.Equal(t, contractAddress, *trace2.To)
require.Equal(t, big.NewInt(321), trace2.Value)
require.Equal(t, "0x141", trace2.Value.String())
expectedInput, err = contractABI.Pack("sendTo", common.Address{0x2}, big.NewInt(3))
require.NoError(t, err)
require.Equal(t, expectedInput, trace2.Input)
require.Empty(t, trace2.Error)
require.Empty(t, trace2.RevertReason)
require.Equal(t, "0x0", trace2.Gas.String())
require.Equal(t, "0x0", trace2.GasUsed.String())

require.Len(t, trace2.Calls, 1)
innerCall2 := trace2.Calls[0]
require.Equal(t, contractAddress, innerCall2.From)
require.Equal(t, common.Address{0x2}, *innerCall2.To)
require.Equal(t, big.NewInt(3), innerCall2.Value)
require.Equal(t, "0x3", innerCall2.Value.String())
require.Empty(t, innerCall2.Input)
require.Empty(t, innerCall2.Error)
require.Empty(t, innerCall2.RevertReason)
require.Contains(t, innerCall2.Gas.String(), "0x")
require.Contains(t, innerCall2.GasUsed.String(), "0x")
}

func TestRPCBlockReceipt(t *testing.T) {
Expand Down
16 changes: 8 additions & 8 deletions packages/evm/jsonrpc/tracer_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ type callLog struct {
type CallFrame struct {
Type vm.OpCode `json:"-"`
From common.Address `json:"from"`
Gas uint64 `json:"gas"`
GasUsed uint64 `json:"gasUsed"`
Gas hexutil.Uint64 `json:"gas"`
GasUsed hexutil.Uint64 `json:"gasUsed"`
To *common.Address `json:"to,omitempty" rlp:"optional"`
Input []byte `json:"input" rlp:"optional"`
Output []byte `json:"output,omitempty" rlp:"optional"`
Expand All @@ -46,7 +46,7 @@ type CallFrame struct {
Logs []callLog `json:"logs,omitempty" rlp:"optional"`
// Placed at end on purpose. The RLP will be decoded to 0 instead of
// nil if there are non-empty elements after in the struct.
Value *big.Int `json:"value,omitempty" rlp:"optional"`
Value hexutil.Big `json:"value,omitempty" rlp:"optional"`
revertedSnapshot bool
}

Expand Down Expand Up @@ -165,11 +165,11 @@ func (t *callTracer) OnEnter(depth int, typ byte, from common.Address, to common
From: from,
To: &toCopy,
Input: common.CopyBytes(input),
Gas: gas,
Value: value,
Gas: hexutil.Uint64(gas),
Value: hexutil.Big(*value),
}
if depth == 0 {
call.Gas = t.gasLimit
call.Gas = hexutil.Uint64(t.gasLimit)
}
t.callstack = append(t.callstack, call)
}
Expand All @@ -196,7 +196,7 @@ func (t *callTracer) OnExit(depth int, output []byte, gasUsed uint64, err error,
t.callstack = t.callstack[:size-1]
size--

call.GasUsed = gasUsed
call.GasUsed = hexutil.Uint64(gasUsed)
call.processOutput(output, err, reverted)
// Nest call into parent.
t.callstack[size-1].Calls = append(t.callstack[size-1].Calls, call)
Expand All @@ -218,7 +218,7 @@ func (t *callTracer) OnTxEnd(receipt *types.Receipt, err error) {
if err != nil {
return
}
t.callstack[0].GasUsed = receipt.GasUsed
t.callstack[0].GasUsed = hexutil.Uint64(receipt.GasUsed)
if t.config.WithLog {
// Logs are not emitted when the call fails
clearFailedLogs(&t.callstack[0], false)
Expand Down

0 comments on commit 3a1b4c2

Please sign in to comment.