Coverage Report

Created: 2024-05-16 12:16

/__w/smoldot/smoldot/repo/lib/src/author/runtime.rs
Line
Count
Source (jump to first uncovered line)
1
// Smoldot
2
// Copyright (C) 2019-2020  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
//! Block generation system.
19
//!
20
//! This module provides the actual block generation code. The output is an unsealed header and
21
//! body.
22
//!
23
//! After a block has been generated, it must still be sealed (in other words, signed by its
24
//! author) by adding a corresponding entry to the log items in its header. This is out of scope
25
//! of this module.
26
//!
27
//! # Detail
28
//!
29
//! Building a block consists in four steps:
30
//!
31
//! - A runtime call to `Core_initialize_block`, passing a header prototype as input. This call
32
//!   performs some initial storage writes.
33
//! - A runtime call to `BlockBuilder_inherent_extrinsics`, passing as input a list of
34
//!   *intrinsics*. This pure call returns a list of extrinsics.
35
//! - Zero or more runtime calls to `BlockBuilder_apply_extrinsic`, passing as input an extrinsic.
36
//!   This must be done once per extrinsic returned by the previous step, plus once for each
37
//!   transaction to push in the block.
38
//! - A runtime call to `BlockBuilder_finalize_block`, which returns the newly-created unsealed
39
//! block header.
40
//!
41
//! The body of the newly-generated block consists in the extrinsics pushed using
42
//! `BlockBuilder_apply_extrinsic` (including the intrinsics).
43
//!
44
45
// TODO: expand docs
46
// TODO: explain what an inherent extrinsic is
47
48
mod tests;
49
50
use crate::{
51
    executor::{host, runtime_call},
52
    header, util,
53
    verify::inherents,
54
};
55
56
use alloc::{borrow::ToOwned as _, vec::Vec};
57
use core::{iter, mem};
58
59
pub use runtime_call::{
60
    Nibble, StorageChanges, TrieChange, TrieChangeStorageValue, TrieEntryVersion,
61
};
62
63
/// Configuration for a block generation.
64
pub struct Config<'a> {
65
    /// Number of bytes used to encode block numbers in the header.
66
    pub block_number_bytes: usize,
67
68
    /// Hash of the parent of the block to generate.
69
    ///
70
    /// Used to populate the header of the new block.
71
    pub parent_hash: &'a [u8; 32],
72
73
    /// Height of the parent of the block to generate.
74
    ///
75
    /// Used to populate the header of the new block.
76
    pub parent_number: u64,
77
78
    /// Runtime used to check the new block. Must be built using the Wasm code found at the
79
    /// `:code` key of the parent block storage.
80
    pub parent_runtime: host::HostVmPrototype,
81
82
    /// Consensus-specific item to put in the digest of the header prototype.
83
    ///
84
    /// > **Note**: In the case of Aura and Babe, contains the slot being claimed.
85
    pub consensus_digest_log_item: ConfigPreRuntime<'a>,
86
87
    /// Capacity to reserve for the number of extrinsics. Should be higher than the approximate
88
    /// number of extrinsics that are going to be applied.
89
    pub block_body_capacity: usize,
90
91
    /// Maximum log level of the runtime.
92
    ///
93
    /// > **Note**: This value is opaque from the point of the view of the client, and the runtime
94
    /// >           is free to interpret it the way it wants. However, usually values are: `0` for
95
    /// >           "off", `1` for "error", `2` for "warn", `3` for "info", `4` for "debug",
96
    /// >           and `5` for "trace".
97
    pub max_log_level: u32,
98
99
    /// If `true`, then [`StorageChanges::trie_changes_iter_ordered`] will return `Some`.
100
    /// Passing `None` requires fewer calculation and fewer storage accesses.
101
    pub calculate_trie_changes: bool,
102
}
103
104
/// Extra configuration depending on the consensus algorithm.
105
// TODO: consider not exposing `header` in the API
106
pub enum ConfigPreRuntime<'a> {
107
    /// Chain uses the Aura consensus algorithm.
108
    Aura(header::AuraPreDigest),
109
    /// Chain uses the Babe consensus algorithm.
110
    Babe(header::BabePreDigestRef<'a>),
111
}
112
113
/// Block successfully verified.
114
pub struct Success {
115
    /// SCALE-encoded header of the produced block.
116
    pub scale_encoded_header: Vec<u8>,
117
    /// Body of the produced block.
118
    pub body: Vec<Vec<u8>>,
119
    /// Runtime that was passed by [`Config`].
120
    pub parent_runtime: host::HostVmPrototype,
121
    /// List of changes to the storage main trie that the block performs.
122
    pub storage_changes: StorageChanges,
123
    /// State trie version indicated by the runtime. All the storage changes indicated by
124
    /// [`Success::storage_changes`] should store this version alongside with them.
125
    pub state_trie_version: TrieEntryVersion,
126
}
127
128
/// Error that can happen during the block production.
129
0
#[derive(Debug, derive_more::Display)]
Unexecuted instantiation: _RNvXs6_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXs6_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_5ErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
130
pub enum Error {
131
    /// Error while executing the Wasm virtual machine.
132
    #[display(fmt = "{_0}")]
133
    WasmVm(runtime_call::ErrorDetail),
134
    /// Error while initializing the Wasm virtual machine.
135
    #[display(fmt = "{_0}")]
136
    VmInit(host::StartErr),
137
    /// Overflow when incrementing block height.
138
    BlockHeightOverflow,
139
    /// `Core_initialize_block` has returned a non-empty output.
140
    InitializeBlockNonEmptyOutput,
141
    /// Error while parsing output of `BlockBuilder_inherent_extrinsics`.
142
    BadInherentExtrinsicsOutput,
143
    /// Error while parsing output of `BlockBuilder_apply_extrinsic`.
144
    BadApplyExtrinsicOutput,
145
    /// Applying an inherent extrinsic has returned a [`DispatchError`].
146
    #[display(fmt = "Error while applying inherent extrinsic: {error}\nExtrinsic: {extrinsic:?}")]
147
    InherentExtrinsicDispatchError {
148
        /// Extrinsic that triggered the problem.
149
        extrinsic: Vec<u8>,
150
        /// Error returned by the runtime.
151
        error: DispatchError,
152
    },
153
    /// Applying an inherent extrinsic has returned a [`TransactionValidityError`].
154
    #[display(fmt = "Error while applying inherent extrinsic: {error}\nExtrinsic: {extrinsic:?}")]
155
    InherentExtrinsicTransactionValidityError {
156
        /// Extrinsic that triggered the problem.
157
        extrinsic: Vec<u8>,
158
        /// Error returned by the runtime.
159
        error: TransactionValidityError,
160
    },
161
}
162
163
/// Start a block building process.
164
1
pub fn build_block(config: Config) -> BlockBuild {
165
1
    let init_result = runtime_call::run(runtime_call::Config {
166
1
        function_to_call: "Core_initialize_block",
167
1
        parameter: {
168
1
            // The `Core_initialize_block` function expects a SCALE-encoded partially-initialized
169
1
            // header.
170
1
            header::HeaderRef {
171
1
                parent_hash: config.parent_hash,
172
1
                number: match config.parent_number.checked_add(1) {
173
1
                    Some(n) => n,
174
                    None => {
175
0
                        return BlockBuild::Finished(Err((
176
0
                            Error::BlockHeightOverflow,
177
0
                            config.parent_runtime,
178
0
                        )))
179
                    }
180
                },
181
1
                extrinsics_root: &[0; 32],
182
1
                state_root: &[0; 32],
183
1
                digest: header::DigestRef::from_slice(&[match config.consensus_digest_log_item {
184
1
                    ConfigPreRuntime::Aura(item) => header::DigestItem::AuraPreDigest(item),
185
0
                    ConfigPreRuntime::Babe(item) => header::DigestItem::BabePreDigest(item.into()),
186
                }])
187
1
                .unwrap(),
188
1
            }
189
1
            .scale_encoding(config.block_number_bytes)
190
1
        },
191
1
        virtual_machine: config.parent_runtime,
192
1
        storage_main_trie_changes: Default::default(),
193
1
        storage_proof_size_behavior: runtime_call::StorageProofSizeBehavior::Unimplemented,
194
1
        max_log_level: config.max_log_level,
195
1
        calculate_trie_changes: config.calculate_trie_changes,
196
    });
197
198
1
    let vm = match init_result {
199
1
        Ok(vm) => vm,
200
0
        Err((err, proto)) => return BlockBuild::Finished(Err((Error::VmInit(err), proto))),
201
    };
202
203
1
    let shared = Shared {
204
1
        stage: Stage::InitializeBlock,
205
1
        block_body: Vec::with_capacity(config.block_body_capacity),
206
1
        max_log_level: config.max_log_level,
207
1
        calculate_trie_changes: config.calculate_trie_changes,
208
1
    };
209
1
210
1
    BlockBuild::from_inner(vm, shared)
211
1
}
_RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime11build_block
Line
Count
Source
164
1
pub fn build_block(config: Config) -> BlockBuild {
165
1
    let init_result = runtime_call::run(runtime_call::Config {
166
1
        function_to_call: "Core_initialize_block",
167
1
        parameter: {
168
1
            // The `Core_initialize_block` function expects a SCALE-encoded partially-initialized
169
1
            // header.
170
1
            header::HeaderRef {
171
1
                parent_hash: config.parent_hash,
172
1
                number: match config.parent_number.checked_add(1) {
173
1
                    Some(n) => n,
174
                    None => {
175
0
                        return BlockBuild::Finished(Err((
176
0
                            Error::BlockHeightOverflow,
177
0
                            config.parent_runtime,
178
0
                        )))
179
                    }
180
                },
181
1
                extrinsics_root: &[0; 32],
182
1
                state_root: &[0; 32],
183
1
                digest: header::DigestRef::from_slice(&[match config.consensus_digest_log_item {
184
1
                    ConfigPreRuntime::Aura(item) => header::DigestItem::AuraPreDigest(item),
185
0
                    ConfigPreRuntime::Babe(item) => header::DigestItem::BabePreDigest(item.into()),
186
                }])
187
1
                .unwrap(),
188
1
            }
189
1
            .scale_encoding(config.block_number_bytes)
190
1
        },
191
1
        virtual_machine: config.parent_runtime,
192
1
        storage_main_trie_changes: Default::default(),
193
1
        storage_proof_size_behavior: runtime_call::StorageProofSizeBehavior::Unimplemented,
194
1
        max_log_level: config.max_log_level,
195
1
        calculate_trie_changes: config.calculate_trie_changes,
196
    });
197
198
1
    let vm = match init_result {
199
1
        Ok(vm) => vm,
200
0
        Err((err, proto)) => return BlockBuild::Finished(Err((Error::VmInit(err), proto))),
201
    };
202
203
1
    let shared = Shared {
204
1
        stage: Stage::InitializeBlock,
205
1
        block_body: Vec::with_capacity(config.block_body_capacity),
206
1
        max_log_level: config.max_log_level,
207
1
        calculate_trie_changes: config.calculate_trie_changes,
208
1
    };
209
1
210
1
    BlockBuild::from_inner(vm, shared)
211
1
}
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime11build_block
212
213
/// Current state of the block building process.
214
#[must_use]
215
pub enum BlockBuild {
216
    /// Block generation is over.
217
    Finished(Result<Success, (Error, host::HostVmPrototype)>),
218
219
    /// The inherent extrinsics are required in order to continue.
220
    ///
221
    /// [`BlockBuild::InherentExtrinsics`] is guaranteed to only be emitted once per block
222
    /// building process.
223
    ///
224
    /// The extrinsics returned by the call to `BlockBuilder_inherent_extrinsics` are
225
    /// automatically pushed to the runtime.
226
    InherentExtrinsics(InherentExtrinsics),
227
228
    /// Block building is ready to accept extrinsics.
229
    ///
230
    /// If [`ApplyExtrinsic::add_extrinsic`] is used, then a [`BlockBuild::ApplyExtrinsicResult`]
231
    /// stage will be emitted later.
232
    ///
233
    /// > **Note**: These extrinsics are generally coming from a transactions pool, but this is
234
    /// >           out of scope of this module.
235
    ApplyExtrinsic(ApplyExtrinsic),
236
237
    /// Result of the previous call to [`ApplyExtrinsic::add_extrinsic`].
238
    ///
239
    /// An [`ApplyExtrinsic`] object is provided in order to continue the operation.
240
    ApplyExtrinsicResult {
241
        /// Result of the previous call to [`ApplyExtrinsic::add_extrinsic`].
242
        result: Result<Result<(), DispatchError>, TransactionValidityError>,
243
        /// Object to use to continue trying to push other transactions or finish the block.
244
        resume: ApplyExtrinsic,
245
    },
246
247
    /// Loading a storage value from the parent storage is required in order to continue.
248
    StorageGet(StorageGet),
249
250
    /// Obtaining the Merkle value of the closest descendant of a trie node is required in order
251
    /// to continue.
252
    ClosestDescendantMerkleValue(ClosestDescendantMerkleValue),
253
254
    /// Fetching the key that follows a given one in the parent storage is required in order to
255
    /// continue.
256
    NextKey(NextKey),
257
258
    /// Setting an offchain storage value is required in order to continue.
259
    OffchainStorageSet(OffchainStorageSet),
260
}
261
262
impl BlockBuild {
263
4.20k
    fn from_inner(inner: runtime_call::RuntimeCall, mut shared: Shared) -> Self {
264
4.20k
        enum Inner {
265
4.20k
            Runtime(runtime_call::RuntimeCall),
266
4.20k
            Transition(runtime_call::Success),
267
4.20k
        }
268
4.20k
269
4.20k
        let mut inner = Inner::Runtime(inner);
270
271
        loop {
272
4.20k
            match (inner, &mut shared.stage) {
273
0
                (Inner::Runtime(runtime_call::RuntimeCall::Finished(Err(err))), _) => {
274
0
                    return BlockBuild::Finished(Err((Error::WasmVm(err.detail), err.prototype)));
275
                }
276
146
                (Inner::Runtime(runtime_call::RuntimeCall::StorageGet(inner)), _) => {
277
146
                    return BlockBuild::StorageGet(StorageGet(inner, shared))
278
                }
279
                (
280
1.86k
                    Inner::Runtime(runtime_call::RuntimeCall::ClosestDescendantMerkleValue(inner)),
281
1.86k
                    _,
282
1.86k
                ) => {
283
1.86k
                    return BlockBuild::ClosestDescendantMerkleValue(ClosestDescendantMerkleValue(
284
1.86k
                        inner, shared,
285
1.86k
                    ))
286
                }
287
2.19k
                (Inner::Runtime(runtime_call::RuntimeCall::NextKey(inner)), _) => {
288
2.19k
                    return BlockBuild::NextKey(NextKey(inner, shared))
289
                }
290
0
                (Inner::Runtime(runtime_call::RuntimeCall::OffchainStorageSet(inner)), _) => {
291
0
                    return BlockBuild::OffchainStorageSet(OffchainStorageSet(inner, shared))
292
                }
293
294
                (
295
1
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
296
1
                    Stage::InitializeBlock,
297
1
                ) => {
298
1
                    if !success.virtual_machine.value().as_ref().is_empty() {
299
0
                        return BlockBuild::Finished(Err((
300
0
                            Error::InitializeBlockNonEmptyOutput,
301
0
                            success.virtual_machine.into_prototype(),
302
0
                        )));
303
1
                    }
304
1
305
1
                    shared.stage = Stage::InherentExtrinsics;
306
1
307
1
                    return BlockBuild::InherentExtrinsics(InherentExtrinsics {
308
1
                        shared,
309
1
                        parent_runtime: success.virtual_machine.into_prototype(),
310
1
                        storage_changes: success.storage_changes,
311
1
                    });
312
                }
313
314
                (
315
1
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
316
1
                    Stage::InherentExtrinsics,
317
1
                ) => {
318
1
                    let parse_result =
319
1
                        parse_inherent_extrinsics_output(success.virtual_machine.value().as_ref());
320
1
                    let extrinsics = match parse_result {
321
1
                        Ok(extrinsics) => extrinsics,
322
0
                        Err(err) => {
323
0
                            return BlockBuild::Finished(Err((
324
0
                                err,
325
0
                                success.virtual_machine.into_prototype(),
326
0
                            )))
327
                        }
328
                    };
329
330
1
                    shared.block_body.reserve(extrinsics.len());
331
1
                    shared.stage = Stage::ApplyInherentExtrinsic { extrinsics };
332
1
                    inner = Inner::Transition(success);
333
                }
334
335
2
                (Inner::Transition(
success1
), Stage::ApplyInherentExtrinsic { extrinsics })
336
2
                    if !extrinsics.is_empty() =>
337
1
                {
338
1
                    let extrinsic = &extrinsics[0];
339
1
340
1
                    let init_result = runtime_call::run(runtime_call::Config {
341
1
                        virtual_machine: success.virtual_machine.into_prototype(),
342
1
                        function_to_call: "BlockBuilder_apply_extrinsic",
343
1
                        parameter: iter::once(extrinsic),
344
1
                        storage_main_trie_changes: success.storage_changes.into_main_trie_diff(),
345
1
                        storage_proof_size_behavior:
346
1
                            runtime_call::StorageProofSizeBehavior::Unimplemented,
347
1
                        max_log_level: shared.max_log_level,
348
1
                        calculate_trie_changes: shared.calculate_trie_changes,
349
1
                    });
350
351
1
                    inner = Inner::Runtime(match init_result {
352
1
                        Ok(vm) => vm,
353
0
                        Err((err, proto)) => {
354
0
                            return BlockBuild::Finished(Err((Error::VmInit(err), proto)))
355
                        }
356
                    });
357
                }
358
359
1
                (Inner::Transition(success), Stage::ApplyInherentExtrinsic { .. }) => {
360
1
                    return BlockBuild::ApplyExtrinsic(ApplyExtrinsic {
361
1
                        shared,
362
1
                        parent_runtime: success.virtual_machine.into_prototype(),
363
1
                        storage_changes: success.storage_changes,
364
1
                    });
365
                }
366
367
                (
368
1
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
369
                    Stage::ApplyInherentExtrinsic { .. },
370
                ) => {
371
1
                    let (extrinsic, new_stage) = match shared.stage {
372
1
                        Stage::ApplyInherentExtrinsic { mut extrinsics } => {
373
1
                            let extrinsic = extrinsics.remove(0);
374
1
                            (extrinsic, Stage::ApplyInherentExtrinsic { extrinsics })
375
                        }
376
0
                        _ => unreachable!(),
377
                    };
378
379
1
                    shared.stage = new_stage;
380
1
381
1
                    let parse_result =
382
1
                        parse_apply_extrinsic_output(success.virtual_machine.value().as_ref());
383
1
                    match parse_result {
384
1
                        Ok(Ok(Ok(()))) => {}
385
0
                        Ok(Ok(Err(error))) => {
386
0
                            return BlockBuild::Finished(Err((
387
0
                                Error::InherentExtrinsicDispatchError { extrinsic, error },
388
0
                                success.virtual_machine.into_prototype(),
389
0
                            )))
390
                        }
391
0
                        Ok(Err(error)) => {
392
0
                            return BlockBuild::Finished(Err((
393
0
                                Error::InherentExtrinsicTransactionValidityError {
394
0
                                    extrinsic,
395
0
                                    error,
396
0
                                },
397
0
                                success.virtual_machine.into_prototype(),
398
0
                            )))
399
                        }
400
0
                        Err(err) => {
401
0
                            return BlockBuild::Finished(Err((
402
0
                                err,
403
0
                                success.virtual_machine.into_prototype(),
404
0
                            )))
405
                        }
406
                    }
407
408
1
                    shared.block_body.push(extrinsic);
409
1
410
1
                    inner = Inner::Transition(success);
411
                }
412
413
                (
414
0
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
415
0
                    Stage::ApplyExtrinsic(_),
416
0
                ) => {
417
0
                    let parse_result =
418
0
                        parse_apply_extrinsic_output(success.virtual_machine.value().as_ref());
419
0
                    let result = match parse_result {
420
0
                        Ok(r) => r,
421
0
                        Err(err) => {
422
0
                            return BlockBuild::Finished(Err((
423
0
                                err,
424
0
                                success.virtual_machine.into_prototype(),
425
0
                            )))
426
                        }
427
                    };
428
429
0
                    if result.is_ok() {
430
0
                        shared.block_body.push(match &mut shared.stage {
431
0
                            Stage::ApplyExtrinsic(ext) => mem::take(ext),
432
0
                            _ => unreachable!(),
433
                        });
434
0
                    }
435
436
                    // TODO: consider giving back extrinsic to user in case of failure
437
438
                    // TODO: IMPORTANT /!\ must throw away storage changes in case of error
439
440
0
                    return BlockBuild::ApplyExtrinsicResult {
441
0
                        result,
442
0
                        resume: ApplyExtrinsic {
443
0
                            shared,
444
0
                            parent_runtime: success.virtual_machine.into_prototype(),
445
0
                            storage_changes: success.storage_changes,
446
0
                        },
447
0
                    };
448
                }
449
450
                (
451
1
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
452
1
                    Stage::FinalizeBlock,
453
1
                ) => {
454
1
                    let scale_encoded_header = success.virtual_machine.value().as_ref().to_owned();
455
1
                    return BlockBuild::Finished(Ok(Success {
456
1
                        scale_encoded_header,
457
1
                        body: shared.block_body,
458
1
                        parent_runtime: success.virtual_machine.into_prototype(),
459
1
                        storage_changes: success.storage_changes,
460
1
                        state_trie_version: success.state_trie_version,
461
1
                    }));
462
                }
463
464
                // TODO: what about SignatureVerification and EmitLog? at the time of writing of this comment, it's not worth fixing as this code would get removed by <https://github.com/smol-dot/smoldot/issues/1517>
465
0
                (_, s) => unreachable!("{:?}", s),
466
            }
467
        }
468
4.20k
    }
_RNvMNtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB2_10BlockBuild10from_inner
Line
Count
Source
263
4.20k
    fn from_inner(inner: runtime_call::RuntimeCall, mut shared: Shared) -> Self {
264
4.20k
        enum Inner {
265
4.20k
            Runtime(runtime_call::RuntimeCall),
266
4.20k
            Transition(runtime_call::Success),
267
4.20k
        }
268
4.20k
269
4.20k
        let mut inner = Inner::Runtime(inner);
270
271
        loop {
272
4.20k
            match (inner, &mut shared.stage) {
273
0
                (Inner::Runtime(runtime_call::RuntimeCall::Finished(Err(err))), _) => {
274
0
                    return BlockBuild::Finished(Err((Error::WasmVm(err.detail), err.prototype)));
275
                }
276
146
                (Inner::Runtime(runtime_call::RuntimeCall::StorageGet(inner)), _) => {
277
146
                    return BlockBuild::StorageGet(StorageGet(inner, shared))
278
                }
279
                (
280
1.86k
                    Inner::Runtime(runtime_call::RuntimeCall::ClosestDescendantMerkleValue(inner)),
281
1.86k
                    _,
282
1.86k
                ) => {
283
1.86k
                    return BlockBuild::ClosestDescendantMerkleValue(ClosestDescendantMerkleValue(
284
1.86k
                        inner, shared,
285
1.86k
                    ))
286
                }
287
2.19k
                (Inner::Runtime(runtime_call::RuntimeCall::NextKey(inner)), _) => {
288
2.19k
                    return BlockBuild::NextKey(NextKey(inner, shared))
289
                }
290
0
                (Inner::Runtime(runtime_call::RuntimeCall::OffchainStorageSet(inner)), _) => {
291
0
                    return BlockBuild::OffchainStorageSet(OffchainStorageSet(inner, shared))
292
                }
293
294
                (
295
1
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
296
1
                    Stage::InitializeBlock,
297
1
                ) => {
298
1
                    if !success.virtual_machine.value().as_ref().is_empty() {
299
0
                        return BlockBuild::Finished(Err((
300
0
                            Error::InitializeBlockNonEmptyOutput,
301
0
                            success.virtual_machine.into_prototype(),
302
0
                        )));
303
1
                    }
304
1
305
1
                    shared.stage = Stage::InherentExtrinsics;
306
1
307
1
                    return BlockBuild::InherentExtrinsics(InherentExtrinsics {
308
1
                        shared,
309
1
                        parent_runtime: success.virtual_machine.into_prototype(),
310
1
                        storage_changes: success.storage_changes,
311
1
                    });
312
                }
313
314
                (
315
1
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
316
1
                    Stage::InherentExtrinsics,
317
1
                ) => {
318
1
                    let parse_result =
319
1
                        parse_inherent_extrinsics_output(success.virtual_machine.value().as_ref());
320
1
                    let extrinsics = match parse_result {
321
1
                        Ok(extrinsics) => extrinsics,
322
0
                        Err(err) => {
323
0
                            return BlockBuild::Finished(Err((
324
0
                                err,
325
0
                                success.virtual_machine.into_prototype(),
326
0
                            )))
327
                        }
328
                    };
329
330
1
                    shared.block_body.reserve(extrinsics.len());
331
1
                    shared.stage = Stage::ApplyInherentExtrinsic { extrinsics };
332
1
                    inner = Inner::Transition(success);
333
                }
334
335
2
                (Inner::Transition(
success1
), Stage::ApplyInherentExtrinsic { extrinsics })
336
2
                    if !extrinsics.is_empty() =>
337
1
                {
338
1
                    let extrinsic = &extrinsics[0];
339
1
340
1
                    let init_result = runtime_call::run(runtime_call::Config {
341
1
                        virtual_machine: success.virtual_machine.into_prototype(),
342
1
                        function_to_call: "BlockBuilder_apply_extrinsic",
343
1
                        parameter: iter::once(extrinsic),
344
1
                        storage_main_trie_changes: success.storage_changes.into_main_trie_diff(),
345
1
                        storage_proof_size_behavior:
346
1
                            runtime_call::StorageProofSizeBehavior::Unimplemented,
347
1
                        max_log_level: shared.max_log_level,
348
1
                        calculate_trie_changes: shared.calculate_trie_changes,
349
1
                    });
350
351
1
                    inner = Inner::Runtime(match init_result {
352
1
                        Ok(vm) => vm,
353
0
                        Err((err, proto)) => {
354
0
                            return BlockBuild::Finished(Err((Error::VmInit(err), proto)))
355
                        }
356
                    });
357
                }
358
359
1
                (Inner::Transition(success), Stage::ApplyInherentExtrinsic { .. }) => {
360
1
                    return BlockBuild::ApplyExtrinsic(ApplyExtrinsic {
361
1
                        shared,
362
1
                        parent_runtime: success.virtual_machine.into_prototype(),
363
1
                        storage_changes: success.storage_changes,
364
1
                    });
365
                }
366
367
                (
368
1
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
369
                    Stage::ApplyInherentExtrinsic { .. },
370
                ) => {
371
1
                    let (extrinsic, new_stage) = match shared.stage {
372
1
                        Stage::ApplyInherentExtrinsic { mut extrinsics } => {
373
1
                            let extrinsic = extrinsics.remove(0);
374
1
                            (extrinsic, Stage::ApplyInherentExtrinsic { extrinsics })
375
                        }
376
0
                        _ => unreachable!(),
377
                    };
378
379
1
                    shared.stage = new_stage;
380
1
381
1
                    let parse_result =
382
1
                        parse_apply_extrinsic_output(success.virtual_machine.value().as_ref());
383
1
                    match parse_result {
384
1
                        Ok(Ok(Ok(()))) => {}
385
0
                        Ok(Ok(Err(error))) => {
386
0
                            return BlockBuild::Finished(Err((
387
0
                                Error::InherentExtrinsicDispatchError { extrinsic, error },
388
0
                                success.virtual_machine.into_prototype(),
389
0
                            )))
390
                        }
391
0
                        Ok(Err(error)) => {
392
0
                            return BlockBuild::Finished(Err((
393
0
                                Error::InherentExtrinsicTransactionValidityError {
394
0
                                    extrinsic,
395
0
                                    error,
396
0
                                },
397
0
                                success.virtual_machine.into_prototype(),
398
0
                            )))
399
                        }
400
0
                        Err(err) => {
401
0
                            return BlockBuild::Finished(Err((
402
0
                                err,
403
0
                                success.virtual_machine.into_prototype(),
404
0
                            )))
405
                        }
406
                    }
407
408
1
                    shared.block_body.push(extrinsic);
409
1
410
1
                    inner = Inner::Transition(success);
411
                }
412
413
                (
414
0
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
415
0
                    Stage::ApplyExtrinsic(_),
416
0
                ) => {
417
0
                    let parse_result =
418
0
                        parse_apply_extrinsic_output(success.virtual_machine.value().as_ref());
419
0
                    let result = match parse_result {
420
0
                        Ok(r) => r,
421
0
                        Err(err) => {
422
0
                            return BlockBuild::Finished(Err((
423
0
                                err,
424
0
                                success.virtual_machine.into_prototype(),
425
0
                            )))
426
                        }
427
                    };
428
429
0
                    if result.is_ok() {
430
0
                        shared.block_body.push(match &mut shared.stage {
431
0
                            Stage::ApplyExtrinsic(ext) => mem::take(ext),
432
0
                            _ => unreachable!(),
433
                        });
434
0
                    }
435
436
                    // TODO: consider giving back extrinsic to user in case of failure
437
438
                    // TODO: IMPORTANT /!\ must throw away storage changes in case of error
439
440
0
                    return BlockBuild::ApplyExtrinsicResult {
441
0
                        result,
442
0
                        resume: ApplyExtrinsic {
443
0
                            shared,
444
0
                            parent_runtime: success.virtual_machine.into_prototype(),
445
0
                            storage_changes: success.storage_changes,
446
0
                        },
447
0
                    };
448
                }
449
450
                (
451
1
                    Inner::Runtime(runtime_call::RuntimeCall::Finished(Ok(success))),
452
1
                    Stage::FinalizeBlock,
453
1
                ) => {
454
1
                    let scale_encoded_header = success.virtual_machine.value().as_ref().to_owned();
455
1
                    return BlockBuild::Finished(Ok(Success {
456
1
                        scale_encoded_header,
457
1
                        body: shared.block_body,
458
1
                        parent_runtime: success.virtual_machine.into_prototype(),
459
1
                        storage_changes: success.storage_changes,
460
1
                        state_trie_version: success.state_trie_version,
461
1
                    }));
462
                }
463
464
                // TODO: what about SignatureVerification and EmitLog? at the time of writing of this comment, it's not worth fixing as this code would get removed by <https://github.com/smol-dot/smoldot/issues/1517>
465
0
                (_, s) => unreachable!("{:?}", s),
466
            }
467
        }
468
4.20k
    }
Unexecuted instantiation: _RNvMNtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB2_10BlockBuild10from_inner
469
}
470
471
/// Extra information maintained in parallel of the [`runtime_call::RuntimeCall`].
472
#[derive(Debug)]
473
struct Shared {
474
    /// The block building process is separated into multiple stages.
475
    stage: Stage,
476
    /// Body of the block under construction. Items are added as construction progresses.
477
    block_body: Vec<Vec<u8>>,
478
    /// Value provided by [`Config::max_log_level`].
479
    max_log_level: u32,
480
    /// Value provided by [`Config::calculate_trie_changes`].
481
    calculate_trie_changes: bool,
482
}
483
484
/// The block building process is separated into multiple stages.
485
#[derive(Debug, Clone)]
486
enum Stage {
487
    InitializeBlock,
488
    InherentExtrinsics,
489
    ApplyInherentExtrinsic {
490
        /// List of inherent extrinsics being applied, including the one currently being applied.
491
        /// This list should thus never be empty.
492
        extrinsics: Vec<Vec<u8>>,
493
    },
494
    ApplyExtrinsic(Vec<u8>),
495
    FinalizeBlock,
496
}
497
498
/// The list of inherent extrinsics are needed in order to continue.
499
#[must_use]
500
pub struct InherentExtrinsics {
501
    shared: Shared,
502
    parent_runtime: host::HostVmPrototype,
503
    storage_changes: StorageChanges,
504
}
505
506
impl InherentExtrinsics {
507
    /// Injects the inherents extrinsics and resumes execution.
508
    ///
509
    /// See the module-level documentation for more information.
510
1
    pub fn inject_inherents(self, inherents: inherents::InherentData) -> BlockBuild {
511
1
        self.inject_raw_inherents_list(inherents.as_raw_list())
512
1
    }
_RNvMs_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB4_18InherentExtrinsics16inject_inherents
Line
Count
Source
510
1
    pub fn inject_inherents(self, inherents: inherents::InherentData) -> BlockBuild {
511
1
        self.inject_raw_inherents_list(inherents.as_raw_list())
512
1
    }
Unexecuted instantiation: _RNvMs_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB4_18InherentExtrinsics16inject_inherents
513
514
    /// Injects a raw list of inherents and resumes execution.
515
    ///
516
    /// This method is a more weakly-typed equivalent to [`InherentExtrinsics::inject_inherents`].
517
    /// Only use this method if you know what you're doing.
518
1
    pub fn inject_raw_inherents_list(
519
1
        self,
520
1
        list: impl ExactSizeIterator<Item = ([u8; 8], impl AsRef<[u8]> + Clone)> + Clone,
521
1
    ) -> BlockBuild {
522
1
        debug_assert!(
matches!0
(self.shared.stage, Stage::InherentExtrinsics));
523
524
1
        let init_result = runtime_call::run(runtime_call::Config {
525
1
            virtual_machine: self.parent_runtime,
526
1
            function_to_call: "BlockBuilder_inherent_extrinsics",
527
1
            parameter: {
528
1
                // The `BlockBuilder_inherent_extrinsics` function expects a SCALE-encoded list of
529
1
                // tuples containing an "inherent identifier" (`[u8; 8]`) and a value (`Vec<u8>`).
530
1
                let len = util::encode_scale_compact_usize(list.len());
531
2
                let encoded_list = list.flat_map(|(id, value)| {
532
2
                    let value_len = util::encode_scale_compact_usize(value.as_ref().len());
533
2
                    let value_and_len = iter::once(value_len)
534
2
                        .map(either::Left)
535
2
                        .chain(iter::once(value).map(either::Right));
536
2
                    iter::once(id)
537
2
                        .map(either::Left)
538
2
                        .chain(value_and_len.map(either::Right))
539
2
                });
_RNCINvMs_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB7_18InherentExtrinsics25inject_raw_inherents_listAhj8_INtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterTB1B_B1B_EKj1_EE0Bb_
Line
Count
Source
531
2
                let encoded_list = list.flat_map(|(id, value)| {
532
2
                    let value_len = util::encode_scale_compact_usize(value.as_ref().len());
533
2
                    let value_and_len = iter::once(value_len)
534
2
                        .map(either::Left)
535
2
                        .chain(iter::once(value).map(either::Right));
536
2
                    iter::once(id)
537
2
                        .map(either::Left)
538
2
                        .chain(value_and_len.map(either::Right))
539
2
                });
Unexecuted instantiation: _RNCINvMs_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB7_18InherentExtrinsics25inject_raw_inherents_listAhj8_INtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterTB1C_B1C_EKj1_EE0Bb_
540
1
541
1
                iter::once(len)
542
1
                    .map(either::Left)
543
1
                    .chain(encoded_list.map(either::Right))
544
1
            },
545
1
            storage_proof_size_behavior: runtime_call::StorageProofSizeBehavior::Unimplemented,
546
1
            storage_main_trie_changes: self.storage_changes.into_main_trie_diff(),
547
1
            max_log_level: self.shared.max_log_level,
548
1
            calculate_trie_changes: self.shared.calculate_trie_changes,
549
1
        });
550
551
1
        let vm = match init_result {
552
1
            Ok(vm) => vm,
553
0
            Err((err, proto)) => return BlockBuild::Finished(Err((Error::VmInit(err), proto))),
554
        };
555
556
1
        BlockBuild::from_inner(vm, self.shared)
557
1
    }
_RINvMs_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_18InherentExtrinsics25inject_raw_inherents_listAhj8_INtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterTB1z_B1z_EKj1_EEB9_
Line
Count
Source
518
1
    pub fn inject_raw_inherents_list(
519
1
        self,
520
1
        list: impl ExactSizeIterator<Item = ([u8; 8], impl AsRef<[u8]> + Clone)> + Clone,
521
1
    ) -> BlockBuild {
522
1
        debug_assert!(
matches!0
(self.shared.stage, Stage::InherentExtrinsics));
523
524
1
        let init_result = runtime_call::run(runtime_call::Config {
525
1
            virtual_machine: self.parent_runtime,
526
1
            function_to_call: "BlockBuilder_inherent_extrinsics",
527
1
            parameter: {
528
1
                // The `BlockBuilder_inherent_extrinsics` function expects a SCALE-encoded list of
529
1
                // tuples containing an "inherent identifier" (`[u8; 8]`) and a value (`Vec<u8>`).
530
1
                let len = util::encode_scale_compact_usize(list.len());
531
1
                let encoded_list = list.flat_map(|(id, value)| {
532
                    let value_len = util::encode_scale_compact_usize(value.as_ref().len());
533
                    let value_and_len = iter::once(value_len)
534
                        .map(either::Left)
535
                        .chain(iter::once(value).map(either::Right));
536
                    iter::once(id)
537
                        .map(either::Left)
538
                        .chain(value_and_len.map(either::Right))
539
1
                });
540
1
541
1
                iter::once(len)
542
1
                    .map(either::Left)
543
1
                    .chain(encoded_list.map(either::Right))
544
1
            },
545
1
            storage_proof_size_behavior: runtime_call::StorageProofSizeBehavior::Unimplemented,
546
1
            storage_main_trie_changes: self.storage_changes.into_main_trie_diff(),
547
1
            max_log_level: self.shared.max_log_level,
548
1
            calculate_trie_changes: self.shared.calculate_trie_changes,
549
1
        });
550
551
1
        let vm = match init_result {
552
1
            Ok(vm) => vm,
553
0
            Err((err, proto)) => return BlockBuild::Finished(Err((Error::VmInit(err), proto))),
554
        };
555
556
1
        BlockBuild::from_inner(vm, self.shared)
557
1
    }
Unexecuted instantiation: _RINvMs_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_18InherentExtrinsics25inject_raw_inherents_listAhj8_INtNtNtCsaYZPK01V26L_4core5array4iter8IntoIterTB1A_B1A_EKj1_EEB9_
558
}
559
560
/// More transactions can be added.
561
#[must_use]
562
pub struct ApplyExtrinsic {
563
    shared: Shared,
564
    parent_runtime: host::HostVmPrototype,
565
    storage_changes: StorageChanges,
566
}
567
568
impl ApplyExtrinsic {
569
    /// Adds a SCALE-encoded extrinsic and resumes execution.
570
    ///
571
    /// See the module-level documentation for more information.
572
0
    pub fn add_extrinsic(mut self, extrinsic: Vec<u8>) -> BlockBuild {
573
0
        let init_result = runtime_call::run(runtime_call::Config {
574
0
            virtual_machine: self.parent_runtime,
575
0
            function_to_call: "BlockBuilder_apply_extrinsic",
576
0
            parameter: iter::once(&extrinsic),
577
0
            storage_proof_size_behavior: runtime_call::StorageProofSizeBehavior::Unimplemented,
578
0
            storage_main_trie_changes: self.storage_changes.into_main_trie_diff(),
579
0
            max_log_level: self.shared.max_log_level,
580
0
            calculate_trie_changes: self.shared.calculate_trie_changes,
581
0
        });
582
0
583
0
        self.shared.stage = Stage::ApplyExtrinsic(extrinsic);
584
585
0
        let vm = match init_result {
586
0
            Ok(vm) => vm,
587
0
            Err((err, proto)) => return BlockBuild::Finished(Err((Error::VmInit(err), proto))),
588
        };
589
590
0
        BlockBuild::from_inner(vm, self.shared)
591
0
    }
Unexecuted instantiation: _RNvMs0_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_14ApplyExtrinsic13add_extrinsic
Unexecuted instantiation: _RNvMs0_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_14ApplyExtrinsic13add_extrinsic
592
593
    /// Indicate that no more extrinsics will be added, and resume execution.
594
1
    pub fn finish(mut self) -> BlockBuild {
595
1
        self.shared.stage = Stage::FinalizeBlock;
596
1
597
1
        let init_result = runtime_call::run(runtime_call::Config {
598
1
            virtual_machine: self.parent_runtime,
599
1
            function_to_call: "BlockBuilder_finalize_block",
600
1
            parameter: iter::empty::<&[u8]>(),
601
1
            storage_proof_size_behavior: runtime_call::StorageProofSizeBehavior::Unimplemented,
602
1
            storage_main_trie_changes: self.storage_changes.into_main_trie_diff(),
603
1
            max_log_level: self.shared.max_log_level,
604
1
            calculate_trie_changes: self.shared.calculate_trie_changes,
605
1
        });
606
607
1
        let vm = match init_result {
608
1
            Ok(vm) => vm,
609
0
            Err((err, proto)) => return BlockBuild::Finished(Err((Error::VmInit(err), proto))),
610
        };
611
612
1
        BlockBuild::from_inner(vm, self.shared)
613
1
    }
_RNvMs0_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_14ApplyExtrinsic6finish
Line
Count
Source
594
1
    pub fn finish(mut self) -> BlockBuild {
595
1
        self.shared.stage = Stage::FinalizeBlock;
596
1
597
1
        let init_result = runtime_call::run(runtime_call::Config {
598
1
            virtual_machine: self.parent_runtime,
599
1
            function_to_call: "BlockBuilder_finalize_block",
600
1
            parameter: iter::empty::<&[u8]>(),
601
1
            storage_proof_size_behavior: runtime_call::StorageProofSizeBehavior::Unimplemented,
602
1
            storage_main_trie_changes: self.storage_changes.into_main_trie_diff(),
603
1
            max_log_level: self.shared.max_log_level,
604
1
            calculate_trie_changes: self.shared.calculate_trie_changes,
605
1
        });
606
607
1
        let vm = match init_result {
608
1
            Ok(vm) => vm,
609
0
            Err((err, proto)) => return BlockBuild::Finished(Err((Error::VmInit(err), proto))),
610
        };
611
612
1
        BlockBuild::from_inner(vm, self.shared)
613
1
    }
Unexecuted instantiation: _RNvMs0_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_14ApplyExtrinsic6finish
614
}
615
616
/// Loading a storage value from the parent storage is required in order to continue.
617
#[must_use]
618
pub struct StorageGet(runtime_call::StorageGet, Shared);
619
620
impl StorageGet {
621
    /// Returns the key whose value must be passed to [`StorageGet::inject_value`].
622
8.72k
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
623
8.72k
        self.0.key()
624
8.72k
    }
_RNvMs1_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_10StorageGet3key
Line
Count
Source
622
8.72k
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
623
8.72k
        self.0.key()
624
8.72k
    }
Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_10StorageGet3key
625
626
    /// If `Some`, read from the given child trie. If `None`, read from the main trie.
627
0
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
628
0
        self.0.child_trie()
629
0
    }
Unexecuted instantiation: _RNvMs1_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_10StorageGet10child_trie
Unexecuted instantiation: _RNvMs1_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_10StorageGet10child_trie
630
631
    /// Injects the corresponding storage value.
632
146
    pub fn inject_value(
633
146
        self,
634
146
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>>, TrieEntryVersion)>,
635
146
    ) -> BlockBuild {
636
146
        BlockBuild::from_inner(self.0.inject_value(value), self.1)
637
146
    }
_RINvMs1_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1f_EEBa_
Line
Count
Source
632
146
    pub fn inject_value(
633
146
        self,
634
146
        value: Option<(impl Iterator<Item = impl AsRef<[u8]>>, TrieEntryVersion)>,
635
146
    ) -> BlockBuild {
636
146
        BlockBuild::from_inner(self.0.inject_value(value), self.1)
637
146
    }
Unexecuted instantiation: _RINvMs1_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB6_10StorageGet12inject_valueppEBa_
Unexecuted instantiation: _RINvMs1_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1g_EECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvMs1_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1g_EECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs1_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB6_10StorageGet12inject_valueRShINtNtNtNtCsaYZPK01V26L_4core4iter7sources4once4OnceB1g_EECsibGXYHQB8Ea_25json_rpc_general_requests
638
}
639
640
/// Obtaining the Merkle value of the closest descendant of a trie node is required in order
641
/// to continue.
642
#[must_use]
643
pub struct ClosestDescendantMerkleValue(runtime_call::ClosestDescendantMerkleValue, Shared);
644
645
impl ClosestDescendantMerkleValue {
646
    /// Returns the key whose closest descendant Merkle value must be passed to
647
    /// [`ClosestDescendantMerkleValue::inject_merkle_value`].
648
0
    pub fn key(&'_ self) -> impl Iterator<Item = Nibble> + '_ {
649
0
        self.0.key()
650
0
    }
Unexecuted instantiation: _RNvMs2_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_28ClosestDescendantMerkleValue3key
Unexecuted instantiation: _RNvMs2_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_28ClosestDescendantMerkleValue3key
651
652
    /// If `Some`, read from the given child trie. If `None`, read from the main trie.
653
0
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
654
0
        self.0.child_trie()
655
0
    }
Unexecuted instantiation: _RNvMs2_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_28ClosestDescendantMerkleValue10child_trie
Unexecuted instantiation: _RNvMs2_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_28ClosestDescendantMerkleValue10child_trie
656
657
    /// Indicate that the value is unknown and resume the calculation.
658
    ///
659
    /// This function be used if you are unaware of the Merkle value. The algorithm will perform
660
    /// the calculation of this Merkle value manually, which takes more time.
661
1.86k
    pub fn resume_unknown(self) -> BlockBuild {
662
1.86k
        BlockBuild::from_inner(self.0.resume_unknown(), self.1)
663
1.86k
    }
_RNvMs2_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_28ClosestDescendantMerkleValue14resume_unknown
Line
Count
Source
661
1.86k
    pub fn resume_unknown(self) -> BlockBuild {
662
1.86k
        BlockBuild::from_inner(self.0.resume_unknown(), self.1)
663
1.86k
    }
Unexecuted instantiation: _RNvMs2_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_28ClosestDescendantMerkleValue14resume_unknown
664
665
    /// Injects the corresponding Merkle value.
666
    ///
667
    /// `None` can be passed if there is no descendant or, in the case of a child trie read, in
668
    /// order to indicate that the child trie does not exist.
669
0
    pub fn inject_merkle_value(self, merkle_value: Option<&[u8]>) -> BlockBuild {
670
0
        BlockBuild::from_inner(self.0.inject_merkle_value(merkle_value), self.1)
671
0
    }
Unexecuted instantiation: _RNvMs2_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_28ClosestDescendantMerkleValue19inject_merkle_value
Unexecuted instantiation: _RNvMs2_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_28ClosestDescendantMerkleValue19inject_merkle_value
672
}
673
674
/// Fetching the key that follows a given one in the parent storage is required in order to
675
/// continue.
676
#[must_use]
677
pub struct NextKey(runtime_call::NextKey, Shared);
678
679
impl NextKey {
680
    /// Returns the key whose next key must be passed back.
681
2.19k
    pub fn key(&'_ self) -> impl Iterator<Item = Nibble> + '_ {
682
2.19k
        self.0.key()
683
2.19k
    }
_RNvMs3_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_7NextKey3key
Line
Count
Source
681
2.19k
    pub fn key(&'_ self) -> impl Iterator<Item = Nibble> + '_ {
682
2.19k
        self.0.key()
683
2.19k
    }
Unexecuted instantiation: _RNvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_7NextKey3key
684
685
    /// If `Some`, read from the given child trie. If `None`, read from the main trie.
686
0
    pub fn child_trie(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
687
0
        self.0.child_trie()
688
0
    }
Unexecuted instantiation: _RNvMs3_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_7NextKey10child_trie
Unexecuted instantiation: _RNvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_7NextKey10child_trie
689
690
    /// If `true`, then the provided value must the one superior or equal to the requested key.
691
    /// If `false`, then the provided value must be strictly superior to the requested key.
692
2.19k
    pub fn or_equal(&self) -> bool {
693
2.19k
        self.0.or_equal()
694
2.19k
    }
_RNvMs3_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_7NextKey8or_equal
Line
Count
Source
692
2.19k
    pub fn or_equal(&self) -> bool {
693
2.19k
        self.0.or_equal()
694
2.19k
    }
Unexecuted instantiation: _RNvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_7NextKey8or_equal
695
696
    /// If `true`, then the search must include both branch nodes and storage nodes. If `false`,
697
    /// the search only covers storage nodes.
698
2.19k
    pub fn branch_nodes(&self) -> bool {
699
2.19k
        self.0.branch_nodes()
700
2.19k
    }
_RNvMs3_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_7NextKey12branch_nodes
Line
Count
Source
698
2.19k
    pub fn branch_nodes(&self) -> bool {
699
2.19k
        self.0.branch_nodes()
700
2.19k
    }
Unexecuted instantiation: _RNvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_7NextKey12branch_nodes
701
702
    /// Returns the prefix the next key must start with. If the next key doesn't start with the
703
    /// given prefix, then `None` should be provided.
704
2.19k
    pub fn prefix(&'_ self) -> impl Iterator<Item = Nibble> + '_ {
705
2.19k
        self.0.prefix()
706
2.19k
    }
_RNvMs3_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_7NextKey6prefix
Line
Count
Source
704
2.19k
    pub fn prefix(&'_ self) -> impl Iterator<Item = Nibble> + '_ {
705
2.19k
        self.0.prefix()
706
2.19k
    }
Unexecuted instantiation: _RNvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_7NextKey6prefix
707
708
    /// Injects the key.
709
    ///
710
    /// # Panic
711
    ///
712
    /// Panics if the key passed as parameter isn't strictly superior to the requested key.
713
    ///
714
2.19k
    pub fn inject_key(self, key: Option<impl Iterator<Item = Nibble>>) -> BlockBuild {
715
2.19k
        BlockBuild::from_inner(self.0.inject_key(key), self.1)
716
2.19k
    }
_RINvMs3_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB6_7NextKey10inject_keyNtNtNtBa_4trie13branch_search21BranchTrieNodeKeyIterEBa_
Line
Count
Source
714
2.19k
    pub fn inject_key(self, key: Option<impl Iterator<Item = Nibble>>) -> BlockBuild {
715
2.19k
        BlockBuild::from_inner(self.0.inject_key(key), self.1)
716
2.19k
    }
Unexecuted instantiation: _RINvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB6_7NextKey10inject_keypEBa_
Unexecuted instantiation: _RINvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB6_7NextKey10inject_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhENCNCNCNvMs_NtCsiUjFBJteJ7x_17smoldot_full_node17consensus_serviceNtB2Z_14SyncBackground12author_block0s6_00EECsiLzmwikkc22_14json_rpc_basic
Unexecuted instantiation: _RINvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB6_7NextKey10inject_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhENCNCNCNvMs_NtCsiUjFBJteJ7x_17smoldot_full_node17consensus_serviceNtB2Z_14SyncBackground12author_block0s6_00EECscDgN54JpMGG_6author
Unexecuted instantiation: _RINvMs3_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB6_7NextKey10inject_keyINtNtNtNtCsaYZPK01V26L_4core4iter8adapters3map3MapINtNtNtCsdZExvAaxgia_5alloc3vec9into_iter8IntoIterhENCNCNCNvMs_NtCsiUjFBJteJ7x_17smoldot_full_node17consensus_serviceNtB2Z_14SyncBackground12author_block0s6_00EECsibGXYHQB8Ea_25json_rpc_general_requests
717
}
718
719
/// Setting the value of an offchain storage value is required.
720
#[must_use]
721
pub struct OffchainStorageSet(runtime_call::OffchainStorageSet, Shared);
722
723
impl OffchainStorageSet {
724
    /// Returns the key whose value must be set.
725
0
    pub fn key(&'_ self) -> impl AsRef<[u8]> + '_ {
726
0
        self.0.key()
727
0
    }
Unexecuted instantiation: _RNvMs4_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_18OffchainStorageSet3key
Unexecuted instantiation: _RNvMs4_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_18OffchainStorageSet3key
728
729
    /// Returns the value to set.
730
    ///
731
    /// If `None` is returned, the key should be removed from the storage entirely.
732
0
    pub fn value(&'_ self) -> Option<impl AsRef<[u8]> + '_> {
733
0
        self.0.value()
734
0
    }
Unexecuted instantiation: _RNvMs4_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_18OffchainStorageSet5value
Unexecuted instantiation: _RNvMs4_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_18OffchainStorageSet5value
735
736
    /// Resumes execution after having set the value.
737
0
    pub fn resume(self) -> BlockBuild {
738
0
        BlockBuild::from_inner(self.0.resume(), self.1)
739
0
    }
Unexecuted instantiation: _RNvMs4_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_18OffchainStorageSet6resume
Unexecuted instantiation: _RNvMs4_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_18OffchainStorageSet6resume
740
}
741
742
/// Analyzes the output of a call to `BlockBuilder_inherent_extrinsics`, and returns the resulting
743
/// extrinsics.
744
// TODO: this method implementation is hacky ; the `BlockBuilder_inherent_extrinsics` function
745
//       returns a `Vec<Extrinsic>`, where `Extrinsic` is opaque and depends on the chain. Because
746
//       we don't know the type of `Extrinsic`, a `Vec<Extrinsic>` is undecodable. However, most
747
//       Substrate chains use `type Extrinsic = OpaqueExtrinsic;` where
748
//       `type OpaqueExtrinsic = Vec<u8>;` here, which happens to start with a length prefix
749
//       containing its remaining size; this length prefix is fully part of the `Extrinsic` though.
750
//       In other words, this function might succeed or fail depending on the Substrate chain.
751
1
fn parse_inherent_extrinsics_output(output: &[u8]) -> Result<Vec<Vec<u8>>, Error> {
752
1
    nom::combinator::all_consuming(nom::combinator::flat_map(
753
1
        crate::util::nom_scale_compact_usize,
754
1
        |num_elems| {
755
1
            nom::multi::many_m_n(
756
1
                num_elems,
757
1
                num_elems,
758
1
                nom::combinator::map(
759
1
                    nom::combinator::recognize(nom::combinator::flat_map(
760
1
                        crate::util::nom_scale_compact_usize,
761
1
                        nom::bytes::streaming::take,
762
1
                    )),
763
1
                    |v: &[u8]| v.to_vec(),
_RNCNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime32parse_inherent_extrinsics_output00B9_
Line
Count
Source
763
1
                    |v: &[u8]| v.to_vec(),
Unexecuted instantiation: _RNCNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime32parse_inherent_extrinsics_output00B9_
764
1
                ),
765
1
            )
766
1
        },
_RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime32parse_inherent_extrinsics_output0B7_
Line
Count
Source
754
1
        |num_elems| {
755
1
            nom::multi::many_m_n(
756
1
                num_elems,
757
1
                num_elems,
758
1
                nom::combinator::map(
759
1
                    nom::combinator::recognize(nom::combinator::flat_map(
760
1
                        crate::util::nom_scale_compact_usize,
761
1
                        nom::bytes::streaming::take,
762
1
                    )),
763
1
                    |v: &[u8]| v.to_vec(),
764
1
                ),
765
1
            )
766
1
        },
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime32parse_inherent_extrinsics_output0B7_
767
1
    ))(output)
768
1
    .map(|(_, parse_result)| parse_result)
_RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime32parse_inherent_extrinsics_outputs_0B7_
Line
Count
Source
768
1
    .map(|(_, parse_result)| parse_result)
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime32parse_inherent_extrinsics_outputs_0B7_
769
1
    .map_err(|_: nom::Err<(&[u8], nom::error::ErrorKind)>| 
Error::BadInherentExtrinsicsOutput0
)
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime32parse_inherent_extrinsics_outputs0_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime32parse_inherent_extrinsics_outputs0_0B7_
770
1
}
_RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime32parse_inherent_extrinsics_output
Line
Count
Source
751
1
fn parse_inherent_extrinsics_output(output: &[u8]) -> Result<Vec<Vec<u8>>, Error> {
752
1
    nom::combinator::all_consuming(nom::combinator::flat_map(
753
1
        crate::util::nom_scale_compact_usize,
754
1
        |num_elems| {
755
            nom::multi::many_m_n(
756
                num_elems,
757
                num_elems,
758
                nom::combinator::map(
759
                    nom::combinator::recognize(nom::combinator::flat_map(
760
                        crate::util::nom_scale_compact_usize,
761
                        nom::bytes::streaming::take,
762
                    )),
763
                    |v: &[u8]| v.to_vec(),
764
                ),
765
            )
766
1
        },
767
1
    ))(output)
768
1
    .map(|(_, parse_result)| parse_result)
769
1
    .map_err(|_: nom::Err<(&[u8], nom::error::ErrorKind)>| Error::BadInherentExtrinsicsOutput)
770
1
}
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime32parse_inherent_extrinsics_output
771
772
/// Analyzes the output of a call to `BlockBuilder_apply_extrinsic`.
773
1
fn parse_apply_extrinsic_output(
774
1
    output: &[u8],
775
1
) -> Result<Result<Result<(), DispatchError>, TransactionValidityError>, Error> {
776
1
    nom::combinator::all_consuming(apply_extrinsic_result)(output)
777
1
        .map(|(_, parse_result)| parse_result)
_RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime28parse_apply_extrinsic_output0B7_
Line
Count
Source
777
1
        .map(|(_, parse_result)| parse_result)
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime28parse_apply_extrinsic_output0B7_
778
1
        .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| 
Error::BadApplyExtrinsicOutput0
)
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime28parse_apply_extrinsic_outputs_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime28parse_apply_extrinsic_outputs_0B7_
779
1
}
_RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime28parse_apply_extrinsic_output
Line
Count
Source
773
1
fn parse_apply_extrinsic_output(
774
1
    output: &[u8],
775
1
) -> Result<Result<Result<(), DispatchError>, TransactionValidityError>, Error> {
776
1
    nom::combinator::all_consuming(apply_extrinsic_result)(output)
777
1
        .map(|(_, parse_result)| parse_result)
778
1
        .map_err(|_: nom::Err<nom::error::Error<&[u8]>>| Error::BadApplyExtrinsicOutput)
779
1
}
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime28parse_apply_extrinsic_output
780
781
// TODO: some parsers below are common with the tx-pool ; figure out how/whether they should be merged
782
783
/// Errors that can occur while checking the validity of a transaction.
784
0
#[derive(Debug, derive_more::Display, Clone, PartialEq, Eq)]
Unexecuted instantiation: _RNvXsb_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_24TransactionValidityErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsb_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_24TransactionValidityErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
785
pub enum TransactionValidityError {
786
    /// The transaction is invalid.
787
    #[display(fmt = "Transaction is invalid: {_0}")]
788
    Invalid(InvalidTransaction),
789
    /// Transaction validity can't be determined.
790
    #[display(fmt = "Transaction validity couldn't be determined: {_0}")]
791
    Unknown(UnknownTransaction),
792
}
793
794
/// An invalid transaction validity.
795
0
#[derive(Debug, derive_more::Display, Clone, PartialEq, Eq)]
Unexecuted instantiation: _RNvXsh_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_18InvalidTransactionNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsh_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_18InvalidTransactionNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
796
pub enum InvalidTransaction {
797
    /// The call of the transaction is not expected.
798
    Call,
799
    /// General error to do with the inability to pay some fees (e.g. account balance too low).
800
    Payment,
801
    /// General error to do with the transaction not yet being valid (e.g. nonce too high).
802
    Future,
803
    /// General error to do with the transaction being outdated (e.g. nonce too low).
804
    Stale,
805
    /// General error to do with the transaction's proofs (e.g. signature).
806
    ///
807
    /// # Possible causes
808
    ///
809
    /// When using a signed extension that provides additional data for signing, it is required
810
    /// that the signing and the verifying side use the same additional data. Additional
811
    /// data will only be used to generate the signature, but will not be part of the transaction
812
    /// itself. As the verifying side does not know which additional data was used while signing
813
    /// it will only be able to assume a bad signature and cannot express a more meaningful error.
814
    BadProof,
815
    /// The transaction birth block is ancient.
816
    AncientBirthBlock,
817
    /// The transaction would exhaust the resources of current block.
818
    ///
819
    /// The transaction might be valid, but there are not enough resources
820
    /// left in the current block.
821
    ExhaustsResources,
822
    /// Any other custom invalid validity that is not covered by this enum.
823
    #[display(fmt = "Other reason (code: {_0})")]
824
    Custom(u8),
825
    /// An extrinsic with a Mandatory dispatch resulted in Error. This is indicative of either a
826
    /// malicious validator or a buggy `provide_inherent`. In any case, it can result in dangerously
827
    /// overweight blocks and therefore if found, invalidates the block.
828
    BadMandatory,
829
    /// A transaction with a mandatory dispatch. This is invalid; only inherent extrinsics are
830
    /// allowed to have mandatory dispatches.
831
    MandatoryDispatch,
832
}
833
834
/// An unknown transaction validity.
835
0
#[derive(Debug, derive_more::Display, Clone, PartialEq, Eq)]
Unexecuted instantiation: _RNvXsn_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_18UnknownTransactionNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXsn_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_18UnknownTransactionNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
836
pub enum UnknownTransaction {
837
    /// Could not lookup some information that is required to validate the transaction.
838
    CannotLookup,
839
    /// No validator found for the given unsigned transaction.
840
    NoUnsignedValidator,
841
    /// Any other custom unknown validity that is not covered by this enum.
842
    #[display(fmt = "Other reason (code: {_0})")]
843
    Custom(u8),
844
}
845
846
/// Reason why a dispatch call failed.
847
0
#[derive(Debug, derive_more::Display, Clone, PartialEq, Eq)]
Unexecuted instantiation: _RNvXst_NtNtCsN16ciHI6Qf_7smoldot6author7runtimeNtB5_13DispatchErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
Unexecuted instantiation: _RNvXst_NtNtCseuYC0Zibziv_7smoldot6author7runtimeNtB5_13DispatchErrorNtNtCsaYZPK01V26L_4core3fmt7Display3fmt
848
pub enum DispatchError {
849
    /// Failed to lookup some data.
850
    CannotLookup,
851
    /// A bad origin.
852
    BadOrigin,
853
    /// A custom error in a module.
854
    #[display(fmt = "Error in module #{index}, error number #{error}")]
855
    Module {
856
        /// Module index, matching the metadata module index.
857
        index: u8,
858
        /// Module specific error value.
859
        error: u8,
860
    },
861
}
862
863
1
fn apply_extrinsic_result(
864
1
    bytes: &[u8],
865
1
) -> nom::IResult<&[u8], Result<Result<(), DispatchError>, TransactionValidityError>> {
866
1
    nom::error::context(
867
1
        "apply extrinsic result",
868
1
        nom::branch::alt((
869
1
            nom::combinator::map(
870
1
                nom::sequence::preceded(nom::bytes::streaming::tag(&[0]), dispatch_outcome),
871
1
                Ok,
872
1
            ),
873
1
            nom::combinator::map(
874
1
                nom::sequence::preceded(
875
1
                    nom::bytes::streaming::tag(&[1]),
876
1
                    transaction_validity_error,
877
1
                ),
878
1
                Err,
879
1
            ),
880
1
        )),
881
1
    )(bytes)
882
1
}
_RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime22apply_extrinsic_result
Line
Count
Source
863
1
fn apply_extrinsic_result(
864
1
    bytes: &[u8],
865
1
) -> nom::IResult<&[u8], Result<Result<(), DispatchError>, TransactionValidityError>> {
866
1
    nom::error::context(
867
1
        "apply extrinsic result",
868
1
        nom::branch::alt((
869
1
            nom::combinator::map(
870
1
                nom::sequence::preceded(nom::bytes::streaming::tag(&[0]), dispatch_outcome),
871
1
                Ok,
872
1
            ),
873
1
            nom::combinator::map(
874
1
                nom::sequence::preceded(
875
1
                    nom::bytes::streaming::tag(&[1]),
876
1
                    transaction_validity_error,
877
1
                ),
878
1
                Err,
879
1
            ),
880
1
        )),
881
1
    )(bytes)
882
1
}
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime22apply_extrinsic_result
883
884
1
fn dispatch_outcome(bytes: &[u8]) -> nom::IResult<&[u8], Result<(), DispatchError>> {
885
1
    nom::error::context(
886
1
        "dispatch outcome",
887
1
        nom::branch::alt((
888
1
            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| Ok(())),
_RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime16dispatch_outcome0B7_
Line
Count
Source
888
1
            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| Ok(())),
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime16dispatch_outcome0B7_
889
1
            nom::combinator::map(
890
1
                nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), dispatch_error),
891
1
                Err,
892
1
            ),
893
1
        )),
894
1
    )(bytes)
895
1
}
_RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime16dispatch_outcome
Line
Count
Source
884
1
fn dispatch_outcome(bytes: &[u8]) -> nom::IResult<&[u8], Result<(), DispatchError>> {
885
1
    nom::error::context(
886
1
        "dispatch outcome",
887
1
        nom::branch::alt((
888
1
            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| Ok(())),
889
1
            nom::combinator::map(
890
1
                nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), dispatch_error),
891
1
                Err,
892
1
            ),
893
1
        )),
894
1
    )(bytes)
895
1
}
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime16dispatch_outcome
896
897
0
fn dispatch_error(bytes: &[u8]) -> nom::IResult<&[u8], DispatchError> {
898
0
    nom::error::context(
899
0
        "dispatch error",
900
0
        nom::branch::alt((
901
0
            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
902
0
                DispatchError::CannotLookup
903
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime14dispatch_error0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime14dispatch_error0B7_
904
0
            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
905
0
                DispatchError::BadOrigin
906
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime14dispatch_errors_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime14dispatch_errors_0B7_
907
0
            nom::combinator::map(
908
0
                nom::sequence::preceded(
909
0
                    nom::bytes::streaming::tag(&[2]),
910
0
                    nom::sequence::tuple((nom::number::streaming::u8, nom::number::streaming::u8)),
911
0
                ),
912
0
                |(index, error)| DispatchError::Module { index, error },
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime14dispatch_errors0_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime14dispatch_errors0_0B7_
913
0
            ),
914
0
        )),
915
0
    )(bytes)
916
0
}
Unexecuted instantiation: _RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime14dispatch_error
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime14dispatch_error
917
918
0
fn transaction_validity_error(bytes: &[u8]) -> nom::IResult<&[u8], TransactionValidityError> {
919
0
    nom::error::context(
920
0
        "transaction validity error",
921
0
        nom::branch::alt((
922
0
            nom::combinator::map(
923
0
                nom::sequence::preceded(nom::bytes::streaming::tag(&[0]), invalid_transaction),
924
0
                TransactionValidityError::Invalid,
925
0
            ),
926
0
            nom::combinator::map(
927
0
                nom::sequence::preceded(nom::bytes::streaming::tag(&[1]), unknown_transaction),
928
0
                TransactionValidityError::Unknown,
929
0
            ),
930
0
        )),
931
0
    )(bytes)
932
0
}
Unexecuted instantiation: _RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime26transaction_validity_error
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime26transaction_validity_error
933
934
0
fn invalid_transaction(bytes: &[u8]) -> nom::IResult<&[u8], InvalidTransaction> {
935
0
    nom::error::context(
936
0
        "invalid transaction",
937
0
        nom::branch::alt((
938
0
            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
939
0
                InvalidTransaction::Call
940
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transaction0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transaction0B7_
941
0
            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
942
0
                InvalidTransaction::Payment
943
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions_0B7_
944
0
            nom::combinator::map(nom::bytes::streaming::tag(&[2]), |_| {
945
0
                InvalidTransaction::Future
946
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions0_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions0_0B7_
947
0
            nom::combinator::map(nom::bytes::streaming::tag(&[3]), |_| {
948
0
                InvalidTransaction::Stale
949
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions1_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions1_0B7_
950
0
            nom::combinator::map(nom::bytes::streaming::tag(&[4]), |_| {
951
0
                InvalidTransaction::BadProof
952
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions2_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions2_0B7_
953
0
            nom::combinator::map(nom::bytes::streaming::tag(&[5]), |_| {
954
0
                InvalidTransaction::AncientBirthBlock
955
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions3_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions3_0B7_
956
0
            nom::combinator::map(nom::bytes::streaming::tag(&[6]), |_| {
957
0
                InvalidTransaction::ExhaustsResources
958
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions4_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions4_0B7_
959
0
            nom::combinator::map(
960
0
                nom::sequence::preceded(
961
0
                    nom::bytes::streaming::tag(&[7]),
962
0
                    nom::bytes::streaming::take(1u32),
963
0
                ),
964
0
                |n: &[u8]| InvalidTransaction::Custom(n[0]),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions5_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions5_0B7_
965
0
            ),
966
0
            nom::combinator::map(nom::bytes::streaming::tag(&[8]), |_| {
967
0
                InvalidTransaction::BadMandatory
968
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions6_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions6_0B7_
969
0
            nom::combinator::map(nom::bytes::streaming::tag(&[9]), |_| {
970
0
                InvalidTransaction::MandatoryDispatch
971
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transactions7_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transactions7_0B7_
972
0
        )),
973
0
    )(bytes)
974
0
}
Unexecuted instantiation: _RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19invalid_transaction
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19invalid_transaction
975
976
0
fn unknown_transaction(bytes: &[u8]) -> nom::IResult<&[u8], UnknownTransaction> {
977
0
    nom::error::context(
978
0
        "unknown transaction",
979
0
        nom::branch::alt((
980
0
            nom::combinator::map(nom::bytes::streaming::tag(&[0]), |_| {
981
0
                UnknownTransaction::CannotLookup
982
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19unknown_transaction0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19unknown_transaction0B7_
983
0
            nom::combinator::map(nom::bytes::streaming::tag(&[1]), |_| {
984
0
                UnknownTransaction::NoUnsignedValidator
985
0
            }),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19unknown_transactions_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19unknown_transactions_0B7_
986
0
            nom::combinator::map(
987
0
                nom::sequence::preceded(
988
0
                    nom::bytes::streaming::tag(&[2]),
989
0
                    nom::bytes::streaming::take(1u32),
990
0
                ),
991
0
                |n: &[u8]| UnknownTransaction::Custom(n[0]),
Unexecuted instantiation: _RNCNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19unknown_transactions0_0B7_
Unexecuted instantiation: _RNCNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19unknown_transactions0_0B7_
992
0
            ),
993
0
        )),
994
0
    )(bytes)
995
0
}
Unexecuted instantiation: _RNvNtNtCsN16ciHI6Qf_7smoldot6author7runtime19unknown_transaction
Unexecuted instantiation: _RNvNtNtCseuYC0Zibziv_7smoldot6author7runtime19unknown_transaction