Skip to content

Commit 7383d23

Browse files
authored
fix(l2): verify a single blob proof in the guest program (#5081)
**Motivation** After Osaka, we (ethrex L2) as blob originators have to update our approach to constructing blob transactions (see [this](https://x.com/vdwijden/status/1978443940098457669?s=46&t=UeaOPcmE9dAwr9hxRE1oWQ)) and [include the cell blob proofs in the bundle](#4814). As a ZK rollup, in the guest program, we verify the blob construction, but the zkVM libraries lack working functionality for verifying blob cell proofs (we've created the following issues on SP1 and RISC0, respectively succinctlabs/kzg-rs#28 and risc0/risc0#3506). **Description** To avoid troubles with libraries, we opted to verify the blob the old-fashioned way (pre-Osaka-like) in the guest program. This can be done without any issue, since what's important in the guest program is to compute the same blob versioned hash as the one that was committed on the L1; how the blob is verified is independent of this. This PR reverts the changes done to the prover crate in pos of verifying cell proofs and updates the prover input generation to generate a single blob proof for the prover.
1 parent dfcc52e commit 7383d23

6 files changed

Lines changed: 39 additions & 42 deletions

File tree

crates/l2/common/src/prover.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ pub struct ProverInputData {
1616
pub elasticity_multiplier: u64,
1717
#[serde_as(as = "[_; 48]")]
1818
pub blob_commitment: blobs_bundle::Commitment,
19-
#[serde_as(as = "Vec<[_; 48]>")]
20-
pub blob_proofs: Vec<blobs_bundle::Proof>,
19+
#[serde_as(as = "[_; 48]")]
20+
pub blob_proof: blobs_bundle::Proof,
2121
pub fee_configs: Vec<FeeConfig>,
2222
}
2323

crates/l2/prover/src/guest_program/src/execution.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ pub fn execution_program(input: ProgramInput) -> Result<ProgramOutput, Stateless
105105
#[cfg(feature = "l2")]
106106
blob_commitment,
107107
#[cfg(feature = "l2")]
108-
blob_proofs,
108+
blob_proof,
109109
} = input;
110110

111111
let chain_id = execution_witness.chain_config.chain_id;
@@ -118,7 +118,7 @@ pub fn execution_program(input: ProgramInput) -> Result<ProgramOutput, Stateless
118118
elasticity_multiplier,
119119
_fee_configs,
120120
blob_commitment,
121-
blob_proofs,
121+
blob_proof,
122122
chain_id,
123123
);
124124
}
@@ -162,7 +162,7 @@ pub fn stateless_validation_l2(
162162
elasticity_multiplier: u64,
163163
fee_configs: Option<Vec<FeeConfig>>,
164164
blob_commitment: Commitment,
165-
blob_proof: Vec<Proof>,
165+
blob_proof: Proof,
166166
chain_id: u64,
167167
) -> Result<ProgramOutput, StatelessExecutionError> {
168168
let initial_db = execution_witness.clone();
@@ -195,7 +195,7 @@ pub fn stateless_validation_l2(
195195
)?;
196196

197197
// TODO: this could be replaced with something like a ProverConfig in the future.
198-
let validium = (blob_commitment, &blob_proof) == ([0; 48], &vec![[0; 48]]);
198+
let validium = (blob_commitment, &blob_proof) == ([0; 48], &[0; 48]);
199199

200200
// Check state diffs are valid
201201
let blob_versioned_hash = if !validium {
@@ -467,22 +467,14 @@ fn compute_l1messages_and_privileged_transactions_digests(
467467
fn verify_blob(
468468
state_diff: StateDiff,
469469
commitment: Commitment,
470-
proof: Vec<Proof>,
470+
proof: Proof,
471471
) -> Result<H256, StatelessExecutionError> {
472-
use ethrex_crypto::kzg::{verify_blob_kzg_proof, verify_cell_kzg_proof_batch};
472+
use ethrex_crypto::kzg::verify_blob_kzg_proof;
473473

474474
let encoded_state_diff = state_diff.encode()?;
475475
let blob_data = blob_from_bytes(encoded_state_diff)?;
476476

477-
let proof_is_valid = if proof.len() == 1 {
478-
// Prior to Osaka type proof
479-
verify_blob_kzg_proof(blob_data, commitment, proof[0])?
480-
} else {
481-
// Osaka type proof
482-
verify_cell_kzg_proof_batch(&[blob_data], &[commitment], &proof)?
483-
};
484-
485-
if !proof_is_valid {
477+
if !verify_blob_kzg_proof(blob_data, commitment, proof)? {
486478
return Err(StatelessExecutionError::InvalidBlobProof);
487479
}
488480

crates/l2/prover/src/guest_program/src/input.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ pub struct ProgramInput {
2626
pub blob_commitment: blobs_bundle::Commitment,
2727
#[cfg(feature = "l2")]
2828
/// KZG opening for a challenge over the blob commitment
29-
#[serde_as(as = "Vec<[_; 48]>")]
30-
pub blob_proofs: Vec<blobs_bundle::Proof>,
29+
#[serde_as(as = "[_; 48]")]
30+
pub blob_proof: blobs_bundle::Proof,
3131
}
3232

3333
impl Default for ProgramInput {
@@ -40,7 +40,7 @@ impl Default for ProgramInput {
4040
#[cfg(feature = "l2")]
4141
blob_commitment: [0; 48],
4242
#[cfg(feature = "l2")]
43-
blob_proofs: vec![[0u8; 48]],
43+
blob_proof: [0u8; 48],
4444
}
4545
}
4646
}

crates/l2/prover/src/prover.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl Prover {
129129
#[cfg(feature = "l2")]
130130
blob_commitment: input.blob_commitment,
131131
#[cfg(feature = "l2")]
132-
blob_proofs: input.blob_proofs,
132+
blob_proof: input.blob_proof,
133133
fee_configs: Some(input.fee_configs),
134134
},
135135
}))

crates/l2/sequencer/l1_committer.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ use ethrex_blockchain::{Blockchain, vm::StoreVmDatabase};
1414
use ethrex_common::{
1515
Address, H256, U256,
1616
types::{
17-
AccountUpdate, BLOB_BASE_FEE_UPDATE_FRACTION, BlobsBundle, Block, BlockNumber,
18-
CELLS_PER_EXT_BLOB, Fork, Genesis, MIN_BASE_FEE_PER_BLOB_GAS, TxType, batch::Batch,
19-
blobs_bundle, fake_exponential_checked,
17+
AccountUpdate, BLOB_BASE_FEE_UPDATE_FRACTION, BlobsBundle, Block, BlockNumber, Fork,
18+
Genesis, MIN_BASE_FEE_PER_BLOB_GAS, TxType, batch::Batch, blobs_bundle,
19+
fake_exponential_checked,
2020
},
2121
};
2222
use ethrex_l2_common::{
@@ -707,37 +707,42 @@ impl L1Committer {
707707
// we are generating the BlobsBundle with BlobsBundle::default which
708708
// sets the commitments and proofs to empty vectors.
709709
let (blob_commitment, blob_proof) = if self.validium {
710-
([0; 48], vec![[0; 48]])
710+
([0; 48], [0; 48])
711711
} else {
712712
let BlobsBundle {
713713
commitments,
714714
proofs,
715+
blobs,
715716
..
716717
} = &batch.blobs_bundle;
717718

718719
let l1_fork = get_l1_active_fork(&self.eth_client, self.osaka_activation_time)
719720
.await
720721
.map_err(CommitterError::EthClientError)?;
721-
let proof_count = if l1_fork < Fork::Osaka {
722-
1
723-
} else {
724-
CELLS_PER_EXT_BLOB
725-
};
722+
726723
let commitment = commitments
727724
.last()
728725
.cloned()
729726
.ok_or_else(|| CommitterError::MissingBlob(batch.number))?;
730727

731-
if proofs.len() != proof_count {
732-
return Err(CommitterError::MissingBlob(batch.number));
733-
}
734-
735-
let proof = proofs
736-
.iter()
737-
.rev()
738-
.take(proof_count)
739-
.cloned()
740-
.collect::<Vec<_>>();
728+
// The prover takes a single proof even for Osaka type proofs, so if
729+
// the committer generated Osaka type proofs (cell proofs), we need
730+
// to create a BlobsBundle from the blobs specifying a pre-Osaka
731+
// fork to get a single proof for the entire blob.
732+
// If we are pre-Osaka, we already have a single proof in the
733+
// previously generated bundle
734+
let proof = if l1_fork < Fork::Osaka {
735+
proofs
736+
.first()
737+
.cloned()
738+
.ok_or_else(|| CommitterError::MissingBlob(batch.number))?
739+
} else {
740+
BlobsBundle::create_from_blobs(blobs, Some(0))?
741+
.proofs
742+
.first()
743+
.cloned()
744+
.ok_or_else(|| CommitterError::MissingBlob(batch.number))?
745+
};
741746

742747
(commitment, proof)
743748
};
@@ -747,7 +752,7 @@ impl L1Committer {
747752
execution_witness: batch_witness,
748753
elasticity_multiplier: self.elasticity_multiplier,
749754
blob_commitment,
750-
blob_proofs: blob_proof,
755+
blob_proof,
751756
fee_configs,
752757
};
753758

crates/l2/tee/quote-gen/src/sender.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ pub async fn get_batch(commit_hash: String) -> Result<(u64, ProgramInput), Strin
3232
#[cfg(feature = "l2")]
3333
blob_commitment: input.blob_commitment,
3434
#[cfg(feature = "l2")]
35-
blob_proofs: input.blob_proofs,
35+
blob_proof: input.blob_proof,
3636
fee_configs: Some(input.fee_configs),
3737
},
3838
)),

0 commit comments

Comments
 (0)