Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/sync/all_forks.rs
Line
Count
Source (jump to first uncovered line)
1
// Substrate-lite
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
//! *All-forks* header and body syncing.
19
//!
20
//! # Overview
21
//!
22
//! This state machine holds:
23
//!
24
//! - A list of sources of blocks, maintained by the API user.
25
//!  - For each source, a list of blocks hashes known by the source.
26
//! - The latest known finalized block.
27
//! - A tree of valid non-finalized blocks that all descend from the latest known finalized block.
28
//! - (if full mode) A list of block headers whose body is currently being downloaded.
29
//! - A list of block header waiting to be verified and whose ancestry with the latest finalized
30
//!   block is currently unknown.
31
//!
32
//! The state machine has the objective to synchronize the tree of non-finalized blocks with its
33
//! equivalent on the sources added by the API user.
34
//!
35
//! Because it is not possible to predict which block in this tree is going to be finalized in
36
//! the future, the entire tree needs to be synchronized.
37
//!
38
//! > **Example**: If the latest finalized block is block number 4, and the tree contains blocks
39
//! >              5, 6, and 7, and a source announces a block 5 that is different from the
40
//! >              locally-known block 5, a block request will be emitted for this block 5, even
41
//! >              if it is certain that this "other" block 5 will not become the local best
42
//! >              block. This is necessary in case it is this other block 5 that will end up
43
//! >              being finalized.
44
//!
45
//! # Bounded and unbounded containers
46
//!
47
//! It is important to limit the memory usage of this state machine no matter how the
48
//! potentially-malicious sources behave.
49
//!
50
//! The state in this state machine can be put into three categories:
51
//!
52
//! - Each source of blocks has a certain fixed-size state associated to it (containing for
53
//!   instance its best block number and height). Each source also has up to one in-flight
54
//!   request, which might incur more memory usage. Managing this additional request is out of
55
//!   scope of this module. The user of this module is expected to limit the number of
56
//!   simultaneous sources.
57
//!
58
//! - A set of verified blocks that descend from the latest finalized block. This set is
59
//!   unbounded. The consensus and finalization algorithms of the chain are supposed to limit
60
//!   the number of possible blocks in this set.
61
//!
62
//! - A set of blocks that can't be verified yet. Receiving a block announce inserts an element
63
//!   in this set. In order to handle situations where a malicious source announces lots of
64
//!   invalid blocks, this set must be bounded. Once it has reached a certain size, the blocks
65
//!   with the highest block number are discarded if their parent is also in this set or being
66
//!   downloaded from a source.
67
//!
68
//! Consequently, and assuming that the number of simultaneous sources is bounded, and that
69
//! the consensus and finalization algorithms of the chain are properly configured, malicious
70
//! sources can't indefinitely grow the state in this state machine.
71
//! Malicious sources, however, can potentially increase the number of block requests required to
72
//! download a long fork. This is, at most, an annoyance, and not a vulnerability.
73
//!
74
75
// TODO: finish ^
76
77
use crate::{
78
    chain::{blocks_tree, chain_information},
79
    finality::decode,
80
    header, verify,
81
};
82
83
use alloc::{borrow::ToOwned as _, boxed::Box, vec::Vec};
84
use core::{
85
    cmp, mem,
86
    num::{NonZeroU32, NonZeroU64},
87
    ops,
88
    time::Duration,
89
};
90
91
mod disjoint;
92
mod pending_blocks;
93
94
pub mod sources;
95
96
pub use pending_blocks::{RequestId, RequestParams, SourceId};
97
98
/// Configuration for the [`AllForksSync`].
99
#[derive(Debug)]
100
pub struct Config {
101
    /// Information about the latest finalized block and its ancestors.
102
    pub chain_information: chain_information::ValidChainInformation,
103
104
    /// Number of bytes used when encoding/decoding the block number. Influences how various data
105
    /// structures should be parsed.
106
    pub block_number_bytes: usize,
107
108
    /// If `false`, blocks containing digest items with an unknown consensus engine will fail to
109
    /// verify.
110
    ///
111
    /// Note that blocks must always contain digest items that are relevant to the current
112
    /// consensus algorithm. This option controls what happens when blocks contain additional
113
    /// digest items that aren't recognized by the implementation.
114
    ///
115
    /// Passing `true` can lead to blocks being considered as valid when they shouldn't, as these
116
    /// additional digest items could have some logic attached to them that restricts which blocks
117
    /// are valid and which are not.
118
    ///
119
    /// However, since a recognized consensus engine must always be present, both `true` and
120
    /// `false` guarantee that the number of authorable blocks over the network is bounded.
121
    pub allow_unknown_consensus_engines: bool,
122
123
    /// Pre-allocated capacity for the number of block sources.
124
    pub sources_capacity: usize,
125
126
    /// Pre-allocated capacity for the number of blocks between the finalized block and the head
127
    /// of the chain.
128
    ///
129
    /// Should be set to the maximum number of block between two consecutive justifications.
130
    pub blocks_capacity: usize,
131
132
    /// Maximum number of blocks of unknown ancestry to keep in memory. A good default is 1024.
133
    ///
134
    /// When a potential long fork is detected, its blocks are downloaded progressively in
135
    /// descending order until a common ancestor is found.
136
    /// Unfortunately, an attack could generate fake very long forks in order to make the node
137
    /// consume a lot of memory keeping track of the blocks in that fork.
138
    /// In order to avoid this, a limit is added to the number of blocks of unknown ancestry that
139
    /// are kept in memory.
140
    ///
141
    /// Note that the download of long forks will always work no matter this limit. In the worst
142
    /// case scenario, the same blocks will be downloaded multiple times. There is an implicit
143
    /// minimum size equal to the number of sources that have been added to the state machine.
144
    ///
145
    /// Increasing this value has no drawback, except for increasing the maximum possible memory
146
    /// consumption of this state machine.
147
    //
148
    // Implementation note: the size of `disjoint_headers` can temporarily grow above this limit
149
    // due to the internal processing of the state machine.
150
    pub max_disjoint_headers: usize,
151
152
    /// Maximum number of simultaneous pending requests made towards the same block.
153
    ///
154
    /// Should be set according to the failure rate of requests. For example if requests have a
155
    /// `10%` chance of failing, then setting to value to `2` gives a `1%` chance that downloading
156
    /// this block will overall fail and has to be attempted again.
157
    ///
158
    /// Also keep in mind that sources might maliciously take a long time to answer requests. A
159
    /// higher value makes it possible to reduce the risks of the syncing taking a long time
160
    /// because of malicious sources.
161
    ///
162
    /// The higher the value, the more bandwidth is potentially wasted.
163
    pub max_requests_per_block: NonZeroU32,
164
165
    /// If true, the body of a block is downloaded (if necessary) before a
166
    /// [`ProcessOne::BlockVerify`] is generated.
167
    pub download_bodies: bool,
168
}
169
170
pub struct AllForksSync<TBl, TRq, TSrc> {
171
    /// Data structure containing the non-finalized blocks.
172
    chain: blocks_tree::NonFinalizedTree<TBl>,
173
174
    /// Extra fields. In a separate structure in order to be moved around.
175
    inner: Box<Inner<TBl, TRq, TSrc>>,
176
}
177
178
/// Extra fields. In a separate structure in order to be moved around.
179
struct Inner<TBl, TRq, TSrc> {
180
    blocks: pending_blocks::PendingBlocks<PendingBlock<TBl>, TRq, Source<TSrc>>,
181
}
182
183
struct PendingBlock<TBl> {
184
    header: Option<Vec<u8>>,
185
    /// SCALE-encoded extrinsics of the block. `None` if unknown. Only ever filled
186
    /// if [`Config::download_bodies`] was `true`.
187
    body: Option<Vec<Vec<u8>>>,
188
    user_data: TBl,
189
}
190
191
struct Source<TSrc> {
192
    /// Each source stores between zero and two finality proofs that haven't been verified yet.
193
    ///
194
    /// If more than two finality proofs are received from the same source, only the one with the
195
    /// lowest target block and the one with the highest target block are kept in memory. This is
196
    /// done in order to have a maximum bound to the amount of memory that is allocated per source
197
    /// and avoid DoS attack vectors.
198
    ///
199
    /// The finality proof with the highest target block is the "best" finality proof. However,
200
    /// keeping the finality proof with the lowest target block guarantees that, assuming the
201
    /// source isn't malicious, we will able to make *some* progress in the finality.
202
    unverified_finality_proofs: SourcePendingJustificationProofs,
203
204
    /// Height of the highest finalized block according to that source. `0` if unknown.
205
    finalized_block_number: u64,
206
207
    /// Similar to [`Source::unverified_finality_proofs`]. Contains proofs that have been checked
208
    /// and have been determined to not be verifiable right now.
209
    pending_finality_proofs: SourcePendingJustificationProofs,
210
211
    /// Opaque data chosen by the API user.
212
    user_data: TSrc,
213
}
214
215
enum SourcePendingJustificationProofs {
216
    None,
217
    One {
218
        target_height: u64,
219
        proof: FinalityProofs,
220
    },
221
    Two {
222
        low_target_height: u64,
223
        low_proof: FinalityProofs,
224
        high_target_height: u64,
225
        high_proof: FinalityProofs,
226
    },
227
}
228
229
impl SourcePendingJustificationProofs {
230
21
    fn is_none(&self) -> bool {
231
21
        
matches!0
(self, SourcePendingJustificationProofs::None)
232
21
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot4sync9all_forksNtB2_32SourcePendingJustificationProofs7is_none
_RNvMNtNtCseuYC0Zibziv_7smoldot4sync9all_forksNtB2_32SourcePendingJustificationProofs7is_none
Line
Count
Source
230
21
    fn is_none(&self) -> bool {
231
21
        
matches!0
(self, SourcePendingJustificationProofs::None)
232
21
    }
233
234
0
    fn insert(&mut self, new_target_height: u64, new_proof: FinalityProofs) {
235
0
        // An empty list of justifications is an invalid state.
236
0
        debug_assert!(
237
0
            !matches!(&new_proof, FinalityProofs::Justifications(list) if list.is_empty())
238
        );
239
240
0
        match mem::replace(self, SourcePendingJustificationProofs::None) {
241
0
            SourcePendingJustificationProofs::None => {
242
0
                *self = SourcePendingJustificationProofs::One {
243
0
                    target_height: new_target_height,
244
0
                    proof: new_proof,
245
0
                };
246
0
            }
247
            SourcePendingJustificationProofs::One {
248
0
                target_height,
249
0
                proof,
250
0
            } if target_height < new_target_height => {
251
0
                *self = SourcePendingJustificationProofs::Two {
252
0
                    low_target_height: target_height,
253
0
                    low_proof: proof,
254
0
                    high_target_height: new_target_height,
255
0
                    high_proof: new_proof,
256
0
                };
257
0
            }
258
            SourcePendingJustificationProofs::One {
259
0
                target_height,
260
0
                proof,
261
0
            } if target_height > new_target_height => {
262
0
                *self = SourcePendingJustificationProofs::Two {
263
0
                    low_target_height: new_target_height,
264
0
                    low_proof: new_proof,
265
0
                    high_target_height: target_height,
266
0
                    high_proof: proof,
267
0
                };
268
0
            }
269
0
            SourcePendingJustificationProofs::One { .. } => {
270
0
                *self = SourcePendingJustificationProofs::One {
271
0
                    target_height: new_target_height,
272
0
                    proof: new_proof,
273
0
                };
274
0
            }
275
            SourcePendingJustificationProofs::Two {
276
0
                high_target_height,
277
0
                low_proof,
278
0
                low_target_height,
279
                ..
280
0
            } if new_target_height >= high_target_height => {
281
0
                *self = SourcePendingJustificationProofs::Two {
282
0
                    high_proof: new_proof,
283
0
                    high_target_height: new_target_height,
284
0
                    low_proof,
285
0
                    low_target_height,
286
0
                };
287
0
            }
288
            SourcePendingJustificationProofs::Two {
289
0
                high_proof,
290
0
                high_target_height,
291
0
                low_target_height,
292
                ..
293
0
            } if new_target_height <= low_target_height => {
294
0
                *self = SourcePendingJustificationProofs::Two {
295
0
                    high_proof,
296
0
                    high_target_height,
297
0
                    low_proof: new_proof,
298
0
                    low_target_height: new_target_height,
299
0
                };
300
0
            }
301
0
            val @ SourcePendingJustificationProofs::Two { .. } => {
302
0
                *self = val;
303
0
            }
304
        }
305
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot4sync9all_forksNtB2_32SourcePendingJustificationProofs6insert
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot4sync9all_forksNtB2_32SourcePendingJustificationProofs6insert
306
307
0
    fn take_one(&mut self) -> Option<FinalityProof> {
308
0
        match mem::replace(self, SourcePendingJustificationProofs::None) {
309
            SourcePendingJustificationProofs::None => {
310
0
                *self = SourcePendingJustificationProofs::None;
311
0
                None
312
            }
313
            SourcePendingJustificationProofs::One {
314
0
                proof: FinalityProofs::GrandpaCommit(commit),
315
0
                ..
316
0
            } => {
317
0
                *self = SourcePendingJustificationProofs::None;
318
0
                Some(FinalityProof::GrandpaCommit(commit))
319
            }
320
            SourcePendingJustificationProofs::One {
321
0
                proof: FinalityProofs::Justifications(justifications),
322
                ..
323
0
            } if justifications.len() == 1 => {
324
0
                *self = SourcePendingJustificationProofs::None;
325
0
                let j = justifications.into_iter().next().unwrap();
326
0
                Some(FinalityProof::Justification(j))
327
            }
328
            SourcePendingJustificationProofs::One {
329
0
                target_height,
330
0
                proof: FinalityProofs::Justifications(mut justifications),
331
0
            } => {
332
0
                let j = justifications.pop().unwrap();
333
0
                *self = SourcePendingJustificationProofs::One {
334
0
                    target_height,
335
0
                    proof: FinalityProofs::Justifications(justifications),
336
0
                };
337
0
                Some(FinalityProof::Justification(j))
338
            }
339
            SourcePendingJustificationProofs::Two {
340
0
                high_proof: FinalityProofs::GrandpaCommit(commit),
341
0
                low_proof,
342
0
                low_target_height,
343
0
                ..
344
0
            } => {
345
0
                *self = SourcePendingJustificationProofs::One {
346
0
                    target_height: low_target_height,
347
0
                    proof: low_proof,
348
0
                };
349
0
                Some(FinalityProof::GrandpaCommit(commit))
350
            }
351
            SourcePendingJustificationProofs::Two {
352
0
                high_proof: FinalityProofs::Justifications(justifications),
353
0
                low_proof,
354
0
                low_target_height,
355
                ..
356
0
            } if justifications.len() == 1 => {
357
0
                let j = justifications.into_iter().next().unwrap();
358
0
                *self = SourcePendingJustificationProofs::One {
359
0
                    target_height: low_target_height,
360
0
                    proof: low_proof,
361
0
                };
362
0
                Some(FinalityProof::Justification(j))
363
            }
364
            SourcePendingJustificationProofs::Two {
365
0
                high_proof: FinalityProofs::Justifications(mut justifications),
366
0
                high_target_height,
367
0
                low_proof,
368
0
                low_target_height,
369
0
            } => {
370
0
                let j = justifications.pop().unwrap();
371
0
                *self = SourcePendingJustificationProofs::Two {
372
0
                    high_proof: FinalityProofs::Justifications(justifications),
373
0
                    high_target_height,
374
0
                    low_proof,
375
0
                    low_target_height,
376
0
                };
377
0
                Some(FinalityProof::Justification(j))
378
            }
379
        }
380
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot4sync9all_forksNtB2_32SourcePendingJustificationProofs8take_one
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot4sync9all_forksNtB2_32SourcePendingJustificationProofs8take_one
381
382
0
    fn merge(&mut self, other: Self) {
383
0
        match other {
384
0
            SourcePendingJustificationProofs::None => {}
385
            SourcePendingJustificationProofs::One {
386
0
                target_height,
387
0
                proof,
388
0
            } => self.insert(target_height, proof),
389
            SourcePendingJustificationProofs::Two {
390
0
                high_proof,
391
0
                high_target_height,
392
0
                low_proof,
393
0
                low_target_height,
394
0
            } => {
395
0
                self.insert(high_target_height, high_proof);
396
0
                self.insert(low_target_height, low_proof);
397
0
            }
398
        }
399
0
    }
Unexecuted instantiation: _RNvMNtNtCsN16ciHI6Qf_7smoldot4sync9all_forksNtB2_32SourcePendingJustificationProofs5merge
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot4sync9all_forksNtB2_32SourcePendingJustificationProofs5merge
400
}
401
402
enum FinalityProofs {
403
    GrandpaCommit(Vec<u8>),
404
    Justifications(Vec<([u8; 4], Vec<u8>)>),
405
}
406
407
enum FinalityProof {
408
    GrandpaCommit(Vec<u8>),
409
    Justification(([u8; 4], Vec<u8>)),
410
}
411
412
impl<TBl, TRq, TSrc> AllForksSync<TBl, TRq, TSrc> {
413
    /// Initializes a new [`AllForksSync`].
414
21
    pub fn new(config: Config) -> Self {
415
21
        let finalized_block_height = config
416
21
            .chain_information
417
21
            .as_ref()
418
21
            .finalized_block_header
419
21
            .number;
420
21
421
21
        let chain = blocks_tree::NonFinalizedTree::new(blocks_tree::Config {
422
21
            chain_information: config.chain_information,
423
21
            block_number_bytes: config.block_number_bytes,
424
21
            blocks_capacity: config.blocks_capacity,
425
21
            allow_unknown_consensus_engines: config.allow_unknown_consensus_engines,
426
21
        });
427
21
428
21
        Self {
429
21
            chain,
430
21
            inner: Box::new(Inner {
431
21
                blocks: pending_blocks::PendingBlocks::new(pending_blocks::Config {
432
21
                    blocks_capacity: config.blocks_capacity,
433
21
                    finalized_block_height,
434
21
                    max_requests_per_block: config.max_requests_per_block,
435
21
                    sources_capacity: config.sources_capacity,
436
21
                    download_bodies: config.download_bodies,
437
21
                }),
438
21
            }),
439
21
        }
440
21
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE3newB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE3newCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE3newB8_
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE3newCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
414
2
    pub fn new(config: Config) -> Self {
415
2
        let finalized_block_height = config
416
2
            .chain_information
417
2
            .as_ref()
418
2
            .finalized_block_header
419
2
            .number;
420
2
421
2
        let chain = blocks_tree::NonFinalizedTree::new(blocks_tree::Config {
422
2
            chain_information: config.chain_information,
423
2
            block_number_bytes: config.block_number_bytes,
424
2
            blocks_capacity: config.blocks_capacity,
425
2
            allow_unknown_consensus_engines: config.allow_unknown_consensus_engines,
426
2
        });
427
2
428
2
        Self {
429
2
            chain,
430
2
            inner: Box::new(Inner {
431
2
                blocks: pending_blocks::PendingBlocks::new(pending_blocks::Config {
432
2
                    blocks_capacity: config.blocks_capacity,
433
2
                    finalized_block_height,
434
2
                    max_requests_per_block: config.max_requests_per_block,
435
2
                    sources_capacity: config.sources_capacity,
436
2
                    download_bodies: config.download_bodies,
437
2
                }),
438
2
            }),
439
2
        }
440
2
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE3newCscDgN54JpMGG_6author
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE3newCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
414
19
    pub fn new(config: Config) -> Self {
415
19
        let finalized_block_height = config
416
19
            .chain_information
417
19
            .as_ref()
418
19
            .finalized_block_header
419
19
            .number;
420
19
421
19
        let chain = blocks_tree::NonFinalizedTree::new(blocks_tree::Config {
422
19
            chain_information: config.chain_information,
423
19
            block_number_bytes: config.block_number_bytes,
424
19
            blocks_capacity: config.blocks_capacity,
425
19
            allow_unknown_consensus_engines: config.allow_unknown_consensus_engines,
426
19
        });
427
19
428
19
        Self {
429
19
            chain,
430
19
            inner: Box::new(Inner {
431
19
                blocks: pending_blocks::PendingBlocks::new(pending_blocks::Config {
432
19
                    blocks_capacity: config.blocks_capacity,
433
19
                    finalized_block_height,
434
19
                    max_requests_per_block: config.max_requests_per_block,
435
19
                    sources_capacity: config.sources_capacity,
436
19
                    download_bodies: config.download_bodies,
437
19
                }),
438
19
            }),
439
19
        }
440
19
    }
441
442
    /// Returns the value that was initially passed in [`Config::block_number_bytes`].
443
0
    pub fn block_number_bytes(&self) -> usize {
444
0
        self.chain.block_number_bytes()
445
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE18block_number_bytesB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE18block_number_bytesB8_
446
447
    /// Builds a [`chain_information::ChainInformationRef`] struct corresponding to the current
448
    /// latest finalized block. Can later be used to reconstruct a chain.
449
0
    pub fn as_chain_information(&self) -> chain_information::ValidChainInformationRef {
450
0
        self.chain.as_chain_information()
451
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE20as_chain_informationB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE20as_chain_informationCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE20as_chain_informationB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20as_chain_informationCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20as_chain_informationCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20as_chain_informationCsibGXYHQB8Ea_25json_rpc_general_requests
452
453
    /// Returns the header of the finalized block.
454
0
    pub fn finalized_block_header(&self) -> &[u8] {
455
0
        self.chain.finalized_block_header()
456
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE22finalized_block_headerB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE22finalized_block_headerCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE22finalized_block_headerB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE22finalized_block_headerCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE22finalized_block_headerCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE22finalized_block_headerCsibGXYHQB8Ea_25json_rpc_general_requests
457
458
    /// Returns the height of the finalized block.
459
0
    pub fn finalized_block_number(&self) -> u64 {
460
0
        self.chain.finalized_block_height()
461
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE22finalized_block_numberB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE22finalized_block_numberCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE22finalized_block_numberB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE22finalized_block_numberCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE22finalized_block_numberCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE22finalized_block_numberCsibGXYHQB8Ea_25json_rpc_general_requests
462
463
    /// Returns the hash of the finalized block.
464
0
    pub fn finalized_block_hash(&self) -> &[u8; 32] {
465
0
        self.chain.finalized_block_hash()
466
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE20finalized_block_hashB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE20finalized_block_hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE20finalized_block_hashB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20finalized_block_hashCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20finalized_block_hashCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20finalized_block_hashCsibGXYHQB8Ea_25json_rpc_general_requests
467
468
    /// Returns the header of the best block.
469
    ///
470
    /// > **Note**: This value is provided only for informative purposes. Keep in mind that this
471
    /// >           best block might be reverted in the future.
472
0
    pub fn best_block_header(&self) -> &[u8] {
473
0
        self.chain.best_block_header()
474
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17best_block_headerB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17best_block_headerB8_
475
476
    /// Returns the number of the best block.
477
    ///
478
    /// > **Note**: This value is provided only for informative purposes. Keep in mind that this
479
    /// >           best block might be reverted in the future.
480
21
    pub fn best_block_number(&self) -> u64 {
481
21
        self.chain.best_block_height()
482
21
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17best_block_numberB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE17best_block_numberCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17best_block_numberB8_
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE17best_block_numberCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
480
2
    pub fn best_block_number(&self) -> u64 {
481
2
        self.chain.best_block_height()
482
2
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE17best_block_numberCscDgN54JpMGG_6author
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE17best_block_numberCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
480
19
    pub fn best_block_number(&self) -> u64 {
481
19
        self.chain.best_block_height()
482
19
    }
483
484
    /// Returns the hash of the best block.
485
    ///
486
    /// > **Note**: This value is provided only for informative purposes. Keep in mind that this
487
    /// >           best block might be reverted in the future.
488
21
    pub fn best_block_hash(&self) -> &[u8; 32] {
489
21
        self.chain.best_block_hash()
490
21
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE15best_block_hashB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE15best_block_hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE15best_block_hashB8_
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE15best_block_hashCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
488
2
    pub fn best_block_hash(&self) -> &[u8; 32] {
489
2
        self.chain.best_block_hash()
490
2
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE15best_block_hashCscDgN54JpMGG_6author
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE15best_block_hashCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
488
19
    pub fn best_block_hash(&self) -> &[u8; 32] {
489
19
        self.chain.best_block_hash()
490
19
    }
491
492
    /// Returns the header of all known non-finalized blocks in the chain without any specific
493
    /// order.
494
0
    pub fn non_finalized_blocks_unordered(
495
0
        &'_ self,
496
0
    ) -> impl Iterator<Item = header::HeaderRef<'_>> + '_ {
497
0
        self.chain.iter_unordered()
498
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE30non_finalized_blocks_unorderedB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE30non_finalized_blocks_unorderedCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE30non_finalized_blocks_unorderedB8_
499
500
    /// Returns the header of all known non-finalized blocks in the chain.
501
    ///
502
    /// The returned items are guaranteed to be in an order in which the parents are found before
503
    /// their children.
504
0
    pub fn non_finalized_blocks_ancestry_order(
505
0
        &'_ self,
506
0
    ) -> impl Iterator<Item = header::HeaderRef<'_>> + '_ {
507
0
        self.chain.iter_ancestry_order()
508
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE35non_finalized_blocks_ancestry_orderB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE35non_finalized_blocks_ancestry_orderCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE35non_finalized_blocks_ancestry_orderB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE35non_finalized_blocks_ancestry_orderCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE35non_finalized_blocks_ancestry_orderCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE35non_finalized_blocks_ancestry_orderCsibGXYHQB8Ea_25json_rpc_general_requests
509
510
    /// Starts the process of inserting a new source in the [`AllForksSync`].
511
    ///
512
    /// This function doesn't modify the state machine, but only looks at the current state of the
513
    /// block referenced by `best_block_number` and `best_block_hash`. It returns an enum that
514
    /// allows performing the actual insertion.
515
21
    pub fn prepare_add_source(
516
21
        &mut self,
517
21
        best_block_number: u64,
518
21
        best_block_hash: [u8; 32],
519
21
    ) -> AddSource<TBl, TRq, TSrc> {
520
21
        if best_block_number <= self.chain.finalized_block_height() {
521
21
            return AddSource::OldBestBlock(AddSourceOldBlock {
522
21
                inner: self,
523
21
                best_block_hash,
524
21
                best_block_number,
525
21
            });
526
0
        }
527
0
528
0
        let best_block_already_verified = self.chain.contains_non_finalized_block(&best_block_hash);
529
0
        let best_block_in_disjoints_list = self
530
0
            .inner
531
0
            .blocks
532
0
            .contains_unverified_block(best_block_number, &best_block_hash);
533
0
534
0
        match (best_block_already_verified, best_block_in_disjoints_list) {
535
0
            (false, false) => AddSource::UnknownBestBlock(AddSourceUnknown {
536
0
                inner: self,
537
0
                best_block_hash,
538
0
                best_block_number,
539
0
            }),
540
0
            (true, false) => AddSource::BestBlockAlreadyVerified(AddSourceKnown {
541
0
                inner: self,
542
0
                best_block_hash,
543
0
                best_block_number,
544
0
            }),
545
0
            (false, true) => AddSource::BestBlockPendingVerification(AddSourceKnown {
546
0
                inner: self,
547
0
                best_block_hash,
548
0
                best_block_number,
549
0
            }),
550
0
            (true, true) => unreachable!(),
551
        }
552
21
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE18prepare_add_sourceB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE18prepare_add_sourceCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE18prepare_add_sourceB8_
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE18prepare_add_sourceCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
515
2
    pub fn prepare_add_source(
516
2
        &mut self,
517
2
        best_block_number: u64,
518
2
        best_block_hash: [u8; 32],
519
2
    ) -> AddSource<TBl, TRq, TSrc> {
520
2
        if best_block_number <= self.chain.finalized_block_height() {
521
2
            return AddSource::OldBestBlock(AddSourceOldBlock {
522
2
                inner: self,
523
2
                best_block_hash,
524
2
                best_block_number,
525
2
            });
526
0
        }
527
0
528
0
        let best_block_already_verified = self.chain.contains_non_finalized_block(&best_block_hash);
529
0
        let best_block_in_disjoints_list = self
530
0
            .inner
531
0
            .blocks
532
0
            .contains_unverified_block(best_block_number, &best_block_hash);
533
0
534
0
        match (best_block_already_verified, best_block_in_disjoints_list) {
535
0
            (false, false) => AddSource::UnknownBestBlock(AddSourceUnknown {
536
0
                inner: self,
537
0
                best_block_hash,
538
0
                best_block_number,
539
0
            }),
540
0
            (true, false) => AddSource::BestBlockAlreadyVerified(AddSourceKnown {
541
0
                inner: self,
542
0
                best_block_hash,
543
0
                best_block_number,
544
0
            }),
545
0
            (false, true) => AddSource::BestBlockPendingVerification(AddSourceKnown {
546
0
                inner: self,
547
0
                best_block_hash,
548
0
                best_block_number,
549
0
            }),
550
0
            (true, true) => unreachable!(),
551
        }
552
2
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE18prepare_add_sourceCscDgN54JpMGG_6author
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE18prepare_add_sourceCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
515
19
    pub fn prepare_add_source(
516
19
        &mut self,
517
19
        best_block_number: u64,
518
19
        best_block_hash: [u8; 32],
519
19
    ) -> AddSource<TBl, TRq, TSrc> {
520
19
        if best_block_number <= self.chain.finalized_block_height() {
521
19
            return AddSource::OldBestBlock(AddSourceOldBlock {
522
19
                inner: self,
523
19
                best_block_hash,
524
19
                best_block_number,
525
19
            });
526
0
        }
527
0
528
0
        let best_block_already_verified = self.chain.contains_non_finalized_block(&best_block_hash);
529
0
        let best_block_in_disjoints_list = self
530
0
            .inner
531
0
            .blocks
532
0
            .contains_unverified_block(best_block_number, &best_block_hash);
533
0
534
0
        match (best_block_already_verified, best_block_in_disjoints_list) {
535
0
            (false, false) => AddSource::UnknownBestBlock(AddSourceUnknown {
536
0
                inner: self,
537
0
                best_block_hash,
538
0
                best_block_number,
539
0
            }),
540
0
            (true, false) => AddSource::BestBlockAlreadyVerified(AddSourceKnown {
541
0
                inner: self,
542
0
                best_block_hash,
543
0
                best_block_number,
544
0
            }),
545
0
            (false, true) => AddSource::BestBlockPendingVerification(AddSourceKnown {
546
0
                inner: self,
547
0
                best_block_hash,
548
0
                best_block_number,
549
0
            }),
550
0
            (true, true) => unreachable!(),
551
        }
552
19
    }
553
554
    /// Removes the source from the [`AllForksSync`].
555
    ///
556
    /// Removing the source implicitly cancels the request that is associated to it (if any).
557
    ///
558
    /// Returns the user data that was originally passed when inserting the source, plus an
559
    /// `Option`.
560
    /// If this `Option` is `Some`, it contains a request that must be started towards the source
561
    /// indicated by the [`SourceId`].
562
    ///
563
    /// > **Note**: For example, if the source that has just been removed was performing an
564
    /// >           ancestry search, the `Option` might contain that same ancestry search.
565
    ///
566
    /// # Panic
567
    ///
568
    /// Panics if the [`SourceId`] is out of range.
569
    ///
570
0
    pub fn remove_source(
571
0
        &mut self,
572
0
        source_id: SourceId,
573
0
    ) -> (TSrc, impl Iterator<Item = (RequestId, RequestParams, TRq)>) {
574
0
        let (user_data, iter) = self.inner.blocks.remove_source(source_id);
575
0
        (user_data.user_data, iter)
576
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE13remove_sourceB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE13remove_sourceCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE13remove_sourceB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE13remove_sourceCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE13remove_sourceCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE13remove_sourceCsibGXYHQB8Ea_25json_rpc_general_requests
577
578
    /// Returns the list of sources in this state machine.
579
0
    pub fn sources(&'_ self) -> impl ExactSizeIterator<Item = SourceId> + '_ {
580
0
        self.inner.blocks.sources()
581
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE7sourcesB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE7sourcesCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE7sourcesB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE7sourcesCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE7sourcesCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE7sourcesCsibGXYHQB8Ea_25json_rpc_general_requests
582
583
    /// Returns true if the source has earlier announced the block passed as parameter or one of
584
    /// its descendants.
585
    ///
586
    /// Also returns true if the requested block is inferior or equal to the known finalized block
587
    /// and the source has announced a block higher or equal to the known finalized block.
588
    ///
589
    /// # Panic
590
    ///
591
    /// Panics if the [`SourceId`] is out of range.
592
    ///
593
    /// Panics if `height` is inferior or equal to the finalized block height. Finalized blocks
594
    /// are intentionally not tracked by this data structure, and panicking when asking for a
595
    /// potentially-finalized block prevents potentially confusing or erroneous situations.
596
    ///
597
0
    pub fn source_knows_non_finalized_block(
598
0
        &self,
599
0
        source_id: SourceId,
600
0
        height: u64,
601
0
        hash: &[u8; 32],
602
0
    ) -> bool {
603
0
        self.inner
604
0
            .blocks
605
0
            .source_knows_non_finalized_block(source_id, height, hash)
606
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE32source_knows_non_finalized_blockB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE32source_knows_non_finalized_blockB8_
607
608
    /// Returns the list of sources for which [`AllForksSync::source_knows_non_finalized_block`]
609
    /// would return `true`.
610
    ///
611
    /// # Panic
612
    ///
613
    /// Panics if `height` is inferior or equal to the finalized block height. Finalized blocks
614
    /// are intentionally not tracked by this data structure, and panicking when asking for a
615
    /// potentially-finalized block prevents potentially confusing or erroneous situations.
616
    ///
617
0
    pub fn knows_non_finalized_block<'a>(
618
0
        &'a self,
619
0
        height: u64,
620
0
        hash: &[u8; 32],
621
0
    ) -> impl Iterator<Item = SourceId> + 'a {
622
0
        self.inner.blocks.knows_non_finalized_block(height, hash)
623
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE25knows_non_finalized_blockB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE25knows_non_finalized_blockCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE25knows_non_finalized_blockB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE25knows_non_finalized_blockCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE25knows_non_finalized_blockCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE25knows_non_finalized_blockCsibGXYHQB8Ea_25json_rpc_general_requests
624
625
    /// Registers a new block that the source is aware of.
626
    ///
627
    /// Has no effect if `height` is inferior or equal to the finalized block height, or if the
628
    /// source was already known to know this block.
629
    ///
630
    /// The block does not need to be known by the data structure.
631
    ///
632
    /// This is automatically done for the blocks added through [`AllForksSync::block_announce`],
633
    /// [`AllForksSync::prepare_add_source`] or [`FinishRequest::add_block`].
634
    ///
635
    /// # Panic
636
    ///
637
    /// Panics if the [`SourceId`] is out of range.
638
    ///
639
0
    pub fn add_known_block_to_source(&mut self, source_id: SourceId, height: u64, hash: [u8; 32]) {
640
0
        self.inner
641
0
            .blocks
642
0
            .add_known_block_to_source(source_id, height, hash);
643
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE25add_known_block_to_sourceB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE25add_known_block_to_sourceB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE25add_known_block_to_sourceCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE25add_known_block_to_sourceCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE25add_known_block_to_sourceCsibGXYHQB8Ea_25json_rpc_general_requests
644
645
    /// Returns the current best block of the given source.
646
    ///
647
    /// This corresponds either the latest call to [`AllForksSync::block_announce`] where
648
    /// `is_best` was `true`, or to the parameter passed to [`AllForksSync::prepare_add_source`].
649
    ///
650
    /// # Panic
651
    ///
652
    /// Panics if the [`SourceId`] is invalid.
653
    ///
654
0
    pub fn source_best_block(&self, source_id: SourceId) -> (u64, &[u8; 32]) {
655
0
        self.inner.blocks.source_best_block(source_id)
656
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17source_best_blockB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE17source_best_blockCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17source_best_blockB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE17source_best_blockCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE17source_best_blockCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE17source_best_blockCsibGXYHQB8Ea_25json_rpc_general_requests
657
658
    /// Returns the number of ongoing requests that concern this source.
659
    ///
660
    /// # Panic
661
    ///
662
    /// Panics if the [`SourceId`] is invalid.
663
    ///
664
0
    pub fn source_num_ongoing_requests(&self, source_id: SourceId) -> usize {
665
0
        self.inner.blocks.source_num_ongoing_requests(source_id)
666
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE27source_num_ongoing_requestsB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE27source_num_ongoing_requestsB8_
667
668
    /// Returns the details of a request to start towards a source.
669
    ///
670
    /// This method doesn't modify the state machine in any way. [`AllForksSync::add_request`]
671
    /// must be called in order for the request to actually be marked as started.
672
43
    pub fn desired_requests(
673
43
        &'_ self,
674
43
    ) -> impl Iterator<Item = (SourceId, &'_ TSrc, RequestParams)> + '_ {
675
43
        // Query justifications of blocks that are necessary in order for finality to progress
676
43
        // against sources that have reported these blocks as finalized.
677
43
        // TODO: make it clear in the API docs that justifications should be requested as part of a request
678
43
        // TODO: this is O(n)
679
43
        let justification_requests =
680
43
            self.chain
681
43
                .finality_checkpoints()
682
43
                .flat_map(move |(block_height, block_hash)| {
683
0
                    self.inner
684
0
                        .blocks
685
0
                        .sources()
686
0
                        .filter(move |s| {
687
0
                            // We assume that all sources have the same finalized blocks and thus
688
0
                            // don't check hashes.
689
0
                            self.inner.blocks[*s].unverified_finality_proofs.is_none()
690
0
                                && self.inner.blocks[*s].finalized_block_number >= block_height
691
0
                        })
Unexecuted instantiation: _RNCNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB8_12AllForksSyncpppE16desired_requests00Bc_
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtBa_3all20AllForksRequestExtraNtB1N_19AllForksSourceExtraE16desired_requests00CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncpppE16desired_requests00Bc_
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB2Z_19AllForksSourceExtraE16desired_requests00CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB2Z_19AllForksSourceExtraE16desired_requests00CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB2Z_19AllForksSourceExtraE16desired_requests00CsibGXYHQB8Ea_25json_rpc_general_requests
692
0
                        .map(move |source_id| {
693
0
                            (
694
0
                                source_id,
695
0
                                &self.inner.blocks[source_id].user_data,
696
0
                                RequestParams {
697
0
                                    first_block_hash: *block_hash,
698
0
                                    first_block_height: block_height,
699
0
                                    num_blocks: NonZeroU64::new(1).unwrap(),
700
0
                                },
701
0
                            )
702
0
                        })
Unexecuted instantiation: _RNCNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB8_12AllForksSyncpppE16desired_requests0s_0Bc_
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtBa_3all20AllForksRequestExtraNtB1N_19AllForksSourceExtraE16desired_requests0s_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncpppE16desired_requests0s_0Bc_
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB2Z_19AllForksSourceExtraE16desired_requests0s_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB2Z_19AllForksSourceExtraE16desired_requests0s_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB2Z_19AllForksSourceExtraE16desired_requests0s_0CsibGXYHQB8Ea_25json_rpc_general_requests
703
43
                });
Unexecuted instantiation: _RNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE16desired_requests0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB8_3all20AllForksRequestExtraNtB1L_19AllForksSourceExtraE16desired_requests0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE16desired_requests0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requests0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requests0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requests0CsibGXYHQB8Ea_25json_rpc_general_requests
704
43
705
43
        let block_requests = self
706
43
            .inner
707
43
            .blocks
708
43
            .desired_requests()
709
43
            .filter(move |rq| {
710
0
                !self
711
0
                    .chain
712
0
                    .contains_non_finalized_block(&rq.request_params.first_block_hash)
713
43
            })
Unexecuted instantiation: _RNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE16desired_requestss_0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB8_3all20AllForksRequestExtraNtB1L_19AllForksSourceExtraE16desired_requestss_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE16desired_requestss_0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requestss_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requestss_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requestss_0CsibGXYHQB8Ea_25json_rpc_general_requests
714
43
            .map(move |rq| {
715
0
                (
716
0
                    rq.source_id,
717
0
                    &self.inner.blocks[rq.source_id].user_data,
718
0
                    rq.request_params,
719
0
                )
720
43
            });
Unexecuted instantiation: _RNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE16desired_requestss0_0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB8_3all20AllForksRequestExtraNtB1L_19AllForksSourceExtraE16desired_requestss0_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE16desired_requestss0_0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requestss0_0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requestss0_0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE16desired_requestss0_0CsibGXYHQB8Ea_25json_rpc_general_requests
721
43
722
43
        justification_requests.chain(block_requests)
723
43
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE16desired_requestsB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE16desired_requestsCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE16desired_requestsB8_
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE16desired_requestsCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
672
4
    pub fn desired_requests(
673
4
        &'_ self,
674
4
    ) -> impl Iterator<Item = (SourceId, &'_ TSrc, RequestParams)> + '_ {
675
4
        // Query justifications of blocks that are necessary in order for finality to progress
676
4
        // against sources that have reported these blocks as finalized.
677
4
        // TODO: make it clear in the API docs that justifications should be requested as part of a request
678
4
        // TODO: this is O(n)
679
4
        let justification_requests =
680
4
            self.chain
681
4
                .finality_checkpoints()
682
4
                .flat_map(move |(block_height, block_hash)| {
683
                    self.inner
684
                        .blocks
685
                        .sources()
686
                        .filter(move |s| {
687
                            // We assume that all sources have the same finalized blocks and thus
688
                            // don't check hashes.
689
                            self.inner.blocks[*s].unverified_finality_proofs.is_none()
690
                                && self.inner.blocks[*s].finalized_block_number >= block_height
691
                        })
692
                        .map(move |source_id| {
693
                            (
694
                                source_id,
695
                                &self.inner.blocks[source_id].user_data,
696
                                RequestParams {
697
                                    first_block_hash: *block_hash,
698
                                    first_block_height: block_height,
699
                                    num_blocks: NonZeroU64::new(1).unwrap(),
700
                                },
701
                            )
702
                        })
703
4
                });
704
4
705
4
        let block_requests = self
706
4
            .inner
707
4
            .blocks
708
4
            .desired_requests()
709
4
            .filter(move |rq| {
710
                !self
711
                    .chain
712
                    .contains_non_finalized_block(&rq.request_params.first_block_hash)
713
4
            })
714
4
            .map(move |rq| {
715
                (
716
                    rq.source_id,
717
                    &self.inner.blocks[rq.source_id].user_data,
718
                    rq.request_params,
719
                )
720
4
            });
721
4
722
4
        justification_requests.chain(block_requests)
723
4
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE16desired_requestsCscDgN54JpMGG_6author
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE16desired_requestsCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
672
39
    pub fn desired_requests(
673
39
        &'_ self,
674
39
    ) -> impl Iterator<Item = (SourceId, &'_ TSrc, RequestParams)> + '_ {
675
39
        // Query justifications of blocks that are necessary in order for finality to progress
676
39
        // against sources that have reported these blocks as finalized.
677
39
        // TODO: make it clear in the API docs that justifications should be requested as part of a request
678
39
        // TODO: this is O(n)
679
39
        let justification_requests =
680
39
            self.chain
681
39
                .finality_checkpoints()
682
39
                .flat_map(move |(block_height, block_hash)| {
683
                    self.inner
684
                        .blocks
685
                        .sources()
686
                        .filter(move |s| {
687
                            // We assume that all sources have the same finalized blocks and thus
688
                            // don't check hashes.
689
                            self.inner.blocks[*s].unverified_finality_proofs.is_none()
690
                                && self.inner.blocks[*s].finalized_block_number >= block_height
691
                        })
692
                        .map(move |source_id| {
693
                            (
694
                                source_id,
695
                                &self.inner.blocks[source_id].user_data,
696
                                RequestParams {
697
                                    first_block_hash: *block_hash,
698
                                    first_block_height: block_height,
699
                                    num_blocks: NonZeroU64::new(1).unwrap(),
700
                                },
701
                            )
702
                        })
703
39
                });
704
39
705
39
        let block_requests = self
706
39
            .inner
707
39
            .blocks
708
39
            .desired_requests()
709
39
            .filter(move |rq| {
710
                !self
711
                    .chain
712
                    .contains_non_finalized_block(&rq.request_params.first_block_hash)
713
39
            })
714
39
            .map(move |rq| {
715
                (
716
                    rq.source_id,
717
                    &self.inner.blocks[rq.source_id].user_data,
718
                    rq.request_params,
719
                )
720
39
            });
721
39
722
39
        justification_requests.chain(block_requests)
723
39
    }
724
725
    /// Inserts a new request in the data structure.
726
    ///
727
    /// > **Note**: The request doesn't necessarily have to match a request returned by
728
    /// >           [`AllForksSync::desired_requests`].
729
    ///
730
    /// # Panic
731
    ///
732
    /// Panics if the [`SourceId`] is out of range.
733
    ///
734
0
    pub fn add_request(
735
0
        &mut self,
736
0
        source_id: SourceId,
737
0
        detail: RequestParams,
738
0
        user_data: TRq,
739
0
    ) -> RequestId {
740
0
        self.inner.blocks.add_request(source_id, detail, user_data)
741
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE11add_requestB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE11add_requestCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE11add_requestB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE11add_requestCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE11add_requestCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE11add_requestCsibGXYHQB8Ea_25json_rpc_general_requests
742
743
    /// Returns a list of requests that are considered obsolete and can be removed using
744
    /// [`AllForksSync::finish_request`].
745
    ///
746
    /// A request becomes obsolete if the state of the request blocks changes in such a way that
747
    /// they don't need to be requested anymore. The response to the request will be useless.
748
    ///
749
    /// > **Note**: It is in no way mandatory to actually call this function and cancel the
750
    /// >           requests that are returned.
751
0
    pub fn obsolete_requests(&'_ self) -> impl Iterator<Item = (RequestId, &'_ TRq)> + '_ {
752
0
        // TODO: requests meant to query justifications only are considered obsolete by the underlying state machine, which right now is okay because the underlying state machine is pretty loose in its definition of obsolete
753
0
        self.inner.blocks.obsolete_requests()
754
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17obsolete_requestsB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE17obsolete_requestsCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17obsolete_requestsB8_
755
756
    /// Returns the [`SourceId`] that is expected to fulfill the given request.
757
    ///
758
    /// # Panic
759
    ///
760
    /// Panics if the [`RequestId`] is invalid.
761
    ///
762
0
    pub fn request_source_id(&self, request_id: RequestId) -> SourceId {
763
0
        self.inner.blocks.request_source_id(request_id)
764
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17request_source_idB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE17request_source_idB8_
765
766
    /// Call in response to a request being successful or failing.
767
    ///
768
    /// This state machine doesn't differentiate between successful or failed requests. If a
769
    /// request has failed, call this function and immediately call [`FinishRequest::finish`].
770
    /// Additionally, it is allow to insert fewer blocks than the number indicated in
771
    /// [`RequestParams::num_blocks`].
772
    ///
773
    /// The added blocks are expected to be sorted in decreasing order. The first block should be
774
    /// the block with the hash that was referred by [`RequestParams::first_block_hash`]. Each
775
    /// subsequent element is then expected to be the parent of the previous one.
776
    ///
777
    /// # Panic
778
    ///
779
    /// Panics if the [`RequestId`] is invalid.
780
    ///
781
0
    pub fn finish_request(
782
0
        &mut self,
783
0
        request_id: RequestId,
784
0
    ) -> (TRq, FinishRequest<TBl, TRq, TSrc>) {
785
0
        // Sets the `occupation` of `source_id` back to `AllSync`.
786
0
        let (
787
0
            pending_blocks::RequestParams {
788
0
                first_block_hash: requested_block_hash,
789
0
                first_block_height: requested_block_height,
790
0
                ..
791
0
            },
792
0
            source_id,
793
0
            request_user_data,
794
0
        ) = self.inner.blocks.remove_request(request_id);
795
0
796
0
        (
797
0
            request_user_data,
798
0
            FinishRequest {
799
0
                inner: self,
800
0
                source_id,
801
0
                any_progress: false,
802
0
                index_in_response: 0,
803
0
                requested_block_hash,
804
0
                requested_block_height,
805
0
                expected_next_hash: requested_block_hash,
806
0
                expected_next_height: requested_block_height,
807
0
            },
808
0
        )
809
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE14finish_requestB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE14finish_requestCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE14finish_requestB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE14finish_requestCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE14finish_requestCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE14finish_requestCsibGXYHQB8Ea_25json_rpc_general_requests
810
811
    /// Update the source with a newly-announced block.
812
    ///
813
    /// > **Note**: This information is normally reported by the source itself. In the case of a
814
    /// >           a networking peer, call this when the source sent a block announce.
815
    ///
816
    /// # Panic
817
    ///
818
    /// Panics if `source_id` is invalid.
819
    ///
820
0
    pub fn block_announce(
821
0
        &mut self,
822
0
        source_id: SourceId,
823
0
        announced_scale_encoded_header: Vec<u8>,
824
0
        is_best: bool,
825
0
    ) -> BlockAnnounceOutcome<TBl, TRq, TSrc> {
826
0
        let announced_header = match header::decode(
827
0
            &announced_scale_encoded_header,
828
0
            self.chain.block_number_bytes(),
829
0
        ) {
830
0
            Ok(h) => h,
831
0
            Err(error) => return BlockAnnounceOutcome::InvalidHeader(error),
832
        };
833
834
0
        let announced_header_number = announced_header.number;
835
0
        let announced_header_parent_hash = *announced_header.parent_hash;
836
0
        let announced_header_hash = announced_header.hash(self.chain.block_number_bytes());
837
0
838
0
        // It is assumed that all sources will eventually agree on the same finalized chain. If
839
0
        // the block number is lower or equal than the locally-finalized block number, it is
840
0
        // assumed that this source is simply late compared to the local node, and that the block
841
0
        // that has been received is either part of the finalized chain or belongs to a fork that
842
0
        // will get discarded by this source in the future.
843
0
        if announced_header_number <= self.chain.finalized_block_height() {
844
            // Even if the block is below the finalized block, we still need to set it as the
845
            // best block of this source, if anything for API consistency purposes.
846
0
            if is_best {
847
0
                self.inner.blocks.add_known_block_to_source_and_set_best(
848
0
                    source_id,
849
0
                    announced_header_number,
850
0
                    announced_header_hash,
851
0
                );
852
0
            }
853
854
0
            return BlockAnnounceOutcome::TooOld {
855
0
                announce_block_height: announced_header_number,
856
0
                finalized_block_height: self.chain.finalized_block_height(),
857
0
            };
858
0
        }
859
0
860
0
        // If the block is already part of the local tree of blocks, nothing more to do.
861
0
        if self
862
0
            .chain
863
0
            .contains_non_finalized_block(&announced_header_hash)
864
        {
865
0
            return BlockAnnounceOutcome::AlreadyVerified(AnnouncedBlockKnown {
866
0
                inner: self,
867
0
                announced_header_hash,
868
0
                announced_header_number,
869
0
                announced_header_parent_hash,
870
0
                announced_header_encoded: announced_scale_encoded_header,
871
0
                source_id,
872
0
                is_in_chain: true,
873
0
                is_best,
874
0
            });
875
0
        }
876
0
877
0
        // At this point, we have excluded blocks that are already part of the chain or too old.
878
0
        // We insert the block in the list of unverified blocks so as to treat all blocks the
879
0
        // same.
880
0
        if !self
881
0
            .inner
882
0
            .blocks
883
0
            .contains_unverified_block(announced_header_number, &announced_header_hash)
884
        {
885
0
            BlockAnnounceOutcome::Unknown(AnnouncedBlockUnknown {
886
0
                inner: self,
887
0
                announced_header_hash,
888
0
                announced_header_number,
889
0
                announced_header_parent_hash,
890
0
                announced_header_encoded: announced_scale_encoded_header,
891
0
                source_id,
892
0
                is_best,
893
0
            })
894
        } else {
895
0
            BlockAnnounceOutcome::AlreadyPending(AnnouncedBlockKnown {
896
0
                inner: self,
897
0
                announced_header_hash,
898
0
                announced_header_number,
899
0
                announced_header_parent_hash,
900
0
                announced_header_encoded: announced_scale_encoded_header,
901
0
                is_in_chain: false,
902
0
                source_id,
903
0
                is_best,
904
0
            })
905
        }
906
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE14block_announceB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE14block_announceCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE14block_announceB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE14block_announceCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE14block_announceCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE14block_announceCsibGXYHQB8Ea_25json_rpc_general_requests
907
908
    /// Update the finalized block height of the given source.
909
    ///
910
    /// # Panic
911
    ///
912
    /// Panics if `source_id` is invalid.
913
    ///
914
0
    pub fn update_source_finality_state(
915
0
        &mut self,
916
0
        source_id: SourceId,
917
0
        finalized_block_height: u64,
918
0
    ) {
919
0
        let source = &mut self.inner.blocks[source_id];
920
0
        source.finalized_block_number =
921
0
            cmp::max(source.finalized_block_number, finalized_block_height);
922
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE28update_source_finality_stateB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE28update_source_finality_stateCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE28update_source_finality_stateB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE28update_source_finality_stateCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE28update_source_finality_stateCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE28update_source_finality_stateCsibGXYHQB8Ea_25json_rpc_general_requests
923
924
    /// Update the state machine with a Grandpa commit message received from the network.
925
    ///
926
    /// This function only inserts the commit message into the state machine, and does not
927
    /// immediately verify it.
928
    ///
929
    /// # Panic
930
    ///
931
    /// Panics if `source_id` is invalid.
932
    ///
933
0
    pub fn grandpa_commit_message(
934
0
        &mut self,
935
0
        source_id: SourceId,
936
0
        scale_encoded_commit: Vec<u8>,
937
0
    ) -> GrandpaCommitMessageOutcome {
938
0
        let source = &mut self.inner.blocks[source_id];
939
940
0
        let block_number = match decode::decode_grandpa_commit(
941
0
            &scale_encoded_commit,
942
0
            self.chain.block_number_bytes(),
943
0
        ) {
944
0
            Ok(msg) => msg.target_number,
945
0
            Err(_) => return GrandpaCommitMessageOutcome::ParseError,
946
        };
947
948
        // The finalized block number of the source is increased even if the commit message
949
        // isn't known to be valid yet.
950
0
        source.finalized_block_number = cmp::max(source.finalized_block_number, block_number);
951
0
952
0
        source.unverified_finality_proofs.insert(
953
0
            block_number,
954
0
            FinalityProofs::GrandpaCommit(scale_encoded_commit),
955
0
        );
956
0
957
0
        GrandpaCommitMessageOutcome::Queued
958
0
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE22grandpa_commit_messageB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE22grandpa_commit_messageCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE22grandpa_commit_messageB8_
959
960
    /// Process the next block in the queue of verification.
961
    ///
962
    /// This method takes ownership of the [`AllForksSync`] and starts a verification
963
    /// process. The [`AllForksSync`] is yielded back at the end of this process.
964
21
    pub fn process_one(mut self) -> ProcessOne<TBl, TRq, TSrc> {
965
21
        // Try to find a block to verify.
966
21
        // All blocks are always verified before verifying justifications, in order to guarantee
967
21
        // that the block that a justification targets has already been verified.
968
21
        // TODO: revisit that ^ as advancing finality should have priority over advancing the chain
969
21
        let block_to_verify = self.inner.blocks.unverified_leaves().find(|block| {
970
0
            block.parent_block_hash == *self.chain.finalized_block_hash()
971
0
                || self
972
0
                    .chain
973
0
                    .contains_non_finalized_block(&block.parent_block_hash)
974
21
        
}0
);
Unexecuted instantiation: _RNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE11process_one0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB8_3all20AllForksRequestExtraNtB1L_19AllForksSourceExtraE11process_one0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE11process_one0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE11process_one0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE11process_one0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE11process_one0CsibGXYHQB8Ea_25json_rpc_general_requests
975
21
        if let Some(
block0
) = block_to_verify {
976
0
            return ProcessOne::BlockVerify(BlockVerify {
977
0
                parent: self,
978
0
                block_to_verify: block,
979
0
            });
980
21
        }
981
21
982
21
        // Try to find a justification to verify.
983
21
        // TODO: O(n)
984
21
        let source_id_with_finality_proof = self
985
21
            .inner
986
21
            .blocks
987
21
            .sources()
988
21
            .find(|id| !self.inner.blocks[*id].unverified_finality_proofs.is_none());
Unexecuted instantiation: _RNCNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE11process_ones_0Ba_
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB8_3all20AllForksRequestExtraNtB1L_19AllForksSourceExtraE11process_ones_0CsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncpppE11process_ones_0Ba_
_RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE11process_ones_0CsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
988
2
            .find(|id| !self.inner.blocks[*id].unverified_finality_proofs.is_none());
Unexecuted instantiation: _RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE11process_ones_0CscDgN54JpMGG_6author
_RNCNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraE11process_ones_0CsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
988
19
            .find(|id| !self.inner.blocks[*id].unverified_finality_proofs.is_none());
989
21
        if let Some(
source_id_with_finality_proof0
) = source_id_with_finality_proof {
990
0
            let finality_proof_to_verify = self.inner.blocks[source_id_with_finality_proof]
991
0
                .unverified_finality_proofs
992
0
                .take_one()
993
0
                .unwrap(); // `take()` always returns `Some` because we've checked `is_none()` above
994
0
            return ProcessOne::FinalityProofVerify(FinalityProofVerify {
995
0
                parent: self,
996
0
                source_id: source_id_with_finality_proof,
997
0
                finality_proof_to_verify,
998
0
            });
999
21
        }
1000
21
1001
21
        ProcessOne::AllSync { sync: self }
1002
21
    }
Unexecuted instantiation: _RNvMs_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE11process_oneB8_
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB6_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE11process_oneCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncpppE11process_oneB8_
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE11process_oneCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
964
2
    pub fn process_one(mut self) -> ProcessOne<TBl, TRq, TSrc> {
965
2
        // Try to find a block to verify.
966
2
        // All blocks are always verified before verifying justifications, in order to guarantee
967
2
        // that the block that a justification targets has already been verified.
968
2
        // TODO: revisit that ^ as advancing finality should have priority over advancing the chain
969
2
        let block_to_verify = self.inner.blocks.unverified_leaves().find(|block| {
970
            block.parent_block_hash == *self.chain.finalized_block_hash()
971
                || self
972
                    .chain
973
                    .contains_non_finalized_block(&block.parent_block_hash)
974
2
        });
975
2
        if let Some(
block0
) = block_to_verify {
976
0
            return ProcessOne::BlockVerify(BlockVerify {
977
0
                parent: self,
978
0
                block_to_verify: block,
979
0
            });
980
2
        }
981
2
982
2
        // Try to find a justification to verify.
983
2
        // TODO: O(n)
984
2
        let source_id_with_finality_proof = self
985
2
            .inner
986
2
            .blocks
987
2
            .sources()
988
2
            .find(|id| !self.inner.blocks[*id].unverified_finality_proofs.is_none());
989
2
        if let Some(
source_id_with_finality_proof0
) = source_id_with_finality_proof {
990
0
            let finality_proof_to_verify = self.inner.blocks[source_id_with_finality_proof]
991
0
                .unverified_finality_proofs
992
0
                .take_one()
993
0
                .unwrap(); // `take()` always returns `Some` because we've checked `is_none()` above
994
0
            return ProcessOne::FinalityProofVerify(FinalityProofVerify {
995
0
                parent: self,
996
0
                source_id: source_id_with_finality_proof,
997
0
                finality_proof_to_verify,
998
0
            });
999
2
        }
1000
2
1001
2
        ProcessOne::AllSync { sync: self }
1002
2
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE11process_oneCscDgN54JpMGG_6author
_RNvMs_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB4_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB6_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE11process_oneCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
964
19
    pub fn process_one(mut self) -> ProcessOne<TBl, TRq, TSrc> {
965
19
        // Try to find a block to verify.
966
19
        // All blocks are always verified before verifying justifications, in order to guarantee
967
19
        // that the block that a justification targets has already been verified.
968
19
        // TODO: revisit that ^ as advancing finality should have priority over advancing the chain
969
19
        let block_to_verify = self.inner.blocks.unverified_leaves().find(|block| {
970
            block.parent_block_hash == *self.chain.finalized_block_hash()
971
                || self
972
                    .chain
973
                    .contains_non_finalized_block(&block.parent_block_hash)
974
19
        });
975
19
        if let Some(
block0
) = block_to_verify {
976
0
            return ProcessOne::BlockVerify(BlockVerify {
977
0
                parent: self,
978
0
                block_to_verify: block,
979
0
            });
980
19
        }
981
19
982
19
        // Try to find a justification to verify.
983
19
        // TODO: O(n)
984
19
        let source_id_with_finality_proof = self
985
19
            .inner
986
19
            .blocks
987
19
            .sources()
988
19
            .find(|id| !self.inner.blocks[*id].unverified_finality_proofs.is_none());
989
19
        if let Some(
source_id_with_finality_proof0
) = source_id_with_finality_proof {
990
0
            let finality_proof_to_verify = self.inner.blocks[source_id_with_finality_proof]
991
0
                .unverified_finality_proofs
992
0
                .take_one()
993
0
                .unwrap(); // `take()` always returns `Some` because we've checked `is_none()` above
994
0
            return ProcessOne::FinalityProofVerify(FinalityProofVerify {
995
0
                parent: self,
996
0
                source_id: source_id_with_finality_proof,
997
0
                finality_proof_to_verify,
998
0
            });
999
19
        }
1000
19
1001
19
        ProcessOne::AllSync { sync: self }
1002
19
    }
1003
}
1004
1005
impl<TBl, TRq, TSrc> ops::Index<SourceId> for AllForksSync<TBl, TRq, TSrc> {
1006
    type Output = TSrc;
1007
1008
    #[track_caller]
1009
0
    fn index(&self, id: SourceId) -> &TSrc {
1010
0
        &self.inner.blocks[id].user_data
1011
0
    }
Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4sync9all_forkss0_0pppEINtB5_12AllForksSyncpppEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexNtNtB5_7sources8SourceIdE5indexB9_
Unexecuted instantiation: _RNvXs0_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1K_19AllForksSourceExtraEINtNtNtB19_3ops5index5IndexNtNtB5_7sources8SourceIdE5indexCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4sync9all_forkss0_0pppEINtB5_12AllForksSyncpppEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexNtNtB5_7sources8SourceIdE5indexB9_
Unexecuted instantiation: _RNvXs0_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index5IndexNtNtB5_7sources8SourceIdE5indexCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvXs0_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index5IndexNtNtB5_7sources8SourceIdE5indexCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvXs0_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index5IndexNtNtB5_7sources8SourceIdE5indexCsibGXYHQB8Ea_25json_rpc_general_requests
1012
}
1013
1014
impl<TBl, TRq, TSrc> ops::IndexMut<SourceId> for AllForksSync<TBl, TRq, TSrc> {
1015
    #[track_caller]
1016
0
    fn index_mut(&mut self, id: SourceId) -> &mut TSrc {
1017
0
        &mut self.inner.blocks[id].user_data
1018
0
    }
Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4sync9all_forkss1_0pppEINtB5_12AllForksSyncpppEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutNtNtB5_7sources8SourceIdE9index_mutB9_
Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4sync9all_forkss1_0pppEINtB5_12AllForksSyncpppEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutNtNtB5_7sources8SourceIdE9index_mutB9_
1019
}
1020
1021
impl<'a, TBl, TRq, TSrc> ops::Index<(u64, &'a [u8; 32])> for AllForksSync<TBl, TRq, TSrc> {
1022
    type Output = TBl;
1023
1024
    #[track_caller]
1025
0
    fn index(&self, (block_height, block_hash): (u64, &'a [u8; 32])) -> &TBl {
1026
0
        if let Some(block) = self.chain.non_finalized_block_user_data(block_hash) {
1027
0
            return block;
1028
0
        }
1029
0
1030
0
        &self
1031
0
            .inner
1032
0
            .blocks
1033
0
            .unverified_block_user_data(block_height, block_hash)
1034
0
            .user_data
1035
0
    }
Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4sync9all_forkss2_0pppEINtB5_12AllForksSyncpppEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexTyRAhj20_EE5indexB9_
Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4sync9all_forkss2_0pppEINtB5_12AllForksSyncpppEINtNtNtCsaYZPK01V26L_4core3ops5index5IndexTyRAhj20_EE5indexB9_
Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index5IndexTyRAhj20_EE5indexCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index5IndexTyRAhj20_EE5indexCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvXs2_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index5IndexTyRAhj20_EE5indexCsibGXYHQB8Ea_25json_rpc_general_requests
1036
}
1037
1038
impl<'a, TBl, TRq, TSrc> ops::IndexMut<(u64, &'a [u8; 32])> for AllForksSync<TBl, TRq, TSrc> {
1039
    #[track_caller]
1040
0
    fn index_mut(&mut self, (block_height, block_hash): (u64, &'a [u8; 32])) -> &mut TBl {
1041
0
        if let Some(block) = self.chain.non_finalized_block_user_data_mut(block_hash) {
1042
0
            return block;
1043
0
        }
1044
0
1045
0
        &mut self
1046
0
            .inner
1047
0
            .blocks
1048
0
            .unverified_block_user_data_mut(block_height, block_hash)
1049
0
            .user_data
1050
0
    }
Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4sync9all_forkss3_0pppEINtB5_12AllForksSyncpppEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutTyRAhj20_EE9index_mutB9_
Unexecuted instantiation: _RNvXs3_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1K_19AllForksSourceExtraEINtNtNtB19_3ops5index8IndexMutTyRAhj20_EE9index_mutCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4sync9all_forkss3_0pppEINtB5_12AllForksSyncpppEINtNtNtCsaYZPK01V26L_4core3ops5index8IndexMutTyRAhj20_EE9index_mutB9_
Unexecuted instantiation: _RNvXs3_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index8IndexMutTyRAhj20_EE9index_mutCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvXs3_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index8IndexMutTyRAhj20_EE9index_mutCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvXs3_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_12AllForksSyncINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2W_19AllForksSourceExtraEINtNtNtB19_3ops5index8IndexMutTyRAhj20_EE9index_mutCsibGXYHQB8Ea_25json_rpc_general_requests
1051
}
1052
1053
/// See [`AllForksSync::finish_request`].
1054
pub struct FinishRequest<'a, TBl, TRq, TSrc> {
1055
    inner: &'a mut AllForksSync<TBl, TRq, TSrc>,
1056
1057
    /// Source that has sent the request that is being answered.
1058
    source_id: SourceId,
1059
1060
    /// Set to true if any block at all have been added.
1061
    any_progress: bool,
1062
1063
    /// Number of blocks added before through that data structure.
1064
    index_in_response: usize,
1065
1066
    /// Hash of the block that was initially request.
1067
    requested_block_hash: [u8; 32],
1068
    /// Height of the block that was initially request.
1069
    requested_block_height: u64,
1070
1071
    /// The next block to add should have a hash equal to this one.
1072
    expected_next_hash: [u8; 32],
1073
    /// The next block to add should have a height equal to this one.
1074
    expected_next_height: u64,
1075
}
1076
1077
impl<'a, TBl, TRq, TSrc> FinishRequest<'a, TBl, TRq, TSrc> {
1078
    /// Adds a block coming from the response that the source has provided.
1079
    ///
1080
    /// On success, the [`FinishRequest`] is turned into an [`AddBlock`]. The block is
1081
    /// inserted in the state machine only after one of the methods in [`AddBlock`] is added.
1082
    ///
1083
    /// If an error is returned, the [`FinishRequest`] is turned back again into a
1084
    /// [`AllForksSync`], but all the blocks that have already been added are retained.
1085
    ///
1086
    /// If [`Config::download_bodies`] was `false`, the content of `scale_encoded_extrinsics`
1087
    /// is ignored.
1088
0
    pub fn add_block(
1089
0
        mut self,
1090
0
        scale_encoded_header: Vec<u8>,
1091
0
        scale_encoded_extrinsics: Vec<Vec<u8>>,
1092
0
        scale_encoded_justifications: impl Iterator<Item = ([u8; 4], impl AsRef<[u8]>)>,
1093
0
    ) -> Result<AddBlock<'a, TBl, TRq, TSrc>, AncestrySearchResponseError> {
1094
0
        // Compare expected with actual hash.
1095
0
        // This ensure that each header being processed is the parent of the previous one.
1096
0
        if self.expected_next_hash != header::hash_from_scale_encoded_header(&scale_encoded_header)
1097
        {
1098
0
            return Err(AncestrySearchResponseError::UnexpectedBlock);
1099
0
        }
1100
1101
        // Invalid headers are erroneous.
1102
0
        let decoded_header =
1103
0
            match header::decode(&scale_encoded_header, self.inner.chain.block_number_bytes()) {
1104
0
                Ok(h) => h,
1105
0
                Err(err) => return Err(AncestrySearchResponseError::InvalidHeader(err)),
1106
            };
1107
1108
        // Also compare the block numbers.
1109
        // The utility of checking the height (even though we've already checked the hash) is
1110
        // questionable, but considering that blocks are identified with their combination of
1111
        // hash and number, checking both the hash and number might prevent malicious sources
1112
        // from introducing state inconsistenties, even though it's unclear how that could happen.
1113
0
        if self.expected_next_height != decoded_header.number {
1114
0
            return Err(AncestrySearchResponseError::UnexpectedBlock);
1115
0
        }
1116
0
1117
0
        // Check whether the SCALE-encoded extrinsics match the extrinsics root found in
1118
0
        // the header.
1119
0
        if self.inner.inner.blocks.downloading_bodies() {
1120
0
            let calculated = header::extrinsics_root(&scale_encoded_extrinsics);
1121
0
            if calculated != *decoded_header.extrinsics_root {
1122
0
                return Err(AncestrySearchResponseError::ExtrinsicsRootMismatch);
1123
0
            }
1124
0
        }
1125
1126
        // At this point, the source has given us correct blocks, and we consider the response
1127
        // as a whole to be useful.
1128
0
        self.any_progress = true;
1129
0
1130
0
        // It is assumed that all sources will eventually agree on the same finalized chain. If
1131
0
        // the block number is lower or equal than the locally-finalized block number, it is
1132
0
        // assumed that this source is simply late compared to the local node, and that the block
1133
0
        // that has been received is either part of the finalized chain or belongs to a fork that
1134
0
        // will get discarded by this source in the future.
1135
0
        if decoded_header.number <= self.inner.chain.finalized_block_height() {
1136
0
            return Err(AncestrySearchResponseError::TooOld);
1137
0
        }
1138
0
1139
0
        // Convert the justifications in an "owned" format, because we're likely going to store
1140
0
        // them.
1141
0
        let justifications = scale_encoded_justifications
1142
0
            .map(|(e, j)| (e, j.as_ref().to_owned()))
Unexecuted instantiation: _RNCINvMs4_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB8_13FinishRequestpppE9add_blockppE0Bc_
Unexecuted instantiation: _RNCINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionuENtNtBa_3all20AllForksRequestExtraNtB1O_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1d_4iter8adapters3map3MapINtNtB2Y_9into_iter8IntoIterNtB1O_13JustificationENCINvMB1O_INtB1O_7AllSyncNtNtCsbAmNCxs6rLz_12futures_util9abortable11AbortHandleTNtNtNtBc_6libp2p7peer_id6PeerIdNtNtNtNtBc_7network5codec15block_announces4RoleEuE23blocks_request_responseINtNtB3z_10filter_map9FilterMapIB44_NtNtB6J_13block_request9BlockDataENCNCINvNtNtCsih6EgvAwZF2_13smoldot_light12sync_service10standalone22start_standalone_chainNtNtCsDDUKWWCHAU_18smoldot_light_wasm8platform11PlatformRefE0sn_0EE0EE0Baw_
Unexecuted instantiation: _RNCINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_13FinishRequestpppE9add_blockppE0Bc_
Unexecuted instantiation: _RNCINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1d_4iter8adapters3map3MapINtNtB4a_9into_iter8IntoIterNtB30_13JustificationENCINvMB30_INtB30_7AllSyncuIB19_NtB1M_17NetworkSourceInfoEB1K_E23blocks_request_responseIB4H_IB5g_NtNtNtNtBc_7network5codec13block_request9BlockDataENCNCNvMs_B1M_NtB1M_14SyncBackground3run0sc_0EE0EE0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1d_4iter8adapters3map3MapINtNtB4a_9into_iter8IntoIterNtB30_13JustificationENCINvMB30_INtB30_7AllSyncuIB19_NtB1M_17NetworkSourceInfoEB1K_E23blocks_request_responseINtNtNtB4N_7sources4once4OnceINtB30_24BlockRequestSuccessBlockB1K_EEE0EE0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1d_4iter8adapters3map3MapINtNtB4a_9into_iter8IntoIterNtB30_13JustificationENCINvMB30_INtB30_7AllSyncuIB19_NtB1M_17NetworkSourceInfoEB1K_E23blocks_request_responseIB4H_IB5g_NtNtNtNtBc_7network5codec13block_request9BlockDataENCNCNvMs_B1M_NtB1M_14SyncBackground3run0sc_0EE0EE0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1d_4iter8adapters3map3MapINtNtB4a_9into_iter8IntoIterNtB30_13JustificationENCINvMB30_INtB30_7AllSyncuIB19_NtB1M_17NetworkSourceInfoEB1K_E23blocks_request_responseINtNtNtB4N_7sources4once4OnceINtB30_24BlockRequestSuccessBlockB1K_EEE0EE0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1d_4iter8adapters3map3MapINtNtB4a_9into_iter8IntoIterNtB30_13JustificationENCINvMB30_INtB30_7AllSyncuIB19_NtB1M_17NetworkSourceInfoEB1K_E23blocks_request_responseIB4H_IB5g_NtNtNtNtBc_7network5codec13block_request9BlockDataENCNCNvMs_B1M_NtB1M_14SyncBackground3run0sc_0EE0EE0CsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RNCINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB8_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtBa_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1d_4iter8adapters3map3MapINtNtB4a_9into_iter8IntoIterNtB30_13JustificationENCINvMB30_INtB30_7AllSyncuIB19_NtB1M_17NetworkSourceInfoEB1K_E23blocks_request_responseINtNtNtB4N_7sources4once4OnceINtB30_24BlockRequestSuccessBlockB1K_EEE0EE0CsibGXYHQB8Ea_25json_rpc_general_requests
1143
0
            .collect::<Vec<_>>();
1144
0
1145
0
        // If the block is already part of the local tree of blocks, nothing more to do.
1146
0
        // Note that the block body is silently discarded, as in the API only non-verified blocks
1147
0
        // exhibit a body.
1148
0
        if self
1149
0
            .inner
1150
0
            .chain
1151
0
            .contains_non_finalized_block(&self.expected_next_hash)
1152
        {
1153
0
            if !justifications.is_empty() {
1154
0
                self.inner.inner.blocks[self.source_id]
1155
0
                    .unverified_finality_proofs
1156
0
                    .insert(
1157
0
                        decoded_header.number,
1158
0
                        FinalityProofs::Justifications(justifications),
1159
0
                    );
1160
0
            }
1161
1162
0
            return Ok(AddBlock::AlreadyInChain(AddBlockOccupied {
1163
0
                inner: self,
1164
0
                block_number: decoded_header.number,
1165
0
                block_parent_hash: *decoded_header.parent_hash,
1166
0
                block_header: scale_encoded_header,
1167
0
                is_verified: true,
1168
0
            }));
1169
0
        }
1170
0
1171
0
        // Block is not part of the finalized chain.
1172
0
        // TODO: also give possibility to update user data
1173
0
        if decoded_header.number == self.inner.chain.finalized_block_height() + 1
1174
0
            && *decoded_header.parent_hash != *self.inner.chain.finalized_block_hash()
1175
        {
1176
            // TODO: remove_verify_failed
1177
            // Block isn't part of the finalized chain.
1178
            // This doesn't necessarily mean that the source and the local node disagree
1179
            // on the finalized chain. It is possible that the finalized block has been
1180
            // updated between the moment the request was emitted and the moment the
1181
            // response is received.
1182
0
            let error = AncestrySearchResponseError::NotFinalizedChain {
1183
0
                discarded_unverified_block_headers: Vec::new(), // TODO: not properly implemented /!\
1184
0
            };
1185
0
            return Err(error);
1186
0
        }
1187
0
1188
0
        // At this point, we have excluded blocks that are already part of the chain or too old.
1189
0
        // We insert the block in the list of unverified blocks so as to treat all blocks the
1190
0
        // same.
1191
0
        if !self
1192
0
            .inner
1193
0
            .inner
1194
0
            .blocks
1195
0
            .contains_unverified_block(decoded_header.number, &self.expected_next_hash)
1196
        {
1197
0
            Ok(AddBlock::UnknownBlock(AddBlockVacant {
1198
0
                inner: self,
1199
0
                block_number: decoded_header.number,
1200
0
                block_parent_hash: *decoded_header.parent_hash,
1201
0
                block_header: scale_encoded_header,
1202
0
                scale_encoded_extrinsics,
1203
0
                justifications,
1204
0
            }))
1205
        } else {
1206
0
            if !justifications.is_empty() {
1207
0
                self.inner.inner.blocks[self.source_id]
1208
0
                    .unverified_finality_proofs
1209
0
                    .insert(
1210
0
                        decoded_header.number,
1211
0
                        FinalityProofs::Justifications(justifications),
1212
0
                    );
1213
0
            }
1214
1215
0
            if self.inner.inner.blocks.downloading_bodies() {
1216
0
                self.inner
1217
0
                    .inner
1218
0
                    .blocks
1219
0
                    .set_unverified_block_header_body_known(
1220
0
                        decoded_header.number,
1221
0
                        &self.expected_next_hash,
1222
0
                        *decoded_header.parent_hash,
1223
0
                    );
1224
0
                self.inner
1225
0
                    .inner
1226
0
                    .blocks
1227
0
                    .unverified_block_user_data_mut(decoded_header.number, &self.expected_next_hash)
1228
0
                    .body = Some(scale_encoded_extrinsics);
1229
0
            }
1230
1231
0
            Ok(AddBlock::AlreadyPending(AddBlockOccupied {
1232
0
                inner: self,
1233
0
                block_number: decoded_header.number,
1234
0
                block_parent_hash: *decoded_header.parent_hash,
1235
0
                block_header: scale_encoded_header,
1236
0
                is_verified: false,
1237
0
            }))
1238
        }
1239
0
    }
Unexecuted instantiation: _RINvMs4_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB6_13FinishRequestpppE9add_blockppEBa_
Unexecuted instantiation: _RINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB8_3all20AllForksRequestExtraNtB1M_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1b_4iter8adapters3map3MapINtNtB2W_9into_iter8IntoIterNtB1M_13JustificationENCINvMB1M_INtB1M_7AllSyncNtNtCsbAmNCxs6rLz_12futures_util9abortable11AbortHandleTNtNtNtBa_6libp2p7peer_id6PeerIdNtNtNtNtBa_7network5codec15block_announces4RoleEuE23blocks_request_responseINtNtB3x_10filter_map9FilterMapIB42_NtNtB6H_13block_request9BlockDataENCNCINvNtNtCsih6EgvAwZF2_13smoldot_light12sync_service10standalone22start_standalone_chainNtNtCsDDUKWWCHAU_18smoldot_light_wasm8platform11PlatformRefE0sn_0EE0EEBau_
Unexecuted instantiation: _RINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_13FinishRequestpppE9add_blockppEBa_
Unexecuted instantiation: _RINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1b_4iter8adapters3map3MapINtNtB48_9into_iter8IntoIterNtB2Y_13JustificationENCINvMB2Y_INtB2Y_7AllSyncuIB17_NtB1K_17NetworkSourceInfoEB1I_E23blocks_request_responseIB4F_IB5e_NtNtNtNtBa_7network5codec13block_request9BlockDataENCNCNvMs_B1K_NtB1K_14SyncBackground3run0sc_0EE0EECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1b_4iter8adapters3map3MapINtNtB48_9into_iter8IntoIterNtB2Y_13JustificationENCINvMB2Y_INtB2Y_7AllSyncuIB17_NtB1K_17NetworkSourceInfoEB1I_E23blocks_request_responseINtNtNtB4L_7sources4once4OnceINtB2Y_24BlockRequestSuccessBlockB1I_EEE0EECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1b_4iter8adapters3map3MapINtNtB48_9into_iter8IntoIterNtB2Y_13JustificationENCINvMB2Y_INtB2Y_7AllSyncuIB17_NtB1K_17NetworkSourceInfoEB1I_E23blocks_request_responseIB4F_IB5e_NtNtNtNtBa_7network5codec13block_request9BlockDataENCNCNvMs_B1K_NtB1K_14SyncBackground3run0sc_0EE0EECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1b_4iter8adapters3map3MapINtNtB48_9into_iter8IntoIterNtB2Y_13JustificationENCINvMB2Y_INtB2Y_7AllSyncuIB17_NtB1K_17NetworkSourceInfoEB1I_E23blocks_request_responseINtNtNtB4L_7sources4once4OnceINtB2Y_24BlockRequestSuccessBlockB1I_EEE0EECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1b_4iter8adapters3map3MapINtNtB48_9into_iter8IntoIterNtB2Y_13JustificationENCINvMB2Y_INtB2Y_7AllSyncuIB17_NtB1K_17NetworkSourceInfoEB1I_E23blocks_request_responseIB4F_IB5e_NtNtNtNtBa_7network5codec13block_request9BlockDataENCNCNvMs_B1K_NtB1K_14SyncBackground3run0sc_0EE0EECsibGXYHQB8Ea_25json_rpc_general_requests
Unexecuted instantiation: _RINvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB6_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB8_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE9add_blockINtNtCsdZExvAaxgia_5alloc3vec3VechEINtNtNtNtB1b_4iter8adapters3map3MapINtNtB48_9into_iter8IntoIterNtB2Y_13JustificationENCINvMB2Y_INtB2Y_7AllSyncuIB17_NtB1K_17NetworkSourceInfoEB1I_E23blocks_request_responseINtNtNtB4L_7sources4once4OnceINtB2Y_24BlockRequestSuccessBlockB1I_EEE0EECsibGXYHQB8Ea_25json_rpc_general_requests
1240
1241
    /// Notifies of the end of the response, and returns back the [`AllForksSync`].
1242
    ///
1243
    /// It is legal to insert fewer blocks than the number of blocks that were requested through
1244
    /// [`RequestParams::num_blocks`].
1245
    /// However, if no block has been added at all (i.e. the response is empty), then the source
1246
    /// of the request is marked as bad.
1247
    ///
1248
    /// > **Note**: Network protocols have a limit to the size of their response, meaning that all
1249
    /// >           the requested blocks might not fit in a single response. For this reason, it
1250
    /// >           is legal for a response to be shorter than expected.
1251
0
    pub fn finish(self) {
1252
0
        drop(self);
1253
0
    }
Unexecuted instantiation: _RNvMs4_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_13FinishRequestpppE6finishB9_
Unexecuted instantiation: _RNvMs4_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_13FinishRequestpppE6finishB9_
1254
}
1255
1256
impl<'a, TBl, TRq, TSrc> Drop for FinishRequest<'a, TBl, TRq, TSrc> {
1257
0
    fn drop(&mut self) {
1258
0
        // If this is reached, then none of the blocks the source has sent back were useful.
1259
0
        if !self.any_progress {
1260
0
            // Assume that the source doesn't know this block, as it is apparently unable to
1261
0
            // serve it anyway. This avoids sending the same request to the same source over and
1262
0
            // over again.
1263
0
            self.inner.inner.blocks.remove_known_block_of_source(
1264
0
                self.source_id,
1265
0
                self.requested_block_height,
1266
0
                &self.requested_block_hash,
1267
0
            );
1268
0
        }
1269
0
    }
Unexecuted instantiation: _RNvXININtNtCsN16ciHI6Qf_7smoldot4sync9all_forkss5_0pppEINtB5_13FinishRequestpppENtNtNtCsaYZPK01V26L_4core3ops4drop4Drop4dropB9_
Unexecuted instantiation: _RNvXs5_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1L_19AllForksSourceExtraENtNtNtB1a_3ops4drop4Drop4dropCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvXININtNtCseuYC0Zibziv_7smoldot4sync9all_forkss5_0pppEINtB5_13FinishRequestpppENtNtNtCsaYZPK01V26L_4core3ops4drop4Drop4dropB9_
Unexecuted instantiation: _RNvXs5_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraENtNtNtB1a_3ops4drop4Drop4dropCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvXs5_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraENtNtNtB1a_3ops4drop4Drop4dropCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvXs5_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_13FinishRequestINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2X_19AllForksSourceExtraENtNtNtB1a_3ops4drop4Drop4dropCsibGXYHQB8Ea_25json_rpc_general_requests
1270
}
1271
1272
/// Result of calling [`FinishRequest::add_block`].
1273
pub enum AddBlock<'a, TBl, TRq, TSrc> {
1274
    /// The block is already in the list of unverified blocks.
1275
    AlreadyPending(AddBlockOccupied<'a, TBl, TRq, TSrc>),
1276
1277
    /// The block hasn't been heard of before.
1278
    UnknownBlock(AddBlockVacant<'a, TBl, TRq, TSrc>),
1279
1280
    /// The block is already in the list of verified blocks.
1281
    ///
1282
    /// This can happen for example if a block announce or different ancestry search response has
1283
    /// been processed in between the request and response.
1284
    AlreadyInChain(AddBlockOccupied<'a, TBl, TRq, TSrc>),
1285
}
1286
1287
/// See [`FinishRequest::add_block`] and [`AddBlock`].
1288
pub struct AddBlockOccupied<'a, TBl, TRq, TSrc> {
1289
    inner: FinishRequest<'a, TBl, TRq, TSrc>,
1290
    block_header: Vec<u8>,
1291
    block_number: u64,
1292
    block_parent_hash: [u8; 32],
1293
    is_verified: bool,
1294
}
1295
1296
impl<'a, TBl, TRq, TSrc> AddBlockOccupied<'a, TBl, TRq, TSrc> {
1297
    /// Gives access to the user data of the block.
1298
0
    pub fn user_data_mut(&mut self) -> &mut TBl {
1299
0
        if self.is_verified {
1300
0
            &mut self.inner.inner.chain[&self.inner.expected_next_hash]
1301
        } else {
1302
0
            &mut self
1303
0
                .inner
1304
0
                .inner
1305
0
                .inner
1306
0
                .blocks
1307
0
                .unverified_block_user_data_mut(self.block_number, &self.inner.expected_next_hash)
1308
0
                .user_data
1309
        }
1310
0
    }
Unexecuted instantiation: _RNvMs6_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_16AddBlockOccupiedpppE13user_data_mutB9_
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddBlockOccupiedpppE13user_data_mutB9_
1311
1312
    /// Replace the existing user data of the block.
1313
    ///
1314
    /// Returns an object that allows continuing inserting blocks, plus the former user data that
1315
    /// was overwritten by the new one.
1316
0
    pub fn replace(mut self, user_data: TBl) -> (FinishRequest<'a, TBl, TRq, TSrc>, TBl) {
1317
0
        // Update the view the state machine maintains for this source.
1318
0
        self.inner.inner.inner.blocks.add_known_block_to_source(
1319
0
            self.inner.source_id,
1320
0
            self.block_number,
1321
0
            self.inner.expected_next_hash,
1322
0
        );
1323
0
1324
0
        // Source also knows the parent of the announced block.
1325
0
        // TODO: do this for the entire chain of blocks if it is known locally?
1326
0
        self.inner.inner.inner.blocks.add_known_block_to_source(
1327
0
            self.inner.source_id,
1328
0
            self.block_number - 1,
1329
0
            self.block_parent_hash,
1330
0
        );
1331
1332
0
        let former_user_data = if self.is_verified {
1333
0
            mem::replace(
1334
0
                &mut self.inner.inner.chain[&self.inner.expected_next_hash],
1335
0
                user_data,
1336
0
            )
1337
        } else {
1338
0
            self.inner
1339
0
                .inner
1340
0
                .inner
1341
0
                .blocks
1342
0
                .set_unverified_block_header_known(
1343
0
                    self.block_number,
1344
0
                    &self.inner.expected_next_hash,
1345
0
                    self.block_parent_hash,
1346
0
                );
1347
0
1348
0
            let block_user_data = self
1349
0
                .inner
1350
0
                .inner
1351
0
                .inner
1352
0
                .blocks
1353
0
                .unverified_block_user_data_mut(self.block_number, &self.inner.expected_next_hash);
1354
0
            if block_user_data.header.is_none() {
1355
0
                block_user_data.header = Some(self.block_header);
1356
0
                // TODO: copying bytes :-/
1357
0
            }
1358
1359
0
            mem::replace(&mut block_user_data.user_data, user_data)
1360
        };
1361
1362
        // Update the state machine for the next iteration.
1363
        // Note: this can't be reached if `expected_next_height` is 0, because that should have
1364
        // resulted either in `NotFinalizedChain` or `AlreadyInChain`, both of which return early.
1365
0
        self.inner.expected_next_hash = self.block_parent_hash;
1366
0
        self.inner.expected_next_height -= 1;
1367
0
        self.inner.index_in_response += 1;
1368
0
        (self.inner, former_user_data)
1369
0
    }
Unexecuted instantiation: _RNvMs6_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_16AddBlockOccupiedpppE7replaceB9_
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddBlockOccupiedINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1O_19AllForksSourceExtraE7replaceCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddBlockOccupiedpppE7replaceB9_
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddBlockOccupiedINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE7replaceCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddBlockOccupiedINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE7replaceCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs6_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddBlockOccupiedINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE7replaceCsibGXYHQB8Ea_25json_rpc_general_requests
1370
}
1371
1372
/// See [`FinishRequest::add_block`] and [`AddBlock`].
1373
pub struct AddBlockVacant<'a, TBl, TRq, TSrc> {
1374
    inner: FinishRequest<'a, TBl, TRq, TSrc>,
1375
    block_header: Vec<u8>,
1376
    block_number: u64,
1377
    block_parent_hash: [u8; 32],
1378
    justifications: Vec<([u8; 4], Vec<u8>)>,
1379
    scale_encoded_extrinsics: Vec<Vec<u8>>,
1380
}
1381
1382
impl<'a, TBl, TRq, TSrc> AddBlockVacant<'a, TBl, TRq, TSrc> {
1383
    /// Insert the block in the state machine, with the given user data.
1384
0
    pub fn insert(mut self, user_data: TBl) -> FinishRequest<'a, TBl, TRq, TSrc> {
1385
0
        // Update the view the state machine maintains for this source.
1386
0
        self.inner.inner.inner.blocks.add_known_block_to_source(
1387
0
            self.inner.source_id,
1388
0
            self.block_number,
1389
0
            self.inner.expected_next_hash,
1390
0
        );
1391
0
1392
0
        // Source also knows the parent of the announced block.
1393
0
        // TODO: do this for the entire chain of blocks if it is known locally?
1394
0
        self.inner.inner.inner.blocks.add_known_block_to_source(
1395
0
            self.inner.source_id,
1396
0
            self.block_number - 1,
1397
0
            self.block_parent_hash,
1398
0
        );
1399
0
1400
0
        self.inner.inner.inner.blocks.insert_unverified_block(
1401
0
            self.block_number,
1402
0
            self.inner.expected_next_hash,
1403
0
            if self.inner.inner.inner.blocks.downloading_bodies() {
1404
0
                pending_blocks::UnverifiedBlockState::HeaderBody {
1405
0
                    parent_hash: self.block_parent_hash,
1406
0
                }
1407
            } else {
1408
0
                pending_blocks::UnverifiedBlockState::Header {
1409
0
                    parent_hash: self.block_parent_hash,
1410
0
                }
1411
            },
1412
0
            PendingBlock {
1413
0
                header: Some(self.block_header),
1414
0
                body: Some(self.scale_encoded_extrinsics),
1415
0
                user_data,
1416
0
            },
1417
0
        );
1418
0
1419
0
        if !self.justifications.is_empty() {
1420
0
            self.inner.inner.inner.blocks[self.inner.source_id]
1421
0
                .unverified_finality_proofs
1422
0
                .insert(
1423
0
                    self.block_number,
1424
0
                    FinalityProofs::Justifications(self.justifications),
1425
0
                );
1426
0
        }
1427
1428
        // If there are too many blocks stored in the blocks list, remove unnecessary ones.
1429
        // Not doing this could lead to an explosion of the size of the collections.
1430
        // TODO: removing blocks should only be done explicitly through an API endpoint, because we want to store user datas in unverified blocks too; see https://github.com/paritytech/smoldot/issues/1572
1431
0
        while self.inner.inner.inner.blocks.num_unverified_blocks() >= 100 {
1432
0
            // TODO: arbitrary constant
1433
0
            let (height, hash) = match self
1434
0
                .inner
1435
0
                .inner
1436
0
                .inner
1437
0
                .blocks
1438
0
                .unnecessary_unverified_blocks()
1439
0
                .next()
1440
            {
1441
0
                Some((n, h)) => (n, *h),
1442
0
                None => break,
1443
            };
1444
1445
            // TODO: restore this block of code; it is extremely complicated because it is unclear which source-block combinations we can add and keep without making memory usage explode
1446
            /*self.inner
1447
            .inner
1448
            .inner
1449
            .blocks
1450
            .remove_sources_known_block(height, &hash);*/
1451
0
            self.inner
1452
0
                .inner
1453
0
                .inner
1454
0
                .blocks
1455
0
                .remove_unverified_block(height, &hash);
1456
        }
1457
1458
        // Update the state machine for the next iteration.
1459
        // Note: this can't be reached if `expected_next_height` is 0, because that should have
1460
        // resulted either in `NotFinalizedChain` or `AlreadyInChain`, both of which return early.
1461
0
        self.inner.expected_next_hash = self.block_parent_hash;
1462
0
        self.inner.expected_next_height -= 1;
1463
0
        self.inner.index_in_response += 1;
1464
0
        self.inner
1465
0
    }
Unexecuted instantiation: _RNvMs7_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_14AddBlockVacantpppE6insertB9_
Unexecuted instantiation: _RNvMs7_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddBlockVacantINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1M_19AllForksSourceExtraE6insertCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs7_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddBlockVacantpppE6insertB9_
Unexecuted instantiation: _RNvMs7_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddBlockVacantINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE6insertCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs7_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddBlockVacantINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE6insertCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs7_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddBlockVacantINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE6insertCsibGXYHQB8Ea_25json_rpc_general_requests
1466
}
1467
1468
/// Outcome of calling [`AllForksSync::block_announce`].
1469
pub enum BlockAnnounceOutcome<'a, TBl, TRq, TSrc> {
1470
    /// Announced block is too old to be part of the finalized chain.
1471
    ///
1472
    /// It is assumed that all sources will eventually agree on the same finalized chain. Blocks
1473
    /// whose height is inferior to the height of the latest known finalized block should simply
1474
    /// be ignored. Whether or not this old block is indeed part of the finalized block isn't
1475
    /// verified, and it is assumed that the source is simply late.
1476
    ///
1477
    /// If the announced block was the source's best block, the state machine has been updated to
1478
    /// take this information into account.
1479
    TooOld {
1480
        /// Height of the announced block.
1481
        announce_block_height: u64,
1482
        /// Height of the currently finalized block.
1483
        finalized_block_height: u64,
1484
    },
1485
1486
    /// Announced block has already been successfully verified and is part of the non-finalized
1487
    /// chain.
1488
    AlreadyVerified(AnnouncedBlockKnown<'a, TBl, TRq, TSrc>),
1489
1490
    /// Announced block is already known by the state machine but hasn't been verified yet.
1491
    AlreadyPending(AnnouncedBlockKnown<'a, TBl, TRq, TSrc>),
1492
1493
    /// Announced block isn't in the state machine.
1494
    Unknown(AnnouncedBlockUnknown<'a, TBl, TRq, TSrc>),
1495
1496
    /// Failed to decode announce header.
1497
    InvalidHeader(header::Error),
1498
}
1499
1500
/// See [`BlockAnnounceOutcome`] and [`AllForksSync::block_announce`].
1501
#[must_use]
1502
pub struct AnnouncedBlockKnown<'a, TBl, TRq, TSrc> {
1503
    inner: &'a mut AllForksSync<TBl, TRq, TSrc>,
1504
    announced_header_hash: [u8; 32],
1505
    announced_header_parent_hash: [u8; 32],
1506
    announced_header_number: u64,
1507
    announced_header_encoded: Vec<u8>,
1508
    is_in_chain: bool,
1509
    is_best: bool,
1510
    source_id: SourceId,
1511
}
1512
1513
impl<'a, TBl, TRq, TSrc> AnnouncedBlockKnown<'a, TBl, TRq, TSrc> {
1514
    /// Returns the parent hash of the announced block.
1515
0
    pub fn parent_hash(&self) -> &[u8; 32] {
1516
0
        &self.announced_header_parent_hash
1517
0
    }
Unexecuted instantiation: _RNvMs8_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE11parent_hashB9_
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1R_19AllForksSourceExtraE11parent_hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE11parent_hashB9_
1518
1519
    /// Returns the height of the announced block.
1520
0
    pub fn height(&self) -> u64 {
1521
0
        self.announced_header_number
1522
0
    }
Unexecuted instantiation: _RNvMs8_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE6heightB9_
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1R_19AllForksSourceExtraE6heightCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE6heightB9_
1523
1524
    /// Returns the hash of the announced block.
1525
0
    pub fn hash(&self) -> &[u8; 32] {
1526
0
        &self.announced_header_hash
1527
0
    }
Unexecuted instantiation: _RNvMs8_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE4hashB9_
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1R_19AllForksSourceExtraE4hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE4hashB9_
1528
1529
    /// Gives access to the user data of the block.
1530
0
    pub fn user_data_mut(&mut self) -> &mut TBl {
1531
0
        if self.is_in_chain {
1532
0
            &mut self.inner.chain[&self.announced_header_hash]
1533
        } else {
1534
0
            &mut self
1535
0
                .inner
1536
0
                .inner
1537
0
                .blocks
1538
0
                .unverified_block_user_data_mut(
1539
0
                    self.announced_header_number,
1540
0
                    &self.announced_header_hash,
1541
0
                )
1542
0
                .user_data
1543
        }
1544
0
    }
Unexecuted instantiation: _RNvMs8_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE13user_data_mutB9_
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE13user_data_mutB9_
1545
1546
    /// Updates the state machine to keep track of the fact that this source knows this block.
1547
    /// If the announced block is the source's best block, also updates this information.
1548
0
    pub fn update_source_and_block(self) {
1549
0
        // No matter what is done below, start by updating the view the state machine maintains
1550
0
        // for this source.
1551
0
        if self.is_best {
1552
0
            self.inner
1553
0
                .inner
1554
0
                .blocks
1555
0
                .add_known_block_to_source_and_set_best(
1556
0
                    self.source_id,
1557
0
                    self.announced_header_number,
1558
0
                    self.announced_header_hash,
1559
0
                );
1560
0
        } else {
1561
0
            self.inner.inner.blocks.add_known_block_to_source(
1562
0
                self.source_id,
1563
0
                self.announced_header_number,
1564
0
                self.announced_header_hash,
1565
0
            );
1566
0
        }
1567
1568
        // Source also knows the parent of the announced block.
1569
0
        self.inner.inner.blocks.add_known_block_to_source(
1570
0
            self.source_id,
1571
0
            self.announced_header_number - 1,
1572
0
            self.announced_header_parent_hash,
1573
0
        );
1574
0
1575
0
        if !self.is_in_chain {
1576
0
            self.inner.inner.blocks.set_unverified_block_header_known(
1577
0
                self.announced_header_number,
1578
0
                &self.announced_header_hash,
1579
0
                self.announced_header_parent_hash,
1580
0
            );
1581
0
1582
0
            let block_user_data = self.inner.inner.blocks.unverified_block_user_data_mut(
1583
0
                self.announced_header_number,
1584
0
                &self.announced_header_hash,
1585
0
            );
1586
0
            if block_user_data.header.is_none() {
1587
0
                block_user_data.header = Some(self.announced_header_encoded);
1588
0
            }
1589
1590
            // Mark block as bad if it is not part of the finalized chain.
1591
            // This might not have been known before, as the header might not have been known.
1592
0
            if self.announced_header_number == self.inner.chain.finalized_block_height() + 1
1593
0
                && self.announced_header_parent_hash != *self.inner.chain.finalized_block_hash()
1594
0
            {
1595
0
                self.inner.inner.blocks.mark_unverified_block_as_bad(
1596
0
                    self.announced_header_number,
1597
0
                    &self.announced_header_hash,
1598
0
                );
1599
0
            }
1600
0
        }
1601
1602
        // TODO: if pending_blocks.num_blocks() > some_max { remove uninteresting block }
1603
0
    }
Unexecuted instantiation: _RNvMs8_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE23update_source_and_blockB9_
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1R_19AllForksSourceExtraE23update_source_and_blockCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownpppE23update_source_and_blockB9_
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE23update_source_and_blockCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE23update_source_and_blockCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs8_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19AnnouncedBlockKnownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE23update_source_and_blockCsibGXYHQB8Ea_25json_rpc_general_requests
1604
}
1605
1606
/// See [`BlockAnnounceOutcome`] and [`AllForksSync::block_announce`].
1607
#[must_use]
1608
pub struct AnnouncedBlockUnknown<'a, TBl, TRq, TSrc> {
1609
    inner: &'a mut AllForksSync<TBl, TRq, TSrc>,
1610
    announced_header_hash: [u8; 32],
1611
    announced_header_parent_hash: [u8; 32],
1612
    announced_header_number: u64,
1613
    announced_header_encoded: Vec<u8>,
1614
    is_best: bool,
1615
    source_id: SourceId,
1616
}
1617
1618
impl<'a, TBl, TRq, TSrc> AnnouncedBlockUnknown<'a, TBl, TRq, TSrc> {
1619
    /// Returns the parent hash of the announced block.
1620
0
    pub fn parent_hash(&self) -> &[u8; 32] {
1621
0
        &self.announced_header_parent_hash
1622
0
    }
Unexecuted instantiation: _RNvMs9_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownpppE11parent_hashB9_
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1T_19AllForksSourceExtraE11parent_hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownpppE11parent_hashB9_
1623
1624
    /// Returns the height of the announced block.
1625
0
    pub fn height(&self) -> u64 {
1626
0
        self.announced_header_number
1627
0
    }
Unexecuted instantiation: _RNvMs9_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownpppE6heightB9_
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1T_19AllForksSourceExtraE6heightCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownpppE6heightB9_
1628
1629
    /// Returns the hash of the announced block.
1630
0
    pub fn hash(&self) -> &[u8; 32] {
1631
0
        &self.announced_header_hash
1632
0
    }
Unexecuted instantiation: _RNvMs9_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownpppE4hashB9_
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1T_19AllForksSourceExtraE4hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownpppE4hashB9_
1633
1634
    /// Inserts the block in the state machine and keeps track of the fact that this source knows
1635
    /// this block.
1636
    ///
1637
    /// If the announced block is the source's best block, also updates this information.
1638
0
    pub fn insert_and_update_source(self, user_data: TBl) {
1639
0
        // No matter what is done below, start by updating the view the state machine maintains
1640
0
        // for this source.
1641
0
        if self.is_best {
1642
0
            self.inner
1643
0
                .inner
1644
0
                .blocks
1645
0
                .add_known_block_to_source_and_set_best(
1646
0
                    self.source_id,
1647
0
                    self.announced_header_number,
1648
0
                    self.announced_header_hash,
1649
0
                );
1650
0
        } else {
1651
0
            self.inner.inner.blocks.add_known_block_to_source(
1652
0
                self.source_id,
1653
0
                self.announced_header_number,
1654
0
                self.announced_header_hash,
1655
0
            );
1656
0
        }
1657
1658
        // Source also knows the parent of the announced block.
1659
0
        self.inner.inner.blocks.add_known_block_to_source(
1660
0
            self.source_id,
1661
0
            self.announced_header_number - 1,
1662
0
            self.announced_header_parent_hash,
1663
0
        );
1664
0
1665
0
        self.inner.inner.blocks.insert_unverified_block(
1666
0
            self.announced_header_number,
1667
0
            self.announced_header_hash,
1668
0
            pending_blocks::UnverifiedBlockState::Header {
1669
0
                parent_hash: self.announced_header_parent_hash,
1670
0
            },
1671
0
            PendingBlock {
1672
0
                header: Some(self.announced_header_encoded),
1673
0
                body: None,
1674
0
                user_data,
1675
0
            },
1676
0
        );
1677
1678
        // If there are too many blocks stored in the blocks list, remove unnecessary ones.
1679
        // Not doing this could lead to an explosion of the size of the collections.
1680
        // TODO: removing blocks should only be done explicitly through an API endpoint, because we want to store user datas in unverified blocks too; see https://github.com/paritytech/smoldot/issues/1572
1681
0
        while self.inner.inner.blocks.num_unverified_blocks() >= 100 {
1682
0
            // TODO: arbitrary constant
1683
0
            let (height, hash) = match self
1684
0
                .inner
1685
0
                .inner
1686
0
                .blocks
1687
0
                .unnecessary_unverified_blocks()
1688
0
                .next()
1689
            {
1690
0
                Some((n, h)) => (n, *h),
1691
0
                None => break,
1692
            };
1693
1694
            // TODO: restore this block of code; it is extremely complicated because it is unclear which source-block combinations we can add and keep without making memory usage explode
1695
            /*self.inner
1696
            .inner
1697
            .blocks
1698
            .remove_sources_known_block(height, &hash);*/
1699
0
            self.inner
1700
0
                .inner
1701
0
                .blocks
1702
0
                .remove_unverified_block(height, &hash);
1703
        }
1704
1705
        // TODO: if pending_blocks.num_blocks() > some_max { remove uninteresting block }
1706
0
    }
Unexecuted instantiation: _RNvMs9_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownpppE24insert_and_update_sourceB9_
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1T_19AllForksSourceExtraE24insert_and_update_sourceCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownpppE24insert_and_update_sourceB9_
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB35_19AllForksSourceExtraE24insert_and_update_sourceCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB35_19AllForksSourceExtraE24insert_and_update_sourceCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMs9_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_21AnnouncedBlockUnknownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB35_19AllForksSourceExtraE24insert_and_update_sourceCsibGXYHQB8Ea_25json_rpc_general_requests
1707
}
1708
1709
/// Error when adding a block using [`FinishRequest::add_block`].
1710
pub enum AncestrySearchResponseError {
1711
    /// Failed to decode block header.
1712
    InvalidHeader(header::Error),
1713
1714
    /// Provided block isn't a block that we expect to be added.
1715
    ///
1716
    /// If this is the first block, then it doesn't correspond to the block that has been
1717
    /// requested. If this is not the first block, then it doesn't correspond to the parent of
1718
    /// the previous block that has been added.
1719
    UnexpectedBlock,
1720
1721
    /// List of SCALE-encoded extrinsics doesn't match the extrinsics root found in the header.
1722
    ///
1723
    /// This can only happen if [`Config::download_bodies`] was `true`.
1724
    ExtrinsicsRootMismatch,
1725
1726
    /// The block height is equal to the locally-known finalized block height, but its hash isn't
1727
    /// the same.
1728
    ///
1729
    /// This doesn't necessarily mean that the source is malicious or uses a different chain. It
1730
    /// is possible for this to legitimately happen, for example if the finalized chain has been
1731
    /// updated while the ancestry search was in progress.
1732
    NotFinalizedChain {
1733
        /// List of block headers that were pending verification and that have now been discarded
1734
        /// since it has been found out that they don't belong to the finalized chain.
1735
        discarded_unverified_block_headers: Vec<Vec<u8>>,
1736
    },
1737
1738
    /// Height of the block is below the height of the finalized block.
1739
    ///
1740
    /// Note that in most situation the previous block should have returned a
1741
    /// [`AncestrySearchResponseError::NotFinalizedChain`] as we notice that its height is equal
1742
    /// to the finalized block's height but hash is different.
1743
    /// However, a [`AncestrySearchResponseError::TooOld`] can still happen in some niche
1744
    /// situations, such as an update to the finalized block height above the first block of the
1745
    /// request.
1746
    TooOld,
1747
}
1748
1749
/// Outcome of calling [`AllForksSync::prepare_add_source`].
1750
#[must_use]
1751
pub enum AddSource<'a, TBl, TRq, TSrc> {
1752
    /// The best block of the source is older or equal to the local latest finalized block. This
1753
    /// block isn't tracked by the state machine.
1754
    OldBestBlock(AddSourceOldBlock<'a, TBl, TRq, TSrc>),
1755
1756
    /// The best block of the source has already been verified by this state machine.
1757
    BestBlockAlreadyVerified(AddSourceKnown<'a, TBl, TRq, TSrc>),
1758
1759
    /// The best block of the source is already known to this state machine but hasn't been
1760
    /// verified yet.
1761
    BestBlockPendingVerification(AddSourceKnown<'a, TBl, TRq, TSrc>),
1762
1763
    /// The best block of the source isn't in this state machine yet and needs to be inserted.
1764
    UnknownBestBlock(AddSourceUnknown<'a, TBl, TRq, TSrc>),
1765
}
1766
1767
/// See [`AddSource`] and [`AllForksSync::prepare_add_source`].
1768
#[must_use]
1769
pub struct AddSourceOldBlock<'a, TBl, TRq, TSrc> {
1770
    inner: &'a mut AllForksSync<TBl, TRq, TSrc>,
1771
    best_block_number: u64,
1772
    best_block_hash: [u8; 32],
1773
}
1774
1775
impl<'a, TBl, TRq, TSrc> AddSourceOldBlock<'a, TBl, TRq, TSrc> {
1776
    /// Inserts a new source in the state machine.
1777
    ///
1778
    /// Returns the newly-allocated identifier for that source.
1779
    ///
1780
    /// The `user_data` parameter is opaque and decided entirely by the user. It can later be
1781
    /// retrieved using the `Index` trait implementation of the [`AllForksSync`].
1782
21
    pub fn add_source(self, source_user_data: TSrc) -> SourceId {
1783
21
        self.inner.inner.blocks.add_source(
1784
21
            Source {
1785
21
                user_data: source_user_data,
1786
21
                unverified_finality_proofs: SourcePendingJustificationProofs::None,
1787
21
                finalized_block_number: 0,
1788
21
                pending_finality_proofs: SourcePendingJustificationProofs::None,
1789
21
            },
1790
21
            self.best_block_number,
1791
21
            self.best_block_hash,
1792
21
        )
1793
21
    }
Unexecuted instantiation: _RNvMsa_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_17AddSourceOldBlockpppE10add_sourceB9_
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_17AddSourceOldBlockINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1P_19AllForksSourceExtraE10add_sourceCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_17AddSourceOldBlockpppE10add_sourceB9_
_RNvMsa_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_17AddSourceOldBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB31_19AllForksSourceExtraE10add_sourceCsiLzmwikkc22_14json_rpc_basic
Line
Count
Source
1782
2
    pub fn add_source(self, source_user_data: TSrc) -> SourceId {
1783
2
        self.inner.inner.blocks.add_source(
1784
2
            Source {
1785
2
                user_data: source_user_data,
1786
2
                unverified_finality_proofs: SourcePendingJustificationProofs::None,
1787
2
                finalized_block_number: 0,
1788
2
                pending_finality_proofs: SourcePendingJustificationProofs::None,
1789
2
            },
1790
2
            self.best_block_number,
1791
2
            self.best_block_hash,
1792
2
        )
1793
2
    }
Unexecuted instantiation: _RNvMsa_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_17AddSourceOldBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB31_19AllForksSourceExtraE10add_sourceCscDgN54JpMGG_6author
_RNvMsa_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_17AddSourceOldBlockINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB31_19AllForksSourceExtraE10add_sourceCsibGXYHQB8Ea_25json_rpc_general_requests
Line
Count
Source
1782
19
    pub fn add_source(self, source_user_data: TSrc) -> SourceId {
1783
19
        self.inner.inner.blocks.add_source(
1784
19
            Source {
1785
19
                user_data: source_user_data,
1786
19
                unverified_finality_proofs: SourcePendingJustificationProofs::None,
1787
19
                finalized_block_number: 0,
1788
19
                pending_finality_proofs: SourcePendingJustificationProofs::None,
1789
19
            },
1790
19
            self.best_block_number,
1791
19
            self.best_block_hash,
1792
19
        )
1793
19
    }
1794
}
1795
1796
/// See [`AddSource`] and [`AllForksSync::prepare_add_source`].
1797
#[must_use]
1798
pub struct AddSourceKnown<'a, TBl, TRq, TSrc> {
1799
    inner: &'a mut AllForksSync<TBl, TRq, TSrc>,
1800
    best_block_number: u64,
1801
    best_block_hash: [u8; 32],
1802
}
1803
1804
impl<'a, TBl, TRq, TSrc> AddSourceKnown<'a, TBl, TRq, TSrc> {
1805
    /// Gives access to the user data of the block.
1806
0
    pub fn user_data_mut(&mut self) -> &mut TBl {
1807
0
        if let Some(block_access) = self
1808
0
            .inner
1809
0
            .chain
1810
0
            .non_finalized_block_user_data_mut(&self.best_block_hash)
1811
        {
1812
0
            block_access
1813
        } else {
1814
0
            &mut self
1815
0
                .inner
1816
0
                .inner
1817
0
                .blocks
1818
0
                .unverified_block_user_data_mut(self.best_block_number, &self.best_block_hash)
1819
0
                .user_data
1820
        }
1821
0
    }
Unexecuted instantiation: _RNvMsb_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_14AddSourceKnownpppE13user_data_mutB9_
Unexecuted instantiation: _RNvMsb_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddSourceKnownpppE13user_data_mutB9_
1822
1823
    /// Inserts a new source in the state machine.
1824
    ///
1825
    /// Returns the newly-allocated identifier for that source.
1826
    ///
1827
    /// The `user_data` parameter is opaque and decided entirely by the user. It can later be
1828
    /// retrieved using the `Index` trait implementation of the [`AllForksSync`].
1829
0
    pub fn add_source(self, source_user_data: TSrc) -> SourceId {
1830
0
        self.inner.inner.blocks.add_source(
1831
0
            Source {
1832
0
                user_data: source_user_data,
1833
0
                unverified_finality_proofs: SourcePendingJustificationProofs::None,
1834
0
                finalized_block_number: 0,
1835
0
                pending_finality_proofs: SourcePendingJustificationProofs::None,
1836
0
            },
1837
0
            self.best_block_number,
1838
0
            self.best_block_hash,
1839
0
        )
1840
0
    }
Unexecuted instantiation: _RNvMsb_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_14AddSourceKnownpppE10add_sourceB9_
Unexecuted instantiation: _RNvMsb_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddSourceKnownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1M_19AllForksSourceExtraE10add_sourceCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMsb_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddSourceKnownpppE10add_sourceB9_
Unexecuted instantiation: _RNvMsb_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddSourceKnownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE10add_sourceCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMsb_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddSourceKnownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE10add_sourceCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMsb_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_14AddSourceKnownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2Y_19AllForksSourceExtraE10add_sourceCsibGXYHQB8Ea_25json_rpc_general_requests
1841
}
1842
1843
/// See [`AddSource`] and [`AllForksSync::prepare_add_source`].
1844
#[must_use]
1845
pub struct AddSourceUnknown<'a, TBl, TRq, TSrc> {
1846
    inner: &'a mut AllForksSync<TBl, TRq, TSrc>,
1847
    best_block_number: u64,
1848
    best_block_hash: [u8; 32],
1849
}
1850
1851
impl<'a, TBl, TRq, TSrc> AddSourceUnknown<'a, TBl, TRq, TSrc> {
1852
    /// Inserts a new source in the state machine, plus the best block of that source.
1853
    ///
1854
    /// Returns the newly-allocated identifier for that source.
1855
    ///
1856
    /// The `source_user_data` parameter is opaque and decided entirely by the user. It can later
1857
    /// be retrieved using the `Index` trait implementation of the [`AllForksSync`].
1858
    ///
1859
    /// The `best_block_user_data` parameter is opaque and decided entirely by the user and is
1860
    /// associated with the best block of the newly-added source.
1861
0
    pub fn add_source_and_insert_block(
1862
0
        self,
1863
0
        source_user_data: TSrc,
1864
0
        best_block_user_data: TBl,
1865
0
    ) -> SourceId {
1866
0
        let source_id = self.inner.inner.blocks.add_source(
1867
0
            Source {
1868
0
                user_data: source_user_data,
1869
0
                unverified_finality_proofs: SourcePendingJustificationProofs::None,
1870
0
                finalized_block_number: 0,
1871
0
                pending_finality_proofs: SourcePendingJustificationProofs::None,
1872
0
            },
1873
0
            self.best_block_number,
1874
0
            self.best_block_hash,
1875
0
        );
1876
0
1877
0
        self.inner.inner.blocks.insert_unverified_block(
1878
0
            self.best_block_number,
1879
0
            self.best_block_hash,
1880
0
            pending_blocks::UnverifiedBlockState::HeightHash,
1881
0
            PendingBlock {
1882
0
                header: None,
1883
0
                body: None,
1884
0
                user_data: best_block_user_data,
1885
0
            },
1886
0
        );
1887
0
1888
0
        source_id
1889
0
    }
Unexecuted instantiation: _RNvMsc_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_16AddSourceUnknownpppE27add_source_and_insert_blockB9_
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddSourceUnknownINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1O_19AllForksSourceExtraE27add_source_and_insert_blockCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddSourceUnknownpppE27add_source_and_insert_blockB9_
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddSourceUnknownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE27add_source_and_insert_blockCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddSourceUnknownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE27add_source_and_insert_blockCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMsc_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_16AddSourceUnknownINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB30_19AllForksSourceExtraE27add_source_and_insert_blockCsibGXYHQB8Ea_25json_rpc_general_requests
1890
}
1891
1892
/// Block verification to be performed.
1893
///
1894
/// Internally holds the [`AllForksSync`].
1895
pub struct BlockVerify<TBl, TRq, TSrc> {
1896
    parent: AllForksSync<TBl, TRq, TSrc>,
1897
    /// Block that can be verified.
1898
    block_to_verify: pending_blocks::TreeRoot,
1899
}
1900
1901
impl<TBl, TRq, TSrc> BlockVerify<TBl, TRq, TSrc> {
1902
    /// Returns the hash of the block to be verified.
1903
0
    pub fn hash(&self) -> &[u8; 32] {
1904
0
        &self.block_to_verify.block_hash
1905
0
    }
Unexecuted instantiation: _RNvMsd_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_11BlockVerifypppE4hashB9_
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE4hashCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifypppE4hashB9_
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE4hashCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE4hashCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE4hashCsibGXYHQB8Ea_25json_rpc_general_requests
1906
1907
    /// Returns the list of SCALE-encoded extrinsics of the block to verify.
1908
    ///
1909
    /// This is `Some` if and only if [`Config::download_bodies`] is `true`
1910
0
    pub fn scale_encoded_extrinsics(
1911
0
        &'_ self,
1912
0
    ) -> Option<impl ExactSizeIterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_> {
1913
0
        if self.parent.inner.blocks.downloading_bodies() {
1914
0
            Some(
1915
0
                self.parent
1916
0
                    .inner
1917
0
                    .blocks
1918
0
                    .unverified_block_user_data(
1919
0
                        self.block_to_verify.block_number,
1920
0
                        &self.block_to_verify.block_hash,
1921
0
                    )
1922
0
                    .body
1923
0
                    .as_ref()
1924
0
                    // The block shouldn't have been proposed for verification if it doesn't
1925
0
                    // have its body available.
1926
0
                    .unwrap_or_else(|| unreachable!())
Unexecuted instantiation: _RNCNvMsd_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB7_11BlockVerifypppE24scale_encoded_extrinsics0Bb_
Unexecuted instantiation: _RNCNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB7_11BlockVerifypppE24scale_encoded_extrinsics0Bb_
1927
0
                    .iter(),
1928
0
            )
1929
        } else {
1930
0
            None
1931
        }
1932
0
    }
Unexecuted instantiation: _RNvMsd_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_11BlockVerifypppE24scale_encoded_extrinsicsB9_
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifypppE24scale_encoded_extrinsicsB9_
1933
1934
    /// Returns the SCALE-encoded header of the block about to be verified.
1935
0
    pub fn scale_encoded_header(&self) -> &[u8] {
1936
0
        self.parent
1937
0
            .inner
1938
0
            .blocks
1939
0
            .unverified_block_user_data(
1940
0
                self.block_to_verify.block_number,
1941
0
                &self.block_to_verify.block_hash,
1942
0
            )
1943
0
            .header
1944
0
            .as_ref()
1945
0
            .unwrap()
1946
0
    }
Unexecuted instantiation: _RNvMsd_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_11BlockVerifypppE20scale_encoded_headerB9_
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE20scale_encoded_headerCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifypppE20scale_encoded_headerB9_
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20scale_encoded_headerCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20scale_encoded_headerCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE20scale_encoded_headerCsibGXYHQB8Ea_25json_rpc_general_requests
1947
1948
    /// Perform the verification.
1949
0
    pub fn verify_header(
1950
0
        mut self,
1951
0
        now_from_unix_epoch: Duration,
1952
0
    ) -> HeaderVerifyOutcome<TBl, TRq, TSrc> {
1953
0
        let to_verify_scale_encoded_header = self.scale_encoded_header().to_owned(); // TODO: overhead
1954
1955
0
        let result = match self
1956
0
            .parent
1957
0
            .chain
1958
0
            .verify_header(to_verify_scale_encoded_header, now_from_unix_epoch)
1959
        {
1960
            Ok(blocks_tree::HeaderVerifySuccess::Verified {
1961
0
                verified_header,
1962
0
                is_new_best,
1963
0
            }) => {
1964
0
                // Block is valid!
1965
0
                Ok((verified_header, is_new_best))
1966
            }
1967
0
            Err(blocks_tree::HeaderVerifyError::VerificationFailed(error)) => {
1968
0
                // Remove the block from `pending_blocks`.
1969
0
                self.parent.inner.blocks.mark_unverified_block_as_bad(
1970
0
                    self.block_to_verify.block_number,
1971
0
                    &self.block_to_verify.block_hash,
1972
0
                );
1973
0
1974
0
                Err(HeaderVerifyError::VerificationFailed(error))
1975
            }
1976
            Err(blocks_tree::HeaderVerifyError::ConsensusMismatch) => {
1977
                // Remove the block from `pending_blocks`.
1978
0
                self.parent.inner.blocks.mark_unverified_block_as_bad(
1979
0
                    self.block_to_verify.block_number,
1980
0
                    &self.block_to_verify.block_hash,
1981
0
                );
1982
0
1983
0
                Err(HeaderVerifyError::ConsensusMismatch)
1984
            }
1985
            Err(blocks_tree::HeaderVerifyError::UnknownConsensusEngine) => {
1986
                // Remove the block from `pending_blocks`.
1987
0
                self.parent.inner.blocks.mark_unverified_block_as_bad(
1988
0
                    self.block_to_verify.block_number,
1989
0
                    &self.block_to_verify.block_hash,
1990
0
                );
1991
0
1992
0
                Err(HeaderVerifyError::UnknownConsensusEngine)
1993
            }
1994
            Ok(blocks_tree::HeaderVerifySuccess::Duplicate)
1995
            | Err(
1996
                blocks_tree::HeaderVerifyError::BadParent { .. }
1997
                | blocks_tree::HeaderVerifyError::InvalidHeader(_),
1998
0
            ) => unreachable!(),
1999
        };
2000
2001
0
        match result {
2002
0
            Ok((verified_header, is_new_best)) => HeaderVerifyOutcome::Success {
2003
0
                is_new_best,
2004
0
                success: HeaderVerifySuccess {
2005
0
                    parent: self.parent,
2006
0
                    block_to_verify: self.block_to_verify,
2007
0
                    verified_header,
2008
0
                },
2009
0
            },
2010
0
            Err(error) => HeaderVerifyOutcome::Error {
2011
0
                sync: self.parent,
2012
0
                error,
2013
0
            },
2014
        }
2015
0
    }
Unexecuted instantiation: _RNvMsd_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_11BlockVerifypppE13verify_headerB9_
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1J_19AllForksSourceExtraE13verify_headerCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifypppE13verify_headerB9_
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE13verify_headerCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE13verify_headerCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB2V_19AllForksSourceExtraE13verify_headerCsibGXYHQB8Ea_25json_rpc_general_requests
2016
2017
    /// Do not actually proceed with the verification.
2018
0
    pub fn cancel(self) -> AllForksSync<TBl, TRq, TSrc> {
2019
0
        self.parent
2020
0
    }
Unexecuted instantiation: _RNvMsd_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_11BlockVerifypppE6cancelB9_
Unexecuted instantiation: _RNvMsd_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_11BlockVerifypppE6cancelB9_
2021
}
2022
2023
/// Header verification successful.
2024
///
2025
/// Internally holds the [`AllForksSync`].
2026
pub struct HeaderVerifySuccess<TBl, TRq, TSrc> {
2027
    parent: AllForksSync<TBl, TRq, TSrc>,
2028
    block_to_verify: pending_blocks::TreeRoot,
2029
    verified_header: blocks_tree::VerifiedHeader,
2030
}
2031
2032
impl<TBl, TRq, TSrc> HeaderVerifySuccess<TBl, TRq, TSrc> {
2033
    /// Returns the height of the block that was verified.
2034
0
    pub fn height(&self) -> u64 {
2035
0
        self.block_to_verify.block_number
2036
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE6heightB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1R_19AllForksSourceExtraE6heightCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE6heightB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6heightCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6heightCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6heightCsibGXYHQB8Ea_25json_rpc_general_requests
2037
2038
    /// Returns the hash of the block that was verified.
2039
0
    pub fn hash(&self) -> &[u8; 32] {
2040
0
        &self.block_to_verify.block_hash
2041
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE4hashB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE4hashB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE4hashCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE4hashCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE4hashCsibGXYHQB8Ea_25json_rpc_general_requests
2042
2043
    /// Returns the hash of the parent of the block that was verified.
2044
0
    pub fn parent_hash(&self) -> &[u8; 32] {
2045
0
        &self.block_to_verify.parent_block_hash
2046
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE11parent_hashB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE11parent_hashB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE11parent_hashCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE11parent_hashCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE11parent_hashCsibGXYHQB8Ea_25json_rpc_general_requests
2047
2048
    /// Returns the user data of the parent of the block to be verified, or `None` if the parent
2049
    /// is the finalized block.
2050
0
    pub fn parent_user_data(&self) -> Option<&TBl> {
2051
0
        self.parent
2052
0
            .chain
2053
0
            .non_finalized_block_user_data(&self.block_to_verify.parent_block_hash)
2054
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE16parent_user_dataB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE16parent_user_dataB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE16parent_user_dataCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE16parent_user_dataCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE16parent_user_dataCsibGXYHQB8Ea_25json_rpc_general_requests
2055
2056
    /// Returns the SCALE-encoded header of the block that was verified.
2057
0
    pub fn scale_encoded_header(&self) -> &[u8] {
2058
0
        self.verified_header.scale_encoded_header()
2059
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE20scale_encoded_headerB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE20scale_encoded_headerB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE20scale_encoded_headerCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE20scale_encoded_headerCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE20scale_encoded_headerCsibGXYHQB8Ea_25json_rpc_general_requests
2060
2061
    /// Returns the list of SCALE-encoded extrinsics of the block to verify.
2062
    ///
2063
    /// This is `Some` if and only if [`Config::download_bodies`] is `true`
2064
0
    pub fn scale_encoded_extrinsics(
2065
0
        &'_ self,
2066
0
    ) -> Option<impl ExactSizeIterator<Item = impl AsRef<[u8]> + Clone + '_> + Clone + '_> {
2067
0
        if self.parent.inner.blocks.downloading_bodies() {
2068
0
            Some(
2069
0
                self.parent
2070
0
                    .inner
2071
0
                    .blocks
2072
0
                    .unverified_block_user_data(
2073
0
                        self.block_to_verify.block_number,
2074
0
                        &self.block_to_verify.block_hash,
2075
0
                    )
2076
0
                    .body
2077
0
                    .as_ref()
2078
0
                    // The block shouldn't have been proposed for verification if it doesn't
2079
0
                    // have its body available.
2080
0
                    .unwrap_or_else(|| unreachable!())
Unexecuted instantiation: _RNCNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB7_19HeaderVerifySuccesspppE24scale_encoded_extrinsics0Bb_
Unexecuted instantiation: _RNCNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB7_19HeaderVerifySuccesspppE24scale_encoded_extrinsics0Bb_
Unexecuted instantiation: _RNCNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB7_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB9_3all20AllForksRequestExtraNtB35_19AllForksSourceExtraE24scale_encoded_extrinsics0CsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNCNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB7_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB9_3all20AllForksRequestExtraNtB35_19AllForksSourceExtraE24scale_encoded_extrinsics0CscDgN54JpMGG_6author
Unexecuted instantiation: _RNCNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB7_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB9_3all20AllForksRequestExtraNtB35_19AllForksSourceExtraE24scale_encoded_extrinsics0CsibGXYHQB8Ea_25json_rpc_general_requests
2081
0
                    .iter(),
2082
0
            )
2083
        } else {
2084
0
            None
2085
        }
2086
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE24scale_encoded_extrinsicsB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE24scale_encoded_extrinsicsB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE24scale_encoded_extrinsicsCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE24scale_encoded_extrinsicsCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE24scale_encoded_extrinsicsCsibGXYHQB8Ea_25json_rpc_general_requests
2087
2088
    /// Returns the SCALE-encoded header of the block that was verified.
2089
0
    pub fn parent_scale_encoded_header(&self) -> &[u8] {
2090
0
        if self.block_to_verify.parent_block_hash == *self.parent.chain.finalized_block_hash() {
2091
0
            self.parent.chain.finalized_block_header()
2092
        } else {
2093
0
            self.parent
2094
0
                .chain
2095
0
                .non_finalized_block_header(&self.block_to_verify.parent_block_hash)
2096
0
                .unwrap()
2097
        }
2098
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE27parent_scale_encoded_headerB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE27parent_scale_encoded_headerB9_
2099
2100
    /// Cancel the block verification.
2101
0
    pub fn cancel(self) -> AllForksSync<TBl, TRq, TSrc> {
2102
0
        self.parent
2103
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE6cancelB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE6cancelB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6cancelCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6cancelCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6cancelCsibGXYHQB8Ea_25json_rpc_general_requests
2104
2105
    /// Reject the block and mark it as bad.
2106
0
    pub fn reject_bad_block(mut self) -> AllForksSync<TBl, TRq, TSrc> {
2107
0
        // Remove the block from `pending_blocks`.
2108
0
        self.parent.inner.blocks.mark_unverified_block_as_bad(
2109
0
            self.block_to_verify.block_number,
2110
0
            &self.block_to_verify.block_hash,
2111
0
        );
2112
0
2113
0
        self.parent
2114
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE16reject_bad_blockB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE16reject_bad_blockB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE16reject_bad_blockCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE16reject_bad_blockCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE16reject_bad_blockCsibGXYHQB8Ea_25json_rpc_general_requests
2115
2116
    /// Finish inserting the block header.
2117
0
    pub fn finish(mut self) -> AllForksSync<TBl, TRq, TSrc> {
2118
0
        // Remove the block from `pending_blocks`.
2119
0
        let pending_block = self.parent.inner.blocks.remove_unverified_block(
2120
0
            self.block_to_verify.block_number,
2121
0
            &self.block_to_verify.block_hash,
2122
0
        );
2123
0
2124
0
        // Now insert the block in `chain`.
2125
0
        self.parent
2126
0
            .chain
2127
0
            .insert_verified_header(self.verified_header, pending_block.user_data);
2128
2129
        // Because a new block is now in the chain, all the previously-unverifiable
2130
        // finality proofs might have now become verifiable.
2131
        // TODO: this way of doing it is correct but quite inefficient
2132
0
        for source in self.parent.inner.blocks.sources_user_data_iter_mut() {
2133
0
            let pending = mem::replace(
2134
0
                &mut source.pending_finality_proofs,
2135
0
                SourcePendingJustificationProofs::None,
2136
0
            );
2137
0
2138
0
            source.unverified_finality_proofs.merge(pending)
2139
        }
2140
2141
0
        self.parent
2142
0
    }
Unexecuted instantiation: _RNvMse_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE6finishB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1R_19AllForksSourceExtraE6finishCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccesspppE6finishB9_
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6finishCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6finishCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMse_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19HeaderVerifySuccessINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6finishCsibGXYHQB8Ea_25json_rpc_general_requests
2143
}
2144
2145
/// Finality proof verification to be performed.
2146
///
2147
/// Internally holds the [`AllForksSync`].
2148
pub struct FinalityProofVerify<TBl, TRq, TSrc> {
2149
    parent: AllForksSync<TBl, TRq, TSrc>,
2150
    /// Source that has sent the finality proof.
2151
    source_id: SourceId,
2152
    /// Justification and its consensus engine id, or commit that can be verified.
2153
    finality_proof_to_verify: FinalityProof,
2154
}
2155
2156
impl<TBl, TRq, TSrc> FinalityProofVerify<TBl, TRq, TSrc> {
2157
    /// Returns the source the justification was obtained from.
2158
0
    pub fn sender(&self) -> (SourceId, &TSrc) {
2159
0
        (self.source_id, &self.parent[self.source_id])
2160
0
    }
Unexecuted instantiation: _RNvMsf_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19FinalityProofVerifypppE6senderB9_
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifyINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1R_19AllForksSourceExtraE6senderCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifypppE6senderB9_
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6senderCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6senderCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE6senderCsibGXYHQB8Ea_25json_rpc_general_requests
2161
2162
    /// Perform the verification.
2163
    ///
2164
    /// A randomness seed must be provided and will be used during the verification. Note that the
2165
    /// verification is nonetheless deterministic.
2166
0
    pub fn perform(
2167
0
        mut self,
2168
0
        randomness_seed: [u8; 32],
2169
0
    ) -> (
2170
0
        AllForksSync<TBl, TRq, TSrc>,
2171
0
        FinalityProofVerifyOutcome<TBl>,
2172
0
    ) {
2173
0
        let finality_apply = match self.finality_proof_to_verify {
2174
0
            FinalityProof::GrandpaCommit(scale_encoded_commit) => {
2175
0
                match self
2176
0
                    .parent
2177
0
                    .chain
2178
0
                    .verify_grandpa_commit_message(&scale_encoded_commit, randomness_seed)
2179
                {
2180
0
                    Ok(finality_apply) => finality_apply,
2181
2182
                    // In case where the commit message concerns a block older or equal to the
2183
                    // finalized block, the operation is silently considered successful.
2184
                    Err(blocks_tree::CommitVerifyError::FinalityVerify(
2185
                        blocks_tree::FinalityVerifyError::EqualToFinalized
2186
                        | blocks_tree::FinalityVerifyError::BelowFinalized,
2187
0
                    )) => return (self.parent, FinalityProofVerifyOutcome::AlreadyFinalized),
2188
2189
                    // The commit can't be verified yet.
2190
                    Err(
2191
                        blocks_tree::CommitVerifyError::FinalityVerify(
2192
                            blocks_tree::FinalityVerifyError::UnknownTargetBlock {
2193
0
                                block_number,
2194
                                ..
2195
                            },
2196
                        )
2197
                        | blocks_tree::CommitVerifyError::FinalityVerify(
2198
                            blocks_tree::FinalityVerifyError::TooFarAhead {
2199
0
                                justification_block_number: block_number,
2200
                                ..
2201
                            },
2202
                        )
2203
                        | blocks_tree::CommitVerifyError::NotEnoughKnownBlocks {
2204
0
                            target_block_number: block_number,
2205
                        },
2206
                    ) => {
2207
0
                        self.parent.inner.blocks[self.source_id]
2208
0
                            .pending_finality_proofs
2209
0
                            .insert(
2210
0
                                block_number,
2211
0
                                FinalityProofs::GrandpaCommit(scale_encoded_commit),
2212
0
                            );
2213
0
                        return (
2214
0
                            self.parent,
2215
0
                            FinalityProofVerifyOutcome::GrandpaCommitPending,
2216
0
                        );
2217
                    }
2218
2219
                    // Any other error means that the commit is invalid.
2220
0
                    Err(err) => {
2221
0
                        return (
2222
0
                            self.parent,
2223
0
                            FinalityProofVerifyOutcome::GrandpaCommitError(err),
2224
0
                        )
2225
                    }
2226
                }
2227
            }
2228
2229
0
            FinalityProof::Justification((consensus_engine_id, scale_encoded_justification)) => {
2230
0
                match self.parent.chain.verify_justification(
2231
0
                    consensus_engine_id,
2232
0
                    &scale_encoded_justification,
2233
0
                    randomness_seed,
2234
0
                ) {
2235
0
                    Ok(finality_apply) => finality_apply,
2236
2237
                    // In case where the commit message concerns a block older or equal to the
2238
                    // finalized block, the operation is silently considered successful.
2239
                    Err(blocks_tree::JustificationVerifyError::FinalityVerify(
2240
                        blocks_tree::FinalityVerifyError::EqualToFinalized
2241
                        | blocks_tree::FinalityVerifyError::BelowFinalized,
2242
0
                    )) => return (self.parent, FinalityProofVerifyOutcome::AlreadyFinalized),
2243
2244
                    // Note that, contrary to commits, there's no such thing as a justification
2245
                    // that can't be verified yet.
2246
0
                    Err(err) => {
2247
0
                        return (
2248
0
                            self.parent,
2249
0
                            FinalityProofVerifyOutcome::JustificationError(err),
2250
0
                        )
2251
                    }
2252
                }
2253
            }
2254
        };
2255
2256
        // Commit or justification successfully verified.
2257
        // Update the local state with the newly-finalized block.
2258
2259
0
        let finalized_blocks_iter = finality_apply.apply();
2260
0
        let updates_best_block = finalized_blocks_iter.updates_best_block();
2261
0
        let mut finalized_blocks = Vec::new();
2262
0
        let mut pruned_blocks = Vec::new();
2263
        // TODO: a bit weird to perform a conversion here
2264
0
        for block in finalized_blocks_iter {
2265
0
            if matches!(block.ty, blocks_tree::RemovedBlockType::Finalized) {
2266
0
                finalized_blocks.push(RemovedBlock {
2267
0
                    block_hash: block.block_hash,
2268
0
                    block_number: block.block_number,
2269
0
                    user_data: block.user_data,
2270
0
                    scale_encoded_header: block.scale_encoded_header,
2271
0
                });
2272
0
            } else {
2273
0
                pruned_blocks.push(RemovedBlock {
2274
0
                    block_hash: block.block_hash,
2275
0
                    block_number: block.block_number,
2276
0
                    user_data: block.user_data,
2277
0
                    scale_encoded_header: block.scale_encoded_header,
2278
0
                });
2279
0
            }
2280
        }
2281
0
        let _finalized_blocks = self
2282
0
            .parent
2283
0
            .inner
2284
0
            .blocks
2285
0
            .set_finalized_block_height(finalized_blocks.last().unwrap().block_number);
2286
0
2287
0
        (
2288
0
            self.parent,
2289
0
            FinalityProofVerifyOutcome::NewFinalized {
2290
0
                finalized_blocks_newest_to_oldest: finalized_blocks,
2291
0
                pruned_blocks,
2292
0
                updates_best_block,
2293
0
            },
2294
0
        )
2295
0
    }
Unexecuted instantiation: _RNvMsf_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19FinalityProofVerifypppE7performB9_
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifyINtNtCsaYZPK01V26L_4core6option6OptionuENtNtB7_3all20AllForksRequestExtraNtB1R_19AllForksSourceExtraE7performCsDDUKWWCHAU_18smoldot_light_wasm
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifypppE7performB9_
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE7performCsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE7performCscDgN54JpMGG_6author
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifyINtNtCsaYZPK01V26L_4core6option6OptionNtNtCsiUjFBJteJ7x_17smoldot_full_node17consensus_service17NonFinalizedBlockENtNtB7_3all20AllForksRequestExtraNtB33_19AllForksSourceExtraE7performCsibGXYHQB8Ea_25json_rpc_general_requests
2296
2297
    /// Do not actually proceed with the verification.
2298
0
    pub fn cancel(self) -> AllForksSync<TBl, TRq, TSrc> {
2299
0
        self.parent
2300
0
    }
Unexecuted instantiation: _RNvMsf_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksINtB5_19FinalityProofVerifypppE6cancelB9_
Unexecuted instantiation: _RNvMsf_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksINtB5_19FinalityProofVerifypppE6cancelB9_
2301
}
2302
2303
/// See [`AllForksSync::grandpa_commit_message`].
2304
#[derive(Debug, Clone)]
2305
pub enum GrandpaCommitMessageOutcome {
2306
    /// Failed to parse message. Commit has been silently discarded.
2307
    ParseError, // TODO: should probably contain the error, but difficult due to lifetimes in said error
2308
    /// Message has been queued for later verification.
2309
    Queued,
2310
}
2311
2312
/// State of the processing of blocks.
2313
pub enum ProcessOne<TBl, TRq, TSrc> {
2314
    /// No processing is necessary.
2315
    ///
2316
    /// Calling [`AllForksSync::process_one`] again is unnecessary.
2317
    AllSync {
2318
        /// The state machine.
2319
        /// The [`AllForksSync::process_one`] method takes ownership of the [`AllForksSync`]. This
2320
        /// field yields it back.
2321
        sync: AllForksSync<TBl, TRq, TSrc>,
2322
    },
2323
2324
    /// A block is ready for verification.
2325
    BlockVerify(BlockVerify<TBl, TRq, TSrc>),
2326
2327
    /// A justification is ready for verification.
2328
    FinalityProofVerify(FinalityProofVerify<TBl, TRq, TSrc>),
2329
}
2330
2331
/// Outcome of calling [`BlockVerify::verify_header`].
2332
pub enum HeaderVerifyOutcome<TBl, TRq, TSrc> {
2333
    /// Header has been successfully verified.
2334
    Success {
2335
        /// True if the newly-verified block is considered the new best block.
2336
        is_new_best: bool,
2337
        success: HeaderVerifySuccess<TBl, TRq, TSrc>,
2338
    },
2339
2340
    /// Header verification failed.
2341
    Error {
2342
        /// State machine yielded back. Use to continue the processing.
2343
        sync: AllForksSync<TBl, TRq, TSrc>,
2344
        /// Error that happened.
2345
        error: HeaderVerifyError,
2346
    },
2347
}
2348
2349
/// Error that can happen when verifying a block header.
2350
0
#[derive(Debug, derive_more::Display)]
Unexecuted instantiation: _RNvXsk_NtNtCsN16ciHI6Qf_7smoldot4sync9all_forksNtB5_17HeaderVerifyErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsk_NtNtCseuYC0Zibziv_7smoldot4sync9all_forksNtB5_17HeaderVerifyErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
2351
pub enum HeaderVerifyError {
2352
    /// Block can't be verified as it uses an unknown consensus engine.
2353
    UnknownConsensusEngine,
2354
    /// Block uses a different consensus than the rest of the chain.
2355
    ConsensusMismatch,
2356
    /// The block verification has failed. The block is invalid and should be thrown away.
2357
    #[display(fmt = "{_0}")]
2358
    VerificationFailed(verify::header_only::Error),
2359
}
2360
2361
/// Information about the outcome of verifying a finality proof.
2362
#[derive(Debug)]
2363
pub enum FinalityProofVerifyOutcome<TBl> {
2364
    /// Verification successful. The block and all its ancestors is now finalized.
2365
    NewFinalized {
2366
        /// List of finalized blocks, in decreasing block number.
2367
        finalized_blocks_newest_to_oldest: Vec<RemovedBlock<TBl>>,
2368
        /// List of blocks that aren't descendant of the latest finalized block, in an unspecified order.
2369
        pruned_blocks: Vec<RemovedBlock<TBl>>,
2370
        /// If `true`, this operation modifies the best block of the non-finalized chain.
2371
        /// This can happen if the previous best block isn't a descendant of the now finalized
2372
        /// block.
2373
        updates_best_block: bool,
2374
    },
2375
    /// Finality proof concerns block that was already finalized.
2376
    AlreadyFinalized,
2377
    /// GrandPa commit cannot be verified yet and has been stored for later.
2378
    GrandpaCommitPending,
2379
    /// Problem while verifying justification.
2380
    JustificationError(blocks_tree::JustificationVerifyError),
2381
    /// Problem while verifying GrandPa commit.
2382
    GrandpaCommitError(blocks_tree::CommitVerifyError),
2383
}
2384
2385
/// See [`FinalityProofVerifyOutcome`].
2386
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2387
pub struct RemovedBlock<TBl> {
2388
    /// Hash of the block.
2389
    pub block_hash: [u8; 32],
2390
    /// Height of the block.
2391
    pub block_number: u64,
2392
    /// User data that was associated with that block.
2393
    pub user_data: TBl,
2394
    /// SCALE-encoded header of the block.
2395
    pub scale_encoded_header: Vec<u8>,
2396
}