Skip to content

Commit

Permalink
BFT-474: Check hash in save cert
Browse files Browse the repository at this point in the history
  • Loading branch information
aakoshh committed Jul 9, 2024
1 parent 6b2d388 commit 2e37721
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 25 deletions.
31 changes: 6 additions & 25 deletions core/lib/dal/src/consensus_dal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use zksync_db_connection::{
error::{DalError, DalResult, SqlxContext},
instrument::{InstrumentExt, Instrumented},
};
use zksync_types::{L1BatchNumber, L2BlockNumber};
use zksync_types::L2BlockNumber;

pub use crate::consensus::Payload;
use crate::{Core, CoreDal};
Expand Down Expand Up @@ -409,29 +409,12 @@ impl ConsensusDal<'_, '_> {
///
/// Insertion is allowed even if it creates gaps in the L1 batch history.
///
/// It fails if the batch payload is missing or it's not consistent with the QC.
/// This method assumes that all payload validation has been carried out by the caller.
pub async fn insert_batch_certificate(
&mut self,
cert: &attester::BatchQC,
) -> Result<(), InsertCertificateError> {
use InsertCertificateError as E;
let mut txn = self.storage.start_transaction().await?;

let l1_batch_number = L1BatchNumber(cert.message.number.0 as u32);
let _l1_batch_header = txn
.blocks_dal()
.get_l1_batch_header(l1_batch_number)
.await?
.ok_or(E::MissingPayload)?;

// TODO: Verify that the certificate matches the stored batch:
// * add the hash of the batch to the `BatchQC`
// * find out which field in the `l1_batches` table contains the hash we need to match
// * ideally move the responsibility of validation outside this method

// if header.payload != want_payload.encode().hash() {
// return Err(E::PayloadMismatch);
// }
let l1_batch_number = cert.message.number.0 as i64;

let res = sqlx::query!(
r#"
Expand All @@ -441,20 +424,18 @@ impl ConsensusDal<'_, '_> {
($1, $2, NOW(), NOW())
ON CONFLICT (l1_batch_number) DO NOTHING
"#,
i64::from(l1_batch_number.0),
l1_batch_number,
zksync_protobuf::serde::serialize(cert, serde_json::value::Serializer).unwrap(),
)
.instrument("insert_batch_certificate")
.report_latency()
.execute(&mut txn)
.execute(self.storage)
.await?;

if res.rows_affected().is_zero() {
tracing::debug!(%l1_batch_number, "duplicate batch certificate");
tracing::debug!(l1_batch_number, "duplicate batch certificate");
}

txn.commit().await.context("commit")?;

Ok(())
}

Expand Down
21 changes: 21 additions & 0 deletions core/node/consensus/src/storage/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use zksync_concurrency::{ctx, error::Wrap as _, time};
use zksync_consensus_roles::{attester, validator};
use zksync_consensus_storage::{self as storage, BatchStoreState};
use zksync_dal::{consensus_dal::Payload, Core, CoreDal, DalError};
use zksync_l1_contract_interface::i_executor::structures::StoredBatchInfo;
use zksync_node_sync::{fetcher::IoCursorExt as _, ActionQueueSender, SyncState};
use zksync_state_keeper::io::common::IoCursor;
use zksync_types::{commitment::L1BatchWithMetadata, L1BatchNumber};
Expand Down Expand Up @@ -120,6 +121,26 @@ impl<'a> Connection<'a> {
ctx: &ctx::Ctx,
cert: &attester::BatchQC,
) -> Result<(), InsertCertificateError> {
use crate::storage::consensus_dal::InsertCertificateError as E;

let l1_batch_number = L1BatchNumber(cert.message.number.0 as u32);

let Some(l1_batch) = self
.0
.blocks_dal()
.get_l1_batch_metadata(l1_batch_number)
.await
.map_err(E::Dal)?
else {
return Err(E::MissingPayload.into());
};

let l1_batch_info = StoredBatchInfo::from(&l1_batch);

if l1_batch_info.hash().0 != *cert.message.hash.0.as_bytes() {
return Err(E::PayloadMismatch.into());
}

Ok(ctx
.wait(self.0.consensus_dal().insert_batch_certificate(cert))
.await??)
Expand Down

0 comments on commit 2e37721

Please sign in to comment.