create-sia-app 0.1.1

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.
Files changed (112) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +179 -0
  3. package/package.json +29 -0
  4. package/template/CLAUDE.md +160 -0
  5. package/template/README.md +102 -0
  6. package/template/_gitignore +5 -0
  7. package/template/biome.json +40 -0
  8. package/template/index.html +13 -0
  9. package/template/package.json +30 -0
  10. package/template/rust/README.md +16 -0
  11. package/template/rust/sia-sdk-rs/.changeset/added_cancel_function_to_cancel_inflight_packed_uploads.md +6 -0
  12. package/template/rust/sia-sdk-rs/.changeset/check_if_we_have_enough_hosts_prior_to_encoding_in_upload_slabs.md +16 -0
  13. package/template/rust/sia-sdk-rs/.changeset/fix_slab_length_in_packed_object.md +5 -0
  14. package/template/rust/sia-sdk-rs/.changeset/fix_upload_racing_race_conditon.md +13 -0
  15. package/template/rust/sia-sdk-rs/.changeset/improved_parallelism_of_packed_uploads.md +5 -0
  16. package/template/rust/sia-sdk-rs/.changeset/progress_callback_will_now_be_called_as_expected_for_packed_uploads.md +5 -0
  17. package/template/rust/sia-sdk-rs/.github/dependabot.yml +10 -0
  18. package/template/rust/sia-sdk-rs/.github/workflows/main.yml +36 -0
  19. package/template/rust/sia-sdk-rs/.github/workflows/prepare-release.yml +34 -0
  20. package/template/rust/sia-sdk-rs/.github/workflows/release.yml +30 -0
  21. package/template/rust/sia-sdk-rs/.rustfmt.toml +4 -0
  22. package/template/rust/sia-sdk-rs/Cargo.lock +4127 -0
  23. package/template/rust/sia-sdk-rs/Cargo.toml +3 -0
  24. package/template/rust/sia-sdk-rs/LICENSE +21 -0
  25. package/template/rust/sia-sdk-rs/README.md +30 -0
  26. package/template/rust/sia-sdk-rs/indexd/CHANGELOG.md +79 -0
  27. package/template/rust/sia-sdk-rs/indexd/Cargo.toml +79 -0
  28. package/template/rust/sia-sdk-rs/indexd/benches/upload.rs +258 -0
  29. package/template/rust/sia-sdk-rs/indexd/src/app_client.rs +1710 -0
  30. package/template/rust/sia-sdk-rs/indexd/src/builder.rs +354 -0
  31. package/template/rust/sia-sdk-rs/indexd/src/download.rs +379 -0
  32. package/template/rust/sia-sdk-rs/indexd/src/hosts.rs +659 -0
  33. package/template/rust/sia-sdk-rs/indexd/src/lib.rs +827 -0
  34. package/template/rust/sia-sdk-rs/indexd/src/mock.rs +162 -0
  35. package/template/rust/sia-sdk-rs/indexd/src/object_encryption.rs +125 -0
  36. package/template/rust/sia-sdk-rs/indexd/src/quic.rs +575 -0
  37. package/template/rust/sia-sdk-rs/indexd/src/rhp4.rs +52 -0
  38. package/template/rust/sia-sdk-rs/indexd/src/slabs.rs +497 -0
  39. package/template/rust/sia-sdk-rs/indexd/src/upload.rs +629 -0
  40. package/template/rust/sia-sdk-rs/indexd/src/wasm_time.rs +41 -0
  41. package/template/rust/sia-sdk-rs/indexd/src/web_transport.rs +398 -0
  42. package/template/rust/sia-sdk-rs/indexd_ffi/CHANGELOG.md +76 -0
  43. package/template/rust/sia-sdk-rs/indexd_ffi/Cargo.toml +47 -0
  44. package/template/rust/sia-sdk-rs/indexd_ffi/examples/python/README.md +10 -0
  45. package/template/rust/sia-sdk-rs/indexd_ffi/examples/python/example.py +130 -0
  46. package/template/rust/sia-sdk-rs/indexd_ffi/src/bin/uniffi-bindgen.rs +3 -0
  47. package/template/rust/sia-sdk-rs/indexd_ffi/src/builder.rs +377 -0
  48. package/template/rust/sia-sdk-rs/indexd_ffi/src/io.rs +155 -0
  49. package/template/rust/sia-sdk-rs/indexd_ffi/src/lib.rs +1039 -0
  50. package/template/rust/sia-sdk-rs/indexd_ffi/src/logging.rs +58 -0
  51. package/template/rust/sia-sdk-rs/indexd_ffi/src/tls.rs +23 -0
  52. package/template/rust/sia-sdk-rs/indexd_wasm/Cargo.toml +33 -0
  53. package/template/rust/sia-sdk-rs/indexd_wasm/src/lib.rs +818 -0
  54. package/template/rust/sia-sdk-rs/knope.toml +54 -0
  55. package/template/rust/sia-sdk-rs/sia_derive/CHANGELOG.md +38 -0
  56. package/template/rust/sia-sdk-rs/sia_derive/Cargo.toml +19 -0
  57. package/template/rust/sia-sdk-rs/sia_derive/src/lib.rs +278 -0
  58. package/template/rust/sia-sdk-rs/sia_sdk/CHANGELOG.md +91 -0
  59. package/template/rust/sia-sdk-rs/sia_sdk/Cargo.toml +59 -0
  60. package/template/rust/sia-sdk-rs/sia_sdk/benches/merkle_root.rs +12 -0
  61. package/template/rust/sia-sdk-rs/sia_sdk/src/blake2.rs +22 -0
  62. package/template/rust/sia-sdk-rs/sia_sdk/src/consensus.rs +767 -0
  63. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding/v1.rs +257 -0
  64. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding/v2.rs +291 -0
  65. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding.rs +26 -0
  66. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding_async/v2.rs +367 -0
  67. package/template/rust/sia-sdk-rs/sia_sdk/src/encoding_async.rs +6 -0
  68. package/template/rust/sia-sdk-rs/sia_sdk/src/encryption.rs +303 -0
  69. package/template/rust/sia-sdk-rs/sia_sdk/src/erasure_coding.rs +347 -0
  70. package/template/rust/sia-sdk-rs/sia_sdk/src/lib.rs +15 -0
  71. package/template/rust/sia-sdk-rs/sia_sdk/src/macros.rs +435 -0
  72. package/template/rust/sia-sdk-rs/sia_sdk/src/merkle.rs +112 -0
  73. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/merkle.rs +357 -0
  74. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/rpc.rs +1507 -0
  75. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/types.rs +146 -0
  76. package/template/rust/sia-sdk-rs/sia_sdk/src/rhp.rs +7 -0
  77. package/template/rust/sia-sdk-rs/sia_sdk/src/seed.rs +278 -0
  78. package/template/rust/sia-sdk-rs/sia_sdk/src/signing.rs +236 -0
  79. package/template/rust/sia-sdk-rs/sia_sdk/src/types/common.rs +677 -0
  80. package/template/rust/sia-sdk-rs/sia_sdk/src/types/currency.rs +450 -0
  81. package/template/rust/sia-sdk-rs/sia_sdk/src/types/specifier.rs +110 -0
  82. package/template/rust/sia-sdk-rs/sia_sdk/src/types/spendpolicy.rs +778 -0
  83. package/template/rust/sia-sdk-rs/sia_sdk/src/types/utils.rs +117 -0
  84. package/template/rust/sia-sdk-rs/sia_sdk/src/types/v1.rs +1737 -0
  85. package/template/rust/sia-sdk-rs/sia_sdk/src/types/v2.rs +1726 -0
  86. package/template/rust/sia-sdk-rs/sia_sdk/src/types/work.rs +59 -0
  87. package/template/rust/sia-sdk-rs/sia_sdk/src/types.rs +16 -0
  88. package/template/scripts/setup-rust.js +29 -0
  89. package/template/src/App.tsx +13 -0
  90. package/template/src/components/DevNote.tsx +21 -0
  91. package/template/src/components/auth/ApproveScreen.tsx +84 -0
  92. package/template/src/components/auth/AuthFlow.tsx +77 -0
  93. package/template/src/components/auth/ConnectScreen.tsx +214 -0
  94. package/template/src/components/auth/LoadingScreen.tsx +8 -0
  95. package/template/src/components/auth/RecoveryScreen.tsx +182 -0
  96. package/template/src/components/upload/UploadZone.tsx +314 -0
  97. package/template/src/index.css +9 -0
  98. package/template/src/lib/constants.ts +8 -0
  99. package/template/src/lib/format.ts +35 -0
  100. package/template/src/lib/hex.ts +13 -0
  101. package/template/src/lib/sdk.ts +25 -0
  102. package/template/src/lib/wasm-env.ts +5 -0
  103. package/template/src/main.tsx +12 -0
  104. package/template/src/stores/auth.ts +86 -0
  105. package/template/tsconfig.app.json +31 -0
  106. package/template/tsconfig.json +7 -0
  107. package/template/tsconfig.node.json +26 -0
  108. package/template/vite.config.ts +18 -0
  109. package/template/wasm/indexd_wasm/indexd_wasm.d.ts +309 -0
  110. package/template/wasm/indexd_wasm/indexd_wasm.js +1507 -0
  111. package/template/wasm/indexd_wasm/indexd_wasm_bg.wasm +0 -0
  112. package/template/wasm/indexd_wasm/package.json +31 -0
@@ -0,0 +1,347 @@
1
+ use crate::rhp::{SECTOR_SIZE, SEGMENT_SIZE};
2
+ use reed_solomon_erasure::galois_8::ReedSolomon;
3
+ use thiserror::Error;
4
+ use tokio::io::{self, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
5
+
6
+ #[derive(Debug, Error)]
7
+ pub enum Error {
8
+ #[error("ReedSolomon error: {0}")]
9
+ ReedSolomon(#[from] reed_solomon_erasure::Error),
10
+
11
+ #[error("IO error: {0}")]
12
+ Io(#[from] io::Error),
13
+ }
14
+
15
+ pub type Result<T> = std::result::Result<T, Error>;
16
+
17
+ pub struct ErasureCoder {
18
+ encoder: ReedSolomon,
19
+ data_shards: usize,
20
+ parity_shards: usize,
21
+ }
22
+
23
+ impl ErasureCoder {
24
+ pub fn new(data_shards: usize, parity_shards: usize) -> Result<Self> {
25
+ Ok(ErasureCoder {
26
+ encoder: ReedSolomon::new(data_shards, parity_shards)?,
27
+ data_shards,
28
+ parity_shards,
29
+ })
30
+ }
31
+
32
+ /// encodes the shards using reed solomon erasure coding,
33
+ /// computing the parity shards and overwriting their values.
34
+ pub fn encode_shards(&self, shards: &mut [Vec<u8>]) -> Result<()> {
35
+ self.encoder.encode(shards)?;
36
+ Ok(())
37
+ }
38
+
39
+ /// reconstructs the missing shards from the available ones.
40
+ pub fn reconstruct(&self, shards: &mut [Option<Vec<u8>>]) -> Result<()> {
41
+ self.encoder.reconstruct(shards)?;
42
+ Ok(())
43
+ }
44
+
45
+ /// reconstructs the missing datashards from the available ones.
46
+ pub fn reconstruct_data_shards(&self, shards: &mut [Option<Vec<u8>>]) -> Result<()> {
47
+ self.encoder.reconstruct_data(shards)?;
48
+ Ok(())
49
+ }
50
+
51
+ /// write_data_shards writes up to 'n' bytes from the given reconstructed shards
52
+ /// to the provided writer, skipping the first `skip` bytes.
53
+ pub async fn write_data_shards<W: AsyncWrite + Unpin>(
54
+ w: &mut W,
55
+ shards: &[Option<Vec<u8>>],
56
+ mut skip: usize,
57
+ mut n: usize,
58
+ ) -> Result<()> {
59
+ let row_bytes = shards.len() * SEGMENT_SIZE;
60
+ let rows = skip / row_bytes;
61
+ let mut offset = rows * SEGMENT_SIZE;
62
+ skip %= row_bytes;
63
+ while n > 0 {
64
+ for shard in shards {
65
+ if n == 0 {
66
+ return Ok(());
67
+ } else if skip > SEGMENT_SIZE {
68
+ skip -= SEGMENT_SIZE;
69
+ continue;
70
+ }
71
+
72
+ let segment = shard.as_ref().ok_or(Error::ReedSolomon(
73
+ reed_solomon_erasure::Error::TooFewDataShards,
74
+ ))?;
75
+
76
+ let start = offset + skip;
77
+ let length = n.min(SEGMENT_SIZE - skip);
78
+
79
+ w.write_all(&segment[start..start + length]).await?;
80
+ n -= length;
81
+ skip = 0;
82
+ }
83
+ offset += SEGMENT_SIZE;
84
+ }
85
+ Ok(())
86
+ }
87
+
88
+ pub async fn read_slab_shards<R: AsyncRead + Unpin>(
89
+ r: &mut R,
90
+ data_shards: usize,
91
+ shards: &mut [Vec<u8>],
92
+ ) -> Result<usize> {
93
+ // limit total read size to the size of the slab's data shards
94
+ let mut r = r.take(data_shards as u64 * SECTOR_SIZE as u64);
95
+ let mut data_size = 0;
96
+ for off in (0..SECTOR_SIZE).step_by(SEGMENT_SIZE) {
97
+ let start = off;
98
+ let end = off + SEGMENT_SIZE;
99
+ for shard in &mut shards[..data_shards].iter_mut() {
100
+ let segment = &mut shard[start..end];
101
+ let mut bytes_read = 0;
102
+ while bytes_read < SEGMENT_SIZE {
103
+ // note: read_exact + UnexpectedEoF is not used due to the documentation
104
+ // saying "the contents of buf are unspecified." when UnexpectedEoF is
105
+ // returned. It's *most likely* fine to rely on the contents being
106
+ // a partial read, but better to not make the assumption for every
107
+ // possible implementation of the Read trait.
108
+ let n = r.read(&mut segment[bytes_read..]).await?;
109
+ if n == 0 {
110
+ return Ok(data_size);
111
+ }
112
+ bytes_read += n;
113
+ data_size += n;
114
+ }
115
+ }
116
+ }
117
+ Ok(data_size)
118
+ }
119
+
120
+ /// read_shards reads data from the given reader into a vector of shards.
121
+ pub async fn read_shards<R: AsyncRead + Unpin>(
122
+ &self,
123
+ r: &mut R,
124
+ ) -> Result<(Vec<Vec<u8>>, u32)> {
125
+ let total_shards = self.data_shards + self.parity_shards;
126
+ let mut shards = vec![vec![0u8; SECTOR_SIZE]; total_shards];
127
+ let mut r = r.take(self.data_shards as u64 * SECTOR_SIZE as u64);
128
+ let slab_size = Self::read_slab_shards(&mut r, self.data_shards, &mut shards).await?;
129
+ Ok((shards, slab_size as u32))
130
+ }
131
+ }
132
+
133
+ #[cfg(test)]
134
+ mod tests {
135
+ use rand::Rng;
136
+
137
+ use super::*;
138
+
139
+ #[tokio::test]
140
+ async fn test_encode_shards() {
141
+ let data_shards = 2;
142
+ let parity_shards = 3;
143
+ let coder = ErasureCoder::new(data_shards, parity_shards).unwrap();
144
+
145
+ let mut shards: Vec<Vec<u8>> = [
146
+ vec![1u8; SECTOR_SIZE],
147
+ vec![2u8; SECTOR_SIZE],
148
+ vec![0u8; SECTOR_SIZE],
149
+ vec![0u8; SECTOR_SIZE],
150
+ vec![0u8; SECTOR_SIZE],
151
+ ]
152
+ .into();
153
+
154
+ coder.encode_shards(&mut shards).unwrap();
155
+
156
+ let expected_shards: Vec<Vec<u8>> = vec![
157
+ vec![1u8; SECTOR_SIZE],
158
+ vec![2u8; SECTOR_SIZE],
159
+ vec![7u8; SECTOR_SIZE], // parity shard 1
160
+ vec![4u8; SECTOR_SIZE], // parity shard 2
161
+ vec![13u8; SECTOR_SIZE], // parity shard 3
162
+ ];
163
+ assert_eq!(shards, expected_shards);
164
+
165
+ // reconstruct every shard
166
+ for i in 0..shards.len() {
167
+ let mut shards: Vec<Option<Vec<u8>>> = shards.iter().cloned().map(Some).collect();
168
+ shards[i] = None;
169
+ coder.reconstruct(&mut shards).unwrap();
170
+ let shards: Vec<Vec<u8>> = shards.into_iter().map(|s| s.unwrap()).collect();
171
+ assert_eq!(shards, expected_shards);
172
+ }
173
+
174
+ // reconstruct data shards
175
+ for i in 0..data_shards {
176
+ let mut shards: Vec<Option<Vec<u8>>> = shards.iter().cloned().map(Some).collect();
177
+ shards[i] = None;
178
+ coder.reconstruct_data_shards(&mut shards).unwrap();
179
+ let shards: Vec<Vec<u8>> = shards.into_iter().map(|s| s.unwrap()).collect();
180
+ assert_eq!(shards, expected_shards);
181
+ }
182
+ }
183
+
184
+ #[tokio::test]
185
+ async fn test_striped_read() {
186
+ const DATA_SHARDS: usize = 3;
187
+ const PARITY_SHARDS: usize = 2;
188
+
189
+ let test_cases = vec![
190
+ // (data size, expected size)
191
+ (100, 100), // under
192
+ (SECTOR_SIZE * DATA_SHARDS, SECTOR_SIZE * DATA_SHARDS), // exact
193
+ (2 * SECTOR_SIZE * DATA_SHARDS, SECTOR_SIZE * DATA_SHARDS), // over
194
+ ];
195
+
196
+ let coder = ErasureCoder::new(DATA_SHARDS, PARITY_SHARDS).unwrap();
197
+
198
+ for (data_size, expected_size) in test_cases {
199
+ let mut data = vec![0u8; data_size];
200
+ rand::rng().fill_bytes(&mut data);
201
+
202
+ let (shards, size) = coder.read_shards(&mut &data[..]).await.unwrap();
203
+
204
+ assert_eq!(
205
+ size as usize, expected_size,
206
+ "data size {data_size} mismatch"
207
+ );
208
+ assert_eq!(
209
+ shards.len(),
210
+ DATA_SHARDS + PARITY_SHARDS,
211
+ "data size {data_size} shard count mismatch"
212
+ );
213
+
214
+ for (i, data) in data[..size as usize].chunks(64).enumerate() {
215
+ let mut chunk = [0u8; SEGMENT_SIZE];
216
+ chunk[..data.len()].copy_from_slice(data); // pad it out with zeros
217
+ let index = i % DATA_SHARDS;
218
+ let offset = (i / DATA_SHARDS) * SEGMENT_SIZE;
219
+
220
+ assert_eq!(
221
+ &shards[index][offset..offset + 64],
222
+ chunk,
223
+ "data size {data_size} shard {index} mismatch at offset {offset}"
224
+ );
225
+ }
226
+ }
227
+ }
228
+
229
+ #[tokio::test]
230
+ async fn test_striped_read_write() {
231
+ const DATA_SHARDS: usize = 4;
232
+ const PARITY_SHARDS: usize = 1;
233
+ let coder = ErasureCoder::new(DATA_SHARDS, PARITY_SHARDS).unwrap();
234
+
235
+ let mut data = vec![0u8; SECTOR_SIZE * 7 / 2]; // 3.5 shards of data
236
+ data[..SECTOR_SIZE].fill(1);
237
+ data[SECTOR_SIZE..2 * SECTOR_SIZE].fill(2);
238
+ data[2 * SECTOR_SIZE..3 * SECTOR_SIZE].fill(3);
239
+ data[3 * SECTOR_SIZE..].fill(4);
240
+
241
+ let (mut shards, size) = coder.read_shards(&mut data.as_slice()).await.unwrap();
242
+
243
+ // we expect 5 shards and the last one is an empty parity shard
244
+ assert_eq!(shards.len(), 5);
245
+ assert_eq!(size as usize, SECTOR_SIZE * 7 / 2);
246
+ assert_eq!(shards[4], [0u8; SECTOR_SIZE]);
247
+
248
+ for shard in &shards[..4] {
249
+ // every shard should be of SECTOR_SIZE
250
+ assert_eq!(shard.len(), SECTOR_SIZE);
251
+
252
+ // first quarter of every shard is 1s
253
+ assert_eq!(shard[0..SECTOR_SIZE / 4], [1u8; SECTOR_SIZE / 4]);
254
+
255
+ // second quarter is 2s
256
+ assert_eq!(
257
+ shard[SECTOR_SIZE / 4..SECTOR_SIZE / 2],
258
+ [2u8; SECTOR_SIZE / 4]
259
+ );
260
+
261
+ // third quarter is 3s
262
+ assert_eq!(
263
+ shard[SECTOR_SIZE / 2..SECTOR_SIZE / 4 * 3],
264
+ [3u8; SECTOR_SIZE / 4]
265
+ );
266
+
267
+ // half of the fourth quarter is 4s
268
+ assert_eq!(
269
+ shard[SECTOR_SIZE / 4 * 3..SECTOR_SIZE / 8 * 7],
270
+ [4u8; SECTOR_SIZE / 8]
271
+ );
272
+
273
+ // remainder is padded with 0s
274
+ assert_eq!(shard[SECTOR_SIZE / 8 * 7..], [0u8; SECTOR_SIZE / 8]);
275
+ }
276
+
277
+ // encoding the read shards should succeed without errors and cause the
278
+ // parity shard to be filled
279
+ coder.encode_shards(&mut shards).unwrap();
280
+ assert_ne!(shards[4], [0u8; SECTOR_SIZE]);
281
+
282
+ // joining the shards back together should result in the original data
283
+ let shards: Vec<Option<Vec<u8>>> = shards.iter().cloned().map(Some).collect();
284
+ let mut joined_data = Vec::new();
285
+ ErasureCoder::write_data_shards(&mut joined_data, &shards[..DATA_SHARDS], 0, data.len())
286
+ .await
287
+ .unwrap();
288
+ assert_eq!(joined_data, data);
289
+
290
+ // join only the first half
291
+ let mut joined_data = Vec::new();
292
+ ErasureCoder::write_data_shards(
293
+ &mut joined_data,
294
+ &shards[..DATA_SHARDS],
295
+ 0,
296
+ data.len() / 2,
297
+ )
298
+ .await
299
+ .unwrap();
300
+ assert_eq!(joined_data, data[..data.len() / 2]);
301
+
302
+ // join only the second half
303
+ let mut joined_data = Vec::new();
304
+ ErasureCoder::write_data_shards(
305
+ &mut joined_data,
306
+ &shards[..DATA_SHARDS],
307
+ data.len() / 2,
308
+ data.len() / 2,
309
+ )
310
+ .await
311
+ .unwrap();
312
+ assert_eq!(joined_data, data[data.len() / 2..]);
313
+ }
314
+
315
+ #[tokio::test]
316
+ async fn test_read_encoded_write_reconstructed() {
317
+ const DATA_SHARDS: usize = 4;
318
+ const PARITY_SHARDS: usize = 1;
319
+ let coder = ErasureCoder::new(DATA_SHARDS, PARITY_SHARDS).unwrap();
320
+ let mut data = vec![0u8; SECTOR_SIZE * 7 / 2]; // 3.5 shards of data
321
+ data[..SECTOR_SIZE].fill(1);
322
+ data[SECTOR_SIZE..2 * SECTOR_SIZE].fill(2);
323
+ data[2 * SECTOR_SIZE..3 * SECTOR_SIZE].fill(3);
324
+ data[3 * SECTOR_SIZE..].fill(4);
325
+
326
+ // encode the data
327
+ let (mut shards, _) = coder.read_shards(&mut &data[..]).await.unwrap();
328
+ coder.encode_shards(&mut shards).unwrap();
329
+
330
+ // drop a shard
331
+ let mut encoded_shards = shards.into_iter().map(Some).collect::<Vec<_>>();
332
+ encoded_shards[2] = None; // drop the third shard
333
+
334
+ // reconstruct the data shards
335
+ let mut reconstructed_data: Vec<u8> = Vec::new();
336
+ coder.reconstruct_data_shards(&mut encoded_shards).unwrap();
337
+ ErasureCoder::write_data_shards(
338
+ &mut reconstructed_data,
339
+ &encoded_shards[..DATA_SHARDS],
340
+ 0,
341
+ data.len(),
342
+ )
343
+ .await
344
+ .unwrap();
345
+ assert_eq!(data, reconstructed_data);
346
+ }
347
+ }
@@ -0,0 +1,15 @@
1
+ pub mod blake2;
2
+ pub mod consensus;
3
+ pub mod encoding;
4
+ pub mod encoding_async;
5
+ pub mod encryption;
6
+ pub mod erasure_coding;
7
+ pub mod rhp;
8
+ pub mod seed;
9
+ pub mod signing;
10
+ pub mod types;
11
+
12
+ pub mod macros;
13
+ pub(crate) mod merkle;
14
+
15
+ extern crate self as sia;