From 6e9036769607b6cd837365312f27810350b6e938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 6 Dec 2018 10:47:51 +0100 Subject: [PATCH 01/12] coreapi: Global options for api constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/coreapi/interface/options/global.go | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 core/coreapi/interface/options/global.go diff --git a/core/coreapi/interface/options/global.go b/core/coreapi/interface/options/global.go new file mode 100644 index 000000000..f43965229 --- /dev/null +++ b/core/coreapi/interface/options/global.go @@ -0,0 +1,32 @@ +package options + +type ApiSettings struct { + Offline bool +} + +type ApiOption func(*ApiSettings) error + +func ApiOptions(opts ...ApiOption) (*ApiSettings, error) { + options := &ApiSettings{ + Offline: false, + } + + for _, opt := range opts { + err := opt(options) + if err != nil { + return nil, err + } + } + return options, nil +} + +type apiOpts struct{} + +var Api dagOpts + +func (dagOpts) Offline(offline bool) ApiOption { + return func(settings *ApiSettings) error { + settings.Offline = offline + return nil + } +} From 3183b1cb8e44a3016776d9ba52e7c0d569442f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 6 Dec 2018 21:00:40 +0100 Subject: [PATCH 02/12] coreapi: Untangle from core.IpfsNode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/commands/pin.go | 6 +-- core/coreapi/block.go | 8 ++-- core/coreapi/coreapi.go | 94 +++++++++++++++++++++++++++++++++++++--- core/coreapi/dht.go | 12 ++--- core/coreapi/key.go | 18 ++++---- core/coreapi/name.go | 45 ++++++++++--------- core/coreapi/object.go | 6 +-- core/coreapi/path.go | 2 +- core/coreapi/pin.go | 26 +++++------ core/coreapi/pubsub.go | 27 ++++++------ core/coreapi/swarm.go | 41 +++++++++--------- core/coreapi/unixfs.go | 23 +++++----- core/corerepo/pinning.go | 14 +++--- core/coreunix/add.go | 12 ++--- 14 files changed, 210 insertions(+), 124 deletions(-) diff --git a/core/commands/pin.go b/core/commands/pin.go index c7be82a8e..9495a4e1a 100644 --- a/core/commands/pin.go +++ b/core/commands/pin.go @@ -88,7 +88,7 @@ var addPinCmd = &cmds.Command{ } if !showProgress { - added, err := corerepo.Pin(n, api, req.Context, req.Arguments, recursive) + added, err := corerepo.Pin(n.Pinning, api, req.Context, req.Arguments, recursive) if err != nil { return err } @@ -105,7 +105,7 @@ var addPinCmd = &cmds.Command{ ch := make(chan pinResult, 1) go func() { - added, err := corerepo.Pin(n, api, ctx, req.Arguments, recursive) + added, err := corerepo.Pin(n.Pinning, api, ctx, req.Arguments, recursive) ch <- pinResult{pins: added, err: err} }() @@ -215,7 +215,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.) return err } - removed, err := corerepo.Unpin(n, api, req.Context, req.Arguments, recursive) + removed, err := corerepo.Unpin(n.Pinning, api, req.Context, req.Arguments, recursive) if err != nil { return err } diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 933d5de72..fafd24755 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -43,7 +43,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc return nil, err } - err = api.node.Blocks.AddBlock(b) + err = api.blocks.AddBlock(b) if err != nil { return nil, err } @@ -57,7 +57,7 @@ func (api *BlockAPI) Get(ctx context.Context, p coreiface.Path) (io.Reader, erro return nil, err } - b, err := api.node.Blocks.GetBlock(ctx, rp.Cid()) + b, err := api.blocks.GetBlock(ctx, rp.Cid()) if err != nil { return nil, err } @@ -78,7 +78,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p coreiface.Path, opts ...caopts.Bl cids := []cid.Cid{rp.Cid()} o := util.RmBlocksOpts{Force: settings.Force} - out, err := util.RmBlocks(api.node.Blockstore, api.node.Pinning, cids, o) + out, err := util.RmBlocks(api.blockstore, api.pinning, cids, o) if err != nil { return err } @@ -109,7 +109,7 @@ func (api *BlockAPI) Stat(ctx context.Context, p coreiface.Path) (coreiface.Bloc return nil, err } - b, err := api.node.Blocks.GetBlock(ctx, rp.Cid()) + b, err := api.blocks.GetBlock(ctx, rp.Cid()) if err != nil { return nil, err } diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index b27a7cfed..ee21bdef8 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -15,25 +15,103 @@ package coreapi import ( "context" + "errors" core "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + namesys "github.com/ipfs/go-ipfs/namesys" + pin "github.com/ipfs/go-ipfs/pin" + repo "github.com/ipfs/go-ipfs/repo" + ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" + exchange "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface" + bserv "gx/ipfs/QmPoh3SrQzFBWtdGK6qmHDV4EanKR6kYPj4DD3J2NLoEmZ/go-blockservice" + routing "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" + blockstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" + peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" + pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub" ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log" dag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag" + record "gx/ipfs/QmfARXVCzpwFXQdepAJZuqyNDgV9doEsMnVCo1ssmuSe1U/go-libp2p-record" + p2phost "gx/ipfs/QmfD51tKgJiTMnW9JEiDiPwsCY4mqUoxkhKhBfyW12spTC/go-libp2p-host" ) var log = logging.Logger("core/coreapi") type CoreAPI struct { - node *core.IpfsNode - dag ipld.DAGService + nctx context.Context + + identity peer.ID //TODO: check mutable structs + privateKey ci.PrivKey + + repo repo.Repo + blockstore blockstore.GCBlockstore + baseBlocks blockstore.Blockstore + blocks bserv.BlockService + dag ipld.DAGService + pinning pin.Pinner + + peerstore pstore.Peerstore + peerHost p2phost.Host + namesys namesys.NameSystem + recordValidator record.Validator + exchange exchange.Interface + + routing routing.IpfsRouting + pubSub *pubsub.PubSub + + checkRouting func(bool) error + + // TODO: this can be generalized to all functions when we implement some + // api based security mechanism + isPublishAllowed func() error } // NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node. -func NewCoreAPI(n *core.IpfsNode) coreiface.CoreAPI { - api := &CoreAPI{n, n.DAG} +func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) coreiface.CoreAPI { + api := &CoreAPI{ + nctx: n.Context(), + + identity: n.Identity, + privateKey: n.PrivateKey, + + repo: n.Repo, + blockstore: n.Blockstore, + baseBlocks: n.BaseBlocks, + blocks: n.Blocks, + dag: n.DAG, + pinning: n.Pinning, + + peerstore: n.Peerstore, + peerHost: n.PeerHost, + namesys: n.Namesys, + recordValidator: n.RecordValidator, + exchange: n.Exchange, + + routing: n.Routing, + pubSub: n.PubSub, + + checkRouting: func(allowOffline bool) error { + if !n.OnlineMode() { + if !allowOffline { + return coreiface.ErrOffline + } + return n.SetupOfflineRouting() + } + return nil + }, + + isPublishAllowed: func() error { + if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { + return errors.New("cannot manually publish while IPNS is mounted") + } + return nil + }, + } + return api } @@ -89,6 +167,10 @@ func (api *CoreAPI) PubSub() coreiface.PubSubAPI { // getSession returns new api backed by the same node with a read-only session DAG func (api *CoreAPI) getSession(ctx context.Context) *CoreAPI { - ng := dag.NewReadOnlyDagService(dag.NewSession(ctx, api.dag)) - return &CoreAPI{api.node, ng} + sesApi := *api + + //TODO: we may want to apply this to other things too + sesApi.dag = dag.NewReadOnlyDagService(dag.NewSession(ctx, api.dag)) + + return &sesApi } diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index ce94e8ca7..7825fe6ee 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -22,7 +22,7 @@ import ( type DhtAPI CoreAPI func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (pstore.PeerInfo, error) { - pi, err := api.node.Routing.FindPeer(ctx, peer.ID(p)) + pi, err := api.routing.FindPeer(ctx, peer.ID(p)) if err != nil { return pstore.PeerInfo{}, err } @@ -46,7 +46,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ... return nil, fmt.Errorf("number of providers must be greater than 0") } - pchan := api.node.Routing.FindProvidersAsync(ctx, rp.Cid(), numProviders) + pchan := api.routing.FindProvidersAsync(ctx, rp.Cid(), numProviders) return pchan, nil } @@ -56,7 +56,7 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao return err } - if api.node.Routing == nil { + if api.routing == nil { return errors.New("cannot provide in offline mode") } @@ -67,7 +67,7 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao c := rp.Cid() - has, err := api.node.Blockstore.Has(c) + has, err := api.blockstore.Has(c) if err != nil { return err } @@ -77,9 +77,9 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao } if settings.Recursive { - err = provideKeysRec(ctx, api.node.Routing, api.node.Blockstore, []cid.Cid{c}) + err = provideKeysRec(ctx, api.routing, api.blockstore, []cid.Cid{c}) } else { - err = provideKeys(ctx, api.node.Routing, []cid.Cid{c}) + err = provideKeys(ctx, api.routing, []cid.Cid{c}) } if err != nil { return err diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 30c26ada9..cf0411046 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -54,7 +54,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key return nil, fmt.Errorf("cannot create key with name 'self'") } - _, err = api.node.Repo.Keystore().Get(name) + _, err = api.repo.Keystore().Get(name) if err == nil { return nil, fmt.Errorf("key with name '%s' already exists", name) } @@ -87,7 +87,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key return nil, fmt.Errorf("unrecognized key type: %s", options.Algorithm) } - err = api.node.Repo.Keystore().Put(name, sk) + err = api.repo.Keystore().Put(name, sk) if err != nil { return nil, err } @@ -102,7 +102,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key // List returns a list keys stored in keystore. func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { - keys, err := api.node.Repo.Keystore().List() + keys, err := api.repo.Keystore().List() if err != nil { return nil, err } @@ -110,10 +110,10 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { sort.Strings(keys) out := make([]coreiface.Key, len(keys)+1) - out[0] = &key{"self", api.node.Identity} + out[0] = &key{"self", api.identity} for n, k := range keys { - privKey, err := api.node.Repo.Keystore().Get(k) + privKey, err := api.repo.Keystore().Get(k) if err != nil { return nil, err } @@ -138,7 +138,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o return nil, false, err } - ks := api.node.Repo.Keystore() + ks := api.repo.Keystore() if oldName == "self" { return nil, false, fmt.Errorf("cannot rename key with name 'self'") @@ -192,7 +192,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o // Remove removes keys from keystore. Returns ipns path of the removed key. func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Key, error) { - ks := api.node.Repo.Keystore() + ks := api.repo.Keystore() if name == "self" { return nil, fmt.Errorf("cannot remove key with name 'self'") @@ -219,9 +219,9 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Key, erro } func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) { - if api.node.Identity == "" { + if api.identity == "" { return nil, errors.New("identity not loaded") } - return &key{"self", api.node.Identity}, nil + return &key{"self", api.identity}, nil } diff --git a/core/coreapi/name.go b/core/coreapi/name.go index e30801317..130361f68 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -7,13 +7,13 @@ import ( "strings" "time" - "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" "github.com/ipfs/go-ipfs/keystore" "github.com/ipfs/go-ipfs/namesys" "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" + ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" ipath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path" "gx/ipfs/QmdmWkx54g7VfVyxeG8ic84uf4G6Eq1GohuyKA3XDuJ8oC/go-ipfs-routing/offline" @@ -38,20 +38,17 @@ func (e *ipnsEntry) Value() coreiface.Path { // Publish announces new IPNS name and returns the new IPNS entry. func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopts.NamePublishOption) (coreiface.IpnsEntry, error) { + if err := api.isPublishAllowed(); err != nil { + return nil, err + } + options, err := caopts.NamePublishOptions(opts...) if err != nil { return nil, err } - n := api.node - if !n.OnlineMode() { - if !options.AllowOffline { - return nil, coreiface.ErrOffline - } - } - - if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { - return nil, errors.New("cannot manually publish while IPNS is mounted") + if err := api.checkRouting(options.AllowOffline); err != nil { + return nil, err } pth, err := ipath.ParsePath(p.String()) @@ -59,7 +56,7 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt return nil, err } - k, err := keylookup(n, options.Key) + k, err := keylookup(api.privateKey, api.repo.Keystore(), options.Key) if err != nil { return nil, err } @@ -69,7 +66,7 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt } eol := time.Now().Add(options.ValidTime) - err = n.Namesys.PublishWithEOL(ctx, k, pth, eol) + err = api.namesys.PublishWithEOL(ctx, k, pth, eol) if err != nil { return nil, err } @@ -91,21 +88,23 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name return nil, err } - n := api.node + if err := api.checkRouting(true); err != nil { + return nil, err + } - var resolver namesys.Resolver = n.Namesys + var resolver namesys.Resolver = api.namesys - if options.Local && !options.Cache { + if options.Local && !options.Cache { //TODO: rm before offline/local global opt merge return nil, errors.New("cannot specify both local and nocache") } if options.Local { - offroute := offline.NewOfflineRouter(n.Repo.Datastore(), n.RecordValidator) + offroute := offline.NewOfflineRouter(api.repo.Datastore(), api.recordValidator) resolver = namesys.NewIpnsResolver(offroute) } if !options.Cache { - resolver = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), 0) + resolver = namesys.NewNameSystem(api.routing, api.repo.Datastore(), 0) } if !strings.HasPrefix(name, "/ipns/") { @@ -150,8 +149,12 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam return p, err } -func keylookup(n *core.IpfsNode, k string) (crypto.PrivKey, error) { - res, err := n.GetKey(k) +func keylookup(self ci.PrivKey, kstore keystore.Keystore, k string) (crypto.PrivKey, error) { + if k == "self" { + return self, nil + } + + res, err := kstore.Get(k) if res != nil { return res, nil } @@ -160,13 +163,13 @@ func keylookup(n *core.IpfsNode, k string) (crypto.PrivKey, error) { return nil, err } - keys, err := n.Repo.Keystore().List() + keys, err := kstore.List() if err != nil { return nil, err } for _, key := range keys { - privKey, err := n.Repo.Keystore().Get(key) + privKey, err := kstore.Get(key) if err != nil { return nil, err } diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 9e18d479b..f343a8e00 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -118,7 +118,7 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj } if options.Pin { - defer api.node.Blockstore.PinLock().Unlock() + defer api.blockstore.PinLock().Unlock() } err = api.dag.Add(ctx, dagnode) @@ -127,8 +127,8 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj } if options.Pin { - api.node.Pinning.PinWithMode(dagnode.Cid(), pin.Recursive) - err = api.node.Pinning.Flush() + api.pinning.PinWithMode(dagnode.Cid(), pin.Recursive) + err = api.pinning.Flush() if err != nil { return nil, err } diff --git a/core/coreapi/path.go b/core/coreapi/path.go index 93d39cd1e..a5706fee1 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -38,7 +38,7 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreifac } ipath := ipfspath.Path(p.String()) - ipath, err := core.ResolveIPNS(ctx, api.node.Namesys, ipath) + ipath, err := core.ResolveIPNS(ctx, api.namesys, ipath) if err == core.ErrNoNamesys { return nil, coreiface.ErrOffline } else if err != nil { diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index d5222fdf7..9e8c15da9 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -27,14 +27,14 @@ func (api *PinAPI) Add(ctx context.Context, p coreiface.Path, opts ...caopts.Pin return err } - defer api.node.Blockstore.PinLock().Unlock() + defer api.blockstore.PinLock().Unlock() - _, err = corerepo.Pin(api.node, api.core(), ctx, []string{rp.Cid().String()}, settings.Recursive) + _, err = corerepo.Pin(api.pinning, api.core(), ctx, []string{rp.Cid().String()}, settings.Recursive) if err != nil { return err } - return api.node.Pinning.Flush() + return api.pinning.Flush() } func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]coreiface.Pin, error) { @@ -53,12 +53,12 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]coreif } func (api *PinAPI) Rm(ctx context.Context, p coreiface.Path) error { - _, err := corerepo.Unpin(api.node, api.core(), ctx, []string{p.String()}, true) + _, err := corerepo.Unpin(api.pinning, api.core(), ctx, []string{p.String()}, true) if err != nil { return err } - return api.node.Pinning.Flush() + return api.pinning.Flush() } func (api *PinAPI) Update(ctx context.Context, from coreiface.Path, to coreiface.Path, opts ...caopts.PinUpdateOption) error { @@ -77,14 +77,14 @@ func (api *PinAPI) Update(ctx context.Context, from coreiface.Path, to coreiface return err } - defer api.node.Blockstore.PinLock().Unlock() + defer api.blockstore.PinLock().Unlock() - err = api.node.Pinning.Update(ctx, fp.Cid(), tp.Cid(), settings.Unpin) + err = api.pinning.Update(ctx, fp.Cid(), tp.Cid(), settings.Unpin) if err != nil { return err } - return api.node.Pinning.Flush() + return api.pinning.Flush() } type pinStatus struct { @@ -117,10 +117,10 @@ func (n *badNode) Err() error { func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, error) { visited := make(map[cid.Cid]*pinStatus) - bs := api.node.Blocks.Blockstore() + bs := api.blockstore DAG := merkledag.NewDAGService(bserv.New(bs, offline.Exchange(bs))) getLinks := merkledag.GetLinksWithDAG(DAG) - recPins := api.node.Pinning.RecursiveKeys() + recPins := api.pinning.RecursiveKeys() var checkPin func(root cid.Cid) *pinStatus checkPin = func(root cid.Cid) *pinStatus { @@ -187,11 +187,11 @@ func (api *PinAPI) pinLsAll(typeStr string, ctx context.Context) ([]coreiface.Pi } if typeStr == "direct" || typeStr == "all" { - AddToResultKeys(api.node.Pinning.DirectKeys(), "direct") + AddToResultKeys(api.pinning.DirectKeys(), "direct") } if typeStr == "indirect" || typeStr == "all" { set := cid.NewSet() - for _, k := range api.node.Pinning.RecursiveKeys() { + for _, k := range api.pinning.RecursiveKeys() { err := merkledag.EnumerateChildren(ctx, merkledag.GetLinksWithDAG(api.dag), k, set.Visit) if err != nil { return nil, err @@ -200,7 +200,7 @@ func (api *PinAPI) pinLsAll(typeStr string, ctx context.Context) ([]coreiface.Pi AddToResultKeys(set.Keys(), "indirect") } if typeStr == "recursive" || typeStr == "all" { - AddToResultKeys(api.node.Pinning.RecursiveKeys(), "recursive") + AddToResultKeys(api.pinning.RecursiveKeys(), "recursive") } out := make([]coreiface.Pin, 0, len(keys)) diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index 119134eea..5dbc6e228 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -7,14 +7,15 @@ import ( "sync" "time" - core "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options" cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" + routing "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub" + p2phost "gx/ipfs/QmfD51tKgJiTMnW9JEiDiPwsCY4mqUoxkhKhBfyW12spTC/go-libp2p-host" ) type PubSubAPI CoreAPI @@ -33,7 +34,7 @@ func (api *PubSubAPI) Ls(ctx context.Context) ([]string, error) { return nil, err } - return api.node.PubSub.GetTopics(), nil + return api.pubSub.GetTopics(), nil } func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOption) ([]peer.ID, error) { @@ -46,7 +47,7 @@ func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio return nil, err } - peers := api.node.PubSub.ListPeers(settings.Topic) + peers := api.pubSub.ListPeers(settings.Topic) out := make([]peer.ID, len(peers)) for i, peer := range peers { @@ -61,7 +62,7 @@ func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) er return err } - return api.node.PubSub.Publish(topic, data) + return api.pubSub.Publish(topic, data) } func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (coreiface.PubSubSubscription, error) { @@ -71,12 +72,12 @@ func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt return nil, err } - sub, err := api.node.PubSub.Subscribe(topic) + sub, err := api.pubSub.Subscribe(topic) if err != nil { return nil, err } - pubctx, cancel := context.WithCancel(api.node.Context()) + pubctx, cancel := context.WithCancel(api.nctx) if options.Discover { go func() { @@ -86,18 +87,18 @@ func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt return } - connectToPubSubPeers(pubctx, api.node, blk.Path().Cid()) + connectToPubSubPeers(pubctx, api.routing, api.peerHost, blk.Path().Cid()) }() } return &pubSubSubscription{cancel, sub}, nil } -func connectToPubSubPeers(ctx context.Context, n *core.IpfsNode, cid cid.Cid) { +func connectToPubSubPeers(ctx context.Context, r routing.IpfsRouting, ph p2phost.Host, cid cid.Cid) { ctx, cancel := context.WithCancel(ctx) defer cancel() - provs := n.Routing.FindProvidersAsync(ctx, cid, 10) + provs := r.FindProvidersAsync(ctx, cid, 10) var wg sync.WaitGroup for p := range provs { wg.Add(1) @@ -105,7 +106,7 @@ func connectToPubSubPeers(ctx context.Context, n *core.IpfsNode, cid cid.Cid) { defer wg.Done() ctx, cancel := context.WithTimeout(ctx, time.Second*10) defer cancel() - err := n.PeerHost.Connect(ctx, pi) + err := ph.Connect(ctx, pi) if err != nil { log.Info("pubsub discover: ", err) return @@ -118,11 +119,11 @@ func connectToPubSubPeers(ctx context.Context, n *core.IpfsNode, cid cid.Cid) { } func (api *PubSubAPI) checkNode() error { - if !api.node.OnlineMode() { - return coreiface.ErrOffline + if err := api.checkRouting(false); err != nil { + return err } - if api.node.PubSub == nil { + if api.pubSub == nil { return errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.") } diff --git a/core/coreapi/swarm.go b/core/coreapi/swarm.go index de4f36533..310b9ada1 100644 --- a/core/coreapi/swarm.go +++ b/core/coreapi/swarm.go @@ -5,7 +5,6 @@ import ( "sort" "time" - core "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" inet "gx/ipfs/QmPtFaR7BWHLAjSwLh9kXcyrgTzDpuhcWLkx8ioa9RMYnx/go-libp2p-net" @@ -21,9 +20,9 @@ import ( type SwarmAPI CoreAPI type connInfo struct { - node *core.IpfsNode - conn net.Conn - dir net.Direction + peerstore pstore.Peerstore + conn net.Conn + dir net.Direction addr ma.Multiaddr peer peer.ID @@ -31,19 +30,19 @@ type connInfo struct { } func (api *SwarmAPI) Connect(ctx context.Context, pi pstore.PeerInfo) error { - if api.node.PeerHost == nil { + if api.peerHost == nil { return coreiface.ErrOffline } - if swrm, ok := api.node.PeerHost.Network().(*swarm.Swarm); ok { + if swrm, ok := api.peerHost.Network().(*swarm.Swarm); ok { swrm.Backoff().Clear(pi.ID) } - return api.node.PeerHost.Connect(ctx, pi) + return api.peerHost.Connect(ctx, pi) } func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error { - if api.node.PeerHost == nil { + if api.peerHost == nil { return coreiface.ErrOffline } @@ -54,7 +53,7 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error { taddr := ia.Transport() id := ia.ID() - net := api.node.PeerHost.Network() + net := api.peerHost.Network() if taddr == nil { if net.Connectedness(id) != inet.Connected { @@ -78,12 +77,12 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error { } func (api *SwarmAPI) KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) { - if api.node.PeerHost == nil { + if api.peerHost == nil { return nil, coreiface.ErrOffline } addrs := make(map[peer.ID][]ma.Multiaddr) - ps := api.node.PeerHost.Network().Peerstore() + ps := api.peerHost.Network().Peerstore() for _, p := range ps.Peers() { for _, a := range ps.Addrs(p) { addrs[p] = append(addrs[p], a) @@ -97,27 +96,27 @@ func (api *SwarmAPI) KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, er } func (api *SwarmAPI) LocalAddrs(context.Context) ([]ma.Multiaddr, error) { - if api.node.PeerHost == nil { + if api.peerHost == nil { return nil, coreiface.ErrOffline } - return api.node.PeerHost.Addrs(), nil + return api.peerHost.Addrs(), nil } func (api *SwarmAPI) ListenAddrs(context.Context) ([]ma.Multiaddr, error) { - if api.node.PeerHost == nil { + if api.peerHost == nil { return nil, coreiface.ErrOffline } - return api.node.PeerHost.Network().InterfaceListenAddresses() + return api.peerHost.Network().InterfaceListenAddresses() } func (api *SwarmAPI) Peers(context.Context) ([]coreiface.ConnectionInfo, error) { - if api.node.PeerHost == nil { + if api.peerHost == nil { return nil, coreiface.ErrOffline } - conns := api.node.PeerHost.Network().Conns() + conns := api.peerHost.Network().Conns() var out []coreiface.ConnectionInfo for _, c := range conns { @@ -125,9 +124,9 @@ func (api *SwarmAPI) Peers(context.Context) ([]coreiface.ConnectionInfo, error) addr := c.RemoteMultiaddr() ci := &connInfo{ - node: api.node, - conn: c, - dir: c.Stat().Direction, + peerstore: api.peerstore, + conn: c, + dir: c.Stat().Direction, addr: addr, peer: pid, @@ -160,7 +159,7 @@ func (ci *connInfo) Direction() net.Direction { } func (ci *connInfo) Latency() (time.Duration, error) { - return ci.node.Peerstore.LatencyEWMA(peer.ID(ci.ID())), nil + return ci.peerstore.LatencyEWMA(peer.ID(ci.ID())), nil } func (ci *connInfo) Streams() ([]protocol.ID, error) { diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 27341c927..372d79e77 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -34,9 +34,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options return nil, err } - n := api.node - - cfg, err := n.Repo.Config() + cfg, err := api.repo.Config() if err != nil { return nil, err } @@ -53,6 +51,13 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options return nil, filestore.ErrFilestoreNotEnabled } + addblockstore := api.blockstore + if !(settings.FsCache || settings.NoCopy) { + addblockstore = bstore.NewGCBlockstore(api.baseBlocks, api.blockstore) + } + exch := api.exchange + pinning := api.pinning + if settings.OnlyHash { nilnode, err := core.NewNode(ctx, &core.BuildCfg{ //TODO: need this to be true or all files @@ -62,15 +67,11 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options if err != nil { return nil, err } - n = nilnode + addblockstore = nilnode.Blockstore + exch = nilnode.Exchange + pinning = nilnode.Pinning } - addblockstore := n.Blockstore - if !(settings.FsCache || settings.NoCopy) { - addblockstore = bstore.NewGCBlockstore(n.BaseBlocks, n.GCLocker) - } - - exch := n.Exchange if settings.Local { exch = offline.Exchange(addblockstore) } @@ -78,7 +79,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options bserv := blockservice.New(addblockstore, exch) // hash security 001 dserv := dag.NewDAGService(bserv) - fileAdder, err := coreunix.NewAdder(ctx, n.Pinning, n.Blockstore, dserv) + fileAdder, err := coreunix.NewAdder(ctx, pinning, addblockstore, dserv) if err != nil { return nil, err } diff --git a/core/corerepo/pinning.go b/core/corerepo/pinning.go index f39d39276..9c2a02781 100644 --- a/core/corerepo/pinning.go +++ b/core/corerepo/pinning.go @@ -16,14 +16,14 @@ package corerepo import ( "context" "fmt" + "github.com/ipfs/go-ipfs/pin" - "github.com/ipfs/go-ipfs/core" "github.com/ipfs/go-ipfs/core/coreapi/interface" "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid" ) -func Pin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) { +func Pin(pinning pin.Pinner, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) { out := make([]cid.Cid, len(paths)) for i, fpath := range paths { @@ -36,14 +36,14 @@ func Pin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []strin if err != nil { return nil, fmt.Errorf("pin: %s", err) } - err = n.Pinning.Pin(ctx, dagnode, recursive) + err = pinning.Pin(ctx, dagnode, recursive) if err != nil { return nil, fmt.Errorf("pin: %s", err) } out[i] = dagnode.Cid() } - err := n.Pinning.Flush() + err := pinning.Flush() if err != nil { return nil, err } @@ -51,7 +51,7 @@ func Pin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []strin return out, nil } -func Unpin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) { +func Unpin(pinning pin.Pinner, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) { unpinned := make([]cid.Cid, len(paths)) for i, p := range paths { @@ -65,14 +65,14 @@ func Unpin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []str return nil, err } - err = n.Pinning.Unpin(ctx, k.Cid(), recursive) + err = pinning.Unpin(ctx, k.Cid(), recursive) if err != nil { return nil, err } unpinned[i] = k.Cid() } - err := n.Pinning.Flush() + err := pinning.Flush() if err != nil { return nil, err } diff --git a/core/coreunix/add.go b/core/coreunix/add.go index e50adaa08..b4636a5ba 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -48,13 +48,13 @@ type Object struct { } // NewAdder Returns a new Adder used for a file add operation. -func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCBlockstore, ds ipld.DAGService) (*Adder, error) { +func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCLocker, ds ipld.DAGService) (*Adder, error) { bufferedDS := ipld.NewBufferedDAG(ctx, ds) return &Adder{ ctx: ctx, pinning: p, - blockstore: bs, + gcLocker: bs, dagService: ds, bufferedDS: bufferedDS, Progress: false, @@ -70,7 +70,7 @@ func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCBlockstore, ds ipld type Adder struct { ctx context.Context pinning pin.Pinner - blockstore bstore.GCBlockstore + gcLocker bstore.GCLocker dagService ipld.DAGService bufferedDS *ipld.BufferedDAG Out chan<- interface{} @@ -401,7 +401,7 @@ func (adder *Adder) addNode(node ipld.Node, path string) error { // AddAllAndPin adds the given request's files and pin them. func (adder *Adder) AddAllAndPin(file files.Node) (ipld.Node, error) { if adder.Pin { - adder.unlocker = adder.blockstore.PinLock() + adder.unlocker = adder.gcLocker.PinLock() } defer func() { if adder.unlocker != nil { @@ -556,14 +556,14 @@ func (adder *Adder) addDir(path string, dir files.Directory) error { } func (adder *Adder) maybePauseForGC() error { - if adder.unlocker != nil && adder.blockstore.GCRequested() { + if adder.unlocker != nil && adder.gcLocker.GCRequested() { err := adder.PinRoot() if err != nil { return err } adder.unlocker.Unlock() - adder.unlocker = adder.blockstore.PinLock() + adder.unlocker = adder.gcLocker.PinLock() } return nil } From c832a32a4c5b6633df9efe4793edb837317ed9fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 6 Dec 2018 22:25:48 +0100 Subject: [PATCH 03/12] coreapi: global offline option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- commands/context.go | 5 +- core/coreapi/coreapi.go | 123 +++++++++++++++------- core/coreapi/dht.go | 24 +++-- core/coreapi/name.go | 9 +- core/coreapi/pubsub.go | 29 ++--- core/coreapi/unixfs_test.go | 5 +- core/corehttp/gateway.go | 7 +- fuse/readonly/ipfs_test.go | 5 +- test/integration/addcat_test.go | 5 +- test/integration/bench_cat_test.go | 5 +- test/integration/three_legged_cat_test.go | 5 +- 11 files changed, 153 insertions(+), 69 deletions(-) diff --git a/commands/context.go b/commands/context.go index 41d6b05d0..29fe652f1 100644 --- a/commands/context.go +++ b/commands/context.go @@ -68,7 +68,10 @@ func (c *Context) GetAPI() (coreiface.CoreAPI, error) { if err != nil { return nil, err } - c.api = coreapi.NewCoreAPI(n) + c.api, err = coreapi.NewCoreAPI(n) + if err != nil { + return nil, err + } } return c.api, nil } diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index ee21bdef8..e9055677f 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -16,26 +16,27 @@ package coreapi import ( "context" "errors" - - core "github.com/ipfs/go-ipfs/core" + "fmt" + "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" - options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" - namesys "github.com/ipfs/go-ipfs/namesys" - pin "github.com/ipfs/go-ipfs/pin" - repo "github.com/ipfs/go-ipfs/repo" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + "github.com/ipfs/go-ipfs/namesys" + "github.com/ipfs/go-ipfs/pin" + "github.com/ipfs/go-ipfs/repo" ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" - exchange "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface" + "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface" bserv "gx/ipfs/QmPoh3SrQzFBWtdGK6qmHDV4EanKR6kYPj4DD3J2NLoEmZ/go-blockservice" - routing "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" - blockstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" - peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" + "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" + "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub" ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log" dag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag" - record "gx/ipfs/QmfARXVCzpwFXQdepAJZuqyNDgV9doEsMnVCo1ssmuSe1U/go-libp2p-record" + offlineroute "gx/ipfs/QmdmWkx54g7VfVyxeG8ic84uf4G6Eq1GohuyKA3XDuJ8oC/go-ipfs-routing/offline" + "gx/ipfs/QmfARXVCzpwFXQdepAJZuqyNDgV9doEsMnVCo1ssmuSe1U/go-libp2p-record" p2phost "gx/ipfs/QmfD51tKgJiTMnW9JEiDiPwsCY4mqUoxkhKhBfyW12spTC/go-libp2p-host" ) @@ -50,20 +51,20 @@ type CoreAPI struct { repo repo.Repo blockstore blockstore.GCBlockstore baseBlocks blockstore.Blockstore - blocks bserv.BlockService - dag ipld.DAGService pinning pin.Pinner + blocks bserv.BlockService + dag ipld.DAGService + peerstore pstore.Peerstore peerHost p2phost.Host - namesys namesys.NameSystem recordValidator record.Validator exchange exchange.Interface - routing routing.IpfsRouting - pubSub *pubsub.PubSub + namesys namesys.NameSystem + routing func(bool) (routing.IpfsRouting, error) - checkRouting func(bool) error + pubSub *pubsub.PubSub // TODO: this can be generalized to all functions when we implement some // api based security mechanism @@ -71,7 +72,12 @@ type CoreAPI struct { } // NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node. -func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) coreiface.CoreAPI { +func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) (coreiface.CoreAPI, error) { + settings, err := options.ApiOptions(opts...) + if err != nil { + return nil, err + } + api := &CoreAPI{ nctx: n.Context(), @@ -81,38 +87,75 @@ func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) coreiface.CoreAPI { repo: n.Repo, blockstore: n.Blockstore, baseBlocks: n.BaseBlocks, - blocks: n.Blocks, - dag: n.DAG, pinning: n.Pinning, + blocks: n.Blocks, + dag: n.DAG, + peerstore: n.Peerstore, peerHost: n.PeerHost, namesys: n.Namesys, recordValidator: n.RecordValidator, exchange: n.Exchange, - routing: n.Routing, - pubSub: n.PubSub, - - checkRouting: func(allowOffline bool) error { - if !n.OnlineMode() { - if !allowOffline { - return coreiface.ErrOffline - } - return n.SetupOfflineRouting() - } - return nil - }, - - isPublishAllowed: func() error { - if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { - return errors.New("cannot manually publish while IPNS is mounted") - } - return nil - }, + pubSub: n.PubSub, } - return api + api.routing = func(allowOffline bool) (routing.IpfsRouting, error) { + if !n.OnlineMode() { + if !allowOffline { + return nil, coreiface.ErrOffline + } + if err := n.SetupOfflineRouting(); err != nil { + return nil, err + } + api.privateKey = n.PrivateKey + api.namesys = n.Namesys + return n.Routing, nil + } + if !settings.Offline { + return n.Routing, nil + } + if !allowOffline { + return nil, coreiface.ErrOffline + } + + //todo: might want to cache this + cfg, err := n.Repo.Config() + if err != nil { + return nil, err + } + + cs := cfg.Ipns.ResolveCacheSize + if cs == 0 { + cs = 128 + } + if cs < 0 { + return nil, fmt.Errorf("cannot specify negative resolve cache size") + } + + offroute := offlineroute.NewOfflineRouter(api.repo.Datastore(), api.recordValidator) + api.namesys = namesys.NewNameSystem(offroute, api.repo.Datastore(), cs) + + return offroute, nil + } + + api.isPublishAllowed = func() error { + if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { + return errors.New("cannot manually publish while IPNS is mounted") + } + return nil + } + + if settings.Offline { + api.peerstore = nil + api.peerHost = nil + api.namesys = nil + api.recordValidator = nil + api.exchange = nil + } + + return api, nil } // Unixfs returns the UnixfsAPI interface implementation backed by the go-ipfs node diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index 7825fe6ee..cc5447b3c 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -2,7 +2,6 @@ package coreapi import ( "context" - "errors" "fmt" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" @@ -22,7 +21,12 @@ import ( type DhtAPI CoreAPI func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (pstore.PeerInfo, error) { - pi, err := api.routing.FindPeer(ctx, peer.ID(p)) + r, err := api.routing(false) + if err != nil { + return pstore.PeerInfo{}, err + } + + pi, err := r.FindPeer(ctx, peer.ID(p)) if err != nil { return pstore.PeerInfo{}, err } @@ -36,6 +40,11 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ... return nil, err } + r, err := api.routing(false) + if err != nil { + return nil, err + } + rp, err := api.core().ResolvePath(ctx, p) if err != nil { return nil, err @@ -46,7 +55,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ... return nil, fmt.Errorf("number of providers must be greater than 0") } - pchan := api.routing.FindProvidersAsync(ctx, rp.Cid(), numProviders) + pchan := r.FindProvidersAsync(ctx, rp.Cid(), numProviders) return pchan, nil } @@ -56,8 +65,9 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao return err } - if api.routing == nil { - return errors.New("cannot provide in offline mode") + r, err := api.routing(false) + if err != nil { + return err } rp, err := api.core().ResolvePath(ctx, path) @@ -77,9 +87,9 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao } if settings.Recursive { - err = provideKeysRec(ctx, api.routing, api.blockstore, []cid.Cid{c}) + err = provideKeysRec(ctx, r, api.blockstore, []cid.Cid{c}) } else { - err = provideKeys(ctx, api.routing, []cid.Cid{c}) + err = provideKeys(ctx, r, []cid.Cid{c}) } if err != nil { return err diff --git a/core/coreapi/name.go b/core/coreapi/name.go index 130361f68..c912bf185 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -47,7 +47,8 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt return nil, err } - if err := api.checkRouting(options.AllowOffline); err != nil { + _, err = api.routing(options.AllowOffline) + if err != nil { return nil, err } @@ -88,7 +89,8 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name return nil, err } - if err := api.checkRouting(true); err != nil { + r, err := api.routing(true) + if err != nil { return nil, err } @@ -98,13 +100,14 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name return nil, errors.New("cannot specify both local and nocache") } + //TODO: can replaced with api.WithOpt(opts.Api.Offline(true)) if options.Local { offroute := offline.NewOfflineRouter(api.repo.Datastore(), api.recordValidator) resolver = namesys.NewIpnsResolver(offroute) } if !options.Cache { - resolver = namesys.NewNameSystem(api.routing, api.repo.Datastore(), 0) + resolver = namesys.NewNameSystem(r, api.repo.Datastore(), 0) } if !strings.HasPrefix(name, "/ipns/") { diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index 5dbc6e228..378e3dbc6 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -30,7 +30,8 @@ type pubSubMessage struct { } func (api *PubSubAPI) Ls(ctx context.Context) ([]string, error) { - if err := api.checkNode(); err != nil { + _, err := api.checkNode() + if err != nil { return nil, err } @@ -38,7 +39,8 @@ func (api *PubSubAPI) Ls(ctx context.Context) ([]string, error) { } func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOption) ([]peer.ID, error) { - if err := api.checkNode(); err != nil { + _, err := api.checkNode() + if err != nil { return nil, err } @@ -58,7 +60,8 @@ func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio } func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) error { - if err := api.checkNode(); err != nil { + _, err := api.checkNode() + if err != nil { return err } @@ -68,7 +71,8 @@ func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) er func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (coreiface.PubSubSubscription, error) { options, err := caopts.PubSubSubscribeOptions(opts...) - if err := api.checkNode(); err != nil { + r, err := api.checkNode() + if err != nil { return nil, err } @@ -87,7 +91,7 @@ func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt return } - connectToPubSubPeers(pubctx, api.routing, api.peerHost, blk.Path().Cid()) + connectToPubSubPeers(pubctx, r, api.peerHost, blk.Path().Cid()) }() } @@ -118,16 +122,17 @@ func connectToPubSubPeers(ctx context.Context, r routing.IpfsRouting, ph p2phost wg.Wait() } -func (api *PubSubAPI) checkNode() error { - if err := api.checkRouting(false); err != nil { - return err - } - +func (api *PubSubAPI) checkNode() (routing.IpfsRouting, error) { if api.pubSub == nil { - return errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.") + return nil, errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.") } - return nil + r, err := api.routing(false) + if err != nil { + return nil, err + } + + return r, nil } func (sub *pubSubSubscription) Close() error { diff --git a/core/coreapi/unixfs_test.go b/core/coreapi/unixfs_test.go index f6a1e48d6..cf30969f2 100644 --- a/core/coreapi/unixfs_test.go +++ b/core/coreapi/unixfs_test.go @@ -102,7 +102,10 @@ func makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]*core.IpfsNo return nil, nil, err } nodes[i] = node - apis[i] = coreapi.NewCoreAPI(node) + apis[i], err = coreapi.NewCoreAPI(node) + if err != nil { + return nil, nil, err + } } err := mn.LinkAll() diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 5fad3acf3..52560750a 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -25,11 +25,16 @@ func GatewayOption(writable bool, paths ...string) ServeOption { return nil, err } + api, err := coreapi.NewCoreAPI(n) + if err != nil { + return nil, err + } + gateway := newGatewayHandler(n, GatewayConfig{ Headers: cfg.Gateway.HTTPHeaders, Writable: writable, PathPrefixes: cfg.Gateway.PathPrefixes, - }, coreapi.NewCoreAPI(n)) + }, api) for _, p := range paths { mux.Handle(p+"/", gateway) diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index 8a02d68d1..34749db95 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -118,7 +118,10 @@ func TestIpfsStressRead(t *testing.T) { nd, mnt := setupIpfsTest(t, nil) defer mnt.Close() - api := coreapi.NewCoreAPI(nd) + api, err := coreapi.NewCoreAPI(nd) + if err != nil { + t.Fatal(err) + } var nodes []ipld.Node var paths []string diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 0d8a20073..099116445 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -120,7 +120,10 @@ func DirectAddCat(data []byte, conf testutil.LatencyConfig) error { } defer catter.Close() - catterApi := coreapi.NewCoreAPI(catter) + catterApi, err := coreapi.NewCoreAPI(catter) + if err != nil { + return err + } err = mn.LinkAll() if err != nil { diff --git a/test/integration/bench_cat_test.go b/test/integration/bench_cat_test.go index d228e45a1..25264fd45 100644 --- a/test/integration/bench_cat_test.go +++ b/test/integration/bench_cat_test.go @@ -66,7 +66,10 @@ func benchCat(b *testing.B, data []byte, conf testutil.LatencyConfig) error { } defer catter.Close() - catterApi := coreapi.NewCoreAPI(catter) + catterApi, err := coreapi.NewCoreAPI(catter) + if err != nil { + return err + } err = mn.LinkAll() if err != nil { diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index 200c584e3..b118c3579 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -103,7 +103,10 @@ func RunThreeLeggedCat(data []byte, conf testutil.LatencyConfig) error { } defer catter.Close() - catterApi := coreapi.NewCoreAPI(catter) + catterApi, err := coreapi.NewCoreAPI(catter) + if err != nil { + return err + } mn.LinkAll() From 50aea0725728648736f695cec2b1bf06b0c4b13c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 10 Dec 2018 14:21:19 +0100 Subject: [PATCH 04/12] coreapi.WithOptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/coreapi/coreapi.go | 197 ++++++++++++++++-------------- core/coreapi/interface/coreapi.go | 6 + 2 files changed, 113 insertions(+), 90 deletions(-) diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index e9055677f..3cf2549d7 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -17,6 +17,7 @@ import ( "context" "errors" "fmt" + "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" @@ -25,18 +26,18 @@ import ( "github.com/ipfs/go-ipfs/repo" ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" - "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface" + exchange "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface" bserv "gx/ipfs/QmPoh3SrQzFBWtdGK6qmHDV4EanKR6kYPj4DD3J2NLoEmZ/go-blockservice" - "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" - "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" - "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + routing "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" + blockstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" + peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub" ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log" dag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag" offlineroute "gx/ipfs/QmdmWkx54g7VfVyxeG8ic84uf4G6Eq1GohuyKA3XDuJ8oC/go-ipfs-routing/offline" - "gx/ipfs/QmfARXVCzpwFXQdepAJZuqyNDgV9doEsMnVCo1ssmuSe1U/go-libp2p-record" + record "gx/ipfs/QmfARXVCzpwFXQdepAJZuqyNDgV9doEsMnVCo1ssmuSe1U/go-libp2p-record" p2phost "gx/ipfs/QmfD51tKgJiTMnW9JEiDiPwsCY4mqUoxkhKhBfyW12spTC/go-libp2p-host" ) @@ -45,7 +46,7 @@ var log = logging.Logger("core/coreapi") type CoreAPI struct { nctx context.Context - identity peer.ID //TODO: check mutable structs + identity peer.ID privateKey ci.PrivKey repo repo.Repo @@ -69,93 +70,14 @@ type CoreAPI struct { // TODO: this can be generalized to all functions when we implement some // api based security mechanism isPublishAllowed func() error + + // ONLY for re-applying options in WithOptions, DO NOT USE ANYWHERE ELSE + nd *core.IpfsNode } // NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node. func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) (coreiface.CoreAPI, error) { - settings, err := options.ApiOptions(opts...) - if err != nil { - return nil, err - } - - api := &CoreAPI{ - nctx: n.Context(), - - identity: n.Identity, - privateKey: n.PrivateKey, - - repo: n.Repo, - blockstore: n.Blockstore, - baseBlocks: n.BaseBlocks, - pinning: n.Pinning, - - blocks: n.Blocks, - dag: n.DAG, - - peerstore: n.Peerstore, - peerHost: n.PeerHost, - namesys: n.Namesys, - recordValidator: n.RecordValidator, - exchange: n.Exchange, - - pubSub: n.PubSub, - } - - api.routing = func(allowOffline bool) (routing.IpfsRouting, error) { - if !n.OnlineMode() { - if !allowOffline { - return nil, coreiface.ErrOffline - } - if err := n.SetupOfflineRouting(); err != nil { - return nil, err - } - api.privateKey = n.PrivateKey - api.namesys = n.Namesys - return n.Routing, nil - } - if !settings.Offline { - return n.Routing, nil - } - if !allowOffline { - return nil, coreiface.ErrOffline - } - - //todo: might want to cache this - cfg, err := n.Repo.Config() - if err != nil { - return nil, err - } - - cs := cfg.Ipns.ResolveCacheSize - if cs == 0 { - cs = 128 - } - if cs < 0 { - return nil, fmt.Errorf("cannot specify negative resolve cache size") - } - - offroute := offlineroute.NewOfflineRouter(api.repo.Datastore(), api.recordValidator) - api.namesys = namesys.NewNameSystem(offroute, api.repo.Datastore(), cs) - - return offroute, nil - } - - api.isPublishAllowed = func() error { - if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { - return errors.New("cannot manually publish while IPNS is mounted") - } - return nil - } - - if settings.Offline { - api.peerstore = nil - api.peerHost = nil - api.namesys = nil - api.recordValidator = nil - api.exchange = nil - } - - return api, nil + return (&CoreAPI{nd: n}).WithOptions(opts...) } // Unixfs returns the UnixfsAPI interface implementation backed by the go-ipfs node @@ -208,11 +130,106 @@ func (api *CoreAPI) PubSub() coreiface.PubSubAPI { return (*PubSubAPI)(api) } +// WithOptions returns api with global options applied +func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, error) { + settings, err := options.ApiOptions(opts...) + if err != nil { + return nil, err + } + + if api.nd == nil { + return nil, errors.New("cannot apply options to api without node") + } + + n := api.nd + + subApi := &CoreAPI{ + nctx: n.Context(), + + identity: n.Identity, + privateKey: n.PrivateKey, + + repo: n.Repo, + blockstore: n.Blockstore, + baseBlocks: n.BaseBlocks, + pinning: n.Pinning, + + blocks: n.Blocks, + dag: n.DAG, + + peerstore: n.Peerstore, + peerHost: n.PeerHost, + namesys: n.Namesys, + recordValidator: n.RecordValidator, + exchange: n.Exchange, + + pubSub: n.PubSub, + + nd: n, + } + + subApi.routing = func(allowOffline bool) (routing.IpfsRouting, error) { + if !n.OnlineMode() { + if !allowOffline { + return nil, coreiface.ErrOffline + } + if err := n.SetupOfflineRouting(); err != nil { + return nil, err + } + subApi.privateKey = n.PrivateKey + subApi.namesys = n.Namesys + return n.Routing, nil + } + if !settings.Offline { + return n.Routing, nil + } + if !allowOffline { + return nil, coreiface.ErrOffline + } + + cfg, err := n.Repo.Config() + if err != nil { + return nil, err + } + + cs := cfg.Ipns.ResolveCacheSize + if cs == 0 { + cs = 128 + } + if cs < 0 { + return nil, fmt.Errorf("cannot specify negative resolve cache size") + } + + offroute := offlineroute.NewOfflineRouter(subApi.repo.Datastore(), subApi.recordValidator) + subApi.namesys = namesys.NewNameSystem(offroute, subApi.repo.Datastore(), cs) + + return offroute, nil + } + + subApi.isPublishAllowed = func() error { + if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { + return errors.New("cannot manually publish while IPNS is mounted") + } + return nil + } + + if settings.Offline { + subApi.peerstore = nil + subApi.peerHost = nil + subApi.namesys = nil + subApi.recordValidator = nil + subApi.exchange = nil + } + + return subApi, nil +} + // getSession returns new api backed by the same node with a read-only session DAG func (api *CoreAPI) getSession(ctx context.Context) *CoreAPI { sesApi := *api - //TODO: we may want to apply this to other things too + // TODO: We could also apply this to api.blocks, and compose into writable api, + // but this requires some changes in blockservice/merkledag sesApi.dag = dag.NewReadOnlyDagService(dag.NewSession(ctx, api.dag)) return &sesApi diff --git a/core/coreapi/interface/coreapi.go b/core/coreapi/interface/coreapi.go index bab4fc13b..226399967 100644 --- a/core/coreapi/interface/coreapi.go +++ b/core/coreapi/interface/coreapi.go @@ -5,6 +5,8 @@ package iface import ( "context" + "github.com/ipfs/go-ipfs/core/coreapi/interface/options" + ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" ) @@ -46,4 +48,8 @@ type CoreAPI interface { // ResolveNode resolves the path (if not resolved already) using Unixfs // resolver, gets and returns the resolved Node ResolveNode(context.Context, Path) (ipld.Node, error) + + // WithOptions creates new instance of CoreAPI based on this instance with + // a set of options applied + WithOptions(...options.ApiOption) (CoreAPI, error) } From 6e18a6b85757cceae2b30688f7245f8b5f4e54db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 10 Dec 2018 14:31:19 +0100 Subject: [PATCH 05/12] coreapi: drop nameopt.Local in favour of api.Offline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/coreapi/interface/options/name.go | 11 ----------- core/coreapi/name.go | 12 ------------ 2 files changed, 23 deletions(-) diff --git a/core/coreapi/interface/options/name.go b/core/coreapi/interface/options/name.go index c614db3ab..e2a0fc164 100644 --- a/core/coreapi/interface/options/name.go +++ b/core/coreapi/interface/options/name.go @@ -20,7 +20,6 @@ type NamePublishSettings struct { } type NameResolveSettings struct { - Local bool Cache bool ResolveOpts []ropts.ResolveOpt @@ -49,7 +48,6 @@ func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error) func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) { options := &NameResolveSettings{ - Local: false, Cache: true, } @@ -106,15 +104,6 @@ func (nameOpts) TTL(ttl time.Duration) NamePublishOption { } } -// Local is an option for Name.Resolve which specifies if the lookup should be -// offline. Default value is false -func (nameOpts) Local(local bool) NameResolveOption { - return func(settings *NameResolveSettings) error { - settings.Local = local - return nil - } -} - // Cache is an option for Name.Resolve which specifies if cache should be used. // Default value is true func (nameOpts) Cache(cache bool) NameResolveOption { diff --git a/core/coreapi/name.go b/core/coreapi/name.go index c912bf185..b72f07051 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -2,7 +2,6 @@ package coreapi import ( "context" - "errors" "fmt" "strings" "time" @@ -16,7 +15,6 @@ import ( ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" ipath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path" - "gx/ipfs/QmdmWkx54g7VfVyxeG8ic84uf4G6Eq1GohuyKA3XDuJ8oC/go-ipfs-routing/offline" ) type NameAPI CoreAPI @@ -96,16 +94,6 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name var resolver namesys.Resolver = api.namesys - if options.Local && !options.Cache { //TODO: rm before offline/local global opt merge - return nil, errors.New("cannot specify both local and nocache") - } - - //TODO: can replaced with api.WithOpt(opts.Api.Offline(true)) - if options.Local { - offroute := offline.NewOfflineRouter(api.repo.Datastore(), api.recordValidator) - resolver = namesys.NewIpnsResolver(offroute) - } - if !options.Cache { resolver = namesys.NewNameSystem(r, api.repo.Datastore(), 0) } From 2c2f9f2bed35dae72a9aa7f2b44bd718a52241f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 10 Dec 2018 15:26:27 +0100 Subject: [PATCH 06/12] coreapi: implement --local with Offline option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/commands/add.go | 4 +--- core/commands/block.go | 8 ++++---- core/commands/cmdenv/env.go | 14 ++++++++++++-- core/commands/files.go | 4 ++-- core/commands/keystore.go | 8 ++++---- core/commands/ls.go | 2 +- core/commands/name/ipns.go | 4 +--- core/commands/name/publish.go | 2 +- core/commands/object/diff.go | 2 +- core/commands/object/object.go | 12 ++++++------ core/commands/object/patch.go | 8 ++++---- core/commands/pin.go | 8 ++++---- core/commands/pubsub.go | 8 ++++---- core/commands/swarm.go | 12 ++++++------ core/commands/unixfs/ls.go | 2 +- core/coreapi/coreapi.go | 6 +++++- core/coreapi/interface/options/unixfs.go | 12 ------------ core/coreapi/unixfs.go | 5 ----- core/coreapi/unixfs_test.go | 19 +++++++++++++------ 19 files changed, 70 insertions(+), 70 deletions(-) diff --git a/core/commands/add.go b/core/commands/add.go index 148e3a76b..a992eaeb8 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -139,7 +139,7 @@ You can now check what blocks have been created by: return nil }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -160,7 +160,6 @@ You can now check what blocks have been created by: inline, _ := req.Options[inlineOptionName].(bool) inlineLimit, _ := req.Options[inlineLimitOptionName].(int) pathName, _ := req.Options[stdinPathName].(string) - local, _ := req.Options["local"].(bool) hashFunCode, ok := mh.Names[strings.ToLower(hashFunStr)] if !ok { @@ -179,7 +178,6 @@ You can now check what blocks have been created by: options.Unixfs.Pin(dopin), options.Unixfs.HashOnly(hash), - options.Unixfs.Local(local), options.Unixfs.FsCache(fscache), options.Unixfs.Nocopy(nocopy), diff --git a/core/commands/block.go b/core/commands/block.go index a95f9d930..52d7a7b96 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -60,7 +60,7 @@ on raw IPFS blocks. It outputs the following to stdout: cmdkit.StringArg("key", true, false, "The base58 multihash of an existing block to stat.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -102,7 +102,7 @@ It outputs to stdout, and is a base58 encoded multihash. cmdkit.StringArg("key", true, false, "The base58 multihash of an existing block to get.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -148,7 +148,7 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1. cmdkit.IntOption(mhlenOptionName, "multihash hash length").WithDefault(-1), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -218,7 +218,7 @@ It takes a list of base58 encoded multihashes to remove. cmdkit.BoolOption(blockQuietOptionName, "q", "Write minimal output."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index c30cd13f8..8a3a0779c 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -6,6 +6,7 @@ import ( "github.com/ipfs/go-ipfs/commands" "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" + options "github.com/ipfs/go-ipfs/core/coreapi/interface/options" config "gx/ipfs/QmYyzmMnhNTtoXx5ttgUaRdHHckYnQWjPL98hgLAR2QLDD/go-ipfs-config" cmds "gx/ipfs/QmaAP56JAwdjwisPTu4yx17whcjTr6y5JCSCF77Y1rahWV/go-ipfs-cmds" @@ -22,13 +23,22 @@ func GetNode(env interface{}) (*core.IpfsNode, error) { } // GetApi extracts CoreAPI instance from the environment. -func GetApi(env cmds.Environment) (coreiface.CoreAPI, error) { +func GetApi(env cmds.Environment, req *cmds.Request) (coreiface.CoreAPI, error) { ctx, ok := env.(*commands.Context) if !ok { return nil, fmt.Errorf("expected env to be of type %T, got %T", ctx, env) } - return ctx.GetAPI() + local, _ := req.Options["local"].(bool) + api, err := ctx.GetAPI() + if err != nil { + return nil, err + } + if local { + return api.WithOptions(options.Api.Offline(local)) + } + + return api, nil } // GetConfig extracts the config from the environment. diff --git a/core/commands/files.go b/core/commands/files.go index 2f98fb083..5ca77a604 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -124,7 +124,7 @@ var filesStatCmd = &cmds.Command{ return err } - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -308,7 +308,7 @@ var filesCpCmd = &cmds.Command{ return err } - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/keystore.go b/core/commands/keystore.go index 2a8ecc81a..7c1517851 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -71,7 +71,7 @@ var keyGenCmd = &cmds.Command{ cmdkit.StringArg("name", true, false, "name of key to create"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -121,7 +121,7 @@ var keyListCmd = &cmds.Command{ cmdkit.BoolOption("l", "Show extra information about keys."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -161,7 +161,7 @@ var keyRenameCmd = &cmds.Command{ cmdkit.BoolOption(keyStoreForceOptionName, "f", "Allow to overwrite an existing key."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -206,7 +206,7 @@ var keyRmCmd = &cmds.Command{ cmdkit.BoolOption("l", "Show extra information about keys."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/ls.go b/core/commands/ls.go index 09009eee2..5c65cfaed 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -74,7 +74,7 @@ The JSON output contains type information. return err } - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index 6187419df..4e18d2ade 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -80,13 +80,12 @@ Resolve the value of a dnslink: cmdkit.BoolOption(streamOptionName, "s", "Stream entries as they are found."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } nocache, _ := req.Options["nocache"].(bool) - local, _ := req.Options["local"].(bool) var name string if len(req.Arguments) == 0 { @@ -105,7 +104,6 @@ Resolve the value of a dnslink: stream, _ := req.Options[streamOptionName].(bool) opts := []options.NameResolveOption{ - options.Name.Local(local), options.Name.Cache(!nocache), } diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 7d083b245..72f874ba2 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -83,7 +83,7 @@ Alternatively, publish an using a valid PeerID (as listed by cmdkit.BoolOption(quieterOptionName, "Q", "Write only final hash."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/object/diff.go b/core/commands/object/diff.go index b37b3375d..d1170ae3b 100644 --- a/core/commands/object/diff.go +++ b/core/commands/object/diff.go @@ -55,7 +55,7 @@ Example: cmdkit.BoolOption(verboseOptionName, "v", "Print extra information."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/object/object.go b/core/commands/object/object.go index 0640a7d6d..bbe2ffb29 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -77,7 +77,7 @@ is the raw data of the object. cmdkit.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -114,7 +114,7 @@ multihash. cmdkit.BoolOption("headers", "v", "Print table headers (Hash, Size, Name)."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -204,7 +204,7 @@ Supported values are: cmdkit.StringOption("data-encoding", "Encoding type of the data field, either \"text\" or \"base64\".").WithDefault("text"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -294,7 +294,7 @@ var ObjectStatCmd = &cmds.Command{ cmdkit.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -386,7 +386,7 @@ And then run: cmdkit.BoolOption("quiet", "q", "Write minimal output."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -459,7 +459,7 @@ Available templates: cmdkit.StringArg("template", false, false, "Template to use. Optional."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index a7c598898..88eeb7a9f 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -50,7 +50,7 @@ the limit will not be respected by the network. cmdkit.FileArg("data", true, false, "Data to append.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -97,7 +97,7 @@ Example: cmdkit.FileArg("data", true, false, "The data to set the object to.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -140,7 +140,7 @@ Remove a Merkle-link from the given object and return the hash of the result. cmdkit.StringArg("name", true, false, "Name of the link to remove."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -192,7 +192,7 @@ to a file containing 'bar', and returns the hash of the new object. cmdkit.BoolOption("create", "p", "Create intermediary nodes."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/pin.go b/core/commands/pin.go index 9495a4e1a..7ad571d64 100644 --- a/core/commands/pin.go +++ b/core/commands/pin.go @@ -72,7 +72,7 @@ var addPinCmd = &cmds.Command{ return err } - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -203,7 +203,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.) return err } - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -294,7 +294,7 @@ Example: return err } - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -366,7 +366,7 @@ new pin and removing the old one. }, Type: PinOutput{}, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index a69a6ec82..c9ae8bc17 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -78,7 +78,7 @@ This command outputs data in the following encodings: cmdkit.BoolOption(pubsubDiscoverOptionName, "try to discover other peers subscribed to the same topic"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -153,7 +153,7 @@ To use, the daemon must be run with '--enable-pubsub-experiment'. cmdkit.StringArg("data", true, true, "Payload of message to publish.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -188,7 +188,7 @@ To use, the daemon must be run with '--enable-pubsub-experiment'. `, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -234,7 +234,7 @@ To use, the daemon must be run with '--enable-pubsub-experiment'. cmdkit.StringArg("topic", false, false, "topic to list connected peers of"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 3c25855ef..75938c89b 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -71,7 +71,7 @@ var swarmPeersCmd = &cmds.Command{ cmdkit.BoolOption(swarmDirectionOptionName, "Also list information about the direction of connection"), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -221,7 +221,7 @@ var swarmAddrsCmd = &cmds.Command{ "listen": swarmAddrsListenCmd, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -275,7 +275,7 @@ var swarmAddrsLocalCmd = &cmds.Command{ cmdkit.BoolOption("id", "Show peer ID in addresses."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -316,7 +316,7 @@ var swarmAddrsListenCmd = &cmds.Command{ `, }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -355,7 +355,7 @@ ipfs swarm connect /ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3 cmdkit.StringArg("address", true, true, "Address of peer to connect to.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } @@ -403,7 +403,7 @@ it will reconnect. cmdkit.StringArg("address", true, true, "Address of peer to disconnect from.").EnableStdin(), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index b7090c688..0f8ab95ca 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -77,7 +77,7 @@ possible, please use 'ipfs ls' instead. return err } - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 3cf2549d7..fab758f64 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -31,6 +31,7 @@ import ( routing "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" blockstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + offlinexch "gx/ipfs/QmYZwey1thDTynSrvd6qQkX24UpTka6TFhQ2v569UpoqxD/go-ipfs-exchange-offline" pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub" ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format" @@ -218,7 +219,10 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e subApi.peerHost = nil subApi.namesys = nil subApi.recordValidator = nil - subApi.exchange = nil + + subApi.exchange = offlinexch.Exchange(subApi.blockstore) + subApi.blocks = bserv.New(api.blockstore, subApi.exchange) + subApi.dag = dag.NewDAGService(subApi.blocks) } return subApi, nil diff --git a/core/coreapi/interface/options/unixfs.go b/core/coreapi/interface/options/unixfs.go index b771896bc..fd748bb4a 100644 --- a/core/coreapi/interface/options/unixfs.go +++ b/core/coreapi/interface/options/unixfs.go @@ -30,7 +30,6 @@ type UnixfsAddSettings struct { Pin bool OnlyHash bool - Local bool FsCache bool NoCopy bool @@ -60,7 +59,6 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, Pin: false, OnlyHash: false, - Local: false, FsCache: false, NoCopy: false, @@ -220,16 +218,6 @@ func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption { } } -// Local will add the data to blockstore without announcing it to the network -// -// Note that this doesn't prevent other nodes from getting this data -func (unixfsOpts) Local(local bool) UnixfsAddOption { - return func(settings *UnixfsAddSettings) error { - settings.Local = local - return nil - } -} - // Wrap tells the adder to wrap the added file structure with an additional // directory. func (unixfsOpts) Wrap(wrap bool) UnixfsAddOption { diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 372d79e77..847eea6e3 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -15,7 +15,6 @@ import ( bstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" mfs "gx/ipfs/QmU3iDRUrxyTYdV2j5MuWLFvP1k7w98vD66PLnNChgvUmZ/go-mfs" files "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files" - offline "gx/ipfs/QmYZwey1thDTynSrvd6qQkX24UpTka6TFhQ2v569UpoqxD/go-ipfs-exchange-offline" cidutil "gx/ipfs/QmbfKu17LbMWyGUxHEUns9Wf5Dkm8PT6be4uPhTkk4YvaV/go-cidutil" ft "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs" uio "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs/io" @@ -72,10 +71,6 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options pinning = nilnode.Pinning } - if settings.Local { - exch = offline.Exchange(addblockstore) - } - bserv := blockservice.New(addblockstore, exch) // hash security 001 dserv := dag.NewDAGService(bserv) diff --git a/core/coreapi/unixfs_test.go b/core/coreapi/unixfs_test.go index cf30969f2..4cdd5e4cf 100644 --- a/core/coreapi/unixfs_test.go +++ b/core/coreapi/unixfs_test.go @@ -183,6 +183,8 @@ func TestAdd(t *testing.T) { data func() files.Node expect func(files.Node) files.Node + apiOpts []options.ApiOption + path string err string @@ -270,10 +272,10 @@ func TestAdd(t *testing.T) { }, // Local { - name: "addLocal", // better cases in sharness - data: strFile(helloStr), - path: hello, - opts: []options.UnixfsAddOption{options.Unixfs.Local(true)}, + name: "addLocal", // better cases in sharness + data: strFile(helloStr), + path: hello, + apiOpts: []options.ApiOption{options.Api.Offline(true)}, }, { name: "hashOnly", // test (non)fetchability @@ -511,9 +513,14 @@ func TestAdd(t *testing.T) { }() } + tapi, err := api.WithOptions(testCase.apiOpts...) + if err != nil { + t.Fatal(err) + } + // Add! - p, err := api.Unixfs().Add(ctx, data, opts...) + p, err := tapi.Unixfs().Add(ctx, data, opts...) close(eventOut) evtWg.Wait() if testCase.err != "" { @@ -594,7 +601,7 @@ func TestAdd(t *testing.T) { } } - f, err := api.Unixfs().Get(ctx, p) + f, err := tapi.Unixfs().Get(ctx, p) if err != nil { t.Fatal(err) } From 47a46393cf0dad35d36e1f7ba0f815604b0c4bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Tue, 11 Dec 2018 22:24:40 +0100 Subject: [PATCH 07/12] coreapi WithOptions: apply on top of parent options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/coreapi/coreapi.go | 16 ++++++++++++---- core/coreapi/interface/options/global.go | 8 ++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index fab758f64..7af4023e5 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -73,12 +73,18 @@ type CoreAPI struct { isPublishAllowed func() error // ONLY for re-applying options in WithOptions, DO NOT USE ANYWHERE ELSE - nd *core.IpfsNode + nd *core.IpfsNode + parentOpts options.ApiSettings } // NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node. func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) (coreiface.CoreAPI, error) { - return (&CoreAPI{nd: n}).WithOptions(opts...) + parentOpts, err := options.ApiOptions() + if err != nil { + return nil, err + } + + return (&CoreAPI{nd: n, parentOpts: *parentOpts}).WithOptions(opts...) } // Unixfs returns the UnixfsAPI interface implementation backed by the go-ipfs node @@ -133,7 +139,8 @@ func (api *CoreAPI) PubSub() coreiface.PubSubAPI { // WithOptions returns api with global options applied func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, error) { - settings, err := options.ApiOptions(opts...) + settings := api.parentOpts // make sure to copy + _, err := options.ApiOptionsTo(&settings, opts...) if err != nil { return nil, err } @@ -166,7 +173,8 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e pubSub: n.PubSub, - nd: n, + nd: n, + parentOpts: settings, } subApi.routing = func(allowOffline bool) (routing.IpfsRouting, error) { diff --git a/core/coreapi/interface/options/global.go b/core/coreapi/interface/options/global.go index f43965229..93d635e41 100644 --- a/core/coreapi/interface/options/global.go +++ b/core/coreapi/interface/options/global.go @@ -11,6 +11,10 @@ func ApiOptions(opts ...ApiOption) (*ApiSettings, error) { Offline: false, } + return ApiOptionsTo(options, opts...) +} + +func ApiOptionsTo(options *ApiSettings, opts ...ApiOption) (*ApiSettings, error) { for _, opt := range opts { err := opt(options) if err != nil { @@ -22,9 +26,9 @@ func ApiOptions(opts ...ApiOption) (*ApiSettings, error) { type apiOpts struct{} -var Api dagOpts +var Api apiOpts -func (dagOpts) Offline(offline bool) ApiOption { +func (apiOpts) Offline(offline bool) ApiOption { return func(settings *ApiSettings) error { settings.Offline = offline return nil From 2dceb0925886e22894c9a40779360313ed26fd35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 12 Dec 2018 13:00:47 +0100 Subject: [PATCH 08/12] commands: deprecate --local for --offline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- cmd/ipfs/daemon.go | 3 +-- core/commands/cmdenv/env.go | 16 +++++++++++++--- core/commands/root.go | 12 +++++++----- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index a1be01c6d..e4c891053 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -40,7 +40,7 @@ const ( ipnsMountKwd = "mount-ipns" migrateKwd = "migrate" mountKwd = "mount" - offlineKwd = "offline" + offlineKwd = "offline" // global option routingOptionKwd = "routing" routingOptionSupernodeKwd = "supernode" routingOptionDHTClientKwd = "dhtclient" @@ -161,7 +161,6 @@ Headers. cmdkit.BoolOption(unencryptTransportKwd, "Disable transport encryption (for debugging protocols)"), cmdkit.BoolOption(enableGCKwd, "Enable automatic periodic repo garbage collection"), cmdkit.BoolOption(adjustFDLimitKwd, "Check and raise file descriptor limits if needed").WithDefault(true), - cmdkit.BoolOption(offlineKwd, "Run offline. Do not connect to the rest of the network but provide local API."), cmdkit.BoolOption(migrateKwd, "If true, assume yes at the migrate prompt. If false, assume no."), cmdkit.BoolOption(enablePubSubKwd, "Instantiate the ipfs daemon with the experimental pubsub feature enabled."), cmdkit.BoolOption(enableIPNSPubSubKwd, "Enable IPNS record distribution through pubsub; enables pubsub."), diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index 8a3a0779c..290239381 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -2,6 +2,7 @@ package cmdenv import ( "fmt" + "strings" "github.com/ipfs/go-ipfs/commands" "github.com/ipfs/go-ipfs/core" @@ -10,8 +11,11 @@ import ( config "gx/ipfs/QmYyzmMnhNTtoXx5ttgUaRdHHckYnQWjPL98hgLAR2QLDD/go-ipfs-config" cmds "gx/ipfs/QmaAP56JAwdjwisPTu4yx17whcjTr6y5JCSCF77Y1rahWV/go-ipfs-cmds" + logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log" ) +var log = logging.Logger("core/commands/cmdenv") + // GetNode extracts the node from the environment. func GetNode(env interface{}) (*core.IpfsNode, error) { ctx, ok := env.(*commands.Context) @@ -29,13 +33,19 @@ func GetApi(env cmds.Environment, req *cmds.Request) (coreiface.CoreAPI, error) return nil, fmt.Errorf("expected env to be of type %T, got %T", ctx, env) } - local, _ := req.Options["local"].(bool) + offline, _ := req.Options["offline"].(bool) + if !offline { + offline, _ = req.Options["local"].(bool) + if offline { + log.Errorf("Command '%s', --local is deprecated, use --offline instead", strings.Join(req.Path, " ")) + } + } api, err := ctx.GetAPI() if err != nil { return nil, err } - if local { - return api.WithOptions(options.Api.Offline(local)) + if offline { + return api.WithOptions(options.Api.Offline(offline)) } return api, nil diff --git a/core/commands/root.go b/core/commands/root.go index ce9fdafa1..08cd1b92e 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -18,10 +18,11 @@ var log = logging.Logger("core/commands") var ErrNotOnline = errors.New("this command must be run in online mode. Try running 'ipfs daemon' first") const ( - ConfigOption = "config" - DebugOption = "debug" - LocalOption = "local" - ApiOption = "api" + ConfigOption = "config" + DebugOption = "debug" + LocalOption = "local" // DEPRECATED: use OfflineOption + OfflineOption = "offline" + ApiOption = "api" ) var Root = &cmds.Command{ @@ -92,7 +93,8 @@ The CLI will exit with one of the following values: cmdkit.BoolOption(DebugOption, "D", "Operate in debug mode."), cmdkit.BoolOption(cmds.OptLongHelp, "Show the full command help text."), cmdkit.BoolOption(cmds.OptShortHelp, "Show a short version of the command help text."), - cmdkit.BoolOption(LocalOption, "L", "Run the command locally, instead of using the daemon."), + cmdkit.BoolOption(LocalOption, "L", "Run the command locally, instead of using the daemon. DEPRECATED: use --offline."), + cmdkit.BoolOption(OfflineOption, "O", "Run the command offline."), cmdkit.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"), // global options, added to every command From a39c29933a71b0d872ab644412347aa6479bef51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 17 Dec 2018 08:52:03 +0100 Subject: [PATCH 09/12] commands: don't use -O as global offline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/commands/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/commands/root.go b/core/commands/root.go index 08cd1b92e..798fc1732 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -94,7 +94,7 @@ The CLI will exit with one of the following values: cmdkit.BoolOption(cmds.OptLongHelp, "Show the full command help text."), cmdkit.BoolOption(cmds.OptShortHelp, "Show a short version of the command help text."), cmdkit.BoolOption(LocalOption, "L", "Run the command locally, instead of using the daemon. DEPRECATED: use --offline."), - cmdkit.BoolOption(OfflineOption, "O", "Run the command offline."), + cmdkit.BoolOption(OfflineOption, "Run the command offline."), cmdkit.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"), // global options, added to every command From 190728f04a13860f2275b116187873ef87180e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Mon, 17 Dec 2018 09:14:35 +0100 Subject: [PATCH 10/12] coreapi: update for always loaded privkey MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/commands/cat.go | 2 +- core/commands/resolve.go | 2 +- core/coreapi/coreapi.go | 59 ++++++++++++++++------------------------ core/coreapi/dht.go | 14 +++++----- core/coreapi/name.go | 6 ++-- core/coreapi/pubsub.go | 4 +-- 6 files changed, 37 insertions(+), 50 deletions(-) diff --git a/core/commands/cat.go b/core/commands/cat.go index fe25d6dc7..663f75b3c 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -34,7 +34,7 @@ var CatCmd = &cmds.Command{ cmdkit.Int64Option(lengthOptionName, "l", "Maximum number of bytes to read."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/commands/resolve.go b/core/commands/resolve.go index 61b826941..32a5b47ca 100644 --- a/core/commands/resolve.go +++ b/core/commands/resolve.go @@ -74,7 +74,7 @@ Resolve the value of an IPFS DAG path: cmdkit.StringOption(resolveDhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."), }, Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error { - api, err := cmdenv.GetApi(env) + api, err := cmdenv.GetApi(env, req) if err != nil { return err } diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 7af4023e5..44068a16e 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -17,7 +17,6 @@ import ( "context" "errors" "fmt" - "github.com/ipfs/go-ipfs/core" coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface" "github.com/ipfs/go-ipfs/core/coreapi/interface/options" @@ -26,11 +25,11 @@ import ( "github.com/ipfs/go-ipfs/repo" ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto" - exchange "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface" + "gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface" bserv "gx/ipfs/QmPoh3SrQzFBWtdGK6qmHDV4EanKR6kYPj4DD3J2NLoEmZ/go-blockservice" - routing "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" - blockstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" - peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" + "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing" + "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore" + "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer" offlinexch "gx/ipfs/QmYZwey1thDTynSrvd6qQkX24UpTka6TFhQ2v569UpoqxD/go-ipfs-exchange-offline" pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore" pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub" @@ -64,13 +63,14 @@ type CoreAPI struct { exchange exchange.Interface namesys namesys.NameSystem - routing func(bool) (routing.IpfsRouting, error) + routing routing.IpfsRouting pubSub *pubsub.PubSub // TODO: this can be generalized to all functions when we implement some // api based security mechanism isPublishAllowed func() error + isOnline func(allowOffline bool) error // ONLY for re-applying options in WithOptions, DO NOT USE ANYWHERE ELSE nd *core.IpfsNode @@ -170,6 +170,7 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e namesys: n.Namesys, recordValidator: n.RecordValidator, exchange: n.Exchange, + routing: n.Routing, pubSub: n.PubSub, @@ -177,25 +178,21 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e parentOpts: settings, } - subApi.routing = func(allowOffline bool) (routing.IpfsRouting, error) { - if !n.OnlineMode() { - if !allowOffline { - return nil, coreiface.ErrOffline - } - if err := n.SetupOfflineRouting(); err != nil { - return nil, err - } - subApi.privateKey = n.PrivateKey - subApi.namesys = n.Namesys - return n.Routing, nil - } - if !settings.Offline { - return n.Routing, nil - } - if !allowOffline { - return nil, coreiface.ErrOffline + subApi.isOnline = func(allowOffline bool) error { + if !n.OnlineMode() && !allowOffline { + return coreiface.ErrOffline } + return nil + } + subApi.isPublishAllowed = func() error { + if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { + return errors.New("cannot manually publish while IPNS is mounted") + } + return nil + } + + if settings.Offline { cfg, err := n.Repo.Config() if err != nil { return nil, err @@ -209,20 +206,9 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e return nil, fmt.Errorf("cannot specify negative resolve cache size") } - offroute := offlineroute.NewOfflineRouter(subApi.repo.Datastore(), subApi.recordValidator) - subApi.namesys = namesys.NewNameSystem(offroute, subApi.repo.Datastore(), cs) + subApi.routing = offlineroute.NewOfflineRouter(subApi.repo.Datastore(), subApi.recordValidator) + subApi.namesys = namesys.NewNameSystem(subApi.routing, subApi.repo.Datastore(), cs) - return offroute, nil - } - - subApi.isPublishAllowed = func() error { - if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { - return errors.New("cannot manually publish while IPNS is mounted") - } - return nil - } - - if settings.Offline { subApi.peerstore = nil subApi.peerHost = nil subApi.namesys = nil @@ -231,6 +217,7 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e subApi.exchange = offlinexch.Exchange(subApi.blockstore) subApi.blocks = bserv.New(api.blockstore, subApi.exchange) subApi.dag = dag.NewDAGService(subApi.blocks) + } return subApi, nil diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index cc5447b3c..4e91169de 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -21,12 +21,12 @@ import ( type DhtAPI CoreAPI func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (pstore.PeerInfo, error) { - r, err := api.routing(false) + err := api.isOnline(false) if err != nil { return pstore.PeerInfo{}, err } - pi, err := r.FindPeer(ctx, peer.ID(p)) + pi, err := api.routing.FindPeer(ctx, peer.ID(p)) if err != nil { return pstore.PeerInfo{}, err } @@ -40,7 +40,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ... return nil, err } - r, err := api.routing(false) + err = api.isOnline(false) if err != nil { return nil, err } @@ -55,7 +55,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ... return nil, fmt.Errorf("number of providers must be greater than 0") } - pchan := r.FindProvidersAsync(ctx, rp.Cid(), numProviders) + pchan := api.routing.FindProvidersAsync(ctx, rp.Cid(), numProviders) return pchan, nil } @@ -65,7 +65,7 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao return err } - r, err := api.routing(false) + err = api.isOnline(false) if err != nil { return err } @@ -87,9 +87,9 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao } if settings.Recursive { - err = provideKeysRec(ctx, r, api.blockstore, []cid.Cid{c}) + err = provideKeysRec(ctx, api.routing, api.blockstore, []cid.Cid{c}) } else { - err = provideKeys(ctx, r, []cid.Cid{c}) + err = provideKeys(ctx, api.routing, []cid.Cid{c}) } if err != nil { return err diff --git a/core/coreapi/name.go b/core/coreapi/name.go index b72f07051..d9e95925e 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -45,7 +45,7 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt return nil, err } - _, err = api.routing(options.AllowOffline) + err = api.isOnline(options.AllowOffline) if err != nil { return nil, err } @@ -87,7 +87,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name return nil, err } - r, err := api.routing(true) + err = api.isOnline(true) if err != nil { return nil, err } @@ -95,7 +95,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name var resolver namesys.Resolver = api.namesys if !options.Cache { - resolver = namesys.NewNameSystem(r, api.repo.Datastore(), 0) + resolver = namesys.NewNameSystem(api.routing, api.repo.Datastore(), 0) } if !strings.HasPrefix(name, "/ipns/") { diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index 378e3dbc6..d02638300 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -127,12 +127,12 @@ func (api *PubSubAPI) checkNode() (routing.IpfsRouting, error) { return nil, errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.") } - r, err := api.routing(false) + err := api.isOnline(false) if err != nil { return nil, err } - return r, nil + return api.routing, nil } func (sub *pubSubSubscription) Close() error { From 6044d2ae8976b126d9e62dccc5dbfe4d554f129b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Wed, 19 Dec 2018 02:08:48 +0100 Subject: [PATCH 11/12] coreapi offline: Address review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/coreapi/coreapi.go | 10 ++++------ core/coreapi/dht.go | 6 +++--- core/coreapi/name.go | 6 +++--- core/coreapi/pubsub.go | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 44068a16e..407d29cdc 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -67,10 +67,8 @@ type CoreAPI struct { pubSub *pubsub.PubSub - // TODO: this can be generalized to all functions when we implement some - // api based security mechanism - isPublishAllowed func() error - isOnline func(allowOffline bool) error + checkPublishAllowed func() error + checkOnline func(allowOffline bool) error // ONLY for re-applying options in WithOptions, DO NOT USE ANYWHERE ELSE nd *core.IpfsNode @@ -178,14 +176,14 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e parentOpts: settings, } - subApi.isOnline = func(allowOffline bool) error { + subApi.checkOnline = func(allowOffline bool) error { if !n.OnlineMode() && !allowOffline { return coreiface.ErrOffline } return nil } - subApi.isPublishAllowed = func() error { + subApi.checkPublishAllowed = func() error { if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() { return errors.New("cannot manually publish while IPNS is mounted") } diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index 4e91169de..4b0616566 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -21,7 +21,7 @@ import ( type DhtAPI CoreAPI func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (pstore.PeerInfo, error) { - err := api.isOnline(false) + err := api.checkOnline(false) if err != nil { return pstore.PeerInfo{}, err } @@ -40,7 +40,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ... return nil, err } - err = api.isOnline(false) + err = api.checkOnline(false) if err != nil { return nil, err } @@ -65,7 +65,7 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao return err } - err = api.isOnline(false) + err = api.checkOnline(false) if err != nil { return err } diff --git a/core/coreapi/name.go b/core/coreapi/name.go index d9e95925e..e986567b5 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -36,7 +36,7 @@ func (e *ipnsEntry) Value() coreiface.Path { // Publish announces new IPNS name and returns the new IPNS entry. func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopts.NamePublishOption) (coreiface.IpnsEntry, error) { - if err := api.isPublishAllowed(); err != nil { + if err := api.checkPublishAllowed(); err != nil { return nil, err } @@ -45,7 +45,7 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt return nil, err } - err = api.isOnline(options.AllowOffline) + err = api.checkOnline(options.AllowOffline) if err != nil { return nil, err } @@ -87,7 +87,7 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name return nil, err } - err = api.isOnline(true) + err = api.checkOnline(true) if err != nil { return nil, err } diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index d02638300..6ec123a98 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -127,7 +127,7 @@ func (api *PubSubAPI) checkNode() (routing.IpfsRouting, error) { return nil, errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.") } - err := api.isOnline(false) + err := api.checkOnline(false) if err != nil { return nil, err } From 3f0945a1bdf12bdafb33a18657893a1896522075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Magiera?= Date: Thu, 20 Dec 2018 17:02:11 +0100 Subject: [PATCH 12/12] coreapi: move DefaultIpnsCacheSize to a const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit License: MIT Signed-off-by: Łukasz Magiera --- core/core.go | 3 ++- core/coreapi/coreapi.go | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/core.go b/core/core.go index 6a146bb20..fe75ad5ea 100644 --- a/core/core.go +++ b/core/core.go @@ -82,6 +82,7 @@ const IpnsValidatorTag = "ipns" const kReprovideFrequency = time.Hour * 12 const discoveryConnTimeout = time.Second * 30 +const DefaultIpnsCacheSize = 128 var log = logging.Logger("core") @@ -601,7 +602,7 @@ func (n *IpfsNode) getCacheSize() (int, error) { cs := cfg.Ipns.ResolveCacheSize if cs == 0 { - cs = 128 + cs = DefaultIpnsCacheSize } if cs < 0 { return 0, fmt.Errorf("cannot specify negative resolve cache size") diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 407d29cdc..b927cea59 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -198,7 +198,7 @@ func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, e cs := cfg.Ipns.ResolveCacheSize if cs == 0 { - cs = 128 + cs = core.DefaultIpnsCacheSize } if cs < 0 { return nil, fmt.Errorf("cannot specify negative resolve cache size")