Skip to content

Commit

Permalink
feat: add compact protobuf format
Browse files Browse the repository at this point in the history
  • Loading branch information
mkg20001 committed Jul 28, 2018
1 parent bd1dc9b commit be1c3e6
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 1 deletion.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"async": "^2.6.1",
"libp2p-crypto": "~0.13.0",
"lodash": "^4.17.10",
"multihashes": "~0.4.13"
"multihashes": "~0.4.13",
"protons": "^1.0.1"
},
"repository": {
"type": "git",
Expand Down
66 changes: 66 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const mh = require('multihashes')
const crypto = require('libp2p-crypto')
const assert = require('assert')
const waterfall = require('async/waterfall')
const {PeerIdProto} = require('./proto')

class PeerId {
constructor (id, privKey, pubKey) {
Expand Down Expand Up @@ -67,6 +68,15 @@ class PeerId {
}
}

// Return the protobuf version of the peer-id
marshal (excludePriv) {
return PeerIdProto.encode({
id: this.toBytes(),
pubKey: this.marshalPubKey(),
privKey: excludePriv ? null : this.marshalPrivKey()
})
}

toPrint () {
let pid = this.toB58String()
// All sha256 nodes start with Qm
Expand Down Expand Up @@ -231,6 +241,62 @@ exports.createFromPrivKey = function (key, callback) {
})
}

exports.createFromProtobuf = function (buf, callback) {
if (typeof callback !== 'function') {
throw new Error('callback is required')
}

let obj
let id
let rawPrivKey
let rawPubKey
let pub

try {
obj = PeerIdProto.decode(buf)
id = obj.id
rawPrivKey = obj.privKey
rawPubKey = obj.pubKey
pub = rawPubKey && crypto.keys.unmarshalPublicKey(rawPubKey)
} catch (err) {
return callback(err)
}

if (rawPrivKey) {
waterfall([
(cb) => crypto.keys.unmarshalPrivateKey(rawPrivKey, cb),
(priv, cb) => priv.public.hash((err, digest) => {
cb(err, digest, priv)
}),
(privDigest, priv, cb) => {
if (pub) {
pub.hash((err, pubDigest) => {
cb(err, privDigest, priv, pubDigest)
})
} else {
cb(null, privDigest, priv)
}
}
], (err, privDigest, priv, pubDigest) => {
if (err) {
return callback(err)
}

if (pub && !privDigest.equals(pubDigest)) {
return callback(new Error('Public and private key do not match'))
}

if (id && !privDigest.equals(id)) {
return callback(new Error('Id and private key do not match'))
}

callback(null, new PeerId(id, priv, pub))
})
} else {
callback(null, new PeerId(id, null, pub))
}
}

exports.createFromJSON = function (obj, callback) {
if (typeof callback !== 'function') {
throw new Error('callback is required')
Expand Down
12 changes: 12 additions & 0 deletions src/proto.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
'use strict'

const protons = require('protons')
module.exports = protons(`
message PeerIdProto {
required bytes id = 1;
bytes pubKey = 2;
bytes privKey = 3;
}
`)
49 changes: 49 additions & 0 deletions test/peer-id.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,55 @@ describe('PeerId', () => {
})
})

describe('fromProtobuf', () => {
it('full node', (done) => {
PeerId.create(testOpts, (err, id) => {
expect(err).to.not.exist()

PeerId.createFromProtobuf(id.marshal(), (err, other) => {
expect(err).to.not.exist()
expect(id.toB58String()).to.equal(other.toB58String())
expect(id.privKey.bytes).to.eql(other.privKey.bytes)
expect(id.pubKey.bytes).to.eql(other.pubKey.bytes)
done()
})
})
})

it('without privKey', (done) => {
PeerId.create(testOpts, (err, id) => {
expect(err).to.not.exist()

PeerId.createFromProtobuf(id.marshal(true), (err, other) => {
expect(err).to.not.exist()
expect(id.toB58String()).to.equal(other.toB58String())
expect(other.privKey).to.not.exist()
expect(id.pubKey.bytes).to.eql(other.pubKey.bytes)
done()
})
})
})

it('only id', (done) => {
crypto.keys.generateKeyPair('RSA', 1024, (err, key) => {
expect(err).to.not.exist()
key.public.hash((err, digest) => {
expect(err).to.not.exist()

const id = PeerId.createFromBytes(digest)
expect(id.privKey).to.not.exist()
expect(id.pubKey).to.not.exist()

PeerId.createFromProtobuf(id.marshal(), (err, other) => {
expect(err).to.not.exist()
expect(id.toB58String()).to.equal(other.toB58String())
done()
})
})
})
})
})

it('set privKey (valid)', (done) => {
PeerId.create(testOpts, (err, peerId) => {
expect(err).to.not.exist()
Expand Down

0 comments on commit be1c3e6

Please sign in to comment.