Skip to content
This repository was archived by the owner on Apr 29, 2020. It is now read-only.

Commit 822ed46

Browse files
committed
level up libp2p functionality
1 parent e24218d commit 822ed46

File tree

7 files changed

+640
-106
lines changed

7 files changed

+640
-106
lines changed

package.json

+9-6
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,19 @@
3333
"homepage": "https://github.com/ipfs/js-libp2p-ipfs#readme",
3434
"devDependencies": {
3535
"aegir": "^3.1.0",
36+
"bl": "^1.1.2",
3637
"chai": "^3.5.0",
37-
"pre-commit": "^1.1.3"
38+
"pre-commit": "^1.1.3",
39+
"run-parallel": "^1.1.6"
3840
},
3941
"dependencies": {
4042
"libp2p-spdy": "^0.6.1",
41-
"libp2p-swarm": "^0.19.0",
42-
"libp2p-tcp": "^0.6.0",
43-
"libp2p-websockets": "^0.6.0",
44-
"mafmt": "^2.1.0",
43+
"libp2p-swarm": "^0.19.4",
44+
"libp2p-tcp": "^0.6.1",
45+
"libp2p-websockets": "^0.6.1",
46+
"mafmt": "^2.1.1",
4547
"multiaddr": "^2.0.2",
48+
"peer-book": "^0.3.0",
4649
"peer-id": "^0.7.0",
4750
"peer-info": "^0.7.0",
4851
"run-parallel": "^1.1.6"
@@ -62,4 +65,4 @@
6265
"Stephen Whitmore <[email protected]>",
6366
"dignifiedquire <[email protected]>"
6467
]
65-
}
68+
}

src/index.js

+173-15
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,199 @@
11
'use strict'
22

33
const Swarm = require('libp2p-swarm')
4-
const Peer = require('peer-info')
4+
const PeerId = require('peer-id')
5+
const PeerInfo = require('peer-info')
6+
const PeerBook = require('peer-book')
57
const TCP = require('libp2p-tcp')
68
// const UTP = require('libp2p-utp')
79
const WS = require('libp2p-websockets')
810
const spdy = require('libp2p-spdy')
911
const multiaddr = require('multiaddr')
12+
const mafmt = require('mafmt')
1013
const EE = require('events').EventEmitter
1114

1215
exports = module.exports
1316

14-
exports.Node = function Node (peerInfo) {
17+
const OFFLINE_ERROR_MESSAGE = 'The libp2p node is not started yet'
18+
const IPFS_CODE = 421
19+
20+
exports.Node = function Node (pInfo, pBook) {
1521
if (!(this instanceof Node)) {
16-
return new Node(peerInfo)
22+
return new Node(pInfo, pBook)
23+
}
24+
25+
if (!pInfo) {
26+
pInfo = new PeerInfo()
27+
pInfo.multiaddr.add(multiaddr('/ip4/0.0.0.0/tcp/0'))
1728
}
18-
if (!peerInfo) {
19-
peerInfo = new Peer()
20-
peerInfo.multiaddr.add(multiaddr('/ip4/0.0.0.0/tcp/0'))
29+
30+
if (!pBook) {
31+
pBook = new PeerBook()
2132
}
2233

34+
this.peerInfo = pInfo
35+
this.peerBook = pBook
36+
2337
// Swarm
24-
this.swarm = new Swarm(peerInfo)
25-
this.swarm.transport.add('ws', new WS())
26-
this.swarm.transport.add('tcp', new TCP())
38+
this.swarm = new Swarm(pInfo)
2739
this.swarm.connection.addStreamMuxer(spdy)
2840
this.swarm.connection.reuse()
2941

30-
this.start = (done) => {
31-
this.swarm.listen(done)
42+
this.swarm.on('peer-mux-established', (peerInfo) => {
43+
this.peerBook.put(peerInfo)
44+
})
45+
46+
this.swarm.on('peer-mux-closed', (peerInfo) => {
47+
this.peerBook.removeByB58String(peerInfo.id.toB58String())
48+
})
49+
50+
let isOnline = false
51+
52+
this.start = (callback) => {
53+
const ws = new WS()
54+
const tcp = new TCP()
55+
56+
// Do not activate the dialer if no listener is going to be present
57+
if (ws.filter(this.peerInfo.multiaddrs).length > 0) {
58+
this.swarm.transport.add('ws', new WS())
59+
}
60+
if (tcp.filter(this.peerInfo.multiaddrs).length > 0) {
61+
this.swarm.transport.add('tcp', new TCP())
62+
}
63+
64+
this.swarm.listen((err) => {
65+
if (err) {
66+
return callback(err)
67+
}
68+
isOnline = true
69+
callback()
70+
})
71+
}
72+
73+
this.stop = (callback) => {
74+
isOnline = false
75+
this.swarm.close(callback)
76+
}
77+
78+
this.dialById = (id, protocol, callback) => {
79+
if (typeof protocol === 'function') {
80+
callback = protocol
81+
protocol = undefined
82+
}
83+
84+
if (!isOnline) {
85+
return callback(new Error(OFFLINE_ERROR_MESSAGE))
86+
}
87+
// NOTE, these dialById only works if a previous dial
88+
// was made until we have PeerRouting
89+
// TODO support PeerRouting when it is Ready
90+
callback(new Error('not implemented yet'))
91+
}
92+
93+
this.dialByMultiaddr = (maddr, protocol, callback) => {
94+
if (typeof protocol === 'function') {
95+
callback = protocol
96+
protocol = undefined
97+
}
98+
99+
if (!isOnline) {
100+
return callback(new Error(OFFLINE_ERROR_MESSAGE))
101+
}
102+
103+
if (typeof maddr === 'string') {
104+
maddr = multiaddr(maddr)
105+
}
106+
107+
if (!mafmt.IPFS.matches(maddr.toString())) {
108+
return callback(new Error('multiaddr not valid'))
109+
}
110+
111+
const ipfsIdB58String = maddr.stringTuples().filter((tuple) => {
112+
if (tuple[0] === IPFS_CODE) {
113+
return true
114+
}
115+
})[0][1]
116+
117+
let peer
118+
try {
119+
peer = this.peerBook.getByB58String(ipfsIdB58String)
120+
} catch (err) {
121+
peer = new PeerInfo(PeerId.createFromB58String(ipfsIdB58String))
122+
}
123+
124+
peer.multiaddr.add(maddr)
125+
this.dialByPeerInfo(peer, protocol, callback)
126+
}
127+
128+
this.dialByPeerInfo = (peer, protocol, callback) => {
129+
if (typeof protocol === 'function') {
130+
callback = protocol
131+
protocol = undefined
132+
}
133+
if (!isOnline) {
134+
return callback(new Error(OFFLINE_ERROR_MESSAGE))
135+
}
136+
137+
this.swarm.dial(peer, protocol, (err, conn) => {
138+
if (err) {
139+
return callback(err)
140+
}
141+
this.peerBook.put(peer)
142+
callback(null, conn)
143+
})
144+
}
145+
146+
this.hangUpById = (id, callback) => {
147+
callback(new Error('not implemented yet'))
148+
// TODO
149+
}
150+
151+
this.hangUpByMultiaddr = (maddr, callback) => {
152+
if (!isOnline) {
153+
return callback(new Error(OFFLINE_ERROR_MESSAGE))
154+
}
155+
156+
if (typeof maddr === 'string') {
157+
maddr = multiaddr(maddr)
158+
}
159+
160+
if (!mafmt.IPFS.matches(maddr.toString())) {
161+
return callback(new Error('multiaddr not valid'))
162+
}
163+
164+
const ipfsIdB58String = maddr.stringTuples().filter((tuple) => {
165+
if (tuple[0] === IPFS_CODE) {
166+
return true
167+
}
168+
})[0][1]
169+
170+
try {
171+
const pi = this.peerBook.getByB58String(ipfsIdB58String)
172+
this.hangUpByPeerInfo(pi, callback)
173+
} catch (err) {
174+
// already disconnected
175+
callback()
176+
}
177+
}
178+
179+
this.hangUpByPeerInfo = (peer, callback) => {
180+
if (!isOnline) {
181+
return callback(new Error(OFFLINE_ERROR_MESSAGE))
182+
}
183+
184+
this.peerBook.removeByB58String(peer.id.toB58String())
185+
this.swarm.hangUp(peer, callback)
186+
}
187+
188+
this.handle = (protocol, handler) => {
189+
return this.swarm.handle(protocol, handler)
190+
}
191+
192+
this.unhandle = (protocol) => {
193+
return this.swarm.unhandle(protocol)
32194
}
33195

34196
this.discovery = new EE()
35197
this.routing = null
36198
this.records = null
37-
38-
this.dial = () => {
39-
throw new Error('THIS WILL BE EQUIVALENT TO THE ROUTED HOST FEATURE, IT WILL FIGURE OUT EVERYTHING :D')
40-
}
41199
}

test/index.spec.js

-85
This file was deleted.

0 commit comments

Comments
 (0)