Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/database/full_sqlite/tests.rs
Line
Count
Source (jump to first uncovered line)
1
// Smoldot
2
// Copyright (C) 2023  Pierre Krieger
3
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
5
// This program is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
10
// This program is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
15
// You should have received a copy of the GNU General Public License
16
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18
#![cfg(test)]
19
20
use super::{
21
    open, Config, ConfigTy, DatabaseOpen, InsertTrieNode, InsertTrieNodeStorageValue,
22
    StorageAccessError,
23
};
24
use crate::{header, trie};
25
26
use alloc::borrow::Cow;
27
use core::{array, iter};
28
use rand::distributions::{Distribution as _, Uniform};
29
30
#[test]
31
1
fn empty_database_fill_then_query() {
32
    // Repeat the test many times due to randomness.
33
1.02k
    for _ in 0..1024 {
34
1.02k
        let DatabaseOpen::Empty(empty_db) = open(Config {
35
1.02k
            block_number_bytes: 4,
36
1.02k
            cache_size: 2 * 1024 * 1024,
37
1.02k
            ty: ConfigTy::Memory,
38
1.02k
        })
39
1.02k
        .unwrap() else {
40
0
            panic!()
41
        };
42
43
18.9M
        fn uniform_sample(min: u8, max: u8) -> u8 {
44
18.9M
            Uniform::new_inclusive(min, max).sample(&mut rand::thread_rng())
45
18.9M
        }
46
47
        // Create a random trie.
48
        // Each node contains a `Some` with the storage value or `None` for branch nodes, plus its
49
        // Merkle value as `Some` if already calculated.
50
1.02k
        let mut trie = trie::trie_structure::TrieStructure::<(
51
1.02k
            Option<Vec<u8>>,
52
1.02k
            Option<trie::trie_node::MerkleValueOutput>,
53
1.02k
        )>::new();
54
1.02k
55
1.02k
        let mut list = vec![Vec::new()];
56
1.02k
        for elem in list.clone().into_iter() {
57
1.02k
            for _ in 0..uniform_sample(0, 4) {
58
1.98k
                let mut elem = elem.clone();
59
2.94k
                for _ in 0..uniform_sample(0, 3) {
60
2.94k
                    elem.push(uniform_sample(0, 255));
61
2.94k
                }
62
1.98k
                list.push(elem);
63
            }
64
        }
65
4.03k
        for 
elem3.01k
in list {
66
3.01k
            let mut storage_value = Vec::new();
67
36.0k
            for _ in 0..uniform_sample(0, 24) {
68
36.0k
                storage_value.push(uniform_sample(0, 255));
69
36.0k
            }
70
71
3.01k
            match trie.node(trie::bytes_to_nibbles(elem.iter().copied())) {
72
2.51k
                trie::trie_structure::Entry::Vacant(e) => {
73
2.51k
                    e.insert_storage_value()
74
2.51k
                        .insert((Some(storage_value), None), (None, None));
75
2.51k
                }
76
                trie::trie_structure::Entry::Occupied(
77
0
                    trie::trie_structure::NodeAccess::Branch(mut e),
78
0
                ) => {
79
0
                    *e.user_data() = (Some(storage_value), None);
80
0
                    e.insert_storage_value();
81
0
                }
82
                trie::trie_structure::Entry::Occupied(
83
                    trie::trie_structure::NodeAccess::Storage(_),
84
496
                ) => {}
85
            }
86
        }
87
88
        // Calculate the Merkle values of the nodes of the trie.
89
2.58k
        for node_index in 
trie.iter_ordered().collect::<Vec<_>>().into_iter().rev()1.02k
{
90
2.58k
            let mut node_access = trie.node_by_index(node_index).unwrap();
91
2.58k
92
41.3k
            let children = core::array::from_fn::<_, 16, _>(|n| {
93
41.3k
                node_access
94
41.3k
                    .child(trie::Nibble::try_from(u8::try_from(n).unwrap()).unwrap())
95
41.3k
                    .map(|mut child| 
child.user_data().1.as_ref().unwrap().clone()1.56k
)
96
41.3k
            });
97
2.58k
98
2.58k
            let is_root_node = node_access.is_root_node();
99
2.58k
            let partial_key = node_access.partial_key().collect::<Vec<_>>().into_iter();
100
101
2.58k
            let storage_value = match node_access.user_data().0.as_ref() {
102
2.51k
                Some(v) => trie::trie_node::StorageValue::Unhashed(&v[..]),
103
68
                None => trie::trie_node::StorageValue::None,
104
            };
105
106
2.58k
            let merkle_value = trie::trie_node::calculate_merkle_value(
107
2.58k
                trie::trie_node::Decoded {
108
2.58k
                    children,
109
2.58k
                    partial_key,
110
2.58k
                    storage_value,
111
2.58k
                },
112
2.58k
                trie::HashFunction::Blake2,
113
2.58k
                is_root_node,
114
2.58k
            )
115
2.58k
            .unwrap();
116
2.58k
117
2.58k
            node_access.into_user_data().1 = Some(merkle_value);
118
        }
119
120
        // Store the trie in the database.
121
1.02k
        let open_db = {
122
1.02k
            let state_root = &trie
123
1.02k
                .root_user_data()
124
1.02k
                .map(|n| *<&[u8; 32]>::try_from(n.1.as_ref().unwrap().as_ref()).unwrap())
125
1.02k
                .unwrap_or(trie::EMPTY_BLAKE2_TRIE_MERKLE_VALUE);
126
1.02k
127
1.02k
            let trie_entries_linear =
128
1.02k
                trie.iter_unordered()
129
1.02k
                    .collect::<Vec<_>>()
130
1.02k
                    .into_iter()
131
2.58k
                    .map(|node_index| {
132
2.58k
                        let (storage_value, Some(merkle_value)) = &trie[node_index] else {
133
0
                            unreachable!()
134
                        };
135
2.58k
                        let storage_value = if let Some(
storage_value2.51k
) = storage_value {
136
2.51k
                            InsertTrieNodeStorageValue::Value {
137
2.51k
                                value: Cow::Owned(storage_value.to_vec()),
138
2.51k
                                references_merkle_value: false, // TODO: test this as well
139
2.51k
                            }
140
                        } else {
141
68
                            InsertTrieNodeStorageValue::NoValue
142
                        };
143
2.58k
                        let merkle_value = merkle_value.as_ref().to_owned();
144
2.58k
                        let mut node_access = trie.node_by_index(node_index).unwrap();
145
2.58k
146
2.58k
                        InsertTrieNode {
147
2.58k
                            storage_value,
148
2.58k
                            merkle_value: Cow::Owned(merkle_value),
149
41.3k
                            children_merkle_values: array::from_fn::<_, 16, _>(|n| {
150
41.3k
                                let child_index =
151
41.3k
                                    trie::Nibble::try_from(u8::try_from(n).unwrap()).unwrap();
152
41.3k
                                if let Some(
mut child1.56k
) = node_access.child(child_index) {
153
1.56k
                                    Some(Cow::Owned(
154
1.56k
                                        child.user_data().1.as_ref().unwrap().as_ref().to_vec(),
155
1.56k
                                    ))
156
                                } else {
157
39.7k
                                    None
158
                                }
159
41.3k
                            }),
160
2.58k
                            partial_key_nibbles: Cow::Owned(
161
2.58k
                                node_access.partial_key().map(u8::from).collect::<Vec<_>>(),
162
2.58k
                            ),
163
2.58k
                        }
164
2.58k
                    });
165
1.02k
166
1.02k
            let db = empty_db
167
1.02k
                .initialize(
168
1.02k
                    &header::HeaderRef {
169
1.02k
                        number: 0,
170
1.02k
                        extrinsics_root: &[0; 32],
171
1.02k
                        parent_hash: &[0; 32],
172
1.02k
                        state_root,
173
1.02k
                        digest: header::DigestRef::empty(),
174
1.02k
                    }
175
1.02k
                    .scale_encoding_vec(4),
176
1.02k
                    iter::empty(),
177
1.02k
                    None,
178
1.02k
                )
179
1.02k
                .unwrap();
180
1.02k
            db.insert_trie_nodes(trie_entries_linear, 0).unwrap();
181
1.02k
            db
182
1.02k
        };
183
1.02k
184
1.02k
        let block0_hash = open_db.finalized_block_hash().unwrap();
185
186
        // Ask random keys.
187
1.04M
        for _ in 0..1024 {
188
1.04M
            let key = (0..uniform_sample(0, 4))
189
2.09M
                .map(|_| uniform_sample(0, 255))
190
1.04M
                .collect::<Vec<_>>();
191
1.04M
            let actual = open_db
192
1.04M
                .block_storage_get(
193
1.04M
                    &block0_hash,
194
1.04M
                    iter::empty::<iter::Empty<_>>(),
195
1.04M
                    trie::bytes_to_nibbles(key.iter().copied()).map(u8::from),
196
1.04M
                )
197
1.04M
                .unwrap();
198
1.04M
            let expected = trie
199
1.04M
                .node_by_full_key(trie::bytes_to_nibbles(key.iter().copied()))
200
1.04M
                .and_then(|n| 
Some((trie[n].0.as_ref()209k
?2
.
clone()209k
, 0u8)
)209k
);
201
1.04M
            assert_eq!(
202
                actual,
203
                expected,
204
0
                "\nkey = {:?}\ntrie = {:?}",
205
0
                key.iter().map(|n| format!("{:x}", n)).collect::<String>(),
206
                trie
207
            );
208
        }
209
210
        // Ask random next keys.
211
1.04M
        for _ in 0..1024 {
212
1.04M
            let key = (0..uniform_sample(0, 8))
213
4.19M
                .map(|_| trie::Nibble::try_from(uniform_sample(0u8, 15)).unwrap())
214
1.04M
                .collect::<Vec<_>>();
215
1.04M
            let prefix = (0..uniform_sample(0, 8))
216
4.19M
                .map(|_| trie::Nibble::try_from(uniform_sample(0u8, 15)).unwrap())
217
1.04M
                .collect::<Vec<_>>();
218
1.04M
            let branch_nodes = rand::random::<bool>();
219
1.04M
            let actual = open_db
220
1.04M
                .block_storage_next_key(
221
1.04M
                    &block0_hash,
222
1.04M
                    iter::empty::<iter::Empty<_>>(),
223
1.04M
                    key.iter().copied().map(u8::from),
224
1.04M
                    prefix.iter().copied().map(u8::from),
225
1.04M
                    branch_nodes,
226
1.04M
                )
227
1.04M
                .unwrap();
228
1.04M
            let expected = trie
229
1.04M
                .iter_ordered()
230
2.20M
                .filter(|n| branch_nodes || 
trie[*n].0.is_some(1.10M
))
231
2.17M
                .map(|n| trie.node_full_key_by_index(n).unwrap().collect::<Vec<_>>())
232
2.17M
                .find(|n| *n >= key)
233
1.04M
                .filter(|n| 
n.starts_with(&prefix)549k
)
234
1.04M
                .map(|k| 
k.iter().copied().map(u8::from).collect::<Vec<_>>()64.3k
);
235
1.04M
            assert_eq!(
236
                actual,
237
                expected,
238
0
                "\nkey = {:?}\nprefix = {:?}\nbranch_nodes = {:?}\ntrie = {:?}",
239
0
                key.iter().map(|n| format!("{:x}", n)).collect::<String>(),
240
0
                prefix
241
0
                    .iter()
242
0
                    .map(|n| format!("{:x}", n))
243
0
                    .collect::<String>(),
244
                branch_nodes,
245
                trie
246
            );
247
        }
248
249
        // Ask random closest descendant Merkle values.
250
1.04M
        for _ in 0..1024 {
251
1.04M
            let key = (0..uniform_sample(0, 8))
252
4.19M
                .map(|_| trie::Nibble::try_from(uniform_sample(0u8, 15)).unwrap())
253
1.04M
                .collect::<Vec<_>>();
254
1.04M
            let actual = open_db
255
1.04M
                .block_storage_closest_descendant_merkle_value(
256
1.04M
                    &block0_hash,
257
1.04M
                    iter::empty::<iter::Empty<_>>(),
258
1.04M
                    key.iter().copied().map(u8::from),
259
1.04M
                )
260
1.04M
                .unwrap();
261
1.04M
            let expected = trie
262
1.04M
                .iter_ordered()
263
2.46M
                .find(|n| {
264
2.46M
                    let full_key = trie.node_full_key_by_index(*n).unwrap().collect::<Vec<_>>();
265
2.46M
                    full_key >= key && 
full_key.starts_with(&key)814k
266
2.46M
                })
267
1.04M
                .map(|n| 
trie[n].1.as_ref().unwrap().as_ref().to_vec()126k
);
268
1.04M
            assert_eq!(
269
                actual,
270
                expected,
271
0
                "\nkey = {:?}\ntrie = {:?}",
272
0
                key.iter().map(|n| format!("{:x}", n)).collect::<String>(),
273
                trie
274
            );
275
        }
276
    }
277
1
}
278
279
#[test]
280
1
fn unknown_block() {
281
1
    let DatabaseOpen::Empty(empty_db) = open(Config {
282
1
        block_number_bytes: 4,
283
1
        cache_size: 2 * 1024 * 1024,
284
1
        ty: ConfigTy::Memory,
285
1
    })
286
1
    .unwrap() else {
287
0
        panic!()
288
    };
289
290
1
    let db = empty_db
291
1
        .initialize(
292
1
            &header::HeaderRef {
293
1
                number: 0,
294
1
                extrinsics_root: &[0; 32],
295
1
                parent_hash: &[0; 32],
296
1
                state_root: &[1; 32],
297
1
                digest: header::DigestRef::empty(),
298
1
            }
299
1
            .scale_encoding_vec(4),
300
1
            iter::empty(),
301
1
            None,
302
1
        )
303
1
        .unwrap();
304
1
305
1
    assert!(
matches!0
(
306
1
        db.block_storage_get(&[0xff; 32], iter::empty::<iter::Empty<_>>(), [].into_iter()),
307
        Err(StorageAccessError::UnknownBlock)
308
    ));
309
310
1
    assert!(
matches!0
(
311
1
        db.block_storage_next_key(
312
1
            &[0xff; 32],
313
1
            iter::empty::<iter::Empty<_>>(),
314
1
            [].into_iter(),
315
1
            [].into_iter(),
316
1
            true
317
1
        ),
318
        Err(StorageAccessError::UnknownBlock)
319
    ));
320
1
    assert!(
matches!0
(
321
1
        db.block_storage_next_key(
322
1
            &[0xff; 32],
323
1
            iter::empty::<iter::Empty<_>>(),
324
1
            [].into_iter(),
325
1
            [].into_iter(),
326
1
            false
327
1
        ),
328
        Err(StorageAccessError::UnknownBlock)
329
    ));
330
331
1
    assert!(
matches!0
(
332
1
        db.block_storage_closest_descendant_merkle_value(
333
1
            &[0xff; 32],
334
1
            iter::empty::<iter::Empty<_>>(),
335
1
            [].into_iter()
336
1
        ),
337
        Err(StorageAccessError::UnknownBlock)
338
    ));
339
1
}
340
341
#[test]
342
1
fn storage_get_partial() {
343
1
    let DatabaseOpen::Empty(empty_db) = open(Config {
344
1
        block_number_bytes: 4,
345
1
        cache_size: 2 * 1024 * 1024,
346
1
        ty: ConfigTy::Memory,
347
1
    })
348
1
    .unwrap() else {
349
0
        panic!()
350
    };
351
352
1
    let db = empty_db
353
1
        .initialize(
354
1
            &header::HeaderRef {
355
1
                number: 0,
356
1
                extrinsics_root: &[0; 32],
357
1
                parent_hash: &[0; 32],
358
1
                state_root: &[1; 32],
359
1
                digest: header::DigestRef::empty(),
360
1
            }
361
1
            .scale_encoding_vec(4),
362
1
            iter::empty(),
363
1
            None,
364
1
        )
365
1
        .unwrap();
366
1
367
1
    assert!(
matches!0
(
368
1
        db.block_storage_get(
369
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
370
1
            iter::empty::<iter::Empty<_>>(),
371
1
            [1, 1].into_iter(),
372
1
        ),
373
        Err(StorageAccessError::IncompleteStorage)
374
    ));
375
376
1
    assert!(
matches!0
(
377
1
        db.block_storage_get(
378
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
379
1
            iter::empty::<iter::Empty<_>>(),
380
1
            [1, 1, 1, 1, 1].into_iter(),
381
1
        ),
382
        Err(StorageAccessError::IncompleteStorage)
383
    ));
384
385
1
    assert!(
matches!0
(
386
1
        db.block_storage_get(
387
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
388
1
            iter::empty::<iter::Empty<_>>(),
389
1
            [1, 1, 2].into_iter(),
390
1
        ),
391
        Err(StorageAccessError::IncompleteStorage)
392
    ));
393
394
1
    assert!(
matches!0
(
395
1
        db.block_storage_get(
396
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
397
1
            iter::empty::<iter::Empty<_>>(),
398
1
            [1, 1, 1, 2].into_iter(),
399
1
        ),
400
        Err(StorageAccessError::IncompleteStorage)
401
    ));
402
403
    // The empty key is specifically tested due to SQLite having some weird behaviors mixing
404
    // null and empty bytes.
405
1
    assert!(
matches!0
(
406
1
        db.block_storage_get(
407
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
408
1
            iter::empty::<iter::Empty<_>>(),
409
1
            [].into_iter(),
410
1
        ),
411
        Err(StorageAccessError::IncompleteStorage)
412
    ));
413
414
1
    db.insert_trie_nodes(
415
1
        [InsertTrieNode {
416
1
            merkle_value: Cow::Borrowed(&[1; 32]),
417
1
            partial_key_nibbles: Cow::Borrowed(&[1, 1]),
418
1
            children_merkle_values: [
419
1
                None,
420
1
                Some(Cow::Borrowed(&[2; 32])),
421
1
                None,
422
1
                None,
423
1
                None,
424
1
                None,
425
1
                None,
426
1
                None,
427
1
                None,
428
1
                None,
429
1
                None,
430
1
                None,
431
1
                None,
432
1
                None,
433
1
                None,
434
1
                None,
435
1
            ],
436
1
            storage_value: InsertTrieNodeStorageValue::Value {
437
1
                value: Cow::Borrowed(b"hello"),
438
1
                references_merkle_value: false,
439
1
            },
440
1
        }]
441
1
        .into_iter(),
442
1
        0,
443
1
    )
444
1
    .unwrap();
445
1
446
1
    assert_eq!(
447
1
        db.block_storage_get(
448
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
449
1
            iter::empty::<iter::Empty<_>>(),
450
1
            [1, 1].into_iter(),
451
1
        )
452
1
        .unwrap()
453
1
        .unwrap()
454
1
        .0,
455
1
        b"hello"
456
1
    );
457
458
1
    assert!(
matches!0
(
459
1
        db.block_storage_get(
460
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
461
1
            iter::empty::<iter::Empty<_>>(),
462
1
            [1, 1, 1, 1, 1].into_iter(),
463
1
        ),
464
        Err(StorageAccessError::IncompleteStorage)
465
    ));
466
467
1
    assert!(db
468
1
        .block_storage_get(
469
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
470
1
            iter::empty::<iter::Empty<_>>(),
471
1
            [1, 1, 2].into_iter(),
472
1
        )
473
1
        .unwrap()
474
1
        .is_none());
475
476
1
    assert!(
matches!0
(
477
1
        db.block_storage_get(
478
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
479
1
            iter::empty::<iter::Empty<_>>(),
480
1
            [1, 1, 1, 2].into_iter(),
481
1
        ),
482
        Err(StorageAccessError::IncompleteStorage)
483
    ));
484
485
1
    db.insert_trie_nodes(
486
1
        [InsertTrieNode {
487
1
            merkle_value: Cow::Borrowed(&[2; 32]),
488
1
            partial_key_nibbles: Cow::Borrowed(&[1, 1]),
489
1
            children_merkle_values: [
490
1
                None, None, None, None, None, None, None, None, None, None, None, None, None, None,
491
1
                None, None,
492
1
            ],
493
1
            storage_value: InsertTrieNodeStorageValue::Value {
494
1
                value: Cow::Borrowed(b"world"),
495
1
                references_merkle_value: false,
496
1
            },
497
1
        }]
498
1
        .into_iter(),
499
1
        0,
500
1
    )
501
1
    .unwrap();
502
1
503
1
    assert_eq!(
504
1
        db.block_storage_get(
505
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
506
1
            iter::empty::<iter::Empty<_>>(),
507
1
            [1, 1].into_iter(),
508
1
        )
509
1
        .unwrap()
510
1
        .unwrap()
511
1
        .0,
512
1
        b"hello"
513
1
    );
514
515
1
    assert_eq!(
516
1
        db.block_storage_get(
517
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
518
1
            iter::empty::<iter::Empty<_>>(),
519
1
            [1, 1, 1, 1, 1].into_iter(),
520
1
        )
521
1
        .unwrap()
522
1
        .unwrap()
523
1
        .0,
524
1
        b"world"
525
1
    );
526
527
1
    assert!(db
528
1
        .block_storage_get(
529
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
530
1
            iter::empty::<iter::Empty<_>>(),
531
1
            [1, 1, 2].into_iter(),
532
1
        )
533
1
        .unwrap()
534
1
        .is_none());
535
536
1
    assert!(db
537
1
        .block_storage_get(
538
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
539
1
            iter::empty::<iter::Empty<_>>(),
540
1
            [1, 1, 1, 2].into_iter(),
541
1
        )
542
1
        .unwrap()
543
1
        .is_none());
544
545
    // The empty key is specifically tested due to SQLite having some weird behaviors mixing
546
    // null and empty bytes.
547
1
    assert!(db
548
1
        .block_storage_get(
549
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
550
1
            iter::empty::<iter::Empty<_>>(),
551
1
            [].into_iter(),
552
1
        )
553
1
        .unwrap()
554
1
        .is_none());
555
1
}
556
557
#[test]
558
1
fn storage_next_key_partial() {
559
1
    let DatabaseOpen::Empty(empty_db) = open(Config {
560
1
        block_number_bytes: 4,
561
1
        cache_size: 2 * 1024 * 1024,
562
1
        ty: ConfigTy::Memory,
563
1
    })
564
1
    .unwrap() else {
565
0
        panic!()
566
    };
567
568
1
    let db = empty_db
569
1
        .initialize(
570
1
            &header::HeaderRef {
571
1
                number: 0,
572
1
                extrinsics_root: &[0; 32],
573
1
                parent_hash: &[0; 32],
574
1
                state_root: &[1; 32],
575
1
                digest: header::DigestRef::empty(),
576
1
            }
577
1
            .scale_encoding_vec(4),
578
1
            iter::empty(),
579
1
            None,
580
1
        )
581
1
        .unwrap();
582
1
583
1
    // The empty key is specifically tested due to SQLite having some weird behaviors mixing
584
1
    // null and empty bytes.
585
1
    assert!(
matches!0
(
586
1
        db.block_storage_next_key(
587
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
588
1
            iter::empty::<iter::Empty<_>>(),
589
1
            [].into_iter(),
590
1
            iter::empty(),
591
1
            true
592
1
        ),
593
        Err(StorageAccessError::IncompleteStorage)
594
    ));
595
596
1
    assert!(
matches!0
(
597
1
        db.block_storage_next_key(
598
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
599
1
            iter::empty::<iter::Empty<_>>(),
600
1
            [1, 1].into_iter(),
601
1
            iter::empty(),
602
1
            true
603
1
        ),
604
        Err(StorageAccessError::IncompleteStorage)
605
    ));
606
607
1
    db.insert_trie_nodes(
608
1
        [InsertTrieNode {
609
1
            merkle_value: Cow::Borrowed(&[1; 32]),
610
1
            partial_key_nibbles: Cow::Borrowed(&[1, 1]),
611
1
            children_merkle_values: [
612
1
                None,
613
1
                Some(Cow::Borrowed(&[2; 32])),
614
1
                Some(Cow::Borrowed(&[3; 32])),
615
1
                None,
616
1
                None,
617
1
                None,
618
1
                None,
619
1
                None,
620
1
                None,
621
1
                None,
622
1
                None,
623
1
                None,
624
1
                None,
625
1
                None,
626
1
                None,
627
1
                None,
628
1
            ],
629
1
            storage_value: InsertTrieNodeStorageValue::NoValue,
630
1
        }]
631
1
        .into_iter(),
632
1
        0,
633
1
    )
634
1
    .unwrap();
635
1
636
1
    assert_eq!(
637
1
        db.block_storage_next_key(
638
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
639
1
            iter::empty::<iter::Empty<_>>(),
640
1
            [1, 0].into_iter(),
641
1
            iter::empty(),
642
1
            true
643
1
        )
644
1
        .unwrap()
645
1
        .unwrap(),
646
1
        vec![1, 1]
647
1
    );
648
649
1
    assert_eq!(
650
1
        db.block_storage_next_key(
651
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
652
1
            iter::empty::<iter::Empty<_>>(),
653
1
            [1, 1].into_iter(),
654
1
            iter::empty(),
655
1
            true
656
1
        )
657
1
        .unwrap()
658
1
        .unwrap(),
659
1
        vec![1, 1]
660
1
    );
661
662
1
    assert!(
matches!0
(
663
1
        db.block_storage_next_key(
664
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
665
1
            iter::empty::<iter::Empty<_>>(),
666
1
            [1, 1].into_iter(),
667
1
            iter::empty(),
668
1
            false
669
1
        ),
670
        Err(StorageAccessError::IncompleteStorage)
671
    ));
672
673
1
    assert!(
matches!0
(
674
1
        db.block_storage_next_key(
675
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
676
1
            iter::empty::<iter::Empty<_>>(),
677
1
            [1, 1, 0].into_iter(),
678
1
            iter::empty(),
679
1
            true
680
1
        ),
681
        Err(StorageAccessError::IncompleteStorage)
682
    ));
683
684
1
    assert!(
matches!0
(
685
1
        db.block_storage_next_key(
686
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
687
1
            iter::empty::<iter::Empty<_>>(),
688
1
            [1, 1, 0].into_iter(),
689
1
            [1, 1, 0].into_iter(),
690
1
            true
691
1
        ),
692
        Ok(None)
693
    ));
694
695
1
    assert!(
matches!0
(
696
1
        db.block_storage_next_key(
697
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
698
1
            iter::empty::<iter::Empty<_>>(),
699
1
            [1, 1, 2].into_iter(),
700
1
            iter::empty(),
701
1
            true
702
1
        ),
703
        Err(StorageAccessError::IncompleteStorage)
704
    ));
705
706
1
    assert!(
matches!0
(
707
1
        db.block_storage_next_key(
708
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
709
1
            iter::empty::<iter::Empty<_>>(),
710
1
            [1, 1, 3].into_iter(),
711
1
            iter::empty(),
712
1
            true
713
1
        ),
714
        Ok(None)
715
    ));
716
717
1
    db.insert_trie_nodes(
718
1
        [InsertTrieNode {
719
1
            merkle_value: Cow::Borrowed(&[3; 32]),
720
1
            partial_key_nibbles: Cow::Borrowed(&[2]),
721
1
            children_merkle_values: [
722
1
                None, None, None, None, None, None, None, None, None, None, None, None, None, None,
723
1
                None, None,
724
1
            ],
725
1
            storage_value: InsertTrieNodeStorageValue::Value {
726
1
                value: Cow::Borrowed(b"hello"),
727
1
                references_merkle_value: false,
728
1
            },
729
1
        }]
730
1
        .into_iter(),
731
1
        0,
732
1
    )
733
1
    .unwrap();
734
1
735
1
    assert_eq!(
736
1
        db.block_storage_next_key(
737
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
738
1
            iter::empty::<iter::Empty<_>>(),
739
1
            [1, 1, 2].into_iter(),
740
1
            iter::empty(),
741
1
            true
742
1
        )
743
1
        .unwrap()
744
1
        .unwrap(),
745
1
        vec![1, 1, 2, 2]
746
1
    );
747
748
1
    assert!(
matches!0
(
749
1
        db.block_storage_next_key(
750
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
751
1
            iter::empty::<iter::Empty<_>>(),
752
1
            [1, 1, 1, 1, 1, 1, 1, 1].into_iter(),
753
1
            iter::empty(),
754
1
            true
755
1
        ),
756
        Err(StorageAccessError::IncompleteStorage)
757
    ));
758
759
1
    db.insert_trie_nodes(
760
1
        [InsertTrieNode {
761
1
            merkle_value: Cow::Borrowed(&[2; 32]),
762
1
            partial_key_nibbles: Cow::Borrowed(&[1, 1]),
763
1
            children_merkle_values: [
764
1
                None, None, None, None, None, None, None, None, None, None, None, None, None, None,
765
1
                None, None,
766
1
            ],
767
1
            storage_value: InsertTrieNodeStorageValue::Value {
768
1
                value: Cow::Borrowed(b"hello"),
769
1
                references_merkle_value: false,
770
1
            },
771
1
        }]
772
1
        .into_iter(),
773
1
        0,
774
1
    )
775
1
    .unwrap();
776
1
777
1
    assert_eq!(
778
1
        db.block_storage_next_key(
779
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
780
1
            iter::empty::<iter::Empty<_>>(),
781
1
            [].into_iter(),
782
1
            iter::empty(),
783
1
            false
784
1
        )
785
1
        .unwrap()
786
1
        .unwrap(),
787
1
        vec![1, 1, 1, 1, 1]
788
1
    );
789
790
1
    assert_eq!(
791
1
        db.block_storage_next_key(
792
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
793
1
            iter::empty::<iter::Empty<_>>(),
794
1
            [1, 1, 1, 1, 1, 1, 1, 1].into_iter(),
795
1
            iter::empty(),
796
1
            true
797
1
        )
798
1
        .unwrap()
799
1
        .unwrap(),
800
1
        vec![1, 1, 2, 2]
801
1
    );
802
803
1
    assert_eq!(
804
1
        db.block_storage_next_key(
805
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
806
1
            iter::empty::<iter::Empty<_>>(),
807
1
            [1, 1, 3].into_iter(),
808
1
            iter::empty(),
809
1
            true
810
1
        )
811
1
        .unwrap(),
812
1
        None
813
1
    );
814
815
1
    assert_eq!(
816
1
        db.block_storage_next_key(
817
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
818
1
            iter::empty::<iter::Empty<_>>(),
819
1
            [3].into_iter(),
820
1
            iter::empty(),
821
1
            true
822
1
        )
823
1
        .unwrap(),
824
1
        None
825
1
    );
826
1
}
827
828
#[test]
829
1
fn storage_closest_descendant_merkle_value_partial() {
830
1
    let DatabaseOpen::Empty(empty_db) = open(Config {
831
1
        block_number_bytes: 4,
832
1
        cache_size: 2 * 1024 * 1024,
833
1
        ty: ConfigTy::Memory,
834
1
    })
835
1
    .unwrap() else {
836
0
        panic!()
837
    };
838
839
1
    let db = empty_db
840
1
        .initialize(
841
1
            &header::HeaderRef {
842
1
                number: 0,
843
1
                extrinsics_root: &[0; 32],
844
1
                parent_hash: &[0; 32],
845
1
                state_root: &[1; 32],
846
1
                digest: header::DigestRef::empty(),
847
1
            }
848
1
            .scale_encoding_vec(4),
849
1
            iter::empty(),
850
1
            None,
851
1
        )
852
1
        .unwrap();
853
1
854
1
    assert_eq!(
855
1
        db.block_storage_closest_descendant_merkle_value(
856
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
857
1
            iter::empty::<iter::Empty<_>>(),
858
1
            [].into_iter(),
859
1
        )
860
1
        .unwrap()
861
1
        .unwrap(),
862
1
        vec![1; 32]
863
1
    );
864
865
1
    assert!(
matches!0
(
866
1
        db.block_storage_closest_descendant_merkle_value(
867
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
868
1
            iter::empty::<iter::Empty<_>>(),
869
1
            [1].into_iter(),
870
1
        ),
871
        Err(StorageAccessError::IncompleteStorage)
872
    ));
873
874
1
    assert!(
matches!0
(
875
1
        db.block_storage_closest_descendant_merkle_value(
876
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
877
1
            iter::empty::<iter::Empty<_>>(),
878
1
            [1, 1].into_iter(),
879
1
        ),
880
        Err(StorageAccessError::IncompleteStorage)
881
    ));
882
883
1
    assert!(
matches!0
(
884
1
        db.block_storage_closest_descendant_merkle_value(
885
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
886
1
            iter::empty::<iter::Empty<_>>(),
887
1
            [1, 2, 3, 4, 5].into_iter(),
888
1
        ),
889
        Err(StorageAccessError::IncompleteStorage)
890
    ));
891
892
1
    db.insert_trie_nodes(
893
1
        [InsertTrieNode {
894
1
            merkle_value: Cow::Borrowed(&[1; 32]),
895
1
            partial_key_nibbles: Cow::Borrowed(&[1, 1]),
896
1
            children_merkle_values: [
897
1
                None,
898
1
                Some(Cow::Borrowed(&[2; 32])),
899
1
                None,
900
1
                None,
901
1
                None,
902
1
                None,
903
1
                None,
904
1
                None,
905
1
                None,
906
1
                None,
907
1
                None,
908
1
                None,
909
1
                None,
910
1
                None,
911
1
                None,
912
1
                None,
913
1
            ],
914
1
            storage_value: InsertTrieNodeStorageValue::Value {
915
1
                value: Cow::Borrowed(b"hello"),
916
1
                references_merkle_value: false,
917
1
            },
918
1
        }]
919
1
        .into_iter(),
920
1
        0,
921
1
    )
922
1
    .unwrap();
923
1
924
1
    assert_eq!(
925
1
        db.block_storage_closest_descendant_merkle_value(
926
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
927
1
            iter::empty::<iter::Empty<_>>(),
928
1
            [1].into_iter(),
929
1
        )
930
1
        .unwrap()
931
1
        .unwrap(),
932
1
        vec![1; 32]
933
1
    );
934
935
1
    assert_eq!(
936
1
        db.block_storage_closest_descendant_merkle_value(
937
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
938
1
            iter::empty::<iter::Empty<_>>(),
939
1
            [1, 1].into_iter(),
940
1
        )
941
1
        .unwrap()
942
1
        .unwrap(),
943
1
        vec![1; 32]
944
1
    );
945
946
1
    assert_eq!(
947
1
        db.block_storage_closest_descendant_merkle_value(
948
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
949
1
            iter::empty::<iter::Empty<_>>(),
950
1
            [1, 1, 1].into_iter(),
951
1
        )
952
1
        .unwrap()
953
1
        .unwrap(),
954
1
        vec![2; 32]
955
1
    );
956
957
1
    assert!(
matches!0
(
958
1
        db.block_storage_closest_descendant_merkle_value(
959
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
960
1
            iter::empty::<iter::Empty<_>>(),
961
1
            [1, 1, 1, 1].into_iter(),
962
1
        ),
963
        Err(StorageAccessError::IncompleteStorage)
964
    ));
965
966
1
    assert_eq!(
967
1
        db.block_storage_closest_descendant_merkle_value(
968
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
969
1
            iter::empty::<iter::Empty<_>>(),
970
1
            [1, 1, 2].into_iter(),
971
1
        )
972
1
        .unwrap(),
973
1
        None
974
1
    );
975
976
1
    assert_eq!(
977
1
        db.block_storage_closest_descendant_merkle_value(
978
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
979
1
            iter::empty::<iter::Empty<_>>(),
980
1
            [5].into_iter(),
981
1
        )
982
1
        .unwrap(),
983
1
        None
984
1
    );
985
986
1
    db.insert_trie_nodes(
987
1
        [InsertTrieNode {
988
1
            merkle_value: Cow::Borrowed(&[2; 32]),
989
1
            partial_key_nibbles: Cow::Borrowed(&[1, 1]),
990
1
            children_merkle_values: [
991
1
                None, None, None, None, None, None, None, None, None, None, None, None, None, None,
992
1
                None, None,
993
1
            ],
994
1
            storage_value: InsertTrieNodeStorageValue::Value {
995
1
                value: Cow::Borrowed(b"world"),
996
1
                references_merkle_value: false,
997
1
            },
998
1
        }]
999
1
        .into_iter(),
1000
1
        0,
1001
1
    )
1002
1
    .unwrap();
1003
1
1004
1
    assert_eq!(
1005
1
        db.block_storage_closest_descendant_merkle_value(
1006
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
1007
1
            iter::empty::<iter::Empty<_>>(),
1008
1
            [1, 1].into_iter(),
1009
1
        )
1010
1
        .unwrap()
1011
1
        .unwrap(),
1012
1
        vec![1; 32]
1013
1
    );
1014
1015
1
    assert_eq!(
1016
1
        db.block_storage_closest_descendant_merkle_value(
1017
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
1018
1
            iter::empty::<iter::Empty<_>>(),
1019
1
            [1, 1, 1].into_iter(),
1020
1
        )
1021
1
        .unwrap()
1022
1
        .unwrap(),
1023
1
        vec![2; 32]
1024
1
    );
1025
1026
1
    assert_eq!(
1027
1
        db.block_storage_closest_descendant_merkle_value(
1028
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
1029
1
            iter::empty::<iter::Empty<_>>(),
1030
1
            [1, 1, 1, 1].into_iter(),
1031
1
        )
1032
1
        .unwrap()
1033
1
        .unwrap(),
1034
1
        vec![2; 32]
1035
1
    );
1036
1037
1
    assert_eq!(
1038
1
        db.block_storage_closest_descendant_merkle_value(
1039
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
1040
1
            iter::empty::<iter::Empty<_>>(),
1041
1
            [1, 1, 2].into_iter(),
1042
1
        )
1043
1
        .unwrap(),
1044
1
        None
1045
1
    );
1046
1047
1
    assert_eq!(
1048
1
        db.block_storage_closest_descendant_merkle_value(
1049
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
1050
1
            iter::empty::<iter::Empty<_>>(),
1051
1
            [1, 1, 1, 2].into_iter(),
1052
1
        )
1053
1
        .unwrap(),
1054
1
        None
1055
1
    );
1056
1057
1
    assert_eq!(
1058
1
        db.block_storage_closest_descendant_merkle_value(
1059
1
            &db.block_hash_by_number(0).unwrap().next().unwrap(),
1060
1
            iter::empty::<iter::Empty<_>>(),
1061
1
            [1, 1, 1, 1, 1, 1, 1, 1].into_iter(),
1062
1
        )
1063
1
        .unwrap(),
1064
1
        None
1065
1
    );
1066
1
}