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

Commit 0900bb9

Browse files
feat: sync with go-ipfs 0.5 (#3013)
New features: - `ipfs.dht.get` accepts string or buffer - http-client `ipfs.dht.get` returns a buffer to match core api Breaking changes: - ipfs.ls remove all options in core api, but keep `long` in http api and cli same as go-ipfs - remove sort from the cli and ignore go-ipfs `U` option - enable http api mfs tests - key.gen defaults, to rsa and 2048 - pin.list only supports streaming responses - -U argument to `files.ls` has been removed - dht put uses body to send data instead of query string Co-authored-by: Alex Potsides <[email protected]>
1 parent 5e0a18a commit 0900bb9

File tree

28 files changed

+215
-276
lines changed

28 files changed

+215
-276
lines changed

docs/core-api/DHT.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ A great source of [examples][] can be found in the tests for this API.
126126

127127
| Name | Type | Description |
128128
| ---- | ---- | ----------- |
129-
| key | Buffer | The key associated with the value to find |
129+
| key | `Buffer` or `string` | The key associated with the value to find |
130130

131131
### Options
132132

docs/core-api/FILES.md

-1
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,6 @@ An optional object which may have the following keys:
916916

917917
| Name | Type | Default | Description |
918918
| ---- | ---- | ------- | ----------- |
919-
| sort | `boolean` | `false` | If true entries will be sorted by filename |
920919
| timeout | `Number` | `undefined` | A timeout in ms |
921920
| signal | [AbortSignal][] | `undefined` | Can be used to cancel any long running requests started as a result of this call |
922921

docs/core-api/KEY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,4 +289,4 @@ A great source of [examples][] can be found in the tests for this API.
289289

290290
[examples]: https://github.com/ipfs/js-ipfs/blob/master/packages/interface-ipfs-core/src/key
291291
[cid]: https://www.npmjs.com/package/cids
292-
[AbortSignal]: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal
292+
[AbortSignal]: https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal

packages/interface-ipfs-core/src/bootstrap/rm.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ module.exports = (common, options) => {
6161
const rmRes = await ipfs.bootstrap.rm(null, { all: true })
6262
const removedPeers = rmRes.Peers
6363

64-
expect(removedPeers).to.eql(addedPeers)
64+
expect(removedPeers.sort()).to.deep.equal(addedPeers.sort())
6565
})
6666
})
6767
}
+9-16
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/* eslint-env mocha */
22
'use strict'
33

4-
const { Buffer } = require('buffer')
54
const { getDescribe, getIt, expect } = require('../utils/mocha')
65
const testTimeout = require('../utils/test-timeout')
7-
const drain = require('it-drain')
6+
const all = require('it-all')
87

98
/** @typedef { import("ipfsd-ctl/src/factory") } Factory */
109
/**
@@ -15,9 +14,7 @@ module.exports = (common, options) => {
1514
const describe = getDescribe(options)
1615
const it = getIt(options)
1716

18-
describe.skip('.dht.get', function () {
19-
this.timeout(80 * 1000)
20-
17+
describe('.dht.get', function () {
2118
let nodeA
2219
let nodeB
2320

@@ -30,12 +27,10 @@ module.exports = (common, options) => {
3027
after(() => common.clean())
3128

3229
it('should respect timeout option when getting a value from the DHT', async () => {
33-
const key = Buffer.from('/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')
34-
const data = Buffer.from('data')
35-
36-
await drain(nodeA.dht.put(key, data, { verbose: true }))
30+
const [data] = await all(nodeA.add('should put a value to the DHT'))
31+
const publish = await nodeA.name.publish(data.cid)
3732

38-
await testTimeout(() => nodeB.dht.get(key, {
33+
await testTimeout(() => nodeB.dht.get(`/ipns/${publish.name}`, {
3934
timeout: 1
4035
}))
4136
})
@@ -46,13 +41,11 @@ module.exports = (common, options) => {
4641
})
4742

4843
it('should get a value after it was put on another node', async () => {
49-
const key = Buffer.from('/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')
50-
const value = Buffer.from('data')
51-
52-
await drain(nodeB.dht.put(key, value))
53-
const result = await nodeA.dht.get(key)
44+
const [data] = await all(nodeA.add('should put a value to the DHT'))
45+
const publish = await nodeA.name.publish(data.cid)
46+
const record = await nodeA.dht.get(`/ipns/${publish.name}`)
5447

55-
expect(result).to.eql(value)
48+
expect(record.toString()).to.contain(data.cid.toString())
5649
})
5750
})
5851
}

packages/interface-ipfs-core/src/dht/put.js

+10-12
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
'use strict'
33

44
const { Buffer } = require('buffer')
5-
const { getDescribe, getIt } = require('../utils/mocha')
6-
const drain = require('it-drain')
5+
const { getDescribe, getIt, expect } = require('../utils/mocha')
76
const testTimeout = require('../utils/test-timeout')
87
const CID = require('cids')
8+
const all = require('it-all')
99

1010
/** @typedef { import("ipfsd-ctl/src/factory") } Factory */
1111
/**
@@ -16,10 +16,7 @@ module.exports = (common, options) => {
1616
const describe = getDescribe(options)
1717
const it = getIt(options)
1818

19-
// TODO unskip this after go-ipfs 0.5.0 ships interface is going to change
20-
describe.skip('.dht.put', function () {
21-
this.timeout(80 * 1000)
22-
19+
describe('.dht.put', function () {
2320
let nodeA
2421
let nodeB
2522

@@ -38,12 +35,13 @@ module.exports = (common, options) => {
3835
})
3936

4037
it('should put a value to the DHT', async function () {
41-
this.timeout(80 * 1000)
42-
43-
const key = Buffer.from('/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn')
44-
const data = Buffer.from('data')
45-
46-
await drain(nodeA.dht.put(key, data, { verbose: true }))
38+
const [data] = await all(nodeA.add('should put a value to the DHT'))
39+
const publish = await nodeA.name.publish(data.cid)
40+
const record = await nodeA.dht.get(`/ipns/${publish.name}`)
41+
const value = await all(nodeA.dht.put(`/ipns/${publish.name}`, record, { verbose: true }))
42+
expect(value).to.has.length(3)
43+
expect(value[2].id.toString()).to.be.equal(nodeB.peerId.id)
44+
expect(value[2].type).to.be.equal(5)
4745
})
4846
})
4947
}

packages/interface-ipfs-core/src/pubsub/publish.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
const { Buffer } = require('buffer')
55
const { nanoid } = require('nanoid')
66
const { getTopic } = require('./utils')
7-
const { getDescribe, getIt } = require('../utils/mocha')
7+
const { getDescribe, getIt, expect } = require('../utils/mocha')
88
const testTimeout = require('../utils/test-timeout')
99

1010
/** @typedef { import("ipfsd-ctl/src/factory") } Factory */
@@ -38,6 +38,11 @@ module.exports = (common, options) => {
3838
return ipfs.pubsub.publish(topic, 'hello friend')
3939
})
4040

41+
it('should fail with undefined msg', async () => {
42+
const topic = getTopic()
43+
await expect(ipfs.pubsub.publish(topic)).to.eventually.rejectedWith('argument "data" is required')
44+
})
45+
4146
it('should publish message from buffer', () => {
4247
const topic = getTopic()
4348
return ipfs.pubsub.publish(topic, Buffer.from(nanoid()))

packages/interface-ipfs-core/src/pubsub/subscribe.js

+67-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
'use strict'
33

44
const { Buffer } = require('buffer')
5+
const { nanoid } = require('nanoid')
56
const pushable = require('it-pushable')
67
const all = require('it-all')
78
const { waitForPeers, getTopic } = require('./utils')
89
const { getDescribe, getIt, expect } = require('../utils/mocha')
910
const delay = require('delay')
10-
const { isWebWorker } = require('ipfs-utils/src/env')
11+
const AbortController = require('abort-controller')
12+
const { isWebWorker, isNode } = require('ipfs-utils/src/env')
1113

1214
/** @typedef { import("ipfsd-ctl/src/factory") } Factory */
1315
/**
@@ -163,6 +165,66 @@ module.exports = (common, options) => {
163165
return ipfs1.swarm.connect(ipfs2Addr)
164166
})
165167

168+
it('should receive messages from a different node with floodsub', async function () {
169+
if (!isNode) {
170+
return this.skip()
171+
}
172+
const expectedString = 'should receive messages from a different node with floodsub'
173+
const topic = `floodsub-${nanoid()}`
174+
const ipfs1 = (await common.spawn({
175+
ipfsOptions: {
176+
config: {
177+
Pubsub: {
178+
Router: 'floodsub'
179+
}
180+
}
181+
}
182+
})).api
183+
const ipfs2 = (await common.spawn({
184+
type: isWebWorker ? 'go' : undefined,
185+
ipfsOptions: {
186+
config: {
187+
Pubsub: {
188+
Router: 'floodsub'
189+
}
190+
}
191+
}
192+
})).api
193+
await ipfs1.swarm.connect(ipfs2.peerId.addresses[0])
194+
195+
const msgStream1 = pushable()
196+
const msgStream2 = pushable()
197+
198+
const sub1 = msg => {
199+
msgStream1.push(msg)
200+
msgStream1.end()
201+
}
202+
const sub2 = msg => {
203+
msgStream2.push(msg)
204+
msgStream2.end()
205+
}
206+
207+
const abort1 = new AbortController()
208+
const abort2 = new AbortController()
209+
await Promise.all([
210+
ipfs1.pubsub.subscribe(topic, sub1, { signal: abort1.signal }),
211+
ipfs2.pubsub.subscribe(topic, sub2, { signal: abort2.signal })
212+
])
213+
214+
await waitForPeers(ipfs2, topic, [ipfs1.peerId.id], 30000)
215+
await ipfs2.pubsub.publish(topic, Buffer.from(expectedString))
216+
217+
const [sub1Msg] = await all(msgStream1)
218+
expect(sub1Msg.data.toString()).to.be.eql(expectedString)
219+
expect(sub1Msg.from).to.eql(ipfs2.peerId.id)
220+
221+
const [sub2Msg] = await all(msgStream2)
222+
expect(sub2Msg.data.toString()).to.be.eql(expectedString)
223+
expect(sub2Msg.from).to.eql(ipfs2.peerId.id)
224+
abort1.abort()
225+
abort2.abort()
226+
})
227+
166228
it('should receive messages from a different node', async () => {
167229
const expectedString = 'hello from the other side'
168230

@@ -184,7 +246,7 @@ module.exports = (common, options) => {
184246
])
185247

186248
await waitForPeers(ipfs2, topic, [ipfs1.peerId.id], 30000)
187-
249+
await delay(5000) // gossipsub need this delay https://github.com/libp2p/go-libp2p-pubsub/issues/331
188250
await ipfs2.pubsub.publish(topic, Buffer.from(expectedString))
189251

190252
const [sub1Msg] = await all(msgStream1)
@@ -218,7 +280,7 @@ module.exports = (common, options) => {
218280
])
219281

220282
await waitForPeers(ipfs2, topic, [ipfs1.peerId.id], 30000)
221-
283+
await delay(5000) // gossipsub need this delay https://github.com/libp2p/go-libp2p-pubsub/issues/331
222284
await ipfs2.pubsub.publish(topic, buffer)
223285

224286
const [sub1Msg] = await all(msgStream1)
@@ -256,7 +318,7 @@ module.exports = (common, options) => {
256318
])
257319

258320
await waitForPeers(ipfs2, topic, [ipfs1.peerId.id], 30000)
259-
321+
await delay(5000) // gossipsub need this delay https://github.com/libp2p/go-libp2p-pubsub/issues/331
260322
outbox.forEach(msg => ipfs2.pubsub.publish(topic, Buffer.from(msg)))
261323

262324
const sub1Msgs = await all(msgStream1)
@@ -290,7 +352,7 @@ module.exports = (common, options) => {
290352
])
291353

292354
await waitForPeers(ipfs1, topic, [ipfs2.peerId.id], 30000)
293-
355+
await delay(5000) // gossipsub need this delay https://github.com/libp2p/go-libp2p-pubsub/issues/331
294356
const startTime = new Date().getTime()
295357

296358
for (let i = 0; i < count; i++) {

packages/ipfs-http-client/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
"devDependencies": {
7171
"aegir": "^22.0.0",
7272
"cross-env": "^7.0.0",
73-
"go-ipfs-dep": "0.4.23-3",
73+
"go-ipfs-dep": "^0.5.1",
7474
"interface-ipfs-core": "^0.135.1",
7575
"ipfsd-ctl": "^4.1.1",
7676
"it-all": "^1.0.1",

packages/ipfs-http-client/src/dht/get.js

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

33
const { Buffer } = require('buffer')
4-
const encodeBufferURIComponent = require('../lib/encode-buffer-uri-component')
54
const configure = require('../lib/configure')
65
const toUrlSearchParams = require('../lib/to-url-search-params')
76
const { Value } = require('./response-types')
87

98
module.exports = configure(api => {
109
return async function get (key, options = {}) {
11-
if (!Buffer.isBuffer(key)) {
12-
throw new Error('invalid key')
13-
}
14-
1510
const res = await api.post('dht/get', {
1611
timeout: options.timeout,
1712
signal: options.signal,
1813
searchParams: toUrlSearchParams({
19-
key: encodeBufferURIComponent(key),
14+
arg: Buffer.isBuffer(key) ? key.toString() : key,
2015
...options
2116
}),
2217
headers: options.headers
2318
})
2419

2520
for await (const message of res.ndjson()) {
2621
if (message.Type === Value) {
27-
return message.Extra
22+
return Buffer.from(message.Extra, 'base64')
2823
}
2924
}
3025

packages/ipfs-http-client/src/dht/put.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ const multiaddr = require('multiaddr')
55
const toCamel = require('../lib/object-to-camel')
66
const configure = require('../lib/configure')
77
const toUrlSearchParams = require('../lib/to-url-search-params')
8+
const multipartRequest = require('../lib/multipart-request')
89

910
module.exports = configure(api => {
1011
return async function * put (key, value, options = {}) {
1112
const res = await api.post('dht/put', {
1213
timeout: options.timeout,
1314
signal: options.signal,
1415
searchParams: toUrlSearchParams({
15-
arg: [
16-
key,
17-
value
18-
],
16+
arg: key,
1917
...options
2018
}),
21-
headers: options.headers
19+
...(
20+
await multipartRequest(value, options.headers)
21+
)
2222
})
2323

2424
for await (let message of res.ndjson()) {

packages/ipfs-http-client/src/files/ls.js

+2-6
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,8 @@ module.exports = configure(api => {
1717
signal: options.signal,
1818
searchParams: toUrlSearchParams({
1919
arg: CID.isCID(path) ? `/ipfs/${path}` : path,
20-
21-
// TODO the args below are not in the go-ipfs or interface core docs
22-
long: options.long == null ? true : options.long,
23-
24-
// TODO: remove after go-ipfs 0.5 is released
25-
l: options.long == null ? true : options.long,
20+
// default long to true, diverges from go-ipfs where its false by default
21+
long: true,
2622
...options,
2723
stream: true
2824
}),

packages/ipfs-http-client/src/lib/encode-buffer-uri-component.js

-25
This file was deleted.

packages/ipfs-http-client/src/lib/multipart-request.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const modeToString = require('../lib/mode-to-string')
77
const mtimeToObject = require('../lib/mtime-to-object')
88
const merge = require('merge-options').bind({ ignoreUndefined: true })
99

10-
async function multipartRequest (source, abortController, headers = {}, boundary = `-----------------------------${nanoid()}`) {
10+
async function multipartRequest (source = '', abortController, headers = {}, boundary = `-----------------------------${nanoid()}`) {
1111
async function * streamFiles (source) {
1212
try {
1313
let index = 0

0 commit comments

Comments
 (0)