From 9f2683a2060f9e490741e23119e8014075c2e9b8 Mon Sep 17 00:00:00 2001 From: Jorropo Date: Tue, 5 Sep 2023 18:45:33 +0200 Subject: [PATCH] coreiface: deprecate DhtAPI in favor of RoutingAPI --- coreiface/coreapi.go | 2 + coreiface/dht.go | 7 +- coreiface/options/dht.go | 68 ++++---------- coreiface/options/routing.go | 62 +++++++++++++ coreiface/routing.go | 16 +++- coreiface/tests/api.go | 1 - coreiface/tests/dht.go | 166 ----------------------------------- coreiface/tests/routing.go | 146 ++++++++++++++++++++++++++++++ 8 files changed, 242 insertions(+), 226 deletions(-) delete mode 100644 coreiface/tests/dht.go diff --git a/coreiface/coreapi.go b/coreiface/coreapi.go index 7276a3f60..0fbae2b76 100644 --- a/coreiface/coreapi.go +++ b/coreiface/coreapi.go @@ -36,6 +36,8 @@ type CoreAPI interface { Object() ObjectAPI // Dht returns an implementation of Dht API + // + // Deprecated: use [CoreAPI.Routing] instead. Dht() DhtAPI // Swarm returns an implementation of Swarm API diff --git a/coreiface/dht.go b/coreiface/dht.go index 93027a406..615909f29 100644 --- a/coreiface/dht.go +++ b/coreiface/dht.go @@ -3,16 +3,15 @@ package iface import ( "context" - "github.com/ipfs/boxo/coreiface/path" - "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" "github.com/libp2p/go-libp2p/core/peer" ) // DhtAPI specifies the interface to the DHT -// Note: This API will likely get deprecated in near future, see -// https://github.com/ipfs/interface-ipfs-core/issues/249 for more context. +// +// Deprecated: Use [RoutingAPI] instead, see https://github.com/ipfs/interface-ipfs-core/issues/249 for more context. type DhtAPI interface { // FindPeer queries the DHT for all of the multiaddresses associated with a // Peer ID diff --git a/coreiface/options/dht.go b/coreiface/options/dht.go index b43bf3e7a..0502491da 100644 --- a/coreiface/options/dht.go +++ b/coreiface/options/dht.go @@ -1,64 +1,26 @@ package options -type DhtProvideSettings struct { - Recursive bool -} +// Deprecated: use [RoutingProvideSettings] instead +type DhtProvideSettings = RoutingProvideSettings -type DhtFindProvidersSettings struct { - NumProviders int -} +// Deprecated: use [RoutingFindProvidersSettings] instead +type DhtFindProvidersSettings = RoutingFindProvidersSettings -type ( - DhtProvideOption func(*DhtProvideSettings) error - DhtFindProvidersOption func(*DhtFindProvidersSettings) error -) +// Deprecated: use [RoutingProvideOption] instead +type DhtProvideOption = RoutingProvideOption -func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { - options := &DhtProvideSettings{ - Recursive: false, - } +// Deprecated: use [RoutingFindProvidersOption] instead +type DhtFindProvidersOption = RoutingFindProvidersOption - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil +// Deprecated: use [RoutingProvideOptions] instead +func DhtProvideOptions(opts ...DhtProvideOption) (*DhtProvideSettings, error) { + return RoutingProvideOptions(opts...) } +// Deprecated: use [RoutingFindProvidersOptions] instead func DhtFindProvidersOptions(opts ...DhtFindProvidersOption) (*DhtFindProvidersSettings, error) { - options := &DhtFindProvidersSettings{ - NumProviders: 20, - } - - for _, opt := range opts { - err := opt(options) - if err != nil { - return nil, err - } - } - return options, nil + return RoutingFindProvidersOptions(opts...) } -type dhtOpts struct{} - -var Dht dhtOpts - -// Recursive is an option for Dht.Provide which specifies whether to provide -// the given path recursively -func (dhtOpts) Recursive(recursive bool) DhtProvideOption { - return func(settings *DhtProvideSettings) error { - settings.Recursive = recursive - return nil - } -} - -// NumProviders is an option for Dht.FindProviders which specifies the -// number of peers to look for. Default is 20 -func (dhtOpts) NumProviders(numProviders int) DhtFindProvidersOption { - return func(settings *DhtFindProvidersSettings) error { - settings.NumProviders = numProviders - return nil - } -} +// Deprecated: use [Routing] instead +var Dht routingOpts diff --git a/coreiface/options/routing.go b/coreiface/options/routing.go index d66d44a0d..7537988ad 100644 --- a/coreiface/options/routing.go +++ b/coreiface/options/routing.go @@ -6,6 +6,18 @@ type RoutingPutSettings struct { type RoutingPutOption func(*RoutingPutSettings) error +type RoutingProvideSettings struct { + Recursive bool +} + +type RoutingProvideOption func(*DhtProvideSettings) error + +type RoutingFindProvidersSettings struct { + NumProviders int +} + +type RoutingFindProvidersOption func(*DhtFindProvidersSettings) error + func RoutingPutOptions(opts ...RoutingPutOption) (*RoutingPutSettings, error) { options := &RoutingPutSettings{ AllowOffline: false, @@ -33,3 +45,53 @@ func (putOpts) AllowOffline(allow bool) RoutingPutOption { return nil } } + +func RoutingProvideOptions(opts ...RoutingProvideOption) (*RoutingProvideSettings, error) { + options := &RoutingProvideSettings{ + Recursive: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +func RoutingFindProvidersOptions(opts ...RoutingFindProvidersOption) (*RoutingFindProvidersSettings, error) { + options := &RoutingFindProvidersSettings{ + NumProviders: 20, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type routingOpts struct{} + +var Routing routingOpts + +// Recursive is an option for Dht.Provide which specifies whether to provide +// the given path recursively +func (routingOpts) Recursive(recursive bool) DhtProvideOption { + return func(settings *DhtProvideSettings) error { + settings.Recursive = recursive + return nil + } +} + +// NumProviders is an option for Dht.FindProviders which specifies the +// number of peers to look for. Default is 20 +func (routingOpts) NumProviders(numProviders int) DhtFindProvidersOption { + return func(settings *DhtFindProvidersSettings) error { + settings.NumProviders = numProviders + return nil + } +} diff --git a/coreiface/routing.go b/coreiface/routing.go index 5099c3de0..722971bc3 100644 --- a/coreiface/routing.go +++ b/coreiface/routing.go @@ -4,13 +4,25 @@ import ( "context" "github.com/ipfs/boxo/coreiface/options" + "github.com/ipfs/boxo/coreiface/path" + + "github.com/libp2p/go-libp2p/core/peer" ) // RoutingAPI specifies the interface to the routing layer. type RoutingAPI interface { - // Get retrieves the best value for a given key + // Get retrieves the best value for a given key. Get(context.Context, string) ([]byte, error) - // Put sets a value for a given key + // Put sets a value for a given key. Put(ctx context.Context, key string, value []byte, opts ...options.RoutingPutOption) error + + // FindPeer queries the DHT for all of the multiaddresses associated with a Peer ID. + FindPeer(context.Context, peer.ID) (peer.AddrInfo, error) + + // FindProviders finds peers in the DHT who can provide a specific value given a key. + FindProviders(context.Context, path.Path, ...options.DhtFindProvidersOption) (<-chan peer.AddrInfo, error) + + // Provide announces to the network that you are providing given values. + Provide(context.Context, path.Path, ...options.DhtProvideOption) error } diff --git a/coreiface/tests/api.go b/coreiface/tests/api.go index a66e2abeb..3bf94425e 100644 --- a/coreiface/tests/api.go +++ b/coreiface/tests/api.go @@ -75,7 +75,6 @@ func TestApi(p Provider) func(t *testing.T) { return func(t *testing.T) { t.Run("Block", tp.TestBlock) t.Run("Dag", tp.TestDag) - t.Run("Dht", tp.TestDht) t.Run("Key", tp.TestKey) t.Run("Name", tp.TestName) t.Run("Object", tp.TestObject) diff --git a/coreiface/tests/dht.go b/coreiface/tests/dht.go deleted file mode 100644 index 3b3ac1d61..000000000 --- a/coreiface/tests/dht.go +++ /dev/null @@ -1,166 +0,0 @@ -package tests - -import ( - "context" - "io" - "testing" - "time" - - iface "github.com/ipfs/boxo/coreiface" - "github.com/ipfs/boxo/coreiface/options" -) - -func (tp *TestSuite) TestDht(t *testing.T) { - tp.hasApi(t, func(api iface.CoreAPI) error { - if api.Dht() == nil { - return errAPINotImplemented - } - return nil - }) - - t.Run("TestDhtFindPeer", tp.TestDhtFindPeer) - t.Run("TestDhtFindProviders", tp.TestDhtFindProviders) - t.Run("TestDhtProvide", tp.TestDhtProvide) -} - -func (tp *TestSuite) TestDhtFindPeer(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - } - - self0, err := apis[0].Key().Self(ctx) - if err != nil { - t.Fatal(err) - } - - laddrs0, err := apis[0].Swarm().LocalAddrs(ctx) - if err != nil { - t.Fatal(err) - } - if len(laddrs0) != 1 { - t.Fatal("unexpected number of local addrs") - } - - time.Sleep(3 * time.Second) - - pi, err := apis[2].Dht().FindPeer(ctx, self0.ID()) - if err != nil { - t.Fatal(err) - } - - if pi.Addrs[0].String() != laddrs0[0].String() { - t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) - } - - self2, err := apis[2].Key().Self(ctx) - if err != nil { - t.Fatal(err) - } - - pi, err = apis[1].Dht().FindPeer(ctx, self2.ID()) - if err != nil { - t.Fatal(err) - } - - laddrs2, err := apis[2].Swarm().LocalAddrs(ctx) - if err != nil { - t.Fatal(err) - } - if len(laddrs2) != 1 { - t.Fatal("unexpected number of local addrs") - } - - if pi.Addrs[0].String() != laddrs2[0].String() { - t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) - } -} - -func (tp *TestSuite) TestDhtFindProviders(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - } - - p, err := addTestObject(ctx, apis[0]) - if err != nil { - t.Fatal(err) - } - - time.Sleep(3 * time.Second) - - out, err := apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) - if err != nil { - t.Fatal(err) - } - - provider := <-out - - self0, err := apis[0].Key().Self(ctx) - if err != nil { - t.Fatal(err) - } - - if provider.ID.String() != self0.ID().String() { - t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) - } -} - -func (tp *TestSuite) TestDhtProvide(t *testing.T) { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - apis, err := tp.MakeAPISwarm(t, ctx, 5) - if err != nil { - t.Fatal(err) - } - - off0, err := apis[0].WithOptions(options.Api.Offline(true)) - if err != nil { - t.Fatal(err) - } - - s, err := off0.Block().Put(ctx, &io.LimitedReader{R: rnd, N: 4092}) - if err != nil { - t.Fatal(err) - } - - p := s.Path() - - time.Sleep(3 * time.Second) - - out, err := apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) - if err != nil { - t.Fatal(err) - } - - _, ok := <-out - - if ok { - t.Fatal("did not expect to find any providers") - } - - self0, err := apis[0].Key().Self(ctx) - if err != nil { - t.Fatal(err) - } - - err = apis[0].Dht().Provide(ctx, p) - if err != nil { - t.Fatal(err) - } - - out, err = apis[2].Dht().FindProviders(ctx, p, options.Dht.NumProviders(1)) - if err != nil { - t.Fatal(err) - } - - provider := <-out - - if provider.ID.String() != self0.ID().String() { - t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) - } -} diff --git a/coreiface/tests/routing.go b/coreiface/tests/routing.go index fd10dffcd..87a49a598 100644 --- a/coreiface/tests/routing.go +++ b/coreiface/tests/routing.go @@ -2,6 +2,7 @@ package tests import ( "context" + "io" "testing" "time" @@ -23,6 +24,9 @@ func (tp *TestSuite) TestRouting(t *testing.T) { t.Run("TestRoutingGet", tp.TestRoutingGet) t.Run("TestRoutingPut", tp.TestRoutingPut) t.Run("TestRoutingPutOffline", tp.TestRoutingPutOffline) + t.Run("TestRoutingFindPeer", tp.TestRoutingFindPeer) + t.Run("TestRoutingFindProviders", tp.TestRoutingFindProviders) + t.Run("TestRoutingProvide", tp.TestRoutingProvide) } func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI, opts ...options.NamePublishOption) (path.Path, ipns.Name) { @@ -98,3 +102,145 @@ func (tp *TestSuite) TestRoutingPutOffline(t *testing.T) { err = api.Routing().Put(ctx, ipns.NamespacePrefix+name.String(), data, options.Put.AllowOffline(true)) require.NoError(t, err) } + +func (tp *TestSuite) TestRoutingFindPeer(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + apis, err := tp.MakeAPISwarm(t, ctx, 5) + if err != nil { + t.Fatal(err) + } + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + laddrs0, err := apis[0].Swarm().LocalAddrs(ctx) + if err != nil { + t.Fatal(err) + } + if len(laddrs0) != 1 { + t.Fatal("unexpected number of local addrs") + } + + time.Sleep(3 * time.Second) + + pi, err := apis[2].Routing().FindPeer(ctx, self0.ID()) + if err != nil { + t.Fatal(err) + } + + if pi.Addrs[0].String() != laddrs0[0].String() { + t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) + } + + self2, err := apis[2].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + pi, err = apis[1].Routing().FindPeer(ctx, self2.ID()) + if err != nil { + t.Fatal(err) + } + + laddrs2, err := apis[2].Swarm().LocalAddrs(ctx) + if err != nil { + t.Fatal(err) + } + if len(laddrs2) != 1 { + t.Fatal("unexpected number of local addrs") + } + + if pi.Addrs[0].String() != laddrs2[0].String() { + t.Errorf("got unexpected address from FindPeer: %s", pi.Addrs[0].String()) + } +} + +func (tp *TestSuite) TestRoutingFindProviders(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + apis, err := tp.MakeAPISwarm(t, ctx, 5) + if err != nil { + t.Fatal(err) + } + + p, err := addTestObject(ctx, apis[0]) + if err != nil { + t.Fatal(err) + } + + time.Sleep(3 * time.Second) + + out, err := apis[2].Routing().FindProviders(ctx, p, options.Dht.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + provider := <-out + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + if provider.ID.String() != self0.ID().String() { + t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) + } +} + +func (tp *TestSuite) TestRoutingProvide(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + apis, err := tp.MakeAPISwarm(t, ctx, 5) + if err != nil { + t.Fatal(err) + } + + off0, err := apis[0].WithOptions(options.Api.Offline(true)) + if err != nil { + t.Fatal(err) + } + + s, err := off0.Block().Put(ctx, &io.LimitedReader{R: rnd, N: 4092}) + if err != nil { + t.Fatal(err) + } + + p := s.Path() + + time.Sleep(3 * time.Second) + + out, err := apis[2].Routing().FindProviders(ctx, p, options.Dht.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + _, ok := <-out + + if ok { + t.Fatal("did not expect to find any providers") + } + + self0, err := apis[0].Key().Self(ctx) + if err != nil { + t.Fatal(err) + } + + err = apis[0].Routing().Provide(ctx, p) + if err != nil { + t.Fatal(err) + } + + out, err = apis[2].Routing().FindProviders(ctx, p, options.Dht.NumProviders(1)) + if err != nil { + t.Fatal(err) + } + + provider := <-out + + if provider.ID.String() != self0.ID().String() { + t.Errorf("got wrong provider: %s != %s", provider.ID.String(), self0.ID().String()) + } +}