/__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 |