Skip to content

Commit 54d68c5

Browse files
committed
fix(proxyd): don't return error for out-of-range block requests
1 parent f9bf450 commit 54d68c5

File tree

4 files changed

+42
-49
lines changed

4 files changed

+42
-49
lines changed

proxyd/backend.go

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,6 @@ var (
9797
Message: "backend is currently not healthy to serve traffic",
9898
HTTPErrorCode: 503,
9999
}
100-
ErrBlockOutOfRange = &RPCErr{
101-
Code: JSONRPCErrorInternal - 19,
102-
Message: "block is out of range",
103-
HTTPErrorCode: 400,
104-
}
105-
106100
ErrRequestBodyTooLarge = &RPCErr{
107101
Code: JSONRPCErrorInternal - 21,
108102
Message: "request body too large",
@@ -1794,9 +1788,7 @@ func (bg *BackendGroup) OverwriteConsensusResponses(rpcReqs []*RPCReq, overridde
17941788
req: req,
17951789
res: &res,
17961790
})
1797-
if errors.Is(err, ErrRewriteBlockOutOfRange) {
1798-
res.Error = ErrBlockOutOfRange
1799-
} else if errors.Is(err, ErrRewriteRangeTooLarge) {
1791+
if errors.Is(err, ErrRewriteRangeTooLarge) {
18001792
res.Error = ErrInvalidParams(
18011793
fmt.Sprintf("block range greater than %d max", rctx.maxBlockRange),
18021794
)

proxyd/integration_tests/consensus_test.go

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -752,19 +752,26 @@ func TestConsensus(t *testing.T) {
752752
require.Equal(t, "0xe1", jsonMap["params"].([]interface{})[0])
753753
})
754754

755-
t.Run("rewrite request of eth_getBlockByNumber - out of range", func(t *testing.T) {
755+
t.Run("rewrite request of eth_getBlockByNumber - out of range is forwarded to backend", func(t *testing.T) {
756756
reset()
757757
useOnlyNode1()
758758

759+
// the request for a future block should be forwarded to the backend,
760+
// which returns null per the Ethereum JSON-RPC spec
761+
override("node1", "eth_getBlockByNumber", "0x300",
762+
`{"jsonrpc":"2.0","id":67,"result":null}`)
763+
759764
resRaw, statusCode, err := client.SendRPC("eth_getBlockByNumber", []interface{}{"0x300"})
760765
require.NoError(t, err)
761-
require.Equal(t, 400, statusCode)
766+
require.Equal(t, 200, statusCode)
762767

763768
var jsonMap map[string]interface{}
764769
err = json.Unmarshal(resRaw, &jsonMap)
765770
require.NoError(t, err)
766-
require.Equal(t, -32019, int(jsonMap["error"].(map[string]interface{})["code"].(float64)))
767-
require.Equal(t, "block is out of range", jsonMap["error"].(map[string]interface{})["message"])
771+
require.Nil(t, jsonMap["result"])
772+
require.Nil(t, jsonMap["error"])
773+
774+
require.Equal(t, 1, len(nodes["node1"].mockBackend.Requests()))
768775
})
769776

770777
t.Run("batched rewrite", func(t *testing.T) {
@@ -786,9 +793,8 @@ func TestConsensus(t *testing.T) {
786793
// rewrite latest to 0x101
787794
require.Equal(t, "0x101", jsonMap[0]["result"].(map[string]interface{})["number"])
788795

789-
// out of bounds for block 0x102
790-
require.Equal(t, -32019, int(jsonMap[1]["error"].(map[string]interface{})["code"].(float64)))
791-
require.Equal(t, "block is out of range", jsonMap[1]["error"].(map[string]interface{})["message"])
796+
// block 0x102 is beyond latest (0x101) but is forwarded to the backend
797+
require.Equal(t, "0x102", jsonMap[1]["result"].(map[string]interface{})["number"])
792798

793799
// dont rewrite for 0xe1
794800
require.Equal(t, "0xe1", jsonMap[2]["result"].(map[string]interface{})["number"])

proxyd/rewriter.go

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@ const (
3232
RewriteOverrideResponse
3333
)
3434

35-
var (
36-
ErrRewriteBlockOutOfRange = errors.New("block is out of range")
37-
ErrRewriteRangeTooLarge = errors.New("block range is too large")
38-
)
35+
var ErrRewriteRangeTooLarge = errors.New("block range is too large")
3936

4037
// RewriteTags modifies the request and the response based on block tags
4138
func RewriteTags(rctx RewriteContext, req *RPCReq, res *RPCRes) (RewriteResult, error) {
@@ -296,10 +293,6 @@ func rewriteTag(rctx RewriteContext, current string) (string, bool, error) {
296293
case rpc.LatestBlockNumber:
297294
return rctx.latest.String(), true, nil
298295
}
299-
default:
300-
if rctx.latest > 0 && bnh.BlockNumber.Int64() > int64(rctx.latest) {
301-
return "", false, ErrRewriteBlockOutOfRange
302-
}
303296
}
304297

305298
return current, false, nil
@@ -324,10 +317,6 @@ func rewriteTagBlockNumberOrHash(rctx RewriteContext, current *rpc.BlockNumberOr
324317
case rpc.LatestBlockNumber:
325318
bn := rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(rctx.latest))
326319
return &bn, true, nil
327-
default:
328-
if current.BlockNumber.Int64() > int64(rctx.latest) {
329-
return nil, false, ErrRewriteBlockOutOfRange
330-
}
331320
}
332321

333322
return current, false, nil

proxyd/rewriter_test.go

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,14 @@ func TestRewriteRequest(t *testing.T) {
6565
req: &RPCReq{Method: "eth_getLogs", Params: mustMarshalJSON([]map[string]interface{}{{"fromBlock": hexutil.Uint64(111).String()}})},
6666
res: nil,
6767
},
68-
expected: RewriteOverrideError,
69-
expectedErr: ErrRewriteBlockOutOfRange,
68+
expected: RewriteOverrideRequest,
69+
check: func(t *testing.T, args args) {
70+
var p []map[string]interface{}
71+
err := json.Unmarshal(args.req.Params, &p)
72+
require.Nil(t, err)
73+
require.Equal(t, hexutil.Uint64(111).String(), p[0]["fromBlock"])
74+
require.Equal(t, hexutil.Uint64(100).String(), p[0]["toBlock"])
75+
},
7076
},
7177
{
7278
name: "eth_getLogs toBlock latest",
@@ -105,8 +111,14 @@ func TestRewriteRequest(t *testing.T) {
105111
req: &RPCReq{Method: "eth_getLogs", Params: mustMarshalJSON([]map[string]interface{}{{"toBlock": hexutil.Uint64(111).String()}})},
106112
res: nil,
107113
},
108-
expected: RewriteOverrideError,
109-
expectedErr: ErrRewriteBlockOutOfRange,
114+
expected: RewriteOverrideRequest,
115+
check: func(t *testing.T, args args) {
116+
var p []map[string]interface{}
117+
err := json.Unmarshal(args.req.Params, &p)
118+
require.Nil(t, err)
119+
require.Equal(t, hexutil.Uint64(100).String(), p[0]["fromBlock"])
120+
require.Equal(t, hexutil.Uint64(111).String(), p[0]["toBlock"])
121+
},
110122
},
111123
{
112124
name: "eth_getLogs fromBlock, toBlock latest",
@@ -147,8 +159,7 @@ func TestRewriteRequest(t *testing.T) {
147159
req: &RPCReq{Method: "eth_getLogs", Params: mustMarshalJSON([]map[string]interface{}{{"fromBlock": hexutil.Uint64(111).String(), "toBlock": hexutil.Uint64(222).String()}})},
148160
res: nil,
149161
},
150-
expected: RewriteOverrideError,
151-
expectedErr: ErrRewriteBlockOutOfRange,
162+
expected: RewriteNone,
152163
},
153164
{
154165
name: "eth_getLogs fromBlock -> toBlock above max range",
@@ -240,14 +251,13 @@ func TestRewriteRequest(t *testing.T) {
240251
},
241252
},
242253
{
243-
name: "debug_getRawReceipts out of range",
254+
name: "debug_getRawReceipts out of range passes through to backend",
244255
args: args{
245256
rctx: RewriteContext{latest: hexutil.Uint64(100), consensusMode: true},
246257
req: &RPCReq{Method: "debug_getRawReceipts", Params: mustMarshalJSON([]string{hexutil.Uint64(111).String()})},
247258
res: nil,
248259
},
249-
expected: RewriteOverrideError,
250-
expectedErr: ErrRewriteBlockOutOfRange,
260+
expected: RewriteNone,
251261
},
252262
{
253263
name: "debug_getRawReceipts missing parameter",
@@ -346,14 +356,13 @@ func TestRewriteRequest(t *testing.T) {
346356
},
347357
},
348358
{
349-
name: "eth_getCode out of range",
359+
name: "eth_getCode out of range passes through to backend",
350360
args: args{
351361
rctx: RewriteContext{latest: hexutil.Uint64(100), consensusMode: true},
352362
req: &RPCReq{Method: "eth_getCode", Params: mustMarshalJSON([]string{"0x123", hexutil.Uint64(111).String()})},
353363
res: nil,
354364
},
355-
expected: RewriteOverrideError,
356-
expectedErr: ErrRewriteBlockOutOfRange,
365+
expected: RewriteNone,
357366
},
358367
/* default block parameter, at position 2 */
359368
{
@@ -415,14 +424,13 @@ func TestRewriteRequest(t *testing.T) {
415424
},
416425
},
417426
{
418-
name: "eth_getStorageAt out of range",
427+
name: "eth_getStorageAt out of range passes through to backend",
419428
args: args{
420429
rctx: RewriteContext{latest: hexutil.Uint64(100), consensusMode: true},
421430
req: &RPCReq{Method: "eth_getStorageAt", Params: mustMarshalJSON([]string{"0x123", "5", hexutil.Uint64(111).String()})},
422431
res: nil,
423432
},
424-
expected: RewriteOverrideError,
425-
expectedErr: ErrRewriteBlockOutOfRange,
433+
expected: RewriteNone,
426434
},
427435
/* default block parameter, at position 0 */
428436
{
@@ -506,14 +514,13 @@ func TestRewriteRequest(t *testing.T) {
506514
},
507515
},
508516
{
509-
name: "eth_getBlockByNumber out of range",
517+
name: "eth_getBlockByNumber out of range passes through to backend",
510518
args: args{
511519
rctx: RewriteContext{latest: hexutil.Uint64(100), consensusMode: true},
512520
req: &RPCReq{Method: "eth_getBlockByNumber", Params: mustMarshalJSON([]string{hexutil.Uint64(111).String()})},
513521
res: nil,
514522
},
515-
expected: RewriteOverrideError,
516-
expectedErr: ErrRewriteBlockOutOfRange,
523+
expected: RewriteNone,
517524
},
518525
{
519526
name: "eth_getStorageAt using rpc.BlockNumberOrHash",
@@ -595,7 +602,7 @@ func TestRewriteRequest(t *testing.T) {
595602
},
596603
},
597604
{
598-
name: "eth_getStorageAt using rpc.BlockNumberOrHash out of range",
605+
name: "eth_getStorageAt using rpc.BlockNumberOrHash out of range passes through to backend",
599606
args: args{
600607
rctx: RewriteContext{latest: hexutil.Uint64(100), consensusMode: true},
601608
req: &RPCReq{Method: "eth_getStorageAt", Params: mustMarshalJSON([]interface{}{
@@ -606,8 +613,7 @@ func TestRewriteRequest(t *testing.T) {
606613
}})},
607614
res: nil,
608615
},
609-
expected: RewriteOverrideError,
610-
expectedErr: ErrRewriteBlockOutOfRange,
616+
expected: RewriteNone,
611617
},
612618
}
613619

0 commit comments

Comments
 (0)