From 6e92e6f97e5947d8abca4268fddca77a5d3474f4 Mon Sep 17 00:00:00 2001 From: CJ Cobb Date: Wed, 7 Feb 2024 11:37:01 -0500 Subject: [PATCH 1/4] fix(ampd): skip events from unknown contracts --- Cargo.lock | 1 + ampd/src/handlers/evm_verify_msg.rs | 11 +-- ampd/src/handlers/evm_verify_worker_set.rs | 11 +-- ampd/src/handlers/multisig.rs | 88 ++++++++++++++++++-- ampd/src/handlers/sui_verify_msg.rs | 10 +-- ampd/src/handlers/sui_verify_worker_set.rs | 11 +-- packages/events/Cargo.toml | 1 + packages/events/src/event.rs | 96 ++++++++++++++++++++++ 8 files changed, 193 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2fd9bbba6..8dbff9548 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2884,6 +2884,7 @@ version = "0.1.0" dependencies = [ "axelar-wasm-std", "base64 0.21.4", + "cosmrs", "error-stack", "serde_json", "tendermint 0.33.0", diff --git a/ampd/src/handlers/evm_verify_msg.rs b/ampd/src/handlers/evm_verify_msg.rs index 219a806cc..0181ff040 100644 --- a/ampd/src/handlers/evm_verify_msg.rs +++ b/ampd/src/handlers/evm_verify_msg.rs @@ -41,8 +41,6 @@ pub struct Message { #[derive(Deserialize, Debug)] #[try_from("wasm-messages_poll_started")] struct PollStartedEvent { - #[serde(rename = "_contract_address")] - contract_address: TMAddress, poll_id: PollId, source_chain: connection_router::state::ChainName, source_gateway_address: EVMAddress, @@ -150,8 +148,11 @@ where type Err = Error; async fn handle(&self, event: &events::Event) -> Result<()> { + if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { + return Ok(()); + } + let PollStartedEvent { - contract_address, poll_id, source_chain, source_gateway_address, @@ -166,10 +167,6 @@ where event => event.change_context(DeserializeEvent)?, }; - if self.voting_verifier != contract_address { - return Ok(()); - } - if self.chain != source_chain { return Ok(()); } diff --git a/ampd/src/handlers/evm_verify_worker_set.rs b/ampd/src/handlers/evm_verify_worker_set.rs index fed1f0e9a..21c974741 100644 --- a/ampd/src/handlers/evm_verify_worker_set.rs +++ b/ampd/src/handlers/evm_verify_worker_set.rs @@ -41,8 +41,6 @@ pub struct WorkerSetConfirmation { #[derive(Deserialize, Debug)] #[try_from("wasm-worker_set_poll_started")] struct PollStartedEvent { - #[serde(rename = "_contract_address")] - contract_address: TMAddress, worker_set: WorkerSetConfirmation, poll_id: PollId, source_chain: connection_router::state::ChainName, @@ -146,8 +144,11 @@ where type Err = Error; async fn handle(&self, event: &events::Event) -> Result<()> { + if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { + return Ok(()); + } + let PollStartedEvent { - contract_address, poll_id, source_chain, source_gateway_address, @@ -162,10 +163,6 @@ where event => event.change_context(Error::DeserializeEvent)?, }; - if self.voting_verifier != contract_address { - return Ok(()); - } - if self.chain != source_chain { return Ok(()); } diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 2bf4115cd..ee2295214 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -28,8 +28,6 @@ use crate::types::TMAddress; #[derive(Debug, Deserialize)] #[try_from("wasm-signing_started")] struct SigningStartedEvent { - #[serde(rename = "_contract_address")] - contract_address: TMAddress, session_id: u64, #[serde(deserialize_with = "deserialize_public_keys")] pub_keys: HashMap, @@ -132,8 +130,11 @@ where type Err = Error; async fn handle(&self, event: &events::Event) -> error_stack::Result<(), Error> { + if !events::event_is_from_contract(event, self.multisig.as_ref()) { + return Ok(()); + } + let SigningStartedEvent { - contract_address, session_id, pub_keys, msg, @@ -145,10 +146,6 @@ where result => result.change_context(DeserializeEvent)?, }; - if self.multisig != contract_address { - return Ok(()); - } - info!( session_id = session_id, msg = encode(&msg), @@ -278,6 +275,44 @@ mod test { .unwrap() } + // this returns an event that is named SigningStarted, + // but the fields are different than what the handler expects + fn wrong_signing_started_event() -> events::Event { + let pub_keys = (0..10) + .map(|_| (rand_account().to_string(), rand_public_key())) + .collect::>(); + + let poll_started = SigningStarted { + session_id: Uint64::one(), + worker_set_id: "worker_set_id".to_string(), + pub_keys, + msg: MsgToSign::unchecked(rand_message()), + chain_name: rand_chain_name(), + expires_at: 100u64, + }; + + let mut event: cosmwasm_std::Event = poll_started.into(); + event.ty = format!("wasm-{}", event.ty); + event = event.add_attribute("_contract_address", MULTISIG_ADDRESS); + let idx = event + .attributes + .iter() + .position(|element| element.key == "expires_at") + .unwrap(); + event.attributes.remove(idx); + + events::Event::try_from(abci::Event::new( + event.ty, + event + .attributes + .into_iter() + .map(|cosmwasm_std::Attribute { key, value }| { + (STANDARD.encode(key), STANDARD.encode(value)) + }), + )) + .unwrap() + } + fn get_handler( worker: TMAddress, multisig: TMAddress, @@ -353,7 +388,44 @@ mod test { } #[tokio::test] - async fn should_not_handle_event_if_multisig_address_does_not_match() { + async fn should_not_handle_wrong_event_if_multisig_address_does_not_match() { + let mut client = MockEcdsaClient::new(); + client + .expect_sign() + .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + + let handler = get_handler( + rand_account(), + rand_account(), + SharableEcdsaClient::new(client), + 100u64, + ); + + assert!(handler.handle(&wrong_signing_started_event()).await.is_ok()); + } + + #[tokio::test] + async fn should_error_on_wrong_event_if_multisig_address_does_match() { + let mut client = MockEcdsaClient::new(); + client + .expect_sign() + .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + + let handler = get_handler( + rand_account(), + TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), + SharableEcdsaClient::new(client), + 100u64, + ); + + assert!(handler + .handle(&wrong_signing_started_event()) + .await + .is_err()); + } + + #[tokio::test] + async fn should_not_handle_correct_event_if_multisig_address_does_not_match() { let mut client = MockEcdsaClient::new(); client .expect_sign() diff --git a/ampd/src/handlers/sui_verify_msg.rs b/ampd/src/handlers/sui_verify_msg.rs index 34ab99696..b19f1e5b8 100644 --- a/ampd/src/handlers/sui_verify_msg.rs +++ b/ampd/src/handlers/sui_verify_msg.rs @@ -35,8 +35,6 @@ pub struct Message { #[derive(Deserialize, Debug)] #[try_from("wasm-messages_poll_started")] struct PollStartedEvent { - #[serde(rename = "_contract_address")] - contract_address: TMAddress, poll_id: PollId, source_gateway_address: SuiAddress, messages: Vec, @@ -102,8 +100,10 @@ where type Err = Error; async fn handle(&self, event: &Event) -> Result<()> { + if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { + return Ok(()); + } let PollStartedEvent { - contract_address, poll_id, source_gateway_address, messages, @@ -117,10 +117,6 @@ where event => event.change_context(Error::DeserializeEvent)?, }; - if self.voting_verifier != contract_address { - return Ok(()); - } - if !participants.contains(&self.worker) { return Ok(()); } diff --git a/ampd/src/handlers/sui_verify_worker_set.rs b/ampd/src/handlers/sui_verify_worker_set.rs index 9adeed329..fff24c5d4 100644 --- a/ampd/src/handlers/sui_verify_worker_set.rs +++ b/ampd/src/handlers/sui_verify_worker_set.rs @@ -40,8 +40,6 @@ pub struct WorkerSetConfirmation { #[derive(Deserialize, Debug)] #[try_from("wasm-worker_set_poll_started")] struct PollStartedEvent { - #[serde(rename = "_contract_address")] - contract_address: TMAddress, poll_id: PollId, source_gateway_address: SuiAddress, worker_set: WorkerSetConfirmation, @@ -110,8 +108,11 @@ where type Err = Error; async fn handle(&self, event: &Event) -> error_stack::Result<(), Error> { + if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { + return Ok(()); + } + let PollStartedEvent { - contract_address, poll_id, source_gateway_address, worker_set, @@ -125,10 +126,6 @@ where event => event.change_context(Error::DeserializeEvent)?, }; - if self.voting_verifier != contract_address { - return Ok(()); - } - if !participants.contains(&self.worker) { return Ok(()); } diff --git a/packages/events/Cargo.toml b/packages/events/Cargo.toml index c852cb4ee..5cf4ba5b2 100644 --- a/packages/events/Cargo.toml +++ b/packages/events/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] axelar-wasm-std = { workspace = true } base64 = "0.21.2" +cosmrs = { version = "0.14.0", features = ["cosmwasm"] } error-stack = { workspace = true } serde_json = "1.0.105" # Need to switch to our own fork of tendermint and tendermint-rpc due to event attribute value being nullable. diff --git a/packages/events/src/event.rs b/packages/events/src/event.rs index 4e8f94dca..38c74dac1 100644 --- a/packages/events/src/event.rs +++ b/packages/events/src/event.rs @@ -9,6 +9,8 @@ use tendermint::{abci, block}; use crate::errors::DecodingError; use crate::Error; +use cosmrs::AccountId; + #[derive(Clone, Debug, PartialEq, Eq)] pub enum Event { BlockBegin(block::Height), @@ -71,3 +73,97 @@ fn decode_event_attribute(attribute: &EventAttribute) -> Result<(String, String) fn base64_to_utf8(base64_str: &str) -> std::result::Result { Ok(STANDARD.decode(base64_str)?.then(String::from_utf8)?) } + +pub fn get_contract_address(event: &Event) -> Option { + let contract_address = match event { + Event::Abci { + event_type: _, + attributes, + } => { + if let Some(address) = attributes.get("_contract_address") { + return serde_json::from_value::(address.clone()).ok(); + } + None + } + _ => None, + }; + contract_address +} + +pub fn event_is_from_contract(event: &Event, contract_address: &AccountId) -> bool { + match get_contract_address(event) { + Some(address) => &address == contract_address, + _ => false, + } +} + +#[cfg(test)] +mod test { + use std::str::FromStr; + + use cosmrs::AccountId; + + use crate::{event_is_from_contract, get_contract_address, Event}; + + fn make_event_with_contract_address(contract_address: &AccountId) -> Event { + let mut attributes = serde_json::Map::new(); + attributes.insert( + "_contract_address".to_string(), + contract_address.to_string().into(), + ); + Event::Abci { + event_type: "some_event".to_string(), + attributes, + } + } + + #[test] + fn should_get_contract_address_if_exists() { + let expected_contract_address = + AccountId::from_str("axelarvaloper1zh9wrak6ke4n6fclj5e8yk397czv430ygs5jz7").unwrap(); + + let event = make_event_with_contract_address(&expected_contract_address); + + let contract_address = get_contract_address(&event); + assert!(contract_address.is_some()); + assert_eq!(contract_address.unwrap(), expected_contract_address); + } + + #[test] + fn should_not_get_contract_address_if_not_exists() { + let event = Event::Abci { + event_type: "some_event".to_string(), + attributes: serde_json::Map::new(), + }; + let contract_address = get_contract_address(&event); + assert!(contract_address.is_none()); + } + + #[test] + fn event_is_from_contract_should_return_true_iff_contract_address_matches() { + let contract_address = + AccountId::from_str("axelarvaloper1zh9wrak6ke4n6fclj5e8yk397czv430ygs5jz7").unwrap(); + let event = make_event_with_contract_address(&contract_address); + assert!(event_is_from_contract(&event, &contract_address)); + + let diff_contract_address = + AccountId::from_str("axelarvaloper1tee73c83k2vqky9gt59jd3ztwxhqjm27l588q6").unwrap(); + assert!(!event_is_from_contract(&event, &diff_contract_address)); + } + + #[test] + fn event_is_from_contract_should_return_false_if_contract_address_does_not_exist() { + let contract_address = + AccountId::from_str("axelarvaloper1zh9wrak6ke4n6fclj5e8yk397czv430ygs5jz7").unwrap(); + + let event_without_contract_address = Event::Abci { + event_type: "some_event".to_string(), + attributes: serde_json::Map::new(), + }; + + assert!(!event_is_from_contract( + &event_without_contract_address, + &contract_address + )); + } +} From 0292261914820af7cbaac4ef789a46fee65c2f5a Mon Sep 17 00:00:00 2001 From: CJ Cobb Date: Thu, 8 Feb 2024 14:30:37 -0500 Subject: [PATCH 2/4] review --- ampd/src/handlers/multisig.rs | 27 ++++++++++++------------- ampd/src/handlers/sui_verify_msg.rs | 1 + packages/events/src/event.rs | 31 ++++++++++++----------------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index ee2295214..ac1c217cf 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -275,9 +275,8 @@ mod test { .unwrap() } - // this returns an event that is named SigningStarted, - // but the fields are different than what the handler expects - fn wrong_signing_started_event() -> events::Event { + // this returns an event that is named SigningStarted, but some expected fields are missing + fn signing_started_event_with_missing_fields(contract_address: &str) -> events::Event { let pub_keys = (0..10) .map(|_| (rand_account().to_string(), rand_public_key())) .collect::>(); @@ -293,13 +292,8 @@ mod test { let mut event: cosmwasm_std::Event = poll_started.into(); event.ty = format!("wasm-{}", event.ty); - event = event.add_attribute("_contract_address", MULTISIG_ADDRESS); - let idx = event - .attributes - .iter() - .position(|element| element.key == "expires_at") - .unwrap(); - event.attributes.remove(idx); + event = event.add_attribute("_contract_address", contract_address); + event.attributes.retain(|attr| attr.key != "expires_at"); events::Event::try_from(abci::Event::new( event.ty, @@ -327,7 +321,7 @@ mod test { let (broadcaster, _) = QueuedBroadcaster::new(broadcaster, Gas::default(), 100, Duration::from_secs(5)); - let (tx, rx) = watch::channel(latest_block_height); + let (_, rx) = watch::channel(latest_block_height); Handler::new(worker, multisig, broadcaster.client(), signer, rx) } @@ -396,12 +390,17 @@ mod test { let handler = get_handler( rand_account(), - rand_account(), + TMAddress::from(MULTISIG_ADDRESS.parse::().unwrap()), SharableEcdsaClient::new(client), 100u64, ); - assert!(handler.handle(&wrong_signing_started_event()).await.is_ok()); + assert!(handler + .handle(&signing_started_event_with_missing_fields( + &rand_account().to_string() + )) + .await + .is_ok()); } #[tokio::test] @@ -419,7 +418,7 @@ mod test { ); assert!(handler - .handle(&wrong_signing_started_event()) + .handle(&signing_started_event_with_missing_fields(MULTISIG_ADDRESS)) .await .is_err()); } diff --git a/ampd/src/handlers/sui_verify_msg.rs b/ampd/src/handlers/sui_verify_msg.rs index b19f1e5b8..be1accdcc 100644 --- a/ampd/src/handlers/sui_verify_msg.rs +++ b/ampd/src/handlers/sui_verify_msg.rs @@ -103,6 +103,7 @@ where if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { return Ok(()); } + let PollStartedEvent { poll_id, source_gateway_address, diff --git a/packages/events/src/event.rs b/packages/events/src/event.rs index 38c74dac1..dd9feaee8 100644 --- a/packages/events/src/event.rs +++ b/packages/events/src/event.rs @@ -74,25 +74,21 @@ fn base64_to_utf8(base64_str: &str) -> std::result::Result Option { - let contract_address = match event { +fn contract_address(event: &Event) -> Option { + match event { Event::Abci { event_type: _, attributes, - } => { - if let Some(address) = attributes.get("_contract_address") { - return serde_json::from_value::(address.clone()).ok(); - } - None - } + } => attributes + .get("_contract_address") + .and_then(|address| serde_json::from_value::(address.clone()).ok()), _ => None, - }; - contract_address + } } -pub fn event_is_from_contract(event: &Event, contract_address: &AccountId) -> bool { - match get_contract_address(event) { - Some(address) => &address == contract_address, +pub fn event_is_from_contract(event: &Event, from_address: &AccountId) -> bool { + match contract_address(event) { + Some(emitting_address) => &emitting_address == from_address, _ => false, } } @@ -103,7 +99,7 @@ mod test { use cosmrs::AccountId; - use crate::{event_is_from_contract, get_contract_address, Event}; + use crate::{event::contract_address, event_is_from_contract, Event}; fn make_event_with_contract_address(contract_address: &AccountId) -> Event { let mut attributes = serde_json::Map::new(); @@ -124,9 +120,8 @@ mod test { let event = make_event_with_contract_address(&expected_contract_address); - let contract_address = get_contract_address(&event); - assert!(contract_address.is_some()); - assert_eq!(contract_address.unwrap(), expected_contract_address); + let contract_address = contract_address(&event); + assert_eq!(contract_address, Some(expected_contract_address)); } #[test] @@ -135,7 +130,7 @@ mod test { event_type: "some_event".to_string(), attributes: serde_json::Map::new(), }; - let contract_address = get_contract_address(&event); + let contract_address = contract_address(&event); assert!(contract_address.is_none()); } From 160860204f56b84b85fcea9ff0ae4344b1af5ad6 Mon Sep 17 00:00:00 2001 From: CJ Cobb Date: Thu, 8 Feb 2024 14:39:03 -0500 Subject: [PATCH 3/4] review --- ampd/src/handlers/multisig.rs | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index ac1c217cf..656a24908 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -382,11 +382,8 @@ mod test { } #[tokio::test] - async fn should_not_handle_wrong_event_if_multisig_address_does_not_match() { - let mut client = MockEcdsaClient::new(); - client - .expect_sign() - .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + async fn should_not_handle_event_with_missing_fields_if_multisig_address_does_not_match() { + let client = MockEcdsaClient::new(); let handler = get_handler( rand_account(), @@ -404,11 +401,8 @@ mod test { } #[tokio::test] - async fn should_error_on_wrong_event_if_multisig_address_does_match() { - let mut client = MockEcdsaClient::new(); - client - .expect_sign() - .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + async fn should_error_on_event_with_missing_fields_if_multisig_address_does_match() { + let client = MockEcdsaClient::new(); let handler = get_handler( rand_account(), @@ -424,11 +418,8 @@ mod test { } #[tokio::test] - async fn should_not_handle_correct_event_if_multisig_address_does_not_match() { - let mut client = MockEcdsaClient::new(); - client - .expect_sign() - .returning(move |_, _, _| Err(Report::from(tofnd::error::Error::SignFailed))); + async fn should_not_handle_event_if_multisig_address_does_not_match() { + let client = MockEcdsaClient::new(); let handler = get_handler( rand_account(), From 11481a51818431ffa6c327f58c73bdede3781983 Mon Sep 17 00:00:00 2001 From: CJ Cobb Date: Mon, 12 Feb 2024 13:31:26 -0500 Subject: [PATCH 4/4] review --- ampd/src/handlers/evm_verify_msg.rs | 2 +- ampd/src/handlers/evm_verify_worker_set.rs | 2 +- ampd/src/handlers/multisig.rs | 2 +- ampd/src/handlers/sui_verify_msg.rs | 2 +- ampd/src/handlers/sui_verify_worker_set.rs | 2 +- packages/events/src/event.rs | 53 ++++++++++------------ 6 files changed, 30 insertions(+), 33 deletions(-) diff --git a/ampd/src/handlers/evm_verify_msg.rs b/ampd/src/handlers/evm_verify_msg.rs index 0181ff040..9206df96c 100644 --- a/ampd/src/handlers/evm_verify_msg.rs +++ b/ampd/src/handlers/evm_verify_msg.rs @@ -148,7 +148,7 @@ where type Err = Error; async fn handle(&self, event: &events::Event) -> Result<()> { - if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { + if !event.is_from_contract(self.voting_verifier.as_ref()) { return Ok(()); } diff --git a/ampd/src/handlers/evm_verify_worker_set.rs b/ampd/src/handlers/evm_verify_worker_set.rs index 21c974741..0be19c085 100644 --- a/ampd/src/handlers/evm_verify_worker_set.rs +++ b/ampd/src/handlers/evm_verify_worker_set.rs @@ -144,7 +144,7 @@ where type Err = Error; async fn handle(&self, event: &events::Event) -> Result<()> { - if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { + if !event.is_from_contract(self.voting_verifier.as_ref()) { return Ok(()); } diff --git a/ampd/src/handlers/multisig.rs b/ampd/src/handlers/multisig.rs index 656a24908..5608b8517 100644 --- a/ampd/src/handlers/multisig.rs +++ b/ampd/src/handlers/multisig.rs @@ -130,7 +130,7 @@ where type Err = Error; async fn handle(&self, event: &events::Event) -> error_stack::Result<(), Error> { - if !events::event_is_from_contract(event, self.multisig.as_ref()) { + if !event.is_from_contract(self.multisig.as_ref()) { return Ok(()); } diff --git a/ampd/src/handlers/sui_verify_msg.rs b/ampd/src/handlers/sui_verify_msg.rs index be1accdcc..cfe2c6c82 100644 --- a/ampd/src/handlers/sui_verify_msg.rs +++ b/ampd/src/handlers/sui_verify_msg.rs @@ -100,7 +100,7 @@ where type Err = Error; async fn handle(&self, event: &Event) -> Result<()> { - if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { + if !event.is_from_contract(self.voting_verifier.as_ref()) { return Ok(()); } diff --git a/ampd/src/handlers/sui_verify_worker_set.rs b/ampd/src/handlers/sui_verify_worker_set.rs index fff24c5d4..b21d2d4ec 100644 --- a/ampd/src/handlers/sui_verify_worker_set.rs +++ b/ampd/src/handlers/sui_verify_worker_set.rs @@ -108,7 +108,7 @@ where type Err = Error; async fn handle(&self, event: &Event) -> error_stack::Result<(), Error> { - if !events::event_is_from_contract(event, self.voting_verifier.as_ref()) { + if !event.is_from_contract(self.voting_verifier.as_ref()) { return Ok(()); } diff --git a/packages/events/src/event.rs b/packages/events/src/event.rs index dd9feaee8..f3e590803 100644 --- a/packages/events/src/event.rs +++ b/packages/events/src/event.rs @@ -29,6 +29,25 @@ impl Event { pub fn block_end(height: impl Into) -> Self { Event::BlockEnd(height.into()) } + + pub fn is_from_contract(&self, from_address: &AccountId) -> bool { + match self.contract_address() { + Some(emitting_address) => &emitting_address == from_address, + _ => false, + } + } + + fn contract_address(&self) -> Option { + match self { + Event::Abci { + event_type: _, + attributes, + } => attributes + .get("_contract_address") + .and_then(|address| serde_json::from_value::(address.clone()).ok()), + _ => None, + } + } } impl TryFrom for Event { @@ -74,32 +93,13 @@ fn base64_to_utf8(base64_str: &str) -> std::result::Result Option { - match event { - Event::Abci { - event_type: _, - attributes, - } => attributes - .get("_contract_address") - .and_then(|address| serde_json::from_value::(address.clone()).ok()), - _ => None, - } -} - -pub fn event_is_from_contract(event: &Event, from_address: &AccountId) -> bool { - match contract_address(event) { - Some(emitting_address) => &emitting_address == from_address, - _ => false, - } -} - #[cfg(test)] mod test { use std::str::FromStr; use cosmrs::AccountId; - use crate::{event::contract_address, event_is_from_contract, Event}; + use crate::Event; fn make_event_with_contract_address(contract_address: &AccountId) -> Event { let mut attributes = serde_json::Map::new(); @@ -120,7 +120,7 @@ mod test { let event = make_event_with_contract_address(&expected_contract_address); - let contract_address = contract_address(&event); + let contract_address = event.contract_address(); assert_eq!(contract_address, Some(expected_contract_address)); } @@ -130,7 +130,7 @@ mod test { event_type: "some_event".to_string(), attributes: serde_json::Map::new(), }; - let contract_address = contract_address(&event); + let contract_address = event.contract_address(); assert!(contract_address.is_none()); } @@ -139,11 +139,11 @@ mod test { let contract_address = AccountId::from_str("axelarvaloper1zh9wrak6ke4n6fclj5e8yk397czv430ygs5jz7").unwrap(); let event = make_event_with_contract_address(&contract_address); - assert!(event_is_from_contract(&event, &contract_address)); + assert!(event.is_from_contract(&contract_address)); let diff_contract_address = AccountId::from_str("axelarvaloper1tee73c83k2vqky9gt59jd3ztwxhqjm27l588q6").unwrap(); - assert!(!event_is_from_contract(&event, &diff_contract_address)); + assert!(!event.is_from_contract(&diff_contract_address)); } #[test] @@ -156,9 +156,6 @@ mod test { attributes: serde_json::Map::new(), }; - assert!(!event_is_from_contract( - &event_without_contract_address, - &contract_address - )); + assert!(!event_without_contract_address.is_from_contract(&contract_address)); } }