Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/header.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
//! Parsing SCALE-encoded header.
19
//!
20
//! Each block of a chain is composed of two parts: its header, and its body.
21
//!
22
//! The header of a block consists in a list of hard coded fields such as the parent block's hash
23
//! or the block number, and a variable-sized list of log items.
24
//!
25
//! The standard format of a block header is the
26
//! [SCALE encoding](https://docs.substrate.io/v3/advanced/scale-codec). It is typically
27
//! under this encoding that block headers are for example transferred over the network or stored
28
//! in the database. Use the [`decode`] function in order to decompose a SCALE-encoded header
29
//! into a usable [`HeaderRef`].
30
//!
31
//! # Example
32
//!
33
//! ```
34
//! // Example encoded header.
35
//! let scale_encoded_header: &[u8] = &[
36
//!     246, 90, 76, 223, 195, 230, 202, 111, 120, 197, 6, 9, 90, 164, 170, 8, 194, 57, 184, 75,
37
//!     95, 67, 240, 169, 62, 244, 171, 95, 237, 85, 86, 1, 122, 169, 8, 0, 138, 149, 72, 185, 56,
38
//!     62, 30, 76, 117, 134, 123, 62, 4, 132, 23, 143, 200, 150, 171, 42, 63, 19, 173, 21, 89, 98,
39
//!     38, 175, 43, 132, 69, 75, 96, 168, 82, 108, 19, 182, 130, 230, 161, 43, 7, 225, 20, 229,
40
//!     92, 103, 57, 188, 151, 170, 16, 8, 126, 122, 98, 131, 121, 43, 181, 19, 180, 228, 8, 6, 66,
41
//!     65, 66, 69, 181, 1, 3, 1, 0, 0, 0, 250, 8, 207, 15, 0, 0, 0, 0, 86, 157, 105, 202, 151,
42
//!     254, 95, 169, 249, 150, 219, 194, 195, 143, 181, 39, 43, 87, 179, 157, 152, 191, 40, 255,
43
//!     23, 66, 18, 249, 93, 170, 58, 15, 178, 210, 130, 18, 66, 244, 232, 119, 74, 190, 92, 145,
44
//!     33, 192, 195, 176, 125, 217, 124, 33, 167, 97, 64, 63, 149, 200, 220, 191, 64, 134, 232, 9,
45
//!     3, 178, 186, 150, 130, 105, 25, 148, 218, 35, 208, 226, 112, 85, 184, 237, 23, 243, 86, 81,
46
//!     27, 127, 188, 223, 162, 244, 26, 77, 234, 116, 24, 11, 5, 66, 65, 66, 69, 1, 1, 112, 68,
47
//!     111, 83, 145, 78, 98, 96, 247, 64, 179, 237, 113, 175, 125, 177, 110, 39, 185, 55, 156,
48
//!     197, 177, 225, 226, 90, 238, 223, 115, 193, 185, 35, 67, 216, 98, 25, 55, 225, 224, 19, 43,
49
//!     255, 226, 125, 22, 160, 33, 182, 222, 213, 150, 40, 108, 108, 124, 254, 140, 228, 155, 29,
50
//!     250, 193, 65, 140,
51
//! ];
52
//!
53
//! // Decoding the header can panic if it is malformed. Do not unwrap if, for example, the
54
//! // header has been received from a remote!
55
//! // The second parameter is specific to each chain and corresponds to the number of bytes
56
//! // that are used to encode block numbers. This value is also necessary when calculating
57
//! // the hash of the header or encoding it.
58
//! let decoded_header = smoldot::header::decode(&scale_encoded_header, 4).unwrap();
59
//!
60
//! println!("Block hash: {:?}", decoded_header.hash(4));
61
//! println!("Header number: {}", decoded_header.number);
62
//! println!("Parent block hash: {:?}", decoded_header.parent_hash);
63
//! for item in decoded_header.digest.logs() {
64
//!     println!("Digest item: {:?}", item);
65
//! }
66
//!
67
//! // Call `scale_encoding` to produce the header encoding.
68
//! let reencoded: Vec<u8> = decoded_header
69
//!     .scale_encoding(4)
70
//!     .fold(Vec::new(), |mut a, b| { a.extend_from_slice(b.as_ref()); a });
71
//! assert_eq!(reencoded, scale_encoded_header);
72
//! ```
73
74
// TODO: consider rewriting the encoding into a more legible style
75
76
use crate::{trie, util};
77
78
use alloc::{vec, vec::Vec};
79
use core::{fmt, iter, slice};
80
81
mod aura;
82
mod babe;
83
mod grandpa;
84
mod tests;
85
86
pub use aura::*;
87
pub use babe::*;
88
pub use grandpa::*;
89
90
/// Returns a hash of a SCALE-encoded header.
91
///
92
/// Does not verify the validity of the header.
93
1.07k
pub fn hash_from_scale_encoded_header(header: impl AsRef<[u8]>) -> [u8; 32] {
94
1.07k
    hash_from_scale_encoded_header_vectored(iter::once(header))
95
1.07k
}
_RINvNtCsN16ciHI6Qf_7smoldot6header30hash_from_scale_encoded_headerRShEB4_
Line
Count
Source
93
1.02k
pub fn hash_from_scale_encoded_header(header: impl AsRef<[u8]>) -> [u8; 32] {
94
1.02k
    hash_from_scale_encoded_header_vectored(iter::once(header))
95
1.02k
}
_RINvNtCsN16ciHI6Qf_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsdZExvAaxgia_5alloc3vec3VechEEB4_
Line
Count
Source
93
5
pub fn hash_from_scale_encoded_header(header: impl AsRef<[u8]>) -> [u8; 32] {
94
5
    hash_from_scale_encoded_header_vectored(iter::once(header))
95
5
}
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRRShECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRShECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsdZExvAaxgia_5alloc3vec3VechEECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsdZExvAaxgia_5alloc3vec3VechEEB4_
_RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRShECsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
93
2
pub fn hash_from_scale_encoded_header(header: impl AsRef<[u8]>) -> [u8; 32] {
94
2
    hash_from_scale_encoded_header_vectored(iter::once(header))
95
2
}
_RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsdZExvAaxgia_5alloc3vec3VechEECsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
93
2
pub fn hash_from_scale_encoded_header(header: impl AsRef<[u8]>) -> [u8; 32] {
94
2
    hash_from_scale_encoded_header_vectored(iter::once(header))
95
2
}
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRShECsiUjFBJteJ7x_17smoldot_full_node
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRShECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsdZExvAaxgia_5alloc3vec3VechEECscDgN54JpMGG_6author
_RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRShECsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
93
19
pub fn hash_from_scale_encoded_header(header: impl AsRef<[u8]>) -> [u8; 32] {
94
19
    hash_from_scale_encoded_header_vectored(iter::once(header))
95
19
}
_RINvNtCseuYC0Zibziv_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsdZExvAaxgia_5alloc3vec3VechEECsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
93
19
pub fn hash_from_scale_encoded_header(header: impl AsRef<[u8]>) -> [u8; 32] {
94
19
    hash_from_scale_encoded_header_vectored(iter::once(header))
95
19
}
96
97
/// Returns a hash of a SCALE-encoded header.
98
///
99
/// Must be passed a list of buffers, which, when concatenated, form the SCALE-encoded header.
100
///
101
/// Does not verify the validity of the header.
102
1.14k
pub fn hash_from_scale_encoded_header_vectored(
103
1.14k
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
1.14k
) -> [u8; 32] {
105
1.14k
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
2.61k
    for 
buf1.46k
in header {
107
1.46k
        hasher.update(buf.as_ref());
108
1.46k
    }
109
110
1.14k
    let result = hasher.finalize();
111
1.14k
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
1.14k
    let mut out = [0; 32];
114
1.14k
    out.copy_from_slice(result.as_bytes());
115
1.14k
    out
116
1.14k
}
_RINvNtCsN16ciHI6Qf_7smoldot6header39hash_from_scale_encoded_header_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1c_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1c_B1O_IB1c_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1L_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3E_3map3MapIB3A_IB3A_IB3A_INtNtNtB3G_7sources4once4OnceB1G_EB4X_EB4X_EB4X_ENcNtB1b_4Left0EIB4s_IB3A_IB4Y_B2F_EINtNtB3E_7flatten7FlatMapNtB2_8LogsIterIB4s_INtNtNtB3I_5array4iter8IntoIterB2O_Kj2_ENcNtB2F_5Right0ENCNvMs2_B2_NtB2_9DigestRef14scale_encoding0EENcNtB1b_5Right0EEEB4_
Line
Count
Source
102
11
pub fn hash_from_scale_encoded_header_vectored(
103
11
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
11
) -> [u8; 32] {
105
11
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
90
    for 
buf79
in header {
107
79
        hasher.update(buf.as_ref());
108
79
    }
109
110
11
    let result = hasher.finalize();
111
11
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
11
    let mut out = [0; 32];
114
11
    out.copy_from_slice(result.as_bytes());
115
11
    out
116
11
}
_RINvNtCsN16ciHI6Qf_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1b_EEB4_
Line
Count
Source
102
5
pub fn hash_from_scale_encoded_header_vectored(
103
5
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
5
) -> [u8; 32] {
105
5
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
10
    for 
buf5
in header {
107
5
        hasher.update(buf.as_ref());
108
5
    }
109
110
5
    let result = hasher.finalize();
111
5
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
5
    let mut out = [0; 32];
114
5
    out.copy_from_slice(result.as_bytes());
115
5
    out
116
5
}
_RINvNtCsN16ciHI6Qf_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1b_EEB4_
Line
Count
Source
102
1.02k
pub fn hash_from_scale_encoded_header_vectored(
103
1.02k
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
1.02k
) -> [u8; 32] {
105
1.02k
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
2.05k
    for 
buf1.02k
in header {
107
1.02k
        hasher.update(buf.as_ref());
108
1.02k
    }
109
110
1.02k
    let result = hasher.finalize();
111
1.02k
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
1.02k
    let mut out = [0; 32];
114
1.02k
    out.copy_from_slice(result.as_bytes());
115
1.02k
    out
116
1.02k
}
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECsDDUKWWCHAU_18smoldot_light_wasm
_RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredINtCs1qmLyiTSqYF_6either6EitherIB1d_RShINtNtCsjZUZ4cETtOy_8arrayvec8arrayvec8ArrayVechKj9_EEIB1d_B1P_IB1d_INtNtCsdZExvAaxgia_5alloc3vec3VechEB1M_EEEINtNtNtNtCsaYZPK01V26L_4core4iter8adapters5chain5ChainINtNtB3F_3map3MapIB3B_IB3B_IB3B_INtNtNtB3H_7sources4once4OnceB1H_EB4Y_EB4Y_EB4Y_ENcNtB1c_4Left0EIB4t_IB3B_IB4Z_B2G_EINtNtB3F_7flatten7FlatMapNtB2_8LogsIterIB4t_INtNtNtB3J_5array4iter8IntoIterB2P_Kj2_ENcNtB2G_5Right0ENCNvMs2_B2_NtB2_9DigestRef14scale_encoding0EENcNtB1c_5Right0EEEB4_
Line
Count
Source
102
63
pub fn hash_from_scale_encoded_header_vectored(
103
63
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
63
) -> [u8; 32] {
105
63
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
378
    for 
buf315
in header {
107
315
        hasher.update(buf.as_ref());
108
315
    }
109
110
63
    let result = hasher.finalize();
111
63
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
63
    let mut out = [0; 32];
114
63
    out.copy_from_slice(result.as_bytes());
115
63
    out
116
63
}
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EEB4_
_RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
102
2
pub fn hash_from_scale_encoded_header_vectored(
103
2
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
2
) -> [u8; 32] {
105
2
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
4
    for 
buf2
in header {
107
2
        hasher.update(buf.as_ref());
108
2
    }
109
110
2
    let result = hasher.finalize();
111
2
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
2
    let mut out = [0; 32];
114
2
    out.copy_from_slice(result.as_bytes());
115
2
    out
116
2
}
_RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
102
2
pub fn hash_from_scale_encoded_header_vectored(
103
2
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
2
) -> [u8; 32] {
105
2
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
4
    for 
buf2
in header {
107
2
        hasher.update(buf.as_ref());
108
2
    }
109
110
2
    let result = hasher.finalize();
111
2
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
2
    let mut out = [0; 32];
114
2
    out.copy_from_slice(result.as_bytes());
115
2
    out
116
2
}
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECsiUjFBJteJ7x_17smoldot_full_node
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECscDgN54JpMGG_6author
_RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
102
19
pub fn hash_from_scale_encoded_header_vectored(
103
19
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
19
) -> [u8; 32] {
105
19
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
38
    for 
buf19
in header {
107
19
        hasher.update(buf.as_ref());
108
19
    }
109
110
19
    let result = hasher.finalize();
111
19
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
19
    let mut out = [0; 32];
114
19
    out.copy_from_slice(result.as_bytes());
115
19
    out
116
19
}
_RINvNtCseuYC0Zibziv_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1c_EECsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
102
19
pub fn hash_from_scale_encoded_header_vectored(
103
19
    header: impl Iterator<Item = impl AsRef<[u8]>>,
104
19
) -> [u8; 32] {
105
19
    let mut hasher = blake2_rfc::blake2b::Blake2b::with_key(32, &[]);
106
38
    for 
buf19
in header {
107
19
        hasher.update(buf.as_ref());
108
19
    }
109
110
19
    let result = hasher.finalize();
111
19
    debug_assert_eq!(result.as_bytes().len(), 32);
112
113
19
    let mut out = [0; 32];
114
19
    out.copy_from_slice(result.as_bytes());
115
19
    out
116
19
}
117
118
/// Returns the value appropriate for [`Header::extrinsics_root`]. Must be passed the list of
119
/// transactions in that block.
120
0
pub fn extrinsics_root(transactions: &[impl AsRef<[u8]>]) -> [u8; 32] {
121
0
    // The extrinsics root is always calculated with V0 of the trie.
122
0
    trie::ordered_root(
123
0
        trie::TrieEntryVersion::V0,
124
0
        trie::HashFunction::Blake2,
125
0
        transactions,
126
0
    )
127
0
}
Unexecuted instantiation: _RINvNtCsN16ciHI6Qf_7smoldot6header15extrinsics_rootpEB4_
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header15extrinsics_rootINtNtCsdZExvAaxgia_5alloc3vec3VechEECsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header15extrinsics_rootpEB4_
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header15extrinsics_rootINtNtCsdZExvAaxgia_5alloc3vec3VechEECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header15extrinsics_rootINtNtCsdZExvAaxgia_5alloc3vec3VechEECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvNtCseuYC0Zibziv_7smoldot6header15extrinsics_rootINtNtCsdZExvAaxgia_5alloc3vec3VechEECsibGXYHQB8Ea_25json_rpc_general_requests
128
129
/// Attempt to decode the given SCALE-encoded header.
130
1.51k
pub fn decode(scale_encoded: &[u8], block_number_bytes: usize) -> Result<HeaderRef, Error> {
131
1.51k
    let (
header, remainder1.51k
) = decode_partial(scale_encoded, block_number_bytes)
?1
;
132
1.51k
    if !remainder.is_empty() {
133
0
        return Err(Error::TooLong);
134
1.51k
    }
135
1.51k
136
1.51k
    Ok(header)
137
1.51k
}
_RNvNtCsN16ciHI6Qf_7smoldot6header6decode
Line
Count
Source
130
1.05k
pub fn decode(scale_encoded: &[u8], block_number_bytes: usize) -> Result<HeaderRef, Error> {
131
1.05k
    let (
header, remainder1.04k
) = decode_partial(scale_encoded, block_number_bytes)
?1
;
132
1.04k
    if !remainder.is_empty() {
133
0
        return Err(Error::TooLong);
134
1.04k
    }
135
1.04k
136
1.04k
    Ok(header)
137
1.05k
}
_RNvNtCseuYC0Zibziv_7smoldot6header6decode
Line
Count
Source
130
464
pub fn decode(scale_encoded: &[u8], block_number_bytes: usize) -> Result<HeaderRef, Error> {
131
464
    let (header, remainder) = decode_partial(scale_encoded, block_number_bytes)
?0
;
132
464
    if !remainder.is_empty() {
133
0
        return Err(Error::TooLong);
134
464
    }
135
464
136
464
    Ok(header)
137
464
}
138
139
/// Attempt to decode the given SCALE-encoded header.
140
///
141
/// Contrary to [`decode`], doesn't return an error if the slice is too long but returns the
142
/// remainder.
143
1.51k
pub fn decode_partial(
144
1.51k
    mut scale_encoded: &[u8],
145
1.51k
    block_number_bytes: usize,
146
1.51k
) -> Result<(HeaderRef, &[u8]), Error> {
147
1.51k
    if scale_encoded.len() < 32 + 1 {
148
0
        return Err(Error::TooShort);
149
1.51k
    }
150
1.51k
151
1.51k
    let parent_hash: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
152
1.51k
    scale_encoded = &scale_encoded[32..];
153
154
1.51k
    let (mut scale_encoded, number) =
155
1.51k
        crate::util::nom_scale_compact_u64::<nom::error::Error<&[u8]>>(scale_encoded)
156
1.51k
            .map_err(|_| 
Error::BlockNumberDecodeError0
)
?0
;
Unexecuted instantiation: _RNCNvNtCsN16ciHI6Qf_7smoldot6header14decode_partial0B5_
Unexecuted instantiation: _RNCNvNtCseuYC0Zibziv_7smoldot6header14decode_partial0B5_
157
158
1.51k
    if scale_encoded.len() < 32 + 32 + 1 {
159
0
        return Err(Error::TooShort);
160
1.51k
    }
161
1.51k
162
1.51k
    let state_root: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
163
1.51k
    scale_encoded = &scale_encoded[32..];
164
1.51k
    let extrinsics_root: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
165
1.51k
    scale_encoded = &scale_encoded[32..];
166
167
1.51k
    let (
digest, remainder1.51k
) = DigestRef::from_scale_bytes(scale_encoded, block_number_bytes)
?1
;
168
169
1.51k
    let header = HeaderRef {
170
1.51k
        parent_hash,
171
1.51k
        number,
172
1.51k
        state_root,
173
1.51k
        extrinsics_root,
174
1.51k
        digest,
175
1.51k
    };
176
1.51k
177
1.51k
    Ok((header, remainder))
178
1.51k
}
_RNvNtCsN16ciHI6Qf_7smoldot6header14decode_partial
Line
Count
Source
143
1.05k
pub fn decode_partial(
144
1.05k
    mut scale_encoded: &[u8],
145
1.05k
    block_number_bytes: usize,
146
1.05k
) -> Result<(HeaderRef, &[u8]), Error> {
147
1.05k
    if scale_encoded.len() < 32 + 1 {
148
0
        return Err(Error::TooShort);
149
1.05k
    }
150
1.05k
151
1.05k
    let parent_hash: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
152
1.05k
    scale_encoded = &scale_encoded[32..];
153
154
1.05k
    let (mut scale_encoded, number) =
155
1.05k
        crate::util::nom_scale_compact_u64::<nom::error::Error<&[u8]>>(scale_encoded)
156
1.05k
            .map_err(|_| Error::BlockNumberDecodeError)
?0
;
157
158
1.05k
    if scale_encoded.len() < 32 + 32 + 1 {
159
0
        return Err(Error::TooShort);
160
1.05k
    }
161
1.05k
162
1.05k
    let state_root: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
163
1.05k
    scale_encoded = &scale_encoded[32..];
164
1.05k
    let extrinsics_root: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
165
1.05k
    scale_encoded = &scale_encoded[32..];
166
167
1.05k
    let (
digest, remainder1.04k
) = DigestRef::from_scale_bytes(scale_encoded, block_number_bytes)
?1
;
168
169
1.04k
    let header = HeaderRef {
170
1.04k
        parent_hash,
171
1.04k
        number,
172
1.04k
        state_root,
173
1.04k
        extrinsics_root,
174
1.04k
        digest,
175
1.04k
    };
176
1.04k
177
1.04k
    Ok((header, remainder))
178
1.05k
}
_RNvNtCseuYC0Zibziv_7smoldot6header14decode_partial
Line
Count
Source
143
464
pub fn decode_partial(
144
464
    mut scale_encoded: &[u8],
145
464
    block_number_bytes: usize,
146
464
) -> Result<(HeaderRef, &[u8]), Error> {
147
464
    if scale_encoded.len() < 32 + 1 {
148
0
        return Err(Error::TooShort);
149
464
    }
150
464
151
464
    let parent_hash: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
152
464
    scale_encoded = &scale_encoded[32..];
153
154
464
    let (mut scale_encoded, number) =
155
464
        crate::util::nom_scale_compact_u64::<nom::error::Error<&[u8]>>(scale_encoded)
156
464
            .map_err(|_| Error::BlockNumberDecodeError)
?0
;
157
158
464
    if scale_encoded.len() < 32 + 32 + 1 {
159
0
        return Err(Error::TooShort);
160
464
    }
161
464
162
464
    let state_root: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
163
464
    scale_encoded = &scale_encoded[32..];
164
464
    let extrinsics_root: &[u8; 32] = TryFrom::try_from(&scale_encoded[0..32]).unwrap();
165
464
    scale_encoded = &scale_encoded[32..];
166
167
464
    let (digest, remainder) = DigestRef::from_scale_bytes(scale_encoded, block_number_bytes)
?0
;
168
169
464
    let header = HeaderRef {
170
464
        parent_hash,
171
464
        number,
172
464
        state_root,
173
464
        extrinsics_root,
174
464
        digest,
175
464
    };
176
464
177
464
    Ok((header, remainder))
178
464
}
179
180
/// Potential error when decoding a header.
181
0
#[derive(Debug, derive_more::Display, Clone)]
Unexecuted instantiation: _RNvXse_NtCsN16ciHI6Qf_7smoldot6headerNtB5_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXse_NtCseuYC0Zibziv_7smoldot6headerNtB5_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
182
pub enum Error {
183
    /// Header is not long enough.
184
    TooShort,
185
    /// Header is too long.
186
    TooLong,
187
    /// Error while decoding the block number.
188
    BlockNumberDecodeError,
189
    /// Error while decoding the digest length.
190
    DigestLenDecodeError,
191
    /// Error while decoding a digest log item length.
192
    DigestItemLenDecodeError,
193
    /// Error while decoding a digest item.
194
    DigestItemDecodeError,
195
    /// Digest log item with an unrecognized type.
196
    #[display(fmt = "Digest log with an unrecognized type {_0}")]
197
    UnknownDigestLogType(u8),
198
    /// Found a seal that isn't the last item in the list.
199
    SealIsntLastItem,
200
    /// Bad length of an AURA seal.
201
    BadAuraSealLength,
202
    BadAuraConsensusRefType,
203
    BadAuraAuthoritiesListLen,
204
    /// There are multiple Aura pre-runtime digests in the block header.
205
    MultipleAuraPreRuntimeDigests,
206
    /// Bad length of a BABE seal.
207
    BadBabeSealLength,
208
    BadBabePreDigestRefType,
209
    BadBabeConsensusRefType,
210
    BadBabeNextConfigVersion,
211
    /// There are multiple Babe pre-runtime digests in the block header.
212
    MultipleBabePreRuntimeDigests,
213
    /// There are multiple Babe epoch descriptor digests in the block header.
214
    MultipleBabeEpochDescriptors,
215
    /// There are multiple Babe configuration descriptor digests in the block header.
216
    MultipleBabeConfigDescriptors,
217
    /// There are multiple runtime environment updated digests in the block header.
218
    MutipleRuntimeEnvironmentUpdated,
219
    /// Found a Babe configuration change digest without an epoch change digest.
220
    UnexpectedBabeConfigDescriptor,
221
    GrandpaConsensusLogDecodeError,
222
    /// Proof-of-work consensus algorithm is intentionally not supported for ideological reasons.
223
    PowIdeologicallyNotSupported,
224
}
225
226
/// Header of a block, after decoding.
227
///
228
/// Note that the information in there are not guaranteed to be exact. The exactness of the
229
/// information depends on the context.
230
#[derive(Debug, Clone)]
231
pub struct HeaderRef<'a> {
232
    /// Hash of the parent block stored in the header.
233
    pub parent_hash: &'a [u8; 32],
234
    /// Block number stored in the header.
235
    pub number: u64,
236
    /// The state trie Merkle root
237
    pub state_root: &'a [u8; 32],
238
    /// The Merkle root of the extrinsics.
239
    ///
240
    /// You can use the [`extrinsics_root`] function to compute this value.
241
    pub extrinsics_root: &'a [u8; 32],
242
    /// List of auxiliary data appended to the block header.
243
    pub digest: DigestRef<'a>,
244
}
245
246
impl<'a> HeaderRef<'a> {
247
    /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE
248
    /// encoding of the header.
249
1.19k
    pub fn scale_encoding(
250
1.19k
        &self,
251
1.19k
        block_number_bytes: usize,
252
1.19k
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
253
1.19k
        self.scale_encoding_before_digest().map(either::Left).chain(
254
1.19k
            self.digest
255
1.19k
                .scale_encoding(block_number_bytes)
256
1.19k
                .map(either::Right),
257
1.19k
        )
258
1.19k
    }
_RNvMNtCsN16ciHI6Qf_7smoldot6headerNtB2_9HeaderRef14scale_encoding
Line
Count
Source
249
1.04k
    pub fn scale_encoding(
250
1.04k
        &self,
251
1.04k
        block_number_bytes: usize,
252
1.04k
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
253
1.04k
        self.scale_encoding_before_digest().map(either::Left).chain(
254
1.04k
            self.digest
255
1.04k
                .scale_encoding(block_number_bytes)
256
1.04k
                .map(either::Right),
257
1.04k
        )
258
1.04k
    }
_RNvMNtCseuYC0Zibziv_7smoldot6headerNtB2_9HeaderRef14scale_encoding
Line
Count
Source
249
147
    pub fn scale_encoding(
250
147
        &self,
251
147
        block_number_bytes: usize,
252
147
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
253
147
        self.scale_encoding_before_digest().map(either::Left).chain(
254
147
            self.digest
255
147
                .scale_encoding(block_number_bytes)
256
147
                .map(either::Right),
257
147
        )
258
147
    }
259
260
    /// Same as [`HeaderRef::scale_encoding`], but with an extra digest item added to the end of
261
    /// the list.
262
    ///
263
    /// > **Note**: Keep in mind that this can produce a potentially invalid header, for example
264
    /// >           if the digest contains duplicate items that shouldn't be duplicate.
265
0
    pub fn scale_encoding_with_extra_digest_item(
266
0
        &self,
267
0
        block_number_bytes: usize,
268
0
        extra_item: DigestItemRef<'a>,
269
0
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
270
0
        self.scale_encoding_before_digest().map(either::Left).chain(
271
0
            self.digest
272
0
                .scale_encoding_with_extra_item(block_number_bytes, extra_item)
273
0
                .map(either::Right),
274
0
        )
275
0
    }
Unexecuted instantiation: _RNvMNtCsN16ciHI6Qf_7smoldot6headerNtB2_9HeaderRef37scale_encoding_with_extra_digest_item
Unexecuted instantiation: _RNvMNtCseuYC0Zibziv_7smoldot6headerNtB2_9HeaderRef37scale_encoding_with_extra_digest_item
276
277
1.19k
    fn scale_encoding_before_digest(
278
1.19k
        &self,
279
1.19k
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
280
1.19k
        iter::once(either::Left(&self.parent_hash[..]))
281
1.19k
            .chain(iter::once(either::Right(util::encode_scale_compact_u64(
282
1.19k
                self.number,
283
1.19k
            ))))
284
1.19k
            .chain(iter::once(either::Left(&self.state_root[..])))
285
1.19k
            .chain(iter::once(either::Left(&self.extrinsics_root[..])))
286
1.19k
    }
_RNvMNtCsN16ciHI6Qf_7smoldot6headerNtB2_9HeaderRef28scale_encoding_before_digest
Line
Count
Source
277
1.04k
    fn scale_encoding_before_digest(
278
1.04k
        &self,
279
1.04k
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
280
1.04k
        iter::once(either::Left(&self.parent_hash[..]))
281
1.04k
            .chain(iter::once(either::Right(util::encode_scale_compact_u64(
282
1.04k
                self.number,
283
1.04k
            ))))
284
1.04k
            .chain(iter::once(either::Left(&self.state_root[..])))
285
1.04k
            .chain(iter::once(either::Left(&self.extrinsics_root[..])))
286
1.04k
    }
_RNvMNtCseuYC0Zibziv_7smoldot6headerNtB2_9HeaderRef28scale_encoding_before_digest
Line
Count
Source
277
147
    fn scale_encoding_before_digest(
278
147
        &self,
279
147
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
280
147
        iter::once(either::Left(&self.parent_hash[..]))
281
147
            .chain(iter::once(either::Right(util::encode_scale_compact_u64(
282
147
                self.number,
283
147
            ))))
284
147
            .chain(iter::once(either::Left(&self.state_root[..])))
285
147
            .chain(iter::once(either::Left(&self.extrinsics_root[..])))
286
147
    }
287
288
    /// Equivalent to [`HeaderRef::scale_encoding`] but returns the data in a `Vec`.
289
1.11k
    pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> {
290
1.11k
        // We assume that an average header should be less than this size.
291
1.11k
        // At the time of writing of this comment, the average Westend/Polkadot/Kusama block
292
1.11k
        // header is 288 bytes, and the average parachain block is 186 bytes. Some blocks
293
1.11k
        // (the epoch transition blocks in particular) have a much larger header, but considering
294
1.11k
        // that they are the vast minority we don't care so much about that.
295
1.11k
        const CAP: usize = 1024;
296
1.11k
297
1.11k
        self.scale_encoding(block_number_bytes)
298
5.63k
            .fold(Vec::with_capacity(CAP), |mut a, b| {
299
5.63k
                a.extend_from_slice(b.as_ref());
300
5.63k
                a
301
5.63k
            })
_RNCNvMNtCsN16ciHI6Qf_7smoldot6headerNtB4_9HeaderRef18scale_encoding_vec0B6_
Line
Count
Source
298
5.21k
            .fold(Vec::with_capacity(CAP), |mut a, b| {
299
5.21k
                a.extend_from_slice(b.as_ref());
300
5.21k
                a
301
5.21k
            })
_RNCNvMNtCseuYC0Zibziv_7smoldot6headerNtB4_9HeaderRef18scale_encoding_vec0B6_
Line
Count
Source
298
420
            .fold(Vec::with_capacity(CAP), |mut a, b| {
299
420
                a.extend_from_slice(b.as_ref());
300
420
                a
301
420
            })
302
1.11k
    }
_RNvMNtCsN16ciHI6Qf_7smoldot6headerNtB2_9HeaderRef18scale_encoding_vec
Line
Count
Source
289
1.03k
    pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> {
290
1.03k
        // We assume that an average header should be less than this size.
291
1.03k
        // At the time of writing of this comment, the average Westend/Polkadot/Kusama block
292
1.03k
        // header is 288 bytes, and the average parachain block is 186 bytes. Some blocks
293
1.03k
        // (the epoch transition blocks in particular) have a much larger header, but considering
294
1.03k
        // that they are the vast minority we don't care so much about that.
295
1.03k
        const CAP: usize = 1024;
296
1.03k
297
1.03k
        self.scale_encoding(block_number_bytes)
298
1.03k
            .fold(Vec::with_capacity(CAP), |mut a, b| {
299
                a.extend_from_slice(b.as_ref());
300
                a
301
1.03k
            })
302
1.03k
    }
_RNvMNtCseuYC0Zibziv_7smoldot6headerNtB2_9HeaderRef18scale_encoding_vec
Line
Count
Source
289
84
    pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> {
290
84
        // We assume that an average header should be less than this size.
291
84
        // At the time of writing of this comment, the average Westend/Polkadot/Kusama block
292
84
        // header is 288 bytes, and the average parachain block is 186 bytes. Some blocks
293
84
        // (the epoch transition blocks in particular) have a much larger header, but considering
294
84
        // that they are the vast minority we don't care so much about that.
295
84
        const CAP: usize = 1024;
296
84
297
84
        self.scale_encoding(block_number_bytes)
298
84
            .fold(Vec::with_capacity(CAP), |mut a, b| {
299
                a.extend_from_slice(b.as_ref());
300
                a
301
84
            })
302
84
    }
303
304
    /// Builds the hash of the header.
305
74
    pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] {
306
74
        hash_from_scale_encoded_header_vectored(self.scale_encoding(block_number_bytes))
307
74
    }
_RNvMNtCsN16ciHI6Qf_7smoldot6headerNtB2_9HeaderRef4hash
Line
Count
Source
305
11
    pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] {
306
11
        hash_from_scale_encoded_header_vectored(self.scale_encoding(block_number_bytes))
307
11
    }
_RNvMNtCseuYC0Zibziv_7smoldot6headerNtB2_9HeaderRef4hash
Line
Count
Source
305
63
    pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] {
306
63
        hash_from_scale_encoded_header_vectored(self.scale_encoding(block_number_bytes))
307
63
    }
308
}
309
310
impl<'a> From<&'a Header> for HeaderRef<'a> {
311
365
    fn from(a: &'a Header) -> HeaderRef<'a> {
312
365
        HeaderRef {
313
365
            parent_hash: &a.parent_hash,
314
365
            number: a.number,
315
365
            state_root: &a.state_root,
316
365
            extrinsics_root: &a.extrinsics_root,
317
365
            digest: (&a.digest).into(),
318
365
        }
319
365
    }
_RNvXs_NtCsN16ciHI6Qf_7smoldot6headerNtB4_9HeaderRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB4_6HeaderE4from
Line
Count
Source
311
8
    fn from(a: &'a Header) -> HeaderRef<'a> {
312
8
        HeaderRef {
313
8
            parent_hash: &a.parent_hash,
314
8
            number: a.number,
315
8
            state_root: &a.state_root,
316
8
            extrinsics_root: &a.extrinsics_root,
317
8
            digest: (&a.digest).into(),
318
8
        }
319
8
    }
_RNvXs_NtCseuYC0Zibziv_7smoldot6headerNtB4_9HeaderRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB4_6HeaderE4from
Line
Count
Source
311
357
    fn from(a: &'a Header) -> HeaderRef<'a> {
312
357
        HeaderRef {
313
357
            parent_hash: &a.parent_hash,
314
357
            number: a.number,
315
357
            state_root: &a.state_root,
316
357
            extrinsics_root: &a.extrinsics_root,
317
357
            digest: (&a.digest).into(),
318
357
        }
319
357
    }
320
}
321
322
/// Header of a block, after decoding.
323
///
324
/// Note that the information in there are not guaranteed to be exact. The exactness of the
325
/// information depends on the context.
326
#[derive(Debug, Clone)]
327
pub struct Header {
328
    /// Hash of the parent block stored in the header.
329
    pub parent_hash: [u8; 32],
330
    /// Block number stored in the header.
331
    pub number: u64,
332
    /// The state trie Merkle root
333
    pub state_root: [u8; 32],
334
    /// The Merkle root of the extrinsics.
335
    ///
336
    /// You can use the [`extrinsics_root`] function to compute this value.
337
    pub extrinsics_root: [u8; 32],
338
    /// List of auxiliary data appended to the block header.
339
    pub digest: Digest,
340
}
341
342
impl Header {
343
    /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE
344
    /// encoding of the header.
345
0
    pub fn scale_encoding(
346
0
        &'_ self,
347
0
        block_number_bytes: usize,
348
0
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_ {
349
0
        HeaderRef::from(self).scale_encoding(block_number_bytes)
350
0
    }
Unexecuted instantiation: _RNvMs0_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Header14scale_encoding
Unexecuted instantiation: _RNvMs0_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Header14scale_encoding
351
352
    /// Equivalent to [`Header::scale_encoding`] but returns the data in a `Vec`.
353
23
    pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> {
354
23
        HeaderRef::from(self).scale_encoding_vec(block_number_bytes)
355
23
    }
_RNvMs0_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Header18scale_encoding_vec
Line
Count
Source
353
2
    pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> {
354
2
        HeaderRef::from(self).scale_encoding_vec(block_number_bytes)
355
2
    }
_RNvMs0_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Header18scale_encoding_vec
Line
Count
Source
353
21
    pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> {
354
21
        HeaderRef::from(self).scale_encoding_vec(block_number_bytes)
355
21
    }
356
357
    /// Builds the hash of the header.
358
23
    pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] {
359
23
        HeaderRef::from(self).hash(block_number_bytes)
360
23
    }
_RNvMs0_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Header4hash
Line
Count
Source
358
2
    pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] {
359
2
        HeaderRef::from(self).hash(block_number_bytes)
360
2
    }
_RNvMs0_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Header4hash
Line
Count
Source
358
21
    pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] {
359
21
        HeaderRef::from(self).hash(block_number_bytes)
360
21
    }
361
}
362
363
impl<'a> From<HeaderRef<'a>> for Header {
364
45
    fn from(a: HeaderRef<'a>) -> Header {
365
45
        Header {
366
45
            parent_hash: *a.parent_hash,
367
45
            number: a.number,
368
45
            state_root: *a.state_root,
369
45
            extrinsics_root: *a.extrinsics_root,
370
45
            digest: a.digest.into(),
371
45
        }
372
45
    }
_RNvXs1_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6HeaderINtNtCsaYZPK01V26L_4core7convert4FromNtB5_9HeaderRefE4from
Line
Count
Source
364
3
    fn from(a: HeaderRef<'a>) -> Header {
365
3
        Header {
366
3
            parent_hash: *a.parent_hash,
367
3
            number: a.number,
368
3
            state_root: *a.state_root,
369
3
            extrinsics_root: *a.extrinsics_root,
370
3
            digest: a.digest.into(),
371
3
        }
372
3
    }
_RNvXs1_NtCseuYC0Zibziv_7smoldot6headerNtB5_6HeaderINtNtCsaYZPK01V26L_4core7convert4FromNtB5_9HeaderRefE4from
Line
Count
Source
364
42
    fn from(a: HeaderRef<'a>) -> Header {
365
42
        Header {
366
42
            parent_hash: *a.parent_hash,
367
42
            number: a.number,
368
42
            state_root: *a.state_root,
369
42
            extrinsics_root: *a.extrinsics_root,
370
42
            digest: a.digest.into(),
371
42
        }
372
42
    }
373
}
374
375
/// Generic header digest.
376
#[derive(Clone)]
377
pub struct DigestRef<'a> {
378
    /// Actual source of digest items.
379
    inner: DigestRefInner<'a>,
380
    /// Index of the [`DigestItemRef::AuraSeal`] item, if any.
381
    aura_seal_index: Option<usize>,
382
    /// Index of the [`DigestItemRef::AuraPreDigest`] item, if any.
383
    aura_predigest_index: Option<usize>,
384
    /// Index of the [`DigestItemRef::BabeSeal`] item, if any.
385
    babe_seal_index: Option<usize>,
386
    /// Index of the [`DigestItemRef::BabePreDigest`] item, if any.
387
    babe_predigest_index: Option<usize>,
388
    /// Index of the [`DigestItemRef::BabeConsensus`] item containing a
389
    /// [`BabeConsensusLogRef::NextEpochData`], if any.
390
    babe_next_epoch_data_index: Option<usize>,
391
    /// Index of the [`DigestItemRef::BabeConsensus`] item containing a
392
    /// [`BabeConsensusLogRef::NextConfigData`], if any.
393
    babe_next_config_data_index: Option<usize>,
394
    /// `true` if there is a [`DigestItemRef::RuntimeEnvironmentUpdated`] item.
395
    has_runtime_environment_updated: bool,
396
}
397
398
#[derive(Clone)]
399
enum DigestRefInner<'a> {
400
    /// Source of data is an undecoded slice of bytes.
401
    Undecoded {
402
        /// Number of log items in the header.
403
        /// Must always match the actual number of items in [`DigestRefInner::Undecoded::digest`].
404
        /// The validity must be verified before a [`DigestRef`] object is instantiated.
405
        digest_logs_len: usize,
406
        /// Encoded digest. Its validity must be verified before a [`DigestRef`] object is
407
        /// instantiated.
408
        digest: &'a [u8],
409
        /// Number of bytes used to encode block numbers in headers.
410
        block_number_bytes: usize,
411
    },
412
    Parsed(&'a [DigestItem]),
413
}
414
415
impl<'a> DigestRef<'a> {
416
    /// Returns a digest with empty logs.
417
1.05k
    pub fn empty() -> DigestRef<'a> {
418
1.05k
        DigestRef {
419
1.05k
            inner: DigestRefInner::Parsed(&[]),
420
1.05k
            aura_seal_index: None,
421
1.05k
            aura_predigest_index: None,
422
1.05k
            babe_seal_index: None,
423
1.05k
            babe_predigest_index: None,
424
1.05k
            babe_next_epoch_data_index: None,
425
1.05k
            babe_next_config_data_index: None,
426
1.05k
            has_runtime_environment_updated: false,
427
1.05k
        }
428
1.05k
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef5empty
Line
Count
Source
417
1.03k
    pub fn empty() -> DigestRef<'a> {
418
1.03k
        DigestRef {
419
1.03k
            inner: DigestRefInner::Parsed(&[]),
420
1.03k
            aura_seal_index: None,
421
1.03k
            aura_predigest_index: None,
422
1.03k
            babe_seal_index: None,
423
1.03k
            babe_predigest_index: None,
424
1.03k
            babe_next_epoch_data_index: None,
425
1.03k
            babe_next_config_data_index: None,
426
1.03k
            has_runtime_environment_updated: false,
427
1.03k
        }
428
1.03k
    }
_RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef5empty
Line
Count
Source
417
21
    pub fn empty() -> DigestRef<'a> {
418
21
        DigestRef {
419
21
            inner: DigestRefInner::Parsed(&[]),
420
21
            aura_seal_index: None,
421
21
            aura_predigest_index: None,
422
21
            babe_seal_index: None,
423
21
            babe_predigest_index: None,
424
21
            babe_next_epoch_data_index: None,
425
21
            babe_next_config_data_index: None,
426
21
            has_runtime_environment_updated: false,
427
21
        }
428
21
    }
429
430
    /// Returns true if the list has any item that belong to the Aura consensus engine.
431
    ///
432
    /// This function is `O(n)` over the number of log items.
433
4
    pub fn has_any_aura(&self) -> bool {
434
10
        self.logs().any(|l| l.is_aura())
_RNCNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB7_9DigestRef12has_any_aura0B9_
Line
Count
Source
434
10
        self.logs().any(|l| l.is_aura())
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef12has_any_aura0B9_
435
4
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef12has_any_aura
Line
Count
Source
433
4
    pub fn has_any_aura(&self) -> bool {
434
4
        self.logs().any(|l| l.is_aura())
435
4
    }
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef12has_any_aura
436
437
    /// Returns true if the list has any item that belong to the Babe consensus engine.
438
    ///
439
    /// This function is `O(n)` over the number of log items.
440
42
    pub fn has_any_babe(&self) -> bool {
441
42
        self.logs().any(|l| 
l.is_babe()0
)
Unexecuted instantiation: _RNCNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB7_9DigestRef12has_any_babe0B9_
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef12has_any_babe0B9_
442
42
    }
Unexecuted instantiation: _RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef12has_any_babe
_RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef12has_any_babe
Line
Count
Source
440
42
    pub fn has_any_babe(&self) -> bool {
441
42
        self.logs().any(|l| l.is_babe())
442
42
    }
443
444
    /// Returns true if the list has any item that belong to the Grandpa finality engine.
445
    ///
446
    /// This function is `O(n)` over the number of log items.
447
0
    pub fn has_any_grandpa(&self) -> bool {
448
0
        self.logs().any(|l| l.is_grandpa())
Unexecuted instantiation: _RNCNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB7_9DigestRef15has_any_grandpa0B9_
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef15has_any_grandpa0B9_
449
0
    }
Unexecuted instantiation: _RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef15has_any_grandpa
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef15has_any_grandpa
450
451
    /// Returns the Aura seal digest item, if any.
452
42
    pub fn aura_seal(&self) -> Option<&'a [u8; 64]> {
453
42
        if let Some(
aura_seal_index0
) = self.aura_seal_index {
454
0
            if let DigestItemRef::AuraSeal(seal) = self.logs().nth(aura_seal_index).unwrap() {
455
0
                Some(seal)
456
            } else {
457
0
                unreachable!()
458
            }
459
        } else {
460
42
            None
461
        }
462
42
    }
Unexecuted instantiation: _RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef9aura_seal
_RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef9aura_seal
Line
Count
Source
452
42
    pub fn aura_seal(&self) -> Option<&'a [u8; 64]> {
453
42
        if let Some(
aura_seal_index0
) = self.aura_seal_index {
454
0
            if let DigestItemRef::AuraSeal(seal) = self.logs().nth(aura_seal_index).unwrap() {
455
0
                Some(seal)
456
            } else {
457
0
                unreachable!()
458
            }
459
        } else {
460
42
            None
461
        }
462
42
    }
463
464
    /// Returns the Aura pre-runtime digest item, if any.
465
42
    pub fn aura_pre_runtime(&self) -> Option<AuraPreDigest> {
466
42
        if let Some(
aura_predigest_index0
) = self.aura_predigest_index {
467
0
            if let DigestItemRef::AuraPreDigest(item) =
468
0
                self.logs().nth(aura_predigest_index).unwrap()
469
            {
470
0
                Some(item)
471
            } else {
472
0
                unreachable!()
473
            }
474
        } else {
475
42
            None
476
        }
477
42
    }
Unexecuted instantiation: _RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef16aura_pre_runtime
_RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef16aura_pre_runtime
Line
Count
Source
465
42
    pub fn aura_pre_runtime(&self) -> Option<AuraPreDigest> {
466
42
        if let Some(
aura_predigest_index0
) = self.aura_predigest_index {
467
0
            if let DigestItemRef::AuraPreDigest(item) =
468
0
                self.logs().nth(aura_predigest_index).unwrap()
469
            {
470
0
                Some(item)
471
            } else {
472
0
                unreachable!()
473
            }
474
        } else {
475
42
            None
476
        }
477
42
    }
478
479
    /// Returns the Babe seal digest item, if any.
480
4
    pub fn babe_seal(&self) -> Option<&'a [u8; 64]> {
481
4
        if let Some(babe_seal_index) = self.babe_seal_index {
482
4
            if let DigestItemRef::BabeSeal(seal) = self.logs().nth(babe_seal_index).unwrap() {
483
4
                Some(seal)
484
            } else {
485
0
                unreachable!()
486
            }
487
        } else {
488
0
            None
489
        }
490
4
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef9babe_seal
Line
Count
Source
480
4
    pub fn babe_seal(&self) -> Option<&'a [u8; 64]> {
481
4
        if let Some(babe_seal_index) = self.babe_seal_index {
482
4
            if let DigestItemRef::BabeSeal(seal) = self.logs().nth(babe_seal_index).unwrap() {
483
4
                Some(seal)
484
            } else {
485
0
                unreachable!()
486
            }
487
        } else {
488
0
            None
489
        }
490
4
    }
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef9babe_seal
491
492
    /// Returns the Babe pre-runtime digest item, if any.
493
6
    pub fn babe_pre_runtime(&self) -> Option<BabePreDigestRef<'a>> {
494
6
        if let Some(babe_predigest_index) = self.babe_predigest_index {
495
6
            if let DigestItemRef::BabePreDigest(item) =
496
6
                self.logs().nth(babe_predigest_index).unwrap()
497
            {
498
6
                Some(item)
499
            } else {
500
0
                unreachable!()
501
            }
502
        } else {
503
0
            None
504
        }
505
6
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef16babe_pre_runtime
Line
Count
Source
493
6
    pub fn babe_pre_runtime(&self) -> Option<BabePreDigestRef<'a>> {
494
6
        if let Some(babe_predigest_index) = self.babe_predigest_index {
495
6
            if let DigestItemRef::BabePreDigest(item) =
496
6
                self.logs().nth(babe_predigest_index).unwrap()
497
            {
498
6
                Some(item)
499
            } else {
500
0
                unreachable!()
501
            }
502
        } else {
503
0
            None
504
        }
505
6
    }
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef16babe_pre_runtime
506
507
    /// Returns the Babe epoch information stored in the header, if any.
508
    ///
509
    /// It is guaranteed that a configuration change is present only if an epoch change is
510
    /// present too.
511
8
    pub fn babe_epoch_information(&self) -> Option<(BabeNextEpochRef<'a>, Option<BabeNextConfig>)> {
512
8
        if let Some(
babe_next_epoch_data_index4
) = self.babe_next_epoch_data_index {
513
4
            if let DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(epoch)) =
514
4
                self.logs().nth(babe_next_epoch_data_index).unwrap()
515
            {
516
4
                if let Some(
babe_next_config_data_index0
) = self.babe_next_config_data_index {
517
                    if let DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(
518
0
                        config,
519
0
                    )) = self.logs().nth(babe_next_config_data_index).unwrap()
520
                    {
521
0
                        Some((epoch, Some(config)))
522
                    } else {
523
0
                        panic!()
524
                    }
525
                } else {
526
4
                    Some((epoch, None))
527
                }
528
            } else {
529
0
                unreachable!()
530
            }
531
        } else {
532
4
            debug_assert!(self.babe_next_config_data_index.is_none());
533
4
            None
534
        }
535
8
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef22babe_epoch_information
Line
Count
Source
511
8
    pub fn babe_epoch_information(&self) -> Option<(BabeNextEpochRef<'a>, Option<BabeNextConfig>)> {
512
8
        if let Some(
babe_next_epoch_data_index4
) = self.babe_next_epoch_data_index {
513
4
            if let DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(epoch)) =
514
4
                self.logs().nth(babe_next_epoch_data_index).unwrap()
515
            {
516
4
                if let Some(
babe_next_config_data_index0
) = self.babe_next_config_data_index {
517
                    if let DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(
518
0
                        config,
519
0
                    )) = self.logs().nth(babe_next_config_data_index).unwrap()
520
                    {
521
0
                        Some((epoch, Some(config)))
522
                    } else {
523
0
                        panic!()
524
                    }
525
                } else {
526
4
                    Some((epoch, None))
527
                }
528
            } else {
529
0
                unreachable!()
530
            }
531
        } else {
532
4
            debug_assert!(self.babe_next_config_data_index.is_none());
533
4
            None
534
        }
535
8
    }
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef22babe_epoch_information
536
537
    /// Returns `true` if there is a [`DigestItemRef::RuntimeEnvironmentUpdated`] item.
538
0
    pub fn has_runtime_environment_updated(&self) -> bool {
539
0
        self.has_runtime_environment_updated
540
0
    }
Unexecuted instantiation: _RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef31has_runtime_environment_updated
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef31has_runtime_environment_updated
541
542
    /// If the last element of the list is a seal, removes it from the [`DigestRef`].
543
4
    pub fn pop_seal(&mut self) -> Option<Seal<'a>> {
544
4
        let seal_pos = self.babe_seal_index.or(self.aura_seal_index)
?0
;
545
546
4
        match &mut self.inner {
547
0
            DigestRefInner::Parsed(list) => {
548
0
                debug_assert!(!list.is_empty());
549
0
                debug_assert_eq!(seal_pos, list.len() - 1);
550
551
0
                let item = &list[seal_pos];
552
0
                *list = &list[..seal_pos];
553
0
554
0
                match item {
555
0
                    DigestItem::AuraSeal(seal) => Some(Seal::Aura(seal)),
556
0
                    DigestItem::BabeSeal(seal) => Some(Seal::Babe(seal)),
557
0
                    _ => unreachable!(),
558
                }
559
            }
560
561
            DigestRefInner::Undecoded {
562
4
                digest,
563
4
                digest_logs_len,
564
4
                block_number_bytes,
565
4
            } => {
566
4
                debug_assert_eq!(seal_pos, *digest_logs_len - 1);
567
568
4
                let mut iter = LogsIter {
569
4
                    inner: LogsIterInner::Undecoded {
570
4
                        pointer: digest,
571
4
                        remaining_len: *digest_logs_len,
572
4
                        block_number_bytes: *block_number_bytes,
573
4
                    },
574
4
                };
575
4
                for _ in 0..seal_pos {
576
6
                    let _item = iter.next();
577
6
                    debug_assert!(_item.is_some());
578
                }
579
580
                if let LogsIterInner::Undecoded {
581
4
                    pointer,
582
4
                    remaining_len,
583
                    ..
584
4
                } = iter.inner
585
                {
586
4
                    *digest_logs_len -= 1;
587
4
                    *digest = &digest[..digest.len() - pointer.len()];
588
4
                    self.babe_seal_index = None;
589
4
                    debug_assert_eq!(remaining_len, 1);
590
                } else {
591
0
                    unreachable!()
592
                }
593
594
4
                match iter.next() {
595
0
                    Some(DigestItemRef::AuraSeal(seal)) => Some(Seal::Aura(seal)),
596
4
                    Some(DigestItemRef::BabeSeal(seal)) => Some(Seal::Babe(seal)),
597
0
                    _ => unreachable!(),
598
                }
599
            }
600
        }
601
4
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef8pop_seal
Line
Count
Source
543
4
    pub fn pop_seal(&mut self) -> Option<Seal<'a>> {
544
4
        let seal_pos = self.babe_seal_index.or(self.aura_seal_index)
?0
;
545
546
4
        match &mut self.inner {
547
0
            DigestRefInner::Parsed(list) => {
548
0
                debug_assert!(!list.is_empty());
549
0
                debug_assert_eq!(seal_pos, list.len() - 1);
550
551
0
                let item = &list[seal_pos];
552
0
                *list = &list[..seal_pos];
553
0
554
0
                match item {
555
0
                    DigestItem::AuraSeal(seal) => Some(Seal::Aura(seal)),
556
0
                    DigestItem::BabeSeal(seal) => Some(Seal::Babe(seal)),
557
0
                    _ => unreachable!(),
558
                }
559
            }
560
561
            DigestRefInner::Undecoded {
562
4
                digest,
563
4
                digest_logs_len,
564
4
                block_number_bytes,
565
4
            } => {
566
4
                debug_assert_eq!(seal_pos, *digest_logs_len - 1);
567
568
4
                let mut iter = LogsIter {
569
4
                    inner: LogsIterInner::Undecoded {
570
4
                        pointer: digest,
571
4
                        remaining_len: *digest_logs_len,
572
4
                        block_number_bytes: *block_number_bytes,
573
4
                    },
574
4
                };
575
4
                for _ in 0..seal_pos {
576
6
                    let _item = iter.next();
577
6
                    debug_assert!(_item.is_some());
578
                }
579
580
                if let LogsIterInner::Undecoded {
581
4
                    pointer,
582
4
                    remaining_len,
583
                    ..
584
4
                } = iter.inner
585
                {
586
4
                    *digest_logs_len -= 1;
587
4
                    *digest = &digest[..digest.len() - pointer.len()];
588
4
                    self.babe_seal_index = None;
589
4
                    debug_assert_eq!(remaining_len, 1);
590
                } else {
591
0
                    unreachable!()
592
                }
593
594
4
                match iter.next() {
595
0
                    Some(DigestItemRef::AuraSeal(seal)) => Some(Seal::Aura(seal)),
596
4
                    Some(DigestItemRef::BabeSeal(seal)) => Some(Seal::Babe(seal)),
597
0
                    _ => unreachable!(),
598
                }
599
            }
600
        }
601
4
    }
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef8pop_seal
602
603
    /// Returns an iterator to the log items in this digest.
604
2.49k
    pub fn logs(&self) -> LogsIter<'a> {
605
2.49k
        LogsIter {
606
2.49k
            inner: match self.inner {
607
2.40k
                DigestRefInner::Parsed(list) => LogsIterInner::Decoded(list.iter()),
608
                DigestRefInner::Undecoded {
609
91
                    digest,
610
91
                    digest_logs_len,
611
91
                    block_number_bytes,
612
91
                } => LogsIterInner::Undecoded {
613
91
                    pointer: digest,
614
91
                    remaining_len: digest_logs_len,
615
91
                    block_number_bytes,
616
91
                },
617
            },
618
        }
619
2.49k
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef4logs
Line
Count
Source
604
2.11k
    pub fn logs(&self) -> LogsIter<'a> {
605
2.11k
        LogsIter {
606
2.11k
            inner: match self.inner {
607
2.07k
                DigestRefInner::Parsed(list) => LogsIterInner::Decoded(list.iter()),
608
                DigestRefInner::Undecoded {
609
47
                    digest,
610
47
                    digest_logs_len,
611
47
                    block_number_bytes,
612
47
                } => LogsIterInner::Undecoded {
613
47
                    pointer: digest,
614
47
                    remaining_len: digest_logs_len,
615
47
                    block_number_bytes,
616
47
                },
617
            },
618
        }
619
2.11k
    }
_RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef4logs
Line
Count
Source
604
380
    pub fn logs(&self) -> LogsIter<'a> {
605
380
        LogsIter {
606
380
            inner: match self.inner {
607
336
                DigestRefInner::Parsed(list) => LogsIterInner::Decoded(list.iter()),
608
                DigestRefInner::Undecoded {
609
44
                    digest,
610
44
                    digest_logs_len,
611
44
                    block_number_bytes,
612
44
                } => LogsIterInner::Undecoded {
613
44
                    pointer: digest,
614
44
                    remaining_len: digest_logs_len,
615
44
                    block_number_bytes,
616
44
                },
617
            },
618
        }
619
380
    }
620
621
    /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE
622
    /// encoding of the digest items.
623
1.19k
    pub fn scale_encoding(
624
1.19k
        &self,
625
1.19k
        block_number_bytes: usize,
626
1.19k
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
627
1.19k
        let encoded_len = util::encode_scale_compact_usize(self.logs().len());
628
1.19k
        iter::once(either::Left(encoded_len)).chain(
629
1.19k
            self.logs()
630
1.19k
                .flat_map(move |v| 
v.scale_encoding(block_number_bytes).map(either::Right)41
),
_RNCNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB7_9DigestRef14scale_encoding0B9_
Line
Count
Source
630
41
                .flat_map(move |v| v.scale_encoding(block_number_bytes).map(either::Right)),
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef14scale_encoding0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef14scale_encoding0B9_
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef14scale_encoding0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef14scale_encoding0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef14scale_encoding0CsibGXYHQB8Ea_25json_rpc_general_requests
631
1.19k
        )
632
1.19k
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef14scale_encoding
Line
Count
Source
623
1.04k
    pub fn scale_encoding(
624
1.04k
        &self,
625
1.04k
        block_number_bytes: usize,
626
1.04k
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
627
1.04k
        let encoded_len = util::encode_scale_compact_usize(self.logs().len());
628
1.04k
        iter::once(either::Left(encoded_len)).chain(
629
1.04k
            self.logs()
630
1.04k
                .flat_map(move |v| v.scale_encoding(block_number_bytes).map(either::Right)),
631
1.04k
        )
632
1.04k
    }
_RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef14scale_encoding
Line
Count
Source
623
147
    pub fn scale_encoding(
624
147
        &self,
625
147
        block_number_bytes: usize,
626
147
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
627
147
        let encoded_len = util::encode_scale_compact_usize(self.logs().len());
628
147
        iter::once(either::Left(encoded_len)).chain(
629
147
            self.logs()
630
147
                .flat_map(move |v| v.scale_encoding(block_number_bytes).map(either::Right)),
631
147
        )
632
147
    }
633
634
    /// Same as [`DigestRef::scale_encoding`], but with an extra item added to the end of the list.
635
0
    pub fn scale_encoding_with_extra_item(
636
0
        &self,
637
0
        block_number_bytes: usize,
638
0
        extra_item: DigestItemRef<'a>,
639
0
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
640
0
        // Given that `self.logs().len()` counts a number of items present in memory, and that
641
0
        // these items have a non-zero size, it is not possible for this value to be equal to
642
0
        // `usize::MAX`, as that would mean that the entire memory is completely full
643
0
        // of digest log items. Therefore, doing `+ 1` is also guaranteed to never overflow.
644
0
        let new_len = self.logs().len() + 1;
645
0
646
0
        let encoded_len = util::encode_scale_compact_usize(new_len);
647
0
        iter::once(either::Left(encoded_len)).chain(
648
0
            self.logs()
649
0
                .chain(iter::once(extra_item))
650
0
                .flat_map(move |v| v.scale_encoding(block_number_bytes).map(either::Right)),
Unexecuted instantiation: _RNCNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB7_9DigestRef30scale_encoding_with_extra_item0B9_
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef30scale_encoding_with_extra_item0B9_
651
0
        )
652
0
    }
Unexecuted instantiation: _RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef30scale_encoding_with_extra_item
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef30scale_encoding_with_extra_item
653
654
    /// Turns an already-decoded list of items into a [`DigestRef`].
655
    ///
656
    /// Error can happen if the list of items is invalid, for example if it contains a seal at the
657
    /// non-last position.
658
1
    pub fn from_slice(slice: &'a [DigestItem]) -> Result<Self, Error> {
659
1
        let mut aura_seal_index = None;
660
1
        let mut aura_predigest_index = None;
661
1
        let mut babe_seal_index = None;
662
1
        let mut babe_predigest_index = None;
663
1
        let mut babe_next_epoch_data_index = None;
664
1
        let mut babe_next_config_data_index = None;
665
1
        let mut has_runtime_environment_updated = false;
666
667
        // Iterate through the log items to see if anything is wrong.
668
1
        for (item_num, item) in slice.iter().enumerate() {
669
0
            match item {
670
1
                DigestItem::AuraPreDigest(_) if aura_predigest_index.is_none() => {
671
1
                    aura_predigest_index = Some(item_num);
672
1
                }
673
0
                DigestItem::AuraPreDigest(_) => return Err(Error::MultipleAuraPreRuntimeDigests),
674
0
                DigestItem::AuraConsensus(_) => {}
675
0
                DigestItem::BabePreDigest(_) if babe_predigest_index.is_none() => {
676
0
                    babe_predigest_index = Some(item_num);
677
0
                }
678
0
                DigestItem::BabePreDigest(_) => return Err(Error::MultipleBabePreRuntimeDigests),
679
                DigestItem::BabeConsensus(BabeConsensusLog::NextEpochData(_))
680
0
                    if babe_next_epoch_data_index.is_none() =>
681
0
                {
682
0
                    babe_next_epoch_data_index = Some(item_num);
683
0
                }
684
                DigestItem::BabeConsensus(BabeConsensusLog::NextEpochData(_)) => {
685
0
                    return Err(Error::MultipleBabeEpochDescriptors);
686
                }
687
                DigestItem::BabeConsensus(BabeConsensusLog::NextConfigData(_))
688
0
                    if babe_next_config_data_index.is_none() =>
689
0
                {
690
0
                    babe_next_config_data_index = Some(item_num);
691
0
                }
692
                DigestItem::BabeConsensus(BabeConsensusLog::NextConfigData(_)) => {
693
0
                    return Err(Error::MultipleBabeConfigDescriptors);
694
                }
695
0
                DigestItem::BabeConsensus(BabeConsensusLog::OnDisabled(_)) => {}
696
0
                DigestItem::GrandpaConsensus(_) => {}
697
0
                DigestItem::AuraSeal(_) if item_num == slice.len() - 1 => {
698
0
                    debug_assert!(aura_seal_index.is_none());
699
0
                    debug_assert!(babe_seal_index.is_none());
700
0
                    aura_seal_index = Some(item_num);
701
                }
702
0
                DigestItem::AuraSeal(_) => return Err(Error::SealIsntLastItem),
703
0
                DigestItem::BabeSeal(_) if item_num == slice.len() - 1 => {
704
0
                    debug_assert!(aura_seal_index.is_none());
705
0
                    debug_assert!(babe_seal_index.is_none());
706
0
                    babe_seal_index = Some(item_num);
707
                }
708
0
                DigestItem::RuntimeEnvironmentUpdated if has_runtime_environment_updated => {
709
0
                    return Err(Error::MutipleRuntimeEnvironmentUpdated);
710
                }
711
0
                DigestItem::RuntimeEnvironmentUpdated => {
712
0
                    has_runtime_environment_updated = true;
713
0
                }
714
0
                DigestItem::BabeSeal(_) => return Err(Error::SealIsntLastItem),
715
0
                DigestItem::UnknownSeal { .. } if item_num == slice.len() - 1 => {
716
0
                    debug_assert!(aura_seal_index.is_none());
717
0
                    debug_assert!(babe_seal_index.is_none());
718
                }
719
0
                DigestItem::UnknownSeal { .. } => return Err(Error::SealIsntLastItem),
720
                DigestItem::UnknownConsensus { .. }
721
                | DigestItem::UnknownPreRuntime { .. }
722
0
                | DigestItem::Other(..) => {}
723
            }
724
        }
725
726
1
        if babe_next_config_data_index.is_some() && 
babe_next_epoch_data_index.is_none()0
{
727
0
            return Err(Error::UnexpectedBabeConfigDescriptor);
728
1
        }
729
1
730
1
        Ok(DigestRef {
731
1
            inner: DigestRefInner::Parsed(slice),
732
1
            aura_seal_index,
733
1
            aura_predigest_index,
734
1
            babe_seal_index,
735
1
            babe_predigest_index,
736
1
            babe_next_epoch_data_index,
737
1
            babe_next_config_data_index,
738
1
            has_runtime_environment_updated,
739
1
        })
740
1
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef10from_slice
Line
Count
Source
658
1
    pub fn from_slice(slice: &'a [DigestItem]) -> Result<Self, Error> {
659
1
        let mut aura_seal_index = None;
660
1
        let mut aura_predigest_index = None;
661
1
        let mut babe_seal_index = None;
662
1
        let mut babe_predigest_index = None;
663
1
        let mut babe_next_epoch_data_index = None;
664
1
        let mut babe_next_config_data_index = None;
665
1
        let mut has_runtime_environment_updated = false;
666
667
        // Iterate through the log items to see if anything is wrong.
668
1
        for (item_num, item) in slice.iter().enumerate() {
669
0
            match item {
670
1
                DigestItem::AuraPreDigest(_) if aura_predigest_index.is_none() => {
671
1
                    aura_predigest_index = Some(item_num);
672
1
                }
673
0
                DigestItem::AuraPreDigest(_) => return Err(Error::MultipleAuraPreRuntimeDigests),
674
0
                DigestItem::AuraConsensus(_) => {}
675
0
                DigestItem::BabePreDigest(_) if babe_predigest_index.is_none() => {
676
0
                    babe_predigest_index = Some(item_num);
677
0
                }
678
0
                DigestItem::BabePreDigest(_) => return Err(Error::MultipleBabePreRuntimeDigests),
679
                DigestItem::BabeConsensus(BabeConsensusLog::NextEpochData(_))
680
0
                    if babe_next_epoch_data_index.is_none() =>
681
0
                {
682
0
                    babe_next_epoch_data_index = Some(item_num);
683
0
                }
684
                DigestItem::BabeConsensus(BabeConsensusLog::NextEpochData(_)) => {
685
0
                    return Err(Error::MultipleBabeEpochDescriptors);
686
                }
687
                DigestItem::BabeConsensus(BabeConsensusLog::NextConfigData(_))
688
0
                    if babe_next_config_data_index.is_none() =>
689
0
                {
690
0
                    babe_next_config_data_index = Some(item_num);
691
0
                }
692
                DigestItem::BabeConsensus(BabeConsensusLog::NextConfigData(_)) => {
693
0
                    return Err(Error::MultipleBabeConfigDescriptors);
694
                }
695
0
                DigestItem::BabeConsensus(BabeConsensusLog::OnDisabled(_)) => {}
696
0
                DigestItem::GrandpaConsensus(_) => {}
697
0
                DigestItem::AuraSeal(_) if item_num == slice.len() - 1 => {
698
0
                    debug_assert!(aura_seal_index.is_none());
699
0
                    debug_assert!(babe_seal_index.is_none());
700
0
                    aura_seal_index = Some(item_num);
701
                }
702
0
                DigestItem::AuraSeal(_) => return Err(Error::SealIsntLastItem),
703
0
                DigestItem::BabeSeal(_) if item_num == slice.len() - 1 => {
704
0
                    debug_assert!(aura_seal_index.is_none());
705
0
                    debug_assert!(babe_seal_index.is_none());
706
0
                    babe_seal_index = Some(item_num);
707
                }
708
0
                DigestItem::RuntimeEnvironmentUpdated if has_runtime_environment_updated => {
709
0
                    return Err(Error::MutipleRuntimeEnvironmentUpdated);
710
                }
711
0
                DigestItem::RuntimeEnvironmentUpdated => {
712
0
                    has_runtime_environment_updated = true;
713
0
                }
714
0
                DigestItem::BabeSeal(_) => return Err(Error::SealIsntLastItem),
715
0
                DigestItem::UnknownSeal { .. } if item_num == slice.len() - 1 => {
716
0
                    debug_assert!(aura_seal_index.is_none());
717
0
                    debug_assert!(babe_seal_index.is_none());
718
                }
719
0
                DigestItem::UnknownSeal { .. } => return Err(Error::SealIsntLastItem),
720
                DigestItem::UnknownConsensus { .. }
721
                | DigestItem::UnknownPreRuntime { .. }
722
0
                | DigestItem::Other(..) => {}
723
            }
724
        }
725
726
1
        if babe_next_config_data_index.is_some() && 
babe_next_epoch_data_index.is_none()0
{
727
0
            return Err(Error::UnexpectedBabeConfigDescriptor);
728
1
        }
729
1
730
1
        Ok(DigestRef {
731
1
            inner: DigestRefInner::Parsed(slice),
732
1
            aura_seal_index,
733
1
            aura_predigest_index,
734
1
            babe_seal_index,
735
1
            babe_predigest_index,
736
1
            babe_next_epoch_data_index,
737
1
            babe_next_config_data_index,
738
1
            has_runtime_environment_updated,
739
1
        })
740
1
    }
Unexecuted instantiation: _RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef10from_slice
741
742
    /// Try to decode a list of digest items, from their SCALE encoding.
743
1.51k
    fn from_scale_bytes(
744
1.51k
        scale_encoded: &'a [u8],
745
1.51k
        block_number_bytes: usize,
746
1.51k
    ) -> Result<(Self, &'a [u8]), Error> {
747
1.51k
        let (scale_encoded, digest_logs_len) =
748
1.51k
            crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(scale_encoded)
749
1.51k
                .map_err(|_| 
Error::DigestItemLenDecodeError0
)
?0
;
Unexecuted instantiation: _RNCNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB7_9DigestRef16from_scale_bytes0B9_
Unexecuted instantiation: _RNCNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB7_9DigestRef16from_scale_bytes0B9_
750
751
1.51k
        let mut aura_seal_index = None;
752
1.51k
        let mut aura_predigest_index = None;
753
1.51k
        let mut babe_seal_index = None;
754
1.51k
        let mut babe_predigest_index = None;
755
1.51k
        let mut babe_next_epoch_data_index = None;
756
1.51k
        let mut babe_next_config_data_index = None;
757
1.51k
        let mut has_runtime_environment_updated = false;
758
1.51k
759
1.51k
        // Iterate through the log items to see if anything is wrong.
760
1.51k
        let mut next_digest = scale_encoded;
761
1.51k
        for 
item_num68
in 0..digest_logs_len {
762
68
            let (
item, next67
) = decode_item(next_digest, block_number_bytes)
?1
;
763
67
            next_digest = next;
764
765
25
            match item {
766
1
                DigestItemRef::AuraPreDigest(_) if aura_predigest_index.is_none() => {
767
1
                    aura_predigest_index = Some(item_num);
768
1
                }
769
                DigestItemRef::AuraPreDigest(_) => {
770
0
                    return Err(Error::MultipleAuraPreRuntimeDigests)
771
                }
772
0
                DigestItemRef::AuraConsensus(_) => {}
773
16
                DigestItemRef::BabePreDigest(_) if babe_predigest_index.is_none() => {
774
16
                    babe_predigest_index = Some(item_num);
775
16
                }
776
                DigestItemRef::BabePreDigest(_) => {
777
0
                    return Err(Error::MultipleBabePreRuntimeDigests)
778
                }
779
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_))
780
8
                    if babe_next_epoch_data_index.is_none() =>
781
8
                {
782
8
                    babe_next_epoch_data_index = Some(item_num);
783
8
                }
784
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) => {
785
0
                    return Err(Error::MultipleBabeEpochDescriptors);
786
                }
787
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_))
788
1
                    if babe_next_config_data_index.is_none() =>
789
1
                {
790
1
                    babe_next_config_data_index = Some(item_num);
791
1
                }
792
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) => {
793
0
                    return Err(Error::MultipleBabeConfigDescriptors);
794
                }
795
11
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::OnDisabled(_)) => {}
796
13
                DigestItemRef::GrandpaConsensus(_) => {}
797
0
                DigestItemRef::AuraSeal(_) if item_num == digest_logs_len - 1 => {
798
0
                    debug_assert!(aura_seal_index.is_none());
799
0
                    debug_assert!(babe_seal_index.is_none());
800
0
                    aura_seal_index = Some(item_num);
801
                }
802
0
                DigestItemRef::AuraSeal(_) => return Err(Error::SealIsntLastItem),
803
16
                DigestItemRef::BabeSeal(_) if item_num == digest_logs_len - 1 => {
804
16
                    debug_assert!(aura_seal_index.is_none());
805
16
                    debug_assert!(babe_seal_index.is_none());
806
16
                    babe_seal_index = Some(item_num);
807
                }
808
0
                DigestItemRef::RuntimeEnvironmentUpdated if has_runtime_environment_updated => {
809
0
                    return Err(Error::MutipleRuntimeEnvironmentUpdated);
810
                }
811
0
                DigestItemRef::RuntimeEnvironmentUpdated => {
812
0
                    has_runtime_environment_updated = true;
813
0
                }
814
0
                DigestItemRef::BabeSeal(_) => return Err(Error::SealIsntLastItem),
815
0
                DigestItemRef::UnknownSeal { .. } if item_num == digest_logs_len - 1 => {
816
0
                    debug_assert!(aura_seal_index.is_none());
817
0
                    debug_assert!(babe_seal_index.is_none());
818
                }
819
0
                DigestItemRef::UnknownSeal { .. } => return Err(Error::SealIsntLastItem),
820
                DigestItemRef::UnknownConsensus { .. }
821
                | DigestItemRef::UnknownPreRuntime { .. }
822
1
                | DigestItemRef::Other { .. } => {}
823
            }
824
        }
825
826
1.51k
        if babe_next_config_data_index.is_some() && 
babe_next_epoch_data_index.is_none()1
{
827
0
            return Err(Error::UnexpectedBabeConfigDescriptor);
828
1.51k
        }
829
1.51k
830
1.51k
        let out = DigestRef {
831
1.51k
            inner: DigestRefInner::Undecoded {
832
1.51k
                digest_logs_len,
833
1.51k
                digest: scale_encoded,
834
1.51k
                block_number_bytes,
835
1.51k
            },
836
1.51k
            aura_seal_index,
837
1.51k
            aura_predigest_index,
838
1.51k
            babe_seal_index,
839
1.51k
            babe_predigest_index,
840
1.51k
            babe_next_epoch_data_index,
841
1.51k
            babe_next_config_data_index,
842
1.51k
            has_runtime_environment_updated,
843
1.51k
        };
844
1.51k
845
1.51k
        Ok((out, next_digest))
846
1.51k
    }
_RNvMs2_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRef16from_scale_bytes
Line
Count
Source
743
1.05k
    fn from_scale_bytes(
744
1.05k
        scale_encoded: &'a [u8],
745
1.05k
        block_number_bytes: usize,
746
1.05k
    ) -> Result<(Self, &'a [u8]), Error> {
747
1.05k
        let (scale_encoded, digest_logs_len) =
748
1.05k
            crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(scale_encoded)
749
1.05k
                .map_err(|_| Error::DigestItemLenDecodeError)
?0
;
750
751
1.05k
        let mut aura_seal_index = None;
752
1.05k
        let mut aura_predigest_index = None;
753
1.05k
        let mut babe_seal_index = None;
754
1.05k
        let mut babe_predigest_index = None;
755
1.05k
        let mut babe_next_epoch_data_index = None;
756
1.05k
        let mut babe_next_config_data_index = None;
757
1.05k
        let mut has_runtime_environment_updated = false;
758
1.05k
759
1.05k
        // Iterate through the log items to see if anything is wrong.
760
1.05k
        let mut next_digest = scale_encoded;
761
1.05k
        for 
item_num68
in 0..digest_logs_len {
762
68
            let (
item, next67
) = decode_item(next_digest, block_number_bytes)
?1
;
763
67
            next_digest = next;
764
765
25
            match item {
766
1
                DigestItemRef::AuraPreDigest(_) if aura_predigest_index.is_none() => {
767
1
                    aura_predigest_index = Some(item_num);
768
1
                }
769
                DigestItemRef::AuraPreDigest(_) => {
770
0
                    return Err(Error::MultipleAuraPreRuntimeDigests)
771
                }
772
0
                DigestItemRef::AuraConsensus(_) => {}
773
16
                DigestItemRef::BabePreDigest(_) if babe_predigest_index.is_none() => {
774
16
                    babe_predigest_index = Some(item_num);
775
16
                }
776
                DigestItemRef::BabePreDigest(_) => {
777
0
                    return Err(Error::MultipleBabePreRuntimeDigests)
778
                }
779
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_))
780
8
                    if babe_next_epoch_data_index.is_none() =>
781
8
                {
782
8
                    babe_next_epoch_data_index = Some(item_num);
783
8
                }
784
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) => {
785
0
                    return Err(Error::MultipleBabeEpochDescriptors);
786
                }
787
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_))
788
1
                    if babe_next_config_data_index.is_none() =>
789
1
                {
790
1
                    babe_next_config_data_index = Some(item_num);
791
1
                }
792
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) => {
793
0
                    return Err(Error::MultipleBabeConfigDescriptors);
794
                }
795
11
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::OnDisabled(_)) => {}
796
13
                DigestItemRef::GrandpaConsensus(_) => {}
797
0
                DigestItemRef::AuraSeal(_) if item_num == digest_logs_len - 1 => {
798
0
                    debug_assert!(aura_seal_index.is_none());
799
0
                    debug_assert!(babe_seal_index.is_none());
800
0
                    aura_seal_index = Some(item_num);
801
                }
802
0
                DigestItemRef::AuraSeal(_) => return Err(Error::SealIsntLastItem),
803
16
                DigestItemRef::BabeSeal(_) if item_num == digest_logs_len - 1 => {
804
16
                    debug_assert!(aura_seal_index.is_none());
805
16
                    debug_assert!(babe_seal_index.is_none());
806
16
                    babe_seal_index = Some(item_num);
807
                }
808
0
                DigestItemRef::RuntimeEnvironmentUpdated if has_runtime_environment_updated => {
809
0
                    return Err(Error::MutipleRuntimeEnvironmentUpdated);
810
                }
811
0
                DigestItemRef::RuntimeEnvironmentUpdated => {
812
0
                    has_runtime_environment_updated = true;
813
0
                }
814
0
                DigestItemRef::BabeSeal(_) => return Err(Error::SealIsntLastItem),
815
0
                DigestItemRef::UnknownSeal { .. } if item_num == digest_logs_len - 1 => {
816
0
                    debug_assert!(aura_seal_index.is_none());
817
0
                    debug_assert!(babe_seal_index.is_none());
818
                }
819
0
                DigestItemRef::UnknownSeal { .. } => return Err(Error::SealIsntLastItem),
820
                DigestItemRef::UnknownConsensus { .. }
821
                | DigestItemRef::UnknownPreRuntime { .. }
822
1
                | DigestItemRef::Other { .. } => {}
823
            }
824
        }
825
826
1.04k
        if babe_next_config_data_index.is_some() && 
babe_next_epoch_data_index.is_none()1
{
827
0
            return Err(Error::UnexpectedBabeConfigDescriptor);
828
1.04k
        }
829
1.04k
830
1.04k
        let out = DigestRef {
831
1.04k
            inner: DigestRefInner::Undecoded {
832
1.04k
                digest_logs_len,
833
1.04k
                digest: scale_encoded,
834
1.04k
                block_number_bytes,
835
1.04k
            },
836
1.04k
            aura_seal_index,
837
1.04k
            aura_predigest_index,
838
1.04k
            babe_seal_index,
839
1.04k
            babe_predigest_index,
840
1.04k
            babe_next_epoch_data_index,
841
1.04k
            babe_next_config_data_index,
842
1.04k
            has_runtime_environment_updated,
843
1.04k
        };
844
1.04k
845
1.04k
        Ok((out, next_digest))
846
1.05k
    }
_RNvMs2_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRef16from_scale_bytes
Line
Count
Source
743
464
    fn from_scale_bytes(
744
464
        scale_encoded: &'a [u8],
745
464
        block_number_bytes: usize,
746
464
    ) -> Result<(Self, &'a [u8]), Error> {
747
464
        let (scale_encoded, digest_logs_len) =
748
464
            crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(scale_encoded)
749
464
                .map_err(|_| Error::DigestItemLenDecodeError)
?0
;
750
751
464
        let mut aura_seal_index = None;
752
464
        let mut aura_predigest_index = None;
753
464
        let mut babe_seal_index = None;
754
464
        let mut babe_predigest_index = None;
755
464
        let mut babe_next_epoch_data_index = None;
756
464
        let mut babe_next_config_data_index = None;
757
464
        let mut has_runtime_environment_updated = false;
758
464
759
464
        // Iterate through the log items to see if anything is wrong.
760
464
        let mut next_digest = scale_encoded;
761
464
        for 
item_num0
in 0..digest_logs_len {
762
0
            let (item, next) = decode_item(next_digest, block_number_bytes)?;
763
0
            next_digest = next;
764
765
0
            match item {
766
0
                DigestItemRef::AuraPreDigest(_) if aura_predigest_index.is_none() => {
767
0
                    aura_predigest_index = Some(item_num);
768
0
                }
769
                DigestItemRef::AuraPreDigest(_) => {
770
0
                    return Err(Error::MultipleAuraPreRuntimeDigests)
771
                }
772
0
                DigestItemRef::AuraConsensus(_) => {}
773
0
                DigestItemRef::BabePreDigest(_) if babe_predigest_index.is_none() => {
774
0
                    babe_predigest_index = Some(item_num);
775
0
                }
776
                DigestItemRef::BabePreDigest(_) => {
777
0
                    return Err(Error::MultipleBabePreRuntimeDigests)
778
                }
779
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_))
780
0
                    if babe_next_epoch_data_index.is_none() =>
781
0
                {
782
0
                    babe_next_epoch_data_index = Some(item_num);
783
0
                }
784
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) => {
785
0
                    return Err(Error::MultipleBabeEpochDescriptors);
786
                }
787
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_))
788
0
                    if babe_next_config_data_index.is_none() =>
789
0
                {
790
0
                    babe_next_config_data_index = Some(item_num);
791
0
                }
792
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) => {
793
0
                    return Err(Error::MultipleBabeConfigDescriptors);
794
                }
795
0
                DigestItemRef::BabeConsensus(BabeConsensusLogRef::OnDisabled(_)) => {}
796
0
                DigestItemRef::GrandpaConsensus(_) => {}
797
0
                DigestItemRef::AuraSeal(_) if item_num == digest_logs_len - 1 => {
798
0
                    debug_assert!(aura_seal_index.is_none());
799
0
                    debug_assert!(babe_seal_index.is_none());
800
0
                    aura_seal_index = Some(item_num);
801
                }
802
0
                DigestItemRef::AuraSeal(_) => return Err(Error::SealIsntLastItem),
803
0
                DigestItemRef::BabeSeal(_) if item_num == digest_logs_len - 1 => {
804
0
                    debug_assert!(aura_seal_index.is_none());
805
0
                    debug_assert!(babe_seal_index.is_none());
806
0
                    babe_seal_index = Some(item_num);
807
                }
808
0
                DigestItemRef::RuntimeEnvironmentUpdated if has_runtime_environment_updated => {
809
0
                    return Err(Error::MutipleRuntimeEnvironmentUpdated);
810
                }
811
0
                DigestItemRef::RuntimeEnvironmentUpdated => {
812
0
                    has_runtime_environment_updated = true;
813
0
                }
814
0
                DigestItemRef::BabeSeal(_) => return Err(Error::SealIsntLastItem),
815
0
                DigestItemRef::UnknownSeal { .. } if item_num == digest_logs_len - 1 => {
816
0
                    debug_assert!(aura_seal_index.is_none());
817
0
                    debug_assert!(babe_seal_index.is_none());
818
                }
819
0
                DigestItemRef::UnknownSeal { .. } => return Err(Error::SealIsntLastItem),
820
                DigestItemRef::UnknownConsensus { .. }
821
                | DigestItemRef::UnknownPreRuntime { .. }
822
0
                | DigestItemRef::Other { .. } => {}
823
            }
824
        }
825
826
464
        if babe_next_config_data_index.is_some() && 
babe_next_epoch_data_index.is_none()0
{
827
0
            return Err(Error::UnexpectedBabeConfigDescriptor);
828
464
        }
829
464
830
464
        let out = DigestRef {
831
464
            inner: DigestRefInner::Undecoded {
832
464
                digest_logs_len,
833
464
                digest: scale_encoded,
834
464
                block_number_bytes,
835
464
            },
836
464
            aura_seal_index,
837
464
            aura_predigest_index,
838
464
            babe_seal_index,
839
464
            babe_predigest_index,
840
464
            babe_next_epoch_data_index,
841
464
            babe_next_config_data_index,
842
464
            has_runtime_environment_updated,
843
464
        };
844
464
845
464
        Ok((out, next_digest))
846
464
    }
847
}
848
849
impl<'a> fmt::Debug for DigestRef<'a> {
850
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
851
0
        f.debug_list().entries(self.logs()).finish()
852
0
    }
Unexecuted instantiation: _RNvXs3_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRefNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs3_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRefNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
853
}
854
855
impl<'a> From<&'a Digest> for DigestRef<'a> {
856
365
    fn from(digest: &'a Digest) -> DigestRef<'a> {
857
365
        DigestRef {
858
365
            inner: DigestRefInner::Parsed(&digest.list),
859
365
            aura_seal_index: digest.aura_seal_index,
860
365
            aura_predigest_index: digest.aura_predigest_index,
861
365
            babe_seal_index: digest.babe_seal_index,
862
365
            babe_predigest_index: digest.babe_predigest_index,
863
365
            babe_next_epoch_data_index: digest.babe_next_epoch_data_index,
864
365
            babe_next_config_data_index: digest.babe_next_config_data_index,
865
365
            has_runtime_environment_updated: digest.has_runtime_environment_updated,
866
365
        }
867
365
    }
_RNvXs4_NtCsN16ciHI6Qf_7smoldot6headerNtB5_9DigestRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_6DigestE4from
Line
Count
Source
856
8
    fn from(digest: &'a Digest) -> DigestRef<'a> {
857
8
        DigestRef {
858
8
            inner: DigestRefInner::Parsed(&digest.list),
859
8
            aura_seal_index: digest.aura_seal_index,
860
8
            aura_predigest_index: digest.aura_predigest_index,
861
8
            babe_seal_index: digest.babe_seal_index,
862
8
            babe_predigest_index: digest.babe_predigest_index,
863
8
            babe_next_epoch_data_index: digest.babe_next_epoch_data_index,
864
8
            babe_next_config_data_index: digest.babe_next_config_data_index,
865
8
            has_runtime_environment_updated: digest.has_runtime_environment_updated,
866
8
        }
867
8
    }
_RNvXs4_NtCseuYC0Zibziv_7smoldot6headerNtB5_9DigestRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_6DigestE4from
Line
Count
Source
856
357
    fn from(digest: &'a Digest) -> DigestRef<'a> {
857
357
        DigestRef {
858
357
            inner: DigestRefInner::Parsed(&digest.list),
859
357
            aura_seal_index: digest.aura_seal_index,
860
357
            aura_predigest_index: digest.aura_predigest_index,
861
357
            babe_seal_index: digest.babe_seal_index,
862
357
            babe_predigest_index: digest.babe_predigest_index,
863
357
            babe_next_epoch_data_index: digest.babe_next_epoch_data_index,
864
357
            babe_next_config_data_index: digest.babe_next_config_data_index,
865
357
            has_runtime_environment_updated: digest.has_runtime_environment_updated,
866
357
        }
867
357
    }
868
}
869
870
/// Seal popped using [`DigestRef::pop_seal`].
871
pub enum Seal<'a> {
872
    Aura(&'a [u8; 64]),
873
    Babe(&'a [u8; 64]),
874
}
875
876
/// Generic header digest.
877
#[derive(Clone)]
878
pub struct Digest {
879
    /// Actual list of items.
880
    list: Vec<DigestItem>,
881
    /// Index of the [`DigestItemRef::AuraSeal`] item, if any.
882
    aura_seal_index: Option<usize>,
883
    /// Index of the [`DigestItemRef::AuraPreDigest`] item, if any.
884
    aura_predigest_index: Option<usize>,
885
    /// Index of the [`DigestItemRef::BabeSeal`] item, if any.
886
    babe_seal_index: Option<usize>,
887
    /// Index of the [`DigestItemRef::BabePreDigest`] item, if any.
888
    babe_predigest_index: Option<usize>,
889
    /// Index of the [`DigestItemRef::BabeConsensus`] item containing a
890
    /// [`BabeConsensusLogRef::NextEpochData`], if any.
891
    babe_next_epoch_data_index: Option<usize>,
892
    /// Index of the [`DigestItemRef::BabeConsensus`] item containing a
893
    /// [`BabeConsensusLogRef::NextConfigData`], if any.
894
    babe_next_config_data_index: Option<usize>,
895
    /// `true` if there is a [`DigestItemRef::RuntimeEnvironmentUpdated`] item.
896
    has_runtime_environment_updated: bool,
897
}
898
899
impl Digest {
900
    /// Returns an iterator to the log items in this digest.
901
0
    pub fn logs(&self) -> LogsIter {
902
0
        DigestRef::from(self).logs()
903
0
    }
Unexecuted instantiation: _RNvMs5_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Digest4logs
Unexecuted instantiation: _RNvMs5_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Digest4logs
904
905
    /// Returns the Aura seal digest item, if any.
906
0
    pub fn aura_seal(&self) -> Option<&[u8; 64]> {
907
0
        DigestRef::from(self).aura_seal()
908
0
    }
Unexecuted instantiation: _RNvMs5_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Digest9aura_seal
Unexecuted instantiation: _RNvMs5_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Digest9aura_seal
909
910
    /// Returns the Babe seal digest item, if any.
911
0
    pub fn babe_seal(&self) -> Option<&[u8; 64]> {
912
0
        DigestRef::from(self).babe_seal()
913
0
    }
Unexecuted instantiation: _RNvMs5_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Digest9babe_seal
Unexecuted instantiation: _RNvMs5_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Digest9babe_seal
914
915
    /// Returns the Babe pre-runtime digest item, if any.
916
0
    pub fn babe_pre_runtime(&self) -> Option<BabePreDigestRef> {
917
0
        DigestRef::from(self).babe_pre_runtime()
918
0
    }
Unexecuted instantiation: _RNvMs5_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Digest16babe_pre_runtime
Unexecuted instantiation: _RNvMs5_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Digest16babe_pre_runtime
919
920
    /// Returns the Babe epoch information stored in the header, if any.
921
    ///
922
    /// It is guaranteed that a configuration change is present only if an epoch change is
923
    /// present too.
924
0
    pub fn babe_epoch_information(&self) -> Option<(BabeNextEpochRef, Option<BabeNextConfig>)> {
925
0
        DigestRef::from(self).babe_epoch_information()
926
0
    }
Unexecuted instantiation: _RNvMs5_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Digest22babe_epoch_information
Unexecuted instantiation: _RNvMs5_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Digest22babe_epoch_information
927
928
    /// Returns `true` if there is a [`DigestItemRef::RuntimeEnvironmentUpdated`] item.
929
0
    pub fn has_runtime_environment_updated(&self) -> bool {
930
0
        self.has_runtime_environment_updated
931
0
    }
Unexecuted instantiation: _RNvMs5_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6Digest31has_runtime_environment_updated
Unexecuted instantiation: _RNvMs5_NtCseuYC0Zibziv_7smoldot6headerNtB5_6Digest31has_runtime_environment_updated
932
}
933
934
impl fmt::Debug for Digest {
935
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
936
0
        f.debug_list()
937
0
            .entries(self.list.iter().map(DigestItemRef::from))
938
0
            .finish()
939
0
    }
Unexecuted instantiation: _RNvXs6_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6DigestNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
Unexecuted instantiation: _RNvXs6_NtCseuYC0Zibziv_7smoldot6headerNtB5_6DigestNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt
940
}
941
942
impl<'a> From<DigestRef<'a>> for Digest {
943
47
    fn from(digest: DigestRef<'a>) -> Digest {
944
47
        Digest {
945
47
            list: digest.logs().map(Into::into).collect(),
946
47
            aura_seal_index: digest.aura_seal_index,
947
47
            aura_predigest_index: digest.aura_predigest_index,
948
47
            babe_seal_index: digest.babe_seal_index,
949
47
            babe_predigest_index: digest.babe_predigest_index,
950
47
            babe_next_epoch_data_index: digest.babe_next_epoch_data_index,
951
47
            babe_next_config_data_index: digest.babe_next_config_data_index,
952
47
            has_runtime_environment_updated: digest.has_runtime_environment_updated,
953
47
        }
954
47
    }
_RNvXs7_NtCsN16ciHI6Qf_7smoldot6headerNtB5_6DigestINtNtCsaYZPK01V26L_4core7convert4FromNtB5_9DigestRefE4from
Line
Count
Source
943
5
    fn from(digest: DigestRef<'a>) -> Digest {
944
5
        Digest {
945
5
            list: digest.logs().map(Into::into).collect(),
946
5
            aura_seal_index: digest.aura_seal_index,
947
5
            aura_predigest_index: digest.aura_predigest_index,
948
5
            babe_seal_index: digest.babe_seal_index,
949
5
            babe_predigest_index: digest.babe_predigest_index,
950
5
            babe_next_epoch_data_index: digest.babe_next_epoch_data_index,
951
5
            babe_next_config_data_index: digest.babe_next_config_data_index,
952
5
            has_runtime_environment_updated: digest.has_runtime_environment_updated,
953
5
        }
954
5
    }
_RNvXs7_NtCseuYC0Zibziv_7smoldot6headerNtB5_6DigestINtNtCsaYZPK01V26L_4core7convert4FromNtB5_9DigestRefE4from
Line
Count
Source
943
42
    fn from(digest: DigestRef<'a>) -> Digest {
944
42
        Digest {
945
42
            list: digest.logs().map(Into::into).collect(),
946
42
            aura_seal_index: digest.aura_seal_index,
947
42
            aura_predigest_index: digest.aura_predigest_index,
948
42
            babe_seal_index: digest.babe_seal_index,
949
42
            babe_predigest_index: digest.babe_predigest_index,
950
42
            babe_next_epoch_data_index: digest.babe_next_epoch_data_index,
951
42
            babe_next_config_data_index: digest.babe_next_config_data_index,
952
42
            has_runtime_environment_updated: digest.has_runtime_environment_updated,
953
42
        }
954
42
    }
955
}
956
957
/// Iterator towards the digest log items.
958
#[derive(Clone)]
959
pub struct LogsIter<'a> {
960
    inner: LogsIterInner<'a>,
961
}
962
963
#[derive(Clone)]
964
enum LogsIterInner<'a> {
965
    Decoded(slice::Iter<'a, DigestItem>),
966
    Undecoded {
967
        /// Encoded digest.
968
        pointer: &'a [u8],
969
        /// Number of log items remaining.
970
        remaining_len: usize,
971
        /// Number of bytes used to encode block numbers in the header.
972
        block_number_bytes: usize,
973
    },
974
}
975
976
impl<'a> Iterator for LogsIter<'a> {
977
    type Item = DigestItemRef<'a>;
978
979
1.40k
    fn next(&mut self) -> Option<Self::Item> {
980
1.40k
        match &mut self.inner {
981
1.22k
            LogsIterInner::Decoded(iter) => iter.next().map(Into::into),
982
            LogsIterInner::Undecoded {
983
175
                pointer,
984
175
                remaining_len,
985
175
                block_number_bytes,
986
175
            } => {
987
175
                if *remaining_len == 0 {
988
68
                    return None;
989
107
                }
990
107
991
107
                // Validity is guaranteed when the `DigestRef` is constructed.
992
107
                let (item, new_pointer) = decode_item(pointer, *block_number_bytes).unwrap();
993
107
                *pointer = new_pointer;
994
107
                *remaining_len -= 1;
995
107
996
107
                Some(item)
997
            }
998
        }
999
1.40k
    }
_RNvXs8_NtCsN16ciHI6Qf_7smoldot6headerNtB5_8LogsIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next
Line
Count
Source
979
1.17k
    fn next(&mut self) -> Option<Self::Item> {
980
1.17k
        match &mut self.inner {
981
1.04k
            LogsIterInner::Decoded(iter) => iter.next().map(Into::into),
982
            LogsIterInner::Undecoded {
983
131
                pointer,
984
131
                remaining_len,
985
131
                block_number_bytes,
986
131
            } => {
987
131
                if *remaining_len == 0 {
988
24
                    return None;
989
107
                }
990
107
991
107
                // Validity is guaranteed when the `DigestRef` is constructed.
992
107
                let (item, new_pointer) = decode_item(pointer, *block_number_bytes).unwrap();
993
107
                *pointer = new_pointer;
994
107
                *remaining_len -= 1;
995
107
996
107
                Some(item)
997
            }
998
        }
999
1.17k
    }
_RNvXs8_NtCseuYC0Zibziv_7smoldot6headerNtB5_8LogsIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next
Line
Count
Source
979
233
    fn next(&mut self) -> Option<Self::Item> {
980
233
        match &mut self.inner {
981
189
            LogsIterInner::Decoded(iter) => iter.next().map(Into::into),
982
            LogsIterInner::Undecoded {
983
44
                pointer,
984
44
                remaining_len,
985
44
                block_number_bytes,
986
44
            } => {
987
44
                if *remaining_len == 0 {
988
44
                    return None;
989
0
                }
990
0
991
0
                // Validity is guaranteed when the `DigestRef` is constructed.
992
0
                let (item, new_pointer) = decode_item(pointer, *block_number_bytes).unwrap();
993
0
                *pointer = new_pointer;
994
0
                *remaining_len -= 1;
995
0
996
0
                Some(item)
997
            }
998
        }
999
233
    }
1000
1001
1.19k
    fn size_hint(&self) -> (usize, Option<usize>) {
1002
1.19k
        match &self.inner {
1003
1.18k
            LogsIterInner::Decoded(iter) => iter.size_hint(),
1004
11
            LogsIterInner::Undecoded { remaining_len, .. } => {
1005
11
                (*remaining_len, Some(*remaining_len))
1006
            }
1007
        }
1008
1.19k
    }
_RNvXs8_NtCsN16ciHI6Qf_7smoldot6headerNtB5_8LogsIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint
Line
Count
Source
1001
1.04k
    fn size_hint(&self) -> (usize, Option<usize>) {
1002
1.04k
        match &self.inner {
1003
1.03k
            LogsIterInner::Decoded(iter) => iter.size_hint(),
1004
11
            LogsIterInner::Undecoded { remaining_len, .. } => {
1005
11
                (*remaining_len, Some(*remaining_len))
1006
            }
1007
        }
1008
1.04k
    }
_RNvXs8_NtCseuYC0Zibziv_7smoldot6headerNtB5_8LogsIterNtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint
Line
Count
Source
1001
147
    fn size_hint(&self) -> (usize, Option<usize>) {
1002
147
        match &self.inner {
1003
147
            LogsIterInner::Decoded(iter) => iter.size_hint(),
1004
0
            LogsIterInner::Undecoded { remaining_len, .. } => {
1005
0
                (*remaining_len, Some(*remaining_len))
1006
            }
1007
        }
1008
147
    }
1009
}
1010
1011
impl<'a> ExactSizeIterator for LogsIter<'a> {}
1012
1013
// TODO: document
1014
#[derive(Debug, PartialEq, Eq, Clone)]
1015
pub enum DigestItemRef<'a> {
1016
    AuraPreDigest(AuraPreDigest),
1017
    /// Block signature made using the AURA consensus engine.
1018
    AuraSeal(&'a [u8; 64]),
1019
    AuraConsensus(AuraConsensusLogRef<'a>),
1020
1021
    BabePreDigest(BabePreDigestRef<'a>),
1022
    BabeConsensus(BabeConsensusLogRef<'a>),
1023
    /// Block signature made using the BABE consensus engine.
1024
    BabeSeal(&'a [u8; 64]),
1025
1026
    GrandpaConsensus(GrandpaConsensusLogRef<'a>),
1027
1028
    /// Consensus item with an engine that hasn't been recognized.
1029
    UnknownConsensus {
1030
        /// Name of the consensus engine.
1031
        engine: [u8; 4],
1032
        /// Smoldot doesn't interpret the content of the log item.
1033
        opaque: &'a [u8],
1034
    },
1035
    /// Pre-runtime item with a consensus engine that hasn't been recognized.
1036
    UnknownPreRuntime {
1037
        /// Name of the consensus engine.
1038
        engine: [u8; 4],
1039
        /// Smoldot doesn't interpret the content of the log item.
1040
        opaque: &'a [u8],
1041
    },
1042
    /// Seal using a consensus engine that hasn't been recognized.
1043
    UnknownSeal {
1044
        /// Name of the consensus engine.
1045
        engine: [u8; 4],
1046
        /// Smoldot doesn't interpret the content of the log item.
1047
        opaque: &'a [u8],
1048
    },
1049
1050
    /// Some other thing. Always ignored.
1051
    ///
1052
    /// Contrary to [`DigestItemRef::UnknownConsensus`], [`DigestItemRef::UnknownPreRuntime`], or
1053
    /// [`DigestItemRef::UnknownSeal`], this item is intentionally meant to always be ignored.
1054
    Other(&'a [u8]),
1055
1056
    /// Runtime of the chain has been updated in this block. This can include the runtime code or
1057
    /// the heap pages.
1058
    RuntimeEnvironmentUpdated,
1059
}
1060
1061
impl<'a> DigestItemRef<'a> {
1062
    /// True if the item is relevant to the Aura consensus engine.
1063
10
    pub fn is_aura(&self) -> bool {
1064
10
        matches!(
1065
10
            self,
1066
            DigestItemRef::AuraPreDigest(_)
1067
                | DigestItemRef::AuraSeal(_)
1068
                | DigestItemRef::AuraConsensus(_)
1069
        )
1070
10
    }
_RNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB5_13DigestItemRef7is_aura
Line
Count
Source
1063
10
    pub fn is_aura(&self) -> bool {
1064
10
        matches!(
1065
10
            self,
1066
            DigestItemRef::AuraPreDigest(_)
1067
                | DigestItemRef::AuraSeal(_)
1068
                | DigestItemRef::AuraConsensus(_)
1069
        )
1070
10
    }
Unexecuted instantiation: _RNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB5_13DigestItemRef7is_aura
1071
1072
    /// True if the item is relevant to the Babe consensus engine.
1073
0
    pub fn is_babe(&self) -> bool {
1074
0
        matches!(
1075
0
            self,
1076
            DigestItemRef::BabePreDigest(_)
1077
                | DigestItemRef::BabeConsensus(_)
1078
                | DigestItemRef::BabeSeal(_)
1079
        )
1080
0
    }
Unexecuted instantiation: _RNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB5_13DigestItemRef7is_babe
Unexecuted instantiation: _RNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB5_13DigestItemRef7is_babe
1081
1082
    /// True if the item is relevant to the Grandpa finality engine.
1083
0
    pub fn is_grandpa(&self) -> bool {
1084
0
        matches!(self, DigestItemRef::GrandpaConsensus(_))
1085
0
    }
Unexecuted instantiation: _RNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB5_13DigestItemRef10is_grandpa
Unexecuted instantiation: _RNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB5_13DigestItemRef10is_grandpa
1086
1087
    /// Decodes a SCALE-encoded digest item.
1088
0
    pub fn from_scale_encoded(bytes: &'a [u8], block_number_bytes: usize) -> Result<Self, Error> {
1089
0
        let (item, remain) = decode_item(bytes, block_number_bytes)?;
1090
0
        if !remain.is_empty() {
1091
0
            return Err(Error::TooLong);
1092
0
        }
1093
0
        Ok(item)
1094
0
    }
Unexecuted instantiation: _RNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB5_13DigestItemRef18from_scale_encoded
Unexecuted instantiation: _RNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB5_13DigestItemRef18from_scale_encoded
1095
1096
    /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE
1097
    /// encoding of that digest item.
1098
41
    pub fn scale_encoding(
1099
41
        &self,
1100
41
        block_number_bytes: usize,
1101
41
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
1102
41
        let (item1, item2) = match *self {
1103
2
            DigestItemRef::AuraPreDigest(ref aura_pre_digest) => {
1104
2
                let encoded = aura_pre_digest
1105
2
                    .scale_encoding()
1106
2
                    .fold(Vec::new(), |mut a, b| {
1107
2
                        a.extend_from_slice(b.as_ref());
1108
2
                        a
1109
2
                    });
_RNCNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB7_13DigestItemRef14scale_encoding0B9_
Line
Count
Source
1106
2
                    .fold(Vec::new(), |mut a, b| {
1107
2
                        a.extend_from_slice(b.as_ref());
1108
2
                        a
1109
2
                    });
Unexecuted instantiation: _RNCNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB7_13DigestItemRef14scale_encoding0B9_
1110
2
1111
2
                let mut ret = Vec::with_capacity(12);
1112
2
                ret.push(6);
1113
2
                ret.extend_from_slice(b"aura");
1114
2
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1115
2
                (ret, either::Left(encoded))
1116
            }
1117
0
            DigestItemRef::AuraSeal(seal) => {
1118
0
                let mut ret = Vec::with_capacity(12);
1119
0
                ret.push(5);
1120
0
                ret.extend_from_slice(b"aura");
1121
0
                ret.extend_from_slice(util::encode_scale_compact_usize(64).as_ref());
1122
0
                (ret, either::Right(&seal[..]))
1123
            }
1124
0
            DigestItemRef::AuraConsensus(ref aura_consensus) => {
1125
0
                let encoded = aura_consensus
1126
0
                    .scale_encoding()
1127
0
                    .fold(Vec::new(), |mut a, b| {
1128
0
                        a.extend_from_slice(b.as_ref());
1129
0
                        a
1130
0
                    });
Unexecuted instantiation: _RNCNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB7_13DigestItemRef14scale_encodings_0B9_
Unexecuted instantiation: _RNCNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB7_13DigestItemRef14scale_encodings_0B9_
1131
0
1132
0
                let mut ret = Vec::with_capacity(12);
1133
0
                ret.push(4);
1134
0
                ret.extend_from_slice(b"aura");
1135
0
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1136
0
                (ret, either::Left(encoded))
1137
            }
1138
7
            DigestItemRef::BabePreDigest(ref babe_pre_digest) => {
1139
7
                let encoded = babe_pre_digest
1140
7
                    .scale_encoding()
1141
27
                    .fold(Vec::new(), |mut a, b| {
1142
27
                        a.extend_from_slice(b.as_ref());
1143
27
                        a
1144
27
                    });
_RNCNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB7_13DigestItemRef14scale_encodings0_0B9_
Line
Count
Source
1141
27
                    .fold(Vec::new(), |mut a, b| {
1142
27
                        a.extend_from_slice(b.as_ref());
1143
27
                        a
1144
27
                    });
Unexecuted instantiation: _RNCNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB7_13DigestItemRef14scale_encodings0_0B9_
1145
7
1146
7
                let mut ret = Vec::with_capacity(12);
1147
7
                ret.push(6);
1148
7
                ret.extend_from_slice(b"BABE");
1149
7
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1150
7
                (ret, either::Left(encoded))
1151
            }
1152
17
            DigestItemRef::BabeConsensus(ref babe_consensus) => {
1153
17
                let encoded = babe_consensus
1154
17
                    .scale_encoding()
1155
1.89k
                    .fold(Vec::new(), |mut a, b| {
1156
1.89k
                        a.extend_from_slice(b.as_ref());
1157
1.89k
                        a
1158
1.89k
                    });
_RNCNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB7_13DigestItemRef14scale_encodings1_0B9_
Line
Count
Source
1155
1.89k
                    .fold(Vec::new(), |mut a, b| {
1156
1.89k
                        a.extend_from_slice(b.as_ref());
1157
1.89k
                        a
1158
1.89k
                    });
Unexecuted instantiation: _RNCNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB7_13DigestItemRef14scale_encodings1_0B9_
1159
17
1160
17
                let mut ret = Vec::with_capacity(12);
1161
17
                ret.push(4);
1162
17
                ret.extend_from_slice(b"BABE");
1163
17
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1164
17
                (ret, either::Left(encoded))
1165
            }
1166
12
            DigestItemRef::GrandpaConsensus(ref gp_consensus) => {
1167
12
                let encoded =
1168
12
                    gp_consensus
1169
12
                        .scale_encoding(block_number_bytes)
1170
1.82k
                        .fold(Vec::new(), |mut a, b| {
1171
1.82k
                            a.extend_from_slice(b.as_ref());
1172
1.82k
                            a
1173
1.82k
                        });
_RNCNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB7_13DigestItemRef14scale_encodings2_0B9_
Line
Count
Source
1170
1.82k
                        .fold(Vec::new(), |mut a, b| {
1171
1.82k
                            a.extend_from_slice(b.as_ref());
1172
1.82k
                            a
1173
1.82k
                        });
Unexecuted instantiation: _RNCNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB7_13DigestItemRef14scale_encodings2_0B9_
1174
12
1175
12
                let mut ret = Vec::with_capacity(12);
1176
12
                ret.push(4);
1177
12
                ret.extend_from_slice(b"FRNK");
1178
12
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1179
12
                (ret, either::Left(encoded))
1180
            }
1181
3
            DigestItemRef::BabeSeal(seal) => {
1182
3
                let mut ret = Vec::with_capacity(12);
1183
3
                ret.push(5);
1184
3
                ret.extend_from_slice(b"BABE");
1185
3
                ret.extend_from_slice(util::encode_scale_compact_usize(64).as_ref());
1186
3
                (ret, either::Right(&seal[..]))
1187
            }
1188
0
            DigestItemRef::UnknownConsensus { engine, opaque } => {
1189
0
                let mut ret = Vec::with_capacity(12);
1190
0
                ret.push(4);
1191
0
                ret.extend_from_slice(&engine);
1192
0
                ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref());
1193
0
                (ret, either::Right(opaque))
1194
            }
1195
0
            DigestItemRef::UnknownSeal { engine, opaque } => {
1196
0
                let mut ret = Vec::with_capacity(12);
1197
0
                ret.push(5);
1198
0
                ret.extend_from_slice(&engine);
1199
0
                ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref());
1200
0
                (ret, either::Right(opaque))
1201
            }
1202
0
            DigestItemRef::UnknownPreRuntime { engine, opaque } => {
1203
0
                let mut ret = Vec::with_capacity(12);
1204
0
                ret.push(6);
1205
0
                ret.extend_from_slice(&engine);
1206
0
                ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref());
1207
0
                (ret, either::Right(opaque))
1208
            }
1209
0
            DigestItemRef::Other(raw) => {
1210
0
                let mut ret = Vec::with_capacity(12);
1211
0
                ret.push(0);
1212
0
                ret.extend_from_slice(util::encode_scale_compact_usize(raw.len()).as_ref());
1213
0
                (ret, either::Right(raw))
1214
            }
1215
0
            DigestItemRef::RuntimeEnvironmentUpdated => (vec![8], either::Right(&[][..])),
1216
        };
1217
1218
41
        [either::Left(item1), item2].into_iter()
1219
41
    }
_RNvMsa_NtCsN16ciHI6Qf_7smoldot6headerNtB5_13DigestItemRef14scale_encoding
Line
Count
Source
1098
41
    pub fn scale_encoding(
1099
41
        &self,
1100
41
        block_number_bytes: usize,
1101
41
    ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + 'a> + Clone + 'a {
1102
41
        let (item1, item2) = match *self {
1103
2
            DigestItemRef::AuraPreDigest(ref aura_pre_digest) => {
1104
2
                let encoded = aura_pre_digest
1105
2
                    .scale_encoding()
1106
2
                    .fold(Vec::new(), |mut a, b| {
1107
                        a.extend_from_slice(b.as_ref());
1108
                        a
1109
2
                    });
1110
2
1111
2
                let mut ret = Vec::with_capacity(12);
1112
2
                ret.push(6);
1113
2
                ret.extend_from_slice(b"aura");
1114
2
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1115
2
                (ret, either::Left(encoded))
1116
            }
1117
0
            DigestItemRef::AuraSeal(seal) => {
1118
0
                let mut ret = Vec::with_capacity(12);
1119
0
                ret.push(5);
1120
0
                ret.extend_from_slice(b"aura");
1121
0
                ret.extend_from_slice(util::encode_scale_compact_usize(64).as_ref());
1122
0
                (ret, either::Right(&seal[..]))
1123
            }
1124
0
            DigestItemRef::AuraConsensus(ref aura_consensus) => {
1125
0
                let encoded = aura_consensus
1126
0
                    .scale_encoding()
1127
0
                    .fold(Vec::new(), |mut a, b| {
1128
                        a.extend_from_slice(b.as_ref());
1129
                        a
1130
0
                    });
1131
0
1132
0
                let mut ret = Vec::with_capacity(12);
1133
0
                ret.push(4);
1134
0
                ret.extend_from_slice(b"aura");
1135
0
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1136
0
                (ret, either::Left(encoded))
1137
            }
1138
7
            DigestItemRef::BabePreDigest(ref babe_pre_digest) => {
1139
7
                let encoded = babe_pre_digest
1140
7
                    .scale_encoding()
1141
7
                    .fold(Vec::new(), |mut a, b| {
1142
                        a.extend_from_slice(b.as_ref());
1143
                        a
1144
7
                    });
1145
7
1146
7
                let mut ret = Vec::with_capacity(12);
1147
7
                ret.push(6);
1148
7
                ret.extend_from_slice(b"BABE");
1149
7
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1150
7
                (ret, either::Left(encoded))
1151
            }
1152
17
            DigestItemRef::BabeConsensus(ref babe_consensus) => {
1153
17
                let encoded = babe_consensus
1154
17
                    .scale_encoding()
1155
17
                    .fold(Vec::new(), |mut a, b| {
1156
                        a.extend_from_slice(b.as_ref());
1157
                        a
1158
17
                    });
1159
17
1160
17
                let mut ret = Vec::with_capacity(12);
1161
17
                ret.push(4);
1162
17
                ret.extend_from_slice(b"BABE");
1163
17
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1164
17
                (ret, either::Left(encoded))
1165
            }
1166
12
            DigestItemRef::GrandpaConsensus(ref gp_consensus) => {
1167
12
                let encoded =
1168
12
                    gp_consensus
1169
12
                        .scale_encoding(block_number_bytes)
1170
12
                        .fold(Vec::new(), |mut a, b| {
1171
                            a.extend_from_slice(b.as_ref());
1172
                            a
1173
12
                        });
1174
12
1175
12
                let mut ret = Vec::with_capacity(12);
1176
12
                ret.push(4);
1177
12
                ret.extend_from_slice(b"FRNK");
1178
12
                ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref());
1179
12
                (ret, either::Left(encoded))
1180
            }
1181
3
            DigestItemRef::BabeSeal(seal) => {
1182
3
                let mut ret = Vec::with_capacity(12);
1183
3
                ret.push(5);
1184
3
                ret.extend_from_slice(b"BABE");
1185
3
                ret.extend_from_slice(util::encode_scale_compact_usize(64).as_ref());
1186
3
                (ret, either::Right(&seal[..]))
1187
            }
1188
0
            DigestItemRef::UnknownConsensus { engine, opaque } => {
1189
0
                let mut ret = Vec::with_capacity(12);
1190
0
                ret.push(4);
1191
0
                ret.extend_from_slice(&engine);
1192
0
                ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref());
1193
0
                (ret, either::Right(opaque))
1194
            }
1195
0
            DigestItemRef::UnknownSeal { engine, opaque } => {
1196
0
                let mut ret = Vec::with_capacity(12);
1197
0
                ret.push(5);
1198
0
                ret.extend_from_slice(&engine);
1199
0
                ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref());
1200
0
                (ret, either::Right(opaque))
1201
            }
1202
0
            DigestItemRef::UnknownPreRuntime { engine, opaque } => {
1203
0
                let mut ret = Vec::with_capacity(12);
1204
0
                ret.push(6);
1205
0
                ret.extend_from_slice(&engine);
1206
0
                ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref());
1207
0
                (ret, either::Right(opaque))
1208
            }
1209
0
            DigestItemRef::Other(raw) => {
1210
0
                let mut ret = Vec::with_capacity(12);
1211
0
                ret.push(0);
1212
0
                ret.extend_from_slice(util::encode_scale_compact_usize(raw.len()).as_ref());
1213
0
                (ret, either::Right(raw))
1214
            }
1215
0
            DigestItemRef::RuntimeEnvironmentUpdated => (vec![8], either::Right(&[][..])),
1216
        };
1217
1218
41
        [either::Left(item1), item2].into_iter()
1219
41
    }
Unexecuted instantiation: _RNvMsa_NtCseuYC0Zibziv_7smoldot6headerNtB5_13DigestItemRef14scale_encoding
1220
}
1221
1222
impl<'a> From<&'a DigestItem> for DigestItemRef<'a> {
1223
2
    fn from(a: &'a DigestItem) -> DigestItemRef<'a> {
1224
2
        match a {
1225
2
            DigestItem::AuraPreDigest(v) => DigestItemRef::AuraPreDigest(v.clone()),
1226
0
            DigestItem::AuraConsensus(v) => DigestItemRef::AuraConsensus(v.into()),
1227
0
            DigestItem::AuraSeal(v) => DigestItemRef::AuraSeal(v),
1228
0
            DigestItem::BabePreDigest(v) => DigestItemRef::BabePreDigest(v.into()),
1229
0
            DigestItem::BabeConsensus(v) => DigestItemRef::BabeConsensus(v.into()),
1230
0
            DigestItem::BabeSeal(v) => DigestItemRef::BabeSeal(v),
1231
0
            DigestItem::GrandpaConsensus(v) => DigestItemRef::GrandpaConsensus(v.into()),
1232
0
            DigestItem::UnknownConsensus { engine, opaque } => DigestItemRef::UnknownConsensus {
1233
0
                engine: *engine,
1234
0
                opaque,
1235
0
            },
1236
0
            DigestItem::UnknownSeal { engine, opaque } => DigestItemRef::UnknownSeal {
1237
0
                engine: *engine,
1238
0
                opaque,
1239
0
            },
1240
0
            DigestItem::UnknownPreRuntime { engine, opaque } => DigestItemRef::UnknownPreRuntime {
1241
0
                engine: *engine,
1242
0
                opaque,
1243
0
            },
1244
0
            DigestItem::Other(v) => DigestItemRef::Other(v),
1245
0
            DigestItem::RuntimeEnvironmentUpdated => DigestItemRef::RuntimeEnvironmentUpdated,
1246
        }
1247
2
    }
_RNvXsb_NtCsN16ciHI6Qf_7smoldot6headerNtB5_13DigestItemRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_10DigestItemE4from
Line
Count
Source
1223
2
    fn from(a: &'a DigestItem) -> DigestItemRef<'a> {
1224
2
        match a {
1225
2
            DigestItem::AuraPreDigest(v) => DigestItemRef::AuraPreDigest(v.clone()),
1226
0
            DigestItem::AuraConsensus(v) => DigestItemRef::AuraConsensus(v.into()),
1227
0
            DigestItem::AuraSeal(v) => DigestItemRef::AuraSeal(v),
1228
0
            DigestItem::BabePreDigest(v) => DigestItemRef::BabePreDigest(v.into()),
1229
0
            DigestItem::BabeConsensus(v) => DigestItemRef::BabeConsensus(v.into()),
1230
0
            DigestItem::BabeSeal(v) => DigestItemRef::BabeSeal(v),
1231
0
            DigestItem::GrandpaConsensus(v) => DigestItemRef::GrandpaConsensus(v.into()),
1232
0
            DigestItem::UnknownConsensus { engine, opaque } => DigestItemRef::UnknownConsensus {
1233
0
                engine: *engine,
1234
0
                opaque,
1235
0
            },
1236
0
            DigestItem::UnknownSeal { engine, opaque } => DigestItemRef::UnknownSeal {
1237
0
                engine: *engine,
1238
0
                opaque,
1239
0
            },
1240
0
            DigestItem::UnknownPreRuntime { engine, opaque } => DigestItemRef::UnknownPreRuntime {
1241
0
                engine: *engine,
1242
0
                opaque,
1243
0
            },
1244
0
            DigestItem::Other(v) => DigestItemRef::Other(v),
1245
0
            DigestItem::RuntimeEnvironmentUpdated => DigestItemRef::RuntimeEnvironmentUpdated,
1246
        }
1247
2
    }
Unexecuted instantiation: _RNvXsb_NtCseuYC0Zibziv_7smoldot6headerNtB5_13DigestItemRefINtNtCsaYZPK01V26L_4core7convert4FromRNtB5_10DigestItemE4from
1248
}
1249
1250
// TODO: document
1251
#[derive(Debug, Clone)]
1252
pub enum DigestItem {
1253
    AuraPreDigest(AuraPreDigest),
1254
    AuraConsensus(AuraConsensusLog),
1255
    /// Block signature made using the AURA consensus engine.
1256
    AuraSeal([u8; 64]),
1257
1258
    BabePreDigest(BabePreDigest),
1259
    BabeConsensus(BabeConsensusLog),
1260
    /// Block signature made using the BABE consensus engine.
1261
    BabeSeal([u8; 64]),
1262
1263
    GrandpaConsensus(GrandpaConsensusLog),
1264
1265
    /// See [`DigestItemRef::UnknownConsensus`].
1266
    UnknownConsensus {
1267
        /// Name of the consensus engine.
1268
        engine: [u8; 4],
1269
        /// Smoldot doesn't interpret the content of the log item.
1270
        opaque: Vec<u8>,
1271
    },
1272
    /// See [`DigestItemRef::UnknownPreRuntime`].
1273
    UnknownPreRuntime {
1274
        /// Name of the consensus engine.
1275
        engine: [u8; 4],
1276
        /// Smoldot doesn't interpret the content of the log item.
1277
        opaque: Vec<u8>,
1278
    },
1279
    /// See [`DigestItemRef::UnknownSeal`].
1280
    UnknownSeal {
1281
        /// Name of the consensus engine.
1282
        engine: [u8; 4],
1283
        /// Smoldot doesn't interpret the content of the log item.
1284
        opaque: Vec<u8>,
1285
    },
1286
1287
    /// Runtime of the chain has been updated in this block. This can include the runtime code or
1288
    /// the heap pages.
1289
    RuntimeEnvironmentUpdated,
1290
1291
    /// Some other thing. Always ignored.
1292
    Other(Vec<u8>),
1293
}
1294
1295
impl<'a> From<DigestItemRef<'a>> for DigestItem {
1296
4
    fn from(a: DigestItemRef<'a>) -> DigestItem {
1297
4
        match a {
1298
0
            DigestItemRef::AuraPreDigest(v) => DigestItem::AuraPreDigest(v),
1299
0
            DigestItemRef::AuraConsensus(v) => DigestItem::AuraConsensus(v.into()),
1300
0
            DigestItemRef::AuraSeal(v) => {
1301
0
                let mut seal = [0; 64];
1302
0
                seal.copy_from_slice(v);
1303
0
                DigestItem::AuraSeal(seal)
1304
            }
1305
2
            DigestItemRef::BabePreDigest(v) => DigestItem::BabePreDigest(v.into()),
1306
0
            DigestItemRef::BabeConsensus(v) => DigestItem::BabeConsensus(v.into()),
1307
2
            DigestItemRef::BabeSeal(v) => {
1308
2
                let mut seal = [0; 64];
1309
2
                seal.copy_from_slice(v);
1310
2
                DigestItem::BabeSeal(seal)
1311
            }
1312
0
            DigestItemRef::GrandpaConsensus(v) => DigestItem::GrandpaConsensus(v.into()),
1313
0
            DigestItemRef::UnknownConsensus { engine, opaque } => DigestItem::UnknownConsensus {
1314
0
                opaque: opaque.to_vec(),
1315
0
                engine,
1316
0
            },
1317
0
            DigestItemRef::UnknownSeal { engine, opaque } => DigestItem::UnknownSeal {
1318
0
                opaque: opaque.to_vec(),
1319
0
                engine,
1320
0
            },
1321
0
            DigestItemRef::UnknownPreRuntime { engine, opaque } => DigestItem::UnknownPreRuntime {
1322
0
                opaque: opaque.to_vec(),
1323
0
                engine,
1324
0
            },
1325
0
            DigestItemRef::Other(v) => DigestItem::Other(v.to_vec()),
1326
0
            DigestItemRef::RuntimeEnvironmentUpdated => DigestItem::RuntimeEnvironmentUpdated,
1327
        }
1328
4
    }
_RNvXsc_NtCsN16ciHI6Qf_7smoldot6headerNtB5_10DigestItemINtNtCsaYZPK01V26L_4core7convert4FromNtB5_13DigestItemRefE4from
Line
Count
Source
1296
4
    fn from(a: DigestItemRef<'a>) -> DigestItem {
1297
4
        match a {
1298
0
            DigestItemRef::AuraPreDigest(v) => DigestItem::AuraPreDigest(v),
1299
0
            DigestItemRef::AuraConsensus(v) => DigestItem::AuraConsensus(v.into()),
1300
0
            DigestItemRef::AuraSeal(v) => {
1301
0
                let mut seal = [0; 64];
1302
0
                seal.copy_from_slice(v);
1303
0
                DigestItem::AuraSeal(seal)
1304
            }
1305
2
            DigestItemRef::BabePreDigest(v) => DigestItem::BabePreDigest(v.into()),
1306
0
            DigestItemRef::BabeConsensus(v) => DigestItem::BabeConsensus(v.into()),
1307
2
            DigestItemRef::BabeSeal(v) => {
1308
2
                let mut seal = [0; 64];
1309
2
                seal.copy_from_slice(v);
1310
2
                DigestItem::BabeSeal(seal)
1311
            }
1312
0
            DigestItemRef::GrandpaConsensus(v) => DigestItem::GrandpaConsensus(v.into()),
1313
0
            DigestItemRef::UnknownConsensus { engine, opaque } => DigestItem::UnknownConsensus {
1314
0
                opaque: opaque.to_vec(),
1315
0
                engine,
1316
0
            },
1317
0
            DigestItemRef::UnknownSeal { engine, opaque } => DigestItem::UnknownSeal {
1318
0
                opaque: opaque.to_vec(),
1319
0
                engine,
1320
0
            },
1321
0
            DigestItemRef::UnknownPreRuntime { engine, opaque } => DigestItem::UnknownPreRuntime {
1322
0
                opaque: opaque.to_vec(),
1323
0
                engine,
1324
0
            },
1325
0
            DigestItemRef::Other(v) => DigestItem::Other(v.to_vec()),
1326
0
            DigestItemRef::RuntimeEnvironmentUpdated => DigestItem::RuntimeEnvironmentUpdated,
1327
        }
1328
4
    }
Unexecuted instantiation: _RNvXsc_NtCseuYC0Zibziv_7smoldot6headerNtB5_10DigestItemINtNtCsaYZPK01V26L_4core7convert4FromNtB5_13DigestItemRefE4from
1329
}
1330
1331
/// Decodes a single digest log item. On success, returns the item and the data that remains
1332
/// after the item.
1333
175
fn decode_item(
1334
175
    mut slice: &[u8],
1335
175
    block_number_bytes: usize,
1336
175
) -> Result<(DigestItemRef, &[u8]), Error> {
1337
175
    let index = *slice.first().ok_or(Error::TooShort)
?0
;
1338
175
    slice = &slice[1..];
1339
175
1340
175
    match index {
1341
175
        4..=6 => {
1342
175
            if slice.len() < 4 {
1343
0
                return Err(Error::TooShort);
1344
175
            }
1345
175
1346
175
            let engine_id: &[u8; 4] = TryFrom::try_from(&slice[..4]).unwrap();
1347
175
            slice = &slice[4..];
1348
1349
175
            let (mut slice, len) =
1350
175
                crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(slice)
1351
175
                    .map_err(|_| 
Error::DigestItemLenDecodeError0
)
?0
;
Unexecuted instantiation: _RNCNvNtCsN16ciHI6Qf_7smoldot6header11decode_item0B5_
Unexecuted instantiation: _RNCNvNtCseuYC0Zibziv_7smoldot6header11decode_item0B5_
1352
1353
175
            if slice.len() < len {
1354
0
                return Err(Error::TooShort);
1355
175
            }
1356
175
1357
175
            let content = &slice[..len];
1358
175
            slice = &slice[len..];
1359
1360
175
            let 
item174
= decode_item_from_parts(index, block_number_bytes, engine_id, content)
?1
;
1361
174
            Ok((item, slice))
1362
        }
1363
0
        8 => Ok((DigestItemRef::RuntimeEnvironmentUpdated, slice)),
1364
        0 => {
1365
0
            let (mut slice, len) =
1366
0
                crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(slice)
1367
0
                    .map_err(|_| Error::DigestItemLenDecodeError)?;
Unexecuted instantiation: _RNCNvNtCsN16ciHI6Qf_7smoldot6header11decode_items_0B5_
Unexecuted instantiation: _RNCNvNtCseuYC0Zibziv_7smoldot6header11decode_items_0B5_
1368
1369
0
            if slice.len() < len {
1370
0
                return Err(Error::TooShort);
1371
0
            }
1372
0
1373
0
            let content = &slice[..len];
1374
0
            slice = &slice[len..];
1375
0
1376
0
            let item = DigestItemRef::Other(content);
1377
0
1378
0
            Ok((item, slice))
1379
        }
1380
0
        ty => Err(Error::UnknownDigestLogType(ty)),
1381
    }
1382
175
}
_RNvNtCsN16ciHI6Qf_7smoldot6header11decode_item
Line
Count
Source
1333
175
fn decode_item(
1334
175
    mut slice: &[u8],
1335
175
    block_number_bytes: usize,
1336
175
) -> Result<(DigestItemRef, &[u8]), Error> {
1337
175
    let index = *slice.first().ok_or(Error::TooShort)
?0
;
1338
175
    slice = &slice[1..];
1339
175
1340
175
    match index {
1341
175
        4..=6 => {
1342
175
            if slice.len() < 4 {
1343
0
                return Err(Error::TooShort);
1344
175
            }
1345
175
1346
175
            let engine_id: &[u8; 4] = TryFrom::try_from(&slice[..4]).unwrap();
1347
175
            slice = &slice[4..];
1348
1349
175
            let (mut slice, len) =
1350
175
                crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(slice)
1351
175
                    .map_err(|_| Error::DigestItemLenDecodeError)
?0
;
1352
1353
175
            if slice.len() < len {
1354
0
                return Err(Error::TooShort);
1355
175
            }
1356
175
1357
175
            let content = &slice[..len];
1358
175
            slice = &slice[len..];
1359
1360
175
            let 
item174
= decode_item_from_parts(index, block_number_bytes, engine_id, content)
?1
;
1361
174
            Ok((item, slice))
1362
        }
1363
0
        8 => Ok((DigestItemRef::RuntimeEnvironmentUpdated, slice)),
1364
        0 => {
1365
0
            let (mut slice, len) =
1366
0
                crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(slice)
1367
0
                    .map_err(|_| Error::DigestItemLenDecodeError)?;
1368
1369
0
            if slice.len() < len {
1370
0
                return Err(Error::TooShort);
1371
0
            }
1372
0
1373
0
            let content = &slice[..len];
1374
0
            slice = &slice[len..];
1375
0
1376
0
            let item = DigestItemRef::Other(content);
1377
0
1378
0
            Ok((item, slice))
1379
        }
1380
0
        ty => Err(Error::UnknownDigestLogType(ty)),
1381
    }
1382
175
}
Unexecuted instantiation: _RNvNtCseuYC0Zibziv_7smoldot6header11decode_item
1383
1384
/// When we know the index, engine id, and content of an item, we can finish decoding.
1385
175
fn decode_item_from_parts<'a>(
1386
175
    index: u8,
1387
175
    block_number_bytes: usize,
1388
175
    engine_id: &'a [u8; 4],
1389
175
    content: &'a [u8],
1390
175
) -> Result<DigestItemRef<'a>, Error> {
1391
175
    Ok(match (index, engine_id) {
1392
0
        (_, b"pow_") => return Err(Error::PowIdeologicallyNotSupported),
1393
        // 4 = Consensus
1394
1
        (4, b"aura") => DigestItemRef::AuraConsensus(AuraConsensusLogRef::from_slice(content)?),
1395
51
        (4, b"BABE") => DigestItemRef::BabeConsensus(BabeConsensusLogRef::from_slice(content)
?0
),
1396
25
        (4, b"FRNK") => DigestItemRef::GrandpaConsensus(GrandpaConsensusLogRef::from_slice(
1397
25
            content,
1398
25
            block_number_bytes,
1399
25
        )
?0
),
1400
1
        (4, engine) => DigestItemRef::UnknownConsensus {
1401
1
            engine: *engine,
1402
1
            opaque: content,
1403
1
        },
1404
        // 5 = Seal
1405
        (5, b"aura") => DigestItemRef::AuraSeal({
1406
0
            TryFrom::try_from(content).map_err(|_| Error::BadAuraSealLength)?
Unexecuted instantiation: _RNCNvNtCsN16ciHI6Qf_7smoldot6header22decode_item_from_parts0B5_
Unexecuted instantiation: _RNCNvNtCseuYC0Zibziv_7smoldot6header22decode_item_from_parts0B5_
1407
        }),
1408
        (5, b"BABE") => DigestItemRef::BabeSeal({
1409
41
            TryFrom::try_from(content).map_err(|_| 
Error::BadBabeSealLength0
)
?0
Unexecuted instantiation: _RNCNvNtCsN16ciHI6Qf_7smoldot6header22decode_item_from_partss_0B5_
Unexecuted instantiation: _RNCNvNtCseuYC0Zibziv_7smoldot6header22decode_item_from_partss_0B5_
1410
        }),
1411
0
        (5, engine) => DigestItemRef::UnknownSeal {
1412
0
            engine: *engine,
1413
0
            opaque: content,
1414
0
        },
1415
        // 6 = PreRuntime
1416
1
        (6, b"aura") => DigestItemRef::AuraPreDigest(AuraPreDigest::from_slice(content)
?0
),
1417
55
        (6, b"BABE") => DigestItemRef::BabePreDigest(BabePreDigestRef::from_slice(content)
?0
),
1418
0
        (6, engine) => DigestItemRef::UnknownPreRuntime {
1419
0
            engine: *engine,
1420
0
            opaque: content,
1421
0
        },
1422
0
        _ => unreachable!(),
1423
    })
1424
175
}
_RNvNtCsN16ciHI6Qf_7smoldot6header22decode_item_from_parts
Line
Count
Source
1385
175
fn decode_item_from_parts<'a>(
1386
175
    index: u8,
1387
175
    block_number_bytes: usize,
1388
175
    engine_id: &'a [u8; 4],
1389
175
    content: &'a [u8],
1390
175
) -> Result<DigestItemRef<'a>, Error> {
1391
175
    Ok(match (index, engine_id) {
1392
0
        (_, b"pow_") => return Err(Error::PowIdeologicallyNotSupported),
1393
        // 4 = Consensus
1394
1
        (4, b"aura") => DigestItemRef::AuraConsensus(AuraConsensusLogRef::from_slice(content)?),
1395
51
        (4, b"BABE") => DigestItemRef::BabeConsensus(BabeConsensusLogRef::from_slice(content)
?0
),
1396
25
        (4, b"FRNK") => DigestItemRef::GrandpaConsensus(GrandpaConsensusLogRef::from_slice(
1397
25
            content,
1398
25
            block_number_bytes,
1399
25
        )
?0
),
1400
1
        (4, engine) => DigestItemRef::UnknownConsensus {
1401
1
            engine: *engine,
1402
1
            opaque: content,
1403
1
        },
1404
        // 5 = Seal
1405
        (5, b"aura") => DigestItemRef::AuraSeal({
1406
0
            TryFrom::try_from(content).map_err(|_| Error::BadAuraSealLength)?
1407
        }),
1408
        (5, b"BABE") => DigestItemRef::BabeSeal({
1409
41
            TryFrom::try_from(content).map_err(|_| Error::BadBabeSealLength)
?0
1410
        }),
1411
0
        (5, engine) => DigestItemRef::UnknownSeal {
1412
0
            engine: *engine,
1413
0
            opaque: content,
1414
0
        },
1415
        // 6 = PreRuntime
1416
1
        (6, b"aura") => DigestItemRef::AuraPreDigest(AuraPreDigest::from_slice(content)
?0
),
1417
55
        (6, b"BABE") => DigestItemRef::BabePreDigest(BabePreDigestRef::from_slice(content)
?0
),
1418
0
        (6, engine) => DigestItemRef::UnknownPreRuntime {
1419
0
            engine: *engine,
1420
0
            opaque: content,
1421
0
        },
1422
0
        _ => unreachable!(),
1423
    })
1424
175
}
Unexecuted instantiation: _RNvNtCseuYC0Zibziv_7smoldot6header22decode_item_from_parts