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

Async endeavour: Use promises #108

Merged
merged 43 commits into from
Nov 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
d7cbe8c
chore: upgrade deps
mkg20001 Jul 18, 2019
94e5119
feat: first iteration of the idea
mkg20001 Jul 18, 2019
0d7f1fa
feat: iterate a layer deeper
mkg20001 Jul 18, 2019
9c1a001
feat: rewrite handshake
mkg20001 Jul 18, 2019
cda8cb8
feat: rewrite propose
mkg20001 Jul 18, 2019
ac9b284
feat: rewrite finish
mkg20001 Jul 18, 2019
05b62f4
feat: rewrite exchange
mkg20001 Jul 18, 2019
022f1c8
feat: rewrite low-level stuff
mkg20001 Jul 18, 2019
2a52e87
feat: work on rewriting tests
mkg20001 Jul 18, 2019
40999a9
refactor: browser tests
mkg20001 Jul 18, 2019
4ca8858
refactor: .aegir.js
mkg20001 Jul 18, 2019
14ca273
feat: refactor benchmarks
mkg20001 Jul 18, 2019
59a08c5
fix: try to make it work
mkg20001 Jul 18, 2019
4cbcf38
fix: lint
mkg20001 Jul 18, 2019
61ac5c5
refactor: move tests
mkg20001 Oct 21, 2019
66a7ad6
refactor: switch deps
mkg20001 Oct 21, 2019
185f66f
refactor: entry file
mkg20001 Oct 21, 2019
3412264
refactor: a bit more
mkg20001 Oct 21, 2019
d947374
fix: tests
mkg20001 Oct 24, 2019
d13f142
feat: inital iterables refactor
mkg20001 Nov 7, 2019
80f9c71
refactor: streaming
mkg20001 Nov 7, 2019
e1bf46c
refactor: cleanup
mkg20001 Nov 7, 2019
e68a9a9
fix: turn bufferlist into buffer
mkg20001 Nov 7, 2019
d40e5d0
fix: use errors from interfaces
mkg20001 Nov 7, 2019
f838af1
refactor: etm
mkg20001 Nov 7, 2019
4da2808
fix: typo
mkg20001 Nov 7, 2019
51d29f2
fix: .read error
mkg20001 Nov 7, 2019
0b22ae1
fix: satisfy output expectations
mkg20001 Nov 7, 2019
afc8241
fix: it works - WARNING: using varint instead of fixed lp, tests lie
mkg20001 Nov 7, 2019
0790a3d
fix: use errors
mkg20001 Nov 7, 2019
5a2bb2a
refactor: benchmarks
mkg20001 Nov 7, 2019
0da751a
fix: add suggestions from review
mkg20001 Nov 12, 2019
f5ddc2f
fix: upgrade deps and use correct lp-encoder
mkg20001 Nov 13, 2019
7305d2b
refactor: apply changes from review
mkg20001 Nov 13, 2019
aea9a40
refactor: apply changes from review
mkg20001 Nov 13, 2019
55a7424
refactor: apply changes from review
mkg20001 Nov 13, 2019
ec435e6
chore: remove old tests
jacobheun Nov 19, 2019
8d418bf
test: fix async benchmarks
jacobheun Nov 20, 2019
72f05bf
chore: clean up deps
jacobheun Nov 21, 2019
840c217
fix: use fixed encoding/decoding everywhere
jacobheun Nov 21, 2019
41ca19b
test: add verify inbound and outbound secio
jacobheun Nov 21, 2019
22fe5e6
test: verify nonces are boxed
jacobheun Nov 21, 2019
f328ff8
chore: add node 12 to ci
jacobheun Nov 21, 2019
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
40 changes: 0 additions & 40 deletions .aegir.js

This file was deleted.

1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ stages:

node_js:
- '10'
- '12'

os:
- linux
Expand Down
39 changes: 2 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,44 +42,9 @@ const secio = require('libp2p-secio')

## API

### `.tag`
This module exposes a crypto interface, as defined in the [js-interfaces](https://github.com/libp2p/js-interfaces)

The current `secio` tag, usable in `multistream`.

### `const encryptedConnection = secio.encrypt(localPeerId, plainTextConnection [, remotePeerId] [, callback])`

- `localPeerId: PeerId` - A PeerId object containing the Private, Public and Id of our node.
- `plainTextConnection: Connection` - The insecure connection to be secured.
- `remotePeerId: PeerId` - A PeerId object containing the Public and/or Id of the node we are doing the SECIO handshake with.
- `callback: Function` - Optional, Called if an error happens during the initialization.

Returns an encrypted [Connection object](https://github.com/libp2p/interface-connection) that is the upgraded `plainTextConnection` with now having every byte encrypted.

Both plainTextConnection and encryptedConnection are at their base, PullStreams.

### This module uses `pull-streams`

We expose a streaming interface based on `pull-streams`, rather then on the Node.js core streams implementation (aka Node.js streams). `pull-streams` offers us a better mechanism for error handling and flow control guarantees. If you would like to know more about why we did this, see the discussion at this [issue](https://github.com/ipfs/js-ipfs/issues/362).

You can learn more about pull-streams at:

- [The history of Node.js streams, nodebp April 2014](https://www.youtube.com/watch?v=g5ewQEuXjsQ)
- [The history of streams, 2016](http://dominictarr.com/post/145135293917/history-of-streams)
- [pull-streams, the simple streaming primitive](http://dominictarr.com/post/149248845122/pull-streams-pull-streams-are-a-very-simple)
- [pull-streams documentation](https://pull-stream.github.io/)

#### Converting `pull-streams` to Node.js Streams

If you are a Node.js streams user, you can convert a pull-stream to a Node.js stream using the module [`pull-stream-to-stream`](https://github.com/pull-stream/pull-stream-to-stream), giving you an instance of a Node.js stream that is linked to the pull-stream. For example:

```js
const pullToStream = require('pull-stream-to-stream')

const nodeStreamInstance = pullToStream(pullStreamInstance)
// nodeStreamInstance is an instance of a Node.js Stream
```

To learn more about this utility, visit https://pull-stream.github.io/#pull-stream-to-stream.
[ » API Docs ](https://github.com/libp2p/js-interfaces/tree/master/src/crypto#api)

## Contribute

Expand Down
124 changes: 65 additions & 59 deletions benchmarks/send.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,70 @@
'use strict'

/* eslint-disable no-console */

const Benchmark = require('benchmark')
const pull = require('pull-stream/pull')
const infinite = require('pull-stream/sources/infinite')
const take = require('pull-stream/throughs/take')
const drain = require('pull-stream/sinks/drain')
const Connection = require('interface-connection').Connection
const parallel = require('async/parallel')
const pair = require('pull-pair/duplex')
const PeerId = require('peer-id')

const secio = require('../src')
const pipe = require('it-pipe')
const { reduce } = require('streaming-iterables')
const DuplexPair = require('it-pair/duplex')

const secio = require('..')

const suite = new Benchmark.Suite('secio')
let peers

function sendData (a, b, opts, finish) {
async function sendData (a, b, opts) {
opts = Object.assign({ times: 1, size: 100 }, opts)

pull(
infinite(() => Buffer.allocUnsafe(opts.size)),
take(opts.times),
let i = opts.times

pipe(
function * () {
while (i--) {
yield Buffer.allocUnsafe(opts.size)
}
},
a
)

let length = 0

pull(
const res = await pipe(
b,
drain((data) => {
length += data.length
}, () => {
if (length !== opts.times * opts.size) {
throw new Error('Did not receive enough chunks')
}
finish.resolve()
})
reduce((acc, val) => acc + val.length, 0)
)
}

function ifErr (err) {
if (err) {
throw err
if (res !== opts.times * opts.size) {
throw new Error('Did not receive enough chunks')
}
}

suite.add('create peers for test', (deferred) => {
parallel([
(cb) => PeerId.createFromJSON(require('./peer-a'), cb),
(cb) => PeerId.createFromJSON(require('./peer-b'), cb)
], (err, _peers) => {
if (err) { throw err }
peers = _peers

suite.add('create peers for test', {
defer: true,
fn: async (deferred) => {
peers = await Promise.all([
PeerId.createFromJSON(require('./peer-a')),
PeerId.createFromJSON(require('./peer-b'))
])
deferred.resolve()
})
}, { defer: true })

suite.add('establish an encrypted channel', (deferred) => {
const p = pair()
}
})
suite.add('establish an encrypted channel', {
defer: true,
fn: async (deferred) => {
const p = DuplexPair()

const peerA = peers[0]
const peerB = peers[1]
const peerA = peers[0]
const peerB = peers[1]

const aToB = secio.encrypt(peerA, new Connection(p[0]), peerB, ifErr)
const bToA = secio.encrypt(peerB, new Connection(p[1]), peerA, ifErr)
const [aToB, bToA] = await Promise.all([
secio.secureInbound(peerA, p[0], peerB),
secio.secureOutbound(peerB, p[1], peerA)
])

sendData(aToB, bToA, {}, deferred)
}, { defer: true })
await sendData(aToB.conn, bToA.conn, {})
deferred.resolve()
}
})

const cases = [
[10, 262144],
Expand All @@ -81,23 +78,32 @@ cases.forEach((el) => {
const times = el[0]
const size = el[1]

suite.add(`send plaintext ${times} x ${size} bytes`, (deferred) => {
const p = pair()
suite.add(`send plaintext ${times} x ${size} bytes`, {
defer: true,
fn: async (deferred) => {
const p = DuplexPair()
await sendData(p[0], p[1], { times: times, size: size })
deferred.resolve()
}
})

sendData(p[0], p[1], { times: times, size: size }, deferred)
}, { defer: true })
suite.add(`send encrypted ${times} x ${size} bytes`, {
defer: true,
fn: async (deferred) => {
const p = DuplexPair()

suite.add(`send encrypted ${times} x ${size} bytes`, (deferred) => {
const p = pair()
const peerA = peers[0]
const peerB = peers[1]

const peerA = peers[0]
const peerB = peers[1]
const [aToB, bToA] = await Promise.all([
secio.secureInbound(peerA, p[0], peerB),
secio.secureOutbound(peerB, p[1], peerA)
])

const aToB = secio.encrypt(peerA, new Connection(p[0]), peerB, ifErr)
const bToA = secio.encrypt(peerB, new Connection(p[1]), peerA, ifErr)

sendData(aToB, bToA, { times: times, size: size }, deferred)
}, { defer: true })
await sendData(aToB.conn, bToA.conn, { times: times, size: size })
deferred.resolve()
}
})
})

suite.on('cycle', (event) => {
Expand Down
33 changes: 14 additions & 19 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,26 @@
],
"license": "MIT",
"dependencies": {
"async": "^2.6.2",
"bl": "^4.0.0",
"debug": "^4.1.1",
"interface-connection": "~0.3.3",
"libp2p-crypto": "~0.16.1",
"multiaddr": "^6.0.6",
"multihashing-async": "~0.6.0",
"once": "^1.4.0",
"peer-id": "~0.12.2",
"peer-info": "~0.15.1",
"protons": "^1.0.1",
"pull-defer": "~0.2.3",
"pull-handshake": "^1.1.4",
"pull-length-prefixed": "^1.3.2",
"pull-stream": "^3.6.9",
"safe-buffer": "^5.1.2"
"it-buffer": "^0.1.1",
"it-length-prefixed": "^3.0.0",
"it-pair": "^1.0.0",
"it-pb-rpc": "^0.1.4",
"it-pipe": "^1.1.0",
"libp2p-crypto": "~0.17.1",
"libp2p-interfaces": "~0.1.3",
"multiaddr": "^7.2.1",
"multihashing-async": "~0.8.0",
"peer-id": "~0.13.5",
"protons": "^1.0.1"
},
"devDependencies": {
"aegir": "^18.2.2",
"aegir": "^20.4.1",
"benchmark": "^2.1.4",
"chai": "^4.2.0",
"dirty-chai": "^2.0.1",
"libp2p-websockets": "~0.12.2",
"multistream-select": "~0.14.4",
"pull-goodbye": "~0.0.2",
"pull-pair": "^1.1.0"
"streaming-iterables": "^4.1.1"
},
"engines": {
"node": ">=6.0.0",
Expand Down
Loading