Skip to content

Commit f4e202a

Browse files
Merge branch 'main' into granite
2 parents 0c04498 + bf1aa87 commit f4e202a

File tree

2 files changed

+185
-4
lines changed

2 files changed

+185
-4
lines changed

pkg/application/app.go

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,50 @@ func (app *Avalanche) UpdateSidecarNetworks(
653653
return nil
654654
}
655655

656+
// extractBlockchainIDFromEndpoint extracts the blockchain ID from an RPC or WS endpoint URL.
657+
// Expected format: {scheme}://{host}/ext/bc/{blockchainID}/{rpc|ws}
658+
// Returns empty string if the blockchain ID cannot be extracted.
659+
func extractBlockchainIDFromEndpoint(endpoint string) string {
660+
// Look for /ext/bc/ pattern followed by the blockchain ID
661+
const bcPrefix = "/ext/bc/"
662+
bcIndex := strings.Index(endpoint, bcPrefix)
663+
if bcIndex == -1 {
664+
return ""
665+
}
666+
667+
// Extract the part after /ext/bc/
668+
afterBC := endpoint[bcIndex+len(bcPrefix):]
669+
670+
// The blockchain ID is everything before the next /
671+
slashIndex := strings.Index(afterBC, "/")
672+
if slashIndex == -1 {
673+
return ""
674+
}
675+
676+
return afterBC[:slashIndex]
677+
}
678+
679+
// filterOutdatedBlockchainEndpoints removes endpoints that contain a blockchain ID
680+
// that doesn't match the current blockchain ID. Endpoints without a blockchain ID
681+
// in the URL are preserved.
682+
func filterOutdatedBlockchainEndpoints(endpoints []string, currentBlockchainID string) []string {
683+
if currentBlockchainID == "" {
684+
return endpoints
685+
}
686+
687+
filtered := []string{}
688+
for _, endpoint := range endpoints {
689+
extractedID := extractBlockchainIDFromEndpoint(endpoint)
690+
// Keep endpoint if:
691+
// 1. It doesn't contain a blockchain ID pattern (extractedID == "")
692+
// 2. It contains the current blockchain ID
693+
if extractedID == "" || extractedID == currentBlockchainID {
694+
filtered = append(filtered, endpoint)
695+
}
696+
}
697+
return filtered
698+
}
699+
656700
// AddDefaultBlockchainRPCsToSidecar, given a list of (public) node URIs, it generates
657701
// the default blockchain RPC and WS endpoints for those URIs, and adds them
658702
// to the blockchain's sidecar as blockchain URLs
@@ -669,11 +713,17 @@ func (app *Avalanche) AddDefaultBlockchainRPCsToSidecar(
669713
if networkInfo.BlockchainID == ids.Empty {
670714
return sc, fmt.Errorf("blockchain %s has not been deployed to %s", blockchainName, networkModel.Name())
671715
}
672-
rpcEndpoints := set.Of(networkInfo.RPCEndpoints...)
673-
wsEndpoints := set.Of(networkInfo.WSEndpoints...)
716+
717+
// Filter out endpoints that reference old blockchain IDs
718+
currentBlockchainID := networkInfo.BlockchainID.String()
719+
filteredRPCEndpoints := filterOutdatedBlockchainEndpoints(networkInfo.RPCEndpoints, currentBlockchainID)
720+
filteredWSEndpoints := filterOutdatedBlockchainEndpoints(networkInfo.WSEndpoints, currentBlockchainID)
721+
722+
rpcEndpoints := set.Of(filteredRPCEndpoints...)
723+
wsEndpoints := set.Of(filteredWSEndpoints...)
674724
for _, nodeURI := range nodeURIs {
675-
rpcEndpoints.Add(models.GetRPCEndpoint(nodeURI, networkInfo.BlockchainID.String()))
676-
wsEndpoints.Add(models.GetWSEndpoint(nodeURI, networkInfo.BlockchainID.String()))
725+
rpcEndpoints.Add(models.GetRPCEndpoint(nodeURI, currentBlockchainID))
726+
wsEndpoints.Add(models.GetWSEndpoint(nodeURI, currentBlockchainID))
677727
}
678728
networkInfo.RPCEndpoints = rpcEndpoints.List()
679729
networkInfo.WSEndpoints = wsEndpoints.List()

pkg/application/app_test.go

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,3 +283,134 @@ func newTestApp(t *testing.T) *Avalanche {
283283
Log: logging.NoLog{},
284284
}
285285
}
286+
287+
func TestExtractBlockchainIDFromEndpoint(t *testing.T) {
288+
tests := []struct {
289+
name string
290+
endpoint string
291+
expected string
292+
}{
293+
{
294+
name: "valid RPC endpoint",
295+
endpoint: "http://127.0.0.1:55067/ext/bc/2ATnxvq9GwPrEPHyULDJqpanFNJecvzSGZ3w5jMzfZAWSmXC6u/rpc",
296+
expected: "2ATnxvq9GwPrEPHyULDJqpanFNJecvzSGZ3w5jMzfZAWSmXC6u",
297+
},
298+
{
299+
name: "valid WS endpoint",
300+
endpoint: "ws://127.0.0.1:55067/ext/bc/X2oDj86zGjCRCy6vd8Cca4FDStMeFAHWc7SUUygPCCfYf9sHh/ws",
301+
expected: "X2oDj86zGjCRCy6vd8Cca4FDStMeFAHWc7SUUygPCCfYf9sHh",
302+
},
303+
{
304+
name: "endpoint without blockchain ID",
305+
endpoint: "http://127.0.0.1:9650/ext/info",
306+
expected: "",
307+
},
308+
{
309+
name: "endpoint with no path after blockchain ID",
310+
endpoint: "http://127.0.0.1:9650/ext/bc/someblockchainid",
311+
expected: "",
312+
},
313+
{
314+
name: "empty endpoint",
315+
endpoint: "",
316+
expected: "",
317+
},
318+
}
319+
320+
for _, tt := range tests {
321+
t.Run(tt.name, func(t *testing.T) {
322+
require := require.New(t)
323+
result := extractBlockchainIDFromEndpoint(tt.endpoint)
324+
require.Equal(tt.expected, result)
325+
})
326+
}
327+
}
328+
329+
func TestFilterOutdatedBlockchainEndpoints(t *testing.T) {
330+
currentBlockchainID := "X2oDj86zGjCRCy6vd8Cca4FDStMeFAHWc7SUUygPCCfYf9sHh"
331+
oldBlockchainID := "2ATnxvq9GwPrEPHyULDJqpanFNJecvzSGZ3w5jMzfZAWSmXC6u"
332+
333+
tests := []struct {
334+
name string
335+
endpoints []string
336+
currentBlockchainID string
337+
expected []string
338+
}{
339+
{
340+
name: "filter out old blockchain ID endpoints",
341+
endpoints: []string{
342+
"http://127.0.0.1:55067/ext/bc/" + oldBlockchainID + "/rpc",
343+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
344+
},
345+
currentBlockchainID: currentBlockchainID,
346+
expected: []string{
347+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
348+
},
349+
},
350+
{
351+
name: "preserve endpoints without blockchain ID",
352+
endpoints: []string{
353+
"http://127.0.0.1:55067/ext/bc/" + oldBlockchainID + "/rpc",
354+
"http://127.0.0.1:9650/ext/info",
355+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
356+
},
357+
currentBlockchainID: currentBlockchainID,
358+
expected: []string{
359+
"http://127.0.0.1:9650/ext/info",
360+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
361+
},
362+
},
363+
{
364+
name: "keep all current blockchain endpoints",
365+
endpoints: []string{
366+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
367+
"http://127.0.0.1:60646/ext/bc/" + currentBlockchainID + "/rpc",
368+
},
369+
currentBlockchainID: currentBlockchainID,
370+
expected: []string{
371+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
372+
"http://127.0.0.1:60646/ext/bc/" + currentBlockchainID + "/rpc",
373+
},
374+
},
375+
{
376+
name: "empty current blockchain ID returns all endpoints",
377+
endpoints: []string{
378+
"http://127.0.0.1:55067/ext/bc/" + oldBlockchainID + "/rpc",
379+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
380+
},
381+
currentBlockchainID: "",
382+
expected: []string{
383+
"http://127.0.0.1:55067/ext/bc/" + oldBlockchainID + "/rpc",
384+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
385+
},
386+
},
387+
{
388+
name: "empty endpoints list",
389+
endpoints: []string{},
390+
currentBlockchainID: currentBlockchainID,
391+
expected: []string{},
392+
},
393+
{
394+
name: "mixed WS and RPC endpoints",
395+
endpoints: []string{
396+
"ws://127.0.0.1:55067/ext/bc/" + oldBlockchainID + "/ws",
397+
"http://127.0.0.1:55067/ext/bc/" + oldBlockchainID + "/rpc",
398+
"ws://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/ws",
399+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
400+
},
401+
currentBlockchainID: currentBlockchainID,
402+
expected: []string{
403+
"ws://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/ws",
404+
"http://127.0.0.1:60645/ext/bc/" + currentBlockchainID + "/rpc",
405+
},
406+
},
407+
}
408+
409+
for _, tt := range tests {
410+
t.Run(tt.name, func(t *testing.T) {
411+
require := require.New(t)
412+
result := filterOutdatedBlockchainEndpoints(tt.endpoints, tt.currentBlockchainID)
413+
require.ElementsMatch(tt.expected, result)
414+
})
415+
}
416+
}

0 commit comments

Comments
 (0)