Skip to content
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

Bind ELF to ProofData #1647

Merged
merged 28 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
550de8d
Bind elf to ProofData and add tests
jfldde Dec 24, 2024
91a1a8d
Add missing import
jfldde Dec 24, 2024
b9b7bfa
With structs v1
jfldde Dec 24, 2024
cfcea45
fix pre fork1 batch proof guest serialization
eyusufatik Dec 25, 2024
e67099d
implement use_latest_elf for batch prover
eyusufatik Dec 26, 2024
aff6562
fix mock e2e tests
eyusufatik Dec 26, 2024
058e5fb
add todo
eyusufatik Dec 26, 2024
6de2754
add short prefix elf for genesis fork batch proof
eyusufatik Dec 26, 2024
bc9d694
add light client prover to fork elf switch test
eyusufatik Jan 2, 2025
9a58b5d
Merge branch 'nightly' into elf-switch
eyusufatik Jan 2, 2025
2c049dc
fix sys-getenv bug1
eyusufatik Jan 2, 2025
02b2abe
fix FromEnv test
eyusufatik Jan 2, 2025
862575b
Merge branch 'nightly' into elf-switch
jfldde Jan 2, 2025
f92b5fe
fix some tests
eyusufatik Jan 2, 2025
a69ebad
fix some more tests
eyusufatik Jan 2, 2025
798971b
fix forkmanager and some tests
eyusufatik Jan 2, 2025
814e8de
fix test_prover_transaction_chaining test
eyusufatik Jan 2, 2025
698eb70
get fork_from_block_number as an arg for evm query functions
eyusufatik Jan 3, 2025
6802fc0
Remove env debug
jfldde Jan 3, 2025
79c34cc
Fix native warning
jfldde Jan 3, 2025
406edc7
ProofData as struct and pub visibility
jfldde Jan 3, 2025
c79020c
Merge branch 'nightly' into elf-switch
jfldde Jan 3, 2025
1d12d48
update evm tests with always fork1
eyusufatik Jan 3, 2025
3841e9a
Fix ProofData struct in tests
jfldde Jan 3, 2025
4ca3f7e
Add missing import
jfldde Jan 3, 2025
552ceb8
Use expect directly
jfldde Jan 3, 2025
f1a6f94
Merge branch 'nightly' into elf-switch
jfldde Jan 3, 2025
f6659f6
Fix bind elf tests (#1663)
ercecan Jan 3, 2025
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
20 changes: 10 additions & 10 deletions bin/citrea/src/guests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,16 @@ lazy_static! {
};
/// The following 2 are used as latest guest builds for tests that use Bitcoin DA.
pub(crate) static ref BATCH_PROOF_LATEST_BITCOIN_GUESTS: HashMap<SpecId, (Digest, Vec<u8>)> = {
let mut m = HashMap::new();

m.insert(
SpecId::Fork1,
(
Digest::new(citrea_risc0_batch_proof::BATCH_PROOF_BITCOIN_ID),
citrea_risc0_batch_proof::BATCH_PROOF_BITCOIN_ELF.to_vec(),
)
);
m
HashMap::from(
[
#[cfg(feature = "testing")]
(SpecId::Genesis, guest!("../../../resources/guests/risc0/devnet/batch-0.elf")),
(SpecId::Fork1,
(Digest::new(citrea_risc0_batch_proof::BATCH_PROOF_BITCOIN_ID),
citrea_risc0_batch_proof::BATCH_PROOF_BITCOIN_ELF.to_vec())
)
]
)
eyusufatik marked this conversation as resolved.
Show resolved Hide resolved
};
pub(crate) static ref LIGHT_CLIENT_LATEST_BITCOIN_GUESTS: HashMap<SpecId, (Digest, Vec<u8>)> = {
let mut m = HashMap::new();
Expand Down
7 changes: 6 additions & 1 deletion bin/citrea/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use sov_modules_api::Spec;
use sov_modules_rollup_blueprint::RollupBlueprint;
use sov_rollup_interface::Network;
use sov_state::storage::NativeStorage;
use tracing::{debug, error, info, instrument};
use tracing::{debug, error, info, instrument, trace};

#[cfg(test)]
mod test_rpc;
Expand Down Expand Up @@ -155,6 +155,11 @@ async fn main() -> Result<(), anyhow::Error> {

info!("Starting node on {network}");

trace!("Running with env :");
for (key, value) in std::env::vars() {
trace!(" {}: {}", key, value);
}
jfldde marked this conversation as resolved.
Show resolved Hide resolved

match args.da_layer {
SupportedDaLayer::Mock => {
start_rollup::<MockDemoRollup, MockDaConfig>(
Expand Down
102 changes: 102 additions & 0 deletions bin/citrea/tests/bitcoin_e2e/batch_prover_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ use citrea_e2e::node::{Config, NodeKind};
use citrea_e2e::test_case::{TestCase, TestCaseRunner};
use citrea_e2e::traits::NodeT;
use citrea_e2e::Result;
use citrea_primitives::forks::{fork_from_block_number, get_forks};
use citrea_primitives::{TO_BATCH_PROOF_PREFIX, TO_LIGHT_CLIENT_PREFIX};
use sov_ledger_rpc::LedgerRpcClient;
use sov_modules_api::fork::ForkManager;
use sov_modules_api::SpecId;
use sov_rollup_interface::da::{DaData, SequencerCommitment};
use sov_rollup_interface::rpc::VerifiedBatchProofResponse;
use tokio::time::sleep;
Expand Down Expand Up @@ -523,3 +526,102 @@ async fn parallel_proving_test() -> Result<()> {
.run()
.await
}

struct ForkElfSwitchingTest;

#[async_trait]
impl TestCase for ForkElfSwitchingTest {
fn test_config() -> TestCaseConfig {
TestCaseConfig {
with_batch_prover: true,
with_full_node: true,
..Default::default()
}
}

fn sequencer_config() -> SequencerConfig {
let fork_1_height = ForkManager::new(get_forks(), 0)
.next_fork()
.unwrap()
.activation_height;

// Set just below fork1 height so we can generate first soft com txs in genesis
// and second batch above fork1
SequencerConfig {
min_soft_confirmations_per_commitment: fork_1_height - 5,
..Default::default()
}
}

async fn run_test(&mut self, f: &mut TestFramework) -> Result<()> {
let da = f.bitcoin_nodes.get(0).unwrap();
let sequencer = f.sequencer.as_ref().unwrap();
let batch_prover = f.batch_prover.as_ref().unwrap();
let full_node = f.full_node.as_ref().unwrap();

let min_soft_confirmations = sequencer.min_soft_confirmations_per_commitment();

for _ in 0..min_soft_confirmations {
sequencer.client.send_publish_batch_request().await?;
}

let height = sequencer
.client
.ledger_get_head_soft_confirmation_height()
.await?;

assert_eq!(fork_from_block_number(height).spec_id, SpecId::Genesis);

// Generate softcom in fork1
for _ in 0..min_soft_confirmations {
sequencer.client.send_publish_batch_request().await?;
}

let height = sequencer
.client
.ledger_get_head_soft_confirmation_height()
.await?;
assert_eq!(fork_from_block_number(height).spec_id, SpecId::Fork1);

da.wait_mempool_len(4, None).await?;

da.generate(FINALITY_DEPTH).await?;

let finalized_height = da.get_finalized_height().await?;

batch_prover
.wait_for_l1_height(finalized_height, None)
.await?;

// Wait for batch proof tx to hit mempool
da.wait_mempool_len(4, None).await?;
da.generate(FINALITY_DEPTH).await?;

full_node
.wait_for_l1_height(finalized_height + FINALITY_DEPTH, None)
.await?;
let proofs = wait_for_zkproofs(full_node, finalized_height + FINALITY_DEPTH, None)
.await
.unwrap();

assert_eq!(proofs.len(), 2);
assert_eq!(
fork_from_block_number(proofs[0].proof_output.last_l2_height).spec_id,
SpecId::Genesis
);
assert_eq!(
fork_from_block_number(proofs[1].proof_output.last_l2_height).spec_id,
SpecId::Fork1
);

Ok(())
}
}

#[tokio::test]
async fn test_fork_elf_switching() -> Result<()> {
TestCaseRunner::new(ForkElfSwitchingTest)
.set_citrea_path(get_citrea_path())
.run()
.await
}
Empty file.
40 changes: 20 additions & 20 deletions crates/batch-prover/src/proving.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use sov_rollup_interface::da::{BlockHeaderTrait, DaNamespace, DaSpec, SequencerC
use sov_rollup_interface::rpc::SoftConfirmationStatus;
use sov_rollup_interface::services::da::DaService;
use sov_rollup_interface::zk::{
BatchProofCircuitInput, OldBatchProofCircuitOutput, Proof, ZkvmHost,
BatchProofCircuitInput, BatchProofCircuitInputV1, OldBatchProofCircuitOutput, Proof, ZkvmHost,
};
use sov_stf_runner::ProverService;
use tokio::sync::Mutex;
Expand Down Expand Up @@ -228,32 +228,33 @@ where
Tx: Clone + BorshSerialize,
{
let submitted_proofs = ledger
.get_proofs_by_l1_height(l1_block.header().height())
.map_err(|e| anyhow!("{e}"))?
.get_proofs_by_l1_height(l1_block.header().height())?
.unwrap_or(vec![]);

// Add each non-proven proof's data to ProverService
for input in inputs {
for (i, input) in inputs.into_iter().enumerate() {
if !state_transition_already_proven::<StateRoot, Witness, Da, Tx>(&input, &submitted_proofs)
{
prover_service
.add_proof_data((borsh::to_vec(&input)?, vec![]))
.await;
let seq_com = sequencer_commitments.get(i).expect("Commitment exists");
let last_l2_height = seq_com.l2_end_block_number;

let current_spec = fork_from_block_number(last_l2_height).spec_id;
let elf = elfs_by_spec
.get(&current_spec)
.expect("Every fork should have an elf attached")
.clone();

let input = match current_spec {
SpecId::Genesis => borsh::to_vec(&BatchProofCircuitInputV1::from(input))?,
_ => borsh::to_vec(&input)?,
};

prover_service.add_proof_data((input, vec![], elf)).await;
}
}

let last_l2_height = sequencer_commitments
.last()
.expect("Should have at least 1 commitment")
.l2_end_block_number;
let current_spec = fork_from_block_number(last_l2_height).spec_id;
let elf = elfs_by_spec
.get(&current_spec)
.expect("Every fork should have an elf attached")
.clone();

// Prove all proofs in parallel
let proofs = prover_service.prove(elf).await?;
let proofs = prover_service.prove().await?;

let txs_and_proofs = prover_service.submit_proofs(proofs).await?;

Expand All @@ -262,8 +263,7 @@ where
txs_and_proofs,
code_commitments_by_spec.clone(),
)
.await
.map_err(|e| anyhow!("{e}"))?;
.await?;

save_commitments(
ledger.clone(),
Expand Down
15 changes: 14 additions & 1 deletion crates/batch-prover/tests/prover_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ async fn test_successful_prover_execution() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash)).unwrap(),
vec![],
vec![],
))
.await;

Expand Down Expand Up @@ -68,6 +69,7 @@ async fn test_parallel_proofs_equal_to_limit() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_1)).unwrap(),
vec![],
vec![],
))
.await;
// 2nd proof
Expand All @@ -76,6 +78,7 @@ async fn test_parallel_proofs_equal_to_limit() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_2)).unwrap(),
vec![],
vec![],
))
.await;

Expand Down Expand Up @@ -120,6 +123,7 @@ async fn test_parallel_proofs_higher_than_limit() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_1)).unwrap(),
vec![],
vec![],
))
.await;
// 2nd proof
Expand All @@ -128,6 +132,7 @@ async fn test_parallel_proofs_higher_than_limit() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_2)).unwrap(),
vec![],
vec![],
))
.await;
// 3rd proof
Expand All @@ -136,6 +141,7 @@ async fn test_parallel_proofs_higher_than_limit() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_3)).unwrap(),
vec![],
vec![],
))
.await;
// 4th proof
Expand All @@ -144,6 +150,7 @@ async fn test_parallel_proofs_higher_than_limit() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_4)).unwrap(),
vec![],
vec![],
))
.await;
// 5th proof
Expand All @@ -152,6 +159,7 @@ async fn test_parallel_proofs_higher_than_limit() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_5)).unwrap(),
vec![],
vec![],
))
.await;

Expand Down Expand Up @@ -218,6 +226,7 @@ async fn test_multiple_parallel_proof_run() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_1)).unwrap(),
vec![],
vec![],
))
.await;
// 2nd proof
Expand All @@ -226,6 +235,7 @@ async fn test_multiple_parallel_proof_run() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_2)).unwrap(),
vec![],
vec![],
))
.await;

Expand All @@ -250,6 +260,7 @@ async fn test_multiple_parallel_proof_run() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_3)).unwrap(),
vec![],
vec![],
))
.await;
// 2nd proof
Expand All @@ -258,6 +269,7 @@ async fn test_multiple_parallel_proof_run() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_4)).unwrap(),
vec![],
vec![],
))
.await;
// 3rd proof
Expand All @@ -266,6 +278,7 @@ async fn test_multiple_parallel_proof_run() {
.add_proof_data((
borsh::to_vec(&make_transition_data(header_hash_5)).unwrap(),
vec![],
vec![],
))
.await;

Expand Down Expand Up @@ -346,7 +359,7 @@ async fn spawn_prove(
) -> oneshot::Receiver<Vec<Proof>> {
let (tx, rx) = oneshot::channel();
tokio::spawn(async move {
let proofs = prover_service.prove(vec![]).await.unwrap();
let proofs = prover_service.prove().await.unwrap();
tx.send(proofs).unwrap();
});

Expand Down
8 changes: 6 additions & 2 deletions crates/light-client-prover/src/da_block_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,10 +337,14 @@ where
let prover_service = self.prover_service.as_ref();

prover_service
.add_proof_data((borsh::to_vec(&circuit_input)?, assumptions))
.add_proof_data((
borsh::to_vec(&circuit_input)?,
assumptions,
light_client_elf,
))
.await;

let proofs = self.prover_service.prove(light_client_elf).await?;
let proofs = self.prover_service.prove().await?;

assert_eq!(proofs.len(), 1);

Expand Down
3 changes: 3 additions & 0 deletions crates/primitives/src/forks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ pub const DEVNET_FORKS: [Fork; 2] = [
Fork::new(SpecId::Fork1, 999_999_999),
];

#[cfg(feature = "testing")]
pub const NIGHTLY_FORKS: [Fork; 2] = [Fork::new(SpecId::Genesis, 0), Fork::new(SpecId::Fork1, 100)];
#[cfg(not(feature = "testing"))]
pub const NIGHTLY_FORKS: [Fork; 1] = [Fork::new(SpecId::Fork1, 0)];

const _CHECK_FORKS: () = {
Expand Down
Loading