Skip to content

Commit

Permalink
blocktime arg
Browse files Browse the repository at this point in the history
  • Loading branch information
liamaharon committed May 20, 2024
1 parent 2254202 commit 00e2962
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 77 deletions.
2 changes: 1 addition & 1 deletion core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
# Crates.io
tokio = { workspace = true }
async-trait = { workspace = true }
array-bytes = { workspace = true }
polkadot-primitives = { workspace = true }
Expand Down Expand Up @@ -64,7 +65,6 @@ similar-asserts = "1.5.0"
assert_cmd = { workspace = true }
regex = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true }

sc-service = { workspace = true }
substrate-cli-test-utils = { workspace = true, features = ["try-runtime"] }
Expand Down
18 changes: 7 additions & 11 deletions core/src/commands/fast_forward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::{
fmt::Debug,
str::FromStr,
sync::{Arc, Mutex},
};
use std::{fmt::Debug, str::FromStr, sync::Arc, time::Duration};

use parity_scale_codec::Encode;
use sc_cli::Result;
use sc_executor::sp_wasm_interface::HostFunctions;
use serde::de::DeserializeOwned;
use sp_core::H256;
use sp_runtime::traits::NumberFor;
use tokio::sync::Mutex;

use crate::{
common::{
Expand All @@ -43,11 +40,9 @@ pub struct Command {
#[arg(long)]
pub n_blocks: u64,

/// Which inherent provider variant to use. In most cases "smart" should be used, which
/// attempts to support all chains.
#[arg(long, default_value = "smart")]
#[clap(value_enum)]
pub provider_variant: ProviderVariant,
/// The chain blocktime in milliseconds.
#[arg(long, default_value = "6000")]
pub blocktime: u64,

/// Which try-state targets to execute when running this command.
///
Expand Down Expand Up @@ -108,14 +103,15 @@ where
let inner_ext = Arc::new(Mutex::new(ext.inner_ext));
let mut parent_header = ext.header.clone();
let mut parent_block_building_info = None;
let provider_variant = ProviderVariant::Smart(Duration::from_millis(command.blocktime));

for _ in 1..=command.n_blocks {
let (next_block_building_info, next_header) = mine_block::<Block, HostFns>(
inner_ext.clone(),
&executor,
parent_block_building_info,
parent_header.clone(),
command.provider_variant,
provider_variant,
command.try_state.clone(),
)
.await?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! Inherent data provider for the [cumulus parachin inherents](https://github.com/paritytech/polkadot-sdk/blob/master/cumulus/primitives/parachain-inherent/src/lib.rs)
//! for empty block production on top of an existing externalities.
use std::sync::{Arc, Mutex};
use std::{ops::DerefMut, sync::Arc};

use parity_scale_codec::{Decode, Encode};
use polkadot_primitives::{BlockNumber, HeadData};
Expand All @@ -27,6 +27,7 @@ use sp_core::twox_128;
use sp_inherents::InherentIdentifier;
use sp_runtime::traits::{Block as BlockT, HashingFor, NumberFor};
use sp_state_machine::TestExternalities;
use tokio::sync::Mutex;

/// Get the para id if it exists
pub fn get_para_id<B: BlockT>(ext: &mut TestExternalities<HashingFor<B>>) -> Option<u32> {
Expand Down Expand Up @@ -61,7 +62,7 @@ pub struct InherentDataProvider<B: BlockT> {
pub timestamp: sp_timestamp::Timestamp,
pub blocktime_millis: u64,
pub parent_header: B::Header,
pub ext: Arc<Mutex<TestExternalities<HashingFor<B>>>>,
pub ext_mutex: Arc<Mutex<TestExternalities<HashingFor<B>>>>,
}

#[async_trait::async_trait]
Expand All @@ -70,9 +71,10 @@ impl<B: BlockT> sp_inherents::InherentDataProvider for InherentDataProvider<B> {
&self,
inherent_data: &mut sp_inherents::InherentData,
) -> Result<(), sp_inherents::Error> {
let maybe_last_relay_chain_block_number =
get_last_relay_chain_block_number::<B>(&mut self.ext.lock().unwrap());
let maybe_para_id = get_para_id::<B>(&mut self.ext.lock().unwrap());
let mut ext_guard = self.ext_mutex.lock().await;
let ext = ext_guard.deref_mut();
let maybe_last_relay_chain_block_number = get_last_relay_chain_block_number::<B>(ext);
let maybe_para_id = get_para_id::<B>(ext);
let (last_relay_chain_block_number, para_id) =
match (maybe_last_relay_chain_block_number, maybe_para_id) {
(Some(last_relay_chain_block_number), Some(para_id)) => {
Expand Down
30 changes: 13 additions & 17 deletions core/src/common/empty_block/inherents/providers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,8 @@

//! Contains providers for inherents required for empty block production.
use std::{
sync::{Arc, Mutex},
time::Duration,
};
use std::{sync::Arc, time::Duration};

use clap::ValueEnum;
use parity_scale_codec::Encode;
use sp_consensus_aura::{Slot, SlotDuration, AURA_ENGINE_ID};
use sp_consensus_babe::{
Expand All @@ -37,6 +33,7 @@ use sp_runtime::{
use sp_state_machine::TestExternalities;
use sp_std::prelude::*;
use strum_macros::{Display, EnumIter};
use tokio::sync::Mutex;

use crate::common::empty_block::inherents::custom_idps;

Expand All @@ -60,12 +57,13 @@ type InherentProviderResult<Err> =
///
/// Currently only Smart is implemented. New implementations may be added if Smart is not suitable
/// for some edge cases.
#[derive(Debug, Clone, clap::Parser, EnumIter, Display, Copy, ValueEnum)]
#[clap(rename_all = "snake_case")]
#[derive(Debug, Clone, EnumIter, Display, Copy)]
pub enum ProviderVariant {
/// Smart chain varient will automatically adjust provided inherents based on the given
/// externalities.
Smart,
///
/// The blocktime is provided in milliseconds.
Smart(core::time::Duration),
}

impl<B: BlockT> InherentProvider<B> for ProviderVariant {
Expand All @@ -78,9 +76,9 @@ impl<B: BlockT> InherentProvider<B> for ProviderVariant {
ext: Arc<Mutex<TestExternalities<HashingFor<B>>>>,
) -> InherentProviderResult<Self::Err> {
match *self {
ProviderVariant::Smart => {
<SmartInherentProvider as InherentProvider<B>>::get_inherent_providers_and_pre_digest(&SmartInherentProvider {
blocktime: Duration::from_secs(6),
ProviderVariant::Smart(blocktime) => {
<SmartInherentProvider as InherentProvider<B>>::get_inherent_providers_and_pre_digest(&SmartInherentProvider {
blocktime,
}, maybe_parent_info, parent_header, ext)
}
}
Expand Down Expand Up @@ -108,24 +106,22 @@ impl<B: BlockT> InherentProvider<B> for SmartInherentProvider {
parent_header: B::Header,
ext: Arc<Mutex<TestExternalities<HashingFor<B>>>>,
) -> InherentProviderResult<Self::Err> {
let blocktime_millis = self.blocktime.as_millis() as u64;

let timestamp_idp = custom_idps::timestamp::InherentDataProvider {
blocktime_millis,
blocktime_millis: self.blocktime.as_millis() as u64,
maybe_parent_info,
};
let para_parachain_idp = custom_idps::para_parachain::InherentDataProvider::<B> {
blocktime_millis,
blocktime_millis: self.blocktime.as_millis() as u64,
parent_header: parent_header.clone(),
timestamp: timestamp_idp.timestamp(),
ext,
ext_mutex: ext,
};
let relay_parachain_data_idp =
custom_idps::relay_parachains::InherentDataProvider::<B>::new(parent_header);

let slot = Slot::from_timestamp(
timestamp_idp.timestamp(),
SlotDuration::from_millis(blocktime_millis),
SlotDuration::from_millis(self.blocktime.as_millis() as u64),
);
let digest = vec![
DigestItem::PreRuntime(
Expand Down
73 changes: 30 additions & 43 deletions core/src/common/empty_block/production.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
use std::{
ops::DerefMut,
str::FromStr,
sync::{Arc, Mutex},
};
use std::{ops::DerefMut, str::FromStr, sync::Arc};

use parity_scale_codec::{Decode, Encode};
use sc_cli::Result;
Expand All @@ -15,6 +11,7 @@ use sp_runtime::{
};
use sp_state_machine::TestExternalities;
use sp_std::fmt::Debug;
use tokio::sync::Mutex;

use super::inherents::{pre_apply::pre_apply_inherents, providers::InherentProvider};
use crate::{
Expand All @@ -23,7 +20,7 @@ use crate::{
};

pub async fn mine_block<Block: BlockT, HostFns: HostFunctions>(

Check failure on line 22 in core/src/common/empty_block/production.rs

View workflow job for this annotation

GitHub Actions / clippy

bound is defined in more than one place

error: bound is defined in more than one place --> core/src/common/empty_block/production.rs:22:25 | 22 | pub async fn mine_block<Block: BlockT, HostFns: HostFunctions>( | ^^^^^ ... 31 | Block: BlockT<Hash = H256> + DeserializeOwned, | ^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#multiple_bound_locations = note: `-D clippy::multiple-bound-locations` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::multiple_bound_locations)]`
ext: Arc<Mutex<TestExternalities<HashingFor<Block>>>>,
ext_mutex: Arc<Mutex<TestExternalities<HashingFor<Block>>>>,
executor: &WasmExecutor<HostFns>,
previous_block_building_info: Option<(InherentData, Digest)>,
parent_header: Block::Header,
Expand All @@ -38,15 +35,18 @@ where
<NumberFor<Block> as FromStr>::Err: Debug,
{
// We are saving state before we overwrite it while producing new block.
let backend = ext.lock().unwrap().deref_mut().as_backend();
let mut ext_guard = ext_mutex.lock().await;
let ext = ext_guard.deref_mut();
let backend = ext.as_backend();
drop(ext_guard);

log::info!(
"Producing new empty block at height {:?}",
*parent_header.number() + One::one()
);

let (next_block, new_block_building_info) = produce_next_block::<Block, HostFns>(
ext.clone(),
ext_mutex.clone(),
executor,
parent_header.clone(),
provider_variant,
Expand All @@ -59,10 +59,13 @@ where
array_bytes::bytes2hex("0x", next_block.header().hash())
);

let mut ext_guard = ext_mutex.lock().await;
let ext = ext_guard.deref_mut();

// And now we restore previous state.
ext.lock().unwrap().deref_mut().backend = backend;
ext.backend = backend;

pre_apply_inherents::<Block>(ext.lock().unwrap().deref_mut());
pre_apply_inherents::<Block>(ext);
let state_root_check = true;
let signature_check = true;
let payload = (
Expand All @@ -72,13 +75,7 @@ where
try_state,
)
.encode();
call::<Block, _>(
ext.lock().unwrap().deref_mut(),
executor,
"TryRuntime_execute_block",
&payload,
)
.await?;
call::<Block, _>(ext, executor, "TryRuntime_execute_block", &payload).await?;

log::info!("Executed the new block");

Expand All @@ -87,7 +84,7 @@ where

/// Produces next block containing only inherents.
pub async fn produce_next_block<Block: BlockT, HostFns: HostFunctions>(

Check failure on line 86 in core/src/common/empty_block/production.rs

View workflow job for this annotation

GitHub Actions / clippy

bound is defined in more than one place

error: bound is defined in more than one place --> core/src/common/empty_block/production.rs:86:33 | 86 | pub async fn produce_next_block<Block: BlockT, HostFns: HostFunctions>( | ^^^^^ ... 94 | Block: BlockT<Hash = H256> + DeserializeOwned, | ^^^^^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#multiple_bound_locations
externalities: Arc<Mutex<TestExternalities<HashingFor<Block>>>>,
ext_mutex: Arc<Mutex<TestExternalities<HashingFor<Block>>>>,
executor: &WasmExecutor<HostFns>,
parent_header: Block::Header,
chain: ProviderVariant,
Expand All @@ -105,10 +102,14 @@ where
&chain,
previous_block_building_info,
parent_header.clone(),
externalities.clone(),
ext_mutex.clone(),
)?;

pre_apply_inherents::<Block>(externalities.clone().lock().unwrap().deref_mut());
let mut ext_guard = ext_mutex.lock().await;
let ext = ext_guard.deref_mut();

pre_apply_inherents::<Block>(ext);
drop(ext_guard);
let inherent_data = inherent_data_provider
.create_inherent_data()
.await
Expand All @@ -123,45 +124,31 @@ where
digest.clone(),
);

call::<Block, _>(
externalities.lock().unwrap().deref_mut(),
executor,
"Core_initialize_block",
&header.encode(),
)
.await?;
let mut ext_guard = ext_mutex.lock().await;
let ext = ext_guard.deref_mut();
call::<Block, _>(ext, executor, "Core_initialize_block", &header.encode()).await?;

let extrinsics = dry_call::<Vec<Block::Extrinsic>, Block, _>(
externalities.lock().unwrap().deref_mut(),
ext,
executor,
"BlockBuilder_inherent_extrinsics",
&inherent_data.encode(),
)?;

for xt in &extrinsics {
call::<Block, _>(
externalities.lock().unwrap().deref_mut(),
executor,
"BlockBuilder_apply_extrinsic",
&xt.encode(),
)
.await?;
call::<Block, _>(ext, executor, "BlockBuilder_apply_extrinsic", &xt.encode()).await?;
}

let header = dry_call::<Block::Header, Block, _>(
externalities.lock().unwrap().deref_mut(),
ext,
executor,
"BlockBuilder_finalize_block",
&[0u8; 0],
)?;

call::<Block, _>(
externalities.lock().unwrap().deref_mut(),
executor,
"BlockBuilder_finalize_block",
&[0u8; 0],
)
.await?;
call::<Block, _>(ext, executor, "BlockBuilder_finalize_block", &[0u8; 0]).await?;

drop(ext_guard);

Ok((Block::new(header, extrinsics), (inherent_data, digest)))
}
Expand Down

0 comments on commit 00e2962

Please sign in to comment.