Skip to content

Commit

Permalink
feat(routing): allow-offline with routing put (#278)
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentsenta authored May 3, 2023
1 parent 268cad8 commit 8059f18
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 24 deletions.
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)
}
}

0 comments on commit 8059f18

Please sign in to comment.