Skip to content

Commit 7f02151

Browse files
committed
fix: update rpc module to include eth fix from ethereum#26064 and ethereum#26723
1 parent 9bb8c8c commit 7f02151

File tree

5 files changed

+82
-2
lines changed

5 files changed

+82
-2
lines changed

rpc/client.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
)
3333

3434
var (
35+
ErrBadResult = errors.New("bad result in JSON-RPC response")
3536
ErrClientQuit = errors.New("client is closed")
3637
ErrNoResult = errors.New("no result in JSON-RPC response")
3738
ErrSubscriptionQueueOverflow = errors.New("subscription queue overflow")
@@ -316,7 +317,10 @@ func (c *Client) CallContext(ctx context.Context, result interface{}, method str
316317
case len(resp.Result) == 0:
317318
return ErrNoResult
318319
default:
319-
return json.Unmarshal(resp.Result, &result)
320+
if result == nil {
321+
return nil
322+
}
323+
return json.Unmarshal(resp.Result, result)
320324
}
321325
}
322326

rpc/client_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package rpc
1818

1919
import (
2020
"context"
21+
"encoding/json"
22+
"errors"
2123
"fmt"
2224
"math/rand"
2325
"net"
@@ -35,6 +37,73 @@ import (
3537
"github.com/davecgh/go-spew/spew"
3638
)
3739

40+
// This test checks calling a method that returns 'null'.
41+
func TestClientNullResponse(t *testing.T) {
42+
server := newTestServer()
43+
defer server.Stop()
44+
45+
client := DialInProc(server)
46+
defer client.Close()
47+
48+
var result json.RawMessage
49+
if err := client.Call(&result, "test_null"); err != nil {
50+
t.Fatal(err)
51+
}
52+
if result == nil {
53+
t.Fatal("Expected non-nil result")
54+
}
55+
if !reflect.DeepEqual(result, json.RawMessage("null")) {
56+
t.Errorf("Expected null, got %s", result)
57+
}
58+
}
59+
60+
func TestClientBatchRequest_len(t *testing.T) {
61+
b, err := json.Marshal([]jsonrpcMessage{
62+
{Version: "2.0", ID: json.RawMessage("1"), Method: "foo", Result: json.RawMessage(`"0x1"`)},
63+
{Version: "2.0", ID: json.RawMessage("2"), Method: "bar", Result: json.RawMessage(`"0x2"`)},
64+
})
65+
if err != nil {
66+
t.Fatal("failed to encode jsonrpc message:", err)
67+
}
68+
s := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
69+
_, err := rw.Write(b)
70+
if err != nil {
71+
t.Error("failed to write response:", err)
72+
}
73+
}))
74+
t.Cleanup(s.Close)
75+
76+
client, err := Dial(s.URL)
77+
if err != nil {
78+
t.Fatal("failed to dial test server:", err)
79+
}
80+
defer client.Close()
81+
82+
t.Run("too-few", func(t *testing.T) {
83+
batch := []BatchElem{
84+
{Method: "foo"},
85+
{Method: "bar"},
86+
{Method: "baz"},
87+
}
88+
ctx, cancelFn := context.WithTimeout(context.Background(), time.Second)
89+
defer cancelFn()
90+
if err := client.BatchCallContext(ctx, batch); !errors.Is(err, ErrBadResult) {
91+
t.Errorf("expected %q but got: %v", ErrBadResult, err)
92+
}
93+
})
94+
95+
t.Run("too-many", func(t *testing.T) {
96+
batch := []BatchElem{
97+
{Method: "foo"},
98+
}
99+
ctx, cancelFn := context.WithTimeout(context.Background(), time.Second)
100+
defer cancelFn()
101+
if err := client.BatchCallContext(ctx, batch); !errors.Is(err, ErrBadResult) {
102+
t.Errorf("expected %q but got: %v", ErrBadResult, err)
103+
}
104+
})
105+
}
106+
38107
func TestClientRequest(t *testing.T) {
39108
server := newTestServer()
40109
defer server.Stop()

rpc/http.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,9 @@ func (c *Client) sendBatchHTTP(ctx context.Context, op *requestOp, msgs []*jsonr
170170
if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil {
171171
return err
172172
}
173+
if len(respmsgs) != len(msgs) {
174+
return fmt.Errorf("batch has %d requests but response has %d: %w", len(msgs), len(respmsgs), ErrBadResult)
175+
}
173176
for i := 0; i < len(respmsgs); i++ {
174177
op.resp <- &respmsgs[i]
175178
}

rpc/server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestServerRegisterName(t *testing.T) {
4545
t.Fatalf("Expected service calc to be registered")
4646
}
4747

48-
wantCallbacks := 9
48+
wantCallbacks := 10
4949
if len(svc.callbacks) != wantCallbacks {
5050
t.Errorf("Expected %d callbacks for service 'service', got %d", wantCallbacks, len(svc.callbacks))
5151
}

rpc/testservice_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ func (s *testService) Sleep(ctx context.Context, duration time.Duration) {
8484
time.Sleep(duration)
8585
}
8686

87+
func (s *testService) Null() any {
88+
return nil
89+
}
90+
8791
func (s *testService) Block(ctx context.Context) error {
8892
<-ctx.Done()
8993
return errors.New("context canceled in testservice_block")

0 commit comments

Comments
 (0)