From 33e1d84d16d05302210ac4d2f816c3d4d6908185 Mon Sep 17 00:00:00 2001 From: ManuelArto Date: Fri, 26 Jun 2026 15:38:32 +0200 Subject: [PATCH] internal/ethapi: return null for missing debug_getRawTransaction Change DebugAPI.GetRawTransaction return type from hexutil.Bytes to *hexutil.Bytes so that a not-found transaction serialises as JSON null instead of "0x". Add TestRPCDebugGetRawTransaction with golden files. --- internal/ethapi/api.go | 16 ++++++-- internal/ethapi/api_test.go | 39 +++++++++++++++++++ .../debug_getRawTransaction-found-legacy.json | 1 + .../debug_getRawTransaction-txhash-empty.json | 1 + ...bug_getRawTransaction-txhash-notfound.json | 1 + 5 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 internal/ethapi/testdata/debug_getRawTransaction-found-legacy.json create mode 100644 internal/ethapi/testdata/debug_getRawTransaction-txhash-empty.json create mode 100644 internal/ethapi/testdata/debug_getRawTransaction-txhash-notfound.json diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index ef600e87df..7904a1f3f8 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -2100,12 +2100,17 @@ func (api *DebugAPI) GetRawReceipts(ctx context.Context, blockNrOrHash rpc.Block } // GetRawTransaction returns the bytes of the transaction for the given hash. -func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { +func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (*hexutil.Bytes, error) { // Retrieve a finalized transaction, or a pooled otherwise found, tx, _, _, _ := api.b.GetCanonicalTransaction(hash) if !found { if tx = api.b.GetPoolTransaction(hash); tx != nil { - return tx.MarshalBinary() + blob, err := tx.MarshalBinary() + if err != nil { + return nil, err + } + b := hexutil.Bytes(blob) + return &b, nil } // If also not in the pool there is a chance the tx indexer is still in progress. if !api.b.TxIndexDone() { @@ -2114,7 +2119,12 @@ func (api *DebugAPI) GetRawTransaction(ctx context.Context, hash common.Hash) (h // Transaction is not found in the pool and the indexer is done. return nil, nil } - return tx.MarshalBinary() + blob, err := tx.MarshalBinary() + if err != nil { + return nil, err + } + b := hexutil.Bytes(blob) + return &b, nil } // PrintBlock retrieves a block and returns its pretty printed form. diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index 6bff5629e9..13bd8c96cc 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -4468,3 +4468,42 @@ func TestRPCGetRawTransactionByBlockNumberAndIndex(t *testing.T) { testRPCResponseWithFile(t, i, result, "eth_getRawTransactionByBlockNumberAndIndex", tt.file) } } + +func TestRPCDebugGetRawTransaction(t *testing.T) { + t.Parallel() + + var ( + backend, txHashes = setupReceiptBackend(t, 2) + api = NewDebugAPI(backend) + ) + + var testSuite = []struct { + txHash common.Hash + file string + }{ + // 0. legacy transfer tx (block 0 default case) + { + txHash: txHashes[0], + file: "found-legacy", + }, + // 1. zero hash, not in chain + { + txHash: common.Hash{}, + file: "txhash-empty", + }, + // 2. unknown hash, not in chain + { + txHash: common.HexToHash("deadbeef"), + file: "txhash-notfound", + }, + } + + for i, tt := range testSuite { + result, err := api.GetRawTransaction(context.Background(), tt.txHash) + if err != nil { + t.Errorf("test %d: want no error, have %v", i, err) + continue + } + testRPCResponseWithFile(t, i, result, "debug_getRawTransaction", tt.file) + } +} diff --git a/internal/ethapi/testdata/debug_getRawTransaction-found-legacy.json b/internal/ethapi/testdata/debug_getRawTransaction-found-legacy.json new file mode 100644 index 0000000000..90360566da --- /dev/null +++ b/internal/ethapi/testdata/debug_getRawTransaction-found-legacy.json @@ -0,0 +1 @@ +"0xf8658084342770c0825208940d3ab14bbad3d99f4203bd7a11acb94882050e7e8203e8801ba0cd190747077598c3b9c5f21ea06f8487d6ab1e23358fbe0e0e0c4e64651b68f3a0467ebcb2186b332969991e2e25244959dcdb3feb7652ff6b81ce96e646d86abd" \ No newline at end of file diff --git a/internal/ethapi/testdata/debug_getRawTransaction-txhash-empty.json b/internal/ethapi/testdata/debug_getRawTransaction-txhash-empty.json new file mode 100644 index 0000000000..ec747fa47d --- /dev/null +++ b/internal/ethapi/testdata/debug_getRawTransaction-txhash-empty.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/internal/ethapi/testdata/debug_getRawTransaction-txhash-notfound.json b/internal/ethapi/testdata/debug_getRawTransaction-txhash-notfound.json new file mode 100644 index 0000000000..ec747fa47d --- /dev/null +++ b/internal/ethapi/testdata/debug_getRawTransaction-txhash-notfound.json @@ -0,0 +1 @@ +null \ No newline at end of file