Skip to content

Commit

Permalink
feat(minor-ampd): update stellar gateway event validation (#662)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahramy authored Oct 21, 2024
1 parent 5f8258a commit 60a0ff2
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 52 deletions.
81 changes: 33 additions & 48 deletions ampd/src/stellar/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::str::FromStr;

use axelar_wasm_std::voting::Vote;
use stellar::WeightedSigners;
use stellar_xdr::curr::{ContractEventBody, ScAddress, ScSymbol, ScVal, StringM};
use stellar_xdr::curr::{BytesM, ContractEventBody, ScAddress, ScBytes, ScSymbol, ScVal, StringM};

use crate::handlers::stellar_verify_msg::Message;
use crate::handlers::stellar_verify_verifier_set::VerifierSetConfirmation;
Expand All @@ -15,67 +15,54 @@ impl PartialEq<ContractEventBody> for Message {
fn eq(&self, event: &ContractEventBody) -> bool {
let ContractEventBody::V0(body) = event;

if body.topics.len() != 3 {
if body.topics.len() != 5 {
return false;
}

let [symbol, source_address, payload_hash] = &body.topics[..] else {
let [symbol, source_address, destination_chain, destination_address, payload_hash] =
&body.topics[..]
else {
return false;
};

let expected_topic: ScVal =
ScSymbol(StringM::from_str(TOPIC_CALLED).expect("must convert str to ScSymbol")).into();

let (dest_chain, dest_address) = match &body.data {
ScVal::Vec(Some(data)) if data.len() == 3 => {
let [dest_chain, dest_address, _] = &data[..] else {
return false;
};
(dest_chain, dest_address)
}
_ => return false,
};

expected_topic == *symbol
&& (ScVal::Address(self.source_address.clone()) == *source_address)
&& (ScVal::Bytes(self.payload_hash.clone()) == *payload_hash)
&& (ScVal::String(self.destination_chain.clone()) == *dest_chain)
&& (ScVal::String(self.destination_address.clone()) == *dest_address)
&& (ScVal::String(self.destination_chain.clone()) == *destination_chain)
&& (ScVal::String(self.destination_address.clone()) == *destination_address)
}
}

impl PartialEq<ContractEventBody> for VerifierSetConfirmation {
fn eq(&self, event: &ContractEventBody) -> bool {
let ContractEventBody::V0(body) = event;

if body.topics.len() != 1 {
if body.topics.len() != 3 {
return false;
}

let [symbol] = &body.topics[..] else {
let [symbol, _, signers_hash] = &body.topics[..] else {
return false;
};

let expected_topic: ScVal =
ScSymbol(StringM::from_str(TOPIC_ROTATED).expect("must convert str to ScSymbol"))
.into();

let rotated_signers = match &body.data {
ScVal::Vec(Some(data)) if data.len() == 1 => {
let [rotated_signers] = &data[..] else {
return false;
};
rotated_signers.clone()
}
_ => return false,
let Some(weighted_signers_hash) = WeightedSigners::try_from(&self.verifier_set)
.ok()
.and_then(|weighted_signers| weighted_signers.hash().ok())
.and_then(|signers_hash| BytesM::try_from(signers_hash).ok())
.map(ScBytes)
.map(ScVal::Bytes)
else {
return false;
};

WeightedSigners::try_from(&self.verifier_set)
.ok()
.and_then(|signers| ScVal::try_from(signers).ok())
.map_or(false, |signers: ScVal| {
symbol == &expected_topic && signers == rotated_signers
})
&expected_topic == symbol && &weighted_signers_hash == signers_hash
}
}

Expand Down Expand Up @@ -147,7 +134,7 @@ mod test {
use stellar::WeightedSigners;
use stellar_xdr::curr::{
AccountId, BytesM, ContractEvent, ContractEventBody, ContractEventType, ContractEventV0,
PublicKey, ScAddress, ScBytes, ScString, ScSymbol, ScVal, ScVec, StringM, Uint256,
PublicKey, ScAddress, ScBytes, ScString, ScSymbol, ScVal, StringM, Uint256,
};

use crate::handlers::stellar_verify_msg::Message;
Expand Down Expand Up @@ -319,19 +306,13 @@ mod test {
topics: vec![
ScVal::Symbol(ScSymbol(StringM::from_str(TOPIC_CALLED).unwrap())),
ScVal::Address(msg.source_address.clone()),
ScVal::String(msg.destination_chain.clone()),
ScVal::String(msg.destination_address.clone()),
ScVal::Bytes(msg.payload_hash.clone()),
]
.try_into()
.unwrap(),
data: ScVal::Vec(Some(
vec![
ScVal::String(msg.destination_chain.clone()),
ScVal::String(msg.destination_address.clone()),
ScVal::String(StringM::from_str("payload").unwrap().into()),
]
.try_into()
.unwrap(),
)),
data: ScVal::Bytes(BytesM::try_from("payload".as_bytes()).unwrap().into()),
});

let event = ContractEvent {
Expand Down Expand Up @@ -372,19 +353,23 @@ mod test {
},
};

let weighted_signers: ScVal =
let weighted_signers_hash = BytesM::try_from(
WeightedSigners::try_from(&verifier_set_confirmation.verifier_set)
.unwrap()
.try_into()
.unwrap();
.hash()
.unwrap(),
)
.unwrap();

let event_body = ContractEventBody::V0(ContractEventV0 {
topics: vec![ScVal::Symbol(ScSymbol(
StringM::from_str(TOPIC_ROTATED).unwrap(),
))]
topics: vec![
ScVal::Symbol(ScSymbol(StringM::from_str(TOPIC_ROTATED).unwrap())),
ScVal::U64(1),
ScVal::Bytes(ScBytes(weighted_signers_hash)),
]
.try_into()
.unwrap(),
data: ScVal::Vec(Some(ScVec::try_from(vec![weighted_signers]).unwrap())),
data: ().into(),
});

let event = ContractEvent {
Expand Down
7 changes: 4 additions & 3 deletions external-gateways/stellar/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ mod test {
}

#[test]
fn signers_rotation_hash() {
fn weighted_signers_hash() {
let weighted_signers = WeightedSigners {
signers: vec![
WeightedSigner {
Expand Down Expand Up @@ -484,9 +484,10 @@ mod test {
.unwrap(),
};

goldie::assert!(
goldie::assert_json!(&vec![
HexBinary::from(weighted_signers.hash().unwrap()).to_hex(),
HexBinary::from(weighted_signers.signers_rotation_hash().unwrap()).to_hex()
);
]);
}

#[test]
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[
"18b1ff823e202dab87cada621717e5be4955734bb973151eb489e6f1576ce3d4",
"4ad8f3015146ac68334fd405f90e6ca75fbf2c276b333a8747c9ba83d9c3f1f6"
]

0 comments on commit 60a0ff2

Please sign in to comment.