Skip to content

Commit

Permalink
make shards inclusive of end block
Browse files Browse the repository at this point in the history
  • Loading branch information
pirtleshell committed Mar 4, 2024
1 parent fb04d8b commit b468bb9
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 16 deletions.
10 changes: 5 additions & 5 deletions config/intervalmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ import (

// IntervalURLMap stores URLs associated with a range of numbers.
// The intervals are defined by their endpoints and must not overlap.
// The intervals are exclusive of the endpoints.
// The intervals are inclusive of the endpoints.
type IntervalURLMap struct {
UrlByEndHeight map[uint64]*url.URL
endpoints []uint64
}

// NewIntervalURLMap creates a new IntervalMap from a map of interval endpoint => url.
// The intervals are exclusive of their endpoint.
// ie. if the lowest value endpoint in the map is 10, the interval is for all numbers 1 through 9.
// The intervals are inclusive of their endpoint.
// ie. if the lowest value endpoint in the map is 10, the interval is for all numbers 1 through 10.
func NewIntervalURLMap(urlByEndHeight map[uint64]*url.URL) IntervalURLMap {
endpoints := make([]uint64, 0, len(urlByEndHeight))
for e := range urlByEndHeight {
Expand All @@ -31,9 +31,9 @@ func NewIntervalURLMap(urlByEndHeight map[uint64]*url.URL) IntervalURLMap {

// Lookup finds the value associated with the interval containing the number, if it exists.
func (im *IntervalURLMap) Lookup(num uint64) (*url.URL, uint64, bool) {
i := sort.Search(len(im.endpoints), func(i int) bool { return im.endpoints[i] > num })
i := sort.Search(len(im.endpoints), func(i int) bool { return im.endpoints[i] >= num })

if i < len(im.endpoints) && num < im.endpoints[i] {
if i < len(im.endpoints) && num <= im.endpoints[i] {
return im.UrlByEndHeight[im.endpoints[i]], im.endpoints[i], true
}

Expand Down
11 changes: 6 additions & 5 deletions config/intervalmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,20 @@ func TestUnitTestIntervalMap(t *testing.T) {
}{
{1, true, 10, "A"},
{9, true, 10, "A"},
{10, true, 20, "B"},
{10, true, 10, "A"},
{15, true, 20, "B"},
{20, true, 100, "C"},
{20, true, 20, "B"},
{75, true, 100, "C"},
{100, false, 0, ""},
{100, true, 100, "C"},
{101, false, 0, ""},
{300, false, 0, ""},
}

for _, tc := range testCases {
t.Run(fmt.Sprintf("Lookup(%d)", tc.value), func(t *testing.T) {
result, endHeight, found := intervalmap.Lookup(tc.value)
require.Equal(t, tc.expectFound, found)
require.Equal(t, tc.expectEndHeight, endHeight)
require.Equal(t, tc.expectFound, found, "unexpected found value")
require.Equal(t, tc.expectEndHeight, endHeight, "unexpected end height found")
if tc.expectResult == "" {
require.Nil(t, result)
} else {
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ services:
- "${KAVA_CONTAINER_EVM_RPC_PORT}"

# shards are in name only. they are standard peer nodes, but will only recieve traffic
# for a specific block range. kava-shard-10 receives requests for heights 1-9
# for a specific block range. kava-shard-10 receives requests for heights 1-10
kava-shard-10:
image: kava/kava:${KAVA_CONTAINER_TAG}
entrypoint: /docker/shared/kava-entrypoint.sh
Expand All @@ -66,7 +66,7 @@ services:
- "${KAVA_CONTAINER_EVM_RPC_PORT}"

# shards are in name only. they are standard peer nodes, but will only recieve traffic
# for a specific block range. kava-shard-20 receives requests for heights 10-19
# for a specific block range. kava-shard-20 receives requests for heights 11-20
kava-shard-20:
image: kava/kava:${KAVA_CONTAINER_TAG}
entrypoint: /docker/shared/kava-entrypoint.sh
Expand Down
41 changes: 37 additions & 4 deletions service/shard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ func TestUnitTest_PruningOrDefaultProxies(t *testing.T) {
}
require.True(t, found, "expected proxy to be found")
require.NotNil(t, proxy)
require.Equal(t, metadata.BackendName, tc.expectBackend)
require.Equal(t, metadata.BackendRoute.String(), tc.expectRoute)
require.Equal(t, tc.expectBackend, metadata.BackendName)
require.Equal(t, tc.expectRoute, metadata.BackendRoute.String())
requireProxyRoutesToUrl(t, proxy, req, tc.expectRoute)
})
}
Expand Down Expand Up @@ -315,6 +315,28 @@ func TestUnitTest_ShardProxies(t *testing.T) {
expectBackend: service.ResponseBackendShard,
expectRoute: shard1Backend,
},
{
name: "end block of shard 1 routes to shard 1",
url: "//archive.kava.io",
req: &decode.EVMRPCRequestEnvelope{
Method: "eth_getBlockByNumber",
Params: []interface{}{"0xA", false}, // block 10
},
expectFound: true,
expectBackend: service.ResponseBackendShard,
expectRoute: shard1Backend,
},
{
name: "first block of shard 2 routes to shard 2",
url: "//archive.kava.io",
req: &decode.EVMRPCRequestEnvelope{
Method: "eth_getBlockByNumber",
Params: []interface{}{"0xB", false}, // block 11
},
expectFound: true,
expectBackend: service.ResponseBackendShard,
expectRoute: shard2Backend,
},
{
name: "routes to shard 2 for specific height in shard 2",
url: "//archive.kava.io",
Expand All @@ -326,6 +348,17 @@ func TestUnitTest_ShardProxies(t *testing.T) {
expectBackend: service.ResponseBackendShard,
expectRoute: shard2Backend,
},
{
name: "end block of shard 2 routes to shard 2",
url: "//archive.kava.io",
req: &decode.EVMRPCRequestEnvelope{
Method: "eth_getBlockByNumber",
Params: []interface{}{"0x14", false}, // block 20
},
expectFound: true,
expectBackend: service.ResponseBackendShard,
expectRoute: shard2Backend,
},
}

for _, tc := range testCases {
Expand All @@ -338,8 +371,8 @@ func TestUnitTest_ShardProxies(t *testing.T) {
}
require.True(t, found, "expected proxy to be found")
require.NotNil(t, proxy)
require.Equal(t, metadata.BackendName, tc.expectBackend)
require.Equal(t, metadata.BackendRoute.String(), tc.expectRoute)
require.Equal(t, tc.expectBackend, metadata.BackendName)
require.Equal(t, tc.expectRoute, metadata.BackendRoute.String())
requireProxyRoutesToUrl(t, proxy, req, tc.expectRoute)
})
}
Expand Down

0 comments on commit b468bb9

Please sign in to comment.