Skip to content
Merged
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
10 changes: 9 additions & 1 deletion crates/da/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::sync::Arc;

use anyhow::{anyhow, Result};
use anyhow::{Result, anyhow};
use async_trait::async_trait;
use celestia_types::Blob;
use lumina_node::events::EventSubscriber;
Expand All @@ -26,13 +26,20 @@ type Groth16Proof = Vec<u8>;
#[cfg(not(target_arch = "wasm32"))]
type Groth16Proof = SP1ProofWithPublicValues;

#[cfg(target_arch = "wasm32")]
type CompressedProof = Vec<u8>;

#[cfg(not(target_arch = "wasm32"))]
type CompressedProof = SP1ProofWithPublicValues;

// FinalizedEpoch is the data structure that represents the finalized epoch data, and is posted to the DA layer.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct FinalizedEpoch {
pub height: u64,
pub prev_commitment: Digest,
pub current_commitment: Digest,
pub proof: Groth16Proof,
pub compressed_proof: CompressedProof,
pub public_values: Vec<u8>,
pub signature: Option<String>,
}
Expand All @@ -51,6 +58,7 @@ impl FinalizedEpoch {
prev_commitment: self.prev_commitment,
current_commitment: self.current_commitment,
proof: self.proof.clone(),
compressed_proof: self.compressed_proof.clone(),
public_values: self.public_values.clone(),
signature: None,
};
Expand Down
57 changes: 46 additions & 11 deletions crates/node_types/prover/src/prover/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use crate::webserver::{WebServer, WebServerConfig};
use prism_common::operation::Operation;
use prism_da::{DataAvailabilityLayer, FinalizedEpoch};
use sp1_sdk::{
CpuProver, HashableKey as _, Prover as _, ProverClient, SP1ProofWithPublicValues,
CpuProver, HashableKey as _, Prover as _, ProverClient, SP1Proof, SP1ProofWithPublicValues,
SP1ProvingKey, SP1Stdin, SP1VerifyingKey,
};

Expand Down Expand Up @@ -444,6 +444,7 @@ impl Prover {
epoch_height: u64,
batch: &Batch,
) -> Result<(
SP1ProofWithPublicValues,
SP1ProofWithPublicValues,
tokio::sync::RwLockReadGuard<'_, CpuProver>,
&SP1VerifyingKey,
Expand All @@ -458,16 +459,26 @@ impl Prover {
let proof = client.prove(&self.base_proving_key, &stdin).groth16().run()?;
#[cfg(not(feature = "groth16"))]
let proof = client.prove(&self.base_proving_key, &stdin).run()?;
info!(
"successfully generated base proof for epoch {}",
epoch_height
);

info!("successfully generated proof for epoch {}", epoch_height);
Ok((proof, client, &self.base_verifying_key))
let compressed_proof = client.prove(&self.base_proving_key, &stdin).compressed().run()?;
info!(
"successfully generated compressed proof for epoch {}",
epoch_height
);

Ok((proof, compressed_proof, client, &self.base_verifying_key))
}

async fn prove_with_recursive_prover(
&self,
epoch_height: u64,
batch: &Batch,
) -> Result<(
SP1ProofWithPublicValues,
SP1ProofWithPublicValues,
tokio::sync::RwLockReadGuard<'_, CpuProver>,
&SP1VerifyingKey,
Expand All @@ -479,10 +490,21 @@ impl Prover {
)
})?;

let vk_to_use = if prev_epoch.height == 0 {
self.base_verifying_key.clone()
} else {
self.recursive_verifying_key.clone()
};

let mut stdin = SP1Stdin::new();
stdin.write_vec(prev_epoch.proof.bytes());
// Write recursive inputs
let compressed_proof = match prev_epoch.compressed_proof.proof {
SP1Proof::Compressed(proof) => proof,
_ => return Err(anyhow!("Invalid proof type: expected compressed proof")),
};
stdin.write_proof(*compressed_proof, vk_to_use.clone().vk);
stdin.write_vec(prev_epoch.public_values.to_vec());
stdin.write(&self.base_verifying_key.bytes32());
stdin.write(&vk_to_use.hash_u32());
stdin.write(batch);

let client = self.recursive_prover_client.read().await;
Expand All @@ -496,17 +518,29 @@ impl Prover {
"successfully generated recursive proof for epoch {}",
epoch_height
);
let compressed_proof =
client.prove(&self.recursive_proving_key, &stdin).compressed().run()?;
info!(
"successfully generated recursive compressed proof for epoch {}",
epoch_height
);

Ok((proof, client, &self.recursive_verifying_key))
Ok((
proof,
compressed_proof,
client,
&self.recursive_verifying_key,
))
}

async fn prove_epoch(&self, epoch_height: u64, batch: &Batch) -> Result<FinalizedEpoch> {
// we use the base prover for the first epoch and always for mock prover because recursive verification is not really supported at the moment
let (proof, client, verifying_key) = if !cfg!(feature = "groth16") || epoch_height == 0 {
self.prove_with_base_prover(epoch_height, batch).await?
} else {
self.prove_with_recursive_prover(epoch_height, batch).await?
};
let (proof, compressed_proof, client, verifying_key) =
if !cfg!(feature = "groth16") || epoch_height == 0 {
self.prove_with_base_prover(epoch_height, batch).await?
} else {
self.prove_with_recursive_prover(epoch_height, batch).await?
};

client.verify(&proof, verifying_key)?;
info!("verified proof for epoch {}", epoch_height);
Expand All @@ -518,6 +552,7 @@ impl Prover {
prev_commitment: batch.prev_root,
current_commitment: batch.new_root,
proof,
compressed_proof,
public_values,
signature: None,
};
Expand Down