diff --git a/SPEC/BITSWAP.md b/SPEC/BITSWAP.md index c50093e41..1670ca664 100644 --- a/SPEC/BITSWAP.md +++ b/SPEC/BITSWAP.md @@ -5,60 +5,59 @@ ### `bitswap.wantlist` -> Returns the wantlist, optionally filtered by peer ID +> Get the list of wanted CIDs for this peer or another peer on the network. -#### `Go` **WIP** +#### Go **WIP** -#### `JavaScript` - ipfs.bitswap.wantlist([peerId], [callback]) +#### JavaScript - `ipfs.bitswap.wantlist([peerId])` -`callback` must follow `function (err, list) {}` signature, where `err` is an error if the operation was not successful. `list` is an Object containing the following keys: +##### Parameters -- `Keys` An array of objects containing the following keys: - - `/` A string multihash +| Name | Type | Description | +|------|------|-------------| +| peerId | `String` | (optional) Base 58 encoded Peer ID to get the wantlist for. Default: this node's peer ID | -If no `callback` is passed, a promise is returned. +##### Returns -**Example:** +| Type | Description | +|------|-------------| +| `Promise<{`
  `Keys>`
`}>` | The list of CIDs wanted by the peer. Each object in the array has a single property "/" a string CID. | -```JavaScript -ipfs.bitswap.wantlist((err, list) => console.log(list)) +##### Example -// { Keys: [{ '/': 'QmHash' }] } +```js +const list = await ipfs.bitswap.wantlist() +console.log(list) // { Keys: [{ '/': 'QmHash' }] } +``` -ipfs.bitswap.wantlist(peerId, (err, list) => console.log(list)) +Wantlist for a given peer: -// { Keys: [{ '/': 'QmHash' }] } +```js +ipfs.bitswap.wantlist('QmZEYeEin6wEB7WNyiT7stYTmbYFGy7BzM7T3hRDzRxTvY') +console.log(list) // { Keys: [{ '/': 'QmHash' }] } ``` #### `bitswap.stat` > Show diagnostic information on the bitswap agent. -##### `Go` **WIP** +##### Go **WIP** -##### `JavaScript` - ipfs.bitswap.stat([callback]) +##### JavaScript - `ipfs.bitswap.stat()` Note: `bitswap.stat` and `stats.bitswap` can be used interchangeably. -`callback` must follow `function (err, stats) {}` signature, where `err` is an error if the operation was not successful. `stats` is an Object containing the following keys: - -- `provideBufLen` is an integer. -- `wantlist` (array of CIDs) -- `peers` (array of peer IDs) -- `blocksReceived` is a [Big Int][1] -- `dataReceived` is a [Big Int][1] -- `blocksSent` is a [Big Int][1] -- `dataSent` is a [Big Int][1] -- `dupBlksReceived` is a [Big Int][1] -- `dupDataReceived` is a [Big Int][1] - -If no `callback` is passed, a promise is returned. +##### Returns -**Example:** +| Type | Description | +|------|-------------| +| `Promise<{`
  `provideBufLen,`
  `wantlist>,`
  `peers>,`
  `blocksReceived<`[`Big`][1]`>,`
  `dataReceived<`[`Big`][1]`>,`
  `blocksSent<`[`Big`][1]`>,`
  `dataSent<`[`Big`][1]`>,`
  `dupBlksReceived<`[`Big`][1]`>,`
  `dupDataReceived<`[`Big`][1]`>,`
`}>` | Diagnostic information on the bitswap agent | -```JavaScript -ipfs.bitswap.stat((err, stats) => console.log(stats)) +##### Example +```js +const stats = await ipfs.bitswap.stat() +console.log(stats) // { provideBufLen: 0, // wantlist: [ { '/': 'QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM' } ], // peers: diff --git a/js/src/bitswap/.tern-port b/js/src/bitswap/.tern-port deleted file mode 100644 index afd86f3dc..000000000 --- a/js/src/bitswap/.tern-port +++ /dev/null @@ -1 +0,0 @@ -36541 \ No newline at end of file diff --git a/js/src/bitswap/stat.js b/js/src/bitswap/stat.js index 024612474..0c214f46a 100644 --- a/js/src/bitswap/stat.js +++ b/js/src/bitswap/stat.js @@ -1,7 +1,6 @@ /* eslint-env mocha */ 'use strict' -const waterfall = require('async/waterfall') const { getDescribe, getIt, expect } = require('../utils/mocha') const { expectIsBitswap } = require('../stats/utils') @@ -13,50 +12,33 @@ module.exports = (createCommon, options) => { describe('.bitswap.stat', () => { let ipfs - before(function (done) { + before(async function () { // CI takes longer to instantiate the daemon, so we need to increase the // timeout for the before step this.timeout(60 * 1000) - common.setup((err, factory) => { - expect(err).to.not.exist() - factory.spawnNode((err, node) => { - expect(err).to.not.exist() - ipfs = node - done() - }) - }) + const factory = await common.setup() + ipfs = await factory.spawnNode() }) - after((done) => common.teardown(done)) + after(() => common.teardown()) - it('should get bitswap stats', (done) => { - ipfs.bitswap.stat((err, res) => { - expectIsBitswap(err, res) - done() - }) + it('should get bitswap stats', async () => { + const res = await ipfs.bitswap.stat() + expectIsBitswap(res) }) - it('should get bitswap stats (promised)', () => { - return ipfs.bitswap.stat().then((res) => { - expectIsBitswap(null, res) - }) - }) - - it('should not get bitswap stats when offline', function (done) { + it('should not get bitswap stats when offline', async function () { this.timeout(60 * 1000) - waterfall([ - (cb) => createCommon().setup(cb), - (factory, cb) => factory.spawnNode(cb), - (node, cb) => node.stop((err) => cb(err, node)) - ], (err, node) => { - expect(err).to.not.exist() - node.bitswap.wantlist((err) => { - expect(err).to.exist() - done() - }) - }) + const common = createCommon() + const factory = await common.setup() + const ipfs = await factory.spawnNode() + await ipfs.stop() + + // TODO: assert on error message/code + await expect(ipfs.bitswap.stat()).to.be.rejected() + return common.teardown() }) }) } diff --git a/js/src/bitswap/utils.js b/js/src/bitswap/utils.js index 5a2c9c351..4638158ae 100644 --- a/js/src/bitswap/utils.js +++ b/js/src/bitswap/utils.js @@ -1,29 +1,17 @@ 'use strict' -const until = require('async/until') - -function waitForWantlistKey (ipfs, key, opts, cb) { - if (typeof opts === 'function') { - cb = opts - opts = {} - } - +async function waitForWantlistKey (ipfs, key, opts) { opts = opts || {} opts.timeout = opts.timeout || 1000 - let list = { Keys: [] } - let timedOut = false + const start = Date.now() - setTimeout(() => { timedOut = true }, opts.timeout) - - const test = () => timedOut ? true : list.Keys.every(k => k['/'] === key) - const iteratee = (cb) => ipfs.bitswap.wantlist(opts.peerId, cb) + while (Date.now() <= start + opts.timeout) { + const list = await ipfs.bitswap.wantlist(opts.peerId) + if (list.Keys.find(k => k['/'] === key)) return + } - until(test, iteratee, (err) => { - if (err) return cb(err) - if (timedOut) return cb(new Error(`Timed out waiting for ${key} in wantlist`)) - cb() - }) + throw new Error(`Timed out waiting for ${key} in wantlist`) } module.exports.waitForWantlistKey = waitForWantlistKey diff --git a/js/src/bitswap/wantlist.js b/js/src/bitswap/wantlist.js index cdc11c570..5f38cfcef 100644 --- a/js/src/bitswap/wantlist.js +++ b/js/src/bitswap/wantlist.js @@ -2,7 +2,6 @@ /* eslint max-nested-callbacks: ["error", 6] */ 'use strict' -const waterfall = require('async/waterfall') const { spawnNodesWithId } = require('../utils/spawn') const { getDescribe, getIt, expect } = require('../utils/mocha') const { waitForWantlistKey } = require('./utils') @@ -18,58 +17,46 @@ module.exports = (createCommon, options) => { let ipfsB const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR' - before(function (done) { + before(async function () { // CI takes longer to instantiate the daemon, so we need to increase the // timeout for the before step this.timeout(60 * 1000) - common.setup((err, factory) => { - expect(err).to.not.exist() + const factory = await common.setup() + const nodes = await spawnNodesWithId(2, factory) - spawnNodesWithId(2, factory, (err, nodes) => { - expect(err).to.not.exist() + ipfsA = nodes[0] + ipfsB = nodes[1] - ipfsA = nodes[0] - ipfsB = nodes[1] + // Add key to the wantlist for ipfsB + ipfsB.block.get(key) - // Add key to the wantlist for ipfsB - ipfsB.block.get(key, () => {}) - - connect(ipfsA, ipfsB.peerId.addresses[0], done) - }) - }) + return connect(ipfsA, ipfsB.peerId.addresses[0]) }) - after(function (done) { + after(async function () { this.timeout(30 * 1000) - common.teardown(done) + return common.teardown() }) - it('should get the wantlist', (done) => { - waitForWantlistKey(ipfsB, key, done) - }) + it('should get the wantlist', () => waitForWantlistKey(ipfsB, key)) - it('should get the wantlist by peer ID for a diffreent node', (done) => { - ipfsB.id((err, info) => { - expect(err).to.not.exist() - waitForWantlistKey(ipfsA, key, { peerId: info.id }, done) - }) + it('should get the wantlist by peer ID for a diffreent node', async () => { + const info = await ipfsB.id() + return waitForWantlistKey(ipfsA, key, { peerId: info.id }) }) - it('should not get the wantlist when offline', function (done) { + it('should not get the wantlist when offline', async function () { this.timeout(60 * 1000) - waterfall([ - (cb) => createCommon().setup(cb), - (factory, cb) => factory.spawnNode(cb), - (node, cb) => node.stop((err) => cb(err, node)) - ], (err, node) => { - expect(err).to.not.exist() - node.bitswap.wantlist((err) => { - expect(err).to.exist() - done() - }) - }) + const common = createCommon() + const factory = await common.setup() + const ipfs = factory.spawnNode() + await ipfs.stop() + + // TODO: assert on error message/code + await expect(ipfs.bitswap.wantlist()).to.be.rejected() + return common.teardown() }) }) } diff --git a/js/src/stats/utils.js b/js/src/stats/utils.js index 7d02ce0e5..101e0a902 100644 --- a/js/src/stats/utils.js +++ b/js/src/stats/utils.js @@ -6,8 +6,7 @@ const isBigInt = (n) => { return n.constructor.name === 'Big' } -exports.expectIsBitswap = (err, stats) => { - expect(err).to.not.exist() +exports.expectIsBitswap = stats => { expect(stats).to.exist() expect(stats).to.have.a.property('provideBufLen') expect(stats).to.have.a.property('wantlist') @@ -30,8 +29,7 @@ exports.expectIsBitswap = (err, stats) => { expect(isBigInt(stats.dupDataReceived)).to.eql(true) } -exports.expectIsBandwidth = (err, stats) => { - expect(err).to.not.exist() +exports.expectIsBandwidth = stats => { expect(stats).to.exist() expect(stats).to.have.a.property('totalIn') expect(stats).to.have.a.property('totalOut') @@ -43,8 +41,7 @@ exports.expectIsBandwidth = (err, stats) => { expect(isBigInt(stats.rateOut)).to.eql(true) } -exports.expectIsRepo = (err, res) => { - expect(err).to.not.exist() +exports.expectIsRepo = res => { expect(res).to.exist() expect(res).to.have.a.property('numObjects') expect(res).to.have.a.property('repoSize')