@cryptotaxi247 / kubo / commits / c832a32a4

coreapi: global offline option

License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>

Łukasz Magiera committed Dec 6, 2018 at 22:25 UTC c832a32a4c5b6633df9efe4793edb837317ed9fd
11 files changed +149 -65
commands/context.go
+4 -1
@@ -68,7 +68,10 @@ func (c *Context) GetAPI() (coreiface.CoreAPI, error) {
68 if err != nil {
69 return nil, err
70 }
71 - c.api = coreapi.NewCoreAPI(n)
71 + c.api, err = coreapi.NewCoreAPI(n)
72 + if err != nil {
73 + return nil, err
74 + }
75 }
76 return c.api, nil
77 }
core/coreapi/coreapi.go
+80 -37
@@ -16,26 +16,27 @@ package coreapi
16 import (
17 "context"
18 "errors"
19 -
20 - core "github.com/ipfs/go-ipfs/core"
19 + "fmt"
20 + "github.com/ipfs/go-ipfs/core"
21 coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
22 - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
23 - namesys "github.com/ipfs/go-ipfs/namesys"
24 - pin "github.com/ipfs/go-ipfs/pin"
25 - repo "github.com/ipfs/go-ipfs/repo"
22 + "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
23 + "github.com/ipfs/go-ipfs/namesys"
24 + "github.com/ipfs/go-ipfs/pin"
25 + "github.com/ipfs/go-ipfs/repo"
26
27 ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto"
28 - exchange "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface"
28 + "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface"
29 bserv "gx/ipfs/QmPoh3SrQzFBWtdGK6qmHDV4EanKR6kYPj4DD3J2NLoEmZ/go-blockservice"
30 - routing "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing"
31 - blockstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore"
32 - peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer"
30 + "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing"
31 + "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore"
32 + "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer"
33 pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore"
34 pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub"
35 ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
36 logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log"
37 dag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag"
38 - record "gx/ipfs/QmfARXVCzpwFXQdepAJZuqyNDgV9doEsMnVCo1ssmuSe1U/go-libp2p-record"
38 + offlineroute "gx/ipfs/QmdmWkx54g7VfVyxeG8ic84uf4G6Eq1GohuyKA3XDuJ8oC/go-ipfs-routing/offline"
39 + "gx/ipfs/QmfARXVCzpwFXQdepAJZuqyNDgV9doEsMnVCo1ssmuSe1U/go-libp2p-record"
40 p2phost "gx/ipfs/QmfD51tKgJiTMnW9JEiDiPwsCY4mqUoxkhKhBfyW12spTC/go-libp2p-host"
41 )
42
@@ -50,20 +51,20 @@ type CoreAPI struct {
51 repo repo.Repo
52 blockstore blockstore.GCBlockstore
53 baseBlocks blockstore.Blockstore
53 - blocks bserv.BlockService
54 - dag ipld.DAGService
54 pinning pin.Pinner
55
56 + blocks bserv.BlockService
57 + dag ipld.DAGService
58 +
59 peerstore pstore.Peerstore
60 peerHost p2phost.Host
59 - namesys namesys.NameSystem
61 recordValidator record.Validator
62 exchange exchange.Interface
63
63 - routing routing.IpfsRouting
64 - pubSub *pubsub.PubSub
64 + namesys namesys.NameSystem
65 + routing func(bool) (routing.IpfsRouting, error)
66
66 - checkRouting func(bool) error
67 + pubSub *pubsub.PubSub
68
69 // TODO: this can be generalized to all functions when we implement some
70 // api based security mechanism
@@ -71,7 +72,12 @@ type CoreAPI struct {
72 }
73
74 // NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node.
74 -func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) coreiface.CoreAPI {
75 +func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) (coreiface.CoreAPI, error) {
76 + settings, err := options.ApiOptions(opts...)
77 + if err != nil {
78 + return nil, err
79 + }
80 +
81 api := &CoreAPI{
82 nctx: n.Context(),
83
@@ -81,38 +87,75 @@ func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) coreiface.CoreAPI {
87 repo: n.Repo,
88 blockstore: n.Blockstore,
89 baseBlocks: n.BaseBlocks,
84 - blocks: n.Blocks,
85 - dag: n.DAG,
90 pinning: n.Pinning,
91
92 + blocks: n.Blocks,
93 + dag: n.DAG,
94 +
95 peerstore: n.Peerstore,
96 peerHost: n.PeerHost,
97 namesys: n.Namesys,
98 recordValidator: n.RecordValidator,
99 exchange: n.Exchange,
100
94 - routing: n.Routing,
95 - pubSub: n.PubSub,
101 + pubSub: n.PubSub,
102 + }
103
97 - checkRouting: func(allowOffline bool) error {
98 - if !n.OnlineMode() {
99 - if !allowOffline {
100 - return coreiface.ErrOffline
101 - }
102 - return n.SetupOfflineRouting()
104 + api.routing = func(allowOffline bool) (routing.IpfsRouting, error) {
105 + if !n.OnlineMode() {
106 + if !allowOffline {
107 + return nil, coreiface.ErrOffline
108 }
104 - return nil
105 - },
106 -
107 - isPublishAllowed: func() error {
108 - if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
109 - return errors.New("cannot manually publish while IPNS is mounted")
109 + if err := n.SetupOfflineRouting(); err != nil {
110 + return nil, err
111 }
111 - return nil
112 - },
112 + api.privateKey = n.PrivateKey
113 + api.namesys = n.Namesys
114 + return n.Routing, nil
115 + }
116 + if !settings.Offline {
117 + return n.Routing, nil
118 + }
119 + if !allowOffline {
120 + return nil, coreiface.ErrOffline
121 + }
122 +
123 + //todo: might want to cache this
124 + cfg, err := n.Repo.Config()
125 + if err != nil {
126 + return nil, err
127 + }
128 +
129 + cs := cfg.Ipns.ResolveCacheSize
130 + if cs == 0 {
131 + cs = 128
132 + }
133 + if cs < 0 {
134 + return nil, fmt.Errorf("cannot specify negative resolve cache size")
135 + }
136 +
137 + offroute := offlineroute.NewOfflineRouter(api.repo.Datastore(), api.recordValidator)
138 + api.namesys = namesys.NewNameSystem(offroute, api.repo.Datastore(), cs)
139 +
140 + return offroute, nil
141 + }
142 +
143 + api.isPublishAllowed = func() error {
144 + if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
145 + return errors.New("cannot manually publish while IPNS is mounted")
146 + }
147 + return nil
148 + }
149 +
150 + if settings.Offline {
151 + api.peerstore = nil
152 + api.peerHost = nil
153 + api.namesys = nil
154 + api.recordValidator = nil
155 + api.exchange = nil
156 }
157
115 - return api
158 + return api, nil
159 }
160
161 // Unixfs returns the UnixfsAPI interface implementation backed by the go-ipfs node
core/coreapi/dht.go
+17 -7
@@ -2,7 +2,6 @@ package coreapi
2
3 import (
4 "context"
5 - "errors"
5 "fmt"
6
7 coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
@@ -22,7 +21,12 @@ import (
21 type DhtAPI CoreAPI
22
23 func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (pstore.PeerInfo, error) {
25 - pi, err := api.routing.FindPeer(ctx, peer.ID(p))
24 + r, err := api.routing(false)
25 + if err != nil {
26 + return pstore.PeerInfo{}, err
27 + }
28 +
29 + pi, err := r.FindPeer(ctx, peer.ID(p))
30 if err != nil {
31 return pstore.PeerInfo{}, err
32 }
@@ -36,6 +40,11 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ...
40 return nil, err
41 }
42
43 + r, err := api.routing(false)
44 + if err != nil {
45 + return nil, err
46 + }
47 +
48 rp, err := api.core().ResolvePath(ctx, p)
49 if err != nil {
50 return nil, err
@@ -46,7 +55,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ...
55 return nil, fmt.Errorf("number of providers must be greater than 0")
56 }
57
49 - pchan := api.routing.FindProvidersAsync(ctx, rp.Cid(), numProviders)
58 + pchan := r.FindProvidersAsync(ctx, rp.Cid(), numProviders)
59 return pchan, nil
60 }
61
@@ -56,8 +65,9 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao
65 return err
66 }
67
59 - if api.routing == nil {
60 - return errors.New("cannot provide in offline mode")
68 + r, err := api.routing(false)
69 + if err != nil {
70 + return err
71 }
72
73 rp, err := api.core().ResolvePath(ctx, path)
@@ -77,9 +87,9 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao
87 }
88
89 if settings.Recursive {
80 - err = provideKeysRec(ctx, api.routing, api.blockstore, []cid.Cid{c})
90 + err = provideKeysRec(ctx, r, api.blockstore, []cid.Cid{c})
91 } else {
82 - err = provideKeys(ctx, api.routing, []cid.Cid{c})
92 + err = provideKeys(ctx, r, []cid.Cid{c})
93 }
94 if err != nil {
95 return err
core/coreapi/name.go
+6 -3
@@ -47,7 +47,8 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt
47 return nil, err
48 }
49
50 - if err := api.checkRouting(options.AllowOffline); err != nil {
50 + _, err = api.routing(options.AllowOffline)
51 + if err != nil {
52 return nil, err
53 }
54
@@ -88,7 +89,8 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name
89 return nil, err
90 }
91
91 - if err := api.checkRouting(true); err != nil {
92 + r, err := api.routing(true)
93 + if err != nil {
94 return nil, err
95 }
96
@@ -98,13 +100,14 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name
100 return nil, errors.New("cannot specify both local and nocache")
101 }
102
103 + //TODO: can replaced with api.WithOpt(opts.Api.Offline(true))
104 if options.Local {
105 offroute := offline.NewOfflineRouter(api.repo.Datastore(), api.recordValidator)
106 resolver = namesys.NewIpnsResolver(offroute)
107 }
108
109 if !options.Cache {
107 - resolver = namesys.NewNameSystem(api.routing, api.repo.Datastore(), 0)
110 + resolver = namesys.NewNameSystem(r, api.repo.Datastore(), 0)
111 }
112
113 if !strings.HasPrefix(name, "/ipns/") {
core/coreapi/pubsub.go
+16 -11
@@ -30,7 +30,8 @@ type pubSubMessage struct {
30 }
31
32 func (api *PubSubAPI) Ls(ctx context.Context) ([]string, error) {
33 - if err := api.checkNode(); err != nil {
33 + _, err := api.checkNode()
34 + if err != nil {
35 return nil, err
36 }
37
@@ -38,7 +39,8 @@ func (api *PubSubAPI) Ls(ctx context.Context) ([]string, error) {
39 }
40
41 func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOption) ([]peer.ID, error) {
41 - if err := api.checkNode(); err != nil {
42 + _, err := api.checkNode()
43 + if err != nil {
44 return nil, err
45 }
46
@@ -58,7 +60,8 @@ func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio
60 }
61
62 func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) error {
61 - if err := api.checkNode(); err != nil {
63 + _, err := api.checkNode()
64 + if err != nil {
65 return err
66 }
67
@@ -68,7 +71,8 @@ func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) er
71 func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (coreiface.PubSubSubscription, error) {
72 options, err := caopts.PubSubSubscribeOptions(opts...)
73
71 - if err := api.checkNode(); err != nil {
74 + r, err := api.checkNode()
75 + if err != nil {
76 return nil, err
77 }
78
@@ -87,7 +91,7 @@ func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt
91 return
92 }
93
90 - connectToPubSubPeers(pubctx, api.routing, api.peerHost, blk.Path().Cid())
94 + connectToPubSubPeers(pubctx, r, api.peerHost, blk.Path().Cid())
95 }()
96 }
97
@@ -118,16 +122,17 @@ func connectToPubSubPeers(ctx context.Context, r routing.IpfsRouting, ph p2phost
122 wg.Wait()
123 }
124
121 -func (api *PubSubAPI) checkNode() error {
122 - if err := api.checkRouting(false); err != nil {
123 - return err
125 +func (api *PubSubAPI) checkNode() (routing.IpfsRouting, error) {
126 + if api.pubSub == nil {
127 + return nil, errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.")
128 }
129
126 - if api.pubSub == nil {
127 - return errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.")
130 + r, err := api.routing(false)
131 + if err != nil {
132 + return nil, err
133 }
134
130 - return nil
135 + return r, nil
136 }
137
138 func (sub *pubSubSubscription) Close() error {
core/coreapi/unixfs_test.go
+4 -1
@@ -102,7 +102,10 @@ func makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]*core.IpfsNo
102 return nil, nil, err
103 }
104 nodes[i] = node
105 - apis[i] = coreapi.NewCoreAPI(node)
105 + apis[i], err = coreapi.NewCoreAPI(node)
106 + if err != nil {
107 + return nil, nil, err
108 + }
109 }
110
111 err := mn.LinkAll()
core/corehttp/gateway.go
+6 -1
@@ -25,11 +25,16 @@ func GatewayOption(writable bool, paths ...string) ServeOption {
25 return nil, err
26 }
27
28 + api, err := coreapi.NewCoreAPI(n)
29 + if err != nil {
30 + return nil, err
31 + }
32 +
33 gateway := newGatewayHandler(n, GatewayConfig{
34 Headers: cfg.Gateway.HTTPHeaders,
35 Writable: writable,
36 PathPrefixes: cfg.Gateway.PathPrefixes,
32 - }, coreapi.NewCoreAPI(n))
37 + }, api)
38
39 for _, p := range paths {
40 mux.Handle(p+"/", gateway)
fuse/readonly/ipfs_test.go
+4 -1
@@ -118,7 +118,10 @@ func TestIpfsStressRead(t *testing.T) {
118 nd, mnt := setupIpfsTest(t, nil)
119 defer mnt.Close()
120
121 - api := coreapi.NewCoreAPI(nd)
121 + api, err := coreapi.NewCoreAPI(nd)
122 + if err != nil {
123 + t.Fatal(err)
124 + }
125
126 var nodes []ipld.Node
127 var paths []string
test/integration/addcat_test.go
+4 -1
@@ -120,7 +120,10 @@ func DirectAddCat(data []byte, conf testutil.LatencyConfig) error {
120 }
121 defer catter.Close()
122
123 - catterApi := coreapi.NewCoreAPI(catter)
123 + catterApi, err := coreapi.NewCoreAPI(catter)
124 + if err != nil {
125 + return err
126 + }
127
128 err = mn.LinkAll()
129 if err != nil {
test/integration/bench_cat_test.go
+4 -1
@@ -66,7 +66,10 @@ func benchCat(b *testing.B, data []byte, conf testutil.LatencyConfig) error {
66 }
67 defer catter.Close()
68
69 - catterApi := coreapi.NewCoreAPI(catter)
69 + catterApi, err := coreapi.NewCoreAPI(catter)
70 + if err != nil {
71 + return err
72 + }
73
74 err = mn.LinkAll()
75 if err != nil {
test/integration/three_legged_cat_test.go
+4 -1
@@ -103,7 +103,10 @@ func RunThreeLeggedCat(data []byte, conf testutil.LatencyConfig) error {
103 }
104 defer catter.Close()
105
106 - catterApi := coreapi.NewCoreAPI(catter)
106 + catterApi, err := coreapi.NewCoreAPI(catter)
107 + if err != nil {
108 + return err
109 + }
110
111 mn.LinkAll()
112