diff --git a/blocks/blockstore/blockstore.go b/blocks/blockstore/blockstore.go index 4ef59ffe3..946b1d69c 100644 --- a/blocks/blockstore/blockstore.go +++ b/blocks/blockstore/blockstore.go @@ -40,12 +40,19 @@ type Blockstore interface { DeleteBlock(*cid.Cid) error Has(*cid.Cid) (bool, error) Get(*cid.Cid) (blocks.Block, error) + + // Put puts a given block to the underlying datastore Put(blocks.Block) error + + // PutMany puts a slice of blocks at the same time using batching + // capabilities of the underlying datastore whenever possible. PutMany([]blocks.Block) error + // AllKeysChan returns a channel from which // the CIDs in the Blockstore can be read. It should respect // the given context, closing the channel if it becomes Done. AllKeysChan(ctx context.Context) (<-chan *cid.Cid, error) + // HashOnRead specifies if every read block should be // rehashed to make sure it matches its CID. HashOnRead(enabled bool) diff --git a/blockservice/blockservice.go b/blockservice/blockservice.go index 7929a67f3..65d98c8d9 100644 --- a/blockservice/blockservice.go +++ b/blockservice/blockservice.go @@ -25,13 +25,26 @@ var ErrNotFound = errors.New("blockservice: key not found") // datastore and may retrieve data from a remote Exchange. // It uses an internal `datastore.Datastore` instance to store values. type BlockService interface { + // Blockstore returns a reference to the underlying blockstore Blockstore() blockstore.Blockstore + + // Exchange returns a reference to the underlying exchange (usually bitswap) Exchange() exchange.Interface + + // AddBlock puts a given block to the underlying datastore AddBlock(o blocks.Block) (*cid.Cid, error) + + // AddBlocks adds a slice of blocks at the same time using batching + // capabilities of the underlying datastore whenever possible. AddBlocks(bs []blocks.Block) ([]*cid.Cid, error) + GetBlock(ctx context.Context, c *cid.Cid) (blocks.Block, error) - GetBlocks(ctx context.Context, ks []*cid.Cid) <-chan blocks.Block DeleteBlock(o blocks.Block) error + + // GetBlocks does a batch request for the given cids, returning blocks as + // they are found, in no particular order. + GetBlocks(ctx context.Context, ks []*cid.Cid) <-chan blocks.Block + Close() error } diff --git a/core/builder.go b/core/builder.go index 9a9d8066d..fd64349d1 100644 --- a/core/builder.go +++ b/core/builder.go @@ -115,6 +115,7 @@ func defaultRepo(dstore repo.Datastore) (repo.Repo, error) { }, nil } +// NewNode constructs and returns an IpfsNode using the given cfg. func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) { if cfg == nil { cfg = new(BuildCfg) diff --git a/core/core.go b/core/core.go index ed50502db..62ed73636 100644 --- a/core/core.go +++ b/core/core.go @@ -420,6 +420,8 @@ func setupDiscoveryOption(d config.Discovery) DiscoveryOption { return nil } +// HandlePeerFound attempts to connect to peer from `PeerInfo`, if it fails +// logs a warning log. func (n *IpfsNode) HandlePeerFound(p pstore.PeerInfo) { log.Warning("trying peer info: ", p) ctx, cancel := context.WithTimeout(n.Context(), discoveryConnTimeout) @@ -590,6 +592,7 @@ func (n *IpfsNode) teardown() error { return nil } +// OnlineMode returns whether or not the IpfsNode is in OnlineMode. func (n *IpfsNode) OnlineMode() bool { switch n.mode { case onlineMode: @@ -599,6 +602,7 @@ func (n *IpfsNode) OnlineMode() bool { } } +// SetLocal will set the IpfsNode to local mode func (n *IpfsNode) SetLocal(isLocal bool) { if isLocal { n.mode = localMode @@ -606,6 +610,7 @@ func (n *IpfsNode) SetLocal(isLocal bool) { n.localModeSet = true } +// LocalMode returns whether or not the IpfsNode is in LocalMode func (n *IpfsNode) LocalMode() bool { if !n.localModeSet { // programmer error should not happen @@ -619,6 +624,7 @@ func (n *IpfsNode) LocalMode() bool { } } +// Bootstrap will set and call the IpfsNodes bootstrap function. func (n *IpfsNode) Bootstrap(cfg BootstrapConfig) error { // TODO what should return value be when in offlineMode? @@ -670,6 +676,7 @@ func (n *IpfsNode) loadID() error { return nil } +// GetKey will return a key from the Keystore with name `name`. func (n *IpfsNode) GetKey(name string) (ic.PrivKey, error) { if name == "self" { return n.PrivateKey, nil diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index 14e43483b..6c1d61dcd 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -15,28 +15,34 @@ type CoreAPI struct { node *core.IpfsNode } -// NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node +// NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node. func NewCoreAPI(n *core.IpfsNode) coreiface.CoreAPI { api := &CoreAPI{n} return api } +// Unixfs returns the UnixfsAPI interface backed by the go-ipfs node func (api *CoreAPI) Unixfs() coreiface.UnixfsAPI { return (*UnixfsAPI)(api) } +// Dag returns the DagAPI interface backed by the go-ipfs node func (api *CoreAPI) Dag() coreiface.DagAPI { return &DagAPI{api, nil} } +// Name returns the NameAPI interface backed by the go-ipfs node func (api *CoreAPI) Name() coreiface.NameAPI { return &NameAPI{api, nil} } +// Key returns the KeyAPI interface backed by the go-ipfs node func (api *CoreAPI) Key() coreiface.KeyAPI { return &KeyAPI{api, nil} } +// ResolveNode resolves the path `p` using Unixfx resolver, gets and returns the +// resolved Node. func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreiface.Node, error) { p, err := api.ResolvePath(ctx, p) if err != nil { @@ -50,6 +56,8 @@ func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (coreifac return node, nil } +// ResolvePath resolves the path `p` using Unixfs resolver, returns the +// resolved path. // TODO: store all of ipfspath.Resolver.ResolvePathComponents() in Path func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreiface.Path, error) { if p.Resolved() { @@ -84,6 +92,7 @@ type path struct { root *cid.Cid } +// ParsePath parses path `p` using ipfspath parser, returns the parsed path. func ParsePath(p string) (coreiface.Path, error) { pp, err := ipfspath.ParsePath(p) if err != nil { @@ -92,10 +101,12 @@ func ParsePath(p string) (coreiface.Path, error) { return &path{path: pp}, nil } +// ParseCid parses the path from `c`, retruns the parsed path. func ParseCid(c *cid.Cid) coreiface.Path { return &path{path: ipfspath.FromCid(c), cid: c, root: c} } +// ResolvePath parses path from string `p`, returns parsed path. func ResolvedPath(p string, c *cid.Cid, r *cid.Cid) coreiface.Path { return &path{path: ipfspath.FromString(p), cid: c, root: r} } diff --git a/core/coreapi/dag.go b/core/coreapi/dag.go index c5d59bc13..3a45fd0a4 100644 --- a/core/coreapi/dag.go +++ b/core/coreapi/dag.go @@ -19,6 +19,9 @@ type DagAPI struct { *caopts.DagOptions } +// Put inserts data using specified format and input encoding. Unless used with +// `WithCodes` or `WithHash`, the defaults "dag-cbor" and "sha256" are used. +// Returns the path of the inserted data. func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPutOption) (coreiface.Path, error) { settings, err := caopts.DagPutOptions(opts...) if err != nil { @@ -46,10 +49,12 @@ func (api *DagAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.DagPut return ParseCid(nds[0].Cid()), nil } +// Get resolves `path` using Unixfs resolver, returns the resolved Node. func (api *DagAPI) Get(ctx context.Context, path coreiface.Path) (coreiface.Node, error) { return api.core().ResolveNode(ctx, path) } +// Tree returns list of paths within a node specified by the path `p`. func (api *DagAPI) Tree(ctx context.Context, p coreiface.Path, opts ...caopts.DagTreeOption) ([]coreiface.Path, error) { settings, err := caopts.DagTreeOptions(opts...) if err != nil { diff --git a/core/coreapi/interface/interface.go b/core/coreapi/interface/interface.go index cdbb2508b..720f935e2 100644 --- a/core/coreapi/interface/interface.go +++ b/core/coreapi/interface/interface.go @@ -17,9 +17,13 @@ import ( // Path is a generic wrapper for paths used in the API. A path can be resolved // to a CID using one of Resolve functions in the API. type Path interface { + // String returns the path as a string. String() string + // Cid returns cid referred to by path Cid() *cid.Cid + // Root returns cid of root path Root() *cid.Cid + // Resolved returns whether path has been fully resolved Resolved() bool } @@ -33,22 +37,31 @@ type Reader interface { io.Closer } +// IpnsEntry specifies the interface to IpnsEntries type IpnsEntry interface { + // Name returns IpnsEntry name Name() string + // Value returns IpnsEntry value Value() Path } +// Key specifies the interface to Keys in KeyAPI Keystore type Key interface { + // Key returns key name Name() string + // Path returns key path Path() Path } // CoreAPI defines an unified interface to IPFS for Go programs. type CoreAPI interface { - // Unixfs returns an implementation of Unixfs API + // Unixfs returns an implementation of Unixfs API. Unixfs() UnixfsAPI + // Dag returns an implementation of Dag API. Dag() DagAPI + // Name returns an implementation of Name API. Name() NameAPI + // Key returns an implementation of Key API. Key() KeyAPI // ResolvePath resolves the path using Unixfs resolver diff --git a/core/coreapi/key.go b/core/coreapi/key.go index b5a0e3308..cb67d9c2d 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -24,14 +24,18 @@ type key struct { peerId string } +// Name returns the key name func (k *key) Name() string { return k.name } +// Path returns the path of the key. func (k *key) Path() coreiface.Path { return &path{path: ipfspath.FromString(ipfspath.Join([]string{"/ipns", k.peerId}))} } +// Generate generates new key, stores it in the keystore under the specified +// name and returns a base58 encoded multihash of its public key. func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.KeyGenerateOption) (coreiface.Key, error) { options, err := caopts.KeyGenerateOptions(opts...) if err != nil { @@ -88,6 +92,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key return &key{name, pid.Pretty()}, nil } +// 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() if err != nil { @@ -117,6 +122,8 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) { return out, nil } +// Rename renames `oldName` to `newName`. Returns the key and whether another +// key was overwritten, or an error. func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, opts ...caopts.KeyRenameOption) (coreiface.Key, bool, error) { options, err := caopts.KeyRenameOptions(opts...) if err != nil { @@ -169,6 +176,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o return &key{newName, pid.Pretty()}, overwrite, ks.Delete(oldName) } +// Remove removes keys from keystore. Returns ipns path of the removed key. func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Path, error) { ks := api.node.Repo.Keystore() diff --git a/core/coreapi/name.go b/core/coreapi/name.go index fd61d250d..c007bba13 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -29,14 +29,17 @@ type ipnsEntry struct { value coreiface.Path } +// Name returns the ipnsEntry name. func (e *ipnsEntry) Name() string { return e.name } +// Value returns the ipnsEntry value. func (e *ipnsEntry) Value() coreiface.Path { return e.value } +// 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) { options, err := caopts.NamePublishOptions(opts...) if err != nil { @@ -82,6 +85,8 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt }, nil } +// Resolve attempts to resolve the newest version of the specified name and +// returns its path. func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.NameResolveOption) (coreiface.Path, error) { options, err := caopts.NameResolveOptions(opts...) if err != nil { diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 5139eb086..e3b458a0d 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -14,6 +14,8 @@ import ( type UnixfsAPI CoreAPI +// Add builds a merkledag node from a reader, adds it to the blockstore, +// and returns the key representing that node. func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.Path, error) { k, err := coreunix.AddWithContext(ctx, api.node, r) if err != nil { @@ -26,6 +28,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.Path, err return ParseCid(c), nil } +// Cat returns the data contained by an IPFS or IPNS object(s) at path `p`. func (api *UnixfsAPI) Cat(ctx context.Context, p coreiface.Path) (coreiface.Reader, error) { dagnode, err := api.core().ResolveNode(ctx, p) if err != nil { @@ -41,6 +44,8 @@ func (api *UnixfsAPI) Cat(ctx context.Context, p coreiface.Path) (coreiface.Read return r, nil } +// Ls returns the contents of an IPFS or IPNS object(s) at path p, with the format: +// ` ` func (api *UnixfsAPI) Ls(ctx context.Context, p coreiface.Path) ([]*coreiface.Link, error) { dagnode, err := api.core().ResolveNode(ctx, p) if err != nil { diff --git a/core/coreunix/add.go b/core/coreunix/add.go index 287fe4f07..c1e815714 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -73,6 +73,7 @@ type AddedObject struct { Size string `json:",omitempty"` } +// NewAdder Returns a new Adder used for a file add operation. func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCBlockstore, ds dag.DAGService) (*Adder, error) { return &Adder{ ctx: ctx, @@ -126,6 +127,7 @@ func (adder *Adder) mfsRoot() (*mfs.Root, error) { return adder.mroot, nil } +// SetMfsRoot sets `r` as the root for Adder. func (adder *Adder) SetMfsRoot(r *mfs.Root) { adder.mroot = r } @@ -152,6 +154,7 @@ func (adder *Adder) add(reader io.Reader) (node.Node, error) { return balanced.BalancedLayout(params.New(chnk)) } +// RootNode returns the root node of the Added. func (adder *Adder) RootNode() (node.Node, error) { // for memoizing if adder.root != nil { @@ -181,6 +184,8 @@ func (adder *Adder) RootNode() (node.Node, error) { return root, err } +// Recursively pins the root node of Adder and +// writes the pin state to the backing datastore. func (adder *Adder) PinRoot() error { root, err := adder.RootNode() if err != nil { @@ -207,6 +212,7 @@ func (adder *Adder) PinRoot() error { return adder.pinning.Flush() } +// Finalize flushes the mfs root directory and returns the mfs root node. func (adder *Adder) Finalize() (node.Node, error) { mr, err := adder.mfsRoot() if err != nil { @@ -566,6 +572,7 @@ func outputDagnode(out chan interface{}, name string, dn node.Node) error { return nil } +// NewMemoryDagService builds and returns a new mem-datastore. func NewMemoryDagService() dag.DAGService { // build mem-datastore for editor's intermediary nodes bs := bstore.NewBlockstore(syncds.MutexWrap(ds.NewMapDatastore())) diff --git a/keystore/keystore.go b/keystore/keystore.go index fd9ab94b4..56dfd1b01 100644 --- a/keystore/keystore.go +++ b/keystore/keystore.go @@ -10,22 +10,25 @@ import ( ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto" ) +// Keystore provides a key management interface type Keystore interface { - // Has return whether or not a key exist in the Keystore + // Has returns whether or not a key exist in the Keystore Has(string) (bool, error) - // Put store a key in the Keystore + // Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists Put(string, ci.PrivKey) error - // Get retrieve a key from the Keystore + // Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey + // otherwise. Get(string) (ci.PrivKey, error) - // Delete remove a key from the Keystore + // Delete removes a key from the Keystore Delete(string) error - // List return a list of key identifier + // List returns a list of key identifier List() ([]string, error) } var ErrNoSuchKey = fmt.Errorf("no key by the given name was found") var ErrKeyExists = fmt.Errorf("key by that name already exists, refusing to overwrite") +// FSKeystore is a keystore backed by files in a given directory stored on disk. type FSKeystore struct { dir string } @@ -60,7 +63,7 @@ func NewFSKeystore(dir string) (*FSKeystore, error) { return &FSKeystore{dir}, nil } -// Has return whether or not a key exist in the Keystore +// Has returns whether or not a key exist in the Keystore func (ks *FSKeystore) Has(name string) (bool, error) { kp := filepath.Join(ks.dir, name) @@ -77,7 +80,7 @@ func (ks *FSKeystore) Has(name string) (bool, error) { return true, nil } -// Put store a key in the Keystore +// Put stores a key in the Keystore, if a key with the same name already exists, returns ErrKeyExists func (ks *FSKeystore) Put(name string, k ci.PrivKey) error { if err := validateName(name); err != nil { return err @@ -108,7 +111,8 @@ func (ks *FSKeystore) Put(name string, k ci.PrivKey) error { return err } -// Get retrieve a key from the Keystore +// Get retrieves a key from the Keystore if it exists, and returns ErrNoSuchKey +// otherwise. func (ks *FSKeystore) Get(name string) (ci.PrivKey, error) { if err := validateName(name); err != nil { return nil, err @@ -127,7 +131,7 @@ func (ks *FSKeystore) Get(name string) (ci.PrivKey, error) { return ci.UnmarshalPrivateKey(data) } -// Delete remove a key from the Keystore +// Delete removes a key from the Keystore func (ks *FSKeystore) Delete(name string) error { if err := validateName(name); err != nil { return err diff --git a/keystore/memkeystore.go b/keystore/memkeystore.go index 3732a3262..6d07f6dc3 100644 --- a/keystore/memkeystore.go +++ b/keystore/memkeystore.go @@ -2,6 +2,8 @@ package keystore import ci "gx/ipfs/QmaPbCnUMBohSGo3KnxEa2bHqyJVVeEEcwtqJAYxerieBo/go-libp2p-crypto" +// MemKeystore is an in memory keystore implementation that is not persisted to +// any backing storage. type MemKeystore struct { keys map[string]ci.PrivKey } @@ -58,7 +60,7 @@ func (mk *MemKeystore) Delete(name string) error { // List return a list of key identifier func (mk *MemKeystore) List() ([]string, error) { out := make([]string, 0, len(mk.keys)) - for k, _ := range mk.keys { + for k := range mk.keys { out = append(out, k) } return out, nil diff --git a/merkledag/merkledag.go b/merkledag/merkledag.go index 7b85bf008..311bcef27 100644 --- a/merkledag/merkledag.go +++ b/merkledag/merkledag.go @@ -27,14 +27,18 @@ var ErrNotFound = fmt.Errorf("merkledag: not found") // DAGService is an IPFS Merkle DAG service. type DAGService interface { + // Add adds the node to the DAGService Add(node.Node) (*cid.Cid, error) + // Get gets the node the from the DAGService Get(context.Context, *cid.Cid) (node.Node, error) + // Remove removes the node from the DAGService Remove(node.Node) error // GetMany returns a channel of NodeOption given // a set of CIDs. GetMany(context.Context, []*cid.Cid) <-chan *NodeOption + // Batch is a buffer for batching adds to a dag. Batch() *Batch LinkService diff --git a/mfs/system.go b/mfs/system.go index 28875d3b3..319ba3020 100644 --- a/mfs/system.go +++ b/mfs/system.go @@ -41,19 +41,19 @@ const ( TDir ) -// FSNode represents any node (directory, root, or file) in the mfs filesystem +// FSNode represents any node (directory, root, or file) in the mfs filesystem. type FSNode interface { GetNode() (node.Node, error) Flush() error Type() NodeType } -// Root represents the root of a filesystem tree +// Root represents the root of a filesystem tree. type Root struct { - // node is the merkledag root + // node is the merkledag root. node *dag.ProtoNode - // val represents the node. It can either be a File or a Directory + // val represents the node. It can either be a File or a Directory. val FSNode repub *Republisher @@ -63,9 +63,10 @@ type Root struct { Type string } +// PubFunc is the function used by the `publish()` method. type PubFunc func(context.Context, *cid.Cid) error -// newRoot creates a new Root and starts up a republisher routine for it +// NewRoot creates a new Root and starts up a republisher routine for it. func NewRoot(parent context.Context, ds dag.DAGService, node *dag.ProtoNode, pf PubFunc) (*Root, error) { var repub *Republisher @@ -107,10 +108,13 @@ func NewRoot(parent context.Context, ds dag.DAGService, node *dag.ProtoNode, pf return root, nil } +// GetValue returns the value of Root. func (kr *Root) GetValue() FSNode { return kr.val } +// Flush signals that an update has occurred since the last publish, +// and updates the Root republisher. func (kr *Root) Flush() error { nd, err := kr.GetValue().GetNode() if err != nil { @@ -154,7 +158,7 @@ func (kr *Root) FlushMemFree(ctx context.Context) error { } // closeChild implements the childCloser interface, and signals to the publisher that -// there are changes ready to be published +// there are changes ready to be published. func (kr *Root) closeChild(name string, nd node.Node, sync bool) error { c, err := kr.dserv.Add(nd) if err != nil { @@ -181,7 +185,7 @@ func (kr *Root) Close() error { return nil } -// Republisher manages when to publish a given entry +// Republisher manages when to publish a given entry. type Republisher struct { TimeoutLong time.Duration TimeoutShort time.Duration @@ -198,7 +202,7 @@ type Republisher struct { } // NewRepublisher creates a new Republisher object to republish the given root -// using the given short and long time intervals +// using the given short and long time intervals. func NewRepublisher(ctx context.Context, pf PubFunc, tshort, tlong time.Duration) *Republisher { ctx, cancel := context.WithCancel(ctx) return &Republisher{ @@ -218,6 +222,8 @@ func (p *Republisher) setVal(c *cid.Cid) { p.val = c } +// WaitPub Returns immediately if `lastpub` value is consistent with the +// current value `val`, else will block until `val` has been published. func (p *Republisher) WaitPub() { p.lk.Lock() consistent := p.lastpub == p.val @@ -239,7 +245,7 @@ func (p *Republisher) Close() error { // Touch signals that an update has occurred since the last publish. // Multiple consecutive touches may extend the time period before -// the next Publish occurs in order to more efficiently batch updates +// the next Publish occurs in order to more efficiently batch updates. func (np *Republisher) Update(c *cid.Cid) { np.setVal(c) select { @@ -248,7 +254,7 @@ func (np *Republisher) Update(c *cid.Cid) { } } -// Run is the main republisher loop +// Run is the main republisher loop. func (np *Republisher) Run() { for { select { @@ -284,6 +290,7 @@ func (np *Republisher) Run() { } } +// publish calls the `PubFunc`. func (np *Republisher) publish(ctx context.Context) error { np.lk.Lock() topub := np.val diff --git a/pin/pin.go b/pin/pin.go index dc2eee7f2..001981792 100644 --- a/pin/pin.go +++ b/pin/pin.go @@ -46,11 +46,22 @@ const ( type PinMode int const ( + // Recursive pins pin the target cids along with any reachable children. Recursive PinMode = iota + + // Direct pins pin just the target cid. Direct + + // Indirect pins are cids who have some ancestor pinned recursively. Indirect + + // Internal pins are cids used to keep the internal state of the pinner. Internal + + // NotPinned NotPinned + + // Any refers to any pinned cid Any ) @@ -82,10 +93,20 @@ func StringToPinMode(s string) (PinMode, bool) { } type Pinner interface { + // IsPinned returns whether or not the given cid is pinned + // and an explanation of why its pinned IsPinned(*cid.Cid) (string, bool, error) + + // IsPinnedWithType returns whether or not the given cid is pinned with the + // given pin type, as well as returning the type of pin its pinned with. IsPinnedWithType(*cid.Cid, PinMode) (string, bool, error) - Pin(context.Context, node.Node, bool) error - Unpin(context.Context, *cid.Cid, bool) error + + // Pin the given node, optionally recursively. + Pin(ctx context.Context, node node.Node, recursive bool) error + + // Unpin the given cid. If recursive is true, removes either a recursive or + // a direct pin. If recursive is false, only removes a direct pin. + Unpin(ctx context.Context, cid *cid.Cid, recursive bool) error // Update updates a recursive pin from one cid to another // this is more efficient than simply pinning the new one and unpinning the @@ -106,9 +127,17 @@ type Pinner interface { // be successful. RemovePinWithMode(*cid.Cid, PinMode) + // Flush writes the pin state to the backing datastore Flush() error + + // DirectKeys returns all directly pinned cids DirectKeys() []*cid.Cid + + // DirectKeys returns all recursively pinned cids RecursiveKeys() []*cid.Cid + + // InternalPins returns all cids kept pinned for the internal state of the + // pinner InternalPins() []*cid.Cid } @@ -118,6 +147,7 @@ type Pinned struct { Via *cid.Cid } +// Pinned returns whether or not the given cid is pinned func (p Pinned) Pinned() bool { if p.Mode == NotPinned { return false @@ -126,6 +156,7 @@ func (p Pinned) Pinned() bool { } } +// String Returns pin status as string func (p Pinned) String() string { switch p.Mode { case NotPinned: @@ -248,6 +279,8 @@ func (p *pinner) IsPinned(c *cid.Cid) (string, bool, error) { return p.isPinnedWithType(c, Any) } +// IsPinnedWithType returns whether or not the given cid is pinned with the +// given pin type, as well as returning the type of pin its pinned with. func (p *pinner) IsPinnedWithType(c *cid.Cid, mode PinMode) (string, bool, error) { p.lock.RLock() defer p.lock.RUnlock() @@ -299,6 +332,8 @@ func (p *pinner) isPinnedWithType(c *cid.Cid, mode PinMode) (string, bool, error return "", false, nil } +// CheckIfPinned Checks if a set of keys are pinned, more efficient than +// calling IsPinned for each key, returns the pinned status of cid(s) func (p *pinner) CheckIfPinned(cids ...*cid.Cid) ([]Pinned, error) { p.lock.RLock() defer p.lock.RUnlock() @@ -364,6 +399,9 @@ func (p *pinner) CheckIfPinned(cids ...*cid.Cid) ([]Pinned, error) { return pinned, nil } +// RemovePinWithMode is for manually editing the pin structure. +// Use with care! If used improperly, garbage collection may not +// be successful. func (p *pinner) RemovePinWithMode(c *cid.Cid, mode PinMode) { p.lock.Lock() defer p.lock.Unlock() @@ -457,6 +495,9 @@ func (p *pinner) RecursiveKeys() []*cid.Cid { return p.recursePin.Keys() } +// Update updates a recursive pin from one cid to another +// this is more efficient than simply pinning the new one and unpinning the +// old one func (p *pinner) Update(ctx context.Context, from, to *cid.Cid, unpin bool) error { p.lock.Lock() defer p.lock.Unlock() @@ -527,6 +568,8 @@ func (p *pinner) Flush() error { return nil } +// InternalPins returns all cids kept pinned for the internal state of the +// pinner func (p *pinner) InternalPins() []*cid.Cid { p.lock.Lock() defer p.lock.Unlock() diff --git a/repo/repo.go b/repo/repo.go index 3403482c9..8cd776594 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -16,24 +16,41 @@ var ( ErrApiNotRunning = errors.New("api not running") ) +// Repo represents all persistent data of a given ipfs node. type Repo interface { + // Config returns the ipfs configuration file from the repo. Changes made + // to the returned config are not automatically persisted. Config() (*config.Config, error) + + // BackupConfig creates a backup of the current configuration file using + // the given prefix for naming. BackupConfig(prefix string) (string, error) + + // SetConfig persists the given configuration struct to storage. SetConfig(*config.Config) error + // SetConfigKey sets the given key-value pair within the config and persists it to storage. SetConfigKey(key string, value interface{}) error + + // GetConfigKey reads the value for the given key from the configuration in storage. GetConfigKey(key string) (interface{}, error) + // Datastore returns a reference to the configured data storage backend. Datastore() Datastore + + // GetStorageUsage returns the number of bytes stored. GetStorageUsage() (uint64, error) + // Keystore returns a reference to the key management interface. Keystore() keystore.Keystore + // FileManager returns a reference to the filestore file manager. FileManager() *filestore.FileManager // SetAPIAddr sets the API address in the repo. SetAPIAddr(addr ma.Multiaddr) error + // SwarmKey returns the configured shared symmetric key for the private networks feature. SwarmKey() ([]byte, error) io.Closer