Skip to content

Commit

Permalink
generalize also the block input
Browse files Browse the repository at this point in the history
  • Loading branch information
Wollac committed Dec 16, 2024
1 parent 5599b10 commit 157a96d
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 43 deletions.
45 changes: 27 additions & 18 deletions steel/src/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,39 @@
// 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<H> {
pub struct Input<H> {
header: H,
state_trie: MerkleTrie,
storage_tries: Vec<MerkleTrie>,
contracts: Vec<Bytes>,
ancestors: Vec<H>,
}

impl<H: EvmBlockHeader> BlockInput<H> {
/// Input committing to the corresponding execution block hash.
pub type BlockInput<H> = ComposeInput<H, BlockCommit>;

/// A commitment to an execution block hash, along with the corresponding block number.
#[derive(Clone, Serialize, Deserialize)]
pub struct BlockCommit;

impl<H: EvmBlockHeader> BlockHeaderCommit<H> for BlockCommit {
#[inline]
fn commit(self, header: &Sealed<H>, config_id: B256) -> Commitment {
Commitment::new(
CommitmentVersion::Block as u16,
header.number(),
header.seal(),
config_id,
)
}
}

impl<H: EvmBlockHeader> Input<H> {
/// Converts the input into a [EvmEnv] for verifiable state access in the guest.
pub fn into_env(self) -> GuestEvmEnv<H> {
// verify that the state root matches the state trie
Expand Down Expand Up @@ -64,22 +79,16 @@ impl<H: EvmBlockHeader> BlockInput<H> {
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())
}
}

#[cfg(feature = "host")]
pub mod host {
use std::fmt::Display;

use super::BlockInput;
use super::Input;
use crate::{
host::db::{AlloyDb, ProofDb, ProviderDb},
EvmBlockHeader,
Expand All @@ -89,7 +98,7 @@ pub mod host {
use anyhow::{anyhow, ensure};
use log::debug;

impl<H: EvmBlockHeader> BlockInput<H> {
impl<H: EvmBlockHeader> Input<H> {
/// Creates the `BlockInput` containing the necessary EVM state that can be verified against
/// the block hash.
pub(crate) async fn from_proof_db<T, N, P>(
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions steel/src/host/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<H> EvmEnv<(), H, ()> {
/// Creates a builder for building an environment.
Expand Down Expand Up @@ -187,7 +188,7 @@ impl<P, H, B> EvmEnvBuilder<P, H, B> {

impl<P, H> EvmEnvBuilder<P, H, ()> {
/// Builds and returns an [EvmEnv] with the configured settings that commits to a block hash.
pub async fn build<T, N>(self) -> Result<HostEvmEnv<AlloyDb<T, N, P>, H, ()>>
pub async fn build<T, N>(self) -> Result<HostEvmEnv<AlloyDb<T, N, P>, H, BlockCommit>>
where
T: Transport + Clone,
N: Network,
Expand All @@ -208,7 +209,7 @@ impl<P, H> EvmEnvBuilder<P, H, ()> {
header.seal(),
));
let commit = HostCommit {
inner: (),
inner: BlockCommit,
config_id: ChainSpec::DEFAULT_DIGEST,
};

Expand Down
37 changes: 20 additions & 17 deletions steel/src/host/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use std::{

use crate::{
beacon::BeaconCommit,
block::BlockInput,
block::Input,
config::ChainSpec,
ethereum::{EthBlockHeader, EthEvmEnv},
history::HistoryCommit,
Expand All @@ -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.
Expand Down Expand Up @@ -177,7 +178,17 @@ impl<D, H: EvmBlockHeader, C> HostEvmEnv<D, H, C> {
}
}

impl<T, N, P, H> HostEvmEnv<AlloyDb<T, N, P>, H, ()>
impl<D, H: EvmBlockHeader, C: Clone + BlockHeaderCommit<H>> HostEvmEnv<D, H, C> {
/// 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<T, N, P, H> HostEvmEnv<AlloyDb<T, N, P>, H, BlockCommit>
where
T: Transport + Clone,
N: Network,
Expand All @@ -187,19 +198,11 @@ where
{
/// Converts the environment into a [EvmInput] committing to an execution block hash.
pub async fn into_input(self) -> Result<EvmInput<H>> {
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<D, H: EvmBlockHeader, C: Clone + BlockHeaderCommit<H>> HostEvmEnv<D, H, C> {
/// 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,
)))
}
}

Expand All @@ -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<EvmInput<EthBlockHeader>> {
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,
Expand All @@ -228,7 +231,7 @@ where
/// block roots.
#[stability::unstable(feature = "history")]
pub async fn into_input(self) -> Result<EvmInput<EthBlockHeader>> {
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,
Expand All @@ -250,7 +253,7 @@ where
pub async fn into_beacon_input(self, url: Url) -> Result<EvmInput<EthBlockHeader>> {
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)))
}
Expand Down
12 changes: 7 additions & 5 deletions steel/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -76,6 +75,8 @@ impl<H: EvmBlockHeader> EvmInput<H> {
}
}



/// A trait linking the block header to a commitment.
pub trait BlockHeaderCommit<H: EvmBlockHeader> {
/// Creates a verifiable [Commitment] of the `header`.
Expand All @@ -88,18 +89,18 @@ pub trait BlockHeaderCommit<H: EvmBlockHeader> {
/// contained within the `input` field.
#[derive(Clone, Serialize, Deserialize)]
pub struct ComposeInput<H, C> {
input: BlockInput<H>,
input: Input<H>,
commit: C,
}

impl<H: EvmBlockHeader, C: BlockHeaderCommit<H>> ComposeInput<H, C> {
/// Creates a new composed input from a [BlockInput] and a [BlockHeaderCommit].
pub const fn new(input: BlockInput<H>, commit: C) -> Self {
/// Creates a new composed input from a [Input] and a [BlockHeaderCommit].
pub const fn new(input: Input<H>, commit: C) -> Self {
Self { input, commit }
}

/// Disassembles this `ComposeInput`, returning the underlying input and commitment creator.
pub fn into_parts(self) -> (BlockInput<H>, C) {
pub fn into_parts(self) -> (Input<H>, C) {
(self.input, self.commit)
}

Expand Down Expand Up @@ -227,6 +228,7 @@ mod private {
}

pub use private::Commitment;
use crate::block::{BlockInput, Input};

/// Version of a [`Commitment`].
#[repr(u16)]
Expand Down
3 changes: 2 additions & 1 deletion steel/tests/corruption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(),
}
}
Expand Down

0 comments on commit 157a96d

Please sign in to comment.