@autonomys/auto-dag-data 1.0.6 → 1.0.7

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,12 +1,14 @@
1
1
  import { BaseBlockstore, MemoryBlockstore } from 'blockstore-core'
2
- import { cidOfNode, cidToString } from '../src'
2
+ import { cidOfNode, cidToString, createSingleFileIpldNode } from '../src'
3
3
  import {
4
+ LINK_SIZE_IN_BYTES,
5
+ NODE_METADATA_SIZE,
4
6
  processFileToIPLDFormat,
5
7
  processFolderToIPLDFormat,
6
8
  processMetadataToIPLDFormat,
7
9
  } from '../src/ipld/chunker'
8
10
  import { createNode, decodeNode, PBNode } from '../src/ipld/utils'
9
- import { IPLDNodeData, MetadataType, OffchainMetadata } from '../src/metadata'
11
+ import { decodeIPLDNodeData, IPLDNodeData, MetadataType, OffchainMetadata } from '../src/metadata'
10
12
 
11
13
  describe('chunker', () => {
12
14
  describe('file creation', () => {
@@ -16,7 +18,12 @@ describe('chunker', () => {
16
18
  const name = 'test.txt'
17
19
  const blockstore = new MemoryBlockstore()
18
20
 
19
- await processFileToIPLDFormat(blockstore, bufferToIterable(Buffer.from(text)), size, name)
21
+ await processFileToIPLDFormat(
22
+ blockstore,
23
+ bufferToIterable(Buffer.from(text)),
24
+ BigInt(size),
25
+ name,
26
+ )
20
27
  const nodes = await nodesFromBlockstore(blockstore)
21
28
  expect(nodes.length).toBe(1)
22
29
 
@@ -31,7 +38,7 @@ describe('chunker', () => {
31
38
  expect(decoded.type).toBe(MetadataType.File)
32
39
  expect(Buffer.from(decoded.data ?? '').toString()).toBe(text)
33
40
  expect(decoded.linkDepth).toBe(0)
34
- expect(decoded.size).toBe(text.length)
41
+ expect(decoded.size?.toString()).toBe(text.length.toString())
35
42
 
36
43
  /// Check no links
37
44
  expect(node?.Links.length).toBe(0)
@@ -52,10 +59,10 @@ describe('chunker', () => {
52
59
  const headCID = await processFileToIPLDFormat(
53
60
  blockstore,
54
61
  bufferToIterable(Buffer.from(text)),
55
- size,
62
+ BigInt(size),
56
63
  name,
57
64
  {
58
- maxChunkSize,
65
+ maxNodeSize: maxChunkSize + NODE_METADATA_SIZE,
59
66
  maxLinkPerNode: maxChunkSize / 64,
60
67
  },
61
68
  )
@@ -72,7 +79,7 @@ describe('chunker', () => {
72
79
  expect(decoded.name).toBe(name)
73
80
  expect(decoded.type).toBe(MetadataType.File)
74
81
  expect(decoded.linkDepth).toBe(1)
75
- expect(decoded.size).toBe(text.length)
82
+ expect(decoded.size!.toString()).toBe(text.length.toString())
76
83
 
77
84
  nodes.forEach((node) => {
78
85
  if (cidToString(cidOfNode(node)) !== cidToString(headCID)) {
@@ -82,9 +89,10 @@ describe('chunker', () => {
82
89
  })
83
90
 
84
91
  it('create a file dag with inlinks', async () => {
85
- const maxChunkSize = 1000
92
+ const chunkLength = 1000
93
+ const maxNodeSize = chunkLength + NODE_METADATA_SIZE
86
94
  const chunkNum = 10
87
- const chunk = 'h'.repeat(maxChunkSize)
95
+ const chunk = 'h'.repeat(chunkLength)
88
96
  const name = 'test.txt'
89
97
  const text = chunk.repeat(chunkNum)
90
98
  const size = text.length
@@ -96,10 +104,10 @@ describe('chunker', () => {
96
104
  const headCID = await processFileToIPLDFormat(
97
105
  blockstore,
98
106
  bufferToIterable(Buffer.from(text)),
99
- size,
107
+ BigInt(size),
100
108
  name,
101
109
  {
102
- maxChunkSize,
110
+ maxNodeSize,
103
111
  maxLinkPerNode: 4,
104
112
  },
105
113
  )
@@ -136,7 +144,7 @@ describe('chunker', () => {
136
144
  const name = 'folder'
137
145
  const size = 1000
138
146
  const blockstore = new MemoryBlockstore()
139
- const headCID = processFolderToIPLDFormat(blockstore, links, name, size, {
147
+ const headCID = processFolderToIPLDFormat(blockstore, links, name, BigInt(size), {
140
148
  maxLinkPerNode: 4,
141
149
  })
142
150
 
@@ -149,7 +157,7 @@ describe('chunker', () => {
149
157
  expect(decoded.name).toBe(name)
150
158
  expect(decoded.type).toBe(MetadataType.Folder)
151
159
  expect(decoded.linkDepth).toBe(0)
152
- expect(decoded.size).toBe(size)
160
+ expect(decoded.size!.toString()).toBe(size.toString())
153
161
  })
154
162
 
155
163
  it('create a folder dag with inlinks', async () => {
@@ -163,7 +171,7 @@ describe('chunker', () => {
163
171
  const EXPECTED_NODE_COUNT = 4
164
172
 
165
173
  const blockstore = new MemoryBlockstore()
166
- const headCID = processFolderToIPLDFormat(blockstore, links, name, size, {
174
+ const headCID = processFolderToIPLDFormat(blockstore, links, name, BigInt(size), {
167
175
  maxLinkPerNode: 4,
168
176
  })
169
177
 
@@ -195,7 +203,7 @@ describe('chunker', () => {
195
203
  dataCid: 'test',
196
204
  name: 'test',
197
205
  mimeType: 'text/plain',
198
- totalSize: 1000,
206
+ totalSize: BigInt(1000),
199
207
  totalChunks: 10,
200
208
  chunks: [],
201
209
  }
@@ -211,15 +219,15 @@ describe('chunker', () => {
211
219
  type: 'file',
212
220
  dataCid: 'test',
213
221
  name: 'test',
214
- mimeType: 'text/plain'.repeat(100),
215
- totalSize: 1000,
222
+ mimeType: 'text/plain'.repeat(1000),
223
+ totalSize: BigInt(10000),
216
224
  totalChunks: 10,
217
225
  chunks: [],
218
226
  }
219
227
 
220
228
  const blockstore = new MemoryBlockstore()
221
229
  const headCID = await processMetadataToIPLDFormat(blockstore, metadata, {
222
- maxChunkSize: 200,
230
+ maxNodeSize: 2000,
223
231
  maxLinkPerNode: 2,
224
232
  })
225
233
  const nodes = await nodesFromBlockstore(blockstore)
@@ -235,13 +243,13 @@ describe('chunker', () => {
235
243
  const singleBufferCID = await processFileToIPLDFormat(
236
244
  blockstore,
237
245
  bufferToIterable(buffer),
238
- buffer.length,
246
+ BigInt(buffer.length),
239
247
  'test.txt',
240
248
  )
241
249
  const chunkedBufferCID = await processFileToIPLDFormat(
242
250
  chunkedBlockstore,
243
251
  separateBufferToIterable(buffer, 5),
244
- buffer.length,
252
+ BigInt(buffer.length),
245
253
  'test.txt',
246
254
  )
247
255
 
@@ -255,19 +263,74 @@ describe('chunker', () => {
255
263
  const singleBufferCID = await processFileToIPLDFormat(
256
264
  blockstore,
257
265
  bufferToIterable(buffer),
258
- buffer.length,
266
+ BigInt(buffer.length),
259
267
  'test.txt',
260
268
  )
261
269
  const chunkedBufferCID = await processFileToIPLDFormat(
262
270
  chunkedBlockstore,
263
271
  separateBufferToIterable(buffer, 5),
264
- buffer.length,
272
+ BigInt(buffer.length),
265
273
  'test.txt',
266
274
  )
267
275
 
268
276
  expect(singleBufferCID).toEqual(chunkedBufferCID)
269
277
  })
270
278
  })
279
+
280
+ describe('nodes sizes', () => {
281
+ it('file root node with inlinks', async () => {
282
+ const maxNodeSize = 1000
283
+ const maxChunkSize = maxNodeSize - NODE_METADATA_SIZE
284
+ const maxLinkPerNode = Math.floor(maxChunkSize / LINK_SIZE_IN_BYTES)
285
+ const buffer = Buffer.from('h'.repeat(maxChunkSize).repeat(maxLinkPerNode ** 3))
286
+
287
+ const blockstore = new MemoryBlockstore()
288
+
289
+ await processFileToIPLDFormat(
290
+ blockstore,
291
+ bufferToIterable(buffer),
292
+ BigInt(buffer.length),
293
+ 'test.txt',
294
+ {
295
+ maxNodeSize,
296
+ maxLinkPerNode,
297
+ },
298
+ )
299
+
300
+ const nodes = await nodesFromBlockstore(blockstore)
301
+
302
+ const inlinks = nodes.filter(
303
+ (node) =>
304
+ IPLDNodeData.decode(node.Data ?? new Uint8Array()).type === MetadataType.FileInlink,
305
+ )
306
+ inlinks.map((e) => e.Links.length).forEach((e) => expect(e).toBe(maxLinkPerNode))
307
+ })
308
+
309
+ it('folder root node with inlinks', async () => {
310
+ const maxLinkPerNode = 4
311
+ const maxNodeSize = maxLinkPerNode * LINK_SIZE_IN_BYTES + NODE_METADATA_SIZE
312
+ const links = Array.from({ length: 16 }, () =>
313
+ cidOfNode(createNode(Buffer.from(Math.random().toString()))),
314
+ )
315
+
316
+ const blockstore = new MemoryBlockstore()
317
+ processFolderToIPLDFormat(blockstore, links, 'test', BigInt(1000), {
318
+ maxLinkPerNode,
319
+ maxNodeSize,
320
+ })
321
+
322
+ const nodes = await nodesFromBlockstore(blockstore)
323
+ for (const node of nodes) {
324
+ expect(node.Data?.length).toBeLessThanOrEqual(maxNodeSize)
325
+ }
326
+
327
+ const inlinks = nodes.filter(
328
+ (node) =>
329
+ IPLDNodeData.decode(node.Data ?? new Uint8Array()).type === MetadataType.FolderInlink,
330
+ )
331
+ inlinks.map((e) => e.Links.length).forEach((e) => expect(e).toBe(maxLinkPerNode))
332
+ })
333
+ })
271
334
  })
272
335
 
273
336
  const bufferToIterable = (buffer: Buffer): AsyncIterable<Buffer> => {
@@ -4,7 +4,7 @@ import {
4
4
  createFileChunkIpldNode,
5
5
  createSingleFileIpldNode,
6
6
  } from '../src/index.js'
7
- import { createNode } from '../src/ipld/index.js'
7
+ import { createNode, DEFAULT_MAX_CHUNK_SIZE } from '../src/ipld/index.js'
8
8
  import { IPLDNodeData, MetadataType } from '../src/metadata/onchain/protobuf/OnchainMetadata.js'
9
9
 
10
10
  describe('node creation', () => {
@@ -15,7 +15,7 @@ describe('node creation', () => {
15
15
  const node = createSingleFileIpldNode(buffer, filename)
16
16
  const decoded = IPLDNodeData.decode(node.Data ?? new Uint8Array())
17
17
  expect(decoded.name).toBe(filename)
18
- expect(decoded.size).toBe(buffer.length)
18
+ expect(decoded.size!.toString()).toBe(buffer.length.toString())
19
19
  expect(Buffer.from(decoded.data ?? '').toString()).toBe(buffer.toString())
20
20
  })
21
21
 
@@ -25,23 +25,29 @@ describe('node creation', () => {
25
25
  const decoded = IPLDNodeData.decode(node.Data ?? new Uint8Array())
26
26
  expect(decoded.type).toBe(MetadataType.File)
27
27
  expect(decoded.name).toBeUndefined()
28
- expect(decoded.size).toBe(buffer.length)
28
+ expect(decoded.size!.toString()).toBe(buffer.length.toString())
29
29
  expect(Buffer.from(decoded.data ?? '').toString()).toBe(buffer.toString())
30
30
  })
31
31
 
32
+ it('single file root node | buffer too large', () => {
33
+ const maxNodeSize = DEFAULT_MAX_CHUNK_SIZE
34
+ const buffer = Buffer.from('h'.repeat(maxNodeSize))
35
+ expect(() => createSingleFileIpldNode(buffer, 'test.txt')).toThrow()
36
+ })
37
+
32
38
  it('chunked file root node | correctly params setup', () => {
33
39
  const links = Array.from({ length: 10 }, () =>
34
40
  cidOfNode(createNode(Buffer.from(Math.random().toString()))),
35
41
  )
36
- const size = 1000
42
+ const size = BigInt(1000)
37
43
  const linkDepth = 1
38
44
  const filename = 'test.txt'
39
- const node = createChunkedFileIpldNode(links, size, linkDepth, filename)
45
+ const node = createChunkedFileIpldNode(links, BigInt(size), linkDepth, filename)
40
46
 
41
47
  const decoded = IPLDNodeData.decode(node.Data ?? new Uint8Array())
42
48
  expect(decoded.type).toBe(MetadataType.File)
43
49
  expect(decoded.name).toBe(filename)
44
- expect(decoded.size).toBe(size)
50
+ expect(decoded.size!.toString()).toBe(size.toString())
45
51
  expect(decoded.linkDepth).toBe(linkDepth)
46
52
  })
47
53
 
@@ -49,14 +55,14 @@ describe('node creation', () => {
49
55
  const links = Array.from({ length: 10 }, () =>
50
56
  cidOfNode(createNode(Buffer.from(Math.random().toString()))),
51
57
  )
52
- const size = 1000
58
+ const size = BigInt(1000)
53
59
  const linkDepth = 1
54
60
  const node = createChunkedFileIpldNode(links, size, linkDepth)
55
61
 
56
62
  const decoded = IPLDNodeData.decode(node.Data ?? new Uint8Array())
57
63
  expect(decoded.type).toBe(MetadataType.File)
58
64
  expect(decoded.name).toBeUndefined()
59
- expect(decoded.size).toBe(size)
65
+ expect(decoded.size!.toString()).toBe(size.toString())
60
66
  expect(decoded.linkDepth).toBe(linkDepth)
61
67
  })
62
68
 
@@ -67,7 +73,7 @@ describe('node creation', () => {
67
73
  const decoded = IPLDNodeData.decode(node.Data ?? new Uint8Array())
68
74
  expect(decoded.type).toBe(MetadataType.FileChunk)
69
75
  expect(decoded.name).toBeUndefined()
70
- expect(decoded.size).toBe(buffer.length)
76
+ expect(decoded.size!.toString()).toBe(buffer.length.toString())
71
77
  expect(decoded.linkDepth).toBe(0)
72
78
  })
73
79
  })