diff --git a/retrievalmarket/impl/client.go b/retrievalmarket/impl/client.go index 31a97a00..4e6838ed 100644 --- a/retrievalmarket/impl/client.go +++ b/retrievalmarket/impl/client.go @@ -2,7 +2,6 @@ package retrievalimpl import ( "context" - "errors" "reflect" "sync" @@ -33,7 +32,10 @@ type client struct { } // NewClient creates a new retrieval client -func NewClient(network rmnet.RetrievalMarketNetwork, bs blockstore.Blockstore, node retrievalmarket.RetrievalClientNode, resolver retrievalmarket.PeerResolver) retrievalmarket.RetrievalClient { +func NewClient(network rmnet.RetrievalMarketNetwork, + bs blockstore.Blockstore, + node retrievalmarket.RetrievalClientNode, + resolver retrievalmarket.PeerResolver) retrievalmarket.RetrievalClient { return &client{network: network, bs: bs, node: node, resolver: resolver} } @@ -42,15 +44,11 @@ func NewClient(network rmnet.RetrievalMarketNetwork, bs blockstore.Blockstore, n // TODO: Implement for retrieval provider V0 epic // https://github.com/filecoin-project/go-retrieval-market-project/issues/12 func (c *client) FindProviders(pieceCIDBytes []byte) []retrievalmarket.RetrievalPeer { - cidLen, pieceCid, err := cid.CidFromBytes(pieceCIDBytes) + _, pieceCid, err := cid.CidFromBytes(pieceCIDBytes) if err != nil { log.Error(err) return []retrievalmarket.RetrievalPeer{} } - if cidLen == 0 { - log.Error(errors.New("zero-length CID")) - return []retrievalmarket.RetrievalPeer{} - } peers, err := c.resolver.GetPeers(pieceCid) if err != nil { log.Error(err) diff --git a/retrievalmarket/impl/client_test.go b/retrievalmarket/impl/client_test.go index dd56256d..aa3216f0 100644 --- a/retrievalmarket/impl/client_test.go +++ b/retrievalmarket/impl/client_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-data-transfer/testutil" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" dss "github.com/ipfs/go-datastore/sync" @@ -114,6 +115,45 @@ func TestClient_Query(t *testing.T) { }) } +func TestClient_FindProviders(t *testing.T) { + bs := bstore.NewBlockstore(dss.MutexWrap(datastore.NewMapDatastore())) + expectedPeer := peer.ID("somevalue") + + var qsb tut.QueryStreamBuilder = func(p peer.ID) (rmnet.RetrievalQueryStream, error) { + return tut.NewTestRetrievalQueryStream(tut.TestQueryStreamParams{ + Writer: tut.TrivialQueryWriter, + RespReader: tut.TrivialQueryResponseReader, + }), nil + } + net := tut.NewTestRetrievalMarketNetwork(tut.TestNetworkParams{ + QueryStreamBuilder: tut.ExpectPeerOnQueryStreamBuilder(t, expectedPeer, qsb, "Peers should match"), + }) + + t.Run("when providers are found, returns providers", func(t *testing.T) { + peers := tut.RequireGenerateRetrievalPeers(t, 3) + testResolver := testPeerResolver{peers: peers} + + c := retrievalimpl.NewClient(net, bs, &testRetrievalNode{}, &testResolver) + testCid := testutil.GenerateCids(1)[0].Bytes() + assert.Len(t, c.FindProviders(testCid), 3) + }) + + t.Run("when there is an error, returns empty provider list", func(t *testing.T) { + peers := tut.RequireGenerateRetrievalPeers(t, 1) + testResolver := testPeerResolver{peers: peers} + c := retrievalimpl.NewClient(net, bs, &testRetrievalNode{}, &testResolver) + badCid := []byte("badcid") + assert.Len(t, c.FindProviders(badCid), 0) + }) + + t.Run("when there are no providers", func(t *testing.T) { + testResolver := testPeerResolver{peers: []retrievalmarket.RetrievalPeer{}} + c := retrievalimpl.NewClient(net, bs, &testRetrievalNode{}, &testResolver) + testCid := testutil.GenerateCids(1)[0].Bytes() + assert.Len(t, c.FindProviders(testCid), 0) + }) +} + type testRetrievalNode struct { } @@ -132,9 +172,9 @@ func (t *testRetrievalNode) CreatePaymentVoucher(ctx context.Context, paymentCha type testPeerResolver struct { peers []retrievalmarket.RetrievalPeer } + var _ retrievalmarket.PeerResolver = &testPeerResolver{} func (t testPeerResolver) GetPeers(data cid.Cid) ([]retrievalmarket.RetrievalPeer, error) { return t.peers, nil } - diff --git a/shared_testutil/test_types.go b/shared_testutil/test_types.go index 4ff30225..f4ad536c 100644 --- a/shared_testutil/test_types.go +++ b/shared_testutil/test_types.go @@ -3,9 +3,12 @@ package shared_testutil import ( "math/big" "math/rand" + "testing" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-data-transfer/testutil" + "github.com/libp2p/go-libp2p-core/test" + "github.com/stretchr/testify/require" "github.com/filecoin-project/go-fil-markets/retrievalmarket" "github.com/filecoin-project/go-fil-markets/shared/tokenamount" @@ -107,3 +110,18 @@ func MakeTestDealPayment() retrievalmarket.DealPayment { PaymentVoucher: MakeTestSignedVoucher(), } } + +func RequireGenerateRetrievalPeers(t *testing.T, numPeers int) []retrievalmarket.RetrievalPeer { + peers := make([]retrievalmarket.RetrievalPeer, numPeers) + for i := range peers { + pid, err := test.RandPeerID() + require.NoError(t, err) + addr, err := address.NewIDAddress(rand.Uint64()) + require.NoError(t, err) + peers[i] = retrievalmarket.RetrievalPeer{ + Address: addr, + ID: pid, + } + } + return peers +}