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

Commit de2ab6e

Browse files
committed
fix: types, make tests pass, don't allow partial DAG
1 parent 0bb4104 commit de2ab6e

File tree

2 files changed

+27
-27
lines changed

2 files changed

+27
-27
lines changed

packages/ipfs-cli/src/commands/dag/export.js

+26-26
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ const { default: parseDuration } = require('parse-duration')
55
const LegacyCID = require('cids')
66
const { CID } = require('multiformats/cid')
77
const Block = require('multiformats/block')
8-
const { base58 } = require('multiformats/bases/base58')
8+
const { base58btc } = require('multiformats/bases/base58')
99
const { CarWriter } = require('@ipld/car/writer')
10+
/**
11+
* @typedef {import('multiformats/codecs/interface').BlockCodec<number, any>} BlockCodec
12+
*/
13+
/** @type {BlockCodec[]} */
1014
const codecs = [
1115
require('@ipld/dag-pb'),
1216
require('@ipld/dag-cbor'),
1317
require('@ipld/dag-json')
14-
].reduce((codecs, codec) => {
18+
].reduce((/** @type {BlockCodec[]} */ codecs, /** @type {BlockCodec} */ codec) => {
1519
codecs[codec.code] = codec
1620
return codecs
1721
}, [])
@@ -53,34 +57,37 @@ module.exports = {
5357
const { writer, out } = await CarWriter.create([cid])
5458
Readable.from(out).pipe(process.stdout)
5559

56-
const complete = await traverseWrite(ipfs, options, cid, writer)
60+
await traverseWrite(ipfs, options, cid, writer)
5761
writer.close()
58-
59-
if (!complete) {
60-
print('cannot decode links in all blocks, DAG may be incomplete')
61-
}
6262
}
6363
}
6464

6565
/**
6666
* @param {IPFS} ipfs
6767
* @param {{ timeout?: number}} options
6868
* @param {CID} cid
69-
* @returns {Promise<{cid:CID, bytes:Uint8Array, links:CID[]|null}>}
69+
* @returns {Promise<{cid:CID, bytes:Uint8Array, links:CID[]}>}
7070
*/
7171
const getBlock = async (ipfs, options, cid) => {
72-
cid = CID.asCID(cid)
7372
const result = await ipfs.block.get(new LegacyCID(cid.bytes), options)
73+
if (!result) {
74+
throw new Error(`Failed to fetch block ${cid}`)
75+
}
76+
const resultCid = CID.asCID(result.cid)
77+
if (!resultCid || !resultCid.equals(cid)) {
78+
// shouldn't happen, but let's sanity check
79+
throw new Error(`Fetched CID ${result.cid} does not match requested ${cid}`)
80+
}
7481
const bytes = result.data
75-
let links = null
82+
/** @type {CID[]} */
83+
let links = []
7684
const codec = codecs[result.cid.code]
7785
if (codec) {
78-
const block = Block.createUnsafe({ bytes: result.data, cid: CID.asCID(result.cid), codec })
86+
const block = Block.createUnsafe({ bytes: result.data, cid, codec })
7987
links = [...block.links()].map((l) => l[1])
80-
} else if (NO_LINKS_CODECS.includes(result.cid.code)) {
81-
// these blocks are known not to contain any IPLD links
82-
links = []
83-
} // else we may have a block with links that we can't decode
88+
} else if (!NO_LINKS_CODECS.includes(result.cid.code)) {
89+
throw new Error(`Can't decode links in block with codec 0x${result.cid.code.toString(16)} to form complete DAG`)
90+
}
8491
return { cid, bytes, links }
8592
}
8693

@@ -90,26 +97,19 @@ const getBlock = async (ipfs, options, cid) => {
9097
* @param {CID} cid
9198
* @param {BlockWriter} writer
9299
* @param {Set<string>} seen
93-
* @returns {boolean} complete DAG
100+
* @returns {Promise<void>}
94101
*/
95102
async function traverseWrite (ipfs, options, cid, writer, seen = new Set()) {
96-
const b58Cid = cid.toString(base58)
103+
const b58Cid = cid.toString(base58btc)
97104
if (seen.has(b58Cid)) {
98-
return true
105+
return
99106
}
100107
const block = await getBlock(ipfs, options, cid)
101108
await writer.put(block)
102109
seen.add(b58Cid)
103-
if (block.links === null) {
104-
return false // potentially incomplete DAG
105-
}
106110

107111
// recursive traversal of all links
108-
let complete = true
109112
for (const link of block.links) {
110-
if (!await traverseWrite(ipfs, options, link, writer, seen)) {
111-
complete = false
112-
}
113+
await traverseWrite(ipfs, options, link, writer, seen)
113114
}
114-
return complete
115115
}

packages/ipfs-cli/test/commands.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
const { expect } = require('aegir/utils/chai')
55
const cli = require('./utils/cli')
66

7-
const commandCount = 110
7+
const commandCount = 111
88

99
describe('commands', () => {
1010
it('list the commands', async () => {

0 commit comments

Comments
 (0)