From bbca4de3fd5d300c7a79a15eefd2fd9a4dc1b57d Mon Sep 17 00:00:00 2001 From: Robert Pirtle Date: Mon, 4 Mar 2024 11:56:06 -0800 Subject: [PATCH] route "earliest" to first shard also, prevent uint64 conversion underflows by routing any other block tag that is encoded to a negative number to the default proxy --- main_test.go | 4 ++-- service/shard.go | 14 +++++++++++++- service/shard_test.go | 23 +++++++++++------------ 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/main_test.go b/main_test.go index f0f7bb8..6f554bd 100644 --- a/main_test.go +++ b/main_test.go @@ -441,10 +441,10 @@ func TestE2ETest_HeightBasedRouting(t *testing.T) { expectRoute: service.ResponseBackendShard, }, { - name: "request for earliest height -> default", + name: "request for earliest height -> 1st shard", method: "eth_getBlockByNumber", params: []interface{}{"earliest", false}, - expectRoute: service.ResponseBackendDefault, + expectRoute: service.ResponseBackendShard, }, { name: "request for latest height -> pruning", diff --git a/service/shard.go b/service/shard.go index e9e6e6d..893802f 100644 --- a/service/shard.go +++ b/service/shard.go @@ -129,12 +129,24 @@ func (sp ShardProxies) ProxyForRequest(r *http.Request) (*httputil.ReverseProxy, } // parse height from the request - height, err := decode.ParseBlockNumberFromParams(decodedReq.Method, decodedReq.Params) + parsedHeight, err := decode.ParseBlockNumberFromParams(decodedReq.Method, decodedReq.Params) if err != nil { sp.Error().Msg(fmt.Sprintf("expected but failed to parse block number for %+v: %s", decodedReq, err)) return sp.defaultProxies.ProxyForRequest(r) } + // handle encoded block numbers + height := parsedHeight + if height == decode.BlockTagToNumberCodec[decode.BlockTagEarliest] { + // convert "earliest" to "1" so it routes to first shard + height = 1 + } else if parsedHeight < 1 { + // route all other encoded tags to default proxy. + // in practice, this is unreachable because they will be handled by the pruning Proxies + // if shard routing is enabled without PruningOrDefaultProxies, this handles all special block tags + return sp.defaultProxies.ProxyForRequest(r) + } + // look for shard including height url, shardHeight, found := shardsForHost.Lookup(uint64(height)) if !found { diff --git a/service/shard_test.go b/service/shard_test.go index 60e36ff..1f9c06a 100644 --- a/service/shard_test.go +++ b/service/shard_test.go @@ -236,18 +236,6 @@ func TestUnitTest_ShardProxies(t *testing.T) { expectBackend: service.ResponseBackendDefault, expectRoute: archiveBackend, }, - { - // TODO: should it do this? if shards exist, route to first shard? - name: "routes to default for 'earliest' block", - url: "//archive.kava.io", - req: &decode.EVMRPCRequestEnvelope{ - Method: "eth_getBlockByNumber", - Params: []interface{}{"earliest", false}, - }, - expectFound: true, - expectBackend: service.ResponseBackendDefault, - expectRoute: archiveBackend, - }, // PRUNING ROUTE CASES { @@ -305,6 +293,17 @@ func TestUnitTest_ShardProxies(t *testing.T) { }, // SHARD ROUTE CASES + { + name: "routes to 1st shard for 'earliest' block", + url: "//archive.kava.io", + req: &decode.EVMRPCRequestEnvelope{ + Method: "eth_getBlockByNumber", + Params: []interface{}{"earliest", false}, + }, + expectFound: true, + expectBackend: service.ResponseBackendShard, + expectRoute: shard1Backend, + }, { name: "routes to shard 1 for specific height in shard 1", url: "//archive.kava.io",