/__w/smoldot/smoldot/repo/lib/src/header.rs
Line | Count | Source |
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 | } _RINvNtCsjlkOsLH0Zfj_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsaFPxhswmqCN_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 | } |
_RINvNtCsjlkOsLH0Zfj_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 | } |
Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsaFPxhswmqCN_5alloc3vec3VechEECscoAnRPySggw_6author Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRShECscoAnRPySggw_6author Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRShECsfFWJyR6nd6r_17smoldot_full_node Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsaFPxhswmqCN_5alloc3vec3VechEEB4_ Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRShECs7snhGEhbuap_18smoldot_light_wasm Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsaFPxhswmqCN_5alloc3vec3VechEECs7snhGEhbuap_18smoldot_light_wasm _RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsaFPxhswmqCN_5alloc3vec3VechEECsjyNE3yDMkgA_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 | } |
_RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRShECsjyNE3yDMkgA_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 | } |
_RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRShECs4VrkfB1pvQ3_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 | } |
_RINvNtCsc1ywvx6YAnK_7smoldot6header30hash_from_scale_encoded_headerRINtNtCsaFPxhswmqCN_5alloc3vec3VechEECs4VrkfB1pvQ3_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 | } _RINvNtCsjlkOsLH0Zfj_7smoldot6header39hash_from_scale_encoded_header_vectoredINtCsfDbbEgL1j7J_6either6EitherIB1d_RShINtNtCsh2B47LN1tya_8arrayvec8arrayvec8ArrayVechKj9_EEIB1d_B1P_IB1d_INtNtCsaFPxhswmqCN_5alloc3vec3VechEB1M_EEEINtNtNtNtCs1p5UDGgVI4d_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 | 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 | } |
_RINvNtCsjlkOsLH0Zfj_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsaFPxhswmqCN_5alloc3vec3VechEINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_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 | } |
_RINvNtCsjlkOsLH0Zfj_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_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: _RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsaFPxhswmqCN_5alloc3vec3VechEINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECscoAnRPySggw_6author Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECscoAnRPySggw_6author Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECsfFWJyR6nd6r_17smoldot_full_node _RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredINtCsfDbbEgL1j7J_6either6EitherIB1d_RShINtNtCsh2B47LN1tya_8arrayvec8arrayvec8ArrayVechKj9_EEIB1d_B1P_IB1d_INtNtCsaFPxhswmqCN_5alloc3vec3VechEB1M_EEEINtNtNtNtCs1p5UDGgVI4d_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: _RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsaFPxhswmqCN_5alloc3vec3VechEINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EEB4_ Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsaFPxhswmqCN_5alloc3vec3VechEINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECs7snhGEhbuap_18smoldot_light_wasm Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECs7snhGEhbuap_18smoldot_light_wasm _RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsaFPxhswmqCN_5alloc3vec3VechEINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECsjyNE3yDMkgA_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 | } |
_RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECsjyNE3yDMkgA_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 | } |
_RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRINtNtCsaFPxhswmqCN_5alloc3vec3VechEINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECs4VrkfB1pvQ3_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 | } |
_RINvNtCsc1ywvx6YAnK_7smoldot6header39hash_from_scale_encoded_header_vectoredRShINtNtNtNtCs1p5UDGgVI4d_4core4iter7sources4once4OnceB1c_EECs4VrkfB1pvQ3_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 | | // 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 | | ) |
127 | 0 | } Unexecuted instantiation: _RINvNtCsjlkOsLH0Zfj_7smoldot6header15extrinsics_rootpEB4_ Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header15extrinsics_rootINtNtCsaFPxhswmqCN_5alloc3vec3VechEECscoAnRPySggw_6author Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header15extrinsics_rootpEB4_ Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header15extrinsics_rootINtNtCsaFPxhswmqCN_5alloc3vec3VechEECs7snhGEhbuap_18smoldot_light_wasm Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header15extrinsics_rootINtNtCsaFPxhswmqCN_5alloc3vec3VechEECsjyNE3yDMkgA_14json_rpc_basic Unexecuted instantiation: _RINvNtCsc1ywvx6YAnK_7smoldot6header15extrinsics_rootINtNtCsaFPxhswmqCN_5alloc3vec3VechEECs4VrkfB1pvQ3_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 (header1.51k , 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 | | |
136 | 1.51k | Ok(header) |
137 | 1.51k | } _RNvNtCsjlkOsLH0Zfj_7smoldot6header6decode Line | Count | Source | 130 | 1.05k | pub fn decode(scale_encoded: &[u8], block_number_bytes: usize) -> Result<HeaderRef, Error> { | 131 | 1.05k | let (header1.04k , 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 | | | 136 | 1.04k | Ok(header) | 137 | 1.05k | } |
_RNvNtCsc1ywvx6YAnK_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 | | | 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 | | |
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::BlockNumberDecodeError)?0 ; |
157 | | |
158 | 1.51k | if scale_encoded.len() < 32 + 32 + 1 { |
159 | 0 | return Err(Error::TooShort); |
160 | 1.51k | } |
161 | | |
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 (digest1.51k , 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 | | |
177 | 1.51k | Ok((header, remainder)) |
178 | 1.51k | } _RNvNtCsjlkOsLH0Zfj_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 | | | 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 | | | 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 (digest1.04k , 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 | | | 177 | 1.04k | Ok((header, remainder)) | 178 | 1.05k | } |
_RNvNtCsc1ywvx6YAnK_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 | | | 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 | | | 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 | | | 177 | 464 | Ok((header, remainder)) | 178 | 464 | } |
|
179 | | |
180 | | /// Potential error when decoding a header. |
181 | | #[derive(Debug, derive_more::Display, derive_more::Error, Clone)] |
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("Digest log with an unrecognized type {unknown_type}")] |
197 | | UnknownDigestLogType { |
198 | | /// Identifier of the type. |
199 | | unknown_type: u8, |
200 | | }, |
201 | | /// Found a seal that isn't the last item in the list. |
202 | | SealIsntLastItem, |
203 | | /// Bad length of an AURA seal. |
204 | | BadAuraSealLength, |
205 | | BadAuraConsensusRefType, |
206 | | BadAuraAuthoritiesListLen, |
207 | | /// There are multiple Aura pre-runtime digests in the block header. |
208 | | MultipleAuraPreRuntimeDigests, |
209 | | /// Bad length of a BABE seal. |
210 | | BadBabeSealLength, |
211 | | BadBabePreDigestRefType, |
212 | | BadBabeConsensusRefType, |
213 | | BadBabeNextConfigVersion, |
214 | | /// There are multiple Babe pre-runtime digests in the block header. |
215 | | MultipleBabePreRuntimeDigests, |
216 | | /// There are multiple Babe epoch descriptor digests in the block header. |
217 | | MultipleBabeEpochDescriptors, |
218 | | /// There are multiple Babe configuration descriptor digests in the block header. |
219 | | MultipleBabeConfigDescriptors, |
220 | | /// There are multiple runtime environment updated digests in the block header. |
221 | | MutipleRuntimeEnvironmentUpdated, |
222 | | /// Found a Babe configuration change digest without an epoch change digest. |
223 | | UnexpectedBabeConfigDescriptor, |
224 | | GrandpaConsensusLogDecodeError, |
225 | | /// Proof-of-work consensus algorithm is intentionally not supported for ideological reasons. |
226 | | PowIdeologicallyNotSupported, |
227 | | } |
228 | | |
229 | | /// Header of a block, after decoding. |
230 | | /// |
231 | | /// Note that the information in there are not guaranteed to be exact. The exactness of the |
232 | | /// information depends on the context. |
233 | | #[derive(Debug, Clone)] |
234 | | pub struct HeaderRef<'a> { |
235 | | /// Hash of the parent block stored in the header. |
236 | | pub parent_hash: &'a [u8; 32], |
237 | | /// Block number stored in the header. |
238 | | pub number: u64, |
239 | | /// The state trie Merkle root |
240 | | pub state_root: &'a [u8; 32], |
241 | | /// The Merkle root of the extrinsics. |
242 | | /// |
243 | | /// You can use the [`extrinsics_root`] function to compute this value. |
244 | | pub extrinsics_root: &'a [u8; 32], |
245 | | /// List of auxiliary data appended to the block header. |
246 | | pub digest: DigestRef<'a>, |
247 | | } |
248 | | |
249 | | impl<'a> HeaderRef<'a> { |
250 | | /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE |
251 | | /// encoding of the header. |
252 | 1.19k | pub fn scale_encoding( |
253 | 1.19k | &self, |
254 | 1.19k | block_number_bytes: usize, |
255 | 1.19k | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { |
256 | 1.19k | self.scale_encoding_before_digest().map(either::Left).chain( |
257 | 1.19k | self.digest |
258 | 1.19k | .scale_encoding(block_number_bytes) |
259 | 1.19k | .map(either::Right), |
260 | | ) |
261 | 1.19k | } _RNvMNtCsjlkOsLH0Zfj_7smoldot6headerNtB2_9HeaderRef14scale_encoding Line | Count | Source | 252 | 1.04k | pub fn scale_encoding( | 253 | 1.04k | &self, | 254 | 1.04k | block_number_bytes: usize, | 255 | 1.04k | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { | 256 | 1.04k | self.scale_encoding_before_digest().map(either::Left).chain( | 257 | 1.04k | self.digest | 258 | 1.04k | .scale_encoding(block_number_bytes) | 259 | 1.04k | .map(either::Right), | 260 | | ) | 261 | 1.04k | } |
_RNvMNtCsc1ywvx6YAnK_7smoldot6headerNtB2_9HeaderRef14scale_encoding Line | Count | Source | 252 | 147 | pub fn scale_encoding( | 253 | 147 | &self, | 254 | 147 | block_number_bytes: usize, | 255 | 147 | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { | 256 | 147 | self.scale_encoding_before_digest().map(either::Left).chain( | 257 | 147 | self.digest | 258 | 147 | .scale_encoding(block_number_bytes) | 259 | 147 | .map(either::Right), | 260 | | ) | 261 | 147 | } |
|
262 | | |
263 | | /// Same as [`HeaderRef::scale_encoding`], but with an extra digest item added to the end of |
264 | | /// the list. |
265 | | /// |
266 | | /// > **Note**: Keep in mind that this can produce a potentially invalid header, for example |
267 | | /// > if the digest contains duplicate items that shouldn't be duplicate. |
268 | 0 | pub fn scale_encoding_with_extra_digest_item( |
269 | 0 | &self, |
270 | 0 | block_number_bytes: usize, |
271 | 0 | extra_item: DigestItemRef<'a>, |
272 | 0 | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { |
273 | 0 | self.scale_encoding_before_digest().map(either::Left).chain( |
274 | 0 | self.digest |
275 | 0 | .scale_encoding_with_extra_item(block_number_bytes, extra_item) |
276 | 0 | .map(either::Right), |
277 | | ) |
278 | 0 | } Unexecuted instantiation: _RNvMNtCsjlkOsLH0Zfj_7smoldot6headerNtB2_9HeaderRef37scale_encoding_with_extra_digest_item Unexecuted instantiation: _RNvMNtCsc1ywvx6YAnK_7smoldot6headerNtB2_9HeaderRef37scale_encoding_with_extra_digest_item |
279 | | |
280 | 1.19k | fn scale_encoding_before_digest( |
281 | 1.19k | &self, |
282 | 1.19k | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { |
283 | 1.19k | iter::once(either::Left(&self.parent_hash[..])) |
284 | 1.19k | .chain(iter::once(either::Right(util::encode_scale_compact_u64( |
285 | 1.19k | self.number, |
286 | 1.19k | )))) |
287 | 1.19k | .chain(iter::once(either::Left(&self.state_root[..]))) |
288 | 1.19k | .chain(iter::once(either::Left(&self.extrinsics_root[..]))) |
289 | 1.19k | } _RNvMNtCsjlkOsLH0Zfj_7smoldot6headerNtB2_9HeaderRef28scale_encoding_before_digest Line | Count | Source | 280 | 1.04k | fn scale_encoding_before_digest( | 281 | 1.04k | &self, | 282 | 1.04k | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { | 283 | 1.04k | iter::once(either::Left(&self.parent_hash[..])) | 284 | 1.04k | .chain(iter::once(either::Right(util::encode_scale_compact_u64( | 285 | 1.04k | self.number, | 286 | 1.04k | )))) | 287 | 1.04k | .chain(iter::once(either::Left(&self.state_root[..]))) | 288 | 1.04k | .chain(iter::once(either::Left(&self.extrinsics_root[..]))) | 289 | 1.04k | } |
_RNvMNtCsc1ywvx6YAnK_7smoldot6headerNtB2_9HeaderRef28scale_encoding_before_digest Line | Count | Source | 280 | 147 | fn scale_encoding_before_digest( | 281 | 147 | &self, | 282 | 147 | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { | 283 | 147 | iter::once(either::Left(&self.parent_hash[..])) | 284 | 147 | .chain(iter::once(either::Right(util::encode_scale_compact_u64( | 285 | 147 | self.number, | 286 | 147 | )))) | 287 | 147 | .chain(iter::once(either::Left(&self.state_root[..]))) | 288 | 147 | .chain(iter::once(either::Left(&self.extrinsics_root[..]))) | 289 | 147 | } |
|
290 | | |
291 | | /// Equivalent to [`HeaderRef::scale_encoding`] but returns the data in a `Vec`. |
292 | 1.11k | pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> { |
293 | | // We assume that an average header should be less than this size. |
294 | | // At the time of writing of this comment, the average Westend/Polkadot/Kusama block |
295 | | // header is 288 bytes, and the average parachain block is 186 bytes. Some blocks |
296 | | // (the epoch transition blocks in particular) have a much larger header, but considering |
297 | | // that they are the vast minority we don't care so much about that. |
298 | | const CAP: usize = 1024; |
299 | | |
300 | 1.11k | self.scale_encoding(block_number_bytes) |
301 | 5.63k | .fold1.11k (Vec::with_capacity1.11k (CAP), |mut a, b| { |
302 | 5.63k | a.extend_from_slice(b.as_ref()); |
303 | 5.63k | a |
304 | 5.63k | }) _RNCNvMNtCsjlkOsLH0Zfj_7smoldot6headerNtB4_9HeaderRef18scale_encoding_vec0B6_ Line | Count | Source | 301 | 5.21k | .fold(Vec::with_capacity(CAP), |mut a, b| { | 302 | 5.21k | a.extend_from_slice(b.as_ref()); | 303 | 5.21k | a | 304 | 5.21k | }) |
_RNCNvMNtCsc1ywvx6YAnK_7smoldot6headerNtB4_9HeaderRef18scale_encoding_vec0B6_ Line | Count | Source | 301 | 420 | .fold(Vec::with_capacity(CAP), |mut a, b| { | 302 | 420 | a.extend_from_slice(b.as_ref()); | 303 | 420 | a | 304 | 420 | }) |
|
305 | 1.11k | } _RNvMNtCsjlkOsLH0Zfj_7smoldot6headerNtB2_9HeaderRef18scale_encoding_vec Line | Count | Source | 292 | 1.03k | pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> { | 293 | | // We assume that an average header should be less than this size. | 294 | | // At the time of writing of this comment, the average Westend/Polkadot/Kusama block | 295 | | // header is 288 bytes, and the average parachain block is 186 bytes. Some blocks | 296 | | // (the epoch transition blocks in particular) have a much larger header, but considering | 297 | | // that they are the vast minority we don't care so much about that. | 298 | | const CAP: usize = 1024; | 299 | | | 300 | 1.03k | self.scale_encoding(block_number_bytes) | 301 | 1.03k | .fold(Vec::with_capacity(CAP), |mut a, b| { | 302 | | a.extend_from_slice(b.as_ref()); | 303 | | a | 304 | | }) | 305 | 1.03k | } |
_RNvMNtCsc1ywvx6YAnK_7smoldot6headerNtB2_9HeaderRef18scale_encoding_vec Line | Count | Source | 292 | 84 | pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> { | 293 | | // We assume that an average header should be less than this size. | 294 | | // At the time of writing of this comment, the average Westend/Polkadot/Kusama block | 295 | | // header is 288 bytes, and the average parachain block is 186 bytes. Some blocks | 296 | | // (the epoch transition blocks in particular) have a much larger header, but considering | 297 | | // that they are the vast minority we don't care so much about that. | 298 | | const CAP: usize = 1024; | 299 | | | 300 | 84 | self.scale_encoding(block_number_bytes) | 301 | 84 | .fold(Vec::with_capacity(CAP), |mut a, b| { | 302 | | a.extend_from_slice(b.as_ref()); | 303 | | a | 304 | | }) | 305 | 84 | } |
|
306 | | |
307 | | /// Builds the hash of the header. |
308 | 74 | pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] { |
309 | 74 | hash_from_scale_encoded_header_vectored(self.scale_encoding(block_number_bytes)) |
310 | 74 | } _RNvMNtCsjlkOsLH0Zfj_7smoldot6headerNtB2_9HeaderRef4hash Line | Count | Source | 308 | 11 | pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] { | 309 | 11 | hash_from_scale_encoded_header_vectored(self.scale_encoding(block_number_bytes)) | 310 | 11 | } |
_RNvMNtCsc1ywvx6YAnK_7smoldot6headerNtB2_9HeaderRef4hash Line | Count | Source | 308 | 63 | pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] { | 309 | 63 | hash_from_scale_encoded_header_vectored(self.scale_encoding(block_number_bytes)) | 310 | 63 | } |
|
311 | | } |
312 | | |
313 | | impl<'a> From<&'a Header> for HeaderRef<'a> { |
314 | 365 | fn from(a: &'a Header) -> HeaderRef<'a> { |
315 | 365 | HeaderRef { |
316 | 365 | parent_hash: &a.parent_hash, |
317 | 365 | number: a.number, |
318 | 365 | state_root: &a.state_root, |
319 | 365 | extrinsics_root: &a.extrinsics_root, |
320 | 365 | digest: (&a.digest).into(), |
321 | 365 | } |
322 | 365 | } _RNvXs_NtCsjlkOsLH0Zfj_7smoldot6headerNtB4_9HeaderRefINtNtCs1p5UDGgVI4d_4core7convert4FromRNtB4_6HeaderE4from Line | Count | Source | 314 | 8 | fn from(a: &'a Header) -> HeaderRef<'a> { | 315 | 8 | HeaderRef { | 316 | 8 | parent_hash: &a.parent_hash, | 317 | 8 | number: a.number, | 318 | 8 | state_root: &a.state_root, | 319 | 8 | extrinsics_root: &a.extrinsics_root, | 320 | 8 | digest: (&a.digest).into(), | 321 | 8 | } | 322 | 8 | } |
_RNvXs_NtCsc1ywvx6YAnK_7smoldot6headerNtB4_9HeaderRefINtNtCs1p5UDGgVI4d_4core7convert4FromRNtB4_6HeaderE4from Line | Count | Source | 314 | 357 | fn from(a: &'a Header) -> HeaderRef<'a> { | 315 | 357 | HeaderRef { | 316 | 357 | parent_hash: &a.parent_hash, | 317 | 357 | number: a.number, | 318 | 357 | state_root: &a.state_root, | 319 | 357 | extrinsics_root: &a.extrinsics_root, | 320 | 357 | digest: (&a.digest).into(), | 321 | 357 | } | 322 | 357 | } |
|
323 | | } |
324 | | |
325 | | /// Header of a block, after decoding. |
326 | | /// |
327 | | /// Note that the information in there are not guaranteed to be exact. The exactness of the |
328 | | /// information depends on the context. |
329 | | #[derive(Debug, Clone)] |
330 | | pub struct Header { |
331 | | /// Hash of the parent block stored in the header. |
332 | | pub parent_hash: [u8; 32], |
333 | | /// Block number stored in the header. |
334 | | pub number: u64, |
335 | | /// The state trie Merkle root |
336 | | pub state_root: [u8; 32], |
337 | | /// The Merkle root of the extrinsics. |
338 | | /// |
339 | | /// You can use the [`extrinsics_root`] function to compute this value. |
340 | | pub extrinsics_root: [u8; 32], |
341 | | /// List of auxiliary data appended to the block header. |
342 | | pub digest: Digest, |
343 | | } |
344 | | |
345 | | impl Header { |
346 | | /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE |
347 | | /// encoding of the header. |
348 | 0 | pub fn scale_encoding( |
349 | 0 | &self, |
350 | 0 | block_number_bytes: usize, |
351 | 0 | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone> + Clone { |
352 | 0 | HeaderRef::from(self).scale_encoding(block_number_bytes) |
353 | 0 | } Unexecuted instantiation: _RNvMs0_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Header14scale_encoding Unexecuted instantiation: _RNvMs0_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Header14scale_encoding |
354 | | |
355 | | /// Equivalent to [`Header::scale_encoding`] but returns the data in a `Vec`. |
356 | 23 | pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> { |
357 | 23 | HeaderRef::from(self).scale_encoding_vec(block_number_bytes) |
358 | 23 | } _RNvMs0_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Header18scale_encoding_vec Line | Count | Source | 356 | 2 | pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> { | 357 | 2 | HeaderRef::from(self).scale_encoding_vec(block_number_bytes) | 358 | 2 | } |
_RNvMs0_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Header18scale_encoding_vec Line | Count | Source | 356 | 21 | pub fn scale_encoding_vec(&self, block_number_bytes: usize) -> Vec<u8> { | 357 | 21 | HeaderRef::from(self).scale_encoding_vec(block_number_bytes) | 358 | 21 | } |
|
359 | | |
360 | | /// Builds the hash of the header. |
361 | 23 | pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] { |
362 | 23 | HeaderRef::from(self).hash(block_number_bytes) |
363 | 23 | } _RNvMs0_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Header4hash Line | Count | Source | 361 | 2 | pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] { | 362 | 2 | HeaderRef::from(self).hash(block_number_bytes) | 363 | 2 | } |
_RNvMs0_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Header4hash Line | Count | Source | 361 | 21 | pub fn hash(&self, block_number_bytes: usize) -> [u8; 32] { | 362 | 21 | HeaderRef::from(self).hash(block_number_bytes) | 363 | 21 | } |
|
364 | | } |
365 | | |
366 | | impl<'a> From<HeaderRef<'a>> for Header { |
367 | 45 | fn from(a: HeaderRef<'a>) -> Header { |
368 | 45 | Header { |
369 | 45 | parent_hash: *a.parent_hash, |
370 | 45 | number: a.number, |
371 | 45 | state_root: *a.state_root, |
372 | 45 | extrinsics_root: *a.extrinsics_root, |
373 | 45 | digest: a.digest.into(), |
374 | 45 | } |
375 | 45 | } _RNvXs1_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6HeaderINtNtCs1p5UDGgVI4d_4core7convert4FromNtB5_9HeaderRefE4from Line | Count | Source | 367 | 3 | fn from(a: HeaderRef<'a>) -> Header { | 368 | 3 | Header { | 369 | 3 | parent_hash: *a.parent_hash, | 370 | 3 | number: a.number, | 371 | 3 | state_root: *a.state_root, | 372 | 3 | extrinsics_root: *a.extrinsics_root, | 373 | 3 | digest: a.digest.into(), | 374 | 3 | } | 375 | 3 | } |
_RNvXs1_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6HeaderINtNtCs1p5UDGgVI4d_4core7convert4FromNtB5_9HeaderRefE4from Line | Count | Source | 367 | 42 | fn from(a: HeaderRef<'a>) -> Header { | 368 | 42 | Header { | 369 | 42 | parent_hash: *a.parent_hash, | 370 | 42 | number: a.number, | 371 | 42 | state_root: *a.state_root, | 372 | 42 | extrinsics_root: *a.extrinsics_root, | 373 | 42 | digest: a.digest.into(), | 374 | 42 | } | 375 | 42 | } |
|
376 | | } |
377 | | |
378 | | /// Generic header digest. |
379 | | #[derive(Clone)] |
380 | | pub struct DigestRef<'a> { |
381 | | /// Actual source of digest items. |
382 | | inner: DigestRefInner<'a>, |
383 | | /// Index of the [`DigestItemRef::AuraSeal`] item, if any. |
384 | | aura_seal_index: Option<usize>, |
385 | | /// Index of the [`DigestItemRef::AuraPreDigest`] item, if any. |
386 | | aura_predigest_index: Option<usize>, |
387 | | /// Index of the [`DigestItemRef::BabeSeal`] item, if any. |
388 | | babe_seal_index: Option<usize>, |
389 | | /// Index of the [`DigestItemRef::BabePreDigest`] item, if any. |
390 | | babe_predigest_index: Option<usize>, |
391 | | /// Index of the [`DigestItemRef::BabeConsensus`] item containing a |
392 | | /// [`BabeConsensusLogRef::NextEpochData`], if any. |
393 | | babe_next_epoch_data_index: Option<usize>, |
394 | | /// Index of the [`DigestItemRef::BabeConsensus`] item containing a |
395 | | /// [`BabeConsensusLogRef::NextConfigData`], if any. |
396 | | babe_next_config_data_index: Option<usize>, |
397 | | /// `true` if there is a [`DigestItemRef::RuntimeEnvironmentUpdated`] item. |
398 | | has_runtime_environment_updated: bool, |
399 | | } |
400 | | |
401 | | #[derive(Clone)] |
402 | | enum DigestRefInner<'a> { |
403 | | /// Source of data is an undecoded slice of bytes. |
404 | | Undecoded { |
405 | | /// Number of log items in the header. |
406 | | /// Must always match the actual number of items in [`DigestRefInner::Undecoded::digest`]. |
407 | | /// The validity must be verified before a [`DigestRef`] object is instantiated. |
408 | | digest_logs_len: usize, |
409 | | /// Encoded digest. Its validity must be verified before a [`DigestRef`] object is |
410 | | /// instantiated. |
411 | | digest: &'a [u8], |
412 | | /// Number of bytes used to encode block numbers in headers. |
413 | | block_number_bytes: usize, |
414 | | }, |
415 | | Parsed(&'a [DigestItem]), |
416 | | } |
417 | | |
418 | | impl<'a> DigestRef<'a> { |
419 | | /// Returns a digest with empty logs. |
420 | 1.05k | pub fn empty() -> DigestRef<'a> { |
421 | 1.05k | DigestRef { |
422 | 1.05k | inner: DigestRefInner::Parsed(&[]), |
423 | 1.05k | aura_seal_index: None, |
424 | 1.05k | aura_predigest_index: None, |
425 | 1.05k | babe_seal_index: None, |
426 | 1.05k | babe_predigest_index: None, |
427 | 1.05k | babe_next_epoch_data_index: None, |
428 | 1.05k | babe_next_config_data_index: None, |
429 | 1.05k | has_runtime_environment_updated: false, |
430 | 1.05k | } |
431 | 1.05k | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef5empty Line | Count | Source | 420 | 1.03k | pub fn empty() -> DigestRef<'a> { | 421 | 1.03k | DigestRef { | 422 | 1.03k | inner: DigestRefInner::Parsed(&[]), | 423 | 1.03k | aura_seal_index: None, | 424 | 1.03k | aura_predigest_index: None, | 425 | 1.03k | babe_seal_index: None, | 426 | 1.03k | babe_predigest_index: None, | 427 | 1.03k | babe_next_epoch_data_index: None, | 428 | 1.03k | babe_next_config_data_index: None, | 429 | 1.03k | has_runtime_environment_updated: false, | 430 | 1.03k | } | 431 | 1.03k | } |
_RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef5empty Line | Count | Source | 420 | 21 | pub fn empty() -> DigestRef<'a> { | 421 | 21 | DigestRef { | 422 | 21 | inner: DigestRefInner::Parsed(&[]), | 423 | 21 | aura_seal_index: None, | 424 | 21 | aura_predigest_index: None, | 425 | 21 | babe_seal_index: None, | 426 | 21 | babe_predigest_index: None, | 427 | 21 | babe_next_epoch_data_index: None, | 428 | 21 | babe_next_config_data_index: None, | 429 | 21 | has_runtime_environment_updated: false, | 430 | 21 | } | 431 | 21 | } |
|
432 | | |
433 | | /// Returns true if the list has any item that belong to the Aura consensus engine. |
434 | | /// |
435 | | /// This function is `O(n)` over the number of log items. |
436 | 4 | pub fn has_any_aura(&self) -> bool { |
437 | 10 | self.logs()4 .any4 (|l| l.is_aura()) _RNCNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_9DigestRef12has_any_aura0B9_ Line | Count | Source | 437 | 10 | self.logs().any(|l| l.is_aura()) |
Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef12has_any_aura0B9_ |
438 | 4 | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef12has_any_aura Line | Count | Source | 436 | 4 | pub fn has_any_aura(&self) -> bool { | 437 | 4 | self.logs().any(|l| l.is_aura()) | 438 | 4 | } |
Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef12has_any_aura |
439 | | |
440 | | /// Returns true if the list has any item that belong to the Babe consensus engine. |
441 | | /// |
442 | | /// This function is `O(n)` over the number of log items. |
443 | 42 | pub fn has_any_babe(&self) -> bool { |
444 | 42 | self.logs().any(|l| l0 .is_babe0 ()) Unexecuted instantiation: _RNCNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_9DigestRef12has_any_babe0B9_ Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef12has_any_babe0B9_ |
445 | 42 | } Unexecuted instantiation: _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef12has_any_babe _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef12has_any_babe Line | Count | Source | 443 | 42 | pub fn has_any_babe(&self) -> bool { | 444 | 42 | self.logs().any(|l| l.is_babe()) | 445 | 42 | } |
|
446 | | |
447 | | /// Returns true if the list has any item that belong to the Grandpa finality engine. |
448 | | /// |
449 | | /// This function is `O(n)` over the number of log items. |
450 | 0 | pub fn has_any_grandpa(&self) -> bool { |
451 | 0 | self.logs().any(|l| l.is_grandpa()) Unexecuted instantiation: _RNCNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_9DigestRef15has_any_grandpa0B9_ Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef15has_any_grandpa0B9_ |
452 | 0 | } Unexecuted instantiation: _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef15has_any_grandpa Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef15has_any_grandpa |
453 | | |
454 | | /// Returns the Aura seal digest item, if any. |
455 | 42 | pub fn aura_seal(&self) -> Option<&'a [u8; 64]> { |
456 | 42 | if let Some(aura_seal_index0 ) = self.aura_seal_index { |
457 | 0 | if let DigestItemRef::AuraSeal(seal) = self.logs().nth(aura_seal_index).unwrap() { |
458 | 0 | Some(seal) |
459 | | } else { |
460 | 0 | unreachable!() |
461 | | } |
462 | | } else { |
463 | 42 | None |
464 | | } |
465 | 42 | } Unexecuted instantiation: _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef9aura_seal _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef9aura_seal Line | Count | Source | 455 | 42 | pub fn aura_seal(&self) -> Option<&'a [u8; 64]> { | 456 | 42 | if let Some(aura_seal_index0 ) = self.aura_seal_index { | 457 | 0 | if let DigestItemRef::AuraSeal(seal) = self.logs().nth(aura_seal_index).unwrap() { | 458 | 0 | Some(seal) | 459 | | } else { | 460 | 0 | unreachable!() | 461 | | } | 462 | | } else { | 463 | 42 | None | 464 | | } | 465 | 42 | } |
|
466 | | |
467 | | /// Returns the Aura pre-runtime digest item, if any. |
468 | 42 | pub fn aura_pre_runtime(&self) -> Option<AuraPreDigest> { |
469 | 42 | if let Some(aura_predigest_index0 ) = self.aura_predigest_index { |
470 | 0 | if let DigestItemRef::AuraPreDigest(item) = |
471 | 0 | self.logs().nth(aura_predigest_index).unwrap() |
472 | | { |
473 | 0 | Some(item) |
474 | | } else { |
475 | 0 | unreachable!() |
476 | | } |
477 | | } else { |
478 | 42 | None |
479 | | } |
480 | 42 | } Unexecuted instantiation: _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef16aura_pre_runtime _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef16aura_pre_runtime Line | Count | Source | 468 | 42 | pub fn aura_pre_runtime(&self) -> Option<AuraPreDigest> { | 469 | 42 | if let Some(aura_predigest_index0 ) = self.aura_predigest_index { | 470 | 0 | if let DigestItemRef::AuraPreDigest(item) = | 471 | 0 | self.logs().nth(aura_predigest_index).unwrap() | 472 | | { | 473 | 0 | Some(item) | 474 | | } else { | 475 | 0 | unreachable!() | 476 | | } | 477 | | } else { | 478 | 42 | None | 479 | | } | 480 | 42 | } |
|
481 | | |
482 | | /// Returns the Babe seal digest item, if any. |
483 | 4 | pub fn babe_seal(&self) -> Option<&'a [u8; 64]> { |
484 | 4 | if let Some(babe_seal_index) = self.babe_seal_index { |
485 | 4 | if let DigestItemRef::BabeSeal(seal) = self.logs().nth(babe_seal_index).unwrap() { |
486 | 4 | Some(seal) |
487 | | } else { |
488 | 0 | unreachable!() |
489 | | } |
490 | | } else { |
491 | 0 | None |
492 | | } |
493 | 4 | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef9babe_seal Line | Count | Source | 483 | 4 | pub fn babe_seal(&self) -> Option<&'a [u8; 64]> { | 484 | 4 | if let Some(babe_seal_index) = self.babe_seal_index { | 485 | 4 | if let DigestItemRef::BabeSeal(seal) = self.logs().nth(babe_seal_index).unwrap() { | 486 | 4 | Some(seal) | 487 | | } else { | 488 | 0 | unreachable!() | 489 | | } | 490 | | } else { | 491 | 0 | None | 492 | | } | 493 | 4 | } |
Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef9babe_seal |
494 | | |
495 | | /// Returns the Babe pre-runtime digest item, if any. |
496 | 6 | pub fn babe_pre_runtime(&self) -> Option<BabePreDigestRef<'a>> { |
497 | 6 | if let Some(babe_predigest_index) = self.babe_predigest_index { |
498 | 6 | if let DigestItemRef::BabePreDigest(item) = |
499 | 6 | self.logs().nth(babe_predigest_index).unwrap() |
500 | | { |
501 | 6 | Some(item) |
502 | | } else { |
503 | 0 | unreachable!() |
504 | | } |
505 | | } else { |
506 | 0 | None |
507 | | } |
508 | 6 | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef16babe_pre_runtime Line | Count | Source | 496 | 6 | pub fn babe_pre_runtime(&self) -> Option<BabePreDigestRef<'a>> { | 497 | 6 | if let Some(babe_predigest_index) = self.babe_predigest_index { | 498 | 6 | if let DigestItemRef::BabePreDigest(item) = | 499 | 6 | self.logs().nth(babe_predigest_index).unwrap() | 500 | | { | 501 | 6 | Some(item) | 502 | | } else { | 503 | 0 | unreachable!() | 504 | | } | 505 | | } else { | 506 | 0 | None | 507 | | } | 508 | 6 | } |
Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef16babe_pre_runtime |
509 | | |
510 | | /// Returns the Babe epoch information stored in the header, if any. |
511 | | /// |
512 | | /// It is guaranteed that a configuration change is present only if an epoch change is |
513 | | /// present too. |
514 | 8 | pub fn babe_epoch_information(&self) -> Option<(BabeNextEpochRef<'a>, Option<BabeNextConfig>)> { |
515 | 8 | if let Some(babe_next_epoch_data_index4 ) = self.babe_next_epoch_data_index { |
516 | 4 | if let DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(epoch)) = |
517 | 4 | self.logs().nth(babe_next_epoch_data_index).unwrap() |
518 | | { |
519 | 4 | if let Some(babe_next_config_data_index0 ) = self.babe_next_config_data_index { |
520 | | if let DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData( |
521 | 0 | config, |
522 | 0 | )) = self.logs().nth(babe_next_config_data_index).unwrap() |
523 | | { |
524 | 0 | Some((epoch, Some(config))) |
525 | | } else { |
526 | 0 | panic!() |
527 | | } |
528 | | } else { |
529 | 4 | Some((epoch, None)) |
530 | | } |
531 | | } else { |
532 | 0 | unreachable!() |
533 | | } |
534 | | } else { |
535 | 4 | debug_assert!(self.babe_next_config_data_index.is_none()); |
536 | 4 | None |
537 | | } |
538 | 8 | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef22babe_epoch_information Line | Count | Source | 514 | 8 | pub fn babe_epoch_information(&self) -> Option<(BabeNextEpochRef<'a>, Option<BabeNextConfig>)> { | 515 | 8 | if let Some(babe_next_epoch_data_index4 ) = self.babe_next_epoch_data_index { | 516 | 4 | if let DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(epoch)) = | 517 | 4 | self.logs().nth(babe_next_epoch_data_index).unwrap() | 518 | | { | 519 | 4 | if let Some(babe_next_config_data_index0 ) = self.babe_next_config_data_index { | 520 | | if let DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData( | 521 | 0 | config, | 522 | 0 | )) = self.logs().nth(babe_next_config_data_index).unwrap() | 523 | | { | 524 | 0 | Some((epoch, Some(config))) | 525 | | } else { | 526 | 0 | panic!() | 527 | | } | 528 | | } else { | 529 | 4 | Some((epoch, None)) | 530 | | } | 531 | | } else { | 532 | 0 | unreachable!() | 533 | | } | 534 | | } else { | 535 | 4 | debug_assert!(self.babe_next_config_data_index.is_none()); | 536 | 4 | None | 537 | | } | 538 | 8 | } |
Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef22babe_epoch_information |
539 | | |
540 | | /// Returns `true` if there is a [`DigestItemRef::RuntimeEnvironmentUpdated`] item. |
541 | 0 | pub fn has_runtime_environment_updated(&self) -> bool { |
542 | 0 | self.has_runtime_environment_updated |
543 | 0 | } Unexecuted instantiation: _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef31has_runtime_environment_updated Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef31has_runtime_environment_updated |
544 | | |
545 | | /// If the last element of the list is a seal, removes it from the [`DigestRef`]. |
546 | 4 | pub fn pop_seal(&mut self) -> Option<Seal<'a>> { |
547 | 4 | let seal_pos = self.babe_seal_index.or(self.aura_seal_index)?0 ; |
548 | | |
549 | 4 | match &mut self.inner { |
550 | 0 | DigestRefInner::Parsed(list) => { |
551 | 0 | debug_assert!(!list.is_empty()); |
552 | 0 | debug_assert_eq!(seal_pos, list.len() - 1); |
553 | | |
554 | 0 | let item = &list[seal_pos]; |
555 | 0 | *list = &list[..seal_pos]; |
556 | | |
557 | 0 | match item { |
558 | 0 | DigestItem::AuraSeal(seal) => Some(Seal::Aura(seal)), |
559 | 0 | DigestItem::BabeSeal(seal) => Some(Seal::Babe(seal)), |
560 | 0 | _ => unreachable!(), |
561 | | } |
562 | | } |
563 | | |
564 | | DigestRefInner::Undecoded { |
565 | 4 | digest, |
566 | 4 | digest_logs_len, |
567 | 4 | block_number_bytes, |
568 | | } => { |
569 | 4 | debug_assert_eq!(seal_pos, *digest_logs_len - 1); |
570 | | |
571 | 4 | let mut iter = LogsIter { |
572 | 4 | inner: LogsIterInner::Undecoded { |
573 | 4 | pointer: digest, |
574 | 4 | remaining_len: *digest_logs_len, |
575 | 4 | block_number_bytes: *block_number_bytes, |
576 | 4 | }, |
577 | 4 | }; |
578 | 4 | for _ in 0..seal_pos { |
579 | 6 | let _item = iter.next(); |
580 | 6 | debug_assert!(_item.is_some()); |
581 | | } |
582 | | |
583 | | if let LogsIterInner::Undecoded { |
584 | 4 | pointer, |
585 | 4 | remaining_len, |
586 | | .. |
587 | 4 | } = iter.inner |
588 | | { |
589 | 4 | *digest_logs_len -= 1; |
590 | 4 | *digest = &digest[..digest.len() - pointer.len()]; |
591 | 4 | self.babe_seal_index = None; |
592 | 4 | debug_assert_eq!(remaining_len, 1); |
593 | | } else { |
594 | 0 | unreachable!() |
595 | | } |
596 | | |
597 | 4 | match iter.next() { |
598 | 0 | Some(DigestItemRef::AuraSeal(seal)) => Some(Seal::Aura(seal)), |
599 | 4 | Some(DigestItemRef::BabeSeal(seal)) => Some(Seal::Babe(seal)), |
600 | 0 | _ => unreachable!(), |
601 | | } |
602 | | } |
603 | | } |
604 | 4 | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef8pop_seal Line | Count | Source | 546 | 4 | pub fn pop_seal(&mut self) -> Option<Seal<'a>> { | 547 | 4 | let seal_pos = self.babe_seal_index.or(self.aura_seal_index)?0 ; | 548 | | | 549 | 4 | match &mut self.inner { | 550 | 0 | DigestRefInner::Parsed(list) => { | 551 | 0 | debug_assert!(!list.is_empty()); | 552 | 0 | debug_assert_eq!(seal_pos, list.len() - 1); | 553 | | | 554 | 0 | let item = &list[seal_pos]; | 555 | 0 | *list = &list[..seal_pos]; | 556 | | | 557 | 0 | match item { | 558 | 0 | DigestItem::AuraSeal(seal) => Some(Seal::Aura(seal)), | 559 | 0 | DigestItem::BabeSeal(seal) => Some(Seal::Babe(seal)), | 560 | 0 | _ => unreachable!(), | 561 | | } | 562 | | } | 563 | | | 564 | | DigestRefInner::Undecoded { | 565 | 4 | digest, | 566 | 4 | digest_logs_len, | 567 | 4 | block_number_bytes, | 568 | | } => { | 569 | 4 | debug_assert_eq!(seal_pos, *digest_logs_len - 1); | 570 | | | 571 | 4 | let mut iter = LogsIter { | 572 | 4 | inner: LogsIterInner::Undecoded { | 573 | 4 | pointer: digest, | 574 | 4 | remaining_len: *digest_logs_len, | 575 | 4 | block_number_bytes: *block_number_bytes, | 576 | 4 | }, | 577 | 4 | }; | 578 | 4 | for _ in 0..seal_pos { | 579 | 6 | let _item = iter.next(); | 580 | 6 | debug_assert!(_item.is_some()); | 581 | | } | 582 | | | 583 | | if let LogsIterInner::Undecoded { | 584 | 4 | pointer, | 585 | 4 | remaining_len, | 586 | | .. | 587 | 4 | } = iter.inner | 588 | | { | 589 | 4 | *digest_logs_len -= 1; | 590 | 4 | *digest = &digest[..digest.len() - pointer.len()]; | 591 | 4 | self.babe_seal_index = None; | 592 | 4 | debug_assert_eq!(remaining_len, 1); | 593 | | } else { | 594 | 0 | unreachable!() | 595 | | } | 596 | | | 597 | 4 | match iter.next() { | 598 | 0 | Some(DigestItemRef::AuraSeal(seal)) => Some(Seal::Aura(seal)), | 599 | 4 | Some(DigestItemRef::BabeSeal(seal)) => Some(Seal::Babe(seal)), | 600 | 0 | _ => unreachable!(), | 601 | | } | 602 | | } | 603 | | } | 604 | 4 | } |
Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef8pop_seal |
605 | | |
606 | | /// Returns an iterator to the log items in this digest. |
607 | 2.49k | pub fn logs(&self) -> LogsIter<'a> { |
608 | | LogsIter { |
609 | 2.49k | inner: match self.inner { |
610 | 2.40k | DigestRefInner::Parsed(list) => LogsIterInner::Decoded(list.iter()), |
611 | | DigestRefInner::Undecoded { |
612 | 91 | digest, |
613 | 91 | digest_logs_len, |
614 | 91 | block_number_bytes, |
615 | 91 | } => LogsIterInner::Undecoded { |
616 | 91 | pointer: digest, |
617 | 91 | remaining_len: digest_logs_len, |
618 | 91 | block_number_bytes, |
619 | 91 | }, |
620 | | }, |
621 | | } |
622 | 2.49k | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef4logs Line | Count | Source | 607 | 2.11k | pub fn logs(&self) -> LogsIter<'a> { | 608 | | LogsIter { | 609 | 2.11k | inner: match self.inner { | 610 | 2.07k | DigestRefInner::Parsed(list) => LogsIterInner::Decoded(list.iter()), | 611 | | DigestRefInner::Undecoded { | 612 | 47 | digest, | 613 | 47 | digest_logs_len, | 614 | 47 | block_number_bytes, | 615 | 47 | } => LogsIterInner::Undecoded { | 616 | 47 | pointer: digest, | 617 | 47 | remaining_len: digest_logs_len, | 618 | 47 | block_number_bytes, | 619 | 47 | }, | 620 | | }, | 621 | | } | 622 | 2.11k | } |
_RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef4logs Line | Count | Source | 607 | 380 | pub fn logs(&self) -> LogsIter<'a> { | 608 | | LogsIter { | 609 | 380 | inner: match self.inner { | 610 | 336 | DigestRefInner::Parsed(list) => LogsIterInner::Decoded(list.iter()), | 611 | | DigestRefInner::Undecoded { | 612 | 44 | digest, | 613 | 44 | digest_logs_len, | 614 | 44 | block_number_bytes, | 615 | 44 | } => LogsIterInner::Undecoded { | 616 | 44 | pointer: digest, | 617 | 44 | remaining_len: digest_logs_len, | 618 | 44 | block_number_bytes, | 619 | 44 | }, | 620 | | }, | 621 | | } | 622 | 380 | } |
|
623 | | |
624 | | /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE |
625 | | /// encoding of the digest items. |
626 | 1.19k | pub fn scale_encoding( |
627 | 1.19k | &self, |
628 | 1.19k | block_number_bytes: usize, |
629 | 1.19k | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { |
630 | 1.19k | let encoded_len = util::encode_scale_compact_usize(self.logs().len()); |
631 | 1.19k | iter::once(either::Left(encoded_len)).chain( |
632 | 1.19k | self.logs() |
633 | 1.19k | .flat_map(move |v| v41 .scale_encoding41 (block_number_bytes41 ).map41 (either::Right)), _RNCNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_9DigestRef14scale_encoding0B9_ Line | Count | Source | 633 | 41 | .flat_map(move |v| v.scale_encoding(block_number_bytes).map(either::Right)), |
Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef14scale_encoding0CscoAnRPySggw_6author Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef14scale_encoding0B9_ Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef14scale_encoding0Cs7snhGEhbuap_18smoldot_light_wasm Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef14scale_encoding0CsjyNE3yDMkgA_14json_rpc_basic Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef14scale_encoding0Cs4VrkfB1pvQ3_25json_rpc_general_requests |
634 | | ) |
635 | 1.19k | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef14scale_encoding Line | Count | Source | 626 | 1.04k | pub fn scale_encoding( | 627 | 1.04k | &self, | 628 | 1.04k | block_number_bytes: usize, | 629 | 1.04k | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { | 630 | 1.04k | let encoded_len = util::encode_scale_compact_usize(self.logs().len()); | 631 | 1.04k | iter::once(either::Left(encoded_len)).chain( | 632 | 1.04k | self.logs() | 633 | 1.04k | .flat_map(move |v| v.scale_encoding(block_number_bytes).map(either::Right)), | 634 | | ) | 635 | 1.04k | } |
_RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef14scale_encoding Line | Count | Source | 626 | 147 | pub fn scale_encoding( | 627 | 147 | &self, | 628 | 147 | block_number_bytes: usize, | 629 | 147 | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { | 630 | 147 | let encoded_len = util::encode_scale_compact_usize(self.logs().len()); | 631 | 147 | iter::once(either::Left(encoded_len)).chain( | 632 | 147 | self.logs() | 633 | 147 | .flat_map(move |v| v.scale_encoding(block_number_bytes).map(either::Right)), | 634 | | ) | 635 | 147 | } |
|
636 | | |
637 | | /// Same as [`DigestRef::scale_encoding`], but with an extra item added to the end of the list. |
638 | 0 | pub fn scale_encoding_with_extra_item( |
639 | 0 | &self, |
640 | 0 | block_number_bytes: usize, |
641 | 0 | extra_item: DigestItemRef<'a>, |
642 | 0 | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { |
643 | | // Given that `self.logs().len()` counts a number of items present in memory, and that |
644 | | // these items have a non-zero size, it is not possible for this value to be equal to |
645 | | // `usize::MAX`, as that would mean that the entire memory is completely full |
646 | | // of digest log items. Therefore, doing `+ 1` is also guaranteed to never overflow. |
647 | 0 | let new_len = self.logs().len() + 1; |
648 | | |
649 | 0 | let encoded_len = util::encode_scale_compact_usize(new_len); |
650 | 0 | iter::once(either::Left(encoded_len)).chain( |
651 | 0 | self.logs() |
652 | 0 | .chain(iter::once(extra_item)) |
653 | 0 | .flat_map(move |v| v.scale_encoding(block_number_bytes).map(either::Right)), Unexecuted instantiation: _RNCNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_9DigestRef30scale_encoding_with_extra_item0B9_ Unexecuted instantiation: _RNCNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_9DigestRef30scale_encoding_with_extra_item0B9_ |
654 | | ) |
655 | 0 | } Unexecuted instantiation: _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef30scale_encoding_with_extra_item Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef30scale_encoding_with_extra_item |
656 | | |
657 | | /// Turns an already-decoded list of items into a [`DigestRef`]. |
658 | | /// |
659 | | /// Error can happen if the list of items is invalid, for example if it contains a seal at the |
660 | | /// non-last position. |
661 | 1 | pub fn from_slice(slice: &'a [DigestItem]) -> Result<Self, Error> { |
662 | 1 | let mut aura_seal_index = None; |
663 | 1 | let mut aura_predigest_index = None; |
664 | 1 | let mut babe_seal_index = None; |
665 | 1 | let mut babe_predigest_index = None; |
666 | 1 | let mut babe_next_epoch_data_index = None; |
667 | 1 | let mut babe_next_config_data_index = None; |
668 | 1 | let mut has_runtime_environment_updated = false; |
669 | | |
670 | | // Iterate through the log items to see if anything is wrong. |
671 | 1 | for (item_num, item) in slice.iter().enumerate() { |
672 | 1 | match item { |
673 | 1 | DigestItem::AuraPreDigest(_) if aura_predigest_index.is_none() => { |
674 | 1 | aura_predigest_index = Some(item_num); |
675 | 1 | } |
676 | 0 | DigestItem::AuraPreDigest(_) => return Err(Error::MultipleAuraPreRuntimeDigests), |
677 | 0 | DigestItem::AuraConsensus(_) => {} |
678 | 0 | DigestItem::BabePreDigest(_) if babe_predigest_index.is_none() => { |
679 | 0 | babe_predigest_index = Some(item_num); |
680 | 0 | } |
681 | 0 | DigestItem::BabePreDigest(_) => return Err(Error::MultipleBabePreRuntimeDigests), |
682 | | DigestItem::BabeConsensus(BabeConsensusLog::NextEpochData(_)) |
683 | 0 | if babe_next_epoch_data_index.is_none() => |
684 | 0 | { |
685 | 0 | babe_next_epoch_data_index = Some(item_num); |
686 | 0 | } |
687 | | DigestItem::BabeConsensus(BabeConsensusLog::NextEpochData(_)) => { |
688 | 0 | return Err(Error::MultipleBabeEpochDescriptors); |
689 | | } |
690 | | DigestItem::BabeConsensus(BabeConsensusLog::NextConfigData(_)) |
691 | 0 | if babe_next_config_data_index.is_none() => |
692 | 0 | { |
693 | 0 | babe_next_config_data_index = Some(item_num); |
694 | 0 | } |
695 | | DigestItem::BabeConsensus(BabeConsensusLog::NextConfigData(_)) => { |
696 | 0 | return Err(Error::MultipleBabeConfigDescriptors); |
697 | | } |
698 | 0 | DigestItem::BabeConsensus(BabeConsensusLog::OnDisabled(_)) => {} |
699 | 0 | DigestItem::GrandpaConsensus(_) => {} |
700 | 0 | DigestItem::AuraSeal(_) if item_num == slice.len() - 1 => { |
701 | 0 | debug_assert!(aura_seal_index.is_none()); |
702 | 0 | debug_assert!(babe_seal_index.is_none()); |
703 | 0 | aura_seal_index = Some(item_num); |
704 | | } |
705 | 0 | DigestItem::AuraSeal(_) => return Err(Error::SealIsntLastItem), |
706 | 0 | DigestItem::BabeSeal(_) if item_num == slice.len() - 1 => { |
707 | 0 | debug_assert!(aura_seal_index.is_none()); |
708 | 0 | debug_assert!(babe_seal_index.is_none()); |
709 | 0 | babe_seal_index = Some(item_num); |
710 | | } |
711 | 0 | DigestItem::RuntimeEnvironmentUpdated if has_runtime_environment_updated => { |
712 | 0 | return Err(Error::MutipleRuntimeEnvironmentUpdated); |
713 | | } |
714 | 0 | DigestItem::RuntimeEnvironmentUpdated => { |
715 | 0 | has_runtime_environment_updated = true; |
716 | 0 | } |
717 | 0 | DigestItem::BabeSeal(_) => return Err(Error::SealIsntLastItem), |
718 | 0 | DigestItem::UnknownSeal { .. } if item_num == slice.len() - 1 => { |
719 | 0 | debug_assert!(aura_seal_index.is_none()); |
720 | 0 | debug_assert!(babe_seal_index.is_none()); |
721 | | } |
722 | 0 | DigestItem::UnknownSeal { .. } => return Err(Error::SealIsntLastItem), |
723 | | DigestItem::UnknownConsensus { .. } |
724 | | | DigestItem::UnknownPreRuntime { .. } |
725 | 0 | | DigestItem::Other(..) => {} |
726 | | } |
727 | | } |
728 | | |
729 | 1 | if babe_next_config_data_index.is_some() && babe_next_epoch_data_index0 .is_none0 () { |
730 | 0 | return Err(Error::UnexpectedBabeConfigDescriptor); |
731 | 1 | } |
732 | | |
733 | 1 | Ok(DigestRef { |
734 | 1 | inner: DigestRefInner::Parsed(slice), |
735 | 1 | aura_seal_index, |
736 | 1 | aura_predigest_index, |
737 | 1 | babe_seal_index, |
738 | 1 | babe_predigest_index, |
739 | 1 | babe_next_epoch_data_index, |
740 | 1 | babe_next_config_data_index, |
741 | 1 | has_runtime_environment_updated, |
742 | 1 | }) |
743 | 1 | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef10from_slice Line | Count | Source | 661 | 1 | pub fn from_slice(slice: &'a [DigestItem]) -> Result<Self, Error> { | 662 | 1 | let mut aura_seal_index = None; | 663 | 1 | let mut aura_predigest_index = None; | 664 | 1 | let mut babe_seal_index = None; | 665 | 1 | let mut babe_predigest_index = None; | 666 | 1 | let mut babe_next_epoch_data_index = None; | 667 | 1 | let mut babe_next_config_data_index = None; | 668 | 1 | let mut has_runtime_environment_updated = false; | 669 | | | 670 | | // Iterate through the log items to see if anything is wrong. | 671 | 1 | for (item_num, item) in slice.iter().enumerate() { | 672 | 1 | match item { | 673 | 1 | DigestItem::AuraPreDigest(_) if aura_predigest_index.is_none() => { | 674 | 1 | aura_predigest_index = Some(item_num); | 675 | 1 | } | 676 | 0 | DigestItem::AuraPreDigest(_) => return Err(Error::MultipleAuraPreRuntimeDigests), | 677 | 0 | DigestItem::AuraConsensus(_) => {} | 678 | 0 | DigestItem::BabePreDigest(_) if babe_predigest_index.is_none() => { | 679 | 0 | babe_predigest_index = Some(item_num); | 680 | 0 | } | 681 | 0 | DigestItem::BabePreDigest(_) => return Err(Error::MultipleBabePreRuntimeDigests), | 682 | | DigestItem::BabeConsensus(BabeConsensusLog::NextEpochData(_)) | 683 | 0 | if babe_next_epoch_data_index.is_none() => | 684 | 0 | { | 685 | 0 | babe_next_epoch_data_index = Some(item_num); | 686 | 0 | } | 687 | | DigestItem::BabeConsensus(BabeConsensusLog::NextEpochData(_)) => { | 688 | 0 | return Err(Error::MultipleBabeEpochDescriptors); | 689 | | } | 690 | | DigestItem::BabeConsensus(BabeConsensusLog::NextConfigData(_)) | 691 | 0 | if babe_next_config_data_index.is_none() => | 692 | 0 | { | 693 | 0 | babe_next_config_data_index = Some(item_num); | 694 | 0 | } | 695 | | DigestItem::BabeConsensus(BabeConsensusLog::NextConfigData(_)) => { | 696 | 0 | return Err(Error::MultipleBabeConfigDescriptors); | 697 | | } | 698 | 0 | DigestItem::BabeConsensus(BabeConsensusLog::OnDisabled(_)) => {} | 699 | 0 | DigestItem::GrandpaConsensus(_) => {} | 700 | 0 | DigestItem::AuraSeal(_) if item_num == slice.len() - 1 => { | 701 | 0 | debug_assert!(aura_seal_index.is_none()); | 702 | 0 | debug_assert!(babe_seal_index.is_none()); | 703 | 0 | aura_seal_index = Some(item_num); | 704 | | } | 705 | 0 | DigestItem::AuraSeal(_) => return Err(Error::SealIsntLastItem), | 706 | 0 | DigestItem::BabeSeal(_) if item_num == slice.len() - 1 => { | 707 | 0 | debug_assert!(aura_seal_index.is_none()); | 708 | 0 | debug_assert!(babe_seal_index.is_none()); | 709 | 0 | babe_seal_index = Some(item_num); | 710 | | } | 711 | 0 | DigestItem::RuntimeEnvironmentUpdated if has_runtime_environment_updated => { | 712 | 0 | return Err(Error::MutipleRuntimeEnvironmentUpdated); | 713 | | } | 714 | 0 | DigestItem::RuntimeEnvironmentUpdated => { | 715 | 0 | has_runtime_environment_updated = true; | 716 | 0 | } | 717 | 0 | DigestItem::BabeSeal(_) => return Err(Error::SealIsntLastItem), | 718 | 0 | DigestItem::UnknownSeal { .. } if item_num == slice.len() - 1 => { | 719 | 0 | debug_assert!(aura_seal_index.is_none()); | 720 | 0 | debug_assert!(babe_seal_index.is_none()); | 721 | | } | 722 | 0 | DigestItem::UnknownSeal { .. } => return Err(Error::SealIsntLastItem), | 723 | | DigestItem::UnknownConsensus { .. } | 724 | | | DigestItem::UnknownPreRuntime { .. } | 725 | 0 | | DigestItem::Other(..) => {} | 726 | | } | 727 | | } | 728 | | | 729 | 1 | if babe_next_config_data_index.is_some() && babe_next_epoch_data_index0 .is_none0 () { | 730 | 0 | return Err(Error::UnexpectedBabeConfigDescriptor); | 731 | 1 | } | 732 | | | 733 | 1 | Ok(DigestRef { | 734 | 1 | inner: DigestRefInner::Parsed(slice), | 735 | 1 | aura_seal_index, | 736 | 1 | aura_predigest_index, | 737 | 1 | babe_seal_index, | 738 | 1 | babe_predigest_index, | 739 | 1 | babe_next_epoch_data_index, | 740 | 1 | babe_next_config_data_index, | 741 | 1 | has_runtime_environment_updated, | 742 | 1 | }) | 743 | 1 | } |
Unexecuted instantiation: _RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef10from_slice |
744 | | |
745 | | /// Try to decode a list of digest items, from their SCALE encoding. |
746 | 1.51k | fn from_scale_bytes( |
747 | 1.51k | scale_encoded: &'a [u8], |
748 | 1.51k | block_number_bytes: usize, |
749 | 1.51k | ) -> Result<(Self, &'a [u8]), Error> { |
750 | 1.51k | let (scale_encoded, digest_logs_len) = |
751 | 1.51k | crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(scale_encoded) |
752 | 1.51k | .map_err(|_| Error::DigestItemLenDecodeError)?0 ; |
753 | | |
754 | 1.51k | let mut aura_seal_index = None; |
755 | 1.51k | let mut aura_predigest_index = None; |
756 | 1.51k | let mut babe_seal_index = None; |
757 | 1.51k | let mut babe_predigest_index = None; |
758 | 1.51k | let mut babe_next_epoch_data_index = None; |
759 | 1.51k | let mut babe_next_config_data_index = None; |
760 | 1.51k | let mut has_runtime_environment_updated = false; |
761 | | |
762 | | // Iterate through the log items to see if anything is wrong. |
763 | 1.51k | let mut next_digest = scale_encoded; |
764 | 1.51k | for item_num68 in 0..digest_logs_len { |
765 | 68 | let (item67 , next67 ) = decode_item(next_digest, block_number_bytes)?1 ; |
766 | 67 | next_digest = next; |
767 | | |
768 | 1 | match item { |
769 | 1 | DigestItemRef::AuraPreDigest(_) if aura_predigest_index.is_none() => { |
770 | 1 | aura_predigest_index = Some(item_num); |
771 | 1 | } |
772 | | DigestItemRef::AuraPreDigest(_) => { |
773 | 0 | return Err(Error::MultipleAuraPreRuntimeDigests); |
774 | | } |
775 | 0 | DigestItemRef::AuraConsensus(_) => {} |
776 | 16 | DigestItemRef::BabePreDigest(_) if babe_predigest_index.is_none() => { |
777 | 16 | babe_predigest_index = Some(item_num); |
778 | 16 | } |
779 | | DigestItemRef::BabePreDigest(_) => { |
780 | 0 | return Err(Error::MultipleBabePreRuntimeDigests); |
781 | | } |
782 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) |
783 | 8 | if babe_next_epoch_data_index.is_none() => |
784 | 8 | { |
785 | 8 | babe_next_epoch_data_index = Some(item_num); |
786 | 8 | } |
787 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) => { |
788 | 0 | return Err(Error::MultipleBabeEpochDescriptors); |
789 | | } |
790 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) |
791 | 1 | if babe_next_config_data_index.is_none() => |
792 | 1 | { |
793 | 1 | babe_next_config_data_index = Some(item_num); |
794 | 1 | } |
795 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) => { |
796 | 0 | return Err(Error::MultipleBabeConfigDescriptors); |
797 | | } |
798 | 11 | DigestItemRef::BabeConsensus(BabeConsensusLogRef::OnDisabled(_)) => {} |
799 | 13 | DigestItemRef::GrandpaConsensus(_) => {} |
800 | 0 | DigestItemRef::AuraSeal(_) if item_num == digest_logs_len - 1 => { |
801 | 0 | debug_assert!(aura_seal_index.is_none()); |
802 | 0 | debug_assert!(babe_seal_index.is_none()); |
803 | 0 | aura_seal_index = Some(item_num); |
804 | | } |
805 | 0 | DigestItemRef::AuraSeal(_) => return Err(Error::SealIsntLastItem), |
806 | 16 | DigestItemRef::BabeSeal(_) if item_num == digest_logs_len - 1 => { |
807 | 16 | debug_assert!(aura_seal_index.is_none()); |
808 | 16 | debug_assert!(babe_seal_index.is_none()); |
809 | 16 | babe_seal_index = Some(item_num); |
810 | | } |
811 | 0 | DigestItemRef::RuntimeEnvironmentUpdated if has_runtime_environment_updated => { |
812 | 0 | return Err(Error::MutipleRuntimeEnvironmentUpdated); |
813 | | } |
814 | 0 | DigestItemRef::RuntimeEnvironmentUpdated => { |
815 | 0 | has_runtime_environment_updated = true; |
816 | 0 | } |
817 | 0 | DigestItemRef::BabeSeal(_) => return Err(Error::SealIsntLastItem), |
818 | 0 | DigestItemRef::UnknownSeal { .. } if item_num == digest_logs_len - 1 => { |
819 | 0 | debug_assert!(aura_seal_index.is_none()); |
820 | 0 | debug_assert!(babe_seal_index.is_none()); |
821 | | } |
822 | 0 | DigestItemRef::UnknownSeal { .. } => return Err(Error::SealIsntLastItem), |
823 | | DigestItemRef::UnknownConsensus { .. } |
824 | | | DigestItemRef::UnknownPreRuntime { .. } |
825 | 1 | | DigestItemRef::Other { .. } => {} |
826 | | } |
827 | | } |
828 | | |
829 | 1.51k | if babe_next_config_data_index.is_some() && babe_next_epoch_data_index1 .is_none1 () { |
830 | 0 | return Err(Error::UnexpectedBabeConfigDescriptor); |
831 | 1.51k | } |
832 | | |
833 | 1.51k | let out = DigestRef { |
834 | 1.51k | inner: DigestRefInner::Undecoded { |
835 | 1.51k | digest_logs_len, |
836 | 1.51k | digest: scale_encoded, |
837 | 1.51k | block_number_bytes, |
838 | 1.51k | }, |
839 | 1.51k | aura_seal_index, |
840 | 1.51k | aura_predigest_index, |
841 | 1.51k | babe_seal_index, |
842 | 1.51k | babe_predigest_index, |
843 | 1.51k | babe_next_epoch_data_index, |
844 | 1.51k | babe_next_config_data_index, |
845 | 1.51k | has_runtime_environment_updated, |
846 | 1.51k | }; |
847 | | |
848 | 1.51k | Ok((out, next_digest)) |
849 | 1.51k | } _RNvMs2_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRef16from_scale_bytes Line | Count | Source | 746 | 1.05k | fn from_scale_bytes( | 747 | 1.05k | scale_encoded: &'a [u8], | 748 | 1.05k | block_number_bytes: usize, | 749 | 1.05k | ) -> Result<(Self, &'a [u8]), Error> { | 750 | 1.05k | let (scale_encoded, digest_logs_len) = | 751 | 1.05k | crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(scale_encoded) | 752 | 1.05k | .map_err(|_| Error::DigestItemLenDecodeError)?0 ; | 753 | | | 754 | 1.05k | let mut aura_seal_index = None; | 755 | 1.05k | let mut aura_predigest_index = None; | 756 | 1.05k | let mut babe_seal_index = None; | 757 | 1.05k | let mut babe_predigest_index = None; | 758 | 1.05k | let mut babe_next_epoch_data_index = None; | 759 | 1.05k | let mut babe_next_config_data_index = None; | 760 | 1.05k | let mut has_runtime_environment_updated = false; | 761 | | | 762 | | // Iterate through the log items to see if anything is wrong. | 763 | 1.05k | let mut next_digest = scale_encoded; | 764 | 1.05k | for item_num68 in 0..digest_logs_len { | 765 | 68 | let (item67 , next67 ) = decode_item(next_digest, block_number_bytes)?1 ; | 766 | 67 | next_digest = next; | 767 | | | 768 | 1 | match item { | 769 | 1 | DigestItemRef::AuraPreDigest(_) if aura_predigest_index.is_none() => { | 770 | 1 | aura_predigest_index = Some(item_num); | 771 | 1 | } | 772 | | DigestItemRef::AuraPreDigest(_) => { | 773 | 0 | return Err(Error::MultipleAuraPreRuntimeDigests); | 774 | | } | 775 | 0 | DigestItemRef::AuraConsensus(_) => {} | 776 | 16 | DigestItemRef::BabePreDigest(_) if babe_predigest_index.is_none() => { | 777 | 16 | babe_predigest_index = Some(item_num); | 778 | 16 | } | 779 | | DigestItemRef::BabePreDigest(_) => { | 780 | 0 | return Err(Error::MultipleBabePreRuntimeDigests); | 781 | | } | 782 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) | 783 | 8 | if babe_next_epoch_data_index.is_none() => | 784 | 8 | { | 785 | 8 | babe_next_epoch_data_index = Some(item_num); | 786 | 8 | } | 787 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) => { | 788 | 0 | return Err(Error::MultipleBabeEpochDescriptors); | 789 | | } | 790 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) | 791 | 1 | if babe_next_config_data_index.is_none() => | 792 | 1 | { | 793 | 1 | babe_next_config_data_index = Some(item_num); | 794 | 1 | } | 795 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) => { | 796 | 0 | return Err(Error::MultipleBabeConfigDescriptors); | 797 | | } | 798 | 11 | DigestItemRef::BabeConsensus(BabeConsensusLogRef::OnDisabled(_)) => {} | 799 | 13 | DigestItemRef::GrandpaConsensus(_) => {} | 800 | 0 | DigestItemRef::AuraSeal(_) if item_num == digest_logs_len - 1 => { | 801 | 0 | debug_assert!(aura_seal_index.is_none()); | 802 | 0 | debug_assert!(babe_seal_index.is_none()); | 803 | 0 | aura_seal_index = Some(item_num); | 804 | | } | 805 | 0 | DigestItemRef::AuraSeal(_) => return Err(Error::SealIsntLastItem), | 806 | 16 | DigestItemRef::BabeSeal(_) if item_num == digest_logs_len - 1 => { | 807 | 16 | debug_assert!(aura_seal_index.is_none()); | 808 | 16 | debug_assert!(babe_seal_index.is_none()); | 809 | 16 | babe_seal_index = Some(item_num); | 810 | | } | 811 | 0 | DigestItemRef::RuntimeEnvironmentUpdated if has_runtime_environment_updated => { | 812 | 0 | return Err(Error::MutipleRuntimeEnvironmentUpdated); | 813 | | } | 814 | 0 | DigestItemRef::RuntimeEnvironmentUpdated => { | 815 | 0 | has_runtime_environment_updated = true; | 816 | 0 | } | 817 | 0 | DigestItemRef::BabeSeal(_) => return Err(Error::SealIsntLastItem), | 818 | 0 | DigestItemRef::UnknownSeal { .. } if item_num == digest_logs_len - 1 => { | 819 | 0 | debug_assert!(aura_seal_index.is_none()); | 820 | 0 | debug_assert!(babe_seal_index.is_none()); | 821 | | } | 822 | 0 | DigestItemRef::UnknownSeal { .. } => return Err(Error::SealIsntLastItem), | 823 | | DigestItemRef::UnknownConsensus { .. } | 824 | | | DigestItemRef::UnknownPreRuntime { .. } | 825 | 1 | | DigestItemRef::Other { .. } => {} | 826 | | } | 827 | | } | 828 | | | 829 | 1.04k | if babe_next_config_data_index.is_some() && babe_next_epoch_data_index1 .is_none1 () { | 830 | 0 | return Err(Error::UnexpectedBabeConfigDescriptor); | 831 | 1.04k | } | 832 | | | 833 | 1.04k | let out = DigestRef { | 834 | 1.04k | inner: DigestRefInner::Undecoded { | 835 | 1.04k | digest_logs_len, | 836 | 1.04k | digest: scale_encoded, | 837 | 1.04k | block_number_bytes, | 838 | 1.04k | }, | 839 | 1.04k | aura_seal_index, | 840 | 1.04k | aura_predigest_index, | 841 | 1.04k | babe_seal_index, | 842 | 1.04k | babe_predigest_index, | 843 | 1.04k | babe_next_epoch_data_index, | 844 | 1.04k | babe_next_config_data_index, | 845 | 1.04k | has_runtime_environment_updated, | 846 | 1.04k | }; | 847 | | | 848 | 1.04k | Ok((out, next_digest)) | 849 | 1.05k | } |
_RNvMs2_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRef16from_scale_bytes Line | Count | Source | 746 | 464 | fn from_scale_bytes( | 747 | 464 | scale_encoded: &'a [u8], | 748 | 464 | block_number_bytes: usize, | 749 | 464 | ) -> Result<(Self, &'a [u8]), Error> { | 750 | 464 | let (scale_encoded, digest_logs_len) = | 751 | 464 | crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(scale_encoded) | 752 | 464 | .map_err(|_| Error::DigestItemLenDecodeError)?0 ; | 753 | | | 754 | 464 | let mut aura_seal_index = None; | 755 | 464 | let mut aura_predigest_index = None; | 756 | 464 | let mut babe_seal_index = None; | 757 | 464 | let mut babe_predigest_index = None; | 758 | 464 | let mut babe_next_epoch_data_index = None; | 759 | 464 | let mut babe_next_config_data_index = None; | 760 | 464 | let mut has_runtime_environment_updated = false; | 761 | | | 762 | | // Iterate through the log items to see if anything is wrong. | 763 | 464 | let mut next_digest = scale_encoded; | 764 | 464 | for item_num0 in 0..digest_logs_len { | 765 | 0 | let (item, next) = decode_item(next_digest, block_number_bytes)?; | 766 | 0 | next_digest = next; | 767 | | | 768 | 0 | match item { | 769 | 0 | DigestItemRef::AuraPreDigest(_) if aura_predigest_index.is_none() => { | 770 | 0 | aura_predigest_index = Some(item_num); | 771 | 0 | } | 772 | | DigestItemRef::AuraPreDigest(_) => { | 773 | 0 | return Err(Error::MultipleAuraPreRuntimeDigests); | 774 | | } | 775 | 0 | DigestItemRef::AuraConsensus(_) => {} | 776 | 0 | DigestItemRef::BabePreDigest(_) if babe_predigest_index.is_none() => { | 777 | 0 | babe_predigest_index = Some(item_num); | 778 | 0 | } | 779 | | DigestItemRef::BabePreDigest(_) => { | 780 | 0 | return Err(Error::MultipleBabePreRuntimeDigests); | 781 | | } | 782 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) | 783 | 0 | if babe_next_epoch_data_index.is_none() => | 784 | 0 | { | 785 | 0 | babe_next_epoch_data_index = Some(item_num); | 786 | 0 | } | 787 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextEpochData(_)) => { | 788 | 0 | return Err(Error::MultipleBabeEpochDescriptors); | 789 | | } | 790 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) | 791 | 0 | if babe_next_config_data_index.is_none() => | 792 | 0 | { | 793 | 0 | babe_next_config_data_index = Some(item_num); | 794 | 0 | } | 795 | | DigestItemRef::BabeConsensus(BabeConsensusLogRef::NextConfigData(_)) => { | 796 | 0 | return Err(Error::MultipleBabeConfigDescriptors); | 797 | | } | 798 | 0 | DigestItemRef::BabeConsensus(BabeConsensusLogRef::OnDisabled(_)) => {} | 799 | 0 | DigestItemRef::GrandpaConsensus(_) => {} | 800 | 0 | DigestItemRef::AuraSeal(_) if item_num == digest_logs_len - 1 => { | 801 | 0 | debug_assert!(aura_seal_index.is_none()); | 802 | 0 | debug_assert!(babe_seal_index.is_none()); | 803 | 0 | aura_seal_index = Some(item_num); | 804 | | } | 805 | 0 | DigestItemRef::AuraSeal(_) => return Err(Error::SealIsntLastItem), | 806 | 0 | DigestItemRef::BabeSeal(_) if item_num == digest_logs_len - 1 => { | 807 | 0 | debug_assert!(aura_seal_index.is_none()); | 808 | 0 | debug_assert!(babe_seal_index.is_none()); | 809 | 0 | babe_seal_index = Some(item_num); | 810 | | } | 811 | 0 | DigestItemRef::RuntimeEnvironmentUpdated if has_runtime_environment_updated => { | 812 | 0 | return Err(Error::MutipleRuntimeEnvironmentUpdated); | 813 | | } | 814 | 0 | DigestItemRef::RuntimeEnvironmentUpdated => { | 815 | 0 | has_runtime_environment_updated = true; | 816 | 0 | } | 817 | 0 | DigestItemRef::BabeSeal(_) => return Err(Error::SealIsntLastItem), | 818 | 0 | DigestItemRef::UnknownSeal { .. } if item_num == digest_logs_len - 1 => { | 819 | 0 | debug_assert!(aura_seal_index.is_none()); | 820 | 0 | debug_assert!(babe_seal_index.is_none()); | 821 | | } | 822 | 0 | DigestItemRef::UnknownSeal { .. } => return Err(Error::SealIsntLastItem), | 823 | | DigestItemRef::UnknownConsensus { .. } | 824 | | | DigestItemRef::UnknownPreRuntime { .. } | 825 | 0 | | DigestItemRef::Other { .. } => {} | 826 | | } | 827 | | } | 828 | | | 829 | 464 | if babe_next_config_data_index.is_some() && babe_next_epoch_data_index0 .is_none0 () { | 830 | 0 | return Err(Error::UnexpectedBabeConfigDescriptor); | 831 | 464 | } | 832 | | | 833 | 464 | let out = DigestRef { | 834 | 464 | inner: DigestRefInner::Undecoded { | 835 | 464 | digest_logs_len, | 836 | 464 | digest: scale_encoded, | 837 | 464 | block_number_bytes, | 838 | 464 | }, | 839 | 464 | aura_seal_index, | 840 | 464 | aura_predigest_index, | 841 | 464 | babe_seal_index, | 842 | 464 | babe_predigest_index, | 843 | 464 | babe_next_epoch_data_index, | 844 | 464 | babe_next_config_data_index, | 845 | 464 | has_runtime_environment_updated, | 846 | 464 | }; | 847 | | | 848 | 464 | Ok((out, next_digest)) | 849 | 464 | } |
|
850 | | } |
851 | | |
852 | | impl<'a> fmt::Debug for DigestRef<'a> { |
853 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
854 | 0 | f.debug_list().entries(self.logs()).finish() |
855 | 0 | } Unexecuted instantiation: _RNvXs3_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRefNtNtCs1p5UDGgVI4d_4core3fmt5Debug3fmt Unexecuted instantiation: _RNvXs3_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRefNtNtCs1p5UDGgVI4d_4core3fmt5Debug3fmt |
856 | | } |
857 | | |
858 | | impl<'a> From<&'a Digest> for DigestRef<'a> { |
859 | 365 | fn from(digest: &'a Digest) -> DigestRef<'a> { |
860 | 365 | DigestRef { |
861 | 365 | inner: DigestRefInner::Parsed(&digest.list), |
862 | 365 | aura_seal_index: digest.aura_seal_index, |
863 | 365 | aura_predigest_index: digest.aura_predigest_index, |
864 | 365 | babe_seal_index: digest.babe_seal_index, |
865 | 365 | babe_predigest_index: digest.babe_predigest_index, |
866 | 365 | babe_next_epoch_data_index: digest.babe_next_epoch_data_index, |
867 | 365 | babe_next_config_data_index: digest.babe_next_config_data_index, |
868 | 365 | has_runtime_environment_updated: digest.has_runtime_environment_updated, |
869 | 365 | } |
870 | 365 | } _RNvXs4_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_9DigestRefINtNtCs1p5UDGgVI4d_4core7convert4FromRNtB5_6DigestE4from Line | Count | Source | 859 | 8 | fn from(digest: &'a Digest) -> DigestRef<'a> { | 860 | 8 | DigestRef { | 861 | 8 | inner: DigestRefInner::Parsed(&digest.list), | 862 | 8 | aura_seal_index: digest.aura_seal_index, | 863 | 8 | aura_predigest_index: digest.aura_predigest_index, | 864 | 8 | babe_seal_index: digest.babe_seal_index, | 865 | 8 | babe_predigest_index: digest.babe_predigest_index, | 866 | 8 | babe_next_epoch_data_index: digest.babe_next_epoch_data_index, | 867 | 8 | babe_next_config_data_index: digest.babe_next_config_data_index, | 868 | 8 | has_runtime_environment_updated: digest.has_runtime_environment_updated, | 869 | 8 | } | 870 | 8 | } |
_RNvXs4_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_9DigestRefINtNtCs1p5UDGgVI4d_4core7convert4FromRNtB5_6DigestE4from Line | Count | Source | 859 | 357 | fn from(digest: &'a Digest) -> DigestRef<'a> { | 860 | 357 | DigestRef { | 861 | 357 | inner: DigestRefInner::Parsed(&digest.list), | 862 | 357 | aura_seal_index: digest.aura_seal_index, | 863 | 357 | aura_predigest_index: digest.aura_predigest_index, | 864 | 357 | babe_seal_index: digest.babe_seal_index, | 865 | 357 | babe_predigest_index: digest.babe_predigest_index, | 866 | 357 | babe_next_epoch_data_index: digest.babe_next_epoch_data_index, | 867 | 357 | babe_next_config_data_index: digest.babe_next_config_data_index, | 868 | 357 | has_runtime_environment_updated: digest.has_runtime_environment_updated, | 869 | 357 | } | 870 | 357 | } |
|
871 | | } |
872 | | |
873 | | /// Seal popped using [`DigestRef::pop_seal`]. |
874 | | pub enum Seal<'a> { |
875 | | Aura(&'a [u8; 64]), |
876 | | Babe(&'a [u8; 64]), |
877 | | } |
878 | | |
879 | | /// Generic header digest. |
880 | | #[derive(Clone)] |
881 | | pub struct Digest { |
882 | | /// Actual list of items. |
883 | | list: Vec<DigestItem>, |
884 | | /// Index of the [`DigestItemRef::AuraSeal`] item, if any. |
885 | | aura_seal_index: Option<usize>, |
886 | | /// Index of the [`DigestItemRef::AuraPreDigest`] item, if any. |
887 | | aura_predigest_index: Option<usize>, |
888 | | /// Index of the [`DigestItemRef::BabeSeal`] item, if any. |
889 | | babe_seal_index: Option<usize>, |
890 | | /// Index of the [`DigestItemRef::BabePreDigest`] item, if any. |
891 | | babe_predigest_index: Option<usize>, |
892 | | /// Index of the [`DigestItemRef::BabeConsensus`] item containing a |
893 | | /// [`BabeConsensusLogRef::NextEpochData`], if any. |
894 | | babe_next_epoch_data_index: Option<usize>, |
895 | | /// Index of the [`DigestItemRef::BabeConsensus`] item containing a |
896 | | /// [`BabeConsensusLogRef::NextConfigData`], if any. |
897 | | babe_next_config_data_index: Option<usize>, |
898 | | /// `true` if there is a [`DigestItemRef::RuntimeEnvironmentUpdated`] item. |
899 | | has_runtime_environment_updated: bool, |
900 | | } |
901 | | |
902 | | impl Digest { |
903 | | /// Returns an iterator to the log items in this digest. |
904 | 0 | pub fn logs(&self) -> LogsIter { |
905 | 0 | DigestRef::from(self).logs() |
906 | 0 | } Unexecuted instantiation: _RNvMs5_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Digest4logs Unexecuted instantiation: _RNvMs5_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Digest4logs |
907 | | |
908 | | /// Returns the Aura seal digest item, if any. |
909 | 0 | pub fn aura_seal(&self) -> Option<&[u8; 64]> { |
910 | 0 | DigestRef::from(self).aura_seal() |
911 | 0 | } Unexecuted instantiation: _RNvMs5_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Digest9aura_seal Unexecuted instantiation: _RNvMs5_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Digest9aura_seal |
912 | | |
913 | | /// Returns the Babe seal digest item, if any. |
914 | 0 | pub fn babe_seal(&self) -> Option<&[u8; 64]> { |
915 | 0 | DigestRef::from(self).babe_seal() |
916 | 0 | } Unexecuted instantiation: _RNvMs5_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Digest9babe_seal Unexecuted instantiation: _RNvMs5_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Digest9babe_seal |
917 | | |
918 | | /// Returns the Babe pre-runtime digest item, if any. |
919 | 0 | pub fn babe_pre_runtime(&self) -> Option<BabePreDigestRef> { |
920 | 0 | DigestRef::from(self).babe_pre_runtime() |
921 | 0 | } Unexecuted instantiation: _RNvMs5_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Digest16babe_pre_runtime Unexecuted instantiation: _RNvMs5_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Digest16babe_pre_runtime |
922 | | |
923 | | /// Returns the Babe epoch information stored in the header, if any. |
924 | | /// |
925 | | /// It is guaranteed that a configuration change is present only if an epoch change is |
926 | | /// present too. |
927 | 0 | pub fn babe_epoch_information(&self) -> Option<(BabeNextEpochRef, Option<BabeNextConfig>)> { |
928 | 0 | DigestRef::from(self).babe_epoch_information() |
929 | 0 | } Unexecuted instantiation: _RNvMs5_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Digest22babe_epoch_information Unexecuted instantiation: _RNvMs5_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Digest22babe_epoch_information |
930 | | |
931 | | /// Returns `true` if there is a [`DigestItemRef::RuntimeEnvironmentUpdated`] item. |
932 | 0 | pub fn has_runtime_environment_updated(&self) -> bool { |
933 | 0 | self.has_runtime_environment_updated |
934 | 0 | } Unexecuted instantiation: _RNvMs5_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6Digest31has_runtime_environment_updated Unexecuted instantiation: _RNvMs5_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6Digest31has_runtime_environment_updated |
935 | | } |
936 | | |
937 | | impl fmt::Debug for Digest { |
938 | 0 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
939 | 0 | f.debug_list() |
940 | 0 | .entries(self.list.iter().map(DigestItemRef::from)) |
941 | 0 | .finish() |
942 | 0 | } Unexecuted instantiation: _RNvXs6_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6DigestNtNtCs1p5UDGgVI4d_4core3fmt5Debug3fmt Unexecuted instantiation: _RNvXs6_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6DigestNtNtCs1p5UDGgVI4d_4core3fmt5Debug3fmt |
943 | | } |
944 | | |
945 | | impl<'a> From<DigestRef<'a>> for Digest { |
946 | 47 | fn from(digest: DigestRef<'a>) -> Digest { |
947 | 47 | Digest { |
948 | 47 | list: digest.logs().map(Into::into).collect(), |
949 | 47 | aura_seal_index: digest.aura_seal_index, |
950 | 47 | aura_predigest_index: digest.aura_predigest_index, |
951 | 47 | babe_seal_index: digest.babe_seal_index, |
952 | 47 | babe_predigest_index: digest.babe_predigest_index, |
953 | 47 | babe_next_epoch_data_index: digest.babe_next_epoch_data_index, |
954 | 47 | babe_next_config_data_index: digest.babe_next_config_data_index, |
955 | 47 | has_runtime_environment_updated: digest.has_runtime_environment_updated, |
956 | 47 | } |
957 | 47 | } _RNvXs7_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_6DigestINtNtCs1p5UDGgVI4d_4core7convert4FromNtB5_9DigestRefE4from Line | Count | Source | 946 | 5 | fn from(digest: DigestRef<'a>) -> Digest { | 947 | 5 | Digest { | 948 | 5 | list: digest.logs().map(Into::into).collect(), | 949 | 5 | aura_seal_index: digest.aura_seal_index, | 950 | 5 | aura_predigest_index: digest.aura_predigest_index, | 951 | 5 | babe_seal_index: digest.babe_seal_index, | 952 | 5 | babe_predigest_index: digest.babe_predigest_index, | 953 | 5 | babe_next_epoch_data_index: digest.babe_next_epoch_data_index, | 954 | 5 | babe_next_config_data_index: digest.babe_next_config_data_index, | 955 | 5 | has_runtime_environment_updated: digest.has_runtime_environment_updated, | 956 | 5 | } | 957 | 5 | } |
_RNvXs7_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_6DigestINtNtCs1p5UDGgVI4d_4core7convert4FromNtB5_9DigestRefE4from Line | Count | Source | 946 | 42 | fn from(digest: DigestRef<'a>) -> Digest { | 947 | 42 | Digest { | 948 | 42 | list: digest.logs().map(Into::into).collect(), | 949 | 42 | aura_seal_index: digest.aura_seal_index, | 950 | 42 | aura_predigest_index: digest.aura_predigest_index, | 951 | 42 | babe_seal_index: digest.babe_seal_index, | 952 | 42 | babe_predigest_index: digest.babe_predigest_index, | 953 | 42 | babe_next_epoch_data_index: digest.babe_next_epoch_data_index, | 954 | 42 | babe_next_config_data_index: digest.babe_next_config_data_index, | 955 | 42 | has_runtime_environment_updated: digest.has_runtime_environment_updated, | 956 | 42 | } | 957 | 42 | } |
|
958 | | } |
959 | | |
960 | | /// Iterator towards the digest log items. |
961 | | #[derive(Clone)] |
962 | | pub struct LogsIter<'a> { |
963 | | inner: LogsIterInner<'a>, |
964 | | } |
965 | | |
966 | | #[derive(Clone)] |
967 | | enum LogsIterInner<'a> { |
968 | | Decoded(slice::Iter<'a, DigestItem>), |
969 | | Undecoded { |
970 | | /// Encoded digest. |
971 | | pointer: &'a [u8], |
972 | | /// Number of log items remaining. |
973 | | remaining_len: usize, |
974 | | /// Number of bytes used to encode block numbers in the header. |
975 | | block_number_bytes: usize, |
976 | | }, |
977 | | } |
978 | | |
979 | | impl<'a> Iterator for LogsIter<'a> { |
980 | | type Item = DigestItemRef<'a>; |
981 | | |
982 | 1.40k | fn next(&mut self) -> Option<Self::Item> { |
983 | 1.40k | match &mut self.inner { |
984 | 1.22k | LogsIterInner::Decoded(iter) => iter.next().map(Into::into), |
985 | | LogsIterInner::Undecoded { |
986 | 175 | pointer, |
987 | 175 | remaining_len, |
988 | 175 | block_number_bytes, |
989 | | } => { |
990 | 175 | if *remaining_len == 0 { |
991 | 68 | return None; |
992 | 107 | } |
993 | | |
994 | | // Validity is guaranteed when the `DigestRef` is constructed. |
995 | 107 | let (item, new_pointer) = decode_item(pointer, *block_number_bytes).unwrap(); |
996 | 107 | *pointer = new_pointer; |
997 | 107 | *remaining_len -= 1; |
998 | | |
999 | 107 | Some(item) |
1000 | | } |
1001 | | } |
1002 | 1.40k | } _RNvXs8_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_8LogsIterNtNtNtNtCs1p5UDGgVI4d_4core4iter6traits8iterator8Iterator4next Line | Count | Source | 982 | 1.17k | fn next(&mut self) -> Option<Self::Item> { | 983 | 1.17k | match &mut self.inner { | 984 | 1.04k | LogsIterInner::Decoded(iter) => iter.next().map(Into::into), | 985 | | LogsIterInner::Undecoded { | 986 | 131 | pointer, | 987 | 131 | remaining_len, | 988 | 131 | block_number_bytes, | 989 | | } => { | 990 | 131 | if *remaining_len == 0 { | 991 | 24 | return None; | 992 | 107 | } | 993 | | | 994 | | // Validity is guaranteed when the `DigestRef` is constructed. | 995 | 107 | let (item, new_pointer) = decode_item(pointer, *block_number_bytes).unwrap(); | 996 | 107 | *pointer = new_pointer; | 997 | 107 | *remaining_len -= 1; | 998 | | | 999 | 107 | Some(item) | 1000 | | } | 1001 | | } | 1002 | 1.17k | } |
_RNvXs8_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_8LogsIterNtNtNtNtCs1p5UDGgVI4d_4core4iter6traits8iterator8Iterator4next Line | Count | Source | 982 | 233 | fn next(&mut self) -> Option<Self::Item> { | 983 | 233 | match &mut self.inner { | 984 | 189 | LogsIterInner::Decoded(iter) => iter.next().map(Into::into), | 985 | | LogsIterInner::Undecoded { | 986 | 44 | pointer, | 987 | 44 | remaining_len, | 988 | 44 | block_number_bytes, | 989 | | } => { | 990 | 44 | if *remaining_len == 0 { | 991 | 44 | return None; | 992 | 0 | } | 993 | | | 994 | | // Validity is guaranteed when the `DigestRef` is constructed. | 995 | 0 | let (item, new_pointer) = decode_item(pointer, *block_number_bytes).unwrap(); | 996 | 0 | *pointer = new_pointer; | 997 | 0 | *remaining_len -= 1; | 998 | | | 999 | 0 | Some(item) | 1000 | | } | 1001 | | } | 1002 | 233 | } |
|
1003 | | |
1004 | 1.19k | fn size_hint(&self) -> (usize, Option<usize>) { |
1005 | 1.19k | match &self.inner { |
1006 | 1.18k | LogsIterInner::Decoded(iter) => iter.size_hint(), |
1007 | 11 | LogsIterInner::Undecoded { remaining_len, .. } => { |
1008 | 11 | (*remaining_len, Some(*remaining_len)) |
1009 | | } |
1010 | | } |
1011 | 1.19k | } _RNvXs8_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_8LogsIterNtNtNtNtCs1p5UDGgVI4d_4core4iter6traits8iterator8Iterator9size_hint Line | Count | Source | 1004 | 1.04k | fn size_hint(&self) -> (usize, Option<usize>) { | 1005 | 1.04k | match &self.inner { | 1006 | 1.03k | LogsIterInner::Decoded(iter) => iter.size_hint(), | 1007 | 11 | LogsIterInner::Undecoded { remaining_len, .. } => { | 1008 | 11 | (*remaining_len, Some(*remaining_len)) | 1009 | | } | 1010 | | } | 1011 | 1.04k | } |
_RNvXs8_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_8LogsIterNtNtNtNtCs1p5UDGgVI4d_4core4iter6traits8iterator8Iterator9size_hint Line | Count | Source | 1004 | 147 | fn size_hint(&self) -> (usize, Option<usize>) { | 1005 | 147 | match &self.inner { | 1006 | 147 | LogsIterInner::Decoded(iter) => iter.size_hint(), | 1007 | 0 | LogsIterInner::Undecoded { remaining_len, .. } => { | 1008 | 0 | (*remaining_len, Some(*remaining_len)) | 1009 | | } | 1010 | | } | 1011 | 147 | } |
|
1012 | | } |
1013 | | |
1014 | | impl<'a> ExactSizeIterator for LogsIter<'a> {} |
1015 | | |
1016 | | // TODO: document |
1017 | | #[derive(Debug, PartialEq, Eq, Clone)] |
1018 | | pub enum DigestItemRef<'a> { |
1019 | | AuraPreDigest(AuraPreDigest), |
1020 | | /// Block signature made using the AURA consensus engine. |
1021 | | AuraSeal(&'a [u8; 64]), |
1022 | | AuraConsensus(AuraConsensusLogRef<'a>), |
1023 | | |
1024 | | BabePreDigest(BabePreDigestRef<'a>), |
1025 | | BabeConsensus(BabeConsensusLogRef<'a>), |
1026 | | /// Block signature made using the BABE consensus engine. |
1027 | | BabeSeal(&'a [u8; 64]), |
1028 | | |
1029 | | GrandpaConsensus(GrandpaConsensusLogRef<'a>), |
1030 | | |
1031 | | /// Consensus item with an engine that hasn't been recognized. |
1032 | | UnknownConsensus { |
1033 | | /// Name of the consensus engine. |
1034 | | engine: [u8; 4], |
1035 | | /// Smoldot doesn't interpret the content of the log item. |
1036 | | opaque: &'a [u8], |
1037 | | }, |
1038 | | /// Pre-runtime item with a consensus engine that hasn't been recognized. |
1039 | | UnknownPreRuntime { |
1040 | | /// Name of the consensus engine. |
1041 | | engine: [u8; 4], |
1042 | | /// Smoldot doesn't interpret the content of the log item. |
1043 | | opaque: &'a [u8], |
1044 | | }, |
1045 | | /// Seal using a consensus engine that hasn't been recognized. |
1046 | | UnknownSeal { |
1047 | | /// Name of the consensus engine. |
1048 | | engine: [u8; 4], |
1049 | | /// Smoldot doesn't interpret the content of the log item. |
1050 | | opaque: &'a [u8], |
1051 | | }, |
1052 | | |
1053 | | /// Some other thing. Always ignored. |
1054 | | /// |
1055 | | /// Contrary to [`DigestItemRef::UnknownConsensus`], [`DigestItemRef::UnknownPreRuntime`], or |
1056 | | /// [`DigestItemRef::UnknownSeal`], this item is intentionally meant to always be ignored. |
1057 | | Other(&'a [u8]), |
1058 | | |
1059 | | /// Runtime of the chain has been updated in this block. This can include the runtime code or |
1060 | | /// the heap pages. |
1061 | | RuntimeEnvironmentUpdated, |
1062 | | } |
1063 | | |
1064 | | impl<'a> DigestItemRef<'a> { |
1065 | | /// True if the item is relevant to the Aura consensus engine. |
1066 | 10 | pub fn is_aura(&self) -> bool { |
1067 | 10 | matches!( |
1068 | 10 | self, |
1069 | | DigestItemRef::AuraPreDigest(_) |
1070 | | | DigestItemRef::AuraSeal(_) |
1071 | | | DigestItemRef::AuraConsensus(_) |
1072 | | ) |
1073 | 10 | } _RNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_13DigestItemRef7is_aura Line | Count | Source | 1066 | 10 | pub fn is_aura(&self) -> bool { | 1067 | 10 | matches!( | 1068 | 10 | self, | 1069 | | DigestItemRef::AuraPreDigest(_) | 1070 | | | DigestItemRef::AuraSeal(_) | 1071 | | | DigestItemRef::AuraConsensus(_) | 1072 | | ) | 1073 | 10 | } |
Unexecuted instantiation: _RNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_13DigestItemRef7is_aura |
1074 | | |
1075 | | /// True if the item is relevant to the Babe consensus engine. |
1076 | 0 | pub fn is_babe(&self) -> bool { |
1077 | 0 | matches!( |
1078 | 0 | self, |
1079 | | DigestItemRef::BabePreDigest(_) |
1080 | | | DigestItemRef::BabeConsensus(_) |
1081 | | | DigestItemRef::BabeSeal(_) |
1082 | | ) |
1083 | 0 | } Unexecuted instantiation: _RNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_13DigestItemRef7is_babe Unexecuted instantiation: _RNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_13DigestItemRef7is_babe |
1084 | | |
1085 | | /// True if the item is relevant to the Grandpa finality engine. |
1086 | 0 | pub fn is_grandpa(&self) -> bool { |
1087 | 0 | matches!(self, DigestItemRef::GrandpaConsensus(_)) |
1088 | 0 | } Unexecuted instantiation: _RNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_13DigestItemRef10is_grandpa Unexecuted instantiation: _RNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_13DigestItemRef10is_grandpa |
1089 | | |
1090 | | /// Decodes a SCALE-encoded digest item. |
1091 | 0 | pub fn from_scale_encoded(bytes: &'a [u8], block_number_bytes: usize) -> Result<Self, Error> { |
1092 | 0 | let (item, remain) = decode_item(bytes, block_number_bytes)?; |
1093 | 0 | if !remain.is_empty() { |
1094 | 0 | return Err(Error::TooLong); |
1095 | 0 | } |
1096 | 0 | Ok(item) |
1097 | 0 | } Unexecuted instantiation: _RNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_13DigestItemRef18from_scale_encoded Unexecuted instantiation: _RNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_13DigestItemRef18from_scale_encoded |
1098 | | |
1099 | | /// Returns an iterator to list of buffers which, when concatenated, produces the SCALE |
1100 | | /// encoding of that digest item. |
1101 | 41 | pub fn scale_encoding( |
1102 | 41 | &self, |
1103 | 41 | block_number_bytes: usize, |
1104 | 41 | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { |
1105 | 41 | let (item1, item2) = match *self { |
1106 | 2 | DigestItemRef::AuraPreDigest(ref aura_pre_digest) => { |
1107 | 2 | let encoded = aura_pre_digest |
1108 | 2 | .scale_encoding() |
1109 | 2 | .fold(Vec::new(), |mut a, b| { |
1110 | 2 | a.extend_from_slice(b.as_ref()); |
1111 | 2 | a |
1112 | 2 | }); _RNCNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_13DigestItemRef14scale_encoding0B9_ Line | Count | Source | 1109 | 2 | .fold(Vec::new(), |mut a, b| { | 1110 | 2 | a.extend_from_slice(b.as_ref()); | 1111 | 2 | a | 1112 | 2 | }); |
Unexecuted instantiation: _RNCNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_13DigestItemRef14scale_encoding0B9_ |
1113 | | |
1114 | 2 | let mut ret = Vec::with_capacity(12); |
1115 | 2 | ret.push(6); |
1116 | 2 | ret.extend_from_slice(b"aura"); |
1117 | 2 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); |
1118 | 2 | (ret, either::Left(encoded)) |
1119 | | } |
1120 | 0 | DigestItemRef::AuraSeal(seal) => { |
1121 | 0 | let mut ret = Vec::with_capacity(12); |
1122 | 0 | ret.push(5); |
1123 | 0 | ret.extend_from_slice(b"aura"); |
1124 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(64).as_ref()); |
1125 | 0 | (ret, either::Right(&seal[..])) |
1126 | | } |
1127 | 0 | DigestItemRef::AuraConsensus(ref aura_consensus) => { |
1128 | 0 | let encoded = aura_consensus |
1129 | 0 | .scale_encoding() |
1130 | 0 | .fold(Vec::new(), |mut a, b| { |
1131 | 0 | a.extend_from_slice(b.as_ref()); |
1132 | 0 | a |
1133 | 0 | }); Unexecuted instantiation: _RNCNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_13DigestItemRef14scale_encodings_0B9_ Unexecuted instantiation: _RNCNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_13DigestItemRef14scale_encodings_0B9_ |
1134 | | |
1135 | 0 | let mut ret = Vec::with_capacity(12); |
1136 | 0 | ret.push(4); |
1137 | 0 | ret.extend_from_slice(b"aura"); |
1138 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); |
1139 | 0 | (ret, either::Left(encoded)) |
1140 | | } |
1141 | 7 | DigestItemRef::BabePreDigest(ref babe_pre_digest) => { |
1142 | 7 | let encoded = babe_pre_digest |
1143 | 7 | .scale_encoding() |
1144 | 27 | .fold7 (Vec::new7 (), |mut a, b| { |
1145 | 27 | a.extend_from_slice(b.as_ref()); |
1146 | 27 | a |
1147 | 27 | }); _RNCNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_13DigestItemRef14scale_encodings0_0B9_ Line | Count | Source | 1144 | 27 | .fold(Vec::new(), |mut a, b| { | 1145 | 27 | a.extend_from_slice(b.as_ref()); | 1146 | 27 | a | 1147 | 27 | }); |
Unexecuted instantiation: _RNCNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_13DigestItemRef14scale_encodings0_0B9_ |
1148 | | |
1149 | 7 | let mut ret = Vec::with_capacity(12); |
1150 | 7 | ret.push(6); |
1151 | 7 | ret.extend_from_slice(b"BABE"); |
1152 | 7 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); |
1153 | 7 | (ret, either::Left(encoded)) |
1154 | | } |
1155 | 17 | DigestItemRef::BabeConsensus(ref babe_consensus) => { |
1156 | 17 | let encoded = babe_consensus |
1157 | 17 | .scale_encoding() |
1158 | 1.89k | .fold17 (Vec::new17 (), |mut a, b| { |
1159 | 1.89k | a.extend_from_slice(b.as_ref()); |
1160 | 1.89k | a |
1161 | 1.89k | }); _RNCNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_13DigestItemRef14scale_encodings1_0B9_ Line | Count | Source | 1158 | 1.89k | .fold(Vec::new(), |mut a, b| { | 1159 | 1.89k | a.extend_from_slice(b.as_ref()); | 1160 | 1.89k | a | 1161 | 1.89k | }); |
Unexecuted instantiation: _RNCNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_13DigestItemRef14scale_encodings1_0B9_ |
1162 | | |
1163 | 17 | let mut ret = Vec::with_capacity(12); |
1164 | 17 | ret.push(4); |
1165 | 17 | ret.extend_from_slice(b"BABE"); |
1166 | 17 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); |
1167 | 17 | (ret, either::Left(encoded)) |
1168 | | } |
1169 | 12 | DigestItemRef::GrandpaConsensus(ref gp_consensus) => { |
1170 | 12 | let encoded = |
1171 | 12 | gp_consensus |
1172 | 12 | .scale_encoding(block_number_bytes) |
1173 | 1.82k | .fold12 (Vec::new12 (), |mut a, b| { |
1174 | 1.82k | a.extend_from_slice(b.as_ref()); |
1175 | 1.82k | a |
1176 | 1.82k | }); _RNCNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB7_13DigestItemRef14scale_encodings2_0B9_ Line | Count | Source | 1173 | 1.82k | .fold(Vec::new(), |mut a, b| { | 1174 | 1.82k | a.extend_from_slice(b.as_ref()); | 1175 | 1.82k | a | 1176 | 1.82k | }); |
Unexecuted instantiation: _RNCNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB7_13DigestItemRef14scale_encodings2_0B9_ |
1177 | | |
1178 | 12 | let mut ret = Vec::with_capacity(12); |
1179 | 12 | ret.push(4); |
1180 | 12 | ret.extend_from_slice(b"FRNK"); |
1181 | 12 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); |
1182 | 12 | (ret, either::Left(encoded)) |
1183 | | } |
1184 | 3 | DigestItemRef::BabeSeal(seal) => { |
1185 | 3 | let mut ret = Vec::with_capacity(12); |
1186 | 3 | ret.push(5); |
1187 | 3 | ret.extend_from_slice(b"BABE"); |
1188 | 3 | ret.extend_from_slice(util::encode_scale_compact_usize(64).as_ref()); |
1189 | 3 | (ret, either::Right(&seal[..])) |
1190 | | } |
1191 | 0 | DigestItemRef::UnknownConsensus { engine, opaque } => { |
1192 | 0 | let mut ret = Vec::with_capacity(12); |
1193 | 0 | ret.push(4); |
1194 | 0 | ret.extend_from_slice(&engine); |
1195 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref()); |
1196 | 0 | (ret, either::Right(opaque)) |
1197 | | } |
1198 | 0 | DigestItemRef::UnknownSeal { engine, opaque } => { |
1199 | 0 | let mut ret = Vec::with_capacity(12); |
1200 | 0 | ret.push(5); |
1201 | 0 | ret.extend_from_slice(&engine); |
1202 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref()); |
1203 | 0 | (ret, either::Right(opaque)) |
1204 | | } |
1205 | 0 | DigestItemRef::UnknownPreRuntime { engine, opaque } => { |
1206 | 0 | let mut ret = Vec::with_capacity(12); |
1207 | 0 | ret.push(6); |
1208 | 0 | ret.extend_from_slice(&engine); |
1209 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref()); |
1210 | 0 | (ret, either::Right(opaque)) |
1211 | | } |
1212 | 0 | DigestItemRef::Other(raw) => { |
1213 | 0 | let mut ret = Vec::with_capacity(12); |
1214 | 0 | ret.push(0); |
1215 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(raw.len()).as_ref()); |
1216 | 0 | (ret, either::Right(raw)) |
1217 | | } |
1218 | 0 | DigestItemRef::RuntimeEnvironmentUpdated => (vec![8], either::Right(&[][..])), |
1219 | | }; |
1220 | | |
1221 | 41 | [either::Left(item1), item2].into_iter() |
1222 | 41 | } _RNvMsa_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_13DigestItemRef14scale_encoding Line | Count | Source | 1101 | 41 | pub fn scale_encoding( | 1102 | 41 | &self, | 1103 | 41 | block_number_bytes: usize, | 1104 | 41 | ) -> impl Iterator<Item = impl AsRef<[u8]> + Clone + use<'a>> + Clone + use<'a> { | 1105 | 41 | let (item1, item2) = match *self { | 1106 | 2 | DigestItemRef::AuraPreDigest(ref aura_pre_digest) => { | 1107 | 2 | let encoded = aura_pre_digest | 1108 | 2 | .scale_encoding() | 1109 | 2 | .fold(Vec::new(), |mut a, b| { | 1110 | | a.extend_from_slice(b.as_ref()); | 1111 | | a | 1112 | | }); | 1113 | | | 1114 | 2 | let mut ret = Vec::with_capacity(12); | 1115 | 2 | ret.push(6); | 1116 | 2 | ret.extend_from_slice(b"aura"); | 1117 | 2 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); | 1118 | 2 | (ret, either::Left(encoded)) | 1119 | | } | 1120 | 0 | DigestItemRef::AuraSeal(seal) => { | 1121 | 0 | let mut ret = Vec::with_capacity(12); | 1122 | 0 | ret.push(5); | 1123 | 0 | ret.extend_from_slice(b"aura"); | 1124 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(64).as_ref()); | 1125 | 0 | (ret, either::Right(&seal[..])) | 1126 | | } | 1127 | 0 | DigestItemRef::AuraConsensus(ref aura_consensus) => { | 1128 | 0 | let encoded = aura_consensus | 1129 | 0 | .scale_encoding() | 1130 | 0 | .fold(Vec::new(), |mut a, b| { | 1131 | | a.extend_from_slice(b.as_ref()); | 1132 | | a | 1133 | | }); | 1134 | | | 1135 | 0 | let mut ret = Vec::with_capacity(12); | 1136 | 0 | ret.push(4); | 1137 | 0 | ret.extend_from_slice(b"aura"); | 1138 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); | 1139 | 0 | (ret, either::Left(encoded)) | 1140 | | } | 1141 | 7 | DigestItemRef::BabePreDigest(ref babe_pre_digest) => { | 1142 | 7 | let encoded = babe_pre_digest | 1143 | 7 | .scale_encoding() | 1144 | 7 | .fold(Vec::new(), |mut a, b| { | 1145 | | a.extend_from_slice(b.as_ref()); | 1146 | | a | 1147 | | }); | 1148 | | | 1149 | 7 | let mut ret = Vec::with_capacity(12); | 1150 | 7 | ret.push(6); | 1151 | 7 | ret.extend_from_slice(b"BABE"); | 1152 | 7 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); | 1153 | 7 | (ret, either::Left(encoded)) | 1154 | | } | 1155 | 17 | DigestItemRef::BabeConsensus(ref babe_consensus) => { | 1156 | 17 | let encoded = babe_consensus | 1157 | 17 | .scale_encoding() | 1158 | 17 | .fold(Vec::new(), |mut a, b| { | 1159 | | a.extend_from_slice(b.as_ref()); | 1160 | | a | 1161 | | }); | 1162 | | | 1163 | 17 | let mut ret = Vec::with_capacity(12); | 1164 | 17 | ret.push(4); | 1165 | 17 | ret.extend_from_slice(b"BABE"); | 1166 | 17 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); | 1167 | 17 | (ret, either::Left(encoded)) | 1168 | | } | 1169 | 12 | DigestItemRef::GrandpaConsensus(ref gp_consensus) => { | 1170 | 12 | let encoded = | 1171 | 12 | gp_consensus | 1172 | 12 | .scale_encoding(block_number_bytes) | 1173 | 12 | .fold(Vec::new(), |mut a, b| { | 1174 | | a.extend_from_slice(b.as_ref()); | 1175 | | a | 1176 | | }); | 1177 | | | 1178 | 12 | let mut ret = Vec::with_capacity(12); | 1179 | 12 | ret.push(4); | 1180 | 12 | ret.extend_from_slice(b"FRNK"); | 1181 | 12 | ret.extend_from_slice(util::encode_scale_compact_usize(encoded.len()).as_ref()); | 1182 | 12 | (ret, either::Left(encoded)) | 1183 | | } | 1184 | 3 | DigestItemRef::BabeSeal(seal) => { | 1185 | 3 | let mut ret = Vec::with_capacity(12); | 1186 | 3 | ret.push(5); | 1187 | 3 | ret.extend_from_slice(b"BABE"); | 1188 | 3 | ret.extend_from_slice(util::encode_scale_compact_usize(64).as_ref()); | 1189 | 3 | (ret, either::Right(&seal[..])) | 1190 | | } | 1191 | 0 | DigestItemRef::UnknownConsensus { engine, opaque } => { | 1192 | 0 | let mut ret = Vec::with_capacity(12); | 1193 | 0 | ret.push(4); | 1194 | 0 | ret.extend_from_slice(&engine); | 1195 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref()); | 1196 | 0 | (ret, either::Right(opaque)) | 1197 | | } | 1198 | 0 | DigestItemRef::UnknownSeal { engine, opaque } => { | 1199 | 0 | let mut ret = Vec::with_capacity(12); | 1200 | 0 | ret.push(5); | 1201 | 0 | ret.extend_from_slice(&engine); | 1202 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref()); | 1203 | 0 | (ret, either::Right(opaque)) | 1204 | | } | 1205 | 0 | DigestItemRef::UnknownPreRuntime { engine, opaque } => { | 1206 | 0 | let mut ret = Vec::with_capacity(12); | 1207 | 0 | ret.push(6); | 1208 | 0 | ret.extend_from_slice(&engine); | 1209 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(opaque.len()).as_ref()); | 1210 | 0 | (ret, either::Right(opaque)) | 1211 | | } | 1212 | 0 | DigestItemRef::Other(raw) => { | 1213 | 0 | let mut ret = Vec::with_capacity(12); | 1214 | 0 | ret.push(0); | 1215 | 0 | ret.extend_from_slice(util::encode_scale_compact_usize(raw.len()).as_ref()); | 1216 | 0 | (ret, either::Right(raw)) | 1217 | | } | 1218 | 0 | DigestItemRef::RuntimeEnvironmentUpdated => (vec![8], either::Right(&[][..])), | 1219 | | }; | 1220 | | | 1221 | 41 | [either::Left(item1), item2].into_iter() | 1222 | 41 | } |
Unexecuted instantiation: _RNvMsa_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_13DigestItemRef14scale_encoding |
1223 | | } |
1224 | | |
1225 | | impl<'a> From<&'a DigestItem> for DigestItemRef<'a> { |
1226 | 2 | fn from(a: &'a DigestItem) -> DigestItemRef<'a> { |
1227 | 2 | match a { |
1228 | 2 | DigestItem::AuraPreDigest(v) => DigestItemRef::AuraPreDigest(v.clone()), |
1229 | 0 | DigestItem::AuraConsensus(v) => DigestItemRef::AuraConsensus(v.into()), |
1230 | 0 | DigestItem::AuraSeal(v) => DigestItemRef::AuraSeal(v), |
1231 | 0 | DigestItem::BabePreDigest(v) => DigestItemRef::BabePreDigest(v.into()), |
1232 | 0 | DigestItem::BabeConsensus(v) => DigestItemRef::BabeConsensus(v.into()), |
1233 | 0 | DigestItem::BabeSeal(v) => DigestItemRef::BabeSeal(v), |
1234 | 0 | DigestItem::GrandpaConsensus(v) => DigestItemRef::GrandpaConsensus(v.into()), |
1235 | 0 | DigestItem::UnknownConsensus { engine, opaque } => DigestItemRef::UnknownConsensus { |
1236 | 0 | engine: *engine, |
1237 | 0 | opaque, |
1238 | 0 | }, |
1239 | 0 | DigestItem::UnknownSeal { engine, opaque } => DigestItemRef::UnknownSeal { |
1240 | 0 | engine: *engine, |
1241 | 0 | opaque, |
1242 | 0 | }, |
1243 | 0 | DigestItem::UnknownPreRuntime { engine, opaque } => DigestItemRef::UnknownPreRuntime { |
1244 | 0 | engine: *engine, |
1245 | 0 | opaque, |
1246 | 0 | }, |
1247 | 0 | DigestItem::Other(v) => DigestItemRef::Other(v), |
1248 | 0 | DigestItem::RuntimeEnvironmentUpdated => DigestItemRef::RuntimeEnvironmentUpdated, |
1249 | | } |
1250 | 2 | } _RNvXsb_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_13DigestItemRefINtNtCs1p5UDGgVI4d_4core7convert4FromRNtB5_10DigestItemE4from Line | Count | Source | 1226 | 2 | fn from(a: &'a DigestItem) -> DigestItemRef<'a> { | 1227 | 2 | match a { | 1228 | 2 | DigestItem::AuraPreDigest(v) => DigestItemRef::AuraPreDigest(v.clone()), | 1229 | 0 | DigestItem::AuraConsensus(v) => DigestItemRef::AuraConsensus(v.into()), | 1230 | 0 | DigestItem::AuraSeal(v) => DigestItemRef::AuraSeal(v), | 1231 | 0 | DigestItem::BabePreDigest(v) => DigestItemRef::BabePreDigest(v.into()), | 1232 | 0 | DigestItem::BabeConsensus(v) => DigestItemRef::BabeConsensus(v.into()), | 1233 | 0 | DigestItem::BabeSeal(v) => DigestItemRef::BabeSeal(v), | 1234 | 0 | DigestItem::GrandpaConsensus(v) => DigestItemRef::GrandpaConsensus(v.into()), | 1235 | 0 | DigestItem::UnknownConsensus { engine, opaque } => DigestItemRef::UnknownConsensus { | 1236 | 0 | engine: *engine, | 1237 | 0 | opaque, | 1238 | 0 | }, | 1239 | 0 | DigestItem::UnknownSeal { engine, opaque } => DigestItemRef::UnknownSeal { | 1240 | 0 | engine: *engine, | 1241 | 0 | opaque, | 1242 | 0 | }, | 1243 | 0 | DigestItem::UnknownPreRuntime { engine, opaque } => DigestItemRef::UnknownPreRuntime { | 1244 | 0 | engine: *engine, | 1245 | 0 | opaque, | 1246 | 0 | }, | 1247 | 0 | DigestItem::Other(v) => DigestItemRef::Other(v), | 1248 | 0 | DigestItem::RuntimeEnvironmentUpdated => DigestItemRef::RuntimeEnvironmentUpdated, | 1249 | | } | 1250 | 2 | } |
Unexecuted instantiation: _RNvXsb_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_13DigestItemRefINtNtCs1p5UDGgVI4d_4core7convert4FromRNtB5_10DigestItemE4from |
1251 | | } |
1252 | | |
1253 | | // TODO: document |
1254 | | #[derive(Debug, Clone)] |
1255 | | pub enum DigestItem { |
1256 | | AuraPreDigest(AuraPreDigest), |
1257 | | AuraConsensus(AuraConsensusLog), |
1258 | | /// Block signature made using the AURA consensus engine. |
1259 | | AuraSeal([u8; 64]), |
1260 | | |
1261 | | BabePreDigest(BabePreDigest), |
1262 | | BabeConsensus(BabeConsensusLog), |
1263 | | /// Block signature made using the BABE consensus engine. |
1264 | | BabeSeal([u8; 64]), |
1265 | | |
1266 | | GrandpaConsensus(GrandpaConsensusLog), |
1267 | | |
1268 | | /// See [`DigestItemRef::UnknownConsensus`]. |
1269 | | UnknownConsensus { |
1270 | | /// Name of the consensus engine. |
1271 | | engine: [u8; 4], |
1272 | | /// Smoldot doesn't interpret the content of the log item. |
1273 | | opaque: Vec<u8>, |
1274 | | }, |
1275 | | /// See [`DigestItemRef::UnknownPreRuntime`]. |
1276 | | UnknownPreRuntime { |
1277 | | /// Name of the consensus engine. |
1278 | | engine: [u8; 4], |
1279 | | /// Smoldot doesn't interpret the content of the log item. |
1280 | | opaque: Vec<u8>, |
1281 | | }, |
1282 | | /// See [`DigestItemRef::UnknownSeal`]. |
1283 | | UnknownSeal { |
1284 | | /// Name of the consensus engine. |
1285 | | engine: [u8; 4], |
1286 | | /// Smoldot doesn't interpret the content of the log item. |
1287 | | opaque: Vec<u8>, |
1288 | | }, |
1289 | | |
1290 | | /// Runtime of the chain has been updated in this block. This can include the runtime code or |
1291 | | /// the heap pages. |
1292 | | RuntimeEnvironmentUpdated, |
1293 | | |
1294 | | /// Some other thing. Always ignored. |
1295 | | Other(Vec<u8>), |
1296 | | } |
1297 | | |
1298 | | impl<'a> From<DigestItemRef<'a>> for DigestItem { |
1299 | 4 | fn from(a: DigestItemRef<'a>) -> DigestItem { |
1300 | 4 | match a { |
1301 | 0 | DigestItemRef::AuraPreDigest(v) => DigestItem::AuraPreDigest(v), |
1302 | 0 | DigestItemRef::AuraConsensus(v) => DigestItem::AuraConsensus(v.into()), |
1303 | 0 | DigestItemRef::AuraSeal(v) => { |
1304 | 0 | let mut seal = [0; 64]; |
1305 | 0 | seal.copy_from_slice(v); |
1306 | 0 | DigestItem::AuraSeal(seal) |
1307 | | } |
1308 | 2 | DigestItemRef::BabePreDigest(v) => DigestItem::BabePreDigest(v.into()), |
1309 | 0 | DigestItemRef::BabeConsensus(v) => DigestItem::BabeConsensus(v.into()), |
1310 | 2 | DigestItemRef::BabeSeal(v) => { |
1311 | 2 | let mut seal = [0; 64]; |
1312 | 2 | seal.copy_from_slice(v); |
1313 | 2 | DigestItem::BabeSeal(seal) |
1314 | | } |
1315 | 0 | DigestItemRef::GrandpaConsensus(v) => DigestItem::GrandpaConsensus(v.into()), |
1316 | 0 | DigestItemRef::UnknownConsensus { engine, opaque } => DigestItem::UnknownConsensus { |
1317 | 0 | opaque: opaque.to_vec(), |
1318 | 0 | engine, |
1319 | 0 | }, |
1320 | 0 | DigestItemRef::UnknownSeal { engine, opaque } => DigestItem::UnknownSeal { |
1321 | 0 | opaque: opaque.to_vec(), |
1322 | 0 | engine, |
1323 | 0 | }, |
1324 | 0 | DigestItemRef::UnknownPreRuntime { engine, opaque } => DigestItem::UnknownPreRuntime { |
1325 | 0 | opaque: opaque.to_vec(), |
1326 | 0 | engine, |
1327 | 0 | }, |
1328 | 0 | DigestItemRef::Other(v) => DigestItem::Other(v.to_vec()), |
1329 | 0 | DigestItemRef::RuntimeEnvironmentUpdated => DigestItem::RuntimeEnvironmentUpdated, |
1330 | | } |
1331 | 4 | } _RNvXsc_NtCsjlkOsLH0Zfj_7smoldot6headerNtB5_10DigestItemINtNtCs1p5UDGgVI4d_4core7convert4FromNtB5_13DigestItemRefE4from Line | Count | Source | 1299 | 4 | fn from(a: DigestItemRef<'a>) -> DigestItem { | 1300 | 4 | match a { | 1301 | 0 | DigestItemRef::AuraPreDigest(v) => DigestItem::AuraPreDigest(v), | 1302 | 0 | DigestItemRef::AuraConsensus(v) => DigestItem::AuraConsensus(v.into()), | 1303 | 0 | DigestItemRef::AuraSeal(v) => { | 1304 | 0 | let mut seal = [0; 64]; | 1305 | 0 | seal.copy_from_slice(v); | 1306 | 0 | DigestItem::AuraSeal(seal) | 1307 | | } | 1308 | 2 | DigestItemRef::BabePreDigest(v) => DigestItem::BabePreDigest(v.into()), | 1309 | 0 | DigestItemRef::BabeConsensus(v) => DigestItem::BabeConsensus(v.into()), | 1310 | 2 | DigestItemRef::BabeSeal(v) => { | 1311 | 2 | let mut seal = [0; 64]; | 1312 | 2 | seal.copy_from_slice(v); | 1313 | 2 | DigestItem::BabeSeal(seal) | 1314 | | } | 1315 | 0 | DigestItemRef::GrandpaConsensus(v) => DigestItem::GrandpaConsensus(v.into()), | 1316 | 0 | DigestItemRef::UnknownConsensus { engine, opaque } => DigestItem::UnknownConsensus { | 1317 | 0 | opaque: opaque.to_vec(), | 1318 | 0 | engine, | 1319 | 0 | }, | 1320 | 0 | DigestItemRef::UnknownSeal { engine, opaque } => DigestItem::UnknownSeal { | 1321 | 0 | opaque: opaque.to_vec(), | 1322 | 0 | engine, | 1323 | 0 | }, | 1324 | 0 | DigestItemRef::UnknownPreRuntime { engine, opaque } => DigestItem::UnknownPreRuntime { | 1325 | 0 | opaque: opaque.to_vec(), | 1326 | 0 | engine, | 1327 | 0 | }, | 1328 | 0 | DigestItemRef::Other(v) => DigestItem::Other(v.to_vec()), | 1329 | 0 | DigestItemRef::RuntimeEnvironmentUpdated => DigestItem::RuntimeEnvironmentUpdated, | 1330 | | } | 1331 | 4 | } |
Unexecuted instantiation: _RNvXsc_NtCsc1ywvx6YAnK_7smoldot6headerNtB5_10DigestItemINtNtCs1p5UDGgVI4d_4core7convert4FromNtB5_13DigestItemRefE4from |
1332 | | } |
1333 | | |
1334 | | /// Decodes a single digest log item. On success, returns the item and the data that remains |
1335 | | /// after the item. |
1336 | 175 | fn decode_item( |
1337 | 175 | mut slice: &[u8], |
1338 | 175 | block_number_bytes: usize, |
1339 | 175 | ) -> Result<(DigestItemRef, &[u8]), Error> { |
1340 | 175 | let index = *slice.first().ok_or(Error::TooShort)?0 ; |
1341 | 175 | slice = &slice[1..]; |
1342 | | |
1343 | 175 | match index { |
1344 | 175 | 4..=6 => { |
1345 | 175 | if slice.len() < 4 { |
1346 | 0 | return Err(Error::TooShort); |
1347 | 175 | } |
1348 | | |
1349 | 175 | let engine_id: &[u8; 4] = TryFrom::try_from(&slice[..4]).unwrap(); |
1350 | 175 | slice = &slice[4..]; |
1351 | | |
1352 | 175 | let (mut slice, len) = |
1353 | 175 | crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(slice) |
1354 | 175 | .map_err(|_| Error::DigestItemLenDecodeError)?0 ; |
1355 | | |
1356 | 175 | if slice.len() < len { |
1357 | 0 | return Err(Error::TooShort); |
1358 | 175 | } |
1359 | | |
1360 | 175 | let content = &slice[..len]; |
1361 | 175 | slice = &slice[len..]; |
1362 | | |
1363 | 175 | let item174 = decode_item_from_parts(index, block_number_bytes, engine_id, content)?1 ; |
1364 | 174 | Ok((item, slice)) |
1365 | | } |
1366 | 0 | 8 => Ok((DigestItemRef::RuntimeEnvironmentUpdated, slice)), |
1367 | | 0 => { |
1368 | 0 | let (mut slice, len) = |
1369 | 0 | crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(slice) |
1370 | 0 | .map_err(|_| Error::DigestItemLenDecodeError)?; |
1371 | | |
1372 | 0 | if slice.len() < len { |
1373 | 0 | return Err(Error::TooShort); |
1374 | 0 | } |
1375 | | |
1376 | 0 | let content = &slice[..len]; |
1377 | 0 | slice = &slice[len..]; |
1378 | | |
1379 | 0 | let item = DigestItemRef::Other(content); |
1380 | | |
1381 | 0 | Ok((item, slice)) |
1382 | | } |
1383 | 0 | ty => Err(Error::UnknownDigestLogType { unknown_type: ty }), |
1384 | | } |
1385 | 175 | } _RNvNtCsjlkOsLH0Zfj_7smoldot6header11decode_item Line | Count | Source | 1336 | 175 | fn decode_item( | 1337 | 175 | mut slice: &[u8], | 1338 | 175 | block_number_bytes: usize, | 1339 | 175 | ) -> Result<(DigestItemRef, &[u8]), Error> { | 1340 | 175 | let index = *slice.first().ok_or(Error::TooShort)?0 ; | 1341 | 175 | slice = &slice[1..]; | 1342 | | | 1343 | 175 | match index { | 1344 | 175 | 4..=6 => { | 1345 | 175 | if slice.len() < 4 { | 1346 | 0 | return Err(Error::TooShort); | 1347 | 175 | } | 1348 | | | 1349 | 175 | let engine_id: &[u8; 4] = TryFrom::try_from(&slice[..4]).unwrap(); | 1350 | 175 | slice = &slice[4..]; | 1351 | | | 1352 | 175 | let (mut slice, len) = | 1353 | 175 | crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(slice) | 1354 | 175 | .map_err(|_| Error::DigestItemLenDecodeError)?0 ; | 1355 | | | 1356 | 175 | if slice.len() < len { | 1357 | 0 | return Err(Error::TooShort); | 1358 | 175 | } | 1359 | | | 1360 | 175 | let content = &slice[..len]; | 1361 | 175 | slice = &slice[len..]; | 1362 | | | 1363 | 175 | let item174 = decode_item_from_parts(index, block_number_bytes, engine_id, content)?1 ; | 1364 | 174 | Ok((item, slice)) | 1365 | | } | 1366 | 0 | 8 => Ok((DigestItemRef::RuntimeEnvironmentUpdated, slice)), | 1367 | | 0 => { | 1368 | 0 | let (mut slice, len) = | 1369 | 0 | crate::util::nom_scale_compact_usize::<nom::error::Error<&[u8]>>(slice) | 1370 | 0 | .map_err(|_| Error::DigestItemLenDecodeError)?; | 1371 | | | 1372 | 0 | if slice.len() < len { | 1373 | 0 | return Err(Error::TooShort); | 1374 | 0 | } | 1375 | | | 1376 | 0 | let content = &slice[..len]; | 1377 | 0 | slice = &slice[len..]; | 1378 | | | 1379 | 0 | let item = DigestItemRef::Other(content); | 1380 | | | 1381 | 0 | Ok((item, slice)) | 1382 | | } | 1383 | 0 | ty => Err(Error::UnknownDigestLogType { unknown_type: ty }), | 1384 | | } | 1385 | 175 | } |
Unexecuted instantiation: _RNvNtCsc1ywvx6YAnK_7smoldot6header11decode_item |
1386 | | |
1387 | | /// When we know the index, engine id, and content of an item, we can finish decoding. |
1388 | 175 | fn decode_item_from_parts<'a>( |
1389 | 175 | index: u8, |
1390 | 175 | block_number_bytes: usize, |
1391 | 175 | engine_id: &'a [u8; 4], |
1392 | 175 | content: &'a [u8], |
1393 | 175 | ) -> Result<DigestItemRef<'a>, Error> { |
1394 | 175 | Ok(match (index, engine_id) { |
1395 | 0 | (_, b"pow_") => return Err(Error::PowIdeologicallyNotSupported), |
1396 | | // 4 = Consensus |
1397 | 1 | (4, b"aura") => DigestItemRef::AuraConsensus(AuraConsensusLogRef::from_slice(content)?), |
1398 | 51 | (4, b"BABE") => DigestItemRef::BabeConsensus(BabeConsensusLogRef::from_slice(content)?0 ), |
1399 | 25 | (4, b"FRNK") => DigestItemRef::GrandpaConsensus(GrandpaConsensusLogRef::from_slice( |
1400 | 25 | content, |
1401 | 25 | block_number_bytes, |
1402 | 0 | )?), |
1403 | 1 | (4, engine) => DigestItemRef::UnknownConsensus { |
1404 | 1 | engine: *engine, |
1405 | 1 | opaque: content, |
1406 | 1 | }, |
1407 | | // 5 = Seal |
1408 | | (5, b"aura") => DigestItemRef::AuraSeal({ |
1409 | 0 | TryFrom::try_from(content).map_err(|_| Error::BadAuraSealLength)? |
1410 | | }), |
1411 | | (5, b"BABE") => DigestItemRef::BabeSeal({ |
1412 | 41 | TryFrom::try_from(content).map_err(|_| Error::BadBabeSealLength)?0 |
1413 | | }), |
1414 | 0 | (5, engine) => DigestItemRef::UnknownSeal { |
1415 | 0 | engine: *engine, |
1416 | 0 | opaque: content, |
1417 | 0 | }, |
1418 | | // 6 = PreRuntime |
1419 | 1 | (6, b"aura") => DigestItemRef::AuraPreDigest(AuraPreDigest::from_slice(content)?0 ), |
1420 | 55 | (6, b"BABE") => DigestItemRef::BabePreDigest(BabePreDigestRef::from_slice(content)?0 ), |
1421 | 0 | (6, engine) => DigestItemRef::UnknownPreRuntime { |
1422 | 0 | engine: *engine, |
1423 | 0 | opaque: content, |
1424 | 0 | }, |
1425 | 0 | _ => unreachable!(), |
1426 | | }) |
1427 | 175 | } _RNvNtCsjlkOsLH0Zfj_7smoldot6header22decode_item_from_parts Line | Count | Source | 1388 | 175 | fn decode_item_from_parts<'a>( | 1389 | 175 | index: u8, | 1390 | 175 | block_number_bytes: usize, | 1391 | 175 | engine_id: &'a [u8; 4], | 1392 | 175 | content: &'a [u8], | 1393 | 175 | ) -> Result<DigestItemRef<'a>, Error> { | 1394 | 175 | Ok(match (index, engine_id) { | 1395 | 0 | (_, b"pow_") => return Err(Error::PowIdeologicallyNotSupported), | 1396 | | // 4 = Consensus | 1397 | 1 | (4, b"aura") => DigestItemRef::AuraConsensus(AuraConsensusLogRef::from_slice(content)?), | 1398 | 51 | (4, b"BABE") => DigestItemRef::BabeConsensus(BabeConsensusLogRef::from_slice(content)?0 ), | 1399 | 25 | (4, b"FRNK") => DigestItemRef::GrandpaConsensus(GrandpaConsensusLogRef::from_slice( | 1400 | 25 | content, | 1401 | 25 | block_number_bytes, | 1402 | 0 | )?), | 1403 | 1 | (4, engine) => DigestItemRef::UnknownConsensus { | 1404 | 1 | engine: *engine, | 1405 | 1 | opaque: content, | 1406 | 1 | }, | 1407 | | // 5 = Seal | 1408 | | (5, b"aura") => DigestItemRef::AuraSeal({ | 1409 | 0 | TryFrom::try_from(content).map_err(|_| Error::BadAuraSealLength)? | 1410 | | }), | 1411 | | (5, b"BABE") => DigestItemRef::BabeSeal({ | 1412 | 41 | TryFrom::try_from(content).map_err(|_| Error::BadBabeSealLength)?0 | 1413 | | }), | 1414 | 0 | (5, engine) => DigestItemRef::UnknownSeal { | 1415 | 0 | engine: *engine, | 1416 | 0 | opaque: content, | 1417 | 0 | }, | 1418 | | // 6 = PreRuntime | 1419 | 1 | (6, b"aura") => DigestItemRef::AuraPreDigest(AuraPreDigest::from_slice(content)?0 ), | 1420 | 55 | (6, b"BABE") => DigestItemRef::BabePreDigest(BabePreDigestRef::from_slice(content)?0 ), | 1421 | 0 | (6, engine) => DigestItemRef::UnknownPreRuntime { | 1422 | 0 | engine: *engine, | 1423 | 0 | opaque: content, | 1424 | 0 | }, | 1425 | 0 | _ => unreachable!(), | 1426 | | }) | 1427 | 175 | } |
Unexecuted instantiation: _RNvNtCsc1ywvx6YAnK_7smoldot6header22decode_item_from_parts |