Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit 45b705d

Browse files
wraithgaralanshaw
authored andcommitted
feat: implement bitswap.wantlist peerid and bitswap.unwant (#1349)
* feat(bitswap.unwant) expose bitswap.unwant to cli and http api * feat(tests) move some bitswap tests to interface Will require including the version of interface-ipfs-core that they are moved to * feat(tests) move some bitswap tests to interface Will require including the version of interface-ipfs-core that they are moved to * feat(bitswap.wantlist) add peer parameter * fix(test) fix cli tests for both bitswap.unwant and bitswap.wantlist peerId * fix: pick peer property from querystring, fix tests License: MIT Signed-off-by: Alan Shaw <alan@tableflip.io> * chore: update interface-ipfs-core dependency License: MIT Signed-off-by: Alan Shaw <alan@tableflip.io> * fix: don't add newline to cli block.get output * chore: increase timeout for bitswap cli test setup License: MIT Signed-off-by: Alan Shaw <alan@tableflip.io> * chore: update interface-ipfs-core dependency License: MIT Signed-off-by: Alan Shaw <alan@tableflip.io>
1 parent 2a5cc5e commit 45b705d

File tree

16 files changed

+213
-144
lines changed

16 files changed

+213
-144
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"expose-loader": "~0.7.5",
7474
"form-data": "^2.3.2",
7575
"hat": "0.0.3",
76-
"interface-ipfs-core": "~0.66.2",
76+
"interface-ipfs-core": "~0.68.2",
7777
"ipfsd-ctl": "~0.37.3",
7878
"lodash": "^4.17.10",
7979
"mocha": "^5.1.1",

src/cli/commands/bitswap/stat.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
'use strict'
22

3-
const CID = require('cids')
43
const print = require('../../utils').print
54

65
module.exports = {
@@ -17,11 +16,7 @@ module.exports = {
1716
}
1817

1918
stats.wantlist = stats.wantlist || []
20-
stats.wantlist = stats.wantlist.map((entry) => {
21-
const buf = Buffer.from(entry.cid.hash.data)
22-
const cid = new CID(entry.cid.version, entry.cid.codec, buf)
23-
return cid.toBaseEncodedString()
24-
})
19+
stats.wantlist = stats.wantlist.map(entry => entry['/'])
2520
stats.peers = stats.peers || []
2621

2722
print(`bitswap status

src/cli/commands/bitswap/unwant.js

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
'use strict'
22

3+
const print = require('../../utils').print
4+
35
module.exports = {
46
command: 'unwant <key>',
57

6-
describe: 'Remove a given block from your wantlist.',
8+
describe: 'Removes a given block from your wantlist.',
79

10+
builder: {
11+
key: {
12+
alias: 'k',
13+
describe: 'Key to remove from your wantlist',
14+
type: 'string'
15+
}
16+
},
817
handler (argv) {
9-
throw new Error('Not implemented yet')
18+
argv.ipfs.bitswap.unwant(argv.key, (err) => {
19+
if (err) {
20+
throw err
21+
}
22+
print(`Key ${argv.key} removed from wantlist`)
23+
})
1024
}
1125
}

src/cli/commands/bitswap/wantlist.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
const print = require('../../utils').print
44

55
module.exports = {
6-
command: 'wantlist',
6+
command: 'wantlist [peer]',
77

88
describe: 'Print out all blocks currently on the bitswap wantlist for the local peer.',
99

@@ -16,13 +16,12 @@ module.exports = {
1616
},
1717

1818
handler (argv) {
19-
// TODO: handle argv.peer
20-
argv.ipfs.bitswap.wantlist((err, res) => {
19+
argv.ipfs.bitswap.wantlist(argv.peer, (err, res) => {
2120
if (err) {
2221
throw err
2322
}
24-
res.Keys.forEach((cidStr) => {
25-
print(cidStr)
23+
res.Keys.forEach((cid) => {
24+
print(cid['/'])
2625
})
2726
})
2827
}

src/cli/commands/block/get.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
const CID = require('cids')
4+
const print = require('../../utils').print
45

56
module.exports = {
67
command: 'get <key>',
@@ -17,7 +18,11 @@ module.exports = {
1718
throw err
1819
}
1920

20-
process.stdout.write(block.data)
21+
if (block) {
22+
print(block.data, false)
23+
} else {
24+
print('Block was unwanted before it could be remotely retrieved')
25+
}
2126
})
2227
}
2328
}

src/core/components/bitswap.js

+40-10
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,42 @@ const OFFLINE_ERROR = require('../utils').OFFLINE_ERROR
44
const promisify = require('promisify-es6')
55
const setImmediate = require('async/setImmediate')
66
const Big = require('big.js')
7+
const CID = require('cids')
8+
const PeerId = require('peer-id')
79

810
function formatWantlist (list) {
9-
return Array.from(list).map((e) => e[1])
11+
return Array.from(list).map((e) => ({ '/': e[1].cid.toBaseEncodedString() }))
1012
}
1113

1214
module.exports = function bitswap (self) {
1315
return {
14-
wantlist: () => {
16+
wantlist: promisify((peerId, callback) => {
17+
if (!callback) {
18+
callback = peerId
19+
peerId = undefined
20+
}
21+
1522
if (!self.isOnline()) {
16-
throw new Error(OFFLINE_ERROR)
23+
return setImmediate(() => callback(new Error(OFFLINE_ERROR)))
1724
}
1825

19-
const list = self._bitswap.getWantlist()
20-
return formatWantlist(list)
21-
},
26+
let list
27+
if (peerId) {
28+
try {
29+
peerId = PeerId.createFromB58String(peerId)
30+
} catch (e) {
31+
peerId = null
32+
}
33+
if (!peerId) {
34+
return setImmediate(() => callback(new Error('Invalid peerId')))
35+
}
36+
list = self._bitswap.wantlistForPeer(peerId)
37+
} else {
38+
list = self._bitswap.getWantlist()
39+
}
40+
list = formatWantlist(list)
41+
return setImmediate(() => callback(null, { Keys: list }))
42+
}),
2243

2344
stat: promisify((callback) => {
2445
if (!self.isOnline()) {
@@ -40,12 +61,21 @@ module.exports = function bitswap (self) {
4061
})
4162
}),
4263

43-
unwant: (key) => {
64+
unwant: promisify((keys, callback) => {
4465
if (!self.isOnline()) {
45-
throw new Error(OFFLINE_ERROR)
66+
return setImmediate(() => callback(new Error(OFFLINE_ERROR)))
4667
}
4768

48-
// TODO: implement when https://github.com/ipfs/js-ipfs-bitswap/pull/10 is merged
49-
}
69+
if (!Array.isArray(keys)) {
70+
keys = [keys]
71+
}
72+
keys = keys.map((key) => {
73+
if (CID.isCID(key)) {
74+
return key
75+
}
76+
return new CID(key)
77+
})
78+
return setImmediate(() => callback(null, self._bitswap.unwant(keys)))
79+
})
5080
}
5181
}

src/http/api/resources/bitswap.js

+43-35
Original file line numberDiff line numberDiff line change
@@ -6,50 +6,58 @@ const parseKey = require('./block').parseKey
66

77
exports = module.exports
88

9-
exports.wantlist = (request, reply) => {
10-
let list
11-
try {
12-
list = request.server.app.ipfs.bitswap.wantlist()
13-
list = list.map((entry) => entry.cid.toBaseEncodedString())
14-
} catch (err) {
15-
return reply(boom.badRequest(err))
9+
exports.wantlist = {
10+
handler: (request, reply) => {
11+
const peerId = request.query.peer
12+
request.server.app.ipfs.bitswap.wantlist(peerId, (err, list) => {
13+
if (err) {
14+
return reply(boom.badRequest(err))
15+
}
16+
reply(list)
17+
})
1618
}
17-
18-
reply({
19-
Keys: list
20-
})
2119
}
2220

23-
exports.stat = (request, reply) => {
24-
const ipfs = request.server.app.ipfs
25-
26-
ipfs.bitswap.stat((err, stats) => {
27-
if (err) {
28-
return reply({
29-
Message: err.toString(),
30-
Code: 0
31-
}).code(500)
32-
}
33-
34-
reply({
35-
ProvideBufLen: stats.provideBufLen,
36-
BlocksReceived: stats.blocksReceived,
37-
Wantlist: stats.wantlist,
38-
Peers: stats.peers,
39-
DupBlksReceived: stats.dupBlksReceived,
40-
DupDataReceived: stats.dupDataReceived,
41-
DataReceived: stats.dataReceived,
42-
BlocksSent: stats.blocksSent,
43-
DataSent: stats.dataSent
21+
exports.stat = {
22+
handler: (request, reply) => {
23+
const ipfs = request.server.app.ipfs
24+
25+
ipfs.bitswap.stat((err, stats) => {
26+
if (err) {
27+
return reply({
28+
Message: err.toString(),
29+
Code: 0
30+
}).code(500)
31+
}
32+
33+
reply({
34+
ProvideBufLen: stats.provideBufLen,
35+
BlocksReceived: stats.blocksReceived,
36+
Wantlist: stats.wantlist,
37+
Peers: stats.peers,
38+
DupBlksReceived: stats.dupBlksReceived,
39+
DupDataReceived: stats.dupDataReceived,
40+
DataReceived: stats.dataReceived,
41+
BlocksSent: stats.blocksSent,
42+
DataSent: stats.dataSent
43+
})
4444
})
45-
})
45+
}
4646
}
4747

4848
exports.unwant = {
49-
// uses common parseKey method that returns a `key`
49+
// uses common parseKey method that assigns a `key` to request.pre.args
5050
parseArgs: parseKey,
5151

52+
// main route handler which is called after the above `parseArgs`, but only if the args were valid
5253
handler: (request, reply) => {
53-
reply(boom.badRequest(new Error('Not implemented yet')))
54+
const key = request.pre.args.key
55+
const ipfs = request.server.app.ipfs
56+
ipfs.bitswap.unwant(key, (err) => {
57+
if (err) {
58+
return reply(boom.badRequest(err))
59+
}
60+
reply({ key: key.toBaseEncodedString() })
61+
})
5462
}
5563
}

src/http/api/resources/block.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,13 @@ exports.get = {
4848
}).code(500)
4949
}
5050

51-
return reply(block.data)
51+
if (block) {
52+
return reply(block.data)
53+
}
54+
return reply({
55+
Message: 'Block was unwanted before it could be remotely retrieved',
56+
Code: 0
57+
}).code(404)
5258
})
5359
}
5460
}

src/http/api/routes/bitswap.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ module.exports = (server) => {
99
method: '*',
1010
path: '/api/v0/bitswap/wantlist',
1111
config: {
12-
handler: resources.bitswap.wantlist
12+
handler: resources.bitswap.wantlist.handler
1313
}
1414
})
1515

1616
api.route({
1717
method: '*',
1818
path: '/api/v0/bitswap/stat',
1919
config: {
20-
handler: resources.bitswap.stat
20+
handler: resources.bitswap.stat.handler
2121
}
2222
})
2323

src/http/api/routes/stats.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module.exports = (server) => {
99
method: '*',
1010
path: '/api/v0/stats/bitswap',
1111
config: {
12-
handler: resources.stats.bitswap
12+
handler: resources.stats.bitswap.handler
1313
}
1414
})
1515

test/cli/bitswap.js

+23-4
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,24 @@
33

44
const expect = require('chai').expect
55
const runOn = require('../utils/on-and-off').on
6+
const PeerId = require('peer-id')
67

78
describe('bitswap', () => runOn((thing) => {
89
let ipfs
10+
let peerId
911
const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR'
1012

11-
before((done) => {
13+
before(function (done) {
14+
this.timeout(60 * 1000)
1215
ipfs = thing.ipfs
1316
ipfs('block get ' + key)
1417
.then(() => {})
1518
.catch(() => {})
16-
setTimeout(done, 800)
19+
PeerId.create((err, peer) => {
20+
expect(err).to.not.exist()
21+
peerId = peer.toB58String()
22+
done()
23+
})
1724
})
1825

1926
it('wantlist', function () {
@@ -23,8 +30,14 @@ describe('bitswap', () => runOn((thing) => {
2330
})
2431
})
2532

26-
// TODO @hacdias fix this with https://github.com/ipfs/js-ipfs/pull/1198
27-
it.skip('stat', function () {
33+
it('wantlist peerid', function () {
34+
this.timeout(20 * 1000)
35+
return ipfs('bitswap wantlist ' + peerId).then((out) => {
36+
expect(out).to.eql('')
37+
})
38+
})
39+
40+
it('stat', function () {
2841
this.timeout(20 * 1000)
2942

3043
return ipfs('bitswap stat').then((out) => {
@@ -40,4 +53,10 @@ describe('bitswap', () => runOn((thing) => {
4053
].join('\n') + '\n')
4154
})
4255
})
56+
57+
it('unwant', function () {
58+
return ipfs('bitswap unwant ' + key).then((out) => {
59+
expect(out).to.eql(`Key ${key} removed from wantlist\n`)
60+
})
61+
})
4362
}))

0 commit comments

Comments
 (0)