Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/author/runtime/tests.rs
Line
Count
Source (jump to first uncovered line)
1
// Smoldot
2
// Copyright (C) 2019-2022  Parity Technologies (UK) Ltd.
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 crate::{trie, verify::inherents};
21
use core::iter;
22
23
#[test]
24
1
fn block_building_works() {
25
1
    let chain_specs = crate::chain_spec::ChainSpec::from_json_bytes(
26
1
        &include_bytes!("example-chain-specs.json")[..],
27
1
    )
28
1
    .unwrap();
29
1
    let genesis_storage = chain_specs.genesis_storage().into_genesis_items().unwrap();
30
1
31
1
    let (chain_info, genesis_runtime) = chain_specs.to_chain_information().unwrap();
32
1
    let genesis_hash = chain_info.as_ref().finalized_block_header.hash(4);
33
1
34
1
    let mut builder = super::build_block(super::Config {
35
1
        block_number_bytes: 4,
36
1
        parent_runtime: genesis_runtime,
37
1
        parent_hash: &genesis_hash,
38
1
        parent_number: 0,
39
1
        block_body_capacity: 0,
40
1
        consensus_digest_log_item: super::ConfigPreRuntime::Aura(crate::header::AuraPreDigest {
41
1
            slot_number: 1234u64,
42
1
        }),
43
1
        max_log_level: 0,
44
1
        calculate_trie_changes: false,
45
1
    });
46
47
    loop {
48
1
        match builder {
49
1
            super::BlockBuild::Finished(Ok(success)) => {
50
1
                let decoded = crate::header::decode(&success.scale_encoded_header, 4).unwrap();
51
1
                assert_eq!(decoded.number, 1);
52
1
                assert_eq!(*decoded.parent_hash, genesis_hash);
53
1
                break;
54
            }
55
0
            super::BlockBuild::Finished(Err((err, _))) => panic!("{}", err),
56
1
            super::BlockBuild::ApplyExtrinsic(ext) => builder = ext.finish(),
57
0
            super::BlockBuild::ApplyExtrinsicResult { .. } => unreachable!(),
58
1
            super::BlockBuild::InherentExtrinsics(ext) => {
59
1
                builder = ext.inject_inherents(inherents::InherentData { timestamp: 1234 });
60
1
            }
61
146
            super::BlockBuild::StorageGet(get) => {
62
146
                let value = genesis_storage
63
146
                    .iter()
64
8.72k
                    .find(|(k, _)| *k == get.key().as_ref())
65
146
                    .map(|(_, v)| 
iter::once(v)97
);
66
146
                builder = get.inject_value(value.map(|v| 
(v, super::TrieEntryVersion::V0)97
));
67
146
            }
68
1.86k
            super::BlockBuild::ClosestDescendantMerkleValue(req) => {
69
1.86k
                builder = req.resume_unknown();
70
1.86k
            }
71
0
            super::BlockBuild::OffchainStorageSet(req) => {
72
0
                builder = req.resume();
73
0
            }
74
2.19k
            super::BlockBuild::NextKey(req) => {
75
2.19k
                let mut search = trie::branch_search::BranchSearch::NextKey(
76
2.19k
                    trie::branch_search::start_branch_search(trie::branch_search::Config {
77
2.19k
                        key_before: req.key().collect::<Vec<_>>().into_iter(),
78
2.19k
                        or_equal: req.or_equal(),
79
2.19k
                        prefix: req.prefix().collect::<Vec<_>>().into_iter(),
80
2.19k
                        no_branch_search: !req.branch_nodes(),
81
2.19k
                    }),
82
2.19k
                );
83
84
4.55k
                let 
next_key2.19k
= loop {
85
4.55k
                    match search {
86
                        trie::branch_search::BranchSearch::Found {
87
2.19k
                            branch_trie_node_key,
88
2.19k
                        } => break branch_trie_node_key,
89
2.35k
                        trie::branch_search::BranchSearch::NextKey(req) => {
90
207k
                            let result = genesis_storage.iter().fold(None, |iter, (key, _)| {
91
207k
                                if key < &req.key_before().collect::<Vec<_>>()[..]
92
102k
                                    || (key == req.key_before().collect::<Vec<_>>()
93
0
                                        && !req.or_equal())
94
102k
                                    || !key.starts_with(&req.prefix().collect::<Vec<_>>())
95
                                {
96
203k
                                    return iter;
97
3.42k
                                }
98
3.42k
99
3.42k
                                if iter.map_or(false, |iter| 
iter < key3.05k
) {
100
3.05k
                                    iter
101
                                } else {
102
369
                                    Some(key)
103
                                }
104
207k
                            });
105
2.35k
106
2.35k
                            search = req.inject(result.map(|k| 
k.iter().copied()369
));
107
2.35k
                        }
108
                    }
109
                };
110
111
2.19k
                builder = req.inject_key(next_key.map(|nk| 
nk.into_iter()122
));
112
            }
113
        }
114
    }
115
1
}