Skip to content

Commit 10f2a2a

Browse files
pmikolajczyk41ark0f
authored andcommitted
try-runtime::fast-forward (paritytech#12896)
* try-runtime::fast-forward * Revert un`pub`ing command's fields * Handle storage change failure * Adjust Substrate node * Feature-gated imports * doc link * Feature-gated imports in node-template * Move trait, blanket implementation and auxiliary functions to a new module * Distinguish between plain babe+timestamp and substrate enhanced info * Remove uncles inherents * Missing argument * Add doc comment about `blocktime_millis` * Add licenses
1 parent c9e7dba commit 10f2a2a

File tree

8 files changed

+473
-4
lines changed

8 files changed

+473
-4
lines changed

Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bin/node-template/node/src/command.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli};
1010
use sc_service::PartialComponents;
1111
use sp_keyring::Sr25519Keyring;
1212

13+
#[cfg(feature = "try-runtime")]
14+
use try_runtime_cli::block_building_info::timestamp_with_aura_info;
15+
1316
impl SubstrateCli for Cli {
1417
fn impl_name() -> String {
1518
"Substrate Node".into()
@@ -184,11 +187,13 @@ pub fn run() -> sc_cli::Result<()> {
184187
let task_manager =
185188
sc_service::TaskManager::new(config.tokio_handle.clone(), registry)
186189
.map_err(|e| sc_cli::Error::Service(sc_service::Error::Prometheus(e)))?;
190+
let info_provider = timestamp_with_aura_info(6000);
191+
187192
Ok((
188193
cmd.run::<Block, ExtendedHostFunctions<
189194
sp_io::SubstrateHostFunctions,
190195
<ExecutorDispatch as NativeExecutionDispatch>::ExtendHostFunctions,
191-
>>(),
196+
>, _>(Some(info_provider)),
192197
task_manager,
193198
))
194199
})

bin/node/cli/src/command.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ use sp_keyring::Sr25519Keyring;
3232

3333
use std::sync::Arc;
3434

35+
#[cfg(feature = "try-runtime")]
36+
use {
37+
kitchensink_runtime::constants::time::SLOT_DURATION,
38+
try_runtime_cli::block_building_info::substrate_info,
39+
};
40+
3541
impl SubstrateCli for Cli {
3642
fn impl_name() -> String {
3743
"Substrate Node".into()
@@ -236,11 +242,13 @@ pub fn run() -> Result<()> {
236242
sc_service::TaskManager::new(config.tokio_handle.clone(), registry)
237243
.map_err(|e| sc_cli::Error::Service(sc_service::Error::Prometheus(e)))?;
238244

245+
let info_provider = substrate_info(SLOT_DURATION);
246+
239247
Ok((
240248
cmd.run::<Block, ExtendedHostFunctions<
241249
sp_io::SubstrateHostFunctions,
242250
<ExecutorDispatch as NativeExecutionDispatch>::ExtendHostFunctions,
243-
>>(),
251+
>, _>(Some(info_provider)),
244252
task_manager,
245253
))
246254
})

utils/frame/try-runtime/cli/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,26 @@ remote-externalities = { version = "0.10.0-dev", path = "../../remote-externalit
1616
sc-cli = { version = "0.10.0-dev", path = "../../../../client/cli" }
1717
sc-executor = { version = "0.10.0-dev", path = "../../../../client/executor" }
1818
sc-service = { version = "0.10.0-dev", default-features = false, path = "../../../../client/service" }
19+
sp-consensus-aura = { path = "../../../../primitives/consensus/aura" }
20+
sp-consensus-babe = { path = "../../../../primitives/consensus/babe" }
1921
sp-core = { version = "7.0.0", path = "../../../../primitives/core" }
2022
sp-externalities = { version = "0.13.0", path = "../../../../primitives/externalities" }
23+
sp-inherents = { path = "../../../../primitives/inherents" }
2124
sp-io = { version = "7.0.0", path = "../../../../primitives/io" }
2225
sp-keystore = { version = "0.13.0", path = "../../../../primitives/keystore" }
2326
sp-runtime = { version = "7.0.0", path = "../../../../primitives/runtime" }
2427
sp-rpc = { version = "6.0.0", path = "../../../../primitives/rpc" }
2528
sp-state-machine = { version = "0.13.0", path = "../../../../primitives/state-machine" }
29+
sp-timestamp = { path = "../../../../primitives/timestamp" }
30+
sp-transaction-storage-proof = { path = "../../../../primitives/transaction-storage-proof" }
2631
sp-version = { version = "5.0.0", path = "../../../../primitives/version" }
2732
sp-debug-derive = { path = "../../../../primitives/debug-derive" }
2833
sp-api = { path = "../../../../primitives/api" }
2934
sp-weights = { version = "4.0.0", path = "../../../../primitives/weights" }
3035
frame-try-runtime = { optional = true, path = "../../../../frame/try-runtime" }
3136
substrate-rpc-client = { path = "../../rpc/client" }
3237

38+
async-trait = "0.1.57"
3339
clap = { version = "4.0.9", features = ["derive"] }
3440
hex = { version = "0.4.3", default-features = false }
3541
log = "0.4.17"
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// This file is part of Substrate.
2+
3+
// Copyright (C) 2021-2022 Parity Technologies (UK) Ltd.
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
use crate::BlockT;
19+
use parity_scale_codec::Encode;
20+
use sc_cli::Result;
21+
use sp_consensus_aura::{Slot, SlotDuration, AURA_ENGINE_ID};
22+
use sp_consensus_babe::{
23+
digests::{PreDigest, SecondaryPlainPreDigest},
24+
BABE_ENGINE_ID,
25+
};
26+
use sp_inherents::{InherentData, InherentDataProvider};
27+
use sp_runtime::{Digest, DigestItem};
28+
use sp_timestamp::TimestampInherentData;
29+
30+
/// Something that can create inherent data providers and pre-runtime digest.
31+
///
32+
/// It is possible for the caller to provide custom arguments to the callee by setting the
33+
/// `ExtraArgs` generic parameter.
34+
///
35+
/// This module already provides some convenience implementation of this trait for closures. So, it
36+
/// should not be required to implement it directly.
37+
#[async_trait::async_trait]
38+
pub trait BlockBuildingInfoProvider<Block: BlockT, ExtraArgs = ()> {
39+
type InherentDataProviders: InherentDataProvider;
40+
41+
async fn get_inherent_providers_and_pre_digest(
42+
&self,
43+
parent_hash: Block::Hash,
44+
extra_args: ExtraArgs,
45+
) -> Result<(Self::InherentDataProviders, Vec<DigestItem>)>;
46+
}
47+
48+
#[async_trait::async_trait]
49+
impl<F, Block, IDP, ExtraArgs, Fut> BlockBuildingInfoProvider<Block, ExtraArgs> for F
50+
where
51+
Block: BlockT,
52+
F: Fn(Block::Hash, ExtraArgs) -> Fut + Sync + Send,
53+
Fut: std::future::Future<Output = Result<(IDP, Vec<DigestItem>)>> + Send + 'static,
54+
IDP: InherentDataProvider + 'static,
55+
ExtraArgs: Send + 'static,
56+
{
57+
type InherentDataProviders = IDP;
58+
59+
async fn get_inherent_providers_and_pre_digest(
60+
&self,
61+
parent: Block::Hash,
62+
extra_args: ExtraArgs,
63+
) -> Result<(Self::InherentDataProviders, Vec<DigestItem>)> {
64+
(*self)(parent, extra_args).await
65+
}
66+
}
67+
68+
/// Provides [`BlockBuildingInfoProvider`] implementation for chains that include timestamp inherent
69+
/// and use Aura for a block production.
70+
///
71+
/// It depends only on the expected block production frequency, i.e. `blocktime_millis`.
72+
pub fn timestamp_with_aura_info<Block: BlockT>(
73+
blocktime_millis: u64,
74+
) -> impl BlockBuildingInfoProvider<Block, Option<(InherentData, Digest)>> {
75+
move |_, maybe_prev_info: Option<(InherentData, Digest)>| async move {
76+
let timestamp_idp = match maybe_prev_info {
77+
Some((inherent_data, _)) => sp_timestamp::InherentDataProvider::new(
78+
inherent_data.timestamp_inherent_data().unwrap().unwrap() + blocktime_millis,
79+
),
80+
None => sp_timestamp::InherentDataProvider::from_system_time(),
81+
};
82+
83+
let slot =
84+
Slot::from_timestamp(*timestamp_idp, SlotDuration::from_millis(blocktime_millis));
85+
let digest = vec![DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())];
86+
87+
Ok((timestamp_idp, digest))
88+
}
89+
}
90+
91+
/// Provides [`BlockBuildingInfoProvider`] implementation for chains that include timestamp inherent
92+
/// and use Babe for a block production.
93+
///
94+
/// It depends only on the expected block production frequency, i.e. `blocktime_millis`.
95+
pub fn timestamp_with_babe_info<Block: BlockT>(
96+
blocktime_millis: u64,
97+
) -> impl BlockBuildingInfoProvider<Block, Option<(InherentData, Digest)>> {
98+
move |_, maybe_prev_info: Option<(InherentData, Digest)>| async move {
99+
let timestamp_idp = match maybe_prev_info {
100+
Some((inherent_data, _)) => sp_timestamp::InherentDataProvider::new(
101+
inherent_data.timestamp_inherent_data().unwrap().unwrap() + blocktime_millis,
102+
),
103+
None => sp_timestamp::InherentDataProvider::from_system_time(),
104+
};
105+
106+
let slot =
107+
Slot::from_timestamp(*timestamp_idp, SlotDuration::from_millis(blocktime_millis));
108+
let slot_idp = sp_consensus_babe::inherents::InherentDataProvider::new(slot);
109+
110+
let digest = vec![DigestItem::PreRuntime(
111+
BABE_ENGINE_ID,
112+
PreDigest::SecondaryPlain(SecondaryPlainPreDigest { slot, authority_index: 0 })
113+
.encode(),
114+
)];
115+
116+
Ok(((slot_idp, timestamp_idp), digest))
117+
}
118+
}
119+
120+
/// Provides [`BlockBuildingInfoProvider`] implementation for chains that use:
121+
/// - timestamp inherent,
122+
/// - Babe for a block production (inherent + digest),
123+
/// - uncles inherent,
124+
/// - storage proof inherent
125+
///
126+
/// It depends only on the expected block production frequency, i.e. `blocktime_millis`.
127+
pub fn substrate_info<Block: BlockT>(
128+
blocktime_millis: u64,
129+
) -> impl BlockBuildingInfoProvider<Block, Option<(InherentData, Digest)>> {
130+
move |_, maybe_prev_info: Option<(InherentData, Digest)>| async move {
131+
let timestamp_idp = match maybe_prev_info {
132+
Some((inherent_data, _)) => sp_timestamp::InherentDataProvider::new(
133+
inherent_data.timestamp_inherent_data().unwrap().unwrap() + blocktime_millis,
134+
),
135+
None => sp_timestamp::InherentDataProvider::from_system_time(),
136+
};
137+
138+
let slot =
139+
Slot::from_timestamp(*timestamp_idp, SlotDuration::from_millis(blocktime_millis));
140+
let slot_idp = sp_consensus_babe::inherents::InherentDataProvider::new(slot);
141+
142+
let storage_proof_idp = sp_transaction_storage_proof::InherentDataProvider::new(None);
143+
144+
let digest = vec![DigestItem::PreRuntime(
145+
BABE_ENGINE_ID,
146+
PreDigest::SecondaryPlain(SecondaryPlainPreDigest { slot, authority_index: 0 })
147+
.encode(),
148+
)];
149+
150+
Ok(((slot_idp, timestamp_idp, storage_proof_idp), digest))
151+
}
152+
}

0 commit comments

Comments
 (0)