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

Commit c539741

Browse files
Merge pull request #195 from ipfs/feat/bitswap
Bitswap Quest
2 parents 4548864 + ea70e0b commit c539741

39 files changed

+832
-129
lines changed

.travis.yml

+11-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,21 @@ script:
1414
- npm test
1515
- npm run coverage
1616

17-
addons:
18-
firefox: 'latest'
1917

2018
before_script:
2119
- export DISPLAY=:99.0
2220
- sh -e /etc/init.d/xvfb start
2321

2422
after_success:
2523
- npm run coverage-publish
24+
25+
env:
26+
- CXX=g++-4.8
27+
28+
addons:
29+
firefox: 'latest'
30+
apt:
31+
sources:
32+
- ubuntu-toolchain-r-test
33+
packages:
34+
- g++-4.8

gulpfile.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict'
2+
3+
const gulp = require('gulp')
4+
const parallel = require('run-parallel')
5+
const series = require('run-series')
6+
const createTempNode = require('./test/utils/temp-node')
7+
const API = require('./src/http-api')
8+
9+
let nodes = []
10+
11+
function startNode (num, done) {
12+
createTempNode(num, (err, node) => {
13+
if (err) throw err
14+
15+
const api = new API(node.repo.path())
16+
nodes.push(api)
17+
api.start(done)
18+
})
19+
}
20+
21+
gulp.task('libnode:start', (done) => {
22+
nodes = []
23+
parallel([
24+
(cb) => startNode(7, cb),
25+
(cb) => startNode(8, cb),
26+
(cb) => startNode(9, cb)
27+
], done)
28+
})
29+
30+
gulp.task('libnode:stop', (done) => {
31+
series(nodes.map((node) => (cb) => {
32+
setTimeout(() => node.stop(cb), 500)
33+
}), done)
34+
})
35+
36+
gulp.task('test:browser:before', ['libnode:start'])
37+
gulp.task('test:node:before', ['libnode:start'])
38+
gulp.task('test:browser:after', ['libnode:stop'])
39+
gulp.task('test:node:after', ['libnode:stop'])
40+
41+
require('aegir/gulp')(gulp)

package.json

+19-14
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
"jsnext:main": "src/core/index.js",
1010
"scripts": {
1111
"lint": "aegir-lint",
12-
"coverage": "aegir-coverage",
13-
"test": "aegir-test",
14-
"test:node": "aegir-test node",
15-
"test:browser": "aegir-test browser",
16-
"build": "aegir-build",
17-
"release": "aegir-release",
18-
"release:minor": "aegir-release --type minor",
19-
"release:major": "aegir-release --type major",
12+
"coverage": "gulp coverage",
13+
"test": "gulp test",
14+
"test:node": "gulp test:node",
15+
"test:browser": "gulp test:browser",
16+
"build": "gulp build",
17+
"release": "gulp release",
18+
"release:minor": "gulp release --type minor",
19+
"release:major": "gulp release --type major",
2020
"coverage-publish": "aegir-coverage publish"
2121
},
2222
"pre-commit": [
@@ -38,12 +38,13 @@
3838
"homepage": "https://github.com/ipfs/js-ipfs#readme",
3939
"devDependencies": {
4040
"aegir": "^3.0.1",
41-
"async": "^2.0.0-rc.4",
4241
"buffer-loader": "0.0.1",
4342
"chai": "^3.5.0",
4443
"expose-loader": "^0.7.1",
4544
"form-data": "^1.0.0-rc3",
45+
"gulp": "^3.9.1",
4646
"idb-plus-blob-store": "^1.1.2",
47+
"libp2p-ipfs-browser": "^0.2.0",
4748
"lodash": "^4.11.2",
4849
"mocha": "^2.4.5",
4950
"ncp": "^2.0.0",
@@ -63,6 +64,7 @@
6364
"glob": "^7.0.3",
6465
"hapi": "^13.3.0",
6566
"ipfs-api": "^3.0.2",
67+
"ipfs-bitswap": "^0.2.0",
6668
"ipfs-block": "^0.3.0",
6769
"ipfs-block-service": "^0.4.0",
6870
"ipfs-merkle-dag": "^0.5.1",
@@ -71,29 +73,32 @@
7173
"ipfs-unixfs-engine": "^0.6.1",
7274
"joi": "^8.0.5",
7375
"libp2p-ipfs": "^0.3.3",
74-
"libp2p-swarm": "^0.12.5",
76+
"libp2p-swarm": "^0.12.11",
7577
"lodash.get": "^4.2.1",
7678
"lodash.set": "^4.1.0",
7779
"multiaddr": "^1.4.1",
7880
"path-exists": "^3.0.0",
79-
"peer-book": "0.1.0",
81+
"peer-book": "^0.1.1",
8082
"peer-id": "^0.6.6",
8183
"peer-info": "^0.6.2",
8284
"readable-stream": "1.1.13",
8385
"ronin": "^0.3.11",
86+
"run-parallel": "^1.1.6",
87+
"run-parallel-limit": "^1.0.3",
88+
"run-series": "^1.1.4",
89+
"run-waterfall": "^1.1.3",
8490
"temp": "^0.8.3"
8591
},
8692
"aegir": {
8793
"webpack": {
8894
"resolve": {
8995
"alias": {
90-
"node-forge": "../../../node_modules/peer-id/vendor/forge.bundle.js"
96+
"node-forge": "../../../node_modules/peer-id/vendor/forge.bundle.js",
97+
"libp2p-ipfs": "libp2p-ipfs-browser"
9198
}
9299
},
93100
"externals": {
94101
"fs": "{}",
95-
"ipfs-data-importing": "{ import: {} }",
96-
"libp2p-ipfs": "{}",
97102
"mkdirp": "{}"
98103
}
99104
}

src/cli/commands/bitswap/stat.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../utils')
5+
6+
module.exports = Command.extend({
7+
desc: 'Show some diagnostic information on the bitswap agent.',
8+
9+
options: {
10+
},
11+
12+
run: () => {
13+
utils.getIPFS((err, ipfs) => {
14+
if (err) {
15+
throw err
16+
}
17+
18+
ipfs.bitswap.stat((err, stats) => {
19+
if (err) {
20+
throw err
21+
}
22+
23+
stats.Wantlist = stats.Wantlist || []
24+
stats.Peers = stats.Peers || []
25+
26+
console.log(`
27+
bitswap status
28+
blocks received: ${stats.BlocksReceived}
29+
dup blocks received: ${stats.DupBlksReceived}
30+
dup data received: ${stats.DupDataReceived}B
31+
wantlist [${stats.Wantlist.length} keys]
32+
${stats.Wantlist.join('\n ')}
33+
partners [${stats.Peers.length}]
34+
${stats.Peers.join('\n ')}`)
35+
})
36+
})
37+
}
38+
})

src/cli/commands/bitswap/unwant.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../utils')
5+
6+
module.exports = Command.extend({
7+
desc: 'Remove a given block from your wantlist.',
8+
9+
options: {
10+
key: {
11+
required: true
12+
}
13+
},
14+
15+
run: (key) => {
16+
utils.getIPFS((err, ipfs) => {
17+
if (err) {
18+
throw err
19+
}
20+
21+
throw new Error('Not implemented yet')
22+
})
23+
}
24+
})

src/cli/commands/bitswap/wantlist.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict'
2+
3+
const Command = require('ronin').Command
4+
const utils = require('../../utils')
5+
6+
module.exports = Command.extend({
7+
desc: 'Print out all blocks currently on the bitswap wantlist for the local peer.',
8+
9+
options: {
10+
},
11+
12+
run: () => {
13+
utils.getIPFS((err, ipfs) => {
14+
if (err) {
15+
throw err
16+
}
17+
18+
ipfs.bitswap.wantlist((err, res) => {
19+
if (err) {
20+
throw err
21+
}
22+
23+
res.Keys.forEach((k) => console.log(k))
24+
})
25+
})
26+
}
27+
})

src/cli/commands/config/edit.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const Command = require('ronin').Command
44
const spawn = require('child_process').spawn
55
const fs = require('fs')
66
const temp = require('temp')
7-
const async = require('async')
7+
const waterfall = require('run-waterfall')
88
const debug = require('debug')
99
const log = debug('cli:config')
1010
log.error = debug('cli:config:error')
@@ -99,7 +99,7 @@ module.exports = Command.extend({
9999
})
100100
}
101101

102-
async.waterfall([
102+
waterfall([
103103
getConfig,
104104
saveTempConfig,
105105
openEditor,

src/cli/commands/files/add.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const log = debug('cli:version')
77
log.error = debug('cli:version:error')
88
const bs58 = require('bs58')
99
const fs = require('fs')
10-
const async = require('async')
10+
const parallelLimit = require('run-parallel-limit')
1111
const path = require('path')
1212
const glob = require('glob')
1313

@@ -69,15 +69,15 @@ module.exports = Command.extend({
6969
})
7070
if (res.length !== 0) {
7171
const index = inPath.lastIndexOf('/')
72-
async.eachLimit(res, 10, (element, callback) => {
72+
parallelLimit(res.map((element) => (callback) => {
7373
if (!fs.statSync(element).isDirectory()) {
7474
i.write({
7575
path: element.substring(index + 1, element.length),
7676
stream: fs.createReadStream(element)
7777
})
7878
}
7979
callback()
80-
}, (err) => {
80+
}), 10, (err) => {
8181
if (err) {
8282
throw err
8383
}

src/core/index.js

+11-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const PeerBook = require('peer-book')
77

88
const defaultRepo = require('./default-repo')
99

10+
const goOnline = require('./ipfs/go-online')
11+
const goOffline = require('./ipfs/go-offline')
12+
const isOnline = require('./ipfs/is-online')
1013
const load = require('./ipfs/load')
1114
const version = require('./ipfs/version')
1215
const id = require('./ipfs/id')
@@ -18,6 +21,7 @@ const block = require('./ipfs/block')
1821
const object = require('./ipfs/object')
1922
const libp2p = require('./ipfs/libp2p')
2023
const files = require('./ipfs/files')
24+
const bitswap = require('./ipfs/bitswap')
2125

2226
exports = module.exports = IPFS
2327

@@ -32,12 +36,16 @@ function IPFS (repoInstance) {
3236
}
3337

3438
this._repo = repoInstance
35-
this._blockS = new BlockService(this._repo)
36-
this._dagS = new DAGService(this._blockS)
3739
this._peerInfoBook = new PeerBook()
3840
this._peerInfo = null
3941
this._libp2pNode = null
42+
this._bitswap = null
43+
this._blockS = new BlockService(this._repo)
44+
this._dagS = new DAGService(this._blockS)
4045

46+
this.goOnline = goOnline(this)
47+
this.goOffline = goOffline(this)
48+
this.isOnline = isOnline(this)
4149
this.load = load(this)
4250
this.version = version(this)
4351
this.id = id(this)
@@ -49,4 +57,5 @@ function IPFS (repoInstance) {
4957
this.object = object(this)
5058
this.libp2p = libp2p(this)
5159
this.files = files(this)
60+
this.bitswap = bitswap(this)
5261
}

src/core/ipfs/bitswap.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict'
2+
3+
const bs58 = require('bs58')
4+
5+
const OFFLINE_ERROR = require('../utils').OFFLINE_ERROR
6+
7+
function formatWantlist (list) {
8+
return Array.from(list).map((el) => {
9+
return bs58.encode(new Buffer(el[0], 'hex'))
10+
})
11+
}
12+
13+
module.exports = function bitswap (self) {
14+
return {
15+
wantlist: () => {
16+
if (!self.isOnline()) {
17+
throw OFFLINE_ERROR
18+
}
19+
20+
const list = self._bitswap.getWantlist()
21+
return formatWantlist(list)
22+
},
23+
stat: () => {
24+
if (!self.isOnline()) {
25+
throw OFFLINE_ERROR
26+
}
27+
28+
const stats = self._bitswap.stat()
29+
stats.wantlist = formatWantlist(stats.wantlist)
30+
stats.peers = stats.peers.map((id) => id.toB58String())
31+
32+
return stats
33+
},
34+
unwant: (key) => {
35+
if (!self.isOnline()) {
36+
throw OFFLINE_ERROR
37+
}
38+
39+
// TODO: implement when https://github.com/ipfs/js-ipfs-bitswap/pull/10 is merged
40+
}
41+
}
42+
}

src/core/ipfs/go-offline.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict'
2+
3+
module.exports = function goOffline (self) {
4+
return (cb) => {
5+
self._blockS.goOffline()
6+
self._bitswap.stop()
7+
self.libp2p.stop(cb)
8+
}
9+
}

0 commit comments

Comments
 (0)