Skip to content

Commit 43883c6

Browse files
authored
eth/tracers: hex-encode returnValue (#31216)
This is a **breaking change** to the opcode tracer. The top-level `returnValue` field of a trace will be now hex-encoded. If the return data is empty, this field will contain "0x". Fixes #31196
1 parent 03cc294 commit 43883c6

File tree

2 files changed

+24
-25
lines changed

2 files changed

+24
-25
lines changed

Diff for: eth/tracers/api_test.go

+21-21
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ func TestTraceCall(t *testing.T) {
354354
},
355355
config: nil,
356356
expectErr: nil,
357-
expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
357+
expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`,
358358
},
359359
// Standard JSON trace upon the head, plain transfer.
360360
{
@@ -366,7 +366,7 @@ func TestTraceCall(t *testing.T) {
366366
},
367367
config: nil,
368368
expectErr: nil,
369-
expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
369+
expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`,
370370
},
371371
// Upon the last state, default to the post block's state
372372
{
@@ -377,7 +377,7 @@ func TestTraceCall(t *testing.T) {
377377
Value: (*hexutil.Big)(new(big.Int).Add(big.NewInt(params.Ether), big.NewInt(100))),
378378
},
379379
config: nil,
380-
expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
380+
expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`,
381381
},
382382
// Before the first transaction, should be failed
383383
{
@@ -411,7 +411,7 @@ func TestTraceCall(t *testing.T) {
411411
},
412412
config: &TraceCallConfig{TxIndex: uintPtr(2)},
413413
expectErr: nil,
414-
expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
414+
expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`,
415415
},
416416
// Standard JSON trace upon the non-existent block, error expects
417417
{
@@ -435,7 +435,7 @@ func TestTraceCall(t *testing.T) {
435435
},
436436
config: nil,
437437
expectErr: nil,
438-
expect: `{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}`,
438+
expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`,
439439
},
440440
// Tracing on 'pending' should fail:
441441
{
@@ -458,7 +458,7 @@ func TestTraceCall(t *testing.T) {
458458
BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
459459
},
460460
expectErr: nil,
461-
expect: ` {"gas":53018,"failed":false,"returnValue":"","structLogs":[
461+
expect: ` {"gas":53018,"failed":false,"returnValue":"0x","structLogs":[
462462
{"pc":0,"op":"NUMBER","gas":24946984,"gasCost":2,"depth":1,"stack":[]},
463463
{"pc":1,"op":"STOP","gas":24946982,"gasCost":0,"depth":1,"stack":["0x1337"]}]}`,
464464
},
@@ -535,7 +535,7 @@ func TestTraceTransaction(t *testing.T) {
535535
if !reflect.DeepEqual(have, &logger.ExecutionResult{
536536
Gas: params.TxGas,
537537
Failed: false,
538-
ReturnValue: "",
538+
ReturnValue: []byte{},
539539
StructLogs: []json.RawMessage{},
540540
}) {
541541
t.Error("Transaction tracing result is different")
@@ -596,7 +596,7 @@ func TestTraceBlock(t *testing.T) {
596596
// Trace head block
597597
{
598598
blockNumber: rpc.BlockNumber(genBlocks),
599-
want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash),
599+
want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}}]`, txHash),
600600
},
601601
// Trace non-existent block
602602
{
@@ -606,12 +606,12 @@ func TestTraceBlock(t *testing.T) {
606606
// Trace latest block
607607
{
608608
blockNumber: rpc.LatestBlockNumber,
609-
want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash),
609+
want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}}]`, txHash),
610610
},
611611
// Trace pending block
612612
{
613613
blockNumber: rpc.PendingBlockNumber,
614-
want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}]`, txHash),
614+
want: fmt.Sprintf(`[{"txHash":"%v","result":{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}}]`, txHash),
615615
},
616616
}
617617
for i, tc := range testSuite {
@@ -704,7 +704,7 @@ func TestTracingWithOverrides(t *testing.T) {
704704
randomAccounts[0].addr: override.OverrideAccount{Balance: newRPCBalance(new(big.Int).Mul(big.NewInt(1), big.NewInt(params.Ether)))},
705705
},
706706
},
707-
want: `{"gas":21000,"failed":false,"returnValue":""}`,
707+
want: `{"gas":21000,"failed":false,"returnValue":"0x"}`,
708708
},
709709
// Invalid call without state overriding
710710
{
@@ -749,7 +749,7 @@ func TestTracingWithOverrides(t *testing.T) {
749749
},
750750
},
751751
},
752-
want: `{"gas":23347,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000007b"}`,
752+
want: `{"gas":23347,"failed":false,"returnValue":"0x000000000000000000000000000000000000000000000000000000000000007b"}`,
753753
},
754754
{ // Override blocknumber
755755
blockNumber: rpc.LatestBlockNumber,
@@ -761,7 +761,7 @@ func TestTracingWithOverrides(t *testing.T) {
761761
config: &TraceCallConfig{
762762
BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
763763
},
764-
want: `{"gas":59537,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000001337"}`,
764+
want: `{"gas":59537,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000001337"}`,
765765
},
766766
{ // Override blocknumber, and query a blockhash
767767
blockNumber: rpc.LatestBlockNumber,
@@ -781,7 +781,7 @@ func TestTracingWithOverrides(t *testing.T) {
781781
config: &TraceCallConfig{
782782
BlockOverrides: &override.BlockOverrides{Number: (*hexutil.Big)(big.NewInt(0x1337))},
783783
},
784-
want: `{"gas":72666,"failed":false,"returnValue":"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}`,
784+
want: `{"gas":72666,"failed":false,"returnValue":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}`,
785785
},
786786
/*
787787
pragma solidity =0.8.12;
@@ -815,7 +815,7 @@ func TestTracingWithOverrides(t *testing.T) {
815815
},
816816
},
817817
},
818-
want: `{"gas":44100,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001"}`,
818+
want: `{"gas":44100,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000001"}`,
819819
},
820820
{ // Same again, this time with storage override
821821
blockNumber: rpc.LatestBlockNumber,
@@ -833,7 +833,7 @@ func TestTracingWithOverrides(t *testing.T) {
833833
},
834834
},
835835
//want: `{"gas":46900,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000539"}`,
836-
want: `{"gas":44100,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001"}`,
836+
want: `{"gas":44100,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000001"}`,
837837
},
838838
{ // No state override
839839
blockNumber: rpc.LatestBlockNumber,
@@ -863,7 +863,7 @@ func TestTracingWithOverrides(t *testing.T) {
863863
},
864864
},
865865
},
866-
want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000077"}`,
866+
want: `{"gas":25288,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000077"}`,
867867
},
868868
{ // Full state override
869869
// The original storage is
@@ -901,7 +901,7 @@ func TestTracingWithOverrides(t *testing.T) {
901901
},
902902
},
903903
},
904-
want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000011"}`,
904+
want: `{"gas":25288,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000011"}`,
905905
},
906906
{ // Partial state override
907907
// The original storage is
@@ -939,7 +939,7 @@ func TestTracingWithOverrides(t *testing.T) {
939939
},
940940
},
941941
},
942-
want: `{"gas":25288,"failed":false,"returnValue":"0000000000000000000000000000000000000000000000000000000000000055"}`,
942+
want: `{"gas":25288,"failed":false,"returnValue":"0x0000000000000000000000000000000000000000000000000000000000000055"}`,
943943
},
944944
{ // Call to precompile ECREC (0x01), but code was modified to add 1 to input
945945
blockNumber: rpc.LatestBlockNumber,
@@ -1084,7 +1084,7 @@ func TestTraceChain(t *testing.T) {
10841084
backend.relHook = func() { rel.Add(1) }
10851085
api := NewAPI(backend)
10861086

1087-
single := `{"txHash":"0x0000000000000000000000000000000000000000000000000000000000000000","result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}`
1087+
single := `{"txHash":"0x0000000000000000000000000000000000000000000000000000000000000000","result":{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}}`
10881088
var cases = []struct {
10891089
start uint64
10901090
end uint64
@@ -1198,7 +1198,7 @@ func TestTraceBlockWithBasefee(t *testing.T) {
11981198
// Trace head block
11991199
{
12001200
blockNumber: rpc.BlockNumber(genBlocks),
1201-
want: fmt.Sprintf(`[{"txHash":"%#x","result":{"gas":21002,"failed":false,"returnValue":"","structLogs":[{"pc":0,"op":"BASEFEE","gas":84000,"gasCost":2,"depth":1,"stack":[]},{"pc":1,"op":"STOP","gas":83998,"gasCost":0,"depth":1,"stack":["%#x"]}]}}]`, txHash, baseFee),
1201+
want: fmt.Sprintf(`[{"txHash":"%#x","result":{"gas":21002,"failed":false,"returnValue":"0x","structLogs":[{"pc":0,"op":"BASEFEE","gas":84000,"gasCost":2,"depth":1,"stack":[]},{"pc":1,"op":"STOP","gas":83998,"gasCost":0,"depth":1,"stack":["%#x"]}]}}]`, txHash, baseFee),
12021202
},
12031203
}
12041204
for i, tc := range testSuite {

Diff for: eth/tracers/logger/logger.go

+3-4
Original file line numberDiff line numberDiff line change
@@ -350,14 +350,13 @@ func (l *StructLogger) GetResult() (json.RawMessage, error) {
350350
failed := l.err != nil
351351
returnData := common.CopyBytes(l.output)
352352
// Return data when successful and revert reason when reverted, otherwise empty.
353-
returnVal := fmt.Sprintf("%x", returnData)
354353
if failed && !errors.Is(l.err, vm.ErrExecutionReverted) {
355-
returnVal = ""
354+
returnData = []byte{}
356355
}
357356
return json.Marshal(&ExecutionResult{
358357
Gas: l.usedGas,
359358
Failed: failed,
360-
ReturnValue: returnVal,
359+
ReturnValue: returnData,
361360
StructLogs: l.logs,
362361
})
363362
}
@@ -527,6 +526,6 @@ func (t *mdLogger) OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.O
527526
type ExecutionResult struct {
528527
Gas uint64 `json:"gas"`
529528
Failed bool `json:"failed"`
530-
ReturnValue string `json:"returnValue"`
529+
ReturnValue hexutil.Bytes `json:"returnValue"`
531530
StructLogs []json.RawMessage `json:"structLogs"`
532531
}

0 commit comments

Comments
 (0)