Skip to content

Commit

Permalink
Fix bug in provider cache aggregation rage loop
Browse files Browse the repository at this point in the history
The loop responsible for aggregating contextual and chain level extended
providers ranges over the values fetched from indexers, passes the
values by reference but does not redeclare the value in each iteration.

Redeclare the value to make sure future iterations do not alter the
providers already added to slice.

While at it fix similar issues in other places.
  • Loading branch information
masih committed Jun 28, 2023
1 parent f3760ef commit 713a74d
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
3 changes: 3 additions & 0 deletions find/client/provider_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ func (pc *providerCache) getResults(ctx context.Context, pid peer.ID, ctxID []by
}
if pinfo.ExtendedProviders != nil {
for _, cxp := range pinfo.ExtendedProviders.Contextual {
cxp := cxp
wrapper.cxps[cxp.ContextID] = &cxp
}
}
Expand Down Expand Up @@ -141,6 +142,7 @@ func (pc *providerCache) getResults(ctx context.Context, pid peer.ID, ctxID []by
if contextualEpRecord, ok := wrapper.cxps[string(ctxID)]; ok {
override = contextualEpRecord.Override
for i, xpinfo := range contextualEpRecord.Providers {
xpinfo := xpinfo
xmd := contextualEpRecord.Metadatas[i]
// Skippng the main provider's record if its metadata is nil or is
// the same as the one retrieved from the indexer, because such EP
Expand Down Expand Up @@ -170,6 +172,7 @@ func (pc *providerCache) getResults(ctx context.Context, pid peer.ID, ctxID []by

// Adding chain-level EPs if such exist
for i, xpinfo := range wrapper.pinfo.ExtendedProviders.Providers {
xpinfo := xpinfo
xmd := wrapper.pinfo.ExtendedProviders.Metadatas[i]
// Skippng the main provider's record if its metadata is nil or is the
// same as the one retrieved from the indexer, because such EP record
Expand Down
106 changes: 106 additions & 0 deletions find/client/provider_cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package client

import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
"net/url"
"testing"

"github.com/ipni/go-libipni/find/model"
"github.com/stretchr/testify/require"
)

func TestChainLevelExtendedProviderIsAsExpected(t *testing.T) {
var want []model.ProviderResult
err := json.Unmarshal([]byte(`[
{
"ContextID": "bG9ic3Rlcg==",
"Metadata": "YmFycmVsZXll",
"Provider": {
"ID": "12D3KooWNSRG5wTShNu6EXCPTkoH7dWsphKAPrbvQchHa5arfsDC",
"Addrs": [
"/ip4/209.94.92.6/tcp/24001"
]
}
},
{
"ContextID": "bG9ic3Rlcg==",
"Metadata": "gBI=",
"Provider": {
"ID": "12D3KooWHf7cahZvAVB36SGaVXc7fiVDoJdRJq42zDRcN2s2512h",
"Addrs": [
"/ip4/209.94.92.6/tcp/24123"
]
}
},
{
"ContextID": "bG9ic3Rlcg==",
"Metadata": "oBIA",
"Provider": {
"ID": "12D3KooWNSRG5wTShNu6EXCPTkoH7dWsphKAPrbvQchHa5arfsDC",
"Addrs": [
"/ip4/209.94.92.6/tcp/7575/http"
]
}
}
]`), &want)
require.NoError(t, err)

testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
_, err := res.Write([]byte(`{
"AddrInfo": {
"ID": "12D3KooWNSRG5wTShNu6EXCPTkoH7dWsphKAPrbvQchHa5arfsDC",
"Addrs": [
"/ip4/209.94.92.6/tcp/24001"
]
},
"LastAdvertisement": {
"/": "baguqeerami47x7t3d4raobz7s2cq5np2fy2lhl3xh2ppiwuevxwbdamuikla"
},
"LastAdvertisementTime": "2023-06-28T12:21:06Z",
"Publisher": {
"ID": "12D3KooWNSRG5wTShNu6EXCPTkoH7dWsphKAPrbvQchHa5arfsDC",
"Addrs": [
"/ip4/209.94.92.6/tcp/24001"
]
},
"IndexCount": 157535217,
"ExtendedProviders": {
"Providers": [
{
"ID": "12D3KooWHf7cahZvAVB36SGaVXc7fiVDoJdRJq42zDRcN2s2512h",
"Addrs": [
"/ip4/209.94.92.6/tcp/24123"
]
},
{
"ID": "12D3KooWNSRG5wTShNu6EXCPTkoH7dWsphKAPrbvQchHa5arfsDC",
"Addrs": [
"/ip4/209.94.92.6/tcp/7575/http"
]
}
],
"Metadatas": [
"gBI=",
"oBIA"
]
},
"FrozenAt": null
}`))
require.NoError(t, err)
}))
defer func() { testServer.Close() }()

u, err := url.Parse(testServer.URL)
require.NoError(t, err)
subject, err := newProviderCache(u, nil)
require.NoError(t, err)

contextID := []byte("lobster")
metadata := []byte("barreleye")
got, err := subject.getResults(context.Background(), "fish", contextID, metadata)
require.NoError(t, err)
require.Equal(t, want, got)
}

0 comments on commit 713a74d

Please sign in to comment.