Skip to content
Open
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
23 changes: 18 additions & 5 deletions bridges/snowbridge/pallets/ethereum-client/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use snowbridge_beacon_primitives::{
merkle_proof::{generalized_index_length, subtree_index},
receipt::verify_receipt_proof,
};
use snowbridge_ethereum::Log as AlloyLog;
use snowbridge_verification_primitives::{
VerificationError::{self, *},
Verifier, *,
Expand Down Expand Up @@ -42,11 +43,7 @@ impl<T: Config> Pallet<T> {
log: &Log,
) -> Result<(), VerificationError> {
let receipt = verify_receipt_proof(receipts_root, receipt_proof).ok_or(InvalidProof)?;
if !receipt.logs().iter().any(|l| {
l.data.data.0 == log.data &&
l.address.0 == log.address.0 &&
l.topics().len() == log.topics.len()
}) {
if !receipt.logs().iter().any(|l| Self::check_log_match(log, l)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add a test too pls

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log::error!(
target: "ethereum-client",
"💫 Event log not found in receipt for transaction",
Expand All @@ -56,6 +53,22 @@ impl<T: Config> Pallet<T> {
Ok(())
}

fn check_log_match(log: &Log, receipt_log: &AlloyLog) -> bool {
let equal = receipt_log.data.data.0 == log.data &&
receipt_log.address.0 == log.address.0 &&
receipt_log.topics().len() == log.topics.len();
if !equal {
return false
}
for (_, (topic1, topic2)) in receipt_log.topics().iter().zip(log.topics.iter()).enumerate()
{
if topic1.0 != topic2.0 {
return false
}
}
true
}

/// Validates an execution header with ancestry_proof against a finalized checkpoint on
/// chain.The beacon header containing the execution header is sent, plus the execution header,
/// along with a proof that the execution header is rooted in the beacon header body.
Expand Down
15 changes: 15 additions & 0 deletions bridges/snowbridge/pallets/ethereum-client/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -959,3 +959,18 @@ fn verify_execution_proof_not_finalized() {
);
});
}

#[test]
fn verify_message_invalid_topic() {
let (event_log, proof) = get_message_verification_payload();
let mut event_log_muted = event_log.clone();
event_log_muted.topics[0] = H256::default();

new_tester().execute_with(|| {
assert_ok!(initialize_storage());
assert_err!(
EthereumBeaconClient::verify(&event_log_muted, &proof),
VerificationError::LogNotFound
);
});
}
9 changes: 9 additions & 0 deletions prdoc/pr_9952.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
title: 'Snowbridge: Fix log equal check'
doc:
- audience: Runtime Dev
description: |-
This fix addresses an issue introduced in PR#9204, where individual event log topics were not fully verified.
crates:
- name: snowbridge-pallet-ethereum-client
bump: patch

Loading