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.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +179 -0
- package/package.json +29 -0
- package/template/CLAUDE.md +160 -0
- package/template/README.md +102 -0
- package/template/_gitignore +5 -0
- package/template/biome.json +40 -0
- package/template/index.html +13 -0
- package/template/package.json +30 -0
- package/template/rust/README.md +16 -0
- package/template/rust/sia-sdk-rs/.changeset/added_cancel_function_to_cancel_inflight_packed_uploads.md +6 -0
- package/template/rust/sia-sdk-rs/.changeset/check_if_we_have_enough_hosts_prior_to_encoding_in_upload_slabs.md +16 -0
- package/template/rust/sia-sdk-rs/.changeset/fix_slab_length_in_packed_object.md +5 -0
- package/template/rust/sia-sdk-rs/.changeset/fix_upload_racing_race_conditon.md +13 -0
- package/template/rust/sia-sdk-rs/.changeset/improved_parallelism_of_packed_uploads.md +5 -0
- package/template/rust/sia-sdk-rs/.changeset/progress_callback_will_now_be_called_as_expected_for_packed_uploads.md +5 -0
- package/template/rust/sia-sdk-rs/.github/dependabot.yml +10 -0
- package/template/rust/sia-sdk-rs/.github/workflows/main.yml +36 -0
- package/template/rust/sia-sdk-rs/.github/workflows/prepare-release.yml +34 -0
- package/template/rust/sia-sdk-rs/.github/workflows/release.yml +30 -0
- package/template/rust/sia-sdk-rs/.rustfmt.toml +4 -0
- package/template/rust/sia-sdk-rs/Cargo.lock +4127 -0
- package/template/rust/sia-sdk-rs/Cargo.toml +3 -0
- package/template/rust/sia-sdk-rs/LICENSE +21 -0
- package/template/rust/sia-sdk-rs/README.md +30 -0
- package/template/rust/sia-sdk-rs/indexd/CHANGELOG.md +79 -0
- package/template/rust/sia-sdk-rs/indexd/Cargo.toml +79 -0
- package/template/rust/sia-sdk-rs/indexd/benches/upload.rs +258 -0
- package/template/rust/sia-sdk-rs/indexd/src/app_client.rs +1710 -0
- package/template/rust/sia-sdk-rs/indexd/src/builder.rs +354 -0
- package/template/rust/sia-sdk-rs/indexd/src/download.rs +379 -0
- package/template/rust/sia-sdk-rs/indexd/src/hosts.rs +659 -0
- package/template/rust/sia-sdk-rs/indexd/src/lib.rs +827 -0
- package/template/rust/sia-sdk-rs/indexd/src/mock.rs +162 -0
- package/template/rust/sia-sdk-rs/indexd/src/object_encryption.rs +125 -0
- package/template/rust/sia-sdk-rs/indexd/src/quic.rs +575 -0
- package/template/rust/sia-sdk-rs/indexd/src/rhp4.rs +52 -0
- package/template/rust/sia-sdk-rs/indexd/src/slabs.rs +497 -0
- package/template/rust/sia-sdk-rs/indexd/src/upload.rs +629 -0
- package/template/rust/sia-sdk-rs/indexd/src/wasm_time.rs +41 -0
- package/template/rust/sia-sdk-rs/indexd/src/web_transport.rs +398 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/CHANGELOG.md +76 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/Cargo.toml +47 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/examples/python/README.md +10 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/examples/python/example.py +130 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/src/bin/uniffi-bindgen.rs +3 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/src/builder.rs +377 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/src/io.rs +155 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/src/lib.rs +1039 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/src/logging.rs +58 -0
- package/template/rust/sia-sdk-rs/indexd_ffi/src/tls.rs +23 -0
- package/template/rust/sia-sdk-rs/indexd_wasm/Cargo.toml +33 -0
- package/template/rust/sia-sdk-rs/indexd_wasm/src/lib.rs +818 -0
- package/template/rust/sia-sdk-rs/knope.toml +54 -0
- package/template/rust/sia-sdk-rs/sia_derive/CHANGELOG.md +38 -0
- package/template/rust/sia-sdk-rs/sia_derive/Cargo.toml +19 -0
- package/template/rust/sia-sdk-rs/sia_derive/src/lib.rs +278 -0
- package/template/rust/sia-sdk-rs/sia_sdk/CHANGELOG.md +91 -0
- package/template/rust/sia-sdk-rs/sia_sdk/Cargo.toml +59 -0
- package/template/rust/sia-sdk-rs/sia_sdk/benches/merkle_root.rs +12 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/blake2.rs +22 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/consensus.rs +767 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/encoding/v1.rs +257 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/encoding/v2.rs +291 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/encoding.rs +26 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/encoding_async/v2.rs +367 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/encoding_async.rs +6 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/encryption.rs +303 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/erasure_coding.rs +347 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/lib.rs +15 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/macros.rs +435 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/merkle.rs +112 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/merkle.rs +357 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/rpc.rs +1507 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/rhp/types.rs +146 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/rhp.rs +7 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/seed.rs +278 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/signing.rs +236 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types/common.rs +677 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types/currency.rs +450 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types/specifier.rs +110 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types/spendpolicy.rs +778 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types/utils.rs +117 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types/v1.rs +1737 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types/v2.rs +1726 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types/work.rs +59 -0
- package/template/rust/sia-sdk-rs/sia_sdk/src/types.rs +16 -0
- package/template/scripts/setup-rust.js +29 -0
- package/template/src/App.tsx +13 -0
- package/template/src/components/DevNote.tsx +21 -0
- package/template/src/components/auth/ApproveScreen.tsx +84 -0
- package/template/src/components/auth/AuthFlow.tsx +77 -0
- package/template/src/components/auth/ConnectScreen.tsx +214 -0
- package/template/src/components/auth/LoadingScreen.tsx +8 -0
- package/template/src/components/auth/RecoveryScreen.tsx +182 -0
- package/template/src/components/upload/UploadZone.tsx +314 -0
- package/template/src/index.css +9 -0
- package/template/src/lib/constants.ts +8 -0
- package/template/src/lib/format.ts +35 -0
- package/template/src/lib/hex.ts +13 -0
- package/template/src/lib/sdk.ts +25 -0
- package/template/src/lib/wasm-env.ts +5 -0
- package/template/src/main.tsx +12 -0
- package/template/src/stores/auth.ts +86 -0
- package/template/tsconfig.app.json +31 -0
- package/template/tsconfig.json +7 -0
- package/template/tsconfig.node.json +26 -0
- package/template/vite.config.ts +18 -0
- package/template/wasm/indexd_wasm/indexd_wasm.d.ts +309 -0
- package/template/wasm/indexd_wasm/indexd_wasm.js +1507 -0
- package/template/wasm/indexd_wasm/indexd_wasm_bg.wasm +0 -0
- package/template/wasm/indexd_wasm/package.json +31 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
use std::collections::VecDeque;
|
|
2
|
+
|
|
3
|
+
use crate::encoding_async::{AsyncSiaDecodable, AsyncSiaEncodable};
|
|
4
|
+
use crate::merkle::{self, Accumulator, LEAF_HASH_PREFIX, NODE_HASH_PREFIX, sum_leaf, sum_node};
|
|
5
|
+
use crate::rhp::{LEAVES_PER_SECTOR, SECTOR_SIZE, SEGMENT_SIZE};
|
|
6
|
+
use crate::types::Hash256;
|
|
7
|
+
use blake2b_simd::Params;
|
|
8
|
+
use blake2b_simd::many::{HashManyJob, hash_many};
|
|
9
|
+
use bytes::Bytes;
|
|
10
|
+
use rayon::prelude::*;
|
|
11
|
+
use sia_derive::{AsyncSiaDecode, AsyncSiaEncode};
|
|
12
|
+
use thiserror::Error;
|
|
13
|
+
use tokio::io::{self, AsyncRead, AsyncReadExt};
|
|
14
|
+
|
|
15
|
+
/// Calculates the Merkle root of a sector
|
|
16
|
+
pub fn sector_root(sector: &[u8]) -> Hash256 {
|
|
17
|
+
assert_eq!(sector.len(), SECTOR_SIZE);
|
|
18
|
+
let mut params = Params::new();
|
|
19
|
+
params.hash_length(32);
|
|
20
|
+
|
|
21
|
+
let mut tree_hashes = vec![Hash256::default(); LEAVES_PER_SECTOR];
|
|
22
|
+
tree_hashes
|
|
23
|
+
.par_chunks_exact_mut(4)
|
|
24
|
+
.enumerate()
|
|
25
|
+
.for_each(|(i, chunk)| {
|
|
26
|
+
// prepare inputs
|
|
27
|
+
let mut inputs = [[0u8; SEGMENT_SIZE + 1]; 4];
|
|
28
|
+
for (j, input) in inputs.iter_mut().enumerate() {
|
|
29
|
+
let start = i * 4 + j;
|
|
30
|
+
let end = start + 1;
|
|
31
|
+
input[0] = LEAF_HASH_PREFIX[0];
|
|
32
|
+
input[1..].copy_from_slice(§or[SEGMENT_SIZE * start..SEGMENT_SIZE * end]);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// hash them
|
|
36
|
+
let mut jobs = [
|
|
37
|
+
HashManyJob::new(¶ms, &inputs[0][..]),
|
|
38
|
+
HashManyJob::new(¶ms, &inputs[1][..]),
|
|
39
|
+
HashManyJob::new(¶ms, &inputs[2][..]),
|
|
40
|
+
HashManyJob::new(¶ms, &inputs[3][..]),
|
|
41
|
+
];
|
|
42
|
+
hash_many(&mut jobs);
|
|
43
|
+
|
|
44
|
+
// collect results
|
|
45
|
+
for j in 0..4 {
|
|
46
|
+
chunk[j] = jobs[j].to_hash().into();
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
let mut chunk_size = 4;
|
|
51
|
+
while chunk_size <= tree_hashes.len() {
|
|
52
|
+
tree_hashes.par_chunks_mut(chunk_size).for_each(|nodes| {
|
|
53
|
+
// prepare inputs
|
|
54
|
+
let mut inputs = [[0u8; 65]; 2];
|
|
55
|
+
for (j, input) in inputs.iter_mut().enumerate() {
|
|
56
|
+
input[0] = NODE_HASH_PREFIX[0];
|
|
57
|
+
let step = j * chunk_size / 2;
|
|
58
|
+
input[1..33].copy_from_slice(nodes[step].as_ref());
|
|
59
|
+
input[33..65].copy_from_slice(nodes[step + chunk_size / 4].as_ref());
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// hash them
|
|
63
|
+
let mut jobs = [
|
|
64
|
+
HashManyJob::new(¶ms, &inputs[0][..]),
|
|
65
|
+
HashManyJob::new(¶ms, &inputs[1][..]),
|
|
66
|
+
];
|
|
67
|
+
hash_many(&mut jobs);
|
|
68
|
+
|
|
69
|
+
// collect results
|
|
70
|
+
nodes[0] = jobs[0].to_hash().into();
|
|
71
|
+
nodes[nodes.len() / 2] = jobs[1].to_hash().into();
|
|
72
|
+
});
|
|
73
|
+
chunk_size *= 2;
|
|
74
|
+
}
|
|
75
|
+
// hash last two nodes into roots
|
|
76
|
+
sum_node(
|
|
77
|
+
¶ms,
|
|
78
|
+
&tree_hashes[0],
|
|
79
|
+
&tree_hashes[tree_hashes.len() / 2],
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
#[derive(Debug, Error)]
|
|
84
|
+
pub enum ProofValidationError {
|
|
85
|
+
#[error("Invalid proof length: expected {expected}, got {actual}")]
|
|
86
|
+
InvalidProofLength { expected: usize, actual: usize },
|
|
87
|
+
|
|
88
|
+
#[error("Invalid proof root: expected {expected}, got {actual}")]
|
|
89
|
+
InvalidProofRoot { expected: Hash256, actual: Hash256 },
|
|
90
|
+
|
|
91
|
+
#[error("IO error: {0}")]
|
|
92
|
+
Io(#[from] io::Error),
|
|
93
|
+
|
|
94
|
+
#[error("The proof data is not segment aligned")]
|
|
95
|
+
NotSegmentAligned,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
#[derive(Debug, AsyncSiaEncode, AsyncSiaDecode, PartialEq)]
|
|
99
|
+
pub struct RangeProof(Vec<Hash256>, Bytes);
|
|
100
|
+
|
|
101
|
+
impl RangeProof {
|
|
102
|
+
pub fn verify(
|
|
103
|
+
self,
|
|
104
|
+
root: &Hash256,
|
|
105
|
+
start: usize,
|
|
106
|
+
end: usize,
|
|
107
|
+
) -> Result<Bytes, ProofValidationError> {
|
|
108
|
+
let mut roots: VecDeque<Hash256> = self.roots(start, end)?;
|
|
109
|
+
let mut proof: VecDeque<Hash256> = self.0.into();
|
|
110
|
+
|
|
111
|
+
if proof.len() != range_proof_size(LEAVES_PER_SECTOR, start, end) {
|
|
112
|
+
return Err(ProofValidationError::InvalidProofLength {
|
|
113
|
+
expected: range_proof_size(LEAVES_PER_SECTOR, start, end),
|
|
114
|
+
actual: proof.len(),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let consume = |acc: &mut Accumulator, roots: &mut VecDeque<Hash256>, i: usize, j: usize| {
|
|
119
|
+
let mut i = i;
|
|
120
|
+
while i < j
|
|
121
|
+
&& let Some(root) = roots.pop_front()
|
|
122
|
+
{
|
|
123
|
+
let subtree_size = next_subtree_size(i, j);
|
|
124
|
+
let height = subtree_size.trailing_zeros(); // log2
|
|
125
|
+
acc.insert_node(root, height as usize);
|
|
126
|
+
i += subtree_size;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
let mut acc = merkle::Accumulator::new();
|
|
131
|
+
consume(&mut acc, &mut proof, 0, start);
|
|
132
|
+
consume(&mut acc, &mut roots, start, end);
|
|
133
|
+
consume(&mut acc, &mut proof, end, LEAVES_PER_SECTOR);
|
|
134
|
+
|
|
135
|
+
if acc.root() != *root {
|
|
136
|
+
return Err(ProofValidationError::InvalidProofRoot {
|
|
137
|
+
expected: *root,
|
|
138
|
+
actual: acc.root(),
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
Ok(self.1)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
fn roots(&self, start: usize, end: usize) -> Result<VecDeque<Hash256>, ProofValidationError> {
|
|
145
|
+
assert!(start < end);
|
|
146
|
+
let mut i = start;
|
|
147
|
+
let j = end;
|
|
148
|
+
let mut roots = VecDeque::new();
|
|
149
|
+
let mut params = Params::new();
|
|
150
|
+
params.hash_length(32);
|
|
151
|
+
|
|
152
|
+
let mut acc = merkle::Accumulator::new();
|
|
153
|
+
let mut off: usize = 0;
|
|
154
|
+
while i < j {
|
|
155
|
+
acc.reset();
|
|
156
|
+
|
|
157
|
+
let subtree_size = next_subtree_size(i, j);
|
|
158
|
+
let n = subtree_size * SEGMENT_SIZE;
|
|
159
|
+
|
|
160
|
+
let leaf_hashes: Vec<Hash256> = self
|
|
161
|
+
.1
|
|
162
|
+
.get(off..off + n)
|
|
163
|
+
.ok_or(ProofValidationError::NotSegmentAligned)?
|
|
164
|
+
.par_chunks_exact(64)
|
|
165
|
+
.map(|segment| sum_leaf(¶ms, segment))
|
|
166
|
+
.collect();
|
|
167
|
+
|
|
168
|
+
for h in leaf_hashes {
|
|
169
|
+
acc.add_leaf(h);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
roots.push_back(acc.root());
|
|
173
|
+
off += n;
|
|
174
|
+
i += subtree_size;
|
|
175
|
+
}
|
|
176
|
+
Ok(roots)
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
fn next_subtree_size(start: usize, end: usize) -> usize {
|
|
181
|
+
assert!(start < end);
|
|
182
|
+
let ideal = start.trailing_zeros();
|
|
183
|
+
let max_size = (end - start)
|
|
184
|
+
.checked_ilog2()
|
|
185
|
+
.expect("should not be None since start < end");
|
|
186
|
+
if ideal > max_size {
|
|
187
|
+
return 1 << max_size;
|
|
188
|
+
}
|
|
189
|
+
1 << ideal
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
fn range_proof_size(leaves_per_sector: usize, start: usize, end: usize) -> usize {
|
|
193
|
+
let left_hashes = start.count_ones() as usize;
|
|
194
|
+
let path_mask = (1usize
|
|
195
|
+
<< ((end - 1) ^ (leaves_per_sector - 1))
|
|
196
|
+
.checked_ilog2()
|
|
197
|
+
.map(|n| n + 1)
|
|
198
|
+
.unwrap_or(0))
|
|
199
|
+
- 1;
|
|
200
|
+
let right_hashes = (!(end - 1) & path_mask).count_ones() as usize;
|
|
201
|
+
left_hashes + right_hashes
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
pub async fn sector_root_from_reader<R: AsyncRead + Unpin>(
|
|
205
|
+
r: &mut R,
|
|
206
|
+
) -> Result<Hash256, ProofValidationError> {
|
|
207
|
+
let mut acc = merkle::Accumulator::new();
|
|
208
|
+
let r = r.take(SECTOR_SIZE as u64); // cap at a sector
|
|
209
|
+
let mut r = io::BufReader::new(r);
|
|
210
|
+
|
|
211
|
+
let mut leaf = [0u8; SEGMENT_SIZE];
|
|
212
|
+
loop {
|
|
213
|
+
// read a leaf
|
|
214
|
+
let mut bytes_read = 0;
|
|
215
|
+
while bytes_read < leaf.len() {
|
|
216
|
+
let n = r.read(&mut leaf[bytes_read..]).await?;
|
|
217
|
+
if n == 0 {
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
bytes_read += n;
|
|
221
|
+
}
|
|
222
|
+
// if no bytes were read, we are done
|
|
223
|
+
// if a full segment was read, we add the leaf
|
|
224
|
+
// otherwise, we got a partial segment, which results in an error
|
|
225
|
+
match bytes_read {
|
|
226
|
+
0 => return Ok(acc.root()),
|
|
227
|
+
SEGMENT_SIZE => {
|
|
228
|
+
let h = sum_leaf(Params::new().hash_length(32), &leaf);
|
|
229
|
+
acc.add_leaf(h);
|
|
230
|
+
}
|
|
231
|
+
_ => {
|
|
232
|
+
return Err(ProofValidationError::NotSegmentAligned);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
#[cfg(test)]
|
|
239
|
+
mod tests {
|
|
240
|
+
use super::*;
|
|
241
|
+
use crate::hash_256;
|
|
242
|
+
|
|
243
|
+
#[test]
|
|
244
|
+
fn test_sector_root() {
|
|
245
|
+
let mut sector = vec![0u8; SECTOR_SIZE];
|
|
246
|
+
let root = sector_root(§or);
|
|
247
|
+
assert_eq!(
|
|
248
|
+
root,
|
|
249
|
+
hash_256!("50ed59cecd5ed3ca9e65cec0797202091dbba45272dafa3faa4e27064eedd52c")
|
|
250
|
+
);
|
|
251
|
+
|
|
252
|
+
sector[0] = 1;
|
|
253
|
+
let root = sector_root(§or);
|
|
254
|
+
assert_eq!(
|
|
255
|
+
root,
|
|
256
|
+
hash_256!("8c20a2c90a733a5139cc57e45755322e304451c3434b0c0a0aad87f2f89a44ab")
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
sector[0] = 0;
|
|
260
|
+
sector[SECTOR_SIZE - 1] = 1;
|
|
261
|
+
let root = sector_root(§or);
|
|
262
|
+
assert_eq!(
|
|
263
|
+
root,
|
|
264
|
+
hash_256!("d0ab6691d76750618452e920386e5f6f98fdd1219a70a06f06ef622ac6c6373c")
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
sector
|
|
268
|
+
.iter_mut()
|
|
269
|
+
.enumerate()
|
|
270
|
+
.for_each(|(i, x)| *x = (i % 256) as u8);
|
|
271
|
+
let root = sector_root(§or);
|
|
272
|
+
assert_eq!(
|
|
273
|
+
root,
|
|
274
|
+
hash_256!("84d0672b204f38469dbb818bcb3caa7391f7781cbf84bce0482b2fd2c2d50938")
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
#[test]
|
|
279
|
+
fn test_range_proof_size() {
|
|
280
|
+
assert_eq!(range_proof_size(LEAVES_PER_SECTOR, 0, LEAVES_PER_SECTOR), 0);
|
|
281
|
+
assert_eq!(range_proof_size(LEAVES_PER_SECTOR, 1, LEAVES_PER_SECTOR), 1);
|
|
282
|
+
assert_eq!(
|
|
283
|
+
range_proof_size(LEAVES_PER_SECTOR, 0, LEAVES_PER_SECTOR / 2),
|
|
284
|
+
1
|
|
285
|
+
);
|
|
286
|
+
assert_eq!(
|
|
287
|
+
range_proof_size(
|
|
288
|
+
LEAVES_PER_SECTOR,
|
|
289
|
+
LEAVES_PER_SECTOR / 2,
|
|
290
|
+
LEAVES_PER_SECTOR / 2
|
|
291
|
+
),
|
|
292
|
+
2
|
|
293
|
+
);
|
|
294
|
+
assert_eq!(range_proof_size(LEAVES_PER_SECTOR, 0, 42), 13);
|
|
295
|
+
assert_eq!(range_proof_size(LEAVES_PER_SECTOR, 24, 42), 15);
|
|
296
|
+
assert_eq!(
|
|
297
|
+
range_proof_size(LEAVES_PER_SECTOR, 24, LEAVES_PER_SECTOR),
|
|
298
|
+
2
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
#[test]
|
|
303
|
+
fn test_next_subtree_size() {
|
|
304
|
+
assert_eq!(next_subtree_size(0, 1), 1);
|
|
305
|
+
assert_eq!(
|
|
306
|
+
next_subtree_size(LEAVES_PER_SECTOR, LEAVES_PER_SECTOR + 1),
|
|
307
|
+
1
|
|
308
|
+
);
|
|
309
|
+
assert_eq!(next_subtree_size(0, LEAVES_PER_SECTOR), 65536);
|
|
310
|
+
assert_eq!(next_subtree_size(0, LEAVES_PER_SECTOR / 2), 32768);
|
|
311
|
+
assert_eq!(
|
|
312
|
+
next_subtree_size(LEAVES_PER_SECTOR / 2, LEAVES_PER_SECTOR),
|
|
313
|
+
32768
|
|
314
|
+
);
|
|
315
|
+
assert_eq!(next_subtree_size(24, 42), 8);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
#[tokio::test]
|
|
319
|
+
async fn test_sector_root_from_reader() {
|
|
320
|
+
// prepare slightly more than a sector worth of data to make sure we
|
|
321
|
+
// only compute the hash over the first SECTOR_SIZE bytes
|
|
322
|
+
let data = vec![0u8; SECTOR_SIZE + 64];
|
|
323
|
+
let root = sector_root_from_reader(&mut &data[..]).await.unwrap();
|
|
324
|
+
|
|
325
|
+
let expected_root =
|
|
326
|
+
hash_256!("50ed59cecd5ed3ca9e65cec0797202091dbba45272dafa3faa4e27064eedd52c");
|
|
327
|
+
assert_eq!(root, expected_root);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
#[test]
|
|
331
|
+
fn test_verify_range_proof() {
|
|
332
|
+
let data = Bytes::from(vec![0u8; SECTOR_SIZE]);
|
|
333
|
+
let sector_root = sector_root(&data);
|
|
334
|
+
let proof: Vec<Hash256> = vec![
|
|
335
|
+
hash_256!("f0022a573326ecc0e4c18cf56b9a31d94dc792f8ec20ecbbc57d33c75db24c54"),
|
|
336
|
+
hash_256!("d66f6fce29310f5d2db0d2398e6d93b23c9fa1982b7249b07664590b7aebc49a"),
|
|
337
|
+
hash_256!("5b3bc22a619574a668c4e2a22fa72210611813c6ed44cf445789ee316102bfe1"),
|
|
338
|
+
hash_256!("3d8e644caa3e7ac720b1f7ce42d829ecf2c0ad7ef656258f4c1c90422074ba23"),
|
|
339
|
+
hash_256!("f0022a573326ecc0e4c18cf56b9a31d94dc792f8ec20ecbbc57d33c75db24c54"),
|
|
340
|
+
hash_256!("9213804e199cab3449185a5517f54e49c1d6b0892b8269ed4baab62dbf3e8ebb"),
|
|
341
|
+
hash_256!("f052bf6db4444532ed0d8fdfc67c0ce9688fb4042d461a5bb367506de5e712a8"),
|
|
342
|
+
hash_256!("61b3d824e7b4662df867477f09335dfecfc990c9f0b3731fbec981428b38190d"),
|
|
343
|
+
hash_256!("272b122c6943a7dd6b5e2797a727de61f53c274f29d7d3e4e30d40620f83dc2b"),
|
|
344
|
+
hash_256!("5ce18ab62a07bb4d4def2509f8bfa982d5cfd07deb533248abfd7b305652470c"),
|
|
345
|
+
hash_256!("39cb8aa6feace01924b732664b81a8f41d688cbd7817154c663c1686a4cf6a0e"),
|
|
346
|
+
hash_256!("95ab608799eb9c485712a4c995d4e22ea7b20024fe81730f5b4deb4982e97b78"),
|
|
347
|
+
hash_256!("6530f5433504ba845332dd51742b57f0666456c99b78f67c72fac381980527b1"),
|
|
348
|
+
hash_256!("53ae21d13da92c6741cf44e9b08e0c0616485402c343e4f6c92e5c8516187bcf"),
|
|
349
|
+
hash_256!("f2c4d3e9ce380389b1088d44ddb30276fbff5f75803c2bd13678b690f4187d7e"),
|
|
350
|
+
];
|
|
351
|
+
|
|
352
|
+
let verified_data = RangeProof(proof, data.clone()) // clone since RangeProof usually owns the data
|
|
353
|
+
.verify(§or_root, 24, 42)
|
|
354
|
+
.expect("proof validation failed");
|
|
355
|
+
assert_eq!(&data, &verified_data);
|
|
356
|
+
}
|
|
357
|
+
}
|