Skip to content

Commit

Permalink
Check that the snapshot is for the previous block
Browse files Browse the repository at this point in the history
  • Loading branch information
gshep committed Oct 18, 2024
1 parent 03c28a2 commit 540ad56
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
35 changes: 25 additions & 10 deletions utils/gear-replay-cli/src/cmd/replay_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! Replaying a block on top of the corresponding chain state

use crate::{
build_executor, fetch_block, full_extensions,
build_executor, fetch_block, fetch_header, full_extensions,
shared_parameters::SharedParams,
state::{LiveState, SnapState, State},
state_machine_call, BlockHashOrNumber, LOG_TARGET,
Expand All @@ -31,7 +31,7 @@ use sc_executor::sp_wasm_interface::ExtendedHostFunctions;
#[cfg(all(not(feature = "always-wasm"), feature = "vara-native"))]
use service::VaraExecutorDispatch;
use sp_runtime::{
traits::{Block as BlockT, Header as HeaderT},
traits::{Block as BlockT, Header as HeaderT, One},
DeserializeOwned,
};
use std::fmt::Debug;
Expand Down Expand Up @@ -94,14 +94,6 @@ where
// Initialize the RPC client.
let rpc = ws_client(&block_ws_uri).await?;

let ext = match command.state {
State::Live(live_state) => {
let prev_block_live_state = live_state.prev_block_live_state().await?;
State::Live(prev_block_live_state).to_ext(None).await?
}
State::Snap(snap_state) => State::Snap(snap_state).to_ext(None).await?,
};

let current_hash = match execute_at {
Some(b) => Some(b.as_hash(&rpc).await?),
_ => None,
Expand All @@ -110,6 +102,29 @@ where
log::info!(target: LOG_TARGET, "Fetching block {:?} ", current_hash);
let block = fetch_block::<Block>(&rpc, current_hash).await?;

let ext = match command.state {
State::Live(live_state) => {
let prev_block_live_state = live_state.prev_block_live_state().await?;
State::Live(prev_block_live_state).to_ext(None).await?
}

State::Snap(snap_state) => {
let ext = State::Snap(snap_state).to_ext(None).await?;

let header_previous = fetch_header::<Block>(&rpc, Some(ext.block_hash)).await?;
let expected = *block.header().number() - One::one();
if *header_previous.number() != expected {
let message = format!(
"Expected snapshot for block number {expected}, but got a snapshot for {}",
header_previous.number()
);
return Err(message.into());
}

ext
}
};

let (mut header, mut extrinsics) = block.deconstruct();

// A digest item gets added when the runtime is processing the block, so we need to pop
Expand Down
16 changes: 16 additions & 0 deletions utils/gear-replay-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,22 @@ where
)
}

pub(crate) async fn fetch_header<Block>(
rpc: &WsClient,
hash: Option<HashFor<Block>>,
) -> sc_cli::Result<Block::Header>
where
Block: BlockT + DeserializeOwned,
Block::Header: DeserializeOwned,
{
Ok(
ChainApi::<(), Block::Hash, Block::Header, SignedBlock<Block>>::header(rpc, hash)
.await
.map_err(rpc_err_handler)?
.expect("header should exist"),
)
}

pub(crate) fn rpc_err_handler(error: impl Debug) -> &'static str {
log::error!(target: LOG_TARGET, "rpc error: {:?}", error);
"rpc error."
Expand Down

0 comments on commit 540ad56

Please sign in to comment.