Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(routing): allow-offline with routing put #278

Merged
merged 4 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions coreiface/options/routing.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package options

type RoutingPutSettings struct {
AllowOffline bool
}

type RoutingPutOption func(*RoutingPutSettings) error

func RoutingPutOptions(opts ...RoutingPutOption) (*RoutingPutSettings, error) {
options := &RoutingPutSettings{
AllowOffline: false,
}

for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}

return options, nil
}

type putOpts struct{}

var Put putOpts

// AllowOffline is an option for Routing.Put which specifies whether to allow
// publishing when the node is offline. Default value is false
func (putOpts) AllowOffline(allow bool) RoutingPutOption {
return func(settings *RoutingPutSettings) error {
settings.AllowOffline = allow
return nil
}
}
4 changes: 3 additions & 1 deletion coreiface/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package iface

import (
"context"

"github.com/ipfs/boxo/coreiface/options"
)

// RoutingAPI specifies the interface to the routing layer.
Expand All @@ -10,5 +12,5 @@ type RoutingAPI interface {
Get(context.Context, string) ([]byte, error)

// Put sets a value for a given key
Put(ctx context.Context, key string, value []byte) error
Put(ctx context.Context, key string, value []byte, opts ...options.RoutingPutOption) error
}
37 changes: 25 additions & 12 deletions coreiface/tests/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,12 @@ import (

var errAPINotImplemented = errors.New("api not implemented")

func (tp *TestSuite) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) {
api, err := tp.MakeAPISwarm(ctx, false, 1)
if err != nil {
return nil, err
}

return api[0], nil
}

type Provider interface {
// Make creates n nodes. fullIdentity set to false can be ignored
MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error)
MakeAPISwarm(ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error)
}

func (tp *TestSuite) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]coreiface.CoreAPI, error) {
func (tp *TestSuite) makeAPISwarm(ctx context.Context, fullIdentity bool, online bool, n int) ([]coreiface.CoreAPI, error) {
if tp.apis != nil {
tp.apis <- 1
go func() {
Expand All @@ -34,7 +25,29 @@ func (tp *TestSuite) MakeAPISwarm(ctx context.Context, fullIdentity bool, n int)
}()
}

return tp.Provider.MakeAPISwarm(ctx, fullIdentity, n)
return tp.Provider.MakeAPISwarm(ctx, fullIdentity, online, n)
}

func (tp *TestSuite) makeAPI(ctx context.Context) (coreiface.CoreAPI, error) {
api, err := tp.makeAPISwarm(ctx, false, false, 1)
if err != nil {
return nil, err
}

return api[0], nil
}

func (tp *TestSuite) makeAPIWithIdentityAndOffline(ctx context.Context) (coreiface.CoreAPI, error) {
api, err := tp.makeAPISwarm(ctx, true, false, 1)
if err != nil {
return nil, err
}

return api[0], nil
}

func (tp *TestSuite) MakeAPISwarm(ctx context.Context, n int) ([]coreiface.CoreAPI, error) {
return tp.makeAPISwarm(ctx, true, true, n)
}

type TestSuite struct {
Expand Down
6 changes: 3 additions & 3 deletions coreiface/tests/dht.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (tp *TestSuite) TestDht(t *testing.T) {
func (tp *TestSuite) TestDhtFindPeer(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
apis, err := tp.MakeAPISwarm(ctx, true, 5)
apis, err := tp.MakeAPISwarm(ctx, 5)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -81,7 +81,7 @@ func (tp *TestSuite) TestDhtFindPeer(t *testing.T) {
func (tp *TestSuite) TestDhtFindProviders(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
apis, err := tp.MakeAPISwarm(ctx, true, 5)
apis, err := tp.MakeAPISwarm(ctx, 5)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -113,7 +113,7 @@ func (tp *TestSuite) TestDhtFindProviders(t *testing.T) {
func (tp *TestSuite) TestDhtProvide(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
apis, err := tp.MakeAPISwarm(ctx, true, 5)
apis, err := tp.MakeAPISwarm(ctx, 5)
if err != nil {
t.Fatal(err)
}
Expand Down
6 changes: 3 additions & 3 deletions coreiface/tests/name.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
init := func() (coreiface.CoreAPI, path.Path) {
apis, err := tp.MakeAPISwarm(ctx, true, 5)
apis, err := tp.MakeAPISwarm(ctx, 5)
if err != nil {
t.Fatal(err)
return nil, nil
Expand Down Expand Up @@ -191,7 +191,7 @@ func (tp *TestSuite) TestPublishResolve(t *testing.T) {
func (tp *TestSuite) TestBasicPublishResolveKey(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
apis, err := tp.MakeAPISwarm(ctx, true, 5)
apis, err := tp.MakeAPISwarm(ctx, 5)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -235,7 +235,7 @@ func (tp *TestSuite) TestBasicPublishResolveTimeout(t *testing.T) {

ctx, cancel := context.WithCancel(context.Background())
defer cancel()
apis, err := tp.MakeAPISwarm(ctx, true, 5)
apis, err := tp.MakeAPISwarm(ctx, 5)
if err != nil {
t.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion coreiface/tests/pubsub.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func (tp *TestSuite) TestBasicPubSub(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

apis, err := tp.MakeAPISwarm(ctx, true, 2)
apis, err := tp.MakeAPISwarm(ctx, 2)
if err != nil {
t.Fatal(err)
}
Expand Down
43 changes: 39 additions & 4 deletions coreiface/tests/routing.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/gogo/protobuf/proto"
iface "github.com/ipfs/boxo/coreiface"
"github.com/ipfs/boxo/coreiface/options"
ipns_pb "github.com/ipfs/boxo/ipns/pb"
)

Expand All @@ -20,15 +21,16 @@ func (tp *TestSuite) TestRouting(t *testing.T) {

t.Run("TestRoutingGet", tp.TestRoutingGet)
t.Run("TestRoutingPut", tp.TestRoutingPut)
t.Run("TestRoutingPutOffline", tp.TestRoutingPutOffline)
}

func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI) iface.IpnsEntry {
func (tp *TestSuite) testRoutingPublishKey(t *testing.T, ctx context.Context, api iface.CoreAPI, opts ...options.NamePublishOption) iface.IpnsEntry {
p, err := addTestObject(ctx, api)
if err != nil {
t.Fatal(err)
}

entry, err := api.Name().Publish(ctx, p)
entry, err := api.Name().Publish(ctx, p, opts...)
if err != nil {
t.Fatal(err)
}
Expand All @@ -41,7 +43,7 @@ func (tp *TestSuite) TestRoutingGet(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

apis, err := tp.MakeAPISwarm(ctx, true, 2)
apis, err := tp.MakeAPISwarm(ctx, 2)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -70,7 +72,7 @@ func (tp *TestSuite) TestRoutingGet(t *testing.T) {
func (tp *TestSuite) TestRoutingPut(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
apis, err := tp.MakeAPISwarm(ctx, true, 2)
apis, err := tp.MakeAPISwarm(ctx, 2)
if err != nil {
t.Fatal(err)
}
Expand All @@ -90,3 +92,36 @@ func (tp *TestSuite) TestRoutingPut(t *testing.T) {
t.Fatal(err)
}
}

func (tp *TestSuite) TestRoutingPutOffline(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

// init a swarm & publish an IPNS entry to get a valid payload
apis, err := tp.MakeAPISwarm(ctx, 2)
if err != nil {
t.Fatal(err)
}

ipnsEntry := tp.testRoutingPublishKey(t, ctx, apis[0], options.Name.AllowOffline(true))
data, err := apis[0].Routing().Get(ctx, "/ipns/"+ipnsEntry.Name())
if err != nil {
t.Fatal(err)
}

// init our offline node and try to put the payload
api, err := tp.makeAPIWithIdentityAndOffline(ctx)
if err != nil {
t.Fatal(err)
}

err = api.Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data)
if err == nil {
t.Fatal("this operation should fail because we are offline")
}

err = api.Routing().Put(ctx, "/ipns/"+ipnsEntry.Name(), data, options.Put.AllowOffline(true))
if err != nil {
t.Fatal(err)
}
}
hacdias marked this conversation as resolved.
Show resolved Hide resolved