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

fix(ampd): stellar tx receipt query and event check #647

Merged
merged 1 commit into from
Oct 4, 2024
Merged
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
20 changes: 17 additions & 3 deletions ampd/src/handlers/stellar_verify_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ use events::Event;
use events_derive::try_from;
use prost_types::Any;
use router_api::ChainName;
use serde::Deserialize;
use serde::de::Error as DeserializeError;
use serde::{Deserialize, Deserializer};
use serde_with::{serde_as, DisplayFromStr};
use stellar_xdr::curr::{ScAddress, ScBytes, ScString};
use tokio::sync::watch::Receiver;
Expand All @@ -26,9 +27,22 @@ use crate::stellar::http_client::Client;
use crate::stellar::verifier::verify_message;
use crate::types::TMAddress;

pub fn deserialize_tx_id<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
let tx_id = String::deserialize(deserializer)?;

tx_id
.strip_prefix("0x")
.map(String::from)
.ok_or(D::Error::custom(Error::DeserializeEvent))
}

#[serde_as]
#[derive(Deserialize, Debug, Clone)]
pub struct Message {
#[serde(deserialize_with = "deserialize_tx_id")]
pub tx_id: String,
pub event_index: u32,
pub destination_address: ScString,
Expand Down Expand Up @@ -129,7 +143,7 @@ impl EventHandler for Handler {

let message_ids = messages
.iter()
.map(|message| format!("{}-{}", message.tx_id, message.event_index))
.map(|message| format!("{}-{}", message.tx_id.clone(), message.event_index))
.collect::<Vec<_>>();

let votes = info_span!(
Expand Down Expand Up @@ -316,7 +330,7 @@ mod tests {
},
messages: (0..2)
.map(|i| TxEventConfirmation {
tx_id: format!("{:x}", Hash::random()).parse().unwrap(),
tx_id: format!("0x{:x}", Hash::random()).parse().unwrap(),
event_index: i,
source_address: ScAddress::Contract(stellar_xdr::curr::Hash::from(
Hash::random().0,
Expand Down
6 changes: 4 additions & 2 deletions ampd/src/handlers/stellar_verify_verifier_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use tracing::{info, info_span};
use valuable::Valuable;
use voting_verifier::msg::ExecuteMsg;

use super::stellar_verify_msg::deserialize_tx_id;
use crate::event_processor::EventHandler;
use crate::handlers::errors::Error;
use crate::handlers::errors::Error::DeserializeEvent;
Expand All @@ -27,6 +28,7 @@ use crate::types::TMAddress;

#[derive(Deserialize, Debug)]
pub struct VerifierSetConfirmation {
#[serde(deserialize_with = "deserialize_tx_id")]
pub tx_id: String,
pub event_index: u32,
pub verifier_set: VerifierSet,
Expand Down Expand Up @@ -117,7 +119,7 @@ impl EventHandler for Handler {
let vote = info_span!(
"verify a new verifier set",
poll_id = poll_id.to_string(),
id = format!("{}-{}", verifier_set.tx_id, verifier_set.event_index),
id = format!("0x{}-{}", verifier_set.tx_id, verifier_set.event_index),
)
.in_scope(|| {
info!("ready to verify verifier set in poll",);
Expand Down Expand Up @@ -291,7 +293,7 @@ mod tests {
.collect(),
},
verifier_set: VerifierSetConfirmation {
tx_id: format!("{:x}", Hash::random()).parse().unwrap(),
tx_id: format!("0x{:x}", Hash::random()).parse().unwrap(),
event_index: 0,
verifier_set: build_verifier_set(KeyType::Ed25519, &ed25519_test_data::signers()),
},
Expand Down
47 changes: 27 additions & 20 deletions ampd/src/stellar/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,24 +48,33 @@
fn eq(&self, event: &ContractEventBody) -> bool {
let ContractEventBody::V0(body) = event;

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

let [symbol, _, signer_hash] = &body.topics[..] else {
let [symbol] = &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;

Check warning on line 66 in ampd/src/stellar/verifier.rs

View check run for this annotation

Codecov / codecov/patch

ampd/src/stellar/verifier.rs#L66

Added line #L66 was not covered by tests
};
rotated_signers.clone()
}
_ => return false,

Check warning on line 70 in ampd/src/stellar/verifier.rs

View check run for this annotation

Codecov / codecov/patch

ampd/src/stellar/verifier.rs#L70

Added line #L70 was not covered by tests
};

WeightedSigners::try_from(&self.verifier_set)
.ok()
.and_then(|signers| signers.hash().ok())
.and_then(|hash| ScVal::try_from(hash).ok())
.map_or(false, |hash| {
symbol == &expected_topic && signer_hash == &hash
.and_then(|signers| ScVal::try_from(signers).ok())
.map_or(false, |signers: ScVal| {
symbol == &expected_topic && signers == rotated_signers
})
}
}
Expand Down Expand Up @@ -138,7 +147,7 @@
use stellar::WeightedSigners;
use stellar_xdr::curr::{
AccountId, BytesM, ContractEvent, ContractEventBody, ContractEventType, ContractEventV0,
PublicKey, ScAddress, ScBytes, ScString, ScSymbol, ScVal, StringM, Uint256,
PublicKey, ScAddress, ScBytes, ScString, ScSymbol, ScVal, ScVec, StringM, Uint256,
};

use crate::handlers::stellar_verify_msg::Message;
Expand Down Expand Up @@ -293,7 +302,7 @@
let signing_key = SigningKey::generate(&mut OsRng);

let msg = Message {
tx_id: Hash::random().to_string(),
tx_id: format!("{:x}", Hash::random()),
event_index: 0,
source_address: ScAddress::Account(AccountId(PublicKey::PublicKeyTypeEd25519(
Uint256::from(signing_key.verifying_key().to_bytes()),
Expand Down Expand Up @@ -351,7 +360,7 @@
let threshold = Uint128::new(2u128);

let verifier_set_confirmation = VerifierSetConfirmation {
tx_id: Hash::random().to_string(),
tx_id: format!("{:x}", Hash::random()),
event_index: 0,
verifier_set: VerifierSet {
signers: signers
Expand All @@ -363,21 +372,19 @@
},
};

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

let event_body = ContractEventBody::V0(ContractEventV0 {
topics: vec![
ScVal::Symbol(ScSymbol(StringM::from_str(TOPIC_ROTATED).unwrap())),
ScVal::Bytes(ScBytes(
BytesM::try_from(Hash::random().to_fixed_bytes()).unwrap(),
)),
ScVal::try_from(signer_hash).unwrap(),
]
topics: vec![ScVal::Symbol(ScSymbol(
StringM::from_str(TOPIC_ROTATED).unwrap(),
))]
.try_into()
.unwrap(),
data: ScVal::Vec(None),
data: ScVal::Vec(Some(ScVec::try_from(vec![weighted_signers]).unwrap())),
});

let event = ContractEvent {
Expand Down
Loading