Skip to content

Commit

Permalink
move block creation out of fast forward
Browse files Browse the repository at this point in the history
  • Loading branch information
liamaharon committed May 10, 2024
1 parent 9632a14 commit 4f7e04e
Show file tree
Hide file tree
Showing 14 changed files with 220 additions and 179 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ zstd = { workspace = true }

frame-remote-externalities = { workspace = true }
frame-try-runtime = { workspace = true, features=["try-runtime"] }
frame-support = { workspace = true }

sc-cli = { workspace = true }
sc-executor = { workspace = true }
Expand Down
192 changes: 16 additions & 176 deletions core/src/commands/fast_forward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,29 @@

use std::{fmt::Debug, str::FromStr};

use parity_scale_codec::{Decode, Encode};
use parity_scale_codec::{Encode};
use sc_cli::Result;
use sc_executor::{sp_wasm_interface::HostFunctions, WasmExecutor};
use sc_executor::{sp_wasm_interface::HostFunctions};
use serde::de::DeserializeOwned;
use sp_core::H256;
use sp_inherents::InherentData;

use sp_runtime::{
traits::{HashingFor, Header, NumberFor, One},
Digest,
traits::{NumberFor},
};
use sp_state_machine::TestExternalities;


use crate::{
common::{
empty_block_creation::inherents::{
pre_apply::pre_apply_inherents,
providers::{InherentProvider, ProviderVariant},
empty_block::{
inherents::{
providers::{ProviderVariant},
},
production::execute_next_block,
},
state::{
build_executor, state_machine_call, state_machine_call_with_proof, RuntimeChecks, State,
build_executor, state_machine_call_with_proof, RuntimeChecks, State,
},
},
full_extensions, BlockT, SharedParams,
}, BlockT, SharedParams,
};

/// Configuration for [`run`].
Expand Down Expand Up @@ -74,134 +74,6 @@ pub struct Command {
pub state: State,
}

/// Call `method` with `data` and return the result. `externalities` will not change.
fn dry_call<T: Decode, Block: BlockT, HostFns: HostFunctions>(
externalities: &TestExternalities<HashingFor<Block>>,
executor: &WasmExecutor<HostFns>,
method: &'static str,
data: &[u8],
) -> Result<T> {
let (_, result) = state_machine_call::<Block, HostFns>(
externalities,
executor,
method,
data,
full_extensions(executor.clone()),
)?;

Ok(<T>::decode(&mut &*result)?)
}

/// Call `method` with `data` and actually save storage changes to `externalities`.
async fn call<Block: BlockT, HostFns: HostFunctions>(
externalities: &mut TestExternalities<HashingFor<Block>>,
executor: &WasmExecutor<HostFns>,
method: &'static str,
data: &[u8],
) -> Result<()> {
let (mut changes, _) = state_machine_call::<Block, HostFns>(
externalities,
executor,
method,
data,
full_extensions(executor.clone()),
)?;

let storage_changes =
changes.drain_storage_changes(&externalities.backend, externalities.state_version)?;

externalities.backend.apply_transaction(
storage_changes.transaction_storage_root,
storage_changes.transaction,
);

Ok(())
}

/// Produces next block containing only inherents.
async fn produce_next_block<Block: BlockT, HostFns: HostFunctions>(
externalities: &mut TestExternalities<HashingFor<Block>>,
executor: &WasmExecutor<HostFns>,
parent_header: Block::Header,
chain: ProviderVariant,
previous_block_building_info: Option<(InherentData, Digest)>,
) -> Result<(Block, Option<(InherentData, Digest)>)>
where
Block: BlockT<Hash = H256> + DeserializeOwned,
Block::Header: DeserializeOwned,
<Block::Hash as FromStr>::Err: Debug,
NumberFor<Block>: FromStr,
<NumberFor<Block> as FromStr>::Err: Debug,
{
let (inherent_data_provider, pre_digest) =
<ProviderVariant as InherentProvider<Block>>::get_inherent_providers_and_pre_digest(
&chain,
previous_block_building_info,
parent_header.clone(),
externalities,
)?;

pre_apply_inherents::<Block>(externalities);
let inherent_data = inherent_data_provider
.create_inherent_data()
.await
.map_err(|s| sc_cli::Error::Input(s.to_string()))?;
let digest = Digest { logs: pre_digest };

let header = Block::Header::new(
*parent_header.number() + One::one(),
Default::default(),
Default::default(),
parent_header.hash(),
digest.clone(),
);

call::<Block, _>(
externalities,
executor,
"Core_initialize_block",
&header.encode(),
)
.await?;

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

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

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

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

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

pub async fn run<Block, HostFns>(shared: SharedParams, command: Command) -> Result<()>
where
Block: BlockT<Hash = H256> + DeserializeOwned,
Expand Down Expand Up @@ -242,50 +114,18 @@ where
let mut parent_block_building_info = None;

for _ in 1..=command.n_blocks {
// We are saving state before we overwrite it while producing new block.
let backend = inner_ext.as_backend();

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>(
let (next_block_building_info, next_header) = execute_next_block::<Block, HostFns>(
&mut inner_ext,
&executor,
parent_block_building_info,
parent_header.clone(),
command.provider_variant,
parent_block_building_info,
)
.await?;

log::info!("Produced a new block: {:?}", next_block.header());

// And now we restore previous state.
inner_ext.backend = backend;

pre_apply_inherents::<Block>(&mut inner_ext);
let state_root_check = true;
let signature_check = true;
let payload = (
next_block.clone(),
state_root_check,
signature_check,
command.try_state.clone(),
)
.encode();
call::<Block, _>(
&mut inner_ext,
&executor,
"TryRuntime_execute_block",
&payload,
)
.await?;

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

parent_block_building_info = new_block_building_info;
parent_header = next_block.header().clone();
parent_block_building_info = Some(next_block_building_info);
parent_header = next_header;
}

Ok(())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use sp_std::prelude::*;
use strum::IntoEnumIterator;
use strum_macros::{Display, EnumIter};

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

/// Trait for providing the inherent data and digest items for block construction.
pub trait InherentProvider<B: BlockT> {
Expand Down
2 changes: 2 additions & 0 deletions core/src/common/empty_block/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod inherents;
pub mod production;
Loading

0 comments on commit 4f7e04e

Please sign in to comment.