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

feat(eigen-client-extra-features): address PR comments (part 2) #374

Merged
Merged
Show file tree
Hide file tree
Changes from 3 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
4 changes: 3 additions & 1 deletion core/node/da_clients/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ ethabi.workspace = true
rust-kzg-bn254.workspace = true
ark-bn254.workspace = true
num-bigint.workspace = true
serial_test.workspace = true
zksync_web3_decl.workspace = true
zksync_eth_client.workspace = true
url.workspace = true

[dev-dependencies]
serial_test.workspace = true
100 changes: 43 additions & 57 deletions core/node/da_clients/src/eigen/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ impl Verifier {
Ok(())
}

pub fn hash_encode_blob_header(&self, blob_header: BlobHeader) -> Vec<u8> {
pub fn hash_encode_blob_header(&self, blob_header: &BlobHeader) -> Vec<u8> {
let mut blob_quorums = vec![];
for quorum in blob_header.blob_quorum_params {
for quorum in &blob_header.blob_quorum_params {
let quorum = Token::Tuple(vec![
Token::Uint(ethabi::Uint::from(quorum.quorum_number)),
Token::Uint(ethabi::Uint::from(quorum.adversary_threshold_percentage)),
Expand Down Expand Up @@ -226,20 +226,16 @@ impl Verifier {
}
let mut computed_hash = leaf.to_vec();
for i in 0..proof.len() / 32 {
let mut combined = proof[i * 32..(i + 1) * 32]
.iter()
.chain(computed_hash.iter())
.cloned()
.collect::<Vec<u8>>();
let mut buffer = [0u8; 64];
if index % 2 == 0 {
combined = computed_hash
.iter()
.chain(proof[i * 32..(i + 1) * 32].iter())
.cloned()
.collect::<Vec<u8>>();
};
buffer[..32].copy_from_slice(&computed_hash);
buffer[32..].copy_from_slice(&proof[i * 32..(i + 1) * 32]);
} else {
buffer[..32].copy_from_slice(&proof[i * 32..(i + 1) * 32]);
buffer[32..].copy_from_slice(&computed_hash);
}
let mut keccak = Keccak::v256();
keccak.update(&combined);
keccak.update(&buffer);
let mut hash = [0u8; 32];
keccak.finalize(&mut hash);
computed_hash = hash.to_vec();
Expand All @@ -250,15 +246,15 @@ impl Verifier {
}

/// Verifies the certificate's batch root
pub fn verify_merkle_proof(&self, cert: BlobInfo) -> Result<(), VerificationError> {
let inclusion_proof = cert.blob_verification_proof.inclusion_proof;
let root = cert
pub fn verify_merkle_proof(&self, cert: &BlobInfo) -> Result<(), VerificationError> {
let inclusion_proof = &cert.blob_verification_proof.inclusion_proof;
let root = &cert
.blob_verification_proof
.batch_medatada
.batch_header
.batch_root;
let blob_index = cert.blob_verification_proof.blob_index;
let blob_header = cert.blob_header;
let blob_header = &cert.blob_header;

let blob_header_hash = self.hash_encode_blob_header(blob_header);
let mut keccak = Keccak::v256();
Expand All @@ -267,24 +263,24 @@ impl Verifier {
keccak.finalize(&mut leaf_hash);

let generated_root =
self.process_inclusion_proof(&inclusion_proof, &leaf_hash, blob_index)?;
self.process_inclusion_proof(inclusion_proof, &leaf_hash, blob_index)?;

if generated_root != root {
if generated_root != *root {
return Err(VerificationError::DifferentRoots);
}
Ok(())
}

fn hash_batch_metadata(
&self,
batch_header: BatchHeader,
signatory_record_hash: Vec<u8>,
batch_header: &BatchHeader,
signatory_record_hash: &[u8],
confirmation_block_number: u32,
) -> Vec<u8> {
let batch_header_token = Token::Tuple(vec![
Token::FixedBytes(batch_header.batch_root),
Token::Bytes(batch_header.quorum_numbers),
Token::Bytes(batch_header.quorum_signed_percentages),
Token::FixedBytes(batch_header.batch_root.clone()), // Clone only where necessary
Token::Bytes(batch_header.quorum_numbers.clone()),
Token::Bytes(batch_header.quorum_signed_percentages.clone()),
Token::Uint(ethabi::Uint::from(batch_header.reference_block_number)),
]);

Expand All @@ -297,7 +293,7 @@ impl Verifier {

let hash_token = Token::Tuple(vec![
Token::FixedBytes(header_hash.to_vec()),
Token::FixedBytes(signatory_record_hash),
Token::FixedBytes(signatory_record_hash.to_owned()), // Clone only if required
]);

let mut hash_encoded = encode(&[hash_token]);
Expand Down Expand Up @@ -330,7 +326,7 @@ impl Verifier {

async fn call_batch_id_to_metadata_hash(
&self,
blob_info: BlobInfo,
blob_info: &BlobInfo,
) -> Result<Vec<u8>, VerificationError> {
let context_block = self.get_context_block().await?;

Expand Down Expand Up @@ -361,21 +357,19 @@ impl Verifier {
}

/// Verifies the certificate batch hash
pub async fn verify_batch(&self, blob_info: BlobInfo) -> Result<(), VerificationError> {
let expected_hash = self
.call_batch_id_to_metadata_hash(blob_info.clone())
.await?;
pub async fn verify_batch(&self, blob_info: &BlobInfo) -> Result<(), VerificationError> {
let expected_hash = self.call_batch_id_to_metadata_hash(blob_info).await?;

if expected_hash == vec![0u8; 32] {
return Err(VerificationError::EmptyHash);
}

let actual_hash = self.hash_batch_metadata(
blob_info
&blob_info
.blob_verification_proof
.batch_medatada
.batch_header,
blob_info
&blob_info
.blob_verification_proof
.batch_medatada
.signatory_record_hash,
Expand All @@ -398,31 +392,23 @@ impl Verifier {
}

// Read the offset (first 32 bytes)
let offset = {
let mut offset_bytes = [0u8; 32];
offset_bytes.copy_from_slice(&encoded[0..32]);
usize::from_be_bytes(
offset_bytes[24..32]
.try_into()
.map_err(|_| "Offset is too large")?,
)
};
let offset = usize::from_be_bytes(
encoded[24..32]
.try_into()
.map_err(|_| "Offset is too large")?,
);

// Check if offset is valid
if offset + 32 > encoded.len() {
return Err("Offset points outside the encoded data".to_string());
}

// Read the length (32 bytes at the offset position)
let length = {
let mut length_bytes = [0u8; 32];
length_bytes.copy_from_slice(&encoded[offset..offset + 32]);
usize::from_be_bytes(
length_bytes[24..32]
.try_into()
.map_err(|_| "Offset is too large")?,
)
};
let length = usize::from_be_bytes(
encoded[offset + 24..offset + 32]
.try_into()
.map_err(|_| "Length is too large")?,
);

// Check if the length is valid
if offset + 32 + length > encoded.len() {
Expand Down Expand Up @@ -485,9 +471,9 @@ impl Verifier {
}

/// Verifies that the certificate's blob quorum params are correct
pub async fn verify_security_params(&self, cert: BlobInfo) -> Result<(), VerificationError> {
let blob_header = cert.blob_header;
let batch_header = cert.blob_verification_proof.batch_medatada.batch_header;
pub async fn verify_security_params(&self, cert: &BlobInfo) -> Result<(), VerificationError> {
let blob_header = &cert.blob_header;
let batch_header = &cert.blob_verification_proof.batch_medatada.batch_header;

let mut confirmed_quorums: HashMap<u32, bool> = HashMap::new();
for i in 0..blob_header.blob_quorum_params.len() {
Expand Down Expand Up @@ -536,9 +522,9 @@ impl Verifier {
&self,
cert: BlobInfo,
) -> Result<(), VerificationError> {
self.verify_batch(cert.clone()).await?;
self.verify_merkle_proof(cert.clone())?;
self.verify_security_params(cert.clone()).await?;
self.verify_batch(&cert).await?;
self.verify_merkle_proof(&cert)?;
self.verify_security_params(&cert).await?;
Ok(())
}
}
16 changes: 8 additions & 8 deletions core/node/da_clients/src/eigen/verifier_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ mod test {
quorum_indexes: vec![0, 1],
},
};
let result = verifier.verify_merkle_proof(cert);
let result = verifier.verify_merkle_proof(&cert);
assert!(result.is_ok());
}

Expand Down Expand Up @@ -293,7 +293,7 @@ mod test {
quorum_indexes: vec![0, 1],
},
};
let result = verifier.verify_merkle_proof(cert);
let result = verifier.verify_merkle_proof(&cert);
assert!(result.is_ok());
}

Expand Down Expand Up @@ -330,7 +330,7 @@ mod test {
},
],
};
let result = verifier.hash_encode_blob_header(blob_header);
let result = verifier.hash_encode_blob_header(&blob_header);
let expected = "ba4675a31c9bf6b2f7abfdcedd34b74645cb7332b35db39bff00ae8516a67393";
assert_eq!(result, hex::decode(expected).unwrap());
}
Expand Down Expand Up @@ -369,7 +369,7 @@ mod test {
},
],
};
let result = verifier.hash_encode_blob_header(blob_header);
let result = verifier.hash_encode_blob_header(&blob_header);
let expected = "ba4675a31c9bf6b2f7abfdcedd34b74645cb7332b35db39bff00ae8516a67393";
assert_eq!(result, hex::decode(expected).unwrap());
}
Expand Down Expand Up @@ -493,7 +493,7 @@ mod test {
quorum_indexes: vec![0, 1],
},
};
let result = verifier.verify_batch(cert).await;
let result = verifier.verify_batch(&cert).await;
assert!(result.is_ok());
}

Expand Down Expand Up @@ -601,7 +601,7 @@ mod test {
quorum_indexes: vec![0, 1],
},
};
let result = verifier.verify_batch(cert).await;
let result = verifier.verify_batch(&cert).await;
assert!(result.is_ok());
}

Expand Down Expand Up @@ -683,7 +683,7 @@ mod test {
quorum_indexes: vec![0, 1],
},
};
let result = verifier.verify_security_params(cert).await;
let result = verifier.verify_security_params(&cert).await;
assert!(result.is_ok());
}

Expand Down Expand Up @@ -808,7 +808,7 @@ mod test {
quorum_indexes: vec![0, 1],
},
};
let result = verifier.verify_security_params(cert).await;
let result = verifier.verify_security_params(&cert).await;
assert!(result.is_ok());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,12 @@ pub struct GetBlobFromDB {

#[async_trait::async_trait]
impl GetBlobData for GetBlobFromDB {
async fn get_blob_data(&self, input: &'_ str) -> anyhow::Result<Option<Vec<u8>>> {
let pool = self.pool.clone();
let input = input.to_string();
let mut conn = pool.connection_tagged("eigen_client").await?;
async fn get_blob_data(&self, input: &str) -> anyhow::Result<Option<Vec<u8>>> {
let mut conn = self.pool.connection_tagged("eigen_client").await?;
let batch = conn
.data_availability_dal()
.get_blob_data_by_blob_id(&input)
.await?;
drop(conn);
Ok(batch.map(|b| b.pubdata))
}
}
Loading