Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
vasco-santos committed Jun 19, 2018
1 parent b584324 commit 53e7b95
Show file tree
Hide file tree
Showing 17 changed files with 418 additions and 299 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
},
"dependencies": {
"async": "^2.6.0",
"base32-encode": "^1.0.0",
"big.js": "^5.0.3",
"binary-querystring": "~0.1.2",
"bl": "^1.2.2",
Expand Down Expand Up @@ -164,7 +165,6 @@
"pull-stream": "^3.6.7",
"pull-stream-to-stream": "^1.3.4",
"pull-zip": "^2.0.1",
"quick-lru": "^1.1.0",
"read-pkg-up": "^3.0.0",
"readable-stream": "2.3.6",
"stream-to-pull-stream": "^1.7.2",
Expand Down
2 changes: 1 addition & 1 deletion src/cli/commands/name/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports = {
throw err
}

print(`Published to ${result.value}: /ipfs/${result.name}`)
print(`Published to ${result.name}: ${result.value}`)
})
}
}
114 changes: 42 additions & 72 deletions src/core/components/name.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
'use strict'

const promisify = require('promisify-es6')
const OFFLINE_ERROR = require('../utils').OFFLINE_ERROR
const series = require('async/series')
const human = require('human-to-milliseconds')
const path = require('../ipns/path')

const OFFLINE_ERROR = require('../utils').OFFLINE_ERROR

const keyLookup = (ipfsNode, kname, cb) => {
if (kname === 'self') {
Expand All @@ -18,29 +21,6 @@ const keyLookup = (ipfsNode, kname, cb) => {
})
}

const publish = (ipfsNode, privateKey, ipfsPath, publishOptions, callback) => {
// Should verify if exists ?
if (publishOptions.verifyIfExists) {
// TODO resolve
// https://github.com/ipfs/go-ipfs/blob/master/core/commands/publish.go#L172
}

// Add pubValidTime

// Publish
const eol = new Date(Date.now())

ipfsNode._namesys.publishWithEOL(privateKey, ipfsPath, eol, (err, res) => {
if (err) {
callback(err)
}

// TODO HERE HERE HERE

callback(null, res)
})
}

module.exports = function name (self) {
return {
/**
Expand All @@ -51,64 +31,55 @@ module.exports = function name (self) {
*
* Examples: TODO such as in go
*
* @param {String} ipfsPath
* @param {Object} options
* @param {String} value ipfs path of the object to be published.
* @param {boolean} resolve resolve given path before publishing.
* @param {String} lifetime time duration that the record will be valid for.
This accepts durations such as "300s", "1.5h" or "2h45m". Valid time units are
"ns", "us" (or "µs"), "ms", "s", "m", "h".
* @param {String} ttl time duration this record should be cached for (caution: experimental).
* @param {String} key name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'.
* @param {function(Error)} [callback]
* @returns {Promise|void}
*/
publish: promisify((ipfsPath, callback) => {
// https://github.com/ipfs/go-ipfs/blob/master/core/commands/publish.go
publish: promisify((value, resolve = true, lifetime = '24h', ttl, key = 'self', callback) => {
if (!self.isOnline()) {
return callback(new Error(OFFLINE_ERROR))
}

// TODO Validate Mounts IPNS - cannot manually publish while IPNS is mounted

// TODO Validate Node identity not validated

// TODO Parse options and create object
const options = {
resolve: true,
d: '24h',
ttl: undefined,
key: 'self'
// Parse ipfs path value
try {
value = path.parsePath(value)
} catch (err) {
return callback(err)
}

// TODO Create waterfall
/* waterfall([
(cb) => human(options.d || '1s', cb),
], callback) */

human(options.d || '1s', (err, value) => {
series([
(cb) => human(lifetime || '1s', cb),
// (cb) => ttl ? human(ttl, cb) : cb(),
(cb) => keyLookup(self, key, cb),
(cb) => resolve ? path.resolvePath(self, value, cb) : cb() // if not resolved, and error will stop the execution
], (err, results) => {
if (err) {
return callback(new Error('Error parsing lifetime option'))
return callback(err)
}

const publishOptions = {
verifyIfExists: options.resolve,
pubValidTime: value
}
const pubValidTime = results[0]
const privateKey = results[1]

// TODO Date.now() + value
// TODO IMPROVEMENT - Handle ttl for cache
// const ttl = results[1]
// const privateKey = results[2]

// TODO TTL integration
// Calculate eol
const eol = new Date(Date.now() + pubValidTime)

// Get Key
keyLookup(self, options.key, (err, key) => {
// Start publishing process
self._ipns.publish(privateKey, value, eol, (err, res) => {
if (err) {
return callback(err)
callback(err)
}

// TODO ParsePath
// https://github.com/ipfs/go-ipfs/blob/master/path/path.go

publish(self, key, ipfsPath, publishOptions, (err, result) => {
if (err) {
callback(err)
}

return callback(null, result)
})
callback(null, res)
})
})
}),
Expand All @@ -125,17 +96,10 @@ module.exports = function name (self) {
resolve: promisify((name, nocache, recursive, callback) => {
const local = true

if (typeof name === 'function') {
callback = name
name = undefined
}

if (!self.isOnline()) {
return callback(new Error(OFFLINE_ERROR))
}

// let resolver = self._namesys.ipnsResolver

if (local && nocache) {
return callback(new Error('Cannot specify both local and nocache'))
}
Expand All @@ -149,9 +113,15 @@ module.exports = function name (self) {
name = `/ipns/${name}`
}

// TODO local public key?
const pubKey = self._peerInfo.id.pubKey
const options = {
local: local,
nocache: nocache,
recursive: recursive
}

self._namesys.resolve(name, pubKey, (err, result) => {
self._ipns.resolve(name, pubKey, options, (err, result) => {
if (err) {
return callback(err)
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const EventEmitter = require('events')
const config = require('./config')
const boot = require('./boot')
const components = require('./components')
const Namesys = require('./namesys')
const IPNS = require('./ipns')
// replaced by repo-browser when running in the browser
const defaultRepo = require('./runtime/repo-nodejs')

Expand Down Expand Up @@ -80,7 +80,7 @@ class IPFS extends EventEmitter {
this._blockService = new BlockService(this._repo)
this._ipld = new Ipld(this._blockService)
this._pubsub = undefined
this._namesys = new Namesys(null, this._repo)
this._ipns = new IPNS(null, this._repo)

// IPFS Core exposed components
// - for booting up a node
Expand Down
23 changes: 9 additions & 14 deletions src/core/namesys/index.js → src/core/ipns/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,20 @@ const series = require('async/series')

const IpnsPublisher = require('./publisher')
const IpnsResolver = require('./resolver')
const path = require('./path')

// const defaultRecordTtl = 60 * 1000

class Namesys {
class IPNS {
constructor (routing, repo, peerInfo) {
this.ipnsPublisher = new IpnsPublisher(routing, repo)
this.ipnsResolver = new IpnsResolver(repo)
// this.cache = new QuickLRU({maxSize: 1000});
}

// Resolve
resolve (name, pubKey, callback) {
// this.ipnsResolver.resolve()

this.ipnsResolver.resolve(name, pubKey, (err, result) => {
resolve (name, pubKey, options, callback) {
this.ipnsResolver.resolve(name, pubKey, options, (err, result) => {
if (err) {
return callback(err)
}
Expand All @@ -29,13 +28,8 @@ class Namesys {
})
}

// publish (value = ipfsPath)
publish (privKey, value) {
// TODO https://github.com/ipfs/go-ipfs/blob/master/namesys/namesys.go#L111
}

// publish with EOL (value = ipfsPath)
publishWithEOL (privKey, value, eol, callback) {
// Publish
publish (privKey, value, eol, callback) {
series([
(cb) => peerId.createFromPrivKey(privKey.bytes.toString('base64'), cb),
(cb) => this.ipnsPublisher.publishWithEOL(privKey, value, eol, cb)
Expand All @@ -44,7 +38,7 @@ class Namesys {
return callback(err)
}

// TODO Add to cache
// TODO IMPROVEMENT - Add to cache
// this.cache.set(id.toB58String(), {
// val: value,
// eol: Date.now() + ttl
Expand All @@ -55,4 +49,5 @@ class Namesys {
}
}

exports = module.exports = Namesys
exports = module.exports = IPNS
exports.path = path
71 changes: 71 additions & 0 deletions src/core/ipns/path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
'use strict'

const CID = require('cids')

const BAD_PATH_ERROR = new Error('invalid \'ipfs ref\' path')
const NO_COMPONENTS_ERROR = new Error('path must contain at least one component')

// Should verify if the value exists before publishing it
const resolvePath = (ipfsNode, value, callback) => {
if (value.startsWith('/ipns/')) {
// TODO resolve local?
// TODO Resolve from DHT
return callback(new Error('not implemented yet'))
}

ipfsNode.dag.get(value.substring('/ipfs/'.length), (err, value) => {
if (err) {
return callback(err)
}

return callback(null, value)
})
}

// parsePath returns a well-formed ipfs Path.
// The returned path will always be prefixed with /ipfs/ or /ipns/.
// If the received string is not a valid ipfs path, an error will be returned
const parsePath = (pathStr) => {
const parts = pathStr.split('/')

if (parts.length === 1) {
return parseCidToPath(pathStr)
}

// if the path does not begin with a slash, we expect this to start with a hash and be an ipfs path
if (parts[0] !== '') {
if (parseCidToPath(parts[0])) {
return `/ipfs/${pathStr}`
}
}

if (parts.length < 3) {
throw BAD_PATH_ERROR
}

if (parts[1] === 'ipfs') {
if (!parseCidToPath(parts[2])) {
throw BAD_PATH_ERROR
}
} else if (parts[1] !== 'ipns') {
throw BAD_PATH_ERROR
}
return pathStr
}

// parseCidToPath takes a CID in string form and returns a valid ipfs Path.
const parseCidToPath = (value) => {
if (value === '') {
throw NO_COMPONENTS_ERROR
}

const cid = new CID(value)
CID.validateCID(cid)

return `/ipfs/${value}`
}

module.exports = {
resolvePath: (ipfsNode, value, callback) => resolvePath(ipfsNode, value, callback),
parsePath: (pathStr) => parsePath(pathStr)
}
File renamed without changes.
15 changes: 13 additions & 2 deletions src/core/namesys/pb/ipnsEntry.js → src/core/ipns/pb/ipnsEntry.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module.exports = {
validityType = ipnsEntryProto.ValidityType.EOL
}

return {
const entry = {
value: value,
signature: signature,
validityType: validityType,
Expand All @@ -19,6 +19,16 @@ module.exports = {
ttl: ttl,
pubKey: pubKey
}

return Object.keys(entry).reduce((acc, key) => {
const reducedEntry = acc

if (entry[key] !== undefined) {
reducedEntry[key] = entry[key]
}

return reducedEntry
}, {})
},
// Marshal
marshal: (ipnsEntry) => {
Expand All @@ -27,5 +37,6 @@ module.exports = {
// Unmarshal
unmarshal: (marsheled) => {
return ipnsEntryProto.decode(marsheled)
}
},
validityType: ipnsEntryProto.ValidityType
}
Loading

0 comments on commit 53e7b95

Please sign in to comment.