From c291ca974219039539272a525a69a0ad7577859e Mon Sep 17 00:00:00 2001 From: Michael Garvin Date: Mon, 16 Apr 2018 09:24:02 -0700 Subject: [PATCH 1/6] feat: add bitswap.unwant javascript spec --- SPEC/BITSWAP.md | 15 +++++- js/src/bitswap.js | 132 ++++++++++++++++++++++++++++++++++++++++++++++ js/src/index.js | 1 + 3 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 js/src/bitswap.js diff --git a/SPEC/BITSWAP.md b/SPEC/BITSWAP.md index 00bc5fc1d..19ba32454 100644 --- a/SPEC/BITSWAP.md +++ b/SPEC/BITSWAP.md @@ -4,7 +4,20 @@ * [bitswap.unwant](#bitswapunwant) * [bitswap.stat](#bitswapstat) -#### `bitswap.wantlist` +#### `unwant` + +> Removes a given block from your wantlist + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.bitswap.unwant(cid) + +`cid` is a [cid][cid] which can be passed as: + +- CID, a CID instance +- String, the base58 encoded version of the multihash + +### `bitswap.wantlist` (not spec'ed yet) diff --git a/js/src/bitswap.js b/js/src/bitswap.js new file mode 100644 index 000000000..867352825 --- /dev/null +++ b/js/src/bitswap.js @@ -0,0 +1,132 @@ +'use strict' + +const chai = require('chai') +const dirtyChai = require('dirty-chai') +const expect = chai.expect +const statsTests = require('./utils/stats') +const spawn = require('./utils/spawn') +chai.use(dirtyChai) +const CID = require('cids') + +module.exports = (common) => { + describe('.bitswap online', () => { + let ipfs + let withGo + const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR' + + before(function (done) { + // CI takes longer to instantiate the daemon, so we need to increase the + // timeout for the before step + this.timeout(60 * 250) + + common.setup((err, factory) => { + expect(err).to.not.exist() + spawn.spawnNodeWithId(factory, (err, node) => { + expect(err).to.not.exist() + ipfs = node + withGo = node.peerId.agentVersion.startsWith('go-ipfs') + ipfs.block.get(key) + .then(() => {}) + .catch(() => {}) + done() + }) + }) + }) + + after((done) => common.teardown(done)) + + it('.stat', (done) => { + + ipfs.bitswap.stat((err, stats) => { + statsTests.expectIsBitswap(err, stats) + done() + }) + }) + + it('.wantlist', (done) => { + ipfs.bitswap.wantlist((err, list) => { + expect(err).to.not.exist() + expect(list.Keys).to.have.length(1); + expect(list.Keys[0]['/']).to.equal(key) + done() + }) + }) + + it('.unwant', function (done) { + if (withGo) { + this.skip() + } + ipfs.bitswap.unwant(key, (err) => { + expect(err).to.not.exist(); + ipfs.bitswap.wantlist((err, list) => { + expect(err).to.not.exist(); + expect(list.Keys).to.be.empty() + done() + }) + }) + }) + }) + + describe('.bitswap offline', () => { + let ipfs + + before(function (done) { + // 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 + ipfs.id((err, id) => { + expect(err).to.not.exist() + ipfs.stop((err) => { + // TODO: go-ipfs returns an error, https://github.com/ipfs/go-ipfs/issues/4078 + if (!id.agentVersion.startsWith('go-ipfs')) { + expect(err).to.not.exist() + } + done() + }) + }) + }) + }) + }) + + it('.stat gives error while offline', () => { + ipfs.bitswap.stat((err, stats) => { + expect(err).to.exist() + //When run against core we get our expected error, when run + //as part of the http tests we get a connection refused + if (err.code !== 'ECONNREFUSED') { + expect(err).to.match(/online mode/) + } + expect(stats).to.not.exist() + }) + }) + + it('.wantlist gives error if offline', () => { + ipfs.bitswap.wantlist((err, list) => { + expect(err).to.exist() + //When run against core we get our expected error, when run + //as part of the http tests we get a connection refused + if (err.code !== 'ECONNREFUSED') { + expect(err).to.match(/online mode/) + } + expect(list).to.not.exist() + }) + }) + + it('.unwant gives error if offline', () => { + expect(() => ipfs.bitswap.unwant(key, (err) => { + expect(err).to.exist() + //When run against core we get our expected error, when run + //as part of the http tests we get a connection refused + if (err.code !== 'ECONNREFUSED') { + expect(err).to.match(/online mode/) + } + })) + }) + }) +} diff --git a/js/src/index.js b/js/src/index.js index dd2012e9f..07904c431 100644 --- a/js/src/index.js +++ b/js/src/index.js @@ -19,3 +19,4 @@ exports.repo = require('./repo') exports.bootstrap = require('./bootstrap') exports.types = require('./types') exports.util = require('./util') +exports.bitswap = require('./bitswap') From d75a3613496b194d048800a2ff115c5f9708e559 Mon Sep 17 00:00:00 2001 From: Michael Garvin Date: Mon, 16 Apr 2018 09:24:02 -0700 Subject: [PATCH 2/6] feat: add bitswap.unwant javascript spec --- js/src/bitswap.js | 51 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/js/src/bitswap.js b/js/src/bitswap.js index 867352825..44cae902e 100644 --- a/js/src/bitswap.js +++ b/js/src/bitswap.js @@ -2,6 +2,7 @@ const chai = require('chai') const dirtyChai = require('dirty-chai') +const series = require('async/series') const expect = chai.expect const statsTests = require('./utils/stats') const spawn = require('./utils/spawn') @@ -10,7 +11,8 @@ const CID = require('cids') module.exports = (common) => { describe('.bitswap online', () => { - let ipfs + let ipfsA + let ipfsB let withGo const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR' @@ -21,30 +23,41 @@ module.exports = (common) => { common.setup((err, factory) => { expect(err).to.not.exist() - spawn.spawnNodeWithId(factory, (err, node) => { - expect(err).to.not.exist() - ipfs = node - withGo = node.peerId.agentVersion.startsWith('go-ipfs') - ipfs.block.get(key) - .then(() => {}) - .catch(() => {}) - done() - }) + series([ + (cb) => spawn.spawnNodeWithId(factory, (err, node) => { + expect(err).to.not.exist() + ipfsA = node + withGo = node.peerId.agentVersion.startsWith('go-ipfs') + cb() + //ipfsA.block.get(key) + //.then(() => {}) + //.catch(() => {}) + //cb() + }), + (cb) => spawn.spawnNodeWithId(factory, (err, node) => { + expect(err).to.not.exist() + ipfsB = node + ipfsB.block.get(new CID(key)) + .then(() => {}) + .catch(() => {}) + ipfsA.swarm.connect(node.peerId.addresses[0], cb) + }) + ], done) }) }) after((done) => common.teardown(done)) it('.stat', (done) => { - - ipfs.bitswap.stat((err, stats) => { + ipfsA.bitswap.stat((err, stats) => { + expect(err).to.not.exist() statsTests.expectIsBitswap(err, stats) done() }) }) it('.wantlist', (done) => { - ipfs.bitswap.wantlist((err, list) => { + ipfsA.bitswap.wantlist((err, list) => { expect(err).to.not.exist() expect(list.Keys).to.have.length(1); expect(list.Keys[0]['/']).to.equal(key) @@ -52,13 +65,21 @@ module.exports = (common) => { }) }) + it('.wantlist peerid', (done) => { + ipfsA.bitswap.wantlist(ipfsBId, (err, list) => { + expect(err).to.not.exist() + expect(list.Keys[0]['/']).to.equal(key) + done() + }) + }) + it('.unwant', function (done) { if (withGo) { this.skip() } - ipfs.bitswap.unwant(key, (err) => { + ipfsA.bitswap.unwant(key, (err) => { expect(err).to.not.exist(); - ipfs.bitswap.wantlist((err, list) => { + ipfsA.bitswap.wantlist((err, list) => { expect(err).to.not.exist(); expect(list.Keys).to.be.empty() done() From df4e67751c5d254e1513d408dda0607df2ba7796 Mon Sep 17 00:00:00 2001 From: Michael Garvin Date: Mon, 16 Apr 2018 09:24:02 -0700 Subject: [PATCH 3/6] feat: add bitswap.unwant javascript spec --- SPEC/BITSWAP.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SPEC/BITSWAP.md b/SPEC/BITSWAP.md index 19ba32454..205d1bc63 100644 --- a/SPEC/BITSWAP.md +++ b/SPEC/BITSWAP.md @@ -17,6 +17,8 @@ - CID, a CID instance - String, the base58 encoded version of the multihash +##### `Go` **WIP** + ### `bitswap.wantlist` (not spec'ed yet) From 9f81bcbe70d4a4ceb63484ba179a6b6979dc1ea9 Mon Sep 17 00:00:00 2001 From: Michael Garvin Date: Thu, 10 May 2018 14:34:52 -0700 Subject: [PATCH 4/6] feat: add peerId param to bitswap.wantlist --- SPEC/BITSWAP.md | 17 +++++++++++++---- js/src/bitswap.js | 35 ++++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/SPEC/BITSWAP.md b/SPEC/BITSWAP.md index 205d1bc63..4f54e01c8 100644 --- a/SPEC/BITSWAP.md +++ b/SPEC/BITSWAP.md @@ -4,7 +4,7 @@ * [bitswap.unwant](#bitswapunwant) * [bitswap.stat](#bitswapstat) -#### `unwant` +#### `bitswap.unwant` > Removes a given block from your wantlist @@ -21,11 +21,20 @@ ### `bitswap.wantlist` -(not spec'ed yet) +> Returns the wantlist, optionally limited by peerID -#### `bitswap.unwant` +#### `Go` **WIP** + +#### `JavaScript` - ipfs.bitswap.wantlist([peerId]) + +```JavaScript +ipfs.bitswap.wantlist((err, list) => console.log(list)) + +//[ { Wantlist object }, ... ] + +ipfs.bitswap.wantlist(peerId, (err, list) => console.log(list)) -(not spec'ed yet) +//[ { Wantlist object }, ... ] #### `bitswap.stat` diff --git a/js/src/bitswap.js b/js/src/bitswap.js index 44cae902e..4b0707f9a 100644 --- a/js/src/bitswap.js +++ b/js/src/bitswap.js @@ -14,6 +14,7 @@ module.exports = (common) => { let ipfsA let ipfsB let withGo + let ipfsBId const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR' before(function (done) { @@ -29,18 +30,18 @@ module.exports = (common) => { ipfsA = node withGo = node.peerId.agentVersion.startsWith('go-ipfs') cb() - //ipfsA.block.get(key) - //.then(() => {}) - //.catch(() => {}) - //cb() }), (cb) => spawn.spawnNodeWithId(factory, (err, node) => { expect(err).to.not.exist() ipfsB = node + ipfsBId = node.peerId ipfsB.block.get(new CID(key)) .then(() => {}) .catch(() => {}) - ipfsA.swarm.connect(node.peerId.addresses[0], cb) + ipfsA.swarm.connect(ipfsBId.addresses[0], (err) => { + expect(err).to.not.exist() + setTimeout(cb, 350) + }) }) ], done) }) @@ -49,7 +50,7 @@ module.exports = (common) => { after((done) => common.teardown(done)) it('.stat', (done) => { - ipfsA.bitswap.stat((err, stats) => { + ipfsB.bitswap.stat((err, stats) => { expect(err).to.not.exist() statsTests.expectIsBitswap(err, stats) done() @@ -57,7 +58,7 @@ module.exports = (common) => { }) it('.wantlist', (done) => { - ipfsA.bitswap.wantlist((err, list) => { + ipfsB.bitswap.wantlist((err, list) => { expect(err).to.not.exist() expect(list.Keys).to.have.length(1); expect(list.Keys[0]['/']).to.equal(key) @@ -66,7 +67,7 @@ module.exports = (common) => { }) it('.wantlist peerid', (done) => { - ipfsA.bitswap.wantlist(ipfsBId, (err, list) => { + ipfsA.bitswap.wantlist(ipfsBId.id, (err, list) => { expect(err).to.not.exist() expect(list.Keys[0]['/']).to.equal(key) done() @@ -77,9 +78,9 @@ module.exports = (common) => { if (withGo) { this.skip() } - ipfsA.bitswap.unwant(key, (err) => { + ipfsB.bitswap.unwant(key, (err) => { expect(err).to.not.exist(); - ipfsA.bitswap.wantlist((err, list) => { + ipfsB.bitswap.wantlist((err, list) => { expect(err).to.not.exist(); expect(list.Keys).to.be.empty() done() @@ -115,7 +116,7 @@ module.exports = (common) => { }) }) - it('.stat gives error while offline', () => { + it('.stat gives error while offline', (done) => { ipfs.bitswap.stat((err, stats) => { expect(err).to.exist() //When run against core we get our expected error, when run @@ -124,10 +125,11 @@ module.exports = (common) => { expect(err).to.match(/online mode/) } expect(stats).to.not.exist() + done() }) }) - it('.wantlist gives error if offline', () => { + it('.wantlist gives error if offline', (done) => { ipfs.bitswap.wantlist((err, list) => { expect(err).to.exist() //When run against core we get our expected error, when run @@ -136,18 +138,21 @@ module.exports = (common) => { expect(err).to.match(/online mode/) } expect(list).to.not.exist() + done() }) }) - it('.unwant gives error if offline', () => { - expect(() => ipfs.bitswap.unwant(key, (err) => { + it('.unwant gives error if offline', (done) => { + const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR' + ipfs.bitswap.unwant(key, (err) => { expect(err).to.exist() //When run against core we get our expected error, when run //as part of the http tests we get a connection refused if (err.code !== 'ECONNREFUSED') { expect(err).to.match(/online mode/) } - })) + done() + }) }) }) } From 7737546010905621071ceb0f94d277c6e0c875bd Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Mon, 18 Jun 2018 13:17:53 +0100 Subject: [PATCH 5/6] fix: improve bitswap wantlist and unwant docs License: MIT Signed-off-by: Alan Shaw --- SPEC/BITSWAP.md | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/SPEC/BITSWAP.md b/SPEC/BITSWAP.md index 4f54e01c8..28949c005 100644 --- a/SPEC/BITSWAP.md +++ b/SPEC/BITSWAP.md @@ -10,31 +10,52 @@ ##### `Go` **WIP** -##### `JavaScript` - ipfs.bitswap.unwant(cid) +##### `JavaScript` - ipfs.bitswap.unwant(cid, [callback]) `cid` is a [cid][cid] which can be passed as: - CID, a CID instance - String, the base58 encoded version of the multihash +`callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful. + + **Example:** + + ```JavaScript + ipfs.bitswap.unwant('QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu', (err) => { + if (err) throw err + console.log('Done') + }) + ``` + ##### `Go` **WIP** ### `bitswap.wantlist` -> Returns the wantlist, optionally limited by peerID +> Returns the wantlist, optionally filtered by peer ID #### `Go` **WIP** -#### `JavaScript` - ipfs.bitswap.wantlist([peerId]) +#### `JavaScript` - ipfs.bitswap.wantlist([peerId], [callback]) + +`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: + +- `Keys` An array of objects containing the following keys: + - `/` A string multihash + +If no `callback` is passed, a promise is returned. + +**Example:** ```JavaScript ipfs.bitswap.wantlist((err, list) => console.log(list)) -//[ { Wantlist object }, ... ] +// { Keys: [{ '/': 'QmHash' }] } ipfs.bitswap.wantlist(peerId, (err, list) => console.log(list)) -//[ { Wantlist object }, ... ] +// { Keys: [{ '/': 'QmHash' }] } +``` #### `bitswap.stat` From fcc834c02aabd59e693e6dc7ae6cc08d617b3a9a Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Mon, 18 Jun 2018 14:38:57 +0100 Subject: [PATCH 6/6] fix: linting errors License: MIT Signed-off-by: Alan Shaw --- js/src/bitswap.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/js/src/bitswap.js b/js/src/bitswap.js index 4b0707f9a..0999e9da4 100644 --- a/js/src/bitswap.js +++ b/js/src/bitswap.js @@ -1,3 +1,4 @@ +/* eslint-env mocha */ 'use strict' const chai = require('chai') @@ -60,7 +61,7 @@ module.exports = (common) => { it('.wantlist', (done) => { ipfsB.bitswap.wantlist((err, list) => { expect(err).to.not.exist() - expect(list.Keys).to.have.length(1); + expect(list.Keys).to.have.length(1) expect(list.Keys[0]['/']).to.equal(key) done() }) @@ -79,9 +80,9 @@ module.exports = (common) => { this.skip() } ipfsB.bitswap.unwant(key, (err) => { - expect(err).to.not.exist(); + expect(err).to.not.exist() ipfsB.bitswap.wantlist((err, list) => { - expect(err).to.not.exist(); + expect(err).to.not.exist() expect(list.Keys).to.be.empty() done() }) @@ -119,8 +120,8 @@ module.exports = (common) => { it('.stat gives error while offline', (done) => { ipfs.bitswap.stat((err, stats) => { expect(err).to.exist() - //When run against core we get our expected error, when run - //as part of the http tests we get a connection refused + // When run against core we get our expected error, when run + // as part of the http tests we get a connection refused if (err.code !== 'ECONNREFUSED') { expect(err).to.match(/online mode/) } @@ -132,8 +133,8 @@ module.exports = (common) => { it('.wantlist gives error if offline', (done) => { ipfs.bitswap.wantlist((err, list) => { expect(err).to.exist() - //When run against core we get our expected error, when run - //as part of the http tests we get a connection refused + // When run against core we get our expected error, when run + // as part of the http tests we get a connection refused if (err.code !== 'ECONNREFUSED') { expect(err).to.match(/online mode/) } @@ -146,8 +147,8 @@ module.exports = (common) => { const key = 'QmUBdnXXPyoDFXj3Hj39dNJ5VkN3QFRskXxcGaYFBB8CNR' ipfs.bitswap.unwant(key, (err) => { expect(err).to.exist() - //When run against core we get our expected error, when run - //as part of the http tests we get a connection refused + // When run against core we get our expected error, when run + // as part of the http tests we get a connection refused if (err.code !== 'ECONNREFUSED') { expect(err).to.match(/online mode/) }