add cache support for debug_getRawReceipts when request is for block hash

This commit is contained in:
Felipe Andrade 2023-05-31 10:48:21 -07:00
parent a2e1667b17
commit 64dab786cf
4 changed files with 52 additions and 3 deletions

@ -87,7 +87,7 @@ Cache use Redis and can be enabled for the following immutable methods:
* `eth_getBlockByHash` * `eth_getBlockByHash`
* `eth_getTransactionByBlockHashAndIndex` * `eth_getTransactionByBlockHashAndIndex`
* `eth_getUncleByBlockHashAndIndex` * `eth_getUncleByBlockHashAndIndex`
* `debug_getRawReceipts` (block hash only)
## Metrics ## Metrics

@ -2,6 +2,8 @@ package proxyd
import ( import (
"context" "context"
"encoding/json"
"github.com/ethereum/go-ethereum/rpc"
"strings" "strings"
"time" "time"
@ -124,6 +126,21 @@ type rpcCache struct {
func newRPCCache(cache Cache) RPCCache { func newRPCCache(cache Cache) RPCCache {
staticHandler := &StaticMethodHandler{cache: cache} 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{ handlers := map[string]RPCMethodHandler{
"eth_chainId": staticHandler, "eth_chainId": staticHandler,
"net_version": staticHandler, "net_version": staticHandler,
@ -132,6 +149,7 @@ func newRPCCache(cache Cache) RPCCache {
"eth_getBlockByHash": staticHandler, "eth_getBlockByHash": staticHandler,
"eth_getTransactionByBlockHashAndIndex": staticHandler, "eth_getTransactionByBlockHashAndIndex": staticHandler,
"eth_getUncleByBlockHashAndIndex": staticHandler, "eth_getUncleByBlockHashAndIndex": staticHandler,
"debug_getRawReceipts": debugGetRawReceiptsHandler,
} }
return &rpcCache{ return &rpcCache{
cache: cache, cache: cache,

@ -101,6 +101,20 @@ func TestRPCCacheImmutableRPCs(t *testing.T) {
}, },
name: "eth_getUncleByBlockHashAndIndex", 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 { for _, rpc := range rpcs {
@ -173,6 +187,15 @@ func TestRPCCacheUnsupportedMethod(t *testing.T) {
ID: ID, ID: ID,
}, },
}, },
{
req: &RPCReq{
JSONRPC: "2.0",
Method: "debug_getRawReceipts",
Params: mustMarshalJSON([]string{"0x100"}),
ID: ID,
},
name: "debug_getRawReceipts",
},
} }
for _, rpc := range rpcs { for _, rpc := range rpcs {

@ -19,6 +19,7 @@ type RPCMethodHandler interface {
type StaticMethodHandler struct { type StaticMethodHandler struct {
cache Cache cache Cache
m sync.RWMutex m sync.RWMutex
filter func(*RPCReq) bool
} }
func (e *StaticMethodHandler) key(req *RPCReq) string { 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 { if e.cache == nil {
return nil, nil return nil, nil
} }
if e.filter != nil && !e.filter(req) {
return nil, nil
}
e.m.RLock() e.m.RLock()
defer e.m.RUnlock() defer e.m.RUnlock()
@ -62,6 +67,9 @@ func (e *StaticMethodHandler) PutRPCMethod(ctx context.Context, req *RPCReq, res
if e.cache == nil { if e.cache == nil {
return nil return nil
} }
if e.filter != nil && !e.filter(req) {
return nil
}
e.m.Lock() e.m.Lock()
defer e.m.Unlock() defer e.m.Unlock()