Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions ethclient/gethclient/gethclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,17 @@ func (ec *Client) CallContractWithBlockOverrides(ctx context.Context, msg ethere
return hex, err
}

// BlockReceipts returns the receipts of a given block number or hash.
// This wrapper preserves geth-specific flags such as requireCanonical.
func (ec *Client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]*types.Receipt, error) {
var r []*types.Receipt
err := ec.c.CallContext(ctx, &r, "eth_getBlockReceipts", blockNrOrHash)
if err == nil && r == nil {
return nil, ethereum.NotFound
}
return r, err
}

// GCStats retrieves the current garbage collection stats from a geth node.
func (ec *Client) GCStats(ctx context.Context) (*debug.GCStats, error) {
var result debug.GCStats
Expand Down
41 changes: 41 additions & 0 deletions ethclient/gethclient/gethclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,3 +620,44 @@ func testCallContractWithBlockOverrides(t *testing.T, client *rpc.Client) {
t.Fatalf("unexpected result: %x", res)
}
}

func TestGethClientBlockReceiptsPreservesRequireCanonical(t *testing.T) {
server := rpc.NewServer()
service := &testGethBlockReceiptsService{}
if err := server.RegisterName("eth", service); err != nil {
t.Fatalf("failed to register test service: %v", err)
}
defer server.Stop()

rpcClient := rpc.DialInProc(server)
defer rpcClient.Close()

client := New(rpcClient)

hash := common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111")
arg := rpc.BlockNumberOrHashWithHash(hash, true)

if _, err := client.BlockReceipts(context.Background(), arg); err != nil {
t.Fatalf("BlockReceipts returned error: %v", err)
}
if !service.called {
t.Fatalf("expected GetBlockReceipts to be called")
}
if !service.lastArg.RequireCanonical {
t.Fatalf("requireCanonical flag was not preserved")
}
if service.lastArg.BlockHash == nil || *service.lastArg.BlockHash != hash {
t.Fatalf("unexpected block hash: %v", service.lastArg.BlockHash)
}
}

type testGethBlockReceiptsService struct {
lastArg rpc.BlockNumberOrHash
called bool
}

func (s *testGethBlockReceiptsService) GetBlockReceipts(ctx context.Context, arg rpc.BlockNumberOrHash) ([]*types.Receipt, error) {
s.lastArg = arg
s.called = true
return []*types.Receipt{}, nil
}