diff --git a/steel/src/block.rs b/steel/src/block.rs index ffde7fc7..2d781401 100644 --- a/steel/src/block.rs +++ b/steel/src/block.rs @@ -12,16 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::{ - config::ChainSpec, state::StateDb, Commitment, CommitmentVersion, EvmBlockHeader, EvmEnv, - GuestEvmEnv, MerkleTrie, -}; +use crate::{state::StateDb, BlockHeaderCommit, Commitment, CommitmentVersion, ComposeInput, EvmBlockHeader, EvmEnv, GuestEvmEnv, MerkleTrie}; use ::serde::{Deserialize, Serialize}; -use alloy_primitives::{map::HashMap, Bytes}; +use alloy_primitives::{map::HashMap, Bytes, Sealed, B256}; -/// Input committing to the corresponding execution block hash. #[derive(Clone, Serialize, Deserialize)] -pub struct BlockInput { +pub struct Input { header: H, state_trie: MerkleTrie, storage_tries: Vec, @@ -29,7 +25,26 @@ pub struct BlockInput { ancestors: Vec, } -impl BlockInput { +/// Input committing to the corresponding execution block hash. +pub type BlockInput = ComposeInput; + +/// A commitment to an execution block hash, along with the corresponding block number. +#[derive(Clone, Serialize, Deserialize)] +pub struct BlockCommit; + +impl BlockHeaderCommit for BlockCommit { + #[inline] + fn commit(self, header: &Sealed, config_id: B256) -> Commitment { + Commitment::new( + CommitmentVersion::Block as u16, + header.number(), + header.seal(), + config_id, + ) + } +} + +impl Input { /// Converts the input into a [EvmEnv] for verifiable state access in the guest. pub fn into_env(self) -> GuestEvmEnv { // verify that the state root matches the state trie @@ -64,14 +79,8 @@ impl BlockInput { self.contracts, block_hashes, ); - let commit = Commitment::new( - CommitmentVersion::Block as u16, - header.number(), - header.seal(), - ChainSpec::DEFAULT_DIGEST, - ); - EvmEnv::new(db, header, commit) + EvmEnv::new(db, header, Commitment::default()) } } @@ -79,7 +88,7 @@ impl BlockInput { pub mod host { use std::fmt::Display; - use super::BlockInput; + use super::Input; use crate::{ host::db::{AlloyDb, ProofDb, ProviderDb}, EvmBlockHeader, @@ -89,7 +98,7 @@ pub mod host { use anyhow::{anyhow, ensure}; use log::debug; - impl BlockInput { + impl Input { /// Creates the `BlockInput` containing the necessary EVM state that can be verified against /// the block hash. pub(crate) async fn from_proof_db( @@ -132,7 +141,7 @@ pub mod host { debug!("contracts: {}", contracts.len()); debug!("ancestor blocks: {}", ancestors.len()); - let input = BlockInput { + let input = Input { header: header.into_inner(), state_trie, storage_tries, diff --git a/steel/src/host/builder.rs b/steel/src/host/builder.rs index 4d02712c..bf03773b 100644 --- a/steel/src/host/builder.rs +++ b/steel/src/host/builder.rs @@ -35,6 +35,7 @@ use alloy_primitives::Sealed; use anyhow::{anyhow, ensure, Context, Result}; use std::{fmt::Display, marker::PhantomData}; use url::Url; +use crate::block::BlockCommit; impl EvmEnv<(), H, ()> { /// Creates a builder for building an environment. @@ -187,7 +188,7 @@ impl EvmEnvBuilder { impl EvmEnvBuilder { /// Builds and returns an [EvmEnv] with the configured settings that commits to a block hash. - pub async fn build(self) -> Result, H, ()>> + pub async fn build(self) -> Result, H, BlockCommit>> where T: Transport + Clone, N: Network, @@ -208,7 +209,7 @@ impl EvmEnvBuilder { header.seal(), )); let commit = HostCommit { - inner: (), + inner: BlockCommit, config_id: ChainSpec::DEFAULT_DIGEST, }; diff --git a/steel/src/host/mod.rs b/steel/src/host/mod.rs index 26a29c98..1ee6b10c 100644 --- a/steel/src/host/mod.rs +++ b/steel/src/host/mod.rs @@ -20,7 +20,7 @@ use std::{ use crate::{ beacon::BeaconCommit, - block::BlockInput, + block::Input, config::ChainSpec, ethereum::{EthBlockHeader, EthEvmEnv}, history::HistoryCommit, @@ -44,6 +44,7 @@ mod builder; pub mod db; pub use builder::EvmEnvBuilder; +use crate::block::BlockCommit; /// A block number (or tag - "latest", "safe", "finalized"). /// This enum is used to specify which block to query when interacting with the blockchain. @@ -177,7 +178,17 @@ impl HostEvmEnv { } } -impl HostEvmEnv, H, ()> +impl> HostEvmEnv { + /// Returns the [Commitment] used to validate the environment. + pub fn commitment(&self) -> Commitment { + self.commit + .inner + .clone() + .commit(&self.header, self.commit.config_id) + } +} + +impl HostEvmEnv, H, BlockCommit> where T: Transport + Clone, N: Network, @@ -187,19 +198,11 @@ where { /// Converts the environment into a [EvmInput] committing to an execution block hash. pub async fn into_input(self) -> Result> { - let input = BlockInput::from_proof_db(self.db.unwrap(), self.header).await?; + let input = Input::from_proof_db(self.db.unwrap(), self.header).await?; - Ok(EvmInput::Block(input)) - } -} - -impl> HostEvmEnv { - /// Returns the [Commitment] used to validate the environment. - pub fn commitment(&self) -> Commitment { - self.commit - .inner - .clone() - .commit(&self.header, self.commit.config_id) + Ok(EvmInput::Block(ComposeInput::new( + input, self.commit.inner, + ))) } } @@ -210,7 +213,7 @@ where { /// Converts the environment into a [EvmInput] committing to a Beacon Chain block root. pub async fn into_input(self) -> Result> { - let input = BlockInput::from_proof_db(self.db.unwrap(), self.header).await?; + let input = Input::from_proof_db(self.db.unwrap(), self.header).await?; Ok(EvmInput::Beacon(ComposeInput::new( input, @@ -228,7 +231,7 @@ where /// block roots. #[stability::unstable(feature = "history")] pub async fn into_input(self) -> Result> { - let input = BlockInput::from_proof_db(self.db.unwrap(), self.header).await?; + let input = Input::from_proof_db(self.db.unwrap(), self.header).await?; Ok(EvmInput::History(ComposeInput::new( input, @@ -250,7 +253,7 @@ where pub async fn into_beacon_input(self, url: Url) -> Result> { let commit = BeaconCommit::from_header(self.header(), self.db().inner().provider(), url).await?; - let input = BlockInput::from_proof_db(self.db.unwrap(), self.header).await?; + let input = Input::from_proof_db(self.db.unwrap(), self.header).await?; Ok(EvmInput::Beacon(ComposeInput::new(input, commit))) } diff --git a/steel/src/lib.rs b/steel/src/lib.rs index 47323b4d..770facc5 100644 --- a/steel/src/lib.rs +++ b/steel/src/lib.rs @@ -39,7 +39,6 @@ mod state; mod verifier; pub use beacon::BeaconInput; -pub use block::BlockInput; pub use contract::{CallBuilder, Contract}; pub use mpt::MerkleTrie; pub use state::{StateAccount, StateDb}; @@ -76,6 +75,8 @@ impl EvmInput { } } + + /// A trait linking the block header to a commitment. pub trait BlockHeaderCommit { /// Creates a verifiable [Commitment] of the `header`. @@ -88,18 +89,18 @@ pub trait BlockHeaderCommit { /// contained within the `input` field. #[derive(Clone, Serialize, Deserialize)] pub struct ComposeInput { - input: BlockInput, + input: Input, commit: C, } impl> ComposeInput { - /// Creates a new composed input from a [BlockInput] and a [BlockHeaderCommit]. - pub const fn new(input: BlockInput, commit: C) -> Self { + /// Creates a new composed input from a [Input] and a [BlockHeaderCommit]. + pub const fn new(input: Input, commit: C) -> Self { Self { input, commit } } /// Disassembles this `ComposeInput`, returning the underlying input and commitment creator. - pub fn into_parts(self) -> (BlockInput, C) { + pub fn into_parts(self) -> (Input, C) { (self.input, self.commit) } @@ -227,6 +228,7 @@ mod private { } pub use private::Commitment; +use crate::block::{BlockInput, Input}; /// Version of a [`Commitment`]. #[repr(u16)] diff --git a/steel/tests/corruption.rs b/steel/tests/corruption.rs index 33309f7d..50691272 100644 --- a/steel/tests/corruption.rs +++ b/steel/tests/corruption.rs @@ -162,8 +162,9 @@ async fn load_or_create<'a, T: serde::ser::Serialize + serde::de::DeserializeOwn fn get_block_input_mut(input: &mut Value) -> &mut Value { let (key, value) = input.as_object_mut().unwrap().into_iter().next().unwrap(); match key.as_str() { - "Block" => value, + "Block" => &mut value["input"], "Beacon" => &mut value["input"], + "History" => &mut value["input"], _ => unreachable!(), } }