From c0f87ba723e2b7e20f9bd203c00f48c098ca3473 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 17 Jan 2025 12:42:00 +0000 Subject: [PATCH 01/18] Add receipt block info to MessageResponse --- .../src/impls/send_message.rs | 10 +++++++--- .../src/types/message_response.rs | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/relayer/crates/starknet-chain-components/src/impls/send_message.rs b/relayer/crates/starknet-chain-components/src/impls/send_message.rs index 3b165f39..7594f627 100644 --- a/relayer/crates/starknet-chain-components/src/impls/send_message.rs +++ b/relayer/crates/starknet-chain-components/src/impls/send_message.rs @@ -9,7 +9,7 @@ use hermes_relayer_components::transaction::traits::submit_tx::CanSubmitTx; use hermes_relayer_components::transaction::traits::types::tx_response::HasTxResponseType; use starknet::accounts::Call; use starknet::core::types::{ - ExecuteInvocation, FunctionInvocation, RevertedInvocation, TransactionTrace, + ExecuteInvocation, FunctionInvocation, ReceiptBlock, RevertedInvocation, TransactionTrace, }; use crate::impls::types::message::StarknetMessage; @@ -45,13 +45,15 @@ where let tx_response = chain.poll_tx_response(&tx_hash).await?; + let receipt_block = tx_response.receipt.block; + match tx_response.trace { TransactionTrace::Invoke(trace) => match trace.execute_invocation { ExecuteInvocation::Success(invocation) => { let message_responses = invocation .calls .into_iter() - .map(extract_events_from_function_invocation) + .map(|e| extract_events_from_function_invocation(&receipt_block, e)) .collect(); Ok(message_responses) @@ -68,6 +70,7 @@ where } pub fn extract_events_from_function_invocation( + receipt_block: &ReceiptBlock, invocation: FunctionInvocation, ) -> StarknetMessageResponse { let mut events: Vec = invocation @@ -83,11 +86,12 @@ pub fn extract_events_from_function_invocation( .collect(); for inner in invocation.calls { - let mut message_response = extract_events_from_function_invocation(inner); + let mut message_response = extract_events_from_function_invocation(receipt_block, inner); events.append(&mut message_response.events); } StarknetMessageResponse { + receipt_block: receipt_block.clone(), result: invocation.result, events, } diff --git a/relayer/crates/starknet-chain-components/src/types/message_response.rs b/relayer/crates/starknet-chain-components/src/types/message_response.rs index 3c6ef5d9..bdcebde5 100644 --- a/relayer/crates/starknet-chain-components/src/types/message_response.rs +++ b/relayer/crates/starknet-chain-components/src/types/message_response.rs @@ -4,12 +4,13 @@ use hermes_chain_type_components::traits::fields::message_response_events::Messa use hermes_chain_type_components::traits::types::message_response::{ HasMessageResponseType, ProvideMessageResponseType, }; -use starknet::core::types::Felt; +use starknet::core::types::{Felt, ReceiptBlock}; use crate::types::event::StarknetEvent; #[derive(Debug)] pub struct StarknetMessageResponse { + pub receipt_block: ReceiptBlock, pub result: Vec, pub events: Vec, } From 2299952de7675f67a64418f61974b38e851e151d Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 17 Jan 2025 16:44:50 +0000 Subject: [PATCH 02/18] Managed to poll SendPacket events successfully --- .../src/tests/ics20.rs | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/relayer/crates/starknet-integration-tests/src/tests/ics20.rs b/relayer/crates/starknet-integration-tests/src/tests/ics20.rs index c9da0a89..147a1e27 100644 --- a/relayer/crates/starknet-integration-tests/src/tests/ics20.rs +++ b/relayer/crates/starknet-integration-tests/src/tests/ics20.rs @@ -5,7 +5,9 @@ use std::path::PathBuf; use std::time::SystemTime; use cgp::prelude::*; -use hermes_chain_components::traits::queries::chain_status::CanQueryChainStatus; +use hermes_chain_components::traits::queries::chain_status::{ + CanQueryChainHeight, CanQueryChainStatus, +}; use hermes_chain_components::traits::queries::client_state::CanQueryClientStateWithLatestHeight; use hermes_cosmos_chain_components::types::channel::CosmosInitChannelOptions; use hermes_cosmos_chain_components::types::connection::CosmosInitConnectionOptions; @@ -64,8 +66,9 @@ use ibc::primitives::Timestamp as IbcTimestamp; use poseidon::Poseidon3Hasher; use sha2::{Digest, Sha256}; use starknet::accounts::Call; -use starknet::core::types::{Felt, U256}; +use starknet::core::types::{BlockId, EventFilter, Felt, U256}; use starknet::macros::{selector, short_string}; +use starknet::providers::Provider; use tracing::info; use crate::contexts::bootstrap::StarknetBootstrap; @@ -122,6 +125,11 @@ fn test_starknet_ics20_contract() -> Result<(), Error> { let starknet_chain = &mut starknet_chain_driver.chain; + info!( + "started starknet chain at port {}", + starknet_chain_driver.node_config.rpc_port + ); + let cosmos_chain_driver = cosmos_bootstrap.bootstrap_chain("cosmos").await?; let cosmos_chain = &cosmos_chain_driver.chain; @@ -509,8 +517,9 @@ fn test_starknet_ics20_contract() -> Result<(), Error> { } }; - // submit to ics20 contract + let event_start_height = starknet_chain.query_chain_height().await?; + // submit to ics20 contract let (send_packet_event, send_ics20_event) = { let call_data = cairo_encoding.encode(&starknet_ics20_send_message)?; @@ -547,9 +556,40 @@ fn test_starknet_ics20_contract() -> Result<(), Error> { panic!("expected send ics20 event"); }; + { + tokio::time::sleep(core::time::Duration::from_secs(1)).await; + + let event_end_height = starknet_chain.query_chain_height().await?; + + info!("polling events from {event_start_height} to {event_end_height}"); + + let events = starknet_chain + .rpc_client + .get_events( + EventFilter { + from_block: Some(BlockId::Number(event_start_height)), + to_block: None, + address: Some(ibc_core_address), + keys: None, + }, + None, + 1000, + ) + .await?; + + info!("polled events: {events:?}"); + + let parsed_events: Vec = + event_encoding.filter_decode_events(&response.events)?; + + info!("parsed polled events: {parsed_events:?}"); + } + (send_packet_event, send_ics20_event) }; + tokio::time::sleep(core::time::Duration::from_secs(999999999)).await; + // create ibc packet let starknet_ibc_packet = { From 7aa9b46ba75068d49baf2efa23355cab7a868dc0 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 17 Jan 2025 19:51:41 +0000 Subject: [PATCH 03/18] Add StarknetEventEncoding field --- .../src/impls/subscription.rs | 7 +++++ .../src/contexts/chain.rs | 2 ++ .../src/contexts/encoding/event.rs | 2 +- .../src/contexts/bootstrap.rs | 1 + .../src/tests/ics20.rs | 27 +++++++++++-------- .../starknet-relayer/src/contexts/builder.rs | 1 + 6 files changed, 28 insertions(+), 12 deletions(-) create mode 100644 relayer/crates/starknet-chain-components/src/impls/subscription.rs diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs new file mode 100644 index 00000000..72ac61c6 --- /dev/null +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -0,0 +1,7 @@ +use hermes_chain_components::traits::types::event::HasEventType; +use hermes_chain_components::traits::types::height::HasHeightType; + + +pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType { + +} \ No newline at end of file diff --git a/relayer/crates/starknet-chain-context/src/contexts/chain.rs b/relayer/crates/starknet-chain-context/src/contexts/chain.rs index 0927e91a..5e7d8f59 100644 --- a/relayer/crates/starknet-chain-context/src/contexts/chain.rs +++ b/relayer/crates/starknet-chain-context/src/contexts/chain.rs @@ -163,6 +163,7 @@ use starknet::providers::JsonRpcClient; use starknet::signers::LocalWallet; use crate::contexts::encoding::cairo::StarknetCairoEncoding; +use crate::contexts::encoding::event::StarknetEventEncoding; use crate::contexts::encoding::protobuf::StarknetProtobufEncoding; use crate::impls::error::HandleStarknetChainError; @@ -174,6 +175,7 @@ pub struct StarknetChain { pub account: SingleOwnerAccount>, LocalWallet>, pub ibc_client_contract_address: Option, pub ibc_core_contract_address: Option, + pub event_encoding: StarknetEventEncoding, } pub struct StarknetChainContextComponents; diff --git a/relayer/crates/starknet-chain-context/src/contexts/encoding/event.rs b/relayer/crates/starknet-chain-context/src/contexts/encoding/event.rs index 5547ec75..0a691573 100644 --- a/relayer/crates/starknet-chain-context/src/contexts/encoding/event.rs +++ b/relayer/crates/starknet-chain-context/src/contexts/encoding/event.rs @@ -23,7 +23,7 @@ use starknet::core::types::Felt; use crate::contexts::encoding::cairo::{ProvideCairoEncoding, StarknetCairoEncoding}; use crate::impls::error::HandleStarknetChainError; -#[derive(HasField, Default)] +#[derive(HasField, Default, Clone)] pub struct StarknetEventEncoding { pub erc20_hashes: HashSet, pub ics20_hashes: HashSet, diff --git a/relayer/crates/starknet-integration-tests/src/contexts/bootstrap.rs b/relayer/crates/starknet-integration-tests/src/contexts/bootstrap.rs index e6ecf5bc..cef25532 100644 --- a/relayer/crates/starknet-integration-tests/src/contexts/bootstrap.rs +++ b/relayer/crates/starknet-integration-tests/src/contexts/bootstrap.rs @@ -143,6 +143,7 @@ impl ChainDriverBuilder for StarknetBootstrapComponents { account, ibc_client_contract_address: None, ibc_core_contract_address: None, + event_encoding: Default::default(), }; let chain_driver = StarknetChainDriver { diff --git a/relayer/crates/starknet-integration-tests/src/tests/ics20.rs b/relayer/crates/starknet-integration-tests/src/tests/ics20.rs index 147a1e27..11fcee90 100644 --- a/relayer/crates/starknet-integration-tests/src/tests/ics20.rs +++ b/relayer/crates/starknet-integration-tests/src/tests/ics20.rs @@ -213,7 +213,7 @@ fn test_starknet_ics20_contract() -> Result<(), Error> { let cairo_encoding = StarknetCairoEncoding; - let event_encoding = StarknetEventEncoding { + starknet_chain.event_encoding = StarknetEventEncoding { erc20_hashes: [erc20_class_hash].into(), ics20_hashes: [ics20_class_hash].into(), ibc_client_hashes: [comet_client_class_hash].into(), @@ -535,13 +535,15 @@ fn test_starknet_ics20_contract() -> Result<(), Error> { info!("ICS20 send packet response: {:?}", response); - let mut ibc_packet_events: Vec = - event_encoding.filter_decode_events(&response.events)?; + let mut ibc_packet_events: Vec = starknet_chain + .event_encoding + .filter_decode_events(&response.events)?; info!("IBC packet events: {:?}", ibc_packet_events); - let mut ibc_transfer_events: Vec = - event_encoding.filter_decode_events(&response.events)?; + let mut ibc_transfer_events: Vec = starknet_chain + .event_encoding + .filter_decode_events(&response.events)?; info!("IBC transfer events: {:?}", ibc_transfer_events); @@ -579,8 +581,9 @@ fn test_starknet_ics20_contract() -> Result<(), Error> { info!("polled events: {events:?}"); - let parsed_events: Vec = - event_encoding.filter_decode_events(&response.events)?; + let parsed_events: Vec = starknet_chain + .event_encoding + .filter_decode_events(&response.events)?; info!("parsed polled events: {parsed_events:?}"); } @@ -762,13 +765,15 @@ fn test_starknet_ics20_contract() -> Result<(), Error> { info!("ICS20 send packet response: {:?}", response); - let mut ibc_packet_events: Vec = - event_encoding.filter_decode_events(&response.events)?; + let mut ibc_packet_events: Vec = starknet_chain + .event_encoding + .filter_decode_events(&response.events)?; info!("IBC packet events: {:?}", ibc_packet_events); - let mut ibc_transfer_events: Vec = - event_encoding.filter_decode_events(&response.events)?; + let mut ibc_transfer_events: Vec = starknet_chain + .event_encoding + .filter_decode_events(&response.events)?; info!("IBC transfer events: {:?}", ibc_transfer_events); diff --git a/relayer/crates/starknet-relayer/src/contexts/builder.rs b/relayer/crates/starknet-relayer/src/contexts/builder.rs index 61a81fbc..34b74988 100644 --- a/relayer/crates/starknet-relayer/src/contexts/builder.rs +++ b/relayer/crates/starknet-relayer/src/contexts/builder.rs @@ -146,6 +146,7 @@ impl StarknetBuilder { account, ibc_client_contract_address: None, ibc_core_contract_address: None, + event_encoding: Default::default(), }; Ok(context) From 984343cd635385ffdc37afc233ac495a1fa7b4eb Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 17 Jan 2025 19:55:27 +0000 Subject: [PATCH 04/18] Implement HasEncoding for StarknetChain --- .../src/types/as_starknet_event.rs | 1 + .../src/types/mod.rs | 1 + .../src/contexts/chain.rs | 21 ++++++++++++++++--- 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 relayer/crates/cairo-encoding-components/src/types/as_starknet_event.rs diff --git a/relayer/crates/cairo-encoding-components/src/types/as_starknet_event.rs b/relayer/crates/cairo-encoding-components/src/types/as_starknet_event.rs new file mode 100644 index 00000000..a30c92a1 --- /dev/null +++ b/relayer/crates/cairo-encoding-components/src/types/as_starknet_event.rs @@ -0,0 +1 @@ +pub struct AsStarknetEvent; diff --git a/relayer/crates/cairo-encoding-components/src/types/mod.rs b/relayer/crates/cairo-encoding-components/src/types/mod.rs index 306c5c12..6ba4df23 100644 --- a/relayer/crates/cairo-encoding-components/src/types/mod.rs +++ b/relayer/crates/cairo-encoding-components/src/types/mod.rs @@ -1,2 +1,3 @@ pub mod as_felt; +pub mod as_starknet_event; pub mod nat; diff --git a/relayer/crates/starknet-chain-context/src/contexts/chain.rs b/relayer/crates/starknet-chain-context/src/contexts/chain.rs index 5e7d8f59..6a8fb63a 100644 --- a/relayer/crates/starknet-chain-context/src/contexts/chain.rs +++ b/relayer/crates/starknet-chain-context/src/contexts/chain.rs @@ -6,6 +6,7 @@ use cgp::core::field::WithField; use cgp::core::types::WithType; use cgp::prelude::*; use hermes_cairo_encoding_components::types::as_felt::AsFelt; +use hermes_cairo_encoding_components::types::as_starknet_event::AsStarknetEvent; use hermes_chain_type_components::traits::fields::chain_id::HasChainId; use hermes_chain_type_components::traits::types::commitment_proof::HasCommitmentProofType; use hermes_chain_type_components::traits::types::height::HasHeightType; @@ -13,9 +14,8 @@ use hermes_chain_type_components::traits::types::message_response::HasMessageRes use hermes_cosmos_chain_components::components::delegate::DelegateCosmosChainComponents; use hermes_cosmos_chain_components::types::connection::CosmosInitConnectionOptions; use hermes_cosmos_relayer::contexts::chain::CosmosChain; -use hermes_encoding_components::impls::default_encoding::GetDefaultEncoding; use hermes_encoding_components::traits::has_encoding::{ - DefaultEncodingGetter, EncodingGetterComponent, HasDefaultEncoding, ProvideEncodingType, + DefaultEncodingGetter, EncodingGetter, HasDefaultEncoding, ProvideEncodingType, }; use hermes_encoding_components::types::AsBytes; use hermes_error::impls::ProvideHermesError; @@ -196,7 +196,6 @@ delegate_components! { GlobalLoggerGetterComponent, ]: ProvideNoLogger, - EncodingGetterComponent: GetDefaultEncoding, [ StarknetProviderTypeComponent, StarknetProviderGetterComponent, @@ -229,12 +228,28 @@ impl ProvideEncodingType for StarknetChainContextComponen type Encoding = StarknetCairoEncoding; } +impl ProvideEncodingType for StarknetChainContextComponents { + type Encoding = StarknetEventEncoding; +} + impl DefaultEncodingGetter for StarknetChainContextComponents { fn default_encoding() -> &'static StarknetCairoEncoding { &StarknetCairoEncoding } } +impl EncodingGetter for StarknetChainContextComponents { + fn encoding(_chain: &StarknetChain) -> &StarknetCairoEncoding { + &StarknetCairoEncoding + } +} + +impl EncodingGetter for StarknetChainContextComponents { + fn encoding(chain: &StarknetChain) -> &StarknetEventEncoding { + &chain.event_encoding + } +} + impl ProvideEncodingType for StarknetChainContextComponents { type Encoding = StarknetProtobufEncoding; } From e5e04b8a134702befc4870da8498c400ea69018d Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 17 Jan 2025 20:32:44 +0000 Subject: [PATCH 05/18] Implementing CanPollStarknetIbcEvents --- relayer/Cargo.lock | 1 + .../starknet-chain-components/Cargo.toml | 1 + .../src/impls/mod.rs | 1 + .../src/impls/send_message.rs | 28 +++++---- .../src/impls/subscription.rs | 59 ++++++++++++++++++- .../src/types/message_response.rs | 1 - 6 files changed, 75 insertions(+), 16 deletions(-) diff --git a/relayer/Cargo.lock b/relayer/Cargo.lock index 7ab1b93a..25e0c6be 100644 --- a/relayer/Cargo.lock +++ b/relayer/Cargo.lock @@ -2258,6 +2258,7 @@ dependencies = [ "cairo-lang-starknet-classes", "cgp", "crypto-bigint", + "hermes-async-runtime-components", "hermes-cairo-encoding-components", "hermes-chain-components", "hermes-chain-type-components", diff --git a/relayer/crates/starknet-chain-components/Cargo.toml b/relayer/crates/starknet-chain-components/Cargo.toml index c6e201e6..30c09e97 100644 --- a/relayer/crates/starknet-chain-components/Cargo.toml +++ b/relayer/crates/starknet-chain-components/Cargo.toml @@ -14,6 +14,7 @@ cgp = { workspace = true } hermes-relayer-components = { workspace = true } hermes-test-components = { workspace = true } hermes-runtime-components = { workspace = true } +hermes-async-runtime-components = { workspace = true } hermes-chain-components = { workspace = true } hermes-chain-type-components = { workspace = true } hermes-encoding-components = { workspace = true } diff --git a/relayer/crates/starknet-chain-components/src/impls/mod.rs b/relayer/crates/starknet-chain-components/src/impls/mod.rs index 84dc93b4..977616cc 100644 --- a/relayer/crates/starknet-chain-components/src/impls/mod.rs +++ b/relayer/crates/starknet-chain-components/src/impls/mod.rs @@ -14,6 +14,7 @@ pub mod queries; pub mod send_message; pub mod starknet_to_cosmos; pub mod submit_tx; +pub mod subscription; pub mod transfer; pub mod tx_response; pub mod types; diff --git a/relayer/crates/starknet-chain-components/src/impls/send_message.rs b/relayer/crates/starknet-chain-components/src/impls/send_message.rs index 7594f627..763400ec 100644 --- a/relayer/crates/starknet-chain-components/src/impls/send_message.rs +++ b/relayer/crates/starknet-chain-components/src/impls/send_message.rs @@ -9,7 +9,7 @@ use hermes_relayer_components::transaction::traits::submit_tx::CanSubmitTx; use hermes_relayer_components::transaction::traits::types::tx_response::HasTxResponseType; use starknet::accounts::Call; use starknet::core::types::{ - ExecuteInvocation, FunctionInvocation, ReceiptBlock, RevertedInvocation, TransactionTrace, + ExecuteInvocation, FunctionInvocation, RevertedInvocation, TransactionTrace, }; use crate::impls::types::message::StarknetMessage; @@ -45,15 +45,13 @@ where let tx_response = chain.poll_tx_response(&tx_hash).await?; - let receipt_block = tx_response.receipt.block; - match tx_response.trace { TransactionTrace::Invoke(trace) => match trace.execute_invocation { ExecuteInvocation::Success(invocation) => { let message_responses = invocation .calls .into_iter() - .map(|e| extract_events_from_function_invocation(&receipt_block, e)) + .map(extract_message_response_from_function_invocation) .collect(); Ok(message_responses) @@ -69,10 +67,18 @@ where } } -pub fn extract_events_from_function_invocation( - receipt_block: &ReceiptBlock, +pub fn extract_message_response_from_function_invocation( invocation: FunctionInvocation, ) -> StarknetMessageResponse { + let result = invocation.result.clone(); + let events = extract_events_from_function_invocation(invocation); + + StarknetMessageResponse { result, events } +} + +pub fn extract_events_from_function_invocation( + invocation: FunctionInvocation, +) -> Vec { let mut events: Vec = invocation .events .into_iter() @@ -86,15 +92,11 @@ pub fn extract_events_from_function_invocation( .collect(); for inner in invocation.calls { - let mut message_response = extract_events_from_function_invocation(receipt_block, inner); - events.append(&mut message_response.events); + let mut in_events = extract_events_from_function_invocation(inner); + events.append(&mut in_events); } - StarknetMessageResponse { - receipt_block: receipt_block.clone(), - result: invocation.result, - events, - } + events } impl Debug for UnexpectedTransactionTraceType { diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index 72ac61c6..7ea3b985 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -1,7 +1,62 @@ +use std::sync::Arc; + +use cgp::prelude::*; +use hermes_async_runtime_components::subscription::traits::subscription::Subscription; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; +use starknet::core::types::BlockId; +use starknet::providers::{Provider, ProviderError}; + +use crate::traits::provider::HasStarknetProvider; +use crate::traits::queries::address::CanQueryContractAddress; +use crate::types::event::StarknetEvent; + +pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType + HasAsyncErrorType { + fn create_event_subscription( + &self, + ) -> Result)>>, Self::Error>; +} + +impl CanCreateStarknetSubscription for Chain +where + Chain: HasHeightType + + HasEventType + + HasAsyncErrorType + + CanQueryContractAddress, +{ + fn create_event_subscription( + &self, + ) -> Result)>>, Self::Error> { + todo!() + } +} + +#[async_trait] +pub trait CanPollStarknetIbcEvents: HasHeightType + HasEventType + HasAsyncErrorType { + async fn poll_starknet_ibc_events( + &self, + height: &Self::Height, + ) -> Result, Self::Error>; +} +impl CanPollStarknetIbcEvents for Chain +where + Chain: HasHeightType + + HasEventType + + HasStarknetProvider + + CanRaiseAsyncError, +{ + async fn poll_starknet_ibc_events( + &self, + height: &u64, + ) -> Result, Self::Error> { + let provider = self.provider(); -pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType { + let traces = provider + .trace_block_transactions(BlockId::Number(*height)) + .await + .map_err(Chain::raise_error)?; -} \ No newline at end of file + todo!() + } +} diff --git a/relayer/crates/starknet-chain-components/src/types/message_response.rs b/relayer/crates/starknet-chain-components/src/types/message_response.rs index bdcebde5..3059506e 100644 --- a/relayer/crates/starknet-chain-components/src/types/message_response.rs +++ b/relayer/crates/starknet-chain-components/src/types/message_response.rs @@ -10,7 +10,6 @@ use crate::types::event::StarknetEvent; #[derive(Debug)] pub struct StarknetMessageResponse { - pub receipt_block: ReceiptBlock, pub result: Vec, pub events: Vec, } From 7a7d8b922a57194f1a6e2b4deafae0cb5506000f Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 17 Jan 2025 20:39:53 +0000 Subject: [PATCH 06/18] Finish draft for CanPollStarknetIbcEvents --- .../src/impls/subscription.rs | 19 +++++++++++++++++-- .../src/types/message_response.rs | 2 +- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index 7ea3b985..2524383e 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -4,9 +4,10 @@ use cgp::prelude::*; use hermes_async_runtime_components::subscription::traits::subscription::Subscription; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; -use starknet::core::types::BlockId; +use starknet::core::types::{BlockId, ExecuteInvocation, TransactionTrace}; use starknet::providers::{Provider, ProviderError}; +use crate::impls::send_message::extract_events_from_function_invocation; use crate::traits::provider::HasStarknetProvider; use crate::traits::queries::address::CanQueryContractAddress; use crate::types::event::StarknetEvent; @@ -57,6 +58,20 @@ where .await .map_err(Chain::raise_error)?; - todo!() + let events: Vec = traces + .into_iter() + .filter_map(|trace| match trace.trace_root { + TransactionTrace::Invoke(invoke) => match invoke.execute_invocation { + ExecuteInvocation::Success(invoke) => { + Some(extract_events_from_function_invocation(invoke)) + } + _ => None, + }, + _ => None, + }) + .flatten() + .collect(); + + Ok(events) } } diff --git a/relayer/crates/starknet-chain-components/src/types/message_response.rs b/relayer/crates/starknet-chain-components/src/types/message_response.rs index 3059506e..3c6ef5d9 100644 --- a/relayer/crates/starknet-chain-components/src/types/message_response.rs +++ b/relayer/crates/starknet-chain-components/src/types/message_response.rs @@ -4,7 +4,7 @@ use hermes_chain_type_components::traits::fields::message_response_events::Messa use hermes_chain_type_components::traits::types::message_response::{ HasMessageResponseType, ProvideMessageResponseType, }; -use starknet::core::types::{Felt, ReceiptBlock}; +use starknet::core::types::Felt; use crate::types::event::StarknetEvent; From efcdc9428161b56e6304f5c8832dd8582e810e98 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Mon, 20 Jan 2025 13:02:04 +0000 Subject: [PATCH 07/18] Define CanQueryBlockEvents component --- .../src/components/starknet_to_cosmos.rs | 1 - .../src/impls/queries/block_events.rs | 48 ++++++++++++++++++ .../src/impls/queries/mod.rs | 1 + .../src/impls/subscription.rs | 49 ------------------- .../src/traits/queries/block_events.rs | 15 ++++++ .../src/traits/queries/mod.rs | 1 + 6 files changed, 65 insertions(+), 50 deletions(-) create mode 100644 relayer/crates/starknet-chain-components/src/impls/queries/block_events.rs create mode 100644 relayer/crates/starknet-chain-components/src/traits/queries/block_events.rs diff --git a/relayer/crates/starknet-chain-components/src/components/starknet_to_cosmos.rs b/relayer/crates/starknet-chain-components/src/components/starknet_to_cosmos.rs index 5acb07cf..26f6ade9 100644 --- a/relayer/crates/starknet-chain-components/src/components/starknet_to_cosmos.rs +++ b/relayer/crates/starknet-chain-components/src/components/starknet_to_cosmos.rs @@ -94,6 +94,5 @@ cgp_preset! { PacketDstChannelIdGetterComponent, ]: ReadPacketDstStarknetFields, - } } diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events.rs new file mode 100644 index 00000000..0bb74d03 --- /dev/null +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events.rs @@ -0,0 +1,48 @@ +use cgp::prelude::*; +use hermes_chain_components::traits::types::event::HasEventType; +use hermes_chain_components::traits::types::height::HasHeightType; +use starknet::core::types::{BlockId, ExecuteInvocation, TransactionTrace}; +use starknet::providers::{Provider, ProviderError}; + +use crate::impls::send_message::extract_events_from_function_invocation; +use crate::traits::provider::HasStarknetProvider; +use crate::traits::queries::block_events::BlockEventsQuerier; +use crate::types::event::StarknetEvent; + +pub struct QueryStarknetBlockEvents; + +impl BlockEventsQuerier for QueryStarknetBlockEvents +where + Chain: HasHeightType + + HasEventType + + HasStarknetProvider + + CanRaiseAsyncError, +{ + async fn query_block_events( + chain: &Chain, + height: &u64, + ) -> Result, Chain::Error> { + let provider = chain.provider(); + + let traces = provider + .trace_block_transactions(BlockId::Number(*height)) + .await + .map_err(Chain::raise_error)?; + + let events: Vec = traces + .into_iter() + .filter_map(|trace| match trace.trace_root { + TransactionTrace::Invoke(invoke) => match invoke.execute_invocation { + ExecuteInvocation::Success(invoke) => { + Some(extract_events_from_function_invocation(invoke)) + } + _ => None, + }, + _ => None, + }) + .flatten() + .collect(); + + Ok(events) + } +} diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/mod.rs b/relayer/crates/starknet-chain-components/src/impls/queries/mod.rs index 0039e263..7b4c3f10 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/mod.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/mod.rs @@ -1,5 +1,6 @@ pub mod ack_commitment; pub mod balance; +pub mod block_events; pub mod channel_end; pub mod client_state; pub mod connection_end; diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index 2524383e..b1a04848 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -4,13 +4,8 @@ use cgp::prelude::*; use hermes_async_runtime_components::subscription::traits::subscription::Subscription; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; -use starknet::core::types::{BlockId, ExecuteInvocation, TransactionTrace}; -use starknet::providers::{Provider, ProviderError}; -use crate::impls::send_message::extract_events_from_function_invocation; -use crate::traits::provider::HasStarknetProvider; use crate::traits::queries::address::CanQueryContractAddress; -use crate::types::event::StarknetEvent; pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType + HasAsyncErrorType { fn create_event_subscription( @@ -31,47 +26,3 @@ where todo!() } } - -#[async_trait] -pub trait CanPollStarknetIbcEvents: HasHeightType + HasEventType + HasAsyncErrorType { - async fn poll_starknet_ibc_events( - &self, - height: &Self::Height, - ) -> Result, Self::Error>; -} - -impl CanPollStarknetIbcEvents for Chain -where - Chain: HasHeightType - + HasEventType - + HasStarknetProvider - + CanRaiseAsyncError, -{ - async fn poll_starknet_ibc_events( - &self, - height: &u64, - ) -> Result, Self::Error> { - let provider = self.provider(); - - let traces = provider - .trace_block_transactions(BlockId::Number(*height)) - .await - .map_err(Chain::raise_error)?; - - let events: Vec = traces - .into_iter() - .filter_map(|trace| match trace.trace_root { - TransactionTrace::Invoke(invoke) => match invoke.execute_invocation { - ExecuteInvocation::Success(invoke) => { - Some(extract_events_from_function_invocation(invoke)) - } - _ => None, - }, - _ => None, - }) - .flatten() - .collect(); - - Ok(events) - } -} diff --git a/relayer/crates/starknet-chain-components/src/traits/queries/block_events.rs b/relayer/crates/starknet-chain-components/src/traits/queries/block_events.rs new file mode 100644 index 00000000..bef480dc --- /dev/null +++ b/relayer/crates/starknet-chain-components/src/traits/queries/block_events.rs @@ -0,0 +1,15 @@ +use cgp::prelude::*; +use hermes_chain_components::traits::types::event::HasEventType; +use hermes_chain_components::traits::types::height::HasHeightType; + +#[cgp_component { + provider: BlockEventsQuerier, + context: Chain, +}] +#[async_trait] +pub trait CanQueryBlockEvents: HasHeightType + HasEventType + HasAsyncErrorType { + async fn query_block_events( + &self, + height: &Self::Height, + ) -> Result, Self::Error>; +} diff --git a/relayer/crates/starknet-chain-components/src/traits/queries/mod.rs b/relayer/crates/starknet-chain-components/src/traits/queries/mod.rs index 86b5c989..8f66ddf6 100644 --- a/relayer/crates/starknet-chain-components/src/traits/queries/mod.rs +++ b/relayer/crates/starknet-chain-components/src/traits/queries/mod.rs @@ -1,2 +1,3 @@ pub mod address; +pub mod block_events; pub mod token_balance; From 9297a51de2425b466dabcd9cc8574888461d5d3a Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Mon, 20 Jan 2025 14:20:00 +0000 Subject: [PATCH 08/18] Drafting Starknet event stream --- relayer/Cargo.lock | 1 + .../starknet-chain-components/Cargo.toml | 1 + .../src/impls/subscription.rs | 66 ++++++++++++++++--- 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/relayer/Cargo.lock b/relayer/Cargo.lock index 25e0c6be..bcb1f708 100644 --- a/relayer/Cargo.lock +++ b/relayer/Cargo.lock @@ -2258,6 +2258,7 @@ dependencies = [ "cairo-lang-starknet-classes", "cgp", "crypto-bigint", + "futures", "hermes-async-runtime-components", "hermes-cairo-encoding-components", "hermes-chain-components", diff --git a/relayer/crates/starknet-chain-components/Cargo.toml b/relayer/crates/starknet-chain-components/Cargo.toml index 30c09e97..93de6eea 100644 --- a/relayer/crates/starknet-chain-components/Cargo.toml +++ b/relayer/crates/starknet-chain-components/Cargo.toml @@ -36,4 +36,5 @@ serde = { workspace = true } serde_json = { workspace = true } starknet = { workspace = true } tonic = { workspace = true } +futures = { workspace = true } crypto-bigint = "0.5.5" diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index b1a04848..1586cc53 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -1,28 +1,76 @@ +use core::marker::PhantomData; +use core::pin::Pin; use std::sync::Arc; use cgp::prelude::*; +use futures::{stream, Stream, StreamExt, TryStreamExt}; +use hermes_async_runtime_components::subscription::impls::closure::CanCreateClosureSubscription; use hermes_async_runtime_components::subscription::traits::subscription::Subscription; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_runtime_components::traits::runtime::HasRuntime; use crate::traits::queries::address::CanQueryContractAddress; +use crate::traits::queries::block_events::CanQueryBlockEvents; +use crate::types::event::StarknetEvent; +#[async_trait] pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType + HasAsyncErrorType { - fn create_event_subscription( - &self, + async fn create_event_subscription( + self, + start_height: Self::Height, ) -> Result)>>, Self::Error>; } impl CanCreateStarknetSubscription for Chain where - Chain: HasHeightType - + HasEventType - + HasAsyncErrorType + Chain: Clone + + Send + + Sync + + 'static + + HasRuntime + + HasHeightType + + HasEventType + + CanQueryBlockEvents + CanQueryContractAddress, + Chain::Runtime: CanCreateClosureSubscription, { - fn create_event_subscription( - &self, - ) -> Result)>>, Self::Error> { - todo!() + async fn create_event_subscription( + self, + mut next_height: u64, + ) -> Result)>>, Self::Error> { + let ibc_core_contract_address = self.query_contract_address(PhantomData).await?; + + Ok(Chain::Runtime::new_closure_subscription(move || { + let chain = self.clone(); + Box::pin(async move { + let height_stream = stream::repeat_with(move || { + let height = next_height.clone(); + next_height += 1; + height + }); + + let event_stream = height_stream + .filter_map(|height| { + let chain = chain.clone(); + async move { + // let chain = chain.clone(); + // let events = chain.query_block_events(&height).await.ok()?; + let events_with_height = + [].into_iter().map(move |event| (height, Arc::new(event))); + + Some(stream::iter(events_with_height)) + } + }) + .flatten(); + + let boxed_stream: Pin< + Box)> + Send + Sync>, + > = Box::pin(event_stream); + + todo!() + // Some(Box::pin(event_stream)) + }) + })) } } From fef94082c6b5687eb2af1aaa04babeb9cbb778eb Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 14:33:23 +0000 Subject: [PATCH 09/18] Done initial implementation of CanCreateStarknetSubscription --- .../src/impls/subscription.rs | 119 ++++++++++++------ 1 file changed, 79 insertions(+), 40 deletions(-) diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index 1586cc53..bac0a1dd 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -1,18 +1,19 @@ -use core::marker::PhantomData; use core::pin::Pin; use std::sync::Arc; use cgp::prelude::*; -use futures::{stream, Stream, StreamExt, TryStreamExt}; +use futures::channel::mpsc::{unbounded, UnboundedSender}; +use futures::Stream; +use hermes_async_runtime_components::channel::types::ChannelClosedError; use hermes_async_runtime_components::subscription::impls::closure::CanCreateClosureSubscription; use hermes_async_runtime_components::subscription::traits::subscription::Subscription; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; use hermes_runtime_components::traits::runtime::HasRuntime; +use hermes_runtime_components::traits::spawn::CanSpawnTask; +use hermes_runtime_components::traits::task::Task; -use crate::traits::queries::address::CanQueryContractAddress; use crate::traits::queries::block_events::CanQueryBlockEvents; -use crate::types::event::StarknetEvent; #[async_trait] pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType + HasAsyncErrorType { @@ -22,54 +23,92 @@ pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType + HasAsync ) -> Result)>>, Self::Error>; } +#[async_trait] +pub trait CanSendStarknetEvents: HasHeightType + HasEventType + HasAsyncErrorType { + async fn send_starknet_events( + &self, + start_height: Self::Height, + sender: UnboundedSender<(Self::Height, Arc)>, + ) -> Result<(), Self::Error>; +} + +impl CanSendStarknetEvents for Chain +where + Chain: HasHeightType + CanQueryBlockEvents + CanRaiseError, +{ + async fn send_starknet_events( + &self, + mut height: u64, + sender: UnboundedSender<(u64, Arc)>, + ) -> Result<(), Self::Error> { + loop { + let events = self.query_block_events(&height).await?; + for event in events { + sender + .unbounded_send((height, Arc::new(event))) + .map_err(|_| Chain::raise_error(ChannelClosedError))?; + } + height += 1; + } + } +} + +pub struct PollStarknetEventsTask +where + Chain: HasHeightType + HasEventType, +{ + pub chain: Chain, + pub height: Chain::Height, + pub sender: UnboundedSender<(Chain::Height, Arc)>, +} + +impl Task for PollStarknetEventsTask +where + Chain: CanSendStarknetEvents, +{ + async fn run(self) -> () { + let _ = self + .chain + .send_starknet_events(self.height, self.sender) + .await; + } +} + impl CanCreateStarknetSubscription for Chain where - Chain: Clone - + Send - + Sync - + 'static - + HasRuntime - + HasHeightType - + HasEventType - + CanQueryBlockEvents - + CanQueryContractAddress, - Chain::Runtime: CanCreateClosureSubscription, + Chain: Clone + HasRuntime + CanSendStarknetEvents, + Chain::Runtime: CanCreateClosureSubscription + CanSpawnTask, { async fn create_event_subscription( self, - mut next_height: u64, - ) -> Result)>>, Self::Error> { - let ibc_core_contract_address = self.query_contract_address(PhantomData).await?; - + height: Chain::Height, + ) -> Result)>>, Chain::Error> + { Ok(Chain::Runtime::new_closure_subscription(move || { let chain = self.clone(); + let height = height.clone(); + Box::pin(async move { - let height_stream = stream::repeat_with(move || { - let height = next_height.clone(); - next_height += 1; - height - }); + let (sender, receiver) = unbounded(); - let event_stream = height_stream - .filter_map(|height| { - let chain = chain.clone(); - async move { - // let chain = chain.clone(); - // let events = chain.query_block_events(&height).await.ok()?; - let events_with_height = - [].into_iter().map(move |event| (height, Arc::new(event))); + let task = PollStarknetEventsTask { + chain: chain.clone(), + sender, + height: height.clone(), + }; - Some(stream::iter(events_with_height)) - } - }) - .flatten(); + chain.runtime().spawn_task(task); - let boxed_stream: Pin< - Box)> + Send + Sync>, - > = Box::pin(event_stream); + let stream: Pin< + Box< + dyn Stream)> + + Send + + Sync + + 'static, + >, + > = Box::pin(receiver); - todo!() - // Some(Box::pin(event_stream)) + Some(stream) }) })) } From c87ceff1113db6374b532fbddd0fee5f8d3e189f Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 15:11:31 +0000 Subject: [PATCH 10/18] Multiplex event subscription --- .../src/impls/subscription.rs | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index bac0a1dd..2c145cd3 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -3,9 +3,11 @@ use std::sync::Arc; use cgp::prelude::*; use futures::channel::mpsc::{unbounded, UnboundedSender}; +use futures::lock::Mutex; use futures::Stream; use hermes_async_runtime_components::channel::types::ChannelClosedError; use hermes_async_runtime_components::subscription::impls::closure::CanCreateClosureSubscription; +use hermes_async_runtime_components::subscription::impls::multiplex::CanMultiplexSubscription; use hermes_async_runtime_components::subscription::traits::subscription::Subscription; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; @@ -27,7 +29,7 @@ pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType + HasAsync pub trait CanSendStarknetEvents: HasHeightType + HasEventType + HasAsyncErrorType { async fn send_starknet_events( &self, - start_height: Self::Height, + start_height: Arc>, sender: UnboundedSender<(Self::Height, Arc)>, ) -> Result<(), Self::Error>; } @@ -38,17 +40,21 @@ where { async fn send_starknet_events( &self, - mut height: u64, + height_mutex: Arc>, sender: UnboundedSender<(u64, Arc)>, ) -> Result<(), Self::Error> { loop { + let mut height_ref = height_mutex.lock().await; + let height = height_ref.clone(); + let events = self.query_block_events(&height).await?; for event in events { sender .unbounded_send((height, Arc::new(event))) .map_err(|_| Chain::raise_error(ChannelClosedError))?; } - height += 1; + + *height_ref = height + 1; } } } @@ -58,7 +64,7 @@ where Chain: HasHeightType + HasEventType, { pub chain: Chain, - pub height: Chain::Height, + pub height: Arc>, pub sender: UnboundedSender<(Chain::Height, Arc)>, } @@ -77,16 +83,19 @@ where impl CanCreateStarknetSubscription for Chain where Chain: Clone + HasRuntime + CanSendStarknetEvents, - Chain::Runtime: CanCreateClosureSubscription + CanSpawnTask, + Chain::Runtime: Clone + CanCreateClosureSubscription + CanMultiplexSubscription + CanSpawnTask, { async fn create_event_subscription( self, height: Chain::Height, ) -> Result)>>, Chain::Error> { - Ok(Chain::Runtime::new_closure_subscription(move || { + let runtime = self.runtime().clone(); + let height_mutex = Arc::new(Mutex::new(height)); + + let subscription = Chain::Runtime::new_closure_subscription(move || { let chain = self.clone(); - let height = height.clone(); + let height_mutex = height_mutex.clone(); Box::pin(async move { let (sender, receiver) = unbounded(); @@ -94,7 +103,7 @@ where let task = PollStarknetEventsTask { chain: chain.clone(), sender, - height: height.clone(), + height: height_mutex.clone(), }; chain.runtime().spawn_task(task); @@ -110,6 +119,10 @@ where Some(stream) }) - })) + }); + + let subscription = runtime.multiplex_subscription(subscription, |e| e); + + Ok(subscription) } } From 0c235a23a469169ff6f56e1d7430c61ab63d71e9 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 15:26:58 +0000 Subject: [PATCH 11/18] Add wait and retry block events querier --- .../src/impls/queries/block_events/mod.rs | 3 ++ .../query.rs} | 0 .../src/impls/queries/block_events/retry.rs | 39 +++++++++++++++++++ .../src/impls/queries/block_events/wait.rs | 36 +++++++++++++++++ 4 files changed, 78 insertions(+) create mode 100644 relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs rename relayer/crates/starknet-chain-components/src/impls/queries/{block_events.rs => block_events/query.rs} (100%) create mode 100644 relayer/crates/starknet-chain-components/src/impls/queries/block_events/retry.rs create mode 100644 relayer/crates/starknet-chain-components/src/impls/queries/block_events/wait.rs diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs new file mode 100644 index 00000000..daf866bc --- /dev/null +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs @@ -0,0 +1,3 @@ +pub mod query; +pub mod retry; +pub mod wait; diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs similarity index 100% rename from relayer/crates/starknet-chain-components/src/impls/queries/block_events.rs rename to relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/retry.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/retry.rs new file mode 100644 index 00000000..59636426 --- /dev/null +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/retry.rs @@ -0,0 +1,39 @@ +use core::marker::PhantomData; +use core::time::Duration; + +use cgp::prelude::HasAsyncErrorType; +use hermes_chain_components::traits::types::event::HasEventType; +use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_runtime_components::traits::runtime::HasRuntime; +use hermes_runtime_components::traits::sleep::CanSleep; + +use crate::traits::queries::block_events::BlockEventsQuerier; + +pub struct RetryQueryBlockEvents(pub PhantomData); + +impl BlockEventsQuerier for RetryQueryBlockEvents +where + Chain: HasRuntime + HasHeightType + HasEventType + HasAsyncErrorType, + InQuerier: BlockEventsQuerier, + Chain::Runtime: CanSleep, +{ + async fn query_block_events( + chain: &Chain, + height: &Chain::Height, + ) -> Result, Chain::Error> { + let runtime = chain.runtime(); + let mut sleep_time = Duration::from_millis(500); + + for _ in 0..5 { + let res = InQuerier::query_block_events(chain, height).await; + if let Ok(events) = res { + return Ok(events); + } + + runtime.sleep(sleep_time).await; + sleep_time *= 2; + } + + InQuerier::query_block_events(chain, height).await + } +} diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/wait.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/wait.rs new file mode 100644 index 00000000..9b7cf80a --- /dev/null +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/wait.rs @@ -0,0 +1,36 @@ +use core::marker::PhantomData; +use core::time::Duration; + +use hermes_chain_components::traits::queries::chain_status::CanQueryChainHeight; +use hermes_chain_components::traits::types::event::HasEventType; +use hermes_runtime_components::traits::runtime::HasRuntime; +use hermes_runtime_components::traits::sleep::CanSleep; + +use crate::traits::queries::block_events::BlockEventsQuerier; + +pub struct WaitBlockHeightAndQueryEvents(pub PhantomData); + +impl BlockEventsQuerier for WaitBlockHeightAndQueryEvents +where + Chain: HasRuntime + HasEventType + CanQueryChainHeight, + InQuerier: BlockEventsQuerier, + Chain::Runtime: CanSleep, +{ + async fn query_block_events( + chain: &Chain, + height: &Chain::Height, + ) -> Result, Chain::Error> { + let runtime = chain.runtime(); + + loop { + let current_height = chain.query_chain_height().await?; + if ¤t_height >= height { + break; + } else { + runtime.sleep(Duration::from_millis(200)).await; + } + } + + InQuerier::query_block_events(chain, height).await + } +} From dd5cc2850112d4b108828843542856eea94169d5 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 15:36:12 +0000 Subject: [PATCH 12/18] Implement CanQueryBlockEvents and CanCreateStarknetSubscription for StarknetChain --- relayer/Cargo.lock | 1 + .../src/components/chain.rs | 4 +++ .../src/impls/queries/block_events/all.rs | 34 +++++++++++++++++++ .../src/impls/queries/block_events/mod.rs | 1 + .../src/impls/subscription.rs | 5 ++- .../crates/starknet-chain-context/Cargo.toml | 1 + .../src/contexts/chain.rs | 10 +++--- 7 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs diff --git a/relayer/Cargo.lock b/relayer/Cargo.lock index bcb1f708..ff7278e5 100644 --- a/relayer/Cargo.lock +++ b/relayer/Cargo.lock @@ -2290,6 +2290,7 @@ dependencies = [ "cairo-lang-starknet-classes", "cgp", "eyre", + "hermes-async-runtime-components", "hermes-cairo-encoding-components", "hermes-chain-type-components", "hermes-cosmos-chain-components", diff --git a/relayer/crates/starknet-chain-components/src/components/chain.rs b/relayer/crates/starknet-chain-components/src/components/chain.rs index 92539c18..4d63347d 100644 --- a/relayer/crates/starknet-chain-components/src/components/chain.rs +++ b/relayer/crates/starknet-chain-components/src/components/chain.rs @@ -73,6 +73,7 @@ use crate::impls::payload_builders::create_client::BuildStarknetCreateClientPayl use crate::impls::payload_builders::update_client::BuildStarknetUpdateClientPayload; use crate::impls::queries::ack_commitment::QueryStarknetAckCommitment; use crate::impls::queries::balance::QueryStarknetWalletBalance; +use crate::impls::queries::block_events::all::QueryBlockEventsWithWaitAndRetry; use crate::impls::queries::channel_end::QueryChannelEndFromStarknet; use crate::impls::queries::client_state::QueryCometClientState; use crate::impls::queries::connection_end::QueryConnectionEndFromStarknet; @@ -111,6 +112,7 @@ pub use crate::traits::contract::invoke::ContractInvokerComponent; pub use crate::traits::contract::message::InvokeContractMessageBuilderComponent; pub use crate::traits::messages::transfer::TransferTokenMessageBuilderComponent; pub use crate::traits::queries::address::ContractAddressQuerierComponent; +use crate::traits::queries::block_events::BlockEventsQuerierComponent; pub use crate::traits::queries::token_balance::TokenBalanceQuerierComponent; pub use crate::traits::transfer::TokenTransferComponent; pub use crate::traits::types::blob::BlobTypeComponent; @@ -229,6 +231,8 @@ cgp_preset! { ReadPacketSrcStarknetFields, ChainStatusQuerierComponent: QueryStarknetChainStatus, + BlockEventsQuerierComponent: + QueryBlockEventsWithWaitAndRetry, MessageSenderComponent: SendCallMessages, TxSubmitterComponent: diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs new file mode 100644 index 00000000..64dec79e --- /dev/null +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs @@ -0,0 +1,34 @@ +use cgp::prelude::CanRaiseAsyncError; +use hermes_chain_components::traits::queries::chain_status::CanQueryChainHeight; +use hermes_chain_components::traits::types::event::HasEventType; +use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_runtime_components::traits::runtime::HasRuntime; +use hermes_runtime_components::traits::sleep::CanSleep; +use starknet::providers::ProviderError; + +use crate::impls::queries::block_events::query::QueryStarknetBlockEvents; +use crate::impls::queries::block_events::retry::RetryQueryBlockEvents; +use crate::impls::queries::block_events::wait::WaitBlockHeightAndQueryEvents; +use crate::traits::provider::HasStarknetProvider; +use crate::traits::queries::block_events::BlockEventsQuerier; +use crate::types::event::StarknetEvent; + +pub struct QueryBlockEventsWithWaitAndRetry; + +impl BlockEventsQuerier for QueryBlockEventsWithWaitAndRetry +where + Chain: HasRuntime + + HasHeightType + + HasEventType + + HasStarknetProvider + + CanQueryChainHeight + + CanRaiseAsyncError, + Chain::Runtime: CanSleep, +{ + async fn query_block_events( + chain: &Chain, + height: &Chain::Height, + ) -> Result, Chain::Error> { + >>::query_block_events(chain, height).await + } +} diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs index daf866bc..2833662b 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs @@ -1,3 +1,4 @@ +pub mod all; pub mod query; pub mod retry; pub mod wait; diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index 2c145cd3..a9b2fc86 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -5,7 +5,6 @@ use cgp::prelude::*; use futures::channel::mpsc::{unbounded, UnboundedSender}; use futures::lock::Mutex; use futures::Stream; -use hermes_async_runtime_components::channel::types::ChannelClosedError; use hermes_async_runtime_components::subscription::impls::closure::CanCreateClosureSubscription; use hermes_async_runtime_components::subscription::impls::multiplex::CanMultiplexSubscription; use hermes_async_runtime_components::subscription::traits::subscription::Subscription; @@ -36,7 +35,7 @@ pub trait CanSendStarknetEvents: HasHeightType + HasEventType + HasAsyncErrorTyp impl CanSendStarknetEvents for Chain where - Chain: HasHeightType + CanQueryBlockEvents + CanRaiseError, + Chain: HasHeightType + CanQueryBlockEvents + CanRaiseError<&'static str>, { async fn send_starknet_events( &self, @@ -51,7 +50,7 @@ where for event in events { sender .unbounded_send((height, Arc::new(event))) - .map_err(|_| Chain::raise_error(ChannelClosedError))?; + .map_err(|_| Chain::raise_error("channel closed"))?; } *height_ref = height + 1; diff --git a/relayer/crates/starknet-chain-context/Cargo.toml b/relayer/crates/starknet-chain-context/Cargo.toml index 44f023b2..32560701 100644 --- a/relayer/crates/starknet-chain-context/Cargo.toml +++ b/relayer/crates/starknet-chain-context/Cargo.toml @@ -15,6 +15,7 @@ ibc = { workspace = true } hermes-error = { workspace = true } hermes-runtime = { workspace = true } hermes-runtime-components = { workspace = true } +hermes-async-runtime-components = { workspace = true } hermes-logging-components = { workspace = true } hermes-encoding-components = { workspace = true } hermes-logger = { workspace = true } diff --git a/relayer/crates/starknet-chain-context/src/contexts/chain.rs b/relayer/crates/starknet-chain-context/src/contexts/chain.rs index 6a8fb63a..d61dc96a 100644 --- a/relayer/crates/starknet-chain-context/src/contexts/chain.rs +++ b/relayer/crates/starknet-chain-context/src/contexts/chain.rs @@ -122,6 +122,7 @@ use hermes_starknet_chain_components::components::chain::{ use hermes_starknet_chain_components::components::starknet_to_cosmos::StarknetToCosmosComponents; use hermes_starknet_chain_components::impls::account::GetStarknetAccountField; use hermes_starknet_chain_components::impls::provider::GetStarknetProviderField; +use hermes_starknet_chain_components::impls::subscription::CanCreateStarknetSubscription; use hermes_starknet_chain_components::traits::account::{ HasStarknetAccount, StarknetAccountGetterComponent, StarknetAccountTypeComponent, }; @@ -134,6 +135,7 @@ use hermes_starknet_chain_components::traits::provider::{ HasStarknetProvider, StarknetProviderGetterComponent, StarknetProviderTypeComponent, }; use hermes_starknet_chain_components::traits::queries::address::CanQueryContractAddress; +use hermes_starknet_chain_components::traits::queries::block_events::CanQueryBlockEvents; use hermes_starknet_chain_components::traits::queries::token_balance::CanQueryTokenBalance; use hermes_starknet_chain_components::traits::transfer::CanTransferToken; use hermes_starknet_chain_components::traits::types::blob::HasBlobType; @@ -294,8 +296,6 @@ pub trait CanUseStarknetChain: + HasConnectionEndType + HasChannelIdType + HasChannelEndType - // // FIXME: cannot use native PortId. PortIdTypeComponent needs to be wired for StarknetChainTypes - // + HasPortIdType + HasPortIdType + HasInitConnectionOptionsType + HasConnectionOpenInitPayloadType @@ -314,6 +314,8 @@ pub trait CanUseStarknetChain: + HasStarknetAccount + CanQueryChainStatus + CanQueryChainHeight + + CanQueryBlockEvents + + CanCreateStarknetSubscription + CanSendMessages + CanSendSingleMessage + CanSubmitTx @@ -383,8 +385,8 @@ pub trait CanUseStarknetChain: + HasSequenceType + CanQueryBalance + HasMemoType - // TODO(rano): need this to >::ibc_transfer_token - // + CanIbcTransferToken +// TODO(rano): need this to >::ibc_transfer_token +// + CanIbcTransferToken { } From b28009abed7d093da4425af866d3d6463bae6c0d Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 16:18:51 +0000 Subject: [PATCH 13/18] Fix clippy --- .../starknet-chain-components/src/impls/subscription.rs | 4 ++-- relayer/crates/starknet-chain-components/src/lib.rs | 1 + relayer/crates/starknet-chain-context/src/contexts/chain.rs | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index a9b2fc86..00e6ac39 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -44,7 +44,7 @@ where ) -> Result<(), Self::Error> { loop { let mut height_ref = height_mutex.lock().await; - let height = height_ref.clone(); + let height = *height_ref; let events = self.query_block_events(&height).await?; for event in events { @@ -71,7 +71,7 @@ impl Task for PollStarknetEventsTask where Chain: CanSendStarknetEvents, { - async fn run(self) -> () { + async fn run(self) { let _ = self .chain .send_starknet_events(self.height, self.sender) diff --git a/relayer/crates/starknet-chain-components/src/lib.rs b/relayer/crates/starknet-chain-components/src/lib.rs index e59116e3..1338cd09 100644 --- a/relayer/crates/starknet-chain-components/src/lib.rs +++ b/relayer/crates/starknet-chain-components/src/lib.rs @@ -1,4 +1,5 @@ #![allow(clippy::needless_lifetimes)] +#![allow(clippy::type_complexity)] pub mod components; pub mod impls; diff --git a/relayer/crates/starknet-chain-context/src/contexts/chain.rs b/relayer/crates/starknet-chain-context/src/contexts/chain.rs index d61dc96a..d34f0094 100644 --- a/relayer/crates/starknet-chain-context/src/contexts/chain.rs +++ b/relayer/crates/starknet-chain-context/src/contexts/chain.rs @@ -102,6 +102,7 @@ use hermes_relayer_components::chain::traits::types::ibc::{ }; use hermes_relayer_components::chain::traits::types::ibc_events::channel::HasChannelOpenTryEvent; use hermes_relayer_components::chain::traits::types::ibc_events::connection::HasConnectionOpenTryEvent; +use hermes_relayer_components::chain::traits::types::ibc_events::send_packet::HasSendPacketEvent; use hermes_relayer_components::chain::traits::types::ibc_events::write_ack::HasWriteAckEvent; use hermes_relayer_components::chain::traits::types::packet::HasOutgoingPacketType; use hermes_relayer_components::chain::traits::types::packets::ack::HasAcknowledgementType; @@ -438,6 +439,8 @@ pub trait CanUseCosmosChainWithStarknet: HasClientStateType + HasAcknowledgementType> + HasSequenceType + + HasSendPacketEvent + + HasWriteAckEvent { } From 319b8c6e37f5295296ef032179d1d39d2b5db696 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 16:21:39 +0000 Subject: [PATCH 14/18] Remove sleep in test --- relayer/crates/starknet-integration-tests/src/tests/ics20.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/relayer/crates/starknet-integration-tests/src/tests/ics20.rs b/relayer/crates/starknet-integration-tests/src/tests/ics20.rs index a7202ef3..a44aeae1 100644 --- a/relayer/crates/starknet-integration-tests/src/tests/ics20.rs +++ b/relayer/crates/starknet-integration-tests/src/tests/ics20.rs @@ -598,8 +598,6 @@ fn test_starknet_ics20_contract() -> Result<(), Error> { (send_packet_event, send_ics20_event) }; - tokio::time::sleep(core::time::Duration::from_secs(999999999)).await; - // create ibc packet let starknet_ibc_packet = { From eb9622b99a15aaa5d6f0397bc50fbaa3a62abd3c Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 21:30:12 +0000 Subject: [PATCH 15/18] Add address argument for get_block_events --- .../src/impls/queries/block_events/all.rs | 6 +++- .../src/impls/queries/block_events/get.rs | 1 + .../src/impls/queries/block_events/mod.rs | 1 + .../src/impls/queries/block_events/query.rs | 11 ++++++-- .../src/impls/queries/block_events/retry.rs | 8 ++++-- .../src/impls/queries/block_events/wait.rs | 6 ++-- .../src/impls/subscription.rs | 28 +++++++++++++++---- .../src/traits/queries/block_events.rs | 6 +++- 8 files changed, 52 insertions(+), 15 deletions(-) create mode 100644 relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs index 64dec79e..d88162fa 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs @@ -2,8 +2,10 @@ use cgp::prelude::CanRaiseAsyncError; use hermes_chain_components::traits::queries::chain_status::CanQueryChainHeight; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_chain_type_components::traits::types::address::HasAddressType; use hermes_runtime_components::traits::runtime::HasRuntime; use hermes_runtime_components::traits::sleep::CanSleep; +use starknet::core::types::Felt; use starknet::providers::ProviderError; use crate::impls::queries::block_events::query::QueryStarknetBlockEvents; @@ -20,6 +22,7 @@ where Chain: HasRuntime + HasHeightType + HasEventType + + HasAddressType
+ HasStarknetProvider + CanQueryChainHeight + CanRaiseAsyncError, @@ -28,7 +31,8 @@ where async fn query_block_events( chain: &Chain, height: &Chain::Height, + address: &Chain::Address, ) -> Result, Chain::Error> { - >>::query_block_events(chain, height).await + >>::query_block_events(chain, height, address).await } } diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs @@ -0,0 +1 @@ + diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs index 2833662b..073071e7 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs @@ -1,4 +1,5 @@ pub mod all; +pub mod get; pub mod query; pub mod retry; pub mod wait; diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs index 0bb74d03..063f96c1 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs @@ -1,7 +1,8 @@ use cgp::prelude::*; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; -use starknet::core::types::{BlockId, ExecuteInvocation, TransactionTrace}; +use hermes_chain_type_components::traits::types::address::HasAddressType; +use starknet::core::types::{BlockId, ExecuteInvocation, Felt, TransactionTrace}; use starknet::providers::{Provider, ProviderError}; use crate::impls::send_message::extract_events_from_function_invocation; @@ -15,12 +16,14 @@ impl BlockEventsQuerier for QueryStarknetBlockEvents where Chain: HasHeightType + HasEventType + + HasAddressType
+ HasStarknetProvider + CanRaiseAsyncError, { async fn query_block_events( chain: &Chain, height: &u64, + address: &Chain::Address, ) -> Result, Chain::Error> { let provider = chain.provider(); @@ -34,7 +37,11 @@ where .filter_map(|trace| match trace.trace_root { TransactionTrace::Invoke(invoke) => match invoke.execute_invocation { ExecuteInvocation::Success(invoke) => { - Some(extract_events_from_function_invocation(invoke)) + if &invoke.contract_address == address { + Some(extract_events_from_function_invocation(invoke)) + } else { + None + } } _ => None, }, diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/retry.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/retry.rs index 59636426..368342a5 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/retry.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/retry.rs @@ -4,6 +4,7 @@ use core::time::Duration; use cgp::prelude::HasAsyncErrorType; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_chain_type_components::traits::types::address::HasAddressType; use hermes_runtime_components::traits::runtime::HasRuntime; use hermes_runtime_components::traits::sleep::CanSleep; @@ -13,19 +14,20 @@ pub struct RetryQueryBlockEvents(pub PhantomData); impl BlockEventsQuerier for RetryQueryBlockEvents where - Chain: HasRuntime + HasHeightType + HasEventType + HasAsyncErrorType, + Chain: HasRuntime + HasHeightType + HasAddressType + HasEventType + HasAsyncErrorType, InQuerier: BlockEventsQuerier, Chain::Runtime: CanSleep, { async fn query_block_events( chain: &Chain, height: &Chain::Height, + address: &Chain::Address, ) -> Result, Chain::Error> { let runtime = chain.runtime(); let mut sleep_time = Duration::from_millis(500); for _ in 0..5 { - let res = InQuerier::query_block_events(chain, height).await; + let res = InQuerier::query_block_events(chain, height, address).await; if let Ok(events) = res { return Ok(events); } @@ -34,6 +36,6 @@ where sleep_time *= 2; } - InQuerier::query_block_events(chain, height).await + InQuerier::query_block_events(chain, height, address).await } } diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/wait.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/wait.rs index 9b7cf80a..4a88684d 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/wait.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/wait.rs @@ -3,6 +3,7 @@ use core::time::Duration; use hermes_chain_components::traits::queries::chain_status::CanQueryChainHeight; use hermes_chain_components::traits::types::event::HasEventType; +use hermes_chain_type_components::traits::types::address::HasAddressType; use hermes_runtime_components::traits::runtime::HasRuntime; use hermes_runtime_components::traits::sleep::CanSleep; @@ -12,13 +13,14 @@ pub struct WaitBlockHeightAndQueryEvents(pub PhantomData); impl BlockEventsQuerier for WaitBlockHeightAndQueryEvents where - Chain: HasRuntime + HasEventType + CanQueryChainHeight, + Chain: HasRuntime + HasAddressType + HasEventType + CanQueryChainHeight, InQuerier: BlockEventsQuerier, Chain::Runtime: CanSleep, { async fn query_block_events( chain: &Chain, height: &Chain::Height, + address: &Chain::Address, ) -> Result, Chain::Error> { let runtime = chain.runtime(); @@ -31,6 +33,6 @@ where } } - InQuerier::query_block_events(chain, height).await + InQuerier::query_block_events(chain, height, address).await } } diff --git a/relayer/crates/starknet-chain-components/src/impls/subscription.rs b/relayer/crates/starknet-chain-components/src/impls/subscription.rs index 00e6ac39..44f758cf 100644 --- a/relayer/crates/starknet-chain-components/src/impls/subscription.rs +++ b/relayer/crates/starknet-chain-components/src/impls/subscription.rs @@ -10,6 +10,7 @@ use hermes_async_runtime_components::subscription::impls::multiplex::CanMultiple use hermes_async_runtime_components::subscription::traits::subscription::Subscription; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_chain_type_components::traits::types::address::HasAddressType; use hermes_runtime_components::traits::runtime::HasRuntime; use hermes_runtime_components::traits::spawn::CanSpawnTask; use hermes_runtime_components::traits::task::Task; @@ -17,17 +18,23 @@ use hermes_runtime_components::traits::task::Task; use crate::traits::queries::block_events::CanQueryBlockEvents; #[async_trait] -pub trait CanCreateStarknetSubscription: HasHeightType + HasEventType + HasAsyncErrorType { +pub trait CanCreateStarknetSubscription: + HasHeightType + HasAddressType + HasEventType + HasAsyncErrorType +{ async fn create_event_subscription( self, start_height: Self::Height, + address: Self::Address, ) -> Result)>>, Self::Error>; } #[async_trait] -pub trait CanSendStarknetEvents: HasHeightType + HasEventType + HasAsyncErrorType { +pub trait CanSendStarknetEvents: + HasHeightType + HasAddressType + HasEventType + HasAsyncErrorType +{ async fn send_starknet_events( &self, + address: &Self::Address, start_height: Arc>, sender: UnboundedSender<(Self::Height, Arc)>, ) -> Result<(), Self::Error>; @@ -35,10 +42,14 @@ pub trait CanSendStarknetEvents: HasHeightType + HasEventType + HasAsyncErrorTyp impl CanSendStarknetEvents for Chain where - Chain: HasHeightType + CanQueryBlockEvents + CanRaiseError<&'static str>, + Chain: HasHeightType + + HasAddressType + + CanQueryBlockEvents + + CanRaiseError<&'static str>, { async fn send_starknet_events( &self, + address: &Self::Address, height_mutex: Arc>, sender: UnboundedSender<(u64, Arc)>, ) -> Result<(), Self::Error> { @@ -46,7 +57,7 @@ where let mut height_ref = height_mutex.lock().await; let height = *height_ref; - let events = self.query_block_events(&height).await?; + let events = self.query_block_events(&height, address).await?; for event in events { sender .unbounded_send((height, Arc::new(event))) @@ -60,9 +71,10 @@ where pub struct PollStarknetEventsTask where - Chain: HasHeightType + HasEventType, + Chain: HasHeightType + HasAddressType + HasEventType, { pub chain: Chain, + pub address: Chain::Address, pub height: Arc>, pub sender: UnboundedSender<(Chain::Height, Arc)>, } @@ -74,7 +86,7 @@ where async fn run(self) { let _ = self .chain - .send_starknet_events(self.height, self.sender) + .send_starknet_events(&self.address, self.height, self.sender) .await; } } @@ -83,10 +95,12 @@ impl CanCreateStarknetSubscription for Chain where Chain: Clone + HasRuntime + CanSendStarknetEvents, Chain::Runtime: Clone + CanCreateClosureSubscription + CanMultiplexSubscription + CanSpawnTask, + Chain::Address: Clone, { async fn create_event_subscription( self, height: Chain::Height, + address: Chain::Address, ) -> Result)>>, Chain::Error> { let runtime = self.runtime().clone(); @@ -94,6 +108,7 @@ where let subscription = Chain::Runtime::new_closure_subscription(move || { let chain = self.clone(); + let address = address.clone(); let height_mutex = height_mutex.clone(); Box::pin(async move { @@ -102,6 +117,7 @@ where let task = PollStarknetEventsTask { chain: chain.clone(), sender, + address, height: height_mutex.clone(), }; diff --git a/relayer/crates/starknet-chain-components/src/traits/queries/block_events.rs b/relayer/crates/starknet-chain-components/src/traits/queries/block_events.rs index bef480dc..09bf0895 100644 --- a/relayer/crates/starknet-chain-components/src/traits/queries/block_events.rs +++ b/relayer/crates/starknet-chain-components/src/traits/queries/block_events.rs @@ -1,15 +1,19 @@ use cgp::prelude::*; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_chain_type_components::traits::types::address::HasAddressType; #[cgp_component { provider: BlockEventsQuerier, context: Chain, }] #[async_trait] -pub trait CanQueryBlockEvents: HasHeightType + HasEventType + HasAsyncErrorType { +pub trait CanQueryBlockEvents: + HasHeightType + HasAddressType + HasEventType + HasAsyncErrorType +{ async fn query_block_events( &self, height: &Self::Height, + address: &Self::Address, ) -> Result, Self::Error>; } From f64742fc099f3de80b7a37eb5ee00c1c66b190f1 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 21:31:59 +0000 Subject: [PATCH 16/18] Rename providers --- .../starknet-chain-components/src/components/chain.rs | 4 ++-- .../src/impls/queries/block_events/{all.rs => default.rs} | 8 ++++---- .../src/impls/queries/block_events/mod.rs | 4 ++-- .../impls/queries/block_events/{query.rs => traces.rs} | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) rename relayer/crates/starknet-chain-components/src/impls/queries/block_events/{all.rs => default.rs} (83%) rename relayer/crates/starknet-chain-components/src/impls/queries/block_events/{query.rs => traces.rs} (96%) diff --git a/relayer/crates/starknet-chain-components/src/components/chain.rs b/relayer/crates/starknet-chain-components/src/components/chain.rs index 4d63347d..cbe03596 100644 --- a/relayer/crates/starknet-chain-components/src/components/chain.rs +++ b/relayer/crates/starknet-chain-components/src/components/chain.rs @@ -73,7 +73,7 @@ use crate::impls::payload_builders::create_client::BuildStarknetCreateClientPayl use crate::impls::payload_builders::update_client::BuildStarknetUpdateClientPayload; use crate::impls::queries::ack_commitment::QueryStarknetAckCommitment; use crate::impls::queries::balance::QueryStarknetWalletBalance; -use crate::impls::queries::block_events::all::QueryBlockEventsWithWaitAndRetry; +use crate::impls::queries::block_events::default::DefaultQueryBlockEvents; use crate::impls::queries::channel_end::QueryChannelEndFromStarknet; use crate::impls::queries::client_state::QueryCometClientState; use crate::impls::queries::connection_end::QueryConnectionEndFromStarknet; @@ -232,7 +232,7 @@ cgp_preset! { ChainStatusQuerierComponent: QueryStarknetChainStatus, BlockEventsQuerierComponent: - QueryBlockEventsWithWaitAndRetry, + DefaultQueryBlockEvents, MessageSenderComponent: SendCallMessages, TxSubmitterComponent: diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/default.rs similarity index 83% rename from relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs rename to relayer/crates/starknet-chain-components/src/impls/queries/block_events/default.rs index d88162fa..aa037a2b 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/all.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/default.rs @@ -8,16 +8,16 @@ use hermes_runtime_components::traits::sleep::CanSleep; use starknet::core::types::Felt; use starknet::providers::ProviderError; -use crate::impls::queries::block_events::query::QueryStarknetBlockEvents; use crate::impls::queries::block_events::retry::RetryQueryBlockEvents; +use crate::impls::queries::block_events::traces::QueryStarknetBlockEventsFromTraces; use crate::impls::queries::block_events::wait::WaitBlockHeightAndQueryEvents; use crate::traits::provider::HasStarknetProvider; use crate::traits::queries::block_events::BlockEventsQuerier; use crate::types::event::StarknetEvent; -pub struct QueryBlockEventsWithWaitAndRetry; +pub struct DefaultQueryBlockEvents; -impl BlockEventsQuerier for QueryBlockEventsWithWaitAndRetry +impl BlockEventsQuerier for DefaultQueryBlockEvents where Chain: HasRuntime + HasHeightType @@ -33,6 +33,6 @@ where height: &Chain::Height, address: &Chain::Address, ) -> Result, Chain::Error> { - >>::query_block_events(chain, height, address).await + >>::query_block_events(chain, height, address).await } } diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs index 073071e7..3b75f60d 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/mod.rs @@ -1,5 +1,5 @@ -pub mod all; +pub mod default; pub mod get; -pub mod query; pub mod retry; +pub mod traces; pub mod wait; diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/traces.rs similarity index 96% rename from relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs rename to relayer/crates/starknet-chain-components/src/impls/queries/block_events/traces.rs index 063f96c1..262d5755 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/query.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/traces.rs @@ -10,9 +10,9 @@ use crate::traits::provider::HasStarknetProvider; use crate::traits::queries::block_events::BlockEventsQuerier; use crate::types::event::StarknetEvent; -pub struct QueryStarknetBlockEvents; +pub struct QueryStarknetBlockEventsFromTraces; -impl BlockEventsQuerier for QueryStarknetBlockEvents +impl BlockEventsQuerier for QueryStarknetBlockEventsFromTraces where Chain: HasHeightType + HasEventType From 87c94c8313d8fc80efac6dddee92e2f77a5b6c3c Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 21:40:01 +0000 Subject: [PATCH 17/18] Implement StarknetEvent::from_emitted_event --- .../src/impls/encoding/option.rs | 15 ++++--- .../src/impls/queries/block_events/get.rs | 45 +++++++++++++++++++ .../src/impls/queries/block_events/traces.rs | 4 +- .../src/types/event.rs | 19 ++++++-- 4 files changed, 73 insertions(+), 10 deletions(-) diff --git a/relayer/crates/starknet-chain-components/src/impls/encoding/option.rs b/relayer/crates/starknet-chain-components/src/impls/encoding/option.rs index 5497a522..e2139a7f 100644 --- a/relayer/crates/starknet-chain-components/src/impls/encoding/option.rs +++ b/relayer/crates/starknet-chain-components/src/impls/encoding/option.rs @@ -21,11 +21,16 @@ where ) -> Result, Encoding::Error> { let class_hashes = encoding.get_field(PhantomData); - if class_hashes.contains(&event.class_hash) { - let value = encoding.decode(event)?; - Ok(Some(value)) - } else { - Ok(None) + match &event.class_hash { + Some(class_hash) => { + if class_hashes.contains(class_hash) { + let value = encoding.decode(event)?; + Ok(Some(value)) + } else { + Ok(None) + } + } + None => Ok(None), } } } diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs index 8b137891..df1dd024 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs @@ -1 +1,46 @@ +use cgp::prelude::*; +use hermes_chain_components::traits::types::event::HasEventType; +use hermes_chain_components::traits::types::height::HasHeightType; +use hermes_chain_type_components::traits::types::address::HasAddressType; +use starknet::core::types::{BlockId, EventFilter, ExecuteInvocation, Felt, TransactionTrace}; +use starknet::providers::{Provider, ProviderError}; +use crate::impls::send_message::extract_events_from_function_invocation; +use crate::traits::provider::HasStarknetProvider; +use crate::traits::queries::block_events::BlockEventsQuerier; +use crate::types::event::StarknetEvent; + +pub struct GetStarknetBlockEvents; + +impl BlockEventsQuerier for GetStarknetBlockEvents +where + Chain: HasHeightType + + HasEventType + + HasAddressType
+ + HasStarknetProvider + + CanRaiseAsyncError, +{ + async fn query_block_events( + chain: &Chain, + height: &u64, + address: &Felt, + ) -> Result, Chain::Error> { + let provider = chain.provider(); + + let events = provider + .get_events( + EventFilter { + from_block: Some(BlockId::Number(*height)), + to_block: Some(BlockId::Number(*height)), + address: Some(*address), + keys: None, + }, + None, + 1000, + ) + .await + .map_err(Chain::raise_error)?; + + todo!() + } +} diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/traces.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/traces.rs index 262d5755..a55606ee 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/traces.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/traces.rs @@ -23,8 +23,8 @@ where async fn query_block_events( chain: &Chain, height: &u64, - address: &Chain::Address, - ) -> Result, Chain::Error> { + address: &Felt, + ) -> Result, Chain::Error> { let provider = chain.provider(); let traces = provider diff --git a/relayer/crates/starknet-chain-components/src/types/event.rs b/relayer/crates/starknet-chain-components/src/types/event.rs index 840c4deb..7515acb2 100644 --- a/relayer/crates/starknet-chain-components/src/types/event.rs +++ b/relayer/crates/starknet-chain-components/src/types/event.rs @@ -1,9 +1,9 @@ -use starknet::core::types::{Felt, OrderedEvent}; +use starknet::core::types::{EmittedEvent, Felt, OrderedEvent}; #[derive(Debug)] pub struct StarknetEvent { pub contract_address: Felt, - pub class_hash: Felt, + pub class_hash: Option, pub selector: Option, pub keys: Vec, pub data: Vec, @@ -27,10 +27,23 @@ impl StarknetEvent { Self { contract_address, - class_hash, + class_hash: Some(class_hash), selector, keys: keys.collect(), data, } } + + pub fn from_emitted_event(event: EmittedEvent) -> Self { + let mut keys = event.keys.into_iter(); + let selector = keys.next(); + + Self { + contract_address: event.from_address, + class_hash: None, + selector, + keys: keys.collect(), + data: event.data, + } + } } From a57c861848f568114f1477b9cdc2efe43c711f98 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Tue, 21 Jan 2025 21:43:04 +0000 Subject: [PATCH 18/18] Implement GetStarknetBlockEvents --- .../src/impls/queries/block_events/default.rs | 4 ++-- .../src/impls/queries/block_events/get.rs | 13 +++++++++---- .../starknet-chain-components/src/types/event.rs | 4 +++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/default.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/default.rs index aa037a2b..577072d6 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/default.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/default.rs @@ -8,8 +8,8 @@ use hermes_runtime_components::traits::sleep::CanSleep; use starknet::core::types::Felt; use starknet::providers::ProviderError; +use crate::impls::queries::block_events::get::GetStarknetBlockEvents; use crate::impls::queries::block_events::retry::RetryQueryBlockEvents; -use crate::impls::queries::block_events::traces::QueryStarknetBlockEventsFromTraces; use crate::impls::queries::block_events::wait::WaitBlockHeightAndQueryEvents; use crate::traits::provider::HasStarknetProvider; use crate::traits::queries::block_events::BlockEventsQuerier; @@ -33,6 +33,6 @@ where height: &Chain::Height, address: &Chain::Address, ) -> Result, Chain::Error> { - >>::query_block_events(chain, height, address).await + >>::query_block_events(chain, height, address).await } } diff --git a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs index df1dd024..2afbf817 100644 --- a/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs +++ b/relayer/crates/starknet-chain-components/src/impls/queries/block_events/get.rs @@ -2,10 +2,9 @@ use cgp::prelude::*; use hermes_chain_components::traits::types::event::HasEventType; use hermes_chain_components::traits::types::height::HasHeightType; use hermes_chain_type_components::traits::types::address::HasAddressType; -use starknet::core::types::{BlockId, EventFilter, ExecuteInvocation, Felt, TransactionTrace}; +use starknet::core::types::{BlockId, EventFilter, Felt}; use starknet::providers::{Provider, ProviderError}; -use crate::impls::send_message::extract_events_from_function_invocation; use crate::traits::provider::HasStarknetProvider; use crate::traits::queries::block_events::BlockEventsQuerier; use crate::types::event::StarknetEvent; @@ -27,7 +26,7 @@ where ) -> Result, Chain::Error> { let provider = chain.provider(); - let events = provider + let raw_events = provider .get_events( EventFilter { from_block: Some(BlockId::Number(*height)), @@ -41,6 +40,12 @@ where .await .map_err(Chain::raise_error)?; - todo!() + let events = raw_events + .events + .into_iter() + .map(StarknetEvent::from) + .collect(); + + Ok(events) } } diff --git a/relayer/crates/starknet-chain-components/src/types/event.rs b/relayer/crates/starknet-chain-components/src/types/event.rs index 7515acb2..7d6e3f77 100644 --- a/relayer/crates/starknet-chain-components/src/types/event.rs +++ b/relayer/crates/starknet-chain-components/src/types/event.rs @@ -33,8 +33,10 @@ impl StarknetEvent { data, } } +} - pub fn from_emitted_event(event: EmittedEvent) -> Self { +impl From for StarknetEvent { + fn from(event: EmittedEvent) -> Self { let mut keys = event.keys.into_iter(); let selector = keys.next();