Skip to content
This repository has been archived by the owner on Aug 11, 2021. It is now read-only.

BREAKING CHANGE: Remove .cid, .multihash and .serialized properties #99

Merged
merged 4 commits into from
Nov 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 17 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,22 @@
- [Add and remove a Link](#add-and-remove-a-link)
- [API](#api)
- [DAGNode functions](#dagnode-functions)
- [DAGNode.create(data, links, hashAlg, callback)](#dagnodecreatedata-links-hashalg-callback)
- [DAGNode.create(data, links, callback)](#dagnodecreatedata-links-callback)
- [addLink(node, link, callback)](#addlinknode-link-callback)
- [rmLink(node, nameOrMultihash, callback)](#rmlinknode-nameormultihash-callback)
- [rmLink(node, nameOrCid, callback)](#rmlinknode-nameorcid-callback)
- [clone(node, callback)](#clonenode-callback)
- [DAGNode instance methods and properties](#dagnode-instance-methods-and-properties)
- [`node.data`](#nodedata)
- [`node.links`](#nodelinks)
- [`node.size`](#nodesize)
- [`node.multihash`](#nodemultihash)
- [`node.serialized`](#nodeserialized)
- [`node.toJSON()`](#nodetojson)
- [`node.toString()`](#nodetostring)
- [DAGLink functions](#daglink-functions)
- [DAGLink.create(name, size, multihash, callback)](#daglinkcreatename-size-multihash-callback)
- [DAGLink.create(name, size, cid, callback)](#daglinkcreatename-size-cid-callback)
- [DAGLink instance methods and properties](#daglink-instance-methods-and-properties)
- [`link.name`](#linkname)
- [`link.size`](#linksize)
- [`link.multihash`](#linkmultihash)
- [`link.cid`](#linkcid)
- [`link.toJSON()`](#linktojson)
- [`link.toString()`](#linktostring)
- [[IPLD Format Specifics](https://github.com/ipld/interface-ipld-format) - Local (node/block scope) resolver](#ipld-format-specificshttpsgithubcomipldinterface-ipld-format---local-nodeblock-scope-resolver)
Expand Down Expand Up @@ -101,7 +99,7 @@ DAGNode.create('some data', (err, node2) => {
```JavaScript
const link = {
name: 'I am a link',
multihash: 'QmHash..',
cid: 'QmHash..',
size: 42
}

Expand Down Expand Up @@ -136,11 +134,10 @@ const dagPB = require('ipld-dag-pb')
const DAGNode = dagPB.DAGNode
```

#### DAGNode.create(data, links, hashAlg, callback)
#### DAGNode.create(data, links, callback)

- `data` - type: Buffer
- `links`- type: Array of DAGLink instances or Array of DAGLink instances in its json format (link.toJSON)
- `hashAlg` - type: String
- `callback` - type: function with signature `function (err, node) {}`

Create a DAGNode.
Expand All @@ -156,7 +153,7 @@ links can be a single or an array of DAGLinks instances or objects with the foll
```JavaScript
{
name: '<some name>',
hash: '<some multihash>', // can also be `multihash: <some multihash>`
cid: '<some cid>',
size: <sizeInBytes>
}
```
Expand All @@ -167,7 +164,7 @@ links can be a single or an array of DAGLinks instances or objects with the foll
- `link` - type: DAGLink or DAGLink in its json format
- `callback` - type: function with signature `function (err, node) {}`

Creates a link on node A to node B by using node B to get its multihash. Returns a *new* instance of DAGNode without modifying the old one.
Creates a link on node A to node B by using node B to get its CID. Returns a *new* instance of DAGNode without modifying the old one.

Creates a new DAGNode instance with the union of node.links plus the new link.

Expand All @@ -180,21 +177,20 @@ Creates a new DAGNode instance with the union of node.links plus the new link.
{
name: '<some string>', // optional
size: <size in bytes>,
multihash: <multihash> // can be a String multihash or multihash buffer
cid: <cid> // can be a String CID, CID buffer or CID object
}
```


#### rmLink(node, nameOrMultihash, callback)
#### rmLink(node, nameOrCid, callback)

- `node` - type: DAGNode
- `nameOrMultihash` - type: String or multihash buffer
- `nameOrCid` - type: String, CID object or CID buffer
- `callback` - type: function with signature `function (err, node) {}`

Removes a link from the node by name. Returns a *new* instance of DAGNode without modifying the old one.

```JavaScript
DAGNode.rmLink(node, 'Link1' (err, dagNode) => ...)
DAGNode.rmLink(node, 'Link1' (err, dagNode) => ...)
```

#### clone(node, callback)
Expand Down Expand Up @@ -222,18 +218,14 @@ An array of `DAGLinks`

Size of the node, in bytes

#### `node.multihash`

#### `node.serialized`

#### `node.toJSON()`

#### `node.toString()`


### DAGLink functions

Following the same pattern as [`DAGNode functions`]() above, DAGLink also offers a function for its creation.
Following the same pattern as [`DAGNode functions`]() above, DAGLink also offers a function for its creation.

You can incude it in your project with:

Expand All @@ -242,13 +234,13 @@ const dagPB = require('ipld-dag-pb')
const DAGLink = dagPB.DAGLink
```

#### DAGLink.create(name, size, multihash, callback)
#### DAGLink.create(name, size, cid, callback)

```JavaScript
DAGLink.create(
'link-to-file', // name of the link (can be empty)
10, // size in bytes
'QmSomeHash...', // can be multihash buffer or string
'QmSomeHash...', // can be CID object, CID buffer or string
(err, link) => {
if (err) {
throw err
Expand All @@ -260,7 +252,7 @@ DAGLink.create(
Note: DAGLinks are simpler objects and can be instantiated directly:

```JavaScript
const link = new DAGLink(name, size, multihash)
const link = new DAGLink(name, size, cid)
```

### DAGLink instance methods and properties
Expand All @@ -269,7 +261,7 @@ const link = new DAGLink(name, size, multihash)

#### `link.size`

#### `link.multihash`
#### `link.cid`

#### `link.toJSON()`

Expand Down
4 changes: 2 additions & 2 deletions src/dag-link/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

const DAGLink = require('./index.js')

function create (name, size, multihash, callback) {
const link = new DAGLink(name, size, multihash)
function create (name, size, cid, callback) {
const link = new DAGLink(name, size, cid)
callback(null, link)
}

Expand Down
16 changes: 4 additions & 12 deletions src/dag-link/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ const withIs = require('class-is')

// Link represents an IPFS Merkle DAG Link between Nodes.
class DAGLink {
constructor (name, size, multihash) {
assert(multihash, 'A link requires a multihash to point to')
constructor (name, size, cid) {
assert(cid, 'A link requires a cid to point to')
// assert(size, 'A link requires a size')
// note - links should include size, but this assert is disabled
// for now to maintain consistency with go-ipfs pinset

this._name = name || ''
this._size = size
this._cid = new CID(multihash)
this._cid = new CID(cid)
}

toString () {
Expand All @@ -26,7 +26,7 @@ class DAGLink {
this._json = Object.freeze({
name: this.name,
size: this.size,
multihash: this._cid.toBaseEncodedString()
cid: this._cid.toBaseEncodedString()
})
}

Expand All @@ -49,14 +49,6 @@ class DAGLink {
throw new Error("Can't set property: 'size' is immutable")
}

get multihash () {
return this._cid.buffer
}

set multihash (multihash) {
throw new Error("Can't set property: 'multihash' is immutable")
}

get cid () {
return this._cid
}
Expand Down
2 changes: 1 addition & 1 deletion src/dag-link/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ function createDagLinkFromB58EncodedHash (link) {
return new DAGLink(
link.name ? link.name : link.Name,
link.size ? link.size : link.Size,
link.hash || link.Hash || link.multihash
link.hash || link.Hash || link.multihash || link.cid
)
}

Expand Down
42 changes: 27 additions & 15 deletions src/dag-node/addLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,40 @@ const DAGLink = require('../dag-link')
const DAGNode = require('./index')
const create = require('./create')

function addLink (node, link, callback) {
const links = cloneLinks(node)
const data = cloneData(node)

function asDAGLink (link, callback) {
if (DAGLink.isDAGLink(link)) {
// It's a DAGLink instance
// no need to do anything
} else if (DAGNode.isDAGNode(link)) {

return callback(null, link)
}

if (DAGNode.isDAGNode(link)) {
// It's a DAGNode instance
// convert to link
link = toDAGLink(link)
} else {
// It's a Object with name, multihash/link and size
try {
link = new DAGLink(link.name, link.size, link.multihash || link.hash)
} catch (err) {
return callback(err)
}
return toDAGLink(link, {}, callback)
}

links.push(link)
create(data, links, callback)
// It's a Object with name, multihash/hash/cid and size
try {
callback(null, new DAGLink(link.name, link.size, link.multihash || link.hash || link.cid))
} catch (err) {
return callback(err)
}
}

function addLink (node, link, callback) {
const links = cloneLinks(node)
const data = cloneData(node)

asDAGLink(link, (error, link) => {
if (error) {
return callback(error)
}

links.push(link)
create(data, links, callback)
})
}

module.exports = addLink
40 changes: 13 additions & 27 deletions src/dag-node/create.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,43 @@
'use strict'

const multihashing = require('multihashing-async')
const sort = require('stable')
const dagPBUtil = require('../util.js')
const serialize = dagPBUtil.serialize
const {
serialize
} = require('../util.js')
const dagNodeUtil = require('./util.js')
const linkSort = dagNodeUtil.linkSort
const DAGNode = require('./index.js')
const DAGLink = require('../dag-link')

function create (data, dagLinks, hashAlg, callback) {
function create (data, links, callback) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a custom hash algorithm ever work? If yes, would it make sense to keep it? Theoretically you can have CIDv1 PB nodes with a different hash algorithm, e.g. if sha2 breaks. Though on the practical side, we (hopefully) won't use dag-pb by then anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, js-ipfs-unixfs-engine even has tests for different hashing algorithms - but they are passed into ipld.dag.put and not to DAGNode.create. Best not to do it in more than one place.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH, I don't quite follow as even a ipld.dag.put would need to forward it to dag-pb at some point. But it sounds like you have it under control.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wait, I got it. You pass in the already encoded data.

Copy link
Member Author

@achingbrain achingbrain Nov 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does - ipld.dag.put passes the hashAlg to util.cid.

if (typeof data === 'function') {
callback = data
data = undefined
} else if (typeof data === 'string') {
data = Buffer.from(data)
}
if (typeof dagLinks === 'function') {
callback = dagLinks
dagLinks = []
}
if (typeof hashAlg === 'function') {
callback = hashAlg
hashAlg = undefined
if (typeof links === 'function') {
callback = links
links = []
}

if (!Buffer.isBuffer(data)) {
return callback(new Error('Passed \'data\' is not a buffer or a string!'))
}

if (!hashAlg) {
hashAlg = 'sha2-256'
}

const links = dagLinks.map((link) => {
links = links.map((link) => {
return DAGLink.isDAGLink(link) ? link : DAGLink.util.createDagLinkFromB58EncodedHash(link)
})
const sortedLinks = sort(links, linkSort)
links = sort(links, linkSort)

serialize({
data: data,
links: sortedLinks
}, (err, serialized) => {
data, links
}, (err, buffer) => {
if (err) {
return callback(err)
}
multihashing(serialized, hashAlg, (err, multihash) => {
if (err) {
return callback(err)
}
const dagNode = new DAGNode(data, sortedLinks, serialized, multihash)
callback(null, dagNode)
})

callback(null, new DAGNode(data, links, buffer.length))
})
}

Expand Down
Loading