use crate::{build_executor, LiveState, SharedParams, State, LOG_TARGET};
use sc_executor::sp_wasm_interface::HostFunctions;
use sp_runtime::traits::{Block as BlockT, NumberFor};
use std::{fmt::Debug, str::FromStr};
use substrate_rpc_client::{ws_client, StateApi};
#[derive(Debug, Clone, clap::Parser)]
pub struct CreateSnapshotCmd {
#[clap(flatten)]
pub from: LiveState,
pub snapshot_path: Option<String>,
}
pub(crate) async fn create_snapshot<Block, HostFns>(
shared: SharedParams,
command: CreateSnapshotCmd,
) -> sc_cli::Result<()>
where
Block: BlockT + serde::de::DeserializeOwned,
Block::Hash: serde::de::DeserializeOwned,
Block::Header: serde::de::DeserializeOwned,
<Block::Hash as FromStr>::Err: Debug,
NumberFor<Block>: FromStr,
<NumberFor<Block> as FromStr>::Err: Debug,
HostFns: HostFunctions,
{
let snapshot_path = command.snapshot_path;
if !matches!(shared.runtime, crate::Runtime::Existing) {
return Err("creating a snapshot is only possible with --runtime existing.".into())
}
let path = match snapshot_path {
Some(path) => path,
None => {
let rpc = ws_client(&command.from.uri).await.unwrap();
let remote_spec = StateApi::<Block::Hash>::runtime_version(&rpc, None).await.unwrap();
let path_str = format!(
"{}-{}@{}.snap",
remote_spec.spec_name.to_lowercase(),
remote_spec.spec_version,
command.from.at.clone().unwrap_or("latest".to_owned())
);
log::info!(target: LOG_TARGET, "snapshot path not provided (-s), using '{}'", path_str);
path_str.into()
},
};
let executor = build_executor::<HostFns>(&shared);
let _ = State::Live(command.from)
.into_ext::<Block, HostFns>(&shared, &executor, Some(path.into()), false)
.await?;
Ok(())
}