This repository was archived by the owner on Feb 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathimport.js
164 lines (128 loc) · 5.62 KB
/
import.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* eslint-env mocha */
import all from 'it-all'
import drain from 'it-drain'
import { CID } from 'multiformats/cid'
import { sha256 } from 'multiformats/hashes/sha2'
import { expect } from 'aegir/chai'
import { getDescribe, getIt } from '../utils/mocha.js'
import { CarWriter, CarReader } from '@ipld/car'
import * as raw from 'multiformats/codecs/raw'
import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string'
import loadFixture from 'aegir/fixtures'
/**
*
* @param {number} num
*/
async function createBlocks (num) {
const blocks = []
for (let i = 0; i < num; i++) {
const bytes = uint8ArrayFromString('block-' + Math.random())
const digest = await sha256.digest(raw.encode(bytes))
const cid = CID.create(1, raw.code, digest)
blocks.push({ bytes, cid })
}
return blocks
}
/**
* @param {{ cid: CID, bytes: Uint8Array }[]} blocks
* @returns {Promise<AsyncIterable<Uint8Array>>}
*/
async function createCar (blocks) {
const rootBlock = blocks[0]
const { writer, out } = await CarWriter.create([rootBlock.cid])
writer.put(rootBlock)
.then(async () => {
for (const block of blocks.slice(1)) {
writer.put(block)
}
await writer.close()
})
return out
}
/**
* @typedef {import('ipfsd-ctl').Factory} Factory
*/
/**
* @param {Factory} factory
* @param {object} options
*/
export function testImport (factory, options) {
const describe = getDescribe(options)
const it = getIt(options)
describe('.dag.import', function () {
this.timeout(540 * 1000)
/** @type {import('ipfs-core-types').IPFS} */
let ipfs
before(async () => {
ipfs = (await factory.spawn()).api
})
after(() => factory.clean())
it('should import a car file', async () => {
const blocks = await createBlocks(5)
const car = await createCar(blocks)
const result = await all(ipfs.dag.import(car))
expect(result).to.have.lengthOf(1)
// @ts-expect-error chai types are messed up
expect(result).to.have.nested.deep.property('[0].root.cid', blocks[0].cid)
for (const { cid } of blocks) {
await expect(ipfs.block.get(cid)).to.eventually.be.ok()
}
await expect(all(ipfs.pin.ls({ paths: blocks[0].cid }))).to.eventually.have.lengthOf(1)
.and.have.nested.property('[0].type', 'recursive')
})
it('should import a car file without pinning the roots', async () => {
const blocks = await createBlocks(5)
const car = await createCar(blocks)
await all(ipfs.dag.import(car, {
pinRoots: false
}))
await expect(all(ipfs.pin.ls({ paths: blocks[0].cid }))).to.eventually.be.rejectedWith(/is not pinned/)
})
it('should import multiple car files', async () => {
const blocks1 = await createBlocks(5)
const car1 = await createCar(blocks1)
const blocks2 = await createBlocks(5)
const car2 = await createCar(blocks2)
const result = await all(ipfs.dag.import([car1, car2]))
expect(result).to.have.lengthOf(2)
expect(result).to.deep.include({ root: { cid: blocks1[0].cid, pinErrorMsg: '' } })
expect(result).to.deep.include({ root: { cid: blocks2[0].cid, pinErrorMsg: '' } })
for (const { cid } of blocks1) {
await expect(ipfs.block.get(cid)).to.eventually.be.ok()
}
for (const { cid } of blocks2) {
await expect(ipfs.block.get(cid)).to.eventually.be.ok()
}
})
it('should import car with roots but no blocks', async () => {
const input = loadFixture('test/fixtures/car/combined_naked_roots_genesis_and_128.car', 'interface-ipfs-core')
const reader = await CarReader.fromBytes(input)
const cids = await reader.getRoots()
expect(cids).to.have.lengthOf(2)
// naked roots car does not contain blocks
const result1 = await all(ipfs.dag.import(async function * () { yield input }()))
expect(result1).to.deep.include({ root: { cid: cids[0], pinErrorMsg: 'blockstore: block not found' } })
expect(result1).to.deep.include({ root: { cid: cids[1], pinErrorMsg: 'blockstore: block not found' } })
await drain(ipfs.dag.import(async function * () { yield loadFixture('test/fixtures/car/lotus_devnet_genesis_shuffled_nulroot.car', 'interface-ipfs-core') }()))
// have some of the blocks now, should be able to pin one root
const result2 = await all(ipfs.dag.import(async function * () { yield input }()))
expect(result2).to.deep.include({ root: { cid: cids[0], pinErrorMsg: '' } })
expect(result2).to.deep.include({ root: { cid: cids[1], pinErrorMsg: 'blockstore: block not found' } })
await drain(ipfs.dag.import(async function * () { yield loadFixture('test/fixtures/car/lotus_testnet_export_128.car', 'interface-ipfs-core') }()))
// have all of the blocks now, should be able to pin both
const result3 = await all(ipfs.dag.import(async function * () { yield input }()))
expect(result3).to.deep.include({ root: { cid: cids[0], pinErrorMsg: '' } })
expect(result3).to.deep.include({ root: { cid: cids[1], pinErrorMsg: '' } })
})
it('should import lotus devnet genesis shuffled nulroot', async () => {
const input = loadFixture('test/fixtures/car/lotus_devnet_genesis_shuffled_nulroot.car', 'interface-ipfs-core')
const reader = await CarReader.fromBytes(input)
const cids = await reader.getRoots()
expect(cids).to.have.lengthOf(1)
expect(cids[0].toString()).to.equal('bafkqaaa')
const result = await all(ipfs.dag.import(async function * () { yield input }()))
// @ts-expect-error chai types are messed up
expect(result).to.have.nested.deep.property('[0].root.cid', cids[0])
})
})
}