/__w/smoldot/smoldot/repo/lib/src/trie/proof_decode.rs
Line | Count | Source (jump to first uncovered line) |
1 | | // Smoldot |
2 | | // Copyright (C) 2019-2022 Parity Technologies (UK) Ltd. |
3 | | // SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 |
4 | | |
5 | | // This program is free software: you can redistribute it and/or modify |
6 | | // it under the terms of the GNU General Public License as published by |
7 | | // the Free Software Foundation, either version 3 of the License, or |
8 | | // (at your option) any later version. |
9 | | |
10 | | // This program is distributed in the hope that it will be useful, |
11 | | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | | // GNU General Public License for more details. |
14 | | |
15 | | // You should have received a copy of the GNU General Public License |
16 | | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | | |
18 | | //! Decodes and verifies a trie proof. |
19 | | //! |
20 | | //! A trie proof is a proof that a certain key in the trie has a certain storage value (or lacks |
21 | | //! a storage value). The proof can be verified by knowing only the Merkle value of the root node. |
22 | | //! |
23 | | //! # Details |
24 | | //! |
25 | | //! > **Note**: For reminder, the Merkle value of a node is the hash of its node value, or the |
26 | | //! > node value directly if its length is smaller than 32 bytes. |
27 | | //! |
28 | | //! A trie proof consists in a list of node values of nodes in the trie. For the proof to be valid, |
29 | | //! the hash of one of these node values must match the expected trie root node value. Since a |
30 | | //! node value contains the Merkle values of the children of the node, it is possible to iterate |
31 | | //! down the hierarchy of nodes until the one closest to the desired key is found. |
32 | | //! |
33 | | //! # Usage |
34 | | //! |
35 | | //! This modules provides the [`decode_and_verify_proof`] function that decodes a proof and |
36 | | //! verifies whether it is correct. |
37 | | //! |
38 | | //! Once decoded, one can examine the content of the proof, in other words the list of storage |
39 | | //! items and values. |
40 | | |
41 | | use super::{nibble, trie_node, TrieEntryVersion}; |
42 | | |
43 | | use alloc::vec::Vec; |
44 | | use core::{fmt, iter, ops}; |
45 | | |
46 | | /// Configuration to pass to [`decode_and_verify_proof`]. |
47 | | pub struct Config<I> { |
48 | | /// List of node values of nodes found in the trie. At least one entry corresponding to the |
49 | | /// root node of the trie must be present in order for the verification to succeed. |
50 | | pub proof: I, |
51 | | } |
52 | | |
53 | | /// Verifies whether a proof is correct and returns an object that allows examining its content. |
54 | | /// |
55 | | /// The proof is then stored within the [`DecodedTrieProof`]. |
56 | | /// |
57 | | /// Due to the generic nature of this function, the proof can be either a `Vec<u8>` or a `&[u8]`. |
58 | | /// |
59 | | /// Returns an error if the proof is invalid, or if the proof contains entries that are |
60 | | /// disconnected from the root node of the trie. |
61 | 1.51k | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> |
62 | 1.51k | where |
63 | 1.51k | T: AsRef<[u8]>, |
64 | 1.51k | { |
65 | 1.51k | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory |
66 | 1.51k | // location. |
67 | 1.51k | let proof_as_ref = config.proof.as_ref(); |
68 | | |
69 | | struct InProgressEntry<'a> { |
70 | | index_in_proof: usize, |
71 | | range_in_proof: ops::Range<usize>, |
72 | | decode_result: Result< |
73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, |
74 | | trie_node::Error, |
75 | | >, |
76 | | } |
77 | | |
78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. |
79 | | // |
80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In |
81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per |
82 | | // entry in `proof`. |
83 | | // |
84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is |
85 | | // possible for an attacker to craft a proof that leads to all entries being in the same |
86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which |
87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function |
88 | | // takes, it is always cause this function to return an error and is actually likely to make |
89 | | // the function actually take less time than if it was a legitimate proof. |
90 | 1.51k | let entries_by_merkle_value = { |
91 | | // TODO: don't use a Vec? |
92 | 1.51k | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( |
93 | 1.51k | crate::util::nom_scale_compact_usize, |
94 | 1.51k | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofAhj43e8_E0B8_ Line | Count | Source | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtCsdZExvAaxgia_5alloc3vec3VechEE0B8_ Line | Count | Source | 94 | 1.50k | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj11_E0B8_ Line | Count | Source | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj1_E0B8_ Line | Count | Source | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj4385_E0B8_ Line | Count | Source | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhja2_E0B8_ Line | Count | Source | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhjfc_E0B8_ Line | Count | Source | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRShE0B8_ Line | Count | Source | 94 | 9 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), |
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShE0B8_ Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShE0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShE0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShE0CsibGXYHQB8Ea_25json_rpc_general_requests |
95 | 1.51k | ))(config.proof.as_ref()) |
96 | 1.51k | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat0 )?0 ; Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofAhj43e8_Es_0B8_ Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtCsdZExvAaxgia_5alloc3vec3VechEEs_0B8_ Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj11_Es_0B8_ Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj1_Es_0B8_ Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj4385_Es_0B8_ Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhja2_Es_0B8_ Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhjfc_Es_0B8_ Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs_0B8_ Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs_0B8_ Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs_0CsibGXYHQB8Ea_25json_rpc_general_requests |
97 | | |
98 | 1.51k | let entries_by_merkle_value = decoded_proof |
99 | 1.51k | .iter() |
100 | 1.51k | .copied() |
101 | 1.51k | .enumerate() |
102 | 1.51k | .map( |
103 | 21.9k | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { |
104 | 21.9k | // The merkle value of a trie node is normally either its hash or the node |
105 | 21.9k | // itself if its length is < 32. In the context of a proof, however, nodes |
106 | 21.9k | // whose length is < 32 aren't supposed to be their own entry. For this reason, |
107 | 21.9k | // we only hash each entry. |
108 | 21.9k | let hash = *<&[u8; 32]>::try_from( |
109 | 21.9k | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), |
110 | 21.9k | ) |
111 | 21.9k | .unwrap(); |
112 | | |
113 | 21.9k | let proof_entry_offset = if proof_entry.is_empty() { |
114 | 0 | 0 |
115 | | } else { |
116 | 21.9k | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize |
117 | | }; |
118 | | |
119 | 21.9k | ( |
120 | 21.9k | hash, |
121 | 21.9k | InProgressEntry { |
122 | 21.9k | index_in_proof: proof_entry_num, |
123 | 21.9k | range_in_proof: proof_entry_offset |
124 | 21.9k | ..(proof_entry_offset + proof_entry.len()), |
125 | 21.9k | decode_result: trie_node::decode(proof_entry), |
126 | 21.9k | }, |
127 | 21.9k | ) |
128 | 21.9k | }, _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofAhj43e8_Es0_0B8_ Line | Count | Source | 103 | 127 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | 127 | // The merkle value of a trie node is normally either its hash or the node | 105 | 127 | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | 127 | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | 127 | // we only hash each entry. | 108 | 127 | let hash = *<&[u8; 32]>::try_from( | 109 | 127 | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | 127 | ) | 111 | 127 | .unwrap(); | 112 | | | 113 | 127 | let proof_entry_offset = if proof_entry.is_empty() { | 114 | 0 | 0 | 115 | | } else { | 116 | 127 | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | 127 | ( | 120 | 127 | hash, | 121 | 127 | InProgressEntry { | 122 | 127 | index_in_proof: proof_entry_num, | 123 | 127 | range_in_proof: proof_entry_offset | 124 | 127 | ..(proof_entry_offset + proof_entry.len()), | 125 | 127 | decode_result: trie_node::decode(proof_entry), | 126 | 127 | }, | 127 | 127 | ) | 128 | 127 | }, |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtCsdZExvAaxgia_5alloc3vec3VechEEs0_0B8_ Line | Count | Source | 103 | 19.9k | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | 19.9k | // The merkle value of a trie node is normally either its hash or the node | 105 | 19.9k | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | 19.9k | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | 19.9k | // we only hash each entry. | 108 | 19.9k | let hash = *<&[u8; 32]>::try_from( | 109 | 19.9k | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | 19.9k | ) | 111 | 19.9k | .unwrap(); | 112 | | | 113 | 19.9k | let proof_entry_offset = if proof_entry.is_empty() { | 114 | 0 | 0 | 115 | | } else { | 116 | 19.9k | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | 19.9k | ( | 120 | 19.9k | hash, | 121 | 19.9k | InProgressEntry { | 122 | 19.9k | index_in_proof: proof_entry_num, | 123 | 19.9k | range_in_proof: proof_entry_offset | 124 | 19.9k | ..(proof_entry_offset + proof_entry.len()), | 125 | 19.9k | decode_result: trie_node::decode(proof_entry), | 126 | 19.9k | }, | 127 | 19.9k | ) | 128 | 19.9k | }, |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj11_Es0_0B8_ Line | Count | Source | 103 | 1 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | 1 | // The merkle value of a trie node is normally either its hash or the node | 105 | 1 | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | 1 | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | 1 | // we only hash each entry. | 108 | 1 | let hash = *<&[u8; 32]>::try_from( | 109 | 1 | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | 1 | ) | 111 | 1 | .unwrap(); | 112 | | | 113 | 1 | let proof_entry_offset = if proof_entry.is_empty() { | 114 | 0 | 0 | 115 | | } else { | 116 | 1 | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | 1 | ( | 120 | 1 | hash, | 121 | 1 | InProgressEntry { | 122 | 1 | index_in_proof: proof_entry_num, | 123 | 1 | range_in_proof: proof_entry_offset | 124 | 1 | ..(proof_entry_offset + proof_entry.len()), | 125 | 1 | decode_result: trie_node::decode(proof_entry), | 126 | 1 | }, | 127 | 1 | ) | 128 | 1 | }, |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj1_Es0_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj4385_Es0_0B8_ Line | Count | Source | 103 | 126 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | 126 | // The merkle value of a trie node is normally either its hash or the node | 105 | 126 | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | 126 | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | 126 | // we only hash each entry. | 108 | 126 | let hash = *<&[u8; 32]>::try_from( | 109 | 126 | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | 126 | ) | 111 | 126 | .unwrap(); | 112 | | | 113 | 126 | let proof_entry_offset = if proof_entry.is_empty() { | 114 | 0 | 0 | 115 | | } else { | 116 | 126 | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | 126 | ( | 120 | 126 | hash, | 121 | 126 | InProgressEntry { | 122 | 126 | index_in_proof: proof_entry_num, | 123 | 126 | range_in_proof: proof_entry_offset | 124 | 126 | ..(proof_entry_offset + proof_entry.len()), | 125 | 126 | decode_result: trie_node::decode(proof_entry), | 126 | 126 | }, | 127 | 126 | ) | 128 | 126 | }, |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhja2_Es0_0B8_ Line | Count | Source | 103 | 2 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | 2 | // The merkle value of a trie node is normally either its hash or the node | 105 | 2 | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | 2 | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | 2 | // we only hash each entry. | 108 | 2 | let hash = *<&[u8; 32]>::try_from( | 109 | 2 | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | 2 | ) | 111 | 2 | .unwrap(); | 112 | | | 113 | 2 | let proof_entry_offset = if proof_entry.is_empty() { | 114 | 0 | 0 | 115 | | } else { | 116 | 2 | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | 2 | ( | 120 | 2 | hash, | 121 | 2 | InProgressEntry { | 122 | 2 | index_in_proof: proof_entry_num, | 123 | 2 | range_in_proof: proof_entry_offset | 124 | 2 | ..(proof_entry_offset + proof_entry.len()), | 125 | 2 | decode_result: trie_node::decode(proof_entry), | 126 | 2 | }, | 127 | 2 | ) | 128 | 2 | }, |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhjfc_Es0_0B8_ Line | Count | Source | 103 | 3 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | 3 | // The merkle value of a trie node is normally either its hash or the node | 105 | 3 | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | 3 | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | 3 | // we only hash each entry. | 108 | 3 | let hash = *<&[u8; 32]>::try_from( | 109 | 3 | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | 3 | ) | 111 | 3 | .unwrap(); | 112 | | | 113 | 3 | let proof_entry_offset = if proof_entry.is_empty() { | 114 | 0 | 0 | 115 | | } else { | 116 | 3 | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | 3 | ( | 120 | 3 | hash, | 121 | 3 | InProgressEntry { | 122 | 3 | index_in_proof: proof_entry_num, | 123 | 3 | range_in_proof: proof_entry_offset | 124 | 3 | ..(proof_entry_offset + proof_entry.len()), | 125 | 3 | decode_result: trie_node::decode(proof_entry), | 126 | 3 | }, | 127 | 3 | ) | 128 | 3 | }, |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs0_0B8_ Line | Count | Source | 103 | 1.75k | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | 1.75k | // The merkle value of a trie node is normally either its hash or the node | 105 | 1.75k | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | 1.75k | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | 1.75k | // we only hash each entry. | 108 | 1.75k | let hash = *<&[u8; 32]>::try_from( | 109 | 1.75k | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | 1.75k | ) | 111 | 1.75k | .unwrap(); | 112 | | | 113 | 1.75k | let proof_entry_offset = if proof_entry.is_empty() { | 114 | 0 | 0 | 115 | | } else { | 116 | 1.75k | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | 1.75k | ( | 120 | 1.75k | hash, | 121 | 1.75k | InProgressEntry { | 122 | 1.75k | index_in_proof: proof_entry_num, | 123 | 1.75k | range_in_proof: proof_entry_offset | 124 | 1.75k | ..(proof_entry_offset + proof_entry.len()), | 125 | 1.75k | decode_result: trie_node::decode(proof_entry), | 126 | 1.75k | }, | 127 | 1.75k | ) | 128 | 1.75k | }, |
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs0_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs0_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs0_0B8_ Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs0_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs0_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs0_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs0_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests |
129 | 1.51k | ) |
130 | 1.51k | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); |
131 | 1.51k | |
132 | 1.51k | // Using a hashmap has the consequence that if multiple proof entries were identical, only |
133 | 1.51k | // one would be tracked. This allows us to make sure that the proof doesn't contain |
134 | 1.51k | // multiple identical entries. |
135 | 1.51k | if entries_by_merkle_value.len() != decoded_proof.len() { |
136 | 1 | return Err(Error::DuplicateProofEntry); |
137 | 1.51k | } |
138 | 1.51k | |
139 | 1.51k | entries_by_merkle_value |
140 | | }; |
141 | | |
142 | | // Start by iterating over each element of the proof, and keep track of elements that are |
143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. |
144 | 1.51k | let trie_roots = { |
145 | 1.51k | let mut maybe_trie_roots = entries_by_merkle_value |
146 | 1.51k | .keys() |
147 | 1.51k | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); |
148 | 21.9k | for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter()1.51k { |
149 | 21.9k | let Ok(decoded21.9k ) = decode_result else { |
150 | 59 | maybe_trie_roots.remove(hash); |
151 | 59 | continue; |
152 | | }; |
153 | 31.8k | for child in decoded.children.into_iter().flatten()21.9k { |
154 | 31.8k | if let Ok(child23.1k ) = &<[u8; 32]>::try_from(child) { |
155 | 23.1k | maybe_trie_roots.remove(child); |
156 | 23.1k | }8.71k |
157 | | } |
158 | | } |
159 | 1.51k | maybe_trie_roots |
160 | 1.51k | }; |
161 | 1.51k | |
162 | 1.51k | // The implementation below iterates down the tree of nodes represented by this proof, keeping |
163 | 1.51k | // note of the traversed elements. |
164 | 1.51k | |
165 | 1.51k | // Keep track of all the entries found in the proof. |
166 | 1.51k | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); |
167 | 1.51k | |
168 | 1.51k | let mut trie_roots_with_entries = |
169 | 1.51k | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); |
170 | 1.51k | |
171 | 1.51k | // Keep track of the proof entries that haven't been visited when traversing. |
172 | 1.51k | let mut unvisited_proof_entries = |
173 | 1.51k | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); |
174 | | |
175 | | // We repeat this operation for every trie root. |
176 | 3.03k | for trie_root_hash1.51k in trie_roots { |
177 | | struct StackEntry<'a> { |
178 | | range_in_proof: ops::Range<usize>, |
179 | | index_in_entries: usize, |
180 | | num_visited_children: u8, |
181 | | children_node_values: [Option<&'a [u8]>; 16], |
182 | | } |
183 | | |
184 | | // Keep track of the number of entries before this trie root. |
185 | | // This allows us to truncate `entries` to this value in case of decoding failure. |
186 | 1.51k | let num_entries_before_current_trie_root = entries.len(); |
187 | 1.51k | |
188 | 1.51k | // Keep track of the indices of the proof entries that are visited when traversing this trie. |
189 | 1.51k | let mut visited_proof_entries_during_trie = |
190 | 1.51k | Vec::with_capacity(entries_by_merkle_value.len()); |
191 | 1.51k | |
192 | 1.51k | // TODO: configurable capacity? |
193 | 1.51k | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); |
194 | | |
195 | | loop { |
196 | | // Find which node to visit next. |
197 | | // This is the next child of the node at the top of the stack, or if the node at |
198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. |
199 | | // If the stack is empty, we are necessarily at the first iteration. |
200 | 30.9k | let (visited_node_entry_range, visited_node_decoded) = |
201 | 93.4k | match visited_entries_stack.last_mut() { |
202 | | None => { |
203 | | // Stack is empty. |
204 | | // Because we immediately `break` after popping the last element, the stack |
205 | | // can only ever be empty at the very start. |
206 | | let InProgressEntry { |
207 | 1.51k | index_in_proof: root_position, |
208 | 1.51k | range_in_proof: root_range, |
209 | 1.51k | decode_result, |
210 | 1.51k | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); |
211 | 1.51k | visited_proof_entries_during_trie.push(*root_position); |
212 | | // If the node can't be decoded, we ignore the entire trie and jump |
213 | | // to the next one. |
214 | 1.51k | let Ok(decoded) = decode_result.clone() else { |
215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); |
216 | 0 | break; |
217 | | }; |
218 | 1.51k | (root_range.clone(), decoded) |
219 | | } |
220 | | Some(StackEntry { |
221 | 91.9k | num_visited_children: stack_top_visited_children, |
222 | 91.9k | .. |
223 | 91.9k | }) if *stack_top_visited_children == 1630.9k => { |
224 | | // We have visited all the children of the top of the stack. Pop the node from |
225 | | // the stack. |
226 | | let Some(StackEntry { |
227 | 30.9k | index_in_entries: stack_top_index_in_entries, |
228 | | .. |
229 | 30.9k | }) = visited_entries_stack.pop() |
230 | | else { |
231 | 0 | unreachable!() |
232 | | }; |
233 | | |
234 | | // Update the value of `child_entries_follow_up` |
235 | | // and `children_present_in_proof_bitmap` of the parent. |
236 | | if let Some(&StackEntry { |
237 | 29.4k | index_in_entries: parent_index_in_entries, |
238 | 29.4k | num_visited_children: parent_children_visited, |
239 | | .. |
240 | 30.9k | }) = visited_entries_stack.last() |
241 | 29.4k | { |
242 | 29.4k | entries[parent_index_in_entries].child_entries_follow_up += |
243 | 29.4k | entries[stack_top_index_in_entries].child_entries_follow_up + 1; |
244 | 29.4k | entries[parent_index_in_entries].children_present_in_proof_bitmap |= |
245 | 29.4k | 1 << (parent_children_visited - 1); |
246 | 29.4k | }1.51k |
247 | | |
248 | | // If we popped the last node of the stack, we have finished the iteration. |
249 | 30.9k | if visited_entries_stack.is_empty() { |
250 | 1.51k | trie_roots_with_entries |
251 | 1.51k | .insert(*trie_root_hash, num_entries_before_current_trie_root); |
252 | | // Remove the visited entries from `unvisited_proof_entries`. |
253 | | // Note that it is questionable what to do if the same entry is visited |
254 | | // multiple times. In case where multiple storage branches are identical, |
255 | | // the sender of the proof should de-duplicate the identical nodes. For |
256 | | // this reason, it could be legitimate for the same proof entry to be |
257 | | // visited multiple times. |
258 | 23.5k | for entry_num22.0k in visited_proof_entries_during_trie { |
259 | 22.0k | unvisited_proof_entries.remove(&entry_num); |
260 | 22.0k | } |
261 | 1.51k | break; |
262 | | } else { |
263 | 29.4k | continue; |
264 | | } |
265 | | } |
266 | | Some(StackEntry { |
267 | 61.0k | range_in_proof: stack_top_proof_range, |
268 | 61.0k | num_visited_children: stack_top_visited_children, |
269 | 61.0k | children_node_values: stack_top_children, |
270 | 61.0k | .. |
271 | 61.0k | }) => { |
272 | 61.0k | // Find the next child of the top of the stack. |
273 | 61.0k | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; |
274 | 61.0k | |
275 | 61.0k | // Find the index of the next child (that we are about to visit). |
276 | 61.0k | let next_child_to_visit = stack_top_children |
277 | 61.0k | .iter() |
278 | 61.0k | .skip(usize::from(*stack_top_visited_children)) |
279 | 495k | .position(|c| c.is_some()) _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofAhj43e8_Es1_0B8_ Line | Count | Source | 279 | 2.35k | .position(|c| c.is_some()) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtCsdZExvAaxgia_5alloc3vec3VechEEs1_0B8_ Line | Count | Source | 279 | 461k | .position(|c| c.is_some()) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj11_Es1_0B8_ Line | Count | Source | 279 | 48 | .position(|c| c.is_some()) |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj1_Es1_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj4385_Es1_0B8_ Line | Count | Source | 279 | 2.32k | .position(|c| c.is_some()) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhja2_Es1_0B8_ Line | Count | Source | 279 | 48 | .position(|c| c.is_some()) |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhjfc_Es1_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs1_0B8_ Line | Count | Source | 279 | 28.4k | .position(|c| c.is_some()) |
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs1_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs1_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs1_0B8_ Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs1_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs1_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs1_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs1_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs1_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs1_0CsibGXYHQB8Ea_25json_rpc_general_requests |
280 | 61.0k | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children32.1k ) _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofAhj43e8_Es2_0B8_ Line | Count | Source | 280 | 392 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtCsdZExvAaxgia_5alloc3vec3VechEEs2_0B8_ Line | Count | Source | 280 | 27.5k | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj11_Es2_0B8_ Line | Count | Source | 280 | 2 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj1_Es2_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj4385_Es2_0B8_ Line | Count | Source | 280 | 391 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhja2_Es2_0B8_ Line | Count | Source | 280 | 2 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhjfc_Es2_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs2_0B8_ Line | Count | Source | 280 | 3.81k | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) |
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs2_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs2_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs2_0B8_ Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs2_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs2_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs2_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs2_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs2_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs2_0CsibGXYHQB8Ea_25json_rpc_general_requests |
281 | 61.0k | .unwrap_or(16); |
282 | 61.0k | |
283 | 61.0k | // `continue` if all children have been visited. The next iteration will |
284 | 61.0k | // pop the stack entry. |
285 | 61.0k | if next_child_to_visit == 16 { |
286 | 28.8k | *stack_top_visited_children = 16; |
287 | 28.8k | continue; |
288 | 32.1k | } |
289 | 32.1k | *stack_top_visited_children = next_child_to_visit + 1; |
290 | 32.1k | |
291 | 32.1k | // The value of the child node is either directly inlined (if less |
292 | 32.1k | // than 32 bytes) or is a hash. |
293 | 32.1k | let child_node_value = |
294 | 32.1k | stack_top_children[usize::from(next_child_to_visit)].unwrap(); |
295 | 32.1k | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. |
296 | 32.1k | if child_node_value.len() < 32 { |
297 | 9.00k | let offset = stack_top_proof_range.start |
298 | 9.00k | + if !child_node_value.is_empty() { |
299 | 9.00k | child_node_value.as_ptr() as usize |
300 | 9.00k | - stack_top_entry.as_ptr() as usize |
301 | | } else { |
302 | 1 | 0 |
303 | | }; |
304 | 9.00k | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); |
305 | 9.00k | debug_assert!( |
306 | 9.00k | offset <= (stack_top_proof_range.start + stack_top_entry.len()) |
307 | | ); |
308 | | |
309 | 9.00k | let child_range_in_proof = offset..(offset + child_node_value.len()); |
310 | | |
311 | | // Decodes the child. |
312 | | // If the node can't be decoded, we ignore the entire trie and jump |
313 | | // to the next one. |
314 | 9.00k | let Ok(child_decoded) = |
315 | 9.00k | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) |
316 | | else { |
317 | 1 | entries.truncate(num_entries_before_current_trie_root); |
318 | 1 | break; |
319 | | }; |
320 | | |
321 | 9.00k | (child_range_in_proof, child_decoded) |
322 | | } else if let Some(&InProgressEntry { |
323 | 20.4k | index_in_proof: child_position, |
324 | 20.4k | range_in_proof: ref child_entry_range, |
325 | 20.4k | ref decode_result, |
326 | 23.1k | }) = entries_by_merkle_value.get(child_node_value) |
327 | | { |
328 | | // If the node value of the child is less than 32 bytes long, it should |
329 | | // have been inlined instead of given separately. |
330 | 20.4k | if child_entry_range.end - child_entry_range.start < 32 { |
331 | 0 | entries.truncate(num_entries_before_current_trie_root); |
332 | 0 | break; |
333 | 20.4k | } |
334 | 20.4k | |
335 | 20.4k | visited_proof_entries_during_trie.push(child_position); |
336 | | |
337 | | // If the node can't be decoded, we ignore the entire trie and jump |
338 | | // to the next one. |
339 | 20.4k | let Ok(decoded) = decode_result.clone() else { |
340 | 0 | entries.truncate(num_entries_before_current_trie_root); |
341 | 0 | break; |
342 | | }; |
343 | 20.4k | (child_entry_range.clone(), decoded) |
344 | | } else { |
345 | | // Child is a hash that was not found in the proof. Simply continue |
346 | | // iterating, in order to try to find the follow-up child. |
347 | 2.71k | continue; |
348 | | } |
349 | | } |
350 | | }; |
351 | | |
352 | | // All nodes must either have a child or a storage value or be the root. |
353 | 30.9k | if visited_node_decoded.children_bitmap() == 0 |
354 | 22.1k | && matches!( |
355 | 22.1k | visited_node_decoded.storage_value, |
356 | | trie_node::StorageValue::None |
357 | | ) |
358 | 1 | && !visited_entries_stack.is_empty() |
359 | | { |
360 | 1 | entries.truncate(num_entries_before_current_trie_root); |
361 | 1 | break; |
362 | 30.9k | } |
363 | 30.9k | |
364 | 30.9k | // Nodes with no storage value and one children are forbidden. |
365 | 30.9k | if visited_node_decoded |
366 | 30.9k | .children |
367 | 30.9k | .iter() |
368 | 495k | .filter(|c| c.is_some()) _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofAhj43e8_Es3_0B8_ Line | Count | Source | 368 | 2.36k | .filter(|c| c.is_some()) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtCsdZExvAaxgia_5alloc3vec3VechEEs3_0B8_ Line | Count | Source | 368 | 461k | .filter(|c| c.is_some()) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj11_Es3_0B8_ Line | Count | Source | 368 | 48 | .filter(|c| c.is_some()) |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj1_Es3_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj4385_Es3_0B8_ Line | Count | Source | 368 | 2.33k | .filter(|c| c.is_some()) |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhja2_Es3_0B8_ Line | Count | Source | 368 | 48 | .filter(|c| c.is_some()) |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhjfc_Es3_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs3_0B8_ Line | Count | Source | 368 | 28.4k | .filter(|c| c.is_some()) |
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs3_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs3_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs3_0B8_ Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs3_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs3_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs3_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs3_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs3_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs3_0CsibGXYHQB8Ea_25json_rpc_general_requests |
369 | 30.9k | .count() |
370 | 30.9k | == 1 |
371 | 703 | && matches!( |
372 | 703 | visited_node_decoded.storage_value, |
373 | | trie_node::StorageValue::None |
374 | | ) |
375 | | { |
376 | 0 | entries.truncate(num_entries_before_current_trie_root); |
377 | 0 | break; |
378 | 30.9k | } |
379 | 30.9k | |
380 | 30.9k | // Add an entry for this node in the final list of entries. |
381 | 30.9k | entries.push(Entry { |
382 | 30.9k | parent_entry_index: visited_entries_stack.last().map(|entry| { |
383 | 29.4k | ( |
384 | 29.4k | entry.index_in_entries, |
385 | 29.4k | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), |
386 | 29.4k | ) |
387 | 30.9k | }), _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofAhj43e8_Es4_0B8_ Line | Count | Source | 382 | 146 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | 146 | ( | 384 | 146 | entry.index_in_entries, | 385 | 146 | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | 146 | ) | 387 | 146 | }), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtCsdZExvAaxgia_5alloc3vec3VechEEs4_0B8_ Line | Count | Source | 382 | 27.3k | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | 27.3k | ( | 384 | 27.3k | entry.index_in_entries, | 385 | 27.3k | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | 27.3k | ) | 387 | 27.3k | }), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj11_Es4_0B8_ Line | Count | Source | 382 | 2 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | 2 | ( | 384 | 2 | entry.index_in_entries, | 385 | 2 | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | 2 | ) | 387 | 2 | }), |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj1_Es4_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj4385_Es4_0B8_ Line | Count | Source | 382 | 144 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | 144 | ( | 384 | 144 | entry.index_in_entries, | 385 | 144 | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | 144 | ) | 387 | 144 | }), |
_RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhja2_Es4_0B8_ Line | Count | Source | 382 | 2 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | 2 | ( | 384 | 2 | entry.index_in_entries, | 385 | 2 | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | 2 | ) | 387 | 2 | }), |
Unexecuted instantiation: _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhjfc_Es4_0B8_ _RNCINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs4_0B8_ Line | Count | Source | 382 | 1.76k | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | 1.76k | ( | 384 | 1.76k | entry.index_in_entries, | 385 | 1.76k | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | 1.76k | ) | 387 | 1.76k | }), |
Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs4_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs4_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs4_0B8_ Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs4_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs4_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs4_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs4_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEEs4_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEs4_0CsibGXYHQB8Ea_25json_rpc_general_requests |
388 | 30.9k | range_in_proof: visited_node_entry_range.clone(), |
389 | 30.9k | storage_value_in_proof: match visited_node_decoded.storage_value { |
390 | 6.57k | trie_node::StorageValue::None => None, |
391 | 76 | trie_node::StorageValue::Hashed(value_hash) => { |
392 | | if let Some(&InProgressEntry { |
393 | 76 | index_in_proof: value_position, |
394 | 76 | range_in_proof: ref value_entry_range, |
395 | | .. |
396 | 76 | }) = entries_by_merkle_value.get(&value_hash[..]) |
397 | | { |
398 | 76 | visited_proof_entries_during_trie.push(value_position); |
399 | 76 | Some(value_entry_range.clone()) |
400 | | } else { |
401 | 0 | None |
402 | | } |
403 | | } |
404 | 24.2k | trie_node::StorageValue::Unhashed(v) => { |
405 | 24.2k | let offset = if !v.is_empty() { |
406 | 23.9k | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize |
407 | | } else { |
408 | 376 | 0 |
409 | | }; |
410 | 24.2k | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start23.9k ); |
411 | 24.2k | debug_assert!(offset <= visited_node_entry_range.end); |
412 | 24.2k | Some(offset..offset + v.len()) |
413 | | } |
414 | | }, |
415 | | child_entries_follow_up: 0, // Filled later. |
416 | | children_present_in_proof_bitmap: 0, // Filled later. |
417 | | }); |
418 | | |
419 | | // Add the visited node to the stack. The next iteration will either go to its first |
420 | | // child, or pop the node from the stack. |
421 | 30.9k | visited_entries_stack.push(StackEntry { |
422 | 30.9k | range_in_proof: visited_node_entry_range, |
423 | 30.9k | index_in_entries: entries.len() - 1, |
424 | 30.9k | num_visited_children: 0, |
425 | 30.9k | children_node_values: visited_node_decoded.children, |
426 | 30.9k | }); |
427 | | } |
428 | | } |
429 | | |
430 | | // The entire reason why we track the unvisited proof entries is to return this error if |
431 | | // necessary. |
432 | 1.51k | if !unvisited_proof_entries.is_empty() { |
433 | 0 | return Err(Error::UnusedProofEntry); |
434 | 1.51k | } |
435 | 1.51k | |
436 | 1.51k | drop(entries_by_merkle_value); |
437 | 1.51k | Ok(DecodedTrieProof { |
438 | 1.51k | proof: config.proof, |
439 | 1.51k | entries, |
440 | 1.51k | trie_roots: trie_roots_with_entries, |
441 | 1.51k | }) |
442 | 1.51k | } _RINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofAhj43e8_EB6_ Line | Count | Source | 61 | 1 | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> | 62 | 1 | where | 63 | 1 | T: AsRef<[u8]>, | 64 | 1 | { | 65 | 1 | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory | 66 | 1 | // location. | 67 | 1 | let proof_as_ref = config.proof.as_ref(); | 68 | | | 69 | | struct InProgressEntry<'a> { | 70 | | index_in_proof: usize, | 71 | | range_in_proof: ops::Range<usize>, | 72 | | decode_result: Result< | 73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, | 74 | | trie_node::Error, | 75 | | >, | 76 | | } | 77 | | | 78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. | 79 | | // | 80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In | 81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per | 82 | | // entry in `proof`. | 83 | | // | 84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is | 85 | | // possible for an attacker to craft a proof that leads to all entries being in the same | 86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which | 87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function | 88 | | // takes, it is always cause this function to return an error and is actually likely to make | 89 | | // the function actually take less time than if it was a legitimate proof. | 90 | 1 | let entries_by_merkle_value = { | 91 | | // TODO: don't use a Vec? | 92 | 1 | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( | 93 | 1 | crate::util::nom_scale_compact_usize, | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), | 95 | 1 | ))(config.proof.as_ref()) | 96 | 1 | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat)?0 ; | 97 | | | 98 | 1 | let entries_by_merkle_value = decoded_proof | 99 | 1 | .iter() | 100 | 1 | .copied() | 101 | 1 | .enumerate() | 102 | 1 | .map( | 103 | 1 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | | // The merkle value of a trie node is normally either its hash or the node | 105 | | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | | // we only hash each entry. | 108 | | let hash = *<&[u8; 32]>::try_from( | 109 | | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | | ) | 111 | | .unwrap(); | 112 | | | 113 | | let proof_entry_offset = if proof_entry.is_empty() { | 114 | | 0 | 115 | | } else { | 116 | | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | | ( | 120 | | hash, | 121 | | InProgressEntry { | 122 | | index_in_proof: proof_entry_num, | 123 | | range_in_proof: proof_entry_offset | 124 | | ..(proof_entry_offset + proof_entry.len()), | 125 | | decode_result: trie_node::decode(proof_entry), | 126 | | }, | 127 | | ) | 128 | 1 | }, | 129 | 1 | ) | 130 | 1 | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); | 131 | 1 | | 132 | 1 | // Using a hashmap has the consequence that if multiple proof entries were identical, only | 133 | 1 | // one would be tracked. This allows us to make sure that the proof doesn't contain | 134 | 1 | // multiple identical entries. | 135 | 1 | if entries_by_merkle_value.len() != decoded_proof.len() { | 136 | 0 | return Err(Error::DuplicateProofEntry); | 137 | 1 | } | 138 | 1 | | 139 | 1 | entries_by_merkle_value | 140 | | }; | 141 | | | 142 | | // Start by iterating over each element of the proof, and keep track of elements that are | 143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. | 144 | 1 | let trie_roots = { | 145 | 1 | let mut maybe_trie_roots = entries_by_merkle_value | 146 | 1 | .keys() | 147 | 1 | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 148 | 127 | for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter()1 { | 149 | 127 | let Ok(decoded98 ) = decode_result else { | 150 | 29 | maybe_trie_roots.remove(hash); | 151 | 29 | continue; | 152 | | }; | 153 | 393 | for child in decoded.children.into_iter().flatten()98 { | 154 | 393 | if let Ok(child340 ) = &<[u8; 32]>::try_from(child) { | 155 | 340 | maybe_trie_roots.remove(child); | 156 | 340 | }53 | 157 | | } | 158 | | } | 159 | 1 | maybe_trie_roots | 160 | 1 | }; | 161 | 1 | | 162 | 1 | // The implementation below iterates down the tree of nodes represented by this proof, keeping | 163 | 1 | // note of the traversed elements. | 164 | 1 | | 165 | 1 | // Keep track of all the entries found in the proof. | 166 | 1 | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); | 167 | 1 | | 168 | 1 | let mut trie_roots_with_entries = | 169 | 1 | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); | 170 | 1 | | 171 | 1 | // Keep track of the proof entries that haven't been visited when traversing. | 172 | 1 | let mut unvisited_proof_entries = | 173 | 1 | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 174 | | | 175 | | // We repeat this operation for every trie root. | 176 | 3 | for trie_root_hash2 in trie_roots { | 177 | | struct StackEntry<'a> { | 178 | | range_in_proof: ops::Range<usize>, | 179 | | index_in_entries: usize, | 180 | | num_visited_children: u8, | 181 | | children_node_values: [Option<&'a [u8]>; 16], | 182 | | } | 183 | | | 184 | | // Keep track of the number of entries before this trie root. | 185 | | // This allows us to truncate `entries` to this value in case of decoding failure. | 186 | 2 | let num_entries_before_current_trie_root = entries.len(); | 187 | 2 | | 188 | 2 | // Keep track of the indices of the proof entries that are visited when traversing this trie. | 189 | 2 | let mut visited_proof_entries_during_trie = | 190 | 2 | Vec::with_capacity(entries_by_merkle_value.len()); | 191 | 2 | | 192 | 2 | // TODO: configurable capacity? | 193 | 2 | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); | 194 | | | 195 | | loop { | 196 | | // Find which node to visit next. | 197 | | // This is the next child of the node at the top of the stack, or if the node at | 198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. | 199 | | // If the stack is empty, we are necessarily at the first iteration. | 200 | 149 | let (visited_node_entry_range, visited_node_decoded) = | 201 | 660 | match visited_entries_stack.last_mut() { | 202 | | None => { | 203 | | // Stack is empty. | 204 | | // Because we immediately `break` after popping the last element, the stack | 205 | | // can only ever be empty at the very start. | 206 | | let InProgressEntry { | 207 | 2 | index_in_proof: root_position, | 208 | 2 | range_in_proof: root_range, | 209 | 2 | decode_result, | 210 | 2 | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); | 211 | 2 | visited_proof_entries_during_trie.push(*root_position); | 212 | | // If the node can't be decoded, we ignore the entire trie and jump | 213 | | // to the next one. | 214 | 2 | let Ok(decoded) = decode_result.clone() else { | 215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); | 216 | 0 | break; | 217 | | }; | 218 | 2 | (root_range.clone(), decoded) | 219 | | } | 220 | | Some(StackEntry { | 221 | 658 | num_visited_children: stack_top_visited_children, | 222 | 658 | .. | 223 | 658 | }) if *stack_top_visited_children == 16147 => { | 224 | | // We have visited all the children of the top of the stack. Pop the node from | 225 | | // the stack. | 226 | | let Some(StackEntry { | 227 | 147 | index_in_entries: stack_top_index_in_entries, | 228 | | .. | 229 | 147 | }) = visited_entries_stack.pop() | 230 | | else { | 231 | 0 | unreachable!() | 232 | | }; | 233 | | | 234 | | // Update the value of `child_entries_follow_up` | 235 | | // and `children_present_in_proof_bitmap` of the parent. | 236 | | if let Some(&StackEntry { | 237 | 146 | index_in_entries: parent_index_in_entries, | 238 | 146 | num_visited_children: parent_children_visited, | 239 | | .. | 240 | 147 | }) = visited_entries_stack.last() | 241 | 146 | { | 242 | 146 | entries[parent_index_in_entries].child_entries_follow_up += | 243 | 146 | entries[stack_top_index_in_entries].child_entries_follow_up + 1; | 244 | 146 | entries[parent_index_in_entries].children_present_in_proof_bitmap |= | 245 | 146 | 1 << (parent_children_visited - 1); | 246 | 146 | }1 | 247 | | | 248 | | // If we popped the last node of the stack, we have finished the iteration. | 249 | 147 | if visited_entries_stack.is_empty() { | 250 | 1 | trie_roots_with_entries | 251 | 1 | .insert(*trie_root_hash, num_entries_before_current_trie_root); | 252 | | // Remove the visited entries from `unvisited_proof_entries`. | 253 | | // Note that it is questionable what to do if the same entry is visited | 254 | | // multiple times. In case where multiple storage branches are identical, | 255 | | // the sender of the proof should de-duplicate the identical nodes. For | 256 | | // this reason, it could be legitimate for the same proof entry to be | 257 | | // visited multiple times. | 258 | 137 | for entry_num136 in visited_proof_entries_during_trie { | 259 | 136 | unvisited_proof_entries.remove(&entry_num); | 260 | 136 | } | 261 | 1 | break; | 262 | | } else { | 263 | 146 | continue; | 264 | | } | 265 | | } | 266 | | Some(StackEntry { | 267 | 511 | range_in_proof: stack_top_proof_range, | 268 | 511 | num_visited_children: stack_top_visited_children, | 269 | 511 | children_node_values: stack_top_children, | 270 | 511 | .. | 271 | 511 | }) => { | 272 | 511 | // Find the next child of the top of the stack. | 273 | 511 | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; | 274 | 511 | | 275 | 511 | // Find the index of the next child (that we are about to visit). | 276 | 511 | let next_child_to_visit = stack_top_children | 277 | 511 | .iter() | 278 | 511 | .skip(usize::from(*stack_top_visited_children)) | 279 | 511 | .position(|c| c.is_some()) | 280 | 511 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) | 281 | 511 | .unwrap_or(16); | 282 | 511 | | 283 | 511 | // `continue` if all children have been visited. The next iteration will | 284 | 511 | // pop the stack entry. | 285 | 511 | if next_child_to_visit == 16 { | 286 | 119 | *stack_top_visited_children = 16; | 287 | 119 | continue; | 288 | 392 | } | 289 | 392 | *stack_top_visited_children = next_child_to_visit + 1; | 290 | 392 | | 291 | 392 | // The value of the child node is either directly inlined (if less | 292 | 392 | // than 32 bytes) or is a hash. | 293 | 392 | let child_node_value = | 294 | 392 | stack_top_children[usize::from(next_child_to_visit)].unwrap(); | 295 | 392 | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. | 296 | 392 | if child_node_value.len() < 32 { | 297 | 49 | let offset = stack_top_proof_range.start | 298 | 49 | + if !child_node_value.is_empty() { | 299 | 49 | child_node_value.as_ptr() as usize | 300 | 49 | - stack_top_entry.as_ptr() as usize | 301 | | } else { | 302 | 0 | 0 | 303 | | }; | 304 | 49 | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); | 305 | 49 | debug_assert!( | 306 | 49 | offset <= (stack_top_proof_range.start + stack_top_entry.len()) | 307 | | ); | 308 | | | 309 | 49 | let child_range_in_proof = offset..(offset + child_node_value.len()); | 310 | | | 311 | | // Decodes the child. | 312 | | // If the node can't be decoded, we ignore the entire trie and jump | 313 | | // to the next one. | 314 | 49 | let Ok(child_decoded) = | 315 | 49 | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) | 316 | | else { | 317 | 0 | entries.truncate(num_entries_before_current_trie_root); | 318 | 0 | break; | 319 | | }; | 320 | | | 321 | 49 | (child_range_in_proof, child_decoded) | 322 | | } else if let Some(&InProgressEntry { | 323 | 98 | index_in_proof: child_position, | 324 | 98 | range_in_proof: ref child_entry_range, | 325 | 98 | ref decode_result, | 326 | 343 | }) = entries_by_merkle_value.get(child_node_value) | 327 | | { | 328 | | // If the node value of the child is less than 32 bytes long, it should | 329 | | // have been inlined instead of given separately. | 330 | 98 | if child_entry_range.end - child_entry_range.start < 32 { | 331 | 0 | entries.truncate(num_entries_before_current_trie_root); | 332 | 0 | break; | 333 | 98 | } | 334 | 98 | | 335 | 98 | visited_proof_entries_during_trie.push(child_position); | 336 | | | 337 | | // If the node can't be decoded, we ignore the entire trie and jump | 338 | | // to the next one. | 339 | 98 | let Ok(decoded) = decode_result.clone() else { | 340 | 0 | entries.truncate(num_entries_before_current_trie_root); | 341 | 0 | break; | 342 | | }; | 343 | 98 | (child_entry_range.clone(), decoded) | 344 | | } else { | 345 | | // Child is a hash that was not found in the proof. Simply continue | 346 | | // iterating, in order to try to find the follow-up child. | 347 | 245 | continue; | 348 | | } | 349 | | } | 350 | | }; | 351 | | | 352 | | // All nodes must either have a child or a storage value or be the root. | 353 | 149 | if visited_node_decoded.children_bitmap() == 0 | 354 | 87 | && matches!( | 355 | 88 | visited_node_decoded.storage_value, | 356 | | trie_node::StorageValue::None | 357 | | ) | 358 | 1 | && !visited_entries_stack.is_empty() | 359 | | { | 360 | 1 | entries.truncate(num_entries_before_current_trie_root); | 361 | 1 | break; | 362 | 148 | } | 363 | 148 | | 364 | 148 | // Nodes with no storage value and one children are forbidden. | 365 | 148 | if visited_node_decoded | 366 | 148 | .children | 367 | 148 | .iter() | 368 | 148 | .filter(|c| c.is_some()) | 369 | 148 | .count() | 370 | 148 | == 1 | 371 | 0 | && matches!( | 372 | 0 | visited_node_decoded.storage_value, | 373 | | trie_node::StorageValue::None | 374 | | ) | 375 | | { | 376 | 0 | entries.truncate(num_entries_before_current_trie_root); | 377 | 0 | break; | 378 | 148 | } | 379 | 148 | | 380 | 148 | // Add an entry for this node in the final list of entries. | 381 | 148 | entries.push(Entry { | 382 | 148 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | | ( | 384 | | entry.index_in_entries, | 385 | | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | | ) | 387 | 148 | }), | 388 | 148 | range_in_proof: visited_node_entry_range.clone(), | 389 | 148 | storage_value_in_proof: match visited_node_decoded.storage_value { | 390 | 60 | trie_node::StorageValue::None => None, | 391 | 37 | trie_node::StorageValue::Hashed(value_hash) => { | 392 | | if let Some(&InProgressEntry { | 393 | 37 | index_in_proof: value_position, | 394 | 37 | range_in_proof: ref value_entry_range, | 395 | | .. | 396 | 37 | }) = entries_by_merkle_value.get(&value_hash[..]) | 397 | | { | 398 | 37 | visited_proof_entries_during_trie.push(value_position); | 399 | 37 | Some(value_entry_range.clone()) | 400 | | } else { | 401 | 0 | None | 402 | | } | 403 | | } | 404 | 51 | trie_node::StorageValue::Unhashed(v) => { | 405 | 51 | let offset = if !v.is_empty() { | 406 | 51 | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 407 | | } else { | 408 | 0 | 0 | 409 | | }; | 410 | 51 | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start); | 411 | 51 | debug_assert!(offset <= visited_node_entry_range.end); | 412 | 51 | Some(offset..offset + v.len()) | 413 | | } | 414 | | }, | 415 | | child_entries_follow_up: 0, // Filled later. | 416 | | children_present_in_proof_bitmap: 0, // Filled later. | 417 | | }); | 418 | | | 419 | | // Add the visited node to the stack. The next iteration will either go to its first | 420 | | // child, or pop the node from the stack. | 421 | 148 | visited_entries_stack.push(StackEntry { | 422 | 148 | range_in_proof: visited_node_entry_range, | 423 | 148 | index_in_entries: entries.len() - 1, | 424 | 148 | num_visited_children: 0, | 425 | 148 | children_node_values: visited_node_decoded.children, | 426 | 148 | }); | 427 | | } | 428 | | } | 429 | | | 430 | | // The entire reason why we track the unvisited proof entries is to return this error if | 431 | | // necessary. | 432 | 1 | if !unvisited_proof_entries.is_empty() { | 433 | 0 | return Err(Error::UnusedProofEntry); | 434 | 1 | } | 435 | 1 | | 436 | 1 | drop(entries_by_merkle_value); | 437 | 1 | Ok(DecodedTrieProof { | 438 | 1 | proof: config.proof, | 439 | 1 | entries, | 440 | 1 | trie_roots: trie_roots_with_entries, | 441 | 1 | }) | 442 | 1 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtCsdZExvAaxgia_5alloc3vec3VechEEB6_ Line | Count | Source | 61 | 1.50k | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> | 62 | 1.50k | where | 63 | 1.50k | T: AsRef<[u8]>, | 64 | 1.50k | { | 65 | 1.50k | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory | 66 | 1.50k | // location. | 67 | 1.50k | let proof_as_ref = config.proof.as_ref(); | 68 | | | 69 | | struct InProgressEntry<'a> { | 70 | | index_in_proof: usize, | 71 | | range_in_proof: ops::Range<usize>, | 72 | | decode_result: Result< | 73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, | 74 | | trie_node::Error, | 75 | | >, | 76 | | } | 77 | | | 78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. | 79 | | // | 80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In | 81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per | 82 | | // entry in `proof`. | 83 | | // | 84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is | 85 | | // possible for an attacker to craft a proof that leads to all entries being in the same | 86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which | 87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function | 88 | | // takes, it is always cause this function to return an error and is actually likely to make | 89 | | // the function actually take less time than if it was a legitimate proof. | 90 | 1.50k | let entries_by_merkle_value = { | 91 | | // TODO: don't use a Vec? | 92 | 1.50k | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( | 93 | 1.50k | crate::util::nom_scale_compact_usize, | 94 | 1.50k | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), | 95 | 1.50k | ))(config.proof.as_ref()) | 96 | 1.50k | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat)?0 ; | 97 | | | 98 | 1.50k | let entries_by_merkle_value = decoded_proof | 99 | 1.50k | .iter() | 100 | 1.50k | .copied() | 101 | 1.50k | .enumerate() | 102 | 1.50k | .map( | 103 | 1.50k | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | | // The merkle value of a trie node is normally either its hash or the node | 105 | | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | | // we only hash each entry. | 108 | | let hash = *<&[u8; 32]>::try_from( | 109 | | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | | ) | 111 | | .unwrap(); | 112 | | | 113 | | let proof_entry_offset = if proof_entry.is_empty() { | 114 | | 0 | 115 | | } else { | 116 | | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | | ( | 120 | | hash, | 121 | | InProgressEntry { | 122 | | index_in_proof: proof_entry_num, | 123 | | range_in_proof: proof_entry_offset | 124 | | ..(proof_entry_offset + proof_entry.len()), | 125 | | decode_result: trie_node::decode(proof_entry), | 126 | | }, | 127 | | ) | 128 | 1.50k | }, | 129 | 1.50k | ) | 130 | 1.50k | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); | 131 | 1.50k | | 132 | 1.50k | // Using a hashmap has the consequence that if multiple proof entries were identical, only | 133 | 1.50k | // one would be tracked. This allows us to make sure that the proof doesn't contain | 134 | 1.50k | // multiple identical entries. | 135 | 1.50k | if entries_by_merkle_value.len() != decoded_proof.len() { | 136 | 0 | return Err(Error::DuplicateProofEntry); | 137 | 1.50k | } | 138 | 1.50k | | 139 | 1.50k | entries_by_merkle_value | 140 | | }; | 141 | | | 142 | | // Start by iterating over each element of the proof, and keep track of elements that are | 143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. | 144 | 1.50k | let trie_roots = { | 145 | 1.50k | let mut maybe_trie_roots = entries_by_merkle_value | 146 | 1.50k | .keys() | 147 | 1.50k | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 148 | 19.9k | for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter()1.50k { | 149 | 19.9k | let Ok(decoded19.9k ) = decode_result else { | 150 | 2 | maybe_trie_roots.remove(hash); | 151 | 2 | continue; | 152 | | }; | 153 | 27.2k | for child in decoded.children.into_iter().flatten()19.9k { | 154 | 27.2k | if let Ok(child18.6k ) = &<[u8; 32]>::try_from(child) { | 155 | 18.6k | maybe_trie_roots.remove(child); | 156 | 18.6k | }8.59k | 157 | | } | 158 | | } | 159 | 1.50k | maybe_trie_roots | 160 | 1.50k | }; | 161 | 1.50k | | 162 | 1.50k | // The implementation below iterates down the tree of nodes represented by this proof, keeping | 163 | 1.50k | // note of the traversed elements. | 164 | 1.50k | | 165 | 1.50k | // Keep track of all the entries found in the proof. | 166 | 1.50k | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); | 167 | 1.50k | | 168 | 1.50k | let mut trie_roots_with_entries = | 169 | 1.50k | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); | 170 | 1.50k | | 171 | 1.50k | // Keep track of the proof entries that haven't been visited when traversing. | 172 | 1.50k | let mut unvisited_proof_entries = | 173 | 1.50k | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 174 | | | 175 | | // We repeat this operation for every trie root. | 176 | 3.00k | for trie_root_hash1.50k in trie_roots { | 177 | | struct StackEntry<'a> { | 178 | | range_in_proof: ops::Range<usize>, | 179 | | index_in_entries: usize, | 180 | | num_visited_children: u8, | 181 | | children_node_values: [Option<&'a [u8]>; 16], | 182 | | } | 183 | | | 184 | | // Keep track of the number of entries before this trie root. | 185 | | // This allows us to truncate `entries` to this value in case of decoding failure. | 186 | 1.50k | let num_entries_before_current_trie_root = entries.len(); | 187 | 1.50k | | 188 | 1.50k | // Keep track of the indices of the proof entries that are visited when traversing this trie. | 189 | 1.50k | let mut visited_proof_entries_during_trie = | 190 | 1.50k | Vec::with_capacity(entries_by_merkle_value.len()); | 191 | 1.50k | | 192 | 1.50k | // TODO: configurable capacity? | 193 | 1.50k | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); | 194 | | | 195 | | loop { | 196 | | // Find which node to visit next. | 197 | | // This is the next child of the node at the top of the stack, or if the node at | 198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. | 199 | | // If the stack is empty, we are necessarily at the first iteration. | 200 | 28.8k | let (visited_node_entry_range, visited_node_decoded) = | 201 | 85.0k | match visited_entries_stack.last_mut() { | 202 | | None => { | 203 | | // Stack is empty. | 204 | | // Because we immediately `break` after popping the last element, the stack | 205 | | // can only ever be empty at the very start. | 206 | | let InProgressEntry { | 207 | 1.50k | index_in_proof: root_position, | 208 | 1.50k | range_in_proof: root_range, | 209 | 1.50k | decode_result, | 210 | 1.50k | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); | 211 | 1.50k | visited_proof_entries_during_trie.push(*root_position); | 212 | | // If the node can't be decoded, we ignore the entire trie and jump | 213 | | // to the next one. | 214 | 1.50k | let Ok(decoded) = decode_result.clone() else { | 215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); | 216 | 0 | break; | 217 | | }; | 218 | 1.50k | (root_range.clone(), decoded) | 219 | | } | 220 | | Some(StackEntry { | 221 | 83.5k | num_visited_children: stack_top_visited_children, | 222 | 83.5k | .. | 223 | 83.5k | }) if *stack_top_visited_children == 1628.8k => { | 224 | | // We have visited all the children of the top of the stack. Pop the node from | 225 | | // the stack. | 226 | | let Some(StackEntry { | 227 | 28.8k | index_in_entries: stack_top_index_in_entries, | 228 | | .. | 229 | 28.8k | }) = visited_entries_stack.pop() | 230 | | else { | 231 | 0 | unreachable!() | 232 | | }; | 233 | | | 234 | | // Update the value of `child_entries_follow_up` | 235 | | // and `children_present_in_proof_bitmap` of the parent. | 236 | | if let Some(&StackEntry { | 237 | 27.3k | index_in_entries: parent_index_in_entries, | 238 | 27.3k | num_visited_children: parent_children_visited, | 239 | | .. | 240 | 28.8k | }) = visited_entries_stack.last() | 241 | 27.3k | { | 242 | 27.3k | entries[parent_index_in_entries].child_entries_follow_up += | 243 | 27.3k | entries[stack_top_index_in_entries].child_entries_follow_up + 1; | 244 | 27.3k | entries[parent_index_in_entries].children_present_in_proof_bitmap |= | 245 | 27.3k | 1 << (parent_children_visited - 1); | 246 | 27.3k | }1.50k | 247 | | | 248 | | // If we popped the last node of the stack, we have finished the iteration. | 249 | 28.8k | if visited_entries_stack.is_empty() { | 250 | 1.50k | trie_roots_with_entries | 251 | 1.50k | .insert(*trie_root_hash, num_entries_before_current_trie_root); | 252 | | // Remove the visited entries from `unvisited_proof_entries`. | 253 | | // Note that it is questionable what to do if the same entry is visited | 254 | | // multiple times. In case where multiple storage branches are identical, | 255 | | // the sender of the proof should de-duplicate the identical nodes. For | 256 | | // this reason, it could be legitimate for the same proof entry to be | 257 | | // visited multiple times. | 258 | 21.4k | for entry_num19.9k in visited_proof_entries_during_trie { | 259 | 19.9k | unvisited_proof_entries.remove(&entry_num); | 260 | 19.9k | } | 261 | 1.50k | break; | 262 | | } else { | 263 | 27.3k | continue; | 264 | | } | 265 | | } | 266 | | Some(StackEntry { | 267 | 54.6k | range_in_proof: stack_top_proof_range, | 268 | 54.6k | num_visited_children: stack_top_visited_children, | 269 | 54.6k | children_node_values: stack_top_children, | 270 | 54.6k | .. | 271 | 54.6k | }) => { | 272 | 54.6k | // Find the next child of the top of the stack. | 273 | 54.6k | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; | 274 | 54.6k | | 275 | 54.6k | // Find the index of the next child (that we are about to visit). | 276 | 54.6k | let next_child_to_visit = stack_top_children | 277 | 54.6k | .iter() | 278 | 54.6k | .skip(usize::from(*stack_top_visited_children)) | 279 | 54.6k | .position(|c| c.is_some()) | 280 | 54.6k | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) | 281 | 54.6k | .unwrap_or(16); | 282 | 54.6k | | 283 | 54.6k | // `continue` if all children have been visited. The next iteration will | 284 | 54.6k | // pop the stack entry. | 285 | 54.6k | if next_child_to_visit == 16 { | 286 | 27.0k | *stack_top_visited_children = 16; | 287 | 27.0k | continue; | 288 | 27.5k | } | 289 | 27.5k | *stack_top_visited_children = next_child_to_visit + 1; | 290 | 27.5k | | 291 | 27.5k | // The value of the child node is either directly inlined (if less | 292 | 27.5k | // than 32 bytes) or is a hash. | 293 | 27.5k | let child_node_value = | 294 | 27.5k | stack_top_children[usize::from(next_child_to_visit)].unwrap(); | 295 | 27.5k | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. | 296 | 27.5k | if child_node_value.len() < 32 { | 297 | 8.89k | let offset = stack_top_proof_range.start | 298 | 8.89k | + if !child_node_value.is_empty() { | 299 | 8.89k | child_node_value.as_ptr() as usize | 300 | 8.89k | - stack_top_entry.as_ptr() as usize | 301 | | } else { | 302 | 0 | 0 | 303 | | }; | 304 | 8.89k | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); | 305 | 8.89k | debug_assert!( | 306 | 8.89k | offset <= (stack_top_proof_range.start + stack_top_entry.len()) | 307 | | ); | 308 | | | 309 | 8.89k | let child_range_in_proof = offset..(offset + child_node_value.len()); | 310 | | | 311 | | // Decodes the child. | 312 | | // If the node can't be decoded, we ignore the entire trie and jump | 313 | | // to the next one. | 314 | 8.89k | let Ok(child_decoded) = | 315 | 8.89k | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) | 316 | | else { | 317 | 0 | entries.truncate(num_entries_before_current_trie_root); | 318 | 0 | break; | 319 | | }; | 320 | | | 321 | 8.89k | (child_range_in_proof, child_decoded) | 322 | | } else if let Some(&InProgressEntry { | 323 | 18.4k | index_in_proof: child_position, | 324 | 18.4k | range_in_proof: ref child_entry_range, | 325 | 18.4k | ref decode_result, | 326 | 18.6k | }) = entries_by_merkle_value.get(child_node_value) | 327 | | { | 328 | | // If the node value of the child is less than 32 bytes long, it should | 329 | | // have been inlined instead of given separately. | 330 | 18.4k | if child_entry_range.end - child_entry_range.start < 32 { | 331 | 0 | entries.truncate(num_entries_before_current_trie_root); | 332 | 0 | break; | 333 | 18.4k | } | 334 | 18.4k | | 335 | 18.4k | visited_proof_entries_during_trie.push(child_position); | 336 | | | 337 | | // If the node can't be decoded, we ignore the entire trie and jump | 338 | | // to the next one. | 339 | 18.4k | let Ok(decoded) = decode_result.clone() else { | 340 | 0 | entries.truncate(num_entries_before_current_trie_root); | 341 | 0 | break; | 342 | | }; | 343 | 18.4k | (child_entry_range.clone(), decoded) | 344 | | } else { | 345 | | // Child is a hash that was not found in the proof. Simply continue | 346 | | // iterating, in order to try to find the follow-up child. | 347 | 173 | continue; | 348 | | } | 349 | | } | 350 | | }; | 351 | | | 352 | | // All nodes must either have a child or a storage value or be the root. | 353 | 28.8k | if visited_node_decoded.children_bitmap() == 0 | 354 | 21.0k | && matches!( | 355 | 21.0k | visited_node_decoded.storage_value, | 356 | | trie_node::StorageValue::None | 357 | | ) | 358 | 0 | && !visited_entries_stack.is_empty() | 359 | | { | 360 | 0 | entries.truncate(num_entries_before_current_trie_root); | 361 | 0 | break; | 362 | 28.8k | } | 363 | 28.8k | | 364 | 28.8k | // Nodes with no storage value and one children are forbidden. | 365 | 28.8k | if visited_node_decoded | 366 | 28.8k | .children | 367 | 28.8k | .iter() | 368 | 28.8k | .filter(|c| c.is_some()) | 369 | 28.8k | .count() | 370 | 28.8k | == 1 | 371 | 703 | && matches!( | 372 | 703 | visited_node_decoded.storage_value, | 373 | | trie_node::StorageValue::None | 374 | | ) | 375 | | { | 376 | 0 | entries.truncate(num_entries_before_current_trie_root); | 377 | 0 | break; | 378 | 28.8k | } | 379 | 28.8k | | 380 | 28.8k | // Add an entry for this node in the final list of entries. | 381 | 28.8k | entries.push(Entry { | 382 | 28.8k | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | | ( | 384 | | entry.index_in_entries, | 385 | | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | | ) | 387 | 28.8k | }), | 388 | 28.8k | range_in_proof: visited_node_entry_range.clone(), | 389 | 28.8k | storage_value_in_proof: match visited_node_decoded.storage_value { | 390 | 5.61k | trie_node::StorageValue::None => None, | 391 | 2 | trie_node::StorageValue::Hashed(value_hash) => { | 392 | | if let Some(&InProgressEntry { | 393 | 2 | index_in_proof: value_position, | 394 | 2 | range_in_proof: ref value_entry_range, | 395 | | .. | 396 | 2 | }) = entries_by_merkle_value.get(&value_hash[..]) | 397 | | { | 398 | 2 | visited_proof_entries_during_trie.push(value_position); | 399 | 2 | Some(value_entry_range.clone()) | 400 | | } else { | 401 | 0 | None | 402 | | } | 403 | | } | 404 | 23.2k | trie_node::StorageValue::Unhashed(v) => { | 405 | 23.2k | let offset = if !v.is_empty() { | 406 | 22.8k | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 407 | | } else { | 408 | 376 | 0 | 409 | | }; | 410 | 23.2k | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start22.8k ); | 411 | 23.2k | debug_assert!(offset <= visited_node_entry_range.end); | 412 | 23.2k | Some(offset..offset + v.len()) | 413 | | } | 414 | | }, | 415 | | child_entries_follow_up: 0, // Filled later. | 416 | | children_present_in_proof_bitmap: 0, // Filled later. | 417 | | }); | 418 | | | 419 | | // Add the visited node to the stack. The next iteration will either go to its first | 420 | | // child, or pop the node from the stack. | 421 | 28.8k | visited_entries_stack.push(StackEntry { | 422 | 28.8k | range_in_proof: visited_node_entry_range, | 423 | 28.8k | index_in_entries: entries.len() - 1, | 424 | 28.8k | num_visited_children: 0, | 425 | 28.8k | children_node_values: visited_node_decoded.children, | 426 | 28.8k | }); | 427 | | } | 428 | | } | 429 | | | 430 | | // The entire reason why we track the unvisited proof entries is to return this error if | 431 | | // necessary. | 432 | 1.50k | if !unvisited_proof_entries.is_empty() { | 433 | 0 | return Err(Error::UnusedProofEntry); | 434 | 1.50k | } | 435 | 1.50k | | 436 | 1.50k | drop(entries_by_merkle_value); | 437 | 1.50k | Ok(DecodedTrieProof { | 438 | 1.50k | proof: config.proof, | 439 | 1.50k | entries, | 440 | 1.50k | trie_roots: trie_roots_with_entries, | 441 | 1.50k | }) | 442 | 1.50k | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj11_EB6_ Line | Count | Source | 61 | 1 | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> | 62 | 1 | where | 63 | 1 | T: AsRef<[u8]>, | 64 | 1 | { | 65 | 1 | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory | 66 | 1 | // location. | 67 | 1 | let proof_as_ref = config.proof.as_ref(); | 68 | | | 69 | | struct InProgressEntry<'a> { | 70 | | index_in_proof: usize, | 71 | | range_in_proof: ops::Range<usize>, | 72 | | decode_result: Result< | 73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, | 74 | | trie_node::Error, | 75 | | >, | 76 | | } | 77 | | | 78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. | 79 | | // | 80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In | 81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per | 82 | | // entry in `proof`. | 83 | | // | 84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is | 85 | | // possible for an attacker to craft a proof that leads to all entries being in the same | 86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which | 87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function | 88 | | // takes, it is always cause this function to return an error and is actually likely to make | 89 | | // the function actually take less time than if it was a legitimate proof. | 90 | 1 | let entries_by_merkle_value = { | 91 | | // TODO: don't use a Vec? | 92 | 1 | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( | 93 | 1 | crate::util::nom_scale_compact_usize, | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), | 95 | 1 | ))(config.proof.as_ref()) | 96 | 1 | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat)?0 ; | 97 | | | 98 | 1 | let entries_by_merkle_value = decoded_proof | 99 | 1 | .iter() | 100 | 1 | .copied() | 101 | 1 | .enumerate() | 102 | 1 | .map( | 103 | 1 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | | // The merkle value of a trie node is normally either its hash or the node | 105 | | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | | // we only hash each entry. | 108 | | let hash = *<&[u8; 32]>::try_from( | 109 | | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | | ) | 111 | | .unwrap(); | 112 | | | 113 | | let proof_entry_offset = if proof_entry.is_empty() { | 114 | | 0 | 115 | | } else { | 116 | | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | | ( | 120 | | hash, | 121 | | InProgressEntry { | 122 | | index_in_proof: proof_entry_num, | 123 | | range_in_proof: proof_entry_offset | 124 | | ..(proof_entry_offset + proof_entry.len()), | 125 | | decode_result: trie_node::decode(proof_entry), | 126 | | }, | 127 | | ) | 128 | 1 | }, | 129 | 1 | ) | 130 | 1 | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); | 131 | 1 | | 132 | 1 | // Using a hashmap has the consequence that if multiple proof entries were identical, only | 133 | 1 | // one would be tracked. This allows us to make sure that the proof doesn't contain | 134 | 1 | // multiple identical entries. | 135 | 1 | if entries_by_merkle_value.len() != decoded_proof.len() { | 136 | 0 | return Err(Error::DuplicateProofEntry); | 137 | 1 | } | 138 | 1 | | 139 | 1 | entries_by_merkle_value | 140 | | }; | 141 | | | 142 | | // Start by iterating over each element of the proof, and keep track of elements that are | 143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. | 144 | 1 | let trie_roots = { | 145 | 1 | let mut maybe_trie_roots = entries_by_merkle_value | 146 | 1 | .keys() | 147 | 1 | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 148 | 1 | for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter() { | 149 | 1 | let Ok(decoded) = decode_result else { | 150 | 0 | maybe_trie_roots.remove(hash); | 151 | 0 | continue; | 152 | | }; | 153 | 2 | for child in decoded.children.into_iter().flatten()1 { | 154 | 2 | if let Ok(child0 ) = &<[u8; 32]>::try_from(child) { | 155 | 0 | maybe_trie_roots.remove(child); | 156 | 2 | } | 157 | | } | 158 | | } | 159 | 1 | maybe_trie_roots | 160 | 1 | }; | 161 | 1 | | 162 | 1 | // The implementation below iterates down the tree of nodes represented by this proof, keeping | 163 | 1 | // note of the traversed elements. | 164 | 1 | | 165 | 1 | // Keep track of all the entries found in the proof. | 166 | 1 | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); | 167 | 1 | | 168 | 1 | let mut trie_roots_with_entries = | 169 | 1 | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); | 170 | 1 | | 171 | 1 | // Keep track of the proof entries that haven't been visited when traversing. | 172 | 1 | let mut unvisited_proof_entries = | 173 | 1 | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 174 | | | 175 | | // We repeat this operation for every trie root. | 176 | 2 | for trie_root_hash1 in trie_roots { | 177 | | struct StackEntry<'a> { | 178 | | range_in_proof: ops::Range<usize>, | 179 | | index_in_entries: usize, | 180 | | num_visited_children: u8, | 181 | | children_node_values: [Option<&'a [u8]>; 16], | 182 | | } | 183 | | | 184 | | // Keep track of the number of entries before this trie root. | 185 | | // This allows us to truncate `entries` to this value in case of decoding failure. | 186 | 1 | let num_entries_before_current_trie_root = entries.len(); | 187 | 1 | | 188 | 1 | // Keep track of the indices of the proof entries that are visited when traversing this trie. | 189 | 1 | let mut visited_proof_entries_during_trie = | 190 | 1 | Vec::with_capacity(entries_by_merkle_value.len()); | 191 | 1 | | 192 | 1 | // TODO: configurable capacity? | 193 | 1 | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); | 194 | | | 195 | | loop { | 196 | | // Find which node to visit next. | 197 | | // This is the next child of the node at the top of the stack, or if the node at | 198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. | 199 | | // If the stack is empty, we are necessarily at the first iteration. | 200 | 3 | let (visited_node_entry_range, visited_node_decoded) = | 201 | 9 | match visited_entries_stack.last_mut() { | 202 | | None => { | 203 | | // Stack is empty. | 204 | | // Because we immediately `break` after popping the last element, the stack | 205 | | // can only ever be empty at the very start. | 206 | | let InProgressEntry { | 207 | 1 | index_in_proof: root_position, | 208 | 1 | range_in_proof: root_range, | 209 | 1 | decode_result, | 210 | 1 | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); | 211 | 1 | visited_proof_entries_during_trie.push(*root_position); | 212 | | // If the node can't be decoded, we ignore the entire trie and jump | 213 | | // to the next one. | 214 | 1 | let Ok(decoded) = decode_result.clone() else { | 215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); | 216 | 0 | break; | 217 | | }; | 218 | 1 | (root_range.clone(), decoded) | 219 | | } | 220 | | Some(StackEntry { | 221 | 8 | num_visited_children: stack_top_visited_children, | 222 | 8 | .. | 223 | 8 | }) if *stack_top_visited_children == 163 => { | 224 | | // We have visited all the children of the top of the stack. Pop the node from | 225 | | // the stack. | 226 | | let Some(StackEntry { | 227 | 3 | index_in_entries: stack_top_index_in_entries, | 228 | | .. | 229 | 3 | }) = visited_entries_stack.pop() | 230 | | else { | 231 | 0 | unreachable!() | 232 | | }; | 233 | | | 234 | | // Update the value of `child_entries_follow_up` | 235 | | // and `children_present_in_proof_bitmap` of the parent. | 236 | | if let Some(&StackEntry { | 237 | 2 | index_in_entries: parent_index_in_entries, | 238 | 2 | num_visited_children: parent_children_visited, | 239 | | .. | 240 | 3 | }) = visited_entries_stack.last() | 241 | 2 | { | 242 | 2 | entries[parent_index_in_entries].child_entries_follow_up += | 243 | 2 | entries[stack_top_index_in_entries].child_entries_follow_up + 1; | 244 | 2 | entries[parent_index_in_entries].children_present_in_proof_bitmap |= | 245 | 2 | 1 << (parent_children_visited - 1); | 246 | 2 | }1 | 247 | | | 248 | | // If we popped the last node of the stack, we have finished the iteration. | 249 | 3 | if visited_entries_stack.is_empty() { | 250 | 1 | trie_roots_with_entries | 251 | 1 | .insert(*trie_root_hash, num_entries_before_current_trie_root); | 252 | | // Remove the visited entries from `unvisited_proof_entries`. | 253 | | // Note that it is questionable what to do if the same entry is visited | 254 | | // multiple times. In case where multiple storage branches are identical, | 255 | | // the sender of the proof should de-duplicate the identical nodes. For | 256 | | // this reason, it could be legitimate for the same proof entry to be | 257 | | // visited multiple times. | 258 | 2 | for entry_num1 in visited_proof_entries_during_trie { | 259 | 1 | unvisited_proof_entries.remove(&entry_num); | 260 | 1 | } | 261 | 1 | break; | 262 | | } else { | 263 | 2 | continue; | 264 | | } | 265 | | } | 266 | | Some(StackEntry { | 267 | 5 | range_in_proof: stack_top_proof_range, | 268 | 5 | num_visited_children: stack_top_visited_children, | 269 | 5 | children_node_values: stack_top_children, | 270 | 5 | .. | 271 | 5 | }) => { | 272 | 5 | // Find the next child of the top of the stack. | 273 | 5 | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; | 274 | 5 | | 275 | 5 | // Find the index of the next child (that we are about to visit). | 276 | 5 | let next_child_to_visit = stack_top_children | 277 | 5 | .iter() | 278 | 5 | .skip(usize::from(*stack_top_visited_children)) | 279 | 5 | .position(|c| c.is_some()) | 280 | 5 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) | 281 | 5 | .unwrap_or(16); | 282 | 5 | | 283 | 5 | // `continue` if all children have been visited. The next iteration will | 284 | 5 | // pop the stack entry. | 285 | 5 | if next_child_to_visit == 16 { | 286 | 3 | *stack_top_visited_children = 16; | 287 | 3 | continue; | 288 | 2 | } | 289 | 2 | *stack_top_visited_children = next_child_to_visit + 1; | 290 | 2 | | 291 | 2 | // The value of the child node is either directly inlined (if less | 292 | 2 | // than 32 bytes) or is a hash. | 293 | 2 | let child_node_value = | 294 | 2 | stack_top_children[usize::from(next_child_to_visit)].unwrap(); | 295 | 2 | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. | 296 | 2 | if child_node_value.len() < 32 { | 297 | 2 | let offset = stack_top_proof_range.start | 298 | 2 | + if !child_node_value.is_empty() { | 299 | 2 | child_node_value.as_ptr() as usize | 300 | 2 | - stack_top_entry.as_ptr() as usize | 301 | | } else { | 302 | 0 | 0 | 303 | | }; | 304 | 2 | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); | 305 | 2 | debug_assert!( | 306 | 2 | offset <= (stack_top_proof_range.start + stack_top_entry.len()) | 307 | | ); | 308 | | | 309 | 2 | let child_range_in_proof = offset..(offset + child_node_value.len()); | 310 | | | 311 | | // Decodes the child. | 312 | | // If the node can't be decoded, we ignore the entire trie and jump | 313 | | // to the next one. | 314 | 2 | let Ok(child_decoded) = | 315 | 2 | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) | 316 | | else { | 317 | 0 | entries.truncate(num_entries_before_current_trie_root); | 318 | 0 | break; | 319 | | }; | 320 | | | 321 | 2 | (child_range_in_proof, child_decoded) | 322 | | } else if let Some(&InProgressEntry { | 323 | 0 | index_in_proof: child_position, | 324 | 0 | range_in_proof: ref child_entry_range, | 325 | 0 | ref decode_result, | 326 | 0 | }) = entries_by_merkle_value.get(child_node_value) | 327 | | { | 328 | | // If the node value of the child is less than 32 bytes long, it should | 329 | | // have been inlined instead of given separately. | 330 | 0 | if child_entry_range.end - child_entry_range.start < 32 { | 331 | 0 | entries.truncate(num_entries_before_current_trie_root); | 332 | 0 | break; | 333 | 0 | } | 334 | 0 |
| 335 | 0 | visited_proof_entries_during_trie.push(child_position); | 336 | | | 337 | | // If the node can't be decoded, we ignore the entire trie and jump | 338 | | // to the next one. | 339 | 0 | let Ok(decoded) = decode_result.clone() else { | 340 | 0 | entries.truncate(num_entries_before_current_trie_root); | 341 | 0 | break; | 342 | | }; | 343 | 0 | (child_entry_range.clone(), decoded) | 344 | | } else { | 345 | | // Child is a hash that was not found in the proof. Simply continue | 346 | | // iterating, in order to try to find the follow-up child. | 347 | 0 | continue; | 348 | | } | 349 | | } | 350 | | }; | 351 | | | 352 | | // All nodes must either have a child or a storage value or be the root. | 353 | 3 | if visited_node_decoded.children_bitmap() == 0 | 354 | 2 | && matches!( | 355 | 2 | visited_node_decoded.storage_value, | 356 | | trie_node::StorageValue::None | 357 | | ) | 358 | 0 | && !visited_entries_stack.is_empty() | 359 | | { | 360 | 0 | entries.truncate(num_entries_before_current_trie_root); | 361 | 0 | break; | 362 | 3 | } | 363 | 3 | | 364 | 3 | // Nodes with no storage value and one children are forbidden. | 365 | 3 | if visited_node_decoded | 366 | 3 | .children | 367 | 3 | .iter() | 368 | 3 | .filter(|c| c.is_some()) | 369 | 3 | .count() | 370 | 3 | == 1 | 371 | 0 | && matches!( | 372 | 0 | visited_node_decoded.storage_value, | 373 | | trie_node::StorageValue::None | 374 | | ) | 375 | | { | 376 | 0 | entries.truncate(num_entries_before_current_trie_root); | 377 | 0 | break; | 378 | 3 | } | 379 | 3 | | 380 | 3 | // Add an entry for this node in the final list of entries. | 381 | 3 | entries.push(Entry { | 382 | 3 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | | ( | 384 | | entry.index_in_entries, | 385 | | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | | ) | 387 | 3 | }), | 388 | 3 | range_in_proof: visited_node_entry_range.clone(), | 389 | 3 | storage_value_in_proof: match visited_node_decoded.storage_value { | 390 | 1 | trie_node::StorageValue::None => None, | 391 | 0 | trie_node::StorageValue::Hashed(value_hash) => { | 392 | | if let Some(&InProgressEntry { | 393 | 0 | index_in_proof: value_position, | 394 | 0 | range_in_proof: ref value_entry_range, | 395 | | .. | 396 | 0 | }) = entries_by_merkle_value.get(&value_hash[..]) | 397 | | { | 398 | 0 | visited_proof_entries_during_trie.push(value_position); | 399 | 0 | Some(value_entry_range.clone()) | 400 | | } else { | 401 | 0 | None | 402 | | } | 403 | | } | 404 | 2 | trie_node::StorageValue::Unhashed(v) => { | 405 | 2 | let offset = if !v.is_empty() { | 406 | 2 | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 407 | | } else { | 408 | 0 | 0 | 409 | | }; | 410 | 2 | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start); | 411 | 2 | debug_assert!(offset <= visited_node_entry_range.end); | 412 | 2 | Some(offset..offset + v.len()) | 413 | | } | 414 | | }, | 415 | | child_entries_follow_up: 0, // Filled later. | 416 | | children_present_in_proof_bitmap: 0, // Filled later. | 417 | | }); | 418 | | | 419 | | // Add the visited node to the stack. The next iteration will either go to its first | 420 | | // child, or pop the node from the stack. | 421 | 3 | visited_entries_stack.push(StackEntry { | 422 | 3 | range_in_proof: visited_node_entry_range, | 423 | 3 | index_in_entries: entries.len() - 1, | 424 | 3 | num_visited_children: 0, | 425 | 3 | children_node_values: visited_node_decoded.children, | 426 | 3 | }); | 427 | | } | 428 | | } | 429 | | | 430 | | // The entire reason why we track the unvisited proof entries is to return this error if | 431 | | // necessary. | 432 | 1 | if !unvisited_proof_entries.is_empty() { | 433 | 0 | return Err(Error::UnusedProofEntry); | 434 | 1 | } | 435 | 1 | | 436 | 1 | drop(entries_by_merkle_value); | 437 | 1 | Ok(DecodedTrieProof { | 438 | 1 | proof: config.proof, | 439 | 1 | entries, | 440 | 1 | trie_roots: trie_roots_with_entries, | 441 | 1 | }) | 442 | 1 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj1_EB6_ Line | Count | Source | 61 | 1 | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> | 62 | 1 | where | 63 | 1 | T: AsRef<[u8]>, | 64 | 1 | { | 65 | 1 | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory | 66 | 1 | // location. | 67 | 1 | let proof_as_ref = config.proof.as_ref(); | 68 | | | 69 | | struct InProgressEntry<'a> { | 70 | | index_in_proof: usize, | 71 | | range_in_proof: ops::Range<usize>, | 72 | | decode_result: Result< | 73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, | 74 | | trie_node::Error, | 75 | | >, | 76 | | } | 77 | | | 78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. | 79 | | // | 80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In | 81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per | 82 | | // entry in `proof`. | 83 | | // | 84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is | 85 | | // possible for an attacker to craft a proof that leads to all entries being in the same | 86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which | 87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function | 88 | | // takes, it is always cause this function to return an error and is actually likely to make | 89 | | // the function actually take less time than if it was a legitimate proof. | 90 | 1 | let entries_by_merkle_value = { | 91 | | // TODO: don't use a Vec? | 92 | 1 | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( | 93 | 1 | crate::util::nom_scale_compact_usize, | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), | 95 | 1 | ))(config.proof.as_ref()) | 96 | 1 | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat)?0 ; | 97 | | | 98 | 1 | let entries_by_merkle_value = decoded_proof | 99 | 1 | .iter() | 100 | 1 | .copied() | 101 | 1 | .enumerate() | 102 | 1 | .map( | 103 | 1 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | | // The merkle value of a trie node is normally either its hash or the node | 105 | | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | | // we only hash each entry. | 108 | | let hash = *<&[u8; 32]>::try_from( | 109 | | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | | ) | 111 | | .unwrap(); | 112 | | | 113 | | let proof_entry_offset = if proof_entry.is_empty() { | 114 | | 0 | 115 | | } else { | 116 | | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | | ( | 120 | | hash, | 121 | | InProgressEntry { | 122 | | index_in_proof: proof_entry_num, | 123 | | range_in_proof: proof_entry_offset | 124 | | ..(proof_entry_offset + proof_entry.len()), | 125 | | decode_result: trie_node::decode(proof_entry), | 126 | | }, | 127 | | ) | 128 | 1 | }, | 129 | 1 | ) | 130 | 1 | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); | 131 | 1 | | 132 | 1 | // Using a hashmap has the consequence that if multiple proof entries were identical, only | 133 | 1 | // one would be tracked. This allows us to make sure that the proof doesn't contain | 134 | 1 | // multiple identical entries. | 135 | 1 | if entries_by_merkle_value.len() != decoded_proof.len() { | 136 | 0 | return Err(Error::DuplicateProofEntry); | 137 | 1 | } | 138 | 1 | | 139 | 1 | entries_by_merkle_value | 140 | | }; | 141 | | | 142 | | // Start by iterating over each element of the proof, and keep track of elements that are | 143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. | 144 | 1 | let trie_roots = { | 145 | 1 | let mut maybe_trie_roots = entries_by_merkle_value | 146 | 1 | .keys() | 147 | 1 | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 148 | 1 | for (hash, InProgressEntry { decode_result0 , .. }) in entries_by_merkle_value.iter() { | 149 | 0 | let Ok(decoded) = decode_result else { | 150 | 0 | maybe_trie_roots.remove(hash); | 151 | 0 | continue; | 152 | | }; | 153 | 0 | for child in decoded.children.into_iter().flatten() { | 154 | 0 | if let Ok(child) = &<[u8; 32]>::try_from(child) { | 155 | 0 | maybe_trie_roots.remove(child); | 156 | 0 | } | 157 | | } | 158 | | } | 159 | 1 | maybe_trie_roots | 160 | 1 | }; | 161 | 1 | | 162 | 1 | // The implementation below iterates down the tree of nodes represented by this proof, keeping | 163 | 1 | // note of the traversed elements. | 164 | 1 | | 165 | 1 | // Keep track of all the entries found in the proof. | 166 | 1 | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); | 167 | 1 | | 168 | 1 | let mut trie_roots_with_entries = | 169 | 1 | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); | 170 | 1 | | 171 | 1 | // Keep track of the proof entries that haven't been visited when traversing. | 172 | 1 | let mut unvisited_proof_entries = | 173 | 1 | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 174 | | | 175 | | // We repeat this operation for every trie root. | 176 | 1 | for trie_root_hash0 in trie_roots { | 177 | | struct StackEntry<'a> { | 178 | | range_in_proof: ops::Range<usize>, | 179 | | index_in_entries: usize, | 180 | | num_visited_children: u8, | 181 | | children_node_values: [Option<&'a [u8]>; 16], | 182 | | } | 183 | | | 184 | | // Keep track of the number of entries before this trie root. | 185 | | // This allows us to truncate `entries` to this value in case of decoding failure. | 186 | 0 | let num_entries_before_current_trie_root = entries.len(); | 187 | 0 |
| 188 | 0 | // Keep track of the indices of the proof entries that are visited when traversing this trie. | 189 | 0 | let mut visited_proof_entries_during_trie = | 190 | 0 | Vec::with_capacity(entries_by_merkle_value.len()); | 191 | 0 |
| 192 | 0 | // TODO: configurable capacity? | 193 | 0 | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); | 194 | | | 195 | | loop { | 196 | | // Find which node to visit next. | 197 | | // This is the next child of the node at the top of the stack, or if the node at | 198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. | 199 | | // If the stack is empty, we are necessarily at the first iteration. | 200 | 0 | let (visited_node_entry_range, visited_node_decoded) = | 201 | 0 | match visited_entries_stack.last_mut() { | 202 | | None => { | 203 | | // Stack is empty. | 204 | | // Because we immediately `break` after popping the last element, the stack | 205 | | // can only ever be empty at the very start. | 206 | | let InProgressEntry { | 207 | 0 | index_in_proof: root_position, | 208 | 0 | range_in_proof: root_range, | 209 | 0 | decode_result, | 210 | 0 | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); | 211 | 0 | visited_proof_entries_during_trie.push(*root_position); | 212 | | // If the node can't be decoded, we ignore the entire trie and jump | 213 | | // to the next one. | 214 | 0 | let Ok(decoded) = decode_result.clone() else { | 215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); | 216 | 0 | break; | 217 | | }; | 218 | 0 | (root_range.clone(), decoded) | 219 | | } | 220 | | Some(StackEntry { | 221 | 0 | num_visited_children: stack_top_visited_children, | 222 | 0 | .. | 223 | 0 | }) if *stack_top_visited_children == 16 => { | 224 | | // We have visited all the children of the top of the stack. Pop the node from | 225 | | // the stack. | 226 | | let Some(StackEntry { | 227 | 0 | index_in_entries: stack_top_index_in_entries, | 228 | | .. | 229 | 0 | }) = visited_entries_stack.pop() | 230 | | else { | 231 | 0 | unreachable!() | 232 | | }; | 233 | | | 234 | | // Update the value of `child_entries_follow_up` | 235 | | // and `children_present_in_proof_bitmap` of the parent. | 236 | | if let Some(&StackEntry { | 237 | 0 | index_in_entries: parent_index_in_entries, | 238 | 0 | num_visited_children: parent_children_visited, | 239 | | .. | 240 | 0 | }) = visited_entries_stack.last() | 241 | 0 | { | 242 | 0 | entries[parent_index_in_entries].child_entries_follow_up += | 243 | 0 | entries[stack_top_index_in_entries].child_entries_follow_up + 1; | 244 | 0 | entries[parent_index_in_entries].children_present_in_proof_bitmap |= | 245 | 0 | 1 << (parent_children_visited - 1); | 246 | 0 | } | 247 | | | 248 | | // If we popped the last node of the stack, we have finished the iteration. | 249 | 0 | if visited_entries_stack.is_empty() { | 250 | 0 | trie_roots_with_entries | 251 | 0 | .insert(*trie_root_hash, num_entries_before_current_trie_root); | 252 | | // Remove the visited entries from `unvisited_proof_entries`. | 253 | | // Note that it is questionable what to do if the same entry is visited | 254 | | // multiple times. In case where multiple storage branches are identical, | 255 | | // the sender of the proof should de-duplicate the identical nodes. For | 256 | | // this reason, it could be legitimate for the same proof entry to be | 257 | | // visited multiple times. | 258 | 0 | for entry_num in visited_proof_entries_during_trie { | 259 | 0 | unvisited_proof_entries.remove(&entry_num); | 260 | 0 | } | 261 | 0 | break; | 262 | | } else { | 263 | 0 | continue; | 264 | | } | 265 | | } | 266 | | Some(StackEntry { | 267 | 0 | range_in_proof: stack_top_proof_range, | 268 | 0 | num_visited_children: stack_top_visited_children, | 269 | 0 | children_node_values: stack_top_children, | 270 | 0 | .. | 271 | 0 | }) => { | 272 | 0 | // Find the next child of the top of the stack. | 273 | 0 | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; | 274 | 0 |
| 275 | 0 | // Find the index of the next child (that we are about to visit). | 276 | 0 | let next_child_to_visit = stack_top_children | 277 | 0 | .iter() | 278 | 0 | .skip(usize::from(*stack_top_visited_children)) | 279 | 0 | .position(|c| c.is_some()) | 280 | 0 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) | 281 | 0 | .unwrap_or(16); | 282 | 0 |
| 283 | 0 | // `continue` if all children have been visited. The next iteration will | 284 | 0 | // pop the stack entry. | 285 | 0 | if next_child_to_visit == 16 { | 286 | 0 | *stack_top_visited_children = 16; | 287 | 0 | continue; | 288 | 0 | } | 289 | 0 | *stack_top_visited_children = next_child_to_visit + 1; | 290 | 0 |
| 291 | 0 | // The value of the child node is either directly inlined (if less | 292 | 0 | // than 32 bytes) or is a hash. | 293 | 0 | let child_node_value = | 294 | 0 | stack_top_children[usize::from(next_child_to_visit)].unwrap(); | 295 | 0 | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. | 296 | 0 | if child_node_value.len() < 32 { | 297 | 0 | let offset = stack_top_proof_range.start | 298 | 0 | + if !child_node_value.is_empty() { | 299 | 0 | child_node_value.as_ptr() as usize | 300 | 0 | - stack_top_entry.as_ptr() as usize | 301 | | } else { | 302 | 0 | 0 | 303 | | }; | 304 | 0 | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); | 305 | 0 | debug_assert!( | 306 | 0 | offset <= (stack_top_proof_range.start + stack_top_entry.len()) | 307 | | ); | 308 | | | 309 | 0 | let child_range_in_proof = offset..(offset + child_node_value.len()); | 310 | | | 311 | | // Decodes the child. | 312 | | // If the node can't be decoded, we ignore the entire trie and jump | 313 | | // to the next one. | 314 | 0 | let Ok(child_decoded) = | 315 | 0 | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) | 316 | | else { | 317 | 0 | entries.truncate(num_entries_before_current_trie_root); | 318 | 0 | break; | 319 | | }; | 320 | | | 321 | 0 | (child_range_in_proof, child_decoded) | 322 | | } else if let Some(&InProgressEntry { | 323 | 0 | index_in_proof: child_position, | 324 | 0 | range_in_proof: ref child_entry_range, | 325 | 0 | ref decode_result, | 326 | 0 | }) = entries_by_merkle_value.get(child_node_value) | 327 | | { | 328 | | // If the node value of the child is less than 32 bytes long, it should | 329 | | // have been inlined instead of given separately. | 330 | 0 | if child_entry_range.end - child_entry_range.start < 32 { | 331 | 0 | entries.truncate(num_entries_before_current_trie_root); | 332 | 0 | break; | 333 | 0 | } | 334 | 0 |
| 335 | 0 | visited_proof_entries_during_trie.push(child_position); | 336 | | | 337 | | // If the node can't be decoded, we ignore the entire trie and jump | 338 | | // to the next one. | 339 | 0 | let Ok(decoded) = decode_result.clone() else { | 340 | 0 | entries.truncate(num_entries_before_current_trie_root); | 341 | 0 | break; | 342 | | }; | 343 | 0 | (child_entry_range.clone(), decoded) | 344 | | } else { | 345 | | // Child is a hash that was not found in the proof. Simply continue | 346 | | // iterating, in order to try to find the follow-up child. | 347 | 0 | continue; | 348 | | } | 349 | | } | 350 | | }; | 351 | | | 352 | | // All nodes must either have a child or a storage value or be the root. | 353 | 0 | if visited_node_decoded.children_bitmap() == 0 | 354 | 0 | && matches!( | 355 | 0 | visited_node_decoded.storage_value, | 356 | | trie_node::StorageValue::None | 357 | | ) | 358 | 0 | && !visited_entries_stack.is_empty() | 359 | | { | 360 | 0 | entries.truncate(num_entries_before_current_trie_root); | 361 | 0 | break; | 362 | 0 | } | 363 | 0 |
| 364 | 0 | // Nodes with no storage value and one children are forbidden. | 365 | 0 | if visited_node_decoded | 366 | 0 | .children | 367 | 0 | .iter() | 368 | 0 | .filter(|c| c.is_some()) | 369 | 0 | .count() | 370 | 0 | == 1 | 371 | 0 | && matches!( | 372 | 0 | visited_node_decoded.storage_value, | 373 | | trie_node::StorageValue::None | 374 | | ) | 375 | | { | 376 | 0 | entries.truncate(num_entries_before_current_trie_root); | 377 | 0 | break; | 378 | 0 | } | 379 | 0 |
| 380 | 0 | // Add an entry for this node in the final list of entries. | 381 | 0 | entries.push(Entry { | 382 | 0 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | | ( | 384 | | entry.index_in_entries, | 385 | | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | | ) | 387 | 0 | }), | 388 | 0 | range_in_proof: visited_node_entry_range.clone(), | 389 | 0 | storage_value_in_proof: match visited_node_decoded.storage_value { | 390 | 0 | trie_node::StorageValue::None => None, | 391 | 0 | trie_node::StorageValue::Hashed(value_hash) => { | 392 | | if let Some(&InProgressEntry { | 393 | 0 | index_in_proof: value_position, | 394 | 0 | range_in_proof: ref value_entry_range, | 395 | | .. | 396 | 0 | }) = entries_by_merkle_value.get(&value_hash[..]) | 397 | | { | 398 | 0 | visited_proof_entries_during_trie.push(value_position); | 399 | 0 | Some(value_entry_range.clone()) | 400 | | } else { | 401 | 0 | None | 402 | | } | 403 | | } | 404 | 0 | trie_node::StorageValue::Unhashed(v) => { | 405 | 0 | let offset = if !v.is_empty() { | 406 | 0 | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 407 | | } else { | 408 | 0 | 0 | 409 | | }; | 410 | 0 | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start); | 411 | 0 | debug_assert!(offset <= visited_node_entry_range.end); | 412 | 0 | Some(offset..offset + v.len()) | 413 | | } | 414 | | }, | 415 | | child_entries_follow_up: 0, // Filled later. | 416 | | children_present_in_proof_bitmap: 0, // Filled later. | 417 | | }); | 418 | | | 419 | | // Add the visited node to the stack. The next iteration will either go to its first | 420 | | // child, or pop the node from the stack. | 421 | 0 | visited_entries_stack.push(StackEntry { | 422 | 0 | range_in_proof: visited_node_entry_range, | 423 | 0 | index_in_entries: entries.len() - 1, | 424 | 0 | num_visited_children: 0, | 425 | 0 | children_node_values: visited_node_decoded.children, | 426 | 0 | }); | 427 | | } | 428 | | } | 429 | | | 430 | | // The entire reason why we track the unvisited proof entries is to return this error if | 431 | | // necessary. | 432 | 1 | if !unvisited_proof_entries.is_empty() { | 433 | 0 | return Err(Error::UnusedProofEntry); | 434 | 1 | } | 435 | 1 | | 436 | 1 | drop(entries_by_merkle_value); | 437 | 1 | Ok(DecodedTrieProof { | 438 | 1 | proof: config.proof, | 439 | 1 | entries, | 440 | 1 | trie_roots: trie_roots_with_entries, | 441 | 1 | }) | 442 | 1 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhj4385_EB6_ Line | Count | Source | 61 | 1 | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> | 62 | 1 | where | 63 | 1 | T: AsRef<[u8]>, | 64 | 1 | { | 65 | 1 | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory | 66 | 1 | // location. | 67 | 1 | let proof_as_ref = config.proof.as_ref(); | 68 | | | 69 | | struct InProgressEntry<'a> { | 70 | | index_in_proof: usize, | 71 | | range_in_proof: ops::Range<usize>, | 72 | | decode_result: Result< | 73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, | 74 | | trie_node::Error, | 75 | | >, | 76 | | } | 77 | | | 78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. | 79 | | // | 80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In | 81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per | 82 | | // entry in `proof`. | 83 | | // | 84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is | 85 | | // possible for an attacker to craft a proof that leads to all entries being in the same | 86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which | 87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function | 88 | | // takes, it is always cause this function to return an error and is actually likely to make | 89 | | // the function actually take less time than if it was a legitimate proof. | 90 | 1 | let entries_by_merkle_value = { | 91 | | // TODO: don't use a Vec? | 92 | 1 | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( | 93 | 1 | crate::util::nom_scale_compact_usize, | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), | 95 | 1 | ))(config.proof.as_ref()) | 96 | 1 | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat)?0 ; | 97 | | | 98 | 1 | let entries_by_merkle_value = decoded_proof | 99 | 1 | .iter() | 100 | 1 | .copied() | 101 | 1 | .enumerate() | 102 | 1 | .map( | 103 | 1 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | | // The merkle value of a trie node is normally either its hash or the node | 105 | | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | | // we only hash each entry. | 108 | | let hash = *<&[u8; 32]>::try_from( | 109 | | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | | ) | 111 | | .unwrap(); | 112 | | | 113 | | let proof_entry_offset = if proof_entry.is_empty() { | 114 | | 0 | 115 | | } else { | 116 | | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | | ( | 120 | | hash, | 121 | | InProgressEntry { | 122 | | index_in_proof: proof_entry_num, | 123 | | range_in_proof: proof_entry_offset | 124 | | ..(proof_entry_offset + proof_entry.len()), | 125 | | decode_result: trie_node::decode(proof_entry), | 126 | | }, | 127 | | ) | 128 | 1 | }, | 129 | 1 | ) | 130 | 1 | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); | 131 | 1 | | 132 | 1 | // Using a hashmap has the consequence that if multiple proof entries were identical, only | 133 | 1 | // one would be tracked. This allows us to make sure that the proof doesn't contain | 134 | 1 | // multiple identical entries. | 135 | 1 | if entries_by_merkle_value.len() != decoded_proof.len() { | 136 | 0 | return Err(Error::DuplicateProofEntry); | 137 | 1 | } | 138 | 1 | | 139 | 1 | entries_by_merkle_value | 140 | | }; | 141 | | | 142 | | // Start by iterating over each element of the proof, and keep track of elements that are | 143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. | 144 | 1 | let trie_roots = { | 145 | 1 | let mut maybe_trie_roots = entries_by_merkle_value | 146 | 1 | .keys() | 147 | 1 | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 148 | 126 | for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter()1 { | 149 | 126 | let Ok(decoded98 ) = decode_result else { | 150 | 28 | maybe_trie_roots.remove(hash); | 151 | 28 | continue; | 152 | | }; | 153 | 389 | for child in decoded.children.into_iter().flatten()98 { | 154 | 389 | if let Ok(child341 ) = &<[u8; 32]>::try_from(child) { | 155 | 341 | maybe_trie_roots.remove(child); | 156 | 341 | }48 | 157 | | } | 158 | | } | 159 | 1 | maybe_trie_roots | 160 | 1 | }; | 161 | 1 | | 162 | 1 | // The implementation below iterates down the tree of nodes represented by this proof, keeping | 163 | 1 | // note of the traversed elements. | 164 | 1 | | 165 | 1 | // Keep track of all the entries found in the proof. | 166 | 1 | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); | 167 | 1 | | 168 | 1 | let mut trie_roots_with_entries = | 169 | 1 | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); | 170 | 1 | | 171 | 1 | // Keep track of the proof entries that haven't been visited when traversing. | 172 | 1 | let mut unvisited_proof_entries = | 173 | 1 | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 174 | | | 175 | | // We repeat this operation for every trie root. | 176 | 3 | for trie_root_hash2 in trie_roots { | 177 | | struct StackEntry<'a> { | 178 | | range_in_proof: ops::Range<usize>, | 179 | | index_in_entries: usize, | 180 | | num_visited_children: u8, | 181 | | children_node_values: [Option<&'a [u8]>; 16], | 182 | | } | 183 | | | 184 | | // Keep track of the number of entries before this trie root. | 185 | | // This allows us to truncate `entries` to this value in case of decoding failure. | 186 | 2 | let num_entries_before_current_trie_root = entries.len(); | 187 | 2 | | 188 | 2 | // Keep track of the indices of the proof entries that are visited when traversing this trie. | 189 | 2 | let mut visited_proof_entries_during_trie = | 190 | 2 | Vec::with_capacity(entries_by_merkle_value.len()); | 191 | 2 | | 192 | 2 | // TODO: configurable capacity? | 193 | 2 | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); | 194 | | | 195 | | loop { | 196 | | // Find which node to visit next. | 197 | | // This is the next child of the node at the top of the stack, or if the node at | 198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. | 199 | | // If the stack is empty, we are necessarily at the first iteration. | 200 | 146 | let (visited_node_entry_range, visited_node_decoded) = | 201 | 655 | match visited_entries_stack.last_mut() { | 202 | | None => { | 203 | | // Stack is empty. | 204 | | // Because we immediately `break` after popping the last element, the stack | 205 | | // can only ever be empty at the very start. | 206 | | let InProgressEntry { | 207 | 2 | index_in_proof: root_position, | 208 | 2 | range_in_proof: root_range, | 209 | 2 | decode_result, | 210 | 2 | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); | 211 | 2 | visited_proof_entries_during_trie.push(*root_position); | 212 | | // If the node can't be decoded, we ignore the entire trie and jump | 213 | | // to the next one. | 214 | 2 | let Ok(decoded) = decode_result.clone() else { | 215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); | 216 | 0 | break; | 217 | | }; | 218 | 2 | (root_range.clone(), decoded) | 219 | | } | 220 | | Some(StackEntry { | 221 | 653 | num_visited_children: stack_top_visited_children, | 222 | 653 | .. | 223 | 653 | }) if *stack_top_visited_children == 16145 => { | 224 | | // We have visited all the children of the top of the stack. Pop the node from | 225 | | // the stack. | 226 | | let Some(StackEntry { | 227 | 145 | index_in_entries: stack_top_index_in_entries, | 228 | | .. | 229 | 145 | }) = visited_entries_stack.pop() | 230 | | else { | 231 | 0 | unreachable!() | 232 | | }; | 233 | | | 234 | | // Update the value of `child_entries_follow_up` | 235 | | // and `children_present_in_proof_bitmap` of the parent. | 236 | | if let Some(&StackEntry { | 237 | 144 | index_in_entries: parent_index_in_entries, | 238 | 144 | num_visited_children: parent_children_visited, | 239 | | .. | 240 | 145 | }) = visited_entries_stack.last() | 241 | 144 | { | 242 | 144 | entries[parent_index_in_entries].child_entries_follow_up += | 243 | 144 | entries[stack_top_index_in_entries].child_entries_follow_up + 1; | 244 | 144 | entries[parent_index_in_entries].children_present_in_proof_bitmap |= | 245 | 144 | 1 << (parent_children_visited - 1); | 246 | 144 | }1 | 247 | | | 248 | | // If we popped the last node of the stack, we have finished the iteration. | 249 | 145 | if visited_entries_stack.is_empty() { | 250 | 1 | trie_roots_with_entries | 251 | 1 | .insert(*trie_root_hash, num_entries_before_current_trie_root); | 252 | | // Remove the visited entries from `unvisited_proof_entries`. | 253 | | // Note that it is questionable what to do if the same entry is visited | 254 | | // multiple times. In case where multiple storage branches are identical, | 255 | | // the sender of the proof should de-duplicate the identical nodes. For | 256 | | // this reason, it could be legitimate for the same proof entry to be | 257 | | // visited multiple times. | 258 | 137 | for entry_num136 in visited_proof_entries_during_trie { | 259 | 136 | unvisited_proof_entries.remove(&entry_num); | 260 | 136 | } | 261 | 1 | break; | 262 | | } else { | 263 | 144 | continue; | 264 | | } | 265 | | } | 266 | | Some(StackEntry { | 267 | 508 | range_in_proof: stack_top_proof_range, | 268 | 508 | num_visited_children: stack_top_visited_children, | 269 | 508 | children_node_values: stack_top_children, | 270 | 508 | .. | 271 | 508 | }) => { | 272 | 508 | // Find the next child of the top of the stack. | 273 | 508 | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; | 274 | 508 | | 275 | 508 | // Find the index of the next child (that we are about to visit). | 276 | 508 | let next_child_to_visit = stack_top_children | 277 | 508 | .iter() | 278 | 508 | .skip(usize::from(*stack_top_visited_children)) | 279 | 508 | .position(|c| c.is_some()) | 280 | 508 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) | 281 | 508 | .unwrap_or(16); | 282 | 508 | | 283 | 508 | // `continue` if all children have been visited. The next iteration will | 284 | 508 | // pop the stack entry. | 285 | 508 | if next_child_to_visit == 16 { | 286 | 117 | *stack_top_visited_children = 16; | 287 | 117 | continue; | 288 | 391 | } | 289 | 391 | *stack_top_visited_children = next_child_to_visit + 1; | 290 | 391 | | 291 | 391 | // The value of the child node is either directly inlined (if less | 292 | 391 | // than 32 bytes) or is a hash. | 293 | 391 | let child_node_value = | 294 | 391 | stack_top_children[usize::from(next_child_to_visit)].unwrap(); | 295 | 391 | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. | 296 | 391 | if child_node_value.len() < 32 { | 297 | 47 | let offset = stack_top_proof_range.start | 298 | 47 | + if !child_node_value.is_empty() { | 299 | 46 | child_node_value.as_ptr() as usize | 300 | 46 | - stack_top_entry.as_ptr() as usize | 301 | | } else { | 302 | 1 | 0 | 303 | | }; | 304 | 47 | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); | 305 | 47 | debug_assert!( | 306 | 47 | offset <= (stack_top_proof_range.start + stack_top_entry.len()) | 307 | | ); | 308 | | | 309 | 47 | let child_range_in_proof = offset..(offset + child_node_value.len()); | 310 | | | 311 | | // Decodes the child. | 312 | | // If the node can't be decoded, we ignore the entire trie and jump | 313 | | // to the next one. | 314 | 46 | let Ok(child_decoded) = | 315 | 47 | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) | 316 | | else { | 317 | 1 | entries.truncate(num_entries_before_current_trie_root); | 318 | 1 | break; | 319 | | }; | 320 | | | 321 | 46 | (child_range_in_proof, child_decoded) | 322 | | } else if let Some(&InProgressEntry { | 323 | 98 | index_in_proof: child_position, | 324 | 98 | range_in_proof: ref child_entry_range, | 325 | 98 | ref decode_result, | 326 | 344 | }) = entries_by_merkle_value.get(child_node_value) | 327 | | { | 328 | | // If the node value of the child is less than 32 bytes long, it should | 329 | | // have been inlined instead of given separately. | 330 | 98 | if child_entry_range.end - child_entry_range.start < 32 { | 331 | 0 | entries.truncate(num_entries_before_current_trie_root); | 332 | 0 | break; | 333 | 98 | } | 334 | 98 | | 335 | 98 | visited_proof_entries_during_trie.push(child_position); | 336 | | | 337 | | // If the node can't be decoded, we ignore the entire trie and jump | 338 | | // to the next one. | 339 | 98 | let Ok(decoded) = decode_result.clone() else { | 340 | 0 | entries.truncate(num_entries_before_current_trie_root); | 341 | 0 | break; | 342 | | }; | 343 | 98 | (child_entry_range.clone(), decoded) | 344 | | } else { | 345 | | // Child is a hash that was not found in the proof. Simply continue | 346 | | // iterating, in order to try to find the follow-up child. | 347 | 246 | continue; | 348 | | } | 349 | | } | 350 | | }; | 351 | | | 352 | | // All nodes must either have a child or a storage value or be the root. | 353 | 146 | if visited_node_decoded.children_bitmap() == 0 | 354 | 85 | && matches!( | 355 | 85 | visited_node_decoded.storage_value, | 356 | | trie_node::StorageValue::None | 357 | | ) | 358 | 0 | && !visited_entries_stack.is_empty() | 359 | | { | 360 | 0 | entries.truncate(num_entries_before_current_trie_root); | 361 | 0 | break; | 362 | 146 | } | 363 | 146 | | 364 | 146 | // Nodes with no storage value and one children are forbidden. | 365 | 146 | if visited_node_decoded | 366 | 146 | .children | 367 | 146 | .iter() | 368 | 146 | .filter(|c| c.is_some()) | 369 | 146 | .count() | 370 | 146 | == 1 | 371 | 0 | && matches!( | 372 | 0 | visited_node_decoded.storage_value, | 373 | | trie_node::StorageValue::None | 374 | | ) | 375 | | { | 376 | 0 | entries.truncate(num_entries_before_current_trie_root); | 377 | 0 | break; | 378 | 146 | } | 379 | 146 | | 380 | 146 | // Add an entry for this node in the final list of entries. | 381 | 146 | entries.push(Entry { | 382 | 146 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | | ( | 384 | | entry.index_in_entries, | 385 | | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | | ) | 387 | 146 | }), | 388 | 146 | range_in_proof: visited_node_entry_range.clone(), | 389 | 146 | storage_value_in_proof: match visited_node_decoded.storage_value { | 390 | 60 | trie_node::StorageValue::None => None, | 391 | 37 | trie_node::StorageValue::Hashed(value_hash) => { | 392 | | if let Some(&InProgressEntry { | 393 | 37 | index_in_proof: value_position, | 394 | 37 | range_in_proof: ref value_entry_range, | 395 | | .. | 396 | 37 | }) = entries_by_merkle_value.get(&value_hash[..]) | 397 | | { | 398 | 37 | visited_proof_entries_during_trie.push(value_position); | 399 | 37 | Some(value_entry_range.clone()) | 400 | | } else { | 401 | 0 | None | 402 | | } | 403 | | } | 404 | 49 | trie_node::StorageValue::Unhashed(v) => { | 405 | 49 | let offset = if !v.is_empty() { | 406 | 49 | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 407 | | } else { | 408 | 0 | 0 | 409 | | }; | 410 | 49 | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start); | 411 | 49 | debug_assert!(offset <= visited_node_entry_range.end); | 412 | 49 | Some(offset..offset + v.len()) | 413 | | } | 414 | | }, | 415 | | child_entries_follow_up: 0, // Filled later. | 416 | | children_present_in_proof_bitmap: 0, // Filled later. | 417 | | }); | 418 | | | 419 | | // Add the visited node to the stack. The next iteration will either go to its first | 420 | | // child, or pop the node from the stack. | 421 | 146 | visited_entries_stack.push(StackEntry { | 422 | 146 | range_in_proof: visited_node_entry_range, | 423 | 146 | index_in_entries: entries.len() - 1, | 424 | 146 | num_visited_children: 0, | 425 | 146 | children_node_values: visited_node_decoded.children, | 426 | 146 | }); | 427 | | } | 428 | | } | 429 | | | 430 | | // The entire reason why we track the unvisited proof entries is to return this error if | 431 | | // necessary. | 432 | 1 | if !unvisited_proof_entries.is_empty() { | 433 | 0 | return Err(Error::UnusedProofEntry); | 434 | 1 | } | 435 | 1 | | 436 | 1 | drop(entries_by_merkle_value); | 437 | 1 | Ok(DecodedTrieProof { | 438 | 1 | proof: config.proof, | 439 | 1 | entries, | 440 | 1 | trie_roots: trie_roots_with_entries, | 441 | 1 | }) | 442 | 1 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhja2_EB6_ Line | Count | Source | 61 | 1 | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> | 62 | 1 | where | 63 | 1 | T: AsRef<[u8]>, | 64 | 1 | { | 65 | 1 | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory | 66 | 1 | // location. | 67 | 1 | let proof_as_ref = config.proof.as_ref(); | 68 | | | 69 | | struct InProgressEntry<'a> { | 70 | | index_in_proof: usize, | 71 | | range_in_proof: ops::Range<usize>, | 72 | | decode_result: Result< | 73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, | 74 | | trie_node::Error, | 75 | | >, | 76 | | } | 77 | | | 78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. | 79 | | // | 80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In | 81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per | 82 | | // entry in `proof`. | 83 | | // | 84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is | 85 | | // possible for an attacker to craft a proof that leads to all entries being in the same | 86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which | 87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function | 88 | | // takes, it is always cause this function to return an error and is actually likely to make | 89 | | // the function actually take less time than if it was a legitimate proof. | 90 | 1 | let entries_by_merkle_value = { | 91 | | // TODO: don't use a Vec? | 92 | 1 | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( | 93 | 1 | crate::util::nom_scale_compact_usize, | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), | 95 | 1 | ))(config.proof.as_ref()) | 96 | 1 | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat)?0 ; | 97 | | | 98 | 1 | let entries_by_merkle_value = decoded_proof | 99 | 1 | .iter() | 100 | 1 | .copied() | 101 | 1 | .enumerate() | 102 | 1 | .map( | 103 | 1 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | | // The merkle value of a trie node is normally either its hash or the node | 105 | | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | | // we only hash each entry. | 108 | | let hash = *<&[u8; 32]>::try_from( | 109 | | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | | ) | 111 | | .unwrap(); | 112 | | | 113 | | let proof_entry_offset = if proof_entry.is_empty() { | 114 | | 0 | 115 | | } else { | 116 | | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | | ( | 120 | | hash, | 121 | | InProgressEntry { | 122 | | index_in_proof: proof_entry_num, | 123 | | range_in_proof: proof_entry_offset | 124 | | ..(proof_entry_offset + proof_entry.len()), | 125 | | decode_result: trie_node::decode(proof_entry), | 126 | | }, | 127 | | ) | 128 | 1 | }, | 129 | 1 | ) | 130 | 1 | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); | 131 | 1 | | 132 | 1 | // Using a hashmap has the consequence that if multiple proof entries were identical, only | 133 | 1 | // one would be tracked. This allows us to make sure that the proof doesn't contain | 134 | 1 | // multiple identical entries. | 135 | 1 | if entries_by_merkle_value.len() != decoded_proof.len() { | 136 | 0 | return Err(Error::DuplicateProofEntry); | 137 | 1 | } | 138 | 1 | | 139 | 1 | entries_by_merkle_value | 140 | | }; | 141 | | | 142 | | // Start by iterating over each element of the proof, and keep track of elements that are | 143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. | 144 | 1 | let trie_roots = { | 145 | 1 | let mut maybe_trie_roots = entries_by_merkle_value | 146 | 1 | .keys() | 147 | 1 | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 148 | 2 | for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter()1 { | 149 | 2 | let Ok(decoded) = decode_result else { | 150 | 0 | maybe_trie_roots.remove(hash); | 151 | 0 | continue; | 152 | | }; | 153 | 2 | for child in decoded.children.into_iter().flatten() { | 154 | 2 | if let Ok(child) = &<[u8; 32]>::try_from(child) { | 155 | 2 | maybe_trie_roots.remove(child); | 156 | 2 | }0 | 157 | | } | 158 | | } | 159 | 1 | maybe_trie_roots | 160 | 1 | }; | 161 | 1 | | 162 | 1 | // The implementation below iterates down the tree of nodes represented by this proof, keeping | 163 | 1 | // note of the traversed elements. | 164 | 1 | | 165 | 1 | // Keep track of all the entries found in the proof. | 166 | 1 | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); | 167 | 1 | | 168 | 1 | let mut trie_roots_with_entries = | 169 | 1 | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); | 170 | 1 | | 171 | 1 | // Keep track of the proof entries that haven't been visited when traversing. | 172 | 1 | let mut unvisited_proof_entries = | 173 | 1 | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 174 | | | 175 | | // We repeat this operation for every trie root. | 176 | 2 | for trie_root_hash1 in trie_roots { | 177 | | struct StackEntry<'a> { | 178 | | range_in_proof: ops::Range<usize>, | 179 | | index_in_entries: usize, | 180 | | num_visited_children: u8, | 181 | | children_node_values: [Option<&'a [u8]>; 16], | 182 | | } | 183 | | | 184 | | // Keep track of the number of entries before this trie root. | 185 | | // This allows us to truncate `entries` to this value in case of decoding failure. | 186 | 1 | let num_entries_before_current_trie_root = entries.len(); | 187 | 1 | | 188 | 1 | // Keep track of the indices of the proof entries that are visited when traversing this trie. | 189 | 1 | let mut visited_proof_entries_during_trie = | 190 | 1 | Vec::with_capacity(entries_by_merkle_value.len()); | 191 | 1 | | 192 | 1 | // TODO: configurable capacity? | 193 | 1 | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); | 194 | | | 195 | | loop { | 196 | | // Find which node to visit next. | 197 | | // This is the next child of the node at the top of the stack, or if the node at | 198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. | 199 | | // If the stack is empty, we are necessarily at the first iteration. | 200 | 3 | let (visited_node_entry_range, visited_node_decoded) = | 201 | 9 | match visited_entries_stack.last_mut() { | 202 | | None => { | 203 | | // Stack is empty. | 204 | | // Because we immediately `break` after popping the last element, the stack | 205 | | // can only ever be empty at the very start. | 206 | | let InProgressEntry { | 207 | 1 | index_in_proof: root_position, | 208 | 1 | range_in_proof: root_range, | 209 | 1 | decode_result, | 210 | 1 | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); | 211 | 1 | visited_proof_entries_during_trie.push(*root_position); | 212 | | // If the node can't be decoded, we ignore the entire trie and jump | 213 | | // to the next one. | 214 | 1 | let Ok(decoded) = decode_result.clone() else { | 215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); | 216 | 0 | break; | 217 | | }; | 218 | 1 | (root_range.clone(), decoded) | 219 | | } | 220 | | Some(StackEntry { | 221 | 8 | num_visited_children: stack_top_visited_children, | 222 | 8 | .. | 223 | 8 | }) if *stack_top_visited_children == 163 => { | 224 | | // We have visited all the children of the top of the stack. Pop the node from | 225 | | // the stack. | 226 | | let Some(StackEntry { | 227 | 3 | index_in_entries: stack_top_index_in_entries, | 228 | | .. | 229 | 3 | }) = visited_entries_stack.pop() | 230 | | else { | 231 | 0 | unreachable!() | 232 | | }; | 233 | | | 234 | | // Update the value of `child_entries_follow_up` | 235 | | // and `children_present_in_proof_bitmap` of the parent. | 236 | | if let Some(&StackEntry { | 237 | 2 | index_in_entries: parent_index_in_entries, | 238 | 2 | num_visited_children: parent_children_visited, | 239 | | .. | 240 | 3 | }) = visited_entries_stack.last() | 241 | 2 | { | 242 | 2 | entries[parent_index_in_entries].child_entries_follow_up += | 243 | 2 | entries[stack_top_index_in_entries].child_entries_follow_up + 1; | 244 | 2 | entries[parent_index_in_entries].children_present_in_proof_bitmap |= | 245 | 2 | 1 << (parent_children_visited - 1); | 246 | 2 | }1 | 247 | | | 248 | | // If we popped the last node of the stack, we have finished the iteration. | 249 | 3 | if visited_entries_stack.is_empty() { | 250 | 1 | trie_roots_with_entries | 251 | 1 | .insert(*trie_root_hash, num_entries_before_current_trie_root); | 252 | | // Remove the visited entries from `unvisited_proof_entries`. | 253 | | // Note that it is questionable what to do if the same entry is visited | 254 | | // multiple times. In case where multiple storage branches are identical, | 255 | | // the sender of the proof should de-duplicate the identical nodes. For | 256 | | // this reason, it could be legitimate for the same proof entry to be | 257 | | // visited multiple times. | 258 | 4 | for entry_num3 in visited_proof_entries_during_trie { | 259 | 3 | unvisited_proof_entries.remove(&entry_num); | 260 | 3 | } | 261 | 1 | break; | 262 | | } else { | 263 | 2 | continue; | 264 | | } | 265 | | } | 266 | | Some(StackEntry { | 267 | 5 | range_in_proof: stack_top_proof_range, | 268 | 5 | num_visited_children: stack_top_visited_children, | 269 | 5 | children_node_values: stack_top_children, | 270 | 5 | .. | 271 | 5 | }) => { | 272 | 5 | // Find the next child of the top of the stack. | 273 | 5 | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; | 274 | 5 | | 275 | 5 | // Find the index of the next child (that we are about to visit). | 276 | 5 | let next_child_to_visit = stack_top_children | 277 | 5 | .iter() | 278 | 5 | .skip(usize::from(*stack_top_visited_children)) | 279 | 5 | .position(|c| c.is_some()) | 280 | 5 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) | 281 | 5 | .unwrap_or(16); | 282 | 5 | | 283 | 5 | // `continue` if all children have been visited. The next iteration will | 284 | 5 | // pop the stack entry. | 285 | 5 | if next_child_to_visit == 16 { | 286 | 3 | *stack_top_visited_children = 16; | 287 | 3 | continue; | 288 | 2 | } | 289 | 2 | *stack_top_visited_children = next_child_to_visit + 1; | 290 | 2 | | 291 | 2 | // The value of the child node is either directly inlined (if less | 292 | 2 | // than 32 bytes) or is a hash. | 293 | 2 | let child_node_value = | 294 | 2 | stack_top_children[usize::from(next_child_to_visit)].unwrap(); | 295 | 2 | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. | 296 | 2 | if child_node_value.len() < 32 { | 297 | 0 | let offset = stack_top_proof_range.start | 298 | 0 | + if !child_node_value.is_empty() { | 299 | 0 | child_node_value.as_ptr() as usize | 300 | 0 | - stack_top_entry.as_ptr() as usize | 301 | | } else { | 302 | 0 | 0 | 303 | | }; | 304 | 0 | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); | 305 | 0 | debug_assert!( | 306 | 0 | offset <= (stack_top_proof_range.start + stack_top_entry.len()) | 307 | | ); | 308 | | | 309 | 0 | let child_range_in_proof = offset..(offset + child_node_value.len()); | 310 | | | 311 | | // Decodes the child. | 312 | | // If the node can't be decoded, we ignore the entire trie and jump | 313 | | // to the next one. | 314 | 0 | let Ok(child_decoded) = | 315 | 0 | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) | 316 | | else { | 317 | 0 | entries.truncate(num_entries_before_current_trie_root); | 318 | 0 | break; | 319 | | }; | 320 | | | 321 | 0 | (child_range_in_proof, child_decoded) | 322 | | } else if let Some(&InProgressEntry { | 323 | 2 | index_in_proof: child_position, | 324 | 2 | range_in_proof: ref child_entry_range, | 325 | 2 | ref decode_result, | 326 | 2 | }) = entries_by_merkle_value.get(child_node_value) | 327 | | { | 328 | | // If the node value of the child is less than 32 bytes long, it should | 329 | | // have been inlined instead of given separately. | 330 | 2 | if child_entry_range.end - child_entry_range.start < 32 { | 331 | 0 | entries.truncate(num_entries_before_current_trie_root); | 332 | 0 | break; | 333 | 2 | } | 334 | 2 | | 335 | 2 | visited_proof_entries_during_trie.push(child_position); | 336 | | | 337 | | // If the node can't be decoded, we ignore the entire trie and jump | 338 | | // to the next one. | 339 | 2 | let Ok(decoded) = decode_result.clone() else { | 340 | 0 | entries.truncate(num_entries_before_current_trie_root); | 341 | 0 | break; | 342 | | }; | 343 | 2 | (child_entry_range.clone(), decoded) | 344 | | } else { | 345 | | // Child is a hash that was not found in the proof. Simply continue | 346 | | // iterating, in order to try to find the follow-up child. | 347 | 0 | continue; | 348 | | } | 349 | | } | 350 | | }; | 351 | | | 352 | | // All nodes must either have a child or a storage value or be the root. | 353 | 3 | if visited_node_decoded.children_bitmap() == 0 | 354 | 2 | && matches!( | 355 | 2 | visited_node_decoded.storage_value, | 356 | | trie_node::StorageValue::None | 357 | | ) | 358 | 0 | && !visited_entries_stack.is_empty() | 359 | | { | 360 | 0 | entries.truncate(num_entries_before_current_trie_root); | 361 | 0 | break; | 362 | 3 | } | 363 | 3 | | 364 | 3 | // Nodes with no storage value and one children are forbidden. | 365 | 3 | if visited_node_decoded | 366 | 3 | .children | 367 | 3 | .iter() | 368 | 3 | .filter(|c| c.is_some()) | 369 | 3 | .count() | 370 | 3 | == 1 | 371 | 0 | && matches!( | 372 | 0 | visited_node_decoded.storage_value, | 373 | | trie_node::StorageValue::None | 374 | | ) | 375 | | { | 376 | 0 | entries.truncate(num_entries_before_current_trie_root); | 377 | 0 | break; | 378 | 3 | } | 379 | 3 | | 380 | 3 | // Add an entry for this node in the final list of entries. | 381 | 3 | entries.push(Entry { | 382 | 3 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | | ( | 384 | | entry.index_in_entries, | 385 | | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | | ) | 387 | 3 | }), | 388 | 3 | range_in_proof: visited_node_entry_range.clone(), | 389 | 3 | storage_value_in_proof: match visited_node_decoded.storage_value { | 390 | 1 | trie_node::StorageValue::None => None, | 391 | 0 | trie_node::StorageValue::Hashed(value_hash) => { | 392 | | if let Some(&InProgressEntry { | 393 | 0 | index_in_proof: value_position, | 394 | 0 | range_in_proof: ref value_entry_range, | 395 | | .. | 396 | 0 | }) = entries_by_merkle_value.get(&value_hash[..]) | 397 | | { | 398 | 0 | visited_proof_entries_during_trie.push(value_position); | 399 | 0 | Some(value_entry_range.clone()) | 400 | | } else { | 401 | 0 | None | 402 | | } | 403 | | } | 404 | 2 | trie_node::StorageValue::Unhashed(v) => { | 405 | 2 | let offset = if !v.is_empty() { | 406 | 2 | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 407 | | } else { | 408 | 0 | 0 | 409 | | }; | 410 | 2 | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start); | 411 | 2 | debug_assert!(offset <= visited_node_entry_range.end); | 412 | 2 | Some(offset..offset + v.len()) | 413 | | } | 414 | | }, | 415 | | child_entries_follow_up: 0, // Filled later. | 416 | | children_present_in_proof_bitmap: 0, // Filled later. | 417 | | }); | 418 | | | 419 | | // Add the visited node to the stack. The next iteration will either go to its first | 420 | | // child, or pop the node from the stack. | 421 | 3 | visited_entries_stack.push(StackEntry { | 422 | 3 | range_in_proof: visited_node_entry_range, | 423 | 3 | index_in_entries: entries.len() - 1, | 424 | 3 | num_visited_children: 0, | 425 | 3 | children_node_values: visited_node_decoded.children, | 426 | 3 | }); | 427 | | } | 428 | | } | 429 | | | 430 | | // The entire reason why we track the unvisited proof entries is to return this error if | 431 | | // necessary. | 432 | 1 | if !unvisited_proof_entries.is_empty() { | 433 | 0 | return Err(Error::UnusedProofEntry); | 434 | 1 | } | 435 | 1 | | 436 | 1 | drop(entries_by_merkle_value); | 437 | 1 | Ok(DecodedTrieProof { | 438 | 1 | proof: config.proof, | 439 | 1 | entries, | 440 | 1 | trie_roots: trie_roots_with_entries, | 441 | 1 | }) | 442 | 1 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRAhjfc_EB6_ Line | Count | Source | 61 | 1 | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> | 62 | 1 | where | 63 | 1 | T: AsRef<[u8]>, | 64 | 1 | { | 65 | 1 | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory | 66 | 1 | // location. | 67 | 1 | let proof_as_ref = config.proof.as_ref(); | 68 | | | 69 | | struct InProgressEntry<'a> { | 70 | | index_in_proof: usize, | 71 | | range_in_proof: ops::Range<usize>, | 72 | | decode_result: Result< | 73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, | 74 | | trie_node::Error, | 75 | | >, | 76 | | } | 77 | | | 78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. | 79 | | // | 80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In | 81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per | 82 | | // entry in `proof`. | 83 | | // | 84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is | 85 | | // possible for an attacker to craft a proof that leads to all entries being in the same | 86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which | 87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function | 88 | | // takes, it is always cause this function to return an error and is actually likely to make | 89 | | // the function actually take less time than if it was a legitimate proof. | 90 | 0 | let entries_by_merkle_value = { | 91 | | // TODO: don't use a Vec? | 92 | 1 | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( | 93 | 1 | crate::util::nom_scale_compact_usize, | 94 | 1 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), | 95 | 1 | ))(config.proof.as_ref()) | 96 | 1 | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat)?0 ; | 97 | | | 98 | 1 | let entries_by_merkle_value = decoded_proof | 99 | 1 | .iter() | 100 | 1 | .copied() | 101 | 1 | .enumerate() | 102 | 1 | .map( | 103 | 1 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | | // The merkle value of a trie node is normally either its hash or the node | 105 | | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | | // we only hash each entry. | 108 | | let hash = *<&[u8; 32]>::try_from( | 109 | | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | | ) | 111 | | .unwrap(); | 112 | | | 113 | | let proof_entry_offset = if proof_entry.is_empty() { | 114 | | 0 | 115 | | } else { | 116 | | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | | ( | 120 | | hash, | 121 | | InProgressEntry { | 122 | | index_in_proof: proof_entry_num, | 123 | | range_in_proof: proof_entry_offset | 124 | | ..(proof_entry_offset + proof_entry.len()), | 125 | | decode_result: trie_node::decode(proof_entry), | 126 | | }, | 127 | | ) | 128 | 1 | }, | 129 | 1 | ) | 130 | 1 | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); | 131 | 1 | | 132 | 1 | // Using a hashmap has the consequence that if multiple proof entries were identical, only | 133 | 1 | // one would be tracked. This allows us to make sure that the proof doesn't contain | 134 | 1 | // multiple identical entries. | 135 | 1 | if entries_by_merkle_value.len() != decoded_proof.len() { | 136 | 1 | return Err(Error::DuplicateProofEntry); | 137 | 0 | } | 138 | 0 |
| 139 | 0 | entries_by_merkle_value | 140 | | }; | 141 | | | 142 | | // Start by iterating over each element of the proof, and keep track of elements that are | 143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. | 144 | 0 | let trie_roots = { | 145 | 0 | let mut maybe_trie_roots = entries_by_merkle_value | 146 | 0 | .keys() | 147 | 0 | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 148 | 0 | for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter() { | 149 | 0 | let Ok(decoded) = decode_result else { | 150 | 0 | maybe_trie_roots.remove(hash); | 151 | 0 | continue; | 152 | | }; | 153 | 0 | for child in decoded.children.into_iter().flatten() { | 154 | 0 | if let Ok(child) = &<[u8; 32]>::try_from(child) { | 155 | 0 | maybe_trie_roots.remove(child); | 156 | 0 | } | 157 | | } | 158 | | } | 159 | 0 | maybe_trie_roots | 160 | 0 | }; | 161 | 0 |
| 162 | 0 | // The implementation below iterates down the tree of nodes represented by this proof, keeping | 163 | 0 | // note of the traversed elements. | 164 | 0 |
| 165 | 0 | // Keep track of all the entries found in the proof. | 166 | 0 | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); | 167 | 0 |
| 168 | 0 | let mut trie_roots_with_entries = | 169 | 0 | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); | 170 | 0 |
| 171 | 0 | // Keep track of the proof entries that haven't been visited when traversing. | 172 | 0 | let mut unvisited_proof_entries = | 173 | 0 | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 174 | | | 175 | | // We repeat this operation for every trie root. | 176 | 0 | for trie_root_hash in trie_roots { | 177 | | struct StackEntry<'a> { | 178 | | range_in_proof: ops::Range<usize>, | 179 | | index_in_entries: usize, | 180 | | num_visited_children: u8, | 181 | | children_node_values: [Option<&'a [u8]>; 16], | 182 | | } | 183 | | | 184 | | // Keep track of the number of entries before this trie root. | 185 | | // This allows us to truncate `entries` to this value in case of decoding failure. | 186 | 0 | let num_entries_before_current_trie_root = entries.len(); | 187 | 0 |
| 188 | 0 | // Keep track of the indices of the proof entries that are visited when traversing this trie. | 189 | 0 | let mut visited_proof_entries_during_trie = | 190 | 0 | Vec::with_capacity(entries_by_merkle_value.len()); | 191 | 0 |
| 192 | 0 | // TODO: configurable capacity? | 193 | 0 | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); | 194 | | | 195 | | loop { | 196 | | // Find which node to visit next. | 197 | | // This is the next child of the node at the top of the stack, or if the node at | 198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. | 199 | | // If the stack is empty, we are necessarily at the first iteration. | 200 | 0 | let (visited_node_entry_range, visited_node_decoded) = | 201 | 0 | match visited_entries_stack.last_mut() { | 202 | | None => { | 203 | | // Stack is empty. | 204 | | // Because we immediately `break` after popping the last element, the stack | 205 | | // can only ever be empty at the very start. | 206 | | let InProgressEntry { | 207 | 0 | index_in_proof: root_position, | 208 | 0 | range_in_proof: root_range, | 209 | 0 | decode_result, | 210 | 0 | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); | 211 | 0 | visited_proof_entries_during_trie.push(*root_position); | 212 | | // If the node can't be decoded, we ignore the entire trie and jump | 213 | | // to the next one. | 214 | 0 | let Ok(decoded) = decode_result.clone() else { | 215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); | 216 | 0 | break; | 217 | | }; | 218 | 0 | (root_range.clone(), decoded) | 219 | | } | 220 | | Some(StackEntry { | 221 | 0 | num_visited_children: stack_top_visited_children, | 222 | 0 | .. | 223 | 0 | }) if *stack_top_visited_children == 16 => { | 224 | | // We have visited all the children of the top of the stack. Pop the node from | 225 | | // the stack. | 226 | | let Some(StackEntry { | 227 | 0 | index_in_entries: stack_top_index_in_entries, | 228 | | .. | 229 | 0 | }) = visited_entries_stack.pop() | 230 | | else { | 231 | 0 | unreachable!() | 232 | | }; | 233 | | | 234 | | // Update the value of `child_entries_follow_up` | 235 | | // and `children_present_in_proof_bitmap` of the parent. | 236 | | if let Some(&StackEntry { | 237 | 0 | index_in_entries: parent_index_in_entries, | 238 | 0 | num_visited_children: parent_children_visited, | 239 | | .. | 240 | 0 | }) = visited_entries_stack.last() | 241 | 0 | { | 242 | 0 | entries[parent_index_in_entries].child_entries_follow_up += | 243 | 0 | entries[stack_top_index_in_entries].child_entries_follow_up + 1; | 244 | 0 | entries[parent_index_in_entries].children_present_in_proof_bitmap |= | 245 | 0 | 1 << (parent_children_visited - 1); | 246 | 0 | } | 247 | | | 248 | | // If we popped the last node of the stack, we have finished the iteration. | 249 | 0 | if visited_entries_stack.is_empty() { | 250 | 0 | trie_roots_with_entries | 251 | 0 | .insert(*trie_root_hash, num_entries_before_current_trie_root); | 252 | | // Remove the visited entries from `unvisited_proof_entries`. | 253 | | // Note that it is questionable what to do if the same entry is visited | 254 | | // multiple times. In case where multiple storage branches are identical, | 255 | | // the sender of the proof should de-duplicate the identical nodes. For | 256 | | // this reason, it could be legitimate for the same proof entry to be | 257 | | // visited multiple times. | 258 | 0 | for entry_num in visited_proof_entries_during_trie { | 259 | 0 | unvisited_proof_entries.remove(&entry_num); | 260 | 0 | } | 261 | 0 | break; | 262 | | } else { | 263 | 0 | continue; | 264 | | } | 265 | | } | 266 | | Some(StackEntry { | 267 | 0 | range_in_proof: stack_top_proof_range, | 268 | 0 | num_visited_children: stack_top_visited_children, | 269 | 0 | children_node_values: stack_top_children, | 270 | 0 | .. | 271 | 0 | }) => { | 272 | 0 | // Find the next child of the top of the stack. | 273 | 0 | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; | 274 | 0 |
| 275 | 0 | // Find the index of the next child (that we are about to visit). | 276 | 0 | let next_child_to_visit = stack_top_children | 277 | 0 | .iter() | 278 | 0 | .skip(usize::from(*stack_top_visited_children)) | 279 | 0 | .position(|c| c.is_some()) | 280 | 0 | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) | 281 | 0 | .unwrap_or(16); | 282 | 0 |
| 283 | 0 | // `continue` if all children have been visited. The next iteration will | 284 | 0 | // pop the stack entry. | 285 | 0 | if next_child_to_visit == 16 { | 286 | 0 | *stack_top_visited_children = 16; | 287 | 0 | continue; | 288 | 0 | } | 289 | 0 | *stack_top_visited_children = next_child_to_visit + 1; | 290 | 0 |
| 291 | 0 | // The value of the child node is either directly inlined (if less | 292 | 0 | // than 32 bytes) or is a hash. | 293 | 0 | let child_node_value = | 294 | 0 | stack_top_children[usize::from(next_child_to_visit)].unwrap(); | 295 | 0 | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. | 296 | 0 | if child_node_value.len() < 32 { | 297 | 0 | let offset = stack_top_proof_range.start | 298 | 0 | + if !child_node_value.is_empty() { | 299 | 0 | child_node_value.as_ptr() as usize | 300 | 0 | - stack_top_entry.as_ptr() as usize | 301 | | } else { | 302 | 0 | 0 | 303 | | }; | 304 | 0 | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); | 305 | 0 | debug_assert!( | 306 | 0 | offset <= (stack_top_proof_range.start + stack_top_entry.len()) | 307 | | ); | 308 | | | 309 | 0 | let child_range_in_proof = offset..(offset + child_node_value.len()); | 310 | | | 311 | | // Decodes the child. | 312 | | // If the node can't be decoded, we ignore the entire trie and jump | 313 | | // to the next one. | 314 | 0 | let Ok(child_decoded) = | 315 | 0 | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) | 316 | | else { | 317 | 0 | entries.truncate(num_entries_before_current_trie_root); | 318 | 0 | break; | 319 | | }; | 320 | | | 321 | 0 | (child_range_in_proof, child_decoded) | 322 | | } else if let Some(&InProgressEntry { | 323 | 0 | index_in_proof: child_position, | 324 | 0 | range_in_proof: ref child_entry_range, | 325 | 0 | ref decode_result, | 326 | 0 | }) = entries_by_merkle_value.get(child_node_value) | 327 | | { | 328 | | // If the node value of the child is less than 32 bytes long, it should | 329 | | // have been inlined instead of given separately. | 330 | 0 | if child_entry_range.end - child_entry_range.start < 32 { | 331 | 0 | entries.truncate(num_entries_before_current_trie_root); | 332 | 0 | break; | 333 | 0 | } | 334 | 0 |
| 335 | 0 | visited_proof_entries_during_trie.push(child_position); | 336 | | | 337 | | // If the node can't be decoded, we ignore the entire trie and jump | 338 | | // to the next one. | 339 | 0 | let Ok(decoded) = decode_result.clone() else { | 340 | 0 | entries.truncate(num_entries_before_current_trie_root); | 341 | 0 | break; | 342 | | }; | 343 | 0 | (child_entry_range.clone(), decoded) | 344 | | } else { | 345 | | // Child is a hash that was not found in the proof. Simply continue | 346 | | // iterating, in order to try to find the follow-up child. | 347 | 0 | continue; | 348 | | } | 349 | | } | 350 | | }; | 351 | | | 352 | | // All nodes must either have a child or a storage value or be the root. | 353 | 0 | if visited_node_decoded.children_bitmap() == 0 | 354 | 0 | && matches!( | 355 | 0 | visited_node_decoded.storage_value, | 356 | | trie_node::StorageValue::None | 357 | | ) | 358 | 0 | && !visited_entries_stack.is_empty() | 359 | | { | 360 | 0 | entries.truncate(num_entries_before_current_trie_root); | 361 | 0 | break; | 362 | 0 | } | 363 | 0 |
| 364 | 0 | // Nodes with no storage value and one children are forbidden. | 365 | 0 | if visited_node_decoded | 366 | 0 | .children | 367 | 0 | .iter() | 368 | 0 | .filter(|c| c.is_some()) | 369 | 0 | .count() | 370 | 0 | == 1 | 371 | 0 | && matches!( | 372 | 0 | visited_node_decoded.storage_value, | 373 | | trie_node::StorageValue::None | 374 | | ) | 375 | | { | 376 | 0 | entries.truncate(num_entries_before_current_trie_root); | 377 | 0 | break; | 378 | 0 | } | 379 | 0 |
| 380 | 0 | // Add an entry for this node in the final list of entries. | 381 | 0 | entries.push(Entry { | 382 | 0 | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | | ( | 384 | | entry.index_in_entries, | 385 | | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | | ) | 387 | 0 | }), | 388 | 0 | range_in_proof: visited_node_entry_range.clone(), | 389 | 0 | storage_value_in_proof: match visited_node_decoded.storage_value { | 390 | 0 | trie_node::StorageValue::None => None, | 391 | 0 | trie_node::StorageValue::Hashed(value_hash) => { | 392 | | if let Some(&InProgressEntry { | 393 | 0 | index_in_proof: value_position, | 394 | 0 | range_in_proof: ref value_entry_range, | 395 | | .. | 396 | 0 | }) = entries_by_merkle_value.get(&value_hash[..]) | 397 | | { | 398 | 0 | visited_proof_entries_during_trie.push(value_position); | 399 | 0 | Some(value_entry_range.clone()) | 400 | | } else { | 401 | 0 | None | 402 | | } | 403 | | } | 404 | 0 | trie_node::StorageValue::Unhashed(v) => { | 405 | 0 | let offset = if !v.is_empty() { | 406 | 0 | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 407 | | } else { | 408 | 0 | 0 | 409 | | }; | 410 | 0 | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start); | 411 | 0 | debug_assert!(offset <= visited_node_entry_range.end); | 412 | 0 | Some(offset..offset + v.len()) | 413 | | } | 414 | | }, | 415 | | child_entries_follow_up: 0, // Filled later. | 416 | | children_present_in_proof_bitmap: 0, // Filled later. | 417 | | }); | 418 | | | 419 | | // Add the visited node to the stack. The next iteration will either go to its first | 420 | | // child, or pop the node from the stack. | 421 | 0 | visited_entries_stack.push(StackEntry { | 422 | 0 | range_in_proof: visited_node_entry_range, | 423 | 0 | index_in_entries: entries.len() - 1, | 424 | 0 | num_visited_children: 0, | 425 | 0 | children_node_values: visited_node_decoded.children, | 426 | 0 | }); | 427 | | } | 428 | | } | 429 | | | 430 | | // The entire reason why we track the unvisited proof entries is to return this error if | 431 | | // necessary. | 432 | 0 | if !unvisited_proof_entries.is_empty() { | 433 | 0 | return Err(Error::UnusedProofEntry); | 434 | 0 | } | 435 | 0 |
| 436 | 0 | drop(entries_by_merkle_value); | 437 | 0 | Ok(DecodedTrieProof { | 438 | 0 | proof: config.proof, | 439 | 0 | entries, | 440 | 0 | trie_roots: trie_roots_with_entries, | 441 | 0 | }) | 442 | 1 | } |
_RINvNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode23decode_and_verify_proofRShEB6_ Line | Count | Source | 61 | 9 | pub fn decode_and_verify_proof<T>(config: Config<T>) -> Result<DecodedTrieProof<T>, Error> | 62 | 9 | where | 63 | 9 | T: AsRef<[u8]>, | 64 | 9 | { | 65 | 9 | // Call `as_ref()` once at the beginning in order to guarantee stability of the memory | 66 | 9 | // location. | 67 | 9 | let proof_as_ref = config.proof.as_ref(); | 68 | | | 69 | | struct InProgressEntry<'a> { | 70 | | index_in_proof: usize, | 71 | | range_in_proof: ops::Range<usize>, | 72 | | decode_result: Result< | 73 | | trie_node::Decoded<'a, trie_node::DecodedPartialKey<'a>, &'a [u8]>, | 74 | | trie_node::Error, | 75 | | >, | 76 | | } | 77 | | | 78 | | // A Merkle proof is a SCALE-encoded `Vec<Vec<u8>>`. | 79 | | // | 80 | | // This `Vec` contains two types of items: trie node values, and standalone storage items. In | 81 | | // both cases, we will later need a hashed version of them. Create a list of hashes, one per | 82 | | // entry in `proof`. | 83 | | // | 84 | | // This hashmap uses a FNV hasher, theoretically vulnerable to HashDos attacks. While it is | 85 | | // possible for an attacker to craft a proof that leads to all entries being in the same | 86 | | // bucket, this proof is going to be invalid (unless the blake2 hash function is broken, which | 87 | | // we assume it isn't). So while an attacker can slightly increase the time that this function | 88 | | // takes, it is always cause this function to return an error and is actually likely to make | 89 | | // the function actually take less time than if it was a legitimate proof. | 90 | 9 | let entries_by_merkle_value = { | 91 | | // TODO: don't use a Vec? | 92 | 9 | let (_, decoded_proof) = nom::combinator::all_consuming(nom::combinator::flat_map( | 93 | 9 | crate::util::nom_scale_compact_usize, | 94 | 9 | |num_elems| nom::multi::many_m_n(num_elems, num_elems, crate::util::nom_bytes_decode), | 95 | 9 | ))(config.proof.as_ref()) | 96 | 9 | .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::InvalidFormat)?0 ; | 97 | | | 98 | 9 | let entries_by_merkle_value = decoded_proof | 99 | 9 | .iter() | 100 | 9 | .copied() | 101 | 9 | .enumerate() | 102 | 9 | .map( | 103 | 9 | |(proof_entry_num, proof_entry)| -> ([u8; 32], InProgressEntry) { | 104 | | // The merkle value of a trie node is normally either its hash or the node | 105 | | // itself if its length is < 32. In the context of a proof, however, nodes | 106 | | // whose length is < 32 aren't supposed to be their own entry. For this reason, | 107 | | // we only hash each entry. | 108 | | let hash = *<&[u8; 32]>::try_from( | 109 | | blake2_rfc::blake2b::blake2b(32, &[], proof_entry).as_bytes(), | 110 | | ) | 111 | | .unwrap(); | 112 | | | 113 | | let proof_entry_offset = if proof_entry.is_empty() { | 114 | | 0 | 115 | | } else { | 116 | | proof_entry.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 117 | | }; | 118 | | | 119 | | ( | 120 | | hash, | 121 | | InProgressEntry { | 122 | | index_in_proof: proof_entry_num, | 123 | | range_in_proof: proof_entry_offset | 124 | | ..(proof_entry_offset + proof_entry.len()), | 125 | | decode_result: trie_node::decode(proof_entry), | 126 | | }, | 127 | | ) | 128 | 9 | }, | 129 | 9 | ) | 130 | 9 | .collect::<hashbrown::HashMap<_, _, fnv::FnvBuildHasher>>(); | 131 | 9 | | 132 | 9 | // Using a hashmap has the consequence that if multiple proof entries were identical, only | 133 | 9 | // one would be tracked. This allows us to make sure that the proof doesn't contain | 134 | 9 | // multiple identical entries. | 135 | 9 | if entries_by_merkle_value.len() != decoded_proof.len() { | 136 | 0 | return Err(Error::DuplicateProofEntry); | 137 | 9 | } | 138 | 9 | | 139 | 9 | entries_by_merkle_value | 140 | | }; | 141 | | | 142 | | // Start by iterating over each element of the proof, and keep track of elements that are | 143 | | // decodable but aren't mentioned in any other element. This gives us the tries roots. | 144 | 9 | let trie_roots = { | 145 | 9 | let mut maybe_trie_roots = entries_by_merkle_value | 146 | 9 | .keys() | 147 | 9 | .collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 148 | 1.75k | for (hash, InProgressEntry { decode_result, .. }) in entries_by_merkle_value.iter()9 { | 149 | 1.75k | let Ok(decoded) = decode_result else { | 150 | 0 | maybe_trie_roots.remove(hash); | 151 | 0 | continue; | 152 | | }; | 153 | 3.81k | for child in decoded.children.into_iter().flatten()1.75k { | 154 | 3.81k | if let Ok(child3.80k ) = &<[u8; 32]>::try_from(child) { | 155 | 3.80k | maybe_trie_roots.remove(child); | 156 | 3.80k | }18 | 157 | | } | 158 | | } | 159 | 9 | maybe_trie_roots | 160 | 9 | }; | 161 | 9 | | 162 | 9 | // The implementation below iterates down the tree of nodes represented by this proof, keeping | 163 | 9 | // note of the traversed elements. | 164 | 9 | | 165 | 9 | // Keep track of all the entries found in the proof. | 166 | 9 | let mut entries: Vec<Entry> = Vec::with_capacity(entries_by_merkle_value.len()); | 167 | 9 | | 168 | 9 | let mut trie_roots_with_entries = | 169 | 9 | hashbrown::HashMap::with_capacity_and_hasher(trie_roots.len(), Default::default()); | 170 | 9 | | 171 | 9 | // Keep track of the proof entries that haven't been visited when traversing. | 172 | 9 | let mut unvisited_proof_entries = | 173 | 9 | (0..entries_by_merkle_value.len()).collect::<hashbrown::HashSet<_, fnv::FnvBuildHasher>>(); | 174 | | | 175 | | // We repeat this operation for every trie root. | 176 | 18 | for trie_root_hash9 in trie_roots { | 177 | | struct StackEntry<'a> { | 178 | | range_in_proof: ops::Range<usize>, | 179 | | index_in_entries: usize, | 180 | | num_visited_children: u8, | 181 | | children_node_values: [Option<&'a [u8]>; 16], | 182 | | } | 183 | | | 184 | | // Keep track of the number of entries before this trie root. | 185 | | // This allows us to truncate `entries` to this value in case of decoding failure. | 186 | 9 | let num_entries_before_current_trie_root = entries.len(); | 187 | 9 | | 188 | 9 | // Keep track of the indices of the proof entries that are visited when traversing this trie. | 189 | 9 | let mut visited_proof_entries_during_trie = | 190 | 9 | Vec::with_capacity(entries_by_merkle_value.len()); | 191 | 9 | | 192 | 9 | // TODO: configurable capacity? | 193 | 9 | let mut visited_entries_stack: Vec<StackEntry> = Vec::with_capacity(24); | 194 | | | 195 | | loop { | 196 | | // Find which node to visit next. | 197 | | // This is the next child of the node at the top of the stack, or if the node at | 198 | | // the top of the stack doesn't have any child, we pop it and continue iterating. | 199 | | // If the stack is empty, we are necessarily at the first iteration. | 200 | 1.77k | let (visited_node_entry_range, visited_node_decoded) = | 201 | 7.15k | match visited_entries_stack.last_mut() { | 202 | | None => { | 203 | | // Stack is empty. | 204 | | // Because we immediately `break` after popping the last element, the stack | 205 | | // can only ever be empty at the very start. | 206 | | let InProgressEntry { | 207 | 9 | index_in_proof: root_position, | 208 | 9 | range_in_proof: root_range, | 209 | 9 | decode_result, | 210 | 9 | } = entries_by_merkle_value.get(&trie_root_hash[..]).unwrap(); | 211 | 9 | visited_proof_entries_during_trie.push(*root_position); | 212 | | // If the node can't be decoded, we ignore the entire trie and jump | 213 | | // to the next one. | 214 | 9 | let Ok(decoded) = decode_result.clone() else { | 215 | 0 | debug_assert_eq!(num_entries_before_current_trie_root, entries.len()); | 216 | 0 | break; | 217 | | }; | 218 | 9 | (root_range.clone(), decoded) | 219 | | } | 220 | | Some(StackEntry { | 221 | 7.14k | num_visited_children: stack_top_visited_children, | 222 | 7.14k | .. | 223 | 7.14k | }) if *stack_top_visited_children == 161.77k => { | 224 | | // We have visited all the children of the top of the stack. Pop the node from | 225 | | // the stack. | 226 | | let Some(StackEntry { | 227 | 1.77k | index_in_entries: stack_top_index_in_entries, | 228 | | .. | 229 | 1.77k | }) = visited_entries_stack.pop() | 230 | | else { | 231 | 0 | unreachable!() | 232 | | }; | 233 | | | 234 | | // Update the value of `child_entries_follow_up` | 235 | | // and `children_present_in_proof_bitmap` of the parent. | 236 | | if let Some(&StackEntry { | 237 | 1.76k | index_in_entries: parent_index_in_entries, | 238 | 1.76k | num_visited_children: parent_children_visited, | 239 | | .. | 240 | 1.77k | }) = visited_entries_stack.last() | 241 | 1.76k | { | 242 | 1.76k | entries[parent_index_in_entries].child_entries_follow_up += | 243 | 1.76k | entries[stack_top_index_in_entries].child_entries_follow_up + 1; | 244 | 1.76k | entries[parent_index_in_entries].children_present_in_proof_bitmap |= | 245 | 1.76k | 1 << (parent_children_visited - 1); | 246 | 1.76k | }9 | 247 | | | 248 | | // If we popped the last node of the stack, we have finished the iteration. | 249 | 1.77k | if visited_entries_stack.is_empty() { | 250 | 9 | trie_roots_with_entries | 251 | 9 | .insert(*trie_root_hash, num_entries_before_current_trie_root); | 252 | | // Remove the visited entries from `unvisited_proof_entries`. | 253 | | // Note that it is questionable what to do if the same entry is visited | 254 | | // multiple times. In case where multiple storage branches are identical, | 255 | | // the sender of the proof should de-duplicate the identical nodes. For | 256 | | // this reason, it could be legitimate for the same proof entry to be | 257 | | // visited multiple times. | 258 | 1.76k | for entry_num1.75k in visited_proof_entries_during_trie { | 259 | 1.75k | unvisited_proof_entries.remove(&entry_num); | 260 | 1.75k | } | 261 | 9 | break; | 262 | | } else { | 263 | 1.76k | continue; | 264 | | } | 265 | | } | 266 | | Some(StackEntry { | 267 | 5.36k | range_in_proof: stack_top_proof_range, | 268 | 5.36k | num_visited_children: stack_top_visited_children, | 269 | 5.36k | children_node_values: stack_top_children, | 270 | 5.36k | .. | 271 | 5.36k | }) => { | 272 | 5.36k | // Find the next child of the top of the stack. | 273 | 5.36k | let stack_top_entry = &proof_as_ref[stack_top_proof_range.clone()]; | 274 | 5.36k | | 275 | 5.36k | // Find the index of the next child (that we are about to visit). | 276 | 5.36k | let next_child_to_visit = stack_top_children | 277 | 5.36k | .iter() | 278 | 5.36k | .skip(usize::from(*stack_top_visited_children)) | 279 | 5.36k | .position(|c| c.is_some()) | 280 | 5.36k | .map(|idx| u8::try_from(idx).unwrap() + *stack_top_visited_children) | 281 | 5.36k | .unwrap_or(16); | 282 | 5.36k | | 283 | 5.36k | // `continue` if all children have been visited. The next iteration will | 284 | 5.36k | // pop the stack entry. | 285 | 5.36k | if next_child_to_visit == 16 { | 286 | 1.54k | *stack_top_visited_children = 16; | 287 | 1.54k | continue; | 288 | 3.81k | } | 289 | 3.81k | *stack_top_visited_children = next_child_to_visit + 1; | 290 | 3.81k | | 291 | 3.81k | // The value of the child node is either directly inlined (if less | 292 | 3.81k | // than 32 bytes) or is a hash. | 293 | 3.81k | let child_node_value = | 294 | 3.81k | stack_top_children[usize::from(next_child_to_visit)].unwrap(); | 295 | 3.81k | debug_assert!(child_node_value.len() <= 32); // Guaranteed by decoding API. | 296 | 3.81k | if child_node_value.len() < 32 { | 297 | 18 | let offset = stack_top_proof_range.start | 298 | 18 | + if !child_node_value.is_empty() { | 299 | 18 | child_node_value.as_ptr() as usize | 300 | 18 | - stack_top_entry.as_ptr() as usize | 301 | | } else { | 302 | 0 | 0 | 303 | | }; | 304 | 18 | debug_assert!(offset == 0 || offset >= stack_top_proof_range.start); | 305 | 18 | debug_assert!( | 306 | 18 | offset <= (stack_top_proof_range.start + stack_top_entry.len()) | 307 | | ); | 308 | | | 309 | 18 | let child_range_in_proof = offset..(offset + child_node_value.len()); | 310 | | | 311 | | // Decodes the child. | 312 | | // If the node can't be decoded, we ignore the entire trie and jump | 313 | | // to the next one. | 314 | 18 | let Ok(child_decoded) = | 315 | 18 | trie_node::decode(&proof_as_ref[child_range_in_proof.clone()]) | 316 | | else { | 317 | 0 | entries.truncate(num_entries_before_current_trie_root); | 318 | 0 | break; | 319 | | }; | 320 | | | 321 | 18 | (child_range_in_proof, child_decoded) | 322 | | } else if let Some(&InProgressEntry { | 323 | 1.75k | index_in_proof: child_position, | 324 | 1.75k | range_in_proof: ref child_entry_range, | 325 | 1.75k | ref decode_result, | 326 | 3.80k | }) = entries_by_merkle_value.get(child_node_value) | 327 | | { | 328 | | // If the node value of the child is less than 32 bytes long, it should | 329 | | // have been inlined instead of given separately. | 330 | 1.75k | if child_entry_range.end - child_entry_range.start < 32 { | 331 | 0 | entries.truncate(num_entries_before_current_trie_root); | 332 | 0 | break; | 333 | 1.75k | } | 334 | 1.75k | | 335 | 1.75k | visited_proof_entries_during_trie.push(child_position); | 336 | | | 337 | | // If the node can't be decoded, we ignore the entire trie and jump | 338 | | // to the next one. | 339 | 1.75k | let Ok(decoded) = decode_result.clone() else { | 340 | 0 | entries.truncate(num_entries_before_current_trie_root); | 341 | 0 | break; | 342 | | }; | 343 | 1.75k | (child_entry_range.clone(), decoded) | 344 | | } else { | 345 | | // Child is a hash that was not found in the proof. Simply continue | 346 | | // iterating, in order to try to find the follow-up child. | 347 | 2.05k | continue; | 348 | | } | 349 | | } | 350 | | }; | 351 | | | 352 | | // All nodes must either have a child or a storage value or be the root. | 353 | 1.77k | if visited_node_decoded.children_bitmap() == 0 | 354 | 943 | && matches!( | 355 | 943 | visited_node_decoded.storage_value, | 356 | | trie_node::StorageValue::None | 357 | | ) | 358 | 0 | && !visited_entries_stack.is_empty() | 359 | | { | 360 | 0 | entries.truncate(num_entries_before_current_trie_root); | 361 | 0 | break; | 362 | 1.77k | } | 363 | 1.77k | | 364 | 1.77k | // Nodes with no storage value and one children are forbidden. | 365 | 1.77k | if visited_node_decoded | 366 | 1.77k | .children | 367 | 1.77k | .iter() | 368 | 1.77k | .filter(|c| c.is_some()) | 369 | 1.77k | .count() | 370 | 1.77k | == 1 | 371 | 0 | && matches!( | 372 | 0 | visited_node_decoded.storage_value, | 373 | | trie_node::StorageValue::None | 374 | | ) | 375 | | { | 376 | 0 | entries.truncate(num_entries_before_current_trie_root); | 377 | 0 | break; | 378 | 1.77k | } | 379 | 1.77k | | 380 | 1.77k | // Add an entry for this node in the final list of entries. | 381 | 1.77k | entries.push(Entry { | 382 | 1.77k | parent_entry_index: visited_entries_stack.last().map(|entry| { | 383 | | ( | 384 | | entry.index_in_entries, | 385 | | nibble::Nibble::try_from(entry.num_visited_children - 1).unwrap(), | 386 | | ) | 387 | 1.77k | }), | 388 | 1.77k | range_in_proof: visited_node_entry_range.clone(), | 389 | 1.77k | storage_value_in_proof: match visited_node_decoded.storage_value { | 390 | 834 | trie_node::StorageValue::None => None, | 391 | 0 | trie_node::StorageValue::Hashed(value_hash) => { | 392 | | if let Some(&InProgressEntry { | 393 | 0 | index_in_proof: value_position, | 394 | 0 | range_in_proof: ref value_entry_range, | 395 | | .. | 396 | 0 | }) = entries_by_merkle_value.get(&value_hash[..]) | 397 | | { | 398 | 0 | visited_proof_entries_during_trie.push(value_position); | 399 | 0 | Some(value_entry_range.clone()) | 400 | | } else { | 401 | 0 | None | 402 | | } | 403 | | } | 404 | 943 | trie_node::StorageValue::Unhashed(v) => { | 405 | 943 | let offset = if !v.is_empty() { | 406 | 943 | v.as_ptr() as usize - proof_as_ref.as_ptr() as usize | 407 | | } else { | 408 | 0 | 0 | 409 | | }; | 410 | 943 | debug_assert!(offset == 0 || offset >= visited_node_entry_range.start); | 411 | 943 | debug_assert!(offset <= visited_node_entry_range.end); | 412 | 943 | Some(offset..offset + v.len()) | 413 | | } | 414 | | }, | 415 | | child_entries_follow_up: 0, // Filled later. | 416 | | children_present_in_proof_bitmap: 0, // Filled later. | 417 | | }); | 418 | | | 419 | | // Add the visited node to the stack. The next iteration will either go to its first | 420 | | // child, or pop the node from the stack. | 421 | 1.77k | visited_entries_stack.push(StackEntry { | 422 | 1.77k | range_in_proof: visited_node_entry_range, | 423 | 1.77k | index_in_entries: entries.len() - 1, | 424 | 1.77k | num_visited_children: 0, | 425 | 1.77k | children_node_values: visited_node_decoded.children, | 426 | 1.77k | }); | 427 | | } | 428 | | } | 429 | | | 430 | | // The entire reason why we track the unvisited proof entries is to return this error if | 431 | | // necessary. | 432 | 9 | if !unvisited_proof_entries.is_empty() { | 433 | 0 | return Err(Error::UnusedProofEntry); | 434 | 9 | } | 435 | 9 | | 436 | 9 | drop(entries_by_merkle_value); | 437 | 9 | Ok(DecodedTrieProof { | 438 | 9 | proof: config.proof, | 439 | 9 | entries, | 440 | 9 | trie_roots: trie_roots_with_entries, | 441 | 9 | }) | 442 | 9 | } |
Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShEB6_ Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShECscDgN54JpMGG_6author Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEECsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RINvNtNtCseuYC0Zibziv_7smoldot4trie12proof_decode23decode_and_verify_proofRShECsibGXYHQB8Ea_25json_rpc_general_requests |
443 | | |
444 | | /// Decoded Merkle proof. The proof is guaranteed valid. |
445 | | pub struct DecodedTrieProof<T> { |
446 | | /// The proof itself. |
447 | | proof: T, |
448 | | |
449 | | /// All entries in the proof, in lexicographic order. Ordering between trie roots is |
450 | | /// unspecified. |
451 | | entries: Vec<Entry>, |
452 | | |
453 | | /// |
454 | | /// Given that hashes are verified to actually match their values, there is no risk of |
455 | | /// HashDoS attack. |
456 | | // TODO: is that true? ^ depends on whether there are a lot of storage values |
457 | | trie_roots: hashbrown::HashMap<[u8; 32], usize, fnv::FnvBuildHasher>, |
458 | | } |
459 | | |
460 | | struct Entry { |
461 | | /// Index within [`DecodedTrieProof::entries`] of the parent of this entry and child direction |
462 | | /// nibble, or `None` if it is the root. |
463 | | parent_entry_index: Option<(usize, nibble::Nibble)>, |
464 | | |
465 | | /// Range within [`DecodedTrieProof::proof`] of the node value of this entry. |
466 | | range_in_proof: ops::Range<usize>, |
467 | | |
468 | | /// Range within [`DecodedTrieProof::proof`] of the unhashed storage value of this entry. |
469 | | /// `None` if the entry doesn't have any storage entry or if it's missing from the proof. |
470 | | storage_value_in_proof: Option<ops::Range<usize>>, |
471 | | |
472 | | // TODO: doc |
473 | | children_present_in_proof_bitmap: u16, |
474 | | |
475 | | /// Given an entry of index `N`, it is always followed with `k` entries that correspond to the |
476 | | /// sub-tree of that entry, where `k` is equal to [`Entry::child_entries_follow_up`]. In order |
477 | | /// to jump to the next sibling of that entry, jump to `N + 1 + k`. If `k` is non-zero, then |
478 | | /// entry `N + 1` corresponds to the first child of the entry of index `N`. |
479 | | child_entries_follow_up: usize, |
480 | | // TODO: by adding the partial key, we should be able to avoid decoding the entry while iterating down the trie |
481 | | } |
482 | | |
483 | | impl<T: AsRef<[u8]>> fmt::Debug for DecodedTrieProof<T> { |
484 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
485 | 0 | f.debug_map() |
486 | 0 | .entries(self.iter_ordered().map( |
487 | 0 | |( |
488 | | EntryKey { |
489 | | trie_root_hash, |
490 | | key, |
491 | | }, |
492 | | entry, |
493 | 0 | )| { |
494 | 0 | struct DummyHash<'a>(&'a [u8]); |
495 | 0 | impl<'a> fmt::Debug for DummyHash<'a> { |
496 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
497 | 0 | if self.0.is_empty() { |
498 | 0 | write!(f, "∅")? |
499 | 0 | } |
500 | 0 | for byte in self.0 { |
501 | 0 | write!(f, "{:02x}", *byte)? |
502 | 0 | } |
503 | 0 | Ok(()) |
504 | 0 | } Unexecuted instantiation: _RNvXNCNvXNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0NtB2_9DummyHashB1f_3fmt Unexecuted instantiation: _RNvXNCNvXNtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0NtB2_9DummyHashB1g_3fmt |
505 | 0 | } |
506 | 0 |
|
507 | 0 | struct DummyNibbles<'a, T: AsRef<[u8]>>(EntryKeyIter<'a, T>); |
508 | 0 | impl<'a, T: AsRef<[u8]>> fmt::Debug for DummyNibbles<'a, T> { |
509 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
510 | 0 | let mut any_written = false; |
511 | 0 | for nibble in self.0.clone() { |
512 | 0 | any_written = true; |
513 | 0 | write!(f, "{:x}", nibble)? |
514 | 0 | } |
515 | 0 | if !any_written { |
516 | 0 | write!(f, "∅")? |
517 | 0 | } |
518 | 0 | Ok(()) |
519 | 0 | } Unexecuted instantiation: _RNvXININCNvXNtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0s_0pEINtB5_12DummyNibblespEB1i_3fmtBe_ Unexecuted instantiation: _RNvXININCNvXNtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0s_0pEINtB5_12DummyNibblespEB1j_3fmtBe_ |
520 | 0 | } |
521 | 0 |
|
522 | 0 | ( |
523 | 0 | (DummyHash(trie_root_hash), DummyNibbles(key)), |
524 | 0 | ( |
525 | 0 | entry.trie_node_info.children, |
526 | 0 | entry.trie_node_info.storage_value, |
527 | 0 | ), |
528 | 0 | ) |
529 | 0 | }, Unexecuted instantiation: _RNCNvXININtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode0pEINtB7_16DecodedTrieProofpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0Bb_ Unexecuted instantiation: _RNCNvXININtNtCseuYC0Zibziv_7smoldot4trie12proof_decode0pEINtB7_16DecodedTrieProofpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmt0Bb_ |
530 | 0 | )) |
531 | 0 | .finish() |
532 | 0 | } Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4trie12proof_decode0pEINtB5_16DecodedTrieProofpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtB9_ Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4trie12proof_decode0pEINtB5_16DecodedTrieProofpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtB9_ |
533 | | } |
534 | | |
535 | | /// Identifier for an entry within a decoded proof. |
536 | | pub struct EntryKey<'a, K> { |
537 | | /// Hash of the root of the trie the key is in. |
538 | | pub trie_root_hash: &'a [u8; 32], |
539 | | /// The trie node key. |
540 | | pub key: K, |
541 | | } |
542 | | |
543 | | impl<T: AsRef<[u8]>> DecodedTrieProof<T> { |
544 | | /// Returns a list of all elements of the proof, ordered by key in lexicographic order. |
545 | | /// |
546 | | /// This function is a convenient wrapper around [`DecodedTrieProof::iter_ordered`] that |
547 | | /// converts the keys into arrays of bytes. If a key can't be represented as an array of |
548 | | /// bytes, then it is filtered out. Assuming that the trie has only ever been used in the |
549 | | /// context of the runtime, then this cannot happen. See the section below for an |
550 | | /// explanation. |
551 | | /// |
552 | | /// The iterator might include branch nodes. It is not possible for this function to |
553 | | /// differentiate between value-less nodes that are present in the proof only because they are |
554 | | /// branch nodes, and value-less nodes that are present in the proof because the fact that they |
555 | | /// have no value is important for the proof. |
556 | | /// |
557 | | /// # Detailed explanation |
558 | | /// |
559 | | /// The trie consists of nodes, each with a key and a value. The keys consist of an array of |
560 | | /// "nibbles", which are 4 bits each. |
561 | | /// |
562 | | /// When the runtime writes a value in the trie, it passes a key as an array a bytes. In order |
563 | | /// to know where to write this value, this array of bytes is converted into an array of |
564 | | /// nibbles by turning each byte into two nibbles. |
565 | | /// |
566 | | /// Due to the fact that the host-runtime interface only ever uses arrays of bytes, it is not |
567 | | /// possible for the runtime to store a value or read a value in the trie at a key that |
568 | | /// consists in an uneven number of nibbles, as an uneven number of nibbles cannot be |
569 | | /// converted to an array of bytes. |
570 | | /// |
571 | | /// In other words, if a trie has only ever been used in the context of a runtime, then it is |
572 | | /// guaranteed to not contain any storage value at key that consists in an uneven number of |
573 | | /// nibbles. |
574 | | /// |
575 | | /// The trie format itself, however, technically doesn't forbid storing reading and writing |
576 | | /// values at keys that consist in an uneven number of nibbles. For this reason, a proof |
577 | | /// containing a value at a key that consists in an uneven number of nibbles is considered as |
578 | | /// valid according to [`decode_and_verify_proof`]. |
579 | | /// |
580 | | // TODO: paragraph below not true anymore |
581 | | /// However, given that [`decode_and_verify_proof`] verifies the trie proof against the state |
582 | | /// trie root hash, we are also guaranteed that this proof reflects the actual trie. If the |
583 | | /// actual trie can't contain any storage value at a key that consists in an uneven number of |
584 | | /// nibbles, then the proof is also guaranteed to not contain any storage value at a key that |
585 | | /// consists in an uneven number of nibbles. Importantly, this is only true if we are sure that |
586 | | /// the block is valid, in other words that it has indeed been created using a runtime. Blocks |
587 | | /// that are invalid might have been created through a fake trie. |
588 | | /// |
589 | | /// As a conclusion, if this proof is made against a trie that has only ever been used in the |
590 | | /// context of a runtime, and that the block using this trie is guaranteed to be valid, then |
591 | | /// this function will work as intended and return the entire content of the proof. |
592 | | /// |
593 | | // TODO: ordering between trie roots unspecified |
594 | | // TODO: consider not returning a Vec |
595 | 0 | pub fn iter_runtime_context_ordered( |
596 | 0 | &'_ self, |
597 | 0 | ) -> impl Iterator<Item = (EntryKey<'_, Vec<u8>>, StorageValue<'_>)> + '_ { |
598 | 0 | self.iter_ordered().filter_map( |
599 | 0 | |( |
600 | | EntryKey { |
601 | | trie_root_hash, |
602 | | key, |
603 | | }, |
604 | | entry, |
605 | 0 | )| { |
606 | 0 | let value = entry.trie_node_info.storage_value; |
607 | 0 |
|
608 | 0 | if key.clone().count() % 2 != 0 { |
609 | 0 | return None; |
610 | 0 | } |
611 | 0 |
|
612 | 0 | let key = nibble::nibbles_to_bytes_suffix_extend(key).collect(); |
613 | 0 | Some(( |
614 | 0 | EntryKey { |
615 | 0 | trie_root_hash, |
616 | 0 | key, |
617 | 0 | }, |
618 | 0 | value, |
619 | 0 | )) |
620 | 0 | }, Unexecuted instantiation: _RNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB6_16DecodedTrieProofpE28iter_runtime_context_ordered0Ba_ Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB6_16DecodedTrieProofpE28iter_runtime_context_ordered0Ba_ |
621 | 0 | ) |
622 | 0 | } Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofpE28iter_runtime_context_orderedB8_ Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofpE28iter_runtime_context_orderedB8_ |
623 | | |
624 | | /// Returns a list of all elements of the proof, ordered by key in lexicographic order. |
625 | | /// |
626 | | /// The iterator includes branch nodes. |
627 | | // TODO: ordering between trie roots unspecified |
628 | 0 | pub fn iter_ordered( |
629 | 0 | &'_ self, |
630 | 0 | ) -> impl Iterator<Item = (EntryKey<'_, EntryKeyIter<'_, T>>, ProofEntry<'_, T>)> + '_ { |
631 | 0 | let proof = self.proof.as_ref(); |
632 | 0 |
|
633 | 0 | self.trie_roots |
634 | 0 | .iter() |
635 | 0 | .flat_map(|(trie_root_hash, &trie_root_entry_index)| { |
636 | 0 | self.entries |
637 | 0 | .iter() |
638 | 0 | .enumerate() |
639 | 0 | .skip(trie_root_entry_index) |
640 | 0 | .take(self.entries[trie_root_entry_index].child_entries_follow_up + 1) |
641 | 0 | .map(|(entry_index, entry)| { |
642 | 0 | let key = EntryKey { |
643 | 0 | trie_root_hash, |
644 | 0 | key: EntryKeyIter::new(self, entry_index), |
645 | 0 | }; |
646 | | |
647 | 0 | let Ok(entry_index_decoded) = |
648 | 0 | trie_node::decode(&proof[entry.range_in_proof.clone()]) |
649 | | else { |
650 | | // Proof has been checked to be entirely decodable. |
651 | 0 | unreachable!() |
652 | | }; |
653 | | |
654 | 0 | let entry = ProofEntry { |
655 | 0 | merkle_value: if let Some((parent_index, parent_nibble)) = |
656 | 0 | self.entries[entry_index].parent_entry_index |
657 | | { |
658 | 0 | let Ok(parent_decoded) = trie_node::decode( |
659 | 0 | &proof[self.entries[parent_index].range_in_proof.clone()], |
660 | 0 | ) else { |
661 | | // Proof has been checked to be entirely decodable. |
662 | 0 | unreachable!() |
663 | | }; |
664 | 0 | parent_decoded.children[usize::from(parent_nibble)] |
665 | 0 | .as_ref() |
666 | 0 | .unwrap() |
667 | | } else { |
668 | 0 | trie_root_hash |
669 | | }, |
670 | 0 | node_value: &self.proof.as_ref()[entry.range_in_proof.clone()], |
671 | 0 | partial_key_nibbles: entry_index_decoded.partial_key, |
672 | 0 | unhashed_storage_value: entry |
673 | 0 | .storage_value_in_proof |
674 | 0 | .as_ref() |
675 | 0 | .map(|range| &proof[range.clone()]), Unexecuted instantiation: _RNCNCNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofpE12iter_ordered000Be_ Unexecuted instantiation: _RNCNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofpE12iter_ordered000Be_ Unexecuted instantiation: _RNCNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofRShE12iter_ordered000CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofRShE12iter_ordered000CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofRShE12iter_ordered000CsibGXYHQB8Ea_25json_rpc_general_requests |
676 | 0 | trie_node_info: TrieNodeInfo { |
677 | 0 | children: Children { |
678 | 0 | children: { |
679 | 0 | let mut children = core::array::from_fn(|_| Child::NoChild); Unexecuted instantiation: _RNCNCNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofpE12iter_ordered00s_0Be_ Unexecuted instantiation: _RNCNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofpE12iter_ordered00s_0Be_ Unexecuted instantiation: _RNCNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofRShE12iter_ordered00s_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofRShE12iter_ordered00s_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtBa_16DecodedTrieProofRShE12iter_ordered00s_0CsibGXYHQB8Ea_25json_rpc_general_requests |
680 | 0 | let mut i = entry_index + 1; |
681 | 0 | for child_num in 0..16 { |
682 | 0 | let Some(child_merkle_value) = |
683 | 0 | entry_index_decoded.children[child_num] |
684 | | else { |
685 | 0 | continue; |
686 | | }; |
687 | 0 | if entry.children_present_in_proof_bitmap |
688 | 0 | & (1 << child_num) |
689 | 0 | != 0 |
690 | 0 | { |
691 | 0 | children[child_num] = Child::InProof { |
692 | 0 | child_key: EntryKeyIter::new(self, i), |
693 | 0 | merkle_value: child_merkle_value, |
694 | 0 | }; |
695 | 0 | i += self.entries[i].child_entries_follow_up; |
696 | 0 | i += 1; |
697 | 0 | } else { |
698 | 0 | children[child_num] = Child::AbsentFromProof { |
699 | 0 | merkle_value: child_merkle_value, |
700 | 0 | }; |
701 | 0 | } |
702 | | } |
703 | 0 | children |
704 | 0 | }, |
705 | 0 | }, |
706 | 0 | storage_value: match ( |
707 | 0 | entry_index_decoded.storage_value, |
708 | 0 | &entry.storage_value_in_proof, |
709 | | ) { |
710 | 0 | (trie_node::StorageValue::Unhashed(value), _) => { |
711 | 0 | StorageValue::Known { |
712 | 0 | value, |
713 | 0 | inline: true, |
714 | 0 | } |
715 | | } |
716 | 0 | (trie_node::StorageValue::Hashed(_), Some(value_range)) => { |
717 | 0 | StorageValue::Known { |
718 | 0 | value: &proof[value_range.clone()], |
719 | 0 | inline: false, |
720 | 0 | } |
721 | | } |
722 | 0 | (trie_node::StorageValue::Hashed(hash), None) => { |
723 | 0 | StorageValue::HashKnownValueMissing(hash) |
724 | | } |
725 | 0 | (trie_node::StorageValue::None, _v) => { |
726 | 0 | debug_assert!(_v.is_none()); |
727 | 0 | StorageValue::None |
728 | | } |
729 | | }, |
730 | | }, |
731 | | }; |
732 | | |
733 | 0 | (key, entry) |
734 | 0 | }) Unexecuted instantiation: _RNCNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB8_16DecodedTrieProofpE12iter_ordered00Bc_ Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB8_16DecodedTrieProofpE12iter_ordered00Bc_ Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB8_16DecodedTrieProofRShE12iter_ordered00CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB8_16DecodedTrieProofRShE12iter_ordered00CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB8_16DecodedTrieProofRShE12iter_ordered00CsibGXYHQB8Ea_25json_rpc_general_requests |
735 | 0 | }) Unexecuted instantiation: _RNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB6_16DecodedTrieProofpE12iter_ordered0Ba_ Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB6_16DecodedTrieProofpE12iter_ordered0Ba_ Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB6_16DecodedTrieProofRShE12iter_ordered0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB6_16DecodedTrieProofRShE12iter_ordered0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB6_16DecodedTrieProofRShE12iter_ordered0CsibGXYHQB8Ea_25json_rpc_general_requests |
736 | 0 | } Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofpE12iter_orderedB8_ Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofpE12iter_orderedB8_ Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofRShE12iter_orderedCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofRShE12iter_orderedCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofRShE12iter_orderedCsibGXYHQB8Ea_25json_rpc_general_requests |
737 | | |
738 | | /// Returns the key of the closest ancestor to the given key that can be found in the proof. |
739 | | /// If `key` is in the proof, returns `key`. |
740 | 0 | pub fn closest_ancestor_in_proof<'a>( |
741 | 0 | &'a self, |
742 | 0 | trie_root_merkle_value: &[u8; 32], |
743 | 0 | mut key: impl Iterator<Item = nibble::Nibble>, |
744 | 0 | ) -> Result<Option<EntryKeyIter<'a, T>>, IncompleteProofError> { |
745 | 0 | let proof = self.proof.as_ref(); |
746 | | |
747 | | // If the proof doesn't contain any entry for the requested trie, then we have no |
748 | | // information about the node whatsoever. |
749 | | // This check is necessary because we assume below that a lack of ancestor means that the |
750 | | // key is outside of the trie. |
751 | 0 | let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else { |
752 | 0 | return Err(IncompleteProofError()); |
753 | | }; |
754 | | |
755 | | loop { |
756 | 0 | let Ok(iter_entry_decoded) = |
757 | 0 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) |
758 | | else { |
759 | 0 | unreachable!() |
760 | | }; |
761 | | |
762 | 0 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; |
763 | | loop { |
764 | 0 | match (key.next(), iter_entry_partial_key_iter.next()) { |
765 | 0 | (Some(a), Some(b)) if a == b => {} |
766 | | (_, Some(_)) => { |
767 | | // Mismatch in partial key. Closest ancestor is the parent entry. |
768 | 0 | let Some((parent_entry, _)) = self.entries[iter_entry].parent_entry_index |
769 | | else { |
770 | | // Key is completely outside of the trie. |
771 | 0 | return Ok(None); |
772 | | }; |
773 | 0 | return Ok(Some(EntryKeyIter::new(self, parent_entry))); |
774 | | } |
775 | 0 | (Some(child_num), None) => { |
776 | 0 | if let Some(_) = iter_entry_decoded.children[usize::from(child_num)] { |
777 | | // Key points to child. Update `iter_entry` and continue. |
778 | 0 | let children_present_in_proof_bitmap = |
779 | 0 | self.entries[iter_entry].children_present_in_proof_bitmap; |
780 | 0 |
|
781 | 0 | // If the child isn't present in the proof, then the proof is |
782 | 0 | // incomplete. |
783 | 0 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { |
784 | 0 | return Err(IncompleteProofError()); |
785 | 0 | } |
786 | | |
787 | 0 | for c in 0..u8::from(child_num) { |
788 | 0 | if children_present_in_proof_bitmap & (1 << c) != 0 { |
789 | 0 | iter_entry += 1; |
790 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; |
791 | 0 | } |
792 | | } |
793 | 0 | iter_entry += 1; |
794 | | } else { |
795 | | // Key points to non-existing child. Closest ancestor is `iter_entry`. |
796 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); |
797 | | } |
798 | 0 | break; |
799 | | } |
800 | | (None, None) => { |
801 | | // Exact match. Closest ancestor is `iter_entry`. |
802 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); |
803 | | } |
804 | | } |
805 | | } |
806 | | } |
807 | 0 | } Unexecuted instantiation: _RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofpE25closest_ancestor_in_proofpEB9_ Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE25closest_ancestor_in_proofINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2l_5slice4iter4IterhEEEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE25closest_ancestor_in_proofINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtB1M_4take4TakeINtNtNtB1Q_5slice4iter4IterNtNtB7_6nibble6NibbleEEEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofpE25closest_ancestor_in_proofpEB9_ Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE25closest_ancestor_in_proofINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtB1M_4take4TakeINtNtNtB1Q_5slice4iter4IterNtNtB7_6nibble6NibbleEEEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE25closest_ancestor_in_proofINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtB1M_4take4TakeINtNtNtB1Q_5slice4iter4IterNtNtB7_6nibble6NibbleEEEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE25closest_ancestor_in_proofINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtB1M_4take4TakeINtNtNtB1Q_5slice4iter4IterNtNtB7_6nibble6NibbleEEEECsibGXYHQB8Ea_25json_rpc_general_requests |
808 | | |
809 | | /// Returns information about a trie node. |
810 | | /// |
811 | | /// Returns an error if the proof doesn't contain enough information about this trie node. |
812 | | /// |
813 | | /// This function will return `Ok` even if there is no node in the trie for `key`, in which |
814 | | /// case the returned [`TrieNodeInfo`] will indicate no storage value and no children. |
815 | 3.73k | pub fn trie_node_info( |
816 | 3.73k | &'_ self, |
817 | 3.73k | trie_root_merkle_value: &[u8; 32], |
818 | 3.73k | mut key: impl Iterator<Item = nibble::Nibble>, |
819 | 3.73k | ) -> Result<TrieNodeInfo<'_, T>, IncompleteProofError> { |
820 | 3.73k | let proof = self.proof.as_ref(); |
821 | | |
822 | | // Find the starting point of the requested trie. |
823 | 3.73k | let Some((mut iter_entry_merkle_value, mut iter_entry3.73k )) = self |
824 | 3.73k | .trie_roots |
825 | 3.73k | .get_key_value(trie_root_merkle_value) |
826 | 3.73k | .map(|(k, v)| (&k[..], *v)3.73k ) _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2H_5slice4iter4IterhEEEE0Bb_ Line | Count | Source | 826 | 16 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2b_5slice4iter4IterhEEEE0Bb_ Line | Count | Source | 826 | 3 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1G_5slice4iter4IterNtNtB9_6nibble6NibbleEEE0Bb_ Line | Count | Source | 826 | 3.71k | .map(|(k, v)| (&k[..], *v)) |
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEE0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEE0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEE0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEE0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEE0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEE0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEE0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEE0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEE0CsibGXYHQB8Ea_25json_rpc_general_requests |
827 | | else { |
828 | 1 | return Err(IncompleteProofError()); |
829 | | }; |
830 | | |
831 | | loop { |
832 | 30.8k | let Ok(iter_entry_decoded) = |
833 | 30.8k | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) |
834 | | else { |
835 | | // Proof has been checked to be entirely decodable. |
836 | 0 | unreachable!() |
837 | | }; |
838 | | |
839 | 30.8k | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; |
840 | | loop { |
841 | 322k | match (key.next(), iter_entry_partial_key_iter.next()) { |
842 | 291k | (Some(a), Some(b)) if a == b => {} |
843 | | (Some(_), Some(_)) => { |
844 | | // Mismatch in partial key. No node with the requested key in the trie. |
845 | 0 | return Ok(TrieNodeInfo { |
846 | 0 | storage_value: StorageValue::None, |
847 | 0 | children: Children { |
848 | 0 | children: core::array::from_fn(|_| Child::NoChild), Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2H_5slice4iter4IterhEEEEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2b_5slice4iter4IterhEEEEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1G_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs_0CsibGXYHQB8Ea_25json_rpc_general_requests |
849 | 0 | }, |
850 | 0 | }); |
851 | | } |
852 | 0 | (None, Some(a)) => { |
853 | 0 | // Input key is a subslice of `iter_entry`'s key. |
854 | 0 | // One has one descendant that is `iter_entry`. |
855 | 0 | let mut children = core::array::from_fn(|_| Child::NoChild); Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2H_5slice4iter4IterhEEEEs0_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2b_5slice4iter4IterhEEEEs0_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1G_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs0_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs0_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs0_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs0_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs0_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs0_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs0_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs0_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs0_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs0_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs0_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests |
856 | 0 | children[usize::from(a)] = Child::InProof { |
857 | 0 | child_key: EntryKeyIter::new(self, iter_entry), |
858 | 0 | merkle_value: iter_entry_merkle_value, |
859 | 0 | }; |
860 | 0 | return Ok(TrieNodeInfo { |
861 | 0 | storage_value: StorageValue::None, |
862 | 0 | children: Children { children }, |
863 | 0 | }); |
864 | | } |
865 | 27.0k | (Some(child_num), None) => { |
866 | 27.0k | if let Some(child27.0k ) = iter_entry_decoded.children[usize::from(child_num)] { |
867 | | // Key points in the direction of a child. |
868 | 27.0k | let children_present_in_proof_bitmap = |
869 | 27.0k | self.entries[iter_entry].children_present_in_proof_bitmap; |
870 | 27.0k | |
871 | 27.0k | // If the child isn't present in the proof, then the proof is |
872 | 27.0k | // incomplete. |
873 | 27.0k | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { |
874 | 1 | return Err(IncompleteProofError()); |
875 | 27.0k | } |
876 | 27.0k | |
877 | 27.0k | // Child is present in the proof. Update `iter_entry` and continue. |
878 | 27.0k | iter_entry_merkle_value = child; |
879 | 207k | for c in 0..u8::from(child_num)27.0k { |
880 | 207k | if children_present_in_proof_bitmap & (1 << c) != 0 { |
881 | 54.7k | iter_entry += 1; |
882 | 54.7k | iter_entry += self.entries[iter_entry].child_entries_follow_up; |
883 | 152k | } |
884 | | } |
885 | 27.0k | iter_entry += 1; |
886 | 27.0k | break; |
887 | | } else { |
888 | | // Key points to non-existing child. |
889 | 2 | return Ok(TrieNodeInfo { |
890 | 2 | storage_value: StorageValue::None, |
891 | 2 | children: Children { |
892 | 32 | children: core::array::from_fn(|_| Child::NoChild), _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2H_5slice4iter4IterhEEEEs1_0Bb_ Line | Count | Source | 892 | 16 | children: core::array::from_fn(|_| Child::NoChild), |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2b_5slice4iter4IterhEEEEs1_0Bb_ Line | Count | Source | 892 | 16 | children: core::array::from_fn(|_| Child::NoChild), |
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1G_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs1_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs1_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs1_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs1_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs1_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs1_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs1_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs1_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs1_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs1_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs1_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs1_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs1_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs1_0CsibGXYHQB8Ea_25json_rpc_general_requests |
893 | 2 | }, |
894 | 2 | }); |
895 | | } |
896 | | } |
897 | | (None, None) => { |
898 | | // Exact match. Trie node is `iter_entry`. |
899 | | return Ok(TrieNodeInfo { |
900 | | storage_value: match ( |
901 | 3.72k | iter_entry_decoded.storage_value, |
902 | 3.72k | &self.entries[iter_entry].storage_value_in_proof, |
903 | | ) { |
904 | 931 | (trie_node::StorageValue::Unhashed(value), _) => { |
905 | 931 | StorageValue::Known { |
906 | 931 | value, |
907 | 931 | inline: true, |
908 | 931 | } |
909 | | } |
910 | 7 | (trie_node::StorageValue::Hashed(_), Some(value_range)) => { |
911 | 7 | StorageValue::Known { |
912 | 7 | value: &proof[value_range.clone()], |
913 | 7 | inline: false, |
914 | 7 | } |
915 | | } |
916 | 0 | (trie_node::StorageValue::Hashed(hash), None) => { |
917 | 0 | StorageValue::HashKnownValueMissing(hash) |
918 | | } |
919 | 2.79k | (trie_node::StorageValue::None, _v) => { |
920 | 2.79k | debug_assert!(_v.is_none()); |
921 | 2.79k | StorageValue::None |
922 | | } |
923 | | }, |
924 | | children: Children { |
925 | | children: { |
926 | 59.6k | let mut children = core::array::from_fn(3.72k |_| Child::NoChild); _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2H_5slice4iter4IterhEEEEs2_0Bb_ Line | Count | Source | 926 | 240 | let mut children = core::array::from_fn(|_| Child::NoChild); |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2b_5slice4iter4IterhEEEEs2_0Bb_ Line | Count | Source | 926 | 16 | let mut children = core::array::from_fn(|_| Child::NoChild); |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1G_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs2_0Bb_ Line | Count | Source | 926 | 59.4k | let mut children = core::array::from_fn(|_| Child::NoChild); |
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs2_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs2_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs2_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs2_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs2_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs2_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs2_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs2_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs2_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs2_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2Z_5slice4iter4IterhEEEEs2_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2c_5slice4iter4IterhEEEEs2_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1H_5slice4iter4IterNtNtB9_6nibble6NibbleEEEs2_0CsibGXYHQB8Ea_25json_rpc_general_requests |
927 | 3.72k | let mut i = iter_entry + 1; |
928 | 63.3k | for child_num59.6k in 0..16 { |
929 | 16.4k | let Some(child_merkle_value) = |
930 | 59.6k | iter_entry_decoded.children[child_num] |
931 | | else { |
932 | 43.2k | continue; |
933 | | }; |
934 | 16.4k | if self.entries[iter_entry].children_present_in_proof_bitmap |
935 | 16.4k | & (1 << child_num) |
936 | 16.4k | != 0 |
937 | 7.82k | { |
938 | 7.82k | children[child_num] = Child::InProof { |
939 | 7.82k | child_key: EntryKeyIter::new(self, i), |
940 | 7.82k | merkle_value: child_merkle_value, |
941 | 7.82k | }; |
942 | 7.82k | i += self.entries[i].child_entries_follow_up; |
943 | 7.82k | i += 1; |
944 | 8.61k | } else { |
945 | 8.61k | children[child_num] = Child::AbsentFromProof { |
946 | 8.61k | merkle_value: child_merkle_value, |
947 | 8.61k | }; |
948 | 8.61k | } |
949 | | } |
950 | 3.72k | children |
951 | | }, |
952 | | }, |
953 | | }); |
954 | | } |
955 | | } |
956 | | } |
957 | | } |
958 | 3.73k | } _RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2F_5slice4iter4IterhEEEEB9_ Line | Count | Source | 815 | 16 | pub fn trie_node_info( | 816 | 16 | &'_ self, | 817 | 16 | trie_root_merkle_value: &[u8; 32], | 818 | 16 | mut key: impl Iterator<Item = nibble::Nibble>, | 819 | 16 | ) -> Result<TrieNodeInfo<'_, T>, IncompleteProofError> { | 820 | 16 | let proof = self.proof.as_ref(); | 821 | | | 822 | | // Find the starting point of the requested trie. | 823 | 16 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 824 | 16 | .trie_roots | 825 | 16 | .get_key_value(trie_root_merkle_value) | 826 | 16 | .map(|(k, v)| (&k[..], *v)) | 827 | | else { | 828 | 0 | return Err(IncompleteProofError()); | 829 | | }; | 830 | | | 831 | | loop { | 832 | 119 | let Ok(iter_entry_decoded) = | 833 | 119 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 834 | | else { | 835 | | // Proof has been checked to be entirely decodable. | 836 | 0 | unreachable!() | 837 | | }; | 838 | | | 839 | 119 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 840 | | loop { | 841 | 1.65k | match (key.next(), iter_entry_partial_key_iter.next()) { | 842 | 1.53k | (Some(a), Some(b)) if a == b => {} | 843 | | (Some(_), Some(_)) => { | 844 | | // Mismatch in partial key. No node with the requested key in the trie. | 845 | 0 | return Ok(TrieNodeInfo { | 846 | 0 | storage_value: StorageValue::None, | 847 | 0 | children: Children { | 848 | 0 | children: core::array::from_fn(|_| Child::NoChild), | 849 | 0 | }, | 850 | 0 | }); | 851 | | } | 852 | 0 | (None, Some(a)) => { | 853 | 0 | // Input key is a subslice of `iter_entry`'s key. | 854 | 0 | // One has one descendant that is `iter_entry`. | 855 | 0 | let mut children = core::array::from_fn(|_| Child::NoChild); | 856 | 0 | children[usize::from(a)] = Child::InProof { | 857 | 0 | child_key: EntryKeyIter::new(self, iter_entry), | 858 | 0 | merkle_value: iter_entry_merkle_value, | 859 | 0 | }; | 860 | 0 | return Ok(TrieNodeInfo { | 861 | 0 | storage_value: StorageValue::None, | 862 | 0 | children: Children { children }, | 863 | 0 | }); | 864 | | } | 865 | 104 | (Some(child_num), None) => { | 866 | 104 | if let Some(child103 ) = iter_entry_decoded.children[usize::from(child_num)] { | 867 | | // Key points in the direction of a child. | 868 | 103 | let children_present_in_proof_bitmap = | 869 | 103 | self.entries[iter_entry].children_present_in_proof_bitmap; | 870 | 103 | | 871 | 103 | // If the child isn't present in the proof, then the proof is | 872 | 103 | // incomplete. | 873 | 103 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 874 | 0 | return Err(IncompleteProofError()); | 875 | 103 | } | 876 | 103 | | 877 | 103 | // Child is present in the proof. Update `iter_entry` and continue. | 878 | 103 | iter_entry_merkle_value = child; | 879 | 580 | for c in 0..u8::from(child_num)103 { | 880 | 580 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 881 | 57 | iter_entry += 1; | 882 | 57 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 883 | 523 | } | 884 | | } | 885 | 103 | iter_entry += 1; | 886 | 103 | break; | 887 | | } else { | 888 | | // Key points to non-existing child. | 889 | 1 | return Ok(TrieNodeInfo { | 890 | 1 | storage_value: StorageValue::None, | 891 | 1 | children: Children { | 892 | 1 | children: core::array::from_fn(|_| Child::NoChild), | 893 | 1 | }, | 894 | 1 | }); | 895 | | } | 896 | | } | 897 | | (None, None) => { | 898 | | // Exact match. Trie node is `iter_entry`. | 899 | | return Ok(TrieNodeInfo { | 900 | | storage_value: match ( | 901 | 15 | iter_entry_decoded.storage_value, | 902 | 15 | &self.entries[iter_entry].storage_value_in_proof, | 903 | | ) { | 904 | 8 | (trie_node::StorageValue::Unhashed(value), _) => { | 905 | 8 | StorageValue::Known { | 906 | 8 | value, | 907 | 8 | inline: true, | 908 | 8 | } | 909 | | } | 910 | 7 | (trie_node::StorageValue::Hashed(_), Some(value_range)) => { | 911 | 7 | StorageValue::Known { | 912 | 7 | value: &proof[value_range.clone()], | 913 | 7 | inline: false, | 914 | 7 | } | 915 | | } | 916 | 0 | (trie_node::StorageValue::Hashed(hash), None) => { | 917 | 0 | StorageValue::HashKnownValueMissing(hash) | 918 | | } | 919 | 0 | (trie_node::StorageValue::None, _v) => { | 920 | 0 | debug_assert!(_v.is_none()); | 921 | 0 | StorageValue::None | 922 | | } | 923 | | }, | 924 | | children: Children { | 925 | | children: { | 926 | 15 | let mut children = core::array::from_fn(|_| Child::NoChild); | 927 | 15 | let mut i = iter_entry + 1; | 928 | 255 | for child_num240 in 0..16 { | 929 | 0 | let Some(child_merkle_value) = | 930 | 240 | iter_entry_decoded.children[child_num] | 931 | | else { | 932 | 240 | continue; | 933 | | }; | 934 | 0 | if self.entries[iter_entry].children_present_in_proof_bitmap | 935 | 0 | & (1 << child_num) | 936 | 0 | != 0 | 937 | 0 | { | 938 | 0 | children[child_num] = Child::InProof { | 939 | 0 | child_key: EntryKeyIter::new(self, i), | 940 | 0 | merkle_value: child_merkle_value, | 941 | 0 | }; | 942 | 0 | i += self.entries[i].child_entries_follow_up; | 943 | 0 | i += 1; | 944 | 0 | } else { | 945 | 0 | children[child_num] = Child::AbsentFromProof { | 946 | 0 | merkle_value: child_merkle_value, | 947 | 0 | }; | 948 | 0 | } | 949 | | } | 950 | 15 | children | 951 | | }, | 952 | | }, | 953 | | }); | 954 | | } | 955 | | } | 956 | | } | 957 | | } | 958 | 16 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB29_5slice4iter4IterhEEEEB9_ Line | Count | Source | 815 | 4 | pub fn trie_node_info( | 816 | 4 | &'_ self, | 817 | 4 | trie_root_merkle_value: &[u8; 32], | 818 | 4 | mut key: impl Iterator<Item = nibble::Nibble>, | 819 | 4 | ) -> Result<TrieNodeInfo<'_, T>, IncompleteProofError> { | 820 | 4 | let proof = self.proof.as_ref(); | 821 | | | 822 | | // Find the starting point of the requested trie. | 823 | 4 | let Some((mut iter_entry_merkle_value, mut iter_entry3 )) = self | 824 | 4 | .trie_roots | 825 | 4 | .get_key_value(trie_root_merkle_value) | 826 | 4 | .map(|(k, v)| (&k[..], *v)) | 827 | | else { | 828 | 1 | return Err(IncompleteProofError()); | 829 | | }; | 830 | | | 831 | | loop { | 832 | 17 | let Ok(iter_entry_decoded) = | 833 | 17 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 834 | | else { | 835 | | // Proof has been checked to be entirely decodable. | 836 | 0 | unreachable!() | 837 | | }; | 838 | | | 839 | 17 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 840 | | loop { | 841 | 325 | match (key.next(), iter_entry_partial_key_iter.next()) { | 842 | 308 | (Some(a), Some(b)) if a == b => {} | 843 | | (Some(_), Some(_)) => { | 844 | | // Mismatch in partial key. No node with the requested key in the trie. | 845 | 0 | return Ok(TrieNodeInfo { | 846 | 0 | storage_value: StorageValue::None, | 847 | 0 | children: Children { | 848 | 0 | children: core::array::from_fn(|_| Child::NoChild), | 849 | 0 | }, | 850 | 0 | }); | 851 | | } | 852 | 0 | (None, Some(a)) => { | 853 | 0 | // Input key is a subslice of `iter_entry`'s key. | 854 | 0 | // One has one descendant that is `iter_entry`. | 855 | 0 | let mut children = core::array::from_fn(|_| Child::NoChild); | 856 | 0 | children[usize::from(a)] = Child::InProof { | 857 | 0 | child_key: EntryKeyIter::new(self, iter_entry), | 858 | 0 | merkle_value: iter_entry_merkle_value, | 859 | 0 | }; | 860 | 0 | return Ok(TrieNodeInfo { | 861 | 0 | storage_value: StorageValue::None, | 862 | 0 | children: Children { children }, | 863 | 0 | }); | 864 | | } | 865 | 16 | (Some(child_num), None) => { | 866 | 16 | if let Some(child15 ) = iter_entry_decoded.children[usize::from(child_num)] { | 867 | | // Key points in the direction of a child. | 868 | 15 | let children_present_in_proof_bitmap = | 869 | 15 | self.entries[iter_entry].children_present_in_proof_bitmap; | 870 | 15 | | 871 | 15 | // If the child isn't present in the proof, then the proof is | 872 | 15 | // incomplete. | 873 | 15 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 874 | 1 | return Err(IncompleteProofError()); | 875 | 14 | } | 876 | 14 | | 877 | 14 | // Child is present in the proof. Update `iter_entry` and continue. | 878 | 14 | iter_entry_merkle_value = child; | 879 | 82 | for c in 0..u8::from(child_num)14 { | 880 | 82 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 881 | 0 | iter_entry += 1; | 882 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 883 | 82 | } | 884 | | } | 885 | 14 | iter_entry += 1; | 886 | 14 | break; | 887 | | } else { | 888 | | // Key points to non-existing child. | 889 | 1 | return Ok(TrieNodeInfo { | 890 | 1 | storage_value: StorageValue::None, | 891 | 1 | children: Children { | 892 | 1 | children: core::array::from_fn(|_| Child::NoChild), | 893 | 1 | }, | 894 | 1 | }); | 895 | | } | 896 | | } | 897 | | (None, None) => { | 898 | | // Exact match. Trie node is `iter_entry`. | 899 | | return Ok(TrieNodeInfo { | 900 | | storage_value: match ( | 901 | 1 | iter_entry_decoded.storage_value, | 902 | 1 | &self.entries[iter_entry].storage_value_in_proof, | 903 | | ) { | 904 | 1 | (trie_node::StorageValue::Unhashed(value), _) => { | 905 | 1 | StorageValue::Known { | 906 | 1 | value, | 907 | 1 | inline: true, | 908 | 1 | } | 909 | | } | 910 | 0 | (trie_node::StorageValue::Hashed(_), Some(value_range)) => { | 911 | 0 | StorageValue::Known { | 912 | 0 | value: &proof[value_range.clone()], | 913 | 0 | inline: false, | 914 | 0 | } | 915 | | } | 916 | 0 | (trie_node::StorageValue::Hashed(hash), None) => { | 917 | 0 | StorageValue::HashKnownValueMissing(hash) | 918 | | } | 919 | 0 | (trie_node::StorageValue::None, _v) => { | 920 | 0 | debug_assert!(_v.is_none()); | 921 | 0 | StorageValue::None | 922 | | } | 923 | | }, | 924 | | children: Children { | 925 | | children: { | 926 | 1 | let mut children = core::array::from_fn(|_| Child::NoChild); | 927 | 1 | let mut i = iter_entry + 1; | 928 | 17 | for child_num16 in 0..16 { | 929 | 0 | let Some(child_merkle_value) = | 930 | 16 | iter_entry_decoded.children[child_num] | 931 | | else { | 932 | 16 | continue; | 933 | | }; | 934 | 0 | if self.entries[iter_entry].children_present_in_proof_bitmap | 935 | 0 | & (1 << child_num) | 936 | 0 | != 0 | 937 | 0 | { | 938 | 0 | children[child_num] = Child::InProof { | 939 | 0 | child_key: EntryKeyIter::new(self, i), | 940 | 0 | merkle_value: child_merkle_value, | 941 | 0 | }; | 942 | 0 | i += self.entries[i].child_entries_follow_up; | 943 | 0 | i += 1; | 944 | 0 | } else { | 945 | 0 | children[child_num] = Child::AbsentFromProof { | 946 | 0 | merkle_value: child_merkle_value, | 947 | 0 | }; | 948 | 0 | } | 949 | | } | 950 | 1 | children | 951 | | }, | 952 | | }, | 953 | | }); | 954 | | } | 955 | | } | 956 | | } | 957 | | } | 958 | 4 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1E_5slice4iter4IterNtNtB7_6nibble6NibbleEEEB9_ Line | Count | Source | 815 | 3.71k | pub fn trie_node_info( | 816 | 3.71k | &'_ self, | 817 | 3.71k | trie_root_merkle_value: &[u8; 32], | 818 | 3.71k | mut key: impl Iterator<Item = nibble::Nibble>, | 819 | 3.71k | ) -> Result<TrieNodeInfo<'_, T>, IncompleteProofError> { | 820 | 3.71k | let proof = self.proof.as_ref(); | 821 | | | 822 | | // Find the starting point of the requested trie. | 823 | 3.71k | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 824 | 3.71k | .trie_roots | 825 | 3.71k | .get_key_value(trie_root_merkle_value) | 826 | 3.71k | .map(|(k, v)| (&k[..], *v)) | 827 | | else { | 828 | 0 | return Err(IncompleteProofError()); | 829 | | }; | 830 | | | 831 | | loop { | 832 | 30.6k | let Ok(iter_entry_decoded) = | 833 | 30.6k | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 834 | | else { | 835 | | // Proof has been checked to be entirely decodable. | 836 | 0 | unreachable!() | 837 | | }; | 838 | | | 839 | 30.6k | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 840 | | loop { | 841 | 320k | match (key.next(), iter_entry_partial_key_iter.next()) { | 842 | 289k | (Some(a), Some(b)) if a == b => {} | 843 | | (Some(_), Some(_)) => { | 844 | | // Mismatch in partial key. No node with the requested key in the trie. | 845 | 0 | return Ok(TrieNodeInfo { | 846 | 0 | storage_value: StorageValue::None, | 847 | 0 | children: Children { | 848 | 0 | children: core::array::from_fn(|_| Child::NoChild), | 849 | 0 | }, | 850 | 0 | }); | 851 | | } | 852 | 0 | (None, Some(a)) => { | 853 | 0 | // Input key is a subslice of `iter_entry`'s key. | 854 | 0 | // One has one descendant that is `iter_entry`. | 855 | 0 | let mut children = core::array::from_fn(|_| Child::NoChild); | 856 | 0 | children[usize::from(a)] = Child::InProof { | 857 | 0 | child_key: EntryKeyIter::new(self, iter_entry), | 858 | 0 | merkle_value: iter_entry_merkle_value, | 859 | 0 | }; | 860 | 0 | return Ok(TrieNodeInfo { | 861 | 0 | storage_value: StorageValue::None, | 862 | 0 | children: Children { children }, | 863 | 0 | }); | 864 | | } | 865 | 26.9k | (Some(child_num), None) => { | 866 | 26.9k | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 867 | | // Key points in the direction of a child. | 868 | 26.9k | let children_present_in_proof_bitmap = | 869 | 26.9k | self.entries[iter_entry].children_present_in_proof_bitmap; | 870 | 26.9k | | 871 | 26.9k | // If the child isn't present in the proof, then the proof is | 872 | 26.9k | // incomplete. | 873 | 26.9k | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 874 | 0 | return Err(IncompleteProofError()); | 875 | 26.9k | } | 876 | 26.9k | | 877 | 26.9k | // Child is present in the proof. Update `iter_entry` and continue. | 878 | 26.9k | iter_entry_merkle_value = child; | 879 | 206k | for c in 0..u8::from(child_num)26.9k { | 880 | 206k | if children_present_in_proof_bitmap & (1 << c) != 0 { | 881 | 54.7k | iter_entry += 1; | 882 | 54.7k | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 883 | 151k | } | 884 | | } | 885 | 26.9k | iter_entry += 1; | 886 | 26.9k | break; | 887 | | } else { | 888 | | // Key points to non-existing child. | 889 | 0 | return Ok(TrieNodeInfo { | 890 | 0 | storage_value: StorageValue::None, | 891 | 0 | children: Children { | 892 | 0 | children: core::array::from_fn(|_| Child::NoChild), | 893 | 0 | }, | 894 | 0 | }); | 895 | | } | 896 | | } | 897 | | (None, None) => { | 898 | | // Exact match. Trie node is `iter_entry`. | 899 | | return Ok(TrieNodeInfo { | 900 | | storage_value: match ( | 901 | 3.71k | iter_entry_decoded.storage_value, | 902 | 3.71k | &self.entries[iter_entry].storage_value_in_proof, | 903 | | ) { | 904 | 922 | (trie_node::StorageValue::Unhashed(value), _) => { | 905 | 922 | StorageValue::Known { | 906 | 922 | value, | 907 | 922 | inline: true, | 908 | 922 | } | 909 | | } | 910 | 0 | (trie_node::StorageValue::Hashed(_), Some(value_range)) => { | 911 | 0 | StorageValue::Known { | 912 | 0 | value: &proof[value_range.clone()], | 913 | 0 | inline: false, | 914 | 0 | } | 915 | | } | 916 | 0 | (trie_node::StorageValue::Hashed(hash), None) => { | 917 | 0 | StorageValue::HashKnownValueMissing(hash) | 918 | | } | 919 | 2.79k | (trie_node::StorageValue::None, _v) => { | 920 | 2.79k | debug_assert!(_v.is_none()); | 921 | 2.79k | StorageValue::None | 922 | | } | 923 | | }, | 924 | | children: Children { | 925 | | children: { | 926 | 3.71k | let mut children = core::array::from_fn(|_| Child::NoChild); | 927 | 3.71k | let mut i = iter_entry + 1; | 928 | 63.1k | for child_num59.4k in 0..16 { | 929 | 16.4k | let Some(child_merkle_value) = | 930 | 59.4k | iter_entry_decoded.children[child_num] | 931 | | else { | 932 | 42.9k | continue; | 933 | | }; | 934 | 16.4k | if self.entries[iter_entry].children_present_in_proof_bitmap | 935 | 16.4k | & (1 << child_num) | 936 | 16.4k | != 0 | 937 | 7.82k | { | 938 | 7.82k | children[child_num] = Child::InProof { | 939 | 7.82k | child_key: EntryKeyIter::new(self, i), | 940 | 7.82k | merkle_value: child_merkle_value, | 941 | 7.82k | }; | 942 | 7.82k | i += self.entries[i].child_entries_follow_up; | 943 | 7.82k | i += 1; | 944 | 8.61k | } else { | 945 | 8.61k | children[child_num] = Child::AbsentFromProof { | 946 | 8.61k | merkle_value: child_merkle_value, | 947 | 8.61k | }; | 948 | 8.61k | } | 949 | | } | 950 | 3.71k | children | 951 | | }, | 952 | | }, | 953 | | }); | 954 | | } | 955 | | } | 956 | | } | 957 | | } | 958 | 3.71k | } |
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2X_5slice4iter4IterhEEEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2a_5slice4iter4IterhEEEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1F_5slice4iter4IterNtNtB7_6nibble6NibbleEEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1F_5slice4iter4IterNtNtB7_6nibble6NibbleEEEB9_ Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2X_5slice4iter4IterhEEEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2a_5slice4iter4IterhEEEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1F_5slice4iter4IterNtNtB7_6nibble6NibbleEEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2X_5slice4iter4IterhEEEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2a_5slice4iter4IterhEEEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1F_5slice4iter4IterNtNtB7_6nibble6NibbleEEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2X_5slice4iter4IterhEEEECsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2a_5slice4iter4IterhEEEECsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE14trie_node_infoINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB1F_5slice4iter4IterNtNtB7_6nibble6NibbleEEECsibGXYHQB8Ea_25json_rpc_general_requests |
959 | | |
960 | | /// Queries from the proof the storage value at the given key. |
961 | | /// |
962 | | /// Returns an error if the storage value couldn't be determined from the proof. Returns |
963 | | /// `Ok(None)` if the storage value is known to have no value. |
964 | | /// |
965 | | /// > **Note**: This function is a convenient wrapper around |
966 | | /// > [`DecodedTrieProof::trie_node_info`]. |
967 | | // TODO: accept param as iterator rather than slice? |
968 | 20 | pub fn storage_value( |
969 | 20 | &'_ self, |
970 | 20 | trie_root_merkle_value: &[u8; 32], |
971 | 20 | key: &[u8], |
972 | 20 | ) -> Result<Option<(&'_ [u8], TrieEntryVersion)>, IncompleteProofError> { |
973 | 20 | match self |
974 | 20 | .trie_node_info( |
975 | 20 | trie_root_merkle_value, |
976 | 20 | nibble::bytes_to_nibbles(key.iter().copied()), |
977 | 20 | )?2 |
978 | | .storage_value |
979 | | { |
980 | 16 | StorageValue::Known { value, inline } => Ok(Some(( |
981 | 16 | value, |
982 | 16 | if inline { |
983 | 9 | TrieEntryVersion::V0 |
984 | | } else { |
985 | 7 | TrieEntryVersion::V1 |
986 | | }, |
987 | | ))), |
988 | 0 | StorageValue::HashKnownValueMissing(_) => Err(IncompleteProofError()), |
989 | 2 | StorageValue::None => Ok(None), |
990 | | } |
991 | 20 | } _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE13storage_valueB8_ Line | Count | Source | 968 | 16 | pub fn storage_value( | 969 | 16 | &'_ self, | 970 | 16 | trie_root_merkle_value: &[u8; 32], | 971 | 16 | key: &[u8], | 972 | 16 | ) -> Result<Option<(&'_ [u8], TrieEntryVersion)>, IncompleteProofError> { | 973 | 16 | match self | 974 | 16 | .trie_node_info( | 975 | 16 | trie_root_merkle_value, | 976 | 16 | nibble::bytes_to_nibbles(key.iter().copied()), | 977 | 16 | )?0 | 978 | | .storage_value | 979 | | { | 980 | 15 | StorageValue::Known { value, inline } => Ok(Some(( | 981 | 15 | value, | 982 | 15 | if inline { | 983 | 8 | TrieEntryVersion::V0 | 984 | | } else { | 985 | 7 | TrieEntryVersion::V1 | 986 | | }, | 987 | | ))), | 988 | 0 | StorageValue::HashKnownValueMissing(_) => Err(IncompleteProofError()), | 989 | 1 | StorageValue::None => Ok(None), | 990 | | } | 991 | 16 | } |
_RNvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofRShE13storage_valueB8_ Line | Count | Source | 968 | 4 | pub fn storage_value( | 969 | 4 | &'_ self, | 970 | 4 | trie_root_merkle_value: &[u8; 32], | 971 | 4 | key: &[u8], | 972 | 4 | ) -> Result<Option<(&'_ [u8], TrieEntryVersion)>, IncompleteProofError> { | 973 | 4 | match self | 974 | 4 | .trie_node_info( | 975 | 4 | trie_root_merkle_value, | 976 | 4 | nibble::bytes_to_nibbles(key.iter().copied()), | 977 | 4 | )?2 | 978 | | .storage_value | 979 | | { | 980 | 1 | StorageValue::Known { value, inline } => Ok(Some(( | 981 | 1 | value, | 982 | 1 | if inline { | 983 | 1 | TrieEntryVersion::V0 | 984 | | } else { | 985 | 0 | TrieEntryVersion::V1 | 986 | | }, | 987 | | ))), | 988 | 0 | StorageValue::HashKnownValueMissing(_) => Err(IncompleteProofError()), | 989 | 1 | StorageValue::None => Ok(None), | 990 | | } | 991 | 4 | } |
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE13storage_valueCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofRShE13storage_valueCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofpE13storage_valueB8_ Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE13storage_valueCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofRShE13storage_valueCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE13storage_valueCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofRShE13storage_valueCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE13storage_valueCsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB4_16DecodedTrieProofRShE13storage_valueCsibGXYHQB8Ea_25json_rpc_general_requests |
992 | | |
993 | | /// Find in the proof the trie node that follows `key_before` in lexicographic order. |
994 | | /// |
995 | | /// If `or_equal` is `true`, then `key_before` is returned if it is equal to a node in the |
996 | | /// trie. If `false`, then only keys that are strictly superior are returned. |
997 | | /// |
998 | | /// The returned value must always start with `prefix`. Note that the value of `prefix` is |
999 | | /// important as it can be the difference between `Err(IncompleteProofError)` and `Ok(None)`. |
1000 | | /// |
1001 | | /// If `branch_nodes` is `false`, then trie nodes that don't have a storage value are skipped. |
1002 | | /// |
1003 | | /// Returns an error if the proof doesn't contain enough information to determine the next key. |
1004 | | /// Returns `Ok(None)` if the proof indicates that there is no next key (within the given |
1005 | | /// prefix). |
1006 | 6 | pub fn next_key( |
1007 | 6 | &'_ self, |
1008 | 6 | trie_root_merkle_value: &[u8; 32], |
1009 | 6 | key_before: impl Iterator<Item = nibble::Nibble>, |
1010 | 6 | mut or_equal: bool, |
1011 | 6 | prefix: impl Iterator<Item = nibble::Nibble>, |
1012 | 6 | branch_nodes: bool, |
1013 | 6 | ) -> Result<Option<EntryKeyIter<'_, T>>, IncompleteProofError> { |
1014 | 6 | let proof = self.proof.as_ref(); |
1015 | 6 | |
1016 | 6 | // The implementation below might continue iterating `prefix` even after it has returned |
1017 | 6 | // `None`, thus we have to fuse it. |
1018 | 6 | let mut prefix = prefix.fuse(); |
1019 | 6 | |
1020 | 6 | // The implementation below might continue iterating `key_before` even after it has |
1021 | 6 | // returned `None`, thus we have to fuse it. |
1022 | 6 | // Furthermore, `key_before` might be modified in the implementation below. When that |
1023 | 6 | // happens, de do this by setting it to `either::Right`. |
1024 | 6 | let mut key_before = either::Left(key_before.fuse()); |
1025 | | |
1026 | | // Find the starting point of the requested trie. |
1027 | 6 | let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else { |
1028 | 0 | return Err(IncompleteProofError()); |
1029 | | }; |
1030 | | |
1031 | | // If `true`, then it was determined that `key_before` was after the last child of |
1032 | | // `iter_entry`. The next iteration must find `iter_entry`'s next sibling. |
1033 | 6 | let mut iterating_up: bool = false; |
1034 | 6 | |
1035 | 6 | // Indicates the depth of ancestors of `iter_entry` that match `prefix`. |
1036 | 6 | // For example, if the value is 2, then `iter_entry`'s parent and grandparent match |
1037 | 6 | //`prefix`, but `iter_entry`'s grandparent parent does not. |
1038 | 6 | let mut prefix_match_iter_entry_ancestor_depth = 0; |
1039 | | |
1040 | | loop { |
1041 | 11 | let Ok(iter_entry_decoded) = |
1042 | 11 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) |
1043 | | else { |
1044 | | // Proof has been checked to be entirely decodable. |
1045 | 0 | unreachable!() |
1046 | | }; |
1047 | | |
1048 | 11 | if iterating_up { |
1049 | 0 | debug_assert!(matches!(key_before, either::Right(_))); |
1050 | 0 | debug_assert!(or_equal); |
1051 | | |
1052 | | // It was determined that `key_before` was after the last child of `iter_entry`. |
1053 | | // The next iteration must find `iter_entry`'s next sibling. |
1054 | | |
1055 | 0 | if prefix_match_iter_entry_ancestor_depth == 0 { |
1056 | | // `prefix` only matches `iter_entry` and not its parent and |
1057 | | // thus wouldn't match `iter_entry`'s sibling or uncle. |
1058 | | // Therefore, the next node is `None`. |
1059 | 0 | return Ok(None); |
1060 | 0 | } |
1061 | | |
1062 | | // Go to `iter_entry`'s next sibling, if any. |
1063 | 0 | let Some((parent_entry, parent_to_child_nibble)) = |
1064 | 0 | self.entries[iter_entry].parent_entry_index |
1065 | | else { |
1066 | | // `iter_entry` is the root of the trie. `key_before` is therefore |
1067 | | // after the last entry of the trie. |
1068 | 0 | return Ok(None); |
1069 | | }; |
1070 | | |
1071 | 0 | let Some(child_num) = iter_entry_decoded |
1072 | 0 | .children |
1073 | 0 | .iter() |
1074 | 0 | .skip(usize::from(parent_to_child_nibble) + 1) |
1075 | 0 | .position(|c| c.is_some()) Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB35_5slice4iter4IterhEEEIB1X_IB2s_INtNvNtBb_4util11as_ref_iter4IterIB1X_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5j_11Interpreter11read_memory12AccessOffsetB57_EEhEEINtNtB31_7flatten7FlatMapINtNtB31_5chain5ChainINtNtB31_3map3MapIB6L_IB3R_NtNtB5n_20trie_root_calculator14InProgressNodeEIB7a_INtNtNtB33_7sources4once4OnceIB1X_ANtB2u_6Nibblej1_RIB1e_B9k_EEEINtNtB35_6option8IntoIterB9e_EENCNvMs3_B7X_NtB7X_5Inner21current_node_full_key0ENcNtIB1X_B9e_B9A_E4Left0EIB8M_Bb9_EEIB4w_Bbz_B9k_EIB4y_B9k_Bbz_EEEEIB1X_IB2s_IB4w_IB1X_B52_B57_EhEEIB1X_B1W_INtNtB8Q_5empty5EmptyB9k_EEEE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB9_6nibble6NibbleEB1q_E0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss0_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss2_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_works0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss3_0EIB1r_IB2f_hKj21_ENCB2S_s4_0EE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss5_0EIB1r_IB2f_hKj1f_ENCB2S_s6_0EE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2A_5slice4iter4IterhEEEIB1s_IB1X_INtNvNtBb_4util11as_ref_iter4IterIB1s_B1e_INtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB4P_11Interpreter11read_memory12AccessOffsetB1e_EEhEEINtNtB2w_7flatten7FlatMapINtNtB2w_5chain5ChainINtNtB2w_3map3MapIB6h_IB3m_NtNtB4T_20trie_root_calculator14InProgressNodeEIB6G_INtNtNtB2y_7sources4once4OnceIB1s_ANtB1Z_6Nibblej1_RINtNtCsdZExvAaxgia_5alloc3vec3VecB8Q_EEEINtNtB2A_6option8IntoIterB8K_EENCNvMs3_B7t_NtB7t_5Inner21current_node_full_key0ENcNtIB1s_B8K_B96_E4Left0EIB8i_Bb7_EEIB41_Bbx_B8Q_EIB43_B8Q_Bbx_EEEEIB1s_IB1X_IB41_IB1s_B4x_B1e_EhEEIB1s_B1r_INtNtB8m_5empty5EmptyB8Q_EEEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofpE8next_keyppE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEE0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEE0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEE0CsibGXYHQB8Ea_25json_rpc_general_requests |
1076 | 0 | .map(|n| n + usize::from(parent_to_child_nibble) + 1) Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB35_5slice4iter4IterhEEEIB1X_IB2s_INtNvNtBb_4util11as_ref_iter4IterIB1X_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5j_11Interpreter11read_memory12AccessOffsetB57_EEhEEINtNtB31_7flatten7FlatMapINtNtB31_5chain5ChainINtNtB31_3map3MapIB6L_IB3R_NtNtB5n_20trie_root_calculator14InProgressNodeEIB7a_INtNtNtB33_7sources4once4OnceIB1X_ANtB2u_6Nibblej1_RIB1e_B9k_EEEINtNtB35_6option8IntoIterB9e_EENCNvMs3_B7X_NtB7X_5Inner21current_node_full_key0ENcNtIB1X_B9e_B9A_E4Left0EIB8M_Bb9_EEIB4w_Bbz_B9k_EIB4y_B9k_Bbz_EEEEIB1X_IB2s_IB4w_IB1X_B52_B57_EhEEIB1X_B1W_INtNtB8Q_5empty5EmptyB9k_EEEEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB9_6nibble6NibbleEB1q_Es_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss0_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss2_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_works0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss3_0EIB1r_IB2f_hKj21_ENCB2S_s4_0EEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss5_0EIB1r_IB2f_hKj1f_ENCB2S_s6_0EEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2A_5slice4iter4IterhEEEIB1s_IB1X_INtNvNtBb_4util11as_ref_iter4IterIB1s_B1e_INtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB4P_11Interpreter11read_memory12AccessOffsetB1e_EEhEEINtNtB2w_7flatten7FlatMapINtNtB2w_5chain5ChainINtNtB2w_3map3MapIB6h_IB3m_NtNtB4T_20trie_root_calculator14InProgressNodeEIB6G_INtNtNtB2y_7sources4once4OnceIB1s_ANtB1Z_6Nibblej1_RINtNtCsdZExvAaxgia_5alloc3vec3VecB8Q_EEEINtNtB2A_6option8IntoIterB8K_EENCNvMs3_B7t_NtB7t_5Inner21current_node_full_key0ENcNtIB1s_B8K_B96_E4Left0EIB8i_Bb7_EEIB41_Bbx_B8Q_EIB43_B8Q_Bbx_EEEEIB1s_IB1X_IB41_IB1s_B4x_B1e_EhEEIB1s_B1r_INtNtB8m_5empty5EmptyB8Q_EEEEs_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofpE8next_keyppEs_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs_0CsibGXYHQB8Ea_25json_rpc_general_requests |
1077 | | else { |
1078 | | // No child found. Continue iterating up. |
1079 | 0 | iterating_up = true; |
1080 | 0 | iter_entry = parent_entry; |
1081 | 0 | prefix_match_iter_entry_ancestor_depth -= 1; |
1082 | 0 | continue; |
1083 | | }; |
1084 | | |
1085 | | // Found a next sibling. |
1086 | | |
1087 | 0 | let children_present_in_proof_bitmap = |
1088 | 0 | self.entries[parent_entry].children_present_in_proof_bitmap; |
1089 | 0 |
|
1090 | 0 | // If the child isn't present in the proof, then the proof is |
1091 | 0 | // incomplete. While in some situations we could prove that the child |
1092 | 0 | // is necessarily the next key, there is no way to know its full key. |
1093 | 0 | if children_present_in_proof_bitmap & (1 << child_num) == 0 { |
1094 | 0 | return Err(IncompleteProofError()); |
1095 | 0 | } |
1096 | 0 |
|
1097 | 0 | // `iter_entry` is still pointing to the child at index `parent_to_child_nibble`. |
1098 | 0 | // Since we're jumping to its next sibling, all we have to do is skip over it |
1099 | 0 | // and its descedants. |
1100 | 0 | iter_entry += 1; |
1101 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; |
1102 | 0 | iterating_up = false; |
1103 | 11 | } |
1104 | | |
1105 | 11 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; |
1106 | | loop { |
1107 | | match ( |
1108 | 164 | key_before.next(), |
1109 | 164 | prefix.next(), |
1110 | 164 | iter_entry_partial_key_iter.next(), |
1111 | | ) { |
1112 | 61 | (Some(k), Some(p), Some(pk60 )) if k == p && p60 == pk => { |
1113 | 60 | // Continue descending down the tree. |
1114 | 60 | } |
1115 | 0 | (None, Some(p), Some(pk)) if p == pk => { |
1116 | 0 | // Continue descending down the tree. |
1117 | 0 | } |
1118 | 91 | (Some(k), None, Some(pk)) if k == pk => { |
1119 | 91 | // Continue descending down the tree. |
1120 | 91 | } |
1121 | 2 | (None, None, Some(_)) => { |
1122 | 2 | // Exact match. Due to the `branch_nodes` setting, we can't just |
1123 | 2 | // return `iter_entry` and instead continue iterating. |
1124 | 2 | or_equal = true; |
1125 | 2 | } |
1126 | 0 | (Some(k), None, Some(pk)) if k < pk => { |
1127 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent |
1128 | 0 | // and `iter_entry`. Due to the `branch_nodes` setting, we can't just |
1129 | 0 | // return `iter_entry` and instead continue iterating. |
1130 | 0 | key_before = either::Right(iter::empty().fuse()); |
1131 | 0 | or_equal = true; |
1132 | 0 | } |
1133 | 3 | (Some(k), Some(p0 ), _) if k > p => { |
1134 | 0 | // `key_before` is strictly superior to `prefix`. The next key is |
1135 | 0 | // thus necessarily `None`. |
1136 | 0 | // Note that this is not a situation that is expected to be common, as |
1137 | 0 | // doing such a call is pointless. |
1138 | 0 | return Ok(None); |
1139 | | } |
1140 | 1 | (Some(k), Some(p), Some(pk0 )) if k < p && p == pk => { |
1141 | 0 | // The key and prefix diverge. |
1142 | 0 | // We know that there isn't any key in the trie between `key_before` |
1143 | 0 | // and `prefix`. |
1144 | 0 | // Starting next iteration, the next node matching the prefix |
1145 | 0 | // will be the result. |
1146 | 0 | key_before = either::Right(iter::empty().fuse()); |
1147 | 0 | or_equal = true; |
1148 | 0 | } |
1149 | 1 | (_, Some(p), Some(pk)) => { |
1150 | 1 | debug_assert!(p != pk); // Other situations covered by other match blocks. |
1151 | | |
1152 | | // Mismatch between prefix and partial key. No matter the value of |
1153 | | // `key_before` There is no node in the trie that starts with `prefix`. |
1154 | 1 | return Ok(None); |
1155 | | } |
1156 | 0 | (Some(k), None, Some(pk)) if k < pk => { |
1157 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent |
1158 | 0 | // and `iter_entry`. We know that `iter_entry` necessarily matches |
1159 | 0 | // the prefix. The next key is necessarily `iter_entry`. |
1160 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); |
1161 | | } |
1162 | 0 | (Some(k), None, Some(pk)) => { |
1163 | 0 | debug_assert!(k > pk); // Checked above. |
1164 | | |
1165 | | // `key_before` points to somewhere between the last child of `iter_entry` |
1166 | | // and its next sibling. |
1167 | | // The next key is thus the next sibling of `iter_entry`. |
1168 | 0 | iterating_up = true; |
1169 | 0 | key_before = either::Right(iter::empty().fuse()); |
1170 | 0 | or_equal = true; |
1171 | 0 | break; |
1172 | | } |
1173 | | (None, None, None) |
1174 | 4 | if or_equal |
1175 | 4 | && (branch_nodes |
1176 | 0 | || !matches!( |
1177 | 1 | iter_entry_decoded.storage_value, |
1178 | | trie_node::StorageValue::None, |
1179 | 3 | )) => |
1180 | 3 | { |
1181 | 3 | // Exact match. Next key is `iter_entry`. |
1182 | 3 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); |
1183 | | } |
1184 | 7 | (key_before_nibble, prefix_nibble, None) => { |
1185 | | // The moment when we have finished traversing a node and go to the |
1186 | | // next one is the most complicated situation. |
1187 | | |
1188 | | // We know for sure that `iter_entry` can't be returned, as it is covered |
1189 | | // by the other match variants above. Therefore, `key_before_nibble` equal |
1190 | | // to `None` is the same as if it is equal to `0`. |
1191 | 7 | let key_before_nibble = match key_before_nibble { |
1192 | 5 | Some(n) => u8::from(n), |
1193 | | None => { |
1194 | 2 | or_equal = true; |
1195 | 2 | 0 |
1196 | | } |
1197 | | }; |
1198 | | |
1199 | | // Try to find the first child that is after `key_before`. |
1200 | 7 | if let Some(child_num) = iter_entry_decoded |
1201 | 7 | .children |
1202 | 7 | .iter() |
1203 | 7 | .skip(usize::from(key_before_nibble)) |
1204 | 17 | .position(|c| c.is_some()) Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB35_5slice4iter4IterhEEEIB1X_IB2s_INtNvNtBb_4util11as_ref_iter4IterIB1X_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5j_11Interpreter11read_memory12AccessOffsetB57_EEhEEINtNtB31_7flatten7FlatMapINtNtB31_5chain5ChainINtNtB31_3map3MapIB6L_IB3R_NtNtB5n_20trie_root_calculator14InProgressNodeEIB7a_INtNtNtB33_7sources4once4OnceIB1X_ANtB2u_6Nibblej1_RIB1e_B9k_EEEINtNtB35_6option8IntoIterB9e_EENCNvMs3_B7X_NtB7X_5Inner21current_node_full_key0ENcNtIB1X_B9e_B9A_E4Left0EIB8M_Bb9_EEIB4w_Bbz_B9k_EIB4y_B9k_Bbz_EEEEIB1X_IB2s_IB4w_IB1X_B52_B57_EhEEIB1X_B1W_INtNtB8Q_5empty5EmptyB9k_EEEEs0_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB9_6nibble6NibbleEB1q_Es0_0Bb_ _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss0_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs0_0Bb_ Line | Count | Source | 1204 | 1 | .position(|c| c.is_some()) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss2_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs0_0Bb_ Line | Count | Source | 1204 | 7 | .position(|c| c.is_some()) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_works0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs0_0Bb_ Line | Count | Source | 1204 | 1 | .position(|c| c.is_some()) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss3_0EIB1r_IB2f_hKj21_ENCB2S_s4_0EEs0_0Bb_ Line | Count | Source | 1204 | 7 | .position(|c| c.is_some()) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss5_0EIB1r_IB2f_hKj1f_ENCB2S_s6_0EEs0_0Bb_ Line | Count | Source | 1204 | 1 | .position(|c| c.is_some()) |
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs0_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2A_5slice4iter4IterhEEEIB1s_IB1X_INtNvNtBb_4util11as_ref_iter4IterIB1s_B1e_INtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB4P_11Interpreter11read_memory12AccessOffsetB1e_EEhEEINtNtB2w_7flatten7FlatMapINtNtB2w_5chain5ChainINtNtB2w_3map3MapIB6h_IB3m_NtNtB4T_20trie_root_calculator14InProgressNodeEIB6G_INtNtNtB2y_7sources4once4OnceIB1s_ANtB1Z_6Nibblej1_RINtNtCsdZExvAaxgia_5alloc3vec3VecB8Q_EEEINtNtB2A_6option8IntoIterB8K_EENCNvMs3_B7t_NtB7t_5Inner21current_node_full_key0ENcNtIB1s_B8K_B96_E4Left0EIB8i_Bb7_EEIB41_Bbx_B8Q_EIB43_B8Q_Bbx_EEEEIB1s_IB1X_IB41_IB1s_B4x_B1e_EhEEIB1s_B1r_INtNtB8m_5empty5EmptyB8Q_EEEEs0_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofpE8next_keyppEs0_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs0_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs0_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs0_0CsibGXYHQB8Ea_25json_rpc_general_requests |
1205 | 7 | .map(|n| n + usize::from(key_before_nibble)) Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB35_5slice4iter4IterhEEEIB1X_IB2s_INtNvNtBb_4util11as_ref_iter4IterIB1X_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5j_11Interpreter11read_memory12AccessOffsetB57_EEhEEINtNtB31_7flatten7FlatMapINtNtB31_5chain5ChainINtNtB31_3map3MapIB6L_IB3R_NtNtB5n_20trie_root_calculator14InProgressNodeEIB7a_INtNtNtB33_7sources4once4OnceIB1X_ANtB2u_6Nibblej1_RIB1e_B9k_EEEINtNtB35_6option8IntoIterB9e_EENCNvMs3_B7X_NtB7X_5Inner21current_node_full_key0ENcNtIB1X_B9e_B9A_E4Left0EIB8M_Bb9_EEIB4w_Bbz_B9k_EIB4y_B9k_Bbz_EEEEIB1X_IB2s_IB4w_IB1X_B52_B57_EhEEIB1X_B1W_INtNtB8Q_5empty5EmptyB9k_EEEEs1_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB9_6nibble6NibbleEB1q_Es1_0Bb_ _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss0_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs1_0Bb_ Line | Count | Source | 1205 | 1 | .map(|n| n + usize::from(key_before_nibble)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss2_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs1_0Bb_ Line | Count | Source | 1205 | 2 | .map(|n| n + usize::from(key_before_nibble)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_works0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs1_0Bb_ Line | Count | Source | 1205 | 1 | .map(|n| n + usize::from(key_before_nibble)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss3_0EIB1r_IB2f_hKj21_ENCB2S_s4_0EEs1_0Bb_ Line | Count | Source | 1205 | 2 | .map(|n| n + usize::from(key_before_nibble)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss5_0EIB1r_IB2f_hKj1f_ENCB2S_s6_0EEs1_0Bb_ Line | Count | Source | 1205 | 1 | .map(|n| n + usize::from(key_before_nibble)) |
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs1_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2A_5slice4iter4IterhEEEIB1s_IB1X_INtNvNtBb_4util11as_ref_iter4IterIB1s_B1e_INtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB4P_11Interpreter11read_memory12AccessOffsetB1e_EEhEEINtNtB2w_7flatten7FlatMapINtNtB2w_5chain5ChainINtNtB2w_3map3MapIB6h_IB3m_NtNtB4T_20trie_root_calculator14InProgressNodeEIB6G_INtNtNtB2y_7sources4once4OnceIB1s_ANtB1Z_6Nibblej1_RINtNtCsdZExvAaxgia_5alloc3vec3VecB8Q_EEEINtNtB2A_6option8IntoIterB8K_EENCNvMs3_B7t_NtB7t_5Inner21current_node_full_key0ENcNtIB1s_B8K_B96_E4Left0EIB8i_Bb7_EEIB41_Bbx_B8Q_EIB43_B8Q_Bbx_EEEEIB1s_IB1X_IB41_IB1s_B4x_B1e_EhEEIB1s_B1r_INtNtB8m_5empty5EmptyB8Q_EEEEs1_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofpE8next_keyppEs1_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs1_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs1_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs1_0CsibGXYHQB8Ea_25json_rpc_general_requests |
1206 | | { |
1207 | | // Found a child. Make sure that it matches the prefix nibble. |
1208 | 7 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)3 ) { Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB35_5slice4iter4IterhEEEIB1X_IB2s_INtNvNtBb_4util11as_ref_iter4IterIB1X_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5j_11Interpreter11read_memory12AccessOffsetB57_EEhEEINtNtB31_7flatten7FlatMapINtNtB31_5chain5ChainINtNtB31_3map3MapIB6L_IB3R_NtNtB5n_20trie_root_calculator14InProgressNodeEIB7a_INtNtNtB33_7sources4once4OnceIB1X_ANtB2u_6Nibblej1_RIB1e_B9k_EEEINtNtB35_6option8IntoIterB9e_EENCNvMs3_B7X_NtB7X_5Inner21current_node_full_key0ENcNtIB1X_B9e_B9A_E4Left0EIB8M_Bb9_EEIB4w_Bbz_B9k_EIB4y_B9k_Bbz_EEEEIB1X_IB2s_IB4w_IB1X_B52_B57_EhEEIB1X_B1W_INtNtB8Q_5empty5EmptyB9k_EEEEs2_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB9_6nibble6NibbleEB1q_Es2_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss0_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs2_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj1f_ENCNvNtB7_5testss_14next_key_workss2_0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs2_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_works0EINtNtNtB1x_7sources5empty5EmptyNtNtB9_6nibble6NibbleEEs2_0Bb_ _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss3_0EIB1r_IB2f_hKj21_ENCB2S_s4_0EEs2_0Bb_ Line | Count | Source | 1208 | 2 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) { |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1z_5array4iter8IntoIterhKj20_ENCNvNtB7_5testss_14next_key_workss5_0EIB1r_IB2f_hKj1f_ENCB2S_s6_0EEs2_0Bb_ Line | Count | Source | 1208 | 1 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) { |
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs2_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2A_5slice4iter4IterhEEEIB1s_IB1X_INtNvNtBb_4util11as_ref_iter4IterIB1s_B1e_INtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB4P_11Interpreter11read_memory12AccessOffsetB1e_EEhEEINtNtB2w_7flatten7FlatMapINtNtB2w_5chain5ChainINtNtB2w_3map3MapIB6h_IB3m_NtNtB4T_20trie_root_calculator14InProgressNodeEIB6G_INtNtNtB2y_7sources4once4OnceIB1s_ANtB1Z_6Nibblej1_RINtNtCsdZExvAaxgia_5alloc3vec3VecB8Q_EEEINtNtB2A_6option8IntoIterB8K_EENCNvMs3_B7t_NtB7t_5Inner21current_node_full_key0ENcNtIB1s_B8K_B96_E4Left0EIB8i_Bb7_EEIB41_Bbx_B8Q_EIB43_B8Q_Bbx_EEEEIB1s_IB1X_IB41_IB1s_B4x_B1e_EhEEIB1s_B1r_INtNtB8m_5empty5EmptyB8Q_EEEEs2_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofpE8next_keyppEs2_0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs2_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs2_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3n_5slice4iter4IterhEEEIB2f_IB2K_INtNvNtBb_4util11as_ref_iter4IterIB2f_RShINtNvMs5_NtNtNtBb_8executor2vm11interpreterNtB5B_11Interpreter11read_memory12AccessOffsetB5p_EEhEEINtNtB3j_7flatten7FlatMapINtNtB3j_5chain5ChainINtNtB3j_3map3MapIB73_IB49_NtNtB5F_20trie_root_calculator14InProgressNodeEIB7s_INtNtNtB3l_7sources4once4OnceIB2f_ANtB2M_6Nibblej1_RINtB1j_3VecB9C_EEEINtNtB3n_6option8IntoIterB9w_EENCNvMs3_B8f_NtB8f_5Inner21current_node_full_key0ENcNtIB2f_B9w_B9S_E4Left0EIB94_Bbx_EEIB4O_BbX_B9C_EIB4Q_B9C_BbX_EEEEIB2f_IB2K_IB4O_IB2f_B5k_B5p_EhEEIB2f_B2e_INtNtB98_5empty5EmptyB9C_EEEEs2_0CsibGXYHQB8Ea_25json_rpc_general_requests |
1209 | | // Child doesn't match prefix. No next key. |
1210 | 1 | return Ok(None); |
1211 | 6 | } |
1212 | 6 | |
1213 | 6 | // Continue iterating down through the child that has been found. |
1214 | 6 | |
1215 | 6 | let children_present_in_proof_bitmap = |
1216 | 6 | self.entries[iter_entry].children_present_in_proof_bitmap; |
1217 | 6 | |
1218 | 6 | // If the child isn't present in the proof, then the proof is |
1219 | 6 | // incomplete. While in some situations we could prove that the child |
1220 | 6 | // is necessarily the next key, there is no way to know its full key. |
1221 | 6 | if children_present_in_proof_bitmap & (1 << key_before_nibble) == 0 { |
1222 | 1 | return Err(IncompleteProofError()); |
1223 | 5 | } |
1224 | | |
1225 | 45 | for c in 0..key_before_nibble5 { |
1226 | 45 | if children_present_in_proof_bitmap & (1 << c) != 0 { |
1227 | 0 | iter_entry += 1; |
1228 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; |
1229 | 45 | } |
1230 | | } |
1231 | | |
1232 | 5 | iter_entry += 1; |
1233 | 5 | prefix_match_iter_entry_ancestor_depth += 1; |
1234 | 5 | if usize::from(key_before_nibble) != child_num { |
1235 | 0 | key_before = either::Right(iter::empty().fuse()); |
1236 | 0 | or_equal = true; |
1237 | 5 | } |
1238 | 5 | break; |
1239 | | } else { |
1240 | | // Childless branch nodes are forbidden. This is checked when |
1241 | | // decoding the proof. |
1242 | 0 | debug_assert!(!matches!( |
1243 | 0 | iter_entry_decoded.storage_value, |
1244 | | trie_node::StorageValue::None, |
1245 | | )); |
1246 | | |
1247 | | // `key_before` is after the last child of `iter_entry`. The next |
1248 | | // node is thus a sibling or uncle of `iter_entry`. |
1249 | 0 | iterating_up = true; |
1250 | 0 | key_before = either::Right(iter::empty().fuse()); |
1251 | 0 | or_equal = true; |
1252 | 0 | break; |
1253 | | } |
1254 | | } |
1255 | | } |
1256 | | } |
1257 | | } |
1258 | 6 | } Unexecuted instantiation: _RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB33_5slice4iter4IterhEEEIB1V_IB2q_INtNvNtB9_4util11as_ref_iter4IterIB1V_RShINtNvMs5_NtNtNtB9_8executor2vm11interpreterNtB5h_11Interpreter11read_memory12AccessOffsetB55_EEhEEINtNtB2Z_7flatten7FlatMapINtNtB2Z_5chain5ChainINtNtB2Z_3map3MapIB6J_IB3P_NtNtB5l_20trie_root_calculator14InProgressNodeEIB78_INtNtNtB31_7sources4once4OnceIB1V_ANtB2s_6Nibblej1_RIB1c_B9i_EEEINtNtB33_6option8IntoIterB9c_EENCNvMs3_B7V_NtB7V_5Inner21current_node_full_key0ENcNtIB1V_B9c_B9y_E4Left0EIB8K_Bb7_EEIB4u_Bbx_B9i_EIB4w_B9i_Bbx_EEEEIB1V_IB2q_IB4u_IB1V_B50_B55_EhEEIB1V_B1U_INtNtB8O_5empty5EmptyB9i_EEEEB9_ _RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB7_6nibble6NibbleEB1o_EB9_ Line | Count | Source | 1006 | 1 | pub fn next_key( | 1007 | 1 | &'_ self, | 1008 | 1 | trie_root_merkle_value: &[u8; 32], | 1009 | 1 | key_before: impl Iterator<Item = nibble::Nibble>, | 1010 | 1 | mut or_equal: bool, | 1011 | 1 | prefix: impl Iterator<Item = nibble::Nibble>, | 1012 | 1 | branch_nodes: bool, | 1013 | 1 | ) -> Result<Option<EntryKeyIter<'_, T>>, IncompleteProofError> { | 1014 | 1 | let proof = self.proof.as_ref(); | 1015 | 1 | | 1016 | 1 | // The implementation below might continue iterating `prefix` even after it has returned | 1017 | 1 | // `None`, thus we have to fuse it. | 1018 | 1 | let mut prefix = prefix.fuse(); | 1019 | 1 | | 1020 | 1 | // The implementation below might continue iterating `key_before` even after it has | 1021 | 1 | // returned `None`, thus we have to fuse it. | 1022 | 1 | // Furthermore, `key_before` might be modified in the implementation below. When that | 1023 | 1 | // happens, de do this by setting it to `either::Right`. | 1024 | 1 | let mut key_before = either::Left(key_before.fuse()); | 1025 | | | 1026 | | // Find the starting point of the requested trie. | 1027 | 1 | let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else { | 1028 | 0 | return Err(IncompleteProofError()); | 1029 | | }; | 1030 | | | 1031 | | // If `true`, then it was determined that `key_before` was after the last child of | 1032 | | // `iter_entry`. The next iteration must find `iter_entry`'s next sibling. | 1033 | 1 | let mut iterating_up: bool = false; | 1034 | 1 | | 1035 | 1 | // Indicates the depth of ancestors of `iter_entry` that match `prefix`. | 1036 | 1 | // For example, if the value is 2, then `iter_entry`'s parent and grandparent match | 1037 | 1 | //`prefix`, but `iter_entry`'s grandparent parent does not. | 1038 | 1 | let mut prefix_match_iter_entry_ancestor_depth = 0; | 1039 | | | 1040 | | loop { | 1041 | 1 | let Ok(iter_entry_decoded) = | 1042 | 1 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1043 | | else { | 1044 | | // Proof has been checked to be entirely decodable. | 1045 | 0 | unreachable!() | 1046 | | }; | 1047 | | | 1048 | 1 | if iterating_up { | 1049 | 0 | debug_assert!(matches!(key_before, either::Right(_))); | 1050 | 0 | debug_assert!(or_equal); | 1051 | | | 1052 | | // It was determined that `key_before` was after the last child of `iter_entry`. | 1053 | | // The next iteration must find `iter_entry`'s next sibling. | 1054 | | | 1055 | 0 | if prefix_match_iter_entry_ancestor_depth == 0 { | 1056 | | // `prefix` only matches `iter_entry` and not its parent and | 1057 | | // thus wouldn't match `iter_entry`'s sibling or uncle. | 1058 | | // Therefore, the next node is `None`. | 1059 | 0 | return Ok(None); | 1060 | 0 | } | 1061 | | | 1062 | | // Go to `iter_entry`'s next sibling, if any. | 1063 | 0 | let Some((parent_entry, parent_to_child_nibble)) = | 1064 | 0 | self.entries[iter_entry].parent_entry_index | 1065 | | else { | 1066 | | // `iter_entry` is the root of the trie. `key_before` is therefore | 1067 | | // after the last entry of the trie. | 1068 | 0 | return Ok(None); | 1069 | | }; | 1070 | | | 1071 | 0 | let Some(child_num) = iter_entry_decoded | 1072 | 0 | .children | 1073 | 0 | .iter() | 1074 | 0 | .skip(usize::from(parent_to_child_nibble) + 1) | 1075 | 0 | .position(|c| c.is_some()) | 1076 | 0 | .map(|n| n + usize::from(parent_to_child_nibble) + 1) | 1077 | | else { | 1078 | | // No child found. Continue iterating up. | 1079 | 0 | iterating_up = true; | 1080 | 0 | iter_entry = parent_entry; | 1081 | 0 | prefix_match_iter_entry_ancestor_depth -= 1; | 1082 | 0 | continue; | 1083 | | }; | 1084 | | | 1085 | | // Found a next sibling. | 1086 | | | 1087 | 0 | let children_present_in_proof_bitmap = | 1088 | 0 | self.entries[parent_entry].children_present_in_proof_bitmap; | 1089 | 0 |
| 1090 | 0 | // If the child isn't present in the proof, then the proof is | 1091 | 0 | // incomplete. While in some situations we could prove that the child | 1092 | 0 | // is necessarily the next key, there is no way to know its full key. | 1093 | 0 | if children_present_in_proof_bitmap & (1 << child_num) == 0 { | 1094 | 0 | return Err(IncompleteProofError()); | 1095 | 0 | } | 1096 | 0 |
| 1097 | 0 | // `iter_entry` is still pointing to the child at index `parent_to_child_nibble`. | 1098 | 0 | // Since we're jumping to its next sibling, all we have to do is skip over it | 1099 | 0 | // and its descedants. | 1100 | 0 | iter_entry += 1; | 1101 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1102 | 0 | iterating_up = false; | 1103 | 1 | } | 1104 | | | 1105 | 1 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1106 | | loop { | 1107 | | match ( | 1108 | 1 | key_before.next(), | 1109 | 1 | prefix.next(), | 1110 | 1 | iter_entry_partial_key_iter.next(), | 1111 | | ) { | 1112 | 0 | (Some(k), Some(p), Some(pk)) if k == p && p == pk => { | 1113 | 0 | // Continue descending down the tree. | 1114 | 0 | } | 1115 | 0 | (None, Some(p), Some(pk)) if p == pk => { | 1116 | 0 | // Continue descending down the tree. | 1117 | 0 | } | 1118 | 0 | (Some(k), None, Some(pk)) if k == pk => { | 1119 | 0 | // Continue descending down the tree. | 1120 | 0 | } | 1121 | 0 | (None, None, Some(_)) => { | 1122 | 0 | // Exact match. Due to the `branch_nodes` setting, we can't just | 1123 | 0 | // return `iter_entry` and instead continue iterating. | 1124 | 0 | or_equal = true; | 1125 | 0 | } | 1126 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1127 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1128 | 0 | // and `iter_entry`. Due to the `branch_nodes` setting, we can't just | 1129 | 0 | // return `iter_entry` and instead continue iterating. | 1130 | 0 | key_before = either::Right(iter::empty().fuse()); | 1131 | 0 | or_equal = true; | 1132 | 0 | } | 1133 | 0 | (Some(k), Some(p), _) if k > p => { | 1134 | 0 | // `key_before` is strictly superior to `prefix`. The next key is | 1135 | 0 | // thus necessarily `None`. | 1136 | 0 | // Note that this is not a situation that is expected to be common, as | 1137 | 0 | // doing such a call is pointless. | 1138 | 0 | return Ok(None); | 1139 | | } | 1140 | 0 | (Some(k), Some(p), Some(pk)) if k < p && p == pk => { | 1141 | 0 | // The key and prefix diverge. | 1142 | 0 | // We know that there isn't any key in the trie between `key_before` | 1143 | 0 | // and `prefix`. | 1144 | 0 | // Starting next iteration, the next node matching the prefix | 1145 | 0 | // will be the result. | 1146 | 0 | key_before = either::Right(iter::empty().fuse()); | 1147 | 0 | or_equal = true; | 1148 | 0 | } | 1149 | 0 | (_, Some(p), Some(pk)) => { | 1150 | 0 | debug_assert!(p != pk); // Other situations covered by other match blocks. | 1151 | | | 1152 | | // Mismatch between prefix and partial key. No matter the value of | 1153 | | // `key_before` There is no node in the trie that starts with `prefix`. | 1154 | 0 | return Ok(None); | 1155 | | } | 1156 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1157 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1158 | 0 | // and `iter_entry`. We know that `iter_entry` necessarily matches | 1159 | 0 | // the prefix. The next key is necessarily `iter_entry`. | 1160 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1161 | | } | 1162 | 0 | (Some(k), None, Some(pk)) => { | 1163 | 0 | debug_assert!(k > pk); // Checked above. | 1164 | | | 1165 | | // `key_before` points to somewhere between the last child of `iter_entry` | 1166 | | // and its next sibling. | 1167 | | // The next key is thus the next sibling of `iter_entry`. | 1168 | 0 | iterating_up = true; | 1169 | 0 | key_before = either::Right(iter::empty().fuse()); | 1170 | 0 | or_equal = true; | 1171 | 0 | break; | 1172 | | } | 1173 | | (None, None, None) | 1174 | 1 | if or_equal | 1175 | 1 | && (branch_nodes | 1176 | 0 | || !matches!( | 1177 | 0 | iter_entry_decoded.storage_value, | 1178 | | trie_node::StorageValue::None, | 1179 | 1 | )) => | 1180 | 1 | { | 1181 | 1 | // Exact match. Next key is `iter_entry`. | 1182 | 1 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1183 | | } | 1184 | 0 | (key_before_nibble, prefix_nibble, None) => { | 1185 | | // The moment when we have finished traversing a node and go to the | 1186 | | // next one is the most complicated situation. | 1187 | | | 1188 | | // We know for sure that `iter_entry` can't be returned, as it is covered | 1189 | | // by the other match variants above. Therefore, `key_before_nibble` equal | 1190 | | // to `None` is the same as if it is equal to `0`. | 1191 | 0 | let key_before_nibble = match key_before_nibble { | 1192 | 0 | Some(n) => u8::from(n), | 1193 | | None => { | 1194 | 0 | or_equal = true; | 1195 | 0 | 0 | 1196 | | } | 1197 | | }; | 1198 | | | 1199 | | // Try to find the first child that is after `key_before`. | 1200 | 0 | if let Some(child_num) = iter_entry_decoded | 1201 | 0 | .children | 1202 | 0 | .iter() | 1203 | 0 | .skip(usize::from(key_before_nibble)) | 1204 | 0 | .position(|c| c.is_some()) | 1205 | 0 | .map(|n| n + usize::from(key_before_nibble)) | 1206 | | { | 1207 | | // Found a child. Make sure that it matches the prefix nibble. | 1208 | 0 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) { | 1209 | | // Child doesn't match prefix. No next key. | 1210 | 0 | return Ok(None); | 1211 | 0 | } | 1212 | 0 |
| 1213 | 0 | // Continue iterating down through the child that has been found. | 1214 | 0 |
| 1215 | 0 | let children_present_in_proof_bitmap = | 1216 | 0 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1217 | 0 |
| 1218 | 0 | // If the child isn't present in the proof, then the proof is | 1219 | 0 | // incomplete. While in some situations we could prove that the child | 1220 | 0 | // is necessarily the next key, there is no way to know its full key. | 1221 | 0 | if children_present_in_proof_bitmap & (1 << key_before_nibble) == 0 { | 1222 | 0 | return Err(IncompleteProofError()); | 1223 | 0 | } | 1224 | | | 1225 | 0 | for c in 0..key_before_nibble { | 1226 | 0 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1227 | 0 | iter_entry += 1; | 1228 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1229 | 0 | } | 1230 | | } | 1231 | | | 1232 | 0 | iter_entry += 1; | 1233 | 0 | prefix_match_iter_entry_ancestor_depth += 1; | 1234 | 0 | if usize::from(key_before_nibble) != child_num { | 1235 | 0 | key_before = either::Right(iter::empty().fuse()); | 1236 | 0 | or_equal = true; | 1237 | 0 | } | 1238 | 0 | break; | 1239 | | } else { | 1240 | | // Childless branch nodes are forbidden. This is checked when | 1241 | | // decoding the proof. | 1242 | 0 | debug_assert!(!matches!( | 1243 | 0 | iter_entry_decoded.storage_value, | 1244 | | trie_node::StorageValue::None, | 1245 | | )); | 1246 | | | 1247 | | // `key_before` is after the last child of `iter_entry`. The next | 1248 | | // node is thus a sibling or uncle of `iter_entry`. | 1249 | 0 | iterating_up = true; | 1250 | 0 | key_before = either::Right(iter::empty().fuse()); | 1251 | 0 | or_equal = true; | 1252 | 0 | break; | 1253 | | } | 1254 | | } | 1255 | | } | 1256 | | } | 1257 | | } | 1258 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1x_5array4iter8IntoIterhKj1f_ENCNvNtB5_5testss_14next_key_workss0_0EINtNtNtB1v_7sources5empty5EmptyNtNtB7_6nibble6NibbleEEB9_ Line | Count | Source | 1006 | 1 | pub fn next_key( | 1007 | 1 | &'_ self, | 1008 | 1 | trie_root_merkle_value: &[u8; 32], | 1009 | 1 | key_before: impl Iterator<Item = nibble::Nibble>, | 1010 | 1 | mut or_equal: bool, | 1011 | 1 | prefix: impl Iterator<Item = nibble::Nibble>, | 1012 | 1 | branch_nodes: bool, | 1013 | 1 | ) -> Result<Option<EntryKeyIter<'_, T>>, IncompleteProofError> { | 1014 | 1 | let proof = self.proof.as_ref(); | 1015 | 1 | | 1016 | 1 | // The implementation below might continue iterating `prefix` even after it has returned | 1017 | 1 | // `None`, thus we have to fuse it. | 1018 | 1 | let mut prefix = prefix.fuse(); | 1019 | 1 | | 1020 | 1 | // The implementation below might continue iterating `key_before` even after it has | 1021 | 1 | // returned `None`, thus we have to fuse it. | 1022 | 1 | // Furthermore, `key_before` might be modified in the implementation below. When that | 1023 | 1 | // happens, de do this by setting it to `either::Right`. | 1024 | 1 | let mut key_before = either::Left(key_before.fuse()); | 1025 | | | 1026 | | // Find the starting point of the requested trie. | 1027 | 1 | let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else { | 1028 | 0 | return Err(IncompleteProofError()); | 1029 | | }; | 1030 | | | 1031 | | // If `true`, then it was determined that `key_before` was after the last child of | 1032 | | // `iter_entry`. The next iteration must find `iter_entry`'s next sibling. | 1033 | 1 | let mut iterating_up: bool = false; | 1034 | 1 | | 1035 | 1 | // Indicates the depth of ancestors of `iter_entry` that match `prefix`. | 1036 | 1 | // For example, if the value is 2, then `iter_entry`'s parent and grandparent match | 1037 | 1 | //`prefix`, but `iter_entry`'s grandparent parent does not. | 1038 | 1 | let mut prefix_match_iter_entry_ancestor_depth = 0; | 1039 | | | 1040 | | loop { | 1041 | 2 | let Ok(iter_entry_decoded) = | 1042 | 2 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1043 | | else { | 1044 | | // Proof has been checked to be entirely decodable. | 1045 | 0 | unreachable!() | 1046 | | }; | 1047 | | | 1048 | 2 | if iterating_up { | 1049 | 0 | debug_assert!(matches!(key_before, either::Right(_))); | 1050 | 0 | debug_assert!(or_equal); | 1051 | | | 1052 | | // It was determined that `key_before` was after the last child of `iter_entry`. | 1053 | | // The next iteration must find `iter_entry`'s next sibling. | 1054 | | | 1055 | 0 | if prefix_match_iter_entry_ancestor_depth == 0 { | 1056 | | // `prefix` only matches `iter_entry` and not its parent and | 1057 | | // thus wouldn't match `iter_entry`'s sibling or uncle. | 1058 | | // Therefore, the next node is `None`. | 1059 | 0 | return Ok(None); | 1060 | 0 | } | 1061 | | | 1062 | | // Go to `iter_entry`'s next sibling, if any. | 1063 | 0 | let Some((parent_entry, parent_to_child_nibble)) = | 1064 | 0 | self.entries[iter_entry].parent_entry_index | 1065 | | else { | 1066 | | // `iter_entry` is the root of the trie. `key_before` is therefore | 1067 | | // after the last entry of the trie. | 1068 | 0 | return Ok(None); | 1069 | | }; | 1070 | | | 1071 | 0 | let Some(child_num) = iter_entry_decoded | 1072 | 0 | .children | 1073 | 0 | .iter() | 1074 | 0 | .skip(usize::from(parent_to_child_nibble) + 1) | 1075 | 0 | .position(|c| c.is_some()) | 1076 | 0 | .map(|n| n + usize::from(parent_to_child_nibble) + 1) | 1077 | | else { | 1078 | | // No child found. Continue iterating up. | 1079 | 0 | iterating_up = true; | 1080 | 0 | iter_entry = parent_entry; | 1081 | 0 | prefix_match_iter_entry_ancestor_depth -= 1; | 1082 | 0 | continue; | 1083 | | }; | 1084 | | | 1085 | | // Found a next sibling. | 1086 | | | 1087 | 0 | let children_present_in_proof_bitmap = | 1088 | 0 | self.entries[parent_entry].children_present_in_proof_bitmap; | 1089 | 0 |
| 1090 | 0 | // If the child isn't present in the proof, then the proof is | 1091 | 0 | // incomplete. While in some situations we could prove that the child | 1092 | 0 | // is necessarily the next key, there is no way to know its full key. | 1093 | 0 | if children_present_in_proof_bitmap & (1 << child_num) == 0 { | 1094 | 0 | return Err(IncompleteProofError()); | 1095 | 0 | } | 1096 | 0 |
| 1097 | 0 | // `iter_entry` is still pointing to the child at index `parent_to_child_nibble`. | 1098 | 0 | // Since we're jumping to its next sibling, all we have to do is skip over it | 1099 | 0 | // and its descedants. | 1100 | 0 | iter_entry += 1; | 1101 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1102 | 0 | iterating_up = false; | 1103 | 2 | } | 1104 | | | 1105 | 2 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1106 | | loop { | 1107 | | match ( | 1108 | 33 | key_before.next(), | 1109 | 33 | prefix.next(), | 1110 | 33 | iter_entry_partial_key_iter.next(), | 1111 | | ) { | 1112 | 0 | (Some(k), Some(p), Some(pk)) if k == p && p == pk => { | 1113 | 0 | // Continue descending down the tree. | 1114 | 0 | } | 1115 | 0 | (None, Some(p), Some(pk)) if p == pk => { | 1116 | 0 | // Continue descending down the tree. | 1117 | 0 | } | 1118 | 30 | (Some(k), None, Some(pk)) if k == pk => { | 1119 | 30 | // Continue descending down the tree. | 1120 | 30 | } | 1121 | 1 | (None, None, Some(_)) => { | 1122 | 1 | // Exact match. Due to the `branch_nodes` setting, we can't just | 1123 | 1 | // return `iter_entry` and instead continue iterating. | 1124 | 1 | or_equal = true; | 1125 | 1 | } | 1126 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1127 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1128 | 0 | // and `iter_entry`. Due to the `branch_nodes` setting, we can't just | 1129 | 0 | // return `iter_entry` and instead continue iterating. | 1130 | 0 | key_before = either::Right(iter::empty().fuse()); | 1131 | 0 | or_equal = true; | 1132 | 0 | } | 1133 | 0 | (Some(k), Some(p), _) if k > p => { | 1134 | 0 | // `key_before` is strictly superior to `prefix`. The next key is | 1135 | 0 | // thus necessarily `None`. | 1136 | 0 | // Note that this is not a situation that is expected to be common, as | 1137 | 0 | // doing such a call is pointless. | 1138 | 0 | return Ok(None); | 1139 | | } | 1140 | 0 | (Some(k), Some(p), Some(pk)) if k < p && p == pk => { | 1141 | 0 | // The key and prefix diverge. | 1142 | 0 | // We know that there isn't any key in the trie between `key_before` | 1143 | 0 | // and `prefix`. | 1144 | 0 | // Starting next iteration, the next node matching the prefix | 1145 | 0 | // will be the result. | 1146 | 0 | key_before = either::Right(iter::empty().fuse()); | 1147 | 0 | or_equal = true; | 1148 | 0 | } | 1149 | 0 | (_, Some(p), Some(pk)) => { | 1150 | 0 | debug_assert!(p != pk); // Other situations covered by other match blocks. | 1151 | | | 1152 | | // Mismatch between prefix and partial key. No matter the value of | 1153 | | // `key_before` There is no node in the trie that starts with `prefix`. | 1154 | 0 | return Ok(None); | 1155 | | } | 1156 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1157 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1158 | 0 | // and `iter_entry`. We know that `iter_entry` necessarily matches | 1159 | 0 | // the prefix. The next key is necessarily `iter_entry`. | 1160 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1161 | | } | 1162 | 0 | (Some(k), None, Some(pk)) => { | 1163 | 0 | debug_assert!(k > pk); // Checked above. | 1164 | | | 1165 | | // `key_before` points to somewhere between the last child of `iter_entry` | 1166 | | // and its next sibling. | 1167 | | // The next key is thus the next sibling of `iter_entry`. | 1168 | 0 | iterating_up = true; | 1169 | 0 | key_before = either::Right(iter::empty().fuse()); | 1170 | 0 | or_equal = true; | 1171 | 0 | break; | 1172 | | } | 1173 | | (None, None, None) | 1174 | 1 | if or_equal | 1175 | 1 | && (branch_nodes | 1176 | 0 | || !matches!( | 1177 | 0 | iter_entry_decoded.storage_value, | 1178 | | trie_node::StorageValue::None, | 1179 | 1 | )) => | 1180 | 1 | { | 1181 | 1 | // Exact match. Next key is `iter_entry`. | 1182 | 1 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1183 | | } | 1184 | 1 | (key_before_nibble, prefix_nibble, None) => { | 1185 | | // The moment when we have finished traversing a node and go to the | 1186 | | // next one is the most complicated situation. | 1187 | | | 1188 | | // We know for sure that `iter_entry` can't be returned, as it is covered | 1189 | | // by the other match variants above. Therefore, `key_before_nibble` equal | 1190 | | // to `None` is the same as if it is equal to `0`. | 1191 | 1 | let key_before_nibble = match key_before_nibble { | 1192 | 1 | Some(n) => u8::from(n), | 1193 | | None => { | 1194 | 0 | or_equal = true; | 1195 | 0 | 0 | 1196 | | } | 1197 | | }; | 1198 | | | 1199 | | // Try to find the first child that is after `key_before`. | 1200 | 1 | if let Some(child_num) = iter_entry_decoded | 1201 | 1 | .children | 1202 | 1 | .iter() | 1203 | 1 | .skip(usize::from(key_before_nibble)) | 1204 | 1 | .position(|c| c.is_some()) | 1205 | 1 | .map(|n| n + usize::from(key_before_nibble)) | 1206 | | { | 1207 | | // Found a child. Make sure that it matches the prefix nibble. | 1208 | 1 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) { | 1209 | | // Child doesn't match prefix. No next key. | 1210 | 0 | return Ok(None); | 1211 | 1 | } | 1212 | 1 | | 1213 | 1 | // Continue iterating down through the child that has been found. | 1214 | 1 | | 1215 | 1 | let children_present_in_proof_bitmap = | 1216 | 1 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1217 | 1 | | 1218 | 1 | // If the child isn't present in the proof, then the proof is | 1219 | 1 | // incomplete. While in some situations we could prove that the child | 1220 | 1 | // is necessarily the next key, there is no way to know its full key. | 1221 | 1 | if children_present_in_proof_bitmap & (1 << key_before_nibble) == 0 { | 1222 | 0 | return Err(IncompleteProofError()); | 1223 | 1 | } | 1224 | | | 1225 | 9 | for c in 0..key_before_nibble1 { | 1226 | 9 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1227 | 0 | iter_entry += 1; | 1228 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1229 | 9 | } | 1230 | | } | 1231 | | | 1232 | 1 | iter_entry += 1; | 1233 | 1 | prefix_match_iter_entry_ancestor_depth += 1; | 1234 | 1 | if usize::from(key_before_nibble) != child_num { | 1235 | 0 | key_before = either::Right(iter::empty().fuse()); | 1236 | 0 | or_equal = true; | 1237 | 1 | } | 1238 | 1 | break; | 1239 | | } else { | 1240 | | // Childless branch nodes are forbidden. This is checked when | 1241 | | // decoding the proof. | 1242 | 0 | debug_assert!(!matches!( | 1243 | 0 | iter_entry_decoded.storage_value, | 1244 | | trie_node::StorageValue::None, | 1245 | | )); | 1246 | | | 1247 | | // `key_before` is after the last child of `iter_entry`. The next | 1248 | | // node is thus a sibling or uncle of `iter_entry`. | 1249 | 0 | iterating_up = true; | 1250 | 0 | key_before = either::Right(iter::empty().fuse()); | 1251 | 0 | or_equal = true; | 1252 | 0 | break; | 1253 | | } | 1254 | | } | 1255 | | } | 1256 | | } | 1257 | | } | 1258 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1x_5array4iter8IntoIterhKj1f_ENCNvNtB5_5testss_14next_key_workss2_0EINtNtNtB1v_7sources5empty5EmptyNtNtB7_6nibble6NibbleEEB9_ Line | Count | Source | 1006 | 1 | pub fn next_key( | 1007 | 1 | &'_ self, | 1008 | 1 | trie_root_merkle_value: &[u8; 32], | 1009 | 1 | key_before: impl Iterator<Item = nibble::Nibble>, | 1010 | 1 | mut or_equal: bool, | 1011 | 1 | prefix: impl Iterator<Item = nibble::Nibble>, | 1012 | 1 | branch_nodes: bool, | 1013 | 1 | ) -> Result<Option<EntryKeyIter<'_, T>>, IncompleteProofError> { | 1014 | 1 | let proof = self.proof.as_ref(); | 1015 | 1 | | 1016 | 1 | // The implementation below might continue iterating `prefix` even after it has returned | 1017 | 1 | // `None`, thus we have to fuse it. | 1018 | 1 | let mut prefix = prefix.fuse(); | 1019 | 1 | | 1020 | 1 | // The implementation below might continue iterating `key_before` even after it has | 1021 | 1 | // returned `None`, thus we have to fuse it. | 1022 | 1 | // Furthermore, `key_before` might be modified in the implementation below. When that | 1023 | 1 | // happens, de do this by setting it to `either::Right`. | 1024 | 1 | let mut key_before = either::Left(key_before.fuse()); | 1025 | | | 1026 | | // Find the starting point of the requested trie. | 1027 | 1 | let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else { | 1028 | 0 | return Err(IncompleteProofError()); | 1029 | | }; | 1030 | | | 1031 | | // If `true`, then it was determined that `key_before` was after the last child of | 1032 | | // `iter_entry`. The next iteration must find `iter_entry`'s next sibling. | 1033 | 1 | let mut iterating_up: bool = false; | 1034 | 1 | | 1035 | 1 | // Indicates the depth of ancestors of `iter_entry` that match `prefix`. | 1036 | 1 | // For example, if the value is 2, then `iter_entry`'s parent and grandparent match | 1037 | 1 | //`prefix`, but `iter_entry`'s grandparent parent does not. | 1038 | 1 | let mut prefix_match_iter_entry_ancestor_depth = 0; | 1039 | | | 1040 | | loop { | 1041 | 2 | let Ok(iter_entry_decoded) = | 1042 | 2 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1043 | | else { | 1044 | | // Proof has been checked to be entirely decodable. | 1045 | 0 | unreachable!() | 1046 | | }; | 1047 | | | 1048 | 2 | if iterating_up { | 1049 | 0 | debug_assert!(matches!(key_before, either::Right(_))); | 1050 | 0 | debug_assert!(or_equal); | 1051 | | | 1052 | | // It was determined that `key_before` was after the last child of `iter_entry`. | 1053 | | // The next iteration must find `iter_entry`'s next sibling. | 1054 | | | 1055 | 0 | if prefix_match_iter_entry_ancestor_depth == 0 { | 1056 | | // `prefix` only matches `iter_entry` and not its parent and | 1057 | | // thus wouldn't match `iter_entry`'s sibling or uncle. | 1058 | | // Therefore, the next node is `None`. | 1059 | 0 | return Ok(None); | 1060 | 0 | } | 1061 | | | 1062 | | // Go to `iter_entry`'s next sibling, if any. | 1063 | 0 | let Some((parent_entry, parent_to_child_nibble)) = | 1064 | 0 | self.entries[iter_entry].parent_entry_index | 1065 | | else { | 1066 | | // `iter_entry` is the root of the trie. `key_before` is therefore | 1067 | | // after the last entry of the trie. | 1068 | 0 | return Ok(None); | 1069 | | }; | 1070 | | | 1071 | 0 | let Some(child_num) = iter_entry_decoded | 1072 | 0 | .children | 1073 | 0 | .iter() | 1074 | 0 | .skip(usize::from(parent_to_child_nibble) + 1) | 1075 | 0 | .position(|c| c.is_some()) | 1076 | 0 | .map(|n| n + usize::from(parent_to_child_nibble) + 1) | 1077 | | else { | 1078 | | // No child found. Continue iterating up. | 1079 | 0 | iterating_up = true; | 1080 | 0 | iter_entry = parent_entry; | 1081 | 0 | prefix_match_iter_entry_ancestor_depth -= 1; | 1082 | 0 | continue; | 1083 | | }; | 1084 | | | 1085 | | // Found a next sibling. | 1086 | | | 1087 | 0 | let children_present_in_proof_bitmap = | 1088 | 0 | self.entries[parent_entry].children_present_in_proof_bitmap; | 1089 | 0 |
| 1090 | 0 | // If the child isn't present in the proof, then the proof is | 1091 | 0 | // incomplete. While in some situations we could prove that the child | 1092 | 0 | // is necessarily the next key, there is no way to know its full key. | 1093 | 0 | if children_present_in_proof_bitmap & (1 << child_num) == 0 { | 1094 | 0 | return Err(IncompleteProofError()); | 1095 | 0 | } | 1096 | 0 |
| 1097 | 0 | // `iter_entry` is still pointing to the child at index `parent_to_child_nibble`. | 1098 | 0 | // Since we're jumping to its next sibling, all we have to do is skip over it | 1099 | 0 | // and its descedants. | 1100 | 0 | iter_entry += 1; | 1101 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1102 | 0 | iterating_up = false; | 1103 | 2 | } | 1104 | | | 1105 | 2 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1106 | | loop { | 1107 | | match ( | 1108 | 33 | key_before.next(), | 1109 | 33 | prefix.next(), | 1110 | 33 | iter_entry_partial_key_iter.next(), | 1111 | | ) { | 1112 | 0 | (Some(k), Some(p), Some(pk)) if k == p && p == pk => { | 1113 | 0 | // Continue descending down the tree. | 1114 | 0 | } | 1115 | 0 | (None, Some(p), Some(pk)) if p == pk => { | 1116 | 0 | // Continue descending down the tree. | 1117 | 0 | } | 1118 | 30 | (Some(k), None, Some(pk)) if k == pk => { | 1119 | 30 | // Continue descending down the tree. | 1120 | 30 | } | 1121 | 1 | (None, None, Some(_)) => { | 1122 | 1 | // Exact match. Due to the `branch_nodes` setting, we can't just | 1123 | 1 | // return `iter_entry` and instead continue iterating. | 1124 | 1 | or_equal = true; | 1125 | 1 | } | 1126 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1127 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1128 | 0 | // and `iter_entry`. Due to the `branch_nodes` setting, we can't just | 1129 | 0 | // return `iter_entry` and instead continue iterating. | 1130 | 0 | key_before = either::Right(iter::empty().fuse()); | 1131 | 0 | or_equal = true; | 1132 | 0 | } | 1133 | 0 | (Some(k), Some(p), _) if k > p => { | 1134 | 0 | // `key_before` is strictly superior to `prefix`. The next key is | 1135 | 0 | // thus necessarily `None`. | 1136 | 0 | // Note that this is not a situation that is expected to be common, as | 1137 | 0 | // doing such a call is pointless. | 1138 | 0 | return Ok(None); | 1139 | | } | 1140 | 0 | (Some(k), Some(p), Some(pk)) if k < p && p == pk => { | 1141 | 0 | // The key and prefix diverge. | 1142 | 0 | // We know that there isn't any key in the trie between `key_before` | 1143 | 0 | // and `prefix`. | 1144 | 0 | // Starting next iteration, the next node matching the prefix | 1145 | 0 | // will be the result. | 1146 | 0 | key_before = either::Right(iter::empty().fuse()); | 1147 | 0 | or_equal = true; | 1148 | 0 | } | 1149 | 0 | (_, Some(p), Some(pk)) => { | 1150 | 0 | debug_assert!(p != pk); // Other situations covered by other match blocks. | 1151 | | | 1152 | | // Mismatch between prefix and partial key. No matter the value of | 1153 | | // `key_before` There is no node in the trie that starts with `prefix`. | 1154 | 0 | return Ok(None); | 1155 | | } | 1156 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1157 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1158 | 0 | // and `iter_entry`. We know that `iter_entry` necessarily matches | 1159 | 0 | // the prefix. The next key is necessarily `iter_entry`. | 1160 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1161 | | } | 1162 | 0 | (Some(k), None, Some(pk)) => { | 1163 | 0 | debug_assert!(k > pk); // Checked above. | 1164 | | | 1165 | | // `key_before` points to somewhere between the last child of `iter_entry` | 1166 | | // and its next sibling. | 1167 | | // The next key is thus the next sibling of `iter_entry`. | 1168 | 0 | iterating_up = true; | 1169 | 0 | key_before = either::Right(iter::empty().fuse()); | 1170 | 0 | or_equal = true; | 1171 | 0 | break; | 1172 | | } | 1173 | | (None, None, None) | 1174 | 1 | if or_equal | 1175 | 1 | && (branch_nodes | 1176 | 0 | || !matches!( | 1177 | 1 | iter_entry_decoded.storage_value, | 1178 | | trie_node::StorageValue::None, | 1179 | 0 | )) => | 1180 | 0 | { | 1181 | 0 | // Exact match. Next key is `iter_entry`. | 1182 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1183 | | } | 1184 | 2 | (key_before_nibble, prefix_nibble, None) => { | 1185 | | // The moment when we have finished traversing a node and go to the | 1186 | | // next one is the most complicated situation. | 1187 | | | 1188 | | // We know for sure that `iter_entry` can't be returned, as it is covered | 1189 | | // by the other match variants above. Therefore, `key_before_nibble` equal | 1190 | | // to `None` is the same as if it is equal to `0`. | 1191 | 2 | let key_before_nibble = match key_before_nibble { | 1192 | 1 | Some(n) => u8::from(n), | 1193 | | None => { | 1194 | 1 | or_equal = true; | 1195 | 1 | 0 | 1196 | | } | 1197 | | }; | 1198 | | | 1199 | | // Try to find the first child that is after `key_before`. | 1200 | 2 | if let Some(child_num) = iter_entry_decoded | 1201 | 2 | .children | 1202 | 2 | .iter() | 1203 | 2 | .skip(usize::from(key_before_nibble)) | 1204 | 2 | .position(|c| c.is_some()) | 1205 | 2 | .map(|n| n + usize::from(key_before_nibble)) | 1206 | | { | 1207 | | // Found a child. Make sure that it matches the prefix nibble. | 1208 | 2 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) { | 1209 | | // Child doesn't match prefix. No next key. | 1210 | 0 | return Ok(None); | 1211 | 2 | } | 1212 | 2 | | 1213 | 2 | // Continue iterating down through the child that has been found. | 1214 | 2 | | 1215 | 2 | let children_present_in_proof_bitmap = | 1216 | 2 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1217 | 2 | | 1218 | 2 | // If the child isn't present in the proof, then the proof is | 1219 | 2 | // incomplete. While in some situations we could prove that the child | 1220 | 2 | // is necessarily the next key, there is no way to know its full key. | 1221 | 2 | if children_present_in_proof_bitmap & (1 << key_before_nibble) == 0 { | 1222 | 1 | return Err(IncompleteProofError()); | 1223 | 1 | } | 1224 | | | 1225 | 9 | for c in 0..key_before_nibble1 { | 1226 | 9 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1227 | 0 | iter_entry += 1; | 1228 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1229 | 9 | } | 1230 | | } | 1231 | | | 1232 | 1 | iter_entry += 1; | 1233 | 1 | prefix_match_iter_entry_ancestor_depth += 1; | 1234 | 1 | if usize::from(key_before_nibble) != child_num { | 1235 | 0 | key_before = either::Right(iter::empty().fuse()); | 1236 | 0 | or_equal = true; | 1237 | 1 | } | 1238 | 1 | break; | 1239 | | } else { | 1240 | | // Childless branch nodes are forbidden. This is checked when | 1241 | | // decoding the proof. | 1242 | 0 | debug_assert!(!matches!( | 1243 | 0 | iter_entry_decoded.storage_value, | 1244 | | trie_node::StorageValue::None, | 1245 | | )); | 1246 | | | 1247 | | // `key_before` is after the last child of `iter_entry`. The next | 1248 | | // node is thus a sibling or uncle of `iter_entry`. | 1249 | 0 | iterating_up = true; | 1250 | 0 | key_before = either::Right(iter::empty().fuse()); | 1251 | 0 | or_equal = true; | 1252 | 0 | break; | 1253 | | } | 1254 | | } | 1255 | | } | 1256 | | } | 1257 | | } | 1258 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1x_5array4iter8IntoIterhKj20_ENCNvNtB5_5testss_14next_key_works0EINtNtNtB1v_7sources5empty5EmptyNtNtB7_6nibble6NibbleEEB9_ Line | Count | Source | 1006 | 1 | pub fn next_key( | 1007 | 1 | &'_ self, | 1008 | 1 | trie_root_merkle_value: &[u8; 32], | 1009 | 1 | key_before: impl Iterator<Item = nibble::Nibble>, | 1010 | 1 | mut or_equal: bool, | 1011 | 1 | prefix: impl Iterator<Item = nibble::Nibble>, | 1012 | 1 | branch_nodes: bool, | 1013 | 1 | ) -> Result<Option<EntryKeyIter<'_, T>>, IncompleteProofError> { | 1014 | 1 | let proof = self.proof.as_ref(); | 1015 | 1 | | 1016 | 1 | // The implementation below might continue iterating `prefix` even after it has returned | 1017 | 1 | // `None`, thus we have to fuse it. | 1018 | 1 | let mut prefix = prefix.fuse(); | 1019 | 1 | | 1020 | 1 | // The implementation below might continue iterating `key_before` even after it has | 1021 | 1 | // returned `None`, thus we have to fuse it. | 1022 | 1 | // Furthermore, `key_before` might be modified in the implementation below. When that | 1023 | 1 | // happens, de do this by setting it to `either::Right`. | 1024 | 1 | let mut key_before = either::Left(key_before.fuse()); | 1025 | | | 1026 | | // Find the starting point of the requested trie. | 1027 | 1 | let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else { | 1028 | 0 | return Err(IncompleteProofError()); | 1029 | | }; | 1030 | | | 1031 | | // If `true`, then it was determined that `key_before` was after the last child of | 1032 | | // `iter_entry`. The next iteration must find `iter_entry`'s next sibling. | 1033 | 1 | let mut iterating_up: bool = false; | 1034 | 1 | | 1035 | 1 | // Indicates the depth of ancestors of `iter_entry` that match `prefix`. | 1036 | 1 | // For example, if the value is 2, then `iter_entry`'s parent and grandparent match | 1037 | 1 | //`prefix`, but `iter_entry`'s grandparent parent does not. | 1038 | 1 | let mut prefix_match_iter_entry_ancestor_depth = 0; | 1039 | | | 1040 | | loop { | 1041 | 2 | let Ok(iter_entry_decoded) = | 1042 | 2 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1043 | | else { | 1044 | | // Proof has been checked to be entirely decodable. | 1045 | 0 | unreachable!() | 1046 | | }; | 1047 | | | 1048 | 2 | if iterating_up { | 1049 | 0 | debug_assert!(matches!(key_before, either::Right(_))); | 1050 | 0 | debug_assert!(or_equal); | 1051 | | | 1052 | | // It was determined that `key_before` was after the last child of `iter_entry`. | 1053 | | // The next iteration must find `iter_entry`'s next sibling. | 1054 | | | 1055 | 0 | if prefix_match_iter_entry_ancestor_depth == 0 { | 1056 | | // `prefix` only matches `iter_entry` and not its parent and | 1057 | | // thus wouldn't match `iter_entry`'s sibling or uncle. | 1058 | | // Therefore, the next node is `None`. | 1059 | 0 | return Ok(None); | 1060 | 0 | } | 1061 | | | 1062 | | // Go to `iter_entry`'s next sibling, if any. | 1063 | 0 | let Some((parent_entry, parent_to_child_nibble)) = | 1064 | 0 | self.entries[iter_entry].parent_entry_index | 1065 | | else { | 1066 | | // `iter_entry` is the root of the trie. `key_before` is therefore | 1067 | | // after the last entry of the trie. | 1068 | 0 | return Ok(None); | 1069 | | }; | 1070 | | | 1071 | 0 | let Some(child_num) = iter_entry_decoded | 1072 | 0 | .children | 1073 | 0 | .iter() | 1074 | 0 | .skip(usize::from(parent_to_child_nibble) + 1) | 1075 | 0 | .position(|c| c.is_some()) | 1076 | 0 | .map(|n| n + usize::from(parent_to_child_nibble) + 1) | 1077 | | else { | 1078 | | // No child found. Continue iterating up. | 1079 | 0 | iterating_up = true; | 1080 | 0 | iter_entry = parent_entry; | 1081 | 0 | prefix_match_iter_entry_ancestor_depth -= 1; | 1082 | 0 | continue; | 1083 | | }; | 1084 | | | 1085 | | // Found a next sibling. | 1086 | | | 1087 | 0 | let children_present_in_proof_bitmap = | 1088 | 0 | self.entries[parent_entry].children_present_in_proof_bitmap; | 1089 | 0 |
| 1090 | 0 | // If the child isn't present in the proof, then the proof is | 1091 | 0 | // incomplete. While in some situations we could prove that the child | 1092 | 0 | // is necessarily the next key, there is no way to know its full key. | 1093 | 0 | if children_present_in_proof_bitmap & (1 << child_num) == 0 { | 1094 | 0 | return Err(IncompleteProofError()); | 1095 | 0 | } | 1096 | 0 |
| 1097 | 0 | // `iter_entry` is still pointing to the child at index `parent_to_child_nibble`. | 1098 | 0 | // Since we're jumping to its next sibling, all we have to do is skip over it | 1099 | 0 | // and its descedants. | 1100 | 0 | iter_entry += 1; | 1101 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1102 | 0 | iterating_up = false; | 1103 | 2 | } | 1104 | | | 1105 | 2 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1106 | | loop { | 1107 | | match ( | 1108 | 33 | key_before.next(), | 1109 | 33 | prefix.next(), | 1110 | 33 | iter_entry_partial_key_iter.next(), | 1111 | | ) { | 1112 | 0 | (Some(k), Some(p), Some(pk)) if k == p && p == pk => { | 1113 | 0 | // Continue descending down the tree. | 1114 | 0 | } | 1115 | 0 | (None, Some(p), Some(pk)) if p == pk => { | 1116 | 0 | // Continue descending down the tree. | 1117 | 0 | } | 1118 | 31 | (Some(k), None, Some(pk)) if k == pk => { | 1119 | 31 | // Continue descending down the tree. | 1120 | 31 | } | 1121 | 0 | (None, None, Some(_)) => { | 1122 | 0 | // Exact match. Due to the `branch_nodes` setting, we can't just | 1123 | 0 | // return `iter_entry` and instead continue iterating. | 1124 | 0 | or_equal = true; | 1125 | 0 | } | 1126 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1127 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1128 | 0 | // and `iter_entry`. Due to the `branch_nodes` setting, we can't just | 1129 | 0 | // return `iter_entry` and instead continue iterating. | 1130 | 0 | key_before = either::Right(iter::empty().fuse()); | 1131 | 0 | or_equal = true; | 1132 | 0 | } | 1133 | 0 | (Some(k), Some(p), _) if k > p => { | 1134 | 0 | // `key_before` is strictly superior to `prefix`. The next key is | 1135 | 0 | // thus necessarily `None`. | 1136 | 0 | // Note that this is not a situation that is expected to be common, as | 1137 | 0 | // doing such a call is pointless. | 1138 | 0 | return Ok(None); | 1139 | | } | 1140 | 0 | (Some(k), Some(p), Some(pk)) if k < p && p == pk => { | 1141 | 0 | // The key and prefix diverge. | 1142 | 0 | // We know that there isn't any key in the trie between `key_before` | 1143 | 0 | // and `prefix`. | 1144 | 0 | // Starting next iteration, the next node matching the prefix | 1145 | 0 | // will be the result. | 1146 | 0 | key_before = either::Right(iter::empty().fuse()); | 1147 | 0 | or_equal = true; | 1148 | 0 | } | 1149 | 0 | (_, Some(p), Some(pk)) => { | 1150 | 0 | debug_assert!(p != pk); // Other situations covered by other match blocks. | 1151 | | | 1152 | | // Mismatch between prefix and partial key. No matter the value of | 1153 | | // `key_before` There is no node in the trie that starts with `prefix`. | 1154 | 0 | return Ok(None); | 1155 | | } | 1156 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1157 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1158 | 0 | // and `iter_entry`. We know that `iter_entry` necessarily matches | 1159 | 0 | // the prefix. The next key is necessarily `iter_entry`. | 1160 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1161 | | } | 1162 | 0 | (Some(k), None, Some(pk)) => { | 1163 | 0 | debug_assert!(k > pk); // Checked above. | 1164 | | | 1165 | | // `key_before` points to somewhere between the last child of `iter_entry` | 1166 | | // and its next sibling. | 1167 | | // The next key is thus the next sibling of `iter_entry`. | 1168 | 0 | iterating_up = true; | 1169 | 0 | key_before = either::Right(iter::empty().fuse()); | 1170 | 0 | or_equal = true; | 1171 | 0 | break; | 1172 | | } | 1173 | | (None, None, None) | 1174 | 1 | if or_equal | 1175 | 1 | && (branch_nodes | 1176 | 0 | || !matches!( | 1177 | 0 | iter_entry_decoded.storage_value, | 1178 | | trie_node::StorageValue::None, | 1179 | 1 | )) => | 1180 | 1 | { | 1181 | 1 | // Exact match. Next key is `iter_entry`. | 1182 | 1 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1183 | | } | 1184 | 1 | (key_before_nibble, prefix_nibble, None) => { | 1185 | | // The moment when we have finished traversing a node and go to the | 1186 | | // next one is the most complicated situation. | 1187 | | | 1188 | | // We know for sure that `iter_entry` can't be returned, as it is covered | 1189 | | // by the other match variants above. Therefore, `key_before_nibble` equal | 1190 | | // to `None` is the same as if it is equal to `0`. | 1191 | 1 | let key_before_nibble = match key_before_nibble { | 1192 | 1 | Some(n) => u8::from(n), | 1193 | | None => { | 1194 | 0 | or_equal = true; | 1195 | 0 | 0 | 1196 | | } | 1197 | | }; | 1198 | | | 1199 | | // Try to find the first child that is after `key_before`. | 1200 | 1 | if let Some(child_num) = iter_entry_decoded | 1201 | 1 | .children | 1202 | 1 | .iter() | 1203 | 1 | .skip(usize::from(key_before_nibble)) | 1204 | 1 | .position(|c| c.is_some()) | 1205 | 1 | .map(|n| n + usize::from(key_before_nibble)) | 1206 | | { | 1207 | | // Found a child. Make sure that it matches the prefix nibble. | 1208 | 1 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) { | 1209 | | // Child doesn't match prefix. No next key. | 1210 | 0 | return Ok(None); | 1211 | 1 | } | 1212 | 1 | | 1213 | 1 | // Continue iterating down through the child that has been found. | 1214 | 1 | | 1215 | 1 | let children_present_in_proof_bitmap = | 1216 | 1 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1217 | 1 | | 1218 | 1 | // If the child isn't present in the proof, then the proof is | 1219 | 1 | // incomplete. While in some situations we could prove that the child | 1220 | 1 | // is necessarily the next key, there is no way to know its full key. | 1221 | 1 | if children_present_in_proof_bitmap & (1 << key_before_nibble) == 0 { | 1222 | 0 | return Err(IncompleteProofError()); | 1223 | 1 | } | 1224 | | | 1225 | 9 | for c in 0..key_before_nibble1 { | 1226 | 9 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1227 | 0 | iter_entry += 1; | 1228 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1229 | 9 | } | 1230 | | } | 1231 | | | 1232 | 1 | iter_entry += 1; | 1233 | 1 | prefix_match_iter_entry_ancestor_depth += 1; | 1234 | 1 | if usize::from(key_before_nibble) != child_num { | 1235 | 0 | key_before = either::Right(iter::empty().fuse()); | 1236 | 0 | or_equal = true; | 1237 | 1 | } | 1238 | 1 | break; | 1239 | | } else { | 1240 | | // Childless branch nodes are forbidden. This is checked when | 1241 | | // decoding the proof. | 1242 | 0 | debug_assert!(!matches!( | 1243 | 0 | iter_entry_decoded.storage_value, | 1244 | | trie_node::StorageValue::None, | 1245 | | )); | 1246 | | | 1247 | | // `key_before` is after the last child of `iter_entry`. The next | 1248 | | // node is thus a sibling or uncle of `iter_entry`. | 1249 | 0 | iterating_up = true; | 1250 | 0 | key_before = either::Right(iter::empty().fuse()); | 1251 | 0 | or_equal = true; | 1252 | 0 | break; | 1253 | | } | 1254 | | } | 1255 | | } | 1256 | | } | 1257 | | } | 1258 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1x_5array4iter8IntoIterhKj20_ENCNvNtB5_5testss_14next_key_workss3_0EIB1p_IB2d_hKj21_ENCB2Q_s4_0EEB9_ Line | Count | Source | 1006 | 1 | pub fn next_key( | 1007 | 1 | &'_ self, | 1008 | 1 | trie_root_merkle_value: &[u8; 32], | 1009 | 1 | key_before: impl Iterator<Item = nibble::Nibble>, | 1010 | 1 | mut or_equal: bool, | 1011 | 1 | prefix: impl Iterator<Item = nibble::Nibble>, | 1012 | 1 | branch_nodes: bool, | 1013 | 1 | ) -> Result<Option<EntryKeyIter<'_, T>>, IncompleteProofError> { | 1014 | 1 | let proof = self.proof.as_ref(); | 1015 | 1 | | 1016 | 1 | // The implementation below might continue iterating `prefix` even after it has returned | 1017 | 1 | // `None`, thus we have to fuse it. | 1018 | 1 | let mut prefix = prefix.fuse(); | 1019 | 1 | | 1020 | 1 | // The implementation below might continue iterating `key_before` even after it has | 1021 | 1 | // returned `None`, thus we have to fuse it. | 1022 | 1 | // Furthermore, `key_before` might be modified in the implementation below. When that | 1023 | 1 | // happens, de do this by setting it to `either::Right`. | 1024 | 1 | let mut key_before = either::Left(key_before.fuse()); | 1025 | | | 1026 | | // Find the starting point of the requested trie. | 1027 | 1 | let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else { | 1028 | 0 | return Err(IncompleteProofError()); | 1029 | | }; | 1030 | | | 1031 | | // If `true`, then it was determined that `key_before` was after the last child of | 1032 | | // `iter_entry`. The next iteration must find `iter_entry`'s next sibling. | 1033 | 1 | let mut iterating_up: bool = false; | 1034 | 1 | | 1035 | 1 | // Indicates the depth of ancestors of `iter_entry` that match `prefix`. | 1036 | 1 | // For example, if the value is 2, then `iter_entry`'s parent and grandparent match | 1037 | 1 | //`prefix`, but `iter_entry`'s grandparent parent does not. | 1038 | 1 | let mut prefix_match_iter_entry_ancestor_depth = 0; | 1039 | | | 1040 | | loop { | 1041 | 2 | let Ok(iter_entry_decoded) = | 1042 | 2 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1043 | | else { | 1044 | | // Proof has been checked to be entirely decodable. | 1045 | 0 | unreachable!() | 1046 | | }; | 1047 | | | 1048 | 2 | if iterating_up { | 1049 | 0 | debug_assert!(matches!(key_before, either::Right(_))); | 1050 | 0 | debug_assert!(or_equal); | 1051 | | | 1052 | | // It was determined that `key_before` was after the last child of `iter_entry`. | 1053 | | // The next iteration must find `iter_entry`'s next sibling. | 1054 | | | 1055 | 0 | if prefix_match_iter_entry_ancestor_depth == 0 { | 1056 | | // `prefix` only matches `iter_entry` and not its parent and | 1057 | | // thus wouldn't match `iter_entry`'s sibling or uncle. | 1058 | | // Therefore, the next node is `None`. | 1059 | 0 | return Ok(None); | 1060 | 0 | } | 1061 | | | 1062 | | // Go to `iter_entry`'s next sibling, if any. | 1063 | 0 | let Some((parent_entry, parent_to_child_nibble)) = | 1064 | 0 | self.entries[iter_entry].parent_entry_index | 1065 | | else { | 1066 | | // `iter_entry` is the root of the trie. `key_before` is therefore | 1067 | | // after the last entry of the trie. | 1068 | 0 | return Ok(None); | 1069 | | }; | 1070 | | | 1071 | 0 | let Some(child_num) = iter_entry_decoded | 1072 | 0 | .children | 1073 | 0 | .iter() | 1074 | 0 | .skip(usize::from(parent_to_child_nibble) + 1) | 1075 | 0 | .position(|c| c.is_some()) | 1076 | 0 | .map(|n| n + usize::from(parent_to_child_nibble) + 1) | 1077 | | else { | 1078 | | // No child found. Continue iterating up. | 1079 | 0 | iterating_up = true; | 1080 | 0 | iter_entry = parent_entry; | 1081 | 0 | prefix_match_iter_entry_ancestor_depth -= 1; | 1082 | 0 | continue; | 1083 | | }; | 1084 | | | 1085 | | // Found a next sibling. | 1086 | | | 1087 | 0 | let children_present_in_proof_bitmap = | 1088 | 0 | self.entries[parent_entry].children_present_in_proof_bitmap; | 1089 | 0 |
| 1090 | 0 | // If the child isn't present in the proof, then the proof is | 1091 | 0 | // incomplete. While in some situations we could prove that the child | 1092 | 0 | // is necessarily the next key, there is no way to know its full key. | 1093 | 0 | if children_present_in_proof_bitmap & (1 << child_num) == 0 { | 1094 | 0 | return Err(IncompleteProofError()); | 1095 | 0 | } | 1096 | 0 |
| 1097 | 0 | // `iter_entry` is still pointing to the child at index `parent_to_child_nibble`. | 1098 | 0 | // Since we're jumping to its next sibling, all we have to do is skip over it | 1099 | 0 | // and its descedants. | 1100 | 0 | iter_entry += 1; | 1101 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1102 | 0 | iterating_up = false; | 1103 | 2 | } | 1104 | | | 1105 | 2 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1106 | | loop { | 1107 | | match ( | 1108 | 33 | key_before.next(), | 1109 | 33 | prefix.next(), | 1110 | 33 | iter_entry_partial_key_iter.next(), | 1111 | | ) { | 1112 | 31 | (Some(k), Some(p), Some(pk)) if k == p && p == pk => { | 1113 | 31 | // Continue descending down the tree. | 1114 | 31 | } | 1115 | 0 | (None, Some(p), Some(pk)) if p == pk => { | 1116 | 0 | // Continue descending down the tree. | 1117 | 0 | } | 1118 | 0 | (Some(k), None, Some(pk)) if k == pk => { | 1119 | 0 | // Continue descending down the tree. | 1120 | 0 | } | 1121 | 0 | (None, None, Some(_)) => { | 1122 | 0 | // Exact match. Due to the `branch_nodes` setting, we can't just | 1123 | 0 | // return `iter_entry` and instead continue iterating. | 1124 | 0 | or_equal = true; | 1125 | 0 | } | 1126 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1127 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1128 | 0 | // and `iter_entry`. Due to the `branch_nodes` setting, we can't just | 1129 | 0 | // return `iter_entry` and instead continue iterating. | 1130 | 0 | key_before = either::Right(iter::empty().fuse()); | 1131 | 0 | or_equal = true; | 1132 | 0 | } | 1133 | 1 | (Some(k), Some(p0 ), _) if k > p => { | 1134 | 0 | // `key_before` is strictly superior to `prefix`. The next key is | 1135 | 0 | // thus necessarily `None`. | 1136 | 0 | // Note that this is not a situation that is expected to be common, as | 1137 | 0 | // doing such a call is pointless. | 1138 | 0 | return Ok(None); | 1139 | | } | 1140 | 0 | (Some(k), Some(p), Some(pk)) if k < p && p == pk => { | 1141 | 0 | // The key and prefix diverge. | 1142 | 0 | // We know that there isn't any key in the trie between `key_before` | 1143 | 0 | // and `prefix`. | 1144 | 0 | // Starting next iteration, the next node matching the prefix | 1145 | 0 | // will be the result. | 1146 | 0 | key_before = either::Right(iter::empty().fuse()); | 1147 | 0 | or_equal = true; | 1148 | 0 | } | 1149 | 0 | (_, Some(p), Some(pk)) => { | 1150 | 0 | debug_assert!(p != pk); // Other situations covered by other match blocks. | 1151 | | | 1152 | | // Mismatch between prefix and partial key. No matter the value of | 1153 | | // `key_before` There is no node in the trie that starts with `prefix`. | 1154 | 0 | return Ok(None); | 1155 | | } | 1156 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1157 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1158 | 0 | // and `iter_entry`. We know that `iter_entry` necessarily matches | 1159 | 0 | // the prefix. The next key is necessarily `iter_entry`. | 1160 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1161 | | } | 1162 | 0 | (Some(k), None, Some(pk)) => { | 1163 | 0 | debug_assert!(k > pk); // Checked above. | 1164 | | | 1165 | | // `key_before` points to somewhere between the last child of `iter_entry` | 1166 | | // and its next sibling. | 1167 | | // The next key is thus the next sibling of `iter_entry`. | 1168 | 0 | iterating_up = true; | 1169 | 0 | key_before = either::Right(iter::empty().fuse()); | 1170 | 0 | or_equal = true; | 1171 | 0 | break; | 1172 | | } | 1173 | | (None, None, None) | 1174 | 0 | if or_equal | 1175 | 0 | && (branch_nodes | 1176 | 0 | || !matches!( | 1177 | 0 | iter_entry_decoded.storage_value, | 1178 | | trie_node::StorageValue::None, | 1179 | 0 | )) => | 1180 | 0 | { | 1181 | 0 | // Exact match. Next key is `iter_entry`. | 1182 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1183 | | } | 1184 | 2 | (key_before_nibble, prefix_nibble, None) => { | 1185 | | // The moment when we have finished traversing a node and go to the | 1186 | | // next one is the most complicated situation. | 1187 | | | 1188 | | // We know for sure that `iter_entry` can't be returned, as it is covered | 1189 | | // by the other match variants above. Therefore, `key_before_nibble` equal | 1190 | | // to `None` is the same as if it is equal to `0`. | 1191 | 2 | let key_before_nibble = match key_before_nibble { | 1192 | 1 | Some(n) => u8::from(n), | 1193 | | None => { | 1194 | 1 | or_equal = true; | 1195 | 1 | 0 | 1196 | | } | 1197 | | }; | 1198 | | | 1199 | | // Try to find the first child that is after `key_before`. | 1200 | 2 | if let Some(child_num) = iter_entry_decoded | 1201 | 2 | .children | 1202 | 2 | .iter() | 1203 | 2 | .skip(usize::from(key_before_nibble)) | 1204 | 2 | .position(|c| c.is_some()) | 1205 | 2 | .map(|n| n + usize::from(key_before_nibble)) | 1206 | | { | 1207 | | // Found a child. Make sure that it matches the prefix nibble. | 1208 | 2 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) { | 1209 | | // Child doesn't match prefix. No next key. | 1210 | 1 | return Ok(None); | 1211 | 1 | } | 1212 | 1 | | 1213 | 1 | // Continue iterating down through the child that has been found. | 1214 | 1 | | 1215 | 1 | let children_present_in_proof_bitmap = | 1216 | 1 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1217 | 1 | | 1218 | 1 | // If the child isn't present in the proof, then the proof is | 1219 | 1 | // incomplete. While in some situations we could prove that the child | 1220 | 1 | // is necessarily the next key, there is no way to know its full key. | 1221 | 1 | if children_present_in_proof_bitmap & (1 << key_before_nibble) == 0 { | 1222 | 0 | return Err(IncompleteProofError()); | 1223 | 1 | } | 1224 | | | 1225 | 9 | for c in 0..key_before_nibble1 { | 1226 | 9 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1227 | 0 | iter_entry += 1; | 1228 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1229 | 9 | } | 1230 | | } | 1231 | | | 1232 | 1 | iter_entry += 1; | 1233 | 1 | prefix_match_iter_entry_ancestor_depth += 1; | 1234 | 1 | if usize::from(key_before_nibble) != child_num { | 1235 | 0 | key_before = either::Right(iter::empty().fuse()); | 1236 | 0 | or_equal = true; | 1237 | 1 | } | 1238 | 1 | break; | 1239 | | } else { | 1240 | | // Childless branch nodes are forbidden. This is checked when | 1241 | | // decoding the proof. | 1242 | 0 | debug_assert!(!matches!( | 1243 | 0 | iter_entry_decoded.storage_value, | 1244 | | trie_node::StorageValue::None, | 1245 | | )); | 1246 | | | 1247 | | // `key_before` is after the last child of `iter_entry`. The next | 1248 | | // node is thus a sibling or uncle of `iter_entry`. | 1249 | 0 | iterating_up = true; | 1250 | 0 | key_before = either::Right(iter::empty().fuse()); | 1251 | 0 | or_equal = true; | 1252 | 0 | break; | 1253 | | } | 1254 | | } | 1255 | | } | 1256 | | } | 1257 | | } | 1258 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE8next_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtB1x_5array4iter8IntoIterhKj20_ENCNvNtB5_5testss_14next_key_workss5_0EIB1p_IB2d_hKj1f_ENCB2Q_s6_0EEB9_ Line | Count | Source | 1006 | 1 | pub fn next_key( | 1007 | 1 | &'_ self, | 1008 | 1 | trie_root_merkle_value: &[u8; 32], | 1009 | 1 | key_before: impl Iterator<Item = nibble::Nibble>, | 1010 | 1 | mut or_equal: bool, | 1011 | 1 | prefix: impl Iterator<Item = nibble::Nibble>, | 1012 | 1 | branch_nodes: bool, | 1013 | 1 | ) -> Result<Option<EntryKeyIter<'_, T>>, IncompleteProofError> { | 1014 | 1 | let proof = self.proof.as_ref(); | 1015 | 1 | | 1016 | 1 | // The implementation below might continue iterating `prefix` even after it has returned | 1017 | 1 | // `None`, thus we have to fuse it. | 1018 | 1 | let mut prefix = prefix.fuse(); | 1019 | 1 | | 1020 | 1 | // The implementation below might continue iterating `key_before` even after it has | 1021 | 1 | // returned `None`, thus we have to fuse it. | 1022 | 1 | // Furthermore, `key_before` might be modified in the implementation below. When that | 1023 | 1 | // happens, de do this by setting it to `either::Right`. | 1024 | 1 | let mut key_before = either::Left(key_before.fuse()); | 1025 | | | 1026 | | // Find the starting point of the requested trie. | 1027 | 1 | let Some(&(mut iter_entry)) = self.trie_roots.get(trie_root_merkle_value) else { | 1028 | 0 | return Err(IncompleteProofError()); | 1029 | | }; | 1030 | | | 1031 | | // If `true`, then it was determined that `key_before` was after the last child of | 1032 | | // `iter_entry`. The next iteration must find `iter_entry`'s next sibling. | 1033 | 1 | let mut iterating_up: bool = false; | 1034 | 1 | | 1035 | 1 | // Indicates the depth of ancestors of `iter_entry` that match `prefix`. | 1036 | 1 | // For example, if the value is 2, then `iter_entry`'s parent and grandparent match | 1037 | 1 | //`prefix`, but `iter_entry`'s grandparent parent does not. | 1038 | 1 | let mut prefix_match_iter_entry_ancestor_depth = 0; | 1039 | | | 1040 | | loop { | 1041 | 2 | let Ok(iter_entry_decoded) = | 1042 | 2 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1043 | | else { | 1044 | | // Proof has been checked to be entirely decodable. | 1045 | 0 | unreachable!() | 1046 | | }; | 1047 | | | 1048 | 2 | if iterating_up { | 1049 | 0 | debug_assert!(matches!(key_before, either::Right(_))); | 1050 | 0 | debug_assert!(or_equal); | 1051 | | | 1052 | | // It was determined that `key_before` was after the last child of `iter_entry`. | 1053 | | // The next iteration must find `iter_entry`'s next sibling. | 1054 | | | 1055 | 0 | if prefix_match_iter_entry_ancestor_depth == 0 { | 1056 | | // `prefix` only matches `iter_entry` and not its parent and | 1057 | | // thus wouldn't match `iter_entry`'s sibling or uncle. | 1058 | | // Therefore, the next node is `None`. | 1059 | 0 | return Ok(None); | 1060 | 0 | } | 1061 | | | 1062 | | // Go to `iter_entry`'s next sibling, if any. | 1063 | 0 | let Some((parent_entry, parent_to_child_nibble)) = | 1064 | 0 | self.entries[iter_entry].parent_entry_index | 1065 | | else { | 1066 | | // `iter_entry` is the root of the trie. `key_before` is therefore | 1067 | | // after the last entry of the trie. | 1068 | 0 | return Ok(None); | 1069 | | }; | 1070 | | | 1071 | 0 | let Some(child_num) = iter_entry_decoded | 1072 | 0 | .children | 1073 | 0 | .iter() | 1074 | 0 | .skip(usize::from(parent_to_child_nibble) + 1) | 1075 | 0 | .position(|c| c.is_some()) | 1076 | 0 | .map(|n| n + usize::from(parent_to_child_nibble) + 1) | 1077 | | else { | 1078 | | // No child found. Continue iterating up. | 1079 | 0 | iterating_up = true; | 1080 | 0 | iter_entry = parent_entry; | 1081 | 0 | prefix_match_iter_entry_ancestor_depth -= 1; | 1082 | 0 | continue; | 1083 | | }; | 1084 | | | 1085 | | // Found a next sibling. | 1086 | | | 1087 | 0 | let children_present_in_proof_bitmap = | 1088 | 0 | self.entries[parent_entry].children_present_in_proof_bitmap; | 1089 | 0 |
| 1090 | 0 | // If the child isn't present in the proof, then the proof is | 1091 | 0 | // incomplete. While in some situations we could prove that the child | 1092 | 0 | // is necessarily the next key, there is no way to know its full key. | 1093 | 0 | if children_present_in_proof_bitmap & (1 << child_num) == 0 { | 1094 | 0 | return Err(IncompleteProofError()); | 1095 | 0 | } | 1096 | 0 |
| 1097 | 0 | // `iter_entry` is still pointing to the child at index `parent_to_child_nibble`. | 1098 | 0 | // Since we're jumping to its next sibling, all we have to do is skip over it | 1099 | 0 | // and its descedants. | 1100 | 0 | iter_entry += 1; | 1101 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1102 | 0 | iterating_up = false; | 1103 | 2 | } | 1104 | | | 1105 | 2 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1106 | | loop { | 1107 | | match ( | 1108 | 31 | key_before.next(), | 1109 | 31 | prefix.next(), | 1110 | 31 | iter_entry_partial_key_iter.next(), | 1111 | | ) { | 1112 | 30 | (Some(k), Some(p), Some(pk29 )) if k == p && p29 == pk => { | 1113 | 29 | // Continue descending down the tree. | 1114 | 29 | } | 1115 | 0 | (None, Some(p), Some(pk)) if p == pk => { | 1116 | 0 | // Continue descending down the tree. | 1117 | 0 | } | 1118 | 0 | (Some(k), None, Some(pk)) if k == pk => { | 1119 | 0 | // Continue descending down the tree. | 1120 | 0 | } | 1121 | 0 | (None, None, Some(_)) => { | 1122 | 0 | // Exact match. Due to the `branch_nodes` setting, we can't just | 1123 | 0 | // return `iter_entry` and instead continue iterating. | 1124 | 0 | or_equal = true; | 1125 | 0 | } | 1126 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1127 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1128 | 0 | // and `iter_entry`. Due to the `branch_nodes` setting, we can't just | 1129 | 0 | // return `iter_entry` and instead continue iterating. | 1130 | 0 | key_before = either::Right(iter::empty().fuse()); | 1131 | 0 | or_equal = true; | 1132 | 0 | } | 1133 | 2 | (Some(k), Some(p0 ), _) if k > p => { | 1134 | 0 | // `key_before` is strictly superior to `prefix`. The next key is | 1135 | 0 | // thus necessarily `None`. | 1136 | 0 | // Note that this is not a situation that is expected to be common, as | 1137 | 0 | // doing such a call is pointless. | 1138 | 0 | return Ok(None); | 1139 | | } | 1140 | 1 | (Some(k), Some(p), Some(pk0 )) if k < p && p == pk => { | 1141 | 0 | // The key and prefix diverge. | 1142 | 0 | // We know that there isn't any key in the trie between `key_before` | 1143 | 0 | // and `prefix`. | 1144 | 0 | // Starting next iteration, the next node matching the prefix | 1145 | 0 | // will be the result. | 1146 | 0 | key_before = either::Right(iter::empty().fuse()); | 1147 | 0 | or_equal = true; | 1148 | 0 | } | 1149 | 1 | (_, Some(p), Some(pk)) => { | 1150 | 1 | debug_assert!(p != pk); // Other situations covered by other match blocks. | 1151 | | | 1152 | | // Mismatch between prefix and partial key. No matter the value of | 1153 | | // `key_before` There is no node in the trie that starts with `prefix`. | 1154 | 1 | return Ok(None); | 1155 | | } | 1156 | 0 | (Some(k), None, Some(pk)) if k < pk => { | 1157 | 0 | // `key_before` points to somewhere between `iter_entry`'s parent | 1158 | 0 | // and `iter_entry`. We know that `iter_entry` necessarily matches | 1159 | 0 | // the prefix. The next key is necessarily `iter_entry`. | 1160 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1161 | | } | 1162 | 0 | (Some(k), None, Some(pk)) => { | 1163 | 0 | debug_assert!(k > pk); // Checked above. | 1164 | | | 1165 | | // `key_before` points to somewhere between the last child of `iter_entry` | 1166 | | // and its next sibling. | 1167 | | // The next key is thus the next sibling of `iter_entry`. | 1168 | 0 | iterating_up = true; | 1169 | 0 | key_before = either::Right(iter::empty().fuse()); | 1170 | 0 | or_equal = true; | 1171 | 0 | break; | 1172 | | } | 1173 | | (None, None, None) | 1174 | 0 | if or_equal | 1175 | 0 | && (branch_nodes | 1176 | 0 | || !matches!( | 1177 | 0 | iter_entry_decoded.storage_value, | 1178 | | trie_node::StorageValue::None, | 1179 | 0 | )) => | 1180 | 0 | { | 1181 | 0 | // Exact match. Next key is `iter_entry`. | 1182 | 0 | return Ok(Some(EntryKeyIter::new(self, iter_entry))); | 1183 | | } | 1184 | 1 | (key_before_nibble, prefix_nibble, None) => { | 1185 | | // The moment when we have finished traversing a node and go to the | 1186 | | // next one is the most complicated situation. | 1187 | | | 1188 | | // We know for sure that `iter_entry` can't be returned, as it is covered | 1189 | | // by the other match variants above. Therefore, `key_before_nibble` equal | 1190 | | // to `None` is the same as if it is equal to `0`. | 1191 | 1 | let key_before_nibble = match key_before_nibble { | 1192 | 1 | Some(n) => u8::from(n), | 1193 | | None => { | 1194 | 0 | or_equal = true; | 1195 | 0 | 0 | 1196 | | } | 1197 | | }; | 1198 | | | 1199 | | // Try to find the first child that is after `key_before`. | 1200 | 1 | if let Some(child_num) = iter_entry_decoded | 1201 | 1 | .children | 1202 | 1 | .iter() | 1203 | 1 | .skip(usize::from(key_before_nibble)) | 1204 | 1 | .position(|c| c.is_some()) | 1205 | 1 | .map(|n| n + usize::from(key_before_nibble)) | 1206 | | { | 1207 | | // Found a child. Make sure that it matches the prefix nibble. | 1208 | 1 | if prefix_nibble.map_or(false, |p| child_num != usize::from(p)) { | 1209 | | // Child doesn't match prefix. No next key. | 1210 | 0 | return Ok(None); | 1211 | 1 | } | 1212 | 1 | | 1213 | 1 | // Continue iterating down through the child that has been found. | 1214 | 1 | | 1215 | 1 | let children_present_in_proof_bitmap = | 1216 | 1 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1217 | 1 | | 1218 | 1 | // If the child isn't present in the proof, then the proof is | 1219 | 1 | // incomplete. While in some situations we could prove that the child | 1220 | 1 | // is necessarily the next key, there is no way to know its full key. | 1221 | 1 | if children_present_in_proof_bitmap & (1 << key_before_nibble) == 0 { | 1222 | 0 | return Err(IncompleteProofError()); | 1223 | 1 | } | 1224 | | | 1225 | 9 | for c in 0..key_before_nibble1 { | 1226 | 9 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1227 | 0 | iter_entry += 1; | 1228 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1229 | 9 | } | 1230 | | } | 1231 | | | 1232 | 1 | iter_entry += 1; | 1233 | 1 | prefix_match_iter_entry_ancestor_depth += 1; | 1234 | 1 | if usize::from(key_before_nibble) != child_num { | 1235 | 0 | key_before = either::Right(iter::empty().fuse()); | 1236 | 0 | or_equal = true; | 1237 | 1 | } | 1238 | 1 | break; | 1239 | | } else { | 1240 | | // Childless branch nodes are forbidden. This is checked when | 1241 | | // decoding the proof. | 1242 | 0 | debug_assert!(!matches!( | 1243 | 0 | iter_entry_decoded.storage_value, | 1244 | | trie_node::StorageValue::None, | 1245 | | )); | 1246 | | | 1247 | | // `key_before` is after the last child of `iter_entry`. The next | 1248 | | // node is thus a sibling or uncle of `iter_entry`. | 1249 | 0 | iterating_up = true; | 1250 | 0 | key_before = either::Right(iter::empty().fuse()); | 1251 | 0 | or_equal = true; | 1252 | 0 | break; | 1253 | | } | 1254 | | } | 1255 | | } | 1256 | | } | 1257 | | } | 1258 | 1 | } |
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3l_5slice4iter4IterhEEEIB2d_IB2I_INtNvNtB9_4util11as_ref_iter4IterIB2d_RShINtNvMs5_NtNtNtB9_8executor2vm11interpreterNtB5z_11Interpreter11read_memory12AccessOffsetB5n_EEhEEINtNtB3h_7flatten7FlatMapINtNtB3h_5chain5ChainINtNtB3h_3map3MapIB71_IB47_NtNtB5D_20trie_root_calculator14InProgressNodeEIB7q_INtNtNtB3j_7sources4once4OnceIB2d_ANtB2K_6Nibblej1_RINtB1h_3VecB9A_EEEINtNtB3l_6option8IntoIterB9u_EENCNvMs3_B8d_NtB8d_5Inner21current_node_full_key0ENcNtIB2d_B9u_B9Q_E4Left0EIB92_Bbv_EEIB4M_BbV_B9A_EIB4O_B9A_BbV_EEEEIB2d_IB2I_IB4M_IB2d_B5i_B5n_EhEEIB2d_B2c_INtNtB96_5empty5EmptyB9A_EEEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2y_5slice4iter4IterhEEEIB1q_IB1V_INtNvNtB9_4util11as_ref_iter4IterIB1q_B1c_INtNvMs5_NtNtNtB9_8executor2vm11interpreterNtB4N_11Interpreter11read_memory12AccessOffsetB1c_EEhEEINtNtB2u_7flatten7FlatMapINtNtB2u_5chain5ChainINtNtB2u_3map3MapIB6f_IB3k_NtNtB4R_20trie_root_calculator14InProgressNodeEIB6E_INtNtNtB2w_7sources4once4OnceIB1q_ANtB1X_6Nibblej1_RINtNtCsdZExvAaxgia_5alloc3vec3VecB8O_EEEINtNtB2y_6option8IntoIterB8I_EENCNvMs3_B7r_NtB7r_5Inner21current_node_full_key0ENcNtIB1q_B8I_B94_E4Left0EIB8g_Bb5_EEIB3Z_Bbv_B8O_EIB41_B8O_Bbv_EEEEIB1q_IB1V_IB3Z_IB1q_B4v_B1c_EhEEIB1q_B1p_INtNtB8k_5empty5EmptyB8O_EEEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofpE8next_keyppEB9_ Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3l_5slice4iter4IterhEEEIB2d_IB2I_INtNvNtB9_4util11as_ref_iter4IterIB2d_RShINtNvMs5_NtNtNtB9_8executor2vm11interpreterNtB5z_11Interpreter11read_memory12AccessOffsetB5n_EEhEEINtNtB3h_7flatten7FlatMapINtNtB3h_5chain5ChainINtNtB3h_3map3MapIB71_IB47_NtNtB5D_20trie_root_calculator14InProgressNodeEIB7q_INtNtNtB3j_7sources4once4OnceIB2d_ANtB2K_6Nibblej1_RINtB1h_3VecB9A_EEEINtNtB3l_6option8IntoIterB9u_EENCNvMs3_B8d_NtB8d_5Inner21current_node_full_key0ENcNtIB2d_B9u_B9Q_E4Left0EIB92_Bbv_EEIB4M_BbV_B9A_EIB4O_B9A_BbV_EEEEIB2d_IB2I_IB4M_IB2d_B5i_B5n_EhEEIB2d_B2c_INtNtB96_5empty5EmptyB9A_EEEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3l_5slice4iter4IterhEEEIB2d_IB2I_INtNvNtB9_4util11as_ref_iter4IterIB2d_RShINtNvMs5_NtNtNtB9_8executor2vm11interpreterNtB5z_11Interpreter11read_memory12AccessOffsetB5n_EEhEEINtNtB3h_7flatten7FlatMapINtNtB3h_5chain5ChainINtNtB3h_3map3MapIB71_IB47_NtNtB5D_20trie_root_calculator14InProgressNodeEIB7q_INtNtNtB3j_7sources4once4OnceIB2d_ANtB2K_6Nibblej1_RINtB1h_3VecB9A_EEEINtNtB3l_6option8IntoIterB9u_EENCNvMs3_B8d_NtB8d_5Inner21current_node_full_key0ENcNtIB2d_B9u_B9Q_E4Left0EIB92_Bbv_EEIB4M_BbV_B9A_EIB4O_B9A_BbV_EEEEIB2d_IB2I_IB4M_IB2d_B5i_B5n_EhEEIB2d_B2c_INtNtB96_5empty5EmptyB9A_EEEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE8next_keyINtCs1qmLyiTSqYF_6either6EitherINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB3l_5slice4iter4IterhEEEIB2d_IB2I_INtNvNtB9_4util11as_ref_iter4IterIB2d_RShINtNvMs5_NtNtNtB9_8executor2vm11interpreterNtB5z_11Interpreter11read_memory12AccessOffsetB5n_EEhEEINtNtB3h_7flatten7FlatMapINtNtB3h_5chain5ChainINtNtB3h_3map3MapIB71_IB47_NtNtB5D_20trie_root_calculator14InProgressNodeEIB7q_INtNtNtB3j_7sources4once4OnceIB2d_ANtB2K_6Nibblej1_RINtB1h_3VecB9A_EEEINtNtB3l_6option8IntoIterB9u_EENCNvMs3_B8d_NtB8d_5Inner21current_node_full_key0ENcNtIB2d_B9u_B9Q_E4Left0EIB92_Bbv_EEIB4M_BbV_B9A_EIB4O_B9A_BbV_EEEEIB2d_IB2I_IB4M_IB2d_B5i_B5n_EhEEIB2d_B2c_INtNtB96_5empty5EmptyB9A_EEEECsibGXYHQB8Ea_25json_rpc_general_requests |
1259 | | |
1260 | | /// Find in the proof the closest trie node that descends from `key` and returns its Merkle |
1261 | | /// value. |
1262 | | /// |
1263 | | /// Returns an error if the proof doesn't contain enough information to determine the Merkle |
1264 | | /// value. |
1265 | | /// Returns `Ok(None)` if the proof indicates that there is no descendant. |
1266 | 1.51k | pub fn closest_descendant_merkle_value( |
1267 | 1.51k | &'_ self, |
1268 | 1.51k | trie_root_merkle_value: &[u8; 32], |
1269 | 1.51k | mut key: impl Iterator<Item = nibble::Nibble>, |
1270 | 1.51k | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { |
1271 | 1.51k | let proof = self.proof.as_ref(); |
1272 | | |
1273 | | // Find the starting point of the requested trie. |
1274 | 1.51k | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self |
1275 | 1.51k | .trie_roots |
1276 | 1.51k | .get_key_value(trie_root_merkle_value) |
1277 | 1.51k | .map(|(k, v)| (&k[..], *v)) _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofAhj43e8_E31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB9_6nibble6NibbleEE0Bb_ Line | Count | Source | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB9_6nibble6NibbleEE0Bb_ Line | Count | Source | 1277 | 1.50k | .map(|(k, v)| (&k[..], *v)) |
Unexecuted instantiation: _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2l_INtNtNtB2t_5slice4iter4IterNtNtNtBb_8executor20trie_root_calculator14InProgressNodeEINtNtB2p_5chain5ChainINtNtNtB2r_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB9_6nibble6Nibblej1_RIB1e_B61_EEEINtNtB2t_6option8IntoIterB5v_EENCNvMs3_B3O_NtB3O_5Inner21current_node_full_key0EINtNvNtBb_4util11as_ref_iter4IterB5v_B61_EIB7X_B61_B5v_EEE0Bb_ _RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRAhj11_E31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB9_6nibble6NibbleEE0Bb_ Line | Count | Source | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB9_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj0_EEE0Bb_ Line | Count | Source | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB9_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj10_EEE0Bb_ Line | Count | Source | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB9_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj3f_EEE0Bb_ Line | Count | Source | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB9_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj40_EEE0Bb_ Line | Count | Source | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB9_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj41_EEE0Bb_ Line | Count | Source | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB9_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKje_EEE0Bb_ Line | Count | Source | 1277 | 2 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterNtNtB9_6nibble6NibbleKj1_EE0Bb_ Line | Count | Source | 1277 | 2 | .map(|(k, v)| (&k[..], *v)) |
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterNtNtB9_6nibble6NibbleKj2_EE0Bb_ Line | Count | Source | 1277 | 2 | .map(|(k, v)| (&k[..], *v)) |
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2D_INtNtNtB2L_5slice4iter4IterNtNtNtBb_8executor20trie_root_calculator14InProgressNodeEINtNtB2H_5chain5ChainINtNtNtB2J_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB9_6nibble6Nibblej1_RINtB1j_3VecB6j_EEEINtNtB2L_6option8IntoIterB5N_EENCNvMs3_B46_NtB46_5Inner21current_node_full_key0EINtNvNtBb_4util11as_ref_iter4IterB5N_B6j_EIB8l_B6j_B5N_EEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB9_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2t_5slice4iter4IterhEEEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB1Q_INtNtNtB1Y_5slice4iter4IterNtNtNtBb_8executor20trie_root_calculator14InProgressNodeEINtNtB1U_5chain5ChainINtNtNtB1W_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB9_6nibble6Nibblej1_RINtNtCsdZExvAaxgia_5alloc3vec3VecB5w_EEEINtNtB1Y_6option8IntoIterB50_EENCNvMs3_B3j_NtB3j_5Inner21current_node_full_key0EINtNvNtBb_4util11as_ref_iter4IterB50_B5w_EIB7U_B5w_B50_EEE0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofpE31closest_descendant_merkle_valuepE0Bb_ Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2D_INtNtNtB2L_5slice4iter4IterNtNtNtBb_8executor20trie_root_calculator14InProgressNodeEINtNtB2H_5chain5ChainINtNtNtB2J_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB9_6nibble6Nibblej1_RINtB1j_3VecB6j_EEEINtNtB2L_6option8IntoIterB5N_EENCNvMs3_B46_NtB46_5Inner21current_node_full_key0EINtNvNtBb_4util11as_ref_iter4IterB5N_B6j_EIB8l_B6j_B5N_EEE0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2D_INtNtNtB2L_5slice4iter4IterNtNtNtBb_8executor20trie_root_calculator14InProgressNodeEINtNtB2H_5chain5ChainINtNtNtB2J_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB9_6nibble6Nibblej1_RINtB1j_3VecB6j_EEEINtNtB2L_6option8IntoIterB5N_EENCNvMs3_B46_NtB46_5Inner21current_node_full_key0EINtNvNtBb_4util11as_ref_iter4IterB5N_B6j_EIB8l_B6j_B5N_EEE0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2D_INtNtNtB2L_5slice4iter4IterNtNtNtBb_8executor20trie_root_calculator14InProgressNodeEINtNtB2H_5chain5ChainINtNtNtB2J_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB9_6nibble6Nibblej1_RINtB1j_3VecB6j_EEEINtNtB2L_6option8IntoIterB5N_EENCNvMs3_B46_NtB46_5Inner21current_node_full_key0EINtNvNtBb_4util11as_ref_iter4IterB5N_B6j_EIB8l_B6j_B5N_EEE0CsibGXYHQB8Ea_25json_rpc_general_requests |
1278 | | else { |
1279 | 0 | return Err(IncompleteProofError()); |
1280 | | }; |
1281 | | |
1282 | | loop { |
1283 | 1.53k | let Ok(iter_entry_decoded) = |
1284 | 1.53k | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) |
1285 | | else { |
1286 | | // Proof has been checked to be entirely decodable. |
1287 | 0 | unreachable!() |
1288 | | }; |
1289 | | |
1290 | 1.53k | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; |
1291 | | loop { |
1292 | 1.98k | match (key.next(), iter_entry_partial_key_iter.next()) { |
1293 | 452 | (Some(a), Some(b451 )) if a == b => {}451 |
1294 | | (Some(_), Some(_)) => { |
1295 | | // Mismatch in partial key. No descendant. |
1296 | 1 | return Ok(None); |
1297 | | } |
1298 | | (None, Some(_)) => { |
1299 | | // Input key is a subslice of `iter_entry`'s key. |
1300 | | // Descendant is thus `iter_entry`. |
1301 | 59 | return Ok(Some(iter_entry_merkle_value)); |
1302 | | } |
1303 | 23 | (Some(child_num), None) => { |
1304 | 23 | if let Some(child20 ) = iter_entry_decoded.children[usize::from(child_num)] { |
1305 | | // Key points in the direction of a child. |
1306 | 20 | let children_present_in_proof_bitmap = |
1307 | 20 | self.entries[iter_entry].children_present_in_proof_bitmap; |
1308 | 20 | |
1309 | 20 | // If the child isn't present in the proof, then the proof is |
1310 | 20 | // incomplete, unless the input key doesn't have any nibble anymore, |
1311 | 20 | // in which case we know that the closest descendant is this child, |
1312 | 20 | // even if it's not present. |
1313 | 20 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { |
1314 | 2 | if key.next().is_none() { |
1315 | 1 | return Ok(Some(child)); |
1316 | | } else { |
1317 | 1 | return Err(IncompleteProofError()); |
1318 | | } |
1319 | 18 | } |
1320 | 18 | |
1321 | 18 | // Child is present in the proof. Update `iter_entry` and continue. |
1322 | 18 | iter_entry_merkle_value = child; |
1323 | 117 | for c in 0..u8::from(child_num)18 { |
1324 | 117 | if children_present_in_proof_bitmap & (1 << c) != 0 { |
1325 | 0 | iter_entry += 1; |
1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; |
1327 | 117 | } |
1328 | | } |
1329 | 18 | iter_entry += 1; |
1330 | 18 | break; |
1331 | | } else { |
1332 | | // Key points to non-existing child. We know that there's no |
1333 | | // descendant. |
1334 | 3 | return Ok(None); |
1335 | | } |
1336 | | } |
1337 | | (None, None) => { |
1338 | | // Exact match. Closest descendant is `iter_entry`. |
1339 | 1.44k | return Ok(Some(iter_entry_merkle_value)); |
1340 | | } |
1341 | | } |
1342 | | } |
1343 | | } |
1344 | 1.51k | } _RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofAhj43e8_E31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB7_6nibble6NibbleEEB9_ Line | Count | Source | 1266 | 1 | pub fn closest_descendant_merkle_value( | 1267 | 1 | &'_ self, | 1268 | 1 | trie_root_merkle_value: &[u8; 32], | 1269 | 1 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 1 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 1 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 1 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 1 | .trie_roots | 1276 | 1 | .get_key_value(trie_root_merkle_value) | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 1 | let Ok(iter_entry_decoded) = | 1284 | 1 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 1 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 1 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 0 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 0 | (Some(child_num), None) => { | 1304 | 0 | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 0 | let children_present_in_proof_bitmap = | 1307 | 0 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 0 |
| 1309 | 0 | // If the child isn't present in the proof, then the proof is | 1310 | 0 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 0 | // in which case we know that the closest descendant is this child, | 1312 | 0 | // even if it's not present. | 1313 | 0 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 0 | } | 1320 | 0 |
| 1321 | 0 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 0 | iter_entry_merkle_value = child; | 1323 | 0 | for c in 0..u8::from(child_num) { | 1324 | 0 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 0 | } | 1328 | | } | 1329 | 0 | iter_entry += 1; | 1330 | 0 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 0 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 1 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB7_6nibble6NibbleEEB9_ Line | Count | Source | 1266 | 1.50k | pub fn closest_descendant_merkle_value( | 1267 | 1.50k | &'_ self, | 1268 | 1.50k | trie_root_merkle_value: &[u8; 32], | 1269 | 1.50k | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 1.50k | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 1.50k | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 1.50k | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 1.50k | .trie_roots | 1276 | 1.50k | .get_key_value(trie_root_merkle_value) | 1277 | 1.50k | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 1.50k | let Ok(iter_entry_decoded) = | 1284 | 1.50k | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 1.50k | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 1.50k | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 0 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 57 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 0 | (Some(child_num), None) => { | 1304 | 0 | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 0 | let children_present_in_proof_bitmap = | 1307 | 0 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 0 |
| 1309 | 0 | // If the child isn't present in the proof, then the proof is | 1310 | 0 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 0 | // in which case we know that the closest descendant is this child, | 1312 | 0 | // even if it's not present. | 1313 | 0 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 0 | } | 1320 | 0 |
| 1321 | 0 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 0 | iter_entry_merkle_value = child; | 1323 | 0 | for c in 0..u8::from(child_num) { | 1324 | 0 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 0 | } | 1328 | | } | 1329 | 0 | iter_entry += 1; | 1330 | 0 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 0 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 1.44k | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 1.50k | } |
Unexecuted instantiation: _RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtCsdZExvAaxgia_5alloc3vec3VechEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2j_INtNtNtB2r_5slice4iter4IterNtNtNtB9_8executor20trie_root_calculator14InProgressNodeEINtNtB2n_5chain5ChainINtNtNtB2p_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB7_6nibble6Nibblej1_RIB1c_B5Z_EEEINtNtB2r_6option8IntoIterB5t_EENCNvMs3_B3M_NtB3M_5Inner21current_node_full_key0EINtNvNtB9_4util11as_ref_iter4IterB5t_B5Z_EIB7V_B5Z_B5t_EEEB9_ _RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRAhj11_E31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter7sources5empty5EmptyNtNtB7_6nibble6NibbleEEB9_ Line | Count | Source | 1266 | 1 | pub fn closest_descendant_merkle_value( | 1267 | 1 | &'_ self, | 1268 | 1 | trie_root_merkle_value: &[u8; 32], | 1269 | 1 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 1 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 1 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 1 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 1 | .trie_roots | 1276 | 1 | .get_key_value(trie_root_merkle_value) | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 1 | let Ok(iter_entry_decoded) = | 1284 | 1 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 1 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 1 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 0 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 0 | (Some(child_num), None) => { | 1304 | 0 | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 0 | let children_present_in_proof_bitmap = | 1307 | 0 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 0 |
| 1309 | 0 | // If the child isn't present in the proof, then the proof is | 1310 | 0 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 0 | // in which case we know that the closest descendant is this child, | 1312 | 0 | // even if it's not present. | 1313 | 0 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 0 | } | 1320 | 0 |
| 1321 | 0 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 0 | iter_entry_merkle_value = child; | 1323 | 0 | for c in 0..u8::from(child_num) { | 1324 | 0 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 0 | } | 1328 | | } | 1329 | 0 | iter_entry += 1; | 1330 | 0 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 0 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 1 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB7_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj0_EEEB9_ Line | Count | Source | 1266 | 1 | pub fn closest_descendant_merkle_value( | 1267 | 1 | &'_ self, | 1268 | 1 | trie_root_merkle_value: &[u8; 32], | 1269 | 1 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 1 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 1 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 1 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 1 | .trie_roots | 1276 | 1 | .get_key_value(trie_root_merkle_value) | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 1 | let Ok(iter_entry_decoded) = | 1284 | 1 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 1 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 1 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 0 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 0 | (Some(child_num), None) => { | 1304 | 0 | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 0 | let children_present_in_proof_bitmap = | 1307 | 0 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 0 |
| 1309 | 0 | // If the child isn't present in the proof, then the proof is | 1310 | 0 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 0 | // in which case we know that the closest descendant is this child, | 1312 | 0 | // even if it's not present. | 1313 | 0 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 0 | } | 1320 | 0 |
| 1321 | 0 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 0 | iter_entry_merkle_value = child; | 1323 | 0 | for c in 0..u8::from(child_num) { | 1324 | 0 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 0 | } | 1328 | | } | 1329 | 0 | iter_entry += 1; | 1330 | 0 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 0 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 1 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB7_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj10_EEEB9_ Line | Count | Source | 1266 | 1 | pub fn closest_descendant_merkle_value( | 1267 | 1 | &'_ self, | 1268 | 1 | trie_root_merkle_value: &[u8; 32], | 1269 | 1 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 1 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 1 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 1 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 1 | .trie_roots | 1276 | 1 | .get_key_value(trie_root_merkle_value) | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 2 | let Ok(iter_entry_decoded) = | 1284 | 2 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 2 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 33 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 31 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 1 | (Some(child_num), None) => { | 1304 | 1 | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 1 | let children_present_in_proof_bitmap = | 1307 | 1 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 1 | | 1309 | 1 | // If the child isn't present in the proof, then the proof is | 1310 | 1 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 1 | // in which case we know that the closest descendant is this child, | 1312 | 1 | // even if it's not present. | 1313 | 1 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 1 | } | 1320 | 1 | | 1321 | 1 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 1 | iter_entry_merkle_value = child; | 1323 | 9 | for c in 0..u8::from(child_num)1 { | 1324 | 9 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 9 | } | 1328 | | } | 1329 | 1 | iter_entry += 1; | 1330 | 1 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 0 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 1 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB7_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj3f_EEEB9_ Line | Count | Source | 1266 | 1 | pub fn closest_descendant_merkle_value( | 1267 | 1 | &'_ self, | 1268 | 1 | trie_root_merkle_value: &[u8; 32], | 1269 | 1 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 1 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 1 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 1 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 1 | .trie_roots | 1276 | 1 | .get_key_value(trie_root_merkle_value) | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 6 | let Ok(iter_entry_decoded) = | 1284 | 6 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 6 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 127 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 121 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 1 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 5 | (Some(child_num), None) => { | 1304 | 5 | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 5 | let children_present_in_proof_bitmap = | 1307 | 5 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 5 | | 1309 | 5 | // If the child isn't present in the proof, then the proof is | 1310 | 5 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 5 | // in which case we know that the closest descendant is this child, | 1312 | 5 | // even if it's not present. | 1313 | 5 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 5 | } | 1320 | 5 | | 1321 | 5 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 5 | iter_entry_merkle_value = child; | 1323 | 30 | for c in 0..u8::from(child_num)5 { | 1324 | 30 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 30 | } | 1328 | | } | 1329 | 5 | iter_entry += 1; | 1330 | 5 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 0 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB7_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj40_EEEB9_ Line | Count | Source | 1266 | 1 | pub fn closest_descendant_merkle_value( | 1267 | 1 | &'_ self, | 1268 | 1 | trie_root_merkle_value: &[u8; 32], | 1269 | 1 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 1 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 1 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 1 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 1 | .trie_roots | 1276 | 1 | .get_key_value(trie_root_merkle_value) | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 6 | let Ok(iter_entry_decoded) = | 1284 | 6 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 6 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 129 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 123 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 5 | (Some(child_num), None) => { | 1304 | 5 | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 5 | let children_present_in_proof_bitmap = | 1307 | 5 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 5 | | 1309 | 5 | // If the child isn't present in the proof, then the proof is | 1310 | 5 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 5 | // in which case we know that the closest descendant is this child, | 1312 | 5 | // even if it's not present. | 1313 | 5 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 5 | } | 1320 | 5 | | 1321 | 5 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 5 | iter_entry_merkle_value = child; | 1323 | 30 | for c in 0..u8::from(child_num)5 { | 1324 | 30 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 30 | } | 1328 | | } | 1329 | 5 | iter_entry += 1; | 1330 | 5 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 0 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 1 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB7_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKj41_EEEB9_ Line | Count | Source | 1266 | 1 | pub fn closest_descendant_merkle_value( | 1267 | 1 | &'_ self, | 1268 | 1 | trie_root_merkle_value: &[u8; 32], | 1269 | 1 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 1 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 1 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 1 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 1 | .trie_roots | 1276 | 1 | .get_key_value(trie_root_merkle_value) | 1277 | 1 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 6 | let Ok(iter_entry_decoded) = | 1284 | 6 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 6 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 129 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 123 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 6 | (Some(child_num), None) => { | 1304 | 6 | if let Some(child5 ) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 5 | let children_present_in_proof_bitmap = | 1307 | 5 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 5 | | 1309 | 5 | // If the child isn't present in the proof, then the proof is | 1310 | 5 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 5 | // in which case we know that the closest descendant is this child, | 1312 | 5 | // even if it's not present. | 1313 | 5 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 5 | } | 1320 | 5 | | 1321 | 5 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 5 | iter_entry_merkle_value = child; | 1323 | 30 | for c in 0..u8::from(child_num)5 { | 1324 | 30 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 30 | } | 1328 | | } | 1329 | 5 | iter_entry += 1; | 1330 | 5 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 1 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 1 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB7_6nibble14BytesToNibblesINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterhKje_EEEB9_ Line | Count | Source | 1266 | 2 | pub fn closest_descendant_merkle_value( | 1267 | 2 | &'_ self, | 1268 | 2 | trie_root_merkle_value: &[u8; 32], | 1269 | 2 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 2 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 2 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 2 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 2 | .trie_roots | 1276 | 2 | .get_key_value(trie_root_merkle_value) | 1277 | 2 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 4 | let Ok(iter_entry_decoded) = | 1284 | 4 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 4 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 57 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 54 | (Some(a), Some(b53 )) if a == b => {}53 | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 1 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 1 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 2 | (Some(child_num), None) => { | 1304 | 2 | if let Some(child) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 2 | let children_present_in_proof_bitmap = | 1307 | 2 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 2 | | 1309 | 2 | // If the child isn't present in the proof, then the proof is | 1310 | 2 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 2 | // in which case we know that the closest descendant is this child, | 1312 | 2 | // even if it's not present. | 1313 | 2 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 0 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 2 | } | 1320 | 2 | | 1321 | 2 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 2 | iter_entry_merkle_value = child; | 1323 | 18 | for c in 0..u8::from(child_num)2 { | 1324 | 18 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 18 | } | 1328 | | } | 1329 | 2 | iter_entry += 1; | 1330 | 2 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 0 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 2 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterNtNtB7_6nibble6NibbleKj1_EEB9_ Line | Count | Source | 1266 | 2 | pub fn closest_descendant_merkle_value( | 1267 | 2 | &'_ self, | 1268 | 2 | trie_root_merkle_value: &[u8; 32], | 1269 | 2 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 2 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 2 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 2 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 2 | .trie_roots | 1276 | 2 | .get_key_value(trie_root_merkle_value) | 1277 | 2 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 2 | let Ok(iter_entry_decoded) = | 1284 | 2 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 2 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 2 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 0 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 2 | (Some(child_num), None) => { | 1304 | 2 | if let Some(child1 ) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 1 | let children_present_in_proof_bitmap = | 1307 | 1 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 1 | | 1309 | 1 | // If the child isn't present in the proof, then the proof is | 1310 | 1 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 1 | // in which case we know that the closest descendant is this child, | 1312 | 1 | // even if it's not present. | 1313 | 1 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 1 | if key.next().is_none() { | 1315 | 1 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 0 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 0 | } | 1320 | 0 |
| 1321 | 0 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 0 | iter_entry_merkle_value = child; | 1323 | 0 | for c in 0..u8::from(child_num) { | 1324 | 0 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 0 | } | 1328 | | } | 1329 | 0 | iter_entry += 1; | 1330 | 0 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 1 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 2 | } |
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterNtNtB7_6nibble6NibbleKj2_EEB9_ Line | Count | Source | 1266 | 2 | pub fn closest_descendant_merkle_value( | 1267 | 2 | &'_ self, | 1268 | 2 | trie_root_merkle_value: &[u8; 32], | 1269 | 2 | mut key: impl Iterator<Item = nibble::Nibble>, | 1270 | 2 | ) -> Result<Option<&'_ [u8]>, IncompleteProofError> { | 1271 | 2 | let proof = self.proof.as_ref(); | 1272 | | | 1273 | | // Find the starting point of the requested trie. | 1274 | 2 | let Some((mut iter_entry_merkle_value, mut iter_entry)) = self | 1275 | 2 | .trie_roots | 1276 | 2 | .get_key_value(trie_root_merkle_value) | 1277 | 2 | .map(|(k, v)| (&k[..], *v)) | 1278 | | else { | 1279 | 0 | return Err(IncompleteProofError()); | 1280 | | }; | 1281 | | | 1282 | | loop { | 1283 | 2 | let Ok(iter_entry_decoded) = | 1284 | 2 | trie_node::decode(&proof[self.entries[iter_entry].range_in_proof.clone()]) | 1285 | | else { | 1286 | | // Proof has been checked to be entirely decodable. | 1287 | 0 | unreachable!() | 1288 | | }; | 1289 | | | 1290 | 2 | let mut iter_entry_partial_key_iter = iter_entry_decoded.partial_key; | 1291 | | loop { | 1292 | 2 | match (key.next(), iter_entry_partial_key_iter.next()) { | 1293 | 0 | (Some(a), Some(b)) if a == b => {} | 1294 | | (Some(_), Some(_)) => { | 1295 | | // Mismatch in partial key. No descendant. | 1296 | 0 | return Ok(None); | 1297 | | } | 1298 | | (None, Some(_)) => { | 1299 | | // Input key is a subslice of `iter_entry`'s key. | 1300 | | // Descendant is thus `iter_entry`. | 1301 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1302 | | } | 1303 | 2 | (Some(child_num), None) => { | 1304 | 2 | if let Some(child1 ) = iter_entry_decoded.children[usize::from(child_num)] { | 1305 | | // Key points in the direction of a child. | 1306 | 1 | let children_present_in_proof_bitmap = | 1307 | 1 | self.entries[iter_entry].children_present_in_proof_bitmap; | 1308 | 1 | | 1309 | 1 | // If the child isn't present in the proof, then the proof is | 1310 | 1 | // incomplete, unless the input key doesn't have any nibble anymore, | 1311 | 1 | // in which case we know that the closest descendant is this child, | 1312 | 1 | // even if it's not present. | 1313 | 1 | if children_present_in_proof_bitmap & (1 << u8::from(child_num)) == 0 { | 1314 | 1 | if key.next().is_none() { | 1315 | 0 | return Ok(Some(child)); | 1316 | | } else { | 1317 | 1 | return Err(IncompleteProofError()); | 1318 | | } | 1319 | 0 | } | 1320 | 0 |
| 1321 | 0 | // Child is present in the proof. Update `iter_entry` and continue. | 1322 | 0 | iter_entry_merkle_value = child; | 1323 | 0 | for c in 0..u8::from(child_num) { | 1324 | 0 | if children_present_in_proof_bitmap & (1 << c) != 0 { | 1325 | 0 | iter_entry += 1; | 1326 | 0 | iter_entry += self.entries[iter_entry].child_entries_follow_up; | 1327 | 0 | } | 1328 | | } | 1329 | 0 | iter_entry += 1; | 1330 | 0 | break; | 1331 | | } else { | 1332 | | // Key points to non-existing child. We know that there's no | 1333 | | // descendant. | 1334 | 1 | return Ok(None); | 1335 | | } | 1336 | | } | 1337 | | (None, None) => { | 1338 | | // Exact match. Closest descendant is `iter_entry`. | 1339 | 0 | return Ok(Some(iter_entry_merkle_value)); | 1340 | | } | 1341 | | } | 1342 | | } | 1343 | | } | 1344 | 2 | } |
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2B_INtNtNtB2J_5slice4iter4IterNtNtNtB9_8executor20trie_root_calculator14InProgressNodeEINtNtB2F_5chain5ChainINtNtNtB2H_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB7_6nibble6Nibblej1_RINtB1h_3VecB6h_EEEINtNtB2J_6option8IntoIterB5L_EENCNvMs3_B44_NtB44_5Inner21current_node_full_key0EINtNvNtB9_4util11as_ref_iter4IterB5L_B6h_EIB8j_B6h_B5L_EEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtB7_6nibble14BytesToNibblesINtNtNtNtCsaYZPK01V26L_4core4iter8adapters6copied6CopiedINtNtNtB2r_5slice4iter4IterhEEEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofRShE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB1O_INtNtNtB1W_5slice4iter4IterNtNtNtB9_8executor20trie_root_calculator14InProgressNodeEINtNtB1S_5chain5ChainINtNtNtB1U_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB7_6nibble6Nibblej1_RINtNtCsdZExvAaxgia_5alloc3vec3VecB5u_EEEINtNtB1W_6option8IntoIterB4Y_EENCNvMs3_B3h_NtB3h_5Inner21current_node_full_key0EINtNvNtB9_4util11as_ref_iter4IterB4Y_B5u_EIB7S_B5u_B4Y_EEECsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofpE31closest_descendant_merkle_valuepEB9_ Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2B_INtNtNtB2J_5slice4iter4IterNtNtNtB9_8executor20trie_root_calculator14InProgressNodeEINtNtB2F_5chain5ChainINtNtNtB2H_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB7_6nibble6Nibblej1_RINtB1h_3VecB6h_EEEINtNtB2J_6option8IntoIterB5L_EENCNvMs3_B44_NtB44_5Inner21current_node_full_key0EINtNvNtB9_4util11as_ref_iter4IterB5L_B6h_EIB8j_B6h_B5L_EEECsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2B_INtNtNtB2J_5slice4iter4IterNtNtNtB9_8executor20trie_root_calculator14InProgressNodeEINtNtB2F_5chain5ChainINtNtNtB2H_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB7_6nibble6Nibblej1_RINtB1h_3VecB6h_EEEINtNtB2J_6option8IntoIterB5L_EENCNvMs3_B44_NtB44_5Inner21current_node_full_key0EINtNvNtB9_4util11as_ref_iter4IterB5L_B6h_EIB8j_B6h_B5L_EEECscDgN54JpMGG_6author Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_16DecodedTrieProofINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE31closest_descendant_merkle_valueINtNtNtNtCsaYZPK01V26L_4core4iter8adapters7flatten7FlatMapIB2B_INtNtNtB2J_5slice4iter4IterNtNtNtB9_8executor20trie_root_calculator14InProgressNodeEINtNtB2F_5chain5ChainINtNtNtB2H_7sources4once4OnceINtCs1qmLyiTSqYF_6either6EitherANtNtB7_6nibble6Nibblej1_RINtB1h_3VecB6h_EEEINtNtB2J_6option8IntoIterB5L_EENCNvMs3_B44_NtB44_5Inner21current_node_full_key0EINtNvNtB9_4util11as_ref_iter4IterB5L_B6h_EIB8j_B6h_B5L_EEECsibGXYHQB8Ea_25json_rpc_general_requests |
1345 | | } |
1346 | | |
1347 | | /// Proof doesn't contain enough information to answer the request. |
1348 | 0 | #[derive(Debug, Clone, derive_more::Display)] Unexecuted instantiation: _RNvXsg_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeNtB5_20IncompleteProofErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt Unexecuted instantiation: _RNvXsg_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeNtB5_20IncompleteProofErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt |
1349 | | pub struct IncompleteProofError(); |
1350 | | |
1351 | | /// Storage value of the node. |
1352 | | #[derive(Copy, Clone)] |
1353 | | pub enum StorageValue<'a> { |
1354 | | /// The storage value was found in the proof. |
1355 | | Known { |
1356 | | /// The storage value. |
1357 | | value: &'a [u8], |
1358 | | /// `true` if the storage value was inline in the node. This indicates "version 0" of the |
1359 | | /// state version, while `false` indicates "version 1". |
1360 | | inline: bool, |
1361 | | }, |
1362 | | /// The hash of the storage value was found, but the un-hashed value wasn't in the proof. This |
1363 | | /// indicates an incomplete proof. |
1364 | | HashKnownValueMissing(&'a [u8; 32]), |
1365 | | /// The node doesn't have a storage value. |
1366 | | None, |
1367 | | } |
1368 | | |
1369 | | impl<'a> fmt::Debug for StorageValue<'a> { |
1370 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1371 | 0 | match self { |
1372 | 0 | StorageValue::Known { value, inline } if value.len() <= 48 => { |
1373 | 0 | write!( |
1374 | 0 | f, |
1375 | 0 | "0x{}{}", |
1376 | 0 | hex::encode(value), |
1377 | 0 | if *inline { " (inline)" } else { "" } |
1378 | | ) |
1379 | | } |
1380 | 0 | StorageValue::Known { value, inline } => { |
1381 | 0 | write!( |
1382 | 0 | f, |
1383 | 0 | "0x{}…{} ({} bytes{})", |
1384 | 0 | hex::encode(&value[0..4]), |
1385 | 0 | hex::encode(&value[value.len() - 4..]), |
1386 | 0 | value.len(), |
1387 | 0 | if *inline { ", inline" } else { "" } |
1388 | | ) |
1389 | | } |
1390 | 0 | StorageValue::HashKnownValueMissing(hash) => { |
1391 | 0 | write!(f, "hash(0x{})", hex::encode(hash)) |
1392 | | } |
1393 | 0 | StorageValue::None => write!(f, "<none>"), |
1394 | | } |
1395 | 0 | } Unexecuted instantiation: _RNvXs0_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeNtB5_12StorageValueNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt Unexecuted instantiation: _RNvXs0_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeNtB5_12StorageValueNtNtCsaYZPK01V26L_4core3fmt5Debug3fmt |
1396 | | } |
1397 | | |
1398 | | /// Possible error returned by [`decode_and_verify_proof`]. |
1399 | 0 | #[derive(Debug, Clone, derive_more::Display)] Unexecuted instantiation: _RNvXsl_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeNtB5_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt Unexecuted instantiation: _RNvXsl_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeNtB5_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt |
1400 | | pub enum Error { |
1401 | | /// Proof is in an invalid format. |
1402 | | InvalidFormat, |
1403 | | /// One of the entries of the proof is disconnected from the root node. |
1404 | | UnusedProofEntry, |
1405 | | /// The same entry has been found multiple times in the proof. |
1406 | | DuplicateProofEntry, |
1407 | | } |
1408 | | |
1409 | | pub struct EntryKeyIter<'a, T> { |
1410 | | proof: &'a DecodedTrieProof<T>, |
1411 | | target_entry: usize, |
1412 | | /// [`EntryKeyIter::entry_key_iterator`] is the `target_entry_depth_remaining` nth ancestor |
1413 | | /// of [`EntryKeyIter::target_entry`]. |
1414 | | target_entry_depth_remaining: usize, |
1415 | | /// `None` if iteration is finished. |
1416 | | entry_key_iterator: Option<trie_node::DecodedPartialKey<'a>>, |
1417 | | } |
1418 | | |
1419 | | impl<'a, T: AsRef<[u8]>> EntryKeyIter<'a, T> { |
1420 | 7.82k | fn new(proof: &'a DecodedTrieProof<T>, target_entry: usize) -> Self { |
1421 | 7.82k | // Find the number of nodes between `target_entry` and the trie root. |
1422 | 7.82k | let mut entry_iter = target_entry; |
1423 | 7.82k | let mut target_entry_depth_remaining = 0; |
1424 | | loop { |
1425 | 66.2k | if let Some((parent58.4k , _)) = proof.entries[entry_iter].parent_entry_index { |
1426 | 58.4k | target_entry_depth_remaining += 1; |
1427 | 58.4k | entry_iter = parent; |
1428 | 58.4k | } else { |
1429 | 7.82k | break; |
1430 | | } |
1431 | | } |
1432 | | |
1433 | 7.82k | let Ok(decoded_entry) = trie_node::decode( |
1434 | 7.82k | &proof.proof.as_ref()[proof.entries[entry_iter].range_in_proof.clone()], |
1435 | 7.82k | ) else { |
1436 | 0 | unreachable!() |
1437 | | }; |
1438 | | |
1439 | 7.82k | EntryKeyIter { |
1440 | 7.82k | proof, |
1441 | 7.82k | target_entry, |
1442 | 7.82k | target_entry_depth_remaining, |
1443 | 7.82k | entry_key_iterator: Some(decoded_entry.partial_key), |
1444 | 7.82k | } |
1445 | 7.82k | } Unexecuted instantiation: _RNvMs1_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtCsdZExvAaxgia_5alloc3vec3VechEE3newB9_ _RNvMs1_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShE3newB9_ Line | Count | Source | 1420 | 7.82k | fn new(proof: &'a DecodedTrieProof<T>, target_entry: usize) -> Self { | 1421 | 7.82k | // Find the number of nodes between `target_entry` and the trie root. | 1422 | 7.82k | let mut entry_iter = target_entry; | 1423 | 7.82k | let mut target_entry_depth_remaining = 0; | 1424 | | loop { | 1425 | 66.2k | if let Some((parent58.4k , _)) = proof.entries[entry_iter].parent_entry_index { | 1426 | 58.4k | target_entry_depth_remaining += 1; | 1427 | 58.4k | entry_iter = parent; | 1428 | 58.4k | } else { | 1429 | 7.82k | break; | 1430 | | } | 1431 | | } | 1432 | | | 1433 | 7.82k | let Ok(decoded_entry) = trie_node::decode( | 1434 | 7.82k | &proof.proof.as_ref()[proof.entries[entry_iter].range_in_proof.clone()], | 1435 | 7.82k | ) else { | 1436 | 0 | unreachable!() | 1437 | | }; | 1438 | | | 1439 | 7.82k | EntryKeyIter { | 1440 | 7.82k | proof, | 1441 | 7.82k | target_entry, | 1442 | 7.82k | target_entry_depth_remaining, | 1443 | 7.82k | entry_key_iterator: Some(decoded_entry.partial_key), | 1444 | 7.82k | } | 1445 | 7.82k | } |
Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE3newCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShE3newCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShE3newB9_ Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE3newCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShE3newCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE3newCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShE3newCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEE3newCsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShE3newCsibGXYHQB8Ea_25json_rpc_general_requests |
1446 | | } |
1447 | | |
1448 | | impl<'a, T: AsRef<[u8]>> Iterator for EntryKeyIter<'a, T> { |
1449 | | type Item = nibble::Nibble; |
1450 | | |
1451 | 156k | fn next(&mut self) -> Option<Self::Item> { |
1452 | | // `entry_key_iterator` is `None` only if the iteration is finished, as a way to fuse |
1453 | | // the iterator. |
1454 | 156k | let Some(entry_key_iterator) = &mut self.entry_key_iterator else { |
1455 | 0 | return None; |
1456 | | }; |
1457 | | |
1458 | | // Still yielding from `entry_key_iterator`. |
1459 | 156k | if let Some(nibble145k ) = entry_key_iterator.next() { |
1460 | 145k | return Some(nibble); |
1461 | 11.2k | } |
1462 | 11.2k | |
1463 | 11.2k | // `entry_key_iterator` has finished iterating. Update the local state for the next node |
1464 | 11.2k | // in the hierarchy. |
1465 | 11.2k | if self.target_entry_depth_remaining == 0 { |
1466 | | // Iteration finished. |
1467 | 1.25k | self.entry_key_iterator = None; |
1468 | 1.25k | return None; |
1469 | 9.95k | } |
1470 | 9.95k | self.target_entry_depth_remaining -= 1; |
1471 | 9.95k | |
1472 | 9.95k | // Find the `target_entry_depth_remaining`th ancestor of `target_entry`. |
1473 | 9.95k | let mut entry_iter = self.target_entry; |
1474 | 34.6k | for _ in 0..self.target_entry_depth_remaining { |
1475 | 34.6k | let Some((parent, _)) = self.proof.entries[entry_iter].parent_entry_index else { |
1476 | 0 | unreachable!() |
1477 | | }; |
1478 | 34.6k | entry_iter = parent; |
1479 | | } |
1480 | | |
1481 | | // Store the partial key of `entry_iter` in `entry_key_iterator`, so that it starts being |
1482 | | // yielded at the next iteration. |
1483 | 9.95k | self.entry_key_iterator = Some( |
1484 | 9.95k | trie_node::decode( |
1485 | 9.95k | &self.proof.proof.as_ref()[self.proof.entries[entry_iter].range_in_proof.clone()], |
1486 | 9.95k | ) |
1487 | 9.95k | .unwrap_or_else(|_| unreachable!()0 ) Unexecuted instantiation: _RNCNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtCsdZExvAaxgia_5alloc3vec3VechEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0Bb_ Unexecuted instantiation: _RNCNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0Bb_ Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0Bb_ Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4next0CsibGXYHQB8Ea_25json_rpc_general_requests |
1488 | 9.95k | .partial_key, |
1489 | 9.95k | ); |
1490 | 9.95k | |
1491 | 9.95k | // Yield the "parent-child nibble" of `entry_iter`. |
1492 | 9.95k | Some( |
1493 | 9.95k | self.proof.entries[entry_iter] |
1494 | 9.95k | .parent_entry_index |
1495 | 9.95k | .unwrap_or_else(|| unreachable!()0 ) Unexecuted instantiation: _RNCNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtCsdZExvAaxgia_5alloc3vec3VechEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0Bb_ Unexecuted instantiation: _RNCNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0Bb_ Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0Bb_ Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nexts_0CsibGXYHQB8Ea_25json_rpc_general_requests |
1496 | 9.95k | .1, |
1497 | 9.95k | ) |
1498 | 156k | } Unexecuted instantiation: _RNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtCsdZExvAaxgia_5alloc3vec3VechEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextB9_ _RNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextB9_ Line | Count | Source | 1451 | 156k | fn next(&mut self) -> Option<Self::Item> { | 1452 | | // `entry_key_iterator` is `None` only if the iteration is finished, as a way to fuse | 1453 | | // the iterator. | 1454 | 156k | let Some(entry_key_iterator) = &mut self.entry_key_iterator else { | 1455 | 0 | return None; | 1456 | | }; | 1457 | | | 1458 | | // Still yielding from `entry_key_iterator`. | 1459 | 156k | if let Some(nibble145k ) = entry_key_iterator.next() { | 1460 | 145k | return Some(nibble); | 1461 | 11.2k | } | 1462 | 11.2k | | 1463 | 11.2k | // `entry_key_iterator` has finished iterating. Update the local state for the next node | 1464 | 11.2k | // in the hierarchy. | 1465 | 11.2k | if self.target_entry_depth_remaining == 0 { | 1466 | | // Iteration finished. | 1467 | 1.25k | self.entry_key_iterator = None; | 1468 | 1.25k | return None; | 1469 | 9.95k | } | 1470 | 9.95k | self.target_entry_depth_remaining -= 1; | 1471 | 9.95k | | 1472 | 9.95k | // Find the `target_entry_depth_remaining`th ancestor of `target_entry`. | 1473 | 9.95k | let mut entry_iter = self.target_entry; | 1474 | 34.6k | for _ in 0..self.target_entry_depth_remaining { | 1475 | 34.6k | let Some((parent, _)) = self.proof.entries[entry_iter].parent_entry_index else { | 1476 | 0 | unreachable!() | 1477 | | }; | 1478 | 34.6k | entry_iter = parent; | 1479 | | } | 1480 | | | 1481 | | // Store the partial key of `entry_iter` in `entry_key_iterator`, so that it starts being | 1482 | | // yielded at the next iteration. | 1483 | 9.95k | self.entry_key_iterator = Some( | 1484 | 9.95k | trie_node::decode( | 1485 | 9.95k | &self.proof.proof.as_ref()[self.proof.entries[entry_iter].range_in_proof.clone()], | 1486 | 9.95k | ) | 1487 | 9.95k | .unwrap_or_else(|_| unreachable!()) | 1488 | 9.95k | .partial_key, | 1489 | 9.95k | ); | 1490 | 9.95k | | 1491 | 9.95k | // Yield the "parent-child nibble" of `entry_iter`. | 1492 | 9.95k | Some( | 1493 | 9.95k | self.proof.entries[entry_iter] | 1494 | 9.95k | .parent_entry_index | 1495 | 9.95k | .unwrap_or_else(|| unreachable!()) | 1496 | 9.95k | .1, | 1497 | 9.95k | ) | 1498 | 156k | } |
Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextB9_ Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextCscDgN54JpMGG_6author Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextCscDgN54JpMGG_6author Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextCsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator4nextCsibGXYHQB8Ea_25json_rpc_general_requests |
1499 | | |
1500 | 4.69k | fn size_hint(&self) -> (usize, Option<usize>) { |
1501 | 4.69k | // We know we're going to yield `self.target_entry_depth_remaining` "parent-child nibbles". |
1502 | 4.69k | // We add to that the size hint of `entry_key_iterator`. |
1503 | 4.69k | let entry_key_iterator = self |
1504 | 4.69k | .entry_key_iterator |
1505 | 4.69k | .as_ref() |
1506 | 4.69k | .map_or(0, |i| i.size_hint().0); Unexecuted instantiation: _RNCNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtCsdZExvAaxgia_5alloc3vec3VechEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0Bb_ _RNCNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0Bb_ Line | Count | Source | 1506 | 4.69k | .map_or(0, |i| i.size_hint().0); |
Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0CsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0Bb_ Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0CsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0CscDgN54JpMGG_6author Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0CsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNCNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB7_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hint0CsibGXYHQB8Ea_25json_rpc_general_requests |
1507 | 4.69k | (entry_key_iterator + self.target_entry_depth_remaining, None) |
1508 | 4.69k | } Unexecuted instantiation: _RNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtCsdZExvAaxgia_5alloc3vec3VechEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintB9_ _RNvXs2_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintB9_ Line | Count | Source | 1500 | 4.69k | fn size_hint(&self) -> (usize, Option<usize>) { | 1501 | 4.69k | // We know we're going to yield `self.target_entry_depth_remaining` "parent-child nibbles". | 1502 | 4.69k | // We add to that the size hint of `entry_key_iterator`. | 1503 | 4.69k | let entry_key_iterator = self | 1504 | 4.69k | .entry_key_iterator | 1505 | 4.69k | .as_ref() | 1506 | 4.69k | .map_or(0, |i| i.size_hint().0); | 1507 | 4.69k | (entry_key_iterator + self.target_entry_depth_remaining, None) | 1508 | 4.69k | } |
Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintB9_ Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintCscDgN54JpMGG_6author Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintCscDgN54JpMGG_6author Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhEENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintCsibGXYHQB8Ea_25json_rpc_general_requests Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtNtNtCsaYZPK01V26L_4core4iter6traits8iterator8Iterator9size_hintCsibGXYHQB8Ea_25json_rpc_general_requests |
1509 | | } |
1510 | | |
1511 | | impl<'a, T: AsRef<[u8]>> iter::FusedIterator for EntryKeyIter<'a, T> {} |
1512 | | |
1513 | | // We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements. |
1514 | | impl<'a, T> Clone for EntryKeyIter<'a, T> { |
1515 | 1.25k | fn clone(&self) -> Self { |
1516 | 1.25k | EntryKeyIter { |
1517 | 1.25k | proof: self.proof, |
1518 | 1.25k | target_entry: self.target_entry, |
1519 | 1.25k | target_entry_depth_remaining: self.target_entry_depth_remaining, |
1520 | 1.25k | entry_key_iterator: self.entry_key_iterator.clone(), |
1521 | 1.25k | } |
1522 | 1.25k | } _RNvXs4_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ Line | Count | Source | 1515 | 1.25k | fn clone(&self) -> Self { | 1516 | 1.25k | EntryKeyIter { | 1517 | 1.25k | proof: self.proof, | 1518 | 1.25k | target_entry: self.target_entry, | 1519 | 1.25k | target_entry_depth_remaining: self.target_entry_depth_remaining, | 1520 | 1.25k | entry_key_iterator: self.entry_key_iterator.clone(), | 1521 | 1.25k | } | 1522 | 1.25k | } |
Unexecuted instantiation: _RNvXs4_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvXs4_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ Unexecuted instantiation: _RNvXs4_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvXs4_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneCscDgN54JpMGG_6author Unexecuted instantiation: _RNvXs4_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_12EntryKeyIterRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneCsibGXYHQB8Ea_25json_rpc_general_requests |
1523 | | } |
1524 | | |
1525 | | impl<'a, T: AsRef<[u8]>> fmt::Debug for EntryKeyIter<'a, T> { |
1526 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1527 | 0 | let mut any_printed = false; |
1528 | 0 | for nibble in self.clone() { |
1529 | 0 | any_printed = true; |
1530 | 0 | write!(f, "{:x}", nibble)?; |
1531 | | } |
1532 | 0 | if !any_printed { |
1533 | 0 | write!(f, "∅")?; |
1534 | 0 | } |
1535 | 0 | Ok(()) |
1536 | 0 | } Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodes5_0pEINtB5_12EntryKeyIterpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtB9_ Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4trie12proof_decodes5_0pEINtB5_12EntryKeyIterpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtB9_ |
1537 | | } |
1538 | | |
1539 | | /// Information about an entry in the proof. |
1540 | | #[derive(Debug)] |
1541 | | pub struct ProofEntry<'a, T> { |
1542 | | /// Information about the node of the trie associated to this entry. |
1543 | | pub trie_node_info: TrieNodeInfo<'a, T>, |
1544 | | |
1545 | | /// Merkle value of that proof entry. |
1546 | | /// |
1547 | | /// > **Note**: This is a low-level information. If you're not familiar with how the trie |
1548 | | /// > works, you most likely don't need this. |
1549 | | pub merkle_value: &'a [u8], |
1550 | | |
1551 | | /// Node value of that proof entry. |
1552 | | /// |
1553 | | /// > **Note**: This is a low-level information. If you're not familiar with how the trie |
1554 | | /// > works, you most likely don't need this. |
1555 | | pub node_value: &'a [u8], |
1556 | | |
1557 | | /// Partial key of that proof entry. |
1558 | | /// |
1559 | | /// > **Note**: This is a low-level information. If you're not familiar with how the trie |
1560 | | /// > works, you most likely don't need this. |
1561 | | pub partial_key_nibbles: trie_node::DecodedPartialKey<'a>, |
1562 | | |
1563 | | /// If [`ProofEntry::node_value`] indicates that the storage value is hashed, then this field |
1564 | | /// contains the unhashed storage value that is found in the proof, if any. |
1565 | | /// |
1566 | | /// If this field contains `Some`, then [`TrieNodeInfo::storage_value`] is guaranteed to |
1567 | | /// contain [`StorageValue::Known`]. However the opposite is not necessarily true. |
1568 | | /// |
1569 | | /// > **Note**: This is a low-level information. If you're not familiar with how the trie |
1570 | | /// > works, you most likely don't need this. |
1571 | | pub unhashed_storage_value: Option<&'a [u8]>, |
1572 | | } |
1573 | | |
1574 | | // We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements. |
1575 | | impl<'a, T> Clone for ProofEntry<'a, T> { |
1576 | 0 | fn clone(&self) -> Self { |
1577 | 0 | ProofEntry { |
1578 | 0 | trie_node_info: self.trie_node_info.clone(), |
1579 | 0 | merkle_value: self.merkle_value, |
1580 | 0 | node_value: self.node_value, |
1581 | 0 | partial_key_nibbles: self.partial_key_nibbles.clone(), |
1582 | 0 | unhashed_storage_value: self.unhashed_storage_value, |
1583 | 0 | } |
1584 | 0 | } Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodes6_0pEINtB5_10ProofEntrypENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4trie12proof_decodes6_0pEINtB5_10ProofEntrypENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ |
1585 | | } |
1586 | | |
1587 | | /// Information about a node of the trie. |
1588 | | /// |
1589 | | /// > **Note**: This structure might represent a node that doesn't actually exist in the trie. |
1590 | | #[derive(Debug)] |
1591 | | pub struct TrieNodeInfo<'a, T> { |
1592 | | /// Storage value of the node, if any. |
1593 | | pub storage_value: StorageValue<'a>, |
1594 | | /// Which children the node has. |
1595 | | pub children: Children<'a, T>, |
1596 | | } |
1597 | | |
1598 | | // We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements. |
1599 | | impl<'a, T> Clone for TrieNodeInfo<'a, T> { |
1600 | 0 | fn clone(&self) -> Self { |
1601 | 0 | TrieNodeInfo { |
1602 | 0 | storage_value: self.storage_value, |
1603 | 0 | children: self.children.clone(), |
1604 | 0 | } |
1605 | 0 | } Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodes7_0pEINtB5_12TrieNodeInfopENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4trie12proof_decodes7_0pEINtB5_12TrieNodeInfopENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ |
1606 | | } |
1607 | | |
1608 | | /// See [`TrieNodeInfo::children`]. |
1609 | | pub struct Children<'a, T> { |
1610 | | children: [Child<'a, T>; 16], |
1611 | | } |
1612 | | |
1613 | | /// Information about a specific child in the list of children. |
1614 | | pub enum Child<'a, T> { |
1615 | | /// Child exists and can be found in the proof. |
1616 | | InProof { |
1617 | | /// Key of the child. Always starts with the key of its parent. |
1618 | | child_key: EntryKeyIter<'a, T>, |
1619 | | /// Merkle value of the child. |
1620 | | merkle_value: &'a [u8], |
1621 | | }, |
1622 | | /// Child exists but isn't present in the proof. |
1623 | | AbsentFromProof { |
1624 | | /// Merkle value of the child. |
1625 | | merkle_value: &'a [u8], |
1626 | | }, |
1627 | | /// Child doesn't exist. |
1628 | | NoChild, |
1629 | | } |
1630 | | |
1631 | | impl<'a, T> Child<'a, T> { |
1632 | | /// Returns the Merkle value of this child. `None` if the child doesn't exist. |
1633 | 0 | pub fn merkle_value(&self) -> Option<&'a [u8]> { |
1634 | 0 | match self { |
1635 | 0 | Child::InProof { merkle_value, .. } => Some(merkle_value), |
1636 | 0 | Child::AbsentFromProof { merkle_value } => Some(merkle_value), |
1637 | 0 | Child::NoChild => None, |
1638 | | } |
1639 | 0 | } Unexecuted instantiation: _RNvMs8_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_5ChildpE12merkle_valueB9_ Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShE12merkle_valueCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildpE12merkle_valueB9_ Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShE12merkle_valueCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShE12merkle_valueCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShE12merkle_valueCsibGXYHQB8Ea_25json_rpc_general_requests |
1640 | | } |
1641 | | |
1642 | | // We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements. |
1643 | | impl<'a, T> Clone for Child<'a, T> { |
1644 | 22.5k | fn clone(&self) -> Self { |
1645 | 22.5k | match self { |
1646 | 2.45k | Child::AbsentFromProof { merkle_value } => Child::AbsentFromProof { merkle_value }, |
1647 | | Child::InProof { |
1648 | 1.25k | child_key, |
1649 | 1.25k | merkle_value, |
1650 | 1.25k | } => Child::InProof { |
1651 | 1.25k | child_key: child_key.clone(), |
1652 | 1.25k | merkle_value, |
1653 | 1.25k | }, |
1654 | 18.8k | Child::NoChild => Child::NoChild, |
1655 | | } |
1656 | 22.5k | } _RNvXs9_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_5ChildRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ Line | Count | Source | 1644 | 22.5k | fn clone(&self) -> Self { | 1645 | 22.5k | match self { | 1646 | 2.45k | Child::AbsentFromProof { merkle_value } => Child::AbsentFromProof { merkle_value }, | 1647 | | Child::InProof { | 1648 | 1.25k | child_key, | 1649 | 1.25k | merkle_value, | 1650 | 1.25k | } => Child::InProof { | 1651 | 1.25k | child_key: child_key.clone(), | 1652 | 1.25k | merkle_value, | 1653 | 1.25k | }, | 1654 | 18.8k | Child::NoChild => Child::NoChild, | 1655 | | } | 1656 | 22.5k | } |
Unexecuted instantiation: _RNvXs9_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvXs9_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ Unexecuted instantiation: _RNvXs9_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvXs9_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneCscDgN54JpMGG_6author Unexecuted instantiation: _RNvXs9_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_5ChildRShENtNtCsaYZPK01V26L_4core5clone5Clone5cloneCsibGXYHQB8Ea_25json_rpc_general_requests |
1657 | | } |
1658 | | |
1659 | | impl<'a, T> Children<'a, T> { |
1660 | | /// Returns `true` if a child in the direction of the given nibble is present. |
1661 | 0 | pub fn has_child(&self, nibble: nibble::Nibble) -> bool { |
1662 | 0 | match self.children[usize::from(u8::from(nibble))] { |
1663 | 0 | Child::InProof { .. } | Child::AbsentFromProof { .. } => true, |
1664 | 0 | Child::NoChild => false, |
1665 | | } |
1666 | 0 | } Unexecuted instantiation: _RNvMsa_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_8ChildrenpE9has_childB9_ Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_8ChildrenpE9has_childB9_ |
1667 | | |
1668 | | /// Returns the information about the child in the given direction. |
1669 | 2.45k | pub fn child(&self, direction: nibble::Nibble) -> Child<'a, T> { |
1670 | 2.45k | self.children[usize::from(u8::from(direction))].clone() |
1671 | 2.45k | } _RNvMsa_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_8ChildrenRShE5childB9_ Line | Count | Source | 1669 | 2.45k | pub fn child(&self, direction: nibble::Nibble) -> Child<'a, T> { | 1670 | 2.45k | self.children[usize::from(u8::from(direction))].clone() | 1671 | 2.45k | } |
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_8ChildrenRShE5childCsDDUKWWCHAU_18smoldot_light_wasm Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_8ChildrenRShE5childB9_ Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_8ChildrenRShE5childCsiLzmwikkc22_14json_rpc_basic Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_8ChildrenRShE5childCscDgN54JpMGG_6author Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_8ChildrenRShE5childCsibGXYHQB8Ea_25json_rpc_general_requests |
1672 | | |
1673 | | /// Returns an iterator of 16 items, one for each child. |
1674 | 1.25k | pub fn children( |
1675 | 1.25k | &'_ self, |
1676 | 1.25k | ) -> impl DoubleEndedIterator + ExactSizeIterator<Item = Child<'a, T>> + '_ { |
1677 | 1.25k | self.children.iter().cloned() |
1678 | 1.25k | } _RNvMsa_NtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodeINtB5_8ChildrenRShE8childrenB9_ Line | Count | Source | 1674 | 1.25k | pub fn children( | 1675 | 1.25k | &'_ self, | 1676 | 1.25k | ) -> impl DoubleEndedIterator + ExactSizeIterator<Item = Child<'a, T>> + '_ { | 1677 | 1.25k | self.children.iter().cloned() | 1678 | 1.25k | } |
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4trie12proof_decodeINtB5_8ChildrenRShE8childrenB9_ |
1679 | | } |
1680 | | |
1681 | | // We need to implement `Clone` manually, otherwise Rust adds an implicit `T: Clone` requirements. |
1682 | | impl<'a, T> Clone for Children<'a, T> { |
1683 | 0 | fn clone(&self) -> Self { |
1684 | 0 | Children { |
1685 | 0 | children: self.children.clone(), |
1686 | 0 | } |
1687 | 0 | } Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodesb_0pEINtB5_8ChildrenpENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4trie12proof_decodesb_0pEINtB5_8ChildrenpENtNtCsaYZPK01V26L_4core5clone5Clone5cloneB9_ |
1688 | | } |
1689 | | |
1690 | | impl<'a, T> fmt::Debug for Children<'a, T> { |
1691 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1692 | 0 | fmt::Binary::fmt(&self, f) |
1693 | 0 | } Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodesc_0pEINtB5_8ChildrenpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtB9_ Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4trie12proof_decodesc_0pEINtB5_8ChildrenpENtNtCsaYZPK01V26L_4core3fmt5Debug3fmtB9_ |
1694 | | } |
1695 | | |
1696 | | impl<'a, T> fmt::Binary for Children<'a, T> { |
1697 | 0 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1698 | 0 | for child in &self.children { |
1699 | 0 | let chr = match child { |
1700 | 0 | Child::InProof { .. } | Child::AbsentFromProof { .. } => '1', |
1701 | 0 | Child::NoChild => '0', |
1702 | | }; |
1703 | | |
1704 | 0 | fmt::Write::write_char(f, chr)? |
1705 | | } |
1706 | | |
1707 | 0 | Ok(()) |
1708 | 0 | } Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4trie12proof_decodesd_0pEINtB5_8ChildrenpENtNtCsaYZPK01V26L_4core3fmt6Binary3fmtB9_ Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4trie12proof_decodesd_0pEINtB5_8ChildrenpENtNtCsaYZPK01V26L_4core3fmt6Binary3fmtB9_ |
1709 | | } |
1710 | | |
1711 | | #[cfg(test)] |
1712 | | mod tests { |
1713 | | use core::iter; |
1714 | | use trie::Nibble; |
1715 | | |
1716 | | use crate::trie; |
1717 | | |
1718 | | // Key/value taken from the Polkadot genesis block. |
1719 | | const EXAMPLE_PROOF: &[u8] = &[ |
1720 | | 24, 212, 125, 1, 84, 37, 150, 173, 176, 93, 97, 64, 193, 112, 172, 71, 158, 223, 124, 253, |
1721 | | 90, 163, 83, 87, 89, 10, 207, 229, 209, 26, 128, 77, 148, 78, 80, 13, 20, 86, 253, 218, |
1722 | | 123, 142, 199, 249, 229, 199, 148, 205, 131, 25, 79, 5, 147, 228, 234, 53, 5, 128, 63, 147, |
1723 | | 128, 78, 76, 108, 66, 34, 183, 71, 229, 7, 0, 142, 241, 222, 240, 99, 187, 13, 45, 238, |
1724 | | 173, 241, 126, 244, 177, 14, 113, 98, 77, 58, 12, 248, 28, 128, 36, 31, 44, 6, 242, 46, |
1725 | | 197, 137, 104, 251, 104, 212, 50, 49, 158, 37, 230, 200, 250, 163, 173, 44, 92, 169, 238, |
1726 | | 72, 242, 232, 237, 21, 142, 36, 128, 173, 138, 104, 35, 73, 50, 38, 152, 70, 188, 64, 36, |
1727 | | 10, 71, 207, 216, 216, 133, 123, 29, 129, 225, 103, 191, 178, 76, 148, 122, 76, 218, 217, |
1728 | | 230, 128, 200, 69, 144, 227, 159, 139, 121, 162, 105, 74, 210, 191, 126, 114, 88, 175, 104, |
1729 | | 107, 71, 47, 56, 176, 100, 187, 206, 125, 8, 64, 73, 49, 164, 48, 128, 92, 114, 242, 91, |
1730 | | 27, 99, 4, 209, 102, 103, 226, 118, 111, 161, 169, 6, 203, 8, 23, 136, 235, 69, 2, 120, |
1731 | | 125, 247, 195, 89, 116, 18, 177, 123, 128, 110, 33, 197, 241, 162, 74, 25, 102, 21, 180, |
1732 | | 229, 179, 109, 33, 40, 12, 220, 200, 0, 152, 193, 226, 188, 232, 238, 175, 48, 30, 153, 81, |
1733 | | 118, 116, 128, 66, 79, 26, 205, 128, 186, 7, 74, 44, 232, 209, 128, 191, 52, 136, 165, 202, |
1734 | | 145, 203, 129, 251, 169, 108, 140, 60, 29, 51, 234, 203, 177, 129, 96, 128, 94, 132, 157, |
1735 | | 92, 20, 140, 163, 97, 165, 90, 44, 155, 56, 78, 23, 206, 145, 158, 147, 108, 203, 128, 17, |
1736 | | 164, 247, 37, 4, 233, 249, 61, 184, 205, 128, 237, 208, 5, 161, 73, 92, 112, 37, 13, 119, |
1737 | | 248, 28, 36, 193, 90, 153, 25, 240, 52, 247, 152, 61, 248, 229, 5, 229, 58, 90, 247, 180, |
1738 | | 2, 19, 128, 18, 160, 221, 144, 73, 123, 101, 49, 43, 218, 103, 234, 21, 153, 101, 120, 238, |
1739 | | 179, 137, 27, 202, 134, 102, 149, 26, 50, 102, 18, 65, 142, 49, 67, 177, 4, 128, 85, 93, |
1740 | | 128, 67, 251, 73, 124, 27, 42, 123, 158, 79, 235, 89, 244, 16, 193, 162, 158, 40, 178, 166, |
1741 | | 40, 255, 156, 96, 3, 224, 128, 246, 185, 250, 221, 149, 249, 128, 110, 141, 145, 27, 104, |
1742 | | 24, 3, 142, 183, 200, 83, 74, 248, 231, 142, 153, 32, 161, 171, 141, 147, 156, 54, 211, |
1743 | | 230, 155, 10, 30, 89, 40, 17, 11, 128, 186, 77, 63, 84, 57, 87, 244, 34, 180, 12, 142, 116, |
1744 | | 175, 157, 224, 10, 203, 235, 168, 21, 74, 252, 165, 122, 127, 128, 251, 188, 254, 187, 30, |
1745 | | 74, 128, 61, 27, 143, 92, 241, 120, 139, 41, 69, 55, 184, 253, 45, 52, 172, 236, 70, 70, |
1746 | | 167, 98, 124, 108, 211, 210, 3, 154, 246, 79, 245, 209, 151, 109, 128, 231, 98, 15, 33, |
1747 | | 207, 19, 150, 79, 41, 211, 75, 167, 8, 195, 180, 78, 164, 94, 161, 28, 88, 251, 190, 221, |
1748 | | 162, 157, 19, 71, 11, 200, 12, 160, 128, 249, 138, 174, 79, 131, 216, 27, 241, 93, 136, 1, |
1749 | | 158, 92, 48, 61, 124, 25, 208, 82, 78, 132, 199, 20, 224, 95, 97, 81, 124, 222, 11, 19, |
1750 | | 130, 128, 213, 24, 250, 245, 102, 253, 196, 208, 69, 9, 74, 190, 55, 43, 179, 187, 236, |
1751 | | 212, 117, 63, 118, 219, 140, 65, 186, 159, 192, 21, 85, 139, 242, 58, 128, 144, 143, 153, |
1752 | | 17, 38, 209, 44, 231, 172, 213, 85, 8, 255, 30, 125, 255, 165, 111, 116, 36, 1, 225, 129, |
1753 | | 79, 193, 70, 150, 88, 167, 140, 122, 127, 128, 1, 176, 160, 141, 160, 200, 50, 83, 213, |
1754 | | 192, 203, 135, 114, 134, 192, 98, 218, 47, 83, 10, 228, 36, 254, 37, 69, 55, 121, 65, 253, |
1755 | | 1, 105, 19, 53, 5, 128, 179, 167, 128, 162, 159, 172, 127, 125, 250, 226, 29, 5, 217, 80, |
1756 | | 110, 125, 166, 81, 91, 127, 161, 173, 151, 15, 248, 118, 222, 53, 241, 190, 194, 89, 158, |
1757 | | 192, 2, 128, 91, 103, 114, 220, 106, 78, 118, 4, 200, 208, 101, 36, 121, 249, 91, 52, 54, |
1758 | | 7, 194, 217, 19, 140, 89, 238, 183, 153, 216, 91, 244, 59, 107, 191, 128, 61, 18, 190, 203, |
1759 | | 106, 75, 153, 25, 221, 199, 197, 151, 61, 4, 238, 215, 105, 108, 131, 79, 144, 199, 121, |
1760 | | 252, 31, 207, 115, 80, 204, 194, 141, 107, 128, 95, 51, 235, 207, 25, 31, 221, 207, 59, 63, |
1761 | | 52, 110, 195, 54, 193, 5, 199, 75, 64, 164, 211, 93, 253, 160, 197, 146, 242, 190, 160, 0, |
1762 | | 132, 233, 128, 247, 100, 199, 51, 214, 227, 87, 113, 169, 178, 106, 31, 168, 107, 155, 236, |
1763 | | 89, 116, 43, 4, 111, 105, 139, 230, 193, 64, 175, 16, 115, 137, 125, 61, 128, 205, 59, 200, |
1764 | | 195, 206, 60, 248, 53, 159, 115, 113, 161, 51, 22, 240, 47, 210, 43, 2, 163, 211, 39, 104, |
1765 | | 74, 43, 97, 244, 164, 126, 0, 34, 184, 128, 218, 117, 42, 250, 235, 146, 93, 83, 0, 228, |
1766 | | 91, 133, 16, 82, 197, 248, 169, 197, 170, 232, 132, 241, 93, 100, 118, 78, 223, 150, 27, |
1767 | | 139, 34, 200, 128, 191, 31, 169, 199, 228, 201, 67, 64, 219, 175, 215, 92, 190, 1, 108, |
1768 | | 152, 13, 14, 93, 91, 78, 118, 130, 63, 161, 30, 97, 98, 144, 20, 195, 75, 128, 79, 84, 161, |
1769 | | 94, 93, 81, 208, 43, 132, 232, 202, 233, 76, 152, 51, 174, 129, 229, 107, 143, 11, 104, 77, |
1770 | | 37, 127, 111, 114, 46, 230, 108, 173, 249, 128, 148, 131, 63, 178, 220, 232, 199, 141, 68, |
1771 | | 60, 214, 120, 110, 12, 1, 216, 151, 74, 75, 119, 156, 23, 142, 245, 230, 107, 73, 224, 33, |
1772 | | 221, 127, 26, 225, 2, 159, 12, 93, 121, 93, 2, 151, 190, 86, 2, 122, 75, 36, 100, 227, 51, |
1773 | | 151, 96, 146, 128, 243, 50, 255, 85, 106, 191, 93, 175, 13, 52, 82, 61, 247, 200, 205, 19, |
1774 | | 105, 188, 182, 173, 187, 35, 164, 128, 147, 191, 7, 10, 151, 17, 191, 52, 128, 56, 41, 52, |
1775 | | 19, 74, 169, 25, 181, 156, 22, 255, 141, 232, 217, 122, 127, 220, 194, 68, 142, 163, 39, |
1776 | | 178, 111, 68, 0, 93, 117, 109, 23, 133, 135, 128, 129, 214, 52, 20, 11, 54, 206, 3, 28, 75, |
1777 | | 108, 98, 102, 226, 167, 193, 157, 154, 136, 227, 143, 221, 138, 210, 58, 189, 61, 178, 14, |
1778 | | 113, 79, 105, 128, 253, 225, 112, 65, 242, 47, 9, 96, 157, 121, 219, 227, 141, 204, 206, |
1779 | | 252, 170, 193, 57, 199, 161, 15, 178, 59, 210, 132, 193, 196, 146, 176, 4, 253, 128, 210, |
1780 | | 135, 173, 29, 10, 222, 101, 230, 77, 57, 105, 244, 171, 133, 163, 112, 118, 129, 96, 49, |
1781 | | 67, 140, 234, 11, 248, 195, 59, 123, 43, 198, 195, 48, 141, 8, 159, 3, 230, 211, 193, 251, |
1782 | | 21, 128, 94, 223, 208, 36, 23, 46, 164, 129, 125, 255, 255, 128, 21, 40, 51, 227, 74, 133, |
1783 | | 46, 151, 81, 207, 192, 249, 84, 174, 184, 53, 225, 248, 67, 147, 107, 169, 151, 152, 83, |
1784 | | 164, 14, 67, 153, 55, 37, 95, 128, 106, 54, 224, 173, 35, 251, 50, 36, 255, 246, 230, 219, |
1785 | | 98, 4, 132, 99, 167, 242, 124, 203, 146, 246, 91, 78, 52, 138, 205, 90, 122, 163, 160, 104, |
1786 | | 128, 39, 182, 224, 153, 193, 21, 129, 251, 46, 138, 207, 59, 107, 148, 234, 237, 68, 34, |
1787 | | 119, 185, 167, 76, 231, 249, 34, 246, 227, 191, 41, 89, 134, 123, 128, 253, 12, 194, 200, |
1788 | | 70, 219, 106, 158, 209, 154, 113, 93, 108, 60, 212, 106, 72, 183, 244, 9, 136, 60, 112, |
1789 | | 178, 212, 201, 120, 179, 6, 222, 55, 158, 128, 171, 0, 138, 120, 195, 64, 245, 204, 117, |
1790 | | 217, 156, 219, 144, 89, 81, 147, 102, 134, 68, 92, 131, 71, 25, 190, 33, 247, 98, 11, 149, |
1791 | | 13, 205, 92, 128, 109, 134, 175, 84, 213, 223, 177, 192, 111, 63, 239, 221, 90, 67, 8, 97, |
1792 | | 192, 209, 158, 37, 250, 212, 186, 208, 124, 110, 112, 212, 166, 121, 240, 184, 128, 243, |
1793 | | 94, 220, 84, 0, 182, 102, 31, 177, 230, 251, 167, 197, 153, 200, 186, 137, 20, 88, 209, 68, |
1794 | | 0, 3, 15, 165, 6, 153, 154, 25, 114, 54, 159, 128, 116, 108, 218, 160, 183, 218, 46, 156, |
1795 | | 56, 100, 151, 31, 80, 241, 45, 155, 66, 129, 248, 4, 213, 162, 219, 166, 235, 224, 105, 89, |
1796 | | 178, 169, 251, 71, 128, 46, 207, 222, 17, 69, 100, 35, 200, 127, 237, 128, 104, 244, 20, |
1797 | | 165, 186, 68, 235, 227, 174, 145, 176, 109, 20, 204, 35, 26, 120, 212, 171, 166, 142, 128, |
1798 | | 246, 85, 41, 24, 51, 164, 156, 242, 61, 5, 123, 177, 92, 66, 211, 119, 197, 93, 80, 245, |
1799 | | 136, 83, 41, 6, 11, 10, 170, 178, 34, 131, 203, 177, 128, 140, 149, 251, 43, 98, 186, 243, |
1800 | | 7, 24, 184, 51, 14, 246, 138, 82, 124, 151, 193, 188, 153, 96, 48, 67, 83, 34, 77, 138, |
1801 | | 138, 232, 138, 121, 213, 128, 69, 193, 182, 217, 144, 74, 225, 113, 213, 115, 189, 206, |
1802 | | 186, 160, 81, 66, 216, 22, 72, 189, 190, 177, 108, 238, 221, 197, 74, 14, 209, 93, 62, 43, |
1803 | | 128, 168, 234, 25, 50, 130, 254, 133, 182, 72, 23, 7, 9, 28, 119, 201, 33, 142, 161, 157, |
1804 | | 233, 20, 231, 89, 80, 146, 95, 232, 100, 0, 251, 12, 176, 128, 194, 34, 206, 171, 83, 85, |
1805 | | 234, 164, 29, 168, 7, 20, 111, 46, 45, 247, 255, 100, 140, 62, 139, 187, 109, 142, 226, 50, |
1806 | | 116, 186, 114, 69, 81, 177, 128, 8, 241, 66, 220, 60, 89, 191, 17, 81, 200, 41, 236, 239, |
1807 | | 234, 53, 145, 158, 128, 69, 61, 181, 233, 102, 159, 90, 115, 137, 154, 170, 81, 102, 238, |
1808 | | 128, 79, 29, 33, 251, 220, 1, 128, 196, 222, 136, 107, 244, 15, 145, 223, 194, 32, 43, 62, |
1809 | | 182, 212, 37, 72, 212, 118, 144, 128, 65, 221, 97, 123, 184, |
1810 | | ]; |
1811 | | |
1812 | | const EXAMPLE_PROOF_STATE_ROOT: &[u8; 32] = &[ |
1813 | | 41, 208, 217, 114, 205, 39, 203, 197, 17, 233, 88, 159, 203, 122, 69, 6, 213, 235, 106, |
1814 | | 158, 141, 242, 5, 240, 4, 114, 229, 171, 53, 74, 78, 23, |
1815 | | ]; |
1816 | | |
1817 | | #[test] |
1818 | 1 | fn empty_is_valid() { |
1819 | 1 | let _ = super::decode_and_verify_proof(super::Config { proof: &[0] }).unwrap(); |
1820 | 1 | } |
1821 | | |
1822 | | #[test] |
1823 | 1 | fn storage_value_works() { |
1824 | 1 | let decoded = super::decode_and_verify_proof(super::Config { |
1825 | 1 | proof: EXAMPLE_PROOF, |
1826 | 1 | }) |
1827 | 1 | .unwrap(); |
1828 | 1 | |
1829 | 1 | assert_eq!( |
1830 | 1 | decoded |
1831 | 1 | .storage_value(EXAMPLE_PROOF_STATE_ROOT, &hex::decode("9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7081542596adb05d6140c170ac479edf7cfd5aa35357590acfe5d11a804d944e").unwrap()) |
1832 | 1 | .unwrap().unwrap().0, |
1833 | 1 | &hex::decode("0d1456fdda7b8ec7f9e5c794cd83194f0593e4ea").unwrap()[..] |
1834 | 1 | ); |
1835 | | |
1836 | 1 | assert!( |
1837 | 1 | decoded |
1838 | 1 | .storage_value(EXAMPLE_PROOF_STATE_ROOT, &hex::decode("9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7081542596adb05d6140c170ac479edf7cfd5aa35357590acfe5d11a804d944e25").unwrap()) |
1839 | 1 | .unwrap().is_none() |
1840 | 1 | ); |
1841 | | |
1842 | 1 | assert!(matches!0 ( |
1843 | 1 | decoded.storage_value( |
1844 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
1845 | 1 | &hex::decode( |
1846 | 1 | "9c5d795d0297be56027a4b2464e3339763e6d3c1fb15805edfd024172ea4817d7000" |
1847 | 1 | ) |
1848 | 1 | .unwrap() |
1849 | 1 | ), |
1850 | | Err(super::IncompleteProofError()) |
1851 | | )); |
1852 | | |
1853 | 1 | assert!(matches!0 ( |
1854 | 1 | decoded.storage_value(&[0; 32], &[]), |
1855 | | Err(super::IncompleteProofError()) |
1856 | | )); |
1857 | 1 | } |
1858 | | |
1859 | | #[test] |
1860 | 1 | fn next_key_works() { |
1861 | 1 | let decoded = super::decode_and_verify_proof(super::Config { |
1862 | 1 | proof: EXAMPLE_PROOF, |
1863 | 1 | }) |
1864 | 1 | .unwrap(); |
1865 | 1 | |
1866 | 1 | assert_eq!( |
1867 | 1 | decoded |
1868 | 1 | .next_key( |
1869 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
1870 | 1 | iter::empty(), |
1871 | 1 | true, |
1872 | 1 | iter::empty(), |
1873 | 1 | true |
1874 | 1 | ) |
1875 | 1 | .unwrap() |
1876 | 1 | .unwrap() |
1877 | 1 | .collect::<Vec<_>>(), |
1878 | 1 | &[] |
1879 | 1 | ); |
1880 | | |
1881 | 1 | assert_eq!( |
1882 | 1 | decoded |
1883 | 1 | .next_key( |
1884 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
1885 | 1 | [ |
1886 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, |
1887 | 1 | 0xb, 2, 4, 6, 4, 0xe, 3, 3, 3, 9, 7 |
1888 | 1 | ] |
1889 | 1 | .into_iter() |
1890 | 32 | .map(|n| Nibble::try_from(n).unwrap()), |
1891 | 1 | true, |
1892 | 1 | iter::empty(), |
1893 | 1 | true |
1894 | 1 | ) |
1895 | 1 | .unwrap() |
1896 | 1 | .unwrap() |
1897 | 1 | .collect::<Vec<_>>(), |
1898 | 1 | [ |
1899 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, 0xb, 2, |
1900 | 1 | 4, 6, 4, 0xe, 3, 3, 3, 9, 7 |
1901 | 1 | ] |
1902 | 1 | .into_iter() |
1903 | 32 | .map(|n| Nibble::try_from(n).unwrap()) |
1904 | 1 | .collect::<Vec<_>>() |
1905 | 1 | ); |
1906 | | |
1907 | 1 | assert_eq!( |
1908 | 1 | decoded |
1909 | 1 | .next_key( |
1910 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
1911 | 1 | [ |
1912 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, |
1913 | 1 | 0xb, 2, 4, 6, 4, 0xe, 3, 3, 3, 9 |
1914 | 1 | ] |
1915 | 1 | .into_iter() |
1916 | 31 | .map(|n| Nibble::try_from(n).unwrap()), |
1917 | 1 | false, |
1918 | 1 | iter::empty(), |
1919 | 1 | true |
1920 | 1 | ) |
1921 | 1 | .unwrap() |
1922 | 1 | .unwrap() |
1923 | 1 | .collect::<Vec<_>>(), |
1924 | 1 | [ |
1925 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, 0xb, 2, |
1926 | 1 | 4, 6, 4, 0xe, 3, 3, 3, 9, 7 |
1927 | 1 | ] |
1928 | 1 | .into_iter() |
1929 | 32 | .map(|n| Nibble::try_from(n).unwrap()) |
1930 | 1 | .collect::<Vec<_>>() |
1931 | 1 | ); |
1932 | | |
1933 | 1 | assert!(matches!0 ( |
1934 | 1 | decoded.next_key( |
1935 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
1936 | 1 | [ |
1937 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, 0xb, |
1938 | 1 | 2, 4, 6, 4, 0xe, 3, 3, 3, 9 |
1939 | 1 | ] |
1940 | 1 | .into_iter() |
1941 | 31 | .map(|n| Nibble::try_from(n).unwrap()), |
1942 | 1 | false, |
1943 | 1 | iter::empty(), |
1944 | 1 | false |
1945 | 1 | ), |
1946 | | Err(super::IncompleteProofError()) |
1947 | | )); |
1948 | | |
1949 | 1 | assert!(decoded |
1950 | 1 | .next_key( |
1951 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
1952 | 1 | [ |
1953 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, 0xb, |
1954 | 1 | 2, 4, 6, 4, 0xe, 3, 3, 3, 9, 7 |
1955 | 1 | ] |
1956 | 1 | .into_iter() |
1957 | 32 | .map(|n| Nibble::try_from(n).unwrap()), |
1958 | 1 | true, |
1959 | 1 | [ |
1960 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, 0xb, |
1961 | 1 | 2, 4, 6, 4, 0xe, 3, 3, 3, 9, 7, 0 |
1962 | 1 | ] |
1963 | 1 | .into_iter() |
1964 | 33 | .map(|n| Nibble::try_from(n).unwrap()), |
1965 | 1 | true |
1966 | 1 | ) |
1967 | 1 | .unwrap() |
1968 | 1 | .is_none()); |
1969 | | |
1970 | 1 | assert!(decoded |
1971 | 1 | .next_key( |
1972 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
1973 | 1 | [ |
1974 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, 0xb, |
1975 | 1 | 2, 4, 6, 4, 0xe, 3, 3, 3, 9, 7 |
1976 | 1 | ] |
1977 | 1 | .into_iter() |
1978 | 31 | .map(|n| Nibble::try_from(n).unwrap()), |
1979 | 1 | true, |
1980 | 1 | [ |
1981 | 1 | 9, 0xc, 5, 0xd, 7, 9, 5, 0xd, 0, 2, 9, 7, 0xb, 0xe, 5, 6, 0, 2, 7, 0xa, 4, 0xb, |
1982 | 1 | 2, 4, 6, 4, 0xe, 3, 3, 3, 0xa |
1983 | 1 | ] |
1984 | 1 | .into_iter() |
1985 | 31 | .map(|n| Nibble::try_from(n).unwrap()), |
1986 | 1 | true |
1987 | 1 | ) |
1988 | 1 | .unwrap() |
1989 | 1 | .is_none()); |
1990 | | |
1991 | | // TODO: more tests |
1992 | 1 | } |
1993 | | |
1994 | | #[test] |
1995 | 1 | fn closest_descendant_merkle_value_works() { |
1996 | 1 | let decoded = super::decode_and_verify_proof(super::Config { |
1997 | 1 | proof: EXAMPLE_PROOF, |
1998 | 1 | }) |
1999 | 1 | .unwrap(); |
2000 | 1 | |
2001 | 1 | assert_eq!( |
2002 | 1 | decoded |
2003 | 1 | .closest_descendant_merkle_value( |
2004 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2005 | 1 | trie::bytes_to_nibbles([].into_iter()) |
2006 | 1 | ) |
2007 | 1 | .unwrap() |
2008 | 1 | .unwrap(), |
2009 | 1 | &EXAMPLE_PROOF_STATE_ROOT[..] |
2010 | 1 | ); |
2011 | | |
2012 | 1 | assert_eq!( |
2013 | 1 | decoded |
2014 | 1 | .closest_descendant_merkle_value( |
2015 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2016 | 1 | [super::nibble::Nibble::try_from(1).unwrap()].into_iter() |
2017 | 1 | ) |
2018 | 1 | .unwrap() |
2019 | 1 | .unwrap(), |
2020 | 1 | &[ |
2021 | 1 | 36, 31, 44, 6, 242, 46, 197, 137, 104, 251, 104, 212, 50, 49, 158, 37, 230, 200, |
2022 | 1 | 250, 163, 173, 44, 92, 169, 238, 72, 242, 232, 237, 21, 142, 36 |
2023 | 1 | ][..] |
2024 | 1 | ); |
2025 | | |
2026 | 1 | assert!(matches!0 ( |
2027 | 1 | dbg!(decoded.closest_descendant_merkle_value( |
2028 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2029 | 1 | [ |
2030 | 1 | super::nibble::Nibble::try_from(1).unwrap(), |
2031 | 1 | super::nibble::Nibble::try_from(0).unwrap() |
2032 | 1 | ] |
2033 | 1 | .into_iter() |
2034 | 1 | )), |
2035 | | Err(super::IncompleteProofError()) |
2036 | | )); |
2037 | | |
2038 | 1 | assert!(decoded |
2039 | 1 | .closest_descendant_merkle_value( |
2040 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2041 | 1 | [super::nibble::Nibble::try_from(0xe).unwrap()].into_iter() |
2042 | 1 | ) |
2043 | 1 | .unwrap() |
2044 | 1 | .is_none()); |
2045 | | |
2046 | 1 | assert!(decoded |
2047 | 1 | .closest_descendant_merkle_value( |
2048 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2049 | 1 | [ |
2050 | 1 | super::nibble::Nibble::try_from(0xe).unwrap(), |
2051 | 1 | super::nibble::Nibble::try_from(0).unwrap() |
2052 | 1 | ] |
2053 | 1 | .into_iter() |
2054 | 1 | ) |
2055 | 1 | .unwrap() |
2056 | 1 | .is_none()); |
2057 | | |
2058 | 1 | assert_eq!( |
2059 | 1 | decoded |
2060 | 1 | .closest_descendant_merkle_value( |
2061 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2062 | 1 | trie::bytes_to_nibbles( |
2063 | 1 | [156, 93, 121, 93, 2, 151, 190, 86, 2, 122, 75, 36, 100, 227].into_iter() |
2064 | 1 | ) |
2065 | 1 | ) |
2066 | 1 | .unwrap() |
2067 | 1 | .unwrap(), |
2068 | 1 | &[ |
2069 | 1 | 94, 132, 157, 92, 20, 140, 163, 97, 165, 90, 44, 155, 56, 78, 23, 206, 145, 158, |
2070 | 1 | 147, 108, 203, 128, 17, 164, 247, 37, 4, 233, 249, 61, 184, 205 |
2071 | 1 | ][..] |
2072 | 1 | ); |
2073 | | |
2074 | 1 | assert!(decoded |
2075 | 1 | .closest_descendant_merkle_value( |
2076 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2077 | 1 | trie::bytes_to_nibbles( |
2078 | 1 | [156, 93, 121, 93, 2, 151, 190, 86, 2, 122, 75, 36, 100, 228].into_iter() |
2079 | 1 | ) |
2080 | 1 | ) |
2081 | 1 | .unwrap() |
2082 | 1 | .is_none()); |
2083 | | |
2084 | 1 | assert_eq!( |
2085 | 1 | decoded |
2086 | 1 | .closest_descendant_merkle_value( |
2087 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2088 | 1 | trie::bytes_to_nibbles( |
2089 | 1 | [156, 93, 121, 93, 2, 151, 190, 86, 2, 122, 75, 36, 100, 227, 51, 151] |
2090 | 1 | .into_iter() |
2091 | 1 | ) |
2092 | 1 | ) |
2093 | 1 | .unwrap() |
2094 | 1 | .unwrap(), |
2095 | 1 | &[ |
2096 | 1 | 94, 132, 157, 92, 20, 140, 163, 97, 165, 90, 44, 155, 56, 78, 23, 206, 145, 158, |
2097 | 1 | 147, 108, 203, 128, 17, 164, 247, 37, 4, 233, 249, 61, 184, 205 |
2098 | 1 | ][..] |
2099 | 1 | ); |
2100 | | |
2101 | 1 | assert!(decoded |
2102 | 1 | .closest_descendant_merkle_value( |
2103 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2104 | 1 | trie::bytes_to_nibbles( |
2105 | 1 | [ |
2106 | 1 | 156, 93, 121, 93, 2, 151, 190, 86, 2, 122, 75, 36, 100, 227, 51, 151, 99, |
2107 | 1 | 230, 211, 193, 251, 21, 128, 94, 223, 208, 36, 23, 46, 164, 129, 125, 112, |
2108 | 1 | 129, 84, 37, 150, 173, 176, 93, 97, 64, 193, 112, 172, 71, 158, 223, 124, |
2109 | 1 | 253, 90, 163, 83, 87, 89, 10, 207, 229, 209, 26, 128, 77, 148, 78, 0 |
2110 | 1 | ] |
2111 | 1 | .into_iter() |
2112 | 1 | ) |
2113 | 1 | ) |
2114 | 1 | .unwrap() |
2115 | 1 | .is_none()); |
2116 | | |
2117 | 1 | assert_eq!( |
2118 | 1 | decoded |
2119 | 1 | .closest_descendant_merkle_value( |
2120 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2121 | 1 | trie::bytes_to_nibbles( |
2122 | 1 | [ |
2123 | 1 | 156, 93, 121, 93, 2, 151, 190, 86, 2, 122, 75, 36, 100, 227, 51, 151, |
2124 | 1 | 99, 230, 211, 193, 251, 21, 128, 94, 223, 208, 36, 23, 46, 164, 129, |
2125 | 1 | 125, 112, 129, 84, 37, 150, 173, 176, 93, 97, 64, 193, 112, 172, 71, |
2126 | 1 | 158, 223, 124, 253, 90, 163, 83, 87, 89, 10, 207, 229, 209, 26, 128, |
2127 | 1 | 77, 148, 78 |
2128 | 1 | ] |
2129 | 1 | .into_iter() |
2130 | 1 | ) |
2131 | 1 | ) |
2132 | 1 | .unwrap() |
2133 | 1 | .unwrap(), |
2134 | 1 | &[ |
2135 | 1 | 205, 59, 200, 195, 206, 60, 248, 53, 159, 115, 113, 161, 51, 22, 240, 47, 210, 43, |
2136 | 1 | 2, 163, 211, 39, 104, 74, 43, 97, 244, 164, 126, 0, 34, 184 |
2137 | 1 | ][..] |
2138 | 1 | ); |
2139 | | |
2140 | 1 | assert_eq!( |
2141 | 1 | decoded |
2142 | 1 | .closest_descendant_merkle_value( |
2143 | 1 | EXAMPLE_PROOF_STATE_ROOT, |
2144 | 1 | trie::bytes_to_nibbles( |
2145 | 1 | [ |
2146 | 1 | 156, 93, 121, 93, 2, 151, 190, 86, 2, 122, 75, 36, 100, 227, 51, 151, |
2147 | 1 | 99, 230, 211, 193, 251, 21, 128, 94, 223, 208, 36, 23, 46, 164, 129, |
2148 | 1 | 125, 112, 129, 84, 37, 150, 173, 176, 93, 97, 64, 193, 112, 172, 71, |
2149 | 1 | 158, 223, 124, 253, 90, 163, 83, 87, 89, 10, 207, 229, 209, 26, 128, |
2150 | 1 | 77, 148 |
2151 | 1 | ] |
2152 | 1 | .into_iter() |
2153 | 1 | ) |
2154 | 1 | ) |
2155 | 1 | .unwrap() |
2156 | 1 | .unwrap(), |
2157 | 1 | &[ |
2158 | 1 | 205, 59, 200, 195, 206, 60, 248, 53, 159, 115, 113, 161, 51, 22, 240, 47, 210, 43, |
2159 | 1 | 2, 163, 211, 39, 104, 74, 43, 97, 244, 164, 126, 0, 34, 184 |
2160 | 1 | ][..] |
2161 | 1 | ); |
2162 | 1 | } |
2163 | | |
2164 | | // TODO: test closest_ancestor |
2165 | | |
2166 | | #[test] |
2167 | 1 | fn node_values_smaller_than_32bytes() { |
2168 | 1 | let proof = vec![ |
2169 | 1 | 12, 17, 1, 158, 195, 101, 195, 207, 89, 214, 113, 235, 114, 218, 14, 122, 65, 19, 196, |
2170 | 1 | 0, 3, 88, 95, 7, 141, 67, 77, 97, 37, 180, 4, 67, 254, 17, 253, 41, 45, 19, 164, 16, 2, |
2171 | 1 | 0, 0, 0, 104, 95, 15, 31, 5, 21, 244, 98, 205, 207, 132, 224, 241, 214, 4, 93, 252, |
2172 | 1 | 187, 32, 80, 82, 127, 41, 119, 1, 0, 0, 185, 5, 128, 175, 188, 128, 15, 126, 137, 9, |
2173 | 1 | 189, 204, 29, 117, 244, 124, 194, 9, 181, 214, 119, 106, 91, 55, 85, 146, 101, 112, 37, |
2174 | 1 | 46, 31, 42, 133, 72, 101, 38, 60, 66, 128, 28, 186, 118, 76, 106, 111, 232, 204, 106, |
2175 | 1 | 88, 52, 218, 113, 2, 76, 119, 132, 172, 202, 215, 130, 198, 184, 230, 206, 134, 44, |
2176 | 1 | 171, 25, 86, 243, 121, 128, 233, 10, 145, 50, 95, 100, 17, 213, 147, 28, 9, 142, 56, |
2177 | 1 | 95, 33, 40, 56, 9, 39, 3, 193, 79, 169, 207, 115, 80, 61, 217, 4, 106, 172, 152, 128, |
2178 | 1 | 12, 255, 241, 157, 249, 219, 101, 33, 139, 178, 174, 121, 165, 33, 175, 0, 232, 230, |
2179 | 1 | 129, 23, 89, 219, 21, 35, 23, 48, 18, 153, 124, 96, 81, 66, 128, 30, 174, 194, 227, |
2180 | 1 | 100, 149, 97, 237, 23, 238, 114, 178, 106, 158, 238, 48, 166, 82, 19, 210, 129, 122, |
2181 | 1 | 70, 165, 94, 186, 31, 28, 80, 29, 73, 252, 128, 16, 56, 19, 158, 188, 178, 192, 234, |
2182 | 1 | 12, 251, 221, 107, 119, 243, 74, 155, 111, 53, 36, 107, 183, 204, 174, 253, 183, 67, |
2183 | 1 | 77, 199, 47, 121, 185, 162, 128, 17, 217, 226, 195, 240, 113, 144, 201, 129, 184, 240, |
2184 | 1 | 237, 204, 79, 68, 191, 165, 29, 219, 170, 152, 134, 160, 153, 245, 38, 181, 131, 83, |
2185 | 1 | 209, 245, 194, 128, 137, 217, 3, 84, 1, 224, 52, 199, 112, 213, 150, 42, 51, 214, 103, |
2186 | 1 | 194, 225, 224, 210, 84, 84, 53, 31, 159, 82, 201, 3, 104, 118, 212, 110, 7, 128, 240, |
2187 | 1 | 251, 81, 190, 126, 80, 60, 139, 88, 152, 39, 153, 231, 178, 31, 184, 56, 44, 133, 31, |
2188 | 1 | 47, 98, 234, 107, 15, 248, 64, 78, 36, 89, 9, 149, 128, 233, 75, 238, 120, 212, 149, |
2189 | 1 | 223, 135, 48, 174, 211, 219, 223, 217, 20, 172, 212, 172, 3, 234, 54, 130, 55, 225, 63, |
2190 | 1 | 17, 255, 217, 150, 252, 93, 15, 128, 89, 54, 254, 99, 202, 80, 50, 27, 92, 48, 57, 174, |
2191 | 1 | 8, 211, 44, 58, 108, 207, 129, 245, 129, 80, 170, 57, 130, 80, 166, 250, 214, 40, 156, |
2192 | 1 | 181, 21, 1, 128, 65, 0, 128, 182, 204, 71, 61, 83, 76, 85, 166, 19, 22, 212, 242, 236, |
2193 | 1 | 229, 51, 88, 16, 191, 227, 125, 217, 54, 7, 31, 36, 176, 211, 111, 72, 220, 181, 241, |
2194 | 1 | 128, 149, 2, 12, 26, 95, 9, 193, 115, 207, 253, 90, 218, 0, 41, 140, 119, 189, 166, |
2195 | 1 | 101, 244, 74, 171, 53, 248, 82, 113, 79, 110, 25, 72, 62, 65, |
2196 | 1 | ]; |
2197 | 1 | |
2198 | 1 | let trie_root = [ |
2199 | 1 | 43, 100, 198, 174, 1, 66, 26, 95, 93, 119, 43, 242, 5, 176, 153, 134, 193, 74, 159, |
2200 | 1 | 215, 134, 15, 252, 135, 67, 129, 21, 16, 20, 211, 97, 217, |
2201 | 1 | ]; |
2202 | 1 | |
2203 | 1 | let decoded = super::decode_and_verify_proof(super::Config { proof }).unwrap(); |
2204 | 1 | |
2205 | 1 | let requested_key = |
2206 | 1 | hex::decode("f0c365c3cf59d671eb72da0e7a4113c49f1f0515f462cdcf84e0f1d6045dfcbb") |
2207 | 1 | .unwrap(); |
2208 | 1 | let obtained = decoded.storage_value(&trie_root, &requested_key).unwrap(); |
2209 | 1 | |
2210 | 1 | assert_eq!(obtained.unwrap().0, &[80, 82, 127, 41, 119, 1, 0, 0][..]); |
2211 | 1 | } |
2212 | | |
2213 | | #[test] |
2214 | 1 | fn very_small_root_node_decodes() { |
2215 | 1 | // Checks that a proof with one root node whose length is < 32 bytes properly verifies. |
2216 | 1 | let proof = vec![ |
2217 | 1 | 4, 64, 66, 3, 52, 120, 31, 215, 222, 245, 16, 76, 51, 181, 0, 245, 192, 194, |
2218 | 1 | ]; |
2219 | 1 | |
2220 | 1 | let proof = super::decode_and_verify_proof(super::Config { proof }).unwrap(); |
2221 | 1 | |
2222 | 1 | assert!(proof |
2223 | 1 | .closest_descendant_merkle_value( |
2224 | 1 | &[ |
2225 | 1 | 83, 2, 191, 235, 8, 252, 233, 114, 129, 199, 229, 115, 221, 238, 15, 205, 193, |
2226 | 1 | 110, 145, 107, 12, 3, 10, 145, 117, 211, 203, 151, 182, 147, 221, 178, |
2227 | 1 | ], |
2228 | 1 | iter::empty() |
2229 | 1 | ) |
2230 | 1 | .is_ok()); |
2231 | 1 | } |
2232 | | |
2233 | | #[test] |
2234 | 1 | fn identical_inline_nodes() { |
2235 | 1 | // One root node with two identical inlined children. |
2236 | 1 | let proof = super::decode_and_verify_proof(super::Config { |
2237 | 1 | proof: &[ |
2238 | 1 | 4, 60, 128, 3, 0, 20, 65, 0, 8, 104, 105, 20, 65, 0, 8, 104, 105, |
2239 | 1 | ], |
2240 | 1 | }) |
2241 | 1 | .unwrap(); |
2242 | 1 | |
2243 | 1 | assert!(proof |
2244 | 1 | .closest_descendant_merkle_value( |
2245 | 1 | &[ |
2246 | 1 | 15, 224, 134, 90, 11, 145, 174, 197, 185, 253, 233, 197, 95, 101, 197, 10, 78, |
2247 | 1 | 28, 137, 217, 102, 198, 242, 100, 90, 96, 9, 204, 213, 69, 174, 4, |
2248 | 1 | ], |
2249 | 1 | iter::empty() |
2250 | 1 | ) |
2251 | 1 | .is_ok()); |
2252 | 1 | } |
2253 | | |
2254 | | #[test] |
2255 | 1 | fn identical_non_inline_nodes() { |
2256 | 1 | // One root node with two identical children and the proof contains the two children |
2257 | 1 | // separately. In other words, the proof is invalid. |
2258 | 1 | assert!(matches!0 ( |
2259 | 1 | super::decode_and_verify_proof(super::Config { |
2260 | 1 | proof: &[ |
2261 | 1 | 12, 21, 1, 128, 3, 0, 128, 205, 154, 249, 23, 88, 152, 61, 75, 170, 87, 182, 7, |
2262 | 1 | 127, 171, 174, 60, 2, 124, 79, 166, 31, 155, 155, 185, 182, 155, 250, 63, 139, |
2263 | 1 | 166, 222, 184, 128, 205, 154, 249, 23, 88, 152, 61, 75, 170, 87, 182, 7, 127, |
2264 | 1 | 171, 174, 60, 2, 124, 79, 166, 31, 155, 155, 185, 182, 155, 250, 63, 139, 166, |
2265 | 1 | 222, 184, 97, 1, 65, 0, 81, 1, 108, 111, 110, 103, 32, 115, 116, 111, 114, 97, |
2266 | 1 | 103, 101, 32, 118, 97, 108, 117, 101, 32, 105, 110, 32, 111, 114, 100, 101, |
2267 | 1 | 114, 32, 116, 111, 32, 101, 110, 115, 117, 114, 101, 32, 116, 104, 97, 116, 32, |
2268 | 1 | 116, 104, 101, 32, 110, 111, 100, 101, 32, 118, 97, 108, 117, 101, 32, 105, |
2269 | 1 | 115, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, 51, 50, 32, 98, 121, |
2270 | 1 | 116, 101, 115, 32, 108, 111, 110, 103, 97, 1, 65, 0, 81, 1, 108, 111, 110, 103, |
2271 | 1 | 32, 115, 116, 111, 114, 97, 103, 101, 32, 118, 97, 108, 117, 101, 32, 105, 110, |
2272 | 1 | 32, 111, 114, 100, 101, 114, 32, 116, 111, 32, 101, 110, 115, 117, 114, 101, |
2273 | 1 | 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 110, 111, 100, 101, 32, 118, 97, |
2274 | 1 | 108, 117, 101, 32, 105, 115, 32, 109, 111, 114, 101, 32, 116, 104, 97, 110, 32, |
2275 | 1 | 51, 50, 32, 98, 121, 116, 101, 115, 32, 108, 111, 110, 103 |
2276 | 1 | ], |
2277 | 1 | }), |
2278 | | Err(super::Error::DuplicateProofEntry) |
2279 | | )); |
2280 | | |
2281 | | // One root node with two identical children that aren't inlined. |
2282 | | // The proof is the same as above, just without two identical proof entries. |
2283 | 1 | super::decode_and_verify_proof(super::Config { |
2284 | 1 | proof: &[ |
2285 | 1 | 8, 21, 1, 128, 3, 0, 128, 205, 154, 249, 23, 88, 152, 61, 75, 170, 87, 182, 7, 127, |
2286 | 1 | 171, 174, 60, 2, 124, 79, 166, 31, 155, 155, 185, 182, 155, 250, 63, 139, 166, 222, |
2287 | 1 | 184, 128, 205, 154, 249, 23, 88, 152, 61, 75, 170, 87, 182, 7, 127, 171, 174, 60, |
2288 | 1 | 2, 124, 79, 166, 31, 155, 155, 185, 182, 155, 250, 63, 139, 166, 222, 184, 97, 1, |
2289 | 1 | 65, 0, 81, 1, 108, 111, 110, 103, 32, 115, 116, 111, 114, 97, 103, 101, 32, 118, |
2290 | 1 | 97, 108, 117, 101, 32, 105, 110, 32, 111, 114, 100, 101, 114, 32, 116, 111, 32, |
2291 | 1 | 101, 110, 115, 117, 114, 101, 32, 116, 104, 97, 116, 32, 116, 104, 101, 32, 110, |
2292 | 1 | 111, 100, 101, 32, 118, 97, 108, 117, 101, 32, 105, 115, 32, 109, 111, 114, 101, |
2293 | 1 | 32, 116, 104, 97, 110, 32, 51, 50, 32, 98, 121, 116, 101, 115, 32, 108, 111, 110, |
2294 | 1 | 103, |
2295 | 1 | ], |
2296 | 1 | }) |
2297 | 1 | .unwrap(); |
2298 | 1 | } |
2299 | | |
2300 | | #[test] |
2301 | 1 | fn storage_values_that_decode_are_ignored() { |
2302 | 1 | // This test makes sure that if a storage value found in a proof accidentally successfully |
2303 | 1 | // decodes as a trie node with an invalid inline child, the decoding doesn't return an |
2304 | 1 | // error and instead simply ignores it. |
2305 | 1 | // It is a regression test for <https://github.com/smol-dot/smoldot/pull/1362>. |
2306 | 1 | super::decode_and_verify_proof(super::Config { |
2307 | 1 | proof: &[ |
2308 | 1 | 249, 1, 97, 3, 0, 0, 48, 0, 0, 80, 0, 0, 170, 170, 10, 0, 0, 0, 64, 0, 251, 255, 0, |
2309 | 1 | 0, 128, 0, 0, 0, 10, 0, 0, 0, 16, 14, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
2310 | 1 | 0, 80, 0, 0, 200, 0, 0, 30, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, |
2311 | 1 | 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 3, 0, 0, 0, 144, 1, |
2312 | 1 | 0, 30, 0, 0, 0, 0, 144, 1, 0, 4, 1, 0, 32, 0, 0, 128, 112, 0, 0, 0, 0, 0, 0, 0, 0, |
2313 | 1 | 0, 0, 16, 39, 0, 0, 128, 178, 230, 14, 128, 195, 201, 1, 128, 150, 152, 0, 0, 0, 0, |
2314 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 3, |
2315 | 1 | 0, 0, 0, 1, 44, 1, 0, 0, 6, 0, 0, 0, 88, 2, 0, 0, 3, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, |
2316 | 1 | 0, 30, 0, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0, 20, 0, 0, 0, 2, 0, 0, 0, 132, 1, 26, 118, |
2317 | 1 | 193, 65, 215, 141, 49, 213, 102, 164, 117, 129, 154, 43, 143, 110, 86, 199, 140, |
2318 | 1 | 245, 110, 51, 237, 121, 42, 47, 47, 177, 40, 203, 202, 36, 176, 54, 255, 111, 125, |
2319 | 1 | 70, 123, 135, 169, 232, 3, 0, 0, 55, 141, 18, 33, 9, 228, 96, 214, 20, 250, 8, 137, |
2320 | 1 | 170, 69, 232, 172, 124, 235, 254, 141, 126, 228, 181, 218, 29, 19, 92, 105, 118, |
2321 | 1 | 141, 224, 39, 176, 54, 255, 111, 125, 70, 123, 135, 169, 232, 3, 0, 0, 129, 135, |
2322 | 1 | 152, 88, 195, 254, 195, 247, 51, 254, 46, 63, 2, 174, 41, 56, 235, 208, 20, 207, |
2323 | 1 | 49, 241, 253, 205, 183, 68, 150, 100, 236, 72, 25, 68, 192, 61, 0, 39, 9, 46, 239, |
2324 | 1 | 5, 69, 232, 3, 0, 0, 215, 7, 0, 0, 32, 27, 15, 127, 205, 121, 190, 185, 62, 204, 1, |
2325 | 1 | 128, 50, 46, 101, 201, 82, 198, 120, 168, 186, 95, 17, 179, 17, 1, 121, 26, 173, |
2326 | 1 | 104, 57, 17, 192, 61, 0, 40, 140, 20, 28, 114, 29, 232, 3, 0, 0, 77, 8, 0, 0, 61, |
2327 | 1 | 150, 210, 254, 230, 222, 187, 225, 31, 60, 227, 34, 93, 204, 79, 11, 98, 237, 182, |
2328 | 1 | 161, 121, 26, 170, 252, 182, 97, 250, 173, 5, 61, 182, 149, 192, 61, 0, 171, 145, |
2329 | 1 | 207, 1, 20, 216, 232, 3, 0, 0, 0, 8, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, |
2330 | 1 | 73, 17, 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, |
2331 | 1 | 126, 41, 190, 130, 192, 61, 4, 23, 57, 95, 192, 189, 223, 234, 3, 0, 0, 232, 3, 0, |
2332 | 1 | 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, 17, 70, 19, 46, 224, 67, 186, 215, |
2333 | 1 | 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, 41, 190, 130, 192, 61, 6, 56, 2, |
2334 | 1 | 208, 248, 212, 114, 232, 3, 0, 0, 231, 7, 0, 0, 211, 146, 25, 139, 229, 251, 35, |
2335 | 1 | 14, 202, 17, 207, 172, 147, 76, 96, 238, 221, 50, 95, 138, 123, 115, 63, 159, 253, |
2336 | 1 | 208, 81, 93, 175, 47, 136, 177, 192, 61, 10, 24, 216, 208, 25, 70, 203, 44, 8, 0, |
2337 | 1 | 0, 232, 3, 0, 0, 108, 191, 211, 90, 169, 83, 96, 196, 220, 49, 111, 155, 130, 94, |
2338 | 1 | 97, 0, 165, 137, 151, 12, 188, 17, 233, 113, 124, 6, 130, 189, 36, 94, 191, 43, |
2339 | 1 | 192, 61, 10, 187, 47, 43, 177, 201, 79, 62, 8, 0, 0, 232, 3, 0, 0, 84, 177, 25, 92, |
2340 | 1 | 85, 110, 50, 152, 111, 126, 60, 169, 206, 199, 73, 245, 186, 191, 14, 129, 210, |
2341 | 1 | 101, 163, 185, 103, 110, 14, 53, 128, 9, 113, 135, 192, 61, 11, 121, 2, 180, 48, |
2342 | 1 | 50, 139, 232, 3, 0, 0, 73, 8, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, 17, |
2343 | 1 | 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, 41, |
2344 | 1 | 190, 130, 192, 61, 11, 128, 7, 157, 139, 153, 243, 232, 3, 0, 0, 36, 8, 0, 0, 110, |
2345 | 1 | 144, 217, 165, 46, 204, 221, 194, 25, 70, 185, 24, 72, 39, 165, 170, 124, 143, 40, |
2346 | 1 | 213, 47, 85, 169, 60, 207, 55, 153, 41, 242, 31, 44, 197, 192, 61, 11, 161, 105, |
2347 | 1 | 169, 49, 149, 179, 232, 3, 0, 0, 209, 7, 0, 0, 135, 0, 122, 33, 98, 228, 190, 91, |
2348 | 1 | 165, 67, 33, 82, 45, 82, 1, 202, 184, 9, 75, 180, 170, 93, 204, 3, 168, 110, 140, |
2349 | 1 | 205, 208, 22, 160, 219, 192, 61, 12, 2, 1, 227, 42, 232, 107, 209, 7, 0, 0, 232, 3, |
2350 | 1 | 0, 0, 151, 238, 85, 106, 200, 180, 9, 113, 172, 175, 77, 132, 69, 70, 173, 83, 112, |
2351 | 1 | 166, 204, 254, 181, 105, 213, 253, 229, 127, 105, 146, 101, 32, 248, 137, 192, 61, |
2352 | 1 | 12, 128, 141, 84, 168, 147, 123, 232, 3, 0, 0, 75, 8, 0, 0, 81, 2, 17, 44, 188, 60, |
2353 | 1 | 147, 230, 242, 73, 17, 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, |
2354 | 1 | 6, 5, 223, 68, 126, 41, 190, 130, 192, 61, 15, 17, 49, 183, 245, 75, 8, 0, 8, 0, 0, |
2355 | 1 | 232, 3, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, 17, 70, 19, 46, 224, 67, |
2356 | 1 | 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, 41, 190, 130, 192, 62, |
2357 | 1 | 0, 83, 243, 142, 189, 253, 66, 231, 7, 0, 0, 232, 3, 0, 0, 21, 35, 22, 233, 213, |
2358 | 1 | 153, 239, 52, 243, 111, 234, 26, 149, 63, 107, 6, 33, 211, 74, 32, 57, 27, 6, 207, |
2359 | 1 | 207, 43, 66, 151, 86, 40, 118, 87, 192, 62, 4, 210, 161, 90, 181, 17, 39, 232, 3, |
2360 | 1 | 0, 0, 208, 7, 0, 0, 4, 243, 195, 134, 53, 116, 171, 92, 152, 71, 180, 32, 53, 111, |
2361 | 1 | 224, 6, 36, 236, 114, 64, 222, 202, 177, 0, 182, 61, 165, 91, 219, 109, 231, 158, |
2362 | 1 | 192, 62, 15, 44, 104, 151, 68, 229, 91, 232, 3, 0, 0, 62, 8, 0, 0, 151, 85, 185, |
2363 | 1 | 250, 155, 84, 76, 229, 101, 161, 127, 21, 135, 253, 52, 187, 111, 33, 157, 167, 72, |
2364 | 1 | 225, 37, 14, 50, 216, 238, 248, 248, 120, 205, 152, 192, 62, 28, 100, 60, 157, 144, |
2365 | 1 | 171, 116, 39, 8, 0, 0, 232, 3, 0, 0, 61, 228, 198, 210, 121, 188, 255, 91, 53, 54, |
2366 | 1 | 69, 220, 240, 77, 12, 65, 152, 229, 254, 250, 154, 180, 171, 174, 11, 6, 197, 14, |
2367 | 1 | 24, 225, 246, 33, 192, 62, 31, 197, 2, 226, 176, 126, 150, 232, 3, 0, 0, 39, 8, 0, |
2368 | 1 | 0, 198, 68, 29, 105, 103, 233, 183, 118, 240, 55, 10, 247, 59, 176, 106, 169, 81, |
2369 | 1 | 90, 210, 122, 16, 181, 63, 247, 57, 61, 166, 31, 129, 98, 190, 31, 192, 62, 41, |
2370 | 1 | 178, 150, 130, 51, 131, 215, 232, 3, 0, 0, 76, 8, 0, 0, 244, 52, 228, 90, 91, 116, |
2371 | 1 | 249, 136, 128, 118, 113, 105, 33, 69, 40, 181, 196, 67, 153, 66, 205, 28, 67, 9, |
2372 | 1 | 208, 157, 110, 181, 72, 232, 201, 38, 192, 62, 59, 169, 1, 144, 95, 128, 192, 36, |
2373 | 1 | 8, 0, 0, 232, 3, 0, 0, 230, 253, 85, 4, 130, 251, 98, 9, 18, 125, 172, 197, 126, |
2374 | 1 | 75, 50, 108, 183, 157, 118, 89, 109, 191, 197, 26, 13, 210, 245, 72, 90, 114, 185, |
2375 | 1 | 169, 192, 62, 67, 215, 59, 253, 0, 17, 49, 42, 8, 0, 0, 232, 3, 0, 0, 229, 151, |
2376 | 1 | 103, 245, 113, 165, 120, 53, 181, 68, 32, 121, 167, 109, 115, 147, 51, 88, 61, 65, |
2377 | 1 | 7, 86, 248, 78, 201, 162, 131, 172, 234, 74, 244, 251, 192, 62, 79, 54, 112, 131, |
2378 | 1 | 102, 183, 34, 208, 7, 0, 0, 232, 3, 0, 0, 103, 90, 111, 142, 18, 131, 50, 58, 146, |
2379 | 1 | 163, 192, 192, 163, 97, 68, 225, 108, 169, 162, 224, 10, 170, 248, 209, 151, 63, |
2380 | 1 | 150, 132, 66, 203, 45, 207, 192, 62, 83, 81, 219, 36, 40, 165, 44, 77, 8, 0, 0, |
2381 | 1 | 232, 3, 0, 0, 149, 206, 115, 106, 124, 106, 114, 192, 139, 11, 141, 73, 232, 176, |
2382 | 1 | 215, 234, 33, 166, 157, 15, 57, 56, 241, 94, 225, 22, 243, 190, 3, 35, 103, 10, |
2383 | 1 | 192, 62, 85, 202, 11, 145, 38, 11, 189, 215, 7, 0, 0, 232, 3, 0, 0, 56, 127, 221, |
2384 | 1 | 245, 176, 100, 38, 121, 224, 118, 170, 244, 143, 186, 43, 47, 46, 134, 100, 151, |
2385 | 1 | 205, 173, 200, 190, 238, 148, 239, 59, 112, 1, 30, 66, 192, 62, 111, 232, 252, 188, |
2386 | 1 | 83, 20, 184, 76, 8, 0, 0, 232, 3, 0, 0, 230, 183, 216, 151, 183, 98, 18, 231, 55, |
2387 | 1 | 243, 106, 173, 152, 61, 41, 4, 97, 17, 6, 25, 151, 197, 112, 254, 231, 159, 111, |
2388 | 1 | 104, 130, 222, 62, 126, 192, 62, 119, 223, 219, 138, 219, 16, 247, 143, 16, 165, |
2389 | 1 | 223, 135, 66, 197, 69, 55, 102, 164, 3, 102, 154, 246, 238, 148, 174, 113, 65, 150, |
2390 | 1 | 173, 230, 159, 47, 183, 165, 25, 168, 157, 123, 104, 30, 195, 80, 69, 135, 156, 46, |
2391 | 1 | 163, 192, 62, 121, 19, 197, 6, 141, 231, 236, 232, 3, 0, 0, 42, 8, 0, 0, 128, 59, |
2392 | 1 | 7, 78, 184, 18, 34, 172, 243, 49, 234, 200, 81, 99, 228, 166, 85, 34, 117, 116, |
2393 | 1 | 166, 178, 215, 164, 76, 198, 91, 77, 70, 53, 206, 43, 192, 62, 123, 154, 227, 54, |
2394 | 1 | 228, 76, 248, 73, 8, 0, 0, 232, 3, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, |
2395 | 1 | 17, 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, |
2396 | 1 | 41, 190, 130, 192, 62, 125, 153, 115, 129, 57, 149, 125, 232, 3, 0, 0, 234, 3, 0, |
2397 | 1 | 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, 17, 70, 19, 46, 224, 67, 186, 215, |
2398 | 1 | 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, 41, 190, 130, 192, 62, 153, 36, |
2399 | 1 | 97, 4, 207, 65, 86, 75, 8, 0, 0, 232, 3, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, |
2400 | 1 | 242, 73, 17, 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, 223, |
2401 | 1 | 68, 126, 41, 190, 130, 192, 62, 160, 196, 240, 37, 252, 100, 103, 37, 8, 0, 0, 232, |
2402 | 1 | 3, 0, 0, 223, 185, 89, 118, 226, 133, 142, 166, 9, 163, 159, 64, 35, 26, 188, 140, |
2403 | 1 | 53, 108, 48, 49, 229, 232, 1, 60, 200, 8, 118, 255, 72, 9, 96, 30, 192, 62, 206, |
2404 | 1 | 67, 51, 57, 104, 130, 146, 232, 3, 0, 0, 37, 8, 0, 0, 66, 254, 119, 40, 12, 101, |
2405 | 1 | 64, 103, 226, 73, 149, 42, 100, 35, 59, 64, 66, 200, 132, 87, 131, 144, 254, 33, |
2406 | 1 | 133, 8, 50, 55, 196, 146, 241, 150, 192, 62, 232, 44, 203, 92, 185, 84, 186, 232, |
2407 | 1 | 3, 0, 0, 44, 8, 0, 0, 62, 187, 190, 68, 94, 177, 253, 116, 133, 112, 96, 78, 161, |
2408 | 1 | 187, 87, 37, 212, 0, 180, 198, 182, 53, 194, 21, 88, 152, 119, 207, 237, 195, 90, |
2409 | 1 | 9, 200, 63, 0, 4, 180, 157, 149, 50, 13, 144, 33, 153, 76, 133, 15, 37, 184, 227, |
2410 | 1 | 133, 162, 89, 119, 34, 17, 36, 96, 55, 65, 56, 67, 180, 116, 208, 29, 129, 93, 170, |
2411 | 1 | 12, 95, 104, 45, 101, 136, 133, 233, 174, 110, 20, 254, 87, 165, 5, 1, 64, 234, 3, |
2412 | 1 | 0, 0, 208, 7, 0, 0, 209, 7, 0, 0, 215, 7, 0, 0, 231, 7, 0, 0, 0, 8, 0, 0, 36, 8, 0, |
2413 | 1 | 0, 37, 8, 0, 0, 39, 8, 0, 0, 42, 8, 0, 0, 44, 8, 0, 0, 62, 8, 0, 0, 73, 8, 0, 0, |
2414 | 1 | 75, 8, 0, 0, 76, 8, 0, 0, 77, 8, 0, 0, 180, 86, 255, 111, 125, 70, 123, 135, 169, |
2415 | 1 | 232, 3, 0, 0, 128, 219, 10, 131, 230, 56, 122, 129, 211, 80, 123, 155, 53, 216, 39, |
2416 | 1 | 58, 194, 18, 17, 30, 231, 17, 210, 11, 206, 79, 177, 111, 226, 103, 216, 183, 15, |
2417 | 1 | 196, 94, 65, 76, 176, 8, 224, 230, 30, 70, 114, 42, 166, 10, 189, 214, 114, 128, |
2418 | 1 | 33, 241, 183, 89, 20, 103, 186, 98, 8, 119, 1, 11, 225, 217, 154, 29, 152, 198, 15, |
2419 | 1 | 79, 41, 78, 47, 52, 60, 22, 92, 162, 158, 255, 42, 61, 196, 94, 230, 120, 121, 157, |
2420 | 1 | 62, 255, 2, 66, 83, 185, 14, 132, 146, 124, 198, 128, 29, 182, 208, 142, 77, 250, |
2421 | 1 | 108, 18, 67, 91, 75, 235, 139, 100, 111, 228, 73, 113, 213, 240, 173, 79, 81, 197, |
2422 | 1 | 219, 218, 131, 93, 165, 176, 105, 39, 21, 1, 128, 0, 20, 128, 39, 144, 14, 91, 130, |
2423 | 1 | 157, 91, 18, 149, 77, 162, 20, 175, 75, 15, 2, 103, 162, 202, 5, 51, 232, 112, 49, |
2424 | 1 | 106, 48, 198, 76, 24, 101, 250, 12, 128, 164, 21, 237, 225, 206, 155, 246, 215, |
2425 | 1 | 186, 11, 95, 28, 134, 173, 249, 51, 229, 224, 164, 189, 49, 249, 124, 12, 223, 1, |
2426 | 1 | 146, 240, 92, 221, 239, 113, 224, 128, 0, 96, 128, 105, 62, 182, 93, 212, 141, 152, |
2427 | 1 | 21, 65, 79, 191, 208, 169, 217, 153, 194, 14, 178, 54, 67, 134, 194, 134, 236, 204, |
2428 | 1 | 134, 126, 69, 138, 20, 244, 100, 76, 94, 123, 144, 18, 9, 107, 65, 196, 235, 58, |
2429 | 1 | 175, 148, 127, 110, 164, 41, 8, 0, 0, 21, 1, 128, 0, 132, 128, 186, 28, 192, 80, |
2430 | 1 | 77, 249, 201, 163, 76, 229, 59, 170, 235, 88, 253, 158, 76, 183, 44, 79, 42, 245, |
2431 | 1 | 24, 171, 191, 194, 37, 247, 74, 131, 62, 39, 128, 38, 101, 17, 82, 38, 152, 50, |
2432 | 1 | 145, 67, 133, 153, 206, 179, 121, 103, 196, 42, 148, 118, 220, 86, 37, 152, 249, |
2433 | 1 | 234, 27, 222, 242, 216, 51, 71, 71, 21, 1, 128, 1, 16, 128, 9, 58, 62, 213, 97, 13, |
2434 | 1 | 210, 5, 10, 1, 165, 252, 5, 204, 60, 117, 216, 243, 136, 184, 223, 7, 134, 241, |
2435 | 1 | 133, 146, 117, 16, 5, 95, 183, 0, 128, 101, 36, 173, 199, 56, 96, 161, 163, 95, |
2436 | 1 | 220, 100, 157, 157, 182, 37, 94, 27, 161, 52, 25, 64, 86, 82, 116, 143, 224, 39, |
2437 | 1 | 42, 231, 195, 190, 79, 21, 1, 128, 1, 16, 128, 185, 102, 197, 105, 241, 189, 112, |
2438 | 1 | 27, 231, 66, 119, 254, 113, 105, 78, 56, 229, 32, 28, 104, 56, 10, 237, 214, 234, |
2439 | 1 | 173, 11, 30, 131, 188, 43, 45, 128, 14, 190, 101, 3, 105, 206, 14, 60, 232, 91, 34, |
2440 | 1 | 129, 97, 129, 245, 152, 204, 110, 207, 122, 59, 34, 49, 67, 87, 171, 65, 129, 185, |
2441 | 1 | 204, 184, 103, 29, 2, 128, 2, 164, 128, 98, 49, 33, 45, 166, 186, 168, 0, 68, 161, |
2442 | 1 | 215, 32, 89, 183, 217, 234, 71, 168, 50, 213, 84, 112, 139, 72, 249, 95, 59, 26, |
2443 | 1 | 232, 24, 64, 4, 128, 229, 86, 253, 119, 78, 183, 52, 147, 198, 35, 185, 41, 210, |
2444 | 1 | 36, 27, 63, 108, 17, 166, 247, 52, 121, 74, 47, 16, 131, 52, 202, 254, 141, 221, |
2445 | 1 | 220, 128, 22, 186, 70, 170, 190, 43, 216, 171, 16, 49, 164, 192, 177, 82, 101, 247, |
2446 | 1 | 19, 85, 217, 105, 84, 82, 118, 199, 144, 102, 118, 173, 136, 81, 125, 139, 128, 70, |
2447 | 1 | 201, 211, 160, 140, 52, 211, 15, 213, 5, 26, 103, 201, 243, 21, 51, 92, 70, 68, |
2448 | 1 | 145, 195, 25, 230, 3, 183, 243, 1, 19, 56, 201, 201, 183, 21, 1, 128, 4, 1, 128, |
2449 | 1 | 30, 34, 108, 150, 45, 162, 139, 6, 57, 227, 175, 254, 55, 177, 176, 249, 226, 106, |
2450 | 1 | 92, 179, 213, 225, 170, 235, 250, 213, 168, 232, 148, 41, 192, 81, 128, 7, 61, 47, |
2451 | 1 | 252, 45, 92, 8, 66, 62, 190, 53, 127, 232, 118, 24, 47, 47, 248, 8, 85, 162, 14, |
2452 | 1 | 126, 143, 35, 118, 191, 225, 171, 221, 246, 179, 21, 1, 128, 4, 4, 128, 142, 128, |
2453 | 1 | 246, 15, 223, 166, 228, 216, 107, 254, 221, 146, 163, 131, 211, 62, 96, 95, 230, |
2454 | 1 | 88, 238, 131, 214, 214, 169, 50, 60, 58, 12, 107, 219, 172, 128, 225, 175, 18, 233, |
2455 | 1 | 5, 78, 91, 57, 216, 56, 102, 193, 238, 3, 183, 243, 194, 4, 26, 103, 158, 111, 39, |
2456 | 1 | 70, 63, 105, 38, 60, 9, 236, 120, 207, 21, 1, 128, 4, 4, 128, 239, 131, 105, 71, |
2457 | 1 | 108, 244, 223, 172, 186, 162, 76, 205, 59, 208, 148, 69, 59, 135, 111, 98, 67, 89, |
2458 | 1 | 72, 42, 25, 149, 35, 156, 167, 12, 196, 246, 128, 15, 230, 176, 54, 57, 255, 39, |
2459 | 1 | 57, 228, 43, 38, 58, 100, 185, 116, 88, 187, 183, 176, 74, 127, 19, 167, 221, 16, |
2460 | 1 | 183, 123, 165, 195, 211, 148, 14, 161, 2, 128, 4, 108, 128, 21, 183, 195, 164, 157, |
2461 | 1 | 34, 208, 32, 48, 32, 81, 127, 117, 125, 42, 211, 19, 47, 197, 30, 224, 164, 228, |
2462 | 1 | 177, 179, 174, 133, 85, 224, 125, 236, 233, 128, 5, 142, 100, 250, 63, 51, 102, 58, |
2463 | 1 | 191, 73, 133, 86, 77, 157, 128, 254, 129, 194, 214, 209, 106, 128, 46, 128, 222, |
2464 | 1 | 50, 176, 135, 228, 229, 132, 162, 128, 143, 131, 240, 216, 230, 57, 158, 159, 157, |
2465 | 1 | 16, 195, 200, 155, 97, 78, 49, 136, 72, 223, 183, 236, 234, 216, 155, 19, 122, 177, |
2466 | 1 | 254, 47, 169, 104, 249, 128, 226, 145, 161, 62, 29, 45, 111, 198, 215, 236, 45, 49, |
2467 | 1 | 25, 57, 59, 121, 38, 26, 6, 27, 22, 229, 173, 82, 161, 54, 9, 202, 158, 222, 247, |
2468 | 1 | 226, 128, 42, 117, 67, 138, 234, 238, 79, 46, 237, 81, 94, 211, 32, 107, 224, 128, |
2469 | 1 | 220, 53, 107, 4, 226, 16, 2, 240, 1, 143, 223, 55, 152, 112, 209, 149, 21, 1, 128, |
2470 | 1 | 8, 2, 128, 29, 121, 195, 67, 100, 133, 169, 193, 23, 58, 103, 159, 112, 135, 125, |
2471 | 1 | 85, 28, 138, 132, 206, 254, 84, 237, 244, 224, 134, 126, 225, 23, 249, 79, 237, |
2472 | 1 | 128, 212, 250, 24, 77, 173, 122, 60, 124, 68, 61, 71, 140, 224, 170, 88, 175, 195, |
2473 | 1 | 236, 38, 77, 58, 174, 0, 148, 60, 173, 114, 195, 74, 50, 180, 167, 220, 128, 8, 32, |
2474 | 1 | 128, 200, 225, 19, 175, 65, 108, 15, 91, 245, 96, 57, 186, 231, 154, 252, 226, 196, |
2475 | 1 | 5, 155, 114, 52, 31, 231, 84, 121, 155, 23, 74, 248, 214, 82, 116, 72, 94, 173, |
2476 | 1 | 110, 239, 92, 75, 28, 104, 234, 167, 30, 161, 122, 2, 217, 222, 4, 0, 169, 3, 128, |
2477 | 1 | 16, 111, 128, 252, 169, 111, 124, 210, 127, 239, 85, 108, 211, 97, 190, 230, 150, |
2478 | 1 | 83, 36, 52, 212, 130, 9, 52, 165, 124, 50, 156, 77, 146, 123, 135, 78, 155, 159, |
2479 | 1 | 128, 118, 54, 94, 247, 229, 189, 13, 15, 66, 244, 152, 205, 98, 163, 106, 210, 119, |
2480 | 1 | 57, 195, 199, 65, 20, 58, 91, 113, 3, 154, 101, 169, 13, 143, 162, 128, 214, 151, |
2481 | 1 | 110, 179, 39, 134, 150, 44, 245, 7, 7, 163, 71, 16, 4, 238, 209, 116, 28, 232, 102, |
2482 | 1 | 201, 224, 234, 253, 152, 61, 96, 197, 221, 220, 20, 128, 140, 66, 249, 51, 155, 64, |
2483 | 1 | 204, 197, 179, 224, 185, 94, 186, 231, 71, 62, 142, 174, 235, 110, 29, 84, 40, 72, |
2484 | 1 | 123, 153, 8, 24, 239, 144, 162, 78, 128, 73, 76, 35, 3, 224, 104, 245, 170, 22, |
2485 | 1 | 101, 89, 66, 102, 79, 38, 6, 247, 133, 195, 101, 94, 35, 142, 133, 0, 230, 216, |
2486 | 1 | 151, 86, 173, 99, 67, 128, 118, 54, 246, 80, 237, 77, 64, 77, 122, 173, 9, 245, |
2487 | 1 | 249, 209, 190, 30, 99, 124, 94, 145, 109, 5, 97, 24, 91, 16, 222, 118, 211, 218, |
2488 | 1 | 182, 217, 128, 6, 224, 127, 165, 31, 198, 32, 42, 219, 23, 52, 38, 217, 241, 132, |
2489 | 1 | 138, 111, 113, 110, 213, 166, 200, 152, 80, 207, 152, 107, 61, 173, 237, 225, 153, |
2490 | 1 | 21, 1, 128, 16, 128, 128, 162, 231, 121, 64, 38, 82, 125, 222, 190, 110, 59, 117, |
2491 | 1 | 195, 119, 83, 156, 250, 10, 119, 79, 100, 94, 197, 124, 14, 241, 25, 122, 220, 76, |
2492 | 1 | 252, 24, 128, 51, 159, 146, 11, 30, 85, 157, 28, 237, 161, 158, 225, 213, 51, 94, |
2493 | 1 | 113, 58, 151, 167, 154, 68, 116, 242, 253, 88, 132, 190, 24, 251, 116, 73, 220, 37, |
2494 | 1 | 3, 128, 17, 23, 128, 96, 131, 252, 204, 90, 217, 72, 158, 143, 255, 212, 105, 70, |
2495 | 1 | 106, 66, 6, 167, 67, 216, 219, 188, 143, 179, 1, 5, 157, 170, 29, 25, 140, 134, 40, |
2496 | 1 | 128, 119, 183, 177, 175, 64, 154, 137, 151, 98, 94, 167, 103, 216, 129, 255, 121, |
2497 | 1 | 221, 60, 77, 27, 71, 46, 31, 10, 31, 163, 196, 196, 249, 99, 36, 207, 128, 224, |
2498 | 1 | 139, 126, 218, 65, 159, 164, 1, 42, 240, 25, 148, 233, 39, 3, 211, 254, 4, 235, |
2499 | 1 | 166, 148, 238, 235, 23, 229, 235, 231, 236, 211, 151, 194, 200, 128, 57, 25, 103, |
2500 | 1 | 24, 47, 116, 198, 179, 179, 98, 130, 75, 44, 58, 64, 167, 148, 156, 192, 146, 160, |
2501 | 1 | 107, 203, 191, 65, 122, 156, 135, 60, 193, 94, 164, 128, 71, 211, 6, 80, 41, 9, |
2502 | 1 | 163, 31, 70, 240, 250, 101, 93, 235, 194, 234, 109, 190, 30, 223, 54, 102, 171, |
2503 | 1 | 178, 160, 174, 163, 245, 145, 58, 120, 217, 128, 242, 161, 250, 223, 31, 70, 182, |
2504 | 1 | 93, 93, 123, 37, 89, 54, 229, 112, 22, 127, 45, 89, 190, 236, 165, 93, 209, 44, |
2505 | 1 | 217, 80, 179, 214, 114, 26, 7, 61, 6, 128, 30, 255, 128, 224, 239, 217, 114, 71, |
2506 | 1 | 189, 38, 205, 232, 77, 47, 243, 106, 119, 93, 124, 72, 98, 64, 26, 160, 237, 23, |
2507 | 1 | 247, 138, 150, 242, 69, 237, 162, 61, 73, 128, 85, 14, 91, 47, 193, 125, 95, 82, |
2508 | 1 | 159, 51, 220, 40, 75, 106, 53, 82, 43, 99, 162, 99, 30, 170, 253, 7, 222, 43, 141, |
2509 | 1 | 187, 117, 231, 60, 33, 128, 34, 60, 85, 159, 51, 19, 15, 5, 223, 58, 20, 80, 102, |
2510 | 1 | 28, 97, 204, 30, 224, 41, 182, 59, 151, 149, 137, 194, 218, 232, 103, 246, 165, |
2511 | 1 | 180, 230, 128, 115, 80, 40, 68, 179, 87, 240, 30, 121, 226, 240, 56, 25, 35, 39, |
2512 | 1 | 49, 88, 75, 47, 4, 19, 144, 183, 32, 80, 141, 53, 189, 126, 158, 125, 212, 128, 68, |
2513 | 1 | 6, 170, 129, 41, 101, 157, 12, 50, 49, 193, 252, 191, 210, 178, 171, 84, 88, 139, |
2514 | 1 | 33, 234, 79, 125, 194, 20, 236, 163, 196, 159, 116, 20, 190, 128, 4, 232, 86, 88, |
2515 | 1 | 190, 112, 35, 31, 66, 74, 201, 162, 128, 160, 131, 141, 149, 161, 251, 104, 250, |
2516 | 1 | 205, 109, 210, 123, 40, 140, 1, 142, 64, 156, 73, 128, 14, 233, 222, 123, 22, 122, |
2517 | 1 | 67, 76, 65, 77, 43, 58, 130, 100, 116, 86, 236, 163, 177, 69, 87, 238, 190, 250, |
2518 | 1 | 232, 14, 26, 208, 226, 0, 72, 238, 128, 147, 54, 250, 178, 243, 117, 250, 237, 22, |
2519 | 1 | 11, 106, 54, 248, 77, 9, 200, 78, 37, 12, 233, 166, 61, 173, 208, 53, 9, 153, 173, |
2520 | 1 | 12, 48, 97, 136, 128, 144, 148, 5, 12, 135, 74, 240, 239, 153, 47, 73, 203, 207, |
2521 | 1 | 133, 52, 101, 108, 205, 165, 57, 26, 89, 35, 77, 51, 116, 47, 103, 9, 203, 97, 134, |
2522 | 1 | 128, 167, 34, 193, 31, 251, 159, 112, 161, 80, 194, 93, 253, 88, 214, 109, 108, |
2523 | 1 | 119, 6, 65, 19, 142, 92, 146, 77, 101, 40, 211, 219, 217, 176, 33, 53, 128, 172, |
2524 | 1 | 106, 169, 168, 254, 215, 132, 77, 99, 193, 207, 252, 18, 140, 54, 193, 112, 253, |
2525 | 1 | 151, 91, 61, 132, 171, 148, 99, 87, 244, 246, 230, 77, 175, 106, 128, 93, 51, 113, |
2526 | 1 | 190, 163, 62, 159, 163, 215, 99, 161, 141, 180, 190, 141, 64, 1, 108, 54, 71, 9, 7, |
2527 | 1 | 104, 183, 103, 118, 182, 26, 13, 145, 65, 206, 21, 1, 128, 32, 128, 128, 130, 69, |
2528 | 1 | 110, 84, 222, 230, 123, 133, 142, 165, 48, 89, 187, 22, 14, 221, 110, 84, 51, 205, |
2529 | 1 | 192, 182, 137, 64, 106, 110, 11, 142, 178, 117, 142, 25, 128, 40, 50, 31, 111, 100, |
2530 | 1 | 67, 204, 173, 37, 95, 70, 243, 13, 235, 180, 148, 98, 195, 236, 80, 231, 152, 83, |
2531 | 1 | 225, 52, 133, 43, 150, 50, 155, 134, 249, 21, 1, 128, 40, 0, 128, 133, 83, 204, 5, |
2532 | 1 | 45, 33, 2, 133, 247, 41, 207, 179, 251, 114, 140, 80, 33, 235, 181, 161, 110, 15, |
2533 | 1 | 95, 8, 29, 244, 229, 12, 124, 86, 31, 147, 128, 200, 118, 89, 49, 88, 144, 241, 1, |
2534 | 1 | 68, 156, 8, 70, 184, 188, 125, 15, 172, 81, 209, 112, 120, 18, 196, 84, 228, 83, |
2535 | 1 | 174, 48, 0, 115, 31, 196, 53, 5, 128, 47, 55, 128, 237, 207, 55, 149, 114, 218, |
2536 | 1 | 173, 176, 15, 40, 210, 50, 101, 165, 249, 165, 195, 69, 172, 243, 153, 183, 239, |
2537 | 1 | 225, 169, 33, 78, 58, 204, 166, 143, 166, 128, 210, 111, 156, 33, 81, 224, 97, 119, |
2538 | 1 | 148, 198, 141, 111, 173, 223, 154, 194, 198, 151, 144, 58, 25, 25, 146, 196, 244, |
2539 | 1 | 231, 114, 167, 71, 213, 23, 228, 128, 125, 241, 8, 196, 99, 144, 50, 249, 52, 210, |
2540 | 1 | 98, 164, 54, 238, 35, 127, 38, 3, 168, 153, 233, 72, 21, 50, 52, 248, 83, 255, 52, |
2541 | 1 | 108, 131, 21, 128, 188, 239, 224, 13, 82, 159, 47, 195, 72, 169, 35, 119, 81, 89, |
2542 | 1 | 81, 35, 247, 32, 248, 117, 184, 53, 240, 134, 58, 243, 85, 186, 105, 243, 103, 74, |
2543 | 1 | 128, 48, 1, 27, 193, 218, 82, 145, 217, 224, 12, 172, 72, 75, 51, 17, 94, 194, 217, |
2544 | 1 | 14, 151, 207, 79, 184, 237, 194, 166, 240, 233, 79, 177, 135, 73, 128, 241, 221, |
2545 | 1 | 177, 252, 135, 34, 158, 84, 213, 138, 204, 241, 232, 22, 130, 191, 153, 56, 5, 51, |
2546 | 1 | 237, 136, 118, 28, 148, 160, 155, 88, 99, 47, 71, 40, 128, 112, 177, 196, 200, 98, |
2547 | 1 | 128, 1, 143, 184, 202, 73, 39, 118, 94, 152, 39, 89, 96, 228, 167, 67, 84, 125, 85, |
2548 | 1 | 124, 216, 46, 247, 170, 92, 26, 83, 128, 135, 182, 225, 255, 176, 147, 51, 226, |
2549 | 1 | 120, 69, 225, 113, 197, 44, 216, 157, 237, 225, 167, 131, 129, 51, 136, 167, 29, |
2550 | 1 | 37, 190, 1, 85, 29, 120, 43, 128, 88, 81, 223, 88, 223, 42, 110, 223, 90, 61, 50, |
2551 | 1 | 123, 95, 10, 254, 207, 224, 31, 237, 93, 54, 207, 198, 199, 43, 126, 78, 151, 33, |
2552 | 1 | 243, 248, 36, 128, 16, 247, 155, 152, 122, 193, 55, 210, 54, 96, 160, 186, 239, |
2553 | 1 | 170, 169, 123, 61, 0, 218, 250, 128, 201, 98, 131, 195, 242, 54, 14, 190, 231, 122, |
2554 | 1 | 199, 53, 5, 128, 62, 157, 128, 128, 122, 198, 51, 221, 186, 48, 79, 13, 100, 236, |
2555 | 1 | 186, 1, 109, 202, 150, 98, 241, 73, 151, 95, 151, 99, 26, 84, 244, 206, 20, 145, 9, |
2556 | 1 | 157, 222, 128, 47, 15, 222, 193, 146, 207, 255, 121, 51, 241, 15, 1, 133, 151, 161, |
2557 | 1 | 174, 74, 215, 135, 52, 77, 196, 86, 144, 8, 69, 1, 196, 81, 2, 55, 71, 128, 210, |
2558 | 1 | 229, 6, 246, 149, 226, 204, 26, 180, 51, 84, 208, 166, 36, 105, 147, 167, 242, 9, |
2559 | 1 | 212, 226, 56, 50, 209, 76, 68, 223, 30, 101, 189, 60, 6, 128, 213, 113, 67, 240, |
2560 | 1 | 104, 23, 42, 17, 111, 152, 22, 229, 22, 229, 161, 114, 214, 115, 146, 58, 55, 40, |
2561 | 1 | 39, 156, 100, 227, 37, 94, 73, 24, 15, 94, 128, 197, 215, 11, 163, 128, 252, 185, |
2562 | 1 | 201, 252, 122, 253, 88, 28, 25, 43, 82, 230, 210, 45, 98, 235, 87, 182, 169, 96, |
2563 | 1 | 138, 121, 195, 195, 3, 14, 89, 128, 50, 225, 140, 159, 253, 248, 101, 93, 50, 218, |
2564 | 1 | 228, 137, 251, 132, 158, 235, 88, 178, 99, 13, 63, 208, 149, 171, 142, 254, 225, |
2565 | 1 | 21, 165, 109, 126, 35, 128, 60, 41, 28, 176, 215, 23, 15, 122, 128, 20, 153, 198, |
2566 | 1 | 106, 169, 91, 42, 239, 143, 167, 67, 30, 172, 233, 132, 53, 105, 149, 123, 145, |
2567 | 1 | 202, 215, 245, 128, 39, 133, 125, 161, 60, 179, 147, 160, 37, 73, 249, 84, 74, 217, |
2568 | 1 | 140, 8, 191, 103, 192, 141, 148, 202, 147, 69, 116, 79, 134, 153, 127, 84, 160, 71, |
2569 | 1 | 128, 35, 19, 156, 185, 233, 164, 137, 20, 250, 202, 96, 198, 38, 47, 73, 180, 147, |
2570 | 1 | 98, 111, 247, 29, 186, 168, 187, 88, 90, 221, 175, 229, 137, 199, 33, 128, 133, |
2571 | 1 | 113, 93, 46, 186, 86, 21, 236, 116, 64, 80, 151, 156, 74, 191, 207, 245, 0, 6, 6, |
2572 | 1 | 101, 56, 75, 169, 223, 243, 248, 237, 200, 105, 15, 164, 21, 1, 128, 64, 1, 128, 0, |
2573 | 1 | 31, 98, 163, 15, 241, 148, 153, 234, 178, 119, 229, 190, 185, 108, 218, 170, 110, |
2574 | 1 | 144, 120, 228, 131, 57, 176, 225, 250, 217, 108, 168, 31, 125, 242, 128, 249, 46, |
2575 | 1 | 148, 69, 46, 66, 42, 104, 200, 216, 85, 87, 137, 237, 63, 209, 60, 196, 49, 192, |
2576 | 1 | 191, 38, 233, 191, 118, 82, 142, 216, 26, 156, 193, 64, 21, 1, 128, 64, 64, 128, |
2577 | 1 | 134, 97, 196, 18, 225, 170, 23, 209, 68, 68, 119, 225, 112, 108, 194, 20, 17, 213, |
2578 | 1 | 228, 182, 73, 212, 101, 214, 28, 71, 91, 75, 207, 162, 252, 51, 128, 65, 19, 116, |
2579 | 1 | 95, 242, 10, 83, 205, 69, 198, 84, 50, 233, 159, 70, 30, 113, 57, 7, 143, 164, 240, |
2580 | 1 | 158, 231, 244, 251, 120, 162, 235, 22, 188, 194, 21, 1, 128, 68, 1, 84, 86, 176, |
2581 | 1 | 50, 73, 34, 37, 51, 123, 234, 3, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 84, 86, 255, |
2582 | 1 | 111, 125, 70, 123, 135, 169, 232, 3, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 84, 86, 110, |
2583 | 1 | 117, 7, 123, 35, 173, 36, 39, 8, 0, 0, 32, 6, 0, 0, 0, 137, 1, 0, 0, 153, 1, 128, |
2584 | 1 | 73, 0, 128, 233, 188, 189, 178, 234, 66, 190, 60, 153, 30, 189, 4, 233, 104, 122, |
2585 | 1 | 212, 43, 77, 251, 126, 150, 142, 191, 61, 193, 223, 110, 73, 181, 238, 14, 93, 128, |
2586 | 1 | 185, 13, 158, 186, 83, 79, 165, 165, 31, 72, 171, 210, 38, 127, 50, 18, 114, 249, |
2587 | 1 | 230, 155, 108, 59, 253, 194, 206, 37, 6, 216, 125, 27, 184, 41, 128, 184, 151, 8, |
2588 | 1 | 214, 38, 239, 198, 156, 242, 160, 99, 152, 109, 58, 191, 120, 242, 71, 214, 165, |
2589 | 1 | 196, 209, 129, 196, 113, 31, 82, 13, 98, 134, 117, 114, 141, 2, 128, 76, 131, 72, |
2590 | 1 | 86, 176, 50, 73, 34, 37, 51, 123, 234, 3, 0, 0, 20, 4, 232, 3, 0, 0, 88, 86, 170, |
2591 | 1 | 94, 34, 92, 48, 154, 56, 47, 8, 0, 0, 36, 8, 208, 7, 0, 0, 215, 7, 0, 0, 128, 99, |
2592 | 1 | 103, 125, 158, 75, 246, 107, 144, 145, 198, 80, 239, 63, 192, 116, 157, 233, 130, |
2593 | 1 | 116, 174, 228, 233, 124, 49, 123, 255, 11, 255, 11, 253, 237, 177, 128, 147, 38, |
2594 | 1 | 36, 170, 3, 219, 57, 41, 170, 154, 70, 101, 148, 97, 56, 10, 78, 228, 73, 31, 80, |
2595 | 1 | 54, 15, 63, 199, 161, 208, 72, 210, 244, 61, 84, 72, 86, 109, 19, 178, 194, 29, 82, |
2596 | 1 | 235, 54, 8, 0, 0, 20, 4, 208, 7, 0, 0, 128, 122, 102, 162, 158, 29, 164, 92, 62, |
2597 | 1 | 144, 29, 97, 68, 81, 73, 99, 210, 255, 196, 11, 153, 154, 75, 119, 11, 175, 64, 97, |
2598 | 1 | 9, 211, 186, 101, 152, 169, 3, 128, 78, 131, 128, 110, 115, 126, 128, 243, 71, 32, |
2599 | 1 | 198, 95, 48, 174, 155, 229, 56, 53, 58, 183, 179, 227, 139, 216, 12, 81, 234, 207, |
2600 | 1 | 44, 238, 102, 197, 209, 1, 208, 128, 208, 168, 47, 69, 46, 74, 211, 132, 214, 176, |
2601 | 1 | 83, 246, 172, 80, 233, 147, 133, 240, 29, 34, 155, 56, 83, 209, 207, 164, 199, 245, |
2602 | 1 | 220, 226, 214, 222, 128, 11, 157, 19, 143, 50, 247, 148, 224, 15, 243, 73, 153, 2, |
2603 | 1 | 196, 64, 26, 4, 54, 83, 240, 24, 94, 108, 55, 120, 101, 134, 66, 251, 140, 75, 74, |
2604 | 1 | 128, 244, 210, 119, 200, 199, 64, 98, 131, 82, 250, 163, 192, 168, 115, 1, 157, 32, |
2605 | 1 | 223, 177, 179, 70, 101, 175, 241, 12, 112, 183, 141, 45, 215, 177, 237, 128, 193, |
2606 | 1 | 190, 173, 227, 220, 226, 149, 160, 42, 237, 100, 179, 133, 176, 218, 254, 52, 202, |
2607 | 1 | 40, 149, 39, 112, 103, 202, 6, 130, 125, 148, 201, 172, 136, 105, 128, 55, 250, |
2608 | 1 | 123, 249, 194, 102, 143, 199, 227, 224, 198, 183, 137, 26, 1, 32, 155, 111, 94, 43, |
2609 | 1 | 18, 60, 232, 54, 161, 189, 243, 55, 82, 253, 61, 178, 128, 35, 11, 46, 39, 210, |
2610 | 1 | 125, 54, 239, 129, 250, 241, 250, 219, 106, 127, 43, 233, 151, 235, 202, 69, 11, |
2611 | 1 | 117, 225, 154, 30, 58, 215, 56, 225, 163, 8, 61, 6, 128, 79, 247, 128, 110, 72, |
2612 | 1 | 222, 57, 57, 166, 76, 0, 123, 20, 217, 211, 99, 120, 187, 51, 76, 170, 148, 20, |
2613 | 1 | 128, 44, 107, 96, 133, 131, 75, 39, 141, 226, 247, 228, 128, 135, 163, 143, 250, |
2614 | 1 | 249, 11, 230, 192, 216, 160, 222, 84, 121, 145, 184, 8, 216, 20, 240, 64, 3, 67, |
2615 | 1 | 252, 168, 69, 115, 176, 134, 187, 242, 83, 50, 128, 35, 97, 242, 87, 164, 192, 90, |
2616 | 1 | 176, 249, 195, 90, 69, 119, 88, 98, 81, 97, 223, 4, 91, 213, 13, 57, 222, 33, 80, |
2617 | 1 | 83, 83, 47, 63, 4, 218, 128, 77, 127, 112, 89, 14, 141, 56, 240, 135, 157, 140, |
2618 | 1 | 218, 70, 61, 130, 167, 111, 107, 119, 1, 191, 43, 122, 64, 237, 163, 143, 169, 70, |
2619 | 1 | 232, 166, 144, 128, 79, 27, 98, 187, 162, 185, 125, 241, 65, 212, 21, 178, 231, 59, |
2620 | 1 | 139, 244, 164, 154, 238, 38, 25, 16, 18, 201, 91, 103, 240, 6, 192, 31, 183, 127, |
2621 | 1 | 128, 52, 118, 216, 62, 104, 191, 32, 61, 212, 113, 154, 195, 184, 106, 195, 40, |
2622 | 1 | 148, 56, 227, 44, 60, 4, 238, 188, 83, 49, 55, 122, 63, 41, 243, 73, 128, 159, 216, |
2623 | 1 | 188, 248, 113, 154, 85, 212, 50, 27, 64, 97, 117, 111, 161, 78, 136, 238, 147, 212, |
2624 | 1 | 146, 176, 12, 165, 198, 7, 106, 174, 77, 192, 233, 196, 128, 191, 37, 239, 196, 45, |
2625 | 1 | 101, 231, 194, 150, 149, 223, 27, 130, 167, 29, 53, 127, 251, 178, 127, 73, 39, |
2626 | 1 | 121, 80, 153, 61, 72, 197, 65, 71, 234, 97, 128, 238, 40, 205, 29, 44, 203, 83, 63, |
2627 | 1 | 252, 5, 25, 248, 58, 27, 47, 234, 5, 233, 8, 182, 135, 8, 24, 194, 155, 203, 65, |
2628 | 1 | 236, 97, 78, 223, 113, 128, 199, 137, 228, 102, 135, 141, 249, 7, 4, 233, 39, 181, |
2629 | 1 | 208, 72, 5, 26, 195, 191, 11, 118, 231, 30, 123, 150, 186, 223, 4, 31, 131, 245, |
2630 | 1 | 158, 167, 128, 99, 102, 62, 30, 131, 72, 196, 178, 124, 233, 119, 32, 38, 140, 119, |
2631 | 1 | 15, 193, 156, 174, 233, 96, 145, 52, 56, 82, 19, 123, 6, 77, 196, 130, 133, 128, |
2632 | 1 | 192, 71, 141, 90, 184, 112, 148, 175, 8, 254, 145, 129, 239, 41, 240, 54, 154, 70, |
2633 | 1 | 64, 188, 250, 19, 103, 108, 201, 186, 234, 172, 134, 155, 112, 250, 169, 3, 128, |
2634 | 1 | 92, 131, 128, 88, 125, 190, 183, 17, 254, 180, 127, 118, 50, 63, 198, 43, 156, 246, |
2635 | 1 | 133, 250, 153, 101, 238, 23, 204, 64, 123, 7, 27, 61, 223, 135, 1, 162, 250, 128, |
2636 | 1 | 145, 197, 244, 206, 108, 25, 176, 239, 66, 39, 129, 37, 57, 248, 146, 179, 2, 252, |
2637 | 1 | 171, 16, 145, 170, 229, 41, 105, 62, 232, 137, 5, 207, 126, 5, 128, 228, 1, 116, |
2638 | 1 | 153, 151, 104, 66, 66, 155, 130, 152, 68, 152, 105, 160, 161, 16, 242, 54, 206, |
2639 | 1 | 189, 45, 83, 81, 139, 64, 81, 117, 34, 98, 187, 9, 128, 190, 197, 105, 170, 91, |
2640 | 1 | 205, 186, 171, 44, 185, 44, 122, 135, 154, 169, 46, 83, 36, 23, 36, 137, 93, 129, |
2641 | 1 | 158, 103, 10, 146, 34, 232, 176, 188, 3, 128, 74, 14, 87, 204, 19, 105, 84, 56, 63, |
2642 | 1 | 16, 23, 48, 78, 153, 226, 236, 33, 115, 115, 219, 232, 182, 157, 235, 127, 27, 183, |
2643 | 1 | 187, 168, 160, 21, 217, 128, 213, 10, 157, 170, 102, 230, 227, 250, 251, 242, 182, |
2644 | 1 | 84, 92, 79, 143, 122, 14, 6, 125, 216, 242, 223, 48, 153, 181, 116, 9, 83, 229, 27, |
2645 | 1 | 162, 47, 128, 246, 255, 41, 225, 153, 210, 213, 120, 188, 22, 40, 219, 31, 243, 76, |
2646 | 1 | 123, 114, 58, 216, 167, 193, 118, 64, 3, 206, 168, 143, 182, 112, 161, 1, 62, 153, |
2647 | 1 | 1, 128, 97, 0, 128, 63, 64, 243, 32, 167, 212, 79, 208, 87, 141, 203, 191, 166, |
2648 | 1 | 145, 121, 200, 153, 94, 216, 129, 218, 188, 74, 30, 226, 20, 148, 249, 139, 18, |
2649 | 1 | 238, 204, 128, 222, 200, 175, 110, 67, 106, 221, 141, 63, 76, 8, 232, 97, 136, 82, |
2650 | 1 | 210, 141, 30, 185, 179, 246, 254, 136, 132, 98, 182, 245, 27, 31, 151, 5, 129, 128, |
2651 | 1 | 12, 113, 218, 42, 183, 196, 72, 154, 247, 125, 54, 106, 241, 208, 223, 167, 227, |
2652 | 1 | 147, 65, 147, 239, 145, 221, 25, 53, 174, 62, 3, 204, 176, 247, 251, 169, 3, 128, |
2653 | 1 | 117, 136, 128, 84, 101, 94, 182, 132, 212, 23, 178, 207, 157, 178, 96, 187, 96, 28, |
2654 | 1 | 189, 74, 94, 123, 43, 156, 159, 18, 185, 189, 153, 241, 24, 217, 81, 153, 21, 128, |
2655 | 1 | 218, 21, 64, 95, 185, 99, 133, 159, 156, 182, 201, 221, 109, 107, 149, 229, 31, |
2656 | 1 | 149, 219, 170, 149, 152, 91, 0, 7, 82, 19, 20, 5, 144, 122, 95, 128, 194, 102, 200, |
2657 | 1 | 251, 124, 176, 138, 225, 34, 42, 78, 39, 138, 150, 90, 16, 97, 0, 119, 26, 88, 253, |
2658 | 1 | 51, 98, 45, 191, 41, 161, 29, 72, 226, 7, 128, 76, 177, 103, 143, 3, 93, 250, 219, |
2659 | 1 | 166, 99, 252, 165, 237, 148, 217, 127, 30, 198, 149, 36, 157, 4, 239, 142, 253, |
2660 | 1 | 105, 235, 1, 2, 64, 133, 191, 128, 57, 206, 238, 180, 9, 57, 140, 173, 104, 92, |
2661 | 1 | 100, 52, 175, 204, 219, 22, 12, 185, 104, 67, 136, 252, 241, 117, 109, 39, 162, |
2662 | 1 | 173, 208, 70, 171, 70, 128, 16, 135, 86, 205, 3, 94, 4, 214, 251, 237, 128, 95, 11, |
2663 | 1 | 197, 106, 130, 142, 22, 62, 99, 133, 187, 215, 145, 120, 130, 154, 250, 24, 10, |
2664 | 1 | 210, 156, 128, 17, 59, 203, 31, 110, 114, 166, 116, 225, 184, 32, 75, 28, 157, 19, |
2665 | 1 | 198, 240, 2, 129, 8, 208, 129, 36, 42, 156, 142, 161, 74, 2, 91, 26, 91, 177, 4, |
2666 | 1 | 128, 127, 3, 128, 207, 181, 9, 54, 184, 244, 210, 220, 98, 100, 250, 186, 23, 86, |
2667 | 1 | 143, 176, 212, 100, 128, 166, 31, 28, 117, 179, 93, 76, 132, 237, 99, 103, 212, 17, |
2668 | 1 | 128, 86, 88, 133, 12, 118, 200, 224, 212, 199, 139, 77, 123, 82, 44, 198, 255, 122, |
2669 | 1 | 120, 60, 230, 141, 183, 44, 244, 154, 244, 203, 47, 179, 17, 142, 188, 128, 122, |
2670 | 1 | 146, 113, 132, 231, 235, 74, 146, 253, 49, 97, 245, 189, 115, 97, 71, 33, 179, 49, |
2671 | 1 | 77, 186, 210, 245, 84, 51, 137, 52, 204, 30, 120, 220, 86, 128, 203, 16, 76, 162, |
2672 | 1 | 26, 173, 176, 110, 166, 23, 166, 9, 102, 235, 244, 12, 67, 18, 154, 61, 6, 107, 30, |
2673 | 1 | 166, 225, 124, 90, 123, 105, 198, 233, 22, 128, 214, 36, 25, 11, 216, 181, 93, 240, |
2674 | 1 | 1, 130, 147, 137, 211, 153, 192, 113, 107, 187, 239, 163, 189, 201, 126, 149, 120, |
2675 | 1 | 134, 35, 148, 175, 219, 173, 161, 128, 190, 247, 23, 190, 177, 146, 35, 141, 100, |
2676 | 1 | 128, 102, 197, 160, 97, 56, 149, 91, 167, 109, 125, 149, 162, 15, 30, 2, 130, 124, |
2677 | 1 | 239, 49, 158, 131, 152, 128, 218, 104, 4, 83, 232, 255, 204, 138, 243, 84, 109, |
2678 | 1 | 249, 83, 248, 255, 84, 8, 180, 141, 7, 17, 47, 174, 46, 94, 4, 23, 60, 132, 15, 22, |
2679 | 1 | 125, 128, 18, 163, 43, 202, 192, 74, 238, 33, 157, 22, 248, 162, 41, 233, 28, 235, |
2680 | 1 | 139, 111, 202, 73, 203, 238, 18, 152, 150, 155, 167, 128, 182, 127, 19, 80, 128, |
2681 | 1 | 10, 242, 182, 70, 219, 195, 62, 249, 143, 251, 36, 78, 116, 122, 8, 48, 112, 120, |
2682 | 1 | 180, 106, 174, 79, 169, 202, 26, 7, 109, 218, 184, 122, 139, 137, 193, 6, 128, 127, |
2683 | 1 | 221, 128, 27, 202, 207, 198, 230, 72, 2, 38, 173, 154, 239, 111, 208, 86, 200, 0, |
2684 | 1 | 25, 154, 223, 131, 217, 90, 53, 175, 29, 11, 220, 189, 240, 58, 69, 179, 128, 89, |
2685 | 1 | 200, 56, 161, 56, 38, 134, 86, 42, 29, 144, 117, 7, 29, 168, 82, 87, 55, 57, 250, |
2686 | 1 | 159, 215, 16, 231, 168, 36, 177, 239, 210, 32, 227, 142, 128, 122, 245, 12, 2, 173, |
2687 | 1 | 235, 38, 135, 112, 201, 94, 90, 128, 237, 105, 94, 254, 148, 133, 161, 42, 246, |
2688 | 1 | 182, 255, 249, 232, 54, 52, 100, 125, 32, 181, 128, 89, 244, 0, 155, 27, 66, 193, |
2689 | 1 | 146, 83, 68, 40, 118, 201, 128, 74, 209, 116, 162, 241, 237, 122, 213, 101, 0, 119, |
2690 | 1 | 4, 74, 249, 165, 53, 61, 97, 128, 26, 91, 236, 132, 54, 200, 118, 34, 45, 153, 180, |
2691 | 1 | 162, 26, 184, 165, 84, 253, 169, 43, 228, 149, 169, 250, 133, 45, 140, 100, 195, |
2692 | 1 | 81, 131, 182, 229, 128, 245, 0, 224, 204, 156, 4, 163, 58, 175, 50, 117, 21, 47, |
2693 | 1 | 176, 142, 139, 31, 116, 111, 244, 38, 1, 203, 230, 63, 96, 46, 86, 77, 171, 28, 22, |
2694 | 1 | 128, 248, 4, 19, 26, 191, 122, 32, 139, 120, 170, 234, 204, 76, 212, 1, 107, 219, |
2695 | 1 | 82, 153, 15, 16, 196, 133, 143, 35, 30, 37, 73, 145, 89, 12, 193, 128, 80, 216, |
2696 | 1 | 254, 63, 116, 250, 216, 29, 247, 110, 200, 133, 27, 169, 197, 13, 79, 57, 178, 99, |
2697 | 1 | 183, 185, 231, 4, 22, 42, 65, 111, 61, 144, 127, 229, 128, 108, 63, 154, 245, 121, |
2698 | 1 | 215, 71, 112, 103, 193, 206, 246, 36, 97, 45, 41, 5, 124, 239, 58, 21, 47, 76, 103, |
2699 | 1 | 224, 209, 16, 64, 84, 4, 251, 247, 128, 78, 136, 92, 34, 160, 37, 152, 191, 98, |
2700 | 1 | 237, 32, 213, 38, 212, 25, 39, 192, 81, 96, 201, 5, 211, 231, 202, 73, 169, 78, |
2701 | 1 | 208, 229, 125, 184, 142, 128, 2, 138, 187, 57, 144, 148, 167, 191, 49, 220, 130, |
2702 | 1 | 10, 156, 251, 179, 142, 79, 149, 229, 86, 242, 156, 62, 72, 26, 40, 103, 16, 89, |
2703 | 1 | 62, 234, 175, 128, 58, 2, 12, 227, 254, 93, 208, 176, 215, 94, 98, 113, 206, 156, |
2704 | 1 | 42, 81, 205, 178, 46, 55, 218, 23, 51, 221, 178, 82, 232, 240, 32, 150, 191, 52, |
2705 | 1 | 128, 142, 38, 228, 88, 187, 244, 156, 85, 26, 227, 56, 145, 64, 175, 223, 23, 182, |
2706 | 1 | 199, 117, 195, 189, 62, 123, 202, 22, 221, 23, 56, 210, 4, 112, 128, 21, 1, 128, |
2707 | 1 | 128, 8, 128, 114, 48, 169, 34, 134, 225, 186, 235, 158, 65, 12, 208, 240, 49, 241, |
2708 | 1 | 59, 250, 236, 56, 33, 227, 117, 255, 242, 226, 38, 143, 23, 11, 141, 119, 94, 128, |
2709 | 1 | 25, 119, 236, 15, 164, 142, 196, 89, 189, 15, 91, 154, 146, 157, 225, 212, 207, |
2710 | 1 | 173, 185, 52, 75, 179, 24, 217, 234, 189, 14, 109, 66, 205, 82, 73, 105, 1, 128, |
2711 | 1 | 128, 23, 52, 70, 7, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, 0, 120, 129, 0, 136, 0, |
2712 | 1 | 48, 68, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, 0, 48, 68, 0, 0, 32, 170, 170, 10, 0, |
2713 | 1 | 0, 0, 64, 0, 52, 70, 3, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, 0, 52, 70, 3, 0, 0, |
2714 | 1 | 32, 170, 170, 10, 0, 0, 0, 64, 0, 52, 70, 8, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, |
2715 | 1 | 0, 29, 2, 128, 136, 20, 128, 234, 21, 24, 31, 100, 187, 95, 231, 71, 251, 19, 154, |
2716 | 1 | 253, 110, 100, 124, 82, 131, 178, 104, 66, 4, 196, 248, 141, 177, 223, 76, 0, 228, |
2717 | 1 | 83, 18, 128, 27, 84, 51, 50, 109, 153, 218, 23, 97, 32, 91, 76, 238, 92, 108, 233, |
2718 | 1 | 75, 153, 216, 73, 202, 147, 57, 91, 187, 21, 214, 194, 17, 250, 227, 230, 128, 32, |
2719 | 1 | 214, 25, 226, 238, 153, 149, 25, 43, 174, 172, 178, 106, 150, 203, 125, 206, 251, |
2720 | 1 | 91, 99, 210, 241, 85, 42, 66, 237, 6, 61, 193, 189, 151, 186, 128, 46, 207, 255, |
2721 | 1 | 17, 19, 214, 251, 229, 90, 118, 82, 55, 220, 135, 239, 251, 41, 49, 118, 150, 182, |
2722 | 1 | 47, 237, 57, 199, 99, 8, 107, 98, 123, 161, 74, 29, 2, 128, 145, 8, 128, 133, 145, |
2723 | 1 | 69, 57, 53, 129, 208, 112, 245, 77, 50, 20, 193, 123, 114, 100, 204, 180, 137, 40, |
2724 | 1 | 212, 5, 154, 14, 80, 36, 226, 11, 44, 101, 2, 219, 128, 193, 173, 73, 151, 65, 122, |
2725 | 1 | 210, 28, 205, 53, 92, 139, 68, 109, 143, 34, 182, 177, 220, 175, 95, 237, 79, 227, |
2726 | 1 | 205, 65, 188, 1, 202, 73, 219, 218, 128, 89, 156, 75, 125, 242, 28, 164, 49, 134, |
2727 | 1 | 244, 162, 10, 127, 109, 171, 142, 239, 1, 207, 77, 150, 90, 136, 247, 227, 103, |
2728 | 1 | 216, 26, 7, 44, 60, 228, 128, 134, 48, 96, 77, 49, 141, 153, 196, 222, 130, 77, 59, |
2729 | 1 | 42, 18, 209, 253, 84, 166, 103, 127, 250, 109, 118, 98, 39, 226, 242, 150, 251, 40, |
2730 | 1 | 164, 11, 53, 5, 128, 166, 243, 128, 21, 126, 43, 160, 126, 125, 205, 88, 105, 228, |
2731 | 1 | 197, 32, 25, 88, 75, 11, 101, 147, 244, 122, 19, 181, 117, 192, 239, 107, 11, 194, |
2732 | 1 | 238, 40, 164, 158, 128, 189, 63, 199, 104, 252, 239, 108, 216, 134, 109, 31, 244, |
2733 | 1 | 155, 141, 23, 100, 59, 234, 2, 38, 117, 124, 220, 5, 84, 239, 56, 41, 114, 76, 220, |
2734 | 1 | 101, 128, 99, 69, 152, 115, 12, 134, 76, 232, 82, 91, 83, 215, 16, 149, 38, 7, 145, |
2735 | 1 | 26, 90, 225, 2, 47, 174, 213, 174, 14, 145, 65, 165, 202, 80, 181, 128, 15, 215, |
2736 | 1 | 126, 220, 79, 106, 33, 145, 47, 149, 163, 39, 112, 117, 237, 243, 63, 129, 12, 24, |
2737 | 1 | 0, 54, 65, 160, 22, 8, 227, 184, 139, 96, 245, 118, 128, 107, 32, 171, 215, 127, |
2738 | 1 | 143, 187, 141, 115, 124, 79, 180, 191, 105, 14, 64, 212, 44, 22, 11, 231, 135, 97, |
2739 | 1 | 141, 115, 93, 124, 209, 115, 18, 208, 73, 128, 116, 154, 99, 151, 231, 95, 142, |
2740 | 1 | 228, 149, 59, 128, 92, 181, 121, 228, 237, 139, 48, 146, 202, 18, 247, 65, 221, |
2741 | 1 | 161, 244, 136, 177, 31, 215, 244, 208, 128, 164, 145, 139, 147, 221, 136, 254, 41, |
2742 | 1 | 246, 210, 96, 27, 184, 86, 175, 62, 132, 34, 32, 105, 137, 226, 6, 143, 31, 249, |
2743 | 1 | 77, 240, 150, 109, 174, 131, 128, 182, 248, 228, 24, 92, 247, 224, 76, 84, 43, 160, |
2744 | 1 | 31, 74, 180, 110, 223, 245, 74, 152, 0, 120, 195, 27, 63, 74, 242, 95, 121, 63, |
2745 | 1 | 108, 32, 82, 128, 246, 130, 222, 70, 161, 135, 213, 246, 151, 152, 58, 44, 100, 78, |
2746 | 1 | 150, 136, 157, 185, 31, 208, 3, 51, 127, 27, 240, 166, 51, 228, 250, 169, 144, 73, |
2747 | 1 | 128, 200, 187, 251, 234, 132, 23, 208, 208, 84, 217, 123, 33, 92, 105, 114, 132, |
2748 | 1 | 178, 124, 50, 65, 11, 214, 7, 177, 241, 51, 76, 150, 6, 102, 62, 134, 21, 1, 128, |
2749 | 1 | 192, 0, 128, 131, 153, 94, 1, 103, 222, 119, 172, 133, 120, 175, 151, 150, 17, 22, |
2750 | 1 | 54, 199, 229, 129, 31, 54, 222, 74, 1, 148, 94, 38, 18, 201, 214, 22, 113, 128, 21, |
2751 | 1 | 94, 86, 90, 231, 243, 234, 147, 32, 123, 63, 204, 187, 51, 133, 73, 99, 164, 187, |
2752 | 1 | 230, 22, 178, 252, 19, 75, 3, 66, 87, 226, 197, 81, 41, 161, 2, 128, 192, 137, 128, |
2753 | 1 | 232, 170, 107, 212, 154, 43, 246, 160, 246, 42, 233, 97, 13, 78, 77, 72, 178, 201, |
2754 | 1 | 224, 233, 249, 199, 32, 42, 180, 80, 56, 65, 55, 199, 12, 211, 128, 224, 87, 83, |
2755 | 1 | 135, 21, 244, 39, 18, 36, 169, 72, 210, 115, 211, 106, 42, 160, 174, 193, 118, 90, |
2756 | 1 | 116, 124, 46, 191, 89, 13, 54, 87, 121, 109, 157, 128, 228, 82, 11, 80, 231, 244, |
2757 | 1 | 99, 162, 152, 108, 136, 47, 200, 194, 140, 94, 3, 75, 221, 134, 177, 11, 208, 104, |
2758 | 1 | 137, 124, 105, 17, 58, 75, 74, 132, 128, 198, 39, 157, 12, 171, 61, 71, 228, 113, |
2759 | 1 | 25, 145, 88, 18, 2, 77, 229, 50, 61, 188, 135, 114, 200, 211, 21, 84, 130, 15, 80, |
2760 | 1 | 50, 214, 213, 22, 128, 154, 149, 239, 96, 134, 200, 120, 103, 76, 161, 98, 4, 132, |
2761 | 1 | 239, 81, 118, 82, 246, 177, 177, 223, 183, 126, 143, 69, 160, 86, 135, 11, 45, 223, |
2762 | 1 | 10, 45, 4, 128, 195, 156, 128, 91, 206, 1, 221, 144, 91, 146, 239, 62, 144, 7, 194, |
2763 | 1 | 86, 158, 84, 189, 69, 123, 48, 236, 94, 255, 52, 51, 78, 31, 163, 137, 92, 53, 26, |
2764 | 1 | 232, 128, 67, 166, 163, 235, 81, 160, 192, 95, 65, 87, 97, 46, 187, 146, 0, 177, |
2765 | 1 | 248, 191, 214, 39, 108, 113, 21, 246, 201, 220, 216, 146, 252, 121, 119, 170, 128, |
2766 | 1 | 34, 157, 88, 166, 119, 216, 68, 88, 5, 196, 60, 209, 191, 63, 113, 166, 233, 209, |
2767 | 1 | 189, 39, 13, 187, 69, 254, 247, 230, 244, 97, 252, 2, 66, 43, 128, 120, 127, 221, |
2768 | 1 | 117, 255, 196, 139, 3, 177, 158, 195, 185, 35, 246, 0, 179, 201, 1, 14, 200, 190, |
2769 | 1 | 59, 211, 99, 121, 75, 172, 168, 120, 208, 221, 227, 128, 91, 188, 126, 217, 191, |
2770 | 1 | 148, 220, 250, 57, 138, 205, 64, 183, 142, 62, 52, 2, 91, 72, 154, 158, 247, 178, |
2771 | 1 | 91, 25, 96, 37, 204, 207, 237, 140, 158, 128, 9, 98, 51, 137, 27, 25, 65, 249, 74, |
2772 | 1 | 68, 138, 199, 122, 180, 179, 12, 135, 144, 146, 252, 10, 98, 200, 0, 172, 62, 221, |
2773 | 1 | 161, 138, 178, 203, 34, 128, 197, 74, 235, 82, 103, 244, 94, 93, 22, 130, 214, 133, |
2774 | 1 | 235, 139, 46, 128, 198, 199, 73, 69, 65, 51, 13, 11, 125, 83, 218, 243, 40, 104, |
2775 | 1 | 163, 76, 128, 106, 199, 171, 70, 60, 21, 5, 165, 236, 63, 91, 185, 18, 84, 178, |
2776 | 1 | 146, 70, 125, 213, 147, 206, 34, 46, 21, 26, 251, 126, 93, 0, 19, 101, 76, 161, 2, |
2777 | 1 | 128, 220, 0, 128, 148, 55, 130, 172, 73, 122, 31, 218, 97, 4, 177, 237, 180, 63, |
2778 | 1 | 235, 206, 165, 106, 247, 14, 38, 41, 139, 66, 142, 130, 90, 203, 107, 181, 208, |
2779 | 1 | 151, 128, 188, 207, 83, 62, 14, 128, 169, 87, 187, 41, 242, 150, 93, 220, 72, 101, |
2780 | 1 | 230, 31, 45, 106, 144, 149, 225, 126, 243, 52, 254, 101, 141, 114, 26, 74, 128, |
2781 | 1 | 182, 4, 240, 217, 196, 20, 63, 210, 63, 107, 159, 124, 47, 130, 184, 252, 193, 153, |
2782 | 1 | 215, 95, 207, 242, 134, 180, 38, 244, 103, 185, 200, 58, 112, 29, 128, 102, 114, |
2783 | 1 | 227, 186, 190, 25, 167, 44, 72, 48, 232, 102, 171, 153, 98, 134, 127, 158, 86, 125, |
2784 | 1 | 35, 236, 119, 195, 194, 197, 213, 43, 92, 210, 41, 34, 128, 4, 212, 195, 198, 159, |
2785 | 1 | 208, 222, 57, 1, 254, 64, 98, 239, 148, 178, 231, 233, 158, 137, 173, 96, 60, 134, |
2786 | 1 | 228, 83, 24, 36, 0, 153, 71, 39, 43, 185, 5, 128, 230, 119, 128, 101, 195, 92, 254, |
2787 | 1 | 39, 167, 70, 226, 25, 48, 175, 65, 60, 166, 33, 103, 51, 27, 5, 236, 212, 220, 154, |
2788 | 1 | 214, 22, 131, 185, 50, 230, 213, 42, 179, 128, 162, 102, 167, 81, 157, 208, 164, |
2789 | 1 | 247, 107, 239, 252, 16, 72, 144, 76, 153, 137, 222, 185, 74, 144, 216, 242, 12, 17, |
2790 | 1 | 39, 251, 171, 109, 196, 209, 249, 128, 151, 103, 157, 240, 71, 137, 234, 197, 153, |
2791 | 1 | 137, 178, 66, 75, 180, 226, 175, 101, 12, 92, 128, 157, 0, 152, 221, 178, 218, 132, |
2792 | 1 | 76, 195, 59, 248, 118, 128, 169, 233, 221, 114, 77, 213, 3, 223, 95, 44, 41, 224, |
2793 | 1 | 30, 7, 70, 151, 212, 160, 237, 139, 102, 176, 19, 186, 19, 94, 86, 26, 57, 138, |
2794 | 1 | 158, 52, 128, 103, 54, 85, 37, 174, 122, 105, 162, 107, 124, 188, 122, 215, 38, 82, |
2795 | 1 | 77, 53, 70, 250, 237, 199, 78, 204, 139, 214, 212, 11, 131, 31, 246, 200, 99, 128, |
2796 | 1 | 141, 94, 22, 106, 210, 251, 174, 187, 143, 165, 218, 180, 147, 133, 234, 74, 200, |
2797 | 1 | 99, 229, 252, 149, 165, 195, 199, 234, 161, 6, 113, 81, 56, 227, 45, 128, 29, 178, |
2798 | 1 | 129, 32, 10, 186, 203, 184, 188, 6, 183, 32, 121, 233, 33, 112, 78, 112, 127, 48, |
2799 | 1 | 148, 193, 150, 121, 179, 99, 215, 156, 151, 139, 141, 145, 128, 114, 94, 183, 175, |
2800 | 1 | 148, 171, 242, 89, 167, 215, 218, 223, 239, 252, 253, 218, 157, 126, 198, 216, 63, |
2801 | 1 | 161, 5, 226, 107, 198, 213, 77, 105, 237, 60, 231, 128, 146, 36, 115, 27, 55, 237, |
2802 | 1 | 145, 44, 183, 4, 33, 201, 99, 237, 209, 235, 51, 106, 32, 213, 60, 9, 57, 182, 163, |
2803 | 1 | 245, 218, 234, 214, 107, 72, 242, 128, 162, 235, 64, 202, 177, 4, 47, 105, 143, 29, |
2804 | 1 | 38, 120, 14, 67, 176, 125, 244, 10, 216, 118, 11, 93, 134, 224, 125, 142, 240, 233, |
2805 | 1 | 108, 201, 224, 207, 128, 63, 198, 192, 19, 206, 71, 211, 171, 29, 74, 196, 95, 31, |
2806 | 1 | 187, 133, 183, 47, 183, 176, 84, 169, 3, 42, 223, 149, 19, 233, 128, 83, 40, 252, |
2807 | 1 | 149, 177, 4, 128, 234, 228, 128, 30, 192, 20, 87, 223, 121, 117, 244, 12, 227, 43, |
2808 | 1 | 102, 15, 250, 107, 29, 11, 164, 34, 194, 100, 22, 251, 230, 189, 28, 194, 232, 239, |
2809 | 1 | 208, 109, 179, 128, 245, 49, 114, 67, 254, 41, 251, 194, 12, 135, 47, 129, 20, 234, |
2810 | 1 | 214, 223, 181, 61, 49, 139, 82, 49, 250, 231, 213, 150, 67, 157, 196, 187, 136, |
2811 | 1 | 118, 128, 194, 40, 244, 203, 244, 205, 138, 233, 198, 213, 95, 72, 209, 159, 238, |
2812 | 1 | 126, 58, 56, 210, 147, 36, 99, 105, 52, 19, 143, 206, 177, 46, 227, 171, 125, 128, |
2813 | 1 | 125, 52, 140, 94, 44, 150, 105, 198, 134, 67, 46, 16, 113, 105, 73, 216, 251, 21, |
2814 | 1 | 84, 3, 144, 253, 155, 49, 140, 47, 54, 115, 90, 210, 18, 99, 128, 142, 79, 4, 216, |
2815 | 1 | 6, 26, 125, 208, 110, 30, 57, 119, 142, 84, 7, 153, 213, 143, 132, 236, 80, 248, |
2816 | 1 | 155, 52, 70, 47, 20, 100, 175, 110, 122, 182, 128, 14, 19, 178, 216, 105, 190, 191, |
2817 | 1 | 175, 69, 45, 180, 143, 169, 26, 52, 215, 129, 11, 209, 254, 128, 143, 96, 96, 34, |
2818 | 1 | 136, 66, 49, 61, 94, 37, 106, 128, 253, 12, 65, 64, 173, 144, 225, 238, 44, 180, |
2819 | 1 | 157, 203, 71, 242, 142, 198, 73, 88, 85, 157, 189, 223, 217, 67, 145, 51, 136, 209, |
2820 | 1 | 14, 131, 21, 183, 128, 1, 228, 69, 51, 15, 139, 33, 195, 6, 150, 124, 69, 163, 159, |
2821 | 1 | 163, 217, 65, 94, 73, 99, 53, 26, 42, 116, 171, 217, 47, 83, 198, 75, 8, 210, 128, |
2822 | 1 | 154, 20, 228, 242, 115, 4, 10, 154, 14, 146, 120, 127, 89, 0, 161, 117, 93, 251, |
2823 | 1 | 212, 215, 200, 84, 147, 215, 4, 189, 35, 116, 105, 52, 226, 31, 61, 6, 128, 249, |
2824 | 1 | 221, 128, 180, 85, 74, 252, 209, 157, 27, 180, 238, 3, 30, 76, 123, 36, 252, 208, |
2825 | 1 | 206, 83, 184, 195, 81, 13, 46, 142, 251, 46, 24, 79, 164, 216, 122, 242, 128, 11, |
2826 | 1 | 108, 238, 99, 155, 87, 3, 218, 158, 188, 173, 127, 101, 29, 16, 76, 82, 248, 56, |
2827 | 1 | 98, 110, 247, 10, 64, 31, 171, 69, 166, 73, 247, 105, 55, 128, 147, 129, 191, 107, |
2828 | 1 | 161, 132, 34, 44, 206, 215, 213, 223, 58, 65, 11, 206, 108, 25, 6, 216, 50, 69, 64, |
2829 | 1 | 246, 161, 161, 135, 214, 136, 249, 79, 124, 128, 22, 202, 150, 185, 135, 85, 34, |
2830 | 1 | 195, 57, 106, 179, 72, 74, 14, 194, 212, 173, 146, 143, 114, 63, 130, 210, 96, 204, |
2831 | 1 | 198, 96, 170, 12, 98, 22, 238, 128, 28, 52, 38, 67, 57, 118, 69, 240, 231, 243, 50, |
2832 | 1 | 189, 86, 169, 92, 46, 155, 251, 202, 130, 176, 3, 107, 32, 7, 222, 180, 209, 118, |
2833 | 1 | 229, 116, 23, 128, 78, 218, 168, 114, 74, 158, 137, 46, 169, 173, 112, 36, 99, 71, |
2834 | 1 | 116, 161, 41, 189, 188, 42, 214, 80, 115, 18, 78, 48, 230, 169, 8, 139, 245, 58, |
2835 | 1 | 128, 189, 8, 116, 87, 219, 183, 63, 54, 25, 77, 96, 237, 94, 161, 119, 46, 64, 33, |
2836 | 1 | 129, 125, 212, 1, 232, 127, 86, 76, 60, 41, 98, 159, 213, 234, 128, 148, 126, 164, |
2837 | 1 | 165, 2, 122, 13, 215, 242, 8, 55, 234, 20, 129, 243, 30, 41, 84, 176, 34, 51, 44, |
2838 | 1 | 190, 34, 16, 144, 186, 184, 166, 175, 218, 43, 128, 217, 86, 38, 63, 245, 2, 107, |
2839 | 1 | 173, 167, 63, 196, 63, 106, 18, 224, 57, 210, 1, 80, 98, 99, 209, 225, 17, 194, |
2840 | 1 | 186, 33, 227, 82, 215, 38, 227, 128, 23, 167, 5, 28, 95, 175, 89, 158, 228, 226, |
2841 | 1 | 55, 133, 75, 142, 98, 105, 246, 154, 97, 107, 75, 109, 244, 117, 130, 13, 192, 89, |
2842 | 1 | 133, 82, 33, 86, 128, 77, 176, 165, 88, 154, 196, 248, 147, 230, 51, 162, 162, 25, |
2843 | 1 | 21, 10, 253, 96, 27, 199, 236, 128, 11, 254, 36, 130, 175, 48, 71, 175, 44, 99, |
2844 | 1 | 254, 128, 21, 233, 211, 129, 106, 250, 141, 55, 14, 77, 44, 53, 154, 204, 233, 79, |
2845 | 1 | 2, 249, 229, 227, 126, 67, 173, 64, 101, 44, 65, 223, 207, 244, 162, 168, 77, 8, |
2846 | 1 | 128, 255, 255, 128, 255, 118, 170, 229, 83, 22, 64, 237, 172, 100, 35, 56, 139, |
2847 | 1 | 238, 143, 61, 205, 215, 239, 27, 67, 96, 215, 3, 165, 31, 232, 216, 152, 225, 64, |
2848 | 1 | 43, 128, 167, 136, 241, 115, 2, 128, 17, 236, 0, 253, 3, 41, 149, 31, 61, 136, 44, |
2849 | 1 | 177, 91, 231, 167, 239, 179, 205, 53, 70, 255, 10, 249, 255, 39, 226, 128, 58, 22, |
2850 | 1 | 172, 241, 130, 27, 64, 145, 25, 6, 130, 207, 165, 179, 133, 205, 152, 222, 86, 12, |
2851 | 1 | 117, 54, 202, 10, 6, 44, 238, 132, 110, 14, 121, 149, 128, 40, 124, 213, 32, 210, |
2852 | 1 | 230, 3, 164, 115, 137, 85, 145, 110, 7, 20, 255, 77, 37, 245, 126, 135, 122, 135, |
2853 | 1 | 192, 62, 177, 217, 39, 188, 199, 186, 67, 128, 25, 87, 33, 113, 242, 130, 9, 27, |
2854 | 1 | 90, 241, 90, 28, 219, 92, 177, 185, 57, 43, 68, 160, 2, 125, 68, 6, 52, 172, 25, |
2855 | 1 | 86, 247, 180, 120, 237, 128, 222, 78, 240, 70, 19, 23, 177, 18, 221, 208, 146, 217, |
2856 | 1 | 255, 207, 220, 10, 44, 135, 91, 164, 82, 88, 120, 208, 148, 204, 255, 249, 237, |
2857 | 1 | 174, 185, 0, 128, 99, 120, 25, 105, 78, 116, 66, 208, 159, 241, 145, 207, 81, 158, |
2858 | 1 | 6, 227, 18, 36, 164, 107, 182, 15, 18, 76, 111, 62, 31, 172, 207, 7, 61, 250, 128, |
2859 | 1 | 84, 224, 106, 171, 118, 226, 77, 102, 191, 95, 180, 7, 212, 255, 213, 82, 222, 166, |
2860 | 1 | 228, 182, 131, 242, 79, 32, 107, 165, 50, 133, 199, 128, 206, 131, 128, 158, 214, |
2861 | 1 | 255, 19, 20, 17, 64, 1, 63, 38, 248, 57, 90, 199, 13, 49, 163, 43, 194, 21, 18, 89, |
2862 | 1 | 133, 140, 10, 61, 244, 176, 45, 176, 240, 60, 128, 48, 213, 11, 228, 208, 79, 171, |
2863 | 1 | 81, 48, 28, 111, 22, 128, 99, 191, 73, 198, 110, 53, 57, 252, 239, 38, 156, 95, |
2864 | 1 | 167, 245, 155, 182, 214, 199, 74, 128, 144, 105, 144, 251, 167, 27, 20, 190, 249, |
2865 | 1 | 250, 75, 198, 52, 125, 187, 215, 140, 10, 189, 206, 92, 58, 171, 114, 161, 110, 0, |
2866 | 1 | 113, 235, 167, 36, 166, 128, 110, 83, 70, 17, 15, 10, 115, 95, 148, 208, 4, 113, |
2867 | 1 | 172, 107, 65, 43, 100, 123, 114, 201, 204, 108, 186, 198, 248, 202, 189, 174, 10, |
2868 | 1 | 81, 174, 149, 128, 231, 188, 123, 44, 107, 161, 10, 166, 138, 71, 163, 179, 24, |
2869 | 1 | 201, 106, 11, 251, 84, 166, 95, 252, 10, 243, 173, 246, 221, 99, 248, 155, 166, 7, |
2870 | 1 | 146, 128, 181, 234, 93, 109, 13, 71, 78, 181, 27, 27, 219, 117, 38, 212, 156, 15, |
2871 | 1 | 132, 7, 224, 81, 168, 150, 23, 218, 71, 184, 124, 23, 209, 115, 49, 213, 128, 122, |
2872 | 1 | 80, 119, 174, 137, 36, 36, 123, 244, 180, 235, 71, 24, 6, 253, 45, 87, 227, 51, |
2873 | 1 | 125, 181, 34, 100, 96, 147, 4, 129, 250, 12, 165, 191, 24, 128, 206, 193, 11, 221, |
2874 | 1 | 45, 101, 107, 193, 70, 96, 196, 168, 174, 64, 231, 107, 42, 210, 201, 237, 100, 49, |
2875 | 1 | 71, 4, 111, 216, 222, 107, 135, 224, 169, 81, 153, 3, 145, 3, 162, 138, 86, 150, |
2876 | 1 | 44, 139, 95, 167, 30, 228, 53, 164, 168, 224, 114, 19, 21, 191, 221, 102, 164, 103, |
2877 | 1 | 241, 200, 115, 238, 239, 58, 174, 29, 89, 137, 254, 0, 98, 1, 59, 215, 12, 13, 239, |
2878 | 1 | 25, 179, 210, 218, 45, 23, 154, 117, 64, 126, 173, 129, 59, 24, 57, 130, 111, 247, |
2879 | 1 | 27, 70, 96, 208, 162, 101, 152, 38, 51, 142, 34, 26, 234, 50, 144, 93, 56, 207, |
2880 | 1 | 226, 56, 145, 166, 252, 75, 215, 132, 55, 202, 178, 147, 90, 227, 157, 22, 243, |
2881 | 1 | 121, 50, 214, 179, 184, 167, 12, 6, 97, 117, 114, 97, 32, 93, 197, 113, 8, 0, 0, 0, |
2882 | 1 | 0, 4, 82, 80, 83, 82, 144, 75, 250, 140, 1, 140, 228, 232, 40, 215, 89, 136, 114, |
2883 | 1 | 235, 90, 147, 241, 47, 215, 198, 210, 92, 196, 192, 0, 100, 222, 229, 179, 161, 43, |
2884 | 1 | 112, 56, 10, 170, 231, 4, 5, 97, 117, 114, 97, 1, 1, 194, 46, 241, 223, 37, 26, 13, |
2885 | 1 | 157, 119, 240, 86, 215, 13, 134, 172, 102, 246, 136, 29, 133, 40, 78, 57, 208, 150, |
2886 | 1 | 43, 8, 118, 107, 9, 179, 47, 74, 146, 171, 225, 233, 152, 27, 110, 172, 92, 136, |
2887 | 1 | 171, 71, 122, 191, 58, 157, 49, 95, 124, 16, 92, 34, 132, 167, 8, 238, 181, 98, |
2888 | 1 | 150, 192, 130, 189, 2, 157, 0, 127, 3, 207, 220, 229, 134, 48, 16, 20, 112, 14, 44, |
2889 | 1 | 37, 147, 209, 192, 128, 99, 130, 139, 212, 253, 194, 223, 190, 188, 45, 122, 119, |
2890 | 1 | 27, 226, 20, 82, 45, 241, 81, 192, 56, 1, 226, 249, 192, 242, 243, 168, 232, 84, |
2891 | 1 | 120, 81, 80, 95, 14, 123, 144, 18, 9, 107, 65, 196, 235, 58, 175, 148, 127, 110, |
2892 | 1 | 164, 41, 8, 1, 0, 104, 95, 13, 158, 243, 183, 138, 253, 218, 183, 245, 199, 20, 33, |
2893 | 1 | 49, 19, 42, 212, 32, 207, 0, 0, 0, 0, 0, 0, 0, 88, 95, 2, 39, 95, 100, 195, 84, |
2894 | 1 | 149, 67, 82, 183, 30, 234, 57, 207, 172, 162, 16, 207, 0, 0, 0, 76, 95, 14, 194, |
2895 | 1 | 209, 122, 118, 21, 63, 245, 24, 23, 241, 45, 156, 252, 60, 127, 4, 0, 128, 210, |
2896 | 1 | 112, 94, 214, 251, 66, 130, 230, 12, 155, 251, 60, 239, 181, 241, 193, 221, 103, |
2897 | 1 | 67, 67, 139, 9, 136, 172, 94, 48, 76, 189, 199, 210, 103, 130, 65, 5, 157, 13, 160, |
2898 | 1 | 92, 165, 153, 19, 188, 56, 168, 99, 5, 144, 242, 98, 124, 23, 221, 128, 235, 218, |
2899 | 1 | 69, 149, 51, 230, 33, 211, 122, 83, 80, 36, 206, 81, 13, 38, 45, 225, 119, 62, 142, |
2900 | 1 | 85, 217, 45, 165, 64, 27, 108, 212, 215, 99, 118, 128, 215, 160, 27, 76, 203, 39, |
2901 | 1 | 127, 179, 185, 28, 239, 170, 10, 154, 42, 4, 61, 56, 185, 142, 235, 109, 25, 1, 47, |
2902 | 1 | 212, 163, 112, 46, 243, 155, 160, 128, 223, 235, 36, 18, 78, 176, 46, 144, 13, 76, |
2903 | 1 | 89, 236, 141, 232, 67, 120, 107, 119, 50, 232, 34, 158, 249, 180, 211, 86, 249, |
2904 | 1 | 236, 108, 85, 218, 49, 80, 95, 14, 123, 144, 18, 9, 107, 65, 196, 235, 58, 175, |
2905 | 1 | 148, 127, 110, 164, 41, 8, 0, 0, 128, 175, 27, 91, 41, 56, 123, 217, 235, 140, 40, |
2906 | 1 | 154, 154, 131, 67, 14, 139, 197, 214, 184, 49, 29, 90, 126, 165, 192, 126, 25, 232, |
2907 | 1 | 124, 194, 250, 214, 128, 202, 206, 27, 75, 192, 204, 77, 23, 16, 132, 253, 121, |
2908 | 1 | 192, 36, 168, 220, 254, 176, 118, 161, 55, 152, 228, 130, 186, 2, 142, 227, 190, |
2909 | 1 | 187, 36, 105, 128, 192, 179, 170, 134, 175, 231, 116, 99, 173, 194, 140, 108, 52, |
2910 | 1 | 199, 26, 32, 14, 56, 136, 199, 37, 49, 68, 152, 69, 203, 27, 206, 111, 61, 139, |
2911 | 1 | 228, 128, 181, 68, 170, 52, 178, 44, 140, 224, 101, 215, 226, 128, 212, 109, 10, |
2912 | 1 | 247, 51, 254, 137, 7, 166, 201, 110, 184, 210, 114, 21, 107, 227, 126, 240, 184, |
2913 | 1 | 128, 109, 170, 53, 136, 243, 42, 150, 87, 60, 116, 224, 215, 52, 68, 196, 100, 124, |
2914 | 1 | 107, 210, 178, 113, 155, 11, 119, 22, 177, 29, 92, 142, 100, 77, 215, 128, 175, 40, |
2915 | 1 | 224, 205, 230, 174, 216, 159, 254, 225, 44, 16, 114, 144, 188, 126, 189, 164, 180, |
2916 | 1 | 199, 245, 46, 79, 156, 187, 174, 101, 19, 23, 215, 122, 222, 217, 4, 158, 113, 11, |
2917 | 1 | 48, 189, 46, 171, 3, 82, 221, 204, 38, 65, 122, 161, 148, 95, 195, 128, 54, 12, |
2918 | 1 | 152, 205, 41, 31, 105, 121, 83, 249, 212, 18, 255, 77, 10, 241, 133, 237, 25, 115, |
2919 | 1 | 37, 151, 216, 231, 186, 183, 152, 39, 151, 90, 117, 176, 128, 228, 96, 161, 133, |
2920 | 1 | 29, 55, 248, 183, 48, 239, 220, 221, 40, 33, 7, 101, 201, 211, 204, 85, 1, 57, 91, |
2921 | 1 | 242, 41, 243, 224, 59, 182, 112, 25, 225, 128, 204, 80, 126, 60, 36, 231, 38, 92, |
2922 | 1 | 39, 86, 213, 234, 91, 14, 178, 139, 215, 62, 83, 228, 109, 178, 146, 170, 185, 167, |
2923 | 1 | 212, 87, 246, 138, 45, 107, 128, 73, 168, 238, 216, 159, 171, 151, 84, 227, 213, |
2924 | 1 | 21, 93, 37, 214, 244, 3, 162, 0, 100, 139, 203, 229, 187, 176, 59, 227, 3, 13, 153, |
2925 | 1 | 220, 223, 190, 80, 95, 14, 123, 144, 18, 9, 107, 65, 196, 235, 58, 175, 148, 127, |
2926 | 1 | 110, 164, 41, 8, 0, 0, 76, 95, 3, 199, 22, 251, 143, 255, 61, 230, 26, 136, 59, |
2927 | 1 | 183, 106, 219, 52, 162, 4, 0, 128, 79, 178, 157, 255, 221, 251, 231, 183, 195, 168, |
2928 | 1 | 1, 228, 242, 43, 144, 78, 112, 207, 182, 129, 243, 116, 39, 6, 238, 0, 69, 165, 43, |
2929 | 1 | 12, 177, 186, 76, 95, 15, 73, 147, 240, 22, 226, 210, 248, 229, 244, 59, 231, 187, |
2930 | 1 | 37, 148, 134, 4, 0, 128, 70, 54, 90, 216, 167, 133, 150, 112, 51, 167, 114, 22, |
2931 | 1 | 158, 185, 150, 66, 119, 69, 225, 19, 165, 184, 253, 41, 194, 213, 100, 182, 150, |
2932 | 1 | 244, 1, 237, 128, 154, 129, 32, 100, 133, 127, 1, 135, 127, 54, 123, 4, 77, 41, |
2933 | 1 | 133, 103, 244, 73, 44, 156, 224, 93, 187, 54, 182, 227, 156, 183, 90, 69, 211, 140, |
2934 | 1 | 5, 8, 158, 127, 239, 196, 8, 170, 197, 157, 191, 232, 10, 114, 172, 142, 60, 229, |
2935 | 1 | 251, 255, 128, 28, 144, 44, 190, 65, 158, 124, 234, 117, 177, 217, 113, 203, 191, |
2936 | 1 | 145, 215, 51, 215, 17, 241, 52, 48, 113, 98, 225, 53, 156, 248, 93, 2, 151, 22, |
2937 | 1 | 128, 246, 44, 225, 89, 41, 109, 48, 176, 151, 95, 167, 3, 200, 131, 53, 222, 234, |
2938 | 1 | 250, 190, 60, 4, 127, 89, 243, 125, 238, 165, 212, 183, 77, 11, 209, 128, 108, 106, |
2939 | 1 | 239, 252, 123, 178, 214, 53, 172, 161, 230, 103, 212, 45, 206, 237, 155, 51, 115, |
2940 | 1 | 7, 202, 248, 65, 246, 67, 239, 177, 115, 205, 182, 160, 92, 128, 153, 49, 60, 253, |
2941 | 1 | 8, 247, 69, 74, 78, 37, 77, 7, 70, 124, 114, 75, 142, 31, 138, 32, 252, 170, 184, |
2942 | 1 | 231, 149, 235, 226, 10, 194, 239, 201, 139, 128, 163, 142, 44, 229, 147, 62, 192, |
2943 | 1 | 83, 7, 252, 110, 17, 248, 37, 146, 214, 46, 130, 54, 218, 34, 167, 116, 105, 149, |
2944 | 1 | 97, 133, 153, 192, 222, 20, 150, 128, 44, 212, 228, 232, 140, 23, 26, 9, 155, 125, |
2945 | 1 | 236, 180, 181, 135, 7, 16, 254, 185, 55, 57, 35, 187, 112, 91, 60, 71, 243, 214, |
2946 | 1 | 76, 69, 95, 49, 128, 36, 154, 200, 132, 247, 87, 96, 128, 121, 116, 94, 200, 68, |
2947 | 1 | 172, 209, 130, 65, 30, 91, 188, 131, 189, 246, 112, 250, 110, 82, 23, 26, 22, 158, |
2948 | 1 | 255, 128, 255, 55, 48, 36, 110, 69, 118, 46, 155, 67, 245, 213, 209, 82, 61, 122, |
2949 | 1 | 87, 99, 232, 50, 134, 158, 207, 141, 13, 182, 55, 31, 245, 114, 138, 0, 128, 84, |
2950 | 1 | 15, 134, 102, 153, 61, 75, 192, 41, 59, 118, 134, 14, 151, 178, 127, 253, 250, 164, |
2951 | 1 | 236, 16, 186, 195, 72, 35, 244, 46, 79, 60, 79, 181, 250, 128, 125, 177, 42, 23, |
2952 | 1 | 178, 140, 13, 11, 255, 231, 201, 197, 34, 202, 100, 42, 145, 237, 73, 158, 220, |
2953 | 1 | 175, 49, 235, 152, 56, 239, 130, 163, 95, 118, 168, 128, 157, 153, 151, 253, 244, |
2954 | 1 | 225, 184, 5, 16, 39, 191, 124, 108, 79, 221, 134, 216, 1, 190, 177, 204, 96, 197, |
2955 | 1 | 60, 17, 134, 144, 72, 206, 47, 27, 77, 128, 120, 188, 171, 32, 209, 114, 55, 254, |
2956 | 1 | 60, 149, 200, 80, 72, 100, 59, 142, 234, 198, 169, 179, 151, 76, 170, 7, 19, 226, |
2957 | 1 | 8, 228, 21, 213, 186, 207, 128, 46, 3, 210, 197, 241, 213, 203, 87, 67, 242, 55, |
2958 | 1 | 221, 56, 18, 59, 218, 83, 84, 234, 179, 181, 107, 31, 106, 69, 121, 253, 210, 144, |
2959 | 1 | 106, 36, 186, 128, 74, 7, 238, 205, 130, 97, 184, 42, 47, 66, 224, 74, 129, 129, |
2960 | 1 | 168, 176, 128, 42, 189, 32, 127, 1, 26, 215, 51, 193, 32, 167, 192, 142, 143, 12, |
2961 | 1 | 128, 216, 70, 54, 152, 177, 220, 44, 147, 187, 142, 216, 215, 30, 8, 181, 223, 133, |
2962 | 1 | 59, 216, 99, 111, 114, 83, 171, 112, 52, 2, 48, 199, 177, 66, 13, 125, 5, 158, 182, |
2963 | 1 | 243, 110, 2, 122, 187, 32, 145, 207, 181, 17, 10, 181, 8, 127, 249, 110, 104, 95, |
2964 | 1 | 6, 21, 91, 60, 217, 168, 201, 229, 233, 162, 63, 213, 220, 19, 165, 237, 32, 188, |
2965 | 1 | 138, 227, 16, 0, 0, 0, 0, 104, 95, 8, 49, 108, 191, 143, 160, 218, 130, 42, 32, |
2966 | 1 | 172, 28, 85, 191, 27, 227, 32, 196, 135, 0, 0, 0, 0, 0, 0, 80, 95, 14, 123, 144, |
2967 | 1 | 18, 9, 107, 65, 196, 235, 58, 175, 148, 127, 110, 164, 41, 8, 0, 0, 128, 234, 178, |
2968 | 1 | 184, 124, 57, 146, 78, 36, 216, 223, 24, 129, 215, 19, 19, 190, 46, 219, 54, 192, |
2969 | 1 | 222, 245, 96, 143, 196, 192, 128, 203, 127, 238, 98, 80, 128, 157, 63, 215, 146, |
2970 | 1 | 117, 166, 140, 220, 174, 150, 5, 77, 118, 79, 113, 140, 216, 205, 207, 202, 255, |
2971 | 1 | 186, 88, 88, 134, 71, 167, 53, 109, 154, 73, 120, 128, 63, 155, 5, 255, 94, 126, |
2972 | 1 | 80, 205, 113, 90, 219, 210, 115, 53, 4, 152, 14, 225, 112, 21, 79, 129, 9, 131, |
2973 | 1 | 181, 216, 150, 18, 36, 65, 21, 11, 128, 13, 73, 254, 240, 57, 81, 124, 195, 18, |
2974 | 1 | 192, 4, 18, 128, 60, 161, 223, 80, 172, 109, 144, 197, 5, 65, 246, 73, 169, 200, |
2975 | 1 | 91, 131, 192, 253, 216, 128, 2, 228, 22, 252, 234, 152, 215, 177, 232, 223, 73, 56, |
2976 | 1 | 119, 185, 48, 114, 236, 202, 168, 96, 228, 42, 8, 26, 128, 215, 131, 30, 113, 167, |
2977 | 1 | 70, 73, 128, 252, 251, 236, 40, 80, 81, 28, 11, 152, 150, 255, 68, 115, 104, 164, |
2978 | 1 | 219, 25, 193, 89, 177, 30, 210, 59, 99, 197, 154, 142, 55, 84, 198, 138, 93, 128, |
2979 | 1 | 105, 249, 88, 224, 100, 223, 75, 194, 147, 154, 226, 255, 242, 208, 63, 227, 182, |
2980 | 1 | 150, 255, 184, 151, 87, 53, 25, 242, 184, 51, 182, 158, 165, 83, 22, 104, 95, 9, |
2981 | 1 | 14, 47, 191, 45, 121, 44, 179, 36, 191, 250, 148, 39, 254, 31, 14, 32, 191, 230, |
2982 | 1 | 57, 1, 23, 233, 57, 1, 113, 1, 158, 222, 61, 138, 84, 210, 126, 68, 169, 213, 206, |
2983 | 1 | 24, 150, 24, 242, 45, 48, 8, 80, 95, 14, 123, 144, 18, 9, 107, 65, 196, 235, 58, |
2984 | 1 | 175, 148, 127, 110, 164, 41, 8, 9, 0, 76, 95, 3, 180, 18, 59, 46, 24, 110, 7, 251, |
2985 | 1 | 123, 173, 93, 218, 95, 85, 192, 4, 0, 128, 114, 115, 217, 102, 145, 229, 217, 201, |
2986 | 1 | 199, 191, 227, 81, 211, 103, 201, 176, 171, 162, 94, 209, 255, 178, 61, 163, 165, |
2987 | 1 | 157, 75, 84, 151, 146, 162, 18, 213, 1, 158, 247, 140, 152, 114, 61, 220, 144, 115, |
2988 | 1 | 82, 62, 243, 190, 239, 218, 12, 16, 68, 128, 189, 101, 232, 147, 82, 103, 131, 19, |
2989 | 1 | 218, 118, 10, 120, 104, 104, 121, 77, 44, 232, 221, 203, 185, 65, 18, 246, 246, 69, |
2990 | 1 | 199, 220, 163, 233, 180, 239, 128, 226, 131, 165, 241, 12, 111, 138, 139, 108, 197, |
2991 | 1 | 180, 249, 115, 81, 167, 161, 77, 56, 73, 103, 232, 179, 125, 193, 114, 144, 231, |
2992 | 1 | 203, 129, 59, 93, 75, 128, 154, 128, 37, 9, 95, 15, 177, 207, 18, 248, 59, 39, 153, |
2993 | 1 | 17, 5, 8, 169, 210, 187, 48, 96, 236, 156, 128, 94, 211, 157, 72, 61, 24, 203, 203, |
2994 | 1 | 21, 7, 159, 1, 43, 116, 109, 207, 50, 232, 67, 53, 69, 131, 201, 112, 44, 192, 32, |
2995 | 1 | 249, 255, 92, 87, 2, 166, 252, 145, 92, 204, 85, 160, 48, 8, 0, 0, 36, 8, 208, 7, |
2996 | 1 | 0, 0, 215, 7, 0, 0, 128, 191, 173, 201, 187, 178, 195, 202, 43, 56, 205, 17, 183, |
2997 | 1 | 37, 176, 244, 26, 77, 8, 42, 84, 45, 184, 54, 123, 224, 193, 73, 17, 232, 188, 102, |
2998 | 1 | 142, 128, 192, 202, 163, 161, 148, 16, 137, 217, 105, 73, 69, 240, 100, 255, 246, |
2999 | 1 | 205, 84, 130, 249, 228, 158, 205, 148, 235, 11, 196, 152, 92, 220, 185, 244, 59, |
3000 | 1 | 128, 13, 147, 166, 123, 17, 250, 116, 106, 207, 108, 92, 127, 169, 181, 143, 82, |
3001 | 1 | 145, 18, 130, 76, 21, 113, 68, 191, 43, 178, 33, 124, 207, 18, 72, 90, 128, 90, 59, |
3002 | 1 | 55, 239, 198, 24, 19, 237, 211, 132, 30, 45, 48, 146, 153, 200, 155, 146, 163, 17, |
3003 | 1 | 24, 78, 6, 95, 244, 75, 72, 173, 141, 161, 245, 255, 108, 87, 7, 61, 229, 152, 2, |
3004 | 1 | 222, 70, 55, 232, 7, 0, 0, 52, 12, 208, 7, 0, 0, 215, 7, 0, 0, 37, 8, 0, 0, 108, |
3005 | 1 | 87, 12, 88, 243, 181, 152, 155, 183, 44, 223, 7, 0, 0, 52, 12, 208, 7, 0, 0, 209, |
3006 | 1 | 7, 0, 0, 231, 7, 0, 0, 128, 119, 15, 117, 76, 101, 140, 192, 56, 249, 91, 82, 13, |
3007 | 1 | 27, 30, 77, 0, 193, 8, 119, 228, 130, 190, 89, 43, 134, 133, 250, 139, 167, 203, |
3008 | 1 | 87, 248, 128, 233, 136, 149, 201, 192, 255, 191, 151, 198, 89, 86, 186, 39, 44, 34, |
3009 | 1 | 136, 122, 163, 84, 104, 67, 76, 159, 133, 225, 225, 56, 29, 49, 225, 227, 129, 128, |
3010 | 1 | 202, 252, 231, 61, 108, 226, 138, 114, 128, 28, 137, 227, 14, 176, 251, 249, 55, |
3011 | 1 | 252, 1, 120, 38, 108, 112, 249, 94, 97, 101, 206, 120, 211, 173, 177, 128, 35, 156, |
3012 | 1 | 52, 249, 202, 144, 19, 104, 137, 129, 10, 32, 51, 112, 158, 91, 207, 125, 15, 15, |
3013 | 1 | 107, 214, 170, 152, 154, 6, 208, 222, 183, 99, 33, 222, 128, 79, 163, 220, 117, |
3014 | 1 | 100, 66, 203, 148, 165, 161, 21, 126, 226, 221, 222, 148, 213, 170, 88, 72, 244, |
3015 | 1 | 206, 224, 234, 79, 247, 174, 206, 174, 219, 208, 241, 128, 0, 167, 138, 177, 252, |
3016 | 1 | 250, 114, 63, 198, 244, 142, 149, 188, 250, 63, 73, 189, 141, 246, 2, 40, 246, 10, |
3017 | 1 | 151, 186, 187, 184, 15, 146, 69, 116, 28, 92, 87, 12, 115, 39, 162, 164, 139, 242, |
3018 | 1 | 177, 73, 8, 0, 0, 36, 8, 232, 3, 0, 0, 62, 8, 0, 0, 141, 8, 159, 6, 96, 76, 255, |
3019 | 1 | 130, 138, 110, 63, 87, 156, 166, 197, 154, 206, 1, 61, 255, 255, 128, 88, 34, 177, |
3020 | 1 | 184, 213, 127, 244, 100, 227, 20, 43, 255, 238, 85, 187, 132, 35, 16, 184, 254, 9, |
3021 | 1 | 172, 75, 93, 198, 229, 52, 222, 27, 159, 78, 138, 128, 35, 104, 172, 142, 63, 55, |
3022 | 1 | 220, 219, 0, 137, 47, 9, 105, 147, 19, 235, 9, 97, 128, 110, 93, 251, 231, 10, 141, |
3023 | 1 | 163, 45, 38, 98, 218, 53, 9, 128, 20, 148, 147, 139, 63, 200, 169, 174, 8, 196, 70, |
3024 | 1 | 95, 247, 30, 243, 121, 199, 168, 205, 187, 70, 119, 200, 90, 249, 242, 192, 82, |
3025 | 1 | 203, 177, 184, 14, 128, 100, 239, 8, 116, 141, 156, 46, 29, 171, 233, 15, 224, 107, |
3026 | 1 | 135, 25, 70, 226, 97, 146, 12, 227, 173, 48, 221, 88, 141, 194, 15, 186, 105, 51, |
3027 | 1 | 196, 128, 89, 52, 22, 50, 195, 242, 2, 81, 149, 157, 54, 165, 197, 251, 114, 73, |
3028 | 1 | 119, 203, 171, 174, 104, 172, 42, 202, 181, 211, 182, 193, 81, 87, 164, 80, 128, |
3029 | 1 | 234, 119, 182, 109, 207, 189, 182, 253, 167, 214, 134, 175, 134, 247, 158, 158, 50, |
3030 | 1 | 236, 45, 141, 105, 158, 224, 92, 191, 0, 170, 75, 205, 221, 206, 250, 128, 53, 200, |
3031 | 1 | 192, 186, 144, 133, 155, 224, 210, 23, 75, 245, 28, 124, 123, 114, 220, 84, 229, |
3032 | 1 | 54, 42, 95, 100, 152, 87, 35, 105, 247, 51, 43, 248, 208, 128, 172, 226, 42, 215, |
3033 | 1 | 90, 50, 155, 232, 38, 139, 227, 128, 250, 152, 98, 6, 199, 7, 254, 140, 196, 8, |
3034 | 1 | 249, 193, 162, 76, 16, 87, 40, 196, 142, 22, 128, 39, 186, 108, 112, 14, 204, 60, |
3035 | 1 | 28, 177, 228, 231, 69, 9, 135, 194, 220, 85, 131, 19, 66, 34, 237, 230, 201, 136, |
3036 | 1 | 226, 39, 147, 68, 39, 234, 161, 128, 30, 209, 132, 153, 155, 209, 178, 175, 52, |
3037 | 1 | 164, 50, 135, 204, 114, 12, 240, 95, 105, 105, 113, 69, 117, 238, 249, 99, 15, 94, |
3038 | 1 | 231, 6, 212, 16, 133, 128, 18, 2, 203, 171, 83, 213, 43, 159, 23, 227, 82, 144, 32, |
3039 | 1 | 250, 203, 55, 71, 244, 162, 232, 244, 150, 250, 234, 82, 106, 27, 18, 234, 175, 92, |
3040 | 1 | 148, 128, 124, 209, 245, 55, 225, 115, 72, 162, 126, 5, 220, 119, 95, 153, 123, 15, |
3041 | 1 | 43, 118, 187, 223, 102, 192, 39, 165, 179, 215, 52, 197, 85, 5, 193, 126, 128, 51, |
3042 | 1 | 198, 32, 189, 209, 207, 75, 13, 206, 20, 250, 216, 154, 146, 12, 175, 150, 110, 78, |
3043 | 1 | 39, 158, 250, 51, 90, 213, 32, 120, 30, 114, 148, 90, 206, 128, 204, 79, 197, 114, |
3044 | 1 | 176, 171, 2, 117, 103, 86, 27, 180, 29, 123, 49, 95, 118, 130, 216, 244, 65, 183, |
3045 | 1 | 205, 211, 76, 63, 160, 119, 244, 235, 203, 199, 128, 29, 240, 183, 179, 22, 161, |
3046 | 1 | 72, 92, 46, 222, 121, 157, 73, 239, 44, 210, 25, 139, 141, 204, 71, 119, 50, 38, |
3047 | 1 | 219, 189, 174, 216, 155, 248, 246, 178, 128, 82, 66, 5, 36, 1, 152, 64, 229, 7, |
3048 | 1 | 151, 240, 170, 92, 157, 5, 7, 35, 136, 138, 147, 86, 86, 103, 75, 83, 75, 211, 96, |
3049 | 1 | 213, 204, 82, 94, 181, 5, 159, 10, 209, 87, 228, 97, 215, 31, 212, 193, 249, 54, |
3050 | 1 | 131, 154, 95, 31, 62, 248, 223, 128, 8, 239, 142, 226, 171, 84, 102, 207, 203, 226, |
3051 | 1 | 37, 28, 208, 170, 76, 158, 67, 180, 161, 90, 106, 41, 25, 235, 231, 140, 60, 239, |
3052 | 1 | 50, 59, 195, 122, 128, 69, 173, 217, 33, 87, 199, 182, 141, 63, 191, 226, 84, 216, |
3053 | 1 | 20, 195, 8, 97, 181, 103, 202, 26, 38, 30, 239, 38, 77, 208, 162, 31, 229, 160, |
3054 | 1 | 204, 88, 87, 12, 136, 67, 61, 248, 98, 219, 203, 36, 8, 0, 0, 32, 0, 0, 0, 0, 0, 0, |
3055 | 1 | 0, 0, 128, 241, 249, 14, 190, 36, 73, 117, 108, 170, 35, 138, 55, 164, 246, 34, |
3056 | 1 | 186, 164, 116, 86, 125, 93, 49, 120, 188, 132, 207, 77, 148, 244, 228, 169, 196, |
3057 | 1 | 88, 87, 7, 61, 229, 152, 2, 222, 70, 55, 232, 7, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, |
3058 | 1 | 88, 87, 12, 88, 243, 181, 152, 155, 183, 44, 223, 7, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, |
3059 | 1 | 0, 128, 164, 58, 156, 173, 184, 223, 50, 123, 208, 53, 97, 95, 147, 209, 204, 153, |
3060 | 1 | 113, 157, 163, 145, 19, 80, 42, 29, 212, 206, 111, 9, 157, 71, 229, 195, 128, 143, |
3061 | 1 | 111, 81, 33, 174, 228, 91, 78, 120, 142, 64, 197, 207, 73, 63, 217, 224, 190, 5, |
3062 | 1 | 24, 124, 206, 35, 177, 200, 97, 247, 188, 179, 177, 254, 175, 128, 129, 62, 59, |
3063 | 1 | 185, 49, 134, 240, 28, 171, 75, 99, 43, 168, 245, 135, 58, 18, 137, 133, 93, 58, |
3064 | 1 | 37, 141, 215, 74, 56, 194, 114, 206, 97, 118, 25, 128, 88, 140, 243, 244, 18, 6, |
3065 | 1 | 65, 63, 124, 109, 254, 63, 241, 216, 91, 239, 206, 3, 14, 254, 80, 163, 184, 232, |
3066 | 1 | 164, 69, 59, 135, 211, 174, 160, 239, 88, 87, 7, 59, 166, 27, 196, 215, 19, 53, 75, |
3067 | 1 | 8, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 88, 87, 12, 115, 39, 162, 164, 139, 242, 177, |
3068 | 1 | 73, 8, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 141, 8, 159, 11, 60, 37, 47, 203, 41, 216, |
3069 | 1 | 142, 255, 79, 61, 229, 222, 68, 118, 195, 255, 255, 128, 186, 2, 77, 251, 27, 119, |
3070 | 1 | 235, 204, 154, 30, 157, 205, 14, 70, 221, 206, 26, 248, 190, 53, 169, 248, 215, |
3071 | 1 | 102, 127, 22, 153, 170, 150, 60, 142, 83, 128, 88, 6, 112, 189, 244, 215, 89, 5, |
3072 | 1 | 182, 228, 216, 226, 33, 87, 51, 242, 11, 197, 224, 29, 155, 132, 126, 100, 62, 59, |
3073 | 1 | 239, 235, 137, 112, 39, 78, 128, 127, 124, 184, 126, 147, 179, 243, 220, 0, 93, 59, |
3074 | 1 | 10, 190, 112, 21, 62, 149, 241, 169, 121, 19, 21, 240, 140, 94, 116, 140, 138, 236, |
3075 | 1 | 15, 173, 201, 128, 76, 225, 117, 86, 242, 58, 129, 175, 101, 207, 121, 248, 236, |
3076 | 1 | 217, 110, 119, 134, 216, 29, 192, 60, 65, 35, 89, 88, 252, 119, 188, 104, 158, 57, |
3077 | 1 | 245, 128, 78, 169, 169, 255, 44, 134, 205, 245, 72, 154, 1, 166, 32, 106, 200, 68, |
3078 | 1 | 182, 249, 124, 40, 66, 84, 224, 147, 142, 125, 182, 80, 120, 26, 39, 31, 128, 146, |
3079 | 1 | 145, 193, 190, 216, 82, 98, 158, 17, 140, 164, 135, 114, 86, 194, 103, 31, 109, 18, |
3080 | 1 | 230, 232, 225, 175, 40, 53, 244, 200, 96, 209, 62, 72, 167, 128, 0, 180, 105, 140, |
3081 | 1 | 181, 228, 43, 43, 36, 205, 143, 131, 124, 205, 195, 5, 102, 154, 145, 186, 8, 67, |
3082 | 1 | 192, 26, 15, 199, 59, 101, 48, 0, 53, 245, 128, 161, 198, 218, 35, 203, 253, 34, |
3083 | 1 | 149, 177, 76, 200, 110, 177, 4, 7, 196, 233, 155, 9, 75, 109, 31, 34, 218, 78, 83, |
3084 | 1 | 241, 192, 254, 110, 255, 5, 128, 3, 0, 133, 165, 214, 107, 123, 40, 18, 43, 74, |
3085 | 1 | 150, 52, 160, 41, 93, 171, 126, 14, 148, 111, 49, 83, 9, 46, 2, 123, 175, 28, 110, |
3086 | 1 | 209, 6, 128, 146, 53, 91, 249, 190, 155, 223, 22, 203, 102, 253, 155, 173, 248, |
3087 | 1 | 175, 162, 6, 252, 191, 144, 153, 107, 173, 176, 200, 125, 51, 5, 15, 110, 47, 44, |
3088 | 1 | 128, 119, 230, 200, 24, 191, 194, 171, 95, 122, 99, 170, 120, 141, 31, 122, 89, 23, |
3089 | 1 | 82, 100, 61, 27, 213, 242, 96, 216, 32, 9, 228, 77, 144, 244, 222, 128, 101, 89, |
3090 | 1 | 78, 212, 192, 131, 159, 241, 123, 254, 208, 132, 135, 136, 91, 13, 208, 136, 99, |
3091 | 1 | 198, 149, 191, 65, 210, 60, 42, 41, 75, 254, 226, 146, 227, 128, 107, 3, 234, 138, |
3092 | 1 | 165, 154, 132, 211, 11, 43, 18, 123, 182, 92, 192, 8, 219, 216, 64, 227, 17, 191, |
3093 | 1 | 26, 143, 139, 104, 253, 10, 176, 26, 94, 250, 128, 59, 99, 238, 65, 153, 171, 231, |
3094 | 1 | 253, 38, 116, 1, 79, 48, 255, 135, 24, 227, 173, 198, 29, 51, 204, 9, 73, 107, 72, |
3095 | 1 | 209, 61, 184, 247, 88, 169, 128, 221, 252, 191, 99, 26, 254, 145, 5, 214, 101, 73, |
3096 | 1 | 64, 106, 200, 111, 44, 100, 241, 127, 95, 219, 37, 218, 105, 198, 122, 68, 51, 43, |
3097 | 1 | 167, 40, 170, 128, 140, 145, 45, 99, 142, 237, 10, 243, 177, 193, 53, 40, 10, 240, |
3098 | 1 | 6, 37, 224, 24, 159, 226, 99, 193, 200, 196, 5, 7, 170, 31, 206, 221, 0, 124, 1, 7, |
3099 | 1 | 159, 13, 55, 25, 245, 176, 177, 44, 113, 5, 192, 115, 197, 7, 68, 89, 72, 249, 255, |
3100 | 1 | 92, 87, 2, 166, 252, 145, 92, 204, 85, 160, 48, 8, 0, 0, 36, 8, 208, 7, 0, 0, 212, |
3101 | 1 | 7, 0, 0, 128, 183, 198, 226, 22, 113, 16, 232, 182, 81, 235, 105, 58, 91, 191, 184, |
3102 | 1 | 59, 111, 150, 128, 145, 71, 130, 34, 225, 54, 166, 131, 137, 242, 205, 56, 92, 128, |
3103 | 1 | 230, 8, 107, 64, 106, 147, 6, 19, 214, 240, 62, 77, 27, 186, 163, 108, 0, 197, 60, |
3104 | 1 | 23, 107, 89, 244, 217, 250, 99, 168, 55, 251, 12, 173, 232, 124, 87, 12, 136, 67, |
3105 | 1 | 61, 248, 98, 219, 203, 36, 8, 0, 0, 68, 16, 232, 3, 0, 0, 208, 7, 0, 0, 212, 7, 0, |
3106 | 1 | 0, 231, 7, 0, 0, 128, 90, 59, 55, 239, 198, 24, 19, 237, 211, 132, 30, 45, 48, 146, |
3107 | 1 | 153, 200, 155, 146, 163, 17, 24, 78, 6, 95, 244, 75, 72, 173, 141, 161, 245, 255, |
3108 | 1 | 92, 87, 7, 61, 229, 152, 2, 222, 70, 55, 232, 7, 0, 0, 36, 8, 208, 7, 0, 0, 37, 8, |
3109 | 1 | 0, 0, 108, 87, 12, 88, 243, 181, 152, 155, 183, 44, 223, 7, 0, 0, 52, 12, 208, 7, |
3110 | 1 | 0, 0, 209, 7, 0, 0, 231, 7, 0, 0, 128, 219, 215, 94, 9, 186, 191, 42, 25, 219, 63, |
3111 | 1 | 237, 243, 130, 215, 231, 161, 105, 120, 205, 2, 199, 129, 177, 204, 174, 40, 73, |
3112 | 1 | 194, 154, 96, 95, 21, 128, 111, 149, 146, 31, 227, 244, 8, 76, 50, 134, 158, 230, |
3113 | 1 | 167, 109, 179, 109, 44, 152, 38, 100, 166, 40, 134, 148, 105, 203, 101, 140, 132, |
3114 | 1 | 126, 190, 115, 128, 202, 252, 231, 61, 108, 226, 138, 114, 128, 28, 137, 227, 14, |
3115 | 1 | 176, 251, 249, 55, 252, 1, 120, 38, 108, 112, 249, 94, 97, 101, 206, 120, 211, 173, |
3116 | 1 | 177, 128, 151, 254, 128, 24, 142, 196, 104, 235, 142, 225, 114, 221, 194, 248, 166, |
3117 | 1 | 96, 100, 130, 240, 144, 88, 179, 252, 0, 52, 89, 107, 230, 40, 103, 171, 9, 128, |
3118 | 1 | 79, 163, 220, 117, 100, 66, 203, 148, 165, 161, 21, 126, 226, 221, 222, 148, 213, |
3119 | 1 | 170, 88, 72, 244, 206, 224, 234, 79, 247, 174, 206, 174, 219, 208, 241, 128, 0, |
3120 | 1 | 167, 138, 177, 252, 250, 114, 63, 198, 244, 142, 149, 188, 250, 63, 73, 189, 141, |
3121 | 1 | 246, 2, 40, 246, 10, 151, 186, 187, 184, 15, 146, 69, 116, 28, 92, 87, 12, 115, 39, |
3122 | 1 | 162, 164, 139, 242, 177, 73, 8, 0, 0, 36, 8, 232, 3, 0, 0, 62, 8, 0, 0, 65, 3, 191, |
3123 | 1 | 14, 2, 101, 108, 97, 121, 95, 100, 105, 115, 112, 97, 116, 99, 104, 95, 113, 117, |
3124 | 1 | 101, 117, 101, 95, 114, 101, 109, 97, 105, 110, 105, 110, 103, 95, 99, 97, 112, 97, |
3125 | 1 | 99, 105, 116, 121, 28, 96, 128, 143, 110, 43, 35, 129, 96, 51, 141, 9, 185, 119, |
3126 | 1 | 112, 66, 66, 63, 44, 8, 13, 37, 84, 87, 91, 139, 76, 130, 130, 96, 110, 145, 240, |
3127 | 1 | 178, 180, 128, 226, 41, 230, 56, 44, 176, 80, 88, 20, 90, 147, 106, 44, 51, 162, |
3128 | 1 | 142, 153, 138, 152, 251, 180, 169, 18, 62, 45, 81, 8, 165, 97, 59, 203, 199, 128, |
3129 | 1 | 70, 44, 111, 211, 18, 241, 216, 196, 138, 174, 50, 229, 189, 104, 102, 187, 131, |
3130 | 1 | 149, 71, 139, 163, 52, 195, 7, 32, 240, 53, 147, 143, 94, 238, 169, 128, 36, 19, |
3131 | 1 | 173, 164, 146, 119, 26, 142, 33, 48, 198, 18, 141, 19, 192, 148, 50, 239, 88, 248, |
3132 | 1 | 1, 6, 192, 225, 124, 7, 250, 151, 187, 35, 236, 29, 128, 176, 1, 138, 144, 229, 9, |
3133 | 1 | 63, 181, 213, 121, 215, 108, 115, 191, 27, 101, 254, 121, 217, 209, 224, 155, 74, |
3134 | 1 | 54, 84, 166, 217, 71, 90, 202, 80, 160, 212, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, |
3135 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3136 | 1 | 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, |
3137 | 1 | 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 5, 250, 215, 160, 174, 53, 135, |
3138 | 1 | 1, 216, 200, 221, 56, 45, 67, 241, 114, 177, 149, 137, 65, 157, 56, 68, 205, 112, |
3139 | 1 | 123, 203, 221, 70, 61, 249, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3140 | 1 | 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, |
3141 | 1 | 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 187, 169, 88, 95, 20, 50, 224, 212, |
3142 | 1 | 228, 182, 45, 208, 52, 119, 109, 35, 159, 124, 135, 152, 198, 95, 126, 249, 187, |
3143 | 1 | 99, 157, 59, 15, 105, 136, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3144 | 1 | 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, |
3145 | 1 | 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 63, 161, 255, 207, 154, 191, 35, |
3146 | 1 | 136, 18, 148, 241, 14, 197, 98, 46, 25, 230, 153, 104, 243, 18, 240, 181, 53, 168, |
3147 | 1 | 8, 103, 28, 141, 179, 126, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3148 | 1 | 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, |
3149 | 1 | 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 43, 148, 250, 148, 228, 172, 67, 132, |
3150 | 1 | 171, 37, 135, 1, 37, 88, 34, 24, 14, 6, 232, 221, 72, 44, 182, 81, 110, 193, 28, |
3151 | 1 | 201, 36, 93, 165, 93, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, |
3152 | 1 | 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, |
3153 | 1 | 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 63, 147, 92, 137, 75, 72, 220, 136, 53, 129, |
3154 | 1 | 224, 54, 43, 157, 136, 1, 50, 158, 178, 236, 248, 83, 156, 227, 92, 237, 144, 14, |
3155 | 1 | 124, 139, 136, 142, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, |
3156 | 1 | 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, |
3157 | 1 | 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 64, 161, 143, 171, 210, 113, 241, 165, 228, |
3158 | 1 | 252, 176, 225, 217, 111, 240, 26, 230, 134, 218, 228, 111, 176, 231, 168, 137, 44, |
3159 | 1 | 236, 151, 248, 186, 85, 116, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3160 | 1 | 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, |
3161 | 1 | 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 83, 202, 220, 165, 167, 190, 142, |
3162 | 1 | 186, 19, 99, 201, 171, 165, 120, 28, 236, 246, 179, 188, 89, 243, 24, 46, 85, 230, |
3163 | 1 | 254, 195, 85, 233, 80, 145, 22, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3164 | 1 | 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3165 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 98, 120, 195, 242, 227, 233, |
3166 | 1 | 193, 24, 169, 0, 95, 229, 165, 68, 204, 39, 139, 96, 82, 71, 46, 75, 28, 195, 43, |
3167 | 1 | 10, 126, 118, 67, 53, 154, 104, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3168 | 1 | 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3169 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 99, 103, 122, 72, 191, 50, 82, |
3170 | 1 | 52, 229, 214, 125, 21, 50, 83, 191, 47, 14, 140, 153, 149, 232, 224, 66, 234, 66, |
3171 | 1 | 222, 204, 33, 137, 61, 74, 233, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3172 | 1 | 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3173 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 106, 27, 252, 162, 221, 223, |
3174 | 1 | 106, 170, 245, 44, 94, 186, 7, 66, 122, 150, 233, 137, 249, 73, 16, 168, 236, 103, |
3175 | 1 | 150, 160, 163, 159, 18, 2, 199, 193, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, |
3176 | 1 | 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3177 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 107, 193, 245, 68, 94, 138, |
3178 | 1 | 210, 194, 81, 181, 247, 113, 165, 206, 101, 60, 10, 33, 77, 188, 96, 11, 153, 24, |
3179 | 1 | 225, 30, 15, 32, 162, 92, 91, 9, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3180 | 1 | 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3181 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 115, 252, 71, 178, 133, 130, |
3182 | 1 | 97, 235, 64, 231, 231, 59, 145, 36, 224, 75, 25, 215, 42, 236, 77, 160, 135, 194, |
3183 | 1 | 55, 0, 40, 92, 22, 199, 202, 125, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3184 | 1 | 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3185 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 124, 234, 33, 244, 40, 178, |
3186 | 1 | 179, 182, 15, 57, 170, 170, 56, 223, 142, 162, 42, 117, 217, 246, 63, 4, 107, 216, |
3187 | 1 | 116, 7, 16, 33, 251, 197, 131, 236, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, |
3188 | 1 | 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3189 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 127, 112, 248, 19, 119, 246, |
3190 | 1 | 252, 26, 160, 149, 112, 164, 23, 155, 129, 181, 148, 231, 184, 235, 250, 189, 7, |
3191 | 1 | 24, 211, 160, 167, 73, 29, 48, 54, 198, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, |
3192 | 1 | 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, |
3193 | 1 | 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 31, 38, 230, 121, 61, |
3194 | 1 | 43, 72, 39, 197, 122, 164, 187, 110, 148, 61, 120, 69, 85, 209, 11, 114, 89, 132, |
3195 | 1 | 165, 46, 56, 120, 202, 60, 233, 206, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, |
3196 | 1 | 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3197 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 154, 191, 201, 150, 135, 211, |
3198 | 1 | 54, 59, 44, 221, 83, 140, 8, 31, 44, 118, 42, 124, 254, 88, 131, 41, 7, 129, 27, |
3199 | 1 | 216, 214, 186, 186, 134, 134, 2, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3200 | 1 | 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3201 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 157, 148, 176, 126, 153, 92, |
3202 | 1 | 236, 87, 64, 254, 99, 40, 220, 29, 83, 165, 253, 178, 150, 132, 69, 68, 189, 252, |
3203 | 1 | 102, 95, 73, 119, 143, 199, 15, 111, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, |
3204 | 1 | 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, |
3205 | 1 | 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 162, 91, 15, 137, 154, 20, 246, |
3206 | 1 | 251, 108, 89, 46, 42, 198, 137, 71, 121, 217, 190, 113, 191, 118, 21, 86, 14, 21, |
3207 | 1 | 34, 210, 1, 46, 165, 40, 246, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3208 | 1 | 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, |
3209 | 1 | 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 176, 91, 183, 236, 44, 199, 97, 95, |
3210 | 1 | 93, 40, 245, 102, 24, 85, 5, 4, 4, 38, 248, 71, 29, 95, 111, 139, 236, 251, 1, 193, |
3211 | 1 | 109, 146, 246, 48, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, |
3212 | 1 | 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, |
3213 | 1 | 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 209, 152, 216, 62, 41, 157, 198, 68, 91, 54, |
3214 | 1 | 85, 17, 2, 164, 178, 234, 164, 122, 186, 205, 59, 6, 87, 181, 177, 228, 152, 71, |
3215 | 1 | 92, 217, 221, 43, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, |
3216 | 1 | 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, |
3217 | 1 | 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 239, 113, 245, 251, 30, 236, 202, 188, 231, |
3218 | 1 | 148, 194, 209, 176, 66, 53, 218, 40, 45, 46, 102, 197, 7, 235, 91, 245, 236, 74, |
3219 | 1 | 143, 143, 20, 12, 90, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, |
3220 | 1 | 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, |
3221 | 1 | 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 246, 160, 240, 191, 80, 255, 103, 121, 52, |
3222 | 1 | 194, 211, 125, 153, 146, 111, 254, 93, 0, 126, 36, 255, 50, 248, 214, 101, 172, |
3223 | 1 | 253, 54, 98, 55, 122, 78, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3224 | 1 | 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, |
3225 | 1 | 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 247, 147, 254, 132, 40, 142, 13, 6, |
3226 | 1 | 186, 140, 32, 40, 197, 149, 95, 102, 41, 231, 175, 29, 22, 170, 219, 135, 254, 155, |
3227 | 1 | 86, 118, 200, 94, 75, 242, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3228 | 1 | 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, |
3229 | 1 | 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 232, 199, 94, 105, 228, 156, 254, |
3230 | 1 | 223, 31, 125, 134, 59, 237, 160, 34, 39, 41, 22, 232, 161, 187, 125, 69, 10, 227, |
3231 | 1 | 1, 104, 252, 95, 14, 129, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3232 | 1 | 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3233 | 1 | ], |
3234 | 1 | }) |
3235 | 1 | .unwrap(); |
3236 | 1 | } |
3237 | | |
3238 | | #[test] |
3239 | 1 | fn invalid_nodes_are_ignored() { |
3240 | 1 | let proof = [ |
3241 | 1 | 253, 1, 97, 3, 0, 0, 48, 0, 0, 80, 0, 0, 170, 170, 10, 0, 0, 0, 64, 0, 251, 255, 0, 0, |
3242 | 1 | 128, 0, 0, 0, 10, 0, 0, 0, 16, 14, 0, 0, 88, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, |
3243 | 1 | 0, 0, 200, 0, 0, 30, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3244 | 1 | 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 3, 0, 0, 0, 144, 1, 0, 30, 0, 0, |
3245 | 1 | 0, 0, 144, 1, 0, 4, 1, 0, 32, 0, 0, 128, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 39, 0, |
3246 | 1 | 0, 128, 178, 230, 14, 128, 195, 201, 1, 128, 150, 152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
3247 | 1 | 0, 0, 5, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0, 1, 3, 0, 0, 0, 1, 44, 1, 0, 0, |
3248 | 1 | 6, 0, 0, 0, 88, 2, 0, 0, 3, 0, 0, 0, 89, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 6, 0, 0, 0, |
3249 | 1 | 2, 0, 0, 0, 20, 0, 0, 0, 2, 0, 0, 0, 132, 1, 63, 230, 114, 140, 224, 116, 43, 2, 167, |
3250 | 1 | 186, 106, 112, 82, 12, 214, 194, 60, 201, 60, 137, 155, 229, 125, 65, 90, 39, 91, 239, |
3251 | 1 | 227, 95, 185, 217, 176, 54, 255, 111, 125, 70, 123, 135, 169, 232, 3, 0, 0, 18, 114, |
3252 | 1 | 237, 245, 194, 144, 52, 2, 76, 204, 79, 195, 207, 227, 150, 137, 228, 147, 153, 88, |
3253 | 1 | 238, 133, 195, 1, 109, 19, 204, 54, 253, 170, 15, 48, 176, 54, 255, 111, 125, 70, 123, |
3254 | 1 | 135, 169, 232, 3, 0, 0, 129, 135, 152, 88, 195, 254, 195, 247, 51, 254, 46, 63, 2, 174, |
3255 | 1 | 41, 56, 235, 208, 20, 207, 49, 241, 253, 205, 183, 68, 150, 100, 236, 72, 25, 68, 192, |
3256 | 1 | 61, 0, 39, 9, 46, 239, 5, 69, 232, 3, 0, 0, 215, 7, 0, 0, 15, 72, 145, 238, 211, 39, |
3257 | 1 | 236, 97, 153, 86, 253, 122, 74, 105, 235, 113, 170, 220, 40, 167, 248, 234, 71, 94, |
3258 | 1 | 133, 118, 69, 223, 120, 56, 86, 249, 192, 61, 0, 40, 140, 20, 28, 114, 29, 232, 3, 0, |
3259 | 1 | 0, 77, 8, 0, 0, 61, 150, 210, 254, 230, 222, 187, 225, 31, 60, 227, 34, 93, 204, 79, |
3260 | 1 | 11, 98, 237, 182, 161, 121, 26, 170, 252, 182, 97, 250, 173, 5, 61, 182, 149, 192, 61, |
3261 | 1 | 0, 171, 145, 207, 1, 20, 216, 232, 3, 0, 0, 0, 8, 0, 0, 81, 2, 17, 44, 188, 60, 147, |
3262 | 1 | 230, 242, 73, 17, 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, |
3263 | 1 | 223, 68, 126, 41, 190, 130, 192, 61, 4, 23, 57, 95, 192, 189, 223, 234, 3, 0, 0, 232, |
3264 | 1 | 3, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, 17, 70, 19, 46, 224, 67, 186, 215, |
3265 | 1 | 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, 41, 190, 130, 192, 61, 6, 56, 2, 208, |
3266 | 1 | 248, 212, 114, 232, 3, 0, 0, 231, 7, 0, 0, 163, 60, 28, 134, 10, 94, 10, 89, 13, 229, |
3267 | 1 | 169, 121, 107, 245, 170, 193, 228, 212, 45, 119, 192, 82, 95, 210, 79, 237, 229, 86, |
3268 | 1 | 227, 13, 18, 30, 192, 61, 10, 187, 47, 43, 177, 201, 79, 62, 8, 0, 0, 232, 3, 0, 0, |
3269 | 1 | 190, 200, 41, 185, 126, 229, 241, 27, 130, 85, 201, 109, 123, 34, 194, 40, 168, 105, |
3270 | 1 | 207, 209, 201, 39, 240, 29, 77, 187, 168, 139, 21, 25, 66, 142, 192, 61, 11, 121, 2, |
3271 | 1 | 180, 48, 50, 139, 232, 3, 0, 0, 73, 8, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, |
3272 | 1 | 17, 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, 41, |
3273 | 1 | 190, 130, 192, 61, 11, 128, 7, 157, 139, 153, 243, 232, 3, 0, 0, 36, 8, 0, 0, 110, 144, |
3274 | 1 | 217, 165, 46, 204, 221, 194, 25, 70, 185, 24, 72, 39, 165, 170, 124, 143, 40, 213, 47, |
3275 | 1 | 85, 169, 60, 207, 55, 153, 41, 242, 31, 44, 197, 192, 61, 11, 161, 105, 169, 49, 149, |
3276 | 1 | 179, 232, 3, 0, 0, 209, 7, 0, 0, 196, 140, 47, 23, 205, 243, 57, 17, 200, 106, 197, |
3277 | 1 | 102, 120, 44, 136, 22, 140, 122, 61, 129, 173, 103, 88, 72, 23, 219, 108, 187, 234, |
3278 | 1 | 204, 182, 63, 192, 61, 12, 2, 1, 227, 42, 232, 107, 209, 7, 0, 0, 232, 3, 0, 0, 204, |
3279 | 1 | 253, 90, 87, 213, 198, 147, 183, 95, 70, 46, 73, 24, 187, 28, 168, 80, 235, 219, 249, |
3280 | 1 | 82, 162, 223, 175, 131, 93, 228, 105, 234, 6, 229, 106, 192, 61, 12, 128, 141, 84, 168, |
3281 | 1 | 147, 123, 232, 3, 0, 0, 75, 8, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, 17, 70, |
3282 | 1 | 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, 41, 190, |
3283 | 1 | 130, 192, 61, 15, 17, 49, 183, 245, 75, 8, 0, 8, 0, 0, 232, 3, 0, 0, 81, 2, 17, 44, |
3284 | 1 | 188, 60, 147, 230, 242, 73, 17, 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, |
3285 | 1 | 240, 6, 5, 223, 68, 126, 41, 190, 130, 192, 62, 0, 83, 243, 142, 189, 253, 66, 231, 7, |
3286 | 1 | 0, 0, 232, 3, 0, 0, 155, 239, 223, 36, 51, 143, 143, 82, 7, 125, 159, 129, 91, 22, 243, |
3287 | 1 | 140, 146, 164, 37, 31, 196, 189, 49, 45, 221, 33, 139, 55, 96, 167, 225, 103, 192, 62, |
3288 | 1 | 4, 210, 161, 90, 181, 17, 39, 232, 3, 0, 0, 208, 7, 0, 0, 89, 190, 147, 253, 0, 203, |
3289 | 1 | 88, 222, 64, 251, 99, 145, 75, 153, 151, 193, 152, 44, 155, 199, 178, 20, 118, 98, 31, |
3290 | 1 | 91, 50, 113, 209, 167, 208, 253, 192, 62, 15, 44, 104, 151, 68, 229, 91, 232, 3, 0, 0, |
3291 | 1 | 62, 8, 0, 0, 116, 141, 30, 175, 209, 222, 101, 7, 211, 131, 89, 253, 95, 37, 119, 144, |
3292 | 1 | 133, 187, 197, 85, 87, 57, 254, 225, 111, 233, 171, 187, 96, 140, 11, 159, 192, 62, 28, |
3293 | 1 | 100, 60, 157, 144, 171, 116, 39, 8, 0, 0, 232, 3, 0, 0, 153, 153, 83, 93, 118, 35, 123, |
3294 | 1 | 168, 47, 214, 207, 207, 28, 38, 189, 111, 152, 156, 210, 81, 245, 46, 51, 80, 200, 6, |
3295 | 1 | 253, 7, 138, 155, 143, 67, 192, 62, 31, 197, 2, 226, 176, 126, 150, 232, 3, 0, 0, 39, |
3296 | 1 | 8, 0, 0, 34, 13, 19, 237, 219, 175, 168, 112, 223, 125, 176, 240, 110, 181, 94, 32, |
3297 | 1 | 169, 194, 195, 249, 236, 212, 93, 140, 167, 57, 42, 159, 157, 23, 31, 16, 192, 62, 41, |
3298 | 1 | 178, 150, 130, 51, 131, 215, 232, 3, 0, 0, 76, 8, 0, 0, 244, 52, 228, 90, 91, 116, 249, |
3299 | 1 | 136, 128, 118, 113, 105, 33, 69, 40, 181, 196, 67, 153, 66, 205, 28, 67, 9, 208, 157, |
3300 | 1 | 110, 181, 72, 232, 201, 38, 192, 62, 59, 169, 1, 144, 95, 128, 192, 36, 8, 0, 0, 232, |
3301 | 1 | 3, 0, 0, 147, 149, 73, 90, 142, 233, 87, 254, 200, 27, 173, 85, 215, 85, 99, 25, 214, |
3302 | 1 | 35, 148, 136, 34, 126, 212, 73, 72, 129, 131, 190, 224, 227, 123, 205, 192, 62, 67, |
3303 | 1 | 215, 59, 253, 0, 17, 49, 42, 8, 0, 0, 232, 3, 0, 0, 107, 155, 78, 78, 98, 243, 9, 12, |
3304 | 1 | 157, 140, 37, 44, 55, 20, 104, 169, 10, 177, 81, 218, 79, 125, 169, 92, 8, 54, 240, 54, |
3305 | 1 | 145, 175, 100, 69, 192, 62, 79, 54, 112, 131, 102, 183, 34, 208, 7, 0, 0, 232, 3, 0, 0, |
3306 | 1 | 166, 115, 48, 17, 145, 171, 52, 201, 53, 139, 209, 217, 53, 14, 81, 77, 79, 22, 21, |
3307 | 1 | 139, 77, 66, 255, 202, 163, 243, 97, 5, 134, 243, 210, 166, 192, 62, 83, 81, 219, 36, |
3308 | 1 | 40, 165, 44, 77, 8, 0, 0, 232, 3, 0, 0, 149, 206, 115, 106, 124, 106, 114, 192, 139, |
3309 | 1 | 11, 141, 73, 232, 176, 215, 234, 33, 166, 157, 15, 57, 56, 241, 94, 225, 22, 243, 190, |
3310 | 1 | 3, 35, 103, 10, 192, 62, 85, 202, 11, 145, 38, 11, 189, 215, 7, 0, 0, 232, 3, 0, 0, 56, |
3311 | 1 | 127, 221, 245, 176, 100, 38, 121, 224, 118, 170, 244, 143, 186, 43, 47, 46, 134, 100, |
3312 | 1 | 151, 205, 173, 200, 190, 238, 148, 239, 59, 112, 1, 30, 66, 192, 62, 111, 232, 252, |
3313 | 1 | 188, 83, 20, 184, 76, 8, 0, 0, 232, 3, 0, 0, 230, 183, 216, 151, 183, 98, 18, 231, 55, |
3314 | 1 | 243, 106, 173, 152, 61, 41, 4, 97, 17, 6, 25, 151, 197, 112, 254, 231, 159, 111, 104, |
3315 | 1 | 130, 222, 62, 126, 192, 62, 119, 223, 219, 138, 219, 16, 247, 143, 16, 165, 223, 135, |
3316 | 1 | 66, 197, 69, 155, 26, 73, 252, 24, 39, 167, 209, 114, 251, 25, 112, 215, 168, 175, 255, |
3317 | 1 | 26, 139, 215, 173, 69, 229, 71, 107, 15, 103, 56, 18, 101, 51, 105, 134, 192, 62, 121, |
3318 | 1 | 19, 197, 6, 141, 231, 236, 232, 3, 0, 0, 42, 8, 0, 0, 210, 73, 43, 11, 163, 228, 23, |
3319 | 1 | 94, 132, 196, 108, 35, 9, 104, 18, 192, 28, 57, 174, 143, 145, 45, 78, 96, 51, 245, |
3320 | 1 | 243, 154, 31, 54, 121, 69, 192, 62, 123, 154, 227, 54, 228, 76, 248, 73, 8, 0, 0, 232, |
3321 | 1 | 3, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, 73, 17, 70, 19, 46, 224, 67, 186, 215, |
3322 | 1 | 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, 41, 190, 130, 192, 62, 125, 153, 115, |
3323 | 1 | 129, 57, 149, 125, 232, 3, 0, 0, 234, 3, 0, 0, 81, 2, 17, 44, 188, 60, 147, 230, 242, |
3324 | 1 | 73, 17, 70, 19, 46, 224, 67, 186, 215, 152, 188, 29, 184, 112, 240, 6, 5, 223, 68, 126, |
3325 | 1 | 41, 190, 130, 192, 62, 153, 36, 97, 4, 207, 65, 86, 75, 8, 0, 0, 232, 3, 0, 0, 143, |
3326 | 1 | 140, 33, 234, 43, 125, 144, 193, 115, 170, 93, 112, 202, 225, 144, 235, 205, 209, 159, |
3327 | 1 | 160, 104, 26, 3, 139, 61, 116, 178, 26, 75, 51, 255, 75, 192, 62, 160, 196, 240, 37, |
3328 | 1 | 252, 100, 103, 37, 8, 0, 0, 232, 3, 0, 0, 117, 238, 16, 62, 188, 233, 65, 122, 23, 220, |
3329 | 1 | 239, 182, 16, 3, 125, 154, 78, 98, 215, 1, 192, 97, 226, 73, 171, 71, 43, 127, 98, 159, |
3330 | 1 | 29, 42, 192, 62, 206, 67, 51, 57, 104, 130, 146, 232, 3, 0, 0, 37, 8, 0, 0, 66, 133, |
3331 | 1 | 30, 23, 16, 154, 223, 78, 204, 172, 173, 234, 216, 161, 190, 155, 151, 196, 43, 228, |
3332 | 1 | 49, 228, 248, 58, 168, 233, 244, 105, 148, 61, 160, 148, 192, 62, 232, 44, 203, 92, |
3333 | 1 | 185, 84, 186, 232, 3, 0, 0, 44, 8, 0, 0, 135, 12, 161, 54, 46, 190, 130, 54, 8, 150, |
3334 | 1 | 78, 0, 217, 206, 250, 19, 186, 130, 9, 24, 209, 60, 111, 244, 26, 79, 126, 68, 29, 7, |
3335 | 1 | 248, 109, 192, 62, 234, 24, 216, 208, 25, 70, 203, 44, 8, 0, 0, 232, 3, 0, 0, 236, 1, |
3336 | 1 | 42, 109, 139, 151, 154, 246, 26, 71, 169, 23, 112, 157, 53, 248, 11, 231, 68, 87, 249, |
3337 | 1 | 69, 153, 95, 85, 57, 8, 27, 50, 128, 122, 126, 200, 63, 0, 4, 180, 157, 149, 50, 13, |
3338 | 1 | 144, 33, 153, 76, 133, 15, 37, 184, 227, 133, 162, 89, 119, 34, 17, 36, 96, 55, 65, 56, |
3339 | 1 | 67, 180, 116, 208, 29, 129, 93, 170, 12, 95, 104, 45, 101, 136, 133, 233, 174, 110, 20, |
3340 | 1 | 254, 87, 165, 5, 1, 64, 234, 3, 0, 0, 208, 7, 0, 0, 209, 7, 0, 0, 215, 7, 0, 0, 231, 7, |
3341 | 1 | 0, 0, 0, 8, 0, 0, 36, 8, 0, 0, 37, 8, 0, 0, 39, 8, 0, 0, 42, 8, 0, 0, 44, 8, 0, 0, 62, |
3342 | 1 | 8, 0, 0, 73, 8, 0, 0, 75, 8, 0, 0, 76, 8, 0, 0, 77, 8, 0, 0, 180, 86, 255, 111, 125, |
3343 | 1 | 70, 123, 135, 169, 232, 3, 0, 0, 128, 44, 223, 145, 191, 55, 104, 138, 225, 255, 66, |
3344 | 1 | 193, 87, 32, 49, 140, 120, 172, 58, 10, 128, 62, 102, 223, 183, 158, 129, 94, 74, 171, |
3345 | 1 | 153, 138, 13, 196, 94, 65, 76, 176, 8, 224, 230, 30, 70, 114, 42, 166, 10, 189, 214, |
3346 | 1 | 114, 128, 178, 46, 116, 104, 70, 160, 85, 100, 101, 106, 39, 99, 145, 180, 104, 81, 50, |
3347 | 1 | 88, 141, 211, 53, 132, 77, 141, 81, 26, 90, 173, 251, 85, 42, 45, 196, 94, 230, 120, |
3348 | 1 | 121, 157, 62, 255, 2, 66, 83, 185, 14, 132, 146, 124, 198, 128, 219, 193, 32, 80, 236, |
3349 | 1 | 155, 53, 65, 181, 114, 170, 166, 163, 124, 79, 88, 217, 230, 99, 219, 86, 154, 111, 83, |
3350 | 1 | 72, 185, 211, 73, 74, 176, 233, 99, 21, 1, 128, 0, 20, 128, 67, 223, 241, 36, 84, 59, |
3351 | 1 | 148, 103, 237, 40, 89, 136, 90, 81, 215, 76, 47, 237, 199, 242, 157, 134, 218, 228, 23, |
3352 | 1 | 110, 252, 28, 170, 15, 192, 19, 128, 164, 202, 140, 55, 117, 232, 237, 146, 49, 117, |
3353 | 1 | 120, 97, 172, 89, 92, 41, 207, 120, 106, 11, 209, 75, 177, 219, 194, 26, 12, 185, 12, |
3354 | 1 | 135, 205, 226, 224, 128, 0, 96, 128, 80, 249, 30, 220, 70, 210, 13, 244, 190, 132, 65, |
3355 | 1 | 220, 19, 236, 239, 201, 246, 140, 86, 197, 149, 205, 254, 5, 216, 6, 244, 24, 65, 226, |
3356 | 1 | 243, 247, 76, 94, 123, 144, 18, 9, 107, 65, 196, 235, 58, 175, 148, 127, 110, 164, 41, |
3357 | 1 | 8, 0, 0, 37, 3, 128, 0, 111, 128, 118, 54, 94, 247, 229, 189, 13, 15, 66, 244, 152, |
3358 | 1 | 205, 98, 163, 106, 210, 119, 57, 195, 199, 65, 20, 58, 91, 113, 3, 154, 101, 169, 13, |
3359 | 1 | 143, 162, 128, 132, 52, 223, 121, 87, 116, 19, 64, 218, 149, 200, 44, 94, 215, 25, 49, |
3360 | 1 | 219, 250, 11, 145, 249, 123, 209, 244, 2, 79, 176, 226, 8, 110, 246, 6, 128, 90, 250, |
3361 | 1 | 216, 176, 251, 137, 75, 248, 71, 209, 2, 100, 50, 229, 142, 77, 20, 121, 29, 138, 25, |
3362 | 1 | 88, 109, 20, 113, 104, 79, 203, 89, 83, 58, 5, 128, 211, 75, 12, 86, 213, 0, 129, 8, |
3363 | 1 | 193, 42, 161, 46, 116, 205, 24, 182, 177, 104, 244, 216, 143, 42, 115, 91, 185, 149, |
3364 | 1 | 124, 191, 49, 85, 125, 140, 128, 136, 36, 192, 120, 23, 217, 39, 42, 47, 156, 191, 39, |
3365 | 1 | 35, 142, 154, 183, 193, 4, 57, 88, 185, 111, 20, 102, 35, 12, 66, 253, 103, 184, 54, |
3366 | 1 | 45, 128, 147, 109, 13, 150, 30, 34, 60, 94, 67, 138, 187, 7, 179, 198, 124, 146, 74, |
3367 | 1 | 56, 80, 232, 104, 37, 198, 225, 70, 60, 59, 35, 63, 85, 9, 8, 21, 1, 128, 0, 132, 128, |
3368 | 1 | 109, 5, 72, 127, 31, 102, 27, 210, 205, 38, 78, 21, 199, 54, 67, 76, 205, 76, 178, 54, |
3369 | 1 | 154, 175, 33, 220, 105, 1, 176, 24, 229, 151, 177, 165, 128, 38, 101, 17, 82, 38, 152, |
3370 | 1 | 50, 145, 67, 133, 153, 206, 179, 121, 103, 196, 42, 148, 118, 220, 86, 37, 152, 249, |
3371 | 1 | 234, 27, 222, 242, 216, 51, 71, 71, 21, 1, 128, 1, 16, 128, 23, 197, 51, 5, 107, 56, |
3372 | 1 | 42, 109, 136, 32, 150, 118, 217, 115, 170, 125, 128, 203, 65, 246, 176, 34, 143, 156, |
3373 | 1 | 221, 178, 239, 135, 144, 54, 22, 51, 128, 82, 15, 168, 118, 27, 39, 63, 162, 237, 163, |
3374 | 1 | 56, 116, 191, 251, 193, 212, 30, 27, 218, 234, 139, 198, 28, 206, 94, 242, 86, 187, 36, |
3375 | 1 | 23, 188, 42, 21, 1, 128, 1, 16, 128, 107, 87, 58, 104, 133, 146, 11, 254, 200, 207, 86, |
3376 | 1 | 146, 70, 178, 5, 239, 153, 137, 232, 36, 136, 251, 177, 246, 67, 10, 237, 149, 125, 9, |
3377 | 1 | 40, 60, 128, 14, 190, 101, 3, 105, 206, 14, 60, 232, 91, 34, 129, 97, 129, 245, 152, |
3378 | 1 | 204, 110, 207, 122, 59, 34, 49, 67, 87, 171, 65, 129, 185, 204, 184, 103, 29, 2, 128, |
3379 | 1 | 2, 164, 128, 98, 49, 33, 45, 166, 186, 168, 0, 68, 161, 215, 32, 89, 183, 217, 234, 71, |
3380 | 1 | 168, 50, 213, 84, 112, 139, 72, 249, 95, 59, 26, 232, 24, 64, 4, 128, 53, 94, 187, 196, |
3381 | 1 | 167, 34, 112, 205, 76, 144, 208, 38, 182, 239, 183, 249, 15, 73, 236, 103, 222, 218, |
3382 | 1 | 235, 31, 165, 30, 65, 47, 101, 79, 172, 111, 128, 2, 203, 187, 184, 43, 129, 106, 231, |
3383 | 1 | 41, 88, 121, 74, 204, 70, 53, 150, 4, 241, 81, 185, 171, 49, 79, 116, 182, 114, 127, |
3384 | 1 | 51, 62, 242, 54, 253, 128, 217, 133, 131, 8, 149, 172, 15, 215, 86, 127, 174, 157, 57, |
3385 | 1 | 22, 15, 98, 144, 169, 92, 193, 187, 104, 113, 130, 155, 70, 152, 218, 66, 199, 158, |
3386 | 1 | 190, 21, 1, 128, 4, 1, 128, 30, 34, 108, 150, 45, 162, 139, 6, 57, 227, 175, 254, 55, |
3387 | 1 | 177, 176, 249, 226, 106, 92, 179, 213, 225, 170, 235, 250, 213, 168, 232, 148, 41, 192, |
3388 | 1 | 81, 128, 7, 61, 47, 252, 45, 92, 8, 66, 62, 190, 53, 127, 232, 118, 24, 47, 47, 248, 8, |
3389 | 1 | 85, 162, 14, 126, 143, 35, 118, 191, 225, 171, 221, 246, 179, 21, 1, 128, 4, 4, 128, |
3390 | 1 | 192, 143, 141, 181, 244, 61, 11, 66, 169, 233, 133, 102, 16, 87, 204, 64, 63, 227, 80, |
3391 | 1 | 55, 59, 117, 241, 62, 20, 140, 247, 170, 94, 101, 84, 139, 128, 225, 175, 18, 233, 5, |
3392 | 1 | 78, 91, 57, 216, 56, 102, 193, 238, 3, 183, 243, 194, 4, 26, 103, 158, 111, 39, 70, 63, |
3393 | 1 | 105, 38, 60, 9, 236, 120, 207, 21, 1, 128, 4, 4, 128, 251, 99, 125, 27, 197, 147, 246, |
3394 | 1 | 180, 223, 158, 192, 140, 146, 50, 72, 98, 99, 86, 37, 210, 94, 178, 180, 99, 94, 198, |
3395 | 1 | 172, 220, 245, 7, 90, 130, 128, 15, 230, 176, 54, 57, 255, 39, 57, 228, 43, 38, 58, |
3396 | 1 | 100, 185, 116, 88, 187, 183, 176, 74, 127, 19, 167, 221, 16, 183, 123, 165, 195, 211, |
3397 | 1 | 148, 14, 161, 2, 128, 4, 108, 128, 205, 99, 3, 130, 139, 243, 193, 20, 255, 199, 209, |
3398 | 1 | 24, 176, 95, 251, 100, 223, 165, 111, 47, 45, 188, 41, 248, 18, 138, 36, 211, 27, 15, |
3399 | 1 | 80, 201, 128, 243, 80, 31, 92, 184, 138, 215, 17, 68, 58, 241, 178, 147, 81, 154, 19, |
3400 | 1 | 109, 167, 183, 50, 115, 197, 124, 38, 67, 224, 102, 10, 9, 105, 186, 25, 128, 143, 131, |
3401 | 1 | 240, 216, 230, 57, 158, 159, 157, 16, 195, 200, 155, 97, 78, 49, 136, 72, 223, 183, |
3402 | 1 | 236, 234, 216, 155, 19, 122, 177, 254, 47, 169, 104, 249, 128, 117, 174, 91, 19, 94, |
3403 | 1 | 210, 222, 196, 197, 109, 193, 249, 112, 47, 169, 50, 128, 80, 75, 79, 118, 102, 86, 71, |
3404 | 1 | 254, 215, 61, 246, 144, 152, 45, 202, 128, 5, 188, 148, 36, 145, 183, 124, 109, 184, |
3405 | 1 | 67, 82, 96, 116, 240, 197, 197, 130, 84, 73, 231, 243, 144, 165, 28, 108, 22, 120, 162, |
3406 | 1 | 147, 24, 217, 244, 21, 1, 128, 8, 2, 128, 29, 121, 195, 67, 100, 133, 169, 193, 23, 58, |
3407 | 1 | 103, 159, 112, 135, 125, 85, 28, 138, 132, 206, 254, 84, 237, 244, 224, 134, 126, 225, |
3408 | 1 | 23, 249, 79, 237, 128, 212, 250, 24, 77, 173, 122, 60, 124, 68, 61, 71, 140, 224, 170, |
3409 | 1 | 88, 175, 195, 236, 38, 77, 58, 174, 0, 148, 60, 173, 114, 195, 74, 50, 180, 167, 153, |
3410 | 1 | 1, 128, 12, 32, 128, 51, 114, 226, 199, 219, 186, 159, 19, 56, 214, 59, 237, 84, 236, |
3411 | 1 | 119, 52, 39, 133, 220, 81, 228, 87, 236, 19, 129, 214, 185, 155, 59, 27, 200, 24, 128, |
3412 | 1 | 210, 90, 254, 160, 227, 18, 34, 92, 39, 30, 224, 33, 126, 96, 136, 245, 195, 111, 233, |
3413 | 1 | 243, 192, 150, 103, 103, 117, 216, 6, 59, 237, 153, 115, 115, 128, 204, 62, 68, 34, |
3414 | 1 | 213, 218, 138, 33, 131, 143, 52, 83, 231, 211, 113, 238, 54, 114, 150, 81, 6, 57, 202, |
3415 | 1 | 30, 61, 95, 250, 193, 205, 208, 143, 46, 21, 1, 128, 16, 128, 128, 129, 106, 55, 122, |
3416 | 1 | 49, 123, 247, 1, 224, 22, 88, 75, 25, 19, 51, 17, 151, 58, 3, 247, 115, 148, 169, 82, |
3417 | 1 | 176, 130, 11, 34, 57, 7, 54, 235, 128, 51, 159, 146, 11, 30, 85, 157, 28, 237, 161, |
3418 | 1 | 158, 225, 213, 51, 94, 113, 58, 151, 167, 154, 68, 116, 242, 253, 88, 132, 190, 24, |
3419 | 1 | 251, 116, 73, 220, 37, 3, 128, 17, 23, 128, 96, 131, 252, 204, 90, 217, 72, 158, 143, |
3420 | 1 | 255, 212, 105, 70, 106, 66, 6, 167, 67, 216, 219, 188, 143, 179, 1, 5, 157, 170, 29, |
3421 | 1 | 25, 140, 134, 40, 128, 242, 3, 22, 95, 115, 21, 107, 104, 98, 211, 83, 143, 23, 227, |
3422 | 1 | 233, 60, 243, 80, 164, 205, 227, 133, 218, 190, 96, 110, 199, 36, 34, 227, 27, 102, |
3423 | 1 | 128, 131, 149, 236, 155, 11, 123, 189, 91, 121, 201, 78, 155, 234, 144, 198, 129, 49, |
3424 | 1 | 11, 122, 242, 88, 93, 92, 46, 34, 179, 165, 182, 136, 185, 231, 109, 128, 186, 239, 0, |
3425 | 1 | 87, 151, 140, 129, 32, 212, 38, 175, 198, 80, 34, 243, 181, 104, 183, 120, 126, 32, |
3426 | 1 | 245, 151, 222, 175, 36, 214, 42, 82, 196, 166, 162, 128, 81, 2, 169, 56, 218, 214, 153, |
3427 | 1 | 15, 202, 86, 64, 223, 232, 58, 60, 174, 142, 247, 83, 166, 62, 180, 238, 109, 214, 8, |
3428 | 1 | 86, 49, 210, 163, 18, 48, 128, 29, 73, 142, 212, 84, 125, 198, 143, 177, 210, 214, 222, |
3429 | 1 | 92, 28, 131, 11, 233, 115, 52, 125, 65, 170, 208, 239, 96, 186, 190, 61, 68, 88, 79, |
3430 | 1 | 122, 61, 6, 128, 30, 255, 128, 221, 171, 178, 121, 236, 163, 215, 95, 242, 180, 136, |
3431 | 1 | 177, 64, 13, 139, 78, 168, 8, 81, 58, 223, 41, 137, 16, 191, 123, 209, 171, 222, 185, |
3432 | 1 | 113, 70, 128, 85, 14, 91, 47, 193, 125, 95, 82, 159, 51, 220, 40, 75, 106, 53, 82, 43, |
3433 | 1 | 99, 162, 99, 30, 170, 253, 7, 222, 43, 141, 187, 117, 231, 60, 33, 128, 13, 244, 155, |
3434 | 1 | 243, 105, 134, 171, 144, 170, 138, 18, 72, 7, 179, 193, 92, 172, 108, 152, 237, 149, |
3435 | 1 | 218, 136, 215, 44, 117, 112, 5, 128, 115, 75, 124, 128, 77, 145, 37, 193, 9, 222, 229, |
3436 | 1 | 43, 107, 48, 35, 141, 169, 54, 89, 11, 68, 200, 218, 212, 50, 199, 163, 227, 227, 129, |
3437 | 1 | 134, 233, 97, 127, 74, 187, 128, 26, 250, 158, 229, 141, 133, 245, 232, 238, 7, 33, |
3438 | 1 | 163, 183, 17, 121, 238, 228, 77, 198, 42, 57, 45, 81, 242, 119, 55, 172, 102, 161, 21, |
3439 | 1 | 249, 157, 128, 4, 232, 86, 88, 190, 112, 35, 31, 66, 74, 201, 162, 128, 160, 131, 141, |
3440 | 1 | 149, 161, 251, 104, 250, 205, 109, 210, 123, 40, 140, 1, 142, 64, 156, 73, 128, 12, 2, |
3441 | 1 | 174, 255, 17, 17, 91, 29, 224, 118, 76, 245, 151, 26, 69, 34, 106, 68, 123, 116, 110, |
3442 | 1 | 20, 142, 103, 63, 2, 227, 3, 38, 184, 179, 3, 128, 105, 84, 77, 181, 48, 140, 211, 25, |
3443 | 1 | 93, 58, 55, 108, 187, 57, 25, 144, 94, 232, 124, 202, 94, 110, 245, 149, 110, 252, 11, |
3444 | 1 | 212, 37, 175, 185, 12, 128, 125, 190, 229, 49, 183, 99, 219, 76, 52, 5, 21, 109, 157, |
3445 | 1 | 219, 110, 224, 215, 80, 29, 75, 144, 177, 106, 227, 173, 91, 85, 29, 246, 108, 160, |
3446 | 1 | 128, 128, 213, 197, 135, 2, 231, 15, 73, 55, 105, 62, 3, 233, 10, 39, 39, 244, 46, 119, |
3447 | 1 | 62, 153, 215, 253, 175, 12, 62, 89, 80, 49, 24, 156, 113, 244, 128, 160, 142, 55, 25, |
3448 | 1 | 67, 215, 255, 187, 164, 72, 90, 58, 19, 182, 12, 249, 102, 152, 8, 77, 29, 40, 100, |
3449 | 1 | 228, 158, 132, 182, 118, 33, 63, 43, 212, 128, 249, 31, 160, 212, 237, 96, 172, 200, |
3450 | 1 | 74, 32, 168, 113, 126, 53, 2, 202, 126, 67, 70, 223, 134, 139, 4, 209, 234, 52, 8, 8, |
3451 | 1 | 131, 137, 170, 90, 21, 1, 128, 32, 128, 128, 130, 69, 110, 84, 222, 230, 123, 133, 142, |
3452 | 1 | 165, 48, 89, 187, 22, 14, 221, 110, 84, 51, 205, 192, 182, 137, 64, 106, 110, 11, 142, |
3453 | 1 | 178, 117, 142, 25, 128, 191, 130, 136, 38, 52, 184, 150, 243, 245, 138, 11, 213, 78, |
3454 | 1 | 128, 63, 216, 198, 189, 216, 250, 58, 81, 168, 203, 179, 30, 187, 161, 217, 223, 204, |
3455 | 1 | 15, 21, 1, 128, 40, 0, 128, 133, 83, 204, 5, 45, 33, 2, 133, 247, 41, 207, 179, 251, |
3456 | 1 | 114, 140, 80, 33, 235, 181, 161, 110, 15, 95, 8, 29, 244, 229, 12, 124, 86, 31, 147, |
3457 | 1 | 128, 253, 162, 5, 65, 64, 226, 4, 227, 195, 217, 134, 222, 106, 242, 163, 246, 14, 191, |
3458 | 1 | 163, 151, 43, 103, 0, 93, 30, 107, 124, 71, 103, 223, 224, 11, 53, 5, 128, 47, 55, 128, |
3459 | 1 | 35, 154, 87, 255, 59, 1, 106, 75, 119, 8, 131, 125, 113, 130, 57, 12, 56, 89, 123, 216, |
3460 | 1 | 94, 157, 71, 101, 245, 59, 115, 246, 65, 134, 178, 199, 128, 153, 222, 72, 239, 248, |
3461 | 1 | 59, 13, 103, 233, 106, 214, 226, 76, 148, 176, 223, 163, 191, 140, 38, 16, 250, 250, |
3462 | 1 | 75, 100, 93, 224, 11, 23, 235, 117, 247, 128, 223, 115, 33, 80, 45, 159, 122, 131, 217, |
3463 | 1 | 185, 30, 61, 13, 174, 186, 165, 144, 240, 179, 226, 20, 113, 179, 169, 95, 208, 132, |
3464 | 1 | 189, 191, 138, 181, 135, 128, 60, 15, 137, 204, 207, 56, 132, 182, 17, 148, 105, 128, |
3465 | 1 | 8, 240, 34, 249, 242, 199, 173, 101, 218, 227, 201, 245, 149, 72, 187, 221, 52, 240, 5, |
3466 | 1 | 114, 128, 48, 1, 27, 193, 218, 82, 145, 217, 224, 12, 172, 72, 75, 51, 17, 94, 194, |
3467 | 1 | 217, 14, 151, 207, 79, 184, 237, 194, 166, 240, 233, 79, 177, 135, 73, 128, 65, 9, 4, |
3468 | 1 | 218, 15, 228, 109, 205, 131, 37, 236, 135, 16, 107, 217, 43, 83, 3, 101, 4, 32, 203, |
3469 | 1 | 185, 186, 99, 63, 219, 223, 198, 252, 139, 122, 128, 96, 118, 120, 123, 177, 30, 37, |
3470 | 1 | 46, 155, 56, 77, 118, 193, 67, 191, 248, 213, 253, 181, 183, 113, 249, 209, 110, 53, |
3471 | 1 | 136, 249, 52, 180, 214, 130, 34, 128, 198, 88, 19, 139, 182, 100, 159, 238, 140, 18, |
3472 | 1 | 152, 161, 87, 159, 159, 29, 159, 105, 25, 91, 55, 78, 213, 57, 147, 191, 191, 42, 189, |
3473 | 1 | 2, 42, 227, 128, 11, 24, 228, 28, 217, 159, 15, 0, 109, 241, 143, 173, 117, 121, 189, |
3474 | 1 | 225, 231, 153, 68, 127, 21, 4, 246, 103, 113, 197, 139, 152, 6, 153, 102, 225, 128, 16, |
3475 | 1 | 247, 155, 152, 122, 193, 55, 210, 54, 96, 160, 186, 239, 170, 169, 123, 61, 0, 218, |
3476 | 1 | 250, 128, 201, 98, 131, 195, 242, 54, 14, 190, 231, 122, 199, 177, 4, 128, 62, 141, |
3477 | 1 | 128, 181, 147, 109, 65, 204, 60, 0, 255, 235, 165, 193, 198, 138, 57, 115, 11, 156, |
3478 | 1 | 234, 65, 77, 73, 35, 218, 69, 156, 176, 39, 42, 68, 250, 224, 183, 128, 172, 43, 79, |
3479 | 1 | 124, 108, 146, 86, 178, 12, 78, 168, 152, 114, 183, 33, 119, 238, 120, 17, 39, 74, 0, |
3480 | 1 | 29, 2, 235, 36, 248, 102, 73, 208, 142, 11, 128, 137, 129, 186, 192, 254, 176, 201, |
3481 | 1 | 127, 97, 168, 83, 43, 207, 37, 88, 209, 212, 170, 252, 214, 231, 196, 93, 31, 249, 224, |
3482 | 1 | 238, 15, 54, 203, 254, 128, 128, 213, 113, 67, 240, 104, 23, 42, 17, 111, 152, 22, 229, |
3483 | 1 | 22, 229, 161, 114, 214, 115, 146, 58, 55, 40, 39, 156, 100, 227, 37, 94, 73, 24, 15, |
3484 | 1 | 94, 128, 197, 215, 11, 163, 128, 252, 185, 201, 252, 122, 253, 88, 28, 25, 43, 82, 230, |
3485 | 1 | 210, 45, 98, 235, 87, 182, 169, 96, 138, 121, 195, 195, 3, 14, 89, 128, 138, 152, 206, |
3486 | 1 | 226, 66, 8, 188, 190, 43, 118, 222, 173, 78, 205, 163, 146, 236, 14, 107, 88, 138, 96, |
3487 | 1 | 113, 230, 66, 182, 127, 223, 84, 181, 28, 174, 128, 60, 41, 28, 176, 215, 23, 15, 122, |
3488 | 1 | 128, 20, 153, 198, 106, 169, 91, 42, 239, 143, 167, 67, 30, 172, 233, 132, 53, 105, |
3489 | 1 | 149, 123, 145, 202, 215, 245, 128, 39, 133, 125, 161, 60, 179, 147, 160, 37, 73, 249, |
3490 | 1 | 84, 74, 217, 140, 8, 191, 103, 192, 141, 148, 202, 147, 69, 116, 79, 134, 153, 127, 84, |
3491 | 1 | 160, 71, 128, 133, 113, 93, 46, 186, 86, 21, 236, 116, 64, 80, 151, 156, 74, 191, 207, |
3492 | 1 | 245, 0, 6, 6, 101, 56, 75, 169, 223, 243, 248, 237, 200, 105, 15, 164, 21, 1, 128, 64, |
3493 | 1 | 1, 128, 4, 115, 106, 34, 26, 197, 194, 99, 1, 98, 83, 161, 78, 247, 150, 107, 19, 28, |
3494 | 1 | 83, 130, 248, 30, 90, 100, 50, 239, 216, 10, 204, 70, 214, 48, 128, 95, 13, 146, 119, |
3495 | 1 | 52, 32, 17, 180, 232, 219, 183, 54, 213, 41, 54, 107, 180, 167, 93, 41, 173, 8, 71, 8, |
3496 | 1 | 20, 241, 235, 167, 211, 251, 117, 144, 21, 1, 128, 68, 1, 84, 86, 176, 50, 73, 34, 37, |
3497 | 1 | 51, 123, 234, 3, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 84, 86, 255, 111, 125, 70, 123, 135, |
3498 | 1 | 169, 232, 3, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 84, 86, 110, 117, 7, 123, 35, 173, 36, |
3499 | 1 | 39, 8, 0, 0, 32, 6, 0, 0, 0, 137, 1, 0, 0, 153, 1, 128, 73, 0, 128, 233, 188, 189, 178, |
3500 | 1 | 234, 66, 190, 60, 153, 30, 189, 4, 233, 104, 122, 212, 43, 77, 251, 126, 150, 142, 191, |
3501 | 1 | 61, 193, 223, 110, 73, 181, 238, 14, 93, 128, 104, 194, 82, 142, 63, 19, 35, 25, 16, |
3502 | 1 | 35, 244, 241, 234, 218, 241, 61, 195, 87, 173, 171, 109, 142, 197, 90, 62, 59, 190, 15, |
3503 | 1 | 124, 133, 56, 158, 128, 42, 145, 213, 213, 242, 56, 172, 224, 163, 99, 160, 135, 128, |
3504 | 1 | 183, 176, 244, 63, 168, 81, 153, 110, 174, 252, 156, 52, 95, 245, 100, 191, 213, 81, |
3505 | 1 | 231, 141, 2, 128, 76, 131, 72, 86, 176, 50, 73, 34, 37, 51, 123, 234, 3, 0, 0, 20, 4, |
3506 | 1 | 232, 3, 0, 0, 88, 86, 170, 94, 34, 92, 48, 154, 56, 47, 8, 0, 0, 36, 8, 208, 7, 0, 0, |
3507 | 1 | 215, 7, 0, 0, 128, 99, 103, 125, 158, 75, 246, 107, 144, 145, 198, 80, 239, 63, 192, |
3508 | 1 | 116, 157, 233, 130, 116, 174, 228, 233, 124, 49, 123, 255, 11, 255, 11, 253, 237, 177, |
3509 | 1 | 128, 147, 38, 36, 170, 3, 219, 57, 41, 170, 154, 70, 101, 148, 97, 56, 10, 78, 228, 73, |
3510 | 1 | 31, 80, 54, 15, 63, 199, 161, 208, 72, 210, 244, 61, 84, 72, 86, 109, 19, 178, 194, 29, |
3511 | 1 | 82, 235, 54, 8, 0, 0, 20, 4, 208, 7, 0, 0, 128, 168, 8, 223, 128, 19, 115, 13, 177, 22, |
3512 | 1 | 48, 50, 80, 72, 252, 203, 215, 48, 60, 129, 188, 92, 5, 13, 163, 145, 124, 179, 220, |
3513 | 1 | 168, 105, 39, 210, 45, 4, 128, 79, 131, 128, 20, 213, 120, 144, 141, 26, 15, 180, 246, |
3514 | 1 | 37, 130, 195, 20, 87, 34, 156, 164, 192, 10, 166, 200, 213, 25, 203, 21, 14, 69, 84, |
3515 | 1 | 226, 56, 192, 99, 128, 110, 115, 126, 128, 243, 71, 32, 198, 95, 48, 174, 155, 229, 56, |
3516 | 1 | 53, 58, 183, 179, 227, 139, 216, 12, 81, 234, 207, 44, 238, 102, 197, 209, 1, 208, 128, |
3517 | 1 | 89, 88, 80, 250, 103, 38, 222, 216, 71, 7, 78, 78, 106, 90, 60, 238, 133, 246, 234, 89, |
3518 | 1 | 19, 134, 52, 83, 122, 79, 86, 156, 156, 240, 174, 168, 128, 18, 109, 61, 180, 55, 209, |
3519 | 1 | 158, 82, 194, 2, 191, 93, 247, 158, 134, 120, 210, 92, 27, 100, 153, 28, 66, 104, 90, |
3520 | 1 | 219, 20, 109, 128, 99, 115, 105, 128, 205, 161, 83, 198, 116, 88, 179, 38, 81, 113, |
3521 | 1 | 164, 203, 138, 212, 213, 62, 203, 136, 190, 174, 170, 215, 241, 154, 78, 190, 26, 50, |
3522 | 1 | 235, 48, 165, 37, 128, 67, 56, 194, 132, 24, 75, 242, 97, 233, 210, 64, 173, 129, 36, |
3523 | 1 | 81, 192, 161, 57, 220, 219, 173, 145, 112, 1, 204, 143, 62, 30, 248, 100, 150, 27, 128, |
3524 | 1 | 55, 250, 123, 249, 194, 102, 143, 199, 227, 224, 198, 183, 137, 26, 1, 32, 155, 111, |
3525 | 1 | 94, 43, 18, 60, 232, 54, 161, 189, 243, 55, 82, 253, 61, 178, 128, 35, 11, 46, 39, 210, |
3526 | 1 | 125, 54, 239, 129, 250, 241, 250, 219, 106, 127, 43, 233, 151, 235, 202, 69, 11, 117, |
3527 | 1 | 225, 154, 30, 58, 215, 56, 225, 163, 8, 61, 6, 128, 79, 247, 128, 101, 216, 101, 61, |
3528 | 1 | 68, 147, 139, 94, 163, 133, 93, 91, 1, 135, 166, 64, 226, 157, 193, 145, 206, 67, 139, |
3529 | 1 | 94, 70, 249, 78, 51, 180, 181, 95, 194, 128, 119, 168, 231, 184, 144, 149, 80, 16, 45, |
3530 | 1 | 136, 189, 172, 154, 110, 72, 200, 168, 14, 56, 144, 74, 145, 146, 34, 152, 27, 144, |
3531 | 1 | 214, 222, 134, 202, 73, 128, 35, 97, 242, 87, 164, 192, 90, 176, 249, 195, 90, 69, 119, |
3532 | 1 | 88, 98, 81, 97, 223, 4, 91, 213, 13, 57, 222, 33, 80, 83, 83, 47, 63, 4, 218, 128, 127, |
3533 | 1 | 185, 204, 141, 45, 105, 190, 96, 207, 251, 98, 246, 128, 19, 238, 219, 241, 95, 143, |
3534 | 1 | 245, 226, 71, 10, 218, 133, 159, 147, 33, 71, 6, 15, 79, 128, 157, 0, 37, 176, 232, 63, |
3535 | 1 | 152, 4, 142, 116, 171, 239, 208, 197, 253, 43, 129, 75, 249, 124, 204, 110, 31, 84, |
3536 | 1 | 126, 33, 92, 225, 218, 79, 74, 168, 128, 52, 118, 216, 62, 104, 191, 32, 61, 212, 113, |
3537 | 1 | 154, 195, 184, 106, 195, 40, 148, 56, 227, 44, 60, 4, 238, 188, 83, 49, 55, 122, 63, |
3538 | 1 | 41, 243, 73, 128, 159, 216, 188, 248, 113, 154, 85, 212, 50, 27, 64, 97, 117, 111, 161, |
3539 | 1 | 78, 136, 238, 147, 212, 146, 176, 12, 165, 198, 7, 106, 174, 77, 192, 233, 196, 128, |
3540 | 1 | 191, 37, 239, 196, 45, 101, 231, 194, 150, 149, 223, 27, 130, 167, 29, 53, 127, 251, |
3541 | 1 | 178, 127, 73, 39, 121, 80, 153, 61, 72, 197, 65, 71, 234, 97, 128, 105, 92, 47, 177, |
3542 | 1 | 139, 229, 77, 134, 20, 219, 71, 102, 157, 6, 246, 137, 23, 189, 41, 20, 252, 202, 151, |
3543 | 1 | 219, 2, 97, 46, 208, 16, 0, 65, 164, 128, 186, 119, 223, 30, 63, 220, 138, 174, 183, |
3544 | 1 | 154, 191, 202, 42, 183, 3, 177, 35, 26, 240, 251, 107, 232, 2, 211, 126, 125, 148, 32, |
3545 | 1 | 170, 79, 89, 147, 128, 64, 140, 157, 182, 120, 15, 172, 143, 144, 94, 148, 165, 183, |
3546 | 1 | 32, 31, 106, 183, 13, 156, 106, 20, 254, 240, 238, 39, 170, 216, 96, 85, 17, 28, 51, |
3547 | 1 | 128, 105, 204, 70, 137, 155, 4, 189, 104, 168, 107, 111, 38, 122, 49, 92, 162, 235, 0, |
3548 | 1 | 20, 230, 237, 59, 171, 115, 112, 229, 101, 60, 235, 61, 246, 85, 169, 3, 128, 92, 131, |
3549 | 1 | 128, 14, 180, 168, 203, 209, 249, 124, 162, 43, 82, 228, 0, 80, 246, 83, 32, 28, 167, |
3550 | 1 | 8, 79, 63, 100, 180, 114, 58, 121, 59, 171, 174, 221, 102, 87, 128, 145, 197, 244, 206, |
3551 | 1 | 108, 25, 176, 239, 66, 39, 129, 37, 57, 248, 146, 179, 2, 252, 171, 16, 145, 170, 229, |
3552 | 1 | 41, 105, 62, 232, 137, 5, 207, 126, 5, 128, 243, 7, 177, 131, 247, 141, 69, 50, 131, |
3553 | 1 | 192, 167, 60, 220, 211, 183, 111, 236, 202, 191, 109, 133, 116, 74, 47, 40, 122, 99, |
3554 | 1 | 157, 169, 177, 18, 94, 128, 127, 55, 72, 203, 178, 1, 55, 56, 95, 162, 106, 6, 170, 8, |
3555 | 1 | 63, 70, 87, 203, 23, 214, 11, 12, 31, 91, 148, 236, 123, 237, 7, 98, 52, 188, 128, 154, |
3556 | 1 | 237, 168, 207, 60, 59, 60, 77, 238, 204, 166, 130, 207, 198, 28, 187, 78, 38, 8, 24, |
3557 | 1 | 192, 88, 37, 129, 207, 15, 206, 87, 31, 85, 125, 5, 128, 213, 10, 157, 170, 102, 230, |
3558 | 1 | 227, 250, 251, 242, 182, 84, 92, 79, 143, 122, 14, 6, 125, 216, 242, 223, 48, 153, 181, |
3559 | 1 | 116, 9, 83, 229, 27, 162, 47, 128, 246, 255, 41, 225, 153, 210, 213, 120, 188, 22, 40, |
3560 | 1 | 219, 31, 243, 76, 123, 114, 58, 216, 167, 193, 118, 64, 3, 206, 168, 143, 182, 112, |
3561 | 1 | 161, 1, 62, 153, 1, 128, 97, 0, 128, 45, 199, 40, 113, 114, 99, 47, 89, 245, 58, 100, |
3562 | 1 | 218, 114, 253, 178, 216, 214, 165, 232, 178, 178, 80, 10, 41, 239, 220, 202, 107, 40, |
3563 | 1 | 27, 42, 110, 128, 167, 212, 116, 25, 76, 228, 46, 26, 189, 37, 28, 123, 207, 152, 106, |
3564 | 1 | 93, 14, 82, 180, 253, 105, 219, 88, 87, 123, 69, 203, 93, 144, 228, 74, 120, 128, 12, |
3565 | 1 | 113, 218, 42, 183, 196, 72, 154, 247, 125, 54, 106, 241, 208, 223, 167, 227, 147, 65, |
3566 | 1 | 147, 239, 145, 221, 25, 53, 174, 62, 3, 204, 176, 247, 251, 169, 3, 128, 117, 136, 128, |
3567 | 1 | 37, 110, 87, 76, 38, 205, 59, 113, 135, 250, 83, 3, 242, 48, 181, 231, 7, 190, 169, |
3568 | 1 | 195, 200, 176, 95, 254, 159, 4, 252, 217, 57, 194, 39, 183, 128, 219, 102, 10, 168, |
3569 | 1 | 143, 146, 226, 128, 96, 221, 46, 13, 111, 99, 91, 214, 232, 242, 235, 16, 7, 87, 139, |
3570 | 1 | 0, 54, 105, 175, 154, 105, 213, 179, 45, 128, 38, 4, 207, 102, 186, 184, 246, 255, 135, |
3571 | 1 | 72, 155, 126, 8, 172, 228, 247, 183, 166, 64, 140, 138, 146, 207, 179, 66, 29, 162, |
3572 | 1 | 184, 170, 41, 213, 247, 128, 246, 88, 16, 133, 243, 123, 211, 255, 191, 22, 55, 46, |
3573 | 1 | 248, 129, 10, 19, 79, 124, 114, 241, 136, 188, 123, 128, 210, 126, 222, 84, 158, 1, |
3574 | 1 | 178, 127, 128, 57, 206, 238, 180, 9, 57, 140, 173, 104, 92, 100, 52, 175, 204, 219, 22, |
3575 | 1 | 12, 185, 104, 67, 136, 252, 241, 117, 109, 39, 162, 173, 208, 70, 171, 70, 128, 220, |
3576 | 1 | 204, 146, 112, 189, 59, 183, 80, 235, 97, 155, 99, 170, 254, 46, 92, 121, 95, 102, 92, |
3577 | 1 | 212, 30, 59, 102, 230, 166, 195, 83, 201, 216, 254, 161, 128, 71, 45, 43, 203, 28, 100, |
3578 | 1 | 234, 156, 200, 119, 114, 254, 26, 209, 31, 137, 109, 195, 174, 26, 50, 226, 34, 216, |
3579 | 1 | 113, 160, 158, 223, 30, 124, 131, 182, 45, 4, 128, 123, 3, 128, 79, 5, 96, 106, 69, |
3580 | 1 | 165, 183, 240, 203, 190, 17, 194, 115, 75, 209, 72, 231, 241, 199, 90, 202, 148, 153, |
3581 | 1 | 24, 73, 109, 39, 15, 236, 230, 185, 5, 128, 91, 211, 91, 190, 44, 198, 19, 38, 21, 57, |
3582 | 1 | 17, 99, 203, 172, 189, 131, 163, 91, 60, 135, 63, 79, 141, 17, 184, 75, 219, 175, 69, |
3583 | 1 | 218, 178, 139, 128, 81, 245, 150, 206, 170, 247, 138, 157, 224, 9, 173, 137, 16, 89, |
3584 | 1 | 58, 8, 238, 204, 121, 119, 184, 254, 31, 225, 79, 239, 69, 74, 199, 99, 42, 5, 128, 54, |
3585 | 1 | 10, 235, 51, 93, 131, 110, 185, 47, 209, 125, 198, 186, 59, 110, 217, 228, 174, 59, 64, |
3586 | 1 | 172, 92, 34, 81, 93, 40, 79, 170, 106, 45, 91, 224, 128, 71, 11, 63, 207, 170, 123, 71, |
3587 | 1 | 59, 23, 21, 98, 83, 95, 34, 187, 98, 129, 15, 201, 98, 217, 203, 65, 82, 5, 22, 90, |
3588 | 1 | 214, 114, 109, 32, 155, 128, 218, 104, 4, 83, 232, 255, 204, 138, 243, 84, 109, 249, |
3589 | 1 | 83, 248, 255, 84, 8, 180, 141, 7, 17, 47, 174, 46, 94, 4, 23, 60, 132, 15, 22, 125, |
3590 | 1 | 128, 18, 163, 43, 202, 192, 74, 238, 33, 157, 22, 248, 162, 41, 233, 28, 235, 139, 111, |
3591 | 1 | 202, 73, 203, 238, 18, 152, 150, 155, 167, 128, 182, 127, 19, 80, 128, 180, 199, 105, |
3592 | 1 | 82, 107, 193, 234, 226, 112, 82, 212, 23, 243, 246, 218, 242, 136, 89, 241, 181, 236, |
3593 | 1 | 126, 166, 43, 45, 123, 241, 252, 172, 155, 101, 227, 193, 6, 128, 127, 221, 128, 27, |
3594 | 1 | 202, 207, 198, 230, 72, 2, 38, 173, 154, 239, 111, 208, 86, 200, 0, 25, 154, 223, 131, |
3595 | 1 | 217, 90, 53, 175, 29, 11, 220, 189, 240, 58, 69, 179, 128, 85, 177, 113, 182, 100, 237, |
3596 | 1 | 49, 35, 26, 114, 195, 251, 45, 76, 169, 33, 69, 115, 125, 104, 252, 202, 133, 67, 241, |
3597 | 1 | 172, 89, 252, 135, 197, 246, 242, 128, 59, 46, 192, 167, 31, 58, 223, 79, 95, 175, 63, |
3598 | 1 | 203, 147, 91, 57, 19, 162, 111, 159, 213, 69, 136, 249, 49, 148, 163, 9, 191, 159, 234, |
3599 | 1 | 160, 23, 128, 114, 27, 121, 70, 247, 203, 210, 27, 232, 1, 51, 138, 43, 137, 86, 43, |
3600 | 1 | 105, 212, 157, 88, 69, 233, 63, 1, 178, 19, 60, 163, 6, 168, 90, 99, 128, 26, 91, 236, |
3601 | 1 | 132, 54, 200, 118, 34, 45, 153, 180, 162, 26, 184, 165, 84, 253, 169, 43, 228, 149, |
3602 | 1 | 169, 250, 133, 45, 140, 100, 195, 81, 131, 182, 229, 128, 245, 0, 224, 204, 156, 4, |
3603 | 1 | 163, 58, 175, 50, 117, 21, 47, 176, 142, 139, 31, 116, 111, 244, 38, 1, 203, 230, 63, |
3604 | 1 | 96, 46, 86, 77, 171, 28, 22, 128, 7, 176, 191, 105, 171, 18, 194, 54, 90, 234, 236, 74, |
3605 | 1 | 37, 86, 49, 94, 106, 39, 202, 147, 25, 213, 64, 216, 188, 228, 234, 113, 166, 22, 200, |
3606 | 1 | 107, 128, 166, 43, 64, 205, 131, 244, 72, 170, 247, 240, 13, 242, 253, 95, 152, 67, |
3607 | 1 | 222, 211, 14, 68, 10, 124, 151, 41, 73, 109, 149, 24, 61, 149, 213, 59, 128, 198, 236, |
3608 | 1 | 228, 247, 8, 86, 104, 247, 81, 100, 184, 202, 247, 36, 8, 202, 169, 218, 193, 42, 51, |
3609 | 1 | 53, 189, 181, 168, 200, 141, 241, 141, 69, 175, 18, 128, 73, 38, 28, 179, 119, 24, 238, |
3610 | 1 | 22, 73, 89, 168, 79, 77, 107, 74, 53, 122, 242, 78, 13, 194, 213, 7, 140, 157, 91, 39, |
3611 | 1 | 125, 60, 50, 161, 143, 128, 2, 138, 187, 57, 144, 148, 167, 191, 49, 220, 130, 10, 156, |
3612 | 1 | 251, 179, 142, 79, 149, 229, 86, 242, 156, 62, 72, 26, 40, 103, 16, 89, 62, 234, 175, |
3613 | 1 | 128, 58, 2, 12, 227, 254, 93, 208, 176, 215, 94, 98, 113, 206, 156, 42, 81, 205, 178, |
3614 | 1 | 46, 55, 218, 23, 51, 221, 178, 82, 232, 240, 32, 150, 191, 52, 128, 162, 252, 53, 223, |
3615 | 1 | 81, 139, 166, 174, 245, 241, 232, 95, 1, 132, 25, 39, 250, 154, 92, 166, 93, 26, 198, |
3616 | 1 | 190, 25, 45, 1, 208, 216, 222, 66, 203, 21, 1, 128, 128, 8, 128, 114, 48, 169, 34, 134, |
3617 | 1 | 225, 186, 235, 158, 65, 12, 208, 240, 49, 241, 59, 250, 236, 56, 33, 227, 117, 255, |
3618 | 1 | 242, 226, 38, 143, 23, 11, 141, 119, 94, 128, 209, 188, 41, 4, 130, 106, 174, 236, 251, |
3619 | 1 | 133, 14, 113, 26, 58, 233, 88, 162, 41, 19, 1, 29, 12, 111, 104, 6, 117, 145, 185, 173, |
3620 | 1 | 131, 13, 76, 105, 1, 128, 128, 23, 52, 70, 7, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, 0, |
3621 | 1 | 120, 129, 0, 136, 0, 48, 68, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, 0, 48, 68, 0, 0, 32, |
3622 | 1 | 170, 170, 10, 0, 0, 0, 64, 0, 52, 70, 3, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, 0, 52, |
3623 | 1 | 70, 3, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, 0, 52, 70, 8, 0, 0, 32, 170, 170, 10, 0, 0, |
3624 | 1 | 0, 64, 0, 29, 2, 128, 136, 20, 128, 143, 139, 167, 161, 117, 195, 85, 136, 73, 184, 83, |
3625 | 1 | 55, 127, 1, 66, 200, 78, 154, 73, 40, 53, 247, 122, 170, 160, 65, 233, 13, 48, 145, 32, |
3626 | 1 | 140, 128, 27, 84, 51, 50, 109, 153, 218, 23, 97, 32, 91, 76, 238, 92, 108, 233, 75, |
3627 | 1 | 153, 216, 73, 202, 147, 57, 91, 187, 21, 214, 194, 17, 250, 227, 230, 128, 222, 59, 6, |
3628 | 1 | 253, 61, 138, 81, 130, 84, 99, 239, 67, 0, 235, 68, 95, 246, 6, 189, 199, 0, 82, 109, |
3629 | 1 | 204, 191, 82, 48, 36, 199, 184, 48, 214, 128, 46, 207, 255, 17, 19, 214, 251, 229, 90, |
3630 | 1 | 118, 82, 55, 220, 135, 239, 251, 41, 49, 118, 150, 182, 47, 237, 57, 199, 99, 8, 107, |
3631 | 1 | 98, 123, 161, 74, 29, 2, 128, 145, 8, 128, 19, 70, 142, 85, 1, 89, 247, 44, 175, 239, |
3632 | 1 | 23, 198, 122, 63, 223, 123, 2, 144, 158, 181, 109, 134, 250, 229, 171, 85, 169, 230, |
3633 | 1 | 196, 47, 34, 238, 128, 140, 143, 186, 186, 121, 102, 5, 30, 92, 82, 92, 130, 217, 98, |
3634 | 1 | 39, 22, 38, 44, 162, 89, 41, 149, 42, 142, 108, 47, 106, 195, 220, 136, 134, 153, 128, |
3635 | 1 | 89, 156, 75, 125, 242, 28, 164, 49, 134, 244, 162, 10, 127, 109, 171, 142, 239, 1, 207, |
3636 | 1 | 77, 150, 90, 136, 247, 227, 103, 216, 26, 7, 44, 60, 228, 128, 106, 243, 15, 51, 147, |
3637 | 1 | 103, 66, 233, 183, 99, 156, 152, 153, 14, 47, 74, 46, 80, 163, 181, 125, 243, 253, 136, |
3638 | 1 | 231, 248, 239, 210, 12, 24, 38, 228, 53, 5, 128, 166, 243, 128, 60, 254, 149, 217, 214, |
3639 | 1 | 10, 154, 116, 160, 73, 126, 32, 228, 50, 39, 237, 169, 109, 205, 110, 181, 177, 64, |
3640 | 1 | 122, 37, 20, 130, 116, 222, 242, 221, 69, 128, 189, 63, 199, 104, 252, 239, 108, 216, |
3641 | 1 | 134, 109, 31, 244, 155, 141, 23, 100, 59, 234, 2, 38, 117, 124, 220, 5, 84, 239, 56, |
3642 | 1 | 41, 114, 76, 220, 101, 128, 99, 69, 152, 115, 12, 134, 76, 232, 82, 91, 83, 215, 16, |
3643 | 1 | 149, 38, 7, 145, 26, 90, 225, 2, 47, 174, 213, 174, 14, 145, 65, 165, 202, 80, 181, |
3644 | 1 | 128, 15, 215, 126, 220, 79, 106, 33, 145, 47, 149, 163, 39, 112, 117, 237, 243, 63, |
3645 | 1 | 129, 12, 24, 0, 54, 65, 160, 22, 8, 227, 184, 139, 96, 245, 118, 128, 238, 93, 61, 45, |
3646 | 1 | 186, 136, 187, 107, 98, 220, 78, 139, 226, 54, 82, 136, 199, 246, 7, 124, 89, 134, 10, |
3647 | 1 | 156, 189, 3, 108, 126, 35, 159, 78, 167, 128, 240, 126, 62, 164, 189, 130, 33, 150, |
3648 | 1 | 194, 154, 59, 36, 160, 24, 250, 128, 54, 183, 125, 69, 57, 194, 81, 17, 15, 160, 177, |
3649 | 1 | 249, 94, 234, 139, 63, 128, 210, 182, 101, 67, 23, 240, 154, 123, 80, 220, 2, 136, 47, |
3650 | 1 | 184, 133, 29, 127, 170, 53, 20, 42, 168, 78, 183, 173, 164, 178, 34, 121, 129, 80, 213, |
3651 | 1 | 128, 65, 149, 234, 136, 181, 209, 12, 122, 140, 115, 72, 196, 158, 6, 199, 126, 53, 97, |
3652 | 1 | 31, 159, 83, 216, 197, 194, 122, 251, 138, 147, 210, 181, 9, 57, 128, 87, 58, 133, 140, |
3653 | 1 | 119, 49, 56, 139, 158, 63, 187, 22, 129, 205, 62, 148, 104, 212, 105, 251, 3, 253, 84, |
3654 | 1 | 200, 243, 27, 217, 245, 143, 52, 80, 32, 128, 1, 23, 243, 176, 109, 129, 63, 150, 3, |
3655 | 1 | 217, 13, 115, 108, 65, 232, 112, 144, 231, 50, 214, 46, 73, 118, 177, 152, 1, 167, 91, |
3656 | 1 | 107, 85, 73, 105, 21, 1, 128, 192, 0, 128, 68, 103, 222, 127, 151, 101, 48, 63, 21, 27, |
3657 | 1 | 249, 99, 114, 241, 152, 144, 198, 236, 81, 26, 238, 173, 237, 74, 222, 82, 3, 23, 83, |
3658 | 1 | 144, 121, 181, 128, 68, 228, 177, 183, 95, 23, 59, 83, 34, 139, 102, 169, 137, 101, |
3659 | 1 | 117, 235, 120, 239, 231, 138, 204, 58, 67, 130, 225, 221, 204, 91, 77, 235, 99, 238, |
3660 | 1 | 161, 2, 128, 192, 137, 128, 232, 170, 107, 212, 154, 43, 246, 160, 246, 42, 233, 97, |
3661 | 1 | 13, 78, 77, 72, 178, 201, 224, 233, 249, 199, 32, 42, 180, 80, 56, 65, 55, 199, 12, |
3662 | 1 | 211, 128, 30, 153, 81, 63, 252, 221, 150, 63, 164, 70, 31, 239, 235, 84, 151, 78, 78, |
3663 | 1 | 116, 195, 250, 32, 213, 7, 150, 41, 212, 48, 49, 200, 7, 95, 43, 128, 68, 194, 200, |
3664 | 1 | 226, 151, 111, 153, 106, 97, 148, 58, 148, 155, 126, 199, 185, 213, 247, 148, 221, 75, |
3665 | 1 | 167, 49, 251, 18, 193, 236, 26, 84, 184, 219, 37, 128, 198, 39, 157, 12, 171, 61, 71, |
3666 | 1 | 228, 113, 25, 145, 88, 18, 2, 77, 229, 50, 61, 188, 135, 114, 200, 211, 21, 84, 130, |
3667 | 1 | 15, 80, 50, 214, 213, 22, 128, 219, 111, 182, 117, 209, 129, 79, 139, 66, 165, 17, 102, |
3668 | 1 | 171, 104, 27, 192, 238, 193, 120, 126, 127, 69, 184, 180, 224, 32, 22, 186, 216, 171, |
3669 | 1 | 184, 99, 45, 4, 128, 195, 156, 128, 171, 120, 138, 42, 238, 136, 62, 91, 110, 195, 9, |
3670 | 1 | 194, 23, 28, 54, 148, 123, 169, 189, 95, 51, 27, 223, 1, 183, 54, 153, 109, 157, 209, |
3671 | 1 | 163, 89, 128, 67, 166, 163, 235, 81, 160, 192, 95, 65, 87, 97, 46, 187, 146, 0, 177, |
3672 | 1 | 248, 191, 214, 39, 108, 113, 21, 246, 201, 220, 216, 146, 252, 121, 119, 170, 128, 34, |
3673 | 1 | 157, 88, 166, 119, 216, 68, 88, 5, 196, 60, 209, 191, 63, 113, 166, 233, 209, 189, 39, |
3674 | 1 | 13, 187, 69, 254, 247, 230, 244, 97, 252, 2, 66, 43, 128, 188, 229, 123, 138, 104, 238, |
3675 | 1 | 43, 99, 118, 167, 53, 88, 184, 188, 251, 208, 208, 194, 189, 65, 55, 36, 75, 201, 255, |
3676 | 1 | 108, 237, 29, 27, 59, 226, 97, 128, 91, 188, 126, 217, 191, 148, 220, 250, 57, 138, |
3677 | 1 | 205, 64, 183, 142, 62, 52, 2, 91, 72, 154, 158, 247, 178, 91, 25, 96, 37, 204, 207, |
3678 | 1 | 237, 140, 158, 128, 251, 223, 131, 111, 163, 194, 203, 64, 124, 77, 112, 193, 54, 144, |
3679 | 1 | 70, 231, 92, 139, 224, 169, 186, 203, 231, 198, 134, 115, 114, 163, 204, 38, 113, 112, |
3680 | 1 | 128, 197, 74, 235, 82, 103, 244, 94, 93, 22, 130, 214, 133, 235, 139, 46, 128, 198, |
3681 | 1 | 199, 73, 69, 65, 51, 13, 11, 125, 83, 218, 243, 40, 104, 163, 76, 128, 106, 199, 171, |
3682 | 1 | 70, 60, 21, 5, 165, 236, 63, 91, 185, 18, 84, 178, 146, 70, 125, 213, 147, 206, 34, 46, |
3683 | 1 | 21, 26, 251, 126, 93, 0, 19, 101, 76, 29, 2, 128, 216, 0, 128, 188, 207, 83, 62, 14, |
3684 | 1 | 128, 169, 87, 187, 41, 242, 150, 93, 220, 72, 101, 230, 31, 45, 106, 144, 149, 225, |
3685 | 1 | 126, 243, 52, 254, 101, 141, 114, 26, 74, 128, 182, 4, 240, 217, 196, 20, 63, 210, 63, |
3686 | 1 | 107, 159, 124, 47, 130, 184, 252, 193, 153, 215, 95, 207, 242, 134, 180, 38, 244, 103, |
3687 | 1 | 185, 200, 58, 112, 29, 128, 102, 114, 227, 186, 190, 25, 167, 44, 72, 48, 232, 102, |
3688 | 1 | 171, 153, 98, 134, 127, 158, 86, 125, 35, 236, 119, 195, 194, 197, 213, 43, 92, 210, |
3689 | 1 | 41, 34, 128, 4, 212, 195, 198, 159, 208, 222, 57, 1, 254, 64, 98, 239, 148, 178, 231, |
3690 | 1 | 233, 158, 137, 173, 96, 60, 134, 228, 83, 24, 36, 0, 153, 71, 39, 43, 185, 5, 128, 230, |
3691 | 1 | 119, 128, 101, 195, 92, 254, 39, 167, 70, 226, 25, 48, 175, 65, 60, 166, 33, 103, 51, |
3692 | 1 | 27, 5, 236, 212, 220, 154, 214, 22, 131, 185, 50, 230, 213, 42, 179, 128, 110, 233, |
3693 | 1 | 144, 217, 154, 56, 204, 107, 58, 10, 152, 235, 170, 6, 25, 10, 90, 28, 178, 149, 186, |
3694 | 1 | 224, 161, 164, 102, 204, 12, 219, 238, 48, 35, 32, 128, 156, 141, 55, 26, 82, 40, 209, |
3695 | 1 | 245, 60, 202, 219, 164, 106, 94, 189, 1, 231, 190, 190, 189, 213, 179, 63, 108, 20, 74, |
3696 | 1 | 235, 166, 170, 62, 100, 21, 128, 169, 233, 221, 114, 77, 213, 3, 223, 95, 44, 41, 224, |
3697 | 1 | 30, 7, 70, 151, 212, 160, 237, 139, 102, 176, 19, 186, 19, 94, 86, 26, 57, 138, 158, |
3698 | 1 | 52, 128, 103, 54, 85, 37, 174, 122, 105, 162, 107, 124, 188, 122, 215, 38, 82, 77, 53, |
3699 | 1 | 70, 250, 237, 199, 78, 204, 139, 214, 212, 11, 131, 31, 246, 200, 99, 128, 141, 94, 22, |
3700 | 1 | 106, 210, 251, 174, 187, 143, 165, 218, 180, 147, 133, 234, 74, 200, 99, 229, 252, 149, |
3701 | 1 | 165, 195, 199, 234, 161, 6, 113, 81, 56, 227, 45, 128, 29, 178, 129, 32, 10, 186, 203, |
3702 | 1 | 184, 188, 6, 183, 32, 121, 233, 33, 112, 78, 112, 127, 48, 148, 193, 150, 121, 179, 99, |
3703 | 1 | 215, 156, 151, 139, 141, 145, 128, 114, 94, 183, 175, 148, 171, 242, 89, 167, 215, 218, |
3704 | 1 | 223, 239, 252, 253, 218, 157, 126, 198, 216, 63, 161, 5, 226, 107, 198, 213, 77, 105, |
3705 | 1 | 237, 60, 231, 128, 236, 110, 114, 56, 203, 168, 8, 28, 132, 25, 55, 59, 43, 217, 243, |
3706 | 1 | 175, 167, 19, 92, 36, 123, 120, 72, 2, 214, 186, 242, 47, 94, 34, 154, 241, 128, 206, |
3707 | 1 | 188, 33, 19, 225, 19, 240, 144, 42, 245, 206, 39, 22, 30, 216, 48, 42, 236, 216, 100, |
3708 | 1 | 91, 73, 54, 155, 248, 148, 209, 196, 124, 233, 150, 121, 128, 245, 219, 17, 139, 77, |
3709 | 1 | 90, 45, 246, 142, 210, 156, 98, 21, 66, 181, 247, 127, 190, 255, 143, 122, 164, 208, |
3710 | 1 | 104, 242, 65, 226, 102, 62, 215, 39, 176, 177, 4, 128, 234, 228, 128, 30, 192, 20, 87, |
3711 | 1 | 223, 121, 117, 244, 12, 227, 43, 102, 15, 250, 107, 29, 11, 164, 34, 194, 100, 22, 251, |
3712 | 1 | 230, 189, 28, 194, 232, 239, 208, 109, 179, 128, 239, 127, 96, 59, 248, 70, 89, 156, |
3713 | 1 | 28, 42, 92, 30, 147, 240, 5, 140, 44, 23, 53, 119, 104, 134, 221, 184, 76, 202, 80, |
3714 | 1 | 193, 126, 70, 222, 191, 128, 243, 14, 165, 135, 159, 4, 240, 225, 212, 40, 50, 122, |
3715 | 1 | 137, 96, 97, 215, 253, 49, 134, 45, 131, 8, 224, 22, 9, 189, 169, 181, 57, 223, 238, |
3716 | 1 | 22, 128, 125, 52, 140, 94, 44, 150, 105, 198, 134, 67, 46, 16, 113, 105, 73, 216, 251, |
3717 | 1 | 21, 84, 3, 144, 253, 155, 49, 140, 47, 54, 115, 90, 210, 18, 99, 128, 142, 79, 4, 216, |
3718 | 1 | 6, 26, 125, 208, 110, 30, 57, 119, 142, 84, 7, 153, 213, 143, 132, 236, 80, 248, 155, |
3719 | 1 | 52, 70, 47, 20, 100, 175, 110, 122, 182, 128, 14, 19, 178, 216, 105, 190, 191, 175, 69, |
3720 | 1 | 45, 180, 143, 169, 26, 52, 215, 129, 11, 209, 254, 128, 143, 96, 96, 34, 136, 66, 49, |
3721 | 1 | 61, 94, 37, 106, 128, 157, 204, 62, 20, 177, 207, 1, 189, 23, 105, 47, 99, 123, 186, |
3722 | 1 | 81, 234, 62, 150, 52, 133, 95, 16, 62, 207, 148, 189, 103, 189, 110, 160, 54, 134, 128, |
3723 | 1 | 167, 36, 90, 235, 145, 50, 172, 144, 76, 59, 237, 96, 34, 68, 117, 34, 216, 227, 239, |
3724 | 1 | 212, 62, 30, 103, 159, 218, 83, 174, 112, 84, 10, 192, 169, 128, 136, 129, 23, 183, |
3725 | 1 | 165, 202, 64, 101, 115, 137, 219, 120, 228, 202, 166, 12, 166, 0, 179, 55, 63, 250, |
3726 | 1 | 223, 240, 52, 114, 230, 147, 235, 70, 27, 220, 61, 6, 128, 249, 221, 128, 180, 85, 74, |
3727 | 1 | 252, 209, 157, 27, 180, 238, 3, 30, 76, 123, 36, 252, 208, 206, 83, 184, 195, 81, 13, |
3728 | 1 | 46, 142, 251, 46, 24, 79, 164, 216, 122, 242, 128, 11, 108, 238, 99, 155, 87, 3, 218, |
3729 | 1 | 158, 188, 173, 127, 101, 29, 16, 76, 82, 248, 56, 98, 110, 247, 10, 64, 31, 171, 69, |
3730 | 1 | 166, 73, 247, 105, 55, 128, 8, 174, 229, 42, 117, 92, 182, 37, 49, 123, 3, 227, 217, |
3731 | 1 | 164, 54, 155, 153, 45, 75, 87, 145, 77, 190, 18, 202, 222, 96, 202, 108, 110, 242, 39, |
3732 | 1 | 128, 59, 51, 191, 181, 246, 176, 10, 136, 252, 191, 169, 221, 11, 201, 44, 222, 74, |
3733 | 1 | 140, 69, 178, 127, 215, 183, 58, 251, 105, 253, 116, 246, 100, 63, 216, 128, 73, 184, |
3734 | 1 | 164, 26, 239, 85, 152, 34, 93, 88, 230, 101, 93, 252, 247, 149, 38, 29, 8, 229, 165, |
3735 | 1 | 162, 106, 166, 57, 87, 164, 244, 57, 78, 180, 124, 128, 78, 218, 168, 114, 74, 158, |
3736 | 1 | 137, 46, 169, 173, 112, 36, 99, 71, 116, 161, 41, 189, 188, 42, 214, 80, 115, 18, 78, |
3737 | 1 | 48, 230, 169, 8, 139, 245, 58, 128, 189, 8, 116, 87, 219, 183, 63, 54, 25, 77, 96, 237, |
3738 | 1 | 94, 161, 119, 46, 64, 33, 129, 125, 212, 1, 232, 127, 86, 76, 60, 41, 98, 159, 213, |
3739 | 1 | 234, 128, 148, 126, 164, 165, 2, 122, 13, 215, 242, 8, 55, 234, 20, 129, 243, 30, 41, |
3740 | 1 | 84, 176, 34, 51, 44, 190, 34, 16, 144, 186, 184, 166, 175, 218, 43, 128, 117, 213, 210, |
3741 | 1 | 131, 220, 245, 104, 21, 29, 36, 83, 200, 130, 242, 107, 53, 97, 14, 234, 87, 208, 88, |
3742 | 1 | 54, 46, 9, 143, 55, 242, 214, 211, 38, 136, 128, 43, 91, 98, 129, 232, 101, 38, 233, |
3743 | 1 | 26, 18, 177, 184, 47, 178, 74, 93, 120, 195, 73, 14, 72, 46, 145, 116, 39, 179, 220, |
3744 | 1 | 175, 220, 16, 246, 30, 128, 173, 215, 139, 229, 96, 88, 25, 222, 54, 197, 229, 77, 223, |
3745 | 1 | 241, 94, 215, 108, 108, 94, 106, 237, 61, 105, 103, 105, 140, 235, 247, 31, 206, 222, |
3746 | 1 | 36, 128, 45, 188, 212, 64, 246, 240, 29, 94, 234, 30, 164, 147, 12, 17, 119, 224, 174, |
3747 | 1 | 255, 195, 32, 197, 246, 216, 96, 219, 162, 184, 127, 172, 243, 4, 93, 77, 8, 128, 255, |
3748 | 1 | 255, 128, 214, 183, 46, 65, 206, 208, 60, 19, 255, 124, 46, 232, 18, 157, 143, 136, |
3749 | 1 | 196, 210, 54, 238, 85, 189, 88, 39, 27, 65, 180, 171, 56, 247, 243, 136, 128, 88, 29, |
3750 | 1 | 232, 38, 203, 121, 45, 5, 219, 134, 121, 144, 136, 98, 228, 93, 170, 51, 113, 202, 185, |
3751 | 1 | 53, 158, 202, 12, 61, 84, 149, 243, 171, 44, 234, 128, 216, 162, 184, 125, 251, 35, |
3752 | 1 | 198, 245, 36, 172, 140, 151, 209, 11, 197, 234, 5, 242, 79, 119, 22, 250, 135, 78, 251, |
3753 | 1 | 52, 178, 27, 221, 152, 73, 230, 128, 76, 193, 93, 5, 59, 133, 125, 206, 104, 138, 175, |
3754 | 1 | 216, 186, 149, 85, 200, 252, 90, 119, 128, 215, 218, 248, 234, 215, 5, 201, 122, 116, |
3755 | 1 | 90, 242, 224, 128, 160, 164, 164, 136, 135, 196, 100, 21, 11, 181, 114, 34, 228, 188, |
3756 | 1 | 20, 43, 105, 235, 84, 69, 26, 213, 62, 224, 32, 125, 63, 0, 65, 23, 44, 214, 128, 62, |
3757 | 1 | 178, 104, 169, 68, 96, 203, 136, 1, 116, 3, 252, 106, 135, 28, 203, 28, 144, 85, 204, |
3758 | 1 | 81, 65, 165, 18, 230, 216, 111, 110, 54, 200, 54, 189, 128, 42, 80, 28, 79, 205, 52, |
3759 | 1 | 213, 153, 204, 223, 10, 224, 159, 153, 128, 199, 98, 122, 209, 98, 159, 70, 116, 13, |
3760 | 1 | 17, 94, 178, 102, 164, 170, 19, 251, 128, 182, 14, 96, 17, 152, 100, 185, 227, 162, |
3761 | 1 | 111, 23, 79, 46, 155, 144, 19, 34, 253, 85, 51, 36, 179, 55, 214, 191, 202, 228, 241, |
3762 | 1 | 138, 138, 144, 224, 128, 113, 30, 86, 213, 49, 187, 12, 21, 94, 211, 71, 144, 238, 113, |
3763 | 1 | 204, 22, 212, 230, 82, 217, 77, 87, 0, 223, 170, 68, 254, 38, 192, 153, 141, 21, 128, |
3764 | 1 | 17, 137, 206, 119, 65, 254, 157, 248, 141, 32, 56, 250, 143, 90, 100, 116, 188, 32, |
3765 | 1 | 250, 210, 76, 18, 126, 15, 27, 44, 225, 219, 191, 12, 251, 82, 128, 138, 108, 229, 32, |
3766 | 1 | 63, 208, 65, 93, 233, 236, 222, 210, 47, 185, 13, 208, 147, 180, 0, 241, 164, 81, 179, |
3767 | 1 | 229, 211, 118, 194, 208, 152, 180, 138, 213, 128, 143, 246, 81, 32, 116, 114, 71, 248, |
3768 | 1 | 245, 9, 146, 196, 249, 29, 174, 216, 126, 120, 86, 221, 103, 126, 33, 116, 49, 107, |
3769 | 1 | 194, 112, 236, 244, 71, 255, 128, 27, 128, 218, 110, 199, 168, 65, 173, 167, 160, 124, |
3770 | 1 | 172, 143, 28, 35, 244, 4, 70, 162, 139, 65, 45, 84, 96, 13, 215, 26, 212, 209, 56, 80, |
3771 | 1 | 109, 128, 91, 243, 155, 88, 236, 144, 195, 210, 249, 195, 180, 131, 239, 123, 123, 14, |
3772 | 1 | 67, 39, 243, 54, 65, 213, 151, 129, 41, 167, 58, 100, 163, 91, 119, 187, 128, 90, 90, |
3773 | 1 | 75, 62, 10, 151, 189, 169, 18, 1, 25, 127, 240, 49, 132, 121, 147, 89, 191, 226, 36, |
3774 | 1 | 181, 66, 142, 156, 109, 35, 22, 7, 213, 108, 34, 128, 153, 240, 224, 49, 50, 154, 152, |
3775 | 1 | 212, 55, 106, 199, 31, 255, 117, 18, 152, 185, 146, 112, 56, 153, 46, 251, 209, 15, 45, |
3776 | 1 | 15, 81, 18, 37, 21, 223, 153, 3, 145, 3, 205, 176, 170, 20, 252, 130, 217, 241, 116, |
3777 | 1 | 109, 64, 227, 40, 66, 241, 42, 123, 46, 106, 207, 143, 212, 151, 166, 178, 183, 182, |
3778 | 1 | 191, 201, 14, 94, 239, 6, 162, 129, 1, 136, 23, 41, 28, 177, 15, 207, 131, 88, 111, |
3779 | 1 | 165, 230, 236, 186, 193, 33, 180, 214, 190, 188, 166, 152, 87, 119, 139, 114, 112, 203, |
3780 | 1 | 253, 184, 205, 22, 21, 70, 4, 48, 164, 26, 194, 148, 207, 197, 239, 95, 123, 247, 159, |
3781 | 1 | 138, 173, 124, 186, 123, 72, 233, 134, 186, 71, 87, 197, 30, 74, 19, 93, 183, 12, 6, |
3782 | 1 | 97, 117, 114, 97, 32, 137, 17, 122, 8, 0, 0, 0, 0, 4, 82, 80, 83, 82, 144, 93, 222, |
3783 | 1 | 196, 165, 53, 152, 190, 195, 59, 30, 52, 200, 188, 178, 200, 141, 57, 113, 179, 126, |
3784 | 1 | 125, 117, 18, 133, 51, 57, 237, 47, 93, 112, 73, 92, 70, 221, 41, 5, 5, 97, 117, 114, |
3785 | 1 | 97, 1, 1, 138, 45, 163, 204, 245, 128, 189, 37, 220, 27, 25, 24, 179, 226, 245, 170, |
3786 | 1 | 29, 146, 54, 138, 250, 138, 66, 60, 225, 190, 78, 223, 217, 210, 42, 69, 90, 227, 186, |
3787 | 1 | 39, 156, 76, 185, 125, 109, 73, 16, 24, 59, 168, 3, 242, 219, 22, 255, 227, 238, 62, |
3788 | 1 | 27, 211, 0, 249, 211, 134, 101, 151, 252, 131, 189, 2, 157, 0, 127, 3, 207, 220, 229, |
3789 | 1 | 134, 48, 16, 20, 112, 14, 44, 37, 147, 209, 192, 128, 99, 130, 139, 212, 253, 194, 223, |
3790 | 1 | 190, 188, 45, 122, 119, 27, 226, 20, 82, 45, 241, 81, 192, 56, 1, 226, 249, 192, 242, |
3791 | 1 | 243, 168, 232, 84, 120, 81, 80, 95, 14, 123, 144, 18, 9, 107, 65, 196, 235, 58, 175, |
3792 | 1 | 148, 127, 110, 164, 41, 8, 1, 0, 104, 95, 13, 158, 243, 183, 138, 253, 218, 183, 245, |
3793 | 1 | 199, 20, 33, 49, 19, 42, 212, 32, 207, 0, 0, 0, 0, 0, 0, 0, 88, 95, 2, 39, 95, 100, |
3794 | 1 | 195, 84, 149, 67, 82, 183, 30, 234, 57, 207, 172, 162, 16, 207, 0, 0, 0, 76, 95, 14, |
3795 | 1 | 194, 209, 122, 118, 21, 63, 245, 24, 23, 241, 45, 156, 252, 60, 127, 4, 0, 128, 252, |
3796 | 1 | 85, 218, 190, 35, 29, 95, 150, 6, 215, 151, 79, 25, 191, 250, 6, 233, 231, 98, 204, |
3797 | 1 | 218, 121, 107, 141, 56, 1, 71, 252, 18, 229, 7, 7, 65, 5, 157, 13, 160, 92, 165, 153, |
3798 | 1 | 19, 188, 56, 168, 99, 5, 144, 242, 98, 124, 23, 221, 128, 214, 76, 43, 0, 25, 180, 196, |
3799 | 1 | 32, 95, 72, 70, 105, 196, 99, 33, 230, 228, 0, 0, 179, 149, 109, 167, 188, 145, 242, |
3800 | 1 | 134, 23, 112, 166, 35, 225, 128, 230, 162, 186, 192, 190, 137, 255, 81, 200, 77, 62, |
3801 | 1 | 88, 131, 41, 224, 140, 137, 230, 92, 69, 189, 106, 48, 201, 154, 40, 28, 232, 195, 177, |
3802 | 1 | 208, 91, 128, 246, 46, 101, 112, 177, 251, 67, 34, 248, 76, 29, 159, 38, 149, 229, 207, |
3803 | 1 | 56, 19, 141, 45, 64, 8, 33, 60, 196, 85, 216, 137, 195, 140, 249, 96, 80, 95, 14, 123, |
3804 | 1 | 144, 18, 9, 107, 65, 196, 235, 58, 175, 148, 127, 110, 164, 41, 8, 0, 0, 128, 138, 164, |
3805 | 1 | 196, 190, 91, 169, 205, 37, 65, 107, 9, 60, 255, 26, 59, 7, 60, 136, 233, 135, 97, 1, |
3806 | 1 | 242, 163, 183, 145, 46, 192, 163, 249, 231, 8, 128, 37, 211, 77, 164, 50, 168, 251, |
3807 | 1 | 122, 59, 148, 129, 121, 37, 80, 116, 152, 106, 126, 121, 206, 28, 119, 15, 172, 150, |
3808 | 1 | 80, 20, 87, 32, 220, 42, 244, 128, 41, 71, 43, 133, 33, 47, 174, 182, 141, 160, 188, |
3809 | 1 | 55, 225, 183, 162, 210, 19, 213, 246, 198, 154, 164, 11, 18, 65, 255, 134, 74, 201, 85, |
3810 | 1 | 219, 43, 128, 70, 109, 244, 126, 9, 6, 105, 218, 161, 35, 22, 242, 196, 224, 15, 75, |
3811 | 1 | 72, 156, 77, 129, 66, 4, 66, 211, 41, 218, 127, 229, 223, 198, 78, 162, 128, 160, 22, |
3812 | 1 | 135, 237, 93, 217, 122, 94, 230, 138, 217, 44, 177, 216, 69, 134, 189, 18, 46, 24, 175, |
3813 | 1 | 110, 245, 187, 10, 83, 137, 12, 113, 96, 199, 88, 128, 18, 96, 166, 85, 235, 178, 43, |
3814 | 1 | 102, 144, 209, 50, 248, 124, 185, 152, 235, 204, 141, 63, 151, 34, 173, 6, 238, 224, |
3815 | 1 | 136, 176, 51, 144, 130, 31, 230, 173, 5, 158, 113, 11, 48, 189, 46, 171, 3, 82, 221, |
3816 | 1 | 204, 38, 65, 122, 161, 148, 95, 211, 128, 224, 161, 245, 222, 111, 139, 192, 87, 188, |
3817 | 1 | 182, 173, 177, 227, 195, 210, 101, 250, 18, 102, 145, 25, 162, 40, 37, 165, 206, 22, |
3818 | 1 | 113, 187, 94, 153, 53, 128, 144, 117, 56, 193, 83, 221, 142, 237, 160, 251, 50, 200, |
3819 | 1 | 96, 86, 38, 200, 189, 155, 210, 52, 65, 115, 19, 67, 120, 86, 112, 30, 212, 50, 12, 28, |
3820 | 1 | 128, 65, 210, 190, 116, 10, 193, 36, 41, 206, 52, 34, 47, 55, 124, 179, 159, 236, 3, 2, |
3821 | 1 | 247, 193, 222, 54, 100, 68, 50, 202, 5, 253, 178, 189, 200, 128, 174, 42, 157, 187, 52, |
3822 | 1 | 154, 35, 4, 14, 22, 200, 232, 71, 43, 52, 87, 143, 212, 213, 30, 189, 175, 51, 42, 246, |
3823 | 1 | 218, 148, 248, 20, 150, 131, 111, 128, 159, 162, 71, 76, 125, 188, 23, 102, 78, 138, |
3824 | 1 | 74, 194, 144, 42, 35, 180, 107, 113, 53, 74, 176, 63, 2, 101, 47, 32, 214, 50, 116, 13, |
3825 | 1 | 216, 66, 108, 95, 3, 199, 22, 251, 143, 255, 61, 230, 26, 136, 59, 183, 106, 219, 52, |
3826 | 1 | 162, 36, 4, 232, 7, 0, 0, 137, 119, 74, 1, 128, 208, 7, 139, 123, 119, 218, 225, 122, |
3827 | 1 | 92, 24, 101, 135, 21, 98, 140, 83, 54, 171, 118, 18, 13, 160, 236, 130, 58, 154, 56, |
3828 | 1 | 112, 99, 173, 47, 53, 76, 95, 15, 73, 147, 240, 22, 226, 210, 248, 229, 244, 59, 231, |
3829 | 1 | 187, 37, 148, 134, 4, 0, 128, 180, 11, 248, 2, 17, 8, 106, 112, 143, 129, 91, 141, 147, |
3830 | 1 | 210, 31, 99, 94, 230, 35, 100, 68, 145, 12, 86, 32, 167, 106, 222, 237, 241, 49, 226, |
3831 | 1 | 128, 209, 13, 198, 37, 212, 80, 79, 61, 79, 2, 64, 63, 17, 102, 252, 45, 212, 158, 10, |
3832 | 1 | 183, 3, 243, 105, 229, 40, 53, 251, 187, 233, 155, 57, 76, 128, 17, 204, 75, 41, 17, |
3833 | 1 | 129, 162, 253, 33, 143, 254, 18, 166, 52, 184, 128, 196, 247, 26, 64, 21, 174, 106, 88, |
3834 | 1 | 40, 42, 42, 11, 129, 56, 135, 98, 200, 158, 123, 187, 70, 2, 112, 100, 43, 91, 202, |
3835 | 1 | 240, 50, 234, 4, 213, 106, 128, 1, 60, 87, 7, 61, 229, 152, 2, 222, 70, 55, 232, 7, 0, |
3836 | 1 | 0, 4, 0, 60, 87, 12, 88, 243, 181, 152, 155, 183, 44, 223, 7, 0, 0, 4, 0, 5, 8, 158, |
3837 | 1 | 127, 239, 196, 8, 170, 197, 157, 191, 232, 10, 114, 172, 142, 60, 229, 251, 255, 128, |
3838 | 1 | 56, 170, 13, 33, 53, 205, 159, 176, 194, 65, 52, 11, 105, 163, 238, 193, 140, 175, 102, |
3839 | 1 | 94, 101, 119, 80, 190, 106, 116, 123, 172, 198, 176, 45, 176, 128, 246, 44, 225, 89, |
3840 | 1 | 41, 109, 48, 176, 151, 95, 167, 3, 200, 131, 53, 222, 234, 250, 190, 60, 4, 127, 89, |
3841 | 1 | 243, 125, 238, 165, 212, 183, 77, 11, 209, 128, 71, 135, 124, 147, 186, 183, 95, 45, |
3842 | 1 | 203, 213, 192, 138, 188, 158, 106, 6, 33, 72, 98, 212, 211, 220, 48, 97, 77, 172, 41, |
3843 | 1 | 120, 21, 224, 31, 148, 128, 155, 245, 85, 248, 225, 133, 117, 0, 81, 176, 198, 90, 253, |
3844 | 1 | 182, 176, 128, 242, 164, 197, 172, 248, 243, 128, 209, 103, 50, 212, 135, 109, 215, |
3845 | 1 | 230, 249, 128, 163, 142, 44, 229, 147, 62, 192, 83, 7, 252, 110, 17, 248, 37, 146, 214, |
3846 | 1 | 46, 130, 54, 218, 34, 167, 116, 105, 149, 97, 133, 153, 192, 222, 20, 150, 128, 150, |
3847 | 1 | 118, 55, 223, 203, 44, 129, 74, 71, 74, 4, 8, 193, 9, 144, 23, 217, 195, 138, 121, 247, |
3848 | 1 | 210, 80, 83, 219, 254, 15, 171, 160, 238, 173, 15, 128, 214, 54, 155, 162, 54, 145, 68, |
3849 | 1 | 39, 228, 118, 106, 54, 93, 184, 45, 161, 236, 109, 18, 43, 134, 108, 113, 32, 247, 231, |
3850 | 1 | 184, 166, 114, 206, 73, 183, 128, 67, 239, 64, 137, 114, 56, 17, 18, 43, 66, 237, 135, |
3851 | 1 | 134, 37, 190, 49, 34, 2, 178, 202, 96, 50, 214, 70, 187, 229, 80, 107, 3, 248, 114, |
3852 | 1 | 197, 128, 19, 75, 75, 209, 181, 183, 74, 54, 119, 212, 232, 137, 45, 169, 213, 118, |
3853 | 1 | 178, 46, 239, 224, 154, 146, 126, 26, 108, 181, 164, 13, 12, 54, 204, 160, 128, 139, |
3854 | 1 | 173, 91, 159, 113, 23, 138, 151, 122, 16, 130, 103, 198, 21, 86, 35, 190, 14, 42, 92, |
3855 | 1 | 141, 228, 189, 162, 92, 151, 29, 104, 76, 89, 84, 11, 128, 222, 150, 203, 163, 119, 75, |
3856 | 1 | 233, 85, 45, 168, 200, 142, 97, 240, 33, 84, 91, 122, 94, 213, 135, 57, 233, 202, 203, |
3857 | 1 | 35, 134, 229, 215, 56, 7, 188, 128, 201, 176, 177, 160, 195, 180, 148, 75, 204, 180, |
3858 | 1 | 149, 21, 188, 59, 171, 141, 59, 244, 12, 162, 217, 74, 116, 96, 219, 76, 123, 204, 94, |
3859 | 1 | 43, 185, 50, 128, 46, 3, 210, 197, 241, 213, 203, 87, 67, 242, 55, 221, 56, 18, 59, |
3860 | 1 | 218, 83, 84, 234, 179, 181, 107, 31, 106, 69, 121, 253, 210, 144, 106, 36, 186, 128, |
3861 | 1 | 74, 7, 238, 205, 130, 97, 184, 42, 47, 66, 224, 74, 129, 129, 168, 176, 128, 42, 189, |
3862 | 1 | 32, 127, 1, 26, 215, 51, 193, 32, 167, 192, 142, 143, 12, 128, 216, 70, 54, 152, 177, |
3863 | 1 | 220, 44, 147, 187, 142, 216, 215, 30, 8, 181, 223, 133, 59, 216, 99, 111, 114, 83, 171, |
3864 | 1 | 112, 52, 2, 48, 199, 177, 66, 13, 125, 5, 158, 182, 243, 110, 2, 122, 187, 32, 145, |
3865 | 1 | 207, 181, 17, 10, 181, 8, 127, 249, 110, 104, 95, 6, 21, 91, 60, 217, 168, 201, 229, |
3866 | 1 | 233, 162, 63, 213, 220, 19, 165, 237, 32, 23, 35, 244, 16, 0, 0, 0, 0, 104, 95, 8, 49, |
3867 | 1 | 108, 191, 143, 160, 218, 130, 42, 32, 172, 28, 85, 191, 27, 227, 32, 217, 142, 0, 0, 0, |
3868 | 1 | 0, 0, 0, 80, 95, 14, 123, 144, 18, 9, 107, 65, 196, 235, 58, 175, 148, 127, 110, 164, |
3869 | 1 | 41, 8, 0, 0, 128, 2, 241, 238, 119, 138, 179, 171, 217, 125, 65, 214, 57, 230, 94, 13, |
3870 | 1 | 190, 168, 63, 159, 87, 232, 227, 197, 193, 81, 183, 142, 96, 228, 167, 149, 37, 128, |
3871 | 1 | 157, 63, 215, 146, 117, 166, 140, 220, 174, 150, 5, 77, 118, 79, 113, 140, 216, 205, |
3872 | 1 | 207, 202, 255, 186, 88, 88, 134, 71, 167, 53, 109, 154, 73, 120, 128, 153, 238, 230, |
3873 | 1 | 194, 186, 40, 165, 7, 172, 203, 178, 42, 80, 75, 47, 87, 217, 239, 45, 101, 77, 142, |
3874 | 1 | 82, 22, 203, 0, 29, 175, 67, 154, 29, 20, 128, 13, 73, 254, 240, 57, 81, 124, 195, 18, |
3875 | 1 | 192, 4, 18, 128, 60, 161, 223, 80, 172, 109, 144, 197, 5, 65, 246, 73, 169, 200, 91, |
3876 | 1 | 131, 192, 253, 216, 128, 5, 186, 225, 243, 58, 155, 95, 18, 12, 122, 8, 136, 144, 222, |
3877 | 1 | 132, 249, 58, 88, 9, 70, 84, 233, 189, 167, 162, 124, 236, 240, 43, 136, 187, 68, 128, |
3878 | 1 | 148, 108, 220, 197, 185, 128, 168, 10, 4, 161, 151, 179, 212, 193, 238, 179, 164, 232, |
3879 | 1 | 236, 13, 156, 2, 29, 131, 144, 233, 45, 95, 109, 146, 86, 190, 128, 55, 232, 201, 40, |
3880 | 1 | 226, 245, 173, 89, 24, 31, 81, 135, 7, 67, 175, 180, 71, 233, 197, 223, 134, 84, 125, |
3881 | 1 | 192, 137, 60, 112, 4, 89, 210, 72, 6, 104, 95, 9, 14, 47, 191, 45, 121, 44, 179, 36, |
3882 | 1 | 191, 250, 148, 39, 254, 31, 14, 32, 110, 116, 74, 1, 197, 118, 74, 1, 113, 1, 158, 222, |
3883 | 1 | 61, 138, 84, 210, 126, 68, 169, 213, 206, 24, 150, 24, 242, 45, 48, 8, 80, 95, 14, 123, |
3884 | 1 | 144, 18, 9, 107, 65, 196, 235, 58, 175, 148, 127, 110, 164, 41, 8, 9, 0, 76, 95, 3, |
3885 | 1 | 180, 18, 59, 46, 24, 110, 7, 251, 123, 173, 93, 218, 95, 85, 192, 4, 0, 128, 114, 115, |
3886 | 1 | 217, 102, 145, 229, 217, 201, 199, 191, 227, 81, 211, 103, 201, 176, 171, 162, 94, 209, |
3887 | 1 | 255, 178, 61, 163, 165, 157, 75, 84, 151, 146, 162, 18, 213, 1, 158, 247, 140, 152, |
3888 | 1 | 114, 61, 220, 144, 115, 82, 62, 243, 190, 239, 218, 12, 16, 68, 128, 167, 19, 190, 77, |
3889 | 1 | 41, 214, 45, 78, 126, 172, 144, 72, 93, 83, 75, 60, 169, 141, 83, 127, 86, 96, 12, 138, |
3890 | 1 | 249, 117, 65, 33, 124, 199, 26, 124, 128, 156, 98, 19, 144, 136, 242, 56, 127, 187, 23, |
3891 | 1 | 105, 48, 64, 117, 65, 176, 129, 157, 68, 103, 107, 137, 27, 110, 103, 173, 130, 108, |
3892 | 1 | 77, 200, 53, 46, 128, 80, 142, 203, 210, 143, 233, 207, 121, 109, 246, 135, 4, 229, 45, |
3893 | 1 | 19, 178, 133, 49, 92, 67, 246, 97, 99, 120, 71, 232, 8, 225, 154, 82, 249, 114, 245, 6, |
3894 | 1 | 159, 1, 43, 116, 109, 207, 50, 232, 67, 53, 69, 131, 201, 112, 44, 192, 32, 249, 255, |
3895 | 1 | 76, 87, 2, 166, 252, 145, 92, 204, 85, 160, 48, 8, 0, 0, 20, 4, 208, 7, 0, 0, 128, 191, |
3896 | 1 | 173, 201, 187, 178, 195, 202, 43, 56, 205, 17, 183, 37, 176, 244, 26, 77, 8, 42, 84, |
3897 | 1 | 45, 184, 54, 123, 224, 193, 73, 17, 232, 188, 102, 142, 128, 192, 202, 163, 161, 148, |
3898 | 1 | 16, 137, 217, 105, 73, 69, 240, 100, 255, 246, 205, 84, 130, 249, 228, 158, 205, 148, |
3899 | 1 | 235, 11, 196, 152, 92, 220, 185, 244, 59, 128, 13, 147, 166, 123, 17, 250, 116, 106, |
3900 | 1 | 207, 108, 92, 127, 169, 181, 143, 82, 145, 18, 130, 76, 21, 113, 68, 191, 43, 178, 33, |
3901 | 1 | 124, 207, 18, 72, 90, 128, 217, 30, 167, 57, 178, 158, 255, 88, 89, 34, 120, 141, 41, |
3902 | 1 | 50, 107, 164, 244, 49, 236, 12, 167, 241, 72, 17, 120, 40, 146, 227, 114, 54, 17, 56, |
3903 | 1 | 92, 87, 7, 61, 229, 152, 2, 222, 70, 55, 232, 7, 0, 0, 36, 8, 208, 7, 0, 0, 37, 8, 0, |
3904 | 1 | 0, 108, 87, 12, 88, 243, 181, 152, 155, 183, 44, 223, 7, 0, 0, 52, 12, 208, 7, 0, 0, |
3905 | 1 | 209, 7, 0, 0, 231, 7, 0, 0, 128, 119, 15, 117, 76, 101, 140, 192, 56, 249, 91, 82, 13, |
3906 | 1 | 27, 30, 77, 0, 193, 8, 119, 228, 130, 190, 89, 43, 134, 133, 250, 139, 167, 203, 87, |
3907 | 1 | 248, 128, 210, 182, 147, 82, 22, 5, 0, 98, 106, 232, 112, 222, 48, 80, 23, 2, 3, 46, |
3908 | 1 | 67, 59, 120, 72, 9, 160, 210, 160, 93, 43, 152, 131, 111, 193, 128, 89, 154, 1, 71, |
3909 | 1 | 154, 63, 57, 100, 241, 38, 125, 249, 23, 23, 17, 134, 122, 139, 126, 202, 191, 76, 85, |
3910 | 1 | 222, 54, 165, 68, 148, 173, 53, 246, 212, 128, 35, 156, 52, 249, 202, 144, 19, 104, |
3911 | 1 | 137, 129, 10, 32, 51, 112, 158, 91, 207, 125, 15, 15, 107, 214, 170, 152, 154, 6, 208, |
3912 | 1 | 222, 183, 99, 33, 222, 128, 79, 163, 220, 117, 100, 66, 203, 148, 165, 161, 21, 126, |
3913 | 1 | 226, 221, 222, 148, 213, 170, 88, 72, 244, 206, 224, 234, 79, 247, 174, 206, 174, 219, |
3914 | 1 | 208, 241, 128, 0, 167, 138, 177, 252, 250, 114, 63, 198, 244, 142, 149, 188, 250, 63, |
3915 | 1 | 73, 189, 141, 246, 2, 40, 246, 10, 151, 186, 187, 184, 15, 146, 69, 116, 28, 92, 87, |
3916 | 1 | 12, 115, 39, 162, 164, 139, 242, 177, 73, 8, 0, 0, 36, 8, 232, 3, 0, 0, 62, 8, 0, 0, |
3917 | 1 | 141, 8, 159, 6, 96, 76, 255, 130, 138, 110, 63, 87, 156, 166, 197, 154, 206, 1, 61, |
3918 | 1 | 255, 255, 128, 123, 20, 155, 144, 143, 139, 40, 225, 129, 183, 242, 90, 168, 229, 169, |
3919 | 1 | 44, 239, 74, 95, 193, 76, 169, 120, 158, 180, 77, 10, 60, 43, 243, 120, 106, 128, 188, |
3920 | 1 | 26, 98, 245, 122, 21, 78, 133, 109, 201, 78, 122, 74, 63, 146, 74, 231, 61, 35, 211, |
3921 | 1 | 236, 78, 237, 43, 38, 244, 199, 152, 179, 50, 61, 106, 128, 148, 134, 149, 100, 27, |
3922 | 1 | 186, 117, 8, 57, 183, 207, 64, 113, 80, 83, 68, 168, 162, 13, 3, 145, 174, 120, 120, |
3923 | 1 | 175, 113, 223, 148, 96, 215, 194, 20, 128, 218, 44, 32, 104, 83, 235, 246, 5, 231, 236, |
3924 | 1 | 80, 209, 36, 242, 32, 8, 114, 201, 228, 89, 79, 244, 147, 236, 158, 181, 128, 229, 95, |
3925 | 1 | 11, 131, 115, 128, 175, 173, 146, 222, 96, 160, 235, 159, 228, 57, 212, 102, 97, 188, |
3926 | 1 | 144, 214, 42, 73, 6, 188, 24, 151, 26, 228, 124, 182, 103, 5, 7, 28, 237, 6, 128, 226, |
3927 | 1 | 141, 250, 99, 130, 105, 216, 103, 107, 119, 92, 167, 38, 155, 234, 59, 192, 28, 195, |
3928 | 1 | 109, 88, 224, 194, 254, 114, 170, 165, 39, 207, 73, 191, 107, 128, 167, 245, 227, 180, |
3929 | 1 | 170, 92, 3, 156, 59, 97, 228, 53, 43, 5, 127, 108, 122, 158, 209, 101, 225, 158, 175, |
3930 | 1 | 10, 85, 225, 140, 100, 42, 72, 218, 230, 128, 224, 114, 207, 115, 190, 8, 91, 231, 37, |
3931 | 1 | 29, 220, 240, 253, 66, 90, 18, 200, 42, 211, 92, 220, 219, 169, 250, 99, 59, 254, 182, |
3932 | 1 | 81, 99, 79, 81, 128, 97, 10, 73, 158, 196, 71, 147, 152, 205, 94, 76, 146, 101, 216, |
3933 | 1 | 121, 130, 190, 230, 22, 142, 244, 18, 163, 104, 179, 170, 175, 89, 217, 10, 130, 158, |
3934 | 1 | 128, 188, 130, 51, 1, 238, 228, 106, 8, 70, 216, 220, 241, 10, 154, 150, 187, 9, 195, |
3935 | 1 | 212, 193, 8, 10, 254, 243, 205, 98, 83, 145, 24, 176, 28, 60, 128, 164, 230, 169, 142, |
3936 | 1 | 220, 117, 187, 182, 86, 200, 151, 133, 36, 42, 204, 36, 130, 59, 128, 110, 155, 73, |
3937 | 1 | 214, 144, 156, 108, 64, 211, 106, 54, 253, 212, 128, 228, 165, 227, 146, 135, 195, 167, |
3938 | 1 | 79, 87, 7, 176, 226, 9, 239, 13, 90, 102, 109, 189, 222, 185, 112, 125, 177, 20, 151, |
3939 | 1 | 254, 182, 44, 198, 171, 118, 128, 209, 223, 224, 149, 88, 186, 118, 222, 109, 176, 77, |
3940 | 1 | 3, 161, 204, 162, 165, 29, 229, 74, 243, 55, 245, 196, 232, 68, 29, 254, 198, 133, 41, |
3941 | 1 | 244, 210, 128, 56, 66, 73, 182, 186, 202, 111, 218, 198, 199, 248, 96, 196, 208, 124, |
3942 | 1 | 174, 163, 30, 30, 175, 33, 170, 58, 167, 223, 66, 0, 77, 36, 158, 53, 176, 128, 1, 12, |
3943 | 1 | 161, 101, 126, 36, 46, 70, 149, 89, 162, 62, 65, 149, 9, 120, 94, 168, 211, 145, 197, |
3944 | 1 | 187, 235, 153, 119, 166, 161, 5, 232, 125, 115, 57, 128, 212, 159, 226, 95, 99, 27, 64, |
3945 | 1 | 98, 31, 163, 188, 175, 126, 135, 20, 109, 201, 75, 92, 176, 176, 147, 206, 201, 169, |
3946 | 1 | 68, 145, 216, 87, 77, 166, 75, 17, 6, 159, 10, 209, 87, 228, 97, 215, 31, 212, 193, |
3947 | 1 | 249, 54, 131, 154, 95, 31, 62, 248, 255, 128, 8, 239, 142, 226, 171, 84, 102, 207, 203, |
3948 | 1 | 226, 37, 28, 208, 170, 76, 158, 67, 180, 161, 90, 106, 41, 25, 235, 231, 140, 60, 239, |
3949 | 1 | 50, 59, 195, 122, 128, 69, 173, 217, 33, 87, 199, 182, 141, 63, 191, 226, 84, 216, 20, |
3950 | 1 | 195, 8, 97, 181, 103, 202, 26, 38, 30, 239, 38, 77, 208, 162, 31, 229, 160, 204, 88, |
3951 | 1 | 87, 12, 136, 67, 61, 248, 98, 219, 203, 36, 8, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 128, |
3952 | 1 | 241, 249, 14, 190, 36, 73, 117, 108, 170, 35, 138, 55, 164, 246, 34, 186, 164, 116, 86, |
3953 | 1 | 125, 93, 49, 120, 188, 132, 207, 77, 148, 244, 228, 169, 196, 88, 87, 7, 61, 229, 152, |
3954 | 1 | 2, 222, 70, 55, 232, 7, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 88, 87, 12, 88, 243, 181, |
3955 | 1 | 152, 155, 183, 44, 223, 7, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 128, 53, 139, 26, 253, |
3956 | 1 | 144, 91, 208, 185, 200, 133, 120, 48, 152, 202, 157, 23, 244, 95, 23, 155, 79, 135, |
3957 | 1 | 110, 183, 155, 112, 143, 31, 84, 82, 58, 113, 128, 143, 111, 81, 33, 174, 228, 91, 78, |
3958 | 1 | 120, 142, 64, 197, 207, 73, 63, 217, 224, 190, 5, 24, 124, 206, 35, 177, 200, 97, 247, |
3959 | 1 | 188, 179, 177, 254, 175, 128, 129, 62, 59, 185, 49, 134, 240, 28, 171, 75, 99, 43, 168, |
3960 | 1 | 245, 135, 58, 18, 137, 133, 93, 58, 37, 141, 215, 74, 56, 194, 114, 206, 97, 118, 25, |
3961 | 1 | 128, 88, 140, 243, 244, 18, 6, 65, 63, 124, 109, 254, 63, 241, 216, 91, 239, 206, 3, |
3962 | 1 | 14, 254, 80, 163, 184, 232, 164, 69, 59, 135, 211, 174, 160, 239, 88, 87, 4, 57, 62, |
3963 | 1 | 186, 145, 241, 23, 217, 220, 7, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 88, 87, 7, 59, 166, |
3964 | 1 | 27, 196, 215, 19, 53, 75, 8, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 88, 87, 12, 115, 39, |
3965 | 1 | 162, 164, 139, 242, 177, 73, 8, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 141, 8, 159, 11, 60, |
3966 | 1 | 37, 47, 203, 41, 216, 142, 255, 79, 61, 229, 222, 68, 118, 195, 255, 255, 128, 185, |
3967 | 1 | 190, 167, 17, 94, 246, 184, 31, 40, 164, 76, 15, 192, 198, 105, 130, 25, 2, 65, 210, |
3968 | 1 | 168, 239, 84, 94, 146, 240, 179, 245, 240, 17, 218, 71, 128, 88, 6, 112, 189, 244, 215, |
3969 | 1 | 89, 5, 182, 228, 216, 226, 33, 87, 51, 242, 11, 197, 224, 29, 155, 132, 126, 100, 62, |
3970 | 1 | 59, 239, 235, 137, 112, 39, 78, 128, 206, 206, 114, 104, 28, 176, 255, 27, 110, 46, 38, |
3971 | 1 | 84, 232, 156, 103, 0, 25, 52, 213, 92, 89, 123, 185, 26, 249, 60, 212, 110, 143, 131, |
3972 | 1 | 211, 52, 128, 121, 153, 176, 38, 230, 10, 9, 88, 172, 216, 95, 77, 173, 8, 169, 23, 62, |
3973 | 1 | 165, 51, 114, 171, 236, 111, 192, 207, 42, 6, 144, 185, 184, 89, 243, 128, 54, 218, |
3974 | 1 | 218, 89, 106, 216, 208, 240, 18, 72, 253, 131, 83, 104, 237, 125, 166, 8, 75, 150, 189, |
3975 | 1 | 198, 210, 254, 170, 250, 199, 248, 196, 74, 101, 181, 128, 88, 198, 85, 119, 253, 45, |
3976 | 1 | 115, 142, 209, 178, 107, 75, 186, 240, 35, 159, 174, 188, 46, 147, 222, 133, 75, 132, |
3977 | 1 | 180, 224, 54, 199, 130, 224, 105, 213, 128, 210, 157, 110, 245, 99, 193, 1, 73, 243, |
3978 | 1 | 88, 98, 76, 219, 252, 192, 74, 126, 112, 138, 157, 225, 110, 117, 83, 15, 122, 46, 183, |
3979 | 1 | 180, 24, 254, 180, 128, 117, 190, 178, 138, 46, 227, 250, 184, 212, 94, 194, 58, 61, |
3980 | 1 | 192, 26, 204, 35, 39, 58, 192, 68, 112, 184, 69, 42, 188, 132, 133, 235, 128, 147, 211, |
3981 | 1 | 128, 75, 29, 115, 72, 46, 228, 25, 72, 49, 104, 137, 215, 104, 67, 29, 21, 14, 210, |
3982 | 1 | 129, 135, 19, 216, 181, 185, 82, 229, 123, 92, 115, 110, 126, 48, 128, 126, 136, 181, |
3983 | 1 | 243, 110, 247, 45, 108, 30, 72, 168, 246, 241, 23, 161, 5, 16, 33, 233, 7, 217, 42, 3, |
3984 | 1 | 251, 251, 76, 84, 75, 163, 195, 101, 68, 128, 209, 22, 183, 168, 62, 223, 120, 219, |
3985 | 1 | 183, 61, 144, 239, 26, 58, 212, 52, 181, 253, 147, 176, 197, 238, 59, 175, 137, 205, |
3986 | 1 | 136, 25, 228, 22, 113, 216, 128, 250, 4, 230, 185, 227, 93, 119, 243, 31, 241, 78, 135, |
3987 | 1 | 151, 12, 240, 113, 159, 52, 38, 50, 242, 18, 60, 7, 160, 239, 16, 161, 152, 99, 80, 9, |
3988 | 1 | 128, 178, 53, 96, 218, 51, 232, 115, 216, 96, 180, 147, 119, 240, 38, 225, 134, 79, 88, |
3989 | 1 | 81, 75, 189, 134, 70, 70, 9, 12, 84, 32, 38, 179, 129, 109, 128, 208, 202, 218, 40, |
3990 | 1 | 139, 65, 231, 246, 15, 185, 165, 113, 179, 111, 252, 75, 38, 88, 212, 154, 242, 0, 147, |
3991 | 1 | 221, 23, 156, 128, 194, 17, 247, 217, 100, 128, 253, 243, 231, 0, 35, 185, 94, 22, 117, |
3992 | 1 | 235, 184, 166, 175, 23, 79, 38, 159, 123, 213, 254, 251, 122, 179, 214, 7, 168, 203, |
3993 | 1 | 244, 37, 253, 126, 40, 128, 53, 76, 58, 205, 243, 253, 64, 35, 147, 65, 19, 203, 129, |
3994 | 1 | 223, 187, 108, 183, 62, 96, 193, 99, 1, 4, 125, 104, 51, 223, 160, 95, 86, 238, 171, 1, |
3995 | 1 | 7, 159, 13, 55, 25, 245, 176, 177, 44, 113, 5, 192, 115, 197, 7, 68, 89, 72, 249, 255, |
3996 | 1 | 92, 87, 2, 166, 252, 145, 92, 204, 85, 160, 48, 8, 0, 0, 36, 8, 208, 7, 0, 0, 212, 7, |
3997 | 1 | 0, 0, 128, 183, 198, 226, 22, 113, 16, 232, 182, 81, 235, 105, 58, 91, 191, 184, 59, |
3998 | 1 | 111, 150, 128, 145, 71, 130, 34, 225, 54, 166, 131, 137, 242, 205, 56, 92, 128, 230, 8, |
3999 | 1 | 107, 64, 106, 147, 6, 19, 214, 240, 62, 77, 27, 186, 163, 108, 0, 197, 60, 23, 107, 89, |
4000 | 1 | 244, 217, 250, 99, 168, 55, 251, 12, 173, 232, 124, 87, 12, 136, 67, 61, 248, 98, 219, |
4001 | 1 | 203, 36, 8, 0, 0, 68, 16, 232, 3, 0, 0, 208, 7, 0, 0, 212, 7, 0, 0, 231, 7, 0, 0, 128, |
4002 | 1 | 217, 30, 167, 57, 178, 158, 255, 88, 89, 34, 120, 141, 41, 50, 107, 164, 244, 49, 236, |
4003 | 1 | 12, 167, 241, 72, 17, 120, 40, 146, 227, 114, 54, 17, 56, 92, 87, 7, 61, 229, 152, 2, |
4004 | 1 | 222, 70, 55, 232, 7, 0, 0, 36, 8, 208, 7, 0, 0, 37, 8, 0, 0, 108, 87, 12, 88, 243, 181, |
4005 | 1 | 152, 155, 183, 44, 223, 7, 0, 0, 52, 12, 208, 7, 0, 0, 209, 7, 0, 0, 231, 7, 0, 0, 128, |
4006 | 1 | 219, 215, 94, 9, 186, 191, 42, 25, 219, 63, 237, 243, 130, 215, 231, 161, 105, 120, |
4007 | 1 | 205, 2, 199, 129, 177, 204, 174, 40, 73, 194, 154, 96, 95, 21, 128, 176, 114, 157, 92, |
4008 | 1 | 163, 126, 236, 55, 179, 142, 48, 21, 107, 89, 42, 131, 164, 127, 239, 22, 236, 175, 72, |
4009 | 1 | 105, 47, 125, 193, 29, 44, 235, 161, 163, 128, 89, 154, 1, 71, 154, 63, 57, 100, 241, |
4010 | 1 | 38, 125, 249, 23, 23, 17, 134, 122, 139, 126, 202, 191, 76, 85, 222, 54, 165, 68, 148, |
4011 | 1 | 173, 53, 246, 212, 128, 151, 254, 128, 24, 142, 196, 104, 235, 142, 225, 114, 221, 194, |
4012 | 1 | 248, 166, 96, 100, 130, 240, 144, 88, 179, 252, 0, 52, 89, 107, 230, 40, 103, 171, 9, |
4013 | 1 | 128, 79, 163, 220, 117, 100, 66, 203, 148, 165, 161, 21, 126, 226, 221, 222, 148, 213, |
4014 | 1 | 170, 88, 72, 244, 206, 224, 234, 79, 247, 174, 206, 174, 219, 208, 241, 128, 0, 167, |
4015 | 1 | 138, 177, 252, 250, 114, 63, 198, 244, 142, 149, 188, 250, 63, 73, 189, 141, 246, 2, |
4016 | 1 | 40, 246, 10, 151, 186, 187, 184, 15, 146, 69, 116, 28, 92, 87, 12, 115, 39, 162, 164, |
4017 | 1 | 139, 242, 177, 73, 8, 0, 0, 36, 8, 232, 3, 0, 0, 62, 8, 0, 0, 125, 3, 191, 14, 2, 101, |
4018 | 1 | 108, 97, 121, 95, 100, 105, 115, 112, 97, 116, 99, 104, 95, 113, 117, 101, 117, 101, |
4019 | 1 | 95, 114, 101, 109, 97, 105, 110, 105, 110, 103, 95, 99, 97, 112, 97, 99, 105, 116, 121, |
4020 | 1 | 29, 96, 56, 71, 10, 13, 0, 0, 32, 170, 170, 10, 0, 0, 0, 64, 0, 128, 143, 110, 43, 35, |
4021 | 1 | 129, 96, 51, 141, 9, 185, 119, 112, 66, 66, 63, 44, 8, 13, 37, 84, 87, 91, 139, 76, |
4022 | 1 | 130, 130, 96, 110, 145, 240, 178, 180, 128, 226, 41, 230, 56, 44, 176, 80, 88, 20, 90, |
4023 | 1 | 147, 106, 44, 51, 162, 142, 153, 138, 152, 251, 180, 169, 18, 62, 45, 81, 8, 165, 97, |
4024 | 1 | 59, 203, 199, 128, 70, 44, 111, 211, 18, 241, 216, 196, 138, 174, 50, 229, 189, 104, |
4025 | 1 | 102, 187, 131, 149, 71, 139, 163, 52, 195, 7, 32, 240, 53, 147, 143, 94, 238, 169, 128, |
4026 | 1 | 10, 186, 206, 24, 53, 123, 138, 47, 49, 104, 93, 123, 68, 198, 253, 84, 208, 214, 83, |
4027 | 1 | 193, 228, 161, 92, 27, 22, 32, 117, 28, 48, 205, 212, 233, 128, 176, 1, 138, 144, 229, |
4028 | 1 | 9, 63, 181, 213, 121, 215, 108, 115, 191, 27, 101, 254, 121, 217, 209, 224, 155, 74, |
4029 | 1 | 54, 84, 166, 217, 71, 90, 202, 80, 160, 212, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, |
4030 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, |
4031 | 1 | 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, |
4032 | 1 | 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 5, 250, 215, 160, 174, 53, 135, 1, 216, 200, |
4033 | 1 | 221, 56, 45, 67, 241, 114, 177, 149, 137, 65, 157, 56, 68, 205, 112, 123, 203, 221, 70, |
4034 | 1 | 61, 249, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, |
4035 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, |
4036 | 1 | 0, 0, 0, 0, 1, 5, 9, 87, 184, 25, 167, 6, 161, 4, 85, 101, 129, 198, 223, 189, 92, 165, |
4037 | 1 | 64, 41, 250, 128, 62, 37, 243, 193, 13, 203, 182, 44, 86, 164, 242, 0, 80, 57, 39, 140, |
4038 | 1 | 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4039 | 1 | 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 18, 239, |
4040 | 1 | 156, 125, 168, 209, 10, 137, 202, 2, 93, 6, 210, 77, 209, 142, 4, 3, 244, 100, 116, 64, |
4041 | 1 | 99, 249, 237, 30, 23, 36, 179, 180, 158, 228, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, |
4042 | 1 | 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, |
4043 | 1 | 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 37, 44, 141, 42, 133, 237, 87, |
4044 | 1 | 232, 67, 242, 205, 156, 176, 10, 24, 107, 29, 117, 247, 84, 118, 191, 83, 73, 228, 200, |
4045 | 1 | 7, 220, 98, 190, 82, 1, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, |
4046 | 1 | 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, |
4047 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 60, 209, 220, 212, 71, 224, 224, 162, 65, 245, 44, 235, |
4048 | 1 | 253, 246, 185, 30, 104, 137, 31, 220, 53, 230, 193, 153, 30, 183, 223, 43, 2, 133, 208, |
4049 | 1 | 182, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, |
4050 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, |
4051 | 1 | 0, 0, 0, 1, 61, 0, 86, 29, 67, 58, 122, 195, 118, 161, 87, 145, 42, 242, 213, 167, 82, |
4052 | 1 | 192, 181, 174, 193, 141, 248, 239, 107, 199, 113, 236, 125, 156, 70, 217, 0, 80, 57, |
4053 | 1 | 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, |
4054 | 1 | 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, |
4055 | 1 | 62, 154, 79, 166, 29, 228, 222, 101, 135, 211, 22, 59, 113, 222, 139, 60, 119, 26, 215, |
4056 | 1 | 232, 195, 34, 120, 182, 208, 72, 134, 2, 148, 213, 254, 29, 0, 80, 57, 39, 140, 4, 0, |
4057 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, |
4058 | 1 | 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 67, 36, 83, 111, |
4059 | 1 | 16, 33, 223, 14, 158, 79, 134, 54, 78, 11, 201, 110, 200, 25, 85, 101, 175, 43, 105, |
4060 | 1 | 28, 44, 221, 169, 73, 152, 138, 79, 5, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, |
4061 | 1 | 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, |
4062 | 1 | 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 98, 120, 195, 242, 227, 233, 193, 24, |
4063 | 1 | 169, 0, 95, 229, 165, 68, 204, 39, 139, 96, 82, 71, 46, 75, 28, 195, 43, 10, 126, 118, |
4064 | 1 | 67, 53, 154, 104, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, |
4065 | 1 | 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, |
4066 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 99, 103, 122, 72, 191, 50, 82, 52, 229, 214, 125, 21, 50, |
4067 | 1 | 83, 191, 47, 14, 140, 153, 149, 232, 224, 66, 234, 66, 222, 204, 33, 137, 61, 74, 233, |
4068 | 1 | 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, |
4069 | 1 | 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, |
4070 | 1 | 0, 1, 103, 61, 173, 239, 0, 157, 208, 20, 207, 0, 203, 46, 75, 93, 19, 119, 42, 233, |
4071 | 1 | 240, 129, 244, 104, 64, 100, 55, 117, 74, 89, 219, 81, 100, 170, 0, 80, 57, 39, 140, 4, |
4072 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, |
4073 | 1 | 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 105, 78, 154, |
4074 | 1 | 240, 149, 199, 222, 97, 98, 175, 66, 82, 130, 173, 167, 27, 215, 158, 93, 176, 190, 37, |
4075 | 1 | 176, 94, 154, 196, 152, 203, 199, 151, 79, 235, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, |
4076 | 1 | 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, |
4077 | 1 | 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 116, 41, 250, 117, 90, 92, |
4078 | 1 | 62, 230, 180, 0, 192, 199, 104, 156, 224, 171, 40, 71, 245, 153, 207, 113, 172, 62, |
4079 | 1 | 151, 168, 178, 217, 248, 92, 21, 76, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4080 | 1 | 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, |
4081 | 1 | 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 117, 202, 170, 105, 43, 138, 249, 48, 231, |
4082 | 1 | 145, 34, 119, 18, 128, 59, 219, 118, 4, 240, 106, 135, 81, 177, 215, 94, 193, 226, 168, |
4083 | 1 | 188, 27, 69, 168, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, |
4084 | 1 | 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, |
4085 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 1, 127, 112, 248, 19, 119, 246, 252, 26, 160, 149, 112, 164, |
4086 | 1 | 23, 155, 129, 181, 148, 231, 184, 235, 250, 189, 7, 24, 211, 160, 167, 73, 29, 48, 54, |
4087 | 1 | 198, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, |
4088 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, |
4089 | 1 | 0, 0, 0, 1, 133, 2, 114, 161, 168, 61, 7, 35, 83, 106, 66, 199, 153, 155, 55, 148, 192, |
4090 | 1 | 207, 82, 92, 141, 211, 82, 52, 137, 59, 159, 140, 10, 10, 180, 228, 0, 80, 57, 39, 140, |
4091 | 1 | 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4092 | 1 | 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 141, 31, |
4093 | 1 | 38, 230, 121, 61, 43, 72, 39, 197, 122, 164, 187, 110, 148, 61, 120, 69, 85, 209, 11, |
4094 | 1 | 114, 89, 132, 165, 46, 56, 120, 202, 60, 233, 206, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, |
4095 | 1 | 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, |
4096 | 1 | 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 176, 91, 183, 236, 44, |
4097 | 1 | 199, 97, 95, 93, 40, 245, 102, 24, 85, 5, 4, 4, 38, 248, 71, 29, 95, 111, 139, 236, |
4098 | 1 | 251, 1, 193, 109, 146, 246, 48, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4099 | 1 | 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, |
4100 | 1 | 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 191, 222, 206, 172, 7, 81, 79, 140, 226, 169, |
4101 | 1 | 207, 110, 83, 77, 125, 212, 141, 217, 118, 95, 68, 76, 157, 34, 180, 112, 176, 97, 110, |
4102 | 1 | 55, 71, 154, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, |
4103 | 1 | 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, |
4104 | 1 | 0, 0, 0, 0, 0, 0, 1, 198, 185, 228, 170, 191, 180, 31, 74, 124, 63, 197, 202, 238, 179, |
4105 | 1 | 65, 216, 119, 9, 27, 224, 211, 23, 159, 4, 7, 108, 122, 245, 73, 1, 124, 52, 0, 80, 57, |
4106 | 1 | 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, |
4107 | 1 | 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, |
4108 | 1 | 217, 246, 149, 197, 84, 191, 116, 27, 204, 157, 95, 154, 80, 197, 154, 157, 93, 103, |
4109 | 1 | 183, 18, 126, 183, 48, 27, 192, 50, 58, 243, 146, 56, 112, 102, 0, 80, 57, 39, 140, 4, |
4110 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, |
4111 | 1 | 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 233, 166, 158, |
4112 | 1 | 134, 74, 157, 149, 169, 245, 181, 55, 200, 47, 241, 81, 237, 110, 153, 242, 203, 233, |
4113 | 1 | 190, 96, 76, 137, 122, 100, 245, 172, 37, 76, 208, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, |
4114 | 1 | 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, |
4115 | 1 | 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 243, 53, 200, 207, 159, |
4116 | 1 | 201, 70, 24, 241, 174, 168, 2, 174, 202, 44, 100, 255, 0, 108, 214, 116, 145, 231, 122, |
4117 | 1 | 133, 104, 89, 136, 101, 192, 155, 8, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
4118 | 1 | 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, |
4119 | 1 | 0, 0, 144, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 246, 7, 73, 55, 186, 150, 255, 241, 119, |
4120 | 1 | 21, 30, 69, 95, 3, 87, 66, 38, 97, 91, 50, 69, 49, 20, 104, 29, 91, 195, 99, 149, 39, |
4121 | 1 | 22, 107, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, |
4122 | 1 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 85, 1, 232, 3, 0, 0, 0, 144, 1, 0, 0, 144, 1, 0, 0, 0, 0, 0, |
4123 | 1 | 0, 0, 0, 0, 1, 253, 0, 50, 51, 160, 134, 122, 180, 61, 247, 47, 80, 159, 12, 5, 146, |
4124 | 1 | 242, 34, 202, 60, 17, 185, 62, 235, 148, 154, 144, 86, 71, 251, 208, 150, 0, 80, 57, |
4125 | 1 | 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 57, 39, 140, 4, 0, 0, 0, 0, 0, 0, 0, |
4126 | 1 | 0, 0, 0, |
4127 | 1 | ]; |
4128 | 1 | |
4129 | 1 | let decoded_proof = super::decode_and_verify_proof(super::Config { proof }).unwrap(); |
4130 | 1 | |
4131 | 1 | assert!(decoded_proof |
4132 | 1 | .closest_descendant_merkle_value( |
4133 | 1 | &[ |
4134 | 1 | 250, 90, 64, 163, 99, 146, 173, 5, 126, 222, 6, 39, 161, 170, 189, 182, 82, |
4135 | 1 | 178, 16, 36, 159, 119, 199, 211, 66, 172, 109, 244, 187, 161, 173, 95, |
4136 | 1 | ], |
4137 | 1 | core::iter::empty() |
4138 | 1 | ) |
4139 | 1 | .is_ok()); |
4140 | 1 | } |
4141 | | } |