Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Add Provide RPC #37

Merged
merged 11 commits into from
Aug 10, 2022
13 changes: 11 additions & 2 deletions client/contentrouting.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package client

import (
"context"
"time"

"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
Expand All @@ -18,8 +19,16 @@ func NewContentRoutingClient(c DelegatedRoutingClient) *ContentRoutingClient {
return &ContentRoutingClient{client: c}
}

func (c *ContentRoutingClient) Provide(context.Context, cid.Cid, bool) error {
return routing.ErrNotSupported
func (c *ContentRoutingClient) Provide(ctx context.Context, key cid.Cid, announce bool) error {
// If 'true' is
// passed, it also announces it, otherwise it is just kept in the local
// accounting of which objects are being provided.
if !announce {
return nil
}

_, err := c.client.Provide(ctx, key, 24*time.Hour)
return err
}

func (c *ContentRoutingClient) FindProvidersAsync(ctx context.Context, key cid.Cid, numResults int) <-chan peer.AddrInfo {
Expand Down
9 changes: 9 additions & 0 deletions client/contentrouting_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package client
import (
"context"
"testing"
"time"

"github.com/ipfs/go-cid"
"github.com/libp2p/go-libp2p-core/peer"
Expand Down Expand Up @@ -45,6 +46,14 @@ func (t TestDelegatedRoutingClient) PutIPNSAsync(ctx context.Context, id []byte,
panic("not supported")
}

func (t TestDelegatedRoutingClient) ProvideAsync(ctx context.Context, key cid.Cid, ttl time.Duration) (<-chan time.Duration, error) {
panic("not supported")
}

func (t TestDelegatedRoutingClient) Provide(ctx context.Context, key cid.Cid, tl time.Duration) (time.Duration, error) {
panic("not supported")
}

// TestContentRoutingFindProvidersUnlimitedResults is testing that ContentRoutingClient.FindProvidersAsync
// correctly wraps DelegatedRoutingClient.FindProvidersAsync in the regime when the former allows for unlimited results.
// This is a test of async semantics only. This is why values are not checked for validity.
Expand Down
38 changes: 38 additions & 0 deletions client/findproviders.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ package client

import (
"context"
"errors"
"time"

"github.com/ipfs/go-cid"
proto "github.com/ipfs/go-delegated-routing/gen/proto"
ipns "github.com/ipfs/go-ipns"
logging "github.com/ipfs/go-log/v2"
"github.com/ipld/edelweiss/values"
"github.com/libp2p/go-libp2p-core/crypto"
"github.com/libp2p/go-libp2p-core/peer"
record "github.com/libp2p/go-libp2p-record"
"github.com/multiformats/go-multiaddr"
Expand All @@ -21,17 +25,34 @@ type DelegatedRoutingClient interface {
GetIPNSAsync(ctx context.Context, id []byte) (<-chan GetIPNSAsyncResult, error)
PutIPNS(ctx context.Context, id []byte, record []byte) error
PutIPNSAsync(ctx context.Context, id []byte, record []byte) (<-chan PutIPNSAsyncResult, error)
Provide(ctx context.Context, key cid.Cid, ttl time.Duration) (time.Duration, error)
ProvideAsync(ctx context.Context, key cid.Cid, ttl time.Duration) (<-chan time.Duration, error)
}

type Client struct {
client proto.DelegatedRouting_Client
validator record.Validator

provider *Provider
identity crypto.PrivKey
}

var _ DelegatedRoutingClient = (*Client)(nil)

func NewClient(c proto.DelegatedRouting_Client) *Client {
return &Client{client: c, validator: ipns.Validator{}}
}

// SetIdentity sets an identity for providing content. the `Provide` methods will not work without it set.
func (c *Client) SetIdentity(p *Provider, identity crypto.PrivKey) error {
willscott marked this conversation as resolved.
Show resolved Hide resolved
if !p.Peer.ID.MatchesPublicKey(identity.GetPublic()) {
return errors.New("identity does not match provider")
}
c.provider = p
c.identity = identity
return nil
}

func (fp *Client) FindProviders(ctx context.Context, key cid.Cid) ([]peer.AddrInfo, error) {
resps, err := fp.client.FindProviders(ctx, cidsToFindProvidersRequest(key))
if err != nil {
Expand Down Expand Up @@ -142,5 +163,22 @@ func ParseNodeAddresses(n *proto.Peer) []peer.AddrInfo {
}
infos = append(infos, peer.AddrInfo{ID: peerID, Addrs: []multiaddr.Multiaddr{ma}})
}
if len(n.Multiaddresses) == 0 {
infos = append(infos, peer.AddrInfo{ID: peerID})
}
return infos
}

// ToProtoPeer creates a protocol Peer structure from address info.
func ToProtoPeer(ai peer.AddrInfo) *proto.Peer {
p := proto.Peer{
ID: values.Bytes(ai.ID),
Multiaddresses: make(proto.AnonList20, 0),
}

for _, addr := range ai.Addrs {
p.Multiaddresses = append(p.Multiaddresses, addr.Bytes())
}

return &p
}
Loading