Skip to content

Commit

Permalink
♻️ more cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
clabby committed Jan 15, 2024
1 parent e0fe105 commit 9a8e130
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 60 deletions.
9 changes: 5 additions & 4 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,9 @@ members = ["crates/*"]
edition = "2021"
version = "0.0.1"
authors = ["clabby"]

[workspace.dependencies]
anyhow = "1.0.79"
tokio = { version = "1.35.1", features = ["macros"] }
async-trait = "0.1.77"
alloy-primitives = "0.6.0"
14 changes: 7 additions & 7 deletions crates/fault/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ version.workspace = true
authors.workspace = true

[dependencies]
# Workspace
anyhow.workspace = true
tokio.workspace = true
async-trait.workspace = true
alloy-primitives.workspace = true

# Internal
durin-primitives = { path = "../primitives" }

# External

alloy-primitives = "0.6.0"
alloy-sol-types = "0.6.0"
alloy-rpc-client = { git = "https://github.com/alloy-rs/alloy" }
alloy-transport = { git = "https://github.com/alloy-rs/alloy" }
alloy-transport-http = { git = "https://github.com/alloy-rs/alloy" }
anyhow = "1.0.79"

# Async
tokio = { version = "1.35.1", features = ["macros"] }
serde = { version = "1.0.195", features = ["derive"] }
url = "2.5.0"
reqwest = "0.11.23"
async-trait = "0.1.77"
futures = "0.3.30"

[dev-dependencies]
Expand Down
11 changes: 6 additions & 5 deletions crates/fault/src/providers/alphabet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use crate::{Gindex, Position, TraceProvider, VMStatus};
use alloy_primitives::{keccak256, U256};
use alloy_sol_types::{sol, SolType};
use anyhow::Result;
use durin_primitives::Claim;
use std::{convert::TryInto, sync::Arc};

Expand All @@ -29,18 +30,18 @@ impl AlphabetTraceProvider {

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

async fn absolute_prestate_hash(&self) -> anyhow::Result<Claim> {
async fn absolute_prestate_hash(&self) -> Result<Claim> {
let prestate = U256::from(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) -> anyhow::Result<Arc<[u8; 1]>> {
async fn state_at(&self, position: Position) -> Result<Arc<[u8; 1]>> {
let absolute_prestate = self.absolute_prestate as u64;
let trace_index = position.trace_index(self.max_depth);

Expand All @@ -50,7 +51,7 @@ impl TraceProvider<[u8; 1]> for AlphabetTraceProvider {
Ok(Arc::new([state]))
}

async fn state_hash(&self, position: Position) -> anyhow::Result<Claim> {
async fn state_hash(&self, position: Position) -> Result<Claim> {
let state_sol = (
U256::from(position.trace_index(self.max_depth)),
U256::from(self.state_at(position).await?[0]),
Expand All @@ -60,7 +61,7 @@ impl TraceProvider<[u8; 1]> for AlphabetTraceProvider {
Ok(state_hash)
}

async fn proof_at(&self, _: Position) -> anyhow::Result<Arc<[u8]>> {
async fn proof_at(&self, _: Position) -> Result<Arc<[u8]>> {
Ok(Arc::new([]))
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/fault/src/providers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ pub use self::alphabet::AlphabetTraceProvider;

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

mod split;
pub use self::split::SplitTraceProvider;
48 changes: 33 additions & 15 deletions crates/fault/src/providers/output.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
//! This module contains the implementation of the [crate::TraceProvider] trait for the mock Alphabet VM.
//! This module contains the implementation of the [crate::TraceProvider] trait for fetching output roots from the
//! rollup node.
use crate::{Position, TraceProvider};
use crate::{Gindex, Position, TraceProvider};
use alloy_primitives::{keccak256, B256};
use alloy_rpc_client::RpcClient;
use alloy_transport::TransportResult;
use alloy_transport_http::Http;
Expand All @@ -14,14 +16,14 @@ use std::sync::Arc;
pub struct OutputTraceProvider {
pub rpc_client: RpcClient<Http<Client>>,
pub starting_block_number: u64,
pub leaf_depth: u64,
pub leaf_depth: u8,
}

impl OutputTraceProvider {
pub fn try_new(
l2_archive_url: String,
starting_block_number: u64,
leaf_depth: u64,
leaf_depth: u8,
) -> Result<Self> {
let rpc_client = RpcClient::builder().reqwest_http(Url::parse(&l2_archive_url)?);
Ok(Self {
Expand All @@ -32,26 +34,42 @@ 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) -> anyhow::Result<Arc<[u8; 32]>> {
todo!()
// let transport_result: TransportResult<> = self.rpc_client.prepare("optimism_outputAtBlock", (self.starting_block_number)).await.map_err(|e| anyhow::anyhow!(e))?
async fn absolute_prestate(&self) -> Result<Arc<[u8; 32]>> {
let result: TransportResult<OutputAtBlockResponse> = self
.rpc_client
.prepare("optimism_outputAtBlock", (self.starting_block_number))
.await;
Ok(Arc::new(*result?.output_root))
}

async fn absolute_prestate_hash(&self) -> anyhow::Result<Claim> {
todo!()
async fn absolute_prestate_hash(&self) -> Result<Claim> {
Ok(keccak256(self.absolute_prestate().await?.as_slice()))
}

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

async fn state_hash(&self, position: Position) -> anyhow::Result<Claim> {
todo!()
async fn state_hash(&self, position: Position) -> Result<Claim> {
Ok(keccak256(self.state_at(position).await?.as_slice()))
}

async fn proof_at(&self, _: Position) -> anyhow::Result<Arc<[u8]>> {
todo!()
async fn proof_at(&self, _: Position) -> Result<Arc<[u8]>> {
unimplemented!("Proofs are not supported for the OutputTraceProvider")
}
}
54 changes: 54 additions & 0 deletions crates/fault/src/providers/split.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! This module contains the implementation of the [crate::TraceProvider] trait for composing two trace providers together
//! based off of the input depth. This implementation can be used to compose several layers of bisection.
use crate::{Gindex, Position, TraceProvider};
use alloy_primitives::keccak256;
use anyhow::Result;
use durin_primitives::Claim;
use std::{marker::PhantomData, sync::Arc};

/// The [SplitTraceProvider] is a [TraceProvider] that composes two trace providers together based off of the input depth.
pub struct SplitTraceProvider<T, TOP, BOTTOM>
where
T: AsRef<[u8]> + Send + Sync,
TOP: TraceProvider<T>,
BOTTOM: TraceProvider<T>,
{
pub top: TOP,
pub bottom: BOTTOM,
pub split_depth: u8,
pub _phantom: PhantomData<T>,
}

#[async_trait::async_trait]
impl<T, TOP, BOTTOM> TraceProvider<T> for SplitTraceProvider<T, TOP, BOTTOM>
where
T: AsRef<[u8]> + Send + Sync,
TOP: TraceProvider<T> + Sync,
BOTTOM: TraceProvider<T> + Sync,
{
async fn absolute_prestate(&self) -> Result<Arc<T>> {
todo!()
}

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

async fn state_at(&self, position: Position) -> Result<Arc<T>> {
if position.depth() <= self.split_depth {
self.top.state_at(position).await
} else {
// TODO: Pass relative position based on split depth?
self.bottom.state_at(position).await
}
}

async fn state_hash(&self, position: Position) -> Result<Claim> {
Ok(keccak256(self.state_at(position).await?.as_ref()))
}

async fn proof_at(&self, _: Position) -> Result<Arc<[u8]>> {
todo!()
}
}
3 changes: 2 additions & 1 deletion crates/fault/src/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
FaultClaimSolver, FaultDisputeGame, FaultDisputeState, FaultSolverResponse, Position,
TraceProvider,
};
use anyhow::Result;
use durin_primitives::{DisputeGame, DisputeSolver};
use std::{marker::PhantomData, sync::Arc};
use tokio::sync::Mutex;
Expand Down Expand Up @@ -44,7 +45,7 @@ where
async fn available_moves(
&self,
game: Arc<Mutex<FaultDisputeState>>,
) -> anyhow::Result<Arc<[FaultSolverResponse<T>]>> {
) -> Result<Arc<[FaultSolverResponse<T>]>> {
let game_lock = game.lock().await;

// Fetch the local opinion on the root claim.
Expand Down
11 changes: 6 additions & 5 deletions crates/fault/src/solvers/alpha.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
ClaimData, FaultClaimSolver, FaultDisputeGame, FaultDisputeState, FaultSolverResponse, Gindex,
Position, TraceProvider,
};
use anyhow::{anyhow, Result};
use durin_primitives::Claim;
use std::{marker::PhantomData, sync::Arc};
use tokio::sync::Mutex;
Expand Down Expand Up @@ -41,7 +42,7 @@ where
world: Arc<Mutex<FaultDisputeState>>,
claim_index: usize,
attacking_root: bool,
) -> anyhow::Result<FaultSolverResponse<T>> {
) -> Result<FaultSolverResponse<T>> {
let mut world_lock = world.lock().await;

// Fetch the maximum depth of the game's position tree.
Expand All @@ -51,7 +52,7 @@ where
let claim = world_lock
.state_mut()
.get_mut(claim_index)
.ok_or(anyhow::anyhow!("Failed to fetch claim from passed state"))?;
.ok_or(anyhow!("Failed to fetch claim from passed state"))?;
let claim_depth = claim.position.depth();

// Mark the claim as visited. This mutates the passed state and must be reverted if an
Expand Down Expand Up @@ -160,7 +161,7 @@ where
provider: &P,
position: Position,
observed_claim: &mut ClaimData,
) -> anyhow::Result<Claim> {
) -> Result<Claim> {
let state_hash = provider.state_hash(position).await.map_err(|e| {
observed_claim.visited = false;
e
Expand All @@ -173,7 +174,7 @@ where
provider: &P,
position: Position,
observed_claim: &mut ClaimData,
) -> anyhow::Result<Arc<T>> {
) -> Result<Arc<T>> {
let state_at = provider.state_at(position).await.map_err(|e| {
observed_claim.visited = false;
e
Expand All @@ -186,7 +187,7 @@ where
provider: &P,
position: Position,
observed_claim: &mut ClaimData,
) -> anyhow::Result<Arc<[u8]>> {
) -> Result<Arc<[u8]>> {
let proof_at = provider.proof_at(position).await.map_err(|e| {
observed_claim.visited = false;
e
Expand Down
13 changes: 7 additions & 6 deletions crates/fault/src/traits.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! This module holds traits related to the [FaultDisputeGame]
use crate::{state::ClaimData, FaultDisputeState, FaultSolverResponse, Position};
use anyhow::Result;
use durin_primitives::{Claim, DisputeGame};
use std::sync::Arc;
use tokio::sync::Mutex;
Expand Down Expand Up @@ -34,7 +35,7 @@ pub trait FaultClaimSolver<T: AsRef<[u8]>, P: TraceProvider<T>> {
world: Arc<Mutex<FaultDisputeState>>,
claim_index: usize,
attacking_root: bool,
) -> anyhow::Result<FaultSolverResponse<T>>;
) -> Result<FaultSolverResponse<T>>;

/// Returns a shared reference to the [TraceProvider] that the solver uses to fetch the state of the VM and
/// commitments to it.
Expand All @@ -46,19 +47,19 @@ pub trait FaultClaimSolver<T: AsRef<[u8]>, P: TraceProvider<T>> {
#[async_trait::async_trait]
pub trait TraceProvider<P: AsRef<[u8]>> {
/// Returns the raw absolute prestate (in bytes).
async fn absolute_prestate(&self) -> anyhow::Result<Arc<P>>;
async fn absolute_prestate(&self) -> Result<Arc<P>>;

/// Returns the absolute prestate hash.
async fn absolute_prestate_hash(&self) -> anyhow::Result<Claim>;
async fn absolute_prestate_hash(&self) -> Result<Claim>;

/// Returns the raw state (in bytes) at the given position.
async fn state_at(&self, position: Position) -> anyhow::Result<Arc<P>>;
async fn state_at(&self, position: Position) -> Result<Arc<P>>;

/// Returns the state hash at the given position.
async fn state_hash(&self, position: Position) -> anyhow::Result<Claim>;
async fn state_hash(&self, position: Position) -> Result<Claim>;

/// Returns the raw proof for the commitment at the given position.
async fn proof_at(&self, position: Position) -> anyhow::Result<Arc<[u8]>>;
async fn proof_at(&self, position: Position) -> Result<Arc<[u8]>>;
}

/// The [Gindex] trait defines the interface of a generalized index within a binary tree.
Expand Down
11 changes: 6 additions & 5 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ description = "Primitive types for Durin."
resolver = "2"

edition.workspace = true
authors.workspace = true
version.workspace = true
authors.workspace = true

[dependencies]
alloy-primitives = "0.6.0"
anyhow = "1.0.79"
async-trait = "0.1.77"
tokio = { version = "1.35.1", features = ["macros"] }
# Workspace
tokio.workspace = true
anyhow.workspace = true
async-trait.workspace = true
alloy-primitives.workspace = true
Loading

0 comments on commit 9a8e130

Please sign in to comment.