Merge pull request #5841 from ethereum-optimism/felipe/rewrite-debug-getRawReceipts
feat(proxyd): add support to rewrite debug_getRawReceipts
This commit is contained in:
commit
ae8bb0957d
@ -71,6 +71,7 @@ The following request methods are rewritten:
|
||||
* `eth_getBlockByNumber`
|
||||
* `eth_getTransactionByBlockNumberAndIndex`
|
||||
* `eth_getUncleByBlockNumberAndIndex`
|
||||
* `debug_getRawReceipts`
|
||||
|
||||
And `eth_blockNumber` response is overridden with current block consensus.
|
||||
|
||||
@ -86,7 +87,7 @@ Cache use Redis and can be enabled for the following immutable methods:
|
||||
* `eth_getBlockByHash`
|
||||
* `eth_getTransactionByBlockHashAndIndex`
|
||||
* `eth_getUncleByBlockHashAndIndex`
|
||||
|
||||
* `debug_getRawReceipts` (block hash only)
|
||||
|
||||
## Metrics
|
||||
|
||||
|
@ -2,9 +2,12 @@ package proxyd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
|
||||
"github.com/go-redis/redis/v8"
|
||||
"github.com/golang/snappy"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
@ -124,6 +127,21 @@ type rpcCache struct {
|
||||
|
||||
func newRPCCache(cache Cache) RPCCache {
|
||||
staticHandler := &StaticMethodHandler{cache: cache}
|
||||
debugGetRawReceiptsHandler := &StaticMethodHandler{cache: cache,
|
||||
filter: func(req *RPCReq) bool {
|
||||
// cache only if the request is for a block hash
|
||||
|
||||
var p []rpc.BlockNumberOrHash
|
||||
err := json.Unmarshal(req.Params, &p)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
if len(p) != 1 {
|
||||
return false
|
||||
}
|
||||
return p[0].BlockHash != nil
|
||||
},
|
||||
}
|
||||
handlers := map[string]RPCMethodHandler{
|
||||
"eth_chainId": staticHandler,
|
||||
"net_version": staticHandler,
|
||||
@ -132,6 +150,7 @@ func newRPCCache(cache Cache) RPCCache {
|
||||
"eth_getBlockByHash": staticHandler,
|
||||
"eth_getTransactionByBlockHashAndIndex": staticHandler,
|
||||
"eth_getUncleByBlockHashAndIndex": staticHandler,
|
||||
"debug_getRawReceipts": debugGetRawReceiptsHandler,
|
||||
}
|
||||
return &rpcCache{
|
||||
cache: cache,
|
||||
|
@ -101,6 +101,20 @@ func TestRPCCacheImmutableRPCs(t *testing.T) {
|
||||
},
|
||||
name: "eth_getUncleByBlockHashAndIndex",
|
||||
},
|
||||
{
|
||||
req: &RPCReq{
|
||||
JSONRPC: "2.0",
|
||||
Method: "debug_getRawReceipts",
|
||||
Params: mustMarshalJSON([]string{"0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b"}),
|
||||
ID: ID,
|
||||
},
|
||||
res: &RPCRes{
|
||||
JSONRPC: "2.0",
|
||||
Result: `{"debug_getRawReceipts":"!"}`,
|
||||
ID: ID,
|
||||
},
|
||||
name: "debug_getRawReceipts",
|
||||
},
|
||||
}
|
||||
|
||||
for _, rpc := range rpcs {
|
||||
@ -173,6 +187,15 @@ func TestRPCCacheUnsupportedMethod(t *testing.T) {
|
||||
ID: ID,
|
||||
},
|
||||
},
|
||||
{
|
||||
req: &RPCReq{
|
||||
JSONRPC: "2.0",
|
||||
Method: "debug_getRawReceipts",
|
||||
Params: mustMarshalJSON([]string{"0x100"}),
|
||||
ID: ID,
|
||||
},
|
||||
name: "debug_getRawReceipts",
|
||||
},
|
||||
}
|
||||
|
||||
for _, rpc := range rpcs {
|
||||
|
@ -17,8 +17,9 @@ type RPCMethodHandler interface {
|
||||
}
|
||||
|
||||
type StaticMethodHandler struct {
|
||||
cache Cache
|
||||
m sync.RWMutex
|
||||
cache Cache
|
||||
m sync.RWMutex
|
||||
filter func(*RPCReq) bool
|
||||
}
|
||||
|
||||
func (e *StaticMethodHandler) key(req *RPCReq) string {
|
||||
@ -33,6 +34,10 @@ func (e *StaticMethodHandler) GetRPCMethod(ctx context.Context, req *RPCReq) (*R
|
||||
if e.cache == nil {
|
||||
return nil, nil
|
||||
}
|
||||
if e.filter != nil && !e.filter(req) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
e.m.RLock()
|
||||
defer e.m.RUnlock()
|
||||
|
||||
@ -62,6 +67,9 @@ func (e *StaticMethodHandler) PutRPCMethod(ctx context.Context, req *RPCReq, res
|
||||
if e.cache == nil {
|
||||
return nil
|
||||
}
|
||||
if e.filter != nil && !e.filter(req) {
|
||||
return nil
|
||||
}
|
||||
|
||||
e.m.Lock()
|
||||
defer e.m.Unlock()
|
||||
|
@ -63,24 +63,26 @@ func RewriteRequest(rctx RewriteContext, req *RPCReq, res *RPCRes) (RewriteResul
|
||||
case "eth_getLogs",
|
||||
"eth_newFilter":
|
||||
return rewriteRange(rctx, req, res, 0)
|
||||
case "debug_getRawReceipts":
|
||||
return rewriteParam(rctx, req, res, 0, true)
|
||||
case "eth_getBalance",
|
||||
"eth_getCode",
|
||||
"eth_getTransactionCount",
|
||||
"eth_call":
|
||||
return rewriteParam(rctx, req, res, 1)
|
||||
return rewriteParam(rctx, req, res, 1, false)
|
||||
case "eth_getStorageAt":
|
||||
return rewriteParam(rctx, req, res, 2)
|
||||
return rewriteParam(rctx, req, res, 2, false)
|
||||
case "eth_getBlockTransactionCountByNumber",
|
||||
"eth_getUncleCountByBlockNumber",
|
||||
"eth_getBlockByNumber",
|
||||
"eth_getTransactionByBlockNumberAndIndex",
|
||||
"eth_getUncleByBlockNumberAndIndex":
|
||||
return rewriteParam(rctx, req, res, 0)
|
||||
return rewriteParam(rctx, req, res, 0, false)
|
||||
}
|
||||
return RewriteNone, nil
|
||||
}
|
||||
|
||||
func rewriteParam(rctx RewriteContext, req *RPCReq, res *RPCRes, pos int) (RewriteResult, error) {
|
||||
func rewriteParam(rctx RewriteContext, req *RPCReq, res *RPCRes, pos int, required bool) (RewriteResult, error) {
|
||||
var p []interface{}
|
||||
err := json.Unmarshal(req.Params, &p)
|
||||
if err != nil {
|
||||
@ -89,9 +91,9 @@ func rewriteParam(rctx RewriteContext, req *RPCReq, res *RPCRes, pos int) (Rewri
|
||||
|
||||
// we assume latest if the param is missing,
|
||||
// and we don't rewrite if there is not enough params
|
||||
if len(p) == pos {
|
||||
if len(p) == pos && !required {
|
||||
p = append(p, "latest")
|
||||
} else if len(p) < pos {
|
||||
} else if len(p) <= pos {
|
||||
return RewriteNone, nil
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,74 @@ func TestRewriteRequest(t *testing.T) {
|
||||
expected: RewriteOverrideError,
|
||||
expectedErr: ErrRewriteBlockOutOfRange,
|
||||
},
|
||||
/* required parameter at pos 0 */
|
||||
{
|
||||
name: "debug_getRawReceipts latest",
|
||||
args: args{
|
||||
rctx: RewriteContext{latest: hexutil.Uint64(100)},
|
||||
req: &RPCReq{Method: "debug_getRawReceipts", Params: mustMarshalJSON([]string{"latest"})},
|
||||
res: nil,
|
||||
},
|
||||
expected: RewriteOverrideRequest,
|
||||
check: func(t *testing.T, args args) {
|
||||
var p []string
|
||||
err := json.Unmarshal(args.req.Params, &p)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, len(p))
|
||||
require.Equal(t, hexutil.Uint64(100).String(), p[0])
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "debug_getRawReceipts within range",
|
||||
args: args{
|
||||
rctx: RewriteContext{latest: hexutil.Uint64(100)},
|
||||
req: &RPCReq{Method: "debug_getRawReceipts", Params: mustMarshalJSON([]string{hexutil.Uint64(55).String()})},
|
||||
res: nil,
|
||||
},
|
||||
expected: RewriteNone,
|
||||
check: func(t *testing.T, args args) {
|
||||
var p []string
|
||||
err := json.Unmarshal(args.req.Params, &p)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, len(p))
|
||||
require.Equal(t, hexutil.Uint64(55).String(), p[0])
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "debug_getRawReceipts out of range",
|
||||
args: args{
|
||||
rctx: RewriteContext{latest: hexutil.Uint64(100)},
|
||||
req: &RPCReq{Method: "debug_getRawReceipts", Params: mustMarshalJSON([]string{hexutil.Uint64(111).String()})},
|
||||
res: nil,
|
||||
},
|
||||
expected: RewriteOverrideError,
|
||||
expectedErr: ErrRewriteBlockOutOfRange,
|
||||
},
|
||||
{
|
||||
name: "debug_getRawReceipts missing parameter",
|
||||
args: args{
|
||||
rctx: RewriteContext{latest: hexutil.Uint64(100)},
|
||||
req: &RPCReq{Method: "debug_getRawReceipts", Params: mustMarshalJSON([]string{})},
|
||||
res: nil,
|
||||
},
|
||||
expected: RewriteNone,
|
||||
},
|
||||
{
|
||||
name: "debug_getRawReceipts with block hash",
|
||||
args: args{
|
||||
rctx: RewriteContext{latest: hexutil.Uint64(100)},
|
||||
req: &RPCReq{Method: "debug_getRawReceipts", Params: mustMarshalJSON([]string{"0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b"})},
|
||||
res: nil,
|
||||
},
|
||||
expected: RewriteNone,
|
||||
check: func(t *testing.T, args args) {
|
||||
var p []string
|
||||
err := json.Unmarshal(args.req.Params, &p)
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, 1, len(p))
|
||||
require.Equal(t, "0xc6ef2fc5426d6ad6fd9e2a26abeab0aa2411b7ab17f30a99d3cb96aed1d1055b", p[0])
|
||||
},
|
||||
},
|
||||
/* default block parameter */
|
||||
{
|
||||
name: "eth_getCode omit block, should add",
|
||||
|
Loading…
Reference in New Issue
Block a user