Skip to content

feat: support eigenda #516

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
393 changes: 281 additions & 112 deletions Cargo.lock

Large diffs are not rendered by default.

18 changes: 14 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ members = [
"utils/build",
"utils/celestia/client",
"utils/celestia/host",
"utils/eigenda/client",
"utils/eigenda/host",
"utils/proof",
"utils/ethereum/client",
"utils/ethereum/host",
Expand Down Expand Up @@ -84,6 +86,12 @@ hana-celestia = { git = "https://github.com/celestiaorg/hana", rev = "a6077b794d
hana-host = { git = "https://github.com/celestiaorg/hana", rev = "a6077b794d1c00fc2af129fb28cbb0151f8c81b9" }
hana-oracle = { git = "https://github.com/celestiaorg/hana", rev = "a6077b794d1c00fc2af129fb28cbb0151f8c81b9" }

# hokulea
hokulea-eigenda = { git = "https://github.com/Layr-Labs/hokulea", rev = "056ee98" }
hokulea-host-bin = { git = "https://github.com/Layr-Labs/hokulea", rev = "056ee98" }
hokulea-proof = { git = "https://github.com/Layr-Labs/hokulea", rev = "056ee98" }
hokulea-zkvm-verification = { git = "https://github.com/Layr-Labs/hokulea", rev = "056ee98" }

# op-succinct
op-succinct-prove = { path = "scripts/prove" }
op-succinct-client-utils = { path = "utils/client" }
Expand All @@ -96,6 +104,8 @@ op-succinct-ethereum-client-utils = { path = "utils/ethereum/client" }
op-succinct-ethereum-host-utils = { path = "utils/ethereum/host" }
op-succinct-celestia-client-utils = { path = "utils/celestia/client" }
op-succinct-celestia-host-utils = { path = "utils/celestia/host" }
op-succinct-eigenda-client-utils = { path = "utils/eigenda/client" }
op-succinct-eigenda-host-utils = { path = "utils/eigenda/host" }
op-succinct-proof-utils = { path = "utils/proof" }
op-succinct-range-utils = { path = "programs/range/utils" }

Expand Down Expand Up @@ -143,10 +153,10 @@ op-revm = { version = "3.0.1", default-features = false }

# SP1
# TODO(fakedev9999): Temporary patch to fix get_proof_status. Bump to v4.2.1 when released.
sp1-sdk = { git = "https://github.com/succinctlabs/sp1", rev = "d2798c9" }
sp1-lib = { version = "4.2.0", features = ["verify"] }
sp1-zkvm = { version = "4.2.0", features = ["verify"] }
sp1-build = { version = "4.2.0" }
sp1-sdk = { version = "4.2.1" }
sp1-lib = { version = "4.2.1", features = ["verify"] }
sp1-zkvm = { version = "4.2.1", features = ["verify"] }
sp1-build = { version = "4.2.1" }

# kzg
kzg-rs = { version = "0.2.6", features = ["rkyv", "serde"] }
Expand Down
35 changes: 35 additions & 0 deletions programs/range/eigenda/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[package]
name = "range-eigenda"
version = "0.1.0"
license.workspace = true
edition.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true

[dependencies]
# general
rkyv.workspace = true
serde_cbor.workspace = true

# kona
kona-proof.workspace = true

# hokulea
hokulea-proof.workspace = true
hokulea-zkvm-verification.workspace = true

# sp1
sp1-zkvm.workspace = true

# op-succinct
op-succinct-client-utils.workspace = true
op-succinct-eigenda-client-utils.workspace = true
op-succinct-range-utils.workspace = true

# `tracing-subscriber` feature dependencies
tracing-subscriber = { workspace = true, optional = true }

[features]
embedded = ["sp1-zkvm/embedded"]
tracing-subscriber = ["dep:tracing-subscriber"]
44 changes: 44 additions & 0 deletions programs/range/eigenda/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//! A program to verify a Optimism L2 block STF with Ethereum DA in the zkVM.
//!
//! This binary contains the client program for executing the Optimism rollup state transition
//! across a range of blocks, which can be used to generate an on chain validity proof. Depending on
//! the compilation pipeline, it will compile to be run either in native mode or in zkVM mode. In
//! native mode, the data for verifying the batch validity is fetched from RPC, while in zkVM mode,
//! the data is supplied by the host binary to the verifiable program.

#![no_main]
sp1_zkvm::entrypoint!(main);

use hokulea_proof::{
canoe_verifier::sp1_cc::CanoeSp1CCVerifier, eigenda_blob_witness::EigenDABlobWitnessData,
};
use hokulea_zkvm_verification::eigenda_witness_to_preloaded_provider;
use op_succinct_client_utils::witness::{EigenDAWitnessData, WitnessData};
use op_succinct_eigenda_client_utils::executor::EigenDAWitnessExecutor;
use op_succinct_range_utils::run_range_program;
#[cfg(feature = "tracing-subscriber")]
use op_succinct_range_utils::setup_tracing;
use rkyv::rancor::Error;

fn main() {
#[cfg(feature = "tracing-subscriber")]
setup_tracing();

kona_proof::block_on(async move {
let witness_rkyv_bytes: Vec<u8> = sp1_zkvm::io::read_vec();
let witness_data = rkyv::from_bytes::<EigenDAWitnessData, Error>(&witness_rkyv_bytes)
.expect("Failed to deserialize witness data.");

let (oracle, _beacon) = witness_data.clone().get_oracle_and_blob_provider().await.unwrap();
let eigenda_witness: EigenDABlobWitnessData = serde_cbor::from_slice(
&witness_data.eigenda_data.clone().expect("eigenda witness data is not present"),
)
.expect("cannot deserialize eigenda witness");
let preloaded_blob_provider =
eigenda_witness_to_preloaded_provider(oracle, CanoeSp1CCVerifier {}, eigenda_witness)
.await
.expect("Failed to get preloaded blob provider");

run_range_program(EigenDAWitnessExecutor::new(preloaded_blob_provider), witness_data).await;
});
}
5 changes: 5 additions & 0 deletions utils/build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,9 @@ pub fn build_all() {
// "celestia-range-elf-embedded",
// Some(vec!["embedded".to_string()]),
// );
// build_program(
// "range/eigenda",
// "eigenda-range-elf-embedded",
// Some(vec!["embedded".to_string()]),
// );
}
20 changes: 20 additions & 0 deletions utils/client/src/witness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,26 @@ impl WitnessData for DefaultWitnessData {
}
}

#[derive(Clone, Debug, Default, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct EigenDAWitnessData {
pub preimage_store: PreimageStore,
pub blob_data: BlobData,
// EigenDABlobWitnessData.
// See https://github.com/Layr-Labs/hokulea/blob/056ee9888964f1a63191384ce882a2d4f805e76e/crates/proof/src/eigenda_blob_witness.rs.
pub eigenda_data: Option<Vec<u8>>,
}

#[async_trait]
impl WitnessData for EigenDAWitnessData {
fn from_parts(preimage_store: PreimageStore, blob_data: BlobData) -> Self {
Self { preimage_store, blob_data, eigenda_data: None }
}

fn into_parts(self) -> (PreimageStore, BlobData) {
(self.preimage_store, self.blob_data)
}
}

#[derive(
Clone, Debug, Default, Serialize, Deserialize, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize,
)]
Expand Down
28 changes: 28 additions & 0 deletions utils/eigenda/client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "op-succinct-eigenda-client-utils"
version = "0.1.0"
license.workspace = true
edition.workspace = true

[dependencies]
# local
op-succinct-client-utils.workspace = true

# kona
kona-derive.workspace = true
kona-driver.workspace = true
kona-executor.workspace = true
kona-genesis.workspace = true
kona-preimage.workspace = true
kona-proof.workspace = true

# hokulea
hokulea-eigenda.workspace = true
hokulea-proof = { workspace = true, features = ["sp1-cc"] }
hokulea-zkvm-verification.workspace = true

# general
anyhow.workspace = true
async-trait.workspace = true
serde_cbor.workspace = true
spin.workspace = true
77 changes: 77 additions & 0 deletions utils/eigenda/client/src/executor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use std::{fmt::Debug, sync::Arc};

use anyhow::Result;
use async_trait::async_trait;
use hokulea_eigenda::{EigenDABlobProvider, EigenDABlobSource, EigenDADataSource};
use kona_derive::{sources::EthereumDataSource, traits::BlobProvider};
use kona_driver::PipelineCursor;
use kona_genesis::RollupConfig;
use kona_preimage::CommsClient;
use kona_proof::{
l1::{OracleL1ChainProvider, OraclePipeline},
l2::OracleL2ChainProvider,
FlushableCache,
};
use op_succinct_client_utils::witness::executor::WitnessExecutor;
use spin::RwLock;

pub struct EigenDAWitnessExecutor<O, B, E>
where
O: CommsClient + FlushableCache + Send + Sync + Debug,
B: BlobProvider + Send + Sync + Debug + Clone,
E: EigenDABlobProvider + Send + Sync + Debug + Clone,
{
eigenda_blob_provider: E,
_marker: std::marker::PhantomData<(O, B)>,
}

#[allow(clippy::new_without_default)]
impl<O, B, E> EigenDAWitnessExecutor<O, B, E>
where
O: CommsClient + FlushableCache + Send + Sync + Debug,
B: BlobProvider + Send + Sync + Debug + Clone,
E: EigenDABlobProvider + Send + Sync + Debug + Clone,
{
pub fn new(eigenda_blob_provider: E) -> Self {
Self { eigenda_blob_provider, _marker: std::marker::PhantomData }
}
}

#[async_trait]
impl<O, B, E> WitnessExecutor for EigenDAWitnessExecutor<O, B, E>
where
O: CommsClient + FlushableCache + Send + Sync + Debug,
B: BlobProvider + Send + Sync + Debug + Clone,
E: EigenDABlobProvider + Send + Sync + Debug + Clone,
{
type O = O;
type B = B;
type L1 = OracleL1ChainProvider<Self::O>;
type L2 = OracleL2ChainProvider<Self::O>;
type DA = EigenDADataSource<Self::L1, Self::B, E>;

async fn create_pipeline(
&self,
rollup_config: Arc<RollupConfig>,
cursor: Arc<RwLock<PipelineCursor>>,
oracle: Arc<Self::O>,
beacon: Self::B,
l1_provider: Self::L1,
l2_provider: Self::L2,
) -> Result<OraclePipeline<Self::O, Self::L1, Self::L2, Self::DA>> {
let ethereum_data_source =
EthereumDataSource::new_from_parts(l1_provider.clone(), beacon, &rollup_config);
let eigenda_blob_source = EigenDABlobSource::new(self.eigenda_blob_provider.clone());
let da_provider = EigenDADataSource::new(ethereum_data_source, eigenda_blob_source);

Ok(OraclePipeline::new(
rollup_config,
cursor,
oracle,
da_provider,
l1_provider,
l2_provider,
)
.await?)
}
}
1 change: 1 addition & 0 deletions utils/eigenda/client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod executor;
32 changes: 32 additions & 0 deletions utils/eigenda/host/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "op-succinct-eigenda-host-utils"
version = "0.1.0"
license.workspace = true
edition.workspace = true

[dependencies]
# sp1
sp1-sdk.workspace = true

# local
op-succinct-eigenda-client-utils.workspace = true
op-succinct-client-utils.workspace = true
op-succinct-host-utils.workspace = true

# kona
kona-preimage.workspace = true
kona-proof.workspace = true

# hokulea
hokulea-eigenda.workspace = true
hokulea-host-bin.workspace = true
hokulea-proof.workspace = true

# alloy
alloy-eips.workspace = true
alloy-primitives.workspace = true

# general
anyhow.workspace = true
async-trait.workspace = true
rkyv.workspace = true
78 changes: 78 additions & 0 deletions utils/eigenda/host/src/host.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
use std::sync::Arc;

use alloy_eips::BlockId;
use alloy_primitives::B256;
use anyhow::Result;
use async_trait::async_trait;
use hokulea_host_bin::cfg::SingleChainHostWithEigenDA;
use hokulea_proof::eigenda_provider::OracleEigenDAProvider;
use op_succinct_eigenda_client_utils::executor::EigenDAWitnessExecutor;
use op_succinct_host_utils::{
fetcher::OPSuccinctDataFetcher, host::OPSuccinctHost, witness_generation::DefaultOracleBase,
};

use crate::witness_generator::EigenDAWitnessGenerator;

#[derive(Clone)]
pub struct EigenDAOPSuccinctHost {
pub fetcher: Arc<OPSuccinctDataFetcher>,
pub witness_generator: Arc<EigenDAWitnessGenerator>,
}

#[async_trait]
impl OPSuccinctHost for EigenDAOPSuccinctHost {
type Args = SingleChainHostWithEigenDA;
type WitnessGenerator = EigenDAWitnessGenerator;

fn witness_generator(&self) -> &Self::WitnessGenerator {
&self.witness_generator
}

async fn fetch(
&self,
l2_start_block: u64,
l2_end_block: u64,
l1_head_hash: Option<B256>,
safe_db_fallback: Option<bool>,
) -> Result<SingleChainHostWithEigenDA> {
let host = self
.fetcher
.get_host_args(
l2_start_block,
l2_end_block,
l1_head_hash,
safe_db_fallback.expect("`safe_db_fallback` must be set"),
)
.await?;

let eigenda_proxy_address = std::env::var("EIGENDA_PROXY_ADDRESS").ok();
Ok(SingleChainHostWithEigenDA { kona_cfg: host, eigenda_proxy_address, verbose: 1 })
}

fn get_l1_head_hash(&self, args: &Self::Args) -> Option<B256> {
Some(args.kona_cfg.l1_head)
}

async fn get_finalized_l2_block_number(
&self,
fetcher: &OPSuccinctDataFetcher,
_: u64,
) -> Result<Option<u64>> {
let finalized_l2_block_number = fetcher.get_l2_header(BlockId::finalized()).await?;
Ok(Some(finalized_l2_block_number.number))
}
}

impl EigenDAOPSuccinctHost {
pub fn new(
fetcher: Arc<OPSuccinctDataFetcher>,
eigenda_blob_provider: OracleEigenDAProvider<DefaultOracleBase>,
) -> Self {
Self {
fetcher,
witness_generator: Arc::new(EigenDAWitnessGenerator {
executor: EigenDAWitnessExecutor::new(eigenda_blob_provider),
}),
}
}
}
2 changes: 2 additions & 0 deletions utils/eigenda/host/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod host;
pub mod witness_generator;
Loading
Loading