Skip to content

Commit

Permalink
♻ continue refactors
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Jan 15, 2024
1 parent 98eeab3 commit 2c7726f
Show file tree
Hide file tree
Showing 17 changed files with 782 additions and 453 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = ["crates/*"]

[workspace.package]
edition = "2021"
version = "0.0.1"
version = "0.1.0"
authors = ["clabby"]

[workspace.dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/fault/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! The fault module contains types and traits related to the FaultDisputeGame.

#![allow(unused, dead_code)]
#![allow(dead_code, unused_imports)]

#[cfg(test)]
extern crate proptest;
Expand Down
15 changes: 7 additions & 8 deletions crates/fault/src/providers/cannon.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
//! This module contains the implementation of the [crate::TraceProvider] trait for calling out to `cannon` to fetch
//! state witnesses and proof values.

use crate::{Gindex, Position, TraceProvider};
use alloy_primitives::keccak256;
use crate::{Position, TraceProvider};
use anyhow::Result;
use durin_primitives::Claim;
use std::{marker::PhantomData, sync::Arc};
use std::sync::Arc;

/// The [CannonTraceProvider] is a [TraceProvider] that runs `cannon` to retrieve state witnesses and proof values.
pub struct CannonTraceProvider {
pub split_depth: u8,
}

#[async_trait::async_trait]
impl TraceProvider<[u8; 32]> for CannonTraceProvider {
async fn absolute_prestate(&self) -> Result<Arc<[u8; 32]>> {
impl TraceProvider for CannonTraceProvider {
async fn absolute_prestate(&self, _: Position) -> Result<Arc<[u8]>> {
todo!()
}

async fn absolute_prestate_hash(&self) -> Result<Claim> {
async fn absolute_prestate_hash(&self, _: Position) -> Result<Claim> {
todo!()
}

async fn state_at(&self, position: Position) -> Result<Arc<[u8; 32]>> {
async fn state_at(&self, _: Position) -> Result<Arc<[u8]>> {
todo!()
}

async fn state_hash(&self, position: Position) -> Result<Claim> {
async fn state_hash(&self, _: Position) -> Result<Claim> {
todo!()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,31 +28,31 @@ impl AlphabetTraceProvider {
}

#[async_trait::async_trait]
impl TraceProvider<[u8; 32]> for AlphabetTraceProvider {
async fn absolute_prestate(&self) -> Result<Arc<[u8; 32]>> {
impl TraceProvider for AlphabetTraceProvider {
async fn absolute_prestate(&self, _: Position) -> Result<Arc<[u8]>> {
Ok(Arc::new(self.absolute_prestate))
}

async fn absolute_prestate_hash(&self) -> Result<Claim> {
async fn absolute_prestate_hash(&self, _: Position) -> Result<Claim> {
let prestate = U256::from_be_bytes(self.absolute_prestate);
let mut prestate_hash = keccak256(<sol!(uint256)>::abi_encode(&prestate));
prestate_hash[0] = VMStatus::Unfinished as u8;
Ok(prestate_hash)
}

async fn state_at(&self, position: Position) -> Result<Arc<[u8; 32]>> {
async fn state_at(&self, position: Position) -> Result<Arc<[u8]>> {
let absolute_prestate = u64::from_be_bytes(self.absolute_prestate[24..32].try_into()?);
let trace_index = position.trace_index(self.max_depth);

// TODO: Handle wrapping.
let state = absolute_prestate + trace_index + 1;
Ok(Arc::new(U256::from(state).to_be_bytes()))
Ok(Arc::<[u8; 32]>::new(U256::from(state).to_be_bytes()))
}

async fn state_hash(&self, position: Position) -> Result<Claim> {
let state: [u8; 32] = (*self.state_at(position).await?).try_into()?;
let state_sol = (
U256::from(position.trace_index(self.max_depth)),
U256::from_be_bytes(*self.state_at(position).await?),
U256::from_be_bytes(state),
);
let mut state_hash = keccak256(AlphabetClaimConstruction::abi_encode(&state_sol));
state_hash[0] = VMStatus::Invalid as u8;
Expand All @@ -77,14 +77,17 @@ mod test {
max_depth: 4,
};

let prestate_sol = U256::from_be_bytes(*provider.absolute_prestate().await.unwrap());
let prestate_bytes: [u8; 32] = (*provider.absolute_prestate(0).await.unwrap())
.try_into()
.unwrap();
let prestate_sol = U256::from_be_bytes(prestate_bytes);
let prestate = <sol!(uint256)>::abi_encode(&prestate_sol);
assert_eq!(
hex!("0000000000000000000000000000000000000000000000000000000000000061"),
prestate.as_slice()
);

let mut prestate_hash = provider.absolute_prestate_hash().await.unwrap();
let mut prestate_hash = provider.absolute_prestate_hash(0).await.unwrap();
prestate_hash[0] = VMStatus::Unfinished as u8;
assert_eq!(
hex!("03ecb75dd1820844c57b6762233d4e26853b3a7b8157bbd9f41f280a0f1cee9b"),
Expand All @@ -110,7 +113,7 @@ mod test {

assert_eq!(
provider.state_at(position).await.unwrap(),
U256::from(expected).to_be_bytes().into()
U256::from(expected).to_be_bytes::<32>().into()
);
assert_eq!(provider.state_hash(position).await.unwrap(), expected_hash);
}
Expand Down
51 changes: 51 additions & 0 deletions crates/fault/src/providers/mocks/mock_output.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//! This module contains the implementation of the [crate::TraceProvider] trait for serving mock output commitments.

use crate::{Gindex, Position, TraceProvider};
use alloy_primitives::U256;
use anyhow::Result;
use durin_primitives::Claim;
use std::sync::Arc;

/// The [MockOutputTraceProvider] is a [TraceProvider] that provides mock L2 output commitments for a [Position].
pub struct MockOutputTraceProvider {
pub starting_block_number: u64,
pub leaf_depth: u8,
}

impl MockOutputTraceProvider {
pub fn new(starting_block_number: u64, leaf_depth: u8) -> Self {
Self {
starting_block_number,
leaf_depth,
}
}
}

#[async_trait::async_trait]
impl TraceProvider for MockOutputTraceProvider {
async fn absolute_prestate(&self, _: Position) -> Result<Arc<[u8]>> {
Ok(Arc::<[u8; 32]>::new(
U256::from(self.starting_block_number).to_be_bytes(),
))
}

async fn absolute_prestate_hash(&self, position: Position) -> Result<Claim> {
// The raw state is equivalent to the state hash in the output trace provider. It must be 32 bytes in size.
Ok((*self.absolute_prestate(position).await?).try_into()?)
}

async fn state_at(&self, position: Position) -> Result<Arc<[u8]>> {
let state =
U256::from(position.trace_index(self.leaf_depth) + self.starting_block_number + 1);
Ok(Arc::<[u8; 32]>::new(state.to_be_bytes()))
}

async fn state_hash(&self, position: Position) -> Result<Claim> {
// The raw state is equivalent to the state hash in the output trace provider. It must be 32 bytes in size.
Ok((*self.state_at(position).await?).try_into()?)
}

async fn proof_at(&self, _: Position) -> Result<Arc<[u8]>> {
unimplemented!("Proofs are not supported for the OutputTraceProvider")
}
}
7 changes: 7 additions & 0 deletions crates/fault/src/providers/mocks/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! Mock implementations of the [crate::TraceProvider] trait for testing.

mod alphabet;
pub use self::alphabet::AlphabetTraceProvider;

mod mock_output;
pub use self::mock_output::MockOutputTraceProvider;
10 changes: 5 additions & 5 deletions crates/fault/src/providers/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
//! This modules contains trace providers for the variants of the [crate::FaultDisputeGame].

mod alphabet;
pub use self::alphabet::AlphabetTraceProvider;
mod split;
pub use self::split::SplitTraceProvider;

mod output;
pub use self::output::OutputTraceProvider;

mod split;
pub use self::split::SplitTraceProvider;

mod cannon;
pub use self::cannon::CannonTraceProvider;

mod mocks;
pub use self::mocks::{AlphabetTraceProvider, MockOutputTraceProvider};
38 changes: 21 additions & 17 deletions crates/fault/src/providers/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! rollup node.

use crate::{Gindex, Position, TraceProvider};
use alloy_primitives::{keccak256, B256};
use alloy_primitives::B256;
use alloy_rpc_client::RpcClient;
use alloy_transport::TransportResult;
use alloy_transport_http::Http;
Expand All @@ -19,13 +19,21 @@ pub struct OutputTraceProvider {
pub leaf_depth: u8,
}

/// A minified response of the `optimism_outputAtBlock` RPC method from the rollup node, containing only the output root
/// requested.
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OutputAtBlockResponse {
pub output_root: B256,
}

impl OutputTraceProvider {
pub fn try_new(
l2_archive_url: String,
l2_archive_url: impl AsRef<str>,
starting_block_number: u64,
leaf_depth: u8,
) -> Result<Self> {
let rpc_client = RpcClient::builder().reqwest_http(Url::parse(&l2_archive_url)?);
let rpc_client = RpcClient::builder().reqwest_http(Url::parse(l2_archive_url.as_ref())?);
Ok(Self {
rpc_client,
starting_block_number,
Expand All @@ -34,39 +42,35 @@ impl OutputTraceProvider {
}
}

#[derive(serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct OutputAtBlockResponse {
pub output_root: B256,
}

#[async_trait::async_trait]
impl TraceProvider<[u8; 32]> for OutputTraceProvider {
async fn absolute_prestate(&self) -> Result<Arc<[u8; 32]>> {
impl TraceProvider for OutputTraceProvider {
async fn absolute_prestate(&self, _: Position) -> Result<Arc<[u8]>> {
let result: TransportResult<OutputAtBlockResponse> = self
.rpc_client
.prepare("optimism_outputAtBlock", (self.starting_block_number))
.prepare("optimism_outputAtBlock", self.starting_block_number)
.await;
Ok(Arc::new(*result?.output_root))
}

async fn absolute_prestate_hash(&self) -> Result<Claim> {
Ok(keccak256(self.absolute_prestate().await?.as_slice()))
async fn absolute_prestate_hash(&self, position: Position) -> Result<Claim> {
// The raw state is equivalent to the state hash in the output trace provider. It must be 32 bytes in size.
Ok((*self.absolute_prestate(position).await?).try_into()?)
}

async fn state_at(&self, position: Position) -> Result<Arc<[u8; 32]>> {
async fn state_at(&self, position: Position) -> Result<Arc<[u8]>> {
let result: TransportResult<OutputAtBlockResponse> = self
.rpc_client
.prepare(
"optimism_outputAtBlock",
(self.starting_block_number + position.trace_index(self.leaf_depth)),
self.starting_block_number + position.trace_index(self.leaf_depth) + 1,
)
.await;
Ok(Arc::new(*result?.output_root))
}

async fn state_hash(&self, position: Position) -> Result<Claim> {
Ok(keccak256(self.state_at(position).await?.as_slice()))
// The raw state is equivalent to the state hash in the output trace provider. It must be 32 bytes in size.
Ok((*self.state_at(position).await?).try_into()?)
}

async fn proof_at(&self, _: Position) -> Result<Arc<[u8]>> {
Expand Down
Loading

0 comments on commit 2c7726f

Please sign in to comment.