Skip to content

Commit

Permalink
Add Provide RPC (#37)
Browse files Browse the repository at this point in the history
* Add Provide RPC per ipfs/specs#285


This commit was moved from ipfs/go-delegated-routing@a6fd1a5
  • Loading branch information
willscott committed Aug 10, 2022
1 parent 4da16f4 commit 1ba943f
Show file tree
Hide file tree
Showing 11 changed files with 1,396 additions and 154 deletions.
13 changes: 11 additions & 2 deletions routing/http/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 routing/http/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
43 changes: 41 additions & 2 deletions routing/http/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,15 +25,33 @@ 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
}

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

// NewClient creates a client.
// The Provider and identity parameters are option. If they are nil, the `Provide` method will not function.
func NewClient(c proto.DelegatedRouting_Client, p *Provider, identity crypto.PrivKey) (*Client, error) {
if p != nil && !p.Peer.ID.MatchesPublicKey(identity.GetPublic()) {
return nil, errors.New("identity does not match provider")
}

return &Client{
client: c,
validator: ipns.Validator{},
provider: p,
identity: identity,
}, nil
}

func (fp *Client) FindProviders(ctx context.Context, key cid.Cid) ([]peer.AddrInfo, error) {
Expand Down Expand Up @@ -142,5 +164,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

0 comments on commit 1ba943f

Please sign in to comment.