Skip to content

Commit 4f75868

Browse files
vasco-santosjacobheun
authored andcommitted
refactor: ping (#505)
* refactor: ping * chore: ping is now a function * chore: address review
1 parent 71f46bf commit 4f75868

File tree

10 files changed

+142
-174
lines changed

10 files changed

+142
-174
lines changed

doc/API.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* [`hangUp`](#hangUp)
1111
* [`handle`](#handle)
1212
* [`unhandle`](#unhandle)
13+
* [`ping`](#ping)
1314
* [`peerRouting.findPeer`](#peerRouting.findPeer)
1415
* [`contentRouting.findProviders`](#contentRouting.findProviders)
1516
* [`contentRouting.provide`](#contentRouting.provide)
@@ -307,6 +308,31 @@ Unregisters all handlers with the given protocols
307308
libp2p.unhandle(['/echo/1.0.0'])
308309
```
309310

311+
### ping
312+
313+
Pings a given peer and get the operation's latency.
314+
315+
`libp2p.ping(peer)`
316+
317+
#### Parameters
318+
319+
| Name | Type | Description |
320+
|------|------|-------------|
321+
| peer | `PeerInfo|PeerId|Multiaddr|string` | peer to ping |
322+
323+
#### Returns
324+
325+
| Type | Description |
326+
|------|-------------|
327+
| `Promise<number>` | Latency of the operation in ms |
328+
329+
#### Example
330+
331+
```js
332+
// ...
333+
const latency = await libp2p.ping(otherPeerId)
334+
```
335+
310336
### peerRouting.findPeer
311337

312338
Iterates over all peer routers in series to find the given peer. If the DHT is enabled, it will be tried first.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"err-code": "^1.1.2",
5151
"hashlru": "^2.3.0",
5252
"it-all": "^1.0.1",
53+
"it-buffer": "^0.1.1",
5354
"it-handshake": "^1.0.1",
5455
"it-length-prefixed": "^3.0.0",
5556
"it-pipe": "^1.1.0",

src/identify/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const { collect, take } = require('streaming-iterables')
99
const PeerInfo = require('peer-info')
1010
const PeerId = require('peer-id')
1111
const multiaddr = require('multiaddr')
12-
const { toBuffer } = require('../util')
12+
const { toBuffer } = require('it-buffer')
1313

1414
const Message = require('./message')
1515

src/index.js

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const TransportManager = require('./transport-manager')
2121
const Upgrader = require('./upgrader')
2222
const PeerStore = require('./peer-store')
2323
const Registrar = require('./registrar')
24+
const ping = require('./ping')
2425
const {
2526
IdentifyService,
2627
multicodecs: IDENTIFY_PROTOCOLS
@@ -148,6 +149,9 @@ class Libp2p extends EventEmitter {
148149
this.peerRouting = peerRouting(this)
149150
this.contentRouting = contentRouting(this)
150151

152+
// Mount default protocols
153+
ping.mount(this)
154+
151155
this._onDiscoveryPeer = this._onDiscoveryPeer.bind(this)
152156
}
153157

@@ -203,6 +207,8 @@ class Libp2p extends EventEmitter {
203207

204208
await this.transportManager.close()
205209
await this.registrar.close()
210+
211+
ping.unmount(this)
206212
} catch (err) {
207213
if (err) {
208214
log.error(err)
@@ -280,17 +286,16 @@ class Libp2p extends EventEmitter {
280286
)
281287
}
282288

283-
// TODO: Update ping
284-
// /**
285-
// * Pings the provided peer
286-
// *
287-
// * @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to ping
288-
// * @returns {Promise<Ping>}
289-
// */
290-
// ping (peer) {
291-
// const peerInfo = await getPeerInfoRemote(peer, this)
292-
// return new Ping(this._switch, peerInfo)
293-
// }
289+
/**
290+
* Pings the given peer
291+
* @param {PeerInfo|PeerId|Multiaddr|string} peer The peer to ping
292+
* @returns {Promise<number>}
293+
*/
294+
async ping (peer) {
295+
const peerInfo = await getPeerInfo(peer, this.peerStore)
296+
297+
return ping(this, peerInfo)
298+
}
294299

295300
/**
296301
* Registers the `handler` for each protocol

src/ping/README.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,11 @@ libp2p-ping JavaScript Implementation
88
## Usage
99

1010
```javascript
11-
var Ping = require('libp2p-ping')
11+
var Ping = require('libp2p/src/ping')
1212

13-
Ping.mount(swarm) // Enable this peer to echo Ping requests
13+
Ping.mount(libp2p) // Enable this peer to echo Ping requests
1414

15-
var p = new Ping(swarm, peerDst) // Ping peerDst, peerDst must be a peer-info object
15+
const latency = await Ping(libp2p, peerDst)
1616

17-
p.on('ping', function (time) {
18-
console.log(time + 'ms')
19-
p.stop() // stop sending pings
20-
})
21-
22-
p.start()
17+
Ping.unmount(libp2p)
2318
```

src/ping/handler.js

Lines changed: 0 additions & 50 deletions
This file was deleted.

src/ping/index.js

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,62 @@
11
'use strict'
22

3-
const handler = require('./handler')
3+
const debug = require('debug')
4+
const log = debug('libp2p-ping')
5+
log.error = debug('libp2p-ping:error')
6+
const errCode = require('err-code')
47

5-
exports = module.exports = require('./ping')
6-
exports.mount = handler.mount
7-
exports.unmount = handler.unmount
8+
const crypto = require('libp2p-crypto')
9+
const pipe = require('it-pipe')
10+
const { toBuffer } = require('it-buffer')
11+
const { collect } = require('streaming-iterables')
12+
13+
const { PROTOCOL, PING_LENGTH } = require('./constants')
14+
15+
/**
16+
* Ping a given peer and wait for its response, getting the operation latency.
17+
* @param {Libp2p} node
18+
* @param {PeerInfo} peer
19+
* @returns {Promise<Number>}
20+
*/
21+
async function ping (node, peer) {
22+
log('dialing %s to %s', PROTOCOL, peer.id.toB58String())
23+
24+
const { stream } = await node.dialProtocol(peer, PROTOCOL)
25+
26+
const start = new Date()
27+
const data = crypto.randomBytes(PING_LENGTH)
28+
29+
const [result] = await pipe(
30+
[data],
31+
stream,
32+
toBuffer,
33+
collect
34+
)
35+
const end = Date.now()
36+
37+
if (!data.equals(result)) {
38+
throw errCode(new Error('Received wrong ping ack'), 'ERR_WRONG_PING_ACK')
39+
}
40+
41+
return end - start
42+
}
43+
44+
/**
45+
* Subscribe ping protocol handler.
46+
* @param {Libp2p} node
47+
*/
48+
function mount (node) {
49+
node.handle(PROTOCOL, ({ stream }) => pipe(stream, stream))
50+
}
51+
52+
/**
53+
* Unsubscribe ping protocol handler.
54+
* @param {Libp2p} node
55+
*/
56+
function unmount (node) {
57+
node.unhandle(PROTOCOL)
58+
}
59+
60+
exports = module.exports = ping
61+
exports.mount = mount
62+
exports.unmount = unmount

src/ping/ping.js

Lines changed: 0 additions & 83 deletions
This file was deleted.

src/util/index.js

Lines changed: 0 additions & 16 deletions
This file was deleted.

test/core/ping.node.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict'
2+
/* eslint-env mocha */
3+
4+
const chai = require('chai')
5+
chai.use(require('dirty-chai'))
6+
const { expect } = chai
7+
8+
const pTimes = require('p-times')
9+
10+
const peerUtils = require('../utils/creators/peer')
11+
const baseOptions = require('../utils/base-options')
12+
13+
describe('ping', () => {
14+
let nodes
15+
16+
beforeEach(async () => {
17+
nodes = await peerUtils.createPeer({
18+
number: 2,
19+
config: baseOptions
20+
})
21+
})
22+
23+
it('ping once from peer0 to peer1', async () => {
24+
const latency = await nodes[0].ping(nodes[1].peerInfo)
25+
26+
expect(latency).to.be.a('Number')
27+
})
28+
29+
it('ping several times for getting an average', async () => {
30+
const latencies = await pTimes(5, () => nodes[1].ping(nodes[0].peerInfo))
31+
32+
const averageLatency = latencies.reduce((p, c) => p + c, 0) / latencies.length
33+
expect(averageLatency).to.be.a('Number')
34+
})
35+
})

0 commit comments

Comments
 (0)