refactor: examples/encrypted-communications (#499)

* refactor: examples/encrypted-communications

* chore: address review
This commit is contained in:
Vasco Santos 2019-12-18 02:35:49 +00:00 committed by Jacob Heun
parent b08d81cee7
commit 835a689965
2 changed files with 53 additions and 67 deletions

View File

@ -1,63 +1,52 @@
'use strict' 'use strict'
const libp2p = require('../../') const Libp2p = require('../../')
const TCP = require('libp2p-tcp') const TCP = require('libp2p-tcp')
const SPDY = require('libp2p-spdy') const Mplex = require('libp2p-mplex')
const SECIO = require('libp2p-secio') const SECIO = require('libp2p-secio')
const PeerInfo = require('peer-info') const PeerInfo = require('peer-info')
const waterfall = require('async/waterfall')
const parallel = require('async/parallel')
const pull = require('pull-stream')
const defaultsDeep = require('@nodeutils/defaults-deep')
class MyBundle extends libp2p { const pipe = require('it-pipe')
constructor (_options) {
const defaults = { const createNode = async () => {
modules: { const peerInfo = await PeerInfo.create()
transport: [ TCP ], peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
streamMuxer: [ SPDY ],
connEncryption: [ SECIO ] const node = await Libp2p.create({
peerInfo,
modules: {
transport: [TCP],
streamMuxer: [Mplex],
connEncryption: [SECIO]
}
})
await node.start()
return node
}
;(async () => {
const [node1, node2] = await Promise.all([
createNode(),
createNode()
])
node2.handle('/a-protocol', ({ stream }) => {
pipe(
stream,
async function (source) {
for await (const msg of source) {
console.log(msg.toString())
}
} }
}
super(defaultsDeep(_options, defaults))
}
}
function createNode (callback) {
let node
waterfall([
(cb) => PeerInfo.create(cb),
(peerInfo, cb) => {
peerInfo.multiaddrs.add('/ip4/0.0.0.0/tcp/0')
node = new MyBundle({
peerInfo
})
node.start(cb)
}
], (err) => callback(err, node))
}
parallel([
(cb) => createNode(cb),
(cb) => createNode(cb)
], (err, nodes) => {
if (err) { throw err }
const node1 = nodes[0]
const node2 = nodes[1]
node2.handle('/a-protocol', (protocol, conn) => {
pull(
conn,
pull.map((v) => v.toString()),
pull.log()
) )
}) })
node1.dialProtocol(node2.peerInfo, '/a-protocol', (err, conn) => { const { stream } = await node1.dialProtocol(node2.peerInfo, '/a-protocol')
if (err) { throw err }
pull(pull.values(['This information is sent out encrypted to the other peer']), conn) await pipe(
}) ['This information is sent out encrypted to the other peer'],
}) stream
)
})();

View File

@ -4,7 +4,7 @@ libp2p can leverage the encrypted communications from the transports it uses (i.
We call this usage a _connection upgrade_ where given a connection between peer A to peer B, a protocol handshake can be performed that gives that connection new properties. We call this usage a _connection upgrade_ where given a connection between peer A to peer B, a protocol handshake can be performed that gives that connection new properties.
A byproduct of having these encrypted communications modules is that we can authenticate the peers we are dialing to. You might have noticed that every time we dial to a peer in libp2p space, we always use its PeerId at the end (e.g /ip4/127.0.0.1/tcp/89765/ipfs/QmWCbVw1XZ8hiYBwwshPce2yaTDYTqTaP7GCHGpry3ykWb), this PeerId is generated by hashing the Public Key of the peer. With this, we can create a crypto challenge when dialing to another peer and prove that peer is the owner of a PrivateKey that matches the Public Key we know. A byproduct of having these encrypted communications modules is that we can authenticate the peers we are dialing to. You might have noticed that every time we dial to a peer in libp2p space, we always use its PeerId at the end (e.g /ip4/127.0.0.1/tcp/89765/p2p/QmWCbVw1XZ8hiYBwwshPce2yaTDYTqTaP7GCHGpry3ykWb), this PeerId is generated by hashing the Public Key of the peer. With this, we can create a crypto challenge when dialing to another peer and prove that peer is the owner of a PrivateKey that matches the Public Key we know.
# 1. Set up encrypted communications with SECIO # 1. Set up encrypted communications with SECIO
@ -12,24 +12,21 @@ We will build this example on top of example for [Protocol and Stream Multiplexi
SECIO is the crypto channel developed for IPFS, it is a TLS 1.3 like crypto channel that established an encrypted communication channel between two peers. SECIO is the crypto channel developed for IPFS, it is a TLS 1.3 like crypto channel that established an encrypted communication channel between two peers.
To add it to your libp2p bundle, all you have to do is: To add it to your libp2p configuration, all you have to do is:
```JavaScript ```JavaScript
const Libp2p = require('libp2p')
const SECIO = require('libp2p-secio') const SECIO = require('libp2p-secio')
class MyBundle extends libp2p { const createNode = () => {
constructor (peerInfo) { return Libp2p.create({
const defaults = { modules: {
modules: { transport: [ TCP ],
transport: [ TCP ], streamMuxer: [ Mplex ],
streamMuxer: [ SPDY ], // Attach secio as the crypto channel to use
// Attach secio as the crypto channel to use connEncryption: [ SECIO ]
connEncryption: [ SECIO ]
}
} }
})
super(defaultsDeep(_options, defaults))
}
} }
``` ```