@helia/interop 7.1.3 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
/* eslint-env mocha */
|
|
2
2
|
import { unixfs } from '@helia/unixfs';
|
|
3
|
+
import * as dagPb from '@ipld/dag-pb';
|
|
4
|
+
import { multiaddr } from '@multiformats/multiaddr';
|
|
3
5
|
import { expect } from 'aegir/chai';
|
|
4
6
|
import { fixedSize } from 'ipfs-unixfs-importer/chunker';
|
|
5
7
|
import { balanced } from 'ipfs-unixfs-importer/layout';
|
|
8
|
+
import drain from 'it-drain';
|
|
9
|
+
import last from 'it-last';
|
|
6
10
|
import { CID } from 'multiformats/cid';
|
|
11
|
+
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
|
|
7
12
|
import { createHeliaNode } from './fixtures/create-helia.js';
|
|
8
13
|
import { createKuboNode } from './fixtures/create-kubo.js';
|
|
9
14
|
describe('@helia/unixfs - files', () => {
|
|
@@ -14,10 +19,24 @@ describe('@helia/unixfs - files', () => {
|
|
|
14
19
|
const cid = await unixFs.addByteStream(data, opts);
|
|
15
20
|
return cid;
|
|
16
21
|
}
|
|
22
|
+
async function importDirectoryToHelia(data, opts) {
|
|
23
|
+
const result = await last(unixFs.addAll(data, opts));
|
|
24
|
+
if (result == null) {
|
|
25
|
+
throw new Error('Nothing imported');
|
|
26
|
+
}
|
|
27
|
+
return CID.parse(result.cid.toString());
|
|
28
|
+
}
|
|
17
29
|
async function importToKubo(data, opts) {
|
|
18
30
|
const result = await kubo.api.add(data, opts);
|
|
19
31
|
return CID.parse(result.cid.toString());
|
|
20
32
|
}
|
|
33
|
+
async function importDirectoryToKubo(data, opts) {
|
|
34
|
+
const result = await last(kubo.api.addAll(data, opts));
|
|
35
|
+
if (result == null) {
|
|
36
|
+
throw new Error('Nothing imported');
|
|
37
|
+
}
|
|
38
|
+
return CID.parse(result.cid.toString());
|
|
39
|
+
}
|
|
21
40
|
async function expectSameCid(data, heliaOpts = {}, kuboOpts = {}) {
|
|
22
41
|
const heliaCid = await importToHelia(data(), {
|
|
23
42
|
// these are the default kubo options
|
|
@@ -63,5 +82,83 @@ describe('@helia/unixfs - files', () => {
|
|
|
63
82
|
}());
|
|
64
83
|
await expectSameCid(candidate);
|
|
65
84
|
});
|
|
85
|
+
it('should return the same directory stats', async () => {
|
|
86
|
+
const candidates = [{
|
|
87
|
+
path: '/foo1.txt',
|
|
88
|
+
content: uint8ArrayFromString('Hello World!')
|
|
89
|
+
}, {
|
|
90
|
+
path: '/foo2.txt',
|
|
91
|
+
content: uint8ArrayFromString('Hello World!')
|
|
92
|
+
}];
|
|
93
|
+
const heliaCid = await importDirectoryToHelia(candidates, {
|
|
94
|
+
wrapWithDirectory: true
|
|
95
|
+
});
|
|
96
|
+
const kuboCid = await importDirectoryToKubo(candidates, {
|
|
97
|
+
cidVersion: 1,
|
|
98
|
+
chunker: `size-${1024 * 1024}`,
|
|
99
|
+
rawLeaves: true,
|
|
100
|
+
wrapWithDirectory: true
|
|
101
|
+
});
|
|
102
|
+
expect(heliaCid.toString()).to.equal(kuboCid.toString());
|
|
103
|
+
const heliaStat = await unixFs.stat(heliaCid, {
|
|
104
|
+
extended: true
|
|
105
|
+
});
|
|
106
|
+
const kuboStat = await kubo.api.files.stat(`/ipfs/${kuboCid}`, {
|
|
107
|
+
withLocal: true
|
|
108
|
+
});
|
|
109
|
+
expect(heliaStat.dagSize.toString()).to.equal(kuboStat.cumulativeSize.toString());
|
|
110
|
+
expect(heliaStat.dagSize.toString()).to.equal(kuboStat.sizeLocal?.toString());
|
|
111
|
+
// +1 because kubo doesn't count the root directory block
|
|
112
|
+
expect(heliaStat.blocks.toString()).to.equal((kuboStat.blocks + 1).toString());
|
|
113
|
+
});
|
|
114
|
+
it('fetches missing blocks during stat', async () => {
|
|
115
|
+
const chunkSize = 1024 * 1024;
|
|
116
|
+
const size = chunkSize * 10;
|
|
117
|
+
const candidate = () => (async function* () {
|
|
118
|
+
for (let i = 0; i < size; i += chunkSize) {
|
|
119
|
+
yield new Uint8Array(new Array(chunkSize).fill(0).map((val, index) => {
|
|
120
|
+
return Math.floor(Math.random() * 256);
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
}());
|
|
124
|
+
const largeFileCid = await importToKubo(candidate());
|
|
125
|
+
const info = await kubo.info();
|
|
126
|
+
await helia.libp2p.dial(info.multiaddrs.map(ma => multiaddr(ma)));
|
|
127
|
+
// pull all blocks from kubo
|
|
128
|
+
await drain(unixFs.cat(largeFileCid));
|
|
129
|
+
// check the root block
|
|
130
|
+
const block = await helia.blockstore.get(largeFileCid);
|
|
131
|
+
const node = dagPb.decode(block);
|
|
132
|
+
expect(node.Links).to.have.lengthOf(40);
|
|
133
|
+
const stats = await unixFs.stat(largeFileCid, {
|
|
134
|
+
extended: true
|
|
135
|
+
});
|
|
136
|
+
expect(stats.unixfs?.fileSize()).to.equal(10485760n);
|
|
137
|
+
expect(stats.blocks).to.equal(41n);
|
|
138
|
+
expect(stats.dagSize).to.equal(10488250n);
|
|
139
|
+
expect(stats.localSize).to.equal(10485760n);
|
|
140
|
+
// remove one of the blocks so we now have an incomplete DAG
|
|
141
|
+
await helia.blockstore.delete(node.Links[0].Hash);
|
|
142
|
+
// block count and local file/dag sizes should be smaller
|
|
143
|
+
const updatedStats = await unixFs.stat(largeFileCid, {
|
|
144
|
+
extended: true,
|
|
145
|
+
offline: true
|
|
146
|
+
});
|
|
147
|
+
expect(updatedStats.unixfs?.fileSize()).to.equal(10485760n);
|
|
148
|
+
expect(updatedStats.blocks).to.equal(40n);
|
|
149
|
+
expect(updatedStats.dagSize).to.equal(10226092n);
|
|
150
|
+
expect(updatedStats.localSize).to.equal(10223616n);
|
|
151
|
+
await new Promise((resolve) => {
|
|
152
|
+
setTimeout(() => {
|
|
153
|
+
resolve();
|
|
154
|
+
}, 1_000);
|
|
155
|
+
});
|
|
156
|
+
// block count and local file/dag sizes should be smaller
|
|
157
|
+
const finalStats = await unixFs.stat(largeFileCid, {
|
|
158
|
+
extended: true
|
|
159
|
+
});
|
|
160
|
+
// should have fetched missing block from Kubo
|
|
161
|
+
expect(finalStats).to.deep.equal(stats, 'did not fetch missing block');
|
|
162
|
+
});
|
|
66
163
|
});
|
|
67
164
|
//# sourceMappingURL=unixfs-files.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unixfs-files.spec.js","sourceRoot":"","sources":["../../src/unixfs-files.spec.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"unixfs-files.spec.js","sourceRoot":"","sources":["../../src/unixfs-files.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@helia/interop",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "Interop tests for Helia",
|
|
5
5
|
"license": "Apache-2.0 OR MIT",
|
|
6
6
|
"homepage": "https://github.com/ipfs/helia/tree/main/packages/interop#readme",
|
|
@@ -60,25 +60,27 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@chainsafe/libp2p-gossipsub": "^14.1.0",
|
|
62
62
|
"@helia/block-brokers": "^4.1.0",
|
|
63
|
-
"@helia/car": "^4.0.
|
|
63
|
+
"@helia/car": "^4.0.4",
|
|
64
64
|
"@helia/dag-cbor": "^4.0.3",
|
|
65
65
|
"@helia/dag-json": "^4.0.3",
|
|
66
66
|
"@helia/http": "^2.0.5",
|
|
67
67
|
"@helia/interface": "^5.2.1",
|
|
68
68
|
"@helia/ipns": "^8.2.0",
|
|
69
69
|
"@helia/json": "^4.0.3",
|
|
70
|
-
"@helia/mfs": "^
|
|
70
|
+
"@helia/mfs": "^5.0.0",
|
|
71
71
|
"@helia/routers": "^3.0.1",
|
|
72
72
|
"@helia/strings": "^4.0.3",
|
|
73
|
-
"@helia/unixfs": "^
|
|
73
|
+
"@helia/unixfs": "^5.0.0",
|
|
74
74
|
"@ipld/car": "^5.3.3",
|
|
75
75
|
"@ipld/dag-cbor": "^9.2.2",
|
|
76
|
+
"@ipld/dag-pb": "^4.1.3",
|
|
76
77
|
"@libp2p/crypto": "^5.0.7",
|
|
77
78
|
"@libp2p/interface": "^2.2.1",
|
|
78
79
|
"@libp2p/kad-dht": "^14.1.3",
|
|
79
80
|
"@libp2p/keychain": "^5.0.10",
|
|
80
81
|
"@libp2p/peer-id": "^5.0.8",
|
|
81
82
|
"@libp2p/websockets": "^9.0.13",
|
|
83
|
+
"@multiformats/multiaddr": "^12.4.0",
|
|
82
84
|
"@multiformats/sha3": "^3.0.2",
|
|
83
85
|
"aegir": "^45.1.1",
|
|
84
86
|
"helia": "^5.3.0",
|
package/src/unixfs-files.spec.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
/* eslint-env mocha */
|
|
2
2
|
|
|
3
3
|
import { unixfs } from '@helia/unixfs'
|
|
4
|
+
import * as dagPb from '@ipld/dag-pb'
|
|
5
|
+
import { multiaddr } from '@multiformats/multiaddr'
|
|
4
6
|
import { expect } from 'aegir/chai'
|
|
5
7
|
import { fixedSize } from 'ipfs-unixfs-importer/chunker'
|
|
6
8
|
import { balanced } from 'ipfs-unixfs-importer/layout'
|
|
9
|
+
import drain from 'it-drain'
|
|
10
|
+
import last from 'it-last'
|
|
7
11
|
import { CID } from 'multiformats/cid'
|
|
12
|
+
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
|
|
8
13
|
import { createHeliaNode } from './fixtures/create-helia.js'
|
|
9
14
|
import { createKuboNode } from './fixtures/create-kubo.js'
|
|
10
15
|
import type { AddOptions, UnixFS } from '@helia/unixfs'
|
|
11
16
|
import type { HeliaLibp2p } from 'helia'
|
|
12
|
-
import type { ByteStream } from 'ipfs-unixfs-importer'
|
|
17
|
+
import type { ByteStream, ImportCandidateStream } from 'ipfs-unixfs-importer'
|
|
13
18
|
import type { KuboNode } from 'ipfsd-ctl'
|
|
14
19
|
import type { AddOptions as KuboAddOptions } from 'kubo-rpc-client'
|
|
15
20
|
|
|
@@ -24,12 +29,32 @@ describe('@helia/unixfs - files', () => {
|
|
|
24
29
|
return cid
|
|
25
30
|
}
|
|
26
31
|
|
|
32
|
+
async function importDirectoryToHelia (data: ImportCandidateStream, opts?: Partial<AddOptions>): Promise<CID> {
|
|
33
|
+
const result = await last(unixFs.addAll(data, opts))
|
|
34
|
+
|
|
35
|
+
if (result == null) {
|
|
36
|
+
throw new Error('Nothing imported')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return CID.parse(result.cid.toString())
|
|
40
|
+
}
|
|
41
|
+
|
|
27
42
|
async function importToKubo (data: ByteStream, opts?: KuboAddOptions): Promise<CID> {
|
|
28
43
|
const result = await kubo.api.add(data, opts)
|
|
29
44
|
|
|
30
45
|
return CID.parse(result.cid.toString())
|
|
31
46
|
}
|
|
32
47
|
|
|
48
|
+
async function importDirectoryToKubo (data: ImportCandidateStream, opts?: KuboAddOptions): Promise<CID> {
|
|
49
|
+
const result = await last(kubo.api.addAll(data, opts))
|
|
50
|
+
|
|
51
|
+
if (result == null) {
|
|
52
|
+
throw new Error('Nothing imported')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return CID.parse(result.cid.toString())
|
|
56
|
+
}
|
|
57
|
+
|
|
33
58
|
async function expectSameCid (data: () => ByteStream, heliaOpts: Partial<AddOptions> = {}, kuboOpts: KuboAddOptions = {}): Promise<void> {
|
|
34
59
|
const heliaCid = await importToHelia(data(), {
|
|
35
60
|
// these are the default kubo options
|
|
@@ -85,4 +110,103 @@ describe('@helia/unixfs - files', () => {
|
|
|
85
110
|
|
|
86
111
|
await expectSameCid(candidate)
|
|
87
112
|
})
|
|
113
|
+
|
|
114
|
+
it('should return the same directory stats', async () => {
|
|
115
|
+
const candidates = [{
|
|
116
|
+
path: '/foo1.txt',
|
|
117
|
+
content: uint8ArrayFromString('Hello World!')
|
|
118
|
+
}, {
|
|
119
|
+
path: '/foo2.txt',
|
|
120
|
+
content: uint8ArrayFromString('Hello World!')
|
|
121
|
+
}]
|
|
122
|
+
|
|
123
|
+
const heliaCid = await importDirectoryToHelia(candidates, {
|
|
124
|
+
wrapWithDirectory: true
|
|
125
|
+
})
|
|
126
|
+
const kuboCid = await importDirectoryToKubo(candidates, {
|
|
127
|
+
cidVersion: 1,
|
|
128
|
+
chunker: `size-${1024 * 1024}`,
|
|
129
|
+
rawLeaves: true,
|
|
130
|
+
wrapWithDirectory: true
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
expect(heliaCid.toString()).to.equal(kuboCid.toString())
|
|
134
|
+
|
|
135
|
+
const heliaStat = await unixFs.stat(heliaCid, {
|
|
136
|
+
extended: true
|
|
137
|
+
})
|
|
138
|
+
const kuboStat = await kubo.api.files.stat(`/ipfs/${kuboCid}`, {
|
|
139
|
+
withLocal: true
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
expect(heliaStat.dagSize.toString()).to.equal(kuboStat.cumulativeSize.toString())
|
|
143
|
+
expect(heliaStat.dagSize.toString()).to.equal(kuboStat.sizeLocal?.toString())
|
|
144
|
+
|
|
145
|
+
// +1 because kubo doesn't count the root directory block
|
|
146
|
+
expect(heliaStat.blocks.toString()).to.equal((kuboStat.blocks + 1).toString())
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it('fetches missing blocks during stat', async () => {
|
|
150
|
+
const chunkSize = 1024 * 1024
|
|
151
|
+
const size = chunkSize * 10
|
|
152
|
+
|
|
153
|
+
const candidate = (): ByteStream => (async function * () {
|
|
154
|
+
for (let i = 0; i < size; i += chunkSize) {
|
|
155
|
+
yield new Uint8Array(new Array(chunkSize).fill(0).map((val, index) => {
|
|
156
|
+
return Math.floor(Math.random() * 256)
|
|
157
|
+
}))
|
|
158
|
+
}
|
|
159
|
+
}())
|
|
160
|
+
|
|
161
|
+
const largeFileCid = await importToKubo(candidate())
|
|
162
|
+
const info = await kubo.info()
|
|
163
|
+
|
|
164
|
+
await helia.libp2p.dial(info.multiaddrs.map(ma => multiaddr(ma)))
|
|
165
|
+
|
|
166
|
+
// pull all blocks from kubo
|
|
167
|
+
await drain(unixFs.cat(largeFileCid))
|
|
168
|
+
|
|
169
|
+
// check the root block
|
|
170
|
+
const block = await helia.blockstore.get(largeFileCid)
|
|
171
|
+
const node = dagPb.decode(block)
|
|
172
|
+
|
|
173
|
+
expect(node.Links).to.have.lengthOf(40)
|
|
174
|
+
|
|
175
|
+
const stats = await unixFs.stat(largeFileCid, {
|
|
176
|
+
extended: true
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
expect(stats.unixfs?.fileSize()).to.equal(10485760n)
|
|
180
|
+
expect(stats.blocks).to.equal(41n)
|
|
181
|
+
expect(stats.dagSize).to.equal(10488250n)
|
|
182
|
+
expect(stats.localSize).to.equal(10485760n)
|
|
183
|
+
|
|
184
|
+
// remove one of the blocks so we now have an incomplete DAG
|
|
185
|
+
await helia.blockstore.delete(node.Links[0].Hash)
|
|
186
|
+
|
|
187
|
+
// block count and local file/dag sizes should be smaller
|
|
188
|
+
const updatedStats = await unixFs.stat(largeFileCid, {
|
|
189
|
+
extended: true,
|
|
190
|
+
offline: true
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
expect(updatedStats.unixfs?.fileSize()).to.equal(10485760n)
|
|
194
|
+
expect(updatedStats.blocks).to.equal(40n)
|
|
195
|
+
expect(updatedStats.dagSize).to.equal(10226092n)
|
|
196
|
+
expect(updatedStats.localSize).to.equal(10223616n)
|
|
197
|
+
|
|
198
|
+
await new Promise<void>((resolve) => {
|
|
199
|
+
setTimeout(() => {
|
|
200
|
+
resolve()
|
|
201
|
+
}, 1_000)
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
// block count and local file/dag sizes should be smaller
|
|
205
|
+
const finalStats = await unixFs.stat(largeFileCid, {
|
|
206
|
+
extended: true
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
// should have fetched missing block from Kubo
|
|
210
|
+
expect(finalStats).to.deep.equal(stats, 'did not fetch missing block')
|
|
211
|
+
})
|
|
88
212
|
})
|