From 8949443adac44d598554ed319812cee6399900a0 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Wed, 18 Dec 2024 23:54:05 +0530 Subject: [PATCH 01/23] feat : l3 support init --- Cargo.lock | 97 ++++--- Cargo.toml | 6 +- crates/client/eth/src/sync.rs | 38 --- .../{eth => settlement_client}/Cargo.toml | 5 +- .../{eth => settlement_client}/README.md | 0 crates/client/settlement_client/src/client.rs | 94 ++++++ .../{eth => settlement_client}/src/error.rs | 0 .../src/eth/mod.rs} | 216 ++++++++------ .../src/eth}/starknet_core.json | 0 .../src/gas_price.rs} | 151 ++++++---- .../src/l1_messaging.rs | 56 ++-- .../{eth => settlement_client}/src/lib.rs | 4 +- .../settlement_client/src/starknet/mod.rs | 270 ++++++++++++++++++ .../src/state_update.rs | 64 ++--- crates/client/settlement_client/src/sync.rs | 46 +++ .../{eth => settlement_client}/src/utils.rs | 12 +- crates/node/Cargo.toml | 4 +- crates/node/src/cli/chain_config_overrides.rs | 2 +- crates/node/src/cli/l1.rs | 37 ++- crates/node/src/main.rs | 48 +++- crates/node/src/service/l1.rs | 189 ++++++++++-- .../chain_config/src/chain_config.rs | 7 +- 22 files changed, 989 insertions(+), 357 deletions(-) delete mode 100644 crates/client/eth/src/sync.rs rename crates/client/{eth => settlement_client}/Cargo.toml (93%) rename crates/client/{eth => settlement_client}/README.md (100%) create mode 100644 crates/client/settlement_client/src/client.rs rename crates/client/{eth => settlement_client}/src/error.rs (100%) rename crates/client/{eth/src/client.rs => settlement_client/src/eth/mod.rs} (59%) rename crates/client/{eth/src/abis => settlement_client/src/eth}/starknet_core.json (100%) rename crates/client/{eth/src/l1_gas_price.rs => settlement_client/src/gas_price.rs} (71%) rename crates/client/{eth => settlement_client}/src/l1_messaging.rs (94%) rename crates/client/{eth => settlement_client}/src/lib.rs (67%) create mode 100644 crates/client/settlement_client/src/starknet/mod.rs rename crates/client/{eth => settlement_client}/src/state_update.rs (74%) create mode 100644 crates/client/settlement_client/src/sync.rs rename crates/client/{eth => settlement_client}/src/utils.rs (89%) diff --git a/Cargo.lock b/Cargo.lock index 66a6c5f5d..42f125cba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5377,11 +5377,11 @@ dependencies = [ "mc-block-production", "mc-db", "mc-devnet", - "mc-eth", "mc-gateway-client", "mc-gateway-server", "mc-mempool", "mc-rpc", + "mc-settlement-client", "mc-sync", "mc-telemetry", "mp-block", @@ -5400,6 +5400,8 @@ dependencies = [ "serde", "serde_json", "serde_yaml", + "starknet-core", + "starknet-providers", "starknet_api", "thiserror 2.0.3", "tokio", @@ -5642,51 +5644,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "mc-eth" -version = "0.7.0" -dependencies = [ - "alloy", - "anyhow", - "bigdecimal", - "bitvec", - "dotenv", - "futures", - "httpmock", - "lazy_static", - "mc-analytics", - "mc-db", - "mc-mempool", - "mp-chain-config", - "mp-convert", - "mp-transactions", - "mp-utils", - "once_cell", - "opentelemetry", - "opentelemetry-appender-tracing", - "opentelemetry-otlp", - "opentelemetry-semantic-conventions", - "opentelemetry-stdout", - "opentelemetry_sdk", - "regex", - "rstest 0.18.2", - "serde", - "serde_json", - "serial_test", - "starknet-types-core 0.1.7 (git+https://github.com/kasarlabs/types-rs.git?branch=feat-deserialize-v0.1.7)", - "starknet_api", - "tempfile", - "thiserror 2.0.3", - "time", - "tokio", - "tracing", - "tracing-core", - "tracing-opentelemetry", - "tracing-subscriber", - "tracing-test", - "url", -] - [[package]] name = "mc-exec" version = "0.7.0" @@ -5854,6 +5811,54 @@ dependencies = [ "tracing", ] +[[package]] +name = "mc-settlement-client" +version = "0.7.0" +dependencies = [ + "alloy", + "anyhow", + "async-trait", + "bigdecimal", + "bitvec", + "dotenv", + "futures", + "httpmock", + "lazy_static", + "mc-analytics", + "mc-db", + "mc-mempool", + "mp-chain-config", + "mp-convert", + "mp-transactions", + "mp-utils", + "once_cell", + "opentelemetry", + "opentelemetry-appender-tracing", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "opentelemetry-stdout", + "opentelemetry_sdk", + "regex", + "rstest 0.18.2", + "serde", + "serde_json", + "serial_test", + "starknet-core", + "starknet-providers", + "starknet-types-core 0.1.7 (git+https://github.com/kasarlabs/types-rs.git?branch=feat-deserialize-v0.1.7)", + "starknet_api", + "tempfile", + "thiserror 2.0.3", + "time", + "tokio", + "tracing", + "tracing-core", + "tracing-opentelemetry", + "tracing-subscriber", + "tracing-test", + "url", +] + [[package]] name = "mc-sync" version = "0.7.0" diff --git a/Cargo.toml b/Cargo.toml index 12273e3be..3b0cf4346 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = [ "crates/client/db", "crates/client/exec", "crates/client/sync", - "crates/client/eth", + "crates/client/settlement_client", "crates/client/rpc", "crates/client/gateway/client", "crates/client/gateway/server", @@ -33,7 +33,7 @@ default-members = [ "crates/client/db", "crates/client/exec", "crates/client/sync", - "crates/client/eth", + "crates/client/settlement_client", "crates/client/gateway/client", "crates/client/gateway/server", "crates/client/rpc", @@ -127,7 +127,7 @@ mc-rpc = { path = "crates/client/rpc" } mc-gateway-client = { path = "crates/client/gateway/client" } mc-gateway-server = { path = "crates/client/gateway/server" } mc-sync = { path = "crates/client/sync" } -mc-eth = { path = "crates/client/eth" } +mc-settlement-client = { path = "crates/client/settlement_client" } mc-mempool = { path = "crates/client/mempool" } mc-block-production = { path = "crates/client/block_production" } mc-block-import = { path = "crates/client/block_import" } diff --git a/crates/client/eth/src/sync.rs b/crates/client/eth/src/sync.rs deleted file mode 100644 index 2a607fcde..000000000 --- a/crates/client/eth/src/sync.rs +++ /dev/null @@ -1,38 +0,0 @@ -use crate::client::EthereumClient; -use crate::l1_gas_price::gas_price_worker; -use crate::l1_messaging::sync; -use crate::state_update::state_update_worker; -use mc_mempool::{GasPriceProvider, Mempool}; -use mp_utils::service::ServiceContext; -use starknet_api::core::ChainId; -use std::sync::Arc; -use std::time::Duration; - -use mc_db::MadaraBackend; - -#[allow(clippy::too_many_arguments)] -pub async fn l1_sync_worker( - backend: Arc, - eth_client: Arc, - chain_id: ChainId, - l1_gas_provider: GasPriceProvider, - gas_price_sync_disabled: bool, - gas_price_poll_ms: Duration, - mempool: Arc, - ctx: ServiceContext, -) -> anyhow::Result<()> { - let mut join_set = tokio::task::JoinSet::new(); - - join_set.spawn(state_update_worker(Arc::clone(&backend), Arc::clone(ð_client), ctx.clone())); - join_set.spawn(sync(Arc::clone(&backend), Arc::clone(ð_client), chain_id, mempool, ctx.clone())); - - if !gas_price_sync_disabled { - join_set.spawn(gas_price_worker(Arc::clone(ð_client), l1_gas_provider, gas_price_poll_ms, ctx.clone())); - } - - while let Some(res) = join_set.join_next().await { - res??; - } - - Ok(()) -} diff --git a/crates/client/eth/Cargo.toml b/crates/client/settlement_client/Cargo.toml similarity index 93% rename from crates/client/eth/Cargo.toml rename to crates/client/settlement_client/Cargo.toml index c424a75f1..4a7327e90 100644 --- a/crates/client/eth/Cargo.toml +++ b/crates/client/settlement_client/Cargo.toml @@ -1,6 +1,6 @@ [package] description = "This crate is responsible to handle l1 communication" -name = "mc-eth" +name = "mc-settlement-client" authors.workspace = true edition.workspace = true license.workspace = true @@ -42,6 +42,8 @@ futures = { workspace = true, default-features = true } regex = "1.10.5" serde = { workspace = true, default-features = true } serde_json = "1" +starknet-providers = { workspace = true } +starknet-core = { workspace = true } thiserror.workspace = true time = "0.3.36" tokio = { workspace = true, features = [ @@ -68,6 +70,7 @@ tracing = { workspace = true } tracing-core = { workspace = true, default-features = false } tracing-opentelemetry = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } +async-trait = { workspace = true } [features] diff --git a/crates/client/eth/README.md b/crates/client/settlement_client/README.md similarity index 100% rename from crates/client/eth/README.md rename to crates/client/settlement_client/README.md diff --git a/crates/client/settlement_client/src/client.rs b/crates/client/settlement_client/src/client.rs new file mode 100644 index 000000000..7f6447842 --- /dev/null +++ b/crates/client/settlement_client/src/client.rs @@ -0,0 +1,94 @@ +use crate::eth::StarknetCoreContract::StarknetCoreContractInstance; +use crate::gas_price::L1BlockMetrics; +use crate::state_update::StateUpdate; +use alloy::contract::Event; +use alloy::primitives::FixedBytes; +use alloy::providers::RootProvider; +use alloy::sol_types::SolEvent; +use alloy::transports::http::{Client, Http}; +use async_trait::async_trait; +use mc_db::MadaraBackend; +use mp_utils::service::ServiceContext; +use starknet_types_core::felt::Felt; +use std::sync::Arc; + +pub enum ClientType { + ETH, + STARKNET, +} + +pub enum CoreContractInstance { + Ethereum(StarknetCoreContractInstance, RootProvider>>), + Starknet(Felt), +} + +impl CoreContractInstance { + #[allow(clippy::type_complexity)] + pub fn event_filter(&self) -> anyhow::Result, &RootProvider>, T>> { + match self { + CoreContractInstance::Ethereum(contract) => Ok(contract.event_filter()), + CoreContractInstance::Starknet(_) => Err(anyhow::anyhow!("Starknet doesn't support event filters")), + } + } +} + +#[async_trait] +pub trait ClientTrait: Send + Sync { + // Provider type used by the implementation + type Provider; + // Configuration type used for initialization + type Config; + + // Basic getter functions + fn get_l1_block_metrics(&self) -> &L1BlockMetrics; + fn get_core_contract_instance(&self) -> CoreContractInstance; + fn get_client_type(&self) -> ClientType; + + // Create a new instance of the client + async fn new(config: Self::Config) -> anyhow::Result + where + Self: Sized; + + // Get the latest block number + async fn get_latest_block_number(&self) -> anyhow::Result; + + // Get the block number of the last occurrence of a specific event + async fn get_last_event_block_number(&self) -> anyhow::Result; + + // Get the last verified block number + async fn get_last_verified_block_number(&self) -> anyhow::Result; + + // Get the last state root + // - change this to Felt in implementation + // - write tests for conversion to Felt from + async fn get_last_state_root(&self) -> anyhow::Result; + + // Get the last verified block hash + async fn get_last_verified_block_hash(&self) -> anyhow::Result; + + // Get initial state from client + async fn get_initial_state(&self) -> anyhow::Result; + async fn listen_for_update_state_events( + &self, + backend: Arc, + ctx: ServiceContext, + ) -> anyhow::Result<()>; + + // get gas prices + async fn get_eth_gas_prices(&self) -> anyhow::Result<(u128, u128)>; + + /// Get cancellation status of an L1 to L2 message + /// + /// This function query the core contract to know if a L1->L2 message has been cancelled + /// # Arguments + /// + /// - msg_hash : Hash of L1 to L2 message + /// + /// # Return + /// + /// - A felt representing a timestamp : + /// - 0 if the message has not been cancelled + /// - timestamp of the cancellation if it has been cancelled + /// - An Error if the call fail + async fn get_l1_to_l2_message_cancellations(&self, msg_hash: FixedBytes<32>) -> anyhow::Result; +} diff --git a/crates/client/eth/src/error.rs b/crates/client/settlement_client/src/error.rs similarity index 100% rename from crates/client/eth/src/error.rs rename to crates/client/settlement_client/src/error.rs diff --git a/crates/client/eth/src/client.rs b/crates/client/settlement_client/src/eth/mod.rs similarity index 59% rename from crates/client/eth/src/client.rs rename to crates/client/settlement_client/src/eth/mod.rs index 8d2e7659f..77e2dd607 100644 --- a/crates/client/eth/src/client.rs +++ b/crates/client/settlement_client/src/eth/mod.rs @@ -1,82 +1,49 @@ -use crate::client::StarknetCoreContract::StarknetCoreContractInstance; -use crate::utils::u256_to_felt; -use alloy::sol_types::SolEvent; -use alloy::{ - primitives::Address, - providers::{Provider, ProviderBuilder, ReqwestProvider, RootProvider}, - rpc::types::Filter, - sol, - transports::http::{Client, Http}, -}; -use mc_analytics::register_gauge_metric_instrument; -use opentelemetry::{global, KeyValue}; -use opentelemetry::{global::Error, metrics::Gauge}; - +use crate::client::{ClientTrait, ClientType, CoreContractInstance}; +use crate::eth::StarknetCoreContract::StarknetCoreContractInstance; +use crate::gas_price::L1BlockMetrics; +use crate::state_update::{update_l1, StateUpdate}; +use crate::utils::{convert_log_state_update, u256_to_felt}; +use alloy::eips::BlockNumberOrTag; +use alloy::primitives::{Address, FixedBytes}; +use alloy::providers::{Provider, ProviderBuilder, ReqwestProvider, RootProvider}; +use alloy::rpc::types::Filter; +use alloy::sol; +use alloy::transports::http::{Client, Http}; use anyhow::{bail, Context}; +use async_trait::async_trait; use bitvec::macros::internal::funty::Fundamental; +use futures::StreamExt; +use mc_db::MadaraBackend; +use mp_utils::service::ServiceContext; use starknet_types_core::felt::Felt; use std::sync::Arc; use url::Url; -#[derive(Clone, Debug)] -pub struct L1BlockMetrics { - // L1 network metrics - pub l1_block_number: Gauge, - // gas price is also define in sync/metrics/block_metrics.rs but this would be the price from l1 - pub l1_gas_price_wei: Gauge, - pub l1_gas_price_strk: Gauge, -} - -impl L1BlockMetrics { - pub fn register() -> Result { - let common_scope_attributes = vec![KeyValue::new("crate", "L1 Block")]; - let eth_meter = global::meter_with_version( - "crates.l1block.opentelemetry", - Some("0.17"), - Some("https://opentelemetry.io/schemas/1.2.0"), - Some(common_scope_attributes.clone()), - ); - - let l1_block_number = register_gauge_metric_instrument( - ð_meter, - "l1_block_number".to_string(), - "Gauge for madara L1 block number".to_string(), - "".to_string(), - ); - - let l1_gas_price_wei = register_gauge_metric_instrument( - ð_meter, - "l1_gas_price_wei".to_string(), - "Gauge for madara L1 gas price in wei".to_string(), - "".to_string(), - ); - - let l1_gas_price_strk = register_gauge_metric_instrument( - ð_meter, - "l1_gas_price_strk".to_string(), - "Gauge for madara L1 gas price in strk".to_string(), - "".to_string(), - ); - - Ok(Self { l1_block_number, l1_gas_price_wei, l1_gas_price_strk }) - } -} - // abi taken from: https://etherscan.io/address/0x6e0acfdc3cf17a7f99ed34be56c3dfb93f464e24#code // The official starknet core contract ^ sol!( #[sol(rpc)] #[derive(Debug)] StarknetCoreContract, - "src/abis/starknet_core.json" + "src/eth/starknet_core.json" ); +const ERR_ARCHIVE: &str = + "Failed to watch event filter - Ensure you are using an L1 RPC endpoint that points to an archive node"; + pub struct EthereumClient { pub provider: Arc, pub l1_core_contract: StarknetCoreContractInstance, RootProvider>>, pub l1_block_metrics: L1BlockMetrics, } +#[derive(Clone)] +pub struct EthereumClientConfig { + pub url: Url, + pub l1_core_address: Address, + pub l1_block_metrics: L1BlockMetrics, +} + impl Clone for EthereumClient { fn clone(&self) -> Self { EthereumClient { @@ -87,38 +54,47 @@ impl Clone for EthereumClient { } } -impl EthereumClient { - /// Create a new EthereumClient instance with the given RPC URL - pub async fn new(url: Url, l1_core_address: Address, l1_block_metrics: L1BlockMetrics) -> anyhow::Result { - let provider = ProviderBuilder::new().on_http(url); +#[async_trait] +impl ClientTrait for EthereumClient { + type Provider = RootProvider>; + type Config = EthereumClientConfig; - EthereumClient::assert_core_contract_exists(&provider, l1_core_address).await?; + fn get_l1_block_metrics(&self) -> &L1BlockMetrics { + &self.l1_block_metrics + } - let core_contract = StarknetCoreContract::new(l1_core_address, provider.clone()); + fn get_core_contract_instance(&self) -> CoreContractInstance { + CoreContractInstance::Ethereum(self.l1_core_contract.clone()) + } - Ok(Self { provider: Arc::new(provider), l1_core_contract: core_contract, l1_block_metrics }) + fn get_client_type(&self) -> ClientType { + ClientType::ETH } - /// Assert that L1 Core contract exists by checking its bytecode. - async fn assert_core_contract_exists( - provider: &RootProvider>, - l1_core_address: Address, - ) -> anyhow::Result<()> { - let l1_core_contract_bytecode = provider.get_code_at(l1_core_address).await?; + /// Create a new EthereumClient instance with the given RPC URL + async fn new(config: EthereumClientConfig) -> anyhow::Result { + let provider = ProviderBuilder::new().on_http(config.url); + // Checking if core contract exists on l1 + let l1_core_contract_bytecode = provider.get_code_at(config.l1_core_address).await?; if l1_core_contract_bytecode.is_empty() { bail!("The L1 Core Contract could not be found. Check that the L2 chain matches the L1 RPC endpoint."); } - Ok(()) + let core_contract = StarknetCoreContract::new(config.l1_core_address, provider.clone()); + Ok(Self { + provider: Arc::new(provider), + l1_core_contract: core_contract, + l1_block_metrics: config.l1_block_metrics, + }) } /// Retrieves the latest Ethereum block number - pub async fn get_latest_block_number(&self) -> anyhow::Result { + async fn get_latest_block_number(&self) -> anyhow::Result { let block_number = self.provider.get_block_number().await?.as_u64(); Ok(block_number) } /// Get the block number of the last occurrence of a given event. - pub async fn get_last_event_block_number(&self) -> anyhow::Result { + async fn get_last_event_block_number(&self) -> anyhow::Result { let latest_block: u64 = self.get_latest_block_number().await?; // Assuming an avg Block time of 15sec we check for a LogStateUpdate occurence in the last ~24h @@ -129,7 +105,10 @@ impl EthereumClient { let logs = self.provider.get_logs(&filter).await?; - let filtered_logs = logs.into_iter().filter_map(|log| log.log_decode::().ok()).collect::>(); + let filtered_logs = logs + .into_iter() + .filter_map(|log| log.log_decode::().ok()) + .collect::>(); if let Some(last_log) = filtered_logs.last() { let last_block: u64 = last_log.block_number.context("no block number in log")?; @@ -140,23 +119,94 @@ impl EthereumClient { } /// Get the last Starknet block number verified on L1 - pub async fn get_last_verified_block_number(&self) -> anyhow::Result { + async fn get_last_verified_block_number(&self) -> anyhow::Result { let block_number = self.l1_core_contract.stateBlockNumber().call().await?; let last_block_number: u64 = (block_number._0).as_u64(); Ok(last_block_number) } /// Get the last Starknet state root verified on L1 - pub async fn get_last_state_root(&self) -> anyhow::Result { + async fn get_last_state_root(&self) -> anyhow::Result { let state_root = self.l1_core_contract.stateRoot().call().await?; u256_to_felt(state_root._0) } /// Get the last Starknet block hash verified on L1 - pub async fn get_last_verified_block_hash(&self) -> anyhow::Result { + async fn get_last_verified_block_hash(&self) -> anyhow::Result { let block_hash = self.l1_core_contract.stateBlockHash().call().await?; u256_to_felt(block_hash._0) } + + async fn get_initial_state(&self) -> anyhow::Result { + let block_number = self.get_last_verified_block_number().await?; + let block_hash = self.get_last_verified_block_hash().await?; + let global_root = self.get_last_state_root().await?; + + Ok(StateUpdate { global_root, block_number, block_hash }) + } + + async fn listen_for_update_state_events( + &self, + backend: Arc, + mut ctx: ServiceContext, + ) -> anyhow::Result<()> { + // Listen to LogStateUpdate (0x77552641) update and send changes continuously + let contract_instance = self.get_core_contract_instance(); + let event_filter = contract_instance.event_filter::(); + + let mut event_stream = match ctx.run_until_cancelled(event_filter?.watch()).await { + Some(res) => res.context(ERR_ARCHIVE)?.into_stream(), + None => return anyhow::Ok(()), + }; + + while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { + let log = event_result.context("listening for events")?; + let format_event: StateUpdate = + convert_log_state_update(log.0.clone()).context("formatting event into an L1StateUpdate")?; + update_l1(&backend, format_event, self.get_l1_block_metrics())?; + } + + Ok(()) + } + + async fn get_eth_gas_prices(&self) -> anyhow::Result<(u128, u128)> { + let block_number = self.get_latest_block_number().await?; + let fee_history = self.provider.get_fee_history(300, BlockNumberOrTag::Number(block_number), &[]).await?; + + // The RPC responds with 301 elements for some reason. It's also just safer to manually + // take the last 300. We choose 300 to get average gas caprice for last one hour (300 * 12 sec block + // time). + let (_, blob_fee_history_one_hour) = + fee_history.base_fee_per_blob_gas.split_at(fee_history.base_fee_per_blob_gas.len().max(300) - 300); + + let avg_blob_base_fee = if !blob_fee_history_one_hour.is_empty() { + blob_fee_history_one_hour.iter().sum::() / blob_fee_history_one_hour.len() as u128 + } else { + 0 // in case blob_fee_history_one_hour has 0 length + }; + + let eth_gas_price = fee_history.base_fee_per_gas.last().context("Getting eth gas price")?; + Ok((*eth_gas_price, avg_blob_base_fee)) + } + + /// Get cancellation status of an L1 to L2 message + /// + /// This function query the core contract to know if a L1->L2 message has been cancelled + /// # Arguments + /// + /// - msg_hash : Hash of L1 to L2 message + /// + /// # Return + /// + /// - A felt representing a timestamp : + /// - 0 if the message has not been cancelled + /// - timestamp of the cancellation if it has been cancelled + /// - An Error if the call fail + async fn get_l1_to_l2_message_cancellations(&self, msg_hash: FixedBytes<32>) -> anyhow::Result { + //l1ToL2MessageCancellations + let cancellation_timestamp = self.l1_core_contract.l1ToL2MessageCancellations(msg_hash).call().await?; + u256_to_felt(cancellation_timestamp._0) + } } #[cfg(test)] @@ -167,6 +217,7 @@ pub mod eth_client_getter_test { primitives::U256, }; + use crate::gas_price::L1BlockMetrics; use serial_test::serial; use std::ops::Range; use std::sync::Mutex; @@ -257,7 +308,10 @@ pub mod eth_client_getter_test { let core_contract_address = Address::parse_checksummed(INVALID_CORE_CONTRACT_ADDRESS, None).unwrap(); let l1_block_metrics = L1BlockMetrics::register().unwrap(); - let new_client_result = EthereumClient::new(rpc_url, core_contract_address, l1_block_metrics).await; + let ethereum_client_config = + EthereumClientConfig { url: rpc_url, l1_core_address: core_contract_address, l1_block_metrics }; + + let new_client_result = EthereumClient::new(ethereum_client_config).await; assert!(new_client_result.is_err(), "EthereumClient::new should fail with an invalid core contract address"); } @@ -277,7 +331,7 @@ pub mod eth_client_getter_test { let anvil = get_shared_anvil(); let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str())); let block_number = eth_client - .get_last_event_block_number::() + .get_last_event_block_number() .await .expect("issue while getting the last block number with given event"); assert_eq!(block_number, L1_BLOCK_NUMBER, "block number with given event not matching"); diff --git a/crates/client/eth/src/abis/starknet_core.json b/crates/client/settlement_client/src/eth/starknet_core.json similarity index 100% rename from crates/client/eth/src/abis/starknet_core.json rename to crates/client/settlement_client/src/eth/starknet_core.json diff --git a/crates/client/eth/src/l1_gas_price.rs b/crates/client/settlement_client/src/gas_price.rs similarity index 71% rename from crates/client/eth/src/l1_gas_price.rs rename to crates/client/settlement_client/src/gas_price.rs index 4d02f4a37..13ac9ab6f 100644 --- a/crates/client/eth/src/l1_gas_price.rs +++ b/crates/client/settlement_client/src/gas_price.rs @@ -1,23 +1,67 @@ -use crate::client::EthereumClient; -use alloy::eips::BlockNumberOrTag; -use alloy::providers::Provider; +use crate::client::ClientTrait; use anyhow::Context; use bigdecimal::BigDecimal; use mc_mempool::{GasPriceProvider, L1DataProvider}; -use std::{ - sync::Arc, - time::{Duration, UNIX_EPOCH}, -}; +use std::sync::Arc; +use std::time::{Duration, UNIX_EPOCH}; +use mc_analytics::register_gauge_metric_instrument; use mp_utils::service::ServiceContext; +use opentelemetry::global::Error; +use opentelemetry::metrics::Gauge; +use opentelemetry::{global, KeyValue}; use std::time::SystemTime; -pub async fn gas_price_worker_once( - eth_client: &EthereumClient, +#[derive(Clone, Debug)] +pub struct L1BlockMetrics { + // L1 network metrics + pub l1_block_number: Gauge, + // gas price is also define in sync/metrics/block_metrics.rs but this would be the price from l1 + pub l1_gas_price_wei: Gauge, + pub l1_gas_price_strk: Gauge, +} + +impl L1BlockMetrics { + pub fn register() -> Result { + let common_scope_attributes = vec![KeyValue::new("crate", "L1 Block")]; + let eth_meter = global::meter_with_version( + "crates.l1block.opentelemetry", + Some("0.17"), + Some("https://opentelemetry.io/schemas/1.2.0"), + Some(common_scope_attributes.clone()), + ); + + let l1_block_number = register_gauge_metric_instrument( + ð_meter, + "l1_block_number".to_string(), + "Gauge for madara L1 block number".to_string(), + "".to_string(), + ); + + let l1_gas_price_wei = register_gauge_metric_instrument( + ð_meter, + "l1_gas_price_wei".to_string(), + "Gauge for madara L1 gas price in wei".to_string(), + "".to_string(), + ); + + let l1_gas_price_strk = register_gauge_metric_instrument( + ð_meter, + "l1_gas_price_strk".to_string(), + "Gauge for madara L1 gas price in strk".to_string(), + "".to_string(), + ); + + Ok(Self { l1_block_number, l1_gas_price_wei, l1_gas_price_strk }) + } +} + +pub async fn gas_price_worker_once( + settlement_client: Arc>>, l1_gas_provider: &GasPriceProvider, gas_price_poll_ms: Duration, ) -> anyhow::Result<()> { - match update_gas_price(eth_client, l1_gas_provider).await { + match update_gas_price(settlement_client, l1_gas_provider).await { Ok(_) => tracing::trace!("Updated gas prices"), Err(e) => tracing::error!("Failed to update gas prices: {:?}", e), } @@ -37,8 +81,8 @@ pub async fn gas_price_worker_once( anyhow::Ok(()) } -pub async fn gas_price_worker( - eth_client: Arc, +pub async fn gas_price_worker( + settlement_client: Arc>>, l1_gas_provider: GasPriceProvider, gas_price_poll_ms: Duration, mut ctx: ServiceContext, @@ -48,38 +92,26 @@ pub async fn gas_price_worker( interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); while ctx.run_until_cancelled(interval.tick()).await.is_some() { - gas_price_worker_once(ð_client, &l1_gas_provider, gas_price_poll_ms).await?; + gas_price_worker_once(Arc::clone(&settlement_client), &l1_gas_provider, gas_price_poll_ms).await?; } anyhow::Ok(()) } -async fn update_gas_price(eth_client: &EthereumClient, l1_gas_provider: &GasPriceProvider) -> anyhow::Result<()> { - let block_number = eth_client.get_latest_block_number().await?; - let fee_history = eth_client.provider.get_fee_history(300, BlockNumberOrTag::Number(block_number), &[]).await?; - - // The RPC responds with 301 elements for some reason. It's also just safer to manually - // take the last 300. We choose 300 to get average gas caprice for last one hour (300 * 12 sec block - // time). - let (_, blob_fee_history_one_hour) = - fee_history.base_fee_per_blob_gas.split_at(fee_history.base_fee_per_blob_gas.len().max(300) - 300); - - let avg_blob_base_fee = if !blob_fee_history_one_hour.is_empty() { - blob_fee_history_one_hour.iter().sum::() / blob_fee_history_one_hour.len() as u128 - } else { - 0 // in case blob_fee_history_one_hour has 0 length - }; - - let eth_gas_price = fee_history.base_fee_per_gas.last().context("Getting eth gas price")?; +async fn update_gas_price( + settlement_client: Arc>>, + l1_gas_provider: &GasPriceProvider, +) -> anyhow::Result<()> { + let (eth_gas_price, avg_blob_base_fee) = settlement_client.get_eth_gas_prices().await?; - l1_gas_provider.update_eth_l1_gas_price(*eth_gas_price); + l1_gas_provider.update_eth_l1_gas_price(eth_gas_price); l1_gas_provider.update_eth_l1_data_gas_price(avg_blob_base_fee); // fetch eth/strk price and update if let Some(oracle_provider) = &l1_gas_provider.oracle_provider { let (eth_strk_price, decimals) = oracle_provider.fetch_eth_strk_price().await.context("failed to retrieve ETH/STRK price")?; - let strk_gas_price = (BigDecimal::new((*eth_gas_price).into(), decimals.into()) + let strk_gas_price = (BigDecimal::new((eth_gas_price).into(), decimals.into()) / BigDecimal::new(eth_strk_price.into(), decimals.into())) .as_bigint_and_exponent(); let strk_data_gas_price = (BigDecimal::new(avg_blob_base_fee.into(), decimals.into()) @@ -101,18 +133,21 @@ async fn update_gas_price(eth_client: &EthereumClient, l1_gas_provider: &GasPric l1_gas_provider.update_last_update_timestamp(); // Update block number separately to avoid holding the lock for too long - update_l1_block_metrics(eth_client, l1_gas_provider).await?; + update_l1_block_metrics( + settlement_client.get_latest_block_number().await?, + settlement_client.get_l1_block_metrics(), + l1_gas_provider, + ) + .await?; Ok(()) } async fn update_l1_block_metrics( - eth_client: &EthereumClient, + block_number: u64, + l1_block_metrics: &L1BlockMetrics, l1_gas_provider: &GasPriceProvider, ) -> anyhow::Result<()> { - // Get the latest block number - let latest_block_number = eth_client.get_latest_block_number().await?; - // Get the current gas price let current_gas_price = l1_gas_provider.get_gas_prices(); let eth_gas_price = current_gas_price.eth_l1_gas_price; @@ -121,8 +156,8 @@ async fn update_l1_block_metrics( // Update the metrics - eth_client.l1_block_metrics.l1_block_number.record(latest_block_number, &[]); - eth_client.l1_block_metrics.l1_gas_price_wei.record(eth_gas_price as u64, &[]); + l1_block_metrics.l1_block_number.record(block_number, &[]); + l1_block_metrics.l1_gas_price_wei.record(eth_gas_price as u64, &[]); // We're ignoring l1_gas_price_strk @@ -132,7 +167,10 @@ async fn update_l1_block_metrics( #[cfg(test)] mod eth_client_gas_price_worker_test { use super::*; - use crate::client::eth_client_getter_test::{create_ethereum_client, get_shared_anvil}; + use crate::eth::eth_client_getter_test::{create_ethereum_client, get_shared_anvil}; + use crate::eth::EthereumClientConfig; + use alloy::providers::RootProvider; + use alloy::transports::http::{Client, Http}; use httpmock::{MockServer, Regex}; use mc_mempool::GasPriceProvider; use serial_test::serial; @@ -152,8 +190,8 @@ mod eth_client_gas_price_worker_test { let eth_client = eth_client.clone(); let l1_gas_provider = l1_gas_provider.clone(); async move { - gas_price_worker( - Arc::new(eth_client), + gas_price_worker::>>( + Arc::new(Box::new(eth_client)), l1_gas_provider, Duration::from_millis(200), ServiceContext::new_for_testing(), @@ -192,7 +230,11 @@ mod eth_client_gas_price_worker_test { let l1_gas_provider = GasPriceProvider::new(); // Run the worker for a short time - let worker_handle = gas_price_worker_once(ð_client, &l1_gas_provider, Duration::from_millis(200)); + let worker_handle = gas_price_worker_once::>>( + Arc::new(Box::new(eth_client)), + &l1_gas_provider, + Duration::from_millis(200), + ); // Wait for the worker to complete worker_handle.await.expect("issue with the gas worker"); @@ -213,7 +255,11 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.set_gas_price_sync_enabled(false); // Run the worker for a short time - let worker_handle = gas_price_worker_once(ð_client, &l1_gas_provider, Duration::from_millis(200)); + let worker_handle = gas_price_worker_once::>>( + Arc::new(Box::new(eth_client)), + &l1_gas_provider, + Duration::from_millis(200), + ); // Wait for the worker to complete worker_handle.await.expect("issue with the gas worker"); @@ -234,7 +280,11 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.set_data_gas_price_sync_enabled(false); // Run the worker for a short time - let worker_handle = gas_price_worker_once(ð_client, &l1_gas_provider, Duration::from_millis(200)); + let worker_handle = gas_price_worker_once::>>( + Arc::new(Box::new(eth_client)), + &l1_gas_provider, + Duration::from_millis(200), + ); // Wait for the worker to complete worker_handle.await.expect("issue with the gas worker"); @@ -284,8 +334,8 @@ mod eth_client_gas_price_worker_test { let result = timeout( timeout_duration, - gas_price_worker( - Arc::new(eth_client), + gas_price_worker::>>( + Arc::new(Box::new(eth_client)), l1_gas_provider.clone(), Duration::from_millis(200), ServiceContext::new_for_testing(), @@ -321,7 +371,12 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.update_last_update_timestamp(); // Update gas prices - update_gas_price(ð_client, &l1_gas_provider).await.expect("Failed to update gas prices"); + update_gas_price::>>( + Arc::new(Box::new(eth_client)), + &l1_gas_provider, + ) + .await + .expect("Failed to update gas prices"); // Access the updated gas prices let updated_prices = l1_gas_provider.get_gas_prices(); diff --git a/crates/client/eth/src/l1_messaging.rs b/crates/client/settlement_client/src/l1_messaging.rs similarity index 94% rename from crates/client/eth/src/l1_messaging.rs rename to crates/client/settlement_client/src/l1_messaging.rs index ee99286f1..307bf35b3 100644 --- a/crates/client/eth/src/l1_messaging.rs +++ b/crates/client/settlement_client/src/l1_messaging.rs @@ -1,5 +1,5 @@ -use crate::client::StarknetCoreContract::LogMessageToL2; -use crate::client::{EthereumClient, StarknetCoreContract}; +use crate::client::ClientTrait; +use crate::eth::StarknetCoreContract::LogMessageToL2; use crate::utils::u256_to_felt; use alloy::eips::BlockNumberOrTag; use alloy::primitives::{keccak256, FixedBytes, U256}; @@ -14,30 +14,9 @@ use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersi use starknet_types_core::felt::Felt; use std::sync::Arc; -impl EthereumClient { - /// Get cancellation status of an L1 to L2 message - /// - /// This function query the core contract to know if a L1->L2 message has been cancelled - /// # Arguments - /// - /// - msg_hash : Hash of L1 to L2 message - /// - /// # Return - /// - /// - A felt representing a timestamp : - /// - 0 if the message has not been cancelled - /// - timestamp of the cancellation if it has been cancelled - /// - An Error if the call fail - pub async fn get_l1_to_l2_message_cancellations(&self, msg_hash: FixedBytes<32>) -> anyhow::Result { - //l1ToL2MessageCancellations - let cancellation_timestamp = self.l1_core_contract.l1ToL2MessageCancellations(msg_hash).call().await?; - u256_to_felt(cancellation_timestamp._0) - } -} - -pub async fn sync( +pub async fn sync( backend: Arc, - client: Arc, + client: Arc>>, chain_id: ChainId, mempool: Arc, mut ctx: ServiceContext, @@ -54,9 +33,11 @@ pub async fn sync( return Err(e.into()); } }; - let event_filter = client.l1_core_contract.event_filter::(); - let mut event_stream = event_filter + let contract_instance = client.get_core_contract_instance(); + let event_filter = contract_instance.event_filter::(); + + let mut event_stream = event_filter? .from_block(last_synced_event_block.block_number) .to_block(BlockNumberOrTag::Finalized) .watch() @@ -216,15 +197,12 @@ mod l1_messaging_tests { use std::{sync::Arc, time::Duration}; + use self::DummyContract::DummyContractInstance; + use crate::eth::StarknetCoreContract::LogMessageToL2; + use crate::eth::{EthereumClient, StarknetCoreContract}; + use crate::gas_price::L1BlockMetrics; use crate::l1_messaging::sync; - use crate::{ - client::{ - EthereumClient, L1BlockMetrics, - StarknetCoreContract::{self, LogMessageToL2}, - }, - l1_messaging::get_l1_to_l2_msg_hash, - utils::felt_to_u256, - }; + use crate::{l1_messaging::get_l1_to_l2_msg_hash, utils::felt_to_u256}; use alloy::{ hex::FromHex, node_bindings::{Anvil, AnvilInstance}, @@ -244,8 +222,6 @@ mod l1_messaging_tests { use tracing_test::traced_test; use url::Url; - use self::DummyContract::DummyContractInstance; - struct TestRunner { #[allow(dead_code)] anvil: AnvilInstance, // Not used but needs to stay in scope otherwise it will be dropped @@ -409,7 +385,7 @@ mod l1_messaging_tests { tokio::spawn(async move { sync( Arc::clone(db.backend()), - Arc::new(eth_client), + Arc::new(Box::new(eth_client)), chain_config.chain_id.clone(), mempool, ServiceContext::new_for_testing(), @@ -470,7 +446,7 @@ mod l1_messaging_tests { tokio::spawn(async move { sync( Arc::clone(db.backend()), - Arc::new(eth_client), + Arc::new(Box::new(eth_client)), chain_config.chain_id.clone(), mempool, ServiceContext::new_for_testing(), @@ -526,7 +502,7 @@ mod l1_messaging_tests { tokio::spawn(async move { sync( Arc::clone(db.backend()), - Arc::new(eth_client), + Arc::new(Box::new(eth_client)), chain_config.chain_id.clone(), mempool, ServiceContext::new_for_testing(), diff --git a/crates/client/eth/src/lib.rs b/crates/client/settlement_client/src/lib.rs similarity index 67% rename from crates/client/eth/src/lib.rs rename to crates/client/settlement_client/src/lib.rs index 4e8675d38..9b7b37ec8 100644 --- a/crates/client/eth/src/lib.rs +++ b/crates/client/settlement_client/src/lib.rs @@ -1,7 +1,9 @@ pub mod client; pub mod error; -pub mod l1_gas_price; +pub mod eth; +pub mod gas_price; pub mod l1_messaging; +pub mod starknet; pub mod state_update; pub mod sync; pub mod utils; diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs new file mode 100644 index 000000000..333bb0bbf --- /dev/null +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -0,0 +1,270 @@ +use crate::client::{ClientTrait, ClientType, CoreContractInstance}; +use crate::gas_price::L1BlockMetrics; +use crate::state_update::{update_l1, StateUpdate}; +use alloy::primitives::FixedBytes; +use anyhow::bail; +use async_trait::async_trait; +use bigdecimal::ToPrimitive; +use mc_db::MadaraBackend; +use mp_utils::service::ServiceContext; +use starknet_core::types::{BlockId, BlockTag, EmittedEvent, EventFilter, FunctionCall}; +use starknet_core::utils::get_selector_from_name; +use starknet_providers::jsonrpc::HttpTransport; +use starknet_providers::{JsonRpcClient, Provider}; +use starknet_types_core::felt::Felt; +use std::sync::Arc; +use std::time::Duration; +use tokio::time::sleep; +use tracing::{error, trace}; +use url::Url; + +pub struct StarknetClient { + pub provider: Arc>, + pub l2_core_contract: Felt, + pub l1_block_metrics: L1BlockMetrics, +} + +#[derive(Clone)] +pub struct StarknetClientConfig { + pub url: Url, + pub l2_contract_address: Felt, + pub l1_block_metrics: L1BlockMetrics, +} + +impl Clone for StarknetClient { + fn clone(&self) -> Self { + StarknetClient { + provider: Arc::clone(&self.provider), + l2_core_contract: self.l2_core_contract, + l1_block_metrics: self.l1_block_metrics.clone(), + } + } +} + +// TODO : Remove github refs after implementing the zaun imports +// Imp ⚠️ : zaun is not yet updated with latest app chain core contract implementations +// For this reason we are adding our own call implementations. +#[async_trait] +impl ClientTrait for StarknetClient { + type Provider = Arc>; + type Config = StarknetClientConfig; + + fn get_l1_block_metrics(&self) -> &L1BlockMetrics { + &self.l1_block_metrics + } + + fn get_core_contract_instance(&self) -> CoreContractInstance { + CoreContractInstance::Starknet(self.l2_core_contract) + } + + fn get_client_type(&self) -> ClientType { + ClientType::STARKNET + } + + async fn new(config: Self::Config) -> anyhow::Result + where + Self: Sized, + { + let provider = JsonRpcClient::new(HttpTransport::new(config.url)); + Ok(Self { + provider: Arc::new(provider), + l2_core_contract: config.l2_contract_address, + l1_block_metrics: config.l1_block_metrics, + }) + } + + async fn get_latest_block_number(&self) -> anyhow::Result { + let block_number = self.provider.block_number().await?; + Ok(block_number) + } + + async fn get_last_event_block_number(&self) -> anyhow::Result { + let latest_block = self.get_latest_block_number().await?; + let last_events = self + .get_events( + BlockId::Number(latest_block - 6000), + BlockId::Number(latest_block), + self.l2_core_contract, + // taken from : https://github.com/keep-starknet-strange/piltover/blob/main/src/appchain.cairo#L102 + vec![get_selector_from_name("LogStateUpdate")?], + ) + .await?; + + let last_update_state_event = last_events.last(); + match last_update_state_event { + Some(event) => { + /* + Github Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/appchain.cairo#L101 + Event description : + ------------------ + #[derive(Drop, starknet::Event)] + struct LogStateUpdate { + state_root: felt252, + block_number: felt252, + block_hash: felt252, + } + */ + assert_eq!(event.data.len(), 3, "Event response invalid !!"); + Ok(event.data[1].to_u64().unwrap()) + } + None => { + bail!("No event found") + } + } + } + + async fn get_last_verified_block_number(&self) -> anyhow::Result { + let call_res = self + .provider + .call( + FunctionCall { + contract_address: self.l2_core_contract, + /* + Github Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 + Function Call response : (StateRoot, BlockNumber, BlockHash) + */ + entry_point_selector: get_selector_from_name("get_state")?, + calldata: vec![], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await?; + assert_eq!(call_res.len(), 3, "Call response invalid !!"); + // Block Number index in call response : 1 + Ok(call_res[1].to_u64().unwrap()) + } + + async fn get_last_state_root(&self) -> anyhow::Result { + let call_res = self + .provider + .call( + FunctionCall { + contract_address: self.l2_core_contract, + /* + Github Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 + Function Call response : (StateRoot, BlockNumber, BlockHash) + */ + entry_point_selector: get_selector_from_name("get_state")?, + calldata: vec![], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await?; + assert_eq!(call_res.len(), 3, "Call response invalid !!"); + // State Root index in call response : 3 + Ok(call_res[0]) + } + + async fn get_last_verified_block_hash(&self) -> anyhow::Result { + let call_res = self + .provider + .call( + FunctionCall { + contract_address: self.l2_core_contract, + /* + Github Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 + Function Call response : (StateRoot, BlockNumber, BlockHash) + */ + entry_point_selector: get_selector_from_name("get_state")?, + calldata: vec![], + }, + BlockId::Tag(BlockTag::Latest), + ) + .await?; + assert_eq!(call_res.len(), 3, "Call response invalid !!"); + // Block Hash index in call response : 2 + Ok(call_res[2]) + } + + async fn get_initial_state(&self) -> anyhow::Result { + let block_number = self.get_last_verified_block_number().await?; + let block_hash = self.get_last_verified_block_hash().await?; + let global_root = self.get_last_state_root().await?; + + Ok(StateUpdate { global_root, block_number, block_hash }) + } + + async fn listen_for_update_state_events( + &self, + backend: Arc, + mut ctx: ServiceContext, + ) -> anyhow::Result<()> { + loop { + let events_response = ctx.run_until_cancelled(self.get_events( + BlockId::Number(self.get_latest_block_number().await?), + BlockId::Number(self.get_latest_block_number().await?), + self.l2_core_contract, + vec![get_selector_from_name("LogStateUpdate")?], + )); + + match events_response.await { + Some(Ok(emitted_events)) => { + if let Some(event) = emitted_events.last() { + let data = event; // Create a longer-lived binding + let formatted_event = StateUpdate { + block_number: data.data[1].to_u64().unwrap(), + global_root: data.data[0], + block_hash: data.data[2], + }; + update_l1(&backend, formatted_event, self.get_l1_block_metrics())?; + } + } + Some(Err(e)) => { + error!("Error processing event: {:?}", e); + } + None => { + trace!("Starknet Client : No event found"); + } + } + + sleep(Duration::from_millis(100)).await; + } + } + + async fn get_eth_gas_prices(&self) -> anyhow::Result<(u128, u128)> { + Ok((0, 0)) + } + + async fn get_l1_to_l2_message_cancellations(&self, _msg_hash: FixedBytes<32>) -> anyhow::Result { + todo!() + } +} + +impl StarknetClient { + async fn get_events( + &self, + from_block: BlockId, + to_block: BlockId, + contract_address: Felt, + keys: Vec, + ) -> anyhow::Result> { + let mut event_vec = Vec::new(); + let mut page_indicator = false; + let mut continuation_token = String::from("0"); + + while !page_indicator { + let events = self + .provider + .get_events( + EventFilter { + from_block: Some(from_block), + to_block: Some(to_block), + address: Some(contract_address), + keys: Some(vec![keys.clone()]), + }, + if continuation_token == "0" { None } else { Some(continuation_token.clone()) }, + 1000, + ) + .await?; + + event_vec.extend(events.events); + if let Some(token) = events.continuation_token { + continuation_token = token; + } else { + page_indicator = true; + } + } + + Ok(event_vec) + } +} diff --git a/crates/client/eth/src/state_update.rs b/crates/client/settlement_client/src/state_update.rs similarity index 74% rename from crates/client/eth/src/state_update.rs rename to crates/client/settlement_client/src/state_update.rs index c38bce421..84c94d61e 100644 --- a/crates/client/eth/src/state_update.rs +++ b/crates/client/settlement_client/src/state_update.rs @@ -1,39 +1,24 @@ use std::sync::Arc; -use crate::client::{L1BlockMetrics, StarknetCoreContract}; -use crate::{ - client::EthereumClient, - utils::{convert_log_state_update, trim_hash}, -}; +use crate::client::ClientTrait; +use crate::gas_price::L1BlockMetrics; +use crate::utils::trim_hash; use anyhow::Context; -use futures::StreamExt; use mc_db::MadaraBackend; use mp_utils::service::ServiceContext; use serde::Deserialize; use starknet_types_core::felt::Felt; -const ERR_ARCHIVE: &str = - "Failed to watch event filter - Ensure you are using an L1 RPC endpoint that points to an archive node"; - #[derive(Debug, Clone, Deserialize, PartialEq)] -pub struct L1StateUpdate { +pub struct StateUpdate { pub block_number: u64, pub global_root: Felt, pub block_hash: Felt, } -/// Get the last Starknet state update verified on the L1 -pub async fn get_initial_state(client: &EthereumClient) -> anyhow::Result { - let block_number = client.get_last_verified_block_number().await?; - let block_hash = client.get_last_verified_block_hash().await?; - let global_root = client.get_last_state_root().await?; - - Ok(L1StateUpdate { global_root, block_number, block_hash }) -} - pub fn update_l1( backend: &MadaraBackend, - state_update: L1StateUpdate, + state_update: StateUpdate, block_metrics: &L1BlockMetrics, ) -> anyhow::Result<()> { tracing::info!( @@ -51,10 +36,10 @@ pub fn update_l1( Ok(()) } -pub async fn state_update_worker( +pub async fn state_update_worker( backend: Arc, - eth_client: Arc, - mut ctx: ServiceContext, + settlement_client: Arc>>, + ctx: ServiceContext, ) -> anyhow::Result<()> { // Clear L1 confirmed block at startup backend.clear_last_confirmed_block().context("Clearing l1 last confirmed block number")?; @@ -64,25 +49,11 @@ pub async fn state_update_worker( // This does not seem to play well with anvil #[cfg(not(test))] { - let initial_state = get_initial_state(ð_client).await.context("Getting initial ethereum state")?; - update_l1(&backend, initial_state, ð_client.l1_block_metrics)?; - } - - // Listen to LogStateUpdate (0x77552641) update and send changes continuously - let event_filter = eth_client.l1_core_contract.event_filter::(); - - let mut event_stream = match ctx.run_until_cancelled(event_filter.watch()).await { - Some(res) => res.context(ERR_ARCHIVE)?.into_stream(), - None => return anyhow::Ok(()), - }; - - while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { - let log = event_result.context("listening for events")?; - let format_event: L1StateUpdate = - convert_log_state_update(log.0.clone()).context("formatting event into an L1StateUpdate")?; - update_l1(&backend, format_event, ð_client.l1_block_metrics)?; + let initial_state = settlement_client.get_initial_state().await.context("Getting initial ethereum state")?; + update_l1(&backend, initial_state, settlement_client.get_l1_block_metrics())?; } + settlement_client.listen_for_update_state_events(backend, ctx).await?; anyhow::Ok(()) } @@ -91,6 +62,9 @@ mod eth_client_event_subscription_test { use super::*; use std::{sync::Arc, time::Duration}; + use crate::eth::{EthereumClient, EthereumClientConfig, StarknetCoreContract}; + use alloy::providers::RootProvider; + use alloy::transports::http::{Client, Http}; use alloy::{node_bindings::Anvil, providers::ProviderBuilder, sol}; use mc_db::DatabaseService; use mp_chain_config::ChainConfig; @@ -169,9 +143,13 @@ mod eth_client_event_subscription_test { let listen_handle = { let db = Arc::clone(&db); tokio::spawn(async move { - state_update_worker(Arc::clone(db.backend()), Arc::new(eth_client), ServiceContext::new_for_testing()) - .await - .unwrap() + state_update_worker::>>( + Arc::clone(db.backend()), + Arc::new(Box::new(eth_client)), + ServiceContext::new_for_testing(), + ) + .await + .unwrap() }) }; diff --git a/crates/client/settlement_client/src/sync.rs b/crates/client/settlement_client/src/sync.rs new file mode 100644 index 000000000..961141f7d --- /dev/null +++ b/crates/client/settlement_client/src/sync.rs @@ -0,0 +1,46 @@ +use crate::client::{ClientTrait, ClientType}; +use crate::gas_price::gas_price_worker; +use crate::l1_messaging::sync; +use crate::state_update::state_update_worker; +use mc_db::MadaraBackend; +use mc_mempool::{GasPriceProvider, Mempool}; +use mp_utils::service::ServiceContext; +use starknet_api::core::ChainId; +use std::sync::Arc; +use std::time::Duration; +use tracing::warn; + +#[allow(clippy::too_many_arguments)] +pub async fn sync_worker( + backend: Arc, + settlement_client: Arc>>, + chain_id: ChainId, + l1_gas_provider: GasPriceProvider, + gas_price_sync_disabled: bool, + gas_price_poll_ms: Duration, + mempool: Arc, + ctx: ServiceContext, +) -> anyhow::Result<()> { + let mut join_set = tokio::task::JoinSet::new(); + + join_set.spawn(state_update_worker(Arc::clone(&backend), settlement_client.clone(), ctx.clone())); + + match settlement_client.get_client_type() { + ClientType::ETH => { + join_set.spawn(sync(Arc::clone(&backend), settlement_client.clone(), chain_id, mempool, ctx.clone())); + } + _ => { + warn!("⚠️ Provided client type does not implement the messaging sync function. Continuing....") + } + } + + if !gas_price_sync_disabled { + join_set.spawn(gas_price_worker(settlement_client.clone(), l1_gas_provider, gas_price_poll_ms, ctx.clone())); + } + + while let Some(res) = join_set.join_next().await { + res??; + } + + Ok(()) +} diff --git a/crates/client/eth/src/utils.rs b/crates/client/settlement_client/src/utils.rs similarity index 89% rename from crates/client/eth/src/utils.rs rename to crates/client/settlement_client/src/utils.rs index 8fc3bf965..29c0dd092 100644 --- a/crates/client/eth/src/utils.rs +++ b/crates/client/settlement_client/src/utils.rs @@ -1,12 +1,10 @@ -use crate::client::StarknetCoreContract; -use crate::state_update::L1StateUpdate; +use crate::eth::StarknetCoreContract; +use crate::state_update::StateUpdate; use alloy::primitives::{I256, U256}; use anyhow::bail; use starknet_types_core::felt::Felt; -pub fn convert_log_state_update( - log_state_update: StarknetCoreContract::LogStateUpdate, -) -> anyhow::Result { +pub fn convert_log_state_update(log_state_update: StarknetCoreContract::LogStateUpdate) -> anyhow::Result { let block_number = if log_state_update.blockNumber >= I256::ZERO { log_state_update.blockNumber.low_u64() } else { @@ -16,7 +14,7 @@ pub fn convert_log_state_update( let global_root = u256_to_felt(log_state_update.globalRoot)?; let block_hash = u256_to_felt(log_state_update.blockHash)?; - Ok(L1StateUpdate { block_number, global_root, block_hash }) + Ok(StateUpdate { block_number, global_root, block_hash }) } pub fn u256_to_felt(u256: U256) -> anyhow::Result { @@ -52,7 +50,7 @@ mod eth_client_conversion_tests { let global_root: u128 = 456; let expected = - L1StateUpdate { block_number, block_hash: Felt::from(block_hash), global_root: Felt::from(global_root) }; + StateUpdate { block_number, block_hash: Felt::from(block_hash), global_root: Felt::from(global_root) }; let input = StarknetCoreContract::LogStateUpdate { blockNumber: I256::from_dec_str(block_number.to_string().as_str()).unwrap(), diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 05240ceea..3a81f384c 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -26,7 +26,7 @@ mc-block-import = { workspace = true } mc-block-production = { workspace = true } mc-db = { workspace = true } mc-devnet = { workspace = true } -mc-eth = { workspace = true } +mc-settlement-client = { workspace = true } mc-gateway-client = { workspace = true } mc-gateway-server = { workspace = true } mc-mempool = { workspace = true } @@ -58,6 +58,8 @@ reqwest.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true serde_yaml.workspace = true +starknet-core.workspace = true +starknet-providers.workspace = true thiserror.workspace = true tokio.workspace = true tower-http.workspace = true diff --git a/crates/node/src/cli/chain_config_overrides.rs b/crates/node/src/cli/chain_config_overrides.rs index 7d86413db..f86f38c2c 100644 --- a/crates/node/src/cli/chain_config_overrides.rs +++ b/crates/node/src/cli/chain_config_overrides.rs @@ -46,7 +46,7 @@ pub struct ChainConfigOverridesInner { #[serde(deserialize_with = "deserialize_bouncer_config", serialize_with = "serialize_bouncer_config")] pub bouncer_config: BouncerConfig, pub sequencer_address: ContractAddress, - pub eth_core_contract_address: H160, + pub eth_core_contract_address: String, pub eth_gps_statement_verifier: H160, #[serde(default)] #[serde(skip_serializing)] diff --git a/crates/node/src/cli/l1.rs b/crates/node/src/cli/l1.rs index 2d28a8b25..5de384644 100644 --- a/crates/node/src/cli/l1.rs +++ b/crates/node/src/cli/l1.rs @@ -1,9 +1,37 @@ +use alloy::primitives::private::derive_more::FromStr; +use std::fmt; use std::time::Duration; - use url::Url; use mp_utils::parsers::{parse_duration, parse_url}; +#[derive(Clone, Debug)] +pub enum MadaraSettlementLayer { + Eth, + Starknet, +} + +impl FromStr for MadaraSettlementLayer { + type Err = String; + + fn from_str(s: &str) -> Result { + match s.to_uppercase().as_str() { + "ETH" => Ok(MadaraSettlementLayer::Eth), + "STARKNET" => Ok(MadaraSettlementLayer::Starknet), + _ => Err(format!("Invalid settlement layer: {}", s)), + } + } +} + +impl fmt::Display for MadaraSettlementLayer { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MadaraSettlementLayer::Eth => write!(f, "ETH"), + MadaraSettlementLayer::Starknet => write!(f, "STARKNET"), + } + } +} + #[derive(Clone, Debug, clap::Args)] pub struct L1SyncParams { /// Disable L1 sync. @@ -46,4 +74,11 @@ pub struct L1SyncParams { value_parser = parse_duration, )] pub gas_price_poll: Duration, + + #[clap( + env = "MADARA_SETTLEMENT_LAYER", + long, + default_value_t = MadaraSettlementLayer::Eth, + )] + pub settlement_layer: MadaraSettlementLayer, } diff --git a/crates/node/src/main.rs b/crates/node/src/main.rs index bb14def92..3f4fa148c 100644 --- a/crates/node/src/main.rs +++ b/crates/node/src/main.rs @@ -5,6 +5,9 @@ mod cli; mod service; mod util; +use crate::cli::l1::MadaraSettlementLayer; +use alloy::providers::RootProvider; +use alloy::transports::http::Http; use anyhow::{bail, Context}; use clap::Parser; use cli::{NetworkType, RunCmd}; @@ -15,11 +18,16 @@ use mc_db::{DatabaseService, TrieLogConfig}; use mc_gateway_client::GatewayProvider; use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; use mc_rpc::providers::{AddTransactionProvider, ForwardToProvider, MempoolAddTxProvider}; +use mc_settlement_client::eth::EthereumClientConfig; +use mc_settlement_client::starknet::StarknetClientConfig; use mc_sync::fetch::fetchers::WarpUpdateConfig; use mc_telemetry::{SysInfo, TelemetryService}; use mp_oracle::pragma::PragmaOracleBuilder; use mp_utils::service::{MadaraServiceId, ServiceMonitor}; +use reqwest::Client; use service::{BlockProductionService, GatewayService, L1SyncService, L2SyncService, RpcService}; +use starknet_providers::jsonrpc::HttpTransport; +use starknet_providers::JsonRpcClient; use std::sync::Arc; const GREET_IMPL_NAME: &str = "Madara"; @@ -151,18 +159,34 @@ async fn main() -> anyhow::Result<()> { mempool.load_txs_from_db().context("Loading mempool transactions")?; let mempool = Arc::new(mempool); - let service_l1_sync = L1SyncService::new( - &run_cmd.l1_sync_params, - &service_db, - l1_gas_setter, - chain_config.chain_id.clone(), - chain_config.eth_core_contract_address, - run_cmd.is_sequencer(), - run_cmd.is_devnet(), - Arc::clone(&mempool), - ) - .await - .context("Initializing the l1 sync service")?; + let service_l1_sync = match &run_cmd.l1_sync_params.settlement_layer { + MadaraSettlementLayer::Eth => L1SyncService::>>::create( + &run_cmd.l1_sync_params, + &service_db, + l1_gas_setter, + chain_config.chain_id.clone(), + chain_config.eth_core_contract_address.clone(), + run_cmd.is_sequencer(), + run_cmd.is_devnet(), + Arc::clone(&mempool), + ) + .await + .context("Initializing the l1 sync service")?, + MadaraSettlementLayer::Starknet => { + L1SyncService::>>::create( + &run_cmd.l1_sync_params, + &service_db, + l1_gas_setter, + chain_config.chain_id.clone(), + chain_config.eth_core_contract_address.clone(), + run_cmd.is_sequencer(), + run_cmd.is_devnet(), + Arc::clone(&mempool), + ) + .await + .context("Initializing the l1 sync service")? + } + }; // L2 Sync diff --git a/crates/node/src/service/l1.rs b/crates/node/src/service/l1.rs index e305d741c..a885c3bfa 100644 --- a/crates/node/src/service/l1.rs +++ b/crates/node/src/service/l1.rs @@ -1,19 +1,32 @@ -use crate::cli::l1::L1SyncParams; +use crate::cli::l1::{L1SyncParams, MadaraSettlementLayer}; use alloy::primitives::Address; +use alloy::providers::RootProvider; +use alloy::transports::http::Http; use anyhow::Context; use mc_db::{DatabaseService, MadaraBackend}; -use mc_eth::client::{EthereumClient, L1BlockMetrics}; use mc_mempool::{GasPriceProvider, Mempool}; -use mp_block::H160; +use mc_settlement_client::client::ClientTrait; +use mc_settlement_client::eth::{EthereumClient, EthereumClientConfig}; +use mc_settlement_client::gas_price::L1BlockMetrics; +use mc_settlement_client::starknet::{StarknetClient, StarknetClientConfig}; use mp_utils::service::{MadaraServiceId, PowerOfTwo, Service, ServiceId, ServiceRunner}; +use reqwest::Client; use starknet_api::core::ChainId; +use starknet_core::types::Felt; +use starknet_providers::jsonrpc::HttpTransport; +use starknet_providers::JsonRpcClient; +use std::str::FromStr; use std::sync::Arc; use std::time::Duration; #[derive(Clone)] -pub struct L1SyncService { +pub struct L1SyncService +where + C: Clone, + P: Clone, +{ db_backend: Arc, - eth_client: Option>, + settlement_client: Option>>>, l1_gas_provider: GasPriceProvider, chain_id: ChainId, gas_price_sync_disabled: bool, @@ -21,56 +34,124 @@ pub struct L1SyncService { mempool: Arc, } -impl L1SyncService { +pub type EthereumSyncService = L1SyncService>>; + +pub type StarknetSyncService = L1SyncService>>; + +// Implementation for Ethereum +impl EthereumSyncService { + #[allow(clippy::too_many_arguments)] + pub async fn new( + config: &L1SyncParams, + db: &DatabaseService, + l1_gas_provider: GasPriceProvider, + chain_id: ChainId, + l1_core_address: String, + authority: bool, + devnet: bool, + mempool: Arc, + ) -> anyhow::Result { + let settlement_client = if !config.l1_sync_disabled && (config.l1_endpoint.is_some() || !devnet) { + if let Some(l1_rpc_url) = &config.l1_endpoint { + let core_address = Address::from_str(l1_core_address.as_str())?; + let l1_block_metrics = L1BlockMetrics::register().expect("Registering metrics"); + let client = EthereumClient::new(EthereumClientConfig { + url: l1_rpc_url.clone(), + l1_core_address: core_address, + l1_block_metrics, + }) + .await + .context("Creating ethereum client")?; + + let client_converted: Box< + dyn ClientTrait>>, + > = Box::new(client); + Some(Arc::new(client_converted)) + } else { + anyhow::bail!( + "No Ethereum endpoint provided. Use --l1-endpoint or disable with --no-l1-sync." + ); + } + } else { + None + }; + + Self::create_service(config, db, settlement_client, l1_gas_provider, chain_id, authority, devnet, mempool).await + } +} + +// Implementation for Starknet +impl StarknetSyncService { #[allow(clippy::too_many_arguments)] pub async fn new( config: &L1SyncParams, db: &DatabaseService, l1_gas_provider: GasPriceProvider, chain_id: ChainId, - l1_core_address: H160, + l1_core_address: String, authority: bool, devnet: bool, mempool: Arc, ) -> anyhow::Result { - let eth_client = if !config.l1_sync_disabled && (config.l1_endpoint.is_some() || !devnet) { + let settlement_client = if !config.l1_sync_disabled && (config.l1_endpoint.is_some() || !devnet) { if let Some(l1_rpc_url) = &config.l1_endpoint { - let core_address = Address::from_slice(l1_core_address.as_bytes()); + let core_address = Felt::from_str(l1_core_address.as_str())?; let l1_block_metrics = L1BlockMetrics::register().expect("Registering metrics"); - let client = EthereumClient::new(l1_rpc_url.clone(), core_address, l1_block_metrics) - .await - .context("Creating ethereum client")?; + let client = StarknetClient::new(StarknetClientConfig { + url: l1_rpc_url.clone(), + l2_contract_address: core_address, + l1_block_metrics, + }) + .await + .context("Creating starknet client")?; - Some(Arc::new(client)) + // StarknetClientConfig, Arc>, Felt + let client_converted: Box< + dyn ClientTrait>>, + > = Box::new(client); + Some(Arc::new(client_converted)) } else { anyhow::bail!( - "No Ethereum endpoint provided. You need to provide one using --l1-endpoint in order to verify the synced state or disable the l1 watcher using --no-l1-sync." + "No Starknet endpoint provided. Use --l1-endpoint or disable with --no-l1-sync." ); } } else { None }; - // Note: gas price should be synced in case the madara is running in sequencer mode, - // we haven't set any fix price for the gas, hence gas price should be none + Self::create_service(config, db, settlement_client, l1_gas_provider, chain_id, authority, devnet, mempool).await + } +} + +// Shared implementation for both services +impl L1SyncService { + #[allow(clippy::too_many_arguments)] + async fn create_service( + config: &L1SyncParams, + db: &DatabaseService, + settlement_client: Option>>>, + l1_gas_provider: GasPriceProvider, + chain_id: ChainId, + authority: bool, + devnet: bool, + mempool: Arc, + ) -> anyhow::Result { let gas_price_sync_enabled = authority && !devnet && (config.gas_price.is_none() || config.blob_gas_price.is_none()); let gas_price_poll = config.gas_price_poll; if gas_price_sync_enabled { - let eth_client = eth_client - .clone() - .context("L1 gas prices require the ethereum service to be enabled. Either disable gas prices syncing using `--gas-price 0`, or disable L1 sync using the `--no-l1-sync` argument.")?; - // running at-least once before the block production service + let settlement_client = + settlement_client.clone().context("L1 gas prices require the service to be enabled...")?; tracing::info!("⏳ Getting initial L1 gas prices"); - mc_eth::l1_gas_price::gas_price_worker_once(ð_client, &l1_gas_provider, gas_price_poll) + mc_settlement_client::gas_price::gas_price_worker_once(settlement_client, &l1_gas_provider, gas_price_poll) .await - .context("Getting initial ethereum gas prices")?; + .context("Getting initial gas prices")?; } Ok(Self { db_backend: Arc::clone(db.backend()), - eth_client, + settlement_client, l1_gas_provider, chain_id, gas_price_sync_disabled: !gas_price_sync_enabled, @@ -78,10 +159,56 @@ impl L1SyncService { mempool, }) } + + // Factory method to create the appropriate service + #[allow(clippy::too_many_arguments)] + pub async fn create( + config: &L1SyncParams, + db: &DatabaseService, + l1_gas_provider: GasPriceProvider, + chain_id: ChainId, + l1_core_address: String, + authority: bool, + devnet: bool, + mempool: Arc, + ) -> anyhow::Result> { + match config.settlement_layer { + MadaraSettlementLayer::Eth => Ok(Box::new( + EthereumSyncService::new( + config, + db, + l1_gas_provider, + chain_id, + l1_core_address, + authority, + devnet, + mempool, + ) + .await?, + )), + MadaraSettlementLayer::Starknet => Ok(Box::new( + StarknetSyncService::new( + config, + db, + l1_gas_provider, + chain_id, + l1_core_address, + authority, + devnet, + mempool, + ) + .await?, + )), + } + } } #[async_trait::async_trait] -impl Service for L1SyncService { +impl Service for L1SyncService +where + C: Clone, + P: Clone, +{ async fn start<'a>(&mut self, runner: ServiceRunner<'a>) -> anyhow::Result<()> { let L1SyncService { db_backend, @@ -93,14 +220,14 @@ impl Service for L1SyncService { .. } = self.clone(); - if let Some(eth_client) = &self.eth_client { + if let Some(settlement_client) = &self.settlement_client { // enabled - let eth_client = Arc::clone(eth_client); + let settlement_client = Arc::clone(settlement_client); runner.service_loop(move |ctx| { - mc_eth::sync::l1_sync_worker( + mc_settlement_client::sync::sync_worker( db_backend, - eth_client, + settlement_client, chain_id, l1_gas_provider, gas_price_sync_disabled, @@ -117,7 +244,11 @@ impl Service for L1SyncService { } } -impl ServiceId for L1SyncService { +impl ServiceId for L1SyncService +where + C: Clone, + P: Clone, +{ #[inline(always)] fn svc_id(&self) -> PowerOfTwo { MadaraServiceId::L1Sync.svc_id() diff --git a/crates/primitives/chain_config/src/chain_config.rs b/crates/primitives/chain_config/src/chain_config.rs index 409ff9bb5..66cb44b9f 100644 --- a/crates/primitives/chain_config/src/chain_config.rs +++ b/crates/primitives/chain_config/src/chain_config.rs @@ -114,7 +114,7 @@ pub struct ChainConfig { pub sequencer_address: ContractAddress, /// The Starknet core contract address for the L1 watcher. - pub eth_core_contract_address: H160, + pub eth_core_contract_address: String, /// The Starknet SHARP verifier La address. Check out the [docs](https://docs.starknet.io/architecture-and-concepts/solidity-verifier/) /// for more information @@ -550,10 +550,7 @@ mod tests { ) .unwrap() ); - assert_eq!( - chain_config.eth_core_contract_address, - H160::from_str("0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4").unwrap() - ); + assert_eq!(chain_config.eth_core_contract_address, "0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4"); } #[rstest] From abc808ea3d8dae9c80ff4627665bf428aeef707d Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Thu, 19 Dec 2024 00:03:22 +0530 Subject: [PATCH 02/23] code : refactor --- crates/client/settlement_client/src/gas_price.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/client/settlement_client/src/gas_price.rs b/crates/client/settlement_client/src/gas_price.rs index 13ac9ab6f..7ade360b5 100644 --- a/crates/client/settlement_client/src/gas_price.rs +++ b/crates/client/settlement_client/src/gas_price.rs @@ -69,13 +69,13 @@ pub async fn gas_price_worker_once( let last_update_timestamp = l1_gas_provider.get_gas_prices_last_update(); let duration_since_last_update = SystemTime::now().duration_since(last_update_timestamp)?; - let last_update_timestemp = + let last_update_timestamp = last_update_timestamp.duration_since(UNIX_EPOCH).expect("SystemTime before UNIX EPOCH!").as_micros(); if duration_since_last_update > 10 * gas_price_poll_ms { anyhow::bail!( "Gas prices have not been updated for {} ms. Last update was at {}", duration_since_last_update.as_micros(), - last_update_timestemp + last_update_timestamp ); } @@ -111,7 +111,7 @@ async fn update_gas_price( if let Some(oracle_provider) = &l1_gas_provider.oracle_provider { let (eth_strk_price, decimals) = oracle_provider.fetch_eth_strk_price().await.context("failed to retrieve ETH/STRK price")?; - let strk_gas_price = (BigDecimal::new((eth_gas_price).into(), decimals.into()) + let strk_gas_price = (BigDecimal::new(eth_gas_price.into(), decimals.into()) / BigDecimal::new(eth_strk_price.into(), decimals.into())) .as_bigint_and_exponent(); let strk_data_gas_price = (BigDecimal::new(avg_blob_base_fee.into(), decimals.into()) From a49e209167f8bdb6116dbb694fe132674c1db26b Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Fri, 20 Dec 2024 21:55:00 +0530 Subject: [PATCH 03/23] feat : added tests for starknet client --- .github/workflows/rust-test.yml | 4 + .gitignore | 3 + Cargo.lock | 4 + crates/client/settlement_client/Cargo.toml | 4 + .../settlement_client/src/starknet/mod.rs | 218 +++++++++++++++++- .../test_contracts/appchain_test.cairo | 53 +++++ .../test_contracts/appchain_test.casm.json | 1 + .../test_contracts/appchain_test.sierra.json | 1 + .../settlement_client/src/starknet/utils.rs | 210 +++++++++++++++++ test-artifacts/devnet.yaml | 34 +++ 10 files changed, 523 insertions(+), 9 deletions(-) create mode 100644 crates/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo create mode 100644 crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json create mode 100644 crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json create mode 100644 crates/client/settlement_client/src/starknet/utils.rs create mode 100644 test-artifacts/devnet.yaml diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index 3a76b05d1..b414b8370 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -30,6 +30,10 @@ jobs: while ! nc -z localhost 8545; do sleep 1 done + - name: Download madara binary for l2 client testing + run: | + curl -L https://madara-test-binary.s3.us-west-1.amazonaws.com/madara -o ./test-artifacts/madara + chmod +x ./test-artifacts/madara - name: Run unit tests run: | diff --git a/.gitignore b/.gitignore index a256a077c..8acd8c1d9 100644 --- a/.gitignore +++ b/.gitignore @@ -68,3 +68,6 @@ tmp/ # Running madara with make and docker compose .secrets image.tar.gz + +# madara test artifacts for testing l2 clients for appchains +test-artifacts/madara \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 42f125cba..62f13049e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5817,6 +5817,7 @@ version = "0.7.0" dependencies = [ "alloy", "anyhow", + "assert_matches", "async-trait", "bigdecimal", "bitvec", @@ -5843,8 +5844,11 @@ dependencies = [ "serde", "serde_json", "serial_test", + "starknet-accounts", + "starknet-contract", "starknet-core", "starknet-providers", + "starknet-signers", "starknet-types-core 0.1.7 (git+https://github.com/kasarlabs/types-rs.git?branch=feat-deserialize-v0.1.7)", "starknet_api", "tempfile", diff --git a/crates/client/settlement_client/Cargo.toml b/crates/client/settlement_client/Cargo.toml index 4a7327e90..7123e4b9b 100644 --- a/crates/client/settlement_client/Cargo.toml +++ b/crates/client/settlement_client/Cargo.toml @@ -33,6 +33,7 @@ starknet_api.workspace = true # Other +assert_matches = "1.5.0" alloy.workspace = true anyhow.workspace = true bigdecimal.workspace = true @@ -44,6 +45,9 @@ serde = { workspace = true, default-features = true } serde_json = "1" starknet-providers = { workspace = true } starknet-core = { workspace = true } +starknet-accounts = "0.11.0" +starknet-signers = { workspace = true } +starknet-contract = "0.11.0" thiserror.workspace = true time = "0.3.36" tokio = { workspace = true, features = [ diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index 333bb0bbf..6ea535edb 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -18,6 +18,10 @@ use tokio::time::sleep; use tracing::{error, trace}; use url::Url; +#[cfg(test)] +mod utils; + +#[derive(Debug)] pub struct StarknetClient { pub provider: Arc>, pub l2_core_contract: Felt, @@ -66,6 +70,9 @@ impl ClientTrait for StarknetClient { Self: Sized, { let provider = JsonRpcClient::new(HttpTransport::new(config.url)); + // Check if l2 contract exists : + // If contract is not there this will error out. + provider.get_class_at(BlockId::Tag(BlockTag::Latest), config.l2_contract_address).await?; Ok(Self { provider: Arc::new(provider), l2_core_contract: config.l2_contract_address, @@ -80,9 +87,11 @@ impl ClientTrait for StarknetClient { async fn get_last_event_block_number(&self) -> anyhow::Result { let latest_block = self.get_latest_block_number().await?; + // If block on l2 is not greater than or equal to 6000 we will consider the last block to 0. + let last_block = if latest_block <= 6000 { 0 } else { 6000 }; let last_events = self .get_events( - BlockId::Number(latest_block - 6000), + BlockId::Number(last_block), BlockId::Number(latest_block), self.l2_core_contract, // taken from : https://github.com/keep-starknet-strange/piltover/blob/main/src/appchain.cairo#L102 @@ -94,7 +103,7 @@ impl ClientTrait for StarknetClient { match last_update_state_event { Some(event) => { /* - Github Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/appchain.cairo#L101 + GitHub Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/appchain.cairo#L101 Event description : ------------------ #[derive(Drop, starknet::Event)] @@ -105,7 +114,11 @@ impl ClientTrait for StarknetClient { } */ assert_eq!(event.data.len(), 3, "Event response invalid !!"); - Ok(event.data[1].to_u64().unwrap()) + // Block number management in case of pending block number events. + match event.block_number { + Some(block_number) => Ok(block_number), + None => Ok(self.get_latest_block_number().await? + 1), + } } None => { bail!("No event found") @@ -120,13 +133,13 @@ impl ClientTrait for StarknetClient { FunctionCall { contract_address: self.l2_core_contract, /* - Github Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 + GitHub Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 Function Call response : (StateRoot, BlockNumber, BlockHash) */ entry_point_selector: get_selector_from_name("get_state")?, calldata: vec![], }, - BlockId::Tag(BlockTag::Latest), + BlockId::Tag(BlockTag::Pending), ) .await?; assert_eq!(call_res.len(), 3, "Call response invalid !!"); @@ -141,13 +154,13 @@ impl ClientTrait for StarknetClient { FunctionCall { contract_address: self.l2_core_contract, /* - Github Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 + GitHub Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 Function Call response : (StateRoot, BlockNumber, BlockHash) */ entry_point_selector: get_selector_from_name("get_state")?, calldata: vec![], }, - BlockId::Tag(BlockTag::Latest), + BlockId::Tag(BlockTag::Pending), ) .await?; assert_eq!(call_res.len(), 3, "Call response invalid !!"); @@ -162,13 +175,13 @@ impl ClientTrait for StarknetClient { FunctionCall { contract_address: self.l2_core_contract, /* - Github Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 + GitHub Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 Function Call response : (StateRoot, BlockNumber, BlockHash) */ entry_point_selector: get_selector_from_name("get_state")?, calldata: vec![], }, - BlockId::Tag(BlockTag::Latest), + BlockId::Tag(BlockTag::Pending), ) .await?; assert_eq!(call_res.len(), 3, "Call response invalid !!"); @@ -268,3 +281,190 @@ impl StarknetClient { Ok(event_vec) } } + +#[cfg(test)] +pub mod starknet_client_tests { + use crate::client::ClientTrait; + use crate::gas_price::L1BlockMetrics; + use crate::starknet::utils::{prepare_starknet_client_test, send_state_update, MADARA_PORT}; + use crate::starknet::{StarknetClient, StarknetClientConfig}; + use crate::state_update::StateUpdate; + use serial_test::serial; + use starknet_types_core::felt::Felt; + use std::str::FromStr; + use std::time::Duration; + use tokio::time::sleep; + use url::Url; + + #[serial] + #[tokio::test] + async fn fail_create_new_client_contract_does_not_exists() -> anyhow::Result<()> { + prepare_starknet_client_test().await?; + let l1_block_metrics = L1BlockMetrics::register()?; + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, + l2_contract_address: Felt::from_str("0xdeadbeef")?, + l1_block_metrics, + }) + .await; + assert!(starknet_client.is_err(), "Should fail to create a new client"); + Ok(()) + } + + #[serial] + #[tokio::test] + async fn create_new_client_contract_exists_starknet_client() -> anyhow::Result<()> { + // Here we need to have madara variable otherwise it will + // get dropped and will kill the madara. + #[allow(unused_variables)] + let (_, deployed_address, madara) = prepare_starknet_client_test().await?; + let l1_block_metrics = L1BlockMetrics::register()?; + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, + l2_contract_address: deployed_address, + l1_block_metrics, + }) + .await; + assert!(starknet_client.is_ok(), "Should not fail to create a new client"); + Ok(()) + } + + #[serial] + #[tokio::test] + async fn get_last_event_block_number_works_starknet_client() -> anyhow::Result<()> { + // Here we need to have madara variable otherwise it will + // get dropped and will kill the madara. + #[allow(unused_variables)] + let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let l1_block_metrics = L1BlockMetrics::register()?; + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, + l2_contract_address: deployed_address, + l1_block_metrics, + }) + .await?; + + // sending state updates : + send_state_update( + &account, + deployed_address, + StateUpdate { + block_number: 99, + global_root: Felt::from_hex("0xdeadbeef")?, + block_hash: Felt::from_hex("0xdeadbeef")?, + }, + ) + .await?; + let last_event_block_number = send_state_update( + &account, + deployed_address, + StateUpdate { + block_number: 100, + global_root: Felt::from_hex("0xdeadbeef")?, + block_hash: Felt::from_hex("0xdeadbeef")?, + }, + ) + .await?; + + // It takes time on madara for events to be stored + sleep(Duration::from_secs(10)).await; + + let latest_event_block_number = starknet_client.get_last_event_block_number().await?; + assert_eq!(latest_event_block_number, last_event_block_number, "Latest event should have block number 100"); + Ok(()) + } + + #[serial] + #[tokio::test] + async fn get_last_verified_block_hash_works_starknet_client() -> anyhow::Result<()> { + // Here we need to have madara variable otherwise it will + // get dropped and will kill the madara. + #[allow(unused_variables)] + let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let l1_block_metrics = L1BlockMetrics::register()?; + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, + l2_contract_address: deployed_address, + l1_block_metrics, + }) + .await?; + + // sending state updates : + let data_felt = Felt::from_hex("0xdeadbeef")?; + send_state_update( + &account, + deployed_address, + StateUpdate { block_number: 100, global_root: data_felt, block_hash: data_felt }, + ) + .await?; + sleep(Duration::from_secs(5)).await; + + let last_verified_block_hash = starknet_client.get_last_verified_block_hash().await?; + assert_eq!(last_verified_block_hash, data_felt, "Block hash should match"); + + Ok(()) + } + + #[serial] + #[tokio::test] + async fn get_last_state_root_works_starknet_client() -> anyhow::Result<()> { + // Here we need to have madara variable otherwise it will + // get dropped and will kill the madara. + #[allow(unused_variables)] + let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let l1_block_metrics = L1BlockMetrics::register()?; + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, + l2_contract_address: deployed_address, + l1_block_metrics, + }) + .await?; + + // sending state updates : + let data_felt = Felt::from_hex("0xdeadbeef")?; + send_state_update( + &account, + deployed_address, + StateUpdate { block_number: 100, global_root: data_felt, block_hash: data_felt }, + ) + .await?; + sleep(Duration::from_secs(5)).await; + + let last_verified_state_root = starknet_client.get_last_state_root().await?; + assert_eq!(last_verified_state_root, data_felt, "Last state root should match"); + + Ok(()) + } + + #[serial] + #[tokio::test] + async fn get_last_verified_block_number_works_starknet_client() -> anyhow::Result<()> { + // Here we need to have madara variable otherwise it will + // get dropped and will kill the madara. + #[allow(unused_variables)] + let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let l1_block_metrics = L1BlockMetrics::register()?; + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, + l2_contract_address: deployed_address, + l1_block_metrics, + }) + .await?; + + // sending state updates : + let data_felt = Felt::from_hex("0xdeadbeef")?; + let block_number = 100; + send_state_update( + &account, + deployed_address, + StateUpdate { block_number, global_root: data_felt, block_hash: data_felt }, + ) + .await?; + sleep(Duration::from_secs(5)).await; + + let last_verified_block_number = starknet_client.get_last_verified_block_number().await?; + assert_eq!(last_verified_block_number, block_number, "Last verified block should match"); + + Ok(()) + } +} diff --git a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo new file mode 100644 index 000000000..78ea72bfa --- /dev/null +++ b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo @@ -0,0 +1,53 @@ +#[starknet::contract] +mod StateUpdateContract { + type StateRoot = felt252; + type BlockNumber = felt252; + type BlockHash = felt252; + + #[storage] + struct Storage { + state_root: StateRoot, + block_number: BlockNumber, + block_hash: BlockHash, + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + LogStateUpdate: LogStateUpdate + } + + #[derive(Drop, starknet::Event)] + struct LogStateUpdate { + state_root: felt252, + block_number: felt252, + block_hash: felt252, + } + + #[constructor] + fn constructor(ref self: ContractState) { + // Initialize with default values + self.state_root.write(0); + self.block_number.write(0); + self.block_hash.write(0); + } + + #[external(v0)] + fn update_state( + ref self: ContractState, + block_number: BlockNumber, + state_root: StateRoot, + block_hash: BlockHash + ) { + self.state_root.write(state_root); + self.block_number.write(block_number); + self.block_hash.write(block_hash); + + self.emit(LogStateUpdate { state_root, block_number, block_hash, }); + } + + #[external(v0)] + fn get_state(self: @ContractState) -> (StateRoot, BlockNumber, BlockHash) { + (self.state_root.read(), self.block_number.read(), self.block_hash.read()) + } +} diff --git a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json new file mode 100644 index 000000000..c613f4cff --- /dev/null +++ b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json @@ -0,0 +1 @@ +{"prime":"0x800000000000011000000000000000000000000000000000000000000000001","compiler_version":"2.8.0","bytecode":["0xa0680017fff8000","0x7","0x482680017ffa8000","0x100000000000000000000000000000000","0x400280007ff97fff","0x10780017fff7fff","0xc0","0x4825800180007ffa","0x0","0x400280007ff97fff","0x482680017ff98000","0x1","0x48297ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0xa","0x482680017ffc8000","0x1","0x480a7ffd7fff8000","0x480680017fff8000","0x0","0x480280007ffc8000","0x10780017fff7fff","0x8","0x480a7ffc7fff8000","0x480a7ffd7fff8000","0x480680017fff8000","0x1","0x480680017fff8000","0x0","0x20680017fff7ffe","0x98","0x48307ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0xa","0x482480017ffb8000","0x1","0x48127ffb7fff8000","0x480680017fff8000","0x0","0x480080007ff88000","0x10780017fff7fff","0x8","0x48127ffb7fff8000","0x48127ffb7fff8000","0x480680017fff8000","0x1","0x480680017fff8000","0x0","0x20680017fff7ffe","0x75","0x48307ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0xa","0x482480017ffb8000","0x1","0x48127ffb7fff8000","0x480680017fff8000","0x0","0x480080007ff88000","0x10780017fff7fff","0x8","0x48127ffb7fff8000","0x48127ffb7fff8000","0x480680017fff8000","0x1","0x480680017fff8000","0x0","0x20680017fff7ffe","0x52","0x48307ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0x10","0x40780017fff7fff","0x1","0x480680017fff8000","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x400080007ffe7fff","0x48127fed7fff8000","0x48127feb7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x1104800180018000","0x250","0x482480017fff8000","0x24f","0x480080007fff8000","0xa0680017fff8000","0x9","0x4824800180007fe9","0xa370","0x482480017fff8000","0x100000000000000000000000000000000","0x400080007fe87fff","0x10780017fff7fff","0x22","0x4824800180007fe9","0xa370","0x400080007fe97fff","0x482480017fe98000","0x1","0x48127ffe7fff8000","0x480a7ffb7fff8000","0x48127feb7fff8000","0x48127fef7fff8000","0x48127ff37fff8000","0x1104800180018000","0x1b6","0x20680017fff7ffd","0xc","0x40780017fff7fff","0x1","0x48127ff97fff8000","0x48127ff97fff8000","0x48127ff97fff8000","0x480680017fff8000","0x0","0x48127ffb7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x48127ffa7fff8000","0x48127ffa7fff8000","0x48127ffa7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482480017fe68000","0x1","0x48127fe47fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4661696c656420746f20646573657269616c697a6520706172616d202333","0x400080007ffe7fff","0x48127fee7fff8000","0x48127fec7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4661696c656420746f20646573657269616c697a6520706172616d202332","0x400080007ffe7fff","0x48127ff37fff8000","0x48127ff17fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4661696c656420746f20646573657269616c697a6520706172616d202331","0x400080007ffe7fff","0x48127ff87fff8000","0x48127ff67fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482680017ff98000","0x1","0x480a7ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0xa0680017fff8000","0x7","0x482680017ffa8000","0x100000000000000000000000000000000","0x400280007ff97fff","0x10780017fff7fff","0x98","0x4825800180007ffa","0x0","0x400280007ff97fff","0x482680017ff98000","0x1","0x48297ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0x10","0x40780017fff7fff","0x1","0x480680017fff8000","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x400080007ffe7fff","0x48127ffc7fff8000","0x48127ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x1104800180018000","0x1bb","0x482480017fff8000","0x1ba","0x480080007fff8000","0xa0680017fff8000","0x9","0x4824800180007ff8","0x65b8","0x482480017fff8000","0x100000000000000000000000000000000","0x400080007ff77fff","0x10780017fff7fff","0x63","0x4824800180007ff8","0x65b8","0x400080007ff87fff","0x480680017fff8000","0x0","0x480680017fff8000","0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1","0x482480017ff68000","0x1","0x480680017fff8000","0x53746f7261676552656164","0x400280007ffb7fff","0x400280017ffb7ffb","0x400280027ffb7ffc","0x400280037ffb7ffd","0x480280057ffb8000","0x20680017fff7fff","0x42","0x480280047ffb8000","0x480680017fff8000","0x0","0x480680017fff8000","0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a","0x480280067ffb8000","0x480680017fff8000","0x53746f7261676552656164","0x400280077ffb7fff","0x400280087ffb7ffb","0x400280097ffb7ffc","0x4002800a7ffb7ffd","0x4802800c7ffb8000","0x20680017fff7fff","0x2a","0x4802800b7ffb8000","0x480680017fff8000","0x0","0x480680017fff8000","0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181","0x4802800d7ffb8000","0x480680017fff8000","0x53746f7261676552656164","0x4002800e7ffb7fff","0x4002800f7ffb7ffb","0x400280107ffb7ffc","0x400280117ffb7ffd","0x480280137ffb8000","0x20680017fff7fff","0x14","0x40780017fff7fff","0x1","0x48127ff67fff8000","0x400080007ffe7fff","0x48127ffb7fff8000","0x400080017ffd7fff","0x480280147ffb8000","0x400080027ffc7fff","0x48127fed7fff8000","0x480280127ffb8000","0x482680017ffb8000","0x15","0x480680017fff8000","0x0","0x48127ff87fff8000","0x482480017ff78000","0x3","0x208b7fff7fff7ffe","0x480280127ffb8000","0x482680017ffb8000","0x16","0x480280147ffb8000","0x480280157ffb8000","0x10780017fff7fff","0x12","0x40780017fff7fff","0x6","0x4802800b7ffb8000","0x482680017ffb8000","0xf","0x4802800d7ffb8000","0x4802800e7ffb8000","0x10780017fff7fff","0x9","0x40780017fff7fff","0xc","0x480280047ffb8000","0x482680017ffb8000","0x8","0x480280067ffb8000","0x480280077ffb8000","0x48127fed7fff8000","0x48127ffb7fff8000","0x48127ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482480017ff58000","0x1","0x48127ff37fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482680017ff98000","0x1","0x480a7ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0xa0680017fff8000","0x7","0x482680017ffa8000","0x100000000000000000000000000000000","0x400280007ff97fff","0x10780017fff7fff","0x98","0x4825800180007ffa","0x0","0x400280007ff97fff","0x482680017ff98000","0x1","0x48297ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0x10","0x40780017fff7fff","0x1","0x480680017fff8000","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x400080007ffe7fff","0x48127ffc7fff8000","0x48127ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x1104800180018000","0x10f","0x482480017fff8000","0x10e","0x480080007fff8000","0xa0680017fff8000","0x9","0x4824800180007ff8","0x6680","0x482480017fff8000","0x100000000000000000000000000000000","0x400080007ff77fff","0x10780017fff7fff","0x63","0x4824800180007ff8","0x6680","0x400080007ff87fff","0x480680017fff8000","0x0","0x480680017fff8000","0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1","0x480680017fff8000","0x0","0x482480017ff58000","0x1","0x480680017fff8000","0x53746f726167655772697465","0x400280007ffb7fff","0x400280017ffb7ffa","0x400280027ffb7ffb","0x400280037ffb7ffc","0x400280047ffb7ffd","0x480280067ffb8000","0x20680017fff7fff","0x3f","0x480280057ffb8000","0x480680017fff8000","0x0","0x480680017fff8000","0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a","0x480680017fff8000","0x0","0x480680017fff8000","0x53746f726167655772697465","0x400280077ffb7fff","0x400280087ffb7ffb","0x400280097ffb7ffc","0x4002800a7ffb7ffd","0x4002800b7ffb7ffe","0x4802800d7ffb8000","0x20680017fff7fff","0x25","0x4802800c7ffb8000","0x480680017fff8000","0x0","0x480680017fff8000","0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181","0x480680017fff8000","0x0","0x480680017fff8000","0x53746f726167655772697465","0x4002800e7ffb7fff","0x4002800f7ffb7ffb","0x400280107ffb7ffc","0x400280117ffb7ffd","0x400280127ffb7ffe","0x480280147ffb8000","0x20680017fff7fff","0xd","0x40780017fff7fff","0x1","0x48127ff07fff8000","0x480280137ffb8000","0x482680017ffb8000","0x15","0x480680017fff8000","0x0","0x48127ffb7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x480280137ffb8000","0x482680017ffb8000","0x17","0x480280157ffb8000","0x480280167ffb8000","0x10780017fff7fff","0x12","0x40780017fff7fff","0x6","0x4802800c7ffb8000","0x482680017ffb8000","0x10","0x4802800e7ffb8000","0x4802800f7ffb8000","0x10780017fff7fff","0x9","0x40780017fff7fff","0xc","0x480280057ffb8000","0x482680017ffb8000","0x9","0x480280077ffb8000","0x480280087ffb8000","0x48127fed7fff8000","0x48127ffb7fff8000","0x48127ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482480017ff58000","0x1","0x48127ff37fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482680017ff98000","0x1","0x480a7ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x480680017fff8000","0x0","0x480680017fff8000","0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1","0x480680017fff8000","0x53746f726167655772697465","0x400280007ffa7fff","0x400380017ffa7ff9","0x400280027ffa7ffd","0x400280037ffa7ffe","0x400380047ffa7ffc","0x480280067ffa8000","0x20680017fff7fff","0x6b","0x480280057ffa8000","0x480680017fff8000","0x0","0x480680017fff8000","0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a","0x480680017fff8000","0x53746f726167655772697465","0x400280077ffa7fff","0x400280087ffa7ffc","0x400280097ffa7ffd","0x4002800a7ffa7ffe","0x4003800b7ffa7ffb","0x4802800d7ffa8000","0x20680017fff7fff","0x51","0x4802800c7ffa8000","0x480680017fff8000","0x0","0x480680017fff8000","0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181","0x480680017fff8000","0x53746f726167655772697465","0x4002800e7ffa7fff","0x4002800f7ffa7ffc","0x400280107ffa7ffd","0x400280117ffa7ffe","0x400380127ffa7ffd","0x480280147ffa8000","0x20680017fff7fff","0x37","0x40780017fff7fff","0x1","0x40780017fff7fff","0x1","0x480680017fff8000","0x0","0x480a7ffc7fff8000","0x480a7ffb7fff8000","0x480a7ffd7fff8000","0x480680017fff8000","0x281848a2ead29305005a1178671c6a7d7780cb656c57678566ea8033dbfa001","0x400080007ff97fff","0x400080007ffa7ffc","0x400080017ffa7ffd","0x400080027ffa7ffe","0x480280137ffa8000","0x48127ff87fff8000","0x482480017ff78000","0x1","0x48127ff77fff8000","0x482480017ff68000","0x3","0x480680017fff8000","0x456d69744576656e74","0x400280157ffa7fff","0x400280167ffa7ffa","0x400280177ffa7ffb","0x400280187ffa7ffc","0x400280197ffa7ffd","0x4002801a7ffa7ffe","0x4802801c7ffa8000","0x20680017fff7fff","0xd","0x480a7ff87fff8000","0x4802801b7ffa8000","0x482680017ffa8000","0x1d","0x480680017fff8000","0x0","0x480680017fff8000","0x0","0x480680017fff8000","0x0","0x208b7fff7fff7ffe","0x480a7ff87fff8000","0x4802801b7ffa8000","0x482680017ffa8000","0x1f","0x480680017fff8000","0x1","0x4802801d7ffa8000","0x4802801e7ffa8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0xe","0x480a7ff87fff8000","0x480280137ffa8000","0x482680017ffa8000","0x17","0x480680017fff8000","0x1","0x480280157ffa8000","0x480280167ffa8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x13","0x480a7ff87fff8000","0x4802800c7ffa8000","0x482680017ffa8000","0x10","0x480680017fff8000","0x1","0x4802800e7ffa8000","0x4802800f7ffa8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x18","0x480a7ff87fff8000","0x480280057ffa8000","0x482680017ffa8000","0x9","0x480680017fff8000","0x1","0x480280077ffa8000","0x480280087ffa8000","0x208b7fff7fff7ffe"],"bytecode_segment_lengths":[212,172,172,130],"hints":[[0,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x0"},"rhs":{"Deref":{"register":"FP","offset":-6}},"dst":{"register":"AP","offset":0}}}]],[80,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[99,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0xa370"},"rhs":{"Deref":{"register":"AP","offset":-22}},"dst":{"register":"AP","offset":0}}}]],[122,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[140,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[155,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[169,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[183,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[197,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[212,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x0"},"rhs":{"Deref":{"register":"FP","offset":-6}},"dst":{"register":"AP","offset":0}}}]],[229,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[248,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x65b8"},"rhs":{"Deref":{"register":"AP","offset":-7}},"dst":{"register":"AP","offset":0}}}]],[272,[{"SystemCall":{"system":{"Deref":{"register":"FP","offset":-5}}}}]],[287,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-5},"b":{"Immediate":"0x7"}}}}}]],[302,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-5},"b":{"Immediate":"0xe"}}}}}]],[305,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[354,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[369,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[384,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x0"},"rhs":{"Deref":{"register":"FP","offset":-6}},"dst":{"register":"AP","offset":0}}}]],[401,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[420,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x6680"},"rhs":{"Deref":{"register":"AP","offset":-7}},"dst":{"register":"AP","offset":0}}}]],[447,[{"SystemCall":{"system":{"Deref":{"register":"FP","offset":-5}}}}]],[464,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-5},"b":{"Immediate":"0x7"}}}}}]],[481,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-5},"b":{"Immediate":"0xe"}}}}}]],[484,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[526,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[541,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[567,[{"SystemCall":{"system":{"Deref":{"register":"FP","offset":-6}}}}]],[582,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-6},"b":{"Immediate":"0x7"}}}}}]],[597,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-6},"b":{"Immediate":"0xe"}}}}}]],[600,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[602,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[630,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-6},"b":{"Immediate":"0x15"}}}}}]]],"entry_points_by_type":{"EXTERNAL":[{"selector":"0x196a5f000a6df3bde4c611e5561aa002ac6cc04b4149c1f02f473b2ef445c76","offset":0,"builtins":["range_check"]},{"selector":"0x3593f537ca0121e22c58378d40e0f5e2ba89b1c6d92a6990ab3066b68088f9c","offset":212,"builtins":["range_check"]}],"L1_HANDLER":[],"CONSTRUCTOR":[{"selector":"0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194","offset":384,"builtins":["range_check"]}]}} \ No newline at end of file diff --git a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json new file mode 100644 index 000000000..299172666 --- /dev/null +++ b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json @@ -0,0 +1 @@ +{"sierra_program":["0x1","0x6","0x0","0x2","0x8","0x0","0xcb","0x35","0x21","0x52616e6765436865636b","0x800000000000000100000000000000000000000000000000","0x436f6e7374","0x800000000000000000000000000000000000000000000002","0x1","0x2","0x281848a2ead29305005a1178671c6a7d7780cb656c57678566ea8033dbfa001","0x66656c74323532","0x800000000000000700000000000000000000000000000000","0x537472756374","0x800000000000000700000000000000000000000000000004","0x0","0x325aa8c5392af856b0b76eb1e9c925ca4854a32ad80c458af6e005fb4b6c83f","0x456e756d","0x800000000000000700000000000000000000000000000002","0x191f49c01d9820fa9a814bc69ef6cc6a88af08a0a74fd50c7687dab2294b39d","0x3","0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3","0x8","0x753332","0x53746f7261676541646472657373","0x53746f726167654261736541646472657373","0x145cc613954179acf89d43c94ed0e091828cbddcca83f5b408785785036d36d","0xa","0x4661696c656420746f20646573657269616c697a6520706172616d202331","0x4661696c656420746f20646573657269616c697a6520706172616d202332","0x4661696c656420746f20646573657269616c697a6520706172616d202333","0x4f7574206f6620676173","0x4172726179","0x800000000000000300000000000000000000000000000001","0x536e617073686f74","0x800000000000000700000000000000000000000000000001","0x10","0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62","0x11","0x12","0x800000000000000f00000000000000000000000000000001","0x36a29999818984cbedaf89ff3c5e77aa63ec49bdb2cf356962e80a4ce228308","0x800000000000000f00000000000000000000000000000003","0x14","0x15","0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672","0x800000000000000300000000000000000000000000000003","0x17","0x9e3a3a7f22220fe7534a6b09e607514c317ae36494e57214a99c6b1b05c29a","0x16","0x18","0x4275696c74696e436f737473","0x53797374656d","0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6","0x13","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x800000000000000700000000000000000000000000000003","0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511","0x426f78","0x4761734275696c74696e","0x55","0x7265766f6b655f61705f747261636b696e67","0x77697468647261775f676173","0x6272616e63685f616c69676e","0x7374727563745f6465636f6e737472756374","0x656e61626c655f61705f747261636b696e67","0x73746f72655f74656d70","0x61727261795f736e617073686f745f706f705f66726f6e74","0x756e626f78","0x72656e616d65","0x656e756d5f696e6974","0x1e","0x6a756d70","0x7374727563745f636f6e737472756374","0x656e756d5f6d61746368","0x64697361626c655f61705f747261636b696e67","0x64726f70","0x1f","0x61727261795f6e6577","0x636f6e73745f61735f696d6d656469617465","0x1d","0x61727261795f617070656e64","0x1c","0x20","0x1b","0x6765745f6275696c74696e5f636f737473","0x1a","0x77697468647261775f6761735f616c6c","0x66756e6374696f6e5f63616c6c","0x19","0x736e617073686f745f74616b65","0xf","0xe","0xd","0xc","0x73746f726167655f626173655f616464726573735f636f6e7374","0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1","0xb","0x73746f726167655f616464726573735f66726f6d5f62617365","0x7","0x9","0x73746f726167655f726561645f73797363616c6c","0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a","0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181","0x6","0x5","0x73746f726167655f77726974655f73797363616c6c","0x647570","0x4","0x656d69745f6576656e745f73797363616c6c","0x243","0xffffffffffffffff","0xaf","0x9f","0x22","0x8e","0x2c","0x23","0x24","0x25","0x26","0x27","0x28","0x31","0x29","0x2a","0x2b","0x7c","0x2d","0x2e","0x47","0x2f","0x30","0x32","0x33","0x34","0x35","0x36","0x37","0x38","0x6b","0x39","0x3a","0x3b","0x3c","0x3d","0x3e","0x3f","0x40","0x64","0x41","0x42","0x43","0x44","0x45","0x46","0x48","0x49","0x4a","0x4b","0x4c","0x4d","0x4e","0x4f","0x50","0x51","0x52","0x53","0x54","0x56","0x57","0x58","0x59","0x5a","0x5b","0x5c","0x5d","0x5e","0x5f","0x60","0x61","0x62","0x63","0x65","0x66","0x142","0xd2","0x135","0x128","0x122","0x11b","0x12c","0x1ba","0x165","0x1ad","0x1a0","0x19b","0x196","0x1a4","0x236","0x229","0x21c","0x212","0xbd","0x150","0x1c8","0x13fd","0x60504031105100c0f0e0605060506050d0c0b0a0908070606050403020100","0x31805170c0f0a0916091509140c0613050403060506050605120c0b0a0c06","0x2105201f06051e1d1c06060504031b06060504031a06060504031906060504","0xc250a29052805120c270a120c250a260c250a2405120c0f0a2305220c0f0a","0x4032f053305320c2b0e023109302f052e052d0c2b0e21052c05120c2b0a2a","0xc3e2405053d0c3c0c3b0c3a3902380605203729050605360c350e34060605","0x454405053f2305053f0c06440506430605054206050541060505400c05053f","0x54b060505494a050549230505490c4844050547050644050643290505460c","0x5053f05064f0506432f0505462c0505460605054e0605053f4d05054c0605","0x5495605054711110555280505460c545305053f0c524f05053f5105053f50","0x505495805054c0c064f050643330505462405054621050549210505572e05","0x5495e0505575e0505465d06055c240505495b05054c5a05054c5905054c29","0x5c6306055c0c626105053f1305053f6005054c0c5f180505425e05053d5e05","0x5680c676605054c2105053f6505053d650505496505055765050546640605","0x5054c690505476905053f69050549690505570c0669050643110505460605","0x5495605053f0c06560506432e0505460c6a2405053f1105053d1105056805","0x60c6065066d6669066c06050c06050c0c6c050c0c0c6b0506560506432805","0x61305650c69056c056905660c0c6c050c690c13056c051105110c0c6c050c","0x610c5a056c055b05130c5b056c051805600c0c6c050c060c5e05591861066c","0xc060c0c33050c5b0c21056c0559055e0c58056c056105180c59056c055a05","0x524055e0c58056c055e05180c24056c052305590c23056c050c5a0c0c6c05","0x54d2e29066c065805650c0c6c050c060c28056e33056c062105580c21056c","0x53056c055605610c56056c052f05130c2f056c052e05600c0c6c050c060c2c","0xc5a0c0c6c050c060c0c6f050c5b0c4f056c0553055e0c51056c052905180c","0x5580c4f056c0544055e0c51056c052c05180c44056c054d05590c4d056c05","0x6c050c060c7205716f00066c065105650c0c6c050c060c5005704a056c064f","0x6c050005180c75056c057405610c74056c057305130c73056c056f05600c0c","0x590c79056c050c5a0c0c6c050c060c0c78050c5b0c77056c0575055e0c7605","0x7c7b056c067705580c77056c057a055e0c76056c057205180c7a056c057905","0x6c050c210c0c6c050c060c80057f7e7d066c067605650c0c6c050c060c7105","0x330c0c6c054a05330c0c6c057b05330c0c6c057e05240c0c6c057d05230c0c","0x81062c0c78056c0578052e0c78056c050c290c81056c050c280c0c6c053305","0x660c85056c058405530c84056c05828306560c83056c050c2f0c82056c0578","0x585056c0585054d0c06056c0506054f0c66056c056605510c69056c056905","0x6c0586054a0c86056c050c440c0c6c058005230c0c6c050c060c8506666969","0xc0c6c050c210c0c6c050c060c8b8a06898887066c0686666911500c8605","0x2e0c06056c0506054f0c88056c058805510c87056c058705660c8c056c050c","0x4a338c068887606f0c7b056c057b052e0c4a056c054a052e0c33056c053305","0x6c059105730c0c6c050c060c93059291056c069005720c908f8e8d696c057b","0x56c059605760c0c6c059505750c9695066c059405740c94056c050c280c0c","0x6c058e05510c8d056c058d05660c7f056c059805790c98056c059705770c97","0xc0c6c050c060c7f8f8e8d69057f056c057f054d0c8f056c058f054f0c8e05","0x8f056c058f054f0c8e056c058e05510c8d056c058d05660c99056c05930553","0x57b05330c0c6c050c210c0c6c050c060c998f8e8d690599056c0599054d0c","0xc9b056c050c7a0c9a056c050c280c0c6c053305330c0c6c054a05330c0c6c","0x56c059c9d06560c9d056c050c2f0c9c056c059b9a062c0c9b056c059b052e","0x6c0506054f0c8b056c058b05510c8a056c058a05660c9f056c059e05530c9e","0x57b0c0c6c050c210c0c6c050c060c9f068b8a69059f056c059f054d0c0605","0x56c050c280c0c6c053305330c0c6c054a05330c0c6c057605230c0c6c0571","0x56c050c2f0ca2056c05a1a0062c0ca1056c05a1052e0ca1056c050c710ca0","0x56605510c69056c056905660ca5056c05a405530ca4056c05a2a306560ca3","0xc6c050c060ca50666696905a5056c05a5054d0c06056c0506054f0c66056c","0x50c280c0c6c055105230c0c6c053305330c0c6c0550057b0c0c6c050c210c","0x50c2f0ca7056c05a639062c0ca6056c05a6052e0ca6056c050c7d0c39056c","0x5510c69056c056905660caa056c05a905530ca9056c05a7a806560ca8056c","0x50c060caa0666696905aa056c05aa054d0c06056c0506054f0c66056c0566","0x7e0cab056c050c280c0c6c055805230c0c6c0528057b0c0c6c050c210c0c6c","0x560cae056c050c2f0cad056c05acab062c0cac056c05ac052e0cac056c050c","0x66056c056605510c69056c056905660cb0056c05af05530caf056c05adae06","0x5800c0c6c050c060cb00666696905b0056c05b0054d0c06056c0506054f0c","0xb2b1062c0cb2056c05b2052e0cb2056c050c7a0cb1056c050c280c0c6c0511","0x5660cb5056c05b405530cb4056c05b39206560c92056c050c2f0cb3056c05","0x6905b5056c05b5054d0c06056c0506054f0c60056c056005510c65056c0565","0xc0c6c050c060c606506b66669066c06050c06050c0c6c050c0c0cb5066065","0x50c060c5e05b71861066c061305650c69056c056905660c13056c05110511","0xc5a056c050c290c5b056c050c280c0c6c051805240c0c6c056105230c0c6c","0x56c05595806560c58056c050c2f0c59056c055a5b062c0c5a056c055a052e","0x6c0506054f0c66056c056605510c69056c056905660c23056c052105530c21","0x440c0c6c055e05230c0c6c050c060c23066669690523056c0523054d0c0605","0xc060c2e2906b82833066c0624666911500c24056c0524054a0c24056c050c","0x5605830c5356066c052f05820c2f056c052c05780c2c056c050c810c0c6c05","0x50c870c4d056c054f05860c4f056c055105850c51056c055305840c0c6c05","0x6c053305660c4d056c054d058a0c44056c054405880c0c6c050c690c44056c","0x6c050c8c0c0c6c050c060c73726f11b900504a116c064d440628698b0c3305","0x57705840c0c6c057605830c7776066c057505820c75056c057405780c7405","0x54a05510c71056c050c870c7b056c057a05860c7a056c057905850c79056c","0x4a698b0c00056c0500052e0c7b056c057b058a0c71056c057105880c4a056c","0x8305780c83056c050c8d0c0c6c050c060c82788111ba807e7d116c067b7150","0x5850c87056c058605840c0c6c058505830c8685066c058405820c84056c05","0x5880c7d056c057d05510c8b056c050c870c8a056c058805860c88056c0587","0x116c068a8b7e7d698b0c80056c0580052e0c8a056c058a058a0c8b056c058b","0x118e0c93056c050c280c0c6c050c210c0c6c050c060c91908f11bb8e8d8c","0x9897116c059605910c0c6c059505900c9695066c0594058f0c94056c058e80","0x59805130c9a056c059993062c0c99056c0599052e0c99056c059705130c7f","0x52e0c9d056c057f05130c9c056c059b9a062c0c9b056c059b052e0c9b056c","0xc0c6c059f05750ca09f066c059e05740c9e056c059d9c062c0c9d056c059d","0x33056c053305660ca3056c05a205790ca2056c05a105770ca1056c05a00576","0xca38d8c336905a3056c05a3054d0c8d056c058d054f0c8c056c058c05510c","0x90054f0ca4056c058f05510c0c6c058005330c0c6c050005330c0c6c050c06","0xc6c050005330c0c6c050c060c0cbc050c5b0c39056c059105930ca5056c05","0xc0cbc050c5b0c39056c058205930ca5056c0578054f0ca4056c058105510c","0x210c39056c057305930ca5056c0572054f0ca4056c056f05510c0c6c050c06","0x5660ca8056c05a705530ca7056c0539a606560ca6056c050c2f0c0c6c050c","0x6905a8056c05a8054d0ca5056c05a5054f0ca4056c05a405510c33056c0533","0x56c05aa052e0caa056c050c7a0ca9056c050c280c0c6c050c060ca8a5a433","0x5ad05530cad056c05abac06560cac056c050c2f0cab056c05aaa9062c0caa","0xae054d0c06056c0506054f0c2e056c052e05510c29056c052905660cae056c","0xcaf056c050c280c0c6c051105800c0c6c050c060cae062e296905ae056c05","0xcb2056c050c2f0cb1056c05b0af062c0cb0056c05b0052e0cb0056c050c7a","0x56c056005510c65056c056505660c92056c05b305530cb3056c05b1b20656","0x50c0c6c050c0c0c92066065690592056c0592054d0c06056c0506054f0c60","0x56905660c13056c051105110c0c6c050c060c606506bd6669066c06050c06","0x5240c0c6c056105230c0c6c050c060c5e05be1861066c061305650c69056c","0x5a5b062c0c5a056c055a052e0c5a056c050c290c5b056c050c280c0c6c0518","0x5660c23056c052105530c21056c05595806560c58056c050c2f0c59056c05","0x690523056c0523054d0c06056c0506054f0c66056c056605510c69056c0569","0x56c0524054a0c24056c050c440c0c6c055e05230c0c6c050c060c23066669","0x860c2c056c050c810c0c6c050c060c2e2906bf2833066c0624666911500c24","0x55305880c0c6c050c690c53056c050c870c56056c050c940c2f056c052c05","0x2866950c33056c053305660c56056c0556052e0c2f056c052f058a0c53056c","0x5005860c50056c050c8c0c0c6c050c060c4a444d11c04f51066c06562f5306","0x57205880c51056c055105510c72056c050c870c6f056c050c940c00056c05","0x73066c066f00724f5166950c6f056c056f052e0c00056c0500058a0c72056c","0x50c940c7a056c057905860c79056c050c8d0c0c6c050c060c77767511c174","0x57a058a0c71056c057105880c73056c057305510c71056c050c870c7b056c","0x60c78818011c27e7d066c067b7a71747366950c7b056c057b052e0c7a056c","0x58305750c8483066c058205740c82056c050c280c0c6c050c210c0c6c050c","0x53305660c87056c058605790c86056c058505770c85056c058405760c0c6c","0x7d33690587056c0587054d0c7e056c057e054f0c7d056c057d05510c33056c","0x56c057805930c8a056c0581054f0c88056c058005510c0c6c050c060c877e","0x930c8a056c0576054f0c88056c057505510c0c6c050c060c0cc3050c5b0c8b","0x544054f0c88056c054d05510c0c6c050c060c0cc3050c5b0c8b056c057705","0x6c058b8c06560c8c056c050c2f0c0c6c050c210c8b056c054a05930c8a056c","0x58a054f0c88056c058805510c33056c053305660c8e056c058d05530c8d05","0xc8f056c050c280c0c6c050c060c8e8a883369058e056c058e054d0c8a056c","0xc93056c050c2f0c91056c05908f062c0c90056c0590052e0c90056c050c7a","0x56c052e05510c29056c052905660c95056c059405530c94056c0591930656","0x800c0c6c050c060c95062e29690595056c0595054d0c06056c0506054f0c2e","0x96062c0c97056c0597052e0c97056c050c7a0c96056c050c280c0c6c051105","0x660c9a056c059905530c99056c05987f06560c7f056c050c2f0c98056c0597","0x59a056c059a054d0c06056c0506054f0c60056c056005510c65056c056505","0x6605960c61056c050c870c13056c056005860c60056c050c810c9a06606569","0x6c06181361060566950c13056c0513058a0c61056c056105880c1866066c05","0x870c23056c052105860c21056c050c8c0c0c6c050c060c58595a11c45b5e06","0xc24056c052405880c5e056c055e05510c3369066c056905960c24056c050c","0xc6c050c060c2f2c2e11c52928066c063323245b5e66950c23056c0523058a","0x4f65066c056505960c51056c050c870c53056c055605860c56056c050c8d0c","0x5351292866950c53056c0553058a0c51056c055105880c28056c052805510c","0x72056c050c280c6f056c050c280c0c6c050c060c00504a11c6444d066c064f","0x7505990c7675066c0574057f0c74056c057305980c73056c0565696611970c","0x56c050c9c0c0c6c050c060c77056c0576059b0c76056c0576059a0c0c6c05","0x7b059e0c7b77066c0577059d0c7a056c05796f062c0c79056c0579052e0c79","0x62c0c80056c057105130c0c6c057e05330c0c6c057d05330c7e7d71116c05","0x6c058205330c848382116c0578059e0c7877066c0577059d0c81056c058072","0x6c0577059e0c86056c058581062c0c85056c058305130c0c6c058405330c0c","0x8b86062c0c8b056c058a05130c0c6c058805330c0c6c058705330c8a888711","0x750c908f066c058c05740c0c6c058d05750c8e8d066c057a05740c8c056c05","0x9f0c4d056c054d05510c93056c059005760c91056c058e05760c0c6c058f05","0x98979611c79594066c069391444d69a00c93056c0593059f0c91056c059105","0xc9a056c059905a20c99056c057f1106a10c7f056c050c5a0c0c6c050c060c","0x9a056c059a05a30c95056c0595054f0c94056c059405510c0c056c050c0566","0x989b06560c9b056c050c2f0c0c6c051105a40c0c6c050c060c9a95940c6905","0x54f0c96056c059605510c0c056c050c05660c9d056c059c05a50c9c056c05","0x6c051105a40c0c6c050c060c9d97960c69059d056c059d05a30c97056c0597","0x560c9e056c050c2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c","0x4a056c054a05510c0c056c050c05660ca0056c059f05a50c9f056c05009e06","0x5a40c0c6c050c060ca0504a0c6905a0056c05a005a30c50056c0550054f0c","0x56c050c2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c6c0511","0x52e05510c0c056c050c05660ca3056c05a205a50ca2056c052fa106560ca1","0xc6c050c060ca32c2e0c6905a3056c05a305a30c2c056c052c054f0c2e056c","0xc2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c6c051105a40c","0x510c0c056c050c05660c39056c05a505a50ca5056c0558a406560ca4056c05","0xc696939595a0c690539056c053905a30c59056c0559054f0c5a056c055a05","0x500c69c81106050c4f51500c692451500c690c1106050c4f51500c69245150","0x66691106050c5651500c690606062851500c60c91106050c4f51500c692451","0xca65"],"sierra_program_debug_info":{"type_names":[[0,"RangeCheck"],[1,"Const"],[2,"felt252"],[3,"temp_cairo::StateUpdateContract::LogStateUpdate"],[4,"temp_cairo::StateUpdateContract::Event"],[5,"Const"],[6,"Tuple"],[7,"Const"],[8,"u32"],[9,"StorageAddress"],[10,"StorageBaseAddress"],[11,"core::starknet::storage::StoragePointer0Offset::"],[12,"Const"],[13,"Const"],[14,"Const"],[15,"Const"],[16,"Array"],[17,"Snapshot>"],[18,"core::array::Span::"],[19,"Tuple>"],[20,"temp_cairo::StateUpdateContract::ContractState"],[21,"Unit"],[22,"Tuple"],[23,"core::panics::Panic"],[24,"Tuple>"],[25,"core::panics::PanicResult::<(temp_cairo::StateUpdateContract::ContractState, ())>"],[26,"BuiltinCosts"],[27,"System"],[28,"core::panics::PanicResult::<(core::array::Span::,)>"],[29,"Const"],[30,"core::option::Option::"],[31,"Box"],[32,"GasBuiltin"]],"libfunc_names":[[0,"revoke_ap_tracking"],[1,"withdraw_gas"],[2,"branch_align"],[3,"struct_deconstruct>"],[4,"enable_ap_tracking"],[5,"store_temp"],[6,"array_snapshot_pop_front"],[7,"unbox"],[8,"rename"],[9,"enum_init, 0>"],[10,"store_temp>>"],[11,"store_temp>"],[12,"jump"],[13,"struct_construct"],[14,"enum_init, 1>"],[15,"enum_match>"],[16,"disable_ap_tracking"],[17,"drop>>"],[18,"drop>"],[19,"drop"],[20,"array_new"],[21,"const_as_immediate>"],[22,"store_temp"],[23,"array_append"],[24,"struct_construct"],[25,"struct_construct>>"],[26,"enum_init,)>, 1>"],[27,"store_temp"],[28,"store_temp"],[29,"store_temp,)>>"],[30,"get_builtin_costs"],[31,"store_temp"],[32,"withdraw_gas_all"],[33,"struct_construct"],[34,"function_call"],[35,"enum_match>"],[36,"drop>"],[37,"snapshot_take>"],[38,"drop>"],[39,"struct_construct>"],[40,"struct_construct>>"],[41,"enum_init,)>, 0>"],[42,"const_as_immediate>"],[43,"drop"],[44,"const_as_immediate>"],[45,"const_as_immediate>"],[46,"const_as_immediate>"],[47,"drop>"],[48,"storage_base_address_const<289565229787362368933081636443797405535488074065834425092593015835915391953>"],[49,"struct_construct>"],[50,"snapshot_take>"],[51,"drop>"],[52,"struct_deconstruct>"],[53,"rename"],[54,"storage_address_from_base"],[55,"const_as_immediate>"],[56,"store_temp"],[57,"store_temp"],[58,"storage_read_syscall"],[59,"storage_base_address_const<1129664241071644691371073118594794953592340198277473102285062464307545102410>"],[60,"storage_base_address_const<1804974537427402286278400303388660593172206410421526189703894999503593972097>"],[61,"struct_construct>"],[62,"snapshot_take>"],[63,"drop>"],[64,"struct_deconstruct>"],[65,"store_temp>"],[66,"const_as_immediate>"],[67,"storage_write_syscall"],[68,"dup"],[69,"struct_construct"],[70,"enum_init"],[71,"snapshot_take"],[72,"drop"],[73,"store_temp"],[74,"enum_match"],[75,"const_as_immediate>"],[76,"dup"],[77,"struct_deconstruct"],[78,"store_temp>"],[79,"emit_event_syscall"],[80,"struct_construct>"],[81,"enum_init, 0>"],[82,"store_temp>"],[83,"drop"],[84,"enum_init, 1>"]],"user_func_names":[[0,"temp_cairo::StateUpdateContract::__wrapper__update_state"],[1,"temp_cairo::StateUpdateContract::__wrapper__get_state"],[2,"temp_cairo::StateUpdateContract::__wrapper__constructor"],[3,"temp_cairo::StateUpdateContract::update_state"]]},"contract_class_version":"0.1.0","entry_points_by_type":{"EXTERNAL":[{"selector":"0x196a5f000a6df3bde4c611e5561aa002ac6cc04b4149c1f02f473b2ef445c76","function_idx":0},{"selector":"0x3593f537ca0121e22c58378d40e0f5e2ba89b1c6d92a6990ab3066b68088f9c","function_idx":1}],"L1_HANDLER":[],"CONSTRUCTOR":[{"selector":"0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194","function_idx":2}]},"abi":[{"type":"constructor","name":"constructor","inputs":[]},{"type":"function","name":"update_state","inputs":[{"name":"block_number","type":"core::felt252"},{"name":"state_root","type":"core::felt252"},{"name":"block_hash","type":"core::felt252"}],"outputs":[],"state_mutability":"external"},{"type":"function","name":"get_state","inputs":[],"outputs":[{"type":"(core::felt252, core::felt252, core::felt252)"}],"state_mutability":"view"},{"type":"event","name":"temp_cairo::StateUpdateContract::LogStateUpdate","kind":"struct","members":[{"name":"state_root","type":"core::felt252","kind":"data"},{"name":"block_number","type":"core::felt252","kind":"data"},{"name":"block_hash","type":"core::felt252","kind":"data"}]},{"type":"event","name":"temp_cairo::StateUpdateContract::Event","kind":"enum","variants":[{"name":"LogStateUpdate","type":"temp_cairo::StateUpdateContract::LogStateUpdate","kind":"nested"}]}]} \ No newline at end of file diff --git a/crates/client/settlement_client/src/starknet/utils.rs b/crates/client/settlement_client/src/starknet/utils.rs new file mode 100644 index 000000000..3c2c90a03 --- /dev/null +++ b/crates/client/settlement_client/src/starknet/utils.rs @@ -0,0 +1,210 @@ +use crate::state_update::StateUpdate; +use assert_matches::assert_matches; +use starknet_accounts::{Account, ConnectedAccount, ExecutionEncoding, SingleOwnerAccount}; +use starknet_core::types::contract::SierraClass; +use starknet_core::types::{BlockId, BlockTag, Call, TransactionReceipt, TransactionReceiptWithBlockInfo}; +use starknet_core::utils::get_selector_from_name; +use starknet_providers::jsonrpc::HttpTransport; +use starknet_providers::{JsonRpcClient, Provider, ProviderError}; +use starknet_signers::{LocalWallet, SigningKey}; +use starknet_types_core::felt::Felt; +use std::future::Future; +use std::net::TcpStream; +use std::path::PathBuf; +use std::process::{Child, Command}; +use std::str::FromStr; +use std::sync::Arc; +use std::thread; + +use std::time::Duration; +use url::Url; + +pub const DEPLOYER_ADDRESS: &str = "0x055be462e718c4166d656d11f89e341115b8bc82389c3762a10eade04fcb225d"; +pub const DEPLOYER_PRIVATE_KEY: &str = "0x077e56c6dc32d40a67f6f7e6625c8dc5e570abe49c0a24e9202e4ae906abcc07"; +pub const UDC_ADDRESS: &str = "0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf"; +pub const MADARA_PORT: &str = "19944"; +pub const MADARA_BINARY_PATH: &str = "../../../test-artifacts/madara"; +pub const MADARA_CONFIG_PATH: &str = "../../../test-artifacts/devnet.yaml"; +pub const APPCHAIN_CONTRACT_SIERRA_PATH: &str = "src/starknet/test_contracts/appchain_test.sierra.json"; + +// starkli class-hash crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json +pub const APPCHAIN_CONTRACT_CASM_HASH: &str = "0x07f36e830605ddeb7c4c094639b628de297cbf61f45385b1fc3231029922b30b"; + +pub type StarknetAccount = SingleOwnerAccount, LocalWallet>; +pub type TransactionReceiptResult = Result; + +pub struct MadaraProcess { + pub process: Child, + #[allow(dead_code)] + pub binary_path: PathBuf, +} + +impl MadaraProcess { + pub fn new(binary_path: PathBuf) -> Result { + let process = Command::new(&binary_path) + .arg("--name") + .arg("madara") + .arg("--base-path") + .arg("../madara-db33") + .arg("--rpc-port") + .arg(MADARA_PORT) + .arg("--rpc-cors") + .arg("*") + .arg("--rpc-external") + .arg("--devnet") + .arg("--chain-config-path") + .arg(MADARA_CONFIG_PATH) + .arg("--feeder-gateway-enable") + .arg("--gateway-enable") + .arg("--gateway-external") + .arg("--gateway-port") + .arg("8080") + .arg("--no-l1-sync") + .spawn()?; + + wait_for_port(MADARA_PORT.parse().unwrap(), 2, 10); + + Ok(Self { process, binary_path }) + } +} + +impl Drop for MadaraProcess { + fn drop(&mut self) { + if let Err(e) = self.process.kill() { + eprintln!("Failed to kill Madara process: {}", e); + } else { + Command::new("rm").arg("-rf").arg("../madara-db33").status().expect("Failed to delete the madara db"); + println!("Madara process killed successfully"); + } + } +} + +pub async fn prepare_starknet_client_test() -> anyhow::Result<(StarknetAccount, Felt, MadaraProcess)> { + let madara = MadaraProcess::new(PathBuf::from(MADARA_BINARY_PATH))?; + let account = starknet_account()?; + let deployed_appchain_contract_address = deploy_contract(&account).await?; + Ok((account, deployed_appchain_contract_address, madara)) +} + +pub async fn send_state_update( + account: &StarknetAccount, + appchain_contract_address: Felt, + update: StateUpdate, +) -> anyhow::Result { + let call = account + .execute_v1(vec![Call { + to: appchain_contract_address, + selector: get_selector_from_name("update_state")?, + calldata: vec![Felt::from(update.block_number), update.global_root, update.block_hash], + }]) + .send() + .await?; + let receipt = get_transaction_receipt(account.provider(), call.transaction_hash).await?; + + let latest_block_number_recorded = account.provider().block_number().await?; + + match receipt.block.block_number() { + Some(block_number) => Ok(block_number), + None => Ok(latest_block_number_recorded + 1), + } +} + +pub fn starknet_account() -> anyhow::Result { + let provider = + JsonRpcClient::new(HttpTransport::new(Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?)); + let signer = LocalWallet::from(SigningKey::from_secret_scalar(Felt::from_str(DEPLOYER_PRIVATE_KEY)?)); + let mut account = SingleOwnerAccount::new( + provider, + signer, + Felt::from_str(DEPLOYER_ADDRESS)?, + // MADARA_DEVNET + Felt::from_str("0x4D41444152415F4445564E4554")?, + ExecutionEncoding::New, + ); + account.set_block_id(BlockId::Tag(BlockTag::Pending)); + Ok(account) +} + +pub async fn deploy_contract(account: &StarknetAccount) -> anyhow::Result { + let contract_artifact: SierraClass = serde_json::from_reader(std::fs::File::open(APPCHAIN_CONTRACT_SIERRA_PATH)?)?; + let flattened_class = contract_artifact.flatten()?; + let result = + account.declare_v2(Arc::new(flattened_class), Felt::from_str(APPCHAIN_CONTRACT_CASM_HASH)?).send().await?; + tokio::time::sleep(Duration::from_secs(5)).await; + let deployment = account + .execute_v3(vec![Call { + to: Felt::from_str(UDC_ADDRESS)?, + selector: get_selector_from_name("deployContract")?, + calldata: vec![result.class_hash, Felt::ZERO, Felt::ZERO, Felt::ZERO], + }]) + .send() + .await?; + let deployed_contract_address = + get_deployed_contract_address(deployment.transaction_hash, account.provider()).await?; + tokio::time::sleep(Duration::from_secs(5)).await; + Ok(deployed_contract_address) +} + +pub async fn get_deployed_contract_address( + txn_hash: Felt, + provider: &JsonRpcClient, +) -> anyhow::Result { + let deploy_tx_receipt = get_transaction_receipt(provider, txn_hash).await?; + let contract_address = assert_matches!( + deploy_tx_receipt, + TransactionReceiptWithBlockInfo { receipt: TransactionReceipt::Invoke(receipt), .. } => { + receipt.events.iter().find(|e| e.keys[0] == get_selector_from_name("ContractDeployed").unwrap()).unwrap().data[0] + } + ); + Ok(contract_address) +} + +pub async fn get_transaction_receipt( + rpc: &JsonRpcClient, + transaction_hash: Felt, +) -> TransactionReceiptResult { + // there is a delay between the transaction being available at the client + // and the sealing of the block, hence sleeping for 500ms + assert_poll(|| async { rpc.get_transaction_receipt(transaction_hash).await.is_ok() }, 500, 20).await; + rpc.get_transaction_receipt(transaction_hash).await +} + +pub async fn assert_poll(f: F, polling_time_ms: u64, max_poll_count: u32) +where + F: Fn() -> Fut, + Fut: Future, +{ + for _poll_count in 0..max_poll_count { + if f().await { + return; + } + tokio::time::sleep(Duration::from_millis(polling_time_ms)).await; + } + panic!("Max poll count exceeded."); +} + +fn wait_for_port(port: u16, timeout_secs: u64, max_retries: u32) -> bool { + let mut attempts = 0; + println!("Waiting for port {} to be available...", port); + + while attempts < max_retries { + if check_port(port, timeout_secs) { + println!("Port {} is now available! (attempt {}/{})", port, attempts + 1, max_retries); + return true; + } + + attempts += 1; + if attempts < max_retries { + println!("Port {} not available, retrying... (attempt {}/{})", port, attempts, max_retries); + thread::sleep(Duration::from_secs(timeout_secs)); + } + } + + println!("Port {} not available after {} attempts", port, max_retries); + false +} + +fn check_port(port: u16, timeout_secs: u64) -> bool { + TcpStream::connect_timeout(&std::net::SocketAddr::from(([127, 0, 0, 1], port)), Duration::from_secs(timeout_secs)) + .is_ok() +} diff --git a/test-artifacts/devnet.yaml b/test-artifacts/devnet.yaml new file mode 100644 index 000000000..8cb18c3fe --- /dev/null +++ b/test-artifacts/devnet.yaml @@ -0,0 +1,34 @@ +chain_name: "Madara" +chain_id: "MADARA_DEVNET" +feeder_gateway_url: "http://localhost:8080/feeder_gateway/" +gateway_url: "http://localhost:8080/gateway/" +native_fee_token_address: "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d" +parent_fee_token_address: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" +latest_protocol_version: "0.13.2" +block_time: "5s" +pending_block_update_time: "1s" +execution_batch_size: 16 +bouncer_config: + block_max_capacity: + builtin_count: + add_mod: 18446744073709551615 + bitwise: 18446744073709551615 + ecdsa: 18446744073709551615 + ec_op: 18446744073709551615 + keccak: 18446744073709551615 + mul_mod: 18446744073709551615 + pedersen: 18446744073709551615 + poseidon: 18446744073709551615 + range_check: 18446744073709551615 + range_check96: 18446744073709551615 + gas: 5000000 + n_steps: 40000000 + message_segment_length: 18446744073709551615 + n_events: 18446744073709551615 + state_diff_size: 131072 +sequencer_address: "0x123" +eth_core_contract_address: "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512" +eth_gps_statement_verifier: "0xf294781D719D2F4169cE54469C28908E6FA752C1" +mempool_tx_limit: 10000 +mempool_declare_tx_limit: 20 +mempool_tx_max_age: null From 0d6168e5cd76d6eb337695246c65609b921c2c5c Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Fri, 20 Dec 2024 22:00:56 +0530 Subject: [PATCH 04/23] changelog update --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4fcaf2a6..52e36c6e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next release +- feat : l3 support - fix(block_production): continue pending block now reexecutes the previous transactions - feat(services): reworked Madara services for better cancellation control - feat: fetch eth/strk price and sync strk gas price From 75229a4422ffff7a35b00ea1963ad0e7f183d47a Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Fri, 20 Dec 2024 22:04:37 +0530 Subject: [PATCH 05/23] fix : lint --- .github/workflows/coverage.yml | 5 + cairo/README.md | 2 +- crates/client/settlement_client/Cargo.toml | 10 +- .../test_contracts/appchain_test.casm.json | 949 +++++++++++++++++- .../test_contracts/appchain_test.sierra.json | 660 +++++++++++- crates/node/Cargo.toml | 2 +- tests/js_tests/basic.test.ts | 34 +- tests/js_tests/utils.ts | 18 +- 8 files changed, 1646 insertions(+), 34 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 418fb07d3..1ce542892 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -39,6 +39,11 @@ jobs: with: version: nightly + - name: Download madara binary for l2 client testing + run: | + curl -L https://madara-test-binary.s3.us-west-1.amazonaws.com/madara -o ./test-artifacts/madara + chmod +x ./test-artifacts/madara + - name: Build and run tests env: ETH_FORK_URL: ${{ secrets.ETH_FORK_URL }} diff --git a/cairo/README.md b/cairo/README.md index 8f46c5a50..e94190c07 100644 --- a/cairo/README.md +++ b/cairo/README.md @@ -3,5 +3,5 @@ These contracts are used for the genesis block in devnet mode. For real world use, the [madara bootstrapper] is used instead. We use [OpenZeppelin] contracts. -[OpenZeppelin]: https://docs.openzeppelin.com +[openzeppelin]: https://docs.openzeppelin.com [madara bootstrapper]: https://github.com/madara-alliance/madara-bootstrapper diff --git a/crates/client/settlement_client/Cargo.toml b/crates/client/settlement_client/Cargo.toml index 7123e4b9b..df739b808 100644 --- a/crates/client/settlement_client/Cargo.toml +++ b/crates/client/settlement_client/Cargo.toml @@ -33,9 +33,9 @@ starknet_api.workspace = true # Other -assert_matches = "1.5.0" alloy.workspace = true anyhow.workspace = true +assert_matches = "1.5.0" bigdecimal.workspace = true bitvec.workspace = true futures = { workspace = true, default-features = true } @@ -43,11 +43,11 @@ futures = { workspace = true, default-features = true } regex = "1.10.5" serde = { workspace = true, default-features = true } serde_json = "1" -starknet-providers = { workspace = true } -starknet-core = { workspace = true } starknet-accounts = "0.11.0" -starknet-signers = { workspace = true } starknet-contract = "0.11.0" +starknet-core = { workspace = true } +starknet-providers = { workspace = true } +starknet-signers = { workspace = true } thiserror.workspace = true time = "0.3.36" tokio = { workspace = true, features = [ @@ -60,6 +60,7 @@ url.workspace = true #Instrumentation +async-trait = { workspace = true } opentelemetry = { workspace = true, features = ["metrics", "logs"] } opentelemetry-appender-tracing = { workspace = true, default-features = false } opentelemetry-otlp = { workspace = true, features = [ @@ -74,7 +75,6 @@ tracing = { workspace = true } tracing-core = { workspace = true, default-features = false } tracing-opentelemetry = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } -async-trait = { workspace = true } [features] diff --git a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json index c613f4cff..c71143f0f 100644 --- a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json +++ b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json @@ -1 +1,948 @@ -{"prime":"0x800000000000011000000000000000000000000000000000000000000000001","compiler_version":"2.8.0","bytecode":["0xa0680017fff8000","0x7","0x482680017ffa8000","0x100000000000000000000000000000000","0x400280007ff97fff","0x10780017fff7fff","0xc0","0x4825800180007ffa","0x0","0x400280007ff97fff","0x482680017ff98000","0x1","0x48297ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0xa","0x482680017ffc8000","0x1","0x480a7ffd7fff8000","0x480680017fff8000","0x0","0x480280007ffc8000","0x10780017fff7fff","0x8","0x480a7ffc7fff8000","0x480a7ffd7fff8000","0x480680017fff8000","0x1","0x480680017fff8000","0x0","0x20680017fff7ffe","0x98","0x48307ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0xa","0x482480017ffb8000","0x1","0x48127ffb7fff8000","0x480680017fff8000","0x0","0x480080007ff88000","0x10780017fff7fff","0x8","0x48127ffb7fff8000","0x48127ffb7fff8000","0x480680017fff8000","0x1","0x480680017fff8000","0x0","0x20680017fff7ffe","0x75","0x48307ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0xa","0x482480017ffb8000","0x1","0x48127ffb7fff8000","0x480680017fff8000","0x0","0x480080007ff88000","0x10780017fff7fff","0x8","0x48127ffb7fff8000","0x48127ffb7fff8000","0x480680017fff8000","0x1","0x480680017fff8000","0x0","0x20680017fff7ffe","0x52","0x48307ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0x10","0x40780017fff7fff","0x1","0x480680017fff8000","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x400080007ffe7fff","0x48127fed7fff8000","0x48127feb7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x1104800180018000","0x250","0x482480017fff8000","0x24f","0x480080007fff8000","0xa0680017fff8000","0x9","0x4824800180007fe9","0xa370","0x482480017fff8000","0x100000000000000000000000000000000","0x400080007fe87fff","0x10780017fff7fff","0x22","0x4824800180007fe9","0xa370","0x400080007fe97fff","0x482480017fe98000","0x1","0x48127ffe7fff8000","0x480a7ffb7fff8000","0x48127feb7fff8000","0x48127fef7fff8000","0x48127ff37fff8000","0x1104800180018000","0x1b6","0x20680017fff7ffd","0xc","0x40780017fff7fff","0x1","0x48127ff97fff8000","0x48127ff97fff8000","0x48127ff97fff8000","0x480680017fff8000","0x0","0x48127ffb7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x48127ffa7fff8000","0x48127ffa7fff8000","0x48127ffa7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482480017fe68000","0x1","0x48127fe47fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4661696c656420746f20646573657269616c697a6520706172616d202333","0x400080007ffe7fff","0x48127fee7fff8000","0x48127fec7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4661696c656420746f20646573657269616c697a6520706172616d202332","0x400080007ffe7fff","0x48127ff37fff8000","0x48127ff17fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4661696c656420746f20646573657269616c697a6520706172616d202331","0x400080007ffe7fff","0x48127ff87fff8000","0x48127ff67fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482680017ff98000","0x1","0x480a7ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0xa0680017fff8000","0x7","0x482680017ffa8000","0x100000000000000000000000000000000","0x400280007ff97fff","0x10780017fff7fff","0x98","0x4825800180007ffa","0x0","0x400280007ff97fff","0x482680017ff98000","0x1","0x48297ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0x10","0x40780017fff7fff","0x1","0x480680017fff8000","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x400080007ffe7fff","0x48127ffc7fff8000","0x48127ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x1104800180018000","0x1bb","0x482480017fff8000","0x1ba","0x480080007fff8000","0xa0680017fff8000","0x9","0x4824800180007ff8","0x65b8","0x482480017fff8000","0x100000000000000000000000000000000","0x400080007ff77fff","0x10780017fff7fff","0x63","0x4824800180007ff8","0x65b8","0x400080007ff87fff","0x480680017fff8000","0x0","0x480680017fff8000","0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1","0x482480017ff68000","0x1","0x480680017fff8000","0x53746f7261676552656164","0x400280007ffb7fff","0x400280017ffb7ffb","0x400280027ffb7ffc","0x400280037ffb7ffd","0x480280057ffb8000","0x20680017fff7fff","0x42","0x480280047ffb8000","0x480680017fff8000","0x0","0x480680017fff8000","0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a","0x480280067ffb8000","0x480680017fff8000","0x53746f7261676552656164","0x400280077ffb7fff","0x400280087ffb7ffb","0x400280097ffb7ffc","0x4002800a7ffb7ffd","0x4802800c7ffb8000","0x20680017fff7fff","0x2a","0x4802800b7ffb8000","0x480680017fff8000","0x0","0x480680017fff8000","0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181","0x4802800d7ffb8000","0x480680017fff8000","0x53746f7261676552656164","0x4002800e7ffb7fff","0x4002800f7ffb7ffb","0x400280107ffb7ffc","0x400280117ffb7ffd","0x480280137ffb8000","0x20680017fff7fff","0x14","0x40780017fff7fff","0x1","0x48127ff67fff8000","0x400080007ffe7fff","0x48127ffb7fff8000","0x400080017ffd7fff","0x480280147ffb8000","0x400080027ffc7fff","0x48127fed7fff8000","0x480280127ffb8000","0x482680017ffb8000","0x15","0x480680017fff8000","0x0","0x48127ff87fff8000","0x482480017ff78000","0x3","0x208b7fff7fff7ffe","0x480280127ffb8000","0x482680017ffb8000","0x16","0x480280147ffb8000","0x480280157ffb8000","0x10780017fff7fff","0x12","0x40780017fff7fff","0x6","0x4802800b7ffb8000","0x482680017ffb8000","0xf","0x4802800d7ffb8000","0x4802800e7ffb8000","0x10780017fff7fff","0x9","0x40780017fff7fff","0xc","0x480280047ffb8000","0x482680017ffb8000","0x8","0x480280067ffb8000","0x480280077ffb8000","0x48127fed7fff8000","0x48127ffb7fff8000","0x48127ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482480017ff58000","0x1","0x48127ff37fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482680017ff98000","0x1","0x480a7ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0xa0680017fff8000","0x7","0x482680017ffa8000","0x100000000000000000000000000000000","0x400280007ff97fff","0x10780017fff7fff","0x98","0x4825800180007ffa","0x0","0x400280007ff97fff","0x482680017ff98000","0x1","0x48297ffc80007ffd","0x20680017fff7fff","0x4","0x10780017fff7fff","0x10","0x40780017fff7fff","0x1","0x480680017fff8000","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x400080007ffe7fff","0x48127ffc7fff8000","0x48127ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x1104800180018000","0x10f","0x482480017fff8000","0x10e","0x480080007fff8000","0xa0680017fff8000","0x9","0x4824800180007ff8","0x6680","0x482480017fff8000","0x100000000000000000000000000000000","0x400080007ff77fff","0x10780017fff7fff","0x63","0x4824800180007ff8","0x6680","0x400080007ff87fff","0x480680017fff8000","0x0","0x480680017fff8000","0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1","0x480680017fff8000","0x0","0x482480017ff58000","0x1","0x480680017fff8000","0x53746f726167655772697465","0x400280007ffb7fff","0x400280017ffb7ffa","0x400280027ffb7ffb","0x400280037ffb7ffc","0x400280047ffb7ffd","0x480280067ffb8000","0x20680017fff7fff","0x3f","0x480280057ffb8000","0x480680017fff8000","0x0","0x480680017fff8000","0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a","0x480680017fff8000","0x0","0x480680017fff8000","0x53746f726167655772697465","0x400280077ffb7fff","0x400280087ffb7ffb","0x400280097ffb7ffc","0x4002800a7ffb7ffd","0x4002800b7ffb7ffe","0x4802800d7ffb8000","0x20680017fff7fff","0x25","0x4802800c7ffb8000","0x480680017fff8000","0x0","0x480680017fff8000","0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181","0x480680017fff8000","0x0","0x480680017fff8000","0x53746f726167655772697465","0x4002800e7ffb7fff","0x4002800f7ffb7ffb","0x400280107ffb7ffc","0x400280117ffb7ffd","0x400280127ffb7ffe","0x480280147ffb8000","0x20680017fff7fff","0xd","0x40780017fff7fff","0x1","0x48127ff07fff8000","0x480280137ffb8000","0x482680017ffb8000","0x15","0x480680017fff8000","0x0","0x48127ffb7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x480280137ffb8000","0x482680017ffb8000","0x17","0x480280157ffb8000","0x480280167ffb8000","0x10780017fff7fff","0x12","0x40780017fff7fff","0x6","0x4802800c7ffb8000","0x482680017ffb8000","0x10","0x4802800e7ffb8000","0x4802800f7ffb8000","0x10780017fff7fff","0x9","0x40780017fff7fff","0xc","0x480280057ffb8000","0x482680017ffb8000","0x9","0x480280077ffb8000","0x480280087ffb8000","0x48127fed7fff8000","0x48127ffb7fff8000","0x48127ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x48127ffa7fff8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482480017ff58000","0x1","0x48127ff37fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x40780017fff7fff","0x1","0x480680017fff8000","0x4f7574206f6620676173","0x400080007ffe7fff","0x482680017ff98000","0x1","0x480a7ffa7fff8000","0x480a7ffb7fff8000","0x480680017fff8000","0x1","0x48127ffa7fff8000","0x482480017ff98000","0x1","0x208b7fff7fff7ffe","0x480680017fff8000","0x0","0x480680017fff8000","0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1","0x480680017fff8000","0x53746f726167655772697465","0x400280007ffa7fff","0x400380017ffa7ff9","0x400280027ffa7ffd","0x400280037ffa7ffe","0x400380047ffa7ffc","0x480280067ffa8000","0x20680017fff7fff","0x6b","0x480280057ffa8000","0x480680017fff8000","0x0","0x480680017fff8000","0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a","0x480680017fff8000","0x53746f726167655772697465","0x400280077ffa7fff","0x400280087ffa7ffc","0x400280097ffa7ffd","0x4002800a7ffa7ffe","0x4003800b7ffa7ffb","0x4802800d7ffa8000","0x20680017fff7fff","0x51","0x4802800c7ffa8000","0x480680017fff8000","0x0","0x480680017fff8000","0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181","0x480680017fff8000","0x53746f726167655772697465","0x4002800e7ffa7fff","0x4002800f7ffa7ffc","0x400280107ffa7ffd","0x400280117ffa7ffe","0x400380127ffa7ffd","0x480280147ffa8000","0x20680017fff7fff","0x37","0x40780017fff7fff","0x1","0x40780017fff7fff","0x1","0x480680017fff8000","0x0","0x480a7ffc7fff8000","0x480a7ffb7fff8000","0x480a7ffd7fff8000","0x480680017fff8000","0x281848a2ead29305005a1178671c6a7d7780cb656c57678566ea8033dbfa001","0x400080007ff97fff","0x400080007ffa7ffc","0x400080017ffa7ffd","0x400080027ffa7ffe","0x480280137ffa8000","0x48127ff87fff8000","0x482480017ff78000","0x1","0x48127ff77fff8000","0x482480017ff68000","0x3","0x480680017fff8000","0x456d69744576656e74","0x400280157ffa7fff","0x400280167ffa7ffa","0x400280177ffa7ffb","0x400280187ffa7ffc","0x400280197ffa7ffd","0x4002801a7ffa7ffe","0x4802801c7ffa8000","0x20680017fff7fff","0xd","0x480a7ff87fff8000","0x4802801b7ffa8000","0x482680017ffa8000","0x1d","0x480680017fff8000","0x0","0x480680017fff8000","0x0","0x480680017fff8000","0x0","0x208b7fff7fff7ffe","0x480a7ff87fff8000","0x4802801b7ffa8000","0x482680017ffa8000","0x1f","0x480680017fff8000","0x1","0x4802801d7ffa8000","0x4802801e7ffa8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0xe","0x480a7ff87fff8000","0x480280137ffa8000","0x482680017ffa8000","0x17","0x480680017fff8000","0x1","0x480280157ffa8000","0x480280167ffa8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x13","0x480a7ff87fff8000","0x4802800c7ffa8000","0x482680017ffa8000","0x10","0x480680017fff8000","0x1","0x4802800e7ffa8000","0x4802800f7ffa8000","0x208b7fff7fff7ffe","0x40780017fff7fff","0x18","0x480a7ff87fff8000","0x480280057ffa8000","0x482680017ffa8000","0x9","0x480680017fff8000","0x1","0x480280077ffa8000","0x480280087ffa8000","0x208b7fff7fff7ffe"],"bytecode_segment_lengths":[212,172,172,130],"hints":[[0,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x0"},"rhs":{"Deref":{"register":"FP","offset":-6}},"dst":{"register":"AP","offset":0}}}]],[80,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[99,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0xa370"},"rhs":{"Deref":{"register":"AP","offset":-22}},"dst":{"register":"AP","offset":0}}}]],[122,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[140,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[155,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[169,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[183,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[197,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[212,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x0"},"rhs":{"Deref":{"register":"FP","offset":-6}},"dst":{"register":"AP","offset":0}}}]],[229,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[248,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x65b8"},"rhs":{"Deref":{"register":"AP","offset":-7}},"dst":{"register":"AP","offset":0}}}]],[272,[{"SystemCall":{"system":{"Deref":{"register":"FP","offset":-5}}}}]],[287,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-5},"b":{"Immediate":"0x7"}}}}}]],[302,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-5},"b":{"Immediate":"0xe"}}}}}]],[305,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[354,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[369,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[384,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x0"},"rhs":{"Deref":{"register":"FP","offset":-6}},"dst":{"register":"AP","offset":0}}}]],[401,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[420,[{"TestLessThanOrEqual":{"lhs":{"Immediate":"0x6680"},"rhs":{"Deref":{"register":"AP","offset":-7}},"dst":{"register":"AP","offset":0}}}]],[447,[{"SystemCall":{"system":{"Deref":{"register":"FP","offset":-5}}}}]],[464,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-5},"b":{"Immediate":"0x7"}}}}}]],[481,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-5},"b":{"Immediate":"0xe"}}}}}]],[484,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[526,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[541,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[567,[{"SystemCall":{"system":{"Deref":{"register":"FP","offset":-6}}}}]],[582,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-6},"b":{"Immediate":"0x7"}}}}}]],[597,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-6},"b":{"Immediate":"0xe"}}}}}]],[600,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[602,[{"AllocSegment":{"dst":{"register":"AP","offset":0}}}]],[630,[{"SystemCall":{"system":{"BinOp":{"op":"Add","a":{"register":"FP","offset":-6},"b":{"Immediate":"0x15"}}}}}]]],"entry_points_by_type":{"EXTERNAL":[{"selector":"0x196a5f000a6df3bde4c611e5561aa002ac6cc04b4149c1f02f473b2ef445c76","offset":0,"builtins":["range_check"]},{"selector":"0x3593f537ca0121e22c58378d40e0f5e2ba89b1c6d92a6990ab3066b68088f9c","offset":212,"builtins":["range_check"]}],"L1_HANDLER":[],"CONSTRUCTOR":[{"selector":"0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194","offset":384,"builtins":["range_check"]}]}} \ No newline at end of file +{ + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "compiler_version": "2.8.0", + "bytecode": [ + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0xc0", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x482680017ff98000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x480280007ffc8000", + "0x10780017fff7fff", + "0x8", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x98", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffb8000", + "0x1", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff88000", + "0x10780017fff7fff", + "0x8", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x75", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffb8000", + "0x1", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480080007ff88000", + "0x10780017fff7fff", + "0x8", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x52", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x10", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127fed7fff8000", + "0x48127feb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x250", + "0x482480017fff8000", + "0x24f", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007fe9", + "0xa370", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007fe87fff", + "0x10780017fff7fff", + "0x22", + "0x4824800180007fe9", + "0xa370", + "0x400080007fe97fff", + "0x482480017fe98000", + "0x1", + "0x48127ffe7fff8000", + "0x480a7ffb7fff8000", + "0x48127feb7fff8000", + "0x48127fef7fff8000", + "0x48127ff37fff8000", + "0x1104800180018000", + "0x1b6", + "0x20680017fff7ffd", + "0xc", + "0x40780017fff7fff", + "0x1", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017fe68000", + "0x1", + "0x48127fe47fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x400080007ffe7fff", + "0x48127fee7fff8000", + "0x48127fec7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x400080007ffe7fff", + "0x48127ff37fff8000", + "0x48127ff17fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x400080007ffe7fff", + "0x48127ff87fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x1", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x98", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x482680017ff98000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x10", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ffc7fff8000", + "0x48127ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x1bb", + "0x482480017fff8000", + "0x1ba", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff8", + "0x65b8", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff77fff", + "0x10780017fff7fff", + "0x63", + "0x4824800180007ff8", + "0x65b8", + "0x400080007ff87fff", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1", + "0x482480017ff68000", + "0x1", + "0x480680017fff8000", + "0x53746f7261676552656164", + "0x400280007ffb7fff", + "0x400280017ffb7ffb", + "0x400280027ffb7ffc", + "0x400280037ffb7ffd", + "0x480280057ffb8000", + "0x20680017fff7fff", + "0x42", + "0x480280047ffb8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a", + "0x480280067ffb8000", + "0x480680017fff8000", + "0x53746f7261676552656164", + "0x400280077ffb7fff", + "0x400280087ffb7ffb", + "0x400280097ffb7ffc", + "0x4002800a7ffb7ffd", + "0x4802800c7ffb8000", + "0x20680017fff7fff", + "0x2a", + "0x4802800b7ffb8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181", + "0x4802800d7ffb8000", + "0x480680017fff8000", + "0x53746f7261676552656164", + "0x4002800e7ffb7fff", + "0x4002800f7ffb7ffb", + "0x400280107ffb7ffc", + "0x400280117ffb7ffd", + "0x480280137ffb8000", + "0x20680017fff7fff", + "0x14", + "0x40780017fff7fff", + "0x1", + "0x48127ff67fff8000", + "0x400080007ffe7fff", + "0x48127ffb7fff8000", + "0x400080017ffd7fff", + "0x480280147ffb8000", + "0x400080027ffc7fff", + "0x48127fed7fff8000", + "0x480280127ffb8000", + "0x482680017ffb8000", + "0x15", + "0x480680017fff8000", + "0x0", + "0x48127ff87fff8000", + "0x482480017ff78000", + "0x3", + "0x208b7fff7fff7ffe", + "0x480280127ffb8000", + "0x482680017ffb8000", + "0x16", + "0x480280147ffb8000", + "0x480280157ffb8000", + "0x10780017fff7fff", + "0x12", + "0x40780017fff7fff", + "0x6", + "0x4802800b7ffb8000", + "0x482680017ffb8000", + "0xf", + "0x4802800d7ffb8000", + "0x4802800e7ffb8000", + "0x10780017fff7fff", + "0x9", + "0x40780017fff7fff", + "0xc", + "0x480280047ffb8000", + "0x482680017ffb8000", + "0x8", + "0x480280067ffb8000", + "0x480280077ffb8000", + "0x48127fed7fff8000", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017ff58000", + "0x1", + "0x48127ff37fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x1", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x98", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x482680017ff98000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x10", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ffc7fff8000", + "0x48127ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x10f", + "0x482480017fff8000", + "0x10e", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff8", + "0x6680", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff77fff", + "0x10780017fff7fff", + "0x63", + "0x4824800180007ff8", + "0x6680", + "0x400080007ff87fff", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1", + "0x480680017fff8000", + "0x0", + "0x482480017ff58000", + "0x1", + "0x480680017fff8000", + "0x53746f726167655772697465", + "0x400280007ffb7fff", + "0x400280017ffb7ffa", + "0x400280027ffb7ffb", + "0x400280037ffb7ffc", + "0x400280047ffb7ffd", + "0x480280067ffb8000", + "0x20680017fff7fff", + "0x3f", + "0x480280057ffb8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x53746f726167655772697465", + "0x400280077ffb7fff", + "0x400280087ffb7ffb", + "0x400280097ffb7ffc", + "0x4002800a7ffb7ffd", + "0x4002800b7ffb7ffe", + "0x4802800d7ffb8000", + "0x20680017fff7fff", + "0x25", + "0x4802800c7ffb8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x53746f726167655772697465", + "0x4002800e7ffb7fff", + "0x4002800f7ffb7ffb", + "0x400280107ffb7ffc", + "0x400280117ffb7ffd", + "0x400280127ffb7ffe", + "0x480280147ffb8000", + "0x20680017fff7fff", + "0xd", + "0x40780017fff7fff", + "0x1", + "0x48127ff07fff8000", + "0x480280137ffb8000", + "0x482680017ffb8000", + "0x15", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x480280137ffb8000", + "0x482680017ffb8000", + "0x17", + "0x480280157ffb8000", + "0x480280167ffb8000", + "0x10780017fff7fff", + "0x12", + "0x40780017fff7fff", + "0x6", + "0x4802800c7ffb8000", + "0x482680017ffb8000", + "0x10", + "0x4802800e7ffb8000", + "0x4802800f7ffb8000", + "0x10780017fff7fff", + "0x9", + "0x40780017fff7fff", + "0xc", + "0x480280057ffb8000", + "0x482680017ffb8000", + "0x9", + "0x480280077ffb8000", + "0x480280087ffb8000", + "0x48127fed7fff8000", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017ff58000", + "0x1", + "0x48127ff37fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x1", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1", + "0x480680017fff8000", + "0x53746f726167655772697465", + "0x400280007ffa7fff", + "0x400380017ffa7ff9", + "0x400280027ffa7ffd", + "0x400280037ffa7ffe", + "0x400380047ffa7ffc", + "0x480280067ffa8000", + "0x20680017fff7fff", + "0x6b", + "0x480280057ffa8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a", + "0x480680017fff8000", + "0x53746f726167655772697465", + "0x400280077ffa7fff", + "0x400280087ffa7ffc", + "0x400280097ffa7ffd", + "0x4002800a7ffa7ffe", + "0x4003800b7ffa7ffb", + "0x4802800d7ffa8000", + "0x20680017fff7fff", + "0x51", + "0x4802800c7ffa8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181", + "0x480680017fff8000", + "0x53746f726167655772697465", + "0x4002800e7ffa7fff", + "0x4002800f7ffa7ffc", + "0x400280107ffa7ffd", + "0x400280117ffa7ffe", + "0x400380127ffa7ffd", + "0x480280147ffa8000", + "0x20680017fff7fff", + "0x37", + "0x40780017fff7fff", + "0x1", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480a7ffc7fff8000", + "0x480a7ffb7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x281848a2ead29305005a1178671c6a7d7780cb656c57678566ea8033dbfa001", + "0x400080007ff97fff", + "0x400080007ffa7ffc", + "0x400080017ffa7ffd", + "0x400080027ffa7ffe", + "0x480280137ffa8000", + "0x48127ff87fff8000", + "0x482480017ff78000", + "0x1", + "0x48127ff77fff8000", + "0x482480017ff68000", + "0x3", + "0x480680017fff8000", + "0x456d69744576656e74", + "0x400280157ffa7fff", + "0x400280167ffa7ffa", + "0x400280177ffa7ffb", + "0x400280187ffa7ffc", + "0x400280197ffa7ffd", + "0x4002801a7ffa7ffe", + "0x4802801c7ffa8000", + "0x20680017fff7fff", + "0xd", + "0x480a7ff87fff8000", + "0x4802801b7ffa8000", + "0x482680017ffa8000", + "0x1d", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0x480a7ff87fff8000", + "0x4802801b7ffa8000", + "0x482680017ffa8000", + "0x1f", + "0x480680017fff8000", + "0x1", + "0x4802801d7ffa8000", + "0x4802801e7ffa8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0xe", + "0x480a7ff87fff8000", + "0x480280137ffa8000", + "0x482680017ffa8000", + "0x17", + "0x480680017fff8000", + "0x1", + "0x480280157ffa8000", + "0x480280167ffa8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x13", + "0x480a7ff87fff8000", + "0x4802800c7ffa8000", + "0x482680017ffa8000", + "0x10", + "0x480680017fff8000", + "0x1", + "0x4802800e7ffa8000", + "0x4802800f7ffa8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x18", + "0x480a7ff87fff8000", + "0x480280057ffa8000", + "0x482680017ffa8000", + "0x9", + "0x480680017fff8000", + "0x1", + "0x480280077ffa8000", + "0x480280087ffa8000", + "0x208b7fff7fff7ffe" + ], + "bytecode_segment_lengths": [212, 172, 172, 130], + "hints": [ + [ + 0, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [80, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 99, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0xa370" }, + "rhs": { "Deref": { "register": "AP", "offset": -22 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [122, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [140, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [155, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [169, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [183, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [197, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 212, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [229, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 248, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x65b8" }, + "rhs": { "Deref": { "register": "AP", "offset": -7 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 272, + [ + { + "SystemCall": { + "system": { "Deref": { "register": "FP", "offset": -5 } } + } + } + ] + ], + [ + 287, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { "register": "FP", "offset": -5 }, + "b": { "Immediate": "0x7" } + } + } + } + } + ] + ], + [ + 302, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { "register": "FP", "offset": -5 }, + "b": { "Immediate": "0xe" } + } + } + } + } + ] + ], + [305, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [354, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [369, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 384, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [401, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 420, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x6680" }, + "rhs": { "Deref": { "register": "AP", "offset": -7 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 447, + [ + { + "SystemCall": { + "system": { "Deref": { "register": "FP", "offset": -5 } } + } + } + ] + ], + [ + 464, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { "register": "FP", "offset": -5 }, + "b": { "Immediate": "0x7" } + } + } + } + } + ] + ], + [ + 481, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { "register": "FP", "offset": -5 }, + "b": { "Immediate": "0xe" } + } + } + } + } + ] + ], + [484, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [526, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [541, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 567, + [ + { + "SystemCall": { + "system": { "Deref": { "register": "FP", "offset": -6 } } + } + } + ] + ], + [ + 582, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { "register": "FP", "offset": -6 }, + "b": { "Immediate": "0x7" } + } + } + } + } + ] + ], + [ + 597, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { "register": "FP", "offset": -6 }, + "b": { "Immediate": "0xe" } + } + } + } + } + ] + ], + [600, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [602, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 630, + [ + { + "SystemCall": { + "system": { + "BinOp": { + "op": "Add", + "a": { "register": "FP", "offset": -6 }, + "b": { "Immediate": "0x15" } + } + } + } + } + ] + ] + ], + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x196a5f000a6df3bde4c611e5561aa002ac6cc04b4149c1f02f473b2ef445c76", + "offset": 0, + "builtins": ["range_check"] + }, + { + "selector": "0x3593f537ca0121e22c58378d40e0f5e2ba89b1c6d92a6990ab3066b68088f9c", + "offset": 212, + "builtins": ["range_check"] + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [ + { + "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "offset": 384, + "builtins": ["range_check"] + } + ] + } +} diff --git a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json index 299172666..a3c87b4d9 100644 --- a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json +++ b/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json @@ -1 +1,659 @@ -{"sierra_program":["0x1","0x6","0x0","0x2","0x8","0x0","0xcb","0x35","0x21","0x52616e6765436865636b","0x800000000000000100000000000000000000000000000000","0x436f6e7374","0x800000000000000000000000000000000000000000000002","0x1","0x2","0x281848a2ead29305005a1178671c6a7d7780cb656c57678566ea8033dbfa001","0x66656c74323532","0x800000000000000700000000000000000000000000000000","0x537472756374","0x800000000000000700000000000000000000000000000004","0x0","0x325aa8c5392af856b0b76eb1e9c925ca4854a32ad80c458af6e005fb4b6c83f","0x456e756d","0x800000000000000700000000000000000000000000000002","0x191f49c01d9820fa9a814bc69ef6cc6a88af08a0a74fd50c7687dab2294b39d","0x3","0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3","0x8","0x753332","0x53746f7261676541646472657373","0x53746f726167654261736541646472657373","0x145cc613954179acf89d43c94ed0e091828cbddcca83f5b408785785036d36d","0xa","0x4661696c656420746f20646573657269616c697a6520706172616d202331","0x4661696c656420746f20646573657269616c697a6520706172616d202332","0x4661696c656420746f20646573657269616c697a6520706172616d202333","0x4f7574206f6620676173","0x4172726179","0x800000000000000300000000000000000000000000000001","0x536e617073686f74","0x800000000000000700000000000000000000000000000001","0x10","0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62","0x11","0x12","0x800000000000000f00000000000000000000000000000001","0x36a29999818984cbedaf89ff3c5e77aa63ec49bdb2cf356962e80a4ce228308","0x800000000000000f00000000000000000000000000000003","0x14","0x15","0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672","0x800000000000000300000000000000000000000000000003","0x17","0x9e3a3a7f22220fe7534a6b09e607514c317ae36494e57214a99c6b1b05c29a","0x16","0x18","0x4275696c74696e436f737473","0x53797374656d","0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6","0x13","0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473","0x800000000000000700000000000000000000000000000003","0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511","0x426f78","0x4761734275696c74696e","0x55","0x7265766f6b655f61705f747261636b696e67","0x77697468647261775f676173","0x6272616e63685f616c69676e","0x7374727563745f6465636f6e737472756374","0x656e61626c655f61705f747261636b696e67","0x73746f72655f74656d70","0x61727261795f736e617073686f745f706f705f66726f6e74","0x756e626f78","0x72656e616d65","0x656e756d5f696e6974","0x1e","0x6a756d70","0x7374727563745f636f6e737472756374","0x656e756d5f6d61746368","0x64697361626c655f61705f747261636b696e67","0x64726f70","0x1f","0x61727261795f6e6577","0x636f6e73745f61735f696d6d656469617465","0x1d","0x61727261795f617070656e64","0x1c","0x20","0x1b","0x6765745f6275696c74696e5f636f737473","0x1a","0x77697468647261775f6761735f616c6c","0x66756e6374696f6e5f63616c6c","0x19","0x736e617073686f745f74616b65","0xf","0xe","0xd","0xc","0x73746f726167655f626173655f616464726573735f636f6e7374","0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1","0xb","0x73746f726167655f616464726573735f66726f6d5f62617365","0x7","0x9","0x73746f726167655f726561645f73797363616c6c","0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a","0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181","0x6","0x5","0x73746f726167655f77726974655f73797363616c6c","0x647570","0x4","0x656d69745f6576656e745f73797363616c6c","0x243","0xffffffffffffffff","0xaf","0x9f","0x22","0x8e","0x2c","0x23","0x24","0x25","0x26","0x27","0x28","0x31","0x29","0x2a","0x2b","0x7c","0x2d","0x2e","0x47","0x2f","0x30","0x32","0x33","0x34","0x35","0x36","0x37","0x38","0x6b","0x39","0x3a","0x3b","0x3c","0x3d","0x3e","0x3f","0x40","0x64","0x41","0x42","0x43","0x44","0x45","0x46","0x48","0x49","0x4a","0x4b","0x4c","0x4d","0x4e","0x4f","0x50","0x51","0x52","0x53","0x54","0x56","0x57","0x58","0x59","0x5a","0x5b","0x5c","0x5d","0x5e","0x5f","0x60","0x61","0x62","0x63","0x65","0x66","0x142","0xd2","0x135","0x128","0x122","0x11b","0x12c","0x1ba","0x165","0x1ad","0x1a0","0x19b","0x196","0x1a4","0x236","0x229","0x21c","0x212","0xbd","0x150","0x1c8","0x13fd","0x60504031105100c0f0e0605060506050d0c0b0a0908070606050403020100","0x31805170c0f0a0916091509140c0613050403060506050605120c0b0a0c06","0x2105201f06051e1d1c06060504031b06060504031a06060504031906060504","0xc250a29052805120c270a120c250a260c250a2405120c0f0a2305220c0f0a","0x4032f053305320c2b0e023109302f052e052d0c2b0e21052c05120c2b0a2a","0xc3e2405053d0c3c0c3b0c3a3902380605203729050605360c350e34060605","0x454405053f2305053f0c06440506430605054206050541060505400c05053f","0x54b060505494a050549230505490c4844050547050644050643290505460c","0x5053f05064f0506432f0505462c0505460605054e0605053f4d05054c0605","0x5495605054711110555280505460c545305053f0c524f05053f5105053f50","0x505495805054c0c064f050643330505462405054621050549210505572e05","0x5495e0505575e0505465d06055c240505495b05054c5a05054c5905054c29","0x5c6306055c0c626105053f1305053f6005054c0c5f180505425e05053d5e05","0x5680c676605054c2105053f6505053d650505496505055765050546640605","0x5054c690505476905053f69050549690505570c0669050643110505460605","0x5495605053f0c06560506432e0505460c6a2405053f1105053d1105056805","0x60c6065066d6669066c06050c06050c0c6c050c0c0c6b0506560506432805","0x61305650c69056c056905660c0c6c050c690c13056c051105110c0c6c050c","0x610c5a056c055b05130c5b056c051805600c0c6c050c060c5e05591861066c","0xc060c0c33050c5b0c21056c0559055e0c58056c056105180c59056c055a05","0x524055e0c58056c055e05180c24056c052305590c23056c050c5a0c0c6c05","0x54d2e29066c065805650c0c6c050c060c28056e33056c062105580c21056c","0x53056c055605610c56056c052f05130c2f056c052e05600c0c6c050c060c2c","0xc5a0c0c6c050c060c0c6f050c5b0c4f056c0553055e0c51056c052905180c","0x5580c4f056c0544055e0c51056c052c05180c44056c054d05590c4d056c05","0x6c050c060c7205716f00066c065105650c0c6c050c060c5005704a056c064f","0x6c050005180c75056c057405610c74056c057305130c73056c056f05600c0c","0x590c79056c050c5a0c0c6c050c060c0c78050c5b0c77056c0575055e0c7605","0x7c7b056c067705580c77056c057a055e0c76056c057205180c7a056c057905","0x6c050c210c0c6c050c060c80057f7e7d066c067605650c0c6c050c060c7105","0x330c0c6c054a05330c0c6c057b05330c0c6c057e05240c0c6c057d05230c0c","0x81062c0c78056c0578052e0c78056c050c290c81056c050c280c0c6c053305","0x660c85056c058405530c84056c05828306560c83056c050c2f0c82056c0578","0x585056c0585054d0c06056c0506054f0c66056c056605510c69056c056905","0x6c0586054a0c86056c050c440c0c6c058005230c0c6c050c060c8506666969","0xc0c6c050c210c0c6c050c060c8b8a06898887066c0686666911500c8605","0x2e0c06056c0506054f0c88056c058805510c87056c058705660c8c056c050c","0x4a338c068887606f0c7b056c057b052e0c4a056c054a052e0c33056c053305","0x6c059105730c0c6c050c060c93059291056c069005720c908f8e8d696c057b","0x56c059605760c0c6c059505750c9695066c059405740c94056c050c280c0c","0x6c058e05510c8d056c058d05660c7f056c059805790c98056c059705770c97","0xc0c6c050c060c7f8f8e8d69057f056c057f054d0c8f056c058f054f0c8e05","0x8f056c058f054f0c8e056c058e05510c8d056c058d05660c99056c05930553","0x57b05330c0c6c050c210c0c6c050c060c998f8e8d690599056c0599054d0c","0xc9b056c050c7a0c9a056c050c280c0c6c053305330c0c6c054a05330c0c6c","0x56c059c9d06560c9d056c050c2f0c9c056c059b9a062c0c9b056c059b052e","0x6c0506054f0c8b056c058b05510c8a056c058a05660c9f056c059e05530c9e","0x57b0c0c6c050c210c0c6c050c060c9f068b8a69059f056c059f054d0c0605","0x56c050c280c0c6c053305330c0c6c054a05330c0c6c057605230c0c6c0571","0x56c050c2f0ca2056c05a1a0062c0ca1056c05a1052e0ca1056c050c710ca0","0x56605510c69056c056905660ca5056c05a405530ca4056c05a2a306560ca3","0xc6c050c060ca50666696905a5056c05a5054d0c06056c0506054f0c66056c","0x50c280c0c6c055105230c0c6c053305330c0c6c0550057b0c0c6c050c210c","0x50c2f0ca7056c05a639062c0ca6056c05a6052e0ca6056c050c7d0c39056c","0x5510c69056c056905660caa056c05a905530ca9056c05a7a806560ca8056c","0x50c060caa0666696905aa056c05aa054d0c06056c0506054f0c66056c0566","0x7e0cab056c050c280c0c6c055805230c0c6c0528057b0c0c6c050c210c0c6c","0x560cae056c050c2f0cad056c05acab062c0cac056c05ac052e0cac056c050c","0x66056c056605510c69056c056905660cb0056c05af05530caf056c05adae06","0x5800c0c6c050c060cb00666696905b0056c05b0054d0c06056c0506054f0c","0xb2b1062c0cb2056c05b2052e0cb2056c050c7a0cb1056c050c280c0c6c0511","0x5660cb5056c05b405530cb4056c05b39206560c92056c050c2f0cb3056c05","0x6905b5056c05b5054d0c06056c0506054f0c60056c056005510c65056c0565","0xc0c6c050c060c606506b66669066c06050c06050c0c6c050c0c0cb5066065","0x50c060c5e05b71861066c061305650c69056c056905660c13056c05110511","0xc5a056c050c290c5b056c050c280c0c6c051805240c0c6c056105230c0c6c","0x56c05595806560c58056c050c2f0c59056c055a5b062c0c5a056c055a052e","0x6c0506054f0c66056c056605510c69056c056905660c23056c052105530c21","0x440c0c6c055e05230c0c6c050c060c23066669690523056c0523054d0c0605","0xc060c2e2906b82833066c0624666911500c24056c0524054a0c24056c050c","0x5605830c5356066c052f05820c2f056c052c05780c2c056c050c810c0c6c05","0x50c870c4d056c054f05860c4f056c055105850c51056c055305840c0c6c05","0x6c053305660c4d056c054d058a0c44056c054405880c0c6c050c690c44056c","0x6c050c8c0c0c6c050c060c73726f11b900504a116c064d440628698b0c3305","0x57705840c0c6c057605830c7776066c057505820c75056c057405780c7405","0x54a05510c71056c050c870c7b056c057a05860c7a056c057905850c79056c","0x4a698b0c00056c0500052e0c7b056c057b058a0c71056c057105880c4a056c","0x8305780c83056c050c8d0c0c6c050c060c82788111ba807e7d116c067b7150","0x5850c87056c058605840c0c6c058505830c8685066c058405820c84056c05","0x5880c7d056c057d05510c8b056c050c870c8a056c058805860c88056c0587","0x116c068a8b7e7d698b0c80056c0580052e0c8a056c058a058a0c8b056c058b","0x118e0c93056c050c280c0c6c050c210c0c6c050c060c91908f11bb8e8d8c","0x9897116c059605910c0c6c059505900c9695066c0594058f0c94056c058e80","0x59805130c9a056c059993062c0c99056c0599052e0c99056c059705130c7f","0x52e0c9d056c057f05130c9c056c059b9a062c0c9b056c059b052e0c9b056c","0xc0c6c059f05750ca09f066c059e05740c9e056c059d9c062c0c9d056c059d","0x33056c053305660ca3056c05a205790ca2056c05a105770ca1056c05a00576","0xca38d8c336905a3056c05a3054d0c8d056c058d054f0c8c056c058c05510c","0x90054f0ca4056c058f05510c0c6c058005330c0c6c050005330c0c6c050c06","0xc6c050005330c0c6c050c060c0cbc050c5b0c39056c059105930ca5056c05","0xc0cbc050c5b0c39056c058205930ca5056c0578054f0ca4056c058105510c","0x210c39056c057305930ca5056c0572054f0ca4056c056f05510c0c6c050c06","0x5660ca8056c05a705530ca7056c0539a606560ca6056c050c2f0c0c6c050c","0x6905a8056c05a8054d0ca5056c05a5054f0ca4056c05a405510c33056c0533","0x56c05aa052e0caa056c050c7a0ca9056c050c280c0c6c050c060ca8a5a433","0x5ad05530cad056c05abac06560cac056c050c2f0cab056c05aaa9062c0caa","0xae054d0c06056c0506054f0c2e056c052e05510c29056c052905660cae056c","0xcaf056c050c280c0c6c051105800c0c6c050c060cae062e296905ae056c05","0xcb2056c050c2f0cb1056c05b0af062c0cb0056c05b0052e0cb0056c050c7a","0x56c056005510c65056c056505660c92056c05b305530cb3056c05b1b20656","0x50c0c6c050c0c0c92066065690592056c0592054d0c06056c0506054f0c60","0x56905660c13056c051105110c0c6c050c060c606506bd6669066c06050c06","0x5240c0c6c056105230c0c6c050c060c5e05be1861066c061305650c69056c","0x5a5b062c0c5a056c055a052e0c5a056c050c290c5b056c050c280c0c6c0518","0x5660c23056c052105530c21056c05595806560c58056c050c2f0c59056c05","0x690523056c0523054d0c06056c0506054f0c66056c056605510c69056c0569","0x56c0524054a0c24056c050c440c0c6c055e05230c0c6c050c060c23066669","0x860c2c056c050c810c0c6c050c060c2e2906bf2833066c0624666911500c24","0x55305880c0c6c050c690c53056c050c870c56056c050c940c2f056c052c05","0x2866950c33056c053305660c56056c0556052e0c2f056c052f058a0c53056c","0x5005860c50056c050c8c0c0c6c050c060c4a444d11c04f51066c06562f5306","0x57205880c51056c055105510c72056c050c870c6f056c050c940c00056c05","0x73066c066f00724f5166950c6f056c056f052e0c00056c0500058a0c72056c","0x50c940c7a056c057905860c79056c050c8d0c0c6c050c060c77767511c174","0x57a058a0c71056c057105880c73056c057305510c71056c050c870c7b056c","0x60c78818011c27e7d066c067b7a71747366950c7b056c057b052e0c7a056c","0x58305750c8483066c058205740c82056c050c280c0c6c050c210c0c6c050c","0x53305660c87056c058605790c86056c058505770c85056c058405760c0c6c","0x7d33690587056c0587054d0c7e056c057e054f0c7d056c057d05510c33056c","0x56c057805930c8a056c0581054f0c88056c058005510c0c6c050c060c877e","0x930c8a056c0576054f0c88056c057505510c0c6c050c060c0cc3050c5b0c8b","0x544054f0c88056c054d05510c0c6c050c060c0cc3050c5b0c8b056c057705","0x6c058b8c06560c8c056c050c2f0c0c6c050c210c8b056c054a05930c8a056c","0x58a054f0c88056c058805510c33056c053305660c8e056c058d05530c8d05","0xc8f056c050c280c0c6c050c060c8e8a883369058e056c058e054d0c8a056c","0xc93056c050c2f0c91056c05908f062c0c90056c0590052e0c90056c050c7a","0x56c052e05510c29056c052905660c95056c059405530c94056c0591930656","0x800c0c6c050c060c95062e29690595056c0595054d0c06056c0506054f0c2e","0x96062c0c97056c0597052e0c97056c050c7a0c96056c050c280c0c6c051105","0x660c9a056c059905530c99056c05987f06560c7f056c050c2f0c98056c0597","0x59a056c059a054d0c06056c0506054f0c60056c056005510c65056c056505","0x6605960c61056c050c870c13056c056005860c60056c050c810c9a06606569","0x6c06181361060566950c13056c0513058a0c61056c056105880c1866066c05","0x870c23056c052105860c21056c050c8c0c0c6c050c060c58595a11c45b5e06","0xc24056c052405880c5e056c055e05510c3369066c056905960c24056c050c","0xc6c050c060c2f2c2e11c52928066c063323245b5e66950c23056c0523058a","0x4f65066c056505960c51056c050c870c53056c055605860c56056c050c8d0c","0x5351292866950c53056c0553058a0c51056c055105880c28056c052805510c","0x72056c050c280c6f056c050c280c0c6c050c060c00504a11c6444d066c064f","0x7505990c7675066c0574057f0c74056c057305980c73056c0565696611970c","0x56c050c9c0c0c6c050c060c77056c0576059b0c76056c0576059a0c0c6c05","0x7b059e0c7b77066c0577059d0c7a056c05796f062c0c79056c0579052e0c79","0x62c0c80056c057105130c0c6c057e05330c0c6c057d05330c7e7d71116c05","0x6c058205330c848382116c0578059e0c7877066c0577059d0c81056c058072","0x6c0577059e0c86056c058581062c0c85056c058305130c0c6c058405330c0c","0x8b86062c0c8b056c058a05130c0c6c058805330c0c6c058705330c8a888711","0x750c908f066c058c05740c0c6c058d05750c8e8d066c057a05740c8c056c05","0x9f0c4d056c054d05510c93056c059005760c91056c058e05760c0c6c058f05","0x98979611c79594066c069391444d69a00c93056c0593059f0c91056c059105","0xc9a056c059905a20c99056c057f1106a10c7f056c050c5a0c0c6c050c060c","0x9a056c059a05a30c95056c0595054f0c94056c059405510c0c056c050c0566","0x989b06560c9b056c050c2f0c0c6c051105a40c0c6c050c060c9a95940c6905","0x54f0c96056c059605510c0c056c050c05660c9d056c059c05a50c9c056c05","0x6c051105a40c0c6c050c060c9d97960c69059d056c059d05a30c97056c0597","0x560c9e056c050c2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c","0x4a056c054a05510c0c056c050c05660ca0056c059f05a50c9f056c05009e06","0x5a40c0c6c050c060ca0504a0c6905a0056c05a005a30c50056c0550054f0c","0x56c050c2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c6c0511","0x52e05510c0c056c050c05660ca3056c05a205a50ca2056c052fa106560ca1","0xc6c050c060ca32c2e0c6905a3056c05a305a30c2c056c052c054f0c2e056c","0xc2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c6c051105a40c","0x510c0c056c050c05660c39056c05a505a50ca5056c0558a406560ca4056c05","0xc696939595a0c690539056c053905a30c59056c0559054f0c5a056c055a05","0x500c69c81106050c4f51500c692451500c690c1106050c4f51500c69245150","0x66691106050c5651500c690606062851500c60c91106050c4f51500c692451","0xca65"],"sierra_program_debug_info":{"type_names":[[0,"RangeCheck"],[1,"Const"],[2,"felt252"],[3,"temp_cairo::StateUpdateContract::LogStateUpdate"],[4,"temp_cairo::StateUpdateContract::Event"],[5,"Const"],[6,"Tuple"],[7,"Const"],[8,"u32"],[9,"StorageAddress"],[10,"StorageBaseAddress"],[11,"core::starknet::storage::StoragePointer0Offset::"],[12,"Const"],[13,"Const"],[14,"Const"],[15,"Const"],[16,"Array"],[17,"Snapshot>"],[18,"core::array::Span::"],[19,"Tuple>"],[20,"temp_cairo::StateUpdateContract::ContractState"],[21,"Unit"],[22,"Tuple"],[23,"core::panics::Panic"],[24,"Tuple>"],[25,"core::panics::PanicResult::<(temp_cairo::StateUpdateContract::ContractState, ())>"],[26,"BuiltinCosts"],[27,"System"],[28,"core::panics::PanicResult::<(core::array::Span::,)>"],[29,"Const"],[30,"core::option::Option::"],[31,"Box"],[32,"GasBuiltin"]],"libfunc_names":[[0,"revoke_ap_tracking"],[1,"withdraw_gas"],[2,"branch_align"],[3,"struct_deconstruct>"],[4,"enable_ap_tracking"],[5,"store_temp"],[6,"array_snapshot_pop_front"],[7,"unbox"],[8,"rename"],[9,"enum_init, 0>"],[10,"store_temp>>"],[11,"store_temp>"],[12,"jump"],[13,"struct_construct"],[14,"enum_init, 1>"],[15,"enum_match>"],[16,"disable_ap_tracking"],[17,"drop>>"],[18,"drop>"],[19,"drop"],[20,"array_new"],[21,"const_as_immediate>"],[22,"store_temp"],[23,"array_append"],[24,"struct_construct"],[25,"struct_construct>>"],[26,"enum_init,)>, 1>"],[27,"store_temp"],[28,"store_temp"],[29,"store_temp,)>>"],[30,"get_builtin_costs"],[31,"store_temp"],[32,"withdraw_gas_all"],[33,"struct_construct"],[34,"function_call"],[35,"enum_match>"],[36,"drop>"],[37,"snapshot_take>"],[38,"drop>"],[39,"struct_construct>"],[40,"struct_construct>>"],[41,"enum_init,)>, 0>"],[42,"const_as_immediate>"],[43,"drop"],[44,"const_as_immediate>"],[45,"const_as_immediate>"],[46,"const_as_immediate>"],[47,"drop>"],[48,"storage_base_address_const<289565229787362368933081636443797405535488074065834425092593015835915391953>"],[49,"struct_construct>"],[50,"snapshot_take>"],[51,"drop>"],[52,"struct_deconstruct>"],[53,"rename"],[54,"storage_address_from_base"],[55,"const_as_immediate>"],[56,"store_temp"],[57,"store_temp"],[58,"storage_read_syscall"],[59,"storage_base_address_const<1129664241071644691371073118594794953592340198277473102285062464307545102410>"],[60,"storage_base_address_const<1804974537427402286278400303388660593172206410421526189703894999503593972097>"],[61,"struct_construct>"],[62,"snapshot_take>"],[63,"drop>"],[64,"struct_deconstruct>"],[65,"store_temp>"],[66,"const_as_immediate>"],[67,"storage_write_syscall"],[68,"dup"],[69,"struct_construct"],[70,"enum_init"],[71,"snapshot_take"],[72,"drop"],[73,"store_temp"],[74,"enum_match"],[75,"const_as_immediate>"],[76,"dup"],[77,"struct_deconstruct"],[78,"store_temp>"],[79,"emit_event_syscall"],[80,"struct_construct>"],[81,"enum_init, 0>"],[82,"store_temp>"],[83,"drop"],[84,"enum_init, 1>"]],"user_func_names":[[0,"temp_cairo::StateUpdateContract::__wrapper__update_state"],[1,"temp_cairo::StateUpdateContract::__wrapper__get_state"],[2,"temp_cairo::StateUpdateContract::__wrapper__constructor"],[3,"temp_cairo::StateUpdateContract::update_state"]]},"contract_class_version":"0.1.0","entry_points_by_type":{"EXTERNAL":[{"selector":"0x196a5f000a6df3bde4c611e5561aa002ac6cc04b4149c1f02f473b2ef445c76","function_idx":0},{"selector":"0x3593f537ca0121e22c58378d40e0f5e2ba89b1c6d92a6990ab3066b68088f9c","function_idx":1}],"L1_HANDLER":[],"CONSTRUCTOR":[{"selector":"0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194","function_idx":2}]},"abi":[{"type":"constructor","name":"constructor","inputs":[]},{"type":"function","name":"update_state","inputs":[{"name":"block_number","type":"core::felt252"},{"name":"state_root","type":"core::felt252"},{"name":"block_hash","type":"core::felt252"}],"outputs":[],"state_mutability":"external"},{"type":"function","name":"get_state","inputs":[],"outputs":[{"type":"(core::felt252, core::felt252, core::felt252)"}],"state_mutability":"view"},{"type":"event","name":"temp_cairo::StateUpdateContract::LogStateUpdate","kind":"struct","members":[{"name":"state_root","type":"core::felt252","kind":"data"},{"name":"block_number","type":"core::felt252","kind":"data"},{"name":"block_hash","type":"core::felt252","kind":"data"}]},{"type":"event","name":"temp_cairo::StateUpdateContract::Event","kind":"enum","variants":[{"name":"LogStateUpdate","type":"temp_cairo::StateUpdateContract::LogStateUpdate","kind":"nested"}]}]} \ No newline at end of file +{ + "sierra_program": [ + "0x1", + "0x6", + "0x0", + "0x2", + "0x8", + "0x0", + "0xcb", + "0x35", + "0x21", + "0x52616e6765436865636b", + "0x800000000000000100000000000000000000000000000000", + "0x436f6e7374", + "0x800000000000000000000000000000000000000000000002", + "0x1", + "0x2", + "0x281848a2ead29305005a1178671c6a7d7780cb656c57678566ea8033dbfa001", + "0x66656c74323532", + "0x800000000000000700000000000000000000000000000000", + "0x537472756374", + "0x800000000000000700000000000000000000000000000004", + "0x0", + "0x325aa8c5392af856b0b76eb1e9c925ca4854a32ad80c458af6e005fb4b6c83f", + "0x456e756d", + "0x800000000000000700000000000000000000000000000002", + "0x191f49c01d9820fa9a814bc69ef6cc6a88af08a0a74fd50c7687dab2294b39d", + "0x3", + "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", + "0x8", + "0x753332", + "0x53746f7261676541646472657373", + "0x53746f726167654261736541646472657373", + "0x145cc613954179acf89d43c94ed0e091828cbddcca83f5b408785785036d36d", + "0xa", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x4661696c656420746f20646573657269616c697a6520706172616d202332", + "0x4661696c656420746f20646573657269616c697a6520706172616d202333", + "0x4f7574206f6620676173", + "0x4172726179", + "0x800000000000000300000000000000000000000000000001", + "0x536e617073686f74", + "0x800000000000000700000000000000000000000000000001", + "0x10", + "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", + "0x11", + "0x12", + "0x800000000000000f00000000000000000000000000000001", + "0x36a29999818984cbedaf89ff3c5e77aa63ec49bdb2cf356962e80a4ce228308", + "0x800000000000000f00000000000000000000000000000003", + "0x14", + "0x15", + "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", + "0x800000000000000300000000000000000000000000000003", + "0x17", + "0x9e3a3a7f22220fe7534a6b09e607514c317ae36494e57214a99c6b1b05c29a", + "0x16", + "0x18", + "0x4275696c74696e436f737473", + "0x53797374656d", + "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", + "0x13", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x800000000000000700000000000000000000000000000003", + "0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511", + "0x426f78", + "0x4761734275696c74696e", + "0x55", + "0x7265766f6b655f61705f747261636b696e67", + "0x77697468647261775f676173", + "0x6272616e63685f616c69676e", + "0x7374727563745f6465636f6e737472756374", + "0x656e61626c655f61705f747261636b696e67", + "0x73746f72655f74656d70", + "0x61727261795f736e617073686f745f706f705f66726f6e74", + "0x756e626f78", + "0x72656e616d65", + "0x656e756d5f696e6974", + "0x1e", + "0x6a756d70", + "0x7374727563745f636f6e737472756374", + "0x656e756d5f6d61746368", + "0x64697361626c655f61705f747261636b696e67", + "0x64726f70", + "0x1f", + "0x61727261795f6e6577", + "0x636f6e73745f61735f696d6d656469617465", + "0x1d", + "0x61727261795f617070656e64", + "0x1c", + "0x20", + "0x1b", + "0x6765745f6275696c74696e5f636f737473", + "0x1a", + "0x77697468647261775f6761735f616c6c", + "0x66756e6374696f6e5f63616c6c", + "0x19", + "0x736e617073686f745f74616b65", + "0xf", + "0xe", + "0xd", + "0xc", + "0x73746f726167655f626173655f616464726573735f636f6e7374", + "0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1", + "0xb", + "0x73746f726167655f616464726573735f66726f6d5f62617365", + "0x7", + "0x9", + "0x73746f726167655f726561645f73797363616c6c", + "0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a", + "0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181", + "0x6", + "0x5", + "0x73746f726167655f77726974655f73797363616c6c", + "0x647570", + "0x4", + "0x656d69745f6576656e745f73797363616c6c", + "0x243", + "0xffffffffffffffff", + "0xaf", + "0x9f", + "0x22", + "0x8e", + "0x2c", + "0x23", + "0x24", + "0x25", + "0x26", + "0x27", + "0x28", + "0x31", + "0x29", + "0x2a", + "0x2b", + "0x7c", + "0x2d", + "0x2e", + "0x47", + "0x2f", + "0x30", + "0x32", + "0x33", + "0x34", + "0x35", + "0x36", + "0x37", + "0x38", + "0x6b", + "0x39", + "0x3a", + "0x3b", + "0x3c", + "0x3d", + "0x3e", + "0x3f", + "0x40", + "0x64", + "0x41", + "0x42", + "0x43", + "0x44", + "0x45", + "0x46", + "0x48", + "0x49", + "0x4a", + "0x4b", + "0x4c", + "0x4d", + "0x4e", + "0x4f", + "0x50", + "0x51", + "0x52", + "0x53", + "0x54", + "0x56", + "0x57", + "0x58", + "0x59", + "0x5a", + "0x5b", + "0x5c", + "0x5d", + "0x5e", + "0x5f", + "0x60", + "0x61", + "0x62", + "0x63", + "0x65", + "0x66", + "0x142", + "0xd2", + "0x135", + "0x128", + "0x122", + "0x11b", + "0x12c", + "0x1ba", + "0x165", + "0x1ad", + "0x1a0", + "0x19b", + "0x196", + "0x1a4", + "0x236", + "0x229", + "0x21c", + "0x212", + "0xbd", + "0x150", + "0x1c8", + "0x13fd", + "0x60504031105100c0f0e0605060506050d0c0b0a0908070606050403020100", + "0x31805170c0f0a0916091509140c0613050403060506050605120c0b0a0c06", + "0x2105201f06051e1d1c06060504031b06060504031a06060504031906060504", + "0xc250a29052805120c270a120c250a260c250a2405120c0f0a2305220c0f0a", + "0x4032f053305320c2b0e023109302f052e052d0c2b0e21052c05120c2b0a2a", + "0xc3e2405053d0c3c0c3b0c3a3902380605203729050605360c350e34060605", + "0x454405053f2305053f0c06440506430605054206050541060505400c05053f", + "0x54b060505494a050549230505490c4844050547050644050643290505460c", + "0x5053f05064f0506432f0505462c0505460605054e0605053f4d05054c0605", + "0x5495605054711110555280505460c545305053f0c524f05053f5105053f50", + "0x505495805054c0c064f050643330505462405054621050549210505572e05", + "0x5495e0505575e0505465d06055c240505495b05054c5a05054c5905054c29", + "0x5c6306055c0c626105053f1305053f6005054c0c5f180505425e05053d5e05", + "0x5680c676605054c2105053f6505053d650505496505055765050546640605", + "0x5054c690505476905053f69050549690505570c0669050643110505460605", + "0x5495605053f0c06560506432e0505460c6a2405053f1105053d1105056805", + "0x60c6065066d6669066c06050c06050c0c6c050c0c0c6b0506560506432805", + "0x61305650c69056c056905660c0c6c050c690c13056c051105110c0c6c050c", + "0x610c5a056c055b05130c5b056c051805600c0c6c050c060c5e05591861066c", + "0xc060c0c33050c5b0c21056c0559055e0c58056c056105180c59056c055a05", + "0x524055e0c58056c055e05180c24056c052305590c23056c050c5a0c0c6c05", + "0x54d2e29066c065805650c0c6c050c060c28056e33056c062105580c21056c", + "0x53056c055605610c56056c052f05130c2f056c052e05600c0c6c050c060c2c", + "0xc5a0c0c6c050c060c0c6f050c5b0c4f056c0553055e0c51056c052905180c", + "0x5580c4f056c0544055e0c51056c052c05180c44056c054d05590c4d056c05", + "0x6c050c060c7205716f00066c065105650c0c6c050c060c5005704a056c064f", + "0x6c050005180c75056c057405610c74056c057305130c73056c056f05600c0c", + "0x590c79056c050c5a0c0c6c050c060c0c78050c5b0c77056c0575055e0c7605", + "0x7c7b056c067705580c77056c057a055e0c76056c057205180c7a056c057905", + "0x6c050c210c0c6c050c060c80057f7e7d066c067605650c0c6c050c060c7105", + "0x330c0c6c054a05330c0c6c057b05330c0c6c057e05240c0c6c057d05230c0c", + "0x81062c0c78056c0578052e0c78056c050c290c81056c050c280c0c6c053305", + "0x660c85056c058405530c84056c05828306560c83056c050c2f0c82056c0578", + "0x585056c0585054d0c06056c0506054f0c66056c056605510c69056c056905", + "0x6c0586054a0c86056c050c440c0c6c058005230c0c6c050c060c8506666969", + "0xc0c6c050c210c0c6c050c060c8b8a06898887066c0686666911500c8605", + "0x2e0c06056c0506054f0c88056c058805510c87056c058705660c8c056c050c", + "0x4a338c068887606f0c7b056c057b052e0c4a056c054a052e0c33056c053305", + "0x6c059105730c0c6c050c060c93059291056c069005720c908f8e8d696c057b", + "0x56c059605760c0c6c059505750c9695066c059405740c94056c050c280c0c", + "0x6c058e05510c8d056c058d05660c7f056c059805790c98056c059705770c97", + "0xc0c6c050c060c7f8f8e8d69057f056c057f054d0c8f056c058f054f0c8e05", + "0x8f056c058f054f0c8e056c058e05510c8d056c058d05660c99056c05930553", + "0x57b05330c0c6c050c210c0c6c050c060c998f8e8d690599056c0599054d0c", + "0xc9b056c050c7a0c9a056c050c280c0c6c053305330c0c6c054a05330c0c6c", + "0x56c059c9d06560c9d056c050c2f0c9c056c059b9a062c0c9b056c059b052e", + "0x6c0506054f0c8b056c058b05510c8a056c058a05660c9f056c059e05530c9e", + "0x57b0c0c6c050c210c0c6c050c060c9f068b8a69059f056c059f054d0c0605", + "0x56c050c280c0c6c053305330c0c6c054a05330c0c6c057605230c0c6c0571", + "0x56c050c2f0ca2056c05a1a0062c0ca1056c05a1052e0ca1056c050c710ca0", + "0x56605510c69056c056905660ca5056c05a405530ca4056c05a2a306560ca3", + "0xc6c050c060ca50666696905a5056c05a5054d0c06056c0506054f0c66056c", + "0x50c280c0c6c055105230c0c6c053305330c0c6c0550057b0c0c6c050c210c", + "0x50c2f0ca7056c05a639062c0ca6056c05a6052e0ca6056c050c7d0c39056c", + "0x5510c69056c056905660caa056c05a905530ca9056c05a7a806560ca8056c", + "0x50c060caa0666696905aa056c05aa054d0c06056c0506054f0c66056c0566", + "0x7e0cab056c050c280c0c6c055805230c0c6c0528057b0c0c6c050c210c0c6c", + "0x560cae056c050c2f0cad056c05acab062c0cac056c05ac052e0cac056c050c", + "0x66056c056605510c69056c056905660cb0056c05af05530caf056c05adae06", + "0x5800c0c6c050c060cb00666696905b0056c05b0054d0c06056c0506054f0c", + "0xb2b1062c0cb2056c05b2052e0cb2056c050c7a0cb1056c050c280c0c6c0511", + "0x5660cb5056c05b405530cb4056c05b39206560c92056c050c2f0cb3056c05", + "0x6905b5056c05b5054d0c06056c0506054f0c60056c056005510c65056c0565", + "0xc0c6c050c060c606506b66669066c06050c06050c0c6c050c0c0cb5066065", + "0x50c060c5e05b71861066c061305650c69056c056905660c13056c05110511", + "0xc5a056c050c290c5b056c050c280c0c6c051805240c0c6c056105230c0c6c", + "0x56c05595806560c58056c050c2f0c59056c055a5b062c0c5a056c055a052e", + "0x6c0506054f0c66056c056605510c69056c056905660c23056c052105530c21", + "0x440c0c6c055e05230c0c6c050c060c23066669690523056c0523054d0c0605", + "0xc060c2e2906b82833066c0624666911500c24056c0524054a0c24056c050c", + "0x5605830c5356066c052f05820c2f056c052c05780c2c056c050c810c0c6c05", + "0x50c870c4d056c054f05860c4f056c055105850c51056c055305840c0c6c05", + "0x6c053305660c4d056c054d058a0c44056c054405880c0c6c050c690c44056c", + "0x6c050c8c0c0c6c050c060c73726f11b900504a116c064d440628698b0c3305", + "0x57705840c0c6c057605830c7776066c057505820c75056c057405780c7405", + "0x54a05510c71056c050c870c7b056c057a05860c7a056c057905850c79056c", + "0x4a698b0c00056c0500052e0c7b056c057b058a0c71056c057105880c4a056c", + "0x8305780c83056c050c8d0c0c6c050c060c82788111ba807e7d116c067b7150", + "0x5850c87056c058605840c0c6c058505830c8685066c058405820c84056c05", + "0x5880c7d056c057d05510c8b056c050c870c8a056c058805860c88056c0587", + "0x116c068a8b7e7d698b0c80056c0580052e0c8a056c058a058a0c8b056c058b", + "0x118e0c93056c050c280c0c6c050c210c0c6c050c060c91908f11bb8e8d8c", + "0x9897116c059605910c0c6c059505900c9695066c0594058f0c94056c058e80", + "0x59805130c9a056c059993062c0c99056c0599052e0c99056c059705130c7f", + "0x52e0c9d056c057f05130c9c056c059b9a062c0c9b056c059b052e0c9b056c", + "0xc0c6c059f05750ca09f066c059e05740c9e056c059d9c062c0c9d056c059d", + "0x33056c053305660ca3056c05a205790ca2056c05a105770ca1056c05a00576", + "0xca38d8c336905a3056c05a3054d0c8d056c058d054f0c8c056c058c05510c", + "0x90054f0ca4056c058f05510c0c6c058005330c0c6c050005330c0c6c050c06", + "0xc6c050005330c0c6c050c060c0cbc050c5b0c39056c059105930ca5056c05", + "0xc0cbc050c5b0c39056c058205930ca5056c0578054f0ca4056c058105510c", + "0x210c39056c057305930ca5056c0572054f0ca4056c056f05510c0c6c050c06", + "0x5660ca8056c05a705530ca7056c0539a606560ca6056c050c2f0c0c6c050c", + "0x6905a8056c05a8054d0ca5056c05a5054f0ca4056c05a405510c33056c0533", + "0x56c05aa052e0caa056c050c7a0ca9056c050c280c0c6c050c060ca8a5a433", + "0x5ad05530cad056c05abac06560cac056c050c2f0cab056c05aaa9062c0caa", + "0xae054d0c06056c0506054f0c2e056c052e05510c29056c052905660cae056c", + "0xcaf056c050c280c0c6c051105800c0c6c050c060cae062e296905ae056c05", + "0xcb2056c050c2f0cb1056c05b0af062c0cb0056c05b0052e0cb0056c050c7a", + "0x56c056005510c65056c056505660c92056c05b305530cb3056c05b1b20656", + "0x50c0c6c050c0c0c92066065690592056c0592054d0c06056c0506054f0c60", + "0x56905660c13056c051105110c0c6c050c060c606506bd6669066c06050c06", + "0x5240c0c6c056105230c0c6c050c060c5e05be1861066c061305650c69056c", + "0x5a5b062c0c5a056c055a052e0c5a056c050c290c5b056c050c280c0c6c0518", + "0x5660c23056c052105530c21056c05595806560c58056c050c2f0c59056c05", + "0x690523056c0523054d0c06056c0506054f0c66056c056605510c69056c0569", + "0x56c0524054a0c24056c050c440c0c6c055e05230c0c6c050c060c23066669", + "0x860c2c056c050c810c0c6c050c060c2e2906bf2833066c0624666911500c24", + "0x55305880c0c6c050c690c53056c050c870c56056c050c940c2f056c052c05", + "0x2866950c33056c053305660c56056c0556052e0c2f056c052f058a0c53056c", + "0x5005860c50056c050c8c0c0c6c050c060c4a444d11c04f51066c06562f5306", + "0x57205880c51056c055105510c72056c050c870c6f056c050c940c00056c05", + "0x73066c066f00724f5166950c6f056c056f052e0c00056c0500058a0c72056c", + "0x50c940c7a056c057905860c79056c050c8d0c0c6c050c060c77767511c174", + "0x57a058a0c71056c057105880c73056c057305510c71056c050c870c7b056c", + "0x60c78818011c27e7d066c067b7a71747366950c7b056c057b052e0c7a056c", + "0x58305750c8483066c058205740c82056c050c280c0c6c050c210c0c6c050c", + "0x53305660c87056c058605790c86056c058505770c85056c058405760c0c6c", + "0x7d33690587056c0587054d0c7e056c057e054f0c7d056c057d05510c33056c", + "0x56c057805930c8a056c0581054f0c88056c058005510c0c6c050c060c877e", + "0x930c8a056c0576054f0c88056c057505510c0c6c050c060c0cc3050c5b0c8b", + "0x544054f0c88056c054d05510c0c6c050c060c0cc3050c5b0c8b056c057705", + "0x6c058b8c06560c8c056c050c2f0c0c6c050c210c8b056c054a05930c8a056c", + "0x58a054f0c88056c058805510c33056c053305660c8e056c058d05530c8d05", + "0xc8f056c050c280c0c6c050c060c8e8a883369058e056c058e054d0c8a056c", + "0xc93056c050c2f0c91056c05908f062c0c90056c0590052e0c90056c050c7a", + "0x56c052e05510c29056c052905660c95056c059405530c94056c0591930656", + "0x800c0c6c050c060c95062e29690595056c0595054d0c06056c0506054f0c2e", + "0x96062c0c97056c0597052e0c97056c050c7a0c96056c050c280c0c6c051105", + "0x660c9a056c059905530c99056c05987f06560c7f056c050c2f0c98056c0597", + "0x59a056c059a054d0c06056c0506054f0c60056c056005510c65056c056505", + "0x6605960c61056c050c870c13056c056005860c60056c050c810c9a06606569", + "0x6c06181361060566950c13056c0513058a0c61056c056105880c1866066c05", + "0x870c23056c052105860c21056c050c8c0c0c6c050c060c58595a11c45b5e06", + "0xc24056c052405880c5e056c055e05510c3369066c056905960c24056c050c", + "0xc6c050c060c2f2c2e11c52928066c063323245b5e66950c23056c0523058a", + "0x4f65066c056505960c51056c050c870c53056c055605860c56056c050c8d0c", + "0x5351292866950c53056c0553058a0c51056c055105880c28056c052805510c", + "0x72056c050c280c6f056c050c280c0c6c050c060c00504a11c6444d066c064f", + "0x7505990c7675066c0574057f0c74056c057305980c73056c0565696611970c", + "0x56c050c9c0c0c6c050c060c77056c0576059b0c76056c0576059a0c0c6c05", + "0x7b059e0c7b77066c0577059d0c7a056c05796f062c0c79056c0579052e0c79", + "0x62c0c80056c057105130c0c6c057e05330c0c6c057d05330c7e7d71116c05", + "0x6c058205330c848382116c0578059e0c7877066c0577059d0c81056c058072", + "0x6c0577059e0c86056c058581062c0c85056c058305130c0c6c058405330c0c", + "0x8b86062c0c8b056c058a05130c0c6c058805330c0c6c058705330c8a888711", + "0x750c908f066c058c05740c0c6c058d05750c8e8d066c057a05740c8c056c05", + "0x9f0c4d056c054d05510c93056c059005760c91056c058e05760c0c6c058f05", + "0x98979611c79594066c069391444d69a00c93056c0593059f0c91056c059105", + "0xc9a056c059905a20c99056c057f1106a10c7f056c050c5a0c0c6c050c060c", + "0x9a056c059a05a30c95056c0595054f0c94056c059405510c0c056c050c0566", + "0x989b06560c9b056c050c2f0c0c6c051105a40c0c6c050c060c9a95940c6905", + "0x54f0c96056c059605510c0c056c050c05660c9d056c059c05a50c9c056c05", + "0x6c051105a40c0c6c050c060c9d97960c69059d056c059d05a30c97056c0597", + "0x560c9e056c050c2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c", + "0x4a056c054a05510c0c056c050c05660ca0056c059f05a50c9f056c05009e06", + "0x5a40c0c6c050c060ca0504a0c6905a0056c05a005a30c50056c0550054f0c", + "0x56c050c2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c6c0511", + "0x52e05510c0c056c050c05660ca3056c05a205a50ca2056c052fa106560ca1", + "0xc6c050c060ca32c2e0c6905a3056c05a305a30c2c056c052c054f0c2e056c", + "0xc2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c6c051105a40c", + "0x510c0c056c050c05660c39056c05a505a50ca5056c0558a406560ca4056c05", + "0xc696939595a0c690539056c053905a30c59056c0559054f0c5a056c055a05", + "0x500c69c81106050c4f51500c692451500c690c1106050c4f51500c69245150", + "0x66691106050c5651500c690606062851500c60c91106050c4f51500c692451", + "0xca65" + ], + "sierra_program_debug_info": { + "type_names": [ + [0, "RangeCheck"], + [ + 1, + "Const" + ], + [2, "felt252"], + [3, "temp_cairo::StateUpdateContract::LogStateUpdate"], + [4, "temp_cairo::StateUpdateContract::Event"], + [5, "Const"], + [6, "Tuple"], + [7, "Const"], + [8, "u32"], + [9, "StorageAddress"], + [10, "StorageBaseAddress"], + [11, "core::starknet::storage::StoragePointer0Offset::"], + [ + 12, + "Const" + ], + [ + 13, + "Const" + ], + [ + 14, + "Const" + ], + [15, "Const"], + [16, "Array"], + [17, "Snapshot>"], + [18, "core::array::Span::"], + [19, "Tuple>"], + [20, "temp_cairo::StateUpdateContract::ContractState"], + [21, "Unit"], + [22, "Tuple"], + [23, "core::panics::Panic"], + [24, "Tuple>"], + [ + 25, + "core::panics::PanicResult::<(temp_cairo::StateUpdateContract::ContractState, ())>" + ], + [26, "BuiltinCosts"], + [27, "System"], + [ + 28, + "core::panics::PanicResult::<(core::array::Span::,)>" + ], + [ + 29, + "Const" + ], + [30, "core::option::Option::"], + [31, "Box"], + [32, "GasBuiltin"] + ], + "libfunc_names": [ + [0, "revoke_ap_tracking"], + [1, "withdraw_gas"], + [2, "branch_align"], + [3, "struct_deconstruct>"], + [4, "enable_ap_tracking"], + [5, "store_temp"], + [6, "array_snapshot_pop_front"], + [7, "unbox"], + [8, "rename"], + [9, "enum_init, 0>"], + [10, "store_temp>>"], + [11, "store_temp>"], + [12, "jump"], + [13, "struct_construct"], + [14, "enum_init, 1>"], + [15, "enum_match>"], + [16, "disable_ap_tracking"], + [17, "drop>>"], + [18, "drop>"], + [19, "drop"], + [20, "array_new"], + [ + 21, + "const_as_immediate>" + ], + [22, "store_temp"], + [23, "array_append"], + [24, "struct_construct"], + [25, "struct_construct>>"], + [ + 26, + "enum_init,)>, 1>" + ], + [27, "store_temp"], + [28, "store_temp"], + [ + 29, + "store_temp,)>>" + ], + [30, "get_builtin_costs"], + [31, "store_temp"], + [32, "withdraw_gas_all"], + [33, "struct_construct"], + [34, "function_call"], + [ + 35, + "enum_match>" + ], + [36, "drop>"], + [37, "snapshot_take>"], + [38, "drop>"], + [39, "struct_construct>"], + [40, "struct_construct>>"], + [ + 41, + "enum_init,)>, 0>" + ], + [42, "const_as_immediate>"], + [43, "drop"], + [ + 44, + "const_as_immediate>" + ], + [ + 45, + "const_as_immediate>" + ], + [ + 46, + "const_as_immediate>" + ], + [47, "drop>"], + [ + 48, + "storage_base_address_const<289565229787362368933081636443797405535488074065834425092593015835915391953>" + ], + [ + 49, + "struct_construct>" + ], + [ + 50, + "snapshot_take>" + ], + [ + 51, + "drop>" + ], + [ + 52, + "struct_deconstruct>" + ], + [53, "rename"], + [54, "storage_address_from_base"], + [55, "const_as_immediate>"], + [56, "store_temp"], + [57, "store_temp"], + [58, "storage_read_syscall"], + [ + 59, + "storage_base_address_const<1129664241071644691371073118594794953592340198277473102285062464307545102410>" + ], + [ + 60, + "storage_base_address_const<1804974537427402286278400303388660593172206410421526189703894999503593972097>" + ], + [61, "struct_construct>"], + [62, "snapshot_take>"], + [63, "drop>"], + [64, "struct_deconstruct>"], + [65, "store_temp>"], + [66, "const_as_immediate>"], + [67, "storage_write_syscall"], + [68, "dup"], + [69, "struct_construct"], + [70, "enum_init"], + [71, "snapshot_take"], + [72, "drop"], + [73, "store_temp"], + [74, "enum_match"], + [ + 75, + "const_as_immediate>" + ], + [76, "dup"], + [ + 77, + "struct_deconstruct" + ], + [78, "store_temp>"], + [79, "emit_event_syscall"], + [ + 80, + "struct_construct>" + ], + [ + 81, + "enum_init, 0>" + ], + [ + 82, + "store_temp>" + ], + [83, "drop"], + [ + 84, + "enum_init, 1>" + ] + ], + "user_func_names": [ + [0, "temp_cairo::StateUpdateContract::__wrapper__update_state"], + [1, "temp_cairo::StateUpdateContract::__wrapper__get_state"], + [2, "temp_cairo::StateUpdateContract::__wrapper__constructor"], + [3, "temp_cairo::StateUpdateContract::update_state"] + ] + }, + "contract_class_version": "0.1.0", + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x196a5f000a6df3bde4c611e5561aa002ac6cc04b4149c1f02f473b2ef445c76", + "function_idx": 0 + }, + { + "selector": "0x3593f537ca0121e22c58378d40e0f5e2ba89b1c6d92a6990ab3066b68088f9c", + "function_idx": 1 + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [ + { + "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "function_idx": 2 + } + ] + }, + "abi": [ + { "type": "constructor", "name": "constructor", "inputs": [] }, + { + "type": "function", + "name": "update_state", + "inputs": [ + { "name": "block_number", "type": "core::felt252" }, + { "name": "state_root", "type": "core::felt252" }, + { "name": "block_hash", "type": "core::felt252" } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_state", + "inputs": [], + "outputs": [{ "type": "(core::felt252, core::felt252, core::felt252)" }], + "state_mutability": "view" + }, + { + "type": "event", + "name": "temp_cairo::StateUpdateContract::LogStateUpdate", + "kind": "struct", + "members": [ + { "name": "state_root", "type": "core::felt252", "kind": "data" }, + { "name": "block_number", "type": "core::felt252", "kind": "data" }, + { "name": "block_hash", "type": "core::felt252", "kind": "data" } + ] + }, + { + "type": "event", + "name": "temp_cairo::StateUpdateContract::Event", + "kind": "enum", + "variants": [ + { + "name": "LogStateUpdate", + "type": "temp_cairo::StateUpdateContract::LogStateUpdate", + "kind": "nested" + } + ] + } + ] +} diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 3a81f384c..49b7f6304 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -26,11 +26,11 @@ mc-block-import = { workspace = true } mc-block-production = { workspace = true } mc-db = { workspace = true } mc-devnet = { workspace = true } -mc-settlement-client = { workspace = true } mc-gateway-client = { workspace = true } mc-gateway-server = { workspace = true } mc-mempool = { workspace = true } mc-rpc = { workspace = true } +mc-settlement-client = { workspace = true } mc-sync = { workspace = true } mc-telemetry = { workspace = true } mp-block = { workspace = true } diff --git a/tests/js_tests/basic.test.ts b/tests/js_tests/basic.test.ts index 4149c32b2..771cbc420 100644 --- a/tests/js_tests/basic.test.ts +++ b/tests/js_tests/basic.test.ts @@ -87,7 +87,7 @@ async function declareContract({ provider, account }: TestContext) { expect(response.sierra_program).toEqual(sierra.sierra_program); expect(response.abi).toEqual(sierra.abi); expect(response.contract_class_version).toEqual( - sierra.contract_class_version, + sierra.contract_class_version ); expect(response.entry_points_by_type).toEqual(sierra.entry_points_by_type); } else { @@ -119,7 +119,7 @@ async function deployContract({ provider, account }: TestContext) { // Retrieve the class hash for the deployed contract let response = await provider.getClassHashAt( - deployResult.contract_address[0], + deployResult.contract_address[0] ); // Verify that the retrieved class hash matches the computed class hash @@ -139,7 +139,7 @@ async function deployContract({ provider, account }: TestContext) { async function deployAccount({ provider, account }: TestContext) { // Read the Sierra contract class for the account const sierra = readContractSierraInArtifacts( - "openzeppelin_AccountUpgradeable", + "openzeppelin_AccountUpgradeable" ); // Compute the class hash of the account contract @@ -159,7 +159,7 @@ async function deployAccount({ provider, account }: TestContext) { publicKey, classHash, calldata, - 0, + 0 ); // Create a new Account instance with the calculated address and private key @@ -174,7 +174,7 @@ async function deployAccount({ provider, account }: TestContext) { }, { maxFee: 0, - }, + } ); // Wait for the transaction to be confirmed and get the receipt @@ -203,14 +203,14 @@ async function transferFunds({ provider, account }: TestContext) { // Read the ERC20 contract class const erc20ContractData = readContractSierraInArtifacts( - "openzeppelin_ERC20Upgradeable", + "openzeppelin_ERC20Upgradeable" ); // Create an instance of the ERC20 contract const erc20Instance = new Contract( erc20ContractData.abi, ERC20_CONTRACT_ADDRESS, - provider, + provider ); // Connect the account to the ERC20 contract instance @@ -218,10 +218,11 @@ async function transferFunds({ provider, account }: TestContext) { // Get the initial balances of sender and receiver const preTransactSenderBalance = await erc20Instance.balance_of( - SIGNER_CONTRACT_ADDRESS, + SIGNER_CONTRACT_ADDRESS + ); + const preTransactReceiverBalance = await erc20Instance.balance_of( + RECEIVER_ADDRESS ); - const preTransactReceiverBalance = - await erc20Instance.balance_of(RECEIVER_ADDRESS); // Execute the transfer // Note: We are setting maxFee to zero here @@ -236,7 +237,7 @@ async function transferFunds({ provider, account }: TestContext) { }, { maxFee: 0, - }, + } ); // Wait for the transfer transaction to be confirmed @@ -244,19 +245,20 @@ async function transferFunds({ provider, account }: TestContext) { // Get the final balances of sender and receiver const postTransactSenderBalance = await erc20Instance.balance_of( - SIGNER_CONTRACT_ADDRESS, + SIGNER_CONTRACT_ADDRESS + ); + const postTransactReceiverBalance = await erc20Instance.balance_of( + RECEIVER_ADDRESS ); - const postTransactReceiverBalance = - await erc20Instance.balance_of(RECEIVER_ADDRESS); // Verify that the balances have been updated correctly // Note: In real world case, the sender balance would be // preTransactionSenderBalance - TRANSFER_AMOUNT - Fees // but we had fees set to zero while executing transaction expect(postTransactSenderBalance).toBe( - preTransactSenderBalance - TRANSFER_AMOUNT, + preTransactSenderBalance - TRANSFER_AMOUNT ); expect(postTransactReceiverBalance).toBe( - preTransactReceiverBalance + TRANSFER_AMOUNT, + preTransactReceiverBalance + TRANSFER_AMOUNT ); } diff --git a/tests/js_tests/utils.ts b/tests/js_tests/utils.ts index f75eded24..e2462f96e 100644 --- a/tests/js_tests/utils.ts +++ b/tests/js_tests/utils.ts @@ -8,10 +8,10 @@ export const readContractCasm = (name: string): CompiledSierraCasm => .readFileSync( path.resolve( __dirname, - `../../cairo/target/dev/${name}.compiled_contract_class.json`, - ), + `../../cairo/target/dev/${name}.compiled_contract_class.json` + ) ) - .toString("ascii"), + .toString("ascii") ); export const readContractSierra = (name: string): CompiledSierra => @@ -20,10 +20,10 @@ export const readContractSierra = (name: string): CompiledSierra => .readFileSync( path.resolve( __dirname, - `../../cairo/target/dev/${name}.contract_class.json`, - ), + `../../cairo/target/dev/${name}.contract_class.json` + ) ) - .toString("ascii"), + .toString("ascii") ); export const readContractSierraInArtifacts = (name: string): CompiledSierra => @@ -32,8 +32,8 @@ export const readContractSierraInArtifacts = (name: string): CompiledSierra => .readFileSync( path.resolve( __dirname, - `../../cairo-artifacts/${name}.contract_class.json`, - ), + `../../cairo-artifacts/${name}.contract_class.json` + ) ) - .toString("ascii"), + .toString("ascii") ); From 661cd330bdc727266d776df95cee1e35ec03f1d4 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Sat, 21 Dec 2024 04:12:23 +0530 Subject: [PATCH 06/23] feat: added update state worker test for starknet client --- .github/workflows/coverage.yml | 6 +- .github/workflows/rust-test.yml | 6 +- .../settlement_client/src/starknet/mod.rs | 2 +- .../settlement_client/src/state_update.rs | 95 +++++++++++++++++++ 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 1ce542892..4cae2cb91 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -39,9 +39,13 @@ jobs: with: version: nightly + # TODO : For now madara binary is stored in aws s3 bucket : + # After the proper release binaries are implemented + # We can directly use that and we can remove this + # temporary AWS implementation - name: Download madara binary for l2 client testing run: | - curl -L https://madara-test-binary.s3.us-west-1.amazonaws.com/madara -o ./test-artifacts/madara + curl -L https://madara-test-binary.s3.us-west-1.amazonaws.com/madara-linux -o ./test-artifacts/madara chmod +x ./test-artifacts/madara - name: Build and run tests diff --git a/.github/workflows/rust-test.yml b/.github/workflows/rust-test.yml index b414b8370..62a5dfe44 100644 --- a/.github/workflows/rust-test.yml +++ b/.github/workflows/rust-test.yml @@ -30,9 +30,13 @@ jobs: while ! nc -z localhost 8545; do sleep 1 done + # TODO : For now madara binary is stored in aws s3 bucket : + # After the proper release binaries are implemented + # We can directly use that and we can remove this + # temporary AWS implementation - name: Download madara binary for l2 client testing run: | - curl -L https://madara-test-binary.s3.us-west-1.amazonaws.com/madara -o ./test-artifacts/madara + curl -L https://madara-test-binary.s3.us-west-1.amazonaws.com/madara-linux -o ./test-artifacts/madara chmod +x ./test-artifacts/madara - name: Run unit tests diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index 6ea535edb..55e8d1d1d 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -19,7 +19,7 @@ use tracing::{error, trace}; use url::Url; #[cfg(test)] -mod utils; +pub mod utils; #[derive(Debug)] pub struct StarknetClient { diff --git a/crates/client/settlement_client/src/state_update.rs b/crates/client/settlement_client/src/state_update.rs index 84c94d61e..8ce7c034d 100644 --- a/crates/client/settlement_client/src/state_update.rs +++ b/crates/client/settlement_client/src/state_update.rs @@ -167,3 +167,98 @@ mod eth_client_event_subscription_test { assert_eq!(block_in_db, Some(L2_BLOCK_NUMBER), "Block in DB does not match expected L2 block number"); } } + +#[cfg(test)] +mod starknet_client_event_subscription_test { + use crate::client::ClientTrait; + use crate::gas_price::L1BlockMetrics; + use crate::starknet::utils::{prepare_starknet_client_test, send_state_update, MADARA_PORT}; + use crate::starknet::{StarknetClient, StarknetClientConfig}; + use crate::state_update::{state_update_worker, StateUpdate}; + use mc_db::DatabaseService; + use mp_chain_config::ChainConfig; + use mp_utils::service::ServiceContext; + use rstest::rstest; + use starknet_providers::jsonrpc::HttpTransport; + use starknet_providers::JsonRpcClient; + use starknet_types_core::felt::Felt; + use std::str::FromStr; + use std::sync::Arc; + use std::time::Duration; + use tempfile::TempDir; + use url::Url; + + #[rstest] + #[tokio::test] + async fn listen_and_update_state_when_event_fired_starknet_client() -> anyhow::Result<()> { + // Setting up the DB and l1 block metrics + // ================================================ + + let chain_info = Arc::new(ChainConfig::madara_test()); + + // Set up database paths + let temp_dir = TempDir::new().expect("issue while creating temporary directory"); + let base_path = temp_dir.path().join("data"); + let backup_dir = Some(temp_dir.path().join("backups")); + + // Initialize database service + let db = Arc::new( + DatabaseService::new(&base_path, backup_dir, false, chain_info.clone(), Default::default()) + .await + .expect("Failed to create database service"), + ); + + // Set up metrics service + let l1_block_metrics = L1BlockMetrics::register().unwrap(); + + // Making Starknet client and start worker + // ================================================ + // Here we need to have madara variable otherwise it will + // get dropped and will kill the madara. + #[allow(unused_variables)] + let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, + l2_contract_address: deployed_address, + l1_block_metrics, + }) + .await?; + + let listen_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + state_update_worker::>>( + Arc::clone(db.backend()), + Arc::new(Box::new(starknet_client)), + ServiceContext::new_for_testing(), + ) + .await + .expect("Failed to init state update worker.") + }) + }; + + // Firing the state update event + send_state_update( + &account, + deployed_address, + StateUpdate { + block_number: 100, + global_root: Felt::from_str("0xbeef")?, + block_hash: Felt::from_str("0xbeef")?, + }, + ) + .await?; + + // Wait for this update to be registered in the DB. Approx 10 secs + tokio::time::sleep(Duration::from_secs(10)).await; + + // Verify the block number + let block_in_db = + db.backend().get_l1_last_confirmed_block().expect("Failed to get L2 last confirmed block number"); + + listen_handle.abort(); + assert_eq!(block_in_db, Some(100), "Block in DB does not match expected L3 block number"); + Ok(()) + } +} From 62fb337429eb26af176114f7a91d5b5ef9395a36 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Thu, 26 Dec 2024 19:13:36 +0530 Subject: [PATCH 07/23] feat : added messaging implementation for l2 client & resolved comments 1 --- Cargo.lock | 1 + crates/client/settlement_client/Cargo.toml | 1 + crates/client/settlement_client/src/client.rs | 48 +- .../client/settlement_client/src/eth/mod.rs | 194 +- .../client/settlement_client/src/gas_price.rs | 36 +- crates/client/settlement_client/src/lib.rs | 2 +- .../src/{l1_messaging.rs => messaging.rs} | 480 ++-- .../settlement_client/src/starknet/mod.rs | 353 ++- .../test_contracts/messaging_test.cairo | 149 ++ .../test_contracts/messaging_test.casm.json | 1982 +++++++++++++++++ .../test_contracts/messaging_test.sierra.json | 1470 ++++++++++++ .../settlement_client/src/starknet/utils.rs | 61 +- .../settlement_client/src/state_update.rs | 19 +- crates/client/settlement_client/src/sync.rs | 18 +- crates/node/src/main.rs | 11 +- crates/node/src/service/l1.rs | 33 +- 16 files changed, 4494 insertions(+), 364 deletions(-) rename crates/client/settlement_client/src/{l1_messaging.rs => messaging.rs} (61%) create mode 100644 crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo create mode 100644 crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json create mode 100644 crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json diff --git a/Cargo.lock b/Cargo.lock index fd507f9ae..415dd3de6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5847,6 +5847,7 @@ dependencies = [ "starknet-accounts", "starknet-contract", "starknet-core", + "starknet-crypto 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "starknet-providers", "starknet-signers", "starknet-types-core 0.1.7 (git+https://github.com/kasarlabs/types-rs.git?branch=feat-deserialize-v0.1.7)", diff --git a/crates/client/settlement_client/Cargo.toml b/crates/client/settlement_client/Cargo.toml index df739b808..034e6bcaf 100644 --- a/crates/client/settlement_client/Cargo.toml +++ b/crates/client/settlement_client/Cargo.toml @@ -46,6 +46,7 @@ serde_json = "1" starknet-accounts = "0.11.0" starknet-contract = "0.11.0" starknet-core = { workspace = true } +starknet-crypto = { workspace = true } starknet-providers = { workspace = true } starknet-signers = { workspace = true } thiserror.workspace = true diff --git a/crates/client/settlement_client/src/client.rs b/crates/client/settlement_client/src/client.rs index 7f6447842..9ba759907 100644 --- a/crates/client/settlement_client/src/client.rs +++ b/crates/client/settlement_client/src/client.rs @@ -2,21 +2,19 @@ use crate::eth::StarknetCoreContract::StarknetCoreContractInstance; use crate::gas_price::L1BlockMetrics; use crate::state_update::StateUpdate; use alloy::contract::Event; -use alloy::primitives::FixedBytes; use alloy::providers::RootProvider; use alloy::sol_types::SolEvent; use alloy::transports::http::{Client, Http}; use async_trait::async_trait; +use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; +use mc_mempool::Mempool; use mp_utils::service::ServiceContext; +use starknet_api::core::ChainId; +use starknet_api::transaction::L1HandlerTransaction; use starknet_types_core::felt::Felt; use std::sync::Arc; -pub enum ClientType { - ETH, - STARKNET, -} - pub enum CoreContractInstance { Ethereum(StarknetCoreContractInstance, RootProvider>>), Starknet(Felt), @@ -34,15 +32,14 @@ impl CoreContractInstance { #[async_trait] pub trait ClientTrait: Send + Sync { - // Provider type used by the implementation - type Provider; // Configuration type used for initialization type Config; + // Event struct type + type EventStruct; // Basic getter functions fn get_l1_block_metrics(&self) -> &L1BlockMetrics; fn get_core_contract_instance(&self) -> CoreContractInstance; - fn get_client_type(&self) -> ClientType; // Create a new instance of the client async fn new(config: Self::Config) -> anyhow::Result @@ -68,14 +65,43 @@ pub trait ClientTrait: Send + Sync { // Get initial state from client async fn get_initial_state(&self) -> anyhow::Result; + + // Listen for update state events async fn listen_for_update_state_events( &self, backend: Arc, ctx: ServiceContext, ) -> anyhow::Result<()>; + // Listen for messaging events + async fn listen_for_messaging_events( + &self, + backend: Arc, + ctx: ServiceContext, + last_synced_event_block: LastSyncedEventBlock, + chain_id: ChainId, + mempool: Arc, + ) -> anyhow::Result<()>; + // get gas prices - async fn get_eth_gas_prices(&self) -> anyhow::Result<(u128, u128)>; + async fn get_gas_prices(&self) -> anyhow::Result<(u128, u128)>; + + // Get message hash from event + fn get_messaging_hash(&self, event: &Self::EventStruct) -> anyhow::Result>; + + // Process message received from event + async fn process_message( + &self, + backend: &MadaraBackend, + event: &Self::EventStruct, + settlement_layer_block_number: &Option, + event_index: &Option, + chain_id: &ChainId, + mempool: Arc, + ) -> anyhow::Result>; + + // Parse the message into madara l1 handler transaction + fn parse_handle_message_transaction(&self, event: &Self::EventStruct) -> anyhow::Result; /// Get cancellation status of an L1 to L2 message /// @@ -90,5 +116,5 @@ pub trait ClientTrait: Send + Sync { /// - 0 if the message has not been cancelled /// - timestamp of the cancellation if it has been cancelled /// - An Error if the call fail - async fn get_l1_to_l2_message_cancellations(&self, msg_hash: FixedBytes<32>) -> anyhow::Result; + async fn get_l1_to_l2_message_cancellations(&self, msg_hash: Vec) -> anyhow::Result; } diff --git a/crates/client/settlement_client/src/eth/mod.rs b/crates/client/settlement_client/src/eth/mod.rs index 77e2dd607..c8d021075 100644 --- a/crates/client/settlement_client/src/eth/mod.rs +++ b/crates/client/settlement_client/src/eth/mod.rs @@ -1,20 +1,25 @@ -use crate::client::{ClientTrait, ClientType, CoreContractInstance}; -use crate::eth::StarknetCoreContract::StarknetCoreContractInstance; +use crate::client::{ClientTrait, CoreContractInstance}; +use crate::eth::StarknetCoreContract::{LogMessageToL2, StarknetCoreContractInstance}; use crate::gas_price::L1BlockMetrics; use crate::state_update::{update_l1, StateUpdate}; use crate::utils::{convert_log_state_update, u256_to_felt}; use alloy::eips::BlockNumberOrTag; -use alloy::primitives::{Address, FixedBytes}; +use alloy::primitives::{keccak256, Address, B256, U256}; use alloy::providers::{Provider, ProviderBuilder, ReqwestProvider, RootProvider}; use alloy::rpc::types::Filter; use alloy::sol; +use alloy::sol_types::SolValue; use alloy::transports::http::{Client, Http}; use anyhow::{bail, Context}; use async_trait::async_trait; use bitvec::macros::internal::funty::Fundamental; use futures::StreamExt; +use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; +use mc_mempool::{Mempool, MempoolProvider}; use mp_utils::service::ServiceContext; +use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; +use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; use starknet_types_core::felt::Felt; use std::sync::Arc; use url::Url; @@ -56,8 +61,8 @@ impl Clone for EthereumClient { #[async_trait] impl ClientTrait for EthereumClient { - type Provider = RootProvider>; type Config = EthereumClientConfig; + type EventStruct = LogMessageToL2; fn get_l1_block_metrics(&self) -> &L1BlockMetrics { &self.l1_block_metrics @@ -67,10 +72,6 @@ impl ClientTrait for EthereumClient { CoreContractInstance::Ethereum(self.l1_core_contract.clone()) } - fn get_client_type(&self) -> ClientType { - ClientType::ETH - } - /// Create a new EthereumClient instance with the given RPC URL async fn new(config: EthereumClientConfig) -> anyhow::Result { let provider = ProviderBuilder::new().on_http(config.url); @@ -169,7 +170,94 @@ impl ClientTrait for EthereumClient { Ok(()) } - async fn get_eth_gas_prices(&self) -> anyhow::Result<(u128, u128)> { + async fn listen_for_messaging_events( + &self, + backend: Arc, + mut ctx: ServiceContext, + last_synced_event_block: LastSyncedEventBlock, + chain_id: ChainId, + mempool: Arc, + ) -> anyhow::Result<()> { + let contract_instance = self.get_core_contract_instance(); + let event_filter = contract_instance.event_filter::(); + + let mut event_stream = event_filter? + .from_block(last_synced_event_block.block_number) + .to_block(BlockNumberOrTag::Finalized) + .watch() + .await + .context( + "Failed to watch event filter - Ensure you are using an L1 RPC endpoint that points to an archive node", + )? + .into_stream(); + + while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { + if let Ok((event, meta)) = event_result { + tracing::info!( + "⟠ Processing L1 Message from block: {:?}, transaction_hash: {:?}, log_index: {:?}, fromAddress: {:?}", + meta.block_number, + meta.transaction_hash, + meta.log_index, + event.fromAddress + ); + + // Check if cancellation was initiated + let event_hash = self.get_messaging_hash(&event)?; + tracing::info!( + "⟠ Checking for cancelation, event hash : {:?}", + Felt::from_bytes_be_slice(event_hash.as_slice()) + ); + let cancellation_timestamp = self.get_l1_to_l2_message_cancellations(event_hash.to_vec()).await?; + if cancellation_timestamp != Felt::ZERO { + tracing::info!("⟠ L1 Message was cancelled in block at timestamp : {:?}", cancellation_timestamp); + let tx_nonce = Nonce(u256_to_felt(event.nonce)?); + // cancelled message nonce should be inserted to avoid reprocessing + match backend.has_l1_messaging_nonce(tx_nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(tx_nonce)?; + } + Ok(true) => {} + Err(e) => { + tracing::error!("⟠ Unexpected DB error: {:?}", e); + return Err(e.into()); + } + }; + continue; + } + + match self + .process_message(&backend, &event, &meta.block_number, &meta.log_index, &chain_id, mempool.clone()) + .await + { + Ok(Some(tx_hash)) => { + tracing::info!( + "⟠ L1 Message from block: {:?}, transaction_hash: {:?}, log_index: {:?} submitted, \ + transaction hash on L2: {:?}", + meta.block_number, + meta.transaction_hash, + meta.log_index, + tx_hash + ); + } + Ok(None) => {} + Err(e) => { + tracing::error!( + "⟠ Unexpected error while processing L1 Message from block: {:?}, transaction_hash: {:?}, \ + log_index: {:?}, error: {:?}", + meta.block_number, + meta.transaction_hash, + meta.log_index, + e + ) + } + } + } + } + + Ok(()) + } + + async fn get_gas_prices(&self) -> anyhow::Result<(u128, u128)> { let block_number = self.get_latest_block_number().await?; let fee_history = self.provider.get_fee_history(300, BlockNumberOrTag::Number(block_number), &[]).await?; @@ -189,6 +277,89 @@ impl ClientTrait for EthereumClient { Ok((*eth_gas_price, avg_blob_base_fee)) } + fn get_messaging_hash(&self, event: &Self::EventStruct) -> anyhow::Result> { + let data = ( + [0u8; 12], + event.fromAddress.0 .0, + event.toAddress, + event.nonce, + event.selector, + U256::from(event.payload.len()), + event.payload.clone(), + ); + Ok(keccak256(data.abi_encode_packed()).as_slice().to_vec()) + } + + async fn process_message( + &self, + backend: &MadaraBackend, + event: &Self::EventStruct, + settlement_layer_block_number: &Option, + event_index: &Option, + _chain_id: &ChainId, + mempool: Arc, + ) -> anyhow::Result> { + let transaction = self.parse_handle_message_transaction(event)?; + let tx_nonce = transaction.nonce; + let fees: u128 = event.fee.try_into()?; + + // Ensure that L1 message has not been executed + match backend.has_l1_messaging_nonce(tx_nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(tx_nonce)?; + } + Ok(true) => { + tracing::debug!("⟠ Event already processed: {:?}", transaction); + return Ok(None); + } + Err(e) => { + tracing::error!("⟠ Unexpected DB error: {:?}", e); + return Err(e.into()); + } + }; + + let res = mempool.accept_l1_handler_tx(transaction.into(), fees)?; + + // TODO: remove unwraps + // Ques: shall it panic if no block number of event_index? + let block_sent = LastSyncedEventBlock::new(settlement_layer_block_number.unwrap(), event_index.unwrap()); + backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; + + Ok(Some(res.transaction_hash)) + } + + fn parse_handle_message_transaction(&self, event: &Self::EventStruct) -> anyhow::Result { + // L1 from address. + let from_address = u256_to_felt(event.fromAddress.into_word().into())?; + + // L2 contract to call. + let contract_address = u256_to_felt(event.toAddress)?; + + // Function of the contract to call. + let entry_point_selector = u256_to_felt(event.selector)?; + + // L1 message nonce. + let nonce = u256_to_felt(event.nonce)?; + + let event_payload = event.payload.clone().into_iter().map(u256_to_felt).collect::>>()?; + + let calldata: Calldata = { + let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); + calldata.push(from_address); + calldata.extend(event_payload); + + Calldata(Arc::new(calldata)) + }; + + Ok(L1HandlerTransaction { + nonce: Nonce(nonce), + contract_address: ContractAddress(contract_address.try_into()?), + entry_point_selector: EntryPointSelector(entry_point_selector), + calldata, + version: TransactionVersion(Felt::ZERO), + }) + } + /// Get cancellation status of an L1 to L2 message /// /// This function query the core contract to know if a L1->L2 message has been cancelled @@ -202,9 +373,10 @@ impl ClientTrait for EthereumClient { /// - 0 if the message has not been cancelled /// - timestamp of the cancellation if it has been cancelled /// - An Error if the call fail - async fn get_l1_to_l2_message_cancellations(&self, msg_hash: FixedBytes<32>) -> anyhow::Result { + async fn get_l1_to_l2_message_cancellations(&self, msg_hash: Vec) -> anyhow::Result { //l1ToL2MessageCancellations - let cancellation_timestamp = self.l1_core_contract.l1ToL2MessageCancellations(msg_hash).call().await?; + let cancellation_timestamp = + self.l1_core_contract.l1ToL2MessageCancellations(B256::from_slice(msg_hash.as_slice())).call().await?; u256_to_felt(cancellation_timestamp._0) } } diff --git a/crates/client/settlement_client/src/gas_price.rs b/crates/client/settlement_client/src/gas_price.rs index 7ade360b5..6c997bb01 100644 --- a/crates/client/settlement_client/src/gas_price.rs +++ b/crates/client/settlement_client/src/gas_price.rs @@ -56,8 +56,8 @@ impl L1BlockMetrics { } } -pub async fn gas_price_worker_once( - settlement_client: Arc>>, +pub async fn gas_price_worker_once( + settlement_client: Arc>>, l1_gas_provider: &GasPriceProvider, gas_price_poll_ms: Duration, ) -> anyhow::Result<()> { @@ -81,8 +81,8 @@ pub async fn gas_price_worker_once( anyhow::Ok(()) } -pub async fn gas_price_worker( - settlement_client: Arc>>, +pub async fn gas_price_worker( + settlement_client: Arc>>, l1_gas_provider: GasPriceProvider, gas_price_poll_ms: Duration, mut ctx: ServiceContext, @@ -98,11 +98,11 @@ pub async fn gas_price_worker( anyhow::Ok(()) } -async fn update_gas_price( - settlement_client: Arc>>, +async fn update_gas_price( + settlement_client: Arc>>, l1_gas_provider: &GasPriceProvider, ) -> anyhow::Result<()> { - let (eth_gas_price, avg_blob_base_fee) = settlement_client.get_eth_gas_prices().await?; + let (eth_gas_price, avg_blob_base_fee) = settlement_client.get_gas_prices().await?; l1_gas_provider.update_eth_l1_gas_price(eth_gas_price); l1_gas_provider.update_eth_l1_data_gas_price(avg_blob_base_fee); @@ -169,8 +169,7 @@ mod eth_client_gas_price_worker_test { use super::*; use crate::eth::eth_client_getter_test::{create_ethereum_client, get_shared_anvil}; use crate::eth::EthereumClientConfig; - use alloy::providers::RootProvider; - use alloy::transports::http::{Client, Http}; + use crate::eth::StarknetCoreContract::LogMessageToL2; use httpmock::{MockServer, Regex}; use mc_mempool::GasPriceProvider; use serial_test::serial; @@ -190,7 +189,7 @@ mod eth_client_gas_price_worker_test { let eth_client = eth_client.clone(); let l1_gas_provider = l1_gas_provider.clone(); async move { - gas_price_worker::>>( + gas_price_worker::( Arc::new(Box::new(eth_client)), l1_gas_provider, Duration::from_millis(200), @@ -230,7 +229,7 @@ mod eth_client_gas_price_worker_test { let l1_gas_provider = GasPriceProvider::new(); // Run the worker for a short time - let worker_handle = gas_price_worker_once::>>( + let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), @@ -255,7 +254,7 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.set_gas_price_sync_enabled(false); // Run the worker for a short time - let worker_handle = gas_price_worker_once::>>( + let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), @@ -280,7 +279,7 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.set_data_gas_price_sync_enabled(false); // Run the worker for a short time - let worker_handle = gas_price_worker_once::>>( + let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), @@ -334,7 +333,7 @@ mod eth_client_gas_price_worker_test { let result = timeout( timeout_duration, - gas_price_worker::>>( + gas_price_worker::( Arc::new(Box::new(eth_client)), l1_gas_provider.clone(), Duration::from_millis(200), @@ -371,12 +370,9 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.update_last_update_timestamp(); // Update gas prices - update_gas_price::>>( - Arc::new(Box::new(eth_client)), - &l1_gas_provider, - ) - .await - .expect("Failed to update gas prices"); + update_gas_price::(Arc::new(Box::new(eth_client)), &l1_gas_provider) + .await + .expect("Failed to update gas prices"); // Access the updated gas prices let updated_prices = l1_gas_provider.get_gas_prices(); diff --git a/crates/client/settlement_client/src/lib.rs b/crates/client/settlement_client/src/lib.rs index 9b7b37ec8..3f0f0e867 100644 --- a/crates/client/settlement_client/src/lib.rs +++ b/crates/client/settlement_client/src/lib.rs @@ -2,7 +2,7 @@ pub mod client; pub mod error; pub mod eth; pub mod gas_price; -pub mod l1_messaging; +pub mod messaging; pub mod starknet; pub mod state_update; pub mod sync; diff --git a/crates/client/settlement_client/src/l1_messaging.rs b/crates/client/settlement_client/src/messaging.rs similarity index 61% rename from crates/client/settlement_client/src/l1_messaging.rs rename to crates/client/settlement_client/src/messaging.rs index 307bf35b3..e98224ca5 100644 --- a/crates/client/settlement_client/src/l1_messaging.rs +++ b/crates/client/settlement_client/src/messaging.rs @@ -1,25 +1,29 @@ use crate::client::ClientTrait; -use crate::eth::StarknetCoreContract::LogMessageToL2; -use crate::utils::u256_to_felt; -use alloy::eips::BlockNumberOrTag; -use alloy::primitives::{keccak256, FixedBytes, U256}; -use alloy::sol_types::SolValue; -use anyhow::Context; -use futures::StreamExt; -use mc_db::{l1_db::LastSyncedEventBlock, MadaraBackend}; -use mc_mempool::{Mempool, MempoolProvider}; +use mc_db::MadaraBackend; +use mc_mempool::Mempool; use mp_utils::service::ServiceContext; -use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; -use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; +use starknet_api::core::ChainId; use starknet_types_core::felt::Felt; use std::sync::Arc; -pub async fn sync( +// L2 (Starknet) <-> L3 messaging format +// GitHub Ref : https://github.com/cartridge-gg/piltover/blob/saya/src/messaging/component.cairo#L85 +#[derive(Clone)] +pub struct MessageSent { + pub message_hash: Felt, + pub from: Felt, + pub to: Felt, + pub selector: Felt, + pub nonce: Felt, + pub payload: Vec, +} + +pub async fn sync( + settlement_client: Arc>>, backend: Arc, - client: Arc>>, chain_id: ChainId, mempool: Arc, - mut ctx: ServiceContext, + ctx: ServiceContext, ) -> anyhow::Result<()> { tracing::info!("⟠ Starting L1 Messages Syncing..."); @@ -34,162 +38,272 @@ pub async fn sync( } }; - let contract_instance = client.get_core_contract_instance(); - let event_filter = contract_instance.event_filter::(); + settlement_client.listen_for_messaging_events(backend, ctx, last_synced_event_block, chain_id, mempool).await?; - let mut event_stream = event_filter? - .from_block(last_synced_event_block.block_number) - .to_block(BlockNumberOrTag::Finalized) - .watch() - .await - .context( - "Failed to watch event filter - Ensure you are using an L1 RPC endpoint that points to an archive node", - )? - .into_stream(); - - while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { - if let Ok((event, meta)) = event_result { - tracing::info!( - "⟠ Processing L1 Message from block: {:?}, transaction_hash: {:?}, log_index: {:?}, fromAddress: {:?}", - meta.block_number, - meta.transaction_hash, - meta.log_index, - event.fromAddress - ); - - // Check if cancellation was initiated - let event_hash = get_l1_to_l2_msg_hash(&event)?; - tracing::info!("⟠ Checking for cancelation, event hash : {:?}", event_hash); - let cancellation_timestamp = client.get_l1_to_l2_message_cancellations(event_hash).await?; - if cancellation_timestamp != Felt::ZERO { - tracing::info!("⟠ L1 Message was cancelled in block at timestamp : {:?}", cancellation_timestamp); - let tx_nonce = Nonce(u256_to_felt(event.nonce)?); - // cancelled message nonce should be inserted to avoid reprocessing - match backend.has_l1_messaging_nonce(tx_nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(tx_nonce)?; - } - Ok(true) => {} - Err(e) => { - tracing::error!("⟠ Unexpected DB error: {:?}", e); - return Err(e.into()); - } - }; - continue; - } + Ok(()) +} + +#[cfg(test)] +mod l2_messaging_test { + use crate::client::ClientTrait; + use crate::gas_price::L1BlockMetrics; + use crate::messaging::sync; + use crate::starknet::utils::{ + cancel_messaging_event, fire_messaging_event, prepare_starknet_client_messaging_test, MadaraProcess, + StarknetAccount, MADARA_PORT, + }; + use crate::starknet::{StarknetClient, StarknetClientConfig}; + use mc_db::DatabaseService; + use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; + use mp_chain_config::ChainConfig; + use mp_utils::service::ServiceContext; + use rstest::{fixture, rstest}; + use starknet_api::core::Nonce; + use starknet_types_core::felt::Felt; + use std::sync::Arc; + use std::time::Duration; + use tempfile::TempDir; + use tracing_test::traced_test; + use url::Url; - match process_l1_message(&backend, &event, &meta.block_number, &meta.log_index, &chain_id, mempool.clone()) + struct TestRunnerStarknet { + #[allow(dead_code)] + madara: MadaraProcess, // Not used but needs to stay in scope otherwise it will be dropped + account: StarknetAccount, + chain_config: Arc, + db_service: Arc, + deployed_address: Felt, + starknet_client: StarknetClient, + mempool: Arc, + } + + #[fixture] + async fn setup_test_env_starknet() -> TestRunnerStarknet { + let (account, deployed_contract_address, madara) = prepare_starknet_client_messaging_test().await.unwrap(); + + // Set up chain info + let chain_config = Arc::new(ChainConfig::madara_test()); + + // Set up database paths + let temp_dir = TempDir::new().expect("issue while creating temporary directory"); + let base_path = temp_dir.path().join("data"); + let backup_dir = Some(temp_dir.path().join("backups")); + + // Initialize database service + let db = Arc::new( + DatabaseService::new(&base_path, backup_dir, false, chain_config.clone(), Default::default()) .await - { - Ok(Some(tx_hash)) => { - tracing::info!( - "⟠ L1 Message from block: {:?}, transaction_hash: {:?}, log_index: {:?} submitted, \ - transaction hash on L2: {:?}", - meta.block_number, - meta.transaction_hash, - meta.log_index, - tx_hash - ); - } - Ok(None) => {} - Err(e) => { - tracing::error!( - "⟠ Unexpected error while processing L1 Message from block: {:?}, transaction_hash: {:?}, \ - log_index: {:?}, error: {:?}", - meta.block_number, - meta.transaction_hash, - meta.log_index, - e - ) - } - } + .expect("Failed to create database service"), + ); + + let l1_block_metrics = L1BlockMetrics::register().unwrap(); + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str()).unwrap(), + l2_contract_address: deployed_contract_address, + l1_block_metrics, + }) + .await + .unwrap(); + + let l1_gas_setter = GasPriceProvider::new(); + let l1_data_provider: Arc = Arc::new(l1_gas_setter.clone()); + + let mempool = Arc::new(Mempool::new( + Arc::clone(db.backend()), + Arc::clone(&l1_data_provider), + MempoolLimits::for_testing(), + )); + + TestRunnerStarknet { + madara, + account, + chain_config, + db_service: db, + deployed_address: deployed_contract_address, + starknet_client, + mempool, } } - Ok(()) -} + #[rstest] + #[traced_test] + #[tokio::test] + async fn e2e_test_basic_workflow_starknet( + #[future] setup_test_env_starknet: TestRunnerStarknet, + ) -> anyhow::Result<()> { + // Initial Setup + // ================================== + let TestRunnerStarknet { + madara: _madara, + account, + chain_config, + db_service: db, + deployed_address: deployed_contract_address, + starknet_client, + mempool, + } = setup_test_env_starknet.await; + + // Start worker handle + // ================================== + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(starknet_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; -async fn process_l1_message( - backend: &MadaraBackend, - event: &LogMessageToL2, - l1_block_number: &Option, - event_index: &Option, - _chain_id: &ChainId, - mempool: Arc, -) -> anyhow::Result> { - let transaction = parse_handle_l1_message_transaction(event)?; - let tx_nonce = transaction.nonce; - let fees: u128 = event.fee.try_into()?; - - // Ensure that L1 message has not been executed - match backend.has_l1_messaging_nonce(tx_nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(tx_nonce)?; - } - Ok(true) => { - tracing::debug!("⟠ Event already processed: {:?}", transaction); - return Ok(None); - } - Err(e) => { - tracing::error!("⟠ Unexpected DB error: {:?}", e); - return Err(e.into()); - } - }; + // Firing the event + let fire_event_block_number = fire_messaging_event(&account, deployed_contract_address).await?; + tokio::time::sleep(Duration::from_secs(10)).await; - let res = mempool.accept_l1_handler_tx(transaction.into(), fees)?; + // Log asserts + // =========== + assert!(logs_contain("fromAddress: 0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493")); + // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 + // expecting the same in logs + assert!(logs_contain("event hash : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0")); - // TODO: remove unwraps - // Ques: shall it panic if no block number of event_index? - let block_sent = LastSyncedEventBlock::new(l1_block_number.unwrap(), event_index.unwrap()); - backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; + // Assert that the event is well stored in db + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_eq!(last_block.block_number, fire_event_block_number); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + assert!(db.backend().has_l1_messaging_nonce(nonce)?); - Ok(Some(res.transaction_hash)) -} + // Cancelling worker + worker_handle.abort(); + Ok(()) + } -pub fn parse_handle_l1_message_transaction(event: &LogMessageToL2) -> anyhow::Result { - // L1 from address. - let from_address = u256_to_felt(event.fromAddress.into_word().into())?; + #[rstest] + #[traced_test] + #[tokio::test] + async fn e2e_test_already_processed_event_starknet( + #[future] setup_test_env_starknet: TestRunnerStarknet, + ) -> anyhow::Result<()> { + // Initial Setup + // ================================== + let TestRunnerStarknet { + madara: _madara, + account, + chain_config, + db_service: db, + deployed_address: deployed_contract_address, + starknet_client, + mempool, + } = setup_test_env_starknet.await; + + // Start worker handle + // ================================== + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(starknet_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; - // L2 contract to call. - let contract_address = u256_to_felt(event.toAddress)?; + // Firing the event + let fire_event_block_number = fire_messaging_event(&account, deployed_contract_address).await?; + tokio::time::sleep(Duration::from_secs(10)).await; - // Function of the contract to call. - let entry_point_selector = u256_to_felt(event.selector)?; + // Log asserts + // =========== + assert!(logs_contain("fromAddress: 0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493")); + // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 + // expecting the same in logs + assert!(logs_contain("event hash : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0")); - // L1 message nonce. - let nonce = u256_to_felt(event.nonce)?; + // Assert that the event is well stored in db + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_eq!(last_block.block_number, fire_event_block_number); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + assert!(db.backend().has_l1_messaging_nonce(nonce)?); - let event_payload = event.payload.clone().into_iter().map(u256_to_felt).collect::>>()?; + // Firing the event second time + fire_messaging_event(&account, deployed_contract_address).await?; + tokio::time::sleep(Duration::from_secs(10)).await; + // Assert that the event processed was in last block only not in the latest block. + assert_eq!( + last_block.block_number, + db.backend() + .messaging_last_synced_l1_block_with_event() + .expect("failed to retrieve block") + .unwrap() + .block_number + ); + assert!(logs_contain("Event already processed")); - let calldata: Calldata = { - let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); - calldata.push(from_address); - calldata.extend(event_payload); + // Cancelling worker + worker_handle.abort(); + Ok(()) + } - Calldata(Arc::new(calldata)) - }; + #[rstest] + #[traced_test] + #[tokio::test] + async fn e2e_test_message_canceled_starknet( + #[future] setup_test_env_starknet: TestRunnerStarknet, + ) -> anyhow::Result<()> { + // Initial Setup + // ================================== + let TestRunnerStarknet { + madara: _madara, + account, + chain_config, + db_service: db, + deployed_address: deployed_contract_address, + starknet_client, + mempool, + } = setup_test_env_starknet.await; + + // Start worker handle + // ================================== + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(starknet_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; - Ok(L1HandlerTransaction { - nonce: Nonce(nonce), - contract_address: ContractAddress(contract_address.try_into()?), - entry_point_selector: EntryPointSelector(entry_point_selector), - calldata, - version: TransactionVersion(Felt::ZERO), - }) -} + cancel_messaging_event(&account, deployed_contract_address).await?; + // Firing cancelled event + fire_messaging_event(&account, deployed_contract_address).await?; + tokio::time::sleep(Duration::from_secs(10)).await; -/// Computes the message hashed with the given event data -fn get_l1_to_l2_msg_hash(event: &LogMessageToL2) -> anyhow::Result> { - let data = ( - [0u8; 12], - event.fromAddress.0 .0, - event.toAddress, - event.nonce, - event.selector, - U256::from(event.payload.len()), - event.payload.clone(), - ); - Ok(keccak256(data.abi_encode_packed())) + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_eq!(last_block.block_number, 0); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + // cancelled message nonce should be inserted to avoid reprocessing + assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); + assert!(logs_contain("L2 Message was cancelled in block at timestamp : 0x66b4f105")); + + // Cancelling worker + worker_handle.abort(); + Ok(()) + } } #[cfg(test)] @@ -198,11 +312,12 @@ mod l1_messaging_tests { use std::{sync::Arc, time::Duration}; use self::DummyContract::DummyContractInstance; + use crate::client::ClientTrait; use crate::eth::StarknetCoreContract::LogMessageToL2; use crate::eth::{EthereumClient, StarknetCoreContract}; use crate::gas_price::L1BlockMetrics; - use crate::l1_messaging::sync; - use crate::{l1_messaging::get_l1_to_l2_msg_hash, utils::felt_to_u256}; + use crate::messaging::sync; + use crate::utils::felt_to_u256; use alloy::{ hex::FromHex, node_bindings::{Anvil, AnvilInstance}, @@ -384,8 +499,8 @@ mod l1_messaging_tests { let db = Arc::clone(&db); tokio::spawn(async move { sync( - Arc::clone(db.backend()), Arc::new(Box::new(eth_client)), + Arc::clone(db.backend()), chain_config.chain_id.clone(), mempool, ServiceContext::new_for_testing(), @@ -445,8 +560,8 @@ mod l1_messaging_tests { let db = Arc::clone(&db); tokio::spawn(async move { sync( - Arc::clone(db.backend()), Arc::new(Box::new(eth_client)), + Arc::clone(db.backend()), chain_config.chain_id.clone(), mempool, ServiceContext::new_for_testing(), @@ -501,8 +616,8 @@ mod l1_messaging_tests { let db = Arc::clone(&db); tokio::spawn(async move { sync( - Arc::clone(db.backend()), Arc::new(Box::new(eth_client)), + Arc::clone(db.backend()), chain_config.chain_id.clone(), mempool, ServiceContext::new_for_testing(), @@ -528,31 +643,42 @@ mod l1_messaging_tests { /// Test taken from starknet.rs to ensure consistency /// https://github.com/xJonathanLEI/starknet-rs/blob/2ddc69479d326ed154df438d22f2d720fbba746e/starknet-core/src/types/msg.rs#L96 - #[test] - fn test_msg_to_l2_hash() { - let msg = get_l1_to_l2_msg_hash(&LogMessageToL2 { - fromAddress: Address::from_hex("c3511006C04EF1d78af4C8E0e74Ec18A6E64Ff9e").unwrap(), - toAddress: felt_to_u256( - Felt::from_hex("0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82").unwrap(), - ), - selector: felt_to_u256( - Felt::from_hex("0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5").unwrap(), - ), - payload: vec![ - felt_to_u256( - Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7").unwrap(), + #[rstest] + #[tokio::test] + async fn test_msg_to_l2_hash() { + let TestRunner { + chain_config: _chain_config, + db_service: _db, + dummy_contract: _contract, + eth_client, + anvil: _anvil, + mempool: _mempool, + } = setup_test_env().await; + + let msg = eth_client + .get_messaging_hash(&LogMessageToL2 { + fromAddress: Address::from_hex("c3511006C04EF1d78af4C8E0e74Ec18A6E64Ff9e").unwrap(), + toAddress: felt_to_u256( + Felt::from_hex("0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82").unwrap(), ), - felt_to_u256(Felt::from_hex("0x2c68af0bb140000").unwrap()), - felt_to_u256(Felt::from_hex("0x0").unwrap()), - ], - nonce: U256::from(775628), - fee: U256::ZERO, - }) - .expect("Failed to compute l1 to l2 msg hash"); + selector: felt_to_u256( + Felt::from_hex("0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5").unwrap(), + ), + payload: vec![ + felt_to_u256( + Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7").unwrap(), + ), + felt_to_u256(Felt::from_hex("0x2c68af0bb140000").unwrap()), + felt_to_u256(Felt::from_hex("0x0").unwrap()), + ], + nonce: U256::from(775628), + fee: U256::ZERO, + }) + .expect("Failed to compute l1 to l2 msg hash"); let expected_hash = <[u8; 32]>::from_hex("c51a543ef9563ad2545342b390b67edfcddf9886aa36846cf70382362fc5fab3").unwrap(); - assert_eq!(msg.0, expected_hash); + assert_eq!(msg, expected_hash); } } diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index 55e8d1d1d..b558053fe 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -1,14 +1,19 @@ -use crate::client::{ClientTrait, ClientType, CoreContractInstance}; +use crate::client::{ClientTrait, CoreContractInstance}; use crate::gas_price::L1BlockMetrics; +use crate::messaging::MessageSent; use crate::state_update::{update_l1, StateUpdate}; -use alloy::primitives::FixedBytes; -use anyhow::bail; +use anyhow::{anyhow, bail}; use async_trait::async_trait; use bigdecimal::ToPrimitive; +use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; +use mc_mempool::{Mempool, MempoolProvider}; use mp_utils::service::ServiceContext; +use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; +use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; use starknet_core::types::{BlockId, BlockTag, EmittedEvent, EventFilter, FunctionCall}; use starknet_core::utils::get_selector_from_name; +use starknet_crypto::poseidon_hash_many; use starknet_providers::jsonrpc::HttpTransport; use starknet_providers::{JsonRpcClient, Provider}; use starknet_types_core::felt::Felt; @@ -50,8 +55,8 @@ impl Clone for StarknetClient { // For this reason we are adding our own call implementations. #[async_trait] impl ClientTrait for StarknetClient { - type Provider = Arc>; type Config = StarknetClientConfig; + type EventStruct = MessageSent; fn get_l1_block_metrics(&self) -> &L1BlockMetrics { &self.l1_block_metrics @@ -61,10 +66,6 @@ impl ClientTrait for StarknetClient { CoreContractInstance::Starknet(self.l2_core_contract) } - fn get_client_type(&self) -> ClientType { - ClientType::STARKNET - } - async fn new(config: Self::Config) -> anyhow::Result where Self: Sized, @@ -113,7 +114,9 @@ impl ClientTrait for StarknetClient { block_hash: felt252, } */ - assert_eq!(event.data.len(), 3, "Event response invalid !!"); + if event.data.len() != 3 { + return Err(anyhow!("Event response invalid !!")); + } // Block number management in case of pending block number events. match event.block_number { Some(block_number) => Ok(block_number), @@ -127,66 +130,18 @@ impl ClientTrait for StarknetClient { } async fn get_last_verified_block_number(&self) -> anyhow::Result { - let call_res = self - .provider - .call( - FunctionCall { - contract_address: self.l2_core_contract, - /* - GitHub Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 - Function Call response : (StateRoot, BlockNumber, BlockHash) - */ - entry_point_selector: get_selector_from_name("get_state")?, - calldata: vec![], - }, - BlockId::Tag(BlockTag::Pending), - ) - .await?; - assert_eq!(call_res.len(), 3, "Call response invalid !!"); // Block Number index in call response : 1 - Ok(call_res[1].to_u64().unwrap()) + Ok(u64::try_from(self.get_state_call().await?[1])?) } async fn get_last_state_root(&self) -> anyhow::Result { - let call_res = self - .provider - .call( - FunctionCall { - contract_address: self.l2_core_contract, - /* - GitHub Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 - Function Call response : (StateRoot, BlockNumber, BlockHash) - */ - entry_point_selector: get_selector_from_name("get_state")?, - calldata: vec![], - }, - BlockId::Tag(BlockTag::Pending), - ) - .await?; - assert_eq!(call_res.len(), 3, "Call response invalid !!"); - // State Root index in call response : 3 - Ok(call_res[0]) + // State Root index in call response : 0 + Ok(self.get_state_call().await?[0]) } async fn get_last_verified_block_hash(&self) -> anyhow::Result { - let call_res = self - .provider - .call( - FunctionCall { - contract_address: self.l2_core_contract, - /* - GitHub Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 - Function Call response : (StateRoot, BlockNumber, BlockHash) - */ - entry_point_selector: get_selector_from_name("get_state")?, - calldata: vec![], - }, - BlockId::Tag(BlockTag::Pending), - ) - .await?; - assert_eq!(call_res.len(), 3, "Call response invalid !!"); // Block Hash index in call response : 2 - Ok(call_res[2]) + Ok(self.get_state_call().await?[2]) } async fn get_initial_state(&self) -> anyhow::Result { @@ -215,7 +170,7 @@ impl ClientTrait for StarknetClient { if let Some(event) = emitted_events.last() { let data = event; // Create a longer-lived binding let formatted_event = StateUpdate { - block_number: data.data[1].to_u64().unwrap(), + block_number: data.data[1].to_u64().expect("Unable to parse Felt result into u64"), global_root: data.data[0], block_hash: data.data[2], }; @@ -234,12 +189,215 @@ impl ClientTrait for StarknetClient { } } - async fn get_eth_gas_prices(&self) -> anyhow::Result<(u128, u128)> { + async fn listen_for_messaging_events( + &self, + backend: Arc, + mut ctx: ServiceContext, + last_synced_event_block: LastSyncedEventBlock, + chain_id: ChainId, + mempool: Arc, + ) -> anyhow::Result<()> { + // This is for checking if initial events are synced. + let mut sync_flag = false; + + loop { + let events_response = ctx.run_until_cancelled(self.get_events( + BlockId::Number(if !sync_flag { + last_synced_event_block.block_number + } else { + self.get_latest_block_number().await? + }), + BlockId::Number(self.get_latest_block_number().await?), + self.l2_core_contract, + vec![get_selector_from_name("MessageSent")?], + )); + + // set synced flag as true. + sync_flag = true; + + match events_response.await { + Some(Ok(emitted_events)) => { + for event in emitted_events { + tracing::info!( + "🔵 Processing L2 Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", + event.block_number, + event.transaction_hash, + event.data[1] + ); + + // For payload in data : + // 6th element is the payload array length. + let mut payload_array = vec![]; + event.data.iter().skip(6).for_each(|data| { + payload_array.push(*data); + }); + + let formatted_event = MessageSent { + message_hash: event.data[0], + from: event.data[1], + to: event.data[2], + selector: event.data[3], + nonce: event.data[4], + payload: payload_array, + }; + + let event_hash = self.get_messaging_hash(&formatted_event)?; + tracing::info!( + "🔵 Checking for cancelation, event hash : {:?}", + Felt::from_bytes_be_slice(event_hash.as_slice()) + ); + let cancellation_timestamp = self.get_l1_to_l2_message_cancellations(event_hash).await?; + if cancellation_timestamp != Felt::ZERO { + tracing::info!( + "🔵 L2 Message was cancelled in block at timestamp : {:?}", + cancellation_timestamp + ); + let tx_nonce = Nonce(event.data[4]); + match backend.has_l1_messaging_nonce(tx_nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(tx_nonce)?; + } + Ok(true) => {} + Err(e) => { + tracing::error!("🔵 Unexpected DB error: {:?}", e); + return Err(e.into()); + } + }; + continue; + } + + // TODO : need to figure out what to pass instead of event index. + // In case of eth we are passing that and using that for indexing the events. + // This value is also stored in db in order to track the events. + // This is also crucial in case which node is killed while executing the messages. + match self + .process_message( + &backend, + &formatted_event, + &event.block_number, + &Some(0), + &chain_id, + mempool.clone(), + ) + .await + { + Ok(Some(tx_hash)) => { + tracing::info!( + "🔵 L2 Message from block: {:?}, transaction_hash: {:?} submitted, \ + transaction hash on L2: {:?}", + event.block_number, + event.transaction_hash, + tx_hash + ); + } + Ok(None) => {} + Err(e) => { + tracing::error!( + "🔵 Unexpected error while processing L2 Message from block: {:?}, transaction_hash: {:?}, \ + error: {:?}", + event.block_number, + event.transaction_hash, + e + ) + } + } + } + } + Some(Err(e)) => { + error!("Error processing event: {:?}", e); + } + None => { + trace!("Starknet Client : No event found"); + } + } + + // TODO : take this as a block time of L2 + sleep(Duration::from_secs(5)).await; + } + } + + // We are returning here (0,0) because we are assuming that + // the L3s will have zero gas prices. for any transaction. + // So that's why we will keep the prices as 0 returning from + // our settlement client. + async fn get_gas_prices(&self) -> anyhow::Result<(u128, u128)> { Ok((0, 0)) } - async fn get_l1_to_l2_message_cancellations(&self, _msg_hash: FixedBytes<32>) -> anyhow::Result { - todo!() + fn get_messaging_hash(&self, event: &Self::EventStruct) -> anyhow::Result> { + Ok(poseidon_hash_many(&self.event_to_felt_array(event)).to_bytes_be().to_vec()) + } + + async fn process_message( + &self, + backend: &MadaraBackend, + event: &Self::EventStruct, + settlement_layer_block_number: &Option, + event_index: &Option, + _chain_id: &ChainId, + mempool: Arc, + ) -> anyhow::Result> { + let transaction = self.parse_handle_message_transaction(event)?; + let tx_nonce = transaction.nonce; + + // Ensure that L2 message has not been executed + match backend.has_l1_messaging_nonce(tx_nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(tx_nonce)?; + } + Ok(true) => { + tracing::debug!("🔵 Event already processed: {:?}", transaction); + return Ok(None); + } + Err(e) => { + tracing::error!("🔵 Unexpected DB error: {:?}", e); + return Err(e.into()); + } + }; + + let res = mempool.accept_l1_handler_tx(transaction.into(), 0); + + // TODO: remove unwraps + // Ques: shall it panic if no block number of event_index? + let block_sent = LastSyncedEventBlock::new(settlement_layer_block_number.unwrap(), event_index.unwrap()); + backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; + + Ok(Some(res?.transaction_hash)) + } + + fn parse_handle_message_transaction(&self, event: &Self::EventStruct) -> anyhow::Result { + let calldata: Calldata = { + let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); + calldata.push(event.from); + calldata.extend(event.payload.clone()); + Calldata(Arc::new(calldata)) + }; + + Ok(L1HandlerTransaction { + nonce: Nonce(event.nonce), + contract_address: ContractAddress(event.from.try_into()?), + entry_point_selector: EntryPointSelector(event.selector), + calldata, + version: TransactionVersion(Felt::ZERO), + }) + } + + async fn get_l1_to_l2_message_cancellations(&self, msg_hash: Vec) -> anyhow::Result { + let call_res = self + .provider + .call( + FunctionCall { + contract_address: self.l2_core_contract, + // No get_message_cancellation function in pilt over as of now + entry_point_selector: get_selector_from_name("l1_to_l2_message_cancellations")?, + calldata: vec![Felt::from_bytes_be_slice(msg_hash.as_slice())], + }, + BlockId::Tag(BlockTag::Pending), + ) + .await?; + // Ensure correct read call : u256 (0, 0) + assert_eq!(call_res.len(), 2, "l1_to_l2_message_cancellations should return only 2 values"); + Ok(call_res[0]) } } @@ -253,7 +411,7 @@ impl StarknetClient { ) -> anyhow::Result> { let mut event_vec = Vec::new(); let mut page_indicator = false; - let mut continuation_token = String::from("0"); + let mut continuation_token: Option = None; while !page_indicator { let events = self @@ -265,14 +423,14 @@ impl StarknetClient { address: Some(contract_address), keys: Some(vec![keys.clone()]), }, - if continuation_token == "0" { None } else { Some(continuation_token.clone()) }, + continuation_token.clone(), 1000, ) .await?; event_vec.extend(events.events); if let Some(token) = events.continuation_token { - continuation_token = token; + continuation_token = Some(token); } else { page_indicator = true; } @@ -280,6 +438,40 @@ impl StarknetClient { Ok(event_vec) } + + fn event_to_felt_array(&self, event: &MessageSent) -> Vec { + let mut felt_vec = vec![event.from, event.to, event.selector, event.nonce]; + felt_vec.push(Felt::from(event.payload.len())); + event.payload.clone().into_iter().for_each(|felt| { + felt_vec.push(felt); + }); + + felt_vec + } +} + +impl StarknetClient { + pub async fn get_state_call(&self) -> anyhow::Result> { + let call_res = self + .provider + .call( + FunctionCall { + contract_address: self.l2_core_contract, + /* + GitHub Ref : https://github.com/keep-starknet-strange/piltover/blob/main/src/state/component.cairo#L59 + Function Call response : (StateRoot, BlockNumber, BlockHash) + */ + entry_point_selector: get_selector_from_name("get_state")?, + calldata: vec![], + }, + BlockId::Tag(BlockTag::Pending), + ) + .await?; + if call_res.len() != 3 { + return Err(anyhow!("Call response invalid !!")); + } + Ok(call_res) + } } #[cfg(test)] @@ -314,10 +506,7 @@ pub mod starknet_client_tests { #[serial] #[tokio::test] async fn create_new_client_contract_exists_starknet_client() -> anyhow::Result<()> { - // Here we need to have madara variable otherwise it will - // get dropped and will kill the madara. - #[allow(unused_variables)] - let (_, deployed_address, madara) = prepare_starknet_client_test().await?; + let (_, deployed_address, _madara) = prepare_starknet_client_test().await?; let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, @@ -332,10 +521,7 @@ pub mod starknet_client_tests { #[serial] #[tokio::test] async fn get_last_event_block_number_works_starknet_client() -> anyhow::Result<()> { - // Here we need to have madara variable otherwise it will - // get dropped and will kill the madara. - #[allow(unused_variables)] - let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, @@ -377,10 +563,7 @@ pub mod starknet_client_tests { #[serial] #[tokio::test] async fn get_last_verified_block_hash_works_starknet_client() -> anyhow::Result<()> { - // Here we need to have madara variable otherwise it will - // get dropped and will kill the madara. - #[allow(unused_variables)] - let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, @@ -408,10 +591,7 @@ pub mod starknet_client_tests { #[serial] #[tokio::test] async fn get_last_state_root_works_starknet_client() -> anyhow::Result<()> { - // Here we need to have madara variable otherwise it will - // get dropped and will kill the madara. - #[allow(unused_variables)] - let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, @@ -439,10 +619,7 @@ pub mod starknet_client_tests { #[serial] #[tokio::test] async fn get_last_verified_block_number_works_starknet_client() -> anyhow::Result<()> { - // Here we need to have madara variable otherwise it will - // get dropped and will kill the madara. - #[allow(unused_variables)] - let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo new file mode 100644 index 000000000..e1c143897 --- /dev/null +++ b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo @@ -0,0 +1,149 @@ +use starknet::ContractAddress; +use core::integer::u256; + +#[derive(Drop, Serde)] +struct MessageData { + from_address: ContractAddress, + to_address: felt252, + selector: felt252, + payload: Array, + nonce: felt252, +} + +// Separate storage struct to handle the array storage properly +#[derive(Drop, Serde, starknet::Store)] +struct StorageMessageData { + from_address: ContractAddress, + to_address: felt252, + selector: felt252, + nonce: felt252, +} + +#[starknet::interface] +trait IMessagingContract { + fn get_message_data(self: @TContractState) -> MessageData; + fn fire_event(ref self: TContractState); + fn l1_to_l2_message_cancellations(self: @TContractState, msg_hash: felt252) -> u256; + fn set_is_canceled(ref self: TContractState, value: bool); + fn get_l1_to_l2_msg_hash(self: @TContractState) -> felt252; +} + +#[starknet::contract] +mod MessagingContract { + use super::IMessagingContract; + use super::MessageData; + use core::array::SpanTrait; + use core::option::OptionTrait; + use core::traits::Into; + use starknet::ContractAddress; + use core::array::ArrayTrait; + use core::poseidon::poseidon_hash_span; + use core::integer::u256; + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + MessageSent: MessageSent, + } + + #[derive(Drop, starknet::Event)] + struct MessageSent { + message_hash: felt252, + from_address: ContractAddress, + to_address: felt252, + selector: felt252, + nonce: felt252, + payload: Array, + } + + #[storage] + struct Storage { + is_canceled: bool + } + + #[abi(embed_v0)] + impl MessagingContract of super::IMessagingContract { + fn get_message_data(self: @ContractState) -> MessageData { + let mut payload: Array = ArrayTrait::new(); + // Transfer L2 ---> L3 + // from_address : + // to_address : + // selector : transfer + // payload : [ , 30 ETH ] + payload + .append( + 1745450722268439108899567493174320056804647958314420522290024379112230030194 + .into() + ); + payload.append(30000000000000000000.into()); + payload.append(0.into()); + + MessageData { + from_address: 3293945099482077566294620753663887236810230524774221047563633702975851058323 + .try_into() + .unwrap(), + to_address: 2087021424722619777119509474943472645767659996348769578120564519014510906823 + .into(), + selector: 232670485425082704932579856502088130646006032362877466777181098476241604910 + .into(), + payload, + nonce: 10000000000000000.into(), + } + } + + fn fire_event(ref self: ContractState) { + let data = self.get_message_data(); + let hash = self.get_l1_to_l2_msg_hash(); + self + .emit( + Event::MessageSent( + MessageSent { + message_hash: hash, + from_address: data.from_address, + to_address: data.to_address, + selector: data.selector, + payload: data.payload, + nonce: data.nonce, + } + ) + ); + } + + fn l1_to_l2_message_cancellations(self: @ContractState, msg_hash: felt252) -> u256 { + if self.is_canceled.read() { + 1723134213.into() + } else { + 0.into() + } + } + + fn set_is_canceled(ref self: ContractState, value: bool) { + self.is_canceled.write(value); + } + + fn get_l1_to_l2_msg_hash(self: @ContractState) -> felt252 { + let data = self.get_message_data(); + let mut hash_data: Array = ArrayTrait::new(); + hash_data.append(data.from_address.into()); + hash_data.append(data.to_address); + hash_data.append(data.selector); + hash_data.append(data.nonce); + let len: felt252 = data.payload.len().into(); + hash_data.append(len); + + let mut i: usize = 0; + let payload_span = data.payload.span(); + loop { + if i >= data.payload.len() { + break; + } + let value = *payload_span.at(i); + let value_felt: felt252 = value.try_into().unwrap(); + hash_data.append(value_felt); + i += 1; + }; + + poseidon_hash_span(hash_data.span()) + } + } +} diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json new file mode 100644 index 000000000..267493e1b --- /dev/null +++ b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json @@ -0,0 +1,1982 @@ +{ + "prime": "0x800000000000011000000000000000000000000000000000000000000000001", + "compiler_version": "2.8.0", + "bytecode": [ + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x93", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x482680017ff98000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x10", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ffc7fff8000", + "0x48127ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x5b0", + "0x482480017fff8000", + "0x5af", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff8", + "0x0", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff77fff", + "0x10780017fff7fff", + "0x5e", + "0x4824800180007ff8", + "0x0", + "0x400080007ff87fff", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x3dbe3dd8c2f721bc24e87bcb739063a10ee738cef090bc752bc0d5a29f10b72", + "0x400080007ffe7fff", + "0x480680017fff8000", + "0x1a055690d9db80000", + "0x400080017ffd7fff", + "0x480680017fff8000", + "0x0", + "0x400080027ffc7fff", + "0x480680017fff8000", + "0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493", + "0x48127ffb7fff8000", + "0x482480017ffa8000", + "0x3", + "0xa0680017fff8004", + "0xe", + "0x4824800180047ffc", + "0x800000000000000000000000000000000000000000000000000000000000000", + "0x484480017ffe8000", + "0x110000000000000000", + "0x48307ffe7fff8002", + "0x480080017fed7ffc", + "0x480080027fec7ffc", + "0x402480017ffb7ffd", + "0xffffffffffffffeeffffffffffffffff", + "0x400080037feb7ffd", + "0x10780017fff7fff", + "0x2e", + "0x484480017fff8001", + "0x8000000000000000000000000000000", + "0x48307fff80007ffb", + "0x480080017fee7ffd", + "0x480080027fed7ffd", + "0x402480017ffc7ffe", + "0xf8000000000000000000000000000000", + "0x400080037fec7ffe", + "0x40780017fff7fff", + "0x1", + "0x482480017feb8000", + "0x4", + "0x48127ff17fff8000", + "0x48127ff57fff8000", + "0x480680017fff8000", + "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + "0x480680017fff8000", + "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "0x48127ff37fff8000", + "0x48127ff37fff8000", + "0x480680017fff8000", + "0x2386f26fc10000", + "0x48127ff77fff8000", + "0x48127ff67fff8000", + "0x1104800180018000", + "0x2ab", + "0x20680017fff7ffd", + "0xa", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482480017fe98000", + "0x4", + "0x48127fef7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017ff58000", + "0x1", + "0x48127ff37fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x1", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff87fff", + "0x10780017fff7fff", + "0x59", + "0x4825800180007ffa", + "0x0", + "0x400280007ff87fff", + "0x482680017ff88000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x11", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ffc7fff8000", + "0x480a7ff97fff8000", + "0x48127ff97fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x508", + "0x482480017fff8000", + "0x507", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff8", + "0x5bae", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff77fff", + "0x10780017fff7fff", + "0x22", + "0x4824800180007ff8", + "0x5bae", + "0x400080007ff87fff", + "0x482480017ff88000", + "0x1", + "0x48127ffe7fff8000", + "0x480a7ff97fff8000", + "0x480a7ffb7fff8000", + "0x1104800180018000", + "0x254", + "0x20680017fff7ffd", + "0xd", + "0x40780017fff7fff", + "0x1", + "0x48127ff87fff8000", + "0x48127ff97fff8000", + "0x48127ff77fff8000", + "0x48127ff87fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x48127ff97fff8000", + "0x48127ffa7fff8000", + "0x48127ff87fff8000", + "0x48127ff97fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017ff58000", + "0x1", + "0x480a7ff97fff8000", + "0x48127ff27fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff88000", + "0x1", + "0x480a7ff97fff8000", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0xd8", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x482680017ff98000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x480280007ffc8000", + "0x10780017fff7fff", + "0x8", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xb0", + "0x48307ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x10", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ff77fff8000", + "0x48127ff57fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x486", + "0x482480017fff8000", + "0x485", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff3", + "0x19fa", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff27fff", + "0x10780017fff7fff", + "0x80", + "0x4824800180007ff3", + "0x19fa", + "0x400080007ff37fff", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x3150ab9073ca993efcd1d4ab278c207ab86418914db765f88aa5d8e7bc5c79", + "0x482480017ff18000", + "0x1", + "0x480680017fff8000", + "0x53746f7261676552656164", + "0x400280007ffb7fff", + "0x400280017ffb7ffb", + "0x400280027ffb7ffc", + "0x400280037ffb7ffd", + "0x480280057ffb8000", + "0x20680017fff7fff", + "0x65", + "0x480280067ffb8000", + "0x480280047ffb8000", + "0x482680017ffb8000", + "0x7", + "0x20680017fff7ffd", + "0x2a", + "0x480680017fff8000", + "0x0", + "0xa0680017fff8000", + "0x16", + "0x480080007ff88003", + "0x480080017ff78003", + "0x4844800180017ffe", + "0x100000000000000000000000000000000", + "0x483080017ffd7ffb", + "0x482480017fff7ffd", + "0x800000000000010fffffffffffffffff7ffffffffffffef0000000000000001", + "0x20680017fff7ffc", + "0x6", + "0x402480017fff7ffd", + "0xffffffffffffffffffffffffffffffff", + "0x10780017fff7fff", + "0x4", + "0x402480017ffe7ffd", + "0xf7ffffffffffffef0000000000000000", + "0x400080027ff37ffd", + "0x20680017fff7ffe", + "0xe", + "0x402780017fff7fff", + "0x1", + "0x400080007ff87ffe", + "0x40780017fff7fff", + "0x5", + "0x482480017ff38000", + "0x1", + "0x48127ff87fff8000", + "0x480680017fff8000", + "0x0", + "0x10780017fff7fff", + "0x6", + "0x482480017ff38000", + "0x3", + "0x48127ffe7fff8000", + "0x48127ffc7fff8000", + "0x10780017fff7fff", + "0x28", + "0x480680017fff8000", + "0x66b4f105", + "0xa0680017fff8000", + "0x16", + "0x480080007ff88003", + "0x480080017ff78003", + "0x4844800180017ffe", + "0x100000000000000000000000000000000", + "0x483080017ffd7ffb", + "0x482480017fff7ffd", + "0x800000000000010fffffffffffffffff7ffffffffffffef0000000000000001", + "0x20680017fff7ffc", + "0x6", + "0x402480017fff7ffd", + "0xffffffffffffffffffffffffffffffff", + "0x10780017fff7fff", + "0x4", + "0x402480017ffe7ffd", + "0xf7ffffffffffffef0000000000000000", + "0x400080027ff37ffd", + "0x20680017fff7ffe", + "0xe", + "0x402780017fff7fff", + "0x1", + "0x400080007ff87ffe", + "0x40780017fff7fff", + "0x5", + "0x482480017ff38000", + "0x1", + "0x48127ff87fff8000", + "0x480680017fff8000", + "0x0", + "0x10780017fff7fff", + "0x6", + "0x482480017ff38000", + "0x3", + "0x48127ffe7fff8000", + "0x48127ffc7fff8000", + "0x40780017fff7fff", + "0x1", + "0x48127ffd7fff8000", + "0x48127ffd7fff8000", + "0x400080007ffd7ffe", + "0x400080017ffd7fff", + "0x48127ffa7fff8000", + "0x48127ff07fff8000", + "0x48127ff07fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x2", + "0x208b7fff7fff7ffe", + "0x48127ffd7fff8000", + "0x480280047ffb8000", + "0x482680017ffb8000", + "0x8", + "0x480680017fff8000", + "0x1", + "0x480280067ffb8000", + "0x480280077ffb8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017ff08000", + "0x1", + "0x48127fee7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x400080007ffe7fff", + "0x48127ff87fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x1", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff97fff", + "0x10780017fff7fff", + "0x8d", + "0x4825800180007ffa", + "0x0", + "0x400280007ff97fff", + "0x482680017ff98000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ffc7fff8000", + "0x10780017fff7fff", + "0x8", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x65", + "0x480080007fff8000", + "0x20680017fff7fff", + "0x6", + "0x480680017fff8000", + "0x1", + "0x10780017fff7fff", + "0x4", + "0x480680017fff8000", + "0x0", + "0x48307ffa80007ffb", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x10", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ff57fff8000", + "0x48127ff37fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x391", + "0x482480017fff8000", + "0x390", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff1", + "0x1284", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff07fff", + "0x10780017fff7fff", + "0x2c", + "0x4824800180007ff1", + "0x1284", + "0x400080007ff17fff", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x3150ab9073ca993efcd1d4ab278c207ab86418914db765f88aa5d8e7bc5c79", + "0x48307ff580007ffd", + "0x482480017fed8000", + "0x1", + "0x480680017fff8000", + "0x53746f726167655772697465", + "0x400280007ffb7fff", + "0x400280017ffb7ff9", + "0x400280027ffb7ffb", + "0x400280037ffb7ffc", + "0x400280047ffb7ffd", + "0x480280067ffb8000", + "0x20680017fff7fff", + "0xd", + "0x40780017fff7fff", + "0x1", + "0x48127ffc7fff8000", + "0x480280057ffb8000", + "0x482680017ffb8000", + "0x7", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x48127ffd7fff8000", + "0x480280057ffb8000", + "0x482680017ffb8000", + "0x9", + "0x480680017fff8000", + "0x1", + "0x480280077ffb8000", + "0x480280087ffb8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017fee8000", + "0x1", + "0x48127fec7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x400080007ffe7fff", + "0x48127ff87fff8000", + "0x48127ff67fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff98000", + "0x1", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ffa8000", + "0x100000000000000000000000000000000", + "0x400280007ff87fff", + "0x10780017fff7fff", + "0x5a", + "0x4825800180007ffa", + "0x0", + "0x400280007ff87fff", + "0x482680017ff88000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0x11", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x400080007ffe7fff", + "0x48127ffc7fff8000", + "0x480a7ff97fff8000", + "0x48127ff97fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0x30d", + "0x482480017fff8000", + "0x30c", + "0x480080007fff8000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007ff8", + "0xae6", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007ff77fff", + "0x10780017fff7fff", + "0x23", + "0x4824800180007ff8", + "0xae6", + "0x400080007ff87fff", + "0x482480017ff88000", + "0x1", + "0x48127ffe7fff8000", + "0x480a7ff97fff8000", + "0x1104800180018000", + "0xf3", + "0x20680017fff7ffd", + "0xf", + "0x40780017fff7fff", + "0x1", + "0x400080007fff7ffe", + "0x48127ff97fff8000", + "0x48127ffa7fff8000", + "0x48127ff87fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x48127ffa7fff8000", + "0x48127ffb7fff8000", + "0x48127ff97fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017ff58000", + "0x1", + "0x480a7ff97fff8000", + "0x48127ff27fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff88000", + "0x1", + "0x480a7ff97fff8000", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x400380007ffd7ff6", + "0x400380017ffd7ff7", + "0x400380027ffd7ff8", + "0x48297ff980007ffa", + "0x400280037ffd7fff", + "0x480a7ff47fff8000", + "0x480a7ff57fff8000", + "0x480a7ff97fff8000", + "0x480a7ffa7fff8000", + "0x480a7ffc7fff8000", + "0x482680017ffd8000", + "0x4", + "0x1104800180018000", + "0x12d", + "0x20680017fff7ffd", + "0xb", + "0x400180007fff7ffb", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ffb7fff8000", + "0x482480017ffb8000", + "0x1", + "0x208b7fff7fff7ffe", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x4", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x3dbe3dd8c2f721bc24e87bcb739063a10ee738cef090bc752bc0d5a29f10b72", + "0x400080007ffe7fff", + "0x480680017fff8000", + "0x1a055690d9db80000", + "0x400080017ffd7fff", + "0x480680017fff8000", + "0x0", + "0x400080027ffc7fff", + "0x400780017fff8003", + "0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493", + "0x40137ffc7fff8001", + "0x402580017ffc8002", + "0x3", + "0xa0680017fff8004", + "0xe", + "0x4825800180048003", + "0x800000000000000000000000000000000000000000000000000000000000000", + "0x484480017ffe8000", + "0x110000000000000000", + "0x48307ffe7fff8002", + "0x480280007ffa7ffc", + "0x480280017ffa7ffc", + "0x402480017ffb7ffd", + "0xffffffffffffffeeffffffffffffffff", + "0x400280027ffa7ffd", + "0x10780017fff7fff", + "0x6b", + "0x484480017fff8001", + "0x8000000000000000000000000000000", + "0x48317fff80008003", + "0x480280007ffa7ffd", + "0x480280017ffa7ffd", + "0x402480017ffc7ffe", + "0xf8000000000000000000000000000000", + "0x400280027ffa7ffe", + "0x482680017ffa8000", + "0x3", + "0x480a7ffb7fff8000", + "0x480a7ffc7fff8000", + "0x1104800180018000", + "0x6d", + "0x40137ffc7fff8000", + "0x20680017fff7ffd", + "0x51", + "0x40780017fff7fff", + "0x1", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ffc7fff8000", + "0x480a80037fff8000", + "0x480680017fff8000", + "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + "0x480680017fff8000", + "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "0x480680017fff8000", + "0x2386f26fc10000", + "0x480a80017fff8000", + "0x480a80027fff8000", + "0x480680017fff8000", + "0x398697ad8745b865eefbaa4afad41e52876386afeeb69101604d297801076ef", + "0x400080007ff57fff", + "0x48127fef7fff8000", + "0x48127fef7fff8000", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x48127fec7fff8000", + "0x482480017feb8000", + "0x1", + "0x48127feb7fff8000", + "0x48127fea7fff8000", + "0x1104800180018000", + "0x109", + "0x20680017fff7ffb", + "0x23", + "0x480680017fff8000", + "0x456d69744576656e74", + "0x400280007ffd7fff", + "0x400280017ffd7ff9", + "0x400280027ffd7ffb", + "0x400280037ffd7ffc", + "0x400280047ffd7ffd", + "0x400280057ffd7ffe", + "0x480280077ffd8000", + "0x20680017fff7fff", + "0xe", + "0x48127ff77fff8000", + "0x480280067ffd8000", + "0x480a80007fff8000", + "0x482680017ffd8000", + "0x8", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x208b7fff7fff7ffe", + "0x48127ff77fff8000", + "0x480280067ffd8000", + "0x480a80007fff8000", + "0x482680017ffd8000", + "0xa", + "0x480680017fff8000", + "0x1", + "0x480280087ffd8000", + "0x480280097ffd8000", + "0x208b7fff7fff7ffe", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x480a80007fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x480a80007fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482680017ffa8000", + "0x3", + "0x480a7ffb7fff8000", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x3dbe3dd8c2f721bc24e87bcb739063a10ee738cef090bc752bc0d5a29f10b72", + "0x400080007ffe7fff", + "0x480680017fff8000", + "0x1a055690d9db80000", + "0x400080017ffd7fff", + "0x480680017fff8000", + "0x0", + "0x400080027ffc7fff", + "0x480680017fff8000", + "0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493", + "0x48127ffb7fff8000", + "0x482480017ffa8000", + "0x3", + "0xa0680017fff8004", + "0xe", + "0x4824800180047ffc", + "0x800000000000000000000000000000000000000000000000000000000000000", + "0x484480017ffe8000", + "0x110000000000000000", + "0x48307ffe7fff8002", + "0x480280007ffb7ffc", + "0x480280017ffb7ffc", + "0x402480017ffb7ffd", + "0xffffffffffffffeeffffffffffffffff", + "0x400280027ffb7ffd", + "0x10780017fff7fff", + "0x55", + "0x484480017fff8001", + "0x8000000000000000000000000000000", + "0x48307fff80007ffb", + "0x480280007ffb7ffd", + "0x480280017ffb7ffd", + "0x402480017ffc7ffe", + "0xf8000000000000000000000000000000", + "0x400280027ffb7ffe", + "0x40780017fff7fff", + "0x1", + "0x400080007fff7ff7", + "0x480680017fff8000", + "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + "0x400080017ffe7fff", + "0x480680017fff8000", + "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "0x400080027ffd7fff", + "0x480680017fff8000", + "0x2386f26fc10000", + "0x400080037ffc7fff", + "0x48307ff580007ff6", + "0x400080047ffb7fff", + "0x482680017ffb8000", + "0x3", + "0x480a7ffc7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff17fff8000", + "0x48127ff17fff8000", + "0x48127ff67fff8000", + "0x482480017ff58000", + "0x5", + "0x48127fed7fff8000", + "0x48127fed7fff8000", + "0x1104800180018000", + "0xa8", + "0x20680017fff7ffc", + "0x27", + "0x1104800180018000", + "0x1c1", + "0x482480017fff8000", + "0x1c0", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480a7ffd7fff8000", + "0x480080007ffc8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x48127ff37fff8000", + "0x48127ff37fff8000", + "0x1104800180018000", + "0x10d", + "0x20680017fff7ffc", + "0xb", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x400080007ffe7fff", + "0x482680017ffb8000", + "0x3", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ff98000", + "0xfffffffffffffffffffffffffffff722", + "0x400280007ff87fff", + "0x10780017fff7fff", + "0x2f", + "0x4825800180007ff9", + "0x8de", + "0x400280007ff87fff", + "0x482680017ff88000", + "0x1", + "0x48297ffa80007ffb", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482680017ffa8000", + "0x1", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ffa7fff8000", + "0x10780017fff7fff", + "0x8", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0xe", + "0x480080007fff8000", + "0x400280007ffd7fff", + "0x48127ff97fff8000", + "0x48127ff77fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x480a7ffc7fff8000", + "0x482680017ffd8000", + "0x1", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffd7", + "0x208b7fff7fff7ffe", + "0x48127ffa7fff8000", + "0x48127ff87fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff88000", + "0x1", + "0x480a7ff97fff8000", + "0x480680017fff8000", + "0x1", + "0x48127ffb7fff8000", + "0x482480017ffa8000", + "0x1", + "0x208b7fff7fff7ffe", + "0x400380007ffd7ff3", + "0x400380017ffd7ff4", + "0x400380027ffd7ff5", + "0x400380037ffd7ff6", + "0x400380047ffd7ff7", + "0x48297ff880007ff9", + "0x400280057ffd7fff", + "0x480a7ff17fff8000", + "0x480a7ff27fff8000", + "0x480a7ff87fff8000", + "0x480a7ff97fff8000", + "0x480a7ffc7fff8000", + "0x482680017ffd8000", + "0x6", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffb1", + "0x20680017fff7ffd", + "0xb", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0x48127ffb7fff8000", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x48127ff97fff8000", + "0x208b7fff7fff7ffe", + "0xa0680017fff8000", + "0x7", + "0x482680017ff68000", + "0xfffffffffffffffffffffffffffff13c", + "0x400280007ff57fff", + "0x10780017fff7fff", + "0x64", + "0x4825800180007ff6", + "0xec4", + "0x400280007ff57fff", + "0x48297ffc80007ffd", + "0x48317fff80017ff7", + "0xa0680017fff7fff", + "0x7", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280017ff57fff", + "0x10780017fff7fff", + "0xc", + "0x400280017ff57fff", + "0x482680017ff58000", + "0x2", + "0x48127ffb7fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ffa7fff8000", + "0x480a7ffb7fff8000", + "0x480a7ff77fff8000", + "0x208b7fff7fff7ffe", + "0x48297ff880007ff9", + "0xa0680017fff8000", + "0x6", + "0x48317ffe80007ff7", + "0x400280027ff57fff", + "0x10780017fff7fff", + "0x37", + "0x482680017ff78000", + "0x1", + "0x48307fff80007ffd", + "0x400280027ff57fff", + "0x482a7ff77ff88000", + "0x480080007fff8000", + "0x400280007ffb7fff", + "0x480680017fff8000", + "0x1", + "0x480a7ffa7fff8000", + "0x482680017ffb8000", + "0x1", + "0xa0680017fff8000", + "0x8", + "0x48327ffc7ff78000", + "0x4824800180007fff", + "0x100000000", + "0x400280037ff57fff", + "0x10780017fff7fff", + "0x13", + "0x48327ffc7ff78001", + "0x4824800180007fff", + "0xffffffffffffffffffffffff00000000", + "0x400280037ff57ffe", + "0x482680017ff58000", + "0x4", + "0x48127fee7fff8000", + "0x48127ffd7fff8000", + "0x480a7ff87fff8000", + "0x480a7ff97fff8000", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffbb", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x7533325f616464204f766572666c6f77", + "0x400080007ffe7fff", + "0x482680017ff58000", + "0x4", + "0x48127fec7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x496e646578206f7574206f6620626f756e6473", + "0x400080007ffe7fff", + "0x482680017ff58000", + "0x3", + "0x48127ff57fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff58000", + "0x1", + "0x480a7ff67fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ffa7fff8000", + "0x482480017ff98000", + "0x1", + "0x208b7fff7fff7ffe", + "0x1104800180018000", + "0xa4", + "0x482480017fff8000", + "0xa3", + "0x480080007fff8000", + "0x480080037fff8000", + "0x482480017fff8000", + "0xc62", + "0xa0680017fff8000", + "0x8", + "0x48317ffe80007ff6", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400280007ff57fff", + "0x10780017fff7fff", + "0x85", + "0x48317ffe80007ff6", + "0x400280007ff57fff", + "0x482680017ff58000", + "0x1", + "0x48297ffc80007ffd", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482680017ffc8000", + "0x1", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x0", + "0x480a7ffc7fff8000", + "0x10780017fff7fff", + "0x8", + "0x480a7ffc7fff8000", + "0x480a7ffd7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x5d", + "0x480080007fff8000", + "0x48307ffb80007ffc", + "0x20680017fff7fff", + "0x4", + "0x10780017fff7fff", + "0xa", + "0x482480017ffa8000", + "0x1", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x0", + "0x48127ff77fff8000", + "0x10780017fff7fff", + "0x8", + "0x48127ffa7fff8000", + "0x48127ffa7fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x20680017fff7ffe", + "0x37", + "0x480080007fff8000", + "0x48327ff97ff98000", + "0x48327ffe7ffa8000", + "0x400280007ff77ffe", + "0x400280017ff77fff", + "0x400380027ff77ffb", + "0x482680017ff78000", + "0x6", + "0x480280037ff78000", + "0x480280047ff78000", + "0x480280057ff78000", + "0xa0680017fff8000", + "0x9", + "0x4824800180007feb", + "0x816", + "0x482480017fff8000", + "0x100000000000000000000000000000000", + "0x400080007fea7fff", + "0x10780017fff7fff", + "0x12", + "0x4824800180007feb", + "0x816", + "0x400080007feb7fff", + "0x482480017feb8000", + "0x1", + "0x48127ffe7fff8000", + "0x48127ff87fff8000", + "0x480a7ff87fff8000", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x48127fec7fff8000", + "0x48127fec7fff8000", + "0x1104800180018000", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffa1", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482480017fe88000", + "0x1", + "0x48127fe67fff8000", + "0x48127ff57fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe", + "0x48327ffa7ff98000", + "0x482680017ffa8000", + "0x1", + "0x400280007ff77ffe", + "0x400280017ff77fff", + "0x400380027ff77ffb", + "0x48127ff27fff8000", + "0x48127ff07fff8000", + "0x482680017ff78000", + "0x6", + "0x480680017fff8000", + "0x0", + "0x48127ff67fff8000", + "0x48127ff67fff8000", + "0x480280037ff78000", + "0x208b7fff7fff7ffe", + "0x482680017ff98000", + "0x1", + "0x400280007ff77fff", + "0x400380017ff77ffa", + "0x400380027ff77ffb", + "0x48127ff97fff8000", + "0x48127ff77fff8000", + "0x482680017ff78000", + "0x6", + "0x480680017fff8000", + "0x0", + "0x48127ff77fff8000", + "0x48127ff77fff8000", + "0x480280037ff78000", + "0x208b7fff7fff7ffe", + "0x40780017fff7fff", + "0x1", + "0x480680017fff8000", + "0x4f7574206f6620676173", + "0x400080007ffe7fff", + "0x482680017ff58000", + "0x1", + "0x480a7ff67fff8000", + "0x480a7ff77fff8000", + "0x480680017fff8000", + "0x1", + "0x480680017fff8000", + "0x0", + "0x48127ff97fff8000", + "0x482480017ff88000", + "0x1", + "0x208b7fff7fff7ffe" + ], + "bytecode_segment_lengths": [ + 167, 110, 236, 161, 111, 32, 153, 128, 66, 38, 121, 164 + ], + "hints": [ + [ + 0, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [17, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 36, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "AP", "offset": -7 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [48, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 64, + [ + { + "TestLessThan": { + "lhs": { "Deref": { "register": "AP", "offset": -3 } }, + "rhs": { + "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" + }, + "dst": { "register": "AP", "offset": 4 } + } + } + ] + ], + [ + 68, + [ + { + "LinearSplit": { + "value": { "Deref": { "register": "AP", "offset": 3 } }, + "scalar": { "Immediate": "0x110000000000000000" }, + "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, + "x": { "register": "AP", "offset": -2 }, + "y": { "register": "AP", "offset": -1 } + } + } + ] + ], + [ + 78, + [ + { + "LinearSplit": { + "value": { "Deref": { "register": "AP", "offset": -4 } }, + "scalar": { "Immediate": "0x8000000000000000000000000000000" }, + "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, + "x": { "register": "AP", "offset": -1 }, + "y": { "register": "AP", "offset": 0 } + } + } + ] + ], + [86, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [122, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [137, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [152, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 167, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [184, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 204, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x5bae" }, + "rhs": { "Deref": { "register": "AP", "offset": -7 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [225, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [245, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [261, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 277, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [315, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 334, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x19fa" }, + "rhs": { "Deref": { "register": "AP", "offset": -12 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 358, + [ + { + "SystemCall": { + "system": { "Deref": { "register": "FP", "offset": -5 } } + } + } + ] + ], + [ + 369, + [ + { + "TestLessThan": { + "lhs": { "Deref": { "register": "AP", "offset": -1 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 371, + [ + { + "DivMod": { + "lhs": { "Deref": { "register": "AP", "offset": -2 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "quotient": { "register": "AP", "offset": 3 }, + "remainder": { "register": "AP", "offset": 4 } + } + } + ] + ], + [ + 409, + [ + { + "TestLessThan": { + "lhs": { "Deref": { "register": "AP", "offset": -1 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 411, + [ + { + "DivMod": { + "lhs": { "Deref": { "register": "AP", "offset": -2 } }, + "rhs": { "Immediate": "0x100000000000000000000000000000000" }, + "quotient": { "register": "AP", "offset": 3 }, + "remainder": { "register": "AP", "offset": 4 } + } + } + ] + ], + [445, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [469, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [484, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [498, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 513, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [560, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 579, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x1284" }, + "rhs": { "Deref": { "register": "AP", "offset": -14 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 607, + [ + { + "SystemCall": { + "system": { "Deref": { "register": "FP", "offset": -5 } } + } + } + ] + ], + [610, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [630, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [645, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [659, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 674, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x0" }, + "rhs": { "Deref": { "register": "FP", "offset": -6 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [691, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 711, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0xae6" }, + "rhs": { "Deref": { "register": "AP", "offset": -7 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [731, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [753, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [769, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [819, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 835, + [ + { + "TestLessThan": { + "lhs": { "Deref": { "register": "FP", "offset": 3 } }, + "rhs": { + "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" + }, + "dst": { "register": "AP", "offset": 4 } + } + } + ] + ], + [ + 839, + [ + { + "LinearSplit": { + "value": { "Deref": { "register": "AP", "offset": 3 } }, + "scalar": { "Immediate": "0x110000000000000000" }, + "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, + "x": { "register": "AP", "offset": -2 }, + "y": { "register": "AP", "offset": -1 } + } + } + ] + ], + [ + 849, + [ + { + "LinearSplit": { + "value": { "Deref": { "register": "FP", "offset": 3 } }, + "scalar": { "Immediate": "0x8000000000000000000000000000000" }, + "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, + "x": { "register": "AP", "offset": -1 }, + "y": { "register": "AP", "offset": 0 } + } + } + ] + ], + [866, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [868, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 911, + [ + { + "SystemCall": { + "system": { "Deref": { "register": "FP", "offset": -3 } } + } + } + ] + ], + [954, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [970, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 986, + [ + { + "TestLessThan": { + "lhs": { "Deref": { "register": "AP", "offset": -3 } }, + "rhs": { + "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" + }, + "dst": { "register": "AP", "offset": 4 } + } + } + ] + ], + [ + 990, + [ + { + "LinearSplit": { + "value": { "Deref": { "register": "AP", "offset": 3 } }, + "scalar": { "Immediate": "0x110000000000000000" }, + "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, + "x": { "register": "AP", "offset": -2 }, + "y": { "register": "AP", "offset": -1 } + } + } + ] + ], + [ + 1000, + [ + { + "LinearSplit": { + "value": { "Deref": { "register": "AP", "offset": -4 } }, + "scalar": { "Immediate": "0x8000000000000000000000000000000" }, + "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, + "x": { "register": "AP", "offset": -1 }, + "y": { "register": "AP", "offset": 0 } + } + } + ] + ], + [1008, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [1083, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 1098, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x8de" }, + "rhs": { "Deref": { "register": "FP", "offset": -7 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [1150, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 1202, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0xec4" }, + "rhs": { "Deref": { "register": "FP", "offset": -10 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 1214, + [ + { + "TestLessThan": { + "lhs": { "Deref": { "register": "AP", "offset": 0 } }, + "rhs": { "Immediate": "0x100000000" }, + "dst": { "register": "AP", "offset": -1 } + } + } + ] + ], + [ + 1232, + [ + { + "TestLessThan": { + "lhs": { "Deref": { "register": "FP", "offset": -9 } }, + "rhs": { "Deref": { "register": "AP", "offset": -1 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 1250, + [ + { + "TestLessThan": { + "lhs": { + "BinOp": { + "op": "Add", + "a": { "register": "FP", "offset": -9 }, + "b": { "Deref": { "register": "AP", "offset": -3 } } + } + }, + "rhs": { "Immediate": "0x100000000" }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [1275, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [1291, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [1307, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [ + 1331, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Deref": { "register": "AP", "offset": -1 } }, + "rhs": { "Deref": { "register": "FP", "offset": -10 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [ + 1397, + [ + { + "TestLessThanOrEqual": { + "lhs": { "Immediate": "0x816" }, + "rhs": { "Deref": { "register": "AP", "offset": -20 } }, + "dst": { "register": "AP", "offset": 0 } + } + } + ] + ], + [1422, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [1470, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]] + ], + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x5de93e1525070ad9e62807a8b7eebf3c7fd7c60dd0a0ec728f9aa3b7c4146b", + "offset": 674, + "builtins": ["range_check", "poseidon"] + }, + { + "selector": "0x148fcde222e93109b646c02f8ed9babeb4fc5dd31b9de5026add8c3601acf9a", + "offset": 167, + "builtins": ["range_check", "poseidon"] + }, + { + "selector": "0x15811ea1dff18014ea6dad7ab86b6ae25e45829c0f8c717c9748a3208e4770e", + "offset": 277, + "builtins": ["range_check"] + }, + { + "selector": "0x21d33b226af0ea4fb717e4f9bff77bd7becd28c61f5bb8a3e3d6c7db1f0f4d8", + "offset": 513, + "builtins": ["range_check"] + }, + { + "selector": "0x3f9333bdab22b77e223157f7ef4f4b91598f4fac1ff161d34e59f646a54482c", + "offset": 0, + "builtins": ["range_check"] + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + } +} diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json new file mode 100644 index 000000000..57f4acbd8 --- /dev/null +++ b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json @@ -0,0 +1,1470 @@ +{ + "sierra_program": [ + "0x1", + "0x6", + "0x0", + "0x2", + "0x8", + "0x0", + "0x171", + "0x8f", + "0x44", + "0x52616e6765436865636b", + "0x800000000000000100000000000000000000000000000000", + "0x436f6e7374", + "0x800000000000000000000000000000000000000000000002", + "0x1", + "0x8", + "0x2", + "0x496e646578206f7574206f6620626f756e6473", + "0x7533325f616464204f766572666c6f77", + "0xe", + "0x4172726179", + "0x800000000000000300000000000000000000000000000001", + "0x536e617073686f74", + "0x800000000000000700000000000000000000000000000001", + "0x5", + "0x537472756374", + "0x800000000000000700000000000000000000000000000002", + "0x0", + "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", + "0x6", + "0x66656c74323532", + "0x800000000000000700000000000000000000000000000000", + "0x800000000000000700000000000000000000000000000003", + "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", + "0x7", + "0x800000000000000f00000000000000000000000000000001", + "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", + "0x800000000000000300000000000000000000000000000003", + "0xa", + "0x456e756d", + "0x2a594b95e3522276fe0ac7ac7a7e4ad8c47eaa6223bc0fd6991aa683b7ee495", + "0x9", + "0xb", + "0x800000000000000700000000000000000000000000000004", + "0x753332", + "0x800000000000000300000000000000000000000000000004", + "0xf", + "0x7da71e1dc546b96d9fd53438ce53f427347947c6c30c6495690af26972951f", + "0x10", + "0x104eb68e98232f2362ae8fd62c9465a5910d805fa88b305d1f7721b8727f04", + "0x12", + "0x398697ad8745b865eefbaa4afad41e52876386afeeb69101604d297801076ef", + "0x436f6e747261637441646472657373", + "0x800000000000000300000000000000000000000000000007", + "0x3dd453aa05a2f3bf86ece4df9fed5c412d578aa6757891c1ad0b57b67790209", + "0x15", + "0x16", + "0x800000000000000300000000000000000000000000000002", + "0x368071f3dba81b34500453fd69db5f6c53faca6693aece4aa9f2a7bc2aa49bc", + "0x18", + "0x556e696e697469616c697a6564", + "0x800000000000000200000000000000000000000000000001", + "0x506f736569646f6e", + "0x1c", + "0x10203be321c62a7bd4c060d69539c1fbe065baa9e253c74d2cc48be163e259", + "0x1e", + "0x3288d594b9a45d15bb2fcb7903f06cdb06b27f0ba88186ec4cfaa98307cb972", + "0x426f78", + "0x29d7d57c04a880978e7b3689f6218e507f3be17588744b58dc17762447ad0e7", + "0x21", + "0x4661696c656420746f20646573657269616c697a6520706172616d202331", + "0x75313238", + "0x25e2ca4b84968c2d8b83ef476ca8549410346b00836ce79beaf538155990bb2", + "0x24", + "0x66b4f105", + "0x4e6f6e5a65726f", + "0x53746f7261676541646472657373", + "0x53746f726167654261736541646472657373", + "0x28a1868d4e0a4c6ae678a74db4e55a60b628ba8668dc128cf0c8e418d0a7945", + "0x2b", + "0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511", + "0x21e8f4b48e39aab91b0f66e96b5501a78cf87c4e56e1214be3451bfd26b2a74", + "0x800000000000000f00000000000000000000000000000003", + "0x2e", + "0x1f952230aae2b27f93ec43fdad476d4b1b5586b5f667332ac43bf94a5b361ae", + "0x2f", + "0x4f7574206f6620676173", + "0x4f7074696f6e3a3a756e77726170206661696c65642e", + "0x74584e9f10ffb1a40aa5a3582e203f6758defc4a497d1a2d5a89f274a320e9", + "0x34", + "0x800000000000000300000000000000000000000000000006", + "0x346f115089c4077e357c839c5a87472e9797e47afb8541ce884b3a13c009605", + "0x36", + "0x2386f26fc10000", + "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + "0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493", + "0x1a055690d9db80000", + "0x3dbe3dd8c2f721bc24e87bcb739063a10ee738cef090bc752bc0d5a29f10b72", + "0x4275696c74696e436f737473", + "0x53797374656d", + "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", + "0x33", + "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", + "0x4761734275696c74696e", + "0xbd", + "0x7265766f6b655f61705f747261636b696e67", + "0x77697468647261775f676173", + "0x6272616e63685f616c69676e", + "0x7374727563745f6465636f6e737472756374", + "0x73746f72655f74656d70", + "0x61727261795f736e617073686f745f706f705f66726f6e74", + "0x64726f70", + "0x61727261795f6e6577", + "0x636f6e73745f61735f696d6d656469617465", + "0x42", + "0x61727261795f617070656e64", + "0x7374727563745f636f6e737472756374", + "0x656e756d5f696e6974", + "0x41", + "0x43", + "0x40", + "0x6765745f6275696c74696e5f636f737473", + "0x3f", + "0x77697468647261775f6761735f616c6c", + "0x3e", + "0x3d", + "0x3c", + "0x3b", + "0x21adb5788e32c84f69a1863d85ef9394b7bf761a0ce1190f826984e5075c371", + "0x3a", + "0x39", + "0x38", + "0x736e617073686f745f74616b65", + "0x37", + "0x66756e6374696f6e5f63616c6c", + "0x3", + "0x656e756d5f6d61746368", + "0x35", + "0x32", + "0x31", + "0x30", + "0x656e61626c655f61705f747261636b696e67", + "0x756e626f78", + "0x72656e616d65", + "0x2d", + "0x6a756d70", + "0x64697361626c655f61705f747261636b696e67", + "0x73746f726167655f626173655f616464726573735f636f6e7374", + "0x3150ab9073ca993efcd1d4ab278c207ab86418914db765f88aa5d8e7bc5c79", + "0x2c", + "0x73746f726167655f616464726573735f66726f6d5f62617365", + "0x29", + "0x2a", + "0x73746f726167655f726561645f73797363616c6c", + "0x66656c743235325f69735f7a65726f", + "0x75313238735f66726f6d5f66656c74323532", + "0x27", + "0x28", + "0x26", + "0x25", + "0x647570", + "0x753132385f746f5f66656c74323532", + "0x23", + "0x22", + "0x20", + "0x626f6f6c5f6e6f745f696d706c", + "0x626f6f6c5f746f5f66656c74323532", + "0x73746f726167655f77726974655f73797363616c6c", + "0x1f", + "0x7374727563745f736e617073686f745f6465636f6e737472756374", + "0x636f6e74726163745f616464726573735f746f5f66656c74323532", + "0x61727261795f6c656e", + "0x7533325f746f5f66656c74323532", + "0x616c6c6f635f6c6f63616c", + "0x66696e616c697a655f6c6f63616c73", + "0x73746f72655f6c6f63616c", + "0x19", + "0x656e756d5f736e617073686f745f6d61746368", + "0x14", + "0x17", + "0x13", + "0x656d69745f6576656e745f73797363616c6c", + "0x1d", + "0x11", + "0xd", + "0xc", + "0x7533325f6f766572666c6f77696e675f737562", + "0x61727261795f676574", + "0x4", + "0x7533325f6f766572666c6f77696e675f616464", + "0x66656c743235325f616464", + "0x68616465735f7065726d75746174696f6e", + "0x4e9", + "0xffffffffffffffff", + "0x66", + "0x59", + "0x1a", + "0x1b", + "0x4b", + "0x45", + "0x46", + "0x47", + "0xbb", + "0x8a", + "0xad", + "0xa5", + "0x16f", + "0xd8", + "0xdd", + "0x15f", + "0xf1", + "0x152", + "0x48", + "0x49", + "0x149", + "0x4a", + "0x11c", + "0x114", + "0x4c", + "0x4d", + "0x118", + "0x4e", + "0x4f", + "0x12e", + "0x50", + "0x51", + "0x127", + "0x12b", + "0x52", + "0x53", + "0x54", + "0x55", + "0x56", + "0x57", + "0x58", + "0x5a", + "0x5b", + "0x5c", + "0x5d", + "0x5e", + "0x5f", + "0x60", + "0x61", + "0x62", + "0x63", + "0x64", + "0x65", + "0x67", + "0x68", + "0x69", + "0x6a", + "0x6b", + "0x6c", + "0x6d", + "0x6e", + "0x6f", + "0x70", + "0x71", + "0x1f4", + "0x189", + "0x18e", + "0x1e4", + "0x199", + "0x19e", + "0x1b0", + "0x1d6", + "0x1cd", + "0x24b", + "0x218", + "0x23d", + "0x235", + "0x72", + "0x73", + "0x74", + "0x297", + "0x75", + "0x76", + "0x77", + "0x78", + "0x79", + "0x7a", + "0x7b", + "0x7c", + "0x7d", + "0x7e", + "0x7f", + "0x304", + "0x80", + "0x2f9", + "0x81", + "0x82", + "0x83", + "0x84", + "0x85", + "0x86", + "0x87", + "0x88", + "0x89", + "0x2f0", + "0x8b", + "0x8c", + "0x2e5", + "0x8d", + "0x8e", + "0x8f", + "0x90", + "0x91", + "0x370", + "0x92", + "0x93", + "0x369", + "0x94", + "0x95", + "0x96", + "0x97", + "0x98", + "0x99", + "0x362", + "0x9a", + "0x9b", + "0x9c", + "0x9d", + "0x9e", + "0x3a8", + "0x38a", + "0x38f", + "0x39d", + "0x9f", + "0xa0", + "0x401", + "0xa1", + "0xa2", + "0xa3", + "0xa4", + "0x454", + "0xa6", + "0x41b", + "0xa7", + "0xa8", + "0xa9", + "0xaa", + "0xab", + "0x444", + "0xac", + "0xae", + "0x434", + "0xaf", + "0xb0", + "0xb1", + "0x4d9", + "0xb2", + "0x471", + "0x476", + "0x4c7", + "0x481", + "0x486", + "0x4b4", + "0xb3", + "0xb4", + "0xb5", + "0x4a2", + "0xb6", + "0xb7", + "0xb8", + "0xb9", + "0xba", + "0xbc", + "0xca", + "0x17d", + "0x202", + "0x25a", + "0x29e", + "0x315", + "0x37e", + "0x3b6", + "0x408", + "0x464", + "0x2c05", + "0x140e0a028100609038180a04018200e06028100605038180a04018080200", + "0x4834100301432050c0482e100b0542805098482210078141c0d03014180b", + "0x180a06028180a18090882021028800a1f090703c0f028740a1809070201b", + "0x484810108144e0513048381e1281414050781430121204030120d0402c23", + "0xb4242c08058562a038180a04018840a29028a0241c0f0940a0f0283c0a18", + "0xcc6405070345e0518848601e178141c0d078140c05030140c05170140c05", + "0x840a38028dc241c0f0180a18090442036028d066021a83c0a34198180a34", + "0xf87a070301408031281478051d8482e1e030141c3a128144a051c8482e1e", + "0x100606028388412039000a04019040e06028100640029000a3f0905c2016", + "0x4090120d0404a05030148e120b8788c052284822100b1102c430901c1405", + "0x1380e0602810064d038180a04018840a4c0292c241c0f0940a4a028602449", + "0x14a412288404205280149e120e0784a050781430120e04032050c0482210", + "0x100655038180a04019500e06028100653028381a060283c0a06028180a2e", + "0x1c0c050200cb0070301408030901c0c050200cae070301408032b01c0c05", + "0x18c246209184c0022f9780e06028100621029740a5c090703c022d858b459", + "0x14d20602814d03c02814ce1402814ce0602814cc1202814ca1902814c812", + "0x140a650281cdc05039b44205029b03a05029b00c05029ac0c0502994d405", + "0x14d27502814d27402814d212399c80a0532848e26e02814ca7002814ca6f", + "0x140a6c3d8140a693d0140a693c8140a69091e01e0502994ee05029a4ec05", + "0x14ce5002814c88102815000f3f814fc7d02814ca5302814ce5302814f853", + "0x140a690901cdc05039b4ba05029b03205029b01e050299c1e05029f04a05", + "0x14ce840281500143f814fc4a02814d83602814ca1902814ce8302814d282", + "0x2251005029942805029942407440140e6d030140a87030140a86092149805", + "0x14d88c038151612450180a0533a200a05400140e880281cda2502814d812", + "0x140a65478140a69092388c0502a1d1a05029911a050299d1a05029f11a05", + "0x1000a05438480a05439000a0532a500a0534849261249049229002814ca0a", + "0x140a984b8140a654b8140a674b8140a7c4b8140a6c4b0140a694a8140a67", + "0x1cda9b02814ca1203a6c0a0736a680a0534849324002814ce9702814c897", + "0x140a670901d3805039b53805029940a074e0140e6d4d8140a800281d3605", + "0xe00a05322800a0540064fe053f1280a05339280a053e0493e124f0493a9c", + "0x2900c0502a8c280502a605c050299c24a2170140a87298140aa13e8140a98", + "0x1f40a0533a040a05328480e810281cda5002814d8063f814fc1902814ca12", + "0x140aa7030140aa7092980c0502a941e0502a946c0502a940a07408140e6d", + "0x2a00a05328c80a05338c80a053e0480e320281cda2f02814d836028154e0f", + "0x1b024ad148140a64560140a80101fc0a7e558140a65550140a69190140aa9", + "0x74fe053f2b80a05338140e840281cda8402814ca1203a100a07369300a05", + "0x140a80109fc0a7e580140a65580140a6c050140a67138140a64578140a80", + "0x15300503a800a0736a800a05328480ea00281cda3802814d82002814c8b1", + "0x2600a07560140e6d560140a650901d5805039b45205029b05e0502a855605", + "0x180a05598640a054c2bc0a05328480eaf0281cda2702814d812590280a05", + "0x140a64038140a690281d5e05039b4fe05029a424b55a0140a691e0140a65", + "0x140a0534ac40a05328140eb10281cda7202814ce720281530125b8496cb0", + "0x1c0a120381424125c8142412092e160050299c2407588140e6d100140a6c", + "0x1568055a0480c055c814fe053f84824b9028480e120c8500eba07ad00eb9", + "0x2e40a200285024125c8142407090840a2e0e8800eb9038180a0f092d00ab9", + "0x1560050e84960055c8142420092c40ab9028480c12092e40a1d028642412", + "0x157205050940eb0090940ab9028496212050157205582c40e21092c00ab9", + "0x9c240f02ae40a0f0289424b402ae40ab402ad024af02ae40a27028282427", + "0x4824b9028480e125781c1eb45a0155e055c8155e05578480e055c8140e05", + "0xa41eb43faa8242902ae40a2902ab0242902ae40a121484824b9028840a14", + "0x2e40a121704956055c81424060904972050901c242f1701d76aa5601d7207", + "0x4978055c814242f092a00ab9028c956071084864055c81464050e8486405", + "0xd80a1d090d80ab90284956125e81572055e2a00e21092f00ab902af00a1d", + "0x1572051c0143a121c0157205090c824ae02ae40a365e81c42121b0157205", + "0x2e40a120384878055f27140075c81c70ac03af024ae02ae40aae02aa02438", + "0x2e40a125704880055c8142436092680ab9028497a124d8157205090182412", + "0x2500a9c0925528075c8152c05500492c055c8152eae20269380f1c0492e05", + "0x2540ab902a540a3c092a80ab902aa80a25092800ab902a800ab4090497205", + "0x2e40e4602a6824464823cfeb902a6d2aaa502d136124d81572054d8155012", + "0x497205260152e12261280eb902a340a400904972050901c2488028011a05", + "0x151e12410157205418152a12092e40a8402a5024834201d7205250152c12", + "0x2e40a9002894248f02ae40a8f02ad0245002ae40a5d02a40245d02ae40a82", + "0x480e122801d208f5a014a0055c814a005578480e055c8140e05138492005", + "0x2400ab902a400a250923c0ab902a3c0ab4092040ab902a200a0a090497205", + "0x2e40a120384902074823d6805408157205408155e12038157205038144e12", + "0x14fa050e848fa055c81424460914c0ab9028480c12092e40aae02a502412", + "0x1572053d9e80eb0091e80ab90284962123d81572053e94c0e21091f40ab9", + "0x9c24aa02ae40aaa02894243c02ae40a3c02ad0247702ae40a79028282479", + "0x4824b9028480e123b81d543c5a014ee055c814ee05578480e055c8140e05", + "0x14ea7603884247502ae40a7502874247502ae40a1246848ec055c8142406", + "0x1b80ab9029c00a0a091c00ab9029d0e40758048e4055c81424b1091d00ab9", + "0x155e12038157205038144e12178157205178144a12170157205170156812", + "0x480c12092e40a7f02a2024125c8142407091b80e2f172d00a6e02ae40a6e", + "0x157205379a80e21091bc0ab9029bc0a1d091bc0ab9028491a12350157205", + "0x2d024c102ae40ac00282824c002ae40a005f81d60125f8157205092c42400", + "0x158205578480e055c8140e051384832055c81432051284828055c8142805", + "0x1d84140781d7207038480e050904972050904824c10386428b402b040ab9", + "0x141e120781572050781568121001572055a014fe12092e40a12038480c19", + "0x1442050c84824b9028740a140904972050901c24b102b0c421d03ae40e20", + "0x1c4212050157205050143a120501572050908024b002ae40a120304824b9", + "0x155e05050495e055c8144a2703ac0242702ae40a12588484a055c81414b0", + "0x500ab9028500a25090140ab9028140a4a0903c0ab90283c0ab4090a40ab9", + "0x142407090a4fe140283c1e05148157205148155e123f81572053f8144e12", + "0x1fd5412560157205560155812560157205090a424125c81562050a04824b9", + "0x2d0243202ae40a122604824b9028480e12558bc0ec4172a80eb903ab0280f", + "0x14fe05138480a055c8140a05250485c055c8145c051284954055c8155405", + "0xe00ab903ab80a83092b86cbd5e2a01eb9028c8fe05172a81e84091fc0ab9", + "0x2700a96092700ab9028480c12092e40a3802a0824125c8142407092800ac5", + "0x1572054d0151e124d01572054d8152a12092e40a3c02a50249b1e01d7205", + "0x9424bd02ae40abd0292824a802ae40aa802ad0249702ae40a4002a402440", + "0x2f17aa8078152e055c8152e05578486c055c8146c051384978055c8157805", + "0x1494125401572055401568124b0157205500141412092e40a12038492e36", + "0x2e40a9602abc243602ae40a360289c24bc02ae40abc0289424bd02ae40abd", + "0x2e40a124684928055c81424060904972050901c24961b2f17aa8078152c05", + "0x4920055c81424b10923c0ab902a552807108492a055c8152a050e8492a05", + "0x14941217815720517815681246815720523014141223015720547a400eb0", + "0x2e40a8d02abc247f02ae40a7f0289c24ab02ae40aab02894240502ae40a05", + "0x2e40a120304824b902ad00a880904972050901c248d3faac0a2f078151a05", + "0x4898055c814948803884244a02ae40a4a02874244a02ae40a12468491005", + "0x640ab4092080ab902a0c0a0a0920c0ab90293108075804908055c81424b1", + "0x1572053f8144e12030157205030144a120281572050281494120c8157205", + "0x1424070284824b9028482412411fc0c050c83c0a8202ae40a8202abc247f", + "0x14245d090180ab9029fc0a7f0904972050901c24190a01d8c0f5a01d7207", + "0x2e40a120384842056387440075c81c0c050784968055c81568055a04824b9", + "0x1f4240a02ae40ab00294c24b002ae40ab102a0424b102ae40a1d029402412", + "0x4824b9028480e12093200a123d0484e055c81414053d8484a055c8144005", + "0x1452053d8484a055c81442053e84852055c8155e053b8495e055c8142479", + "0x49720556014ea12092e40a1203849540564ab00ab90389c0a760909c0ab9", + "0x142812092e40a123a04824b9028480e1255815942f1701d7207128141e12", + "0x7424a802ae40a121004864055c8142406090497205178143212092e40a2e", + "0x2f17a07580497a055c81424b1092f00ab902aa064071084950055c8155005", + "0x157205078144a125a01572055a01568125701572051b01414121b0157205", + "0x142407092b80e0f5a2d00aae02ae40aae02abc240702ae40a070289c240f", + "0x1470055604870055c8142429090497205558142812092e40a123a04824b9", + "0x48e412092e40a1203849363c03b2d38a003ae40e3807ad0feaa090e00ab9", + "0x2e40a97029a824964b81d720520014dc122001572054d014e0124d0157205", + "0x300248f02ae40a9502afc249502ae40a9402800249402ae40a96029bc2412", + "0x2e40aa002ad0248f02ae40a8f02b30249002ae40a9002b04249002ae40a12", + "0x4824b9028480e1242130947f672211a463fae40e8f4801d38b4668494005", + "0x2e40a8d0289c244602ae40a4602894248802ae40a880287424125c814245d", + "0x74248202ae40a125584824b9028480e1241815a0125c81d1005678491a05", + "0x4972050901c247d29a04fed1281740eb903a0940075f04904055c8150405", + "0x1ec0ad3091e40ab9029400ad3091e80ab9029740ab4091ec0ab902849a412", + "0x15a6123d0157205408156812092e40a120384824d402848f4123b8157205", + "0x2e40a7902b58247602ae40a7a02b54247702ae40a5302b4c247902ae40a7d", + "0x1506056c04824b9028480e120935c0a123d048e8055c814ee056b048ea05", + "0x1b8e0075c81ce4a003af8247202ae40a7202874247202ae40a126c84824b9", + "0x4980055c814e0055a0497e055c81424d20904972050901c2400379a8feda", + "0x4972050901c24126d814247a093300ab902afc0ad3093040ab9029b80ad3", + "0x15aa1266015720537815a61260815720500015a612600157205350156812", + "0x497205091d0247402ae40acc02b58247502ae40ac102b58247602ae40ac0", + "0x37824d25f01d720567815ba126781572053a1d40edc093340ab9028480c12", + "0x15a60570849a6d203ae40ad202b8024d202ae40ad202b7c24125c8157c05", + "0x3640ab902b600abb093600ab902b540ad60904972056b015c4126b3540eb9", + "0x35824125c815ba0571049bcdd03ae40ad202b8424dc02ae40ad96681c4212", + "0x3840a96093840ab902b81b80710849c0055c815be055d849be055c815bc05", + "0x157205718151e127181572055d8152a12092e40ae202a5024bb7101d7205", + "0x9c244602ae40a4602894247602ae40a7602ad024e502ae40ae402a4024e4", + "0x4824b9028480e1272a348c765a015ca055c815ca05578491a055c8151a05", + "0x2800ab4093a00ab902b9c0a0a0939c0ab902a11cc0758049cc055c81424b1", + "0x157205740155e12260157205260144e12250157205250144a12500157205", + "0x3a80ab9028491a127481572050901824125c8142407093a0984a502d00ae8", + "0x1d6012760157205092c424eb02ae40aea7481c4212750157205750143a12", + "0x1536051284878055c81478055a049dc055c815da0505049da055c815d6ec", + "0x1c24ee03a6c78b402bb80ab902bb80aaf0901c0ab90281c0a270926c0ab9", + "0x480c12092e40a250285024125c81554054b84824b902848e812092e40a12", + "0x15720577ae80e21093bc0ab902bbc0a1d093bc0ab902849c6125d0157205", + "0x2d024f302ae40af20282824f202ae40af07881d6012788157205092c424f0", + "0x15e605578480e055c8140e05138481e055c8141e051284968055c8156805", + "0x2e40a120304824b9029fc0a880904972050901c24f30383d68b402bcc0ab9", + "0x49ec055c815eaf40388424f502ae40af50287424f502ae40a1246849e805", + "0x500ab4093e40ab902be00a0a093e00ab902bd9ee0758049ee055c81424b1", + "0x1572057c8155e12038157205038144e120c81572050c8144a120a0157205", + "0x6428077d03d68075c81c0a120381424125c8142412093e40e190a2d00af9", + "0x1572055a0156812092e40a122e8480c055c814fe053f84824b9028480e12", + "0x2c40ab9028740ae40904972050901c242102bec3a2003ae40e060283c24b4", + "0x2e40a120384824fc02848f41205015720558815ca1258015720510014fa12", + "0x15ca1258015720510814fa1213815720512815cc12128157205091e42412", + "0x155e052804824b9028480e1214815faaf02ae40e0a02b9c240a02ae40a27", + "0x3f824b903aa80acf092a80ab902aa80a1d092a80ab902ab00a81092b00ab9", + "0x2ac0ae9092ac0ab9028bc0ae8090bc0ab902848f212092e40a12038485c05", + "0x14247909049720517015b012092e40a120384824ff02848f412190157205", + "0x2f40eb903ac00a0f090c80ab902af00ae9092f00ab902aa00aea092a00ab9", + "0xd80a190904972055e8142812092e40a123a04824b9028480e12570160036", + "0x143a1250015720509080243802ae40a120304824b9028c80aeb090497205", + "0x15383c03ac0243c02ae40a125884938055c81540380388424a002ae40aa0", + "0x3c0ab90283c0a25092d00ab902ad00ab4092680ab902a6c0a0a0926c0ab9", + "0x2e40a1203849340707ad168054d01572054d0155e12038157205038144e12", + "0x2e40a4002ab0244002ae40a121484824b902ab80a14090497205091d02412", + "0x1424720904972050901c24954a01e02964b81d72072003d687f550488005", + "0x2340ab902a3c0abf091180ab902a400aed092400ab9028c80aec0923c0ab9", + "0x1180a1d092340ab902a340acc092200ab902a200ac1092200ab9028498012", + "0x1fe044c2501d72072323510074b03ddc124b81572054b8156812230157205", + "0x25024812801d72052e8152c122e81572050901824125c8142407092090684", + "0x2e40a7d02a40247d02ae40a5302a3c245302ae40a8102a5424125c814a005", + "0x4898055c81498051384894055c8149405128492e055c8152e055a048f605", + "0x48f4055c81424b10904972050901c247b261292eb4029ec0ab9029ec0aaf", + "0x144a124b81572054b81568123b81572053c81414123c8157205411e80eb0", + "0x1dd06844bad00a7702ae40a7702abc248302ae40a830289c248402ae40a84", + "0x1d40ab9028491a123b01572050901824125c81464057584824b9028480e12", + "0x1d6012390157205092c4247402ae40a753b01c42123a81572053a8143a12", + "0x152a051284928055c81528055a048dc055c814e00505048e0055c814e872", + "0x1c246e03a5528b4029b80ab9029b80aaf0901c0ab90281c0a27092540ab9", + "0x480c12092e40ab00285024125c81452054b84824b902848e812092e40a12", + "0x157205379a80e21091bc0ab9029bc0a1d091bc0ab902849c612350157205", + "0x2d024c102ae40ac00282824c002ae40a005f81d60125f8157205092c42400", + "0x158205578480e055c8140e05138481e055c8141e051284968055c8156805", + "0x2e40a120304824b9029fc0a880904972050901c24c10383d68b402b040ab9", + "0x499e055c8159acc0388424cd02ae40acd0287424cd02ae40a12468499805", + "0x500ab40934c0ab902b480a0a093480ab902b3d7c07580497c055c81424b1", + "0x157205698155e12038157205038144e120c81572050c8144a120a0157205", + "0x183207818501e075c81c0e120381424125c81424120934c0e190a2d00ad3", + "0x1c4005078481e055c8141e055a04840055c81568053f84824b9028480e12", + "0x497205108143212092e40a1d0285024125c8142407092c40b04108740eb9", + "0x2960071084814055c81414050e84814055c8142420092c00ab9028480c12", + "0x1572055781414125781572051289c0eb00909c0ab9028496212128157205", + "0x9c241402ae40a1402894240502ae40a0502928240f02ae40a0f02ad02429", + "0x4972050901c24293f8500a0f0781452055c814520557848fe055c814fe05", + "0x501e7f5504958055c81558055604958055c8142429090497205588142812", + "0xc80aba090c80ab9028489812092e40a1203849562f03c145caa03ae40eac", + "0x157205170144a12550157205550156812092e40aa802bbc24bc5401d7205", + "0xe00af1090e15c365ead172055e0145caa5a3c0240502ae40a0502928242e", + "0x15720550015e4121e01572050901824125c8142407092700b06500157207", + "0x4824b9029000a940925c80075c81534054b04934055c815363c03884249b", + "0x2f40ab4092540ab902a500a90092500ab902a580a8f092580ab902a5c0a95", + "0x1572053f8144e121b01572051b0144a125701572055701494125e8157205", + "0x1538050504824b9028480e124a9fc6cae5e83c0a9502ae40a9502abc247f", + "0xd80ab9028d80a25092b80ab902ab80a4a092f40ab902af40ab40923c0ab9", + "0x1424070923cfe36572f41e05478157205478155e123f81572053f8144e12", + "0x1c4212230157205230143a1223015720509234249002ae40a120304824b9", + "0x1494050504894055c8151a8803ac0248802ae40a12588491a055c8148c90", + "0x2ac0ab902aac0a25090140ab9028140a4a090bc0ab9028bc0ab4091300ab9", + "0x14240709130feab028bc1e05260157205260155e123f81572053f8144e12", + "0x20c0a1d0920c0ab9028491a124201572050901824125c81568054404824b9", + "0x2e40a822e81d60122e8157205092c4248202ae40a834201c4212418157205", + "0x480a055c8140a052504832055c81432055a04902055c814a00505048a005", + "0x14320f02a040ab902a040aaf091fc0ab9029fc0a27090180ab9028180a25", + "0x501e0f5c81568057a049680703ae40a0702bcc24125c814247409204fe06", + "0x14ea12092e40a060285024125c81432053a84824b9028500a75090800c19", + "0x2e40a213f81c42121081572050e815ec120e815720507815ea12092e40a20", + "0x280af7090a55e27128281eb902ac00af4092c00e075c8140e05798496205", + "0x150212092e40a29029d424125c8155e050a04824b90289c0a75090497205", + "0xb80af4090b80e075c8140e057984954055c81558b10388424ac02ae40a25", + "0x1550050a04824b902aac0a7509049720517815ee125e2a064ab1783d7205", + "0x486c055c8157aaa0388424bd02ae40a3202a0424125c81578053a84824b9", + "0x4972051c015ee124d8f138a01c03d720557015e8125701c0eb90281c0af3", + "0x2e40a3c02be024125c81536053a84824b902a700a7509049720550014ea12", + "0x25c0ab902a5c0a1d0925c0ab9029000b07091000ab902a680af9092687807", + "0x94241202ae40a1202ad0249402ae40a3c02a54249602ae40a971b01c4212", + "0x1424b4848492c055c8152c055404928055c8152805840480a055c8140a05", + "0x10024125c8142407092340b0a2301572074801534124823d2a7f5c8152c94", + "0x48ba8241a10980f5c8140e057a04824b9029280a970912910075c8148c05", + "0x497205410142812092e40a83029d424125c81508053a84824b9029300af7", + "0x1e1612298157205091e4248102ae40a504401c42122801572052e8150212", + "0x151e05128492a055c8152a055a048f6055c814fa0586048fa055c814a681", + "0x140e058704824b9028480e123da3d2a7f029ec0ab9029ec0b0d0923c0ab9", + "0x491e055c8151e05128492a055c8152a055a048f4055c8151a058784824b9", + "0x480c055c8142511090500ab90284a20123d23d2a7f029e80ab9029e80b0d", + "0xb8242102ae40a120304824b902848e812092e40a12898483a055c8142512", + "0x2e40a121784960055c81562210388424b102ae40ab10287424b102ae40a12", + "0x484e055c81424ab090940ab90282960071084814055c81414050e8481405", + "0x740f14090800ab90284864120c8157205138940e210909c0ab90289c0a1d", + "0x2b00b1614abc0eb90388024075e04832055c814320603c54242002ae40a20", + "0x140a25092bc0ab902abc0ab4090b954075c81568055d04824b9028480e12", + "0x48640f558bd68b9028b80e0557ad1e012038157205038149412028157205", + "0x1824125c8142407092f00b1854015720719015e212078157205078500f17", + "0x4870055c8142436092b80ab9028497a121b01572050901824bd02ae40a12", + "0xf00ab9028654038570a538148c84938055c81550057904940055c81424ae", + "0x163a12092e40a9a02c7024404d01d72054d81636124d81572051e0163412", + "0x492c055c814251f0904972050901c249702ae40a4002c78244002ae40a40", + "0x144a121781572051781568124a01572054b2f40e21092580ab902a580a1d", + "0x2e40a3602aa0249402ae40a9402aa0249702ae40a9702c8024ab02ae40aab", + "0x2340b222301572074801586124823d2a7f5c8146c944baac5e0f908486c05", + "0x2200a96090497205260152e1226129107f5c8148c059184824b9028480e12", + "0x2e40a8202a50245d4101d7205250152c12092e40a8402a5024834201d7205", + "0x1d720740940fe8f5a490248102ae40a5d02a54245002ae40a8302a542412", + "0x2e40a775501e4c123b8157205091e424125c8142407091e4f47b3fc94fa53", + "0x48a6055c814a605128492a055c8152a055a048ea055c814ec0593848ec05", + "0x14d2a0f029d40ab9029d40b28091f40ab9029f40a270903c0ab90283c0a4a", + "0x1d00eb0091d00ab9028496212092e40aaa02bbc24125c8142407091d4fa0f", + "0x2e40a7b02894249502ae40a9502ad0247002ae40a7202ca4247202ae40a79", + "0x14e0055c814e00594048f4055c814f405138481e055c8141e0525048f605", + "0x1b80ab902a340b2909049720555015de12092e40a1203848e07a079ed2a0f", + "0x144e12078157205078149412478157205478144a124a81572054a8156812", + "0x4824b9028480e12371fc1e8f4a83c0a6e02ae40a6e02ca0247f02ae40a7f", + "0x1572055e0165212092e40a1902a5024125c81452057b84824b902aa80aef", + "0x9c240f02ae40a0f0292824ab02ae40aab02894242f02ae40a2f02ad0246a", + "0x4972050901c246a3f83d562f07814d4055c814d40594048fe055c814fe05", + "0x1572050901824125c81428059504824b9028640a940904972055a015de12", + "0x2c424bf02ae40a003781c4212000157205000143a1200015720509118246f", + "0x1558055a04998055c81582059484982055c8157ec003ac024c002ae40a12", + "0x1fc0ab9029fc0a270901c0ab90281c0a4a090140ab9028140a25092b00ab9", + "0x2e40a7f02bbc24125c814247409330fe0702ab01e05660157205660165012", + "0x2d00e210903c0ab90283c0a1d0903c0ab9028485c125a0157205090182412", + "0x2e40a190a01c42120c81572050c8143a120c8157205090bc241402ae40a0f", + "0x483a055c814400603884242002ae40a2002874242002ae40a12558480c05", + "0x8424075e0483a055c8143a055404842055c81442050e84842055c8142432", + "0x2e40ab002bd8242502ae40a120304824b9028480e120501656b05881d7207", + "0x4852055c81452050e84852055c81424bd092bc0ab90289c4a07108484e05", + "0x2b00e21092a80ab902aa80a1d092a80ab9028486c1256015720514abc0e21", + "0x2e40a2f1701c4212178157205178143a12178157205092b8242e02ae40aaa", + "0x2f40ab902af00b07092f00ab902aa00af9092a064075c8143a054b0495605", + "0x152c1257015720509300243602ae40abd5581c42125e81572055e8143a12", + "0x1540054a84824b902a700a94090f138075c81470054b049403803ae40a32", + "0x2b80ab902ab80ac1090140ab9028140a25092c40ab902ac40ab40926c0ab9", + "0x5258121e01572051e014fa121b01572051b01550124d81572054d8161012", + "0x142407092500b2e4b01572074b8165a124b901347f5c81478364dab80ab1", + "0x4824b902a400b3009119208f3fae40a9602cbc249502ae40a121484824b9", + "0x2e40a125584824b902a340a94092211a075c8151e054b04824b9029180a97", + "0x4906055c815084c251fe6212420157205092ac244c02ae40a12558489405", + "0x1c0a4a091000ab9029000a25092680ab902a680ab4092080ab902a200a95", + "0x1572054101610124181572054181664124a81572054a8155812038157205", + "0x166a7d02ae40e5302cd0245340940bab45c81504834a81c809a0a4cc2482", + "0x1e40b370904972053d01510123c9e80eb9029f40b360904972050901c247b", + "0x157205280144a122e81572052e81568123b01572053b81670123b8157205", + "0x142407091d902502ead00a7602ae40a7602ce4248102ae40a81029282450", + "0x48a0055c814a00512848ba055c814ba055a048ea055c814f6059d04824b9", + "0x4972050901c247540940bab4029d40ab9029d40b39092040ab902a040a4a", + "0x149412200157205200144a124d01572054d01568123a01572054a0167412", + "0x25024125c8142407091d00e404d2d00a7402ae40a7402ce4240702ae40a07", + "0x1c00ab9029c00a1d091c00ab9028488c123901572050901824125c8143a05", + "0x4e8246f02ae40a6e3501d6012350157205092c4246e02ae40a703901c4212", + "0x140e05250480a055c8140a051284814055c81414055a04800055c814de05", + "0x480e05090497205091d024000381414b4028000ab9028000b390901c0ab9", + "0x48ba1203015720503814fe12092e40a1203848321403cec1eb403ae40e05", + "0x142407090840b3c0e8800eb9038180a0f092d00ab902ad00ab4090497205", + "0x4814055c81562057284960055c81440053e84962055c8143a057204824b9", + "0x484e055c8144a05730484a055c81424790904972050901c24129e814247a", + "0x4852059f2bc0ab9038280ae7090280ab90289c0ae5092c00ab9028840a7d", + "0x2a80ab902ab00a81092b00ab902abc0a50090497205091d024125c8142407", + "0x2d0242f02ae40ab002a54242e02ae40aaa3f81c4212550157205550143a12", + "0x145c05540485e055c8145e05840481e055c8141e051284968055c8156805", + "0x4972050901c24a8192acfe05540c9567f5c8145c2f07ad16909090b80ab9", + "0x2f00ab902848f212092e40ab00285024125c81452054b84824b902848e812", + "0x9424b402ae40ab402ad0243602ae40abd02c3024bd02ae40abc3f81e1612", + "0x25024125c8142407090d81eb43f8146c055c8146c05868481e055c8141e05", + "0x4870055c814248d092b80ab9028480c12092e40a0702a2024125c814fe05", + "0x2700eb0092700ab90284962125001572051c2b80e21090e00ab9028e00a1d", + "0x2e40a1902894241402ae40a1402ad0249b02ae40a3c02c3c243c02ae40aa0", + "0x2e40a0702cfc24125c81424740926c32143f81536055c8153605868483205", + "0x180a750904972050c815ee121087440060c85028b90283c0b400903c0e07", + "0x150212092e40a210285024125c8143a053a84824b9028800a75090497205", + "0x280b40090280e075c8140e059f84960055c81562b40388424b102ae40a14", + "0xa40a7509049720557814ea12092e40a25029d424aa560a55e27128517205", + "0x3d8242e02ae40a2702bd424125c81554050a04824b902ab00a75090497205", + "0x1680121901c0eb90281c0b3f092ac0ab9028bd6007108485e055c8145c05", + "0x14ea12092e40abc02bdc24125c81550053a84870ae1b2f578a80a2e40a32", + "0x4940055c8157a054084824b9028e00a1409049720557014ea12092e40a36", + "0x101349b0a2e40a3c02d00243c0381d7205038167e124e0157205502ac0e21", + "0x14ea12092e40a40029d424125c81534057b84824b902a6c0a75092512c97", + "0x1572054aa700e21092540ab902a5c0a810904972054a0142812092e40a96", + "0x1180a7509210984a442348c145c8152005a0049200703ae40a0702cfc248f", + "0x142812092e40a4a029d424125c81510053a84824b902a340af7090497205", + "0x2e40a0702d00248202ae40a834781c4212418157205260150212092e40a84", + "0x2e40a81029d424125c814a0057b84824b9029740a75091ecfa5340940ba14", + "0x15f2123d1ec0eb9029ec0af80904972053e814ea12092e40a53029d42412", + "0x14ee8203884247702ae40a7702874247702ae40a7902c1c247902ae40a7a", + "0x140ab9028140a25090480ab9028480ab4091d40ab9029ec0a95091d80ab9", + "0x1d0feb9029d8ea05092d212123b01572053b01550123a81572053a8161012", + "0x1bc0eb9029b80a400904972050901c246a02d04dc055c81ce0054d048e072", + "0x50c24c002ae40abf379fcff42092fc0ab902848f212092e40a0002a5c2400", + "0x158205a2048e4055c814e40512848e8055c814e8055a04982055c8158005", + "0x2e40a6a02d1424125c814fe054a04824b9028480e12609c8e87f02b040ab9", + "0x1598055c8159805a2048e4055c814e40512848e8055c814e8055a0499805", + "0x480e12100180f460c8500eb90381424070284824b902848e812661c8e87f", + "0x1d7205038158a121081572050e815f2120e83c0eb90283c0af8090497205", + "0x1c24271281e900a5801d720710ac4287fa384842055c8144205608496207", + "0x1e424125c814fe054404824b90283c0a14090497205050166012092e40a12", + "0x2c00ab4092b00ab9028a40b4a090a40ab902abc0eb43fd2424af02ae40a12", + "0x1c24ac0cac0fe055601572055601696120c81572050c8144a12580157205", + "0x15720555014fe12551fc0eb9029fc0b4c090497205138166012092e40a12", + "0x480e12540169c325581d7207178b84a7fa68485e0703ae40a0702b14242e", + "0x2f40ab902af00a81092f00ab9028c80a50090c80ab9028c80b4f090497205", + "0x15821257015720509310243602ae40abd5a01c42125e81572055e8143a12", + "0x2700f51500e00eb903ab80eab3fd40243602ae40a3602aa024ae02ae40aae", + "0x2800ac1090640ab9028640a25090e00ab9028e00ab40904972050901c243c", + "0x15720507814fa121b01572051b01550123f81572053f8161012500157205", + "0x4972050901c24404d26cfe0520269367f5c8141e363fa8032380a4b0240f", + "0x2e40a7f02a2024125c8146c054a04824b90283c0a140904972051e0166012", + "0x25c0e21092580ab902a580a1d092580ab90284aa4124b8157205090182412", + "0x2e40a8f02d4c248f02ae40a944a81d60124a8157205092c4249402ae40a96", + "0x1520055c8152005a584832055c81432051284938055c81538055a0492005", + "0x151012092e40a0702cc024125c8141e050a04824b9028480e1248065387f", + "0x74248d02ae40a12aa0488c055c81424060904972055a0152812092e40a7f", + "0x22094075804894055c81424b1092200ab902a348c07108491a055c8151a05", + "0x1572050c8144a1254015720554015681242015720526016a612260157205", + "0x497205038166012092e40a12038490819541fc0a8402ae40a8402d2c2419", + "0x1572050901824125c8141e050a04824b902ad00a940904972053f8151012", + "0x2c4245d02ae40a824181c4212410157205410143a12410157205092342483", + "0x140c055a048a6055c8150205a984902055c814ba5003ac0245002ae40a12", + "0x48e812298800c7f0294c0ab90294c0b4b090800ab9028800a25090180ab9", + "0x2d00b560904972050901c24200301eaa190a01d7207028480e05090497205", + "0x1572050a0156812092e40a122e84960055c8141e053f84962210e9fd7205", + "0x2bc0ab9028940ae40904972050901c242702d5c4a0a03ae40eb00283c2414", + "0x2e40a1203848255802848f41256015720557815ca1214815720505014fa12", + "0x15ca1214815720513814fa1217015720555015cc12550157205091e42412", + "0x145e052804824b9028480e1255816b22f02ae40eac02b9c24ac02ae40a2e", + "0x2f00eb9038a40a0f092a00ab902aa00a1d092a00ab9028c80a81090c80ab9", + "0x4870055c81578053e8495c055c8157a057204824b9028480e121b016b4bd", + "0x4938055c81424790904972050901c2412ad814247a092800ab902ab80ae5", + "0xe00a95092800ab9028f00ae5090e00ab9028d80a7d090f00ab902a700ae6", + "0x497205091d024125c8142407091000b5c4d015720750015ce124d8157205", + "0x74249402ae40aa80e81eba124b01572054b81502124b81572054d014a012", + "0x2540a1d092500ab902a500a1d092540ab902a584207ae8492c055c8152c05", + "0x220fe075c814fe05af8491a464823d68b902ac52a9403ad2bc124a8157205", + "0x143a12230157205230143a12480157205480143a12478157205478149412", + "0x4824b9028480e1241a100f60261280eb903a2032143faa8248d02ae40a8d", + "0x128244c02ae40a4c02894244a02ae40a4a02ad0248202ae40a8d23240ff31", + "0x1536058404904055c815040599048fe055c814fe05560491e055c8151e05", + "0x1c245340940bab40294d02502ead172054da08fe8f2612829330926c0ab9", + "0x1d424125c814fe05b084824b902a400a750904972054d8151012092e40a12", + "0x48f6055c814248d091f40ab9028480c12092e40a8d029d424125c8148c05", + "0x1e40eb0091e40ab90284962123d01572053d9f40e21091ec0ab9029ec0a1d", + "0x2e40a8302894248402ae40a8402ad0247602ae40a7702d88247702ae40a7a", + "0x480e123b23d06845a014ec055c814ec05b18491e055c8151e05250490605", + "0x740f5d0904972053f816c212092e40a4002a5c24125c8142474090497205", + "0x2e40a7502874247202ae40a741081eba123a015720509590247502ae40aa8", + "0x14ea12379a8dc705a2e40ab1391d40eb4af048e4055c814e4050e848ea05", + "0x1572050001584120001572053726c0f6509049720537814ea12092e40a6a", + "0x58c247002ae40a7002928241902ae40a1902894241402ae40a1402ad024bf", + "0x152e12092e40a123a04824b9028480e125f9c032145a0157e055c8157e05", + "0x3040ab902b003a07ae84980055c81425640904972053f816c212092e40aab", + "0x159e053a8497ccf66b3168b902ac442c103ad2bc12608157205608143a12", + "0x49a6055c8159ad203d9424d202ae40a2902a5424125c8157c053a84824b9", + "0x3300a4a090640ab9028640a25090500ab9028500ab4093540ab902b4c0ac2", + "0x151012092e40a1203849aacc0c85168056a81572056a816c612660157205", + "0x23424d602ae40a120304824b902ad00b660904972053f816c212092e40a0f", + "0x2e40a1258849b2055c815b0d60388424d802ae40ad80287424d802ae40a12", + "0x180ab9028180ab4093780ab902b740b62093740ab902b65b80758049b805", + "0x1968056f01572056f016c612038157205038149412100157205100144a12", + "0x481e19381bc6c1207848fe0702848dc70378496819381bc24b458b780e20", + "0x4969673f81c0a12371c0de125a064e06f092d212b43f81c0a12371c0de36", + "0x14246e381bc6c1207864e06f1b0481f683f81c0a12371c0de125a064e06f", + "0x1bc240f251c06c6f0903ed47f03814248137848fe0f3e9bc24b4b4ad0fe07", + "0x1bc24b4b61fc0e05092806c6f092d0943637849696b5a1fc0e0509210e036", + "0x5b9687f0381424ac37848fe0f07aacde1207db4fe0702849026f091fc1e19", + "0x496819581c86c6f09052de0f5a1fc0e05092bcde123f8501e19051bc2414", + "0x2e00f5a1fc0e05092c46c6f" + ], + "sierra_program_debug_info": { + "type_names": [ + [0, "RangeCheck"], + [1, "Const"], + [2, "Const"], + [3, "Const"], + [4, "Const"], + [5, "Array"], + [6, "Snapshot>"], + [7, "core::array::Span::"], + [8, "felt252"], + [9, "Tuple, felt252>"], + [10, "core::panics::Panic"], + [11, "Tuple>"], + [ + 12, + "core::panics::PanicResult::<(core::array::Span::, core::felt252)>" + ], + [13, "Tuple"], + [14, "u32"], + [15, "Unit"], + [16, "Tuple, u32, Unit>"], + [ + 17, + "core::panics::PanicResult::<(core::array::Array::, core::integer::u32, ())>" + ], + [18, "Tuple, Array, Unit>"], + [ + 19, + "core::panics::PanicResult::<(core::array::Array::, core::array::Array::, ())>" + ], + [ + 20, + "Const" + ], + [21, "ContractAddress"], + [22, "temp_cairo::messaging::MessagingContract::MessageSent"], + [23, "Snapshot"], + [24, "temp_cairo::messaging::MessagingContract::Event"], + [25, "Snapshot"], + [26, "Uninitialized"], + [27, "Uninitialized>"], + [28, "Poseidon"], + [29, "Uninitialized"], + [30, "Tuple"], + [31, "core::panics::PanicResult::<(core::felt252,)>"], + [32, "core::bool"], + [33, "Box"], + [34, "core::option::Option::>"], + [ + 35, + "Const" + ], + [36, "u128"], + [37, "core::integer::u256"], + [38, "Const"], + [39, "Const"], + [40, "NonZero"], + [41, "Const"], + [42, "StorageAddress"], + [43, "StorageBaseAddress"], + [44, "core::starknet::storage::StoragePointer0Offset::"], + [45, "core::option::Option::"], + [46, "temp_cairo::messaging::MessagingContract::ContractState"], + [ + 47, + "Tuple" + ], + [ + 48, + "core::panics::PanicResult::<(temp_cairo::messaging::MessagingContract::ContractState, ())>" + ], + [49, "Const"], + [ + 50, + "Const" + ], + [51, "Tuple>"], + [52, "Tuple, Unit>"], + [ + 53, + "core::panics::PanicResult::<(core::array::Array::, ())>" + ], + [54, "temp_cairo::messaging::MessageData"], + [55, "Snapshot"], + [56, "Const"], + [ + 57, + "Const" + ], + [ + 58, + "Const" + ], + [ + 59, + "Const" + ], + [60, "Const"], + [61, "Const"], + [ + 62, + "Const" + ], + [63, "BuiltinCosts"], + [64, "System"], + [ + 65, + "core::panics::PanicResult::<(core::array::Span::,)>" + ], + [ + 66, + "Const" + ], + [67, "GasBuiltin"] + ], + "libfunc_names": [ + [0, "revoke_ap_tracking"], + [1, "withdraw_gas"], + [2, "branch_align"], + [3, "struct_deconstruct>"], + [4, "store_temp"], + [5, "array_snapshot_pop_front"], + [6, "drop>>"], + [7, "drop>"], + [8, "array_new"], + [ + 9, + "const_as_immediate>" + ], + [10, "store_temp"], + [11, "array_append"], + [12, "struct_construct"], + [13, "struct_construct>>"], + [ + 14, + "enum_init,)>, 1>" + ], + [15, "store_temp"], + [16, "store_temp"], + [ + 17, + "store_temp,)>>" + ], + [18, "get_builtin_costs"], + [19, "store_temp"], + [20, "withdraw_gas_all"], + [ + 21, + "const_as_immediate>" + ], + [22, "const_as_immediate>"], + [23, "const_as_immediate>"], + [ + 24, + "const_as_immediate>" + ], + [25, "store_temp>"], + [26, "contract_address_try_from_felt252"], + [ + 27, + "const_as_immediate>" + ], + [ + 28, + "const_as_immediate>" + ], + [29, "const_as_immediate>"], + [30, "struct_construct"], + [31, "snapshot_take"], + [32, "drop"], + [33, "store_temp>"], + [ + 34, + "function_call" + ], + [ + 35, + "enum_match, ())>>" + ], + [36, "struct_deconstruct, Unit>>"], + [37, "drop"], + [38, "snapshot_take>"], + [39, "drop>"], + [40, "struct_construct>"], + [41, "struct_construct>>"], + [ + 42, + "enum_init,)>, 0>" + ], + [ + 43, + "const_as_immediate>" + ], + [44, "const_as_immediate>"], + [45, "drop>"], + [46, "store_temp"], + [ + 47, + "struct_construct" + ], + [ + 48, + "function_call" + ], + [ + 49, + "enum_match>" + ], + [ + 50, + "drop>" + ], + [51, "enable_ap_tracking"], + [52, "unbox"], + [53, "rename"], + [54, "enum_init, 0>"], + [55, "store_temp>>"], + [56, "store_temp>"], + [57, "jump"], + [58, "struct_construct"], + [59, "enum_init, 1>"], + [60, "enum_match>"], + [61, "drop"], + [62, "disable_ap_tracking"], + [ + 63, + "storage_base_address_const<87132271245367979733157522781602464771675853065476568805507240456934415481>" + ], + [ + 64, + "struct_construct>" + ], + [ + 65, + "snapshot_take>" + ], + [ + 66, + "drop>" + ], + [ + 67, + "struct_deconstruct>" + ], + [68, "rename"], + [69, "storage_address_from_base"], + [70, "const_as_immediate>"], + [71, "store_temp"], + [72, "store_temp"], + [73, "storage_read_syscall"], + [74, "felt252_is_zero"], + [75, "u128s_from_felt252"], + [76, "const_as_immediate>"], + [77, "store_temp"], + [78, "rename"], + [79, "rename"], + [80, "drop>"], + [81, "const_as_immediate>"], + [82, "struct_construct"], + [83, "snapshot_take"], + [84, "drop"], + [85, "store_temp"], + [86, "dup"], + [87, "struct_deconstruct"], + [88, "drop"], + [89, "u128_to_felt252"], + [ + 90, + "const_as_immediate>" + ], + [ + 91, + "enum_init>, 0>" + ], + [ + 92, + "store_temp>>" + ], + [ + 93, + "enum_init>, 1>" + ], + [ + 94, + "enum_match>>" + ], + [95, "enum_init"], + [96, "store_temp"], + [97, "enum_init"], + [98, "drop"], + [99, "bool_not_impl"], + [100, "bool_to_felt252"], + [101, "storage_write_syscall"], + [ + 102, + "snapshot_take" + ], + [103, "drop"], + [ + 104, + "function_call" + ], + [105, "enum_match>"], + [106, "struct_deconstruct>"], + [107, "dup>"], + [108, "struct_snapshot_deconstruct"], + [109, "rename"], + [110, "contract_address_to_felt252"], + [111, "drop"], + [112, "dup>>"], + [113, "array_len"], + [114, "u32_to_felt252"], + [115, "store_temp>"], + [ + 116, + "function_call>" + ], + [117, "struct_construct, Unit>>"], + [ + 118, + "enum_init, ())>, 0>" + ], + [ + 119, + "store_temp, ())>>" + ], + [120, "drop>"], + [ + 121, + "enum_init, ())>, 1>" + ], + [122, "alloc_local"], + [123, "alloc_local>"], + [124, "alloc_local"], + [125, "finalize_locals"], + [126, "store_local"], + [127, "store_local>"], + [128, "store_local"], + [ + 129, + "struct_construct" + ], + [130, "enum_init"], + [131, "snapshot_take"], + [132, "drop"], + [ + 133, + "store_temp>" + ], + [ + 134, + "enum_snapshot_match" + ], + [ + 135, + "const_as_immediate>" + ], + [ + 136, + "store_temp>" + ], + [ + 137, + "function_call" + ], + [ + 138, + "enum_match, core::array::Array::, ())>>" + ], + [139, "struct_deconstruct, Array, Unit>>"], + [140, "emit_event_syscall"], + [ + 141, + "struct_construct>" + ], + [ + 142, + "enum_init, 0>" + ], + [ + 143, + "store_temp>" + ], + [ + 144, + "enum_init, 1>" + ], + [145, "drop>"], + [ + 146, + "function_call" + ], + [ + 147, + "enum_match, core::integer::u32, ())>>" + ], + [148, "struct_deconstruct, u32, Unit>>"], + [149, "drop"], + [150, "struct_construct>"], + [151, "store_temp>"], + [152, "function_call"], + [ + 153, + "enum_match, core::felt252)>>" + ], + [ + 154, + "struct_deconstruct, felt252>>" + ], + [155, "struct_construct>"], + [156, "enum_init, 0>"], + [157, "store_temp>"], + [158, "enum_init, 1>"], + [ + 159, + "dup>" + ], + [ + 160, + "struct_snapshot_deconstruct" + ], + [161, "struct_construct, Array, Unit>>"], + [ + 162, + "enum_init, core::array::Array::, ())>, 0>" + ], + [ + 163, + "store_temp, core::array::Array::, ())>>" + ], + [ + 164, + "enum_init, core::array::Array::, ())>, 1>" + ], + [165, "dup"], + [166, "u32_overflowing_sub"], + [167, "struct_construct, u32, Unit>>"], + [ + 168, + "enum_init, core::integer::u32, ())>, 0>" + ], + [ + 169, + "store_temp, core::integer::u32, ())>>" + ], + [170, "dup>"], + [171, "array_get"], + [172, "store_temp>"], + [173, "const_as_immediate>"], + [174, "u32_overflowing_add"], + [ + 175, + "const_as_immediate>" + ], + [ + 176, + "enum_init, core::integer::u32, ())>, 1>" + ], + [ + 177, + "const_as_immediate>" + ], + [178, "struct_deconstruct>"], + [179, "felt252_add"], + [180, "hades_permutation"], + [181, "dup"], + [182, "drop"], + [ + 183, + "enum_init, core::felt252)>, 1>" + ], + [ + 184, + "store_temp, core::felt252)>>" + ], + [185, "const_as_immediate>"], + [ + 186, + "struct_construct, felt252>>" + ], + [ + 187, + "enum_init, core::felt252)>, 0>" + ], + [188, "drop>"] + ], + "user_func_names": [ + [ + 0, + "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__get_message_data" + ], + [ + 1, + "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__fire_event" + ], + [ + 2, + "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__l1_to_l2_message_cancellations" + ], + [ + 3, + "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__set_is_canceled" + ], + [ + 4, + "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__get_l1_to_l2_msg_hash" + ], + [5, "temp_cairo::messaging::MessageDataSerde::serialize"], + [ + 6, + "temp_cairo::messaging::MessagingContract::MessagingContract::fire_event" + ], + [ + 7, + "temp_cairo::messaging::MessagingContract::MessagingContract::get_l1_to_l2_msg_hash" + ], + [ + 8, + "core::array::serialize_array_helper::" + ], + [ + 9, + "temp_cairo::messaging::MessagingContract::MessageSentIsEvent::append_keys_and_data" + ], + [ + 10, + "temp_cairo::messaging::MessagingContract::MessagingContract::get_l1_to_l2_msg_hash[expr55]" + ], + [11, "core::poseidon::_poseidon_hash_span_inner"] + ] + }, + "contract_class_version": "0.1.0", + "entry_points_by_type": { + "EXTERNAL": [ + { + "selector": "0x5de93e1525070ad9e62807a8b7eebf3c7fd7c60dd0a0ec728f9aa3b7c4146b", + "function_idx": 4 + }, + { + "selector": "0x148fcde222e93109b646c02f8ed9babeb4fc5dd31b9de5026add8c3601acf9a", + "function_idx": 1 + }, + { + "selector": "0x15811ea1dff18014ea6dad7ab86b6ae25e45829c0f8c717c9748a3208e4770e", + "function_idx": 2 + }, + { + "selector": "0x21d33b226af0ea4fb717e4f9bff77bd7becd28c61f5bb8a3e3d6c7db1f0f4d8", + "function_idx": 3 + }, + { + "selector": "0x3f9333bdab22b77e223157f7ef4f4b91598f4fac1ff161d34e59f646a54482c", + "function_idx": 0 + } + ], + "L1_HANDLER": [], + "CONSTRUCTOR": [] + }, + "abi": [ + { + "type": "impl", + "name": "MessagingContract", + "interface_name": "temp_cairo::messaging::IMessagingContract" + }, + { + "type": "struct", + "name": "temp_cairo::messaging::MessageData", + "members": [ + { + "name": "from_address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { "name": "to_address", "type": "core::felt252" }, + { "name": "selector", "type": "core::felt252" }, + { "name": "payload", "type": "core::array::Array::" }, + { "name": "nonce", "type": "core::felt252" } + ] + }, + { + "type": "struct", + "name": "core::integer::u256", + "members": [ + { "name": "low", "type": "core::integer::u128" }, + { "name": "high", "type": "core::integer::u128" } + ] + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { "name": "False", "type": "()" }, + { "name": "True", "type": "()" } + ] + }, + { + "type": "interface", + "name": "temp_cairo::messaging::IMessagingContract", + "items": [ + { + "type": "function", + "name": "get_message_data", + "inputs": [], + "outputs": [{ "type": "temp_cairo::messaging::MessageData" }], + "state_mutability": "view" + }, + { + "type": "function", + "name": "fire_event", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "l1_to_l2_message_cancellations", + "inputs": [{ "name": "msg_hash", "type": "core::felt252" }], + "outputs": [{ "type": "core::integer::u256" }], + "state_mutability": "view" + }, + { + "type": "function", + "name": "set_is_canceled", + "inputs": [{ "name": "value", "type": "core::bool" }], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_l1_to_l2_msg_hash", + "inputs": [], + "outputs": [{ "type": "core::felt252" }], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "temp_cairo::messaging::MessagingContract::MessageSent", + "kind": "struct", + "members": [ + { "name": "message_hash", "type": "core::felt252", "kind": "data" }, + { + "name": "from_address", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { "name": "to_address", "type": "core::felt252", "kind": "data" }, + { "name": "selector", "type": "core::felt252", "kind": "data" }, + { "name": "nonce", "type": "core::felt252", "kind": "data" }, + { + "name": "payload", + "type": "core::array::Array::", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "temp_cairo::messaging::MessagingContract::Event", + "kind": "enum", + "variants": [ + { + "name": "MessageSent", + "type": "temp_cairo::messaging::MessagingContract::MessageSent", + "kind": "nested" + } + ] + } + ] +} diff --git a/crates/client/settlement_client/src/starknet/utils.rs b/crates/client/settlement_client/src/starknet/utils.rs index 3c2c90a03..c293c4f1a 100644 --- a/crates/client/settlement_client/src/starknet/utils.rs +++ b/crates/client/settlement_client/src/starknet/utils.rs @@ -26,9 +26,12 @@ pub const MADARA_PORT: &str = "19944"; pub const MADARA_BINARY_PATH: &str = "../../../test-artifacts/madara"; pub const MADARA_CONFIG_PATH: &str = "../../../test-artifacts/devnet.yaml"; pub const APPCHAIN_CONTRACT_SIERRA_PATH: &str = "src/starknet/test_contracts/appchain_test.sierra.json"; +pub const MESSAGING_CONTRACT_SIERRA_PATH: &str = "src/starknet/test_contracts/messaging_test.sierra.json"; // starkli class-hash crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json pub const APPCHAIN_CONTRACT_CASM_HASH: &str = "0x07f36e830605ddeb7c4c094639b628de297cbf61f45385b1fc3231029922b30b"; +// starkli class-hash crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json +pub const MESSAGING_CONTRACT_CASM_HASH: &str = "0x0267b5e87ff42dacc469c25ec0c2e3f8eb798a7d6723ad0aa1c68cbd3f9d8586"; pub type StarknetAccount = SingleOwnerAccount, LocalWallet>; pub type TransactionReceiptResult = Result; @@ -82,7 +85,16 @@ impl Drop for MadaraProcess { pub async fn prepare_starknet_client_test() -> anyhow::Result<(StarknetAccount, Felt, MadaraProcess)> { let madara = MadaraProcess::new(PathBuf::from(MADARA_BINARY_PATH))?; let account = starknet_account()?; - let deployed_appchain_contract_address = deploy_contract(&account).await?; + let deployed_appchain_contract_address = + deploy_contract(&account, APPCHAIN_CONTRACT_SIERRA_PATH, APPCHAIN_CONTRACT_CASM_HASH).await?; + Ok((account, deployed_appchain_contract_address, madara)) +} + +pub async fn prepare_starknet_client_messaging_test() -> anyhow::Result<(StarknetAccount, Felt, MadaraProcess)> { + let madara = MadaraProcess::new(PathBuf::from(MADARA_BINARY_PATH))?; + let account = starknet_account()?; + let deployed_appchain_contract_address = + deploy_contract(&account, MESSAGING_CONTRACT_SIERRA_PATH, MESSAGING_CONTRACT_CASM_HASH).await?; Ok((account, deployed_appchain_contract_address, madara)) } @@ -109,6 +121,44 @@ pub async fn send_state_update( } } +pub async fn fire_messaging_event(account: &StarknetAccount, appchain_contract_address: Felt) -> anyhow::Result { + let call = account + .execute_v1(vec![Call { + to: appchain_contract_address, + selector: get_selector_from_name("fire_event")?, + calldata: vec![], + }]) + .send() + .await?; + let receipt = get_transaction_receipt(account.provider(), call.transaction_hash).await?; + + let latest_block_number_recorded = account.provider().block_number().await?; + + match receipt.block.block_number() { + Some(block_number) => Ok(block_number), + None => Ok(latest_block_number_recorded + 1), + } +} + +pub async fn cancel_messaging_event(account: &StarknetAccount, appchain_contract_address: Felt) -> anyhow::Result { + let call = account + .execute_v1(vec![Call { + to: appchain_contract_address, + selector: get_selector_from_name("set_is_canceled")?, + calldata: vec![Felt::ONE], + }]) + .send() + .await?; + let receipt = get_transaction_receipt(account.provider(), call.transaction_hash).await?; + + let latest_block_number_recorded = account.provider().block_number().await?; + + match receipt.block.block_number() { + Some(block_number) => Ok(block_number), + None => Ok(latest_block_number_recorded + 1), + } +} + pub fn starknet_account() -> anyhow::Result { let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?)); @@ -125,11 +175,10 @@ pub fn starknet_account() -> anyhow::Result { Ok(account) } -pub async fn deploy_contract(account: &StarknetAccount) -> anyhow::Result { - let contract_artifact: SierraClass = serde_json::from_reader(std::fs::File::open(APPCHAIN_CONTRACT_SIERRA_PATH)?)?; +pub async fn deploy_contract(account: &StarknetAccount, sierra_path: &str, casm_hash: &str) -> anyhow::Result { + let contract_artifact: SierraClass = serde_json::from_reader(std::fs::File::open(sierra_path)?)?; let flattened_class = contract_artifact.flatten()?; - let result = - account.declare_v2(Arc::new(flattened_class), Felt::from_str(APPCHAIN_CONTRACT_CASM_HASH)?).send().await?; + let result = account.declare_v2(Arc::new(flattened_class), Felt::from_str(casm_hash)?).send().await?; tokio::time::sleep(Duration::from_secs(5)).await; let deployment = account .execute_v3(vec![Call { @@ -164,7 +213,7 @@ pub async fn get_transaction_receipt( transaction_hash: Felt, ) -> TransactionReceiptResult { // there is a delay between the transaction being available at the client - // and the sealing of the block, hence sleeping for 500ms + // and the pending tick of the block, hence sleeping for 500ms assert_poll(|| async { rpc.get_transaction_receipt(transaction_hash).await.is_ok() }, 500, 20).await; rpc.get_transaction_receipt(transaction_hash).await } diff --git a/crates/client/settlement_client/src/state_update.rs b/crates/client/settlement_client/src/state_update.rs index 8ce7c034d..e45e9eb8f 100644 --- a/crates/client/settlement_client/src/state_update.rs +++ b/crates/client/settlement_client/src/state_update.rs @@ -36,9 +36,9 @@ pub fn update_l1( Ok(()) } -pub async fn state_update_worker( +pub async fn state_update_worker( backend: Arc, - settlement_client: Arc>>, + settlement_client: Arc>>, ctx: ServiceContext, ) -> anyhow::Result<()> { // Clear L1 confirmed block at startup @@ -62,9 +62,8 @@ mod eth_client_event_subscription_test { use super::*; use std::{sync::Arc, time::Duration}; + use crate::eth::StarknetCoreContract::LogMessageToL2; use crate::eth::{EthereumClient, EthereumClientConfig, StarknetCoreContract}; - use alloy::providers::RootProvider; - use alloy::transports::http::{Client, Http}; use alloy::{node_bindings::Anvil, providers::ProviderBuilder, sol}; use mc_db::DatabaseService; use mp_chain_config::ChainConfig; @@ -143,7 +142,7 @@ mod eth_client_event_subscription_test { let listen_handle = { let db = Arc::clone(&db); tokio::spawn(async move { - state_update_worker::>>( + state_update_worker::( Arc::clone(db.backend()), Arc::new(Box::new(eth_client)), ServiceContext::new_for_testing(), @@ -172,6 +171,7 @@ mod eth_client_event_subscription_test { mod starknet_client_event_subscription_test { use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; + use crate::messaging::MessageSent; use crate::starknet::utils::{prepare_starknet_client_test, send_state_update, MADARA_PORT}; use crate::starknet::{StarknetClient, StarknetClientConfig}; use crate::state_update::{state_update_worker, StateUpdate}; @@ -179,8 +179,6 @@ mod starknet_client_event_subscription_test { use mp_chain_config::ChainConfig; use mp_utils::service::ServiceContext; use rstest::rstest; - use starknet_providers::jsonrpc::HttpTransport; - use starknet_providers::JsonRpcClient; use starknet_types_core::felt::Felt; use std::str::FromStr; use std::sync::Arc; @@ -213,10 +211,7 @@ mod starknet_client_event_subscription_test { // Making Starknet client and start worker // ================================================ - // Here we need to have madara variable otherwise it will - // get dropped and will kill the madara. - #[allow(unused_variables)] - let (account, deployed_address, madara) = prepare_starknet_client_test().await?; + let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, @@ -228,7 +223,7 @@ mod starknet_client_event_subscription_test { let listen_handle = { let db = Arc::clone(&db); tokio::spawn(async move { - state_update_worker::>>( + state_update_worker::( Arc::clone(db.backend()), Arc::new(Box::new(starknet_client)), ServiceContext::new_for_testing(), diff --git a/crates/client/settlement_client/src/sync.rs b/crates/client/settlement_client/src/sync.rs index 961141f7d..36710a05f 100644 --- a/crates/client/settlement_client/src/sync.rs +++ b/crates/client/settlement_client/src/sync.rs @@ -1,6 +1,6 @@ -use crate::client::{ClientTrait, ClientType}; +use crate::client::ClientTrait; use crate::gas_price::gas_price_worker; -use crate::l1_messaging::sync; +use crate::messaging::sync; use crate::state_update::state_update_worker; use mc_db::MadaraBackend; use mc_mempool::{GasPriceProvider, Mempool}; @@ -8,12 +8,11 @@ use mp_utils::service::ServiceContext; use starknet_api::core::ChainId; use std::sync::Arc; use std::time::Duration; -use tracing::warn; #[allow(clippy::too_many_arguments)] -pub async fn sync_worker( +pub async fn sync_worker( backend: Arc, - settlement_client: Arc>>, + settlement_client: Arc>>, chain_id: ChainId, l1_gas_provider: GasPriceProvider, gas_price_sync_disabled: bool, @@ -25,14 +24,7 @@ pub async fn sync_worker( join_set.spawn(state_update_worker(Arc::clone(&backend), settlement_client.clone(), ctx.clone())); - match settlement_client.get_client_type() { - ClientType::ETH => { - join_set.spawn(sync(Arc::clone(&backend), settlement_client.clone(), chain_id, mempool, ctx.clone())); - } - _ => { - warn!("⚠️ Provided client type does not implement the messaging sync function. Continuing....") - } - } + join_set.spawn(sync(settlement_client.clone(), Arc::clone(&backend), chain_id, mempool, ctx.clone())); if !gas_price_sync_disabled { join_set.spawn(gas_price_worker(settlement_client.clone(), l1_gas_provider, gas_price_poll_ms, ctx.clone())); diff --git a/crates/node/src/main.rs b/crates/node/src/main.rs index a67f2d5da..e523e04fb 100644 --- a/crates/node/src/main.rs +++ b/crates/node/src/main.rs @@ -6,8 +6,6 @@ mod service; mod util; use crate::cli::l1::MadaraSettlementLayer; -use alloy::providers::RootProvider; -use alloy::transports::http::Http; use anyhow::{bail, Context}; use clap::Parser; use cli::{NetworkType, RunCmd}; @@ -19,15 +17,14 @@ use mc_gateway_client::GatewayProvider; use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; use mc_rpc::providers::{AddTransactionProvider, ForwardToProvider, MempoolAddTxProvider}; use mc_settlement_client::eth::EthereumClientConfig; +use mc_settlement_client::eth::StarknetCoreContract::LogMessageToL2; +use mc_settlement_client::messaging::MessageSent; use mc_settlement_client::starknet::StarknetClientConfig; use mc_sync::fetch::fetchers::WarpUpdateConfig; use mc_telemetry::{SysInfo, TelemetryService}; use mp_oracle::pragma::PragmaOracleBuilder; use mp_utils::service::{MadaraServiceId, ServiceMonitor}; -use reqwest::Client; use service::{BlockProductionService, GatewayService, L1SyncService, L2SyncService, RpcService}; -use starknet_providers::jsonrpc::HttpTransport; -use starknet_providers::JsonRpcClient; use std::sync::Arc; const GREET_IMPL_NAME: &str = "Madara"; @@ -162,7 +159,7 @@ async fn main() -> anyhow::Result<()> { let mempool = Arc::new(mempool); let service_l1_sync = match &run_cmd.l1_sync_params.settlement_layer { - MadaraSettlementLayer::Eth => L1SyncService::>>::create( + MadaraSettlementLayer::Eth => L1SyncService::::create( &run_cmd.l1_sync_params, &service_db, l1_gas_setter, @@ -175,7 +172,7 @@ async fn main() -> anyhow::Result<()> { .await .context("Initializing the l1 sync service")?, MadaraSettlementLayer::Starknet => { - L1SyncService::>>::create( + L1SyncService::::create( &run_cmd.l1_sync_params, &service_db, l1_gas_setter, diff --git a/crates/node/src/service/l1.rs b/crates/node/src/service/l1.rs index a885c3bfa..6f4949a0e 100644 --- a/crates/node/src/service/l1.rs +++ b/crates/node/src/service/l1.rs @@ -1,32 +1,29 @@ use crate::cli::l1::{L1SyncParams, MadaraSettlementLayer}; use alloy::primitives::Address; -use alloy::providers::RootProvider; -use alloy::transports::http::Http; use anyhow::Context; use mc_db::{DatabaseService, MadaraBackend}; use mc_mempool::{GasPriceProvider, Mempool}; use mc_settlement_client::client::ClientTrait; +use mc_settlement_client::eth::StarknetCoreContract::LogMessageToL2; use mc_settlement_client::eth::{EthereumClient, EthereumClientConfig}; use mc_settlement_client::gas_price::L1BlockMetrics; +use mc_settlement_client::messaging::MessageSent; use mc_settlement_client::starknet::{StarknetClient, StarknetClientConfig}; use mp_utils::service::{MadaraServiceId, PowerOfTwo, Service, ServiceId, ServiceRunner}; -use reqwest::Client; use starknet_api::core::ChainId; use starknet_core::types::Felt; -use starknet_providers::jsonrpc::HttpTransport; -use starknet_providers::JsonRpcClient; use std::str::FromStr; use std::sync::Arc; use std::time::Duration; #[derive(Clone)] -pub struct L1SyncService +pub struct L1SyncService where C: Clone, - P: Clone, + E: Clone, { db_backend: Arc, - settlement_client: Option>>>, + settlement_client: Option>>>, l1_gas_provider: GasPriceProvider, chain_id: ChainId, gas_price_sync_disabled: bool, @@ -34,9 +31,9 @@ where mempool: Arc, } -pub type EthereumSyncService = L1SyncService>>; +pub type EthereumSyncService = L1SyncService; -pub type StarknetSyncService = L1SyncService>>; +pub type StarknetSyncService = L1SyncService; // Implementation for Ethereum impl EthereumSyncService { @@ -64,7 +61,7 @@ impl EthereumSyncService { .context("Creating ethereum client")?; let client_converted: Box< - dyn ClientTrait>>, + dyn ClientTrait, > = Box::new(client); Some(Arc::new(client_converted)) } else { @@ -107,7 +104,7 @@ impl StarknetSyncService { // StarknetClientConfig, Arc>, Felt let client_converted: Box< - dyn ClientTrait>>, + dyn ClientTrait, > = Box::new(client); Some(Arc::new(client_converted)) } else { @@ -124,12 +121,12 @@ impl StarknetSyncService { } // Shared implementation for both services -impl L1SyncService { +impl L1SyncService { #[allow(clippy::too_many_arguments)] async fn create_service( config: &L1SyncParams, db: &DatabaseService, - settlement_client: Option>>>, + settlement_client: Option>>>, l1_gas_provider: GasPriceProvider, chain_id: ChainId, authority: bool, @@ -204,10 +201,10 @@ impl L1SyncService { } #[async_trait::async_trait] -impl Service for L1SyncService +impl Service for L1SyncService where C: Clone, - P: Clone, + E: Clone, { async fn start<'a>(&mut self, runner: ServiceRunner<'a>) -> anyhow::Result<()> { let L1SyncService { @@ -244,10 +241,10 @@ where } } -impl ServiceId for L1SyncService +impl ServiceId for L1SyncService where C: Clone, - P: Clone, + E: Clone, { #[inline(always)] fn svc_id(&self) -> PowerOfTwo { From d4aa9881cbae93b6e1ab08da6cde73b94dd384d5 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Fri, 27 Dec 2024 13:52:34 +0530 Subject: [PATCH 08/23] feat : updated l2 messaging implementation --- crates/client/settlement_client/src/client.rs | 21 ----- .../client/settlement_client/src/eth/mod.rs | 16 ++-- .../settlement_client/src/starknet/mod.rs | 76 ++++++++++++++----- crates/node/src/main.rs | 26 +++---- crates/node/src/service/l1.rs | 5 +- 5 files changed, 76 insertions(+), 68 deletions(-) diff --git a/crates/client/settlement_client/src/client.rs b/crates/client/settlement_client/src/client.rs index 9ba759907..bedfa8e3e 100644 --- a/crates/client/settlement_client/src/client.rs +++ b/crates/client/settlement_client/src/client.rs @@ -1,10 +1,5 @@ -use crate::eth::StarknetCoreContract::StarknetCoreContractInstance; use crate::gas_price::L1BlockMetrics; use crate::state_update::StateUpdate; -use alloy::contract::Event; -use alloy::providers::RootProvider; -use alloy::sol_types::SolEvent; -use alloy::transports::http::{Client, Http}; use async_trait::async_trait; use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; @@ -15,21 +10,6 @@ use starknet_api::transaction::L1HandlerTransaction; use starknet_types_core::felt::Felt; use std::sync::Arc; -pub enum CoreContractInstance { - Ethereum(StarknetCoreContractInstance, RootProvider>>), - Starknet(Felt), -} - -impl CoreContractInstance { - #[allow(clippy::type_complexity)] - pub fn event_filter(&self) -> anyhow::Result, &RootProvider>, T>> { - match self { - CoreContractInstance::Ethereum(contract) => Ok(contract.event_filter()), - CoreContractInstance::Starknet(_) => Err(anyhow::anyhow!("Starknet doesn't support event filters")), - } - } -} - #[async_trait] pub trait ClientTrait: Send + Sync { // Configuration type used for initialization @@ -39,7 +19,6 @@ pub trait ClientTrait: Send + Sync { // Basic getter functions fn get_l1_block_metrics(&self) -> &L1BlockMetrics; - fn get_core_contract_instance(&self) -> CoreContractInstance; // Create a new instance of the client async fn new(config: Self::Config) -> anyhow::Result diff --git a/crates/client/settlement_client/src/eth/mod.rs b/crates/client/settlement_client/src/eth/mod.rs index c8d021075..565e87207 100644 --- a/crates/client/settlement_client/src/eth/mod.rs +++ b/crates/client/settlement_client/src/eth/mod.rs @@ -1,4 +1,4 @@ -use crate::client::{ClientTrait, CoreContractInstance}; +use crate::client::ClientTrait; use crate::eth::StarknetCoreContract::{LogMessageToL2, StarknetCoreContractInstance}; use crate::gas_price::L1BlockMetrics; use crate::state_update::{update_l1, StateUpdate}; @@ -68,10 +68,6 @@ impl ClientTrait for EthereumClient { &self.l1_block_metrics } - fn get_core_contract_instance(&self) -> CoreContractInstance { - CoreContractInstance::Ethereum(self.l1_core_contract.clone()) - } - /// Create a new EthereumClient instance with the given RPC URL async fn new(config: EthereumClientConfig) -> anyhow::Result { let provider = ProviderBuilder::new().on_http(config.url); @@ -152,10 +148,9 @@ impl ClientTrait for EthereumClient { mut ctx: ServiceContext, ) -> anyhow::Result<()> { // Listen to LogStateUpdate (0x77552641) update and send changes continuously - let contract_instance = self.get_core_contract_instance(); - let event_filter = contract_instance.event_filter::(); + let event_filter = self.l1_core_contract.event_filter::(); - let mut event_stream = match ctx.run_until_cancelled(event_filter?.watch()).await { + let mut event_stream = match ctx.run_until_cancelled(event_filter.watch()).await { Some(res) => res.context(ERR_ARCHIVE)?.into_stream(), None => return anyhow::Ok(()), }; @@ -178,10 +173,9 @@ impl ClientTrait for EthereumClient { chain_id: ChainId, mempool: Arc, ) -> anyhow::Result<()> { - let contract_instance = self.get_core_contract_instance(); - let event_filter = contract_instance.event_filter::(); + let event_filter = self.l1_core_contract.event_filter::(); - let mut event_stream = event_filter? + let mut event_stream = event_filter .from_block(last_synced_event_block.block_number) .to_block(BlockNumberOrTag::Finalized) .watch() diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index b558053fe..013aa46c8 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -1,4 +1,4 @@ -use crate::client::{ClientTrait, CoreContractInstance}; +use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; use crate::messaging::MessageSent; use crate::state_update::{update_l1, StateUpdate}; @@ -62,10 +62,6 @@ impl ClientTrait for StarknetClient { &self.l1_block_metrics } - fn get_core_contract_instance(&self) -> CoreContractInstance { - CoreContractInstance::Starknet(self.l2_core_contract) - } - async fn new(config: Self::Config) -> anyhow::Result where Self: Sized, @@ -201,13 +197,17 @@ impl ClientTrait for StarknetClient { let mut sync_flag = false; loop { + let latest_block_number = self.get_latest_block_number().await?; + let starting_block = if !sync_flag { + last_synced_event_block.block_number + } else if latest_block_number < 100 { + 0 + } else { + latest_block_number - 100 + }; let events_response = ctx.run_until_cancelled(self.get_events( - BlockId::Number(if !sync_flag { - last_synced_event_block.block_number - } else { - self.get_latest_block_number().await? - }), - BlockId::Number(self.get_latest_block_number().await?), + BlockId::Number(starting_block), + BlockId::Number(latest_block_number), self.l2_core_contract, vec![get_selector_from_name("MessageSent")?], )); @@ -218,6 +218,11 @@ impl ClientTrait for StarknetClient { match events_response.await { Some(Ok(emitted_events)) => { for event in emitted_events { + // Check if the message is already processed, if yes then skip that message + if backend.has_l1_messaging_nonce(Nonce(event.data[4]))? { + continue; + } + tracing::info!( "🔵 Processing L2 Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", event.block_number, @@ -482,6 +487,12 @@ pub mod starknet_client_tests { use crate::starknet::{StarknetClient, StarknetClientConfig}; use crate::state_update::StateUpdate; use serial_test::serial; + use starknet_accounts::ConnectedAccount; + use starknet_core::types::BlockId; + use starknet_core::types::MaybePendingBlockWithTxHashes::{Block, PendingBlock}; + use starknet_providers::jsonrpc::HttpTransport; + use starknet_providers::ProviderError::StarknetError; + use starknet_providers::{JsonRpcClient, Provider}; use starknet_types_core::felt::Felt; use std::str::FromStr; use std::time::Duration; @@ -552,8 +563,7 @@ pub mod starknet_client_tests { ) .await?; - // It takes time on madara for events to be stored - sleep(Duration::from_secs(10)).await; + poll_on_block_completion(last_event_block_number, account.provider(), 100).await?; let latest_event_block_number = starknet_client.get_last_event_block_number().await?; assert_eq!(latest_event_block_number, last_event_block_number, "Latest event should have block number 100"); @@ -574,13 +584,13 @@ pub mod starknet_client_tests { // sending state updates : let data_felt = Felt::from_hex("0xdeadbeef")?; - send_state_update( + let block_number = send_state_update( &account, deployed_address, StateUpdate { block_number: 100, global_root: data_felt, block_hash: data_felt }, ) .await?; - sleep(Duration::from_secs(5)).await; + poll_on_block_completion(block_number, account.provider(), 100).await?; let last_verified_block_hash = starknet_client.get_last_verified_block_hash().await?; assert_eq!(last_verified_block_hash, data_felt, "Block hash should match"); @@ -602,13 +612,13 @@ pub mod starknet_client_tests { // sending state updates : let data_felt = Felt::from_hex("0xdeadbeef")?; - send_state_update( + let block_number = send_state_update( &account, deployed_address, StateUpdate { block_number: 100, global_root: data_felt, block_hash: data_felt }, ) .await?; - sleep(Duration::from_secs(5)).await; + poll_on_block_completion(block_number, account.provider(), 100).await?; let last_verified_state_root = starknet_client.get_last_state_root().await?; assert_eq!(last_verified_state_root, data_felt, "Last state root should match"); @@ -631,17 +641,45 @@ pub mod starknet_client_tests { // sending state updates : let data_felt = Felt::from_hex("0xdeadbeef")?; let block_number = 100; - send_state_update( + let event_block_number = send_state_update( &account, deployed_address, StateUpdate { block_number, global_root: data_felt, block_hash: data_felt }, ) .await?; - sleep(Duration::from_secs(5)).await; + poll_on_block_completion(event_block_number, account.provider(), 100).await?; let last_verified_block_number = starknet_client.get_last_verified_block_number().await?; assert_eq!(last_verified_block_number, block_number, "Last verified block should match"); Ok(()) } + + const RETRY_DELAY: Duration = Duration::from_millis(100); + + pub async fn poll_on_block_completion( + block_number: u64, + provider: &JsonRpcClient, + max_retries: u64, + ) -> anyhow::Result<()> { + for try_count in 0..=max_retries { + match provider.get_block_with_tx_hashes(BlockId::Number(block_number)).await { + Ok(Block(_)) => { + return Ok(()); + } + Ok(PendingBlock(_)) | Err(StarknetError(starknet_core::types::StarknetError::BlockNotFound)) => { + if try_count == max_retries { + return Err(anyhow::anyhow!("Max retries reached while polling for block {}", block_number)); + } + sleep(RETRY_DELAY).await; + } + Err(e) => { + return Err(anyhow::anyhow!("Provider error while polling block {}: {}", block_number, e)); + } + } + } + + // This line should never be reached due to the return in the loop + Err(anyhow::anyhow!("Max retries reached while polling for block {}", block_number)) + } } diff --git a/crates/node/src/main.rs b/crates/node/src/main.rs index e523e04fb..ae633a9e5 100644 --- a/crates/node/src/main.rs +++ b/crates/node/src/main.rs @@ -171,20 +171,18 @@ async fn main() -> anyhow::Result<()> { ) .await .context("Initializing the l1 sync service")?, - MadaraSettlementLayer::Starknet => { - L1SyncService::::create( - &run_cmd.l1_sync_params, - &service_db, - l1_gas_setter, - chain_config.chain_id.clone(), - chain_config.eth_core_contract_address.clone(), - run_cmd.is_sequencer(), - run_cmd.is_devnet(), - Arc::clone(&mempool), - ) - .await - .context("Initializing the l1 sync service")? - } + MadaraSettlementLayer::Starknet => L1SyncService::::create( + &run_cmd.l1_sync_params, + &service_db, + l1_gas_setter, + chain_config.chain_id.clone(), + chain_config.eth_core_contract_address.clone(), + run_cmd.is_sequencer(), + run_cmd.is_devnet(), + Arc::clone(&mempool), + ) + .await + .context("Initializing the l1 sync service")?, }; // L2 Sync diff --git a/crates/node/src/service/l1.rs b/crates/node/src/service/l1.rs index 6f4949a0e..5cce1150e 100644 --- a/crates/node/src/service/l1.rs +++ b/crates/node/src/service/l1.rs @@ -103,9 +103,8 @@ impl StarknetSyncService { .context("Creating starknet client")?; // StarknetClientConfig, Arc>, Felt - let client_converted: Box< - dyn ClientTrait, - > = Box::new(client); + let client_converted: Box> = + Box::new(client); Some(Arc::new(client_converted)) } else { anyhow::bail!( From a4314be38b3a8bddc9caee7d524695ee7d8697b3 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Fri, 27 Dec 2024 13:54:59 +0530 Subject: [PATCH 09/23] feat : updated l2 messaging implementation --- crates/client/settlement_client/src/starknet/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index 013aa46c8..364c52f6f 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -205,6 +205,7 @@ impl ClientTrait for StarknetClient { } else { latest_block_number - 100 }; + assert!(starting_block <= latest_block_number); // safety check let events_response = ctx.run_until_cancelled(self.get_events( BlockId::Number(starting_block), BlockId::Number(latest_block_number), From 9dea223252498b13890a422cf7d998fa378f66ba Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Fri, 27 Dec 2024 18:34:43 +0530 Subject: [PATCH 10/23] feat : updated messaging logic --- .../client/settlement_client/src/eth/mod.rs | 71 ++-------- .../settlement_client/src/messaging/mod.rs | 122 ++++++++++++++++++ .../settlement_client/src/messaging/sync.rs | 44 +++++++ .../src/{messaging.rs => messaging/tests.rs} | 59 +-------- .../settlement_client/src/starknet/mod.rs | 92 +++---------- .../settlement_client/src/state_update.rs | 2 +- crates/client/settlement_client/src/sync.rs | 2 +- crates/node/src/main.rs | 2 +- crates/node/src/service/l1.rs | 2 +- 9 files changed, 205 insertions(+), 191 deletions(-) create mode 100644 crates/client/settlement_client/src/messaging/mod.rs create mode 100644 crates/client/settlement_client/src/messaging/sync.rs rename crates/client/settlement_client/src/{messaging.rs => messaging/tests.rs} (93%) diff --git a/crates/client/settlement_client/src/eth/mod.rs b/crates/client/settlement_client/src/eth/mod.rs index 565e87207..fef45202f 100644 --- a/crates/client/settlement_client/src/eth/mod.rs +++ b/crates/client/settlement_client/src/eth/mod.rs @@ -1,6 +1,7 @@ use crate::client::ClientTrait; use crate::eth::StarknetCoreContract::{LogMessageToL2, StarknetCoreContractInstance}; use crate::gas_price::L1BlockMetrics; +use crate::messaging::MessageProcessingExt; use crate::state_update::{update_l1, StateUpdate}; use crate::utils::{convert_log_state_update, u256_to_felt}; use alloy::eips::BlockNumberOrTag; @@ -22,6 +23,7 @@ use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; use starknet_types_core::felt::Felt; use std::sync::Arc; +use tracing::error; use url::Url; // abi taken from: https://etherscan.io/address/0x6e0acfdc3cf17a7f99ed34be56c3dfb93f464e24#code @@ -173,6 +175,7 @@ impl ClientTrait for EthereumClient { chain_id: ChainId, mempool: Arc, ) -> anyhow::Result<()> { + let processor = self.message_processor(backend.clone(), chain_id, mempool.clone()); let event_filter = self.l1_core_contract.event_filter::(); let mut event_stream = event_filter @@ -180,70 +183,22 @@ impl ClientTrait for EthereumClient { .to_block(BlockNumberOrTag::Finalized) .watch() .await - .context( - "Failed to watch event filter - Ensure you are using an L1 RPC endpoint that points to an archive node", - )? + .context(ERR_ARCHIVE)? .into_stream(); while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { if let Ok((event, meta)) = event_result { - tracing::info!( - "⟠ Processing L1 Message from block: {:?}, transaction_hash: {:?}, log_index: {:?}, fromAddress: {:?}", - meta.block_number, - meta.transaction_hash, - meta.log_index, - event.fromAddress - ); - - // Check if cancellation was initiated - let event_hash = self.get_messaging_hash(&event)?; - tracing::info!( - "⟠ Checking for cancelation, event hash : {:?}", - Felt::from_bytes_be_slice(event_hash.as_slice()) - ); - let cancellation_timestamp = self.get_l1_to_l2_message_cancellations(event_hash.to_vec()).await?; - if cancellation_timestamp != Felt::ZERO { - tracing::info!("⟠ L1 Message was cancelled in block at timestamp : {:?}", cancellation_timestamp); - let tx_nonce = Nonce(u256_to_felt(event.nonce)?); - // cancelled message nonce should be inserted to avoid reprocessing - match backend.has_l1_messaging_nonce(tx_nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(tx_nonce)?; - } - Ok(true) => {} - Err(e) => { - tracing::error!("⟠ Unexpected DB error: {:?}", e); - return Err(e.into()); - } - }; - continue; - } - - match self - .process_message(&backend, &event, &meta.block_number, &meta.log_index, &chain_id, mempool.clone()) + if let Err(e) = processor + .process_event( + &event, + meta.block_number, + meta.log_index, + Some(meta.transaction_hash.unwrap().to_string()), + Some(event.fromAddress.to_string()), + ) .await { - Ok(Some(tx_hash)) => { - tracing::info!( - "⟠ L1 Message from block: {:?}, transaction_hash: {:?}, log_index: {:?} submitted, \ - transaction hash on L2: {:?}", - meta.block_number, - meta.transaction_hash, - meta.log_index, - tx_hash - ); - } - Ok(None) => {} - Err(e) => { - tracing::error!( - "⟠ Unexpected error while processing L1 Message from block: {:?}, transaction_hash: {:?}, \ - log_index: {:?}, error: {:?}", - meta.block_number, - meta.transaction_hash, - meta.log_index, - e - ) - } + error!("Error processing event: {:?}", e); } } } diff --git a/crates/client/settlement_client/src/messaging/mod.rs b/crates/client/settlement_client/src/messaging/mod.rs new file mode 100644 index 000000000..46c24fea0 --- /dev/null +++ b/crates/client/settlement_client/src/messaging/mod.rs @@ -0,0 +1,122 @@ +use crate::client::ClientTrait; +use anyhow::Result; +use mc_db::l1_db::LastSyncedEventBlock; +use mc_db::MadaraBackend; +use mc_mempool::Mempool; +use starknet_api::core::{ChainId, Nonce}; +use starknet_types_core::felt::Felt; +use std::sync::Arc; +use tracing::{error, info}; + +pub mod sync; + +#[cfg(test)] +mod tests; + +// Defining a common message processor struct with +// processing methods. +// This is to keep the common code out of the trait implementations. +pub struct MessageProcessor<'a, T: ?Sized> { + client: &'a T, + backend: Arc, + chain_id: ChainId, + mempool: Arc, +} + +impl<'a, T: ClientTrait> MessageProcessor<'a, T> { + pub fn new(client: &'a T, backend: Arc, chain_id: ChainId, mempool: Arc) -> Self { + Self { client, backend, chain_id, mempool } + } + + pub async fn process_event( + &self, + event: &T::EventStruct, + block_number: Option, + event_index: Option, + transaction_hash: Option, + from_address: Option, + ) -> Result<()> { + let tx = self.client.parse_handle_message_transaction(event)?; + let tx_nonce = tx.nonce; + + // Skip if already processed + if self.backend.has_l1_messaging_nonce(tx_nonce)? { + info!("Event already processed"); + return Ok(()); + } + + info!( + "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", + block_number, + transaction_hash.unwrap(), + from_address.unwrap(), + ); + + // Check message hash and cancellation + let event_hash = self.client.get_messaging_hash(event)?; + info!("Checking for cancellation, event hash: {:?}", Felt::from_bytes_be_slice(event_hash.as_slice())); + + let cancellation_timestamp = self.client.get_l1_to_l2_message_cancellations(event_hash).await?; + if cancellation_timestamp != Felt::ZERO { + info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); + self.handle_cancelled_message(tx_nonce)?; + return Ok(()); + } + + // Process message + match self + .client + .process_message(&self.backend, event, &block_number, &event_index, &self.chain_id, self.mempool.clone()) + .await + { + Ok(Some(tx_hash)) => { + info!("Message from block: {:?} submitted, transaction hash: {:?}", block_number, tx_hash); + + // Update last synced block if available + if let (Some(block_num), Some(evt_idx)) = (block_number, event_index) { + let block_sent = LastSyncedEventBlock::new(block_num, evt_idx); + self.backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; + } + } + Ok(None) => {} + Err(e) => { + error!("Unexpected error while processing Message from block: {:?}, error: {:?}", block_number, e); + return Err(e); + } + } + + Ok(()) + } + + fn handle_cancelled_message(&self, nonce: Nonce) -> Result<()> { + match self.backend.has_l1_messaging_nonce(nonce) { + Ok(false) => { + self.backend.set_l1_messaging_nonce(nonce)?; + } + Ok(true) => {} + Err(e) => { + error!("Unexpected DB error: {:?}", e); + return Err(e.into()); + } + } + Ok(()) + } +} + +// Extension trait for easy processor creation +pub trait MessageProcessingExt: ClientTrait { + fn message_processor( + &self, + backend: Arc, + chain_id: ChainId, + mempool: Arc, + ) -> MessageProcessor + where + Self: Sized, + { + MessageProcessor::new(self, backend, chain_id, mempool) + } +} + +// Blanket implementation for all ClientTrait implementors +impl MessageProcessingExt for T {} diff --git a/crates/client/settlement_client/src/messaging/sync.rs b/crates/client/settlement_client/src/messaging/sync.rs new file mode 100644 index 000000000..44265eaf9 --- /dev/null +++ b/crates/client/settlement_client/src/messaging/sync.rs @@ -0,0 +1,44 @@ +use crate::client::ClientTrait; +use mc_db::MadaraBackend; +use mc_mempool::Mempool; +use mp_utils::service::ServiceContext; +use starknet_api::core::ChainId; +use starknet_types_core::felt::Felt; +use std::sync::Arc; + +// L2 (Starknet) <-> L3 messaging format +// GitHub Ref : https://github.com/cartridge-gg/piltover/blob/saya/src/messaging/component.cairo#L85 +#[derive(Clone)] +pub struct MessageSent { + pub message_hash: Felt, + pub from: Felt, + pub to: Felt, + pub selector: Felt, + pub nonce: Felt, + pub payload: Vec, +} + +pub async fn sync( + settlement_client: Arc>>, + backend: Arc, + chain_id: ChainId, + mempool: Arc, + ctx: ServiceContext, +) -> anyhow::Result<()> { + tracing::info!("⟠ Starting L1 Messages Syncing..."); + + let last_synced_event_block = match backend.messaging_last_synced_l1_block_with_event() { + Ok(Some(blk)) => blk, + Ok(None) => { + unreachable!("Should never be None") + } + Err(e) => { + tracing::error!("⟠ Madara Messaging DB unavailable: {:?}", e); + return Err(e.into()); + } + }; + + settlement_client.listen_for_messaging_events(backend, ctx, last_synced_event_block, chain_id, mempool).await?; + + Ok(()) +} diff --git a/crates/client/settlement_client/src/messaging.rs b/crates/client/settlement_client/src/messaging/tests.rs similarity index 93% rename from crates/client/settlement_client/src/messaging.rs rename to crates/client/settlement_client/src/messaging/tests.rs index e98224ca5..e7857187d 100644 --- a/crates/client/settlement_client/src/messaging.rs +++ b/crates/client/settlement_client/src/messaging/tests.rs @@ -1,53 +1,8 @@ -use crate::client::ClientTrait; -use mc_db::MadaraBackend; -use mc_mempool::Mempool; -use mp_utils::service::ServiceContext; -use starknet_api::core::ChainId; -use starknet_types_core::felt::Felt; -use std::sync::Arc; - -// L2 (Starknet) <-> L3 messaging format -// GitHub Ref : https://github.com/cartridge-gg/piltover/blob/saya/src/messaging/component.cairo#L85 -#[derive(Clone)] -pub struct MessageSent { - pub message_hash: Felt, - pub from: Felt, - pub to: Felt, - pub selector: Felt, - pub nonce: Felt, - pub payload: Vec, -} - -pub async fn sync( - settlement_client: Arc>>, - backend: Arc, - chain_id: ChainId, - mempool: Arc, - ctx: ServiceContext, -) -> anyhow::Result<()> { - tracing::info!("⟠ Starting L1 Messages Syncing..."); - - let last_synced_event_block = match backend.messaging_last_synced_l1_block_with_event() { - Ok(Some(blk)) => blk, - Ok(None) => { - unreachable!("Should never be None") - } - Err(e) => { - tracing::error!("⟠ Madara Messaging DB unavailable: {:?}", e); - return Err(e.into()); - } - }; - - settlement_client.listen_for_messaging_events(backend, ctx, last_synced_event_block, chain_id, mempool).await?; - - Ok(()) -} - #[cfg(test)] mod l2_messaging_test { use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; - use crate::messaging::sync; + use crate::messaging::sync::sync; use crate::starknet::utils::{ cancel_messaging_event, fire_messaging_event, prepare_starknet_client_messaging_test, MadaraProcess, StarknetAccount, MADARA_PORT, @@ -165,10 +120,10 @@ mod l2_messaging_test { // Log asserts // =========== - assert!(logs_contain("fromAddress: 0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493")); + assert!(logs_contain("fromAddress: \"0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 // expecting the same in logs - assert!(logs_contain("event hash : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0")); + assert!(logs_contain("event hash: 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0")); // Assert that the event is well stored in db let last_block = @@ -222,10 +177,10 @@ mod l2_messaging_test { // Log asserts // =========== - assert!(logs_contain("fromAddress: 0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493")); + assert!(logs_contain("fromAddress: \"0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 // expecting the same in logs - assert!(logs_contain("event hash : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0")); + assert!(logs_contain("event hash: 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0")); // Assert that the event is well stored in db let last_block = @@ -298,7 +253,7 @@ mod l2_messaging_test { let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); // cancelled message nonce should be inserted to avoid reprocessing assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); - assert!(logs_contain("L2 Message was cancelled in block at timestamp : 0x66b4f105")); + assert!(logs_contain("Message was cancelled in block at timestamp: 0x66b4f105")); // Cancelling worker worker_handle.abort(); @@ -316,7 +271,7 @@ mod l1_messaging_tests { use crate::eth::StarknetCoreContract::LogMessageToL2; use crate::eth::{EthereumClient, StarknetCoreContract}; use crate::gas_price::L1BlockMetrics; - use crate::messaging::sync; + use crate::messaging::sync::sync; use crate::utils::felt_to_u256; use alloy::{ hex::FromHex, diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index 364c52f6f..b9285a161 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -1,6 +1,7 @@ use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; -use crate::messaging::MessageSent; +use crate::messaging::sync::MessageSent; +use crate::messaging::MessageProcessingExt; use crate::state_update::{update_l1, StateUpdate}; use anyhow::{anyhow, bail}; use async_trait::async_trait; @@ -85,7 +86,7 @@ impl ClientTrait for StarknetClient { async fn get_last_event_block_number(&self) -> anyhow::Result { let latest_block = self.get_latest_block_number().await?; // If block on l2 is not greater than or equal to 6000 we will consider the last block to 0. - let last_block = if latest_block <= 6000 { 0 } else { 6000 }; + let last_block = if latest_block <= 6000 { 0 } else { latest_block - 6000 }; let last_events = self .get_events( BlockId::Number(last_block), @@ -193,7 +194,7 @@ impl ClientTrait for StarknetClient { chain_id: ChainId, mempool: Arc, ) -> anyhow::Result<()> { - // This is for checking if initial events are synced. + let processor = self.message_processor(backend.clone(), chain_id, mempool.clone()); let mut sync_flag = false; loop { @@ -205,7 +206,9 @@ impl ClientTrait for StarknetClient { } else { latest_block_number - 100 }; - assert!(starting_block <= latest_block_number); // safety check + + assert!(starting_block <= latest_block_number); + let events_response = ctx.run_until_cancelled(self.get_events( BlockId::Number(starting_block), BlockId::Number(latest_block_number), @@ -213,26 +216,11 @@ impl ClientTrait for StarknetClient { vec![get_selector_from_name("MessageSent")?], )); - // set synced flag as true. sync_flag = true; match events_response.await { Some(Ok(emitted_events)) => { for event in emitted_events { - // Check if the message is already processed, if yes then skip that message - if backend.has_l1_messaging_nonce(Nonce(event.data[4]))? { - continue; - } - - tracing::info!( - "🔵 Processing L2 Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", - event.block_number, - event.transaction_hash, - event.data[1] - ); - - // For payload in data : - // 6th element is the payload array length. let mut payload_array = vec![]; event.data.iter().skip(6).for_each(|data| { payload_array.push(*data); @@ -247,65 +235,17 @@ impl ClientTrait for StarknetClient { payload: payload_array, }; - let event_hash = self.get_messaging_hash(&formatted_event)?; - tracing::info!( - "🔵 Checking for cancelation, event hash : {:?}", - Felt::from_bytes_be_slice(event_hash.as_slice()) - ); - let cancellation_timestamp = self.get_l1_to_l2_message_cancellations(event_hash).await?; - if cancellation_timestamp != Felt::ZERO { - tracing::info!( - "🔵 L2 Message was cancelled in block at timestamp : {:?}", - cancellation_timestamp - ); - let tx_nonce = Nonce(event.data[4]); - match backend.has_l1_messaging_nonce(tx_nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(tx_nonce)?; - } - Ok(true) => {} - Err(e) => { - tracing::error!("🔵 Unexpected DB error: {:?}", e); - return Err(e.into()); - } - }; - continue; - } - - // TODO : need to figure out what to pass instead of event index. - // In case of eth we are passing that and using that for indexing the events. - // This value is also stored in db in order to track the events. - // This is also crucial in case which node is killed while executing the messages. - match self - .process_message( - &backend, + if let Err(e) = processor + .process_event( &formatted_event, - &event.block_number, - &Some(0), - &chain_id, - mempool.clone(), + event.block_number, + Some(0), + Some(event.transaction_hash.to_hex_string()), + Some(formatted_event.from.to_hex_string()), ) .await { - Ok(Some(tx_hash)) => { - tracing::info!( - "🔵 L2 Message from block: {:?}, transaction_hash: {:?} submitted, \ - transaction hash on L2: {:?}", - event.block_number, - event.transaction_hash, - tx_hash - ); - } - Ok(None) => {} - Err(e) => { - tracing::error!( - "🔵 Unexpected error while processing L2 Message from block: {:?}, transaction_hash: {:?}, \ - error: {:?}", - event.block_number, - event.transaction_hash, - e - ) - } + error!("Error processing event: {:?}", e); } } } @@ -313,15 +253,13 @@ impl ClientTrait for StarknetClient { error!("Error processing event: {:?}", e); } None => { - trace!("Starknet Client : No event found"); + trace!("No events found"); } } - // TODO : take this as a block time of L2 sleep(Duration::from_secs(5)).await; } } - // We are returning here (0,0) because we are assuming that // the L3s will have zero gas prices. for any transaction. // So that's why we will keep the prices as 0 returning from diff --git a/crates/client/settlement_client/src/state_update.rs b/crates/client/settlement_client/src/state_update.rs index e45e9eb8f..6694d1be5 100644 --- a/crates/client/settlement_client/src/state_update.rs +++ b/crates/client/settlement_client/src/state_update.rs @@ -171,7 +171,7 @@ mod eth_client_event_subscription_test { mod starknet_client_event_subscription_test { use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; - use crate::messaging::MessageSent; + use crate::messaging::sync::MessageSent; use crate::starknet::utils::{prepare_starknet_client_test, send_state_update, MADARA_PORT}; use crate::starknet::{StarknetClient, StarknetClientConfig}; use crate::state_update::{state_update_worker, StateUpdate}; diff --git a/crates/client/settlement_client/src/sync.rs b/crates/client/settlement_client/src/sync.rs index 36710a05f..f62db3242 100644 --- a/crates/client/settlement_client/src/sync.rs +++ b/crates/client/settlement_client/src/sync.rs @@ -1,6 +1,6 @@ use crate::client::ClientTrait; use crate::gas_price::gas_price_worker; -use crate::messaging::sync; +use crate::messaging::sync::sync; use crate::state_update::state_update_worker; use mc_db::MadaraBackend; use mc_mempool::{GasPriceProvider, Mempool}; diff --git a/crates/node/src/main.rs b/crates/node/src/main.rs index ae633a9e5..30814d214 100644 --- a/crates/node/src/main.rs +++ b/crates/node/src/main.rs @@ -18,7 +18,7 @@ use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; use mc_rpc::providers::{AddTransactionProvider, ForwardToProvider, MempoolAddTxProvider}; use mc_settlement_client::eth::EthereumClientConfig; use mc_settlement_client::eth::StarknetCoreContract::LogMessageToL2; -use mc_settlement_client::messaging::MessageSent; +use mc_settlement_client::messaging::sync::MessageSent; use mc_settlement_client::starknet::StarknetClientConfig; use mc_sync::fetch::fetchers::WarpUpdateConfig; use mc_telemetry::{SysInfo, TelemetryService}; diff --git a/crates/node/src/service/l1.rs b/crates/node/src/service/l1.rs index 5cce1150e..c011b4604 100644 --- a/crates/node/src/service/l1.rs +++ b/crates/node/src/service/l1.rs @@ -7,7 +7,7 @@ use mc_settlement_client::client::ClientTrait; use mc_settlement_client::eth::StarknetCoreContract::LogMessageToL2; use mc_settlement_client::eth::{EthereumClient, EthereumClientConfig}; use mc_settlement_client::gas_price::L1BlockMetrics; -use mc_settlement_client::messaging::MessageSent; +use mc_settlement_client::messaging::sync::MessageSent; use mc_settlement_client::starknet::{StarknetClient, StarknetClientConfig}; use mp_utils::service::{MadaraServiceId, PowerOfTwo, Service, ServiceId, ServiceRunner}; use starknet_api::core::ChainId; From fafd2c31230c080d2d6407a7839d2e12fcef9790 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Mon, 6 Jan 2025 17:25:34 +0530 Subject: [PATCH 11/23] clients refactoring done --- crates/client/settlement_client/src/client.rs | 40 +--- .../client/settlement_client/src/eth/event.rs | 56 +++++ .../client/settlement_client/src/eth/mod.rs | 146 +++---------- .../client/settlement_client/src/gas_price.rs | 29 ++- .../settlement_client/src/messaging/mod.rs | 118 ----------- .../settlement_client/src/messaging/sync.rs | 198 +++++++++++++++++- .../settlement_client/src/starknet/event.rs | 120 +++++++++++ .../settlement_client/src/starknet/mod.rs | 169 +++------------ .../settlement_client/src/state_update.rs | 11 +- crates/client/settlement_client/src/sync.rs | 12 +- crates/node/src/main.rs | 8 +- crates/node/src/service/l1.rs | 60 +++--- 12 files changed, 500 insertions(+), 467 deletions(-) create mode 100644 crates/client/settlement_client/src/eth/event.rs create mode 100644 crates/client/settlement_client/src/starknet/event.rs diff --git a/crates/client/settlement_client/src/client.rs b/crates/client/settlement_client/src/client.rs index bedfa8e3e..079bb586a 100644 --- a/crates/client/settlement_client/src/client.rs +++ b/crates/client/settlement_client/src/client.rs @@ -1,12 +1,11 @@ use crate::gas_price::L1BlockMetrics; +use crate::messaging::sync::CommonMessagingEventData; use crate::state_update::StateUpdate; use async_trait::async_trait; +use futures::Stream; use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; -use mc_mempool::Mempool; use mp_utils::service::ServiceContext; -use starknet_api::core::ChainId; -use starknet_api::transaction::L1HandlerTransaction; use starknet_types_core::felt::Felt; use std::sync::Arc; @@ -14,8 +13,6 @@ use std::sync::Arc; pub trait ClientTrait: Send + Sync { // Configuration type used for initialization type Config; - // Event struct type - type EventStruct; // Basic getter functions fn get_l1_block_metrics(&self) -> &L1BlockMetrics; @@ -52,35 +49,11 @@ pub trait ClientTrait: Send + Sync { ctx: ServiceContext, ) -> anyhow::Result<()>; - // Listen for messaging events - async fn listen_for_messaging_events( - &self, - backend: Arc, - ctx: ServiceContext, - last_synced_event_block: LastSyncedEventBlock, - chain_id: ChainId, - mempool: Arc, - ) -> anyhow::Result<()>; - // get gas prices async fn get_gas_prices(&self) -> anyhow::Result<(u128, u128)>; // Get message hash from event - fn get_messaging_hash(&self, event: &Self::EventStruct) -> anyhow::Result>; - - // Process message received from event - async fn process_message( - &self, - backend: &MadaraBackend, - event: &Self::EventStruct, - settlement_layer_block_number: &Option, - event_index: &Option, - chain_id: &ChainId, - mempool: Arc, - ) -> anyhow::Result>; - - // Parse the message into madara l1 handler transaction - fn parse_handle_message_transaction(&self, event: &Self::EventStruct) -> anyhow::Result; + fn get_messaging_hash(&self, event: &CommonMessagingEventData) -> anyhow::Result>; /// Get cancellation status of an L1 to L2 message /// @@ -96,4 +69,11 @@ pub trait ClientTrait: Send + Sync { /// - timestamp of the cancellation if it has been cancelled /// - An Error if the call fail async fn get_l1_to_l2_message_cancellations(&self, msg_hash: Vec) -> anyhow::Result; + + // ============================================================ + // Stream Implementations : + // ============================================================ + type StreamType: Stream>>; + async fn get_event_stream(&self, last_synced_event_block: LastSyncedEventBlock) + -> anyhow::Result; } diff --git a/crates/client/settlement_client/src/eth/event.rs b/crates/client/settlement_client/src/eth/event.rs new file mode 100644 index 000000000..0c570646c --- /dev/null +++ b/crates/client/settlement_client/src/eth/event.rs @@ -0,0 +1,56 @@ +use crate::eth::StarknetCoreContract::LogMessageToL2; +use crate::messaging::sync::CommonMessagingEventData; +use alloy::contract::EventPoller; +use alloy::rpc::types::Log; +use alloy::sol_types::SolEvent; +use alloy::transports::http::{Client, Http}; +use anyhow::Error; +use futures::Stream; +use std::pin::Pin; +use std::task::{Context, Poll}; + +pub struct EthereumEventStream { + stream: Pin> + Send + 'static>>, +} + +impl EthereumEventStream { + pub fn new(watcher: EventPoller, LogMessageToL2>) -> Self { + Self { stream: Box::pin(watcher.poller.into_stream()) } + } +} + +impl Stream for EthereumEventStream { + type Item = Option>; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.stream.as_mut().poll_next(cx) { + Poll::Ready(Some(logs)) => { + if let Some(log) = logs.into_iter().next() { + match LogMessageToL2::decode_log(log.as_ref(), false) { + Ok(event) => Poll::Ready(Some(Some(Ok(CommonMessagingEventData { + from: event.data.fromAddress.as_slice().into(), + to: event.data.toAddress.to_be_bytes_vec(), + selector: event.data.selector.to_be_bytes_vec(), + nonce: event.nonce.to_be_bytes_vec(), + payload: { + let mut payload_vec = vec![]; + event.payload.iter().for_each(|ele| payload_vec.push(ele.to_be_bytes_vec())); + payload_vec + }, + fee: Some(event.data.fee.to_be_bytes_vec()), + transaction_hash: None, + message_hash: None, + block_number: None, + event_index: None, + })))), + Err(e) => Poll::Ready(Some(Some(Err(Error::from(e))))), + } + } else { + Poll::Ready(None) + } + } + Poll::Ready(None) => Poll::Ready(None), + Poll::Pending => Poll::Pending, + } + } +} diff --git a/crates/client/settlement_client/src/eth/mod.rs b/crates/client/settlement_client/src/eth/mod.rs index fef45202f..e15c59730 100644 --- a/crates/client/settlement_client/src/eth/mod.rs +++ b/crates/client/settlement_client/src/eth/mod.rs @@ -1,7 +1,10 @@ +pub mod event; + use crate::client::ClientTrait; +use crate::eth::event::EthereumEventStream; use crate::eth::StarknetCoreContract::{LogMessageToL2, StarknetCoreContractInstance}; use crate::gas_price::L1BlockMetrics; -use crate::messaging::MessageProcessingExt; +use crate::messaging::sync::CommonMessagingEventData; use crate::state_update::{update_l1, StateUpdate}; use crate::utils::{convert_log_state_update, u256_to_felt}; use alloy::eips::BlockNumberOrTag; @@ -17,13 +20,9 @@ use bitvec::macros::internal::funty::Fundamental; use futures::StreamExt; use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; -use mc_mempool::{Mempool, MempoolProvider}; use mp_utils::service::ServiceContext; -use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; -use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; use starknet_types_core::felt::Felt; use std::sync::Arc; -use tracing::error; use url::Url; // abi taken from: https://etherscan.io/address/0x6e0acfdc3cf17a7f99ed34be56c3dfb93f464e24#code @@ -64,7 +63,6 @@ impl Clone for EthereumClient { #[async_trait] impl ClientTrait for EthereumClient { type Config = EthereumClientConfig; - type EventStruct = LogMessageToL2; fn get_l1_block_metrics(&self) -> &L1BlockMetrics { &self.l1_block_metrics @@ -167,45 +165,6 @@ impl ClientTrait for EthereumClient { Ok(()) } - async fn listen_for_messaging_events( - &self, - backend: Arc, - mut ctx: ServiceContext, - last_synced_event_block: LastSyncedEventBlock, - chain_id: ChainId, - mempool: Arc, - ) -> anyhow::Result<()> { - let processor = self.message_processor(backend.clone(), chain_id, mempool.clone()); - let event_filter = self.l1_core_contract.event_filter::(); - - let mut event_stream = event_filter - .from_block(last_synced_event_block.block_number) - .to_block(BlockNumberOrTag::Finalized) - .watch() - .await - .context(ERR_ARCHIVE)? - .into_stream(); - - while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { - if let Ok((event, meta)) = event_result { - if let Err(e) = processor - .process_event( - &event, - meta.block_number, - meta.log_index, - Some(meta.transaction_hash.unwrap().to_string()), - Some(event.fromAddress.to_string()), - ) - .await - { - error!("Error processing event: {:?}", e); - } - } - } - - Ok(()) - } - async fn get_gas_prices(&self) -> anyhow::Result<(u128, u128)> { let block_number = self.get_latest_block_number().await?; let fee_history = self.provider.get_fee_history(300, BlockNumberOrTag::Number(block_number), &[]).await?; @@ -226,89 +185,19 @@ impl ClientTrait for EthereumClient { Ok((*eth_gas_price, avg_blob_base_fee)) } - fn get_messaging_hash(&self, event: &Self::EventStruct) -> anyhow::Result> { + fn get_messaging_hash(&self, event: &CommonMessagingEventData) -> anyhow::Result> { let data = ( [0u8; 12], - event.fromAddress.0 .0, - event.toAddress, - event.nonce, - event.selector, + event.from.clone(), + event.to.clone(), + event.nonce.clone(), + event.selector.clone(), U256::from(event.payload.len()), event.payload.clone(), ); Ok(keccak256(data.abi_encode_packed()).as_slice().to_vec()) } - async fn process_message( - &self, - backend: &MadaraBackend, - event: &Self::EventStruct, - settlement_layer_block_number: &Option, - event_index: &Option, - _chain_id: &ChainId, - mempool: Arc, - ) -> anyhow::Result> { - let transaction = self.parse_handle_message_transaction(event)?; - let tx_nonce = transaction.nonce; - let fees: u128 = event.fee.try_into()?; - - // Ensure that L1 message has not been executed - match backend.has_l1_messaging_nonce(tx_nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(tx_nonce)?; - } - Ok(true) => { - tracing::debug!("⟠ Event already processed: {:?}", transaction); - return Ok(None); - } - Err(e) => { - tracing::error!("⟠ Unexpected DB error: {:?}", e); - return Err(e.into()); - } - }; - - let res = mempool.accept_l1_handler_tx(transaction.into(), fees)?; - - // TODO: remove unwraps - // Ques: shall it panic if no block number of event_index? - let block_sent = LastSyncedEventBlock::new(settlement_layer_block_number.unwrap(), event_index.unwrap()); - backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; - - Ok(Some(res.transaction_hash)) - } - - fn parse_handle_message_transaction(&self, event: &Self::EventStruct) -> anyhow::Result { - // L1 from address. - let from_address = u256_to_felt(event.fromAddress.into_word().into())?; - - // L2 contract to call. - let contract_address = u256_to_felt(event.toAddress)?; - - // Function of the contract to call. - let entry_point_selector = u256_to_felt(event.selector)?; - - // L1 message nonce. - let nonce = u256_to_felt(event.nonce)?; - - let event_payload = event.payload.clone().into_iter().map(u256_to_felt).collect::>>()?; - - let calldata: Calldata = { - let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); - calldata.push(from_address); - calldata.extend(event_payload); - - Calldata(Arc::new(calldata)) - }; - - Ok(L1HandlerTransaction { - nonce: Nonce(nonce), - contract_address: ContractAddress(contract_address.try_into()?), - entry_point_selector: EntryPointSelector(entry_point_selector), - calldata, - version: TransactionVersion(Felt::ZERO), - }) - } - /// Get cancellation status of an L1 to L2 message /// /// This function query the core contract to know if a L1->L2 message has been cancelled @@ -328,6 +217,23 @@ impl ClientTrait for EthereumClient { self.l1_core_contract.l1ToL2MessageCancellations(B256::from_slice(msg_hash.as_slice())).call().await?; u256_to_felt(cancellation_timestamp._0) } + + // ============================================================ + // Stream Implementations : + // ============================================================ + type StreamType = EthereumEventStream; + async fn get_event_stream( + &self, + last_synced_event_block: LastSyncedEventBlock, + ) -> anyhow::Result { + let filter = self.l1_core_contract.event_filter::(); + let event_stream = filter + .from_block(last_synced_event_block.block_number) + .to_block(BlockNumberOrTag::Finalized) + .watch() + .await?; + Ok(EthereumEventStream::new(event_stream)) + } } #[cfg(test)] diff --git a/crates/client/settlement_client/src/gas_price.rs b/crates/client/settlement_client/src/gas_price.rs index 6c997bb01..ffa7e5217 100644 --- a/crates/client/settlement_client/src/gas_price.rs +++ b/crates/client/settlement_client/src/gas_price.rs @@ -5,6 +5,8 @@ use mc_mempool::{GasPriceProvider, L1DataProvider}; use std::sync::Arc; use std::time::{Duration, UNIX_EPOCH}; +use crate::messaging::sync::CommonMessagingEventData; +use futures::Stream; use mc_analytics::register_gauge_metric_instrument; use mp_utils::service::ServiceContext; use opentelemetry::global::Error; @@ -56,11 +58,14 @@ impl L1BlockMetrics { } } -pub async fn gas_price_worker_once( - settlement_client: Arc>>, +pub async fn gas_price_worker_once( + settlement_client: Arc>>, l1_gas_provider: &GasPriceProvider, gas_price_poll_ms: Duration, -) -> anyhow::Result<()> { +) -> anyhow::Result<()> +where + S: Stream>> + Send + 'static, +{ match update_gas_price(settlement_client, l1_gas_provider).await { Ok(_) => tracing::trace!("Updated gas prices"), Err(e) => tracing::error!("Failed to update gas prices: {:?}", e), @@ -81,12 +86,15 @@ pub async fn gas_price_worker_once( anyhow::Ok(()) } -pub async fn gas_price_worker( - settlement_client: Arc>>, +pub async fn gas_price_worker( + settlement_client: Arc>>, l1_gas_provider: GasPriceProvider, gas_price_poll_ms: Duration, mut ctx: ServiceContext, -) -> anyhow::Result<()> { +) -> anyhow::Result<()> +where + S: Stream>> + Send + 'static, +{ l1_gas_provider.update_last_update_timestamp(); let mut interval = tokio::time::interval(gas_price_poll_ms); interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); @@ -98,10 +106,13 @@ pub async fn gas_price_worker( anyhow::Ok(()) } -async fn update_gas_price( - settlement_client: Arc>>, +async fn update_gas_price( + settlement_client: Arc>>, l1_gas_provider: &GasPriceProvider, -) -> anyhow::Result<()> { +) -> anyhow::Result<()> +where + S: Stream>> + Send + 'static, +{ let (eth_gas_price, avg_blob_base_fee) = settlement_client.get_gas_prices().await?; l1_gas_provider.update_eth_l1_gas_price(eth_gas_price); diff --git a/crates/client/settlement_client/src/messaging/mod.rs b/crates/client/settlement_client/src/messaging/mod.rs index 46c24fea0..ca5096656 100644 --- a/crates/client/settlement_client/src/messaging/mod.rs +++ b/crates/client/settlement_client/src/messaging/mod.rs @@ -1,122 +1,4 @@ -use crate::client::ClientTrait; -use anyhow::Result; -use mc_db::l1_db::LastSyncedEventBlock; -use mc_db::MadaraBackend; -use mc_mempool::Mempool; -use starknet_api::core::{ChainId, Nonce}; -use starknet_types_core::felt::Felt; -use std::sync::Arc; -use tracing::{error, info}; - pub mod sync; #[cfg(test)] mod tests; - -// Defining a common message processor struct with -// processing methods. -// This is to keep the common code out of the trait implementations. -pub struct MessageProcessor<'a, T: ?Sized> { - client: &'a T, - backend: Arc, - chain_id: ChainId, - mempool: Arc, -} - -impl<'a, T: ClientTrait> MessageProcessor<'a, T> { - pub fn new(client: &'a T, backend: Arc, chain_id: ChainId, mempool: Arc) -> Self { - Self { client, backend, chain_id, mempool } - } - - pub async fn process_event( - &self, - event: &T::EventStruct, - block_number: Option, - event_index: Option, - transaction_hash: Option, - from_address: Option, - ) -> Result<()> { - let tx = self.client.parse_handle_message_transaction(event)?; - let tx_nonce = tx.nonce; - - // Skip if already processed - if self.backend.has_l1_messaging_nonce(tx_nonce)? { - info!("Event already processed"); - return Ok(()); - } - - info!( - "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", - block_number, - transaction_hash.unwrap(), - from_address.unwrap(), - ); - - // Check message hash and cancellation - let event_hash = self.client.get_messaging_hash(event)?; - info!("Checking for cancellation, event hash: {:?}", Felt::from_bytes_be_slice(event_hash.as_slice())); - - let cancellation_timestamp = self.client.get_l1_to_l2_message_cancellations(event_hash).await?; - if cancellation_timestamp != Felt::ZERO { - info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); - self.handle_cancelled_message(tx_nonce)?; - return Ok(()); - } - - // Process message - match self - .client - .process_message(&self.backend, event, &block_number, &event_index, &self.chain_id, self.mempool.clone()) - .await - { - Ok(Some(tx_hash)) => { - info!("Message from block: {:?} submitted, transaction hash: {:?}", block_number, tx_hash); - - // Update last synced block if available - if let (Some(block_num), Some(evt_idx)) = (block_number, event_index) { - let block_sent = LastSyncedEventBlock::new(block_num, evt_idx); - self.backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; - } - } - Ok(None) => {} - Err(e) => { - error!("Unexpected error while processing Message from block: {:?}, error: {:?}", block_number, e); - return Err(e); - } - } - - Ok(()) - } - - fn handle_cancelled_message(&self, nonce: Nonce) -> Result<()> { - match self.backend.has_l1_messaging_nonce(nonce) { - Ok(false) => { - self.backend.set_l1_messaging_nonce(nonce)?; - } - Ok(true) => {} - Err(e) => { - error!("Unexpected DB error: {:?}", e); - return Err(e.into()); - } - } - Ok(()) - } -} - -// Extension trait for easy processor creation -pub trait MessageProcessingExt: ClientTrait { - fn message_processor( - &self, - backend: Arc, - chain_id: ChainId, - mempool: Arc, - ) -> MessageProcessor - where - Self: Sized, - { - MessageProcessor::new(self, backend, chain_id, mempool) - } -} - -// Blanket implementation for all ClientTrait implementors -impl MessageProcessingExt for T {} diff --git a/crates/client/settlement_client/src/messaging/sync.rs b/crates/client/settlement_client/src/messaging/sync.rs index 44265eaf9..a096487bd 100644 --- a/crates/client/settlement_client/src/messaging/sync.rs +++ b/crates/client/settlement_client/src/messaging/sync.rs @@ -1,10 +1,14 @@ use crate::client::ClientTrait; +use futures::{Stream, StreamExt}; +use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; -use mc_mempool::Mempool; +use mc_mempool::{Mempool, MempoolProvider}; use mp_utils::service::ServiceContext; -use starknet_api::core::ChainId; +use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; +use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; use starknet_types_core::felt::Felt; use std::sync::Arc; +use tracing::{error, info}; // L2 (Starknet) <-> L3 messaging format // GitHub Ref : https://github.com/cartridge-gg/piltover/blob/saya/src/messaging/component.cairo#L85 @@ -18,14 +22,31 @@ pub struct MessageSent { pub payload: Vec, } -pub async fn sync( - settlement_client: Arc>>, +#[derive(Clone)] +pub struct CommonMessagingEventData { + pub from: Vec, + pub to: Vec, + pub selector: Vec, + pub nonce: Vec, + pub payload: Vec>, + pub fee: Option>, + pub transaction_hash: Option>, + pub message_hash: Option>, + pub block_number: Option, + pub event_index: Option, +} + +pub async fn sync( + settlement_client: Arc>>, backend: Arc, chain_id: ChainId, mempool: Arc, - ctx: ServiceContext, -) -> anyhow::Result<()> { - tracing::info!("⟠ Starting L1 Messages Syncing..."); + mut ctx: ServiceContext, +) -> anyhow::Result<()> +where + S: Stream>> + Send + 'static, +{ + info!("⟠ Starting L1 Messages Syncing..."); let last_synced_event_block = match backend.messaging_last_synced_l1_block_with_event() { Ok(Some(blk)) => blk, @@ -33,12 +54,171 @@ pub async fn sync( unreachable!("Should never be None") } Err(e) => { - tracing::error!("⟠ Madara Messaging DB unavailable: {:?}", e); + error!("⟠ Madara Messaging DB unavailable: {:?}", e); return Err(e.into()); } }; - settlement_client.listen_for_messaging_events(backend, ctx, last_synced_event_block, chain_id, mempool).await?; + let stream = settlement_client.get_event_stream(last_synced_event_block).await?; + let mut event_stream = Box::pin(stream); + + while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { + match event_result { + Some(event) => { + let event_data = event?; + let tx = parse_handle_message_transaction(&event_data)?; + let tx_nonce = tx.nonce; + + // Skip if already processed + if backend.has_l1_messaging_nonce(tx_nonce)? { + info!("Event already processed"); + return Ok(()); + } + + info!( + "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", + event_data.block_number, event_data.transaction_hash, event_data.from, + ); + // Check message hash and cancellation + let event_hash = settlement_client.get_messaging_hash(&event_data)?; + info!("Checking for cancellation, event hash: {:?}", Felt::from_bytes_be_slice(event_hash.as_slice())); + + let cancellation_timestamp = settlement_client.get_l1_to_l2_message_cancellations(event_hash).await?; + if cancellation_timestamp != Felt::ZERO { + info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); + handle_cancelled_message(backend, tx_nonce)?; + return Ok(()); + } + + // Process message + match process_message( + &backend, + &event_data, + &event_data.block_number, + &event_data.event_index, + &chain_id, + mempool.clone(), + ) + .await + { + Ok(Some(tx_hash)) => { + info!( + "Message from block: {:?} submitted, transaction hash: {:?}", + event_data.block_number, tx_hash + ); + + // Update last synced block if available + if let (Some(block_num), Some(evt_idx)) = (event_data.block_number, event_data.event_index) { + let block_sent = LastSyncedEventBlock::new(block_num, evt_idx); + backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; + } + } + Ok(None) => {} + Err(e) => { + error!( + "Unexpected error while processing Message from block: {:?}, error: {:?}", + event_data.block_number, e + ); + return Err(e); + } + } + } + None => {} + } + } Ok(()) } + +fn handle_cancelled_message(backend: Arc, nonce: Nonce) -> anyhow::Result<()> { + match backend.has_l1_messaging_nonce(nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(nonce)?; + } + Ok(true) => {} + Err(e) => { + error!("Unexpected DB error: {:?}", e); + return Err(e.into()); + } + } + Ok(()) +} + +pub fn parse_handle_message_transaction(event: &CommonMessagingEventData) -> anyhow::Result { + // L1 from address. + let from_address = Felt::from_bytes_be_slice(event.from.as_slice()); + + // L2 contract to call. + let contract_address = Felt::from_bytes_be_slice(event.to.as_slice()); + + // Function of the contract to call. + let entry_point_selector = Felt::from_bytes_be_slice(event.selector.as_slice()); + + // L1 message nonce. + let nonce = Felt::from_bytes_be_slice(event.nonce.as_slice()); + + let event_payload: Vec = + event.payload.clone().into_iter().map(|ele| Felt::from_bytes_be_slice(ele.as_slice())).collect(); + + let calldata: Calldata = { + let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); + calldata.push(from_address); + calldata.extend(event_payload); + Calldata(Arc::new(calldata)) + }; + + Ok(L1HandlerTransaction { + nonce: Nonce(nonce), + contract_address: ContractAddress(contract_address.try_into()?), + entry_point_selector: EntryPointSelector(entry_point_selector), + calldata, + version: TransactionVersion(Felt::ZERO), + }) +} + +async fn process_message( + backend: &MadaraBackend, + event: &CommonMessagingEventData, + settlement_layer_block_number: &Option, + event_index: &Option, + _chain_id: &ChainId, + mempool: Arc, +) -> anyhow::Result> { + let transaction = parse_handle_message_transaction(event)?; + let tx_nonce = transaction.nonce; + let fees = vec_to_u128_be(event.fee.clone().unwrap()); + + // Ensure that L1 message has not been executed + match backend.has_l1_messaging_nonce(tx_nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(tx_nonce)?; + } + Ok(true) => { + tracing::debug!("⟠ Event already processed: {:?}", transaction); + return Ok(None); + } + Err(e) => { + error!("⟠ Unexpected DB error: {:?}", e); + return Err(e.into()); + } + }; + + let res = mempool.accept_l1_handler_tx(transaction.into(), fees.unwrap_or(0))?; + + // TODO: remove unwraps + // Ques: shall it panic if no block number of event_index? + let block_sent = LastSyncedEventBlock::new(settlement_layer_block_number.unwrap(), event_index.unwrap()); + backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; + + Ok(Some(res.transaction_hash)) +} + +fn vec_to_u128_be(bytes: Vec) -> Option { + if bytes.len() > 16 { + return None; + } + // Pad with zeros if less than 16 bytes + let mut padded = vec![0u8; 16]; + padded[16 - bytes.len()..].copy_from_slice(&bytes); + Some(u128::from_be_bytes(padded.try_into().unwrap())) +} diff --git a/crates/client/settlement_client/src/starknet/event.rs b/crates/client/settlement_client/src/starknet/event.rs new file mode 100644 index 000000000..1ad4ea4a5 --- /dev/null +++ b/crates/client/settlement_client/src/starknet/event.rs @@ -0,0 +1,120 @@ +use crate::messaging::sync::CommonMessagingEventData; +use bigdecimal::ToPrimitive; +use futures::{Stream, TryFuture}; +use starknet_core::types::{BlockId, EmittedEvent, EventFilter}; +use starknet_providers::jsonrpc::HttpTransport; +use starknet_providers::{JsonRpcClient, Provider}; +use std::collections::HashSet; +use std::pin::Pin; +use std::sync::Arc; +use std::task::{Context, Poll}; + +#[derive(Hash, Eq, PartialEq)] +struct EventKey { + block_number: u64, + transaction_hash: String, + event_index: u64, +} + +impl From<&EmittedEvent> for EventKey { + fn from(event: &EmittedEvent) -> Self { + Self { + block_number: event.block_number.unwrap_or(0), + transaction_hash: event.transaction_hash.to_string(), + event_index: event.data[4].to_u64().unwrap(), // nonce of the event + } + } +} + +pub struct StarknetEventStream { + provider: Arc>, + filter: EventFilter, + processed_events: HashSet, +} + +impl StarknetEventStream { + pub fn new(provider: Arc>, filter: EventFilter) -> Self { + Self { provider, filter, processed_events: HashSet::new() } + } + + fn is_duplicate(&self, event: &EmittedEvent) -> bool { + self.processed_events.contains(&EventKey::from(event)) + } + + async fn get_events(&self) -> anyhow::Result> { + let mut event_vec = Vec::new(); + let mut page_indicator = false; + let mut continuation_token: Option = None; + + while !page_indicator { + let events = self + .provider + .get_events( + EventFilter { + from_block: self.filter.from_block, + to_block: self.filter.to_block, + address: self.filter.address, + keys: self.filter.keys.clone(), + }, + continuation_token.clone(), + 1000, + ) + .await?; + + event_vec.extend(events.events); + if let Some(token) = events.continuation_token { + continuation_token = Some(token); + } else { + page_indicator = true; + } + } + + Ok(event_vec) + } +} + +impl Stream for StarknetEventStream { + type Item = Option>; + + fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let future = async { + let events = self.get_events().await?; + let latest_block = self.provider.block_number().await?; + self.filter.from_block = Some(BlockId::Number(latest_block)); + self.filter.to_block = Some(BlockId::Number(latest_block)); + + for event in events { + if !self.is_duplicate(&event) { + let key = EventKey::from(&event); + self.processed_events.insert(key); + return Ok(Some(event)); + } + } + + Ok(None) + }; + + match futures::ready!(Box::pin(future).as_mut().try_poll(cx)) { + Ok(Some(event)) => Poll::Ready(Some(Some(Ok(CommonMessagingEventData { + from: event.data[1].to_bytes_be().to_vec(), + to: event.data[2].to_bytes_be().to_vec(), + selector: event.data[3].to_bytes_be().to_vec(), + nonce: event.data[4].to_bytes_be().to_vec(), + payload: { + let mut payload_array = vec![]; + event.data.iter().skip(6).for_each(|data| { + payload_array.push(data.to_bytes_be().to_vec()); + }); + payload_array + }, + fee: None, + transaction_hash: None, + message_hash: Some(event.data[0].to_bytes_be().to_vec()), + block_number: None, + event_index: None, + })))), + Ok(None) => Poll::Ready(None), + Err(e) => Poll::Ready(Some(Some(Err(e)))), + } + } +} diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index b9285a161..dbe744cae 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -1,17 +1,14 @@ use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; -use crate::messaging::sync::MessageSent; -use crate::messaging::MessageProcessingExt; +use crate::messaging::sync::CommonMessagingEventData; +use crate::starknet::event::StarknetEventStream; use crate::state_update::{update_l1, StateUpdate}; use anyhow::{anyhow, bail}; use async_trait::async_trait; use bigdecimal::ToPrimitive; use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; -use mc_mempool::{Mempool, MempoolProvider}; use mp_utils::service::ServiceContext; -use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; -use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; use starknet_core::types::{BlockId, BlockTag, EmittedEvent, EventFilter, FunctionCall}; use starknet_core::utils::get_selector_from_name; use starknet_crypto::poseidon_hash_many; @@ -24,6 +21,7 @@ use tokio::time::sleep; use tracing::{error, trace}; use url::Url; +pub mod event; #[cfg(test)] pub mod utils; @@ -57,7 +55,6 @@ impl Clone for StarknetClient { #[async_trait] impl ClientTrait for StarknetClient { type Config = StarknetClientConfig; - type EventStruct = MessageSent; fn get_l1_block_metrics(&self) -> &L1BlockMetrics { &self.l1_block_metrics @@ -186,80 +183,6 @@ impl ClientTrait for StarknetClient { } } - async fn listen_for_messaging_events( - &self, - backend: Arc, - mut ctx: ServiceContext, - last_synced_event_block: LastSyncedEventBlock, - chain_id: ChainId, - mempool: Arc, - ) -> anyhow::Result<()> { - let processor = self.message_processor(backend.clone(), chain_id, mempool.clone()); - let mut sync_flag = false; - - loop { - let latest_block_number = self.get_latest_block_number().await?; - let starting_block = if !sync_flag { - last_synced_event_block.block_number - } else if latest_block_number < 100 { - 0 - } else { - latest_block_number - 100 - }; - - assert!(starting_block <= latest_block_number); - - let events_response = ctx.run_until_cancelled(self.get_events( - BlockId::Number(starting_block), - BlockId::Number(latest_block_number), - self.l2_core_contract, - vec![get_selector_from_name("MessageSent")?], - )); - - sync_flag = true; - - match events_response.await { - Some(Ok(emitted_events)) => { - for event in emitted_events { - let mut payload_array = vec![]; - event.data.iter().skip(6).for_each(|data| { - payload_array.push(*data); - }); - - let formatted_event = MessageSent { - message_hash: event.data[0], - from: event.data[1], - to: event.data[2], - selector: event.data[3], - nonce: event.data[4], - payload: payload_array, - }; - - if let Err(e) = processor - .process_event( - &formatted_event, - event.block_number, - Some(0), - Some(event.transaction_hash.to_hex_string()), - Some(formatted_event.from.to_hex_string()), - ) - .await - { - error!("Error processing event: {:?}", e); - } - } - } - Some(Err(e)) => { - error!("Error processing event: {:?}", e); - } - None => { - trace!("No events found"); - } - } - - sleep(Duration::from_secs(5)).await; - } - } // We are returning here (0,0) because we are assuming that // the L3s will have zero gas prices. for any transaction. // So that's why we will keep the prices as 0 returning from @@ -268,64 +191,10 @@ impl ClientTrait for StarknetClient { Ok((0, 0)) } - fn get_messaging_hash(&self, event: &Self::EventStruct) -> anyhow::Result> { + fn get_messaging_hash(&self, event: &CommonMessagingEventData) -> anyhow::Result> { Ok(poseidon_hash_many(&self.event_to_felt_array(event)).to_bytes_be().to_vec()) } - async fn process_message( - &self, - backend: &MadaraBackend, - event: &Self::EventStruct, - settlement_layer_block_number: &Option, - event_index: &Option, - _chain_id: &ChainId, - mempool: Arc, - ) -> anyhow::Result> { - let transaction = self.parse_handle_message_transaction(event)?; - let tx_nonce = transaction.nonce; - - // Ensure that L2 message has not been executed - match backend.has_l1_messaging_nonce(tx_nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(tx_nonce)?; - } - Ok(true) => { - tracing::debug!("🔵 Event already processed: {:?}", transaction); - return Ok(None); - } - Err(e) => { - tracing::error!("🔵 Unexpected DB error: {:?}", e); - return Err(e.into()); - } - }; - - let res = mempool.accept_l1_handler_tx(transaction.into(), 0); - - // TODO: remove unwraps - // Ques: shall it panic if no block number of event_index? - let block_sent = LastSyncedEventBlock::new(settlement_layer_block_number.unwrap(), event_index.unwrap()); - backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; - - Ok(Some(res?.transaction_hash)) - } - - fn parse_handle_message_transaction(&self, event: &Self::EventStruct) -> anyhow::Result { - let calldata: Calldata = { - let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); - calldata.push(event.from); - calldata.extend(event.payload.clone()); - Calldata(Arc::new(calldata)) - }; - - Ok(L1HandlerTransaction { - nonce: Nonce(event.nonce), - contract_address: ContractAddress(event.from.try_into()?), - entry_point_selector: EntryPointSelector(event.selector), - calldata, - version: TransactionVersion(Felt::ZERO), - }) - } - async fn get_l1_to_l2_message_cancellations(&self, msg_hash: Vec) -> anyhow::Result { let call_res = self .provider @@ -343,6 +212,23 @@ impl ClientTrait for StarknetClient { assert_eq!(call_res.len(), 2, "l1_to_l2_message_cancellations should return only 2 values"); Ok(call_res[0]) } + + // ============================================================ + // Stream Implementations : + // ============================================================ + type StreamType = StarknetEventStream; + async fn get_event_stream( + &self, + last_synced_event_block: LastSyncedEventBlock, + ) -> anyhow::Result { + let filter = EventFilter { + from_block: Some(BlockId::Number(last_synced_event_block.block_number)), + to_block: None, + address: Some(self.l2_core_contract), + keys: Some(vec![vec![get_selector_from_name("MessageSent")?]]), + }; + Ok(StarknetEventStream::new(self.provider.clone(), filter)) + } } impl StarknetClient { @@ -383,18 +269,21 @@ impl StarknetClient { Ok(event_vec) } - fn event_to_felt_array(&self, event: &MessageSent) -> Vec { - let mut felt_vec = vec![event.from, event.to, event.selector, event.nonce]; + fn event_to_felt_array(&self, event: &CommonMessagingEventData) -> Vec { + let mut felt_vec = vec![ + Felt::from_bytes_be_slice(event.from.as_slice()), + Felt::from_bytes_be_slice(event.to.as_slice()), + Felt::from_bytes_be_slice(event.selector.as_slice()), + Felt::from_bytes_be_slice(event.nonce.as_slice()), + ]; felt_vec.push(Felt::from(event.payload.len())); event.payload.clone().into_iter().for_each(|felt| { - felt_vec.push(felt); + felt_vec.push(Felt::from_bytes_be_slice(felt.as_slice())); }); felt_vec } -} -impl StarknetClient { pub async fn get_state_call(&self) -> anyhow::Result> { let call_res = self .provider diff --git a/crates/client/settlement_client/src/state_update.rs b/crates/client/settlement_client/src/state_update.rs index 6694d1be5..e4967de6a 100644 --- a/crates/client/settlement_client/src/state_update.rs +++ b/crates/client/settlement_client/src/state_update.rs @@ -2,8 +2,10 @@ use std::sync::Arc; use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; +use crate::messaging::sync::CommonMessagingEventData; use crate::utils::trim_hash; use anyhow::Context; +use futures::Stream; use mc_db::MadaraBackend; use mp_utils::service::ServiceContext; use serde::Deserialize; @@ -36,11 +38,14 @@ pub fn update_l1( Ok(()) } -pub async fn state_update_worker( +pub async fn state_update_worker( backend: Arc, - settlement_client: Arc>>, + settlement_client: Arc>>, ctx: ServiceContext, -) -> anyhow::Result<()> { +) -> anyhow::Result<()> +where + S: Stream>> + Send + 'static, +{ // Clear L1 confirmed block at startup backend.clear_last_confirmed_block().context("Clearing l1 last confirmed block number")?; tracing::debug!("update_l1: cleared confirmed block number"); diff --git a/crates/client/settlement_client/src/sync.rs b/crates/client/settlement_client/src/sync.rs index f62db3242..4ee69c3eb 100644 --- a/crates/client/settlement_client/src/sync.rs +++ b/crates/client/settlement_client/src/sync.rs @@ -1,7 +1,8 @@ use crate::client::ClientTrait; use crate::gas_price::gas_price_worker; -use crate::messaging::sync::sync; +use crate::messaging::sync::{sync, CommonMessagingEventData}; use crate::state_update::state_update_worker; +use futures::Stream; use mc_db::MadaraBackend; use mc_mempool::{GasPriceProvider, Mempool}; use mp_utils::service::ServiceContext; @@ -10,16 +11,19 @@ use std::sync::Arc; use std::time::Duration; #[allow(clippy::too_many_arguments)] -pub async fn sync_worker( +pub async fn sync_worker( backend: Arc, - settlement_client: Arc>>, + settlement_client: Arc>>, chain_id: ChainId, l1_gas_provider: GasPriceProvider, gas_price_sync_disabled: bool, gas_price_poll_ms: Duration, mempool: Arc, ctx: ServiceContext, -) -> anyhow::Result<()> { +) -> anyhow::Result<()> +where + S: Stream>> + Send + 'static, +{ let mut join_set = tokio::task::JoinSet::new(); join_set.spawn(state_update_worker(Arc::clone(&backend), settlement_client.clone(), ctx.clone())); diff --git a/crates/node/src/main.rs b/crates/node/src/main.rs index 30814d214..b4c0ceb86 100644 --- a/crates/node/src/main.rs +++ b/crates/node/src/main.rs @@ -17,8 +17,6 @@ use mc_gateway_client::GatewayProvider; use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; use mc_rpc::providers::{AddTransactionProvider, ForwardToProvider, MempoolAddTxProvider}; use mc_settlement_client::eth::EthereumClientConfig; -use mc_settlement_client::eth::StarknetCoreContract::LogMessageToL2; -use mc_settlement_client::messaging::sync::MessageSent; use mc_settlement_client::starknet::StarknetClientConfig; use mc_sync::fetch::fetchers::WarpUpdateConfig; use mc_telemetry::{SysInfo, TelemetryService}; @@ -26,6 +24,8 @@ use mp_oracle::pragma::PragmaOracleBuilder; use mp_utils::service::{MadaraServiceId, ServiceMonitor}; use service::{BlockProductionService, GatewayService, L1SyncService, L2SyncService, RpcService}; use std::sync::Arc; +use mc_settlement_client::eth::event::EthereumEventStream; +use mc_settlement_client::starknet::event::StarknetEventStream; const GREET_IMPL_NAME: &str = "Madara"; const GREET_SUPPORT_URL: &str = "https://github.com/madara-alliance/madara/issues"; @@ -159,7 +159,7 @@ async fn main() -> anyhow::Result<()> { let mempool = Arc::new(mempool); let service_l1_sync = match &run_cmd.l1_sync_params.settlement_layer { - MadaraSettlementLayer::Eth => L1SyncService::::create( + MadaraSettlementLayer::Eth => L1SyncService::::create( &run_cmd.l1_sync_params, &service_db, l1_gas_setter, @@ -171,7 +171,7 @@ async fn main() -> anyhow::Result<()> { ) .await .context("Initializing the l1 sync service")?, - MadaraSettlementLayer::Starknet => L1SyncService::::create( + MadaraSettlementLayer::Starknet => L1SyncService::::create( &run_cmd.l1_sync_params, &service_db, l1_gas_setter, diff --git a/crates/node/src/service/l1.rs b/crates/node/src/service/l1.rs index c011b4604..386614dfd 100644 --- a/crates/node/src/service/l1.rs +++ b/crates/node/src/service/l1.rs @@ -4,10 +4,11 @@ use anyhow::Context; use mc_db::{DatabaseService, MadaraBackend}; use mc_mempool::{GasPriceProvider, Mempool}; use mc_settlement_client::client::ClientTrait; -use mc_settlement_client::eth::StarknetCoreContract::LogMessageToL2; +use mc_settlement_client::eth::event::EthereumEventStream; use mc_settlement_client::eth::{EthereumClient, EthereumClientConfig}; use mc_settlement_client::gas_price::L1BlockMetrics; -use mc_settlement_client::messaging::sync::MessageSent; +use mc_settlement_client::messaging::sync::{CommonMessagingEventData}; +use mc_settlement_client::starknet::event::StarknetEventStream; use mc_settlement_client::starknet::{StarknetClient, StarknetClientConfig}; use mp_utils::service::{MadaraServiceId, PowerOfTwo, Service, ServiceId, ServiceRunner}; use starknet_api::core::ChainId; @@ -15,15 +16,15 @@ use starknet_core::types::Felt; use std::str::FromStr; use std::sync::Arc; use std::time::Duration; +use futures::Stream; -#[derive(Clone)] -pub struct L1SyncService +pub struct L1SyncService where C: Clone, - E: Clone, + S: Send + Stream>>, { db_backend: Arc, - settlement_client: Option>>>, + settlement_client: Option>>>, l1_gas_provider: GasPriceProvider, chain_id: ChainId, gas_price_sync_disabled: bool, @@ -31,9 +32,8 @@ where mempool: Arc, } -pub type EthereumSyncService = L1SyncService; - -pub type StarknetSyncService = L1SyncService; +pub type EthereumSyncService = L1SyncService; +pub type StarknetSyncService = L1SyncService; // Implementation for Ethereum impl EthereumSyncService { @@ -61,7 +61,7 @@ impl EthereumSyncService { .context("Creating ethereum client")?; let client_converted: Box< - dyn ClientTrait, + dyn ClientTrait, > = Box::new(client); Some(Arc::new(client_converted)) } else { @@ -103,8 +103,9 @@ impl StarknetSyncService { .context("Creating starknet client")?; // StarknetClientConfig, Arc>, Felt - let client_converted: Box> = - Box::new(client); + let client_converted: Box< + dyn ClientTrait, + > = Box::new(client); Some(Arc::new(client_converted)) } else { anyhow::bail!( @@ -120,12 +121,16 @@ impl StarknetSyncService { } // Shared implementation for both services -impl L1SyncService { +impl L1SyncService +where + C: Clone + 'static, + S: Send + Stream>> + 'static, +{ #[allow(clippy::too_many_arguments)] async fn create_service( config: &L1SyncParams, db: &DatabaseService, - settlement_client: Option>>>, + settlement_client: Option>>>, l1_gas_provider: GasPriceProvider, chain_id: ChainId, authority: bool, @@ -200,26 +205,21 @@ impl L1SyncService { } #[async_trait::async_trait] -impl Service for L1SyncService +impl Service for L1SyncService where C: Clone, - E: Clone, + S: Send + Stream>>, { async fn start<'a>(&mut self, runner: ServiceRunner<'a>) -> anyhow::Result<()> { - let L1SyncService { - db_backend, - l1_gas_provider, - chain_id, - gas_price_sync_disabled, - gas_price_poll, - mempool, - .. - } = self.clone(); - if let Some(settlement_client) = &self.settlement_client { - // enabled - + let db_backend = Arc::clone(&self.db_backend); let settlement_client = Arc::clone(settlement_client); + let chain_id = self.chain_id.clone(); + let l1_gas_provider = self.l1_gas_provider.clone(); + let gas_price_sync_disabled = self.gas_price_sync_disabled; + let gas_price_poll = self.gas_price_poll; + let mempool = Arc::clone(&self.mempool); + runner.service_loop(move |ctx| { mc_settlement_client::sync::sync_worker( db_backend, @@ -240,10 +240,10 @@ where } } -impl ServiceId for L1SyncService +impl ServiceId for L1SyncService where C: Clone, - E: Clone, + S: Send + Stream>>, { #[inline(always)] fn svc_id(&self) -> PowerOfTwo { From aa7834e10acaed8e717d390caf18c2970dbe9b80 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Mon, 6 Jan 2025 17:35:19 +0530 Subject: [PATCH 12/23] refactor : tests --- .../client/settlement_client/src/gas_price.rs | 14 +++---- .../settlement_client/src/messaging/tests.rs | 41 +++++++++++-------- .../settlement_client/src/state_update.rs | 8 ++-- crates/node/src/main.rs | 4 +- crates/node/src/service/l1.rs | 4 +- 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/crates/client/settlement_client/src/gas_price.rs b/crates/client/settlement_client/src/gas_price.rs index ffa7e5217..9203cce34 100644 --- a/crates/client/settlement_client/src/gas_price.rs +++ b/crates/client/settlement_client/src/gas_price.rs @@ -179,8 +179,8 @@ async fn update_l1_block_metrics( mod eth_client_gas_price_worker_test { use super::*; use crate::eth::eth_client_getter_test::{create_ethereum_client, get_shared_anvil}; + use crate::eth::event::EthereumEventStream; use crate::eth::EthereumClientConfig; - use crate::eth::StarknetCoreContract::LogMessageToL2; use httpmock::{MockServer, Regex}; use mc_mempool::GasPriceProvider; use serial_test::serial; @@ -200,7 +200,7 @@ mod eth_client_gas_price_worker_test { let eth_client = eth_client.clone(); let l1_gas_provider = l1_gas_provider.clone(); async move { - gas_price_worker::( + gas_price_worker::( Arc::new(Box::new(eth_client)), l1_gas_provider, Duration::from_millis(200), @@ -240,7 +240,7 @@ mod eth_client_gas_price_worker_test { let l1_gas_provider = GasPriceProvider::new(); // Run the worker for a short time - let worker_handle = gas_price_worker_once::( + let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), @@ -265,7 +265,7 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.set_gas_price_sync_enabled(false); // Run the worker for a short time - let worker_handle = gas_price_worker_once::( + let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), @@ -290,7 +290,7 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.set_data_gas_price_sync_enabled(false); // Run the worker for a short time - let worker_handle = gas_price_worker_once::( + let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), @@ -344,7 +344,7 @@ mod eth_client_gas_price_worker_test { let result = timeout( timeout_duration, - gas_price_worker::( + gas_price_worker::( Arc::new(Box::new(eth_client)), l1_gas_provider.clone(), Duration::from_millis(200), @@ -381,7 +381,7 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.update_last_update_timestamp(); // Update gas prices - update_gas_price::(Arc::new(Box::new(eth_client)), &l1_gas_provider) + update_gas_price::(Arc::new(Box::new(eth_client)), &l1_gas_provider) .await .expect("Failed to update gas prices"); diff --git a/crates/client/settlement_client/src/messaging/tests.rs b/crates/client/settlement_client/src/messaging/tests.rs index e7857187d..12a4336fe 100644 --- a/crates/client/settlement_client/src/messaging/tests.rs +++ b/crates/client/settlement_client/src/messaging/tests.rs @@ -268,11 +268,9 @@ mod l1_messaging_tests { use self::DummyContract::DummyContractInstance; use crate::client::ClientTrait; - use crate::eth::StarknetCoreContract::LogMessageToL2; use crate::eth::{EthereumClient, StarknetCoreContract}; use crate::gas_price::L1BlockMetrics; - use crate::messaging::sync::sync; - use crate::utils::felt_to_u256; + use crate::messaging::sync::{sync, CommonMessagingEventData}; use alloy::{ hex::FromHex, node_bindings::{Anvil, AnvilInstance}, @@ -611,23 +609,30 @@ mod l1_messaging_tests { } = setup_test_env().await; let msg = eth_client - .get_messaging_hash(&LogMessageToL2 { - fromAddress: Address::from_hex("c3511006C04EF1d78af4C8E0e74Ec18A6E64Ff9e").unwrap(), - toAddress: felt_to_u256( - Felt::from_hex("0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82").unwrap(), - ), - selector: felt_to_u256( - Felt::from_hex("0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5").unwrap(), - ), + .get_messaging_hash(&CommonMessagingEventData { + from: Address::from_hex("c3511006C04EF1d78af4C8E0e74Ec18A6E64Ff9e").unwrap().0 .0.to_vec(), + to: Felt::from_hex("0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82") + .unwrap() + .to_bytes_be() + .to_vec(), + selector: Felt::from_hex("0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5") + .unwrap() + .to_bytes_be() + .to_vec(), payload: vec![ - felt_to_u256( - Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7").unwrap(), - ), - felt_to_u256(Felt::from_hex("0x2c68af0bb140000").unwrap()), - felt_to_u256(Felt::from_hex("0x0").unwrap()), + Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7") + .unwrap() + .to_bytes_be() + .to_vec(), + Felt::from_hex("0x2c68af0bb140000").unwrap().to_bytes_be().to_vec(), + Felt::from_hex("0x0").unwrap().to_bytes_be().to_vec(), ], - nonce: U256::from(775628), - fee: U256::ZERO, + nonce: U256::from(775628).to_be_bytes_vec(), + fee: Some(U256::ZERO.to_be_bytes_vec()), + transaction_hash: None, + message_hash: None, + block_number: None, + event_index: None, }) .expect("Failed to compute l1 to l2 msg hash"); diff --git a/crates/client/settlement_client/src/state_update.rs b/crates/client/settlement_client/src/state_update.rs index e4967de6a..8d7fe00e8 100644 --- a/crates/client/settlement_client/src/state_update.rs +++ b/crates/client/settlement_client/src/state_update.rs @@ -67,7 +67,7 @@ mod eth_client_event_subscription_test { use super::*; use std::{sync::Arc, time::Duration}; - use crate::eth::StarknetCoreContract::LogMessageToL2; + use crate::eth::event::EthereumEventStream; use crate::eth::{EthereumClient, EthereumClientConfig, StarknetCoreContract}; use alloy::{node_bindings::Anvil, providers::ProviderBuilder, sol}; use mc_db::DatabaseService; @@ -147,7 +147,7 @@ mod eth_client_event_subscription_test { let listen_handle = { let db = Arc::clone(&db); tokio::spawn(async move { - state_update_worker::( + state_update_worker::( Arc::clone(db.backend()), Arc::new(Box::new(eth_client)), ServiceContext::new_for_testing(), @@ -176,7 +176,7 @@ mod eth_client_event_subscription_test { mod starknet_client_event_subscription_test { use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; - use crate::messaging::sync::MessageSent; + use crate::starknet::event::StarknetEventStream; use crate::starknet::utils::{prepare_starknet_client_test, send_state_update, MADARA_PORT}; use crate::starknet::{StarknetClient, StarknetClientConfig}; use crate::state_update::{state_update_worker, StateUpdate}; @@ -228,7 +228,7 @@ mod starknet_client_event_subscription_test { let listen_handle = { let db = Arc::clone(&db); tokio::spawn(async move { - state_update_worker::( + state_update_worker::( Arc::clone(db.backend()), Arc::new(Box::new(starknet_client)), ServiceContext::new_for_testing(), diff --git a/crates/node/src/main.rs b/crates/node/src/main.rs index b4c0ceb86..fa933cd12 100644 --- a/crates/node/src/main.rs +++ b/crates/node/src/main.rs @@ -16,7 +16,9 @@ use mc_db::{DatabaseService, TrieLogConfig}; use mc_gateway_client::GatewayProvider; use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; use mc_rpc::providers::{AddTransactionProvider, ForwardToProvider, MempoolAddTxProvider}; +use mc_settlement_client::eth::event::EthereumEventStream; use mc_settlement_client::eth::EthereumClientConfig; +use mc_settlement_client::starknet::event::StarknetEventStream; use mc_settlement_client::starknet::StarknetClientConfig; use mc_sync::fetch::fetchers::WarpUpdateConfig; use mc_telemetry::{SysInfo, TelemetryService}; @@ -24,8 +26,6 @@ use mp_oracle::pragma::PragmaOracleBuilder; use mp_utils::service::{MadaraServiceId, ServiceMonitor}; use service::{BlockProductionService, GatewayService, L1SyncService, L2SyncService, RpcService}; use std::sync::Arc; -use mc_settlement_client::eth::event::EthereumEventStream; -use mc_settlement_client::starknet::event::StarknetEventStream; const GREET_IMPL_NAME: &str = "Madara"; const GREET_SUPPORT_URL: &str = "https://github.com/madara-alliance/madara/issues"; diff --git a/crates/node/src/service/l1.rs b/crates/node/src/service/l1.rs index 386614dfd..ffe879865 100644 --- a/crates/node/src/service/l1.rs +++ b/crates/node/src/service/l1.rs @@ -1,13 +1,14 @@ use crate::cli::l1::{L1SyncParams, MadaraSettlementLayer}; use alloy::primitives::Address; use anyhow::Context; +use futures::Stream; use mc_db::{DatabaseService, MadaraBackend}; use mc_mempool::{GasPriceProvider, Mempool}; use mc_settlement_client::client::ClientTrait; use mc_settlement_client::eth::event::EthereumEventStream; use mc_settlement_client::eth::{EthereumClient, EthereumClientConfig}; use mc_settlement_client::gas_price::L1BlockMetrics; -use mc_settlement_client::messaging::sync::{CommonMessagingEventData}; +use mc_settlement_client::messaging::sync::CommonMessagingEventData; use mc_settlement_client::starknet::event::StarknetEventStream; use mc_settlement_client::starknet::{StarknetClient, StarknetClientConfig}; use mp_utils::service::{MadaraServiceId, PowerOfTwo, Service, ServiceId, ServiceRunner}; @@ -16,7 +17,6 @@ use starknet_core::types::Felt; use std::str::FromStr; use std::sync::Arc; use std::time::Duration; -use futures::Stream; pub struct L1SyncService where From 6c1ff95e139a15ae1b68524615e4f30a7a83bfd4 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Tue, 7 Jan 2025 15:35:02 +0530 Subject: [PATCH 13/23] fix : tests --- Cargo.lock | 1 + crates/client/settlement_client/Cargo.toml | 1 + .../client/settlement_client/src/eth/event.rs | 8 +- .../settlement_client/src/messaging/sync.rs | 123 ++++++----- .../settlement_client/src/messaging/tests.rs | 7 +- .../settlement_client/src/starknet/event.rs | 203 ++++++++++-------- .../settlement_client/src/starknet/mod.rs | 4 +- crates/client/settlement_client/src/sync.rs | 2 +- 8 files changed, 191 insertions(+), 158 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 415dd3de6..d00969da0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5823,6 +5823,7 @@ dependencies = [ "bitvec", "dotenv", "futures", + "hex", "httpmock", "lazy_static", "mc-analytics", diff --git a/crates/client/settlement_client/Cargo.toml b/crates/client/settlement_client/Cargo.toml index 034e6bcaf..3f933b645 100644 --- a/crates/client/settlement_client/Cargo.toml +++ b/crates/client/settlement_client/Cargo.toml @@ -76,6 +76,7 @@ tracing = { workspace = true } tracing-core = { workspace = true, default-features = false } tracing-opentelemetry = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } +hex = "0.4.3" [features] diff --git a/crates/client/settlement_client/src/eth/event.rs b/crates/client/settlement_client/src/eth/event.rs index 0c570646c..4d0fabaf8 100644 --- a/crates/client/settlement_client/src/eth/event.rs +++ b/crates/client/settlement_client/src/eth/event.rs @@ -38,10 +38,12 @@ impl Stream for EthereumEventStream { payload_vec }, fee: Some(event.data.fee.to_be_bytes_vec()), - transaction_hash: None, + transaction_hash: Some( + log.transaction_hash.expect("Unable to get transaction hash from event log.").to_vec(), + ), message_hash: None, - block_number: None, - event_index: None, + block_number: Some(log.block_number.expect("Unable to get block number from event log.")), + event_index: Some(log.log_index.expect("Unable to get log index from event log.")), })))), Err(e) => Poll::Ready(Some(Some(Err(Error::from(e))))), } diff --git a/crates/client/settlement_client/src/messaging/sync.rs b/crates/client/settlement_client/src/messaging/sync.rs index a096487bd..531d79318 100644 --- a/crates/client/settlement_client/src/messaging/sync.rs +++ b/crates/client/settlement_client/src/messaging/sync.rs @@ -63,68 +63,67 @@ where let mut event_stream = Box::pin(stream); while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { - match event_result { - Some(event) => { - let event_data = event?; - let tx = parse_handle_message_transaction(&event_data)?; - let tx_nonce = tx.nonce; - - // Skip if already processed - if backend.has_l1_messaging_nonce(tx_nonce)? { - info!("Event already processed"); - return Ok(()); - } - - info!( - "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", - event_data.block_number, event_data.transaction_hash, event_data.from, - ); - - // Check message hash and cancellation - let event_hash = settlement_client.get_messaging_hash(&event_data)?; - info!("Checking for cancellation, event hash: {:?}", Felt::from_bytes_be_slice(event_hash.as_slice())); + if let Some(event) = event_result { + let event_data = event?; + let tx = parse_handle_message_transaction(&event_data)?; + let tx_nonce = tx.nonce; + + // Skip if already processed + if backend.has_l1_messaging_nonce(tx_nonce)? { + info!("Event already processed"); + return Ok(()); + } - let cancellation_timestamp = settlement_client.get_l1_to_l2_message_cancellations(event_hash).await?; - if cancellation_timestamp != Felt::ZERO { - info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); - handle_cancelled_message(backend, tx_nonce)?; - return Ok(()); - } + info!( + "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", + event_data.block_number, + to_hex_string(event_data.transaction_hash.clone().unwrap_or(vec![0]).as_slice()), + to_hex_string(event_data.from.as_slice()), + ); + + // Check message hash and cancellation + let event_hash = settlement_client.get_messaging_hash(&event_data)?; + info!("Checking for cancellation, event hash: {:?}", Felt::from_bytes_be_slice(event_hash.as_slice())); + + let cancellation_timestamp = settlement_client.get_l1_to_l2_message_cancellations(event_hash).await?; + if cancellation_timestamp != Felt::ZERO { + info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); + handle_cancelled_message(backend, tx_nonce)?; + return Ok(()); + } - // Process message - match process_message( - &backend, - &event_data, - &event_data.block_number, - &event_data.event_index, - &chain_id, - mempool.clone(), - ) - .await - { - Ok(Some(tx_hash)) => { - info!( - "Message from block: {:?} submitted, transaction hash: {:?}", - event_data.block_number, tx_hash - ); - - // Update last synced block if available - if let (Some(block_num), Some(evt_idx)) = (event_data.block_number, event_data.event_index) { - let block_sent = LastSyncedEventBlock::new(block_num, evt_idx); - backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; - } - } - Ok(None) => {} - Err(e) => { - error!( - "Unexpected error while processing Message from block: {:?}, error: {:?}", - event_data.block_number, e - ); - return Err(e); + // Process message + match process_message( + &backend, + &event_data, + &event_data.block_number, + &event_data.event_index, + &chain_id, + mempool.clone(), + ) + .await + { + Ok(Some(tx_hash)) => { + info!( + "Message from block: {:?} submitted, transaction hash: {:?}", + event_data.block_number, tx_hash + ); + + // Update last synced block if available + if let (Some(block_num), Some(evt_idx)) = (event_data.block_number, event_data.event_index) { + let block_sent = LastSyncedEventBlock::new(block_num, evt_idx); + backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; } } + Ok(None) => {} + Err(e) => { + error!( + "Unexpected error while processing Message from block: {:?}, error: {:?}", + event_data.block_number, e + ); + return Err(e); + } } - None => {} } } Ok(()) @@ -186,7 +185,7 @@ async fn process_message( ) -> anyhow::Result> { let transaction = parse_handle_message_transaction(event)?; let tx_nonce = transaction.nonce; - let fees = vec_to_u128_be(event.fee.clone().unwrap()); + let fees = vec_to_u128_be(event.fee.clone().unwrap_or(vec![0])); // Ensure that L1 message has not been executed match backend.has_l1_messaging_nonce(tx_nonce) { @@ -207,7 +206,7 @@ async fn process_message( // TODO: remove unwraps // Ques: shall it panic if no block number of event_index? - let block_sent = LastSyncedEventBlock::new(settlement_layer_block_number.unwrap(), event_index.unwrap()); + let block_sent = LastSyncedEventBlock::new(settlement_layer_block_number.unwrap(), event_index.unwrap_or(0)); backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; Ok(Some(res.transaction_hash)) @@ -222,3 +221,9 @@ fn vec_to_u128_be(bytes: Vec) -> Option { padded[16 - bytes.len()..].copy_from_slice(&bytes); Some(u128::from_be_bytes(padded.try_into().unwrap())) } + +fn to_hex_string(bytes: &[u8]) -> String { + let hex = hex::encode(bytes); + let trimmed = if hex.starts_with('0') { hex.trim_start_matches('0').to_string() } else { hex }; + format!("0x{}", trimmed) +} diff --git a/crates/client/settlement_client/src/messaging/tests.rs b/crates/client/settlement_client/src/messaging/tests.rs index 12a4336fe..c9cd06669 100644 --- a/crates/client/settlement_client/src/messaging/tests.rs +++ b/crates/client/settlement_client/src/messaging/tests.rs @@ -140,6 +140,9 @@ mod l2_messaging_test { #[rstest] #[traced_test] #[tokio::test] + // This test is redundant now as the event poller will not return the same + // event twice with same nonce that's why added ignore here. + #[ignore] async fn e2e_test_already_processed_event_starknet( #[future] setup_test_env_starknet: TestRunnerStarknet, ) -> anyhow::Result<()> { @@ -191,7 +194,7 @@ mod l2_messaging_test { // Firing the event second time fire_messaging_event(&account, deployed_contract_address).await?; - tokio::time::sleep(Duration::from_secs(10)).await; + tokio::time::sleep(Duration::from_secs(15)).await; // Assert that the event processed was in last block only not in the latest block. assert_eq!( last_block.block_number, @@ -245,7 +248,7 @@ mod l2_messaging_test { cancel_messaging_event(&account, deployed_contract_address).await?; // Firing cancelled event fire_messaging_event(&account, deployed_contract_address).await?; - tokio::time::sleep(Duration::from_secs(10)).await; + tokio::time::sleep(Duration::from_secs(15)).await; let last_block = db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); diff --git a/crates/client/settlement_client/src/starknet/event.rs b/crates/client/settlement_client/src/starknet/event.rs index 1ad4ea4a5..d84d10885 100644 --- a/crates/client/settlement_client/src/starknet/event.rs +++ b/crates/client/settlement_client/src/starknet/event.rs @@ -1,75 +1,30 @@ use crate::messaging::sync::CommonMessagingEventData; -use bigdecimal::ToPrimitive; -use futures::{Stream, TryFuture}; +use futures::Stream; use starknet_core::types::{BlockId, EmittedEvent, EventFilter}; use starknet_providers::jsonrpc::HttpTransport; use starknet_providers::{JsonRpcClient, Provider}; +use starknet_types_core::felt::Felt; use std::collections::HashSet; +use std::future::Future; use std::pin::Pin; use std::sync::Arc; use std::task::{Context, Poll}; +use std::time::Duration; +use tokio::time::sleep; -#[derive(Hash, Eq, PartialEq)] -struct EventKey { - block_number: u64, - transaction_hash: String, - event_index: u64, -} - -impl From<&EmittedEvent> for EventKey { - fn from(event: &EmittedEvent) -> Self { - Self { - block_number: event.block_number.unwrap_or(0), - transaction_hash: event.transaction_hash.to_string(), - event_index: event.data[4].to_u64().unwrap(), // nonce of the event - } - } -} +type FutureType = Pin, EventFilter)>> + Send>>; pub struct StarknetEventStream { provider: Arc>, filter: EventFilter, - processed_events: HashSet, + processed_events: HashSet, + future: Option, + polling_interval: Duration, } impl StarknetEventStream { - pub fn new(provider: Arc>, filter: EventFilter) -> Self { - Self { provider, filter, processed_events: HashSet::new() } - } - - fn is_duplicate(&self, event: &EmittedEvent) -> bool { - self.processed_events.contains(&EventKey::from(event)) - } - - async fn get_events(&self) -> anyhow::Result> { - let mut event_vec = Vec::new(); - let mut page_indicator = false; - let mut continuation_token: Option = None; - - while !page_indicator { - let events = self - .provider - .get_events( - EventFilter { - from_block: self.filter.from_block, - to_block: self.filter.to_block, - address: self.filter.address, - keys: self.filter.keys.clone(), - }, - continuation_token.clone(), - 1000, - ) - .await?; - - event_vec.extend(events.events); - if let Some(token) = events.continuation_token { - continuation_token = Some(token); - } else { - page_indicator = true; - } - } - - Ok(event_vec) + pub fn new(provider: Arc>, filter: EventFilter, polling_interval: Duration) -> Self { + Self { provider, filter, processed_events: HashSet::new(), future: None, polling_interval } } } @@ -77,44 +32,110 @@ impl Stream for StarknetEventStream { type Item = Option>; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - let future = async { - let events = self.get_events().await?; - let latest_block = self.provider.block_number().await?; - self.filter.from_block = Some(BlockId::Number(latest_block)); - self.filter.to_block = Some(BlockId::Number(latest_block)); - - for event in events { - if !self.is_duplicate(&event) { - let key = EventKey::from(&event); - self.processed_events.insert(key); - return Ok(Some(event)); + if self.future.is_none() { + let provider = self.provider.clone(); + let filter = self.filter.clone(); + let processed_events = self.processed_events.clone(); + let polling_interval = self.polling_interval; + + async fn fetch_events( + provider: Arc>, + mut filter: EventFilter, + processed_events: HashSet, + polling_interval: Duration, + ) -> anyhow::Result<(Option, EventFilter)> { + // Adding sleep to introduce delay + sleep(polling_interval).await; + + let mut event_vec = Vec::new(); + let mut page_indicator = false; + let mut continuation_token: Option = None; + + while !page_indicator { + let events = provider + .get_events( + EventFilter { + from_block: filter.from_block, + to_block: filter.to_block, + address: filter.address, + keys: filter.keys.clone(), + }, + continuation_token.clone(), + 1000, + ) + .await?; + + event_vec.extend(events.events); + if let Some(token) = events.continuation_token { + continuation_token = Some(token); + } else { + page_indicator = true; + } } + + for event in event_vec.clone() { + let event_nonce = event.data[4]; + if !processed_events.contains(&event_nonce) { + return Ok((Some(event), filter)); + } + } + + let latest_block = provider.block_number().await?; + filter.from_block = filter.to_block; + filter.to_block = Some(BlockId::Number(latest_block)); + + Ok((None, filter)) } - Ok(None) - }; - - match futures::ready!(Box::pin(future).as_mut().try_poll(cx)) { - Ok(Some(event)) => Poll::Ready(Some(Some(Ok(CommonMessagingEventData { - from: event.data[1].to_bytes_be().to_vec(), - to: event.data[2].to_bytes_be().to_vec(), - selector: event.data[3].to_bytes_be().to_vec(), - nonce: event.data[4].to_bytes_be().to_vec(), - payload: { - let mut payload_array = vec![]; - event.data.iter().skip(6).for_each(|data| { - payload_array.push(data.to_bytes_be().to_vec()); - }); - payload_array - }, - fee: None, - transaction_hash: None, - message_hash: Some(event.data[0].to_bytes_be().to_vec()), - block_number: None, - event_index: None, - })))), - Ok(None) => Poll::Ready(None), - Err(e) => Poll::Ready(Some(Some(Err(e)))), + let future = async move { + let (event, updated_filter) = + fetch_events(provider, filter, processed_events, polling_interval).await?; + Ok((event, updated_filter)) + }; + + self.future = Some(Box::pin(future)); + } + + // Poll the future + let fut = self.future.as_mut().unwrap(); + match fut.as_mut().poll(cx) { + Poll::Ready(result) => { + self.future = None; + match result { + Ok((Some(event), updated_filter)) => { + // Update the filter + self.filter = updated_filter; + // Insert the event nonce before returning + self.processed_events.insert(event.data[4]); + + Poll::Ready(Some(Some(Ok(CommonMessagingEventData { + from: event.data[1].to_bytes_be().to_vec(), + to: event.data[2].to_bytes_be().to_vec(), + selector: event.data[3].to_bytes_be().to_vec(), + nonce: event.data[4].to_bytes_be().to_vec(), + payload: { + let mut payload_array = vec![]; + event.data.iter().skip(6).for_each(|data| { + payload_array.push(data.to_bytes_be().to_vec()); + }); + payload_array + }, + fee: None, + transaction_hash: Some(event.transaction_hash.to_bytes_be().to_vec()), + message_hash: Some(event.data[0].to_bytes_be().to_vec()), + block_number: Some(event.block_number.expect("Unable to get block number from event.")), + event_index: None, + })))) + } + Ok((None, updated_filter)) => { + // Update the filter even when no events are found + self.filter = updated_filter; + Poll::Ready(Some(None)) + } + Err(e) => Poll::Ready(Some(Some(Err(e)))), + } + } + Poll::Pending => Poll::Pending, } } } diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index dbe744cae..0bb7e7d7a 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -223,11 +223,11 @@ impl ClientTrait for StarknetClient { ) -> anyhow::Result { let filter = EventFilter { from_block: Some(BlockId::Number(last_synced_event_block.block_number)), - to_block: None, + to_block: Some(BlockId::Number(self.get_latest_block_number().await?)), address: Some(self.l2_core_contract), keys: Some(vec![vec![get_selector_from_name("MessageSent")?]]), }; - Ok(StarknetEventStream::new(self.provider.clone(), filter)) + Ok(StarknetEventStream::new(self.provider.clone(), filter, Duration::from_secs(1))) } } diff --git a/crates/client/settlement_client/src/sync.rs b/crates/client/settlement_client/src/sync.rs index 4ee69c3eb..30009db25 100644 --- a/crates/client/settlement_client/src/sync.rs +++ b/crates/client/settlement_client/src/sync.rs @@ -11,7 +11,7 @@ use std::sync::Arc; use std::time::Duration; #[allow(clippy::too_many_arguments)] -pub async fn sync_worker( +pub async fn sync_worker( backend: Arc, settlement_client: Arc>>, chain_id: ChainId, From 26c9319eee7e3b8de2faa56c3a3fb56e90a669fb Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Tue, 14 Jan 2025 15:38:49 +0530 Subject: [PATCH 14/23] feat : updated streams and added tests for streams --- Cargo.lock | 22 +- crates/client/settlement_client/Cargo.toml | 4 +- crates/client/settlement_client/src/client.rs | 12 +- .../client/settlement_client/src/eth/event.rs | 205 +++++++++++++--- .../client/settlement_client/src/eth/mod.rs | 14 +- .../client/settlement_client/src/gas_price.rs | 2 +- .../settlement_client/src/messaging/mod.rs | 217 ++++++++++++++++- .../settlement_client/src/messaging/sync.rs | 229 ------------------ .../settlement_client/src/messaging/tests.rs | 26 +- .../settlement_client/src/starknet/event.rs | 184 +++++++++++++- .../settlement_client/src/starknet/mod.rs | 28 ++- .../settlement_client/src/state_update.rs | 2 +- crates/client/settlement_client/src/sync.rs | 2 +- crates/node/src/cli/chain_config_overrides.rs | 3 +- crates/node/src/service/l1.rs | 2 +- .../chain_config/src/chain_config.rs | 3 +- 16 files changed, 645 insertions(+), 310 deletions(-) delete mode 100644 crates/client/settlement_client/src/messaging/sync.rs diff --git a/Cargo.lock b/Cargo.lock index d00969da0..cb1bae3d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4658,6 +4658,19 @@ dependencies = [ "tower-service", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.31", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -5686,7 +5699,7 @@ dependencies = [ "http 1.1.0", "http-body-util", "hyper 1.5.0", - "hyper-tls", + "hyper-tls 0.6.0", "hyper-util", "mp-block", "mp-class", @@ -5826,6 +5839,7 @@ dependencies = [ "hex", "httpmock", "lazy_static", + "matchers", "mc-analytics", "mc-db", "mc-mempool", @@ -5841,6 +5855,7 @@ dependencies = [ "opentelemetry-stdout", "opentelemetry_sdk", "regex", + "reqwest 0.11.27", "rstest 0.18.2", "serde", "serde_json", @@ -7224,10 +7239,12 @@ dependencies = [ "http-body 0.4.6", "hyper 0.14.31", "hyper-rustls 0.24.2", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", "mime", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -7239,6 +7256,7 @@ dependencies = [ "sync_wrapper 0.1.2", "system-configuration 0.5.1", "tokio", + "tokio-native-tls", "tokio-rustls 0.24.1", "tower-service", "url", @@ -7267,7 +7285,7 @@ dependencies = [ "http-body-util", "hyper 1.5.0", "hyper-rustls 0.27.3", - "hyper-tls", + "hyper-tls 0.6.0", "hyper-util", "ipnet", "js-sys", diff --git a/crates/client/settlement_client/Cargo.toml b/crates/client/settlement_client/Cargo.toml index 3f933b645..9ef5d5bb0 100644 --- a/crates/client/settlement_client/Cargo.toml +++ b/crates/client/settlement_client/Cargo.toml @@ -62,6 +62,8 @@ url.workspace = true #Instrumentation async-trait = { workspace = true } +hex = "0.4.3" +matchers = "0.1.0" opentelemetry = { workspace = true, features = ["metrics", "logs"] } opentelemetry-appender-tracing = { workspace = true, default-features = false } opentelemetry-otlp = { workspace = true, features = [ @@ -72,11 +74,11 @@ opentelemetry-otlp = { workspace = true, features = [ opentelemetry-semantic-conventions = { workspace = true } opentelemetry-stdout = { workspace = true } opentelemetry_sdk = { workspace = true, features = ["rt-tokio", "logs"] } +reqwest = "0.11.27" tracing = { workspace = true } tracing-core = { workspace = true, default-features = false } tracing-opentelemetry = { workspace = true } tracing-subscriber = { workspace = true, features = ["env-filter"] } -hex = "0.4.3" [features] diff --git a/crates/client/settlement_client/src/client.rs b/crates/client/settlement_client/src/client.rs index 079bb586a..f9066f457 100644 --- a/crates/client/settlement_client/src/client.rs +++ b/crates/client/settlement_client/src/client.rs @@ -1,5 +1,5 @@ use crate::gas_price::L1BlockMetrics; -use crate::messaging::sync::CommonMessagingEventData; +use crate::messaging::CommonMessagingEventData; use crate::state_update::StateUpdate; use async_trait::async_trait; use futures::Stream; @@ -9,11 +9,19 @@ use mp_utils::service::ServiceContext; use starknet_types_core::felt::Felt; use std::sync::Arc; +pub enum ClientType { + ETH, + STARKNET, +} + #[async_trait] pub trait ClientTrait: Send + Sync { // Configuration type used for initialization type Config; + // Get client type + fn get_client_type(&self) -> ClientType; + // Basic getter functions fn get_l1_block_metrics(&self) -> &L1BlockMetrics; @@ -34,7 +42,7 @@ pub trait ClientTrait: Send + Sync { // Get the last state root // - change this to Felt in implementation // - write tests for conversion to Felt from - async fn get_last_state_root(&self) -> anyhow::Result; + async fn get_last_verified_state_root(&self) -> anyhow::Result; // Get the last verified block hash async fn get_last_verified_block_hash(&self) -> anyhow::Result; diff --git a/crates/client/settlement_client/src/eth/event.rs b/crates/client/settlement_client/src/eth/event.rs index 4d0fabaf8..b60479ba9 100644 --- a/crates/client/settlement_client/src/eth/event.rs +++ b/crates/client/settlement_client/src/eth/event.rs @@ -1,21 +1,24 @@ use crate::eth::StarknetCoreContract::LogMessageToL2; -use crate::messaging::sync::CommonMessagingEventData; +use crate::messaging::CommonMessagingEventData; use alloy::contract::EventPoller; use alloy::rpc::types::Log; -use alloy::sol_types::SolEvent; use alloy::transports::http::{Client, Http}; use anyhow::Error; use futures::Stream; use std::pin::Pin; use std::task::{Context, Poll}; +type StreamItem = Result<(LogMessageToL2, Log), alloy::sol_types::Error>; +type StreamType = Pin + Send + 'static>>; + pub struct EthereumEventStream { - stream: Pin> + Send + 'static>>, + stream: StreamType, } impl EthereumEventStream { pub fn new(watcher: EventPoller, LogMessageToL2>) -> Self { - Self { stream: Box::pin(watcher.poller.into_stream()) } + let stream = watcher.into_stream(); + Self { stream: Box::pin(stream) } } } @@ -24,35 +27,173 @@ impl Stream for EthereumEventStream { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.stream.as_mut().poll_next(cx) { - Poll::Ready(Some(logs)) => { - if let Some(log) = logs.into_iter().next() { - match LogMessageToL2::decode_log(log.as_ref(), false) { - Ok(event) => Poll::Ready(Some(Some(Ok(CommonMessagingEventData { - from: event.data.fromAddress.as_slice().into(), - to: event.data.toAddress.to_be_bytes_vec(), - selector: event.data.selector.to_be_bytes_vec(), - nonce: event.nonce.to_be_bytes_vec(), - payload: { - let mut payload_vec = vec![]; - event.payload.iter().for_each(|ele| payload_vec.push(ele.to_be_bytes_vec())); - payload_vec - }, - fee: Some(event.data.fee.to_be_bytes_vec()), - transaction_hash: Some( - log.transaction_hash.expect("Unable to get transaction hash from event log.").to_vec(), - ), - message_hash: None, - block_number: Some(log.block_number.expect("Unable to get block number from event log.")), - event_index: Some(log.log_index.expect("Unable to get log index from event log.")), - })))), - Err(e) => Poll::Ready(Some(Some(Err(Error::from(e))))), - } - } else { - Poll::Ready(None) - } - } - Poll::Ready(None) => Poll::Ready(None), + Poll::Ready(Some(result)) => match result { + Ok((event, log)) => Poll::Ready(Some(Some(Ok(CommonMessagingEventData { + from: event.fromAddress.as_slice().into(), + to: event.toAddress.to_be_bytes_vec(), + selector: event.selector.to_be_bytes_vec(), + nonce: event.nonce.to_be_bytes_vec(), + payload: { + let mut payload_vec = vec![]; + event.payload.iter().for_each(|ele| payload_vec.push(ele.to_be_bytes_vec())); + payload_vec + }, + fee: Some(event.fee.to_be_bytes_vec()), + transaction_hash: log.transaction_hash.expect("Missing transaction hash").to_vec(), + message_hash: None, + block_number: log.block_number.expect("Missing block number"), + event_index: Some(log.log_index.expect("Missing log index")), + })))), + Err(e) => Poll::Ready(Some(Some(Err(Error::from(e))))), + }, + Poll::Ready(None) => Poll::Ready(Some(None)), Poll::Pending => Poll::Pending, } } } + +#[cfg(test)] +mod eth_event_stream_tests { + use super::*; + use alloy::primitives::{Address, LogData, B256, U256}; + use futures::stream::iter; + use futures::StreamExt; + use rstest::rstest; + use std::str::FromStr; + + // Helper function to create mock event + fn create_mock_event() -> LogMessageToL2 { + LogMessageToL2 { + fromAddress: Address::from_str("0x1234567890123456789012345678901234567890").unwrap(), + toAddress: U256::from(1u64), + selector: U256::from(2u64), + fee: U256::from(1000u64), + nonce: U256::from(1u64), + payload: vec![U256::from(1u64), U256::from(2u64)], + } + } + + // Helper function to create mock log + fn create_mock_log() -> Log { + Log { + inner: alloy::primitives::Log { + address: Address::from_str("0x1234567890123456789012345678901234567890").unwrap(), + data: LogData::default(), + }, + block_hash: Some( + B256::from_str("0x0000000000000000000000000000000000000000000000000000000000000002").unwrap(), + ), + block_number: Some(100), + block_timestamp: Some(1643234567), + transaction_hash: Some( + B256::from_str("0x0000000000000000000000000000000000000000000000000000000000000003").unwrap(), + ), + transaction_index: Some(0), + log_index: Some(0), + removed: false, + } + } + + #[tokio::test] + #[rstest] + async fn test_successful_event_stream() { + // Create a sequence of mock events + let mock_events = + vec![Ok((create_mock_event(), create_mock_log())), Ok((create_mock_event(), create_mock_log()))]; + + // Create a mock stream from the events + let mock_stream = iter(mock_events); + + // Create EthereumEventStream with mock stream + let mut ethereum_stream = EthereumEventStream { stream: Box::pin(mock_stream) }; + + let mut events = Vec::new(); + + while let Some(Some(event)) = ethereum_stream.next().await { + events.push(event); + } + + assert_eq!(events.len(), 2); + + // Verify first event + match &events[0] { + Ok(event_data) => { + assert_eq!(event_data.block_number, 100); + assert_eq!(event_data.event_index, Some(0u64)); + // Add more assertions as needed + } + _ => panic!("Expected successful event"), + } + } + + #[tokio::test] + #[rstest] + async fn test_error_handling() { + // Create a stream with an error + let mock_events = vec![Err(alloy::sol_types::Error::InvalidLog { name: "", log: Box::default() })]; + + let mock_stream = iter(mock_events); + + let mut ethereum_stream = EthereumEventStream { stream: Box::pin(mock_stream) }; + + let event = ethereum_stream.next().await.unwrap(); + + match event { + Some(Err(_)) => { /* Test passed */ } + _ => panic!("Expected error event"), + } + } + + #[tokio::test] + #[rstest] + async fn test_empty_stream() { + // Create an empty stream + let mock_events: Vec> = vec![]; + let mock_stream = iter(mock_events); + + let mut ethereum_stream = EthereumEventStream { stream: Box::pin(mock_stream) }; + + let event = ethereum_stream.next().await; + + assert!(event.unwrap().is_none(), "Expected None for empty stream"); + } + + #[tokio::test] + #[rstest] + async fn test_mixed_events() { + // Create a stream with mixed success and error events + let mock_events = vec![ + Ok((create_mock_event(), create_mock_log())), + Err(alloy::sol_types::Error::InvalidLog { name: "", log: Box::default() }), + Ok((create_mock_event(), create_mock_log())), + ]; + + let mock_stream = iter(mock_events); + + let mut ethereum_stream = EthereumEventStream { stream: Box::pin(mock_stream) }; + + let mut events = Vec::new(); + + while let Some(Some(event)) = ethereum_stream.next().await { + events.push(event); + } + + assert_eq!(events.len(), 3); + + // Verify event sequence + match &events[0] { + Ok(_) => {} + _ => panic!("First event should be successful"), + } + + match &events[1] { + Err(_) => {} + _ => panic!("Second event should be an error"), + } + + match &events[2] { + Ok(_) => {} + _ => panic!("Third event should be successful"), + } + } +} diff --git a/crates/client/settlement_client/src/eth/mod.rs b/crates/client/settlement_client/src/eth/mod.rs index e15c59730..4e09806a9 100644 --- a/crates/client/settlement_client/src/eth/mod.rs +++ b/crates/client/settlement_client/src/eth/mod.rs @@ -1,10 +1,10 @@ pub mod event; -use crate::client::ClientTrait; +use crate::client::{ClientTrait, ClientType}; use crate::eth::event::EthereumEventStream; use crate::eth::StarknetCoreContract::{LogMessageToL2, StarknetCoreContractInstance}; use crate::gas_price::L1BlockMetrics; -use crate::messaging::sync::CommonMessagingEventData; +use crate::messaging::CommonMessagingEventData; use crate::state_update::{update_l1, StateUpdate}; use crate::utils::{convert_log_state_update, u256_to_felt}; use alloy::eips::BlockNumberOrTag; @@ -64,6 +64,10 @@ impl Clone for EthereumClient { impl ClientTrait for EthereumClient { type Config = EthereumClientConfig; + fn get_client_type(&self) -> ClientType { + ClientType::ETH + } + fn get_l1_block_metrics(&self) -> &L1BlockMetrics { &self.l1_block_metrics } @@ -123,7 +127,7 @@ impl ClientTrait for EthereumClient { } /// Get the last Starknet state root verified on L1 - async fn get_last_state_root(&self) -> anyhow::Result { + async fn get_last_verified_state_root(&self) -> anyhow::Result { let state_root = self.l1_core_contract.stateRoot().call().await?; u256_to_felt(state_root._0) } @@ -137,7 +141,7 @@ impl ClientTrait for EthereumClient { async fn get_initial_state(&self) -> anyhow::Result { let block_number = self.get_last_verified_block_number().await?; let block_hash = self.get_last_verified_block_hash().await?; - let global_root = self.get_last_state_root().await?; + let global_root = self.get_last_verified_state_root().await?; Ok(StateUpdate { global_root, block_number, block_hash }) } @@ -380,7 +384,7 @@ pub mod eth_client_getter_test { async fn get_last_state_root_works() { let anvil = get_shared_anvil(); let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str())); - let state_root = eth_client.get_last_state_root().await.expect("issue while getting the state root"); + let state_root = eth_client.get_last_verified_state_root().await.expect("issue while getting the state root"); let expected = u256_to_felt(U256::from_str_radix(L2_STATE_ROOT, 10).unwrap()).unwrap(); assert_eq!(state_root, expected, "latest block state root not matching"); } diff --git a/crates/client/settlement_client/src/gas_price.rs b/crates/client/settlement_client/src/gas_price.rs index 9203cce34..f6986799d 100644 --- a/crates/client/settlement_client/src/gas_price.rs +++ b/crates/client/settlement_client/src/gas_price.rs @@ -5,7 +5,7 @@ use mc_mempool::{GasPriceProvider, L1DataProvider}; use std::sync::Arc; use std::time::{Duration, UNIX_EPOCH}; -use crate::messaging::sync::CommonMessagingEventData; +use crate::messaging::CommonMessagingEventData; use futures::Stream; use mc_analytics::register_gauge_metric_instrument; use mp_utils::service::ServiceContext; diff --git a/crates/client/settlement_client/src/messaging/mod.rs b/crates/client/settlement_client/src/messaging/mod.rs index ca5096656..772deb573 100644 --- a/crates/client/settlement_client/src/messaging/mod.rs +++ b/crates/client/settlement_client/src/messaging/mod.rs @@ -1,4 +1,217 @@ -pub mod sync; - #[cfg(test)] mod tests; + +use crate::client::{ClientTrait, ClientType}; +use alloy::primitives::B256; +use futures::{Stream, StreamExt}; +use mc_db::l1_db::LastSyncedEventBlock; +use mc_db::MadaraBackend; +use mc_mempool::{Mempool, MempoolProvider}; +use mp_utils::service::ServiceContext; +use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; +use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; +use starknet_types_core::felt::Felt; +use std::sync::Arc; +use tracing::{error, info}; + +#[derive(Clone, Debug)] +pub struct CommonMessagingEventData { + pub from: Vec, + pub to: Vec, + pub selector: Vec, + pub nonce: Vec, + pub payload: Vec>, + pub fee: Option>, + pub transaction_hash: Vec, + pub message_hash: Option>, + pub block_number: u64, + pub event_index: Option, +} + +pub async fn sync( + settlement_client: Arc>>, + backend: Arc, + chain_id: ChainId, + mempool: Arc, + mut ctx: ServiceContext, +) -> anyhow::Result<()> +where + S: Stream>> + Send + 'static, +{ + info!("⟠ Starting L1 Messages Syncing..."); + + let last_synced_event_block = match backend.messaging_last_synced_l1_block_with_event() { + Ok(Some(blk)) => blk, + Ok(None) => { + unreachable!("Should never be None") + } + Err(e) => { + error!("⟠ Madara Messaging DB unavailable: {:?}", e); + return Err(e.into()); + } + }; + + let stream = settlement_client.get_event_stream(last_synced_event_block).await?; + let mut event_stream = Box::pin(stream); + + while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { + if let Some(event) = event_result { + let event_data = event?; + let tx = parse_handle_message_transaction(&event_data)?; + let tx_nonce = tx.nonce; + + // Skip if already processed + if backend.has_l1_messaging_nonce(tx_nonce)? { + info!("Event already processed"); + return Ok(()); + } + + info!( + "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", + event_data.block_number, + format!("0x{}", hex::encode(event_data.transaction_hash.clone().as_slice())), + format!("0x{}", hex::encode(event_data.from.as_slice())), + ); + + // Check message hash and cancellation + let event_hash = settlement_client.get_messaging_hash(&event_data)?; + let converted_event_hash = match settlement_client.get_client_type() { + ClientType::ETH => B256::from_slice(event_hash.as_slice()).to_string(), + ClientType::STARKNET => Felt::from_bytes_be_slice(event_hash.as_slice()).to_hex_string(), + }; + info!("Checking for cancellation, event hash: {:?}", converted_event_hash); + + let cancellation_timestamp = settlement_client.get_l1_to_l2_message_cancellations(event_hash).await?; + if cancellation_timestamp != Felt::ZERO { + info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); + handle_cancelled_message(backend, tx_nonce)?; + return Ok(()); + } + + // Process message + match process_message(&backend, &event_data, &chain_id, mempool.clone()).await { + Ok(Some(tx_hash)) => { + info!( + "Message from block: {:?} submitted, transaction hash: {:?}", + event_data.block_number, tx_hash + ); + + let block_sent = + LastSyncedEventBlock::new(event_data.block_number, event_data.event_index.unwrap_or(0)); + backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; + } + Ok(None) => {} + Err(e) => { + error!( + "Unexpected error while processing Message from block: {:?}, error: {:?}", + event_data.block_number, e + ); + return Err(e); + } + } + } + } + Ok(()) +} + +fn handle_cancelled_message(backend: Arc, nonce: Nonce) -> anyhow::Result<()> { + match backend.has_l1_messaging_nonce(nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(nonce)?; + } + Ok(true) => {} + Err(e) => { + error!("Unexpected DB error: {:?}", e); + return Err(e.into()); + } + } + Ok(()) +} + +pub fn parse_handle_message_transaction(event: &CommonMessagingEventData) -> anyhow::Result { + // L1 from address. + let from_address = Felt::from_bytes_be_slice(event.from.as_slice()); + + // L2 contract to call. + let contract_address = Felt::from_bytes_be_slice(event.to.as_slice()); + + // Function of the contract to call. + let entry_point_selector = Felt::from_bytes_be_slice(event.selector.as_slice()); + + // L1 message nonce. + let nonce = Felt::from_bytes_be_slice(event.nonce.as_slice()); + + let event_payload: Vec = + event.payload.clone().into_iter().map(|ele| Felt::from_bytes_be_slice(ele.as_slice())).collect(); + + let calldata: Calldata = { + let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); + calldata.push(from_address); + calldata.extend(event_payload); + Calldata(Arc::new(calldata)) + }; + + Ok(L1HandlerTransaction { + nonce: Nonce(nonce), + contract_address: ContractAddress(contract_address.try_into()?), + entry_point_selector: EntryPointSelector(entry_point_selector), + calldata, + version: TransactionVersion(Felt::ZERO), + }) +} + +async fn process_message( + backend: &MadaraBackend, + event: &CommonMessagingEventData, + _chain_id: &ChainId, + mempool: Arc, +) -> anyhow::Result> { + let transaction = parse_handle_message_transaction(event)?; + let tx_nonce = transaction.nonce; + let fees = vec_to_u128_be(event.fee.clone().unwrap_or(vec![0])); + + // Ensure that L1 message has not been executed + match backend.has_l1_messaging_nonce(tx_nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(tx_nonce)?; + } + Ok(true) => { + tracing::debug!("⟠ Event already processed: {:?}", transaction); + return Ok(None); + } + Err(e) => { + error!("⟠ Unexpected DB error: {:?}", e); + return Err(e.into()); + } + }; + + let res = mempool.accept_l1_handler_tx(transaction.into(), fees.unwrap_or(0))?; + + Ok(Some(res.transaction_hash)) +} + +fn vec_to_u128_be(bytes: Vec) -> Option { + if bytes.len() > 16 { + return None; + } + // Pad with zeros if less than 16 bytes + let mut padded = vec![0u8; 16]; + padded[16 - bytes.len()..].copy_from_slice(&bytes); + Some(u128::from_be_bytes(padded.try_into().unwrap())) +} + +#[cfg(test)] +mod sync_utils_tests { + use crate::messaging::vec_to_u128_be; + use rstest::rstest; + + #[rstest] + #[case(vec![1, 2, 3, 4], Some(0x00000000000000000000000001020304))] + #[case(vec![], Some(0x00000000000000000000000000000000))] + #[case(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], Some(0x0102030405060708090a0b0c0d0e0f10))] + #[case(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], None)] + fn vec_to_u128(#[case] bytes: Vec, #[case] expected: Option) { + let result = vec_to_u128_be(bytes); + assert_eq!(result, expected); + } +} diff --git a/crates/client/settlement_client/src/messaging/sync.rs b/crates/client/settlement_client/src/messaging/sync.rs deleted file mode 100644 index 531d79318..000000000 --- a/crates/client/settlement_client/src/messaging/sync.rs +++ /dev/null @@ -1,229 +0,0 @@ -use crate::client::ClientTrait; -use futures::{Stream, StreamExt}; -use mc_db::l1_db::LastSyncedEventBlock; -use mc_db::MadaraBackend; -use mc_mempool::{Mempool, MempoolProvider}; -use mp_utils::service::ServiceContext; -use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; -use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; -use starknet_types_core::felt::Felt; -use std::sync::Arc; -use tracing::{error, info}; - -// L2 (Starknet) <-> L3 messaging format -// GitHub Ref : https://github.com/cartridge-gg/piltover/blob/saya/src/messaging/component.cairo#L85 -#[derive(Clone)] -pub struct MessageSent { - pub message_hash: Felt, - pub from: Felt, - pub to: Felt, - pub selector: Felt, - pub nonce: Felt, - pub payload: Vec, -} - -#[derive(Clone)] -pub struct CommonMessagingEventData { - pub from: Vec, - pub to: Vec, - pub selector: Vec, - pub nonce: Vec, - pub payload: Vec>, - pub fee: Option>, - pub transaction_hash: Option>, - pub message_hash: Option>, - pub block_number: Option, - pub event_index: Option, -} - -pub async fn sync( - settlement_client: Arc>>, - backend: Arc, - chain_id: ChainId, - mempool: Arc, - mut ctx: ServiceContext, -) -> anyhow::Result<()> -where - S: Stream>> + Send + 'static, -{ - info!("⟠ Starting L1 Messages Syncing..."); - - let last_synced_event_block = match backend.messaging_last_synced_l1_block_with_event() { - Ok(Some(blk)) => blk, - Ok(None) => { - unreachable!("Should never be None") - } - Err(e) => { - error!("⟠ Madara Messaging DB unavailable: {:?}", e); - return Err(e.into()); - } - }; - - let stream = settlement_client.get_event_stream(last_synced_event_block).await?; - let mut event_stream = Box::pin(stream); - - while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { - if let Some(event) = event_result { - let event_data = event?; - let tx = parse_handle_message_transaction(&event_data)?; - let tx_nonce = tx.nonce; - - // Skip if already processed - if backend.has_l1_messaging_nonce(tx_nonce)? { - info!("Event already processed"); - return Ok(()); - } - - info!( - "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", - event_data.block_number, - to_hex_string(event_data.transaction_hash.clone().unwrap_or(vec![0]).as_slice()), - to_hex_string(event_data.from.as_slice()), - ); - - // Check message hash and cancellation - let event_hash = settlement_client.get_messaging_hash(&event_data)?; - info!("Checking for cancellation, event hash: {:?}", Felt::from_bytes_be_slice(event_hash.as_slice())); - - let cancellation_timestamp = settlement_client.get_l1_to_l2_message_cancellations(event_hash).await?; - if cancellation_timestamp != Felt::ZERO { - info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); - handle_cancelled_message(backend, tx_nonce)?; - return Ok(()); - } - - // Process message - match process_message( - &backend, - &event_data, - &event_data.block_number, - &event_data.event_index, - &chain_id, - mempool.clone(), - ) - .await - { - Ok(Some(tx_hash)) => { - info!( - "Message from block: {:?} submitted, transaction hash: {:?}", - event_data.block_number, tx_hash - ); - - // Update last synced block if available - if let (Some(block_num), Some(evt_idx)) = (event_data.block_number, event_data.event_index) { - let block_sent = LastSyncedEventBlock::new(block_num, evt_idx); - backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; - } - } - Ok(None) => {} - Err(e) => { - error!( - "Unexpected error while processing Message from block: {:?}, error: {:?}", - event_data.block_number, e - ); - return Err(e); - } - } - } - } - Ok(()) -} - -fn handle_cancelled_message(backend: Arc, nonce: Nonce) -> anyhow::Result<()> { - match backend.has_l1_messaging_nonce(nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(nonce)?; - } - Ok(true) => {} - Err(e) => { - error!("Unexpected DB error: {:?}", e); - return Err(e.into()); - } - } - Ok(()) -} - -pub fn parse_handle_message_transaction(event: &CommonMessagingEventData) -> anyhow::Result { - // L1 from address. - let from_address = Felt::from_bytes_be_slice(event.from.as_slice()); - - // L2 contract to call. - let contract_address = Felt::from_bytes_be_slice(event.to.as_slice()); - - // Function of the contract to call. - let entry_point_selector = Felt::from_bytes_be_slice(event.selector.as_slice()); - - // L1 message nonce. - let nonce = Felt::from_bytes_be_slice(event.nonce.as_slice()); - - let event_payload: Vec = - event.payload.clone().into_iter().map(|ele| Felt::from_bytes_be_slice(ele.as_slice())).collect(); - - let calldata: Calldata = { - let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); - calldata.push(from_address); - calldata.extend(event_payload); - Calldata(Arc::new(calldata)) - }; - - Ok(L1HandlerTransaction { - nonce: Nonce(nonce), - contract_address: ContractAddress(contract_address.try_into()?), - entry_point_selector: EntryPointSelector(entry_point_selector), - calldata, - version: TransactionVersion(Felt::ZERO), - }) -} - -async fn process_message( - backend: &MadaraBackend, - event: &CommonMessagingEventData, - settlement_layer_block_number: &Option, - event_index: &Option, - _chain_id: &ChainId, - mempool: Arc, -) -> anyhow::Result> { - let transaction = parse_handle_message_transaction(event)?; - let tx_nonce = transaction.nonce; - let fees = vec_to_u128_be(event.fee.clone().unwrap_or(vec![0])); - - // Ensure that L1 message has not been executed - match backend.has_l1_messaging_nonce(tx_nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(tx_nonce)?; - } - Ok(true) => { - tracing::debug!("⟠ Event already processed: {:?}", transaction); - return Ok(None); - } - Err(e) => { - error!("⟠ Unexpected DB error: {:?}", e); - return Err(e.into()); - } - }; - - let res = mempool.accept_l1_handler_tx(transaction.into(), fees.unwrap_or(0))?; - - // TODO: remove unwraps - // Ques: shall it panic if no block number of event_index? - let block_sent = LastSyncedEventBlock::new(settlement_layer_block_number.unwrap(), event_index.unwrap_or(0)); - backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; - - Ok(Some(res.transaction_hash)) -} - -fn vec_to_u128_be(bytes: Vec) -> Option { - if bytes.len() > 16 { - return None; - } - // Pad with zeros if less than 16 bytes - let mut padded = vec![0u8; 16]; - padded[16 - bytes.len()..].copy_from_slice(&bytes); - Some(u128::from_be_bytes(padded.try_into().unwrap())) -} - -fn to_hex_string(bytes: &[u8]) -> String { - let hex = hex::encode(bytes); - let trimmed = if hex.starts_with('0') { hex.trim_start_matches('0').to_string() } else { hex }; - format!("0x{}", trimmed) -} diff --git a/crates/client/settlement_client/src/messaging/tests.rs b/crates/client/settlement_client/src/messaging/tests.rs index c9cd06669..01935144e 100644 --- a/crates/client/settlement_client/src/messaging/tests.rs +++ b/crates/client/settlement_client/src/messaging/tests.rs @@ -2,7 +2,7 @@ mod l2_messaging_test { use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; - use crate::messaging::sync::sync; + use crate::messaging::sync; use crate::starknet::utils::{ cancel_messaging_event, fire_messaging_event, prepare_starknet_client_messaging_test, MadaraProcess, StarknetAccount, MADARA_PORT, @@ -120,10 +120,10 @@ mod l2_messaging_test { // Log asserts // =========== - assert!(logs_contain("fromAddress: \"0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); + assert!(logs_contain("fromAddress: \"0x07484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 // expecting the same in logs - assert!(logs_contain("event hash: 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0")); + assert!(logs_contain("event hash: \"0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0\"")); // Assert that the event is well stored in db let last_block = @@ -180,10 +180,10 @@ mod l2_messaging_test { // Log asserts // =========== - assert!(logs_contain("fromAddress: \"0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); + assert!(logs_contain("fromAddress: \"0x07484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 // expecting the same in logs - assert!(logs_contain("event hash: 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0")); + assert!(logs_contain("event hash: \"0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0\"")); // Assert that the event is well stored in db let last_block = @@ -273,7 +273,7 @@ mod l1_messaging_tests { use crate::client::ClientTrait; use crate::eth::{EthereumClient, StarknetCoreContract}; use crate::gas_price::L1BlockMetrics; - use crate::messaging::sync::{sync, CommonMessagingEventData}; + use crate::messaging::{sync, CommonMessagingEventData}; use alloy::{ hex::FromHex, node_bindings::{Anvil, AnvilInstance}, @@ -472,13 +472,11 @@ mod l1_messaging_tests { // Assert that event was caught by the worker with correct data // TODO: Maybe add some more assert - assert!(logs_contain("fromAddress: 0xae0ee0a63a2ce6baeeffe56e7714fb4efe48d419")); + assert!(logs_contain("fromAddress: \"0xae0ee0a63a2ce6baeeffe56e7714fb4efe48d419\"")); // Assert the tx hash computed by the worker is correct - assert!(logs_contain( - format!("event hash : {:?}", contract.getL1ToL2MsgHash().call().await.expect("failed to get hash")._0) - .as_str() - )); + let event_hash = contract.getL1ToL2MsgHash().call().await.expect("failed to get hash")._0.to_string(); + assert!(logs_contain(&format!("event hash: {:?}", event_hash))); // TODO : Assert that the tx has been included in the mempool @@ -592,7 +590,7 @@ mod l1_messaging_tests { let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); // cancelled message nonce should be inserted to avoid reprocessing assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); - assert!(logs_contain("L1 Message was cancelled in block at timestamp : 0x66b4f105")); + assert!(logs_contain("Message was cancelled in block at timestamp: 0x66b4f105")); worker_handle.abort(); } @@ -632,9 +630,9 @@ mod l1_messaging_tests { ], nonce: U256::from(775628).to_be_bytes_vec(), fee: Some(U256::ZERO.to_be_bytes_vec()), - transaction_hash: None, + transaction_hash: vec![0], message_hash: None, - block_number: None, + block_number: 0, event_index: None, }) .expect("Failed to compute l1 to l2 msg hash"); diff --git a/crates/client/settlement_client/src/starknet/event.rs b/crates/client/settlement_client/src/starknet/event.rs index d84d10885..5f33005b8 100644 --- a/crates/client/settlement_client/src/starknet/event.rs +++ b/crates/client/settlement_client/src/starknet/event.rs @@ -1,4 +1,4 @@ -use crate::messaging::sync::CommonMessagingEventData; +use crate::messaging::CommonMessagingEventData; use futures::Stream; use starknet_core::types::{BlockId, EmittedEvent, EventFilter}; use starknet_providers::jsonrpc::HttpTransport; @@ -73,6 +73,8 @@ impl Stream for StarknetEventStream { } } + let latest_block = provider.block_number().await?; + for event in event_vec.clone() { let event_nonce = event.data[4]; if !processed_events.contains(&event_nonce) { @@ -80,7 +82,6 @@ impl Stream for StarknetEventStream { } } - let latest_block = provider.block_number().await?; filter.from_block = filter.to_block; filter.to_block = Some(BlockId::Number(latest_block)); @@ -121,9 +122,9 @@ impl Stream for StarknetEventStream { payload_array }, fee: None, - transaction_hash: Some(event.transaction_hash.to_bytes_be().to_vec()), + transaction_hash: event.transaction_hash.to_bytes_be().to_vec(), message_hash: Some(event.data[0].to_bytes_be().to_vec()), - block_number: Some(event.block_number.expect("Unable to get block number from event.")), + block_number: event.block_number.expect("Unable to get block number from event."), event_index: None, })))) } @@ -139,3 +140,178 @@ impl Stream for StarknetEventStream { } } } + +#[cfg(test)] +mod starknet_event_stream_tests { + use super::*; + use futures::StreamExt; + use httpmock::prelude::*; + use httpmock::Mock; + use rstest::rstest; + use serde_json::json; + use std::str::FromStr; + use url::Url; + + struct MockStarknetServer { + server: MockServer, + } + + impl MockStarknetServer { + fn new() -> Self { + Self { server: MockServer::start() } + } + + fn url(&self) -> String { + self.server.base_url() + } + + fn mock_get_events(&self, events: Vec, continuation_token: Option<&str>) -> Mock { + self.server.mock(|when, then| { + when.method(POST).path("/").header("Content-Type", "application/json").matches(|req| { + let body = req.body.clone().unwrap(); + let body_str = std::str::from_utf8(body.as_slice()).unwrap_or_default(); + body_str.contains("starknet_getEvents") + }); + + then.status(200).json_body(json!({ + "jsonrpc": "2.0", + "id": 1, + "result": { + "events": events, + "continuation_token": continuation_token + } + })); + }) + } + + fn mock_block_number(&self, block_number: u64) -> Mock { + self.server.mock(|when, then| { + when.method(POST).path("/").matches(|req| { + let body = req.body.clone().unwrap(); + let body_str = std::str::from_utf8(body.as_slice()).unwrap_or_default(); + body_str.contains("starknet_blockNumber") + }); + + then.status(200).json_body(json!({ + "jsonrpc": "2.0", + "id": 1, + "result": block_number + })); + }) + } + + fn mock_error_response(&self, error_code: i64, error_message: &str) -> Mock { + self.server.mock(|when, then| { + when.method(POST).path("/"); + + then.status(200).json_body(json!({ + "jsonrpc": "2.0", + "id": 1, + "error": { + "code": error_code, + "message": error_message + } + })); + }) + } + } + + fn create_test_event(nonce: u64, block_number: u64) -> EmittedEvent { + EmittedEvent { + from_address: Default::default(), + transaction_hash: Felt::from_hex("0x1234").unwrap(), + block_number: Some(block_number), + block_hash: Some(Felt::from_hex("0x5678").unwrap()), + data: vec![ + Felt::from_hex("0x0001").unwrap(), // message_hash + Felt::from_hex("0x1111").unwrap(), // from + Felt::from_hex("0x2222").unwrap(), // to + Felt::from_hex("0x3333").unwrap(), // selector + Felt::from_hex(&format!("0x{:x}", nonce)).unwrap(), // nonce + Felt::from_hex("0x5555").unwrap(), // len + Felt::from_hex("0x6666").unwrap(), // payload[0] + Felt::from_hex("0x7777").unwrap(), // payload[1] + ], + keys: vec![], + } + } + + fn setup_stream(mock_server: &MockStarknetServer) -> StarknetEventStream { + let provider = JsonRpcClient::new(HttpTransport::new(Url::from_str(&mock_server.url()).unwrap())); + + StarknetEventStream::new( + Arc::new(provider), + EventFilter { + from_block: Some(BlockId::Number(0)), + to_block: Some(BlockId::Number(100)), + address: Some(Felt::from_hex("0x1").unwrap()), + keys: Some(vec![]), + }, + Duration::from_secs(1), + ) + } + + #[tokio::test] + #[rstest] + async fn test_single_event() { + let mock_server = MockStarknetServer::new(); + + // Setup mocks + let test_event = create_test_event(1, 100); + let events_mock = mock_server.mock_get_events(vec![test_event], None); + let block_mock = mock_server.mock_block_number(101); + + let mut stream = Box::pin(setup_stream(&mock_server)); + + if let Some(Some(Ok(event_data))) = stream.next().await { + assert_eq!(event_data.block_number, 100); + assert!(event_data.message_hash.is_some()); + assert_eq!(event_data.payload.len(), 2); + } else { + panic!("Expected successful event"); + } + + // Verify mocks were called + events_mock.assert(); + events_mock.assert(); + block_mock.assert(); + } + + #[tokio::test] + #[rstest] + async fn test_error_handling() { + let mock_server = MockStarknetServer::new(); + + let error_mock = mock_server.mock_error_response(-32000, "Internal error"); + + let mut stream = Box::pin(setup_stream(&mock_server)); + + match stream.next().await { + Some(Some(Err(e))) => { + assert!(e.to_string().contains("Internal error")); + } + _ => panic!("Expected error"), + } + + error_mock.assert(); + } + + #[tokio::test] + #[rstest] + async fn test_empty_events() { + let mock_server = MockStarknetServer::new(); + + let events_mock = mock_server.mock_get_events(vec![], None); + let block_mock = mock_server.mock_block_number(100); + + let mut stream = Box::pin(setup_stream(&mock_server)); + + match stream.next().await { + Some(None) => { /* Expected */ } + _ => panic!("Expected None for empty events"), + } + + events_mock.assert(); + block_mock.assert(); + } +} diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/client/settlement_client/src/starknet/mod.rs index 0bb7e7d7a..a631206ca 100644 --- a/crates/client/settlement_client/src/starknet/mod.rs +++ b/crates/client/settlement_client/src/starknet/mod.rs @@ -1,6 +1,6 @@ -use crate::client::ClientTrait; +use crate::client::{ClientTrait, ClientType}; use crate::gas_price::L1BlockMetrics; -use crate::messaging::sync::CommonMessagingEventData; +use crate::messaging::CommonMessagingEventData; use crate::starknet::event::StarknetEventStream; use crate::state_update::{update_l1, StateUpdate}; use anyhow::{anyhow, bail}; @@ -56,6 +56,10 @@ impl Clone for StarknetClient { impl ClientTrait for StarknetClient { type Config = StarknetClientConfig; + fn get_client_type(&self) -> ClientType { + ClientType::STARKNET + } + fn get_l1_block_metrics(&self) -> &L1BlockMetrics { &self.l1_block_metrics } @@ -128,7 +132,7 @@ impl ClientTrait for StarknetClient { Ok(u64::try_from(self.get_state_call().await?[1])?) } - async fn get_last_state_root(&self) -> anyhow::Result { + async fn get_last_verified_state_root(&self) -> anyhow::Result { // State Root index in call response : 0 Ok(self.get_state_call().await?[0]) } @@ -141,7 +145,7 @@ impl ClientTrait for StarknetClient { async fn get_initial_state(&self) -> anyhow::Result { let block_number = self.get_last_verified_block_number().await?; let block_hash = self.get_last_verified_block_hash().await?; - let global_root = self.get_last_state_root().await?; + let global_root = self.get_last_verified_state_root().await?; Ok(StateUpdate { global_root, block_number, block_hash }) } @@ -411,17 +415,18 @@ pub mod starknet_client_tests { .await?; // sending state updates : - let data_felt = Felt::from_hex("0xdeadbeef")?; + let block_hash_event = Felt::from_hex("0xdeadbeef")?; + let global_root_event = Felt::from_hex("0xdeadbeef")?; let block_number = send_state_update( &account, deployed_address, - StateUpdate { block_number: 100, global_root: data_felt, block_hash: data_felt }, + StateUpdate { block_number: 100, global_root: global_root_event, block_hash: block_hash_event }, ) .await?; poll_on_block_completion(block_number, account.provider(), 100).await?; let last_verified_block_hash = starknet_client.get_last_verified_block_hash().await?; - assert_eq!(last_verified_block_hash, data_felt, "Block hash should match"); + assert_eq!(last_verified_block_hash, block_hash_event, "Block hash should match"); Ok(()) } @@ -439,17 +444,18 @@ pub mod starknet_client_tests { .await?; // sending state updates : - let data_felt = Felt::from_hex("0xdeadbeef")?; + let block_hash_event = Felt::from_hex("0xdeadbeef")?; + let global_root_event = Felt::from_hex("0xdeadbeef")?; let block_number = send_state_update( &account, deployed_address, - StateUpdate { block_number: 100, global_root: data_felt, block_hash: data_felt }, + StateUpdate { block_number: 100, global_root: global_root_event, block_hash: block_hash_event }, ) .await?; poll_on_block_completion(block_number, account.provider(), 100).await?; - let last_verified_state_root = starknet_client.get_last_state_root().await?; - assert_eq!(last_verified_state_root, data_felt, "Last state root should match"); + let last_verified_state_root = starknet_client.get_last_verified_state_root().await?; + assert_eq!(last_verified_state_root, global_root_event, "Last state root should match"); Ok(()) } diff --git a/crates/client/settlement_client/src/state_update.rs b/crates/client/settlement_client/src/state_update.rs index 8d7fe00e8..5dd8a3439 100644 --- a/crates/client/settlement_client/src/state_update.rs +++ b/crates/client/settlement_client/src/state_update.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; -use crate::messaging::sync::CommonMessagingEventData; +use crate::messaging::CommonMessagingEventData; use crate::utils::trim_hash; use anyhow::Context; use futures::Stream; diff --git a/crates/client/settlement_client/src/sync.rs b/crates/client/settlement_client/src/sync.rs index 30009db25..e066046b5 100644 --- a/crates/client/settlement_client/src/sync.rs +++ b/crates/client/settlement_client/src/sync.rs @@ -1,6 +1,6 @@ use crate::client::ClientTrait; use crate::gas_price::gas_price_worker; -use crate::messaging::sync::{sync, CommonMessagingEventData}; +use crate::messaging::{sync, CommonMessagingEventData}; use crate::state_update::state_update_worker; use futures::Stream; use mc_db::MadaraBackend; diff --git a/crates/node/src/cli/chain_config_overrides.rs b/crates/node/src/cli/chain_config_overrides.rs index f86f38c2c..3fa7dd60f 100644 --- a/crates/node/src/cli/chain_config_overrides.rs +++ b/crates/node/src/cli/chain_config_overrides.rs @@ -8,7 +8,6 @@ use serde::{Deserialize, Serialize}; use serde_yaml::Value; use starknet_api::core::{ChainId, ContractAddress}; -use mp_block::H160; use mp_chain_config::{ deserialize_bouncer_config, deserialize_starknet_version, serialize_bouncer_config, serialize_starknet_version, ChainConfig, StarknetVersion, @@ -47,7 +46,7 @@ pub struct ChainConfigOverridesInner { pub bouncer_config: BouncerConfig, pub sequencer_address: ContractAddress, pub eth_core_contract_address: String, - pub eth_gps_statement_verifier: H160, + pub eth_gps_statement_verifier: String, #[serde(default)] #[serde(skip_serializing)] #[serde(deserialize_with = "deserialize_private_key")] diff --git a/crates/node/src/service/l1.rs b/crates/node/src/service/l1.rs index ffe879865..e89eed318 100644 --- a/crates/node/src/service/l1.rs +++ b/crates/node/src/service/l1.rs @@ -8,7 +8,7 @@ use mc_settlement_client::client::ClientTrait; use mc_settlement_client::eth::event::EthereumEventStream; use mc_settlement_client::eth::{EthereumClient, EthereumClientConfig}; use mc_settlement_client::gas_price::L1BlockMetrics; -use mc_settlement_client::messaging::sync::CommonMessagingEventData; +use mc_settlement_client::messaging::CommonMessagingEventData; use mc_settlement_client::starknet::event::StarknetEventStream; use mc_settlement_client::starknet::{StarknetClient, StarknetClientConfig}; use mp_utils::service::{MadaraServiceId, PowerOfTwo, Service, ServiceId, ServiceRunner}; diff --git a/crates/primitives/chain_config/src/chain_config.rs b/crates/primitives/chain_config/src/chain_config.rs index 66cb44b9f..38253aa16 100644 --- a/crates/primitives/chain_config/src/chain_config.rs +++ b/crates/primitives/chain_config/src/chain_config.rs @@ -18,7 +18,6 @@ use blockifier::bouncer::{BouncerWeights, BuiltinCount}; use blockifier::{bouncer::BouncerConfig, versioned_constants::VersionedConstants}; use lazy_static::__Deref; use mp_utils::crypto::ZeroingPrivateKey; -use primitive_types::H160; use serde::de::{MapAccess, Visitor}; use serde::{Deserialize, Deserializer, Serialize}; use starknet_api::core::{ChainId, ContractAddress, PatriciaKey}; @@ -118,7 +117,7 @@ pub struct ChainConfig { /// The Starknet SHARP verifier La address. Check out the [docs](https://docs.starknet.io/architecture-and-concepts/solidity-verifier/) /// for more information - pub eth_gps_statement_verifier: H160, + pub eth_gps_statement_verifier: String, /// Private key used by the node to sign blocks provided through the /// feeder gateway. This serves as a proof of origin and in the future From 2a19391c1ee2823f291fd076d07923770a853483 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Tue, 14 Jan 2025 17:34:00 +0530 Subject: [PATCH 15/23] fix : changed event params in messaging contract --- .../settlement_client/src/starknet/event.rs | 12 +- .../test_contracts/messaging_test.cairo | 3 + .../test_contracts/messaging_test.casm.json | 83 +++--- .../test_contracts/messaging_test.sierra.json | 239 +++++++++--------- .../settlement_client/src/starknet/utils.rs | 2 +- 5 files changed, 174 insertions(+), 165 deletions(-) diff --git a/crates/client/settlement_client/src/starknet/event.rs b/crates/client/settlement_client/src/starknet/event.rs index 5f33005b8..36b484f7a 100644 --- a/crates/client/settlement_client/src/starknet/event.rs +++ b/crates/client/settlement_client/src/starknet/event.rs @@ -110,20 +110,20 @@ impl Stream for StarknetEventStream { self.processed_events.insert(event.data[4]); Poll::Ready(Some(Some(Ok(CommonMessagingEventData { - from: event.data[1].to_bytes_be().to_vec(), - to: event.data[2].to_bytes_be().to_vec(), - selector: event.data[3].to_bytes_be().to_vec(), - nonce: event.data[4].to_bytes_be().to_vec(), + from: event.keys[2].to_bytes_be().to_vec(), + to: event.keys[3].to_bytes_be().to_vec(), + selector: event.data[0].to_bytes_be().to_vec(), + nonce: event.data[1].to_bytes_be().to_vec(), payload: { let mut payload_array = vec![]; - event.data.iter().skip(6).for_each(|data| { + event.data.iter().skip(3).for_each(|data| { payload_array.push(data.to_bytes_be().to_vec()); }); payload_array }, fee: None, transaction_hash: event.transaction_hash.to_bytes_be().to_vec(), - message_hash: Some(event.data[0].to_bytes_be().to_vec()), + message_hash: Some(event.keys[1].to_bytes_be().to_vec()), block_number: event.block_number.expect("Unable to get block number from event."), event_index: None, })))) diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo index e1c143897..0a2ca28a6 100644 --- a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo +++ b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo @@ -48,8 +48,11 @@ mod MessagingContract { #[derive(Drop, starknet::Event)] struct MessageSent { + #[key] message_hash: felt252, + #[key] from_address: ContractAddress, + #[key] to_address: felt252, selector: felt252, nonce: felt252, diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json index 267493e1b..662d21e45 100644 --- a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json +++ b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json @@ -34,9 +34,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x5b0", + "0x5b5", "0x482480017fff8000", - "0x5af", + "0x5b4", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -202,21 +202,21 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x508", + "0x50d", "0x482480017fff8000", - "0x507", + "0x50c", "0x480080007fff8000", "0xa0680017fff8000", "0x9", "0x4824800180007ff8", - "0x5bae", + "0x5cda", "0x482480017fff8000", "0x100000000000000000000000000000000", "0x400080007ff77fff", "0x10780017fff7fff", "0x22", "0x4824800180007ff8", - "0x5bae", + "0x5cda", "0x400080007ff87fff", "0x482480017ff88000", "0x1", @@ -332,9 +332,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x486", + "0x48b", "0x482480017fff8000", - "0x485", + "0x48a", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -577,9 +577,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x391", + "0x396", "0x482480017fff8000", - "0x390", + "0x395", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -709,9 +709,9 @@ "0x1", "0x208b7fff7fff7ffe", "0x1104800180018000", - "0x30d", + "0x312", "0x482480017fff8000", - "0x30c", + "0x311", "0x480080007fff8000", "0xa0680017fff8000", "0x9", @@ -1037,13 +1037,13 @@ "0x48127fed7fff8000", "0x48127fed7fff8000", "0x1104800180018000", - "0xa8", + "0xad", "0x20680017fff7ffc", "0x27", "0x1104800180018000", - "0x1c1", + "0x1c6", "0x482480017fff8000", - "0x1c0", + "0x1c5", "0x48127ff77fff8000", "0x48127ff77fff8000", "0x480a7ffd7fff8000", @@ -1057,7 +1057,7 @@ "0x48127ff37fff8000", "0x48127ff37fff8000", "0x1104800180018000", - "0x10d", + "0x112", "0x20680017fff7ffc", "0xb", "0x48127ff97fff8000", @@ -1166,30 +1166,35 @@ "0x482480017ffa8000", "0x1", "0x208b7fff7fff7ffe", - "0x400380007ffd7ff3", - "0x400380017ffd7ff4", - "0x400380027ffd7ff5", - "0x400380037ffd7ff6", - "0x400380047ffd7ff7", + "0x40780017fff7fff", + "0x2", + "0x400380007ffb7ff3", + "0x400380017ffb7ff4", + "0x400380027ffb7ff5", + "0x400380007ffd7ff6", + "0x400380017ffd7ff7", "0x48297ff880007ff9", - "0x400280057ffd7fff", + "0x400280027ffd7fff", "0x480a7ff17fff8000", "0x480a7ff27fff8000", "0x480a7ff87fff8000", "0x480a7ff97fff8000", "0x480a7ffc7fff8000", "0x482680017ffd8000", - "0x6", + "0x3", + "0x400b7ffa7fff8000", + "0x402780017ffb8001", + "0x3", "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffb1", + "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffac", "0x20680017fff7ffd", "0xb", "0x48127ffb7fff8000", "0x48127ffb7fff8000", "0x480680017fff8000", "0x0", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", + "0x480a80007fff8000", + "0x480a80017fff8000", "0x48127ff97fff8000", "0x48127ff97fff8000", "0x208b7fff7fff7ffe", @@ -1491,7 +1496,7 @@ "0x208b7fff7fff7ffe" ], "bytecode_segment_lengths": [ - 167, 110, 236, 161, 111, 32, 153, 128, 66, 38, 121, 164 + 167, 110, 236, 161, 111, 32, 153, 128, 66, 43, 121, 164 ], "hints": [ [ @@ -1584,7 +1589,7 @@ [ { "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x5bae" }, + "lhs": { "Immediate": "0x5cda" }, "rhs": { "Deref": { "register": "AP", "offset": -7 } }, "dst": { "register": "AP", "offset": 0 } } @@ -1865,7 +1870,7 @@ ], [1150, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], [ - 1202, + 1207, [ { "TestLessThanOrEqual": { @@ -1877,7 +1882,7 @@ ] ], [ - 1214, + 1219, [ { "TestLessThan": { @@ -1889,7 +1894,7 @@ ] ], [ - 1232, + 1237, [ { "TestLessThan": { @@ -1901,7 +1906,7 @@ ] ], [ - 1250, + 1255, [ { "TestLessThan": { @@ -1918,11 +1923,11 @@ } ] ], - [1275, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [1291, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [1307, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [1280, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [1296, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [1312, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], [ - 1331, + 1336, [ { "TestLessThanOrEqual": { @@ -1934,7 +1939,7 @@ ] ], [ - 1397, + 1402, [ { "TestLessThanOrEqual": { @@ -1945,8 +1950,8 @@ } ] ], - [1422, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [1470, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]] + [1427, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], + [1475, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]] ], "entry_points_by_type": { "EXTERNAL": [ diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json index 57f4acbd8..2f2671266 100644 --- a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json +++ b/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json @@ -192,7 +192,7 @@ "0x7533325f6f766572666c6f77696e675f616464", "0x66656c743235325f616464", "0x68616465735f7065726d75746174696f6e", - "0x4e9", + "0x4ec", "0xffffffffffffffff", "0x66", "0x59", @@ -329,38 +329,38 @@ "0x39d", "0x9f", "0xa0", - "0x401", + "0x404", "0xa1", "0xa2", "0xa3", "0xa4", - "0x454", + "0x457", "0xa6", - "0x41b", + "0x41e", "0xa7", "0xa8", "0xa9", "0xaa", "0xab", - "0x444", + "0x447", "0xac", "0xae", - "0x434", + "0x437", "0xaf", "0xb0", "0xb1", - "0x4d9", + "0x4dc", "0xb2", - "0x471", - "0x476", - "0x4c7", - "0x481", - "0x486", - "0x4b4", + "0x474", + "0x479", + "0x4ca", + "0x484", + "0x489", + "0x4b7", "0xb3", "0xb4", "0xb5", - "0x4a2", + "0x4a5", "0xb6", "0xb7", "0xb8", @@ -375,9 +375,9 @@ "0x315", "0x37e", "0x3b6", - "0x408", - "0x464", - "0x2c05", + "0x40b", + "0x467", + "0x2c1b", "0x140e0a028100609038180a04018200e06028100605038180a04018080200", "0x4834100301432050c0482e100b0542805098482210078141c0d03014180b", "0x180a06028180a18090882021028800a1f090703c0f028740a1809070201b", @@ -697,105 +697,106 @@ "0x4870055c814248d092b80ab9028480c12092e40a0702a2024125c814fe05", "0x2700eb0092700ab90284962125001572051c2b80e21090e00ab9028e00a1d", "0x2e40a1902894241402ae40a1402ad0249b02ae40a3c02c3c243c02ae40aa0", - "0x2e40a0702cfc24125c81424740926c32143f81536055c8153605868483205", - "0x180a750904972050c815ee121087440060c85028b90283c0b400903c0e07", - "0x150212092e40a210285024125c8143a053a84824b9028800a75090497205", - "0x280b40090280e075c8140e059f84960055c81562b40388424b102ae40a14", - "0xa40a7509049720557814ea12092e40a25029d424aa560a55e27128517205", - "0x3d8242e02ae40a2702bd424125c81554050a04824b902ab00a75090497205", - "0x1680121901c0eb90281c0b3f092ac0ab9028bd6007108485e055c8145c05", - "0x14ea12092e40abc02bdc24125c81550053a84870ae1b2f578a80a2e40a32", - "0x4940055c8157a054084824b9028e00a1409049720557014ea12092e40a36", - "0x101349b0a2e40a3c02d00243c0381d7205038167e124e0157205502ac0e21", - "0x14ea12092e40a40029d424125c81534057b84824b902a6c0a75092512c97", - "0x1572054aa700e21092540ab902a5c0a810904972054a0142812092e40a96", - "0x1180a7509210984a442348c145c8152005a0049200703ae40a0702cfc248f", - "0x142812092e40a4a029d424125c81510053a84824b902a340af7090497205", - "0x2e40a0702d00248202ae40a834781c4212418157205260150212092e40a84", - "0x2e40a81029d424125c814a0057b84824b9029740a75091ecfa5340940ba14", - "0x15f2123d1ec0eb9029ec0af80904972053e814ea12092e40a53029d42412", - "0x14ee8203884247702ae40a7702874247702ae40a7902c1c247902ae40a7a", - "0x140ab9028140a25090480ab9028480ab4091d40ab9029ec0a95091d80ab9", - "0x1d0feb9029d8ea05092d212123b01572053b01550123a81572053a8161012", - "0x1bc0eb9029b80a400904972050901c246a02d04dc055c81ce0054d048e072", - "0x50c24c002ae40abf379fcff42092fc0ab902848f212092e40a0002a5c2400", - "0x158205a2048e4055c814e40512848e8055c814e8055a04982055c8158005", - "0x2e40a6a02d1424125c814fe054a04824b9028480e12609c8e87f02b040ab9", - "0x1598055c8159805a2048e4055c814e40512848e8055c814e8055a0499805", - "0x480e12100180f460c8500eb90381424070284824b902848e812661c8e87f", - "0x1d7205038158a121081572050e815f2120e83c0eb90283c0af8090497205", - "0x1c24271281e900a5801d720710ac4287fa384842055c8144205608496207", - "0x1e424125c814fe054404824b90283c0a14090497205050166012092e40a12", - "0x2c00ab4092b00ab9028a40b4a090a40ab902abc0eb43fd2424af02ae40a12", - "0x1c24ac0cac0fe055601572055601696120c81572050c8144a12580157205", - "0x15720555014fe12551fc0eb9029fc0b4c090497205138166012092e40a12", - "0x480e12540169c325581d7207178b84a7fa68485e0703ae40a0702b14242e", - "0x2f40ab902af00a81092f00ab9028c80a50090c80ab9028c80b4f090497205", - "0x15821257015720509310243602ae40abd5a01c42125e81572055e8143a12", - "0x2700f51500e00eb903ab80eab3fd40243602ae40a3602aa024ae02ae40aae", - "0x2800ac1090640ab9028640a25090e00ab9028e00ab40904972050901c243c", - "0x15720507814fa121b01572051b01550123f81572053f8161012500157205", - "0x4972050901c24404d26cfe0520269367f5c8141e363fa8032380a4b0240f", - "0x2e40a7f02a2024125c8146c054a04824b90283c0a140904972051e0166012", - "0x25c0e21092580ab902a580a1d092580ab90284aa4124b8157205090182412", - "0x2e40a8f02d4c248f02ae40a944a81d60124a8157205092c4249402ae40a96", - "0x1520055c8152005a584832055c81432051284938055c81538055a0492005", - "0x151012092e40a0702cc024125c8141e050a04824b9028480e1248065387f", - "0x74248d02ae40a12aa0488c055c81424060904972055a0152812092e40a7f", - "0x22094075804894055c81424b1092200ab902a348c07108491a055c8151a05", - "0x1572050c8144a1254015720554015681242015720526016a612260157205", - "0x497205038166012092e40a12038490819541fc0a8402ae40a8402d2c2419", - "0x1572050901824125c8141e050a04824b902ad00a940904972053f8151012", - "0x2c4245d02ae40a824181c4212410157205410143a12410157205092342483", - "0x140c055a048a6055c8150205a984902055c814ba5003ac0245002ae40a12", - "0x48e812298800c7f0294c0ab90294c0b4b090800ab9028800a25090180ab9", - "0x2d00b560904972050901c24200301eaa190a01d7207028480e05090497205", - "0x1572050a0156812092e40a122e84960055c8141e053f84962210e9fd7205", - "0x2bc0ab9028940ae40904972050901c242702d5c4a0a03ae40eb00283c2414", - "0x2e40a1203848255802848f41256015720557815ca1214815720505014fa12", - "0x15ca1214815720513814fa1217015720555015cc12550157205091e42412", - "0x145e052804824b9028480e1255816b22f02ae40eac02b9c24ac02ae40a2e", - "0x2f00eb9038a40a0f092a00ab902aa00a1d092a00ab9028c80a81090c80ab9", - "0x4870055c81578053e8495c055c8157a057204824b9028480e121b016b4bd", - "0x4938055c81424790904972050901c2412ad814247a092800ab902ab80ae5", - "0xe00a95092800ab9028f00ae5090e00ab9028d80a7d090f00ab902a700ae6", - "0x497205091d024125c8142407091000b5c4d015720750015ce124d8157205", - "0x74249402ae40aa80e81eba124b01572054b81502124b81572054d014a012", - "0x2540a1d092500ab902a500a1d092540ab902a584207ae8492c055c8152c05", - "0x220fe075c814fe05af8491a464823d68b902ac52a9403ad2bc124a8157205", - "0x143a12230157205230143a12480157205480143a12478157205478149412", - "0x4824b9028480e1241a100f60261280eb903a2032143faa8248d02ae40a8d", - "0x128244c02ae40a4c02894244a02ae40a4a02ad0248202ae40a8d23240ff31", - "0x1536058404904055c815040599048fe055c814fe05560491e055c8151e05", - "0x1c245340940bab40294d02502ead172054da08fe8f2612829330926c0ab9", - "0x1d424125c814fe05b084824b902a400a750904972054d8151012092e40a12", - "0x48f6055c814248d091f40ab9028480c12092e40a8d029d424125c8148c05", - "0x1e40eb0091e40ab90284962123d01572053d9f40e21091ec0ab9029ec0a1d", - "0x2e40a8302894248402ae40a8402ad0247602ae40a7702d88247702ae40a7a", - "0x480e123b23d06845a014ec055c814ec05b18491e055c8151e05250490605", - "0x740f5d0904972053f816c212092e40a4002a5c24125c8142474090497205", - "0x2e40a7502874247202ae40a741081eba123a015720509590247502ae40aa8", - "0x14ea12379a8dc705a2e40ab1391d40eb4af048e4055c814e4050e848ea05", - "0x1572050001584120001572053726c0f6509049720537814ea12092e40a6a", - "0x58c247002ae40a7002928241902ae40a1902894241402ae40a1402ad024bf", - "0x152e12092e40a123a04824b9028480e125f9c032145a0157e055c8157e05", - "0x3040ab902b003a07ae84980055c81425640904972053f816c212092e40aab", - "0x159e053a8497ccf66b3168b902ac442c103ad2bc12608157205608143a12", - "0x49a6055c8159ad203d9424d202ae40a2902a5424125c8157c053a84824b9", - "0x3300a4a090640ab9028640a25090500ab9028500ab4093540ab902b4c0ac2", - "0x151012092e40a1203849aacc0c85168056a81572056a816c612660157205", - "0x23424d602ae40a120304824b902ad00b660904972053f816c212092e40a0f", - "0x2e40a1258849b2055c815b0d60388424d802ae40ad80287424d802ae40a12", - "0x180ab9028180ab4093780ab902b740b62093740ab902b65b80758049b805", - "0x1968056f01572056f016c612038157205038149412100157205100144a12", - "0x481e19381bc6c1207848fe0702848dc70378496819381bc24b458b780e20", - "0x4969673f81c0a12371c0de125a064e06f092d212b43f81c0a12371c0de36", - "0x14246e381bc6c1207864e06f1b0481f683f81c0a12371c0de125a064e06f", - "0x1bc240f251c06c6f0903ed47f03814248137848fe0f3e9bc24b4b4ad0fe07", - "0x1bc24b4b61fc0e05092806c6f092d0943637849696b5a1fc0e0509210e036", - "0x5b9687f0381424ac37848fe0f07aacde1207db4fe0702849026f091fc1e19", - "0x496819581c86c6f09052de0f5a1fc0e05092bcde123f8501e19051bc2414", - "0x2e00f5a1fc0e05092c46c6f" + "0x2e40a128984828055c81425110926c32143f81536055c8153605868483205", + "0x843a200305172050c81680120c81c0eb90281c0b3f090497205091d02412", + "0x2c40a7509049720510814ea12092e40a1d029d424125c81440057b84960b1", + "0x940ab902828fe071084814055c8140c054084824b902ac00a14090497205", + "0x155e053a8485e2e552b052af0a2e40a2702d0024270381d7205038167e12", + "0xbc0a1409049720517014ea12092e40aaa029d424125c81558053a84824b9", + "0x157205190940e21090c80ab902aac0af6092ac0ab9028a40af5090497205", + "0x2f40a75092714038570d97a145c8157805a0049780703ae40a0702cfc24a8", + "0x142812092e40aa0029d424125c81470053a84824b9028d80af7090497205", + "0x2e40a0702cfc240f02ae40a3c5401c42121e0157205570150212092e40a9c", + "0x1000af70904972054d014ea124aa512c972026828b902a6c0b400926c0e07", + "0x150212092e40a950285024125c81528053a84824b902a5c0a75090497205", + "0x1180b40091180e075c8140e059f84920055c8151eb403884248f02ae40a96", + "0x1280a7509049720544015ee12092e40a8d029d42483421309488468517205", + "0x84248202ae40a8402a0424125c81506050a04824b9029300a75090497205", + "0x49720528014ea123d1ecfa534094028b90281c0b40091740ab902a092007", + "0x2e40a7b029d424125c814fa053a84824b90294c0a7509049720540815ee12", + "0x48ec055c814ee0583848ee055c814f2057c848f27a03ae40a7a02be02412", + "0x1568123a01572053d0152a123a81572053b1740e21091d80ab9029d80a1d", + "0x2e40a7502aa0247402ae40a7402c20240502ae40a0502894241202ae40a12", + "0x153412371c0e47f5c814ea740284969090903c0ab90283c28078a848ea05", + "0x2fc0a97092fc00075c814d4052004824b9028480e1237816826a02ae40e6e", + "0x157205608168612608157205600001e7fa104980055c8142479090497205", + "0x1fc0acc02ae40acc02d10247002ae40a7002894247202ae40a7202ad024cc", + "0x156812668157205378168a12092e40a0f02a5024125c814240709330e072", + "0x499a70391fc0acd02ae40acd02d10247002ae40a7002894247202ae40a72", + "0x3e024125c8142407090800c07a306428075c81c0a120381424125c8142474", + "0x1582125881c0eb90281c0ac5090840ab9028740af9090741e075c8141e05", + "0x4824b9028480e12138940f48052c00eb90388562143fd1c242102ae40a21", + "0x2bc0ab902848f212092e40a7f02a2024125c8141e050a04824b9028280b30", + "0x4960055c81560055a04958055c8145205a504852055c8155e075a1fe9212", + "0x4824b9028480e1256065607f02ab00ab902ab00b4b090640ab9028640a25", + "0x1c0ac5090b80ab902aa80a7f092a8fe075c814fe05a604824b90289c0b30", + "0x53c24125c8142407092a00b4e192ac0eb9038bc5c253fd34242f0381d7205", + "0x157a050e8497a055c81578054084978055c81464052804864055c8146405", + "0x2b80ab902ab80ac1092b80ab90284988121b01572055ead00e21092f40ab9", + "0x142407090f13807a8a8070075c81d5c07559fea0121b01572051b0155012", + "0x4940055c81540056084832055c81432051284870055c81470055a04824b9", + "0xe0292c0903c0ab90283c0a7d090d80ab9028d80aa8091fc0ab9029fc0b08", + "0x1478059804824b9028480e1220269367f02901349b3fae40a0f1b1fd4019", + "0x1424060904972053f8151012092e40a3602a5024125c8141e050a04824b9", + "0x2500ab902a592e07108492c055c8152c050e8492c055c81425520925c0ab9", + "0x15681248015720547816a6124781572054a2540eb0092540ab9028496212", + "0x4920194e1fc0a9002ae40a9002d2c241902ae40a1902894249c02ae40a9c", + "0x4824b9029fc0a88090497205038166012092e40a0f0285024125c8142407", + "0x157205468143a1246815720509550244602ae40a120304824b902ad00a94", + "0x4898055c815104a03ac0244a02ae40a125884910055c8151a4603884248d", + "0x2100b4b090640ab9028640a25092a00ab902aa00ab4092100ab9029300b53", + "0x14fe054404824b90281c0b300904972050901c24840caa0fe05420157205", + "0x14248d0920c0ab9028480c12092e40a0f0285024125c81568054a04824b9", + "0x1400ab90284962122e81572054120c0e21092080ab902a080a1d092080ab9", + "0x94240602ae40a0602ad0245302ae40a8102d4c248102ae40a5d2801d6012", + "0x1424125c81424740914c40063f814a6055c814a605a584840055c8144005", + "0x843a7f5c8156805ab04824b9028480e12100180f550c8500eb9038142407", + "0x2c00a0f090500ab9028500ab40904972050917424b002ae40a0f029fc24b1", + "0x1414053e8495e055c8144a057204824b9028480e1213816ae250501d7207", + "0x1424790904972050901c2412ac014247a092b00ab902abc0ae5090a40ab9", + "0x2b00ab9028b80ae5090a40ab90289c0a7d090b80ab902aa80ae6092a80ab9", + "0x204243202ae40a2f0294024125c8142407092ac0b5917815720756015ce12", + "0x486c05ad2f578075c81c52050784950055c81550050e84950055c8146405", + "0x2e40aae02b94243802ae40abc029f424ae02ae40abd02b9024125c8142407", + "0x2e40a9c02b98249c02ae40a123c84824b9028480e120956c0a123d0494005", + "0x4936055c81470054a84940055c81478057284870055c8146c053e8487805", + "0x1534052804824b902848e812092e40a12038488005ae2680ab903a800ae7", + "0x1572054b0143a124a0157205540740f5d092580ab902a5c0a810925c0ab9", + "0x492a055c8152a050e84928055c81528050e8492a055c8152c2103d742496", + "0x151e0525049107f03ae40a7f02d7c248d232411eb45c81562954a01d695e", + "0x2340ab902a340a1d091180ab9029180a1d092400ab902a400a1d0923c0ab9", + "0x2348c903fcc424125c81424070920d0807b013094075c81d10190a1fd5412", + "0x157205478149412260157205260144a12250157205250156812410157205", + "0x4cc249b02ae40a9b02c20248202ae40a8202cc8247f02ae40a7f02ab0248f", + "0x4824b9028480e1229a04a05d5a014a6812817568b902a6d047f479309414", + "0x49720523014ea12092e40a7f02d8424125c81520053a84824b902a6c0a88", + "0x2e40a7b02874247b02ae40a1246848fa055c814240609049720546814ea12", + "0x1dc0ab9029e8f20758048f2055c81424b1091e80ab9029ecfa0710848f605", + "0x149412418157205418144a124201572054201568123b01572053b816c412", + "0x1d024125c8142407091d91e83422d00a7602ae40a7602d8c248f02ae40a8f", + "0x1d40ab902aa03a07ae84824b9029fc0b61090497205200152e12092e40a12", + "0x143a123a81572053a8143a123901572053a0840f5d091d00ab90284ac812", + "0x4824b9029a80a75091bcd46e382d17205589c8ea075a578247202ae40a72", + "0x500ab4092fc0ab9028000ac2090000ab9029b93607b284824b9029bc0a75", + "0x1572055f816c6123801572053801494120c81572050c8144a120a0157205", + "0x4824b902aac0a97090497205091d024125c8142407092fce0190a2d00abf", + "0x1582050e84982055c815801d03d7424c002ae40a12b204824b9029fc0b61", + "0x14ea12092e40acf029d424be67b3598b45c81562216081d695e093040ab9", + "0x2e40ad302b0824d302ae40acd6901eca12690157205148152a12092e40abe", + "0x4998055c81598052504832055c81432051284828055c81428055a049aa05", + "0x4824b90283c0a880904972050901c24d56606428b402b540ab902b540b63", + "0x3600ab9028491a126b01572050901824125c8156805b304824b9029fc0b61", + "0x1d60126e0157205092c424d902ae40ad86b01c42126c01572056c0143a12", + "0x144005128480c055c8140c055a049bc055c815ba05b1049ba055c815b2dc", + "0x2d162de038800cb402b780ab902b780b630901c0ab90281c0a4a090800ab9", + "0x48dc70378d8240f0c9c0de360903c247f03814246e381bc24b40c9c0de12", + "0x496819381bc24b4b39fc0e05091b8e06f092d032703784969095a1fc0e05", + "0x2d2d2b43f81c0a12371c0de360903c3270378d8240fb41fc0e05091b8e06f", + "0x142484380d8de1207928e036378481f6a3f81c0a12409bc247f079f4de12", + "0x1bc247f07864de125a5b0fe0702849403637849684a1b1bc24b4b5ad0fe07", + "0x64146f09052dcb43f81c0a12561bc247f0783d566f0903eda7f038142481", + "0x1424b11b1bc24b40cac0e43637848296f07ad0fe07028495e6f091fc280f", + "0x17007ad0fe07" ], "sierra_program_debug_info": { "type_names": [ @@ -1438,13 +1439,13 @@ "name": "temp_cairo::messaging::MessagingContract::MessageSent", "kind": "struct", "members": [ - { "name": "message_hash", "type": "core::felt252", "kind": "data" }, + { "name": "message_hash", "type": "core::felt252", "kind": "key" }, { "name": "from_address", "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" + "kind": "key" }, - { "name": "to_address", "type": "core::felt252", "kind": "data" }, + { "name": "to_address", "type": "core::felt252", "kind": "key" }, { "name": "selector", "type": "core::felt252", "kind": "data" }, { "name": "nonce", "type": "core::felt252", "kind": "data" }, { diff --git a/crates/client/settlement_client/src/starknet/utils.rs b/crates/client/settlement_client/src/starknet/utils.rs index c293c4f1a..01a4e8935 100644 --- a/crates/client/settlement_client/src/starknet/utils.rs +++ b/crates/client/settlement_client/src/starknet/utils.rs @@ -31,7 +31,7 @@ pub const MESSAGING_CONTRACT_SIERRA_PATH: &str = "src/starknet/test_contracts/me // starkli class-hash crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json pub const APPCHAIN_CONTRACT_CASM_HASH: &str = "0x07f36e830605ddeb7c4c094639b628de297cbf61f45385b1fc3231029922b30b"; // starkli class-hash crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json -pub const MESSAGING_CONTRACT_CASM_HASH: &str = "0x0267b5e87ff42dacc469c25ec0c2e3f8eb798a7d6723ad0aa1c68cbd3f9d8586"; +pub const MESSAGING_CONTRACT_CASM_HASH: &str = "0x077de37b708f9abe01c1a797856398c5e1e5dfde8213f884668fa37b13d77e30"; pub type StarknetAccount = SingleOwnerAccount, LocalWallet>; pub type TransactionReceiptResult = Result; From 8abf99928ce5e8510d8b23a5d91cedb732aaecf7 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Tue, 14 Jan 2025 17:45:45 +0530 Subject: [PATCH 16/23] refactor : removed external devnet.yaml file --- .../settlement_client/src/starknet/utils.rs | 3 +- test-artifacts/devnet.yaml | 34 ------------------- 2 files changed, 2 insertions(+), 35 deletions(-) delete mode 100644 test-artifacts/devnet.yaml diff --git a/crates/client/settlement_client/src/starknet/utils.rs b/crates/client/settlement_client/src/starknet/utils.rs index 01a4e8935..9a176f1c4 100644 --- a/crates/client/settlement_client/src/starknet/utils.rs +++ b/crates/client/settlement_client/src/starknet/utils.rs @@ -24,7 +24,7 @@ pub const DEPLOYER_PRIVATE_KEY: &str = "0x077e56c6dc32d40a67f6f7e6625c8dc5e570ab pub const UDC_ADDRESS: &str = "0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf"; pub const MADARA_PORT: &str = "19944"; pub const MADARA_BINARY_PATH: &str = "../../../test-artifacts/madara"; -pub const MADARA_CONFIG_PATH: &str = "../../../test-artifacts/devnet.yaml"; +pub const MADARA_CONFIG_PATH: &str = "../../../configs/presets/devnet.yaml"; pub const APPCHAIN_CONTRACT_SIERRA_PATH: &str = "src/starknet/test_contracts/appchain_test.sierra.json"; pub const MESSAGING_CONTRACT_SIERRA_PATH: &str = "src/starknet/test_contracts/messaging_test.sierra.json"; @@ -63,6 +63,7 @@ impl MadaraProcess { .arg("--gateway-port") .arg("8080") .arg("--no-l1-sync") + .arg("--chain-config-override=block_time=5s,pending_block_update_time=1s") .spawn()?; wait_for_port(MADARA_PORT.parse().unwrap(), 2, 10); diff --git a/test-artifacts/devnet.yaml b/test-artifacts/devnet.yaml deleted file mode 100644 index 8cb18c3fe..000000000 --- a/test-artifacts/devnet.yaml +++ /dev/null @@ -1,34 +0,0 @@ -chain_name: "Madara" -chain_id: "MADARA_DEVNET" -feeder_gateway_url: "http://localhost:8080/feeder_gateway/" -gateway_url: "http://localhost:8080/gateway/" -native_fee_token_address: "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d" -parent_fee_token_address: "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7" -latest_protocol_version: "0.13.2" -block_time: "5s" -pending_block_update_time: "1s" -execution_batch_size: 16 -bouncer_config: - block_max_capacity: - builtin_count: - add_mod: 18446744073709551615 - bitwise: 18446744073709551615 - ecdsa: 18446744073709551615 - ec_op: 18446744073709551615 - keccak: 18446744073709551615 - mul_mod: 18446744073709551615 - pedersen: 18446744073709551615 - poseidon: 18446744073709551615 - range_check: 18446744073709551615 - range_check96: 18446744073709551615 - gas: 5000000 - n_steps: 40000000 - message_segment_length: 18446744073709551615 - n_events: 18446744073709551615 - state_diff_size: 131072 -sequencer_address: "0x123" -eth_core_contract_address: "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512" -eth_gps_statement_verifier: "0xf294781D719D2F4169cE54469C28908E6FA752C1" -mempool_tx_limit: 10000 -mempool_declare_tx_limit: 20 -mempool_tx_max_age: null From 749df1c9ed251ae9cd46758bfbcdb15b104ab727 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Tue, 14 Jan 2025 18:26:19 +0530 Subject: [PATCH 17/23] feat : removed expects --- .../client/settlement_client/src/eth/event.rs | 41 ++++++---- .../settlement_client/src/starknet/event.rs | 80 ++++++++++--------- 2 files changed, 68 insertions(+), 53 deletions(-) diff --git a/crates/client/settlement_client/src/eth/event.rs b/crates/client/settlement_client/src/eth/event.rs index b60479ba9..04ad63b4f 100644 --- a/crates/client/settlement_client/src/eth/event.rs +++ b/crates/client/settlement_client/src/eth/event.rs @@ -28,22 +28,31 @@ impl Stream for EthereumEventStream { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.stream.as_mut().poll_next(cx) { Poll::Ready(Some(result)) => match result { - Ok((event, log)) => Poll::Ready(Some(Some(Ok(CommonMessagingEventData { - from: event.fromAddress.as_slice().into(), - to: event.toAddress.to_be_bytes_vec(), - selector: event.selector.to_be_bytes_vec(), - nonce: event.nonce.to_be_bytes_vec(), - payload: { - let mut payload_vec = vec![]; - event.payload.iter().for_each(|ele| payload_vec.push(ele.to_be_bytes_vec())); - payload_vec - }, - fee: Some(event.fee.to_be_bytes_vec()), - transaction_hash: log.transaction_hash.expect("Missing transaction hash").to_vec(), - message_hash: None, - block_number: log.block_number.expect("Missing block number"), - event_index: Some(log.log_index.expect("Missing log index")), - })))), + Ok((event, log)) => { + let event_data = (|| -> anyhow::Result { + Ok(CommonMessagingEventData { + from: event.fromAddress.as_slice().into(), + to: event.toAddress.to_be_bytes_vec(), + selector: event.selector.to_be_bytes_vec(), + nonce: event.nonce.to_be_bytes_vec(), + payload: { + let mut payload_vec = vec![]; + event.payload.iter().for_each(|ele| payload_vec.push(ele.to_be_bytes_vec())); + payload_vec + }, + fee: Some(event.fee.to_be_bytes_vec()), + transaction_hash: log + .transaction_hash + .ok_or_else(|| anyhow::anyhow!("Missing transaction hash"))? + .to_vec(), + message_hash: None, + block_number: log.block_number.ok_or_else(|| anyhow::anyhow!("Missing block number"))?, + event_index: Some(log.log_index.ok_or_else(|| anyhow::anyhow!("Missing log index"))?), + }) + })(); + + Poll::Ready(Some(Some(event_data))) + } Err(e) => Poll::Ready(Some(Some(Err(Error::from(e))))), }, Poll::Ready(None) => Poll::Ready(Some(None)), diff --git a/crates/client/settlement_client/src/starknet/event.rs b/crates/client/settlement_client/src/starknet/event.rs index 36b484f7a..8a4b215f4 100644 --- a/crates/client/settlement_client/src/starknet/event.rs +++ b/crates/client/settlement_client/src/starknet/event.rs @@ -97,46 +97,52 @@ impl Stream for StarknetEventStream { self.future = Some(Box::pin(future)); } - // Poll the future - let fut = self.future.as_mut().unwrap(); - match fut.as_mut().poll(cx) { - Poll::Ready(result) => { - self.future = None; - match result { - Ok((Some(event), updated_filter)) => { - // Update the filter - self.filter = updated_filter; - // Insert the event nonce before returning - self.processed_events.insert(event.data[4]); - - Poll::Ready(Some(Some(Ok(CommonMessagingEventData { - from: event.keys[2].to_bytes_be().to_vec(), - to: event.keys[3].to_bytes_be().to_vec(), - selector: event.data[0].to_bytes_be().to_vec(), - nonce: event.data[1].to_bytes_be().to_vec(), - payload: { - let mut payload_array = vec![]; - event.data.iter().skip(3).for_each(|data| { - payload_array.push(data.to_bytes_be().to_vec()); + match self.future.as_mut() { + Some(fut) => match fut.as_mut().poll(cx) { + Poll::Ready(result) => { + self.future = None; + match result { + Ok((Some(event), updated_filter)) => { + // Update the filter + self.filter = updated_filter; + // Insert the event nonce before returning + self.processed_events.insert(event.data[4]); + + let event_data = event + .block_number + .ok_or_else(|| anyhow::anyhow!("Unable to get block number from event")) + .map(|block_number| CommonMessagingEventData { + from: event.keys[2].to_bytes_be().to_vec(), + to: event.keys[3].to_bytes_be().to_vec(), + selector: event.data[0].to_bytes_be().to_vec(), + nonce: event.data[1].to_bytes_be().to_vec(), + payload: { + let mut payload_array = vec![]; + event.data.iter().skip(3).for_each(|data| { + payload_array.push(data.to_bytes_be().to_vec()); + }); + payload_array + }, + fee: None, + transaction_hash: event.transaction_hash.to_bytes_be().to_vec(), + message_hash: Some(event.keys[1].to_bytes_be().to_vec()), + block_number, + event_index: None, }); - payload_array - }, - fee: None, - transaction_hash: event.transaction_hash.to_bytes_be().to_vec(), - message_hash: Some(event.keys[1].to_bytes_be().to_vec()), - block_number: event.block_number.expect("Unable to get block number from event."), - event_index: None, - })))) - } - Ok((None, updated_filter)) => { - // Update the filter even when no events are found - self.filter = updated_filter; - Poll::Ready(Some(None)) + + Poll::Ready(Some(Some(event_data))) + } + Ok((None, updated_filter)) => { + // Update the filter even when no events are found + self.filter = updated_filter; + Poll::Ready(Some(None)) + } + Err(e) => Poll::Ready(Some(Some(Err(e)))), } - Err(e) => Poll::Ready(Some(Some(Err(e)))), } - } - Poll::Pending => Poll::Pending, + Poll::Pending => Poll::Pending, + }, + None => Poll::Ready(Some(None)), // Handle the case where future is None } } } From b63cf6164266974d2ed739d4cdc1136cb0c01d67 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Tue, 14 Jan 2025 18:49:17 +0530 Subject: [PATCH 18/23] refactor crates structure --- Cargo.toml | 148 +++++++++--------- .../mempool/proptest-regressions/inner.txt | 11 -- .../cairo-test-contracts/Cargo.toml | 0 .../cairo-test-contracts/build.rs | 0 .../cairo-test-contracts/src/lib.rs | 2 +- .../{ => madara}/client/analytics/Cargo.toml | 0 .../{ => madara}/client/analytics/src/lib.rs | 0 .../client/block_import/Cargo.toml | 0 .../client/block_import/src/lib.rs | 0 .../client/block_import/src/metrics.rs | 0 .../client/block_import/src/pre_validate.rs | 0 .../client/block_import/src/rayon.rs | 0 .../client/block_import/src/tests.rs | 0 .../src/tests/block_import_utils.rs | 0 .../client/block_import/src/types.rs | 0 .../client/block_import/src/verify_apply.rs | 0 .../block_import/src/verify_apply/classes.rs | 0 .../src/verify_apply/contracts.rs | 0 .../client/block_production/Cargo.toml | 0 .../block_production/src/close_block.rs | 0 .../src/finalize_execution_state.rs | 0 .../client/block_production/src/lib.rs | 0 .../client/block_production/src/metrics.rs | 0 .../src/re_add_finalized_to_blockifier.rs | 0 crates/{ => madara}/client/db/Cargo.toml | 0 .../client/db/docs/flat_storage.md | 4 +- .../client/db/docs/flat_storage.png | Bin .../client/db/docs/flat_storage_iterator.png | Bin crates/{ => madara}/client/db/src/block_db.rs | 0 .../{ => madara}/client/db/src/bonsai_db.rs | 0 crates/{ => madara}/client/db/src/class_db.rs | 0 .../{ => madara}/client/db/src/contract_db.rs | 0 .../{ => madara}/client/db/src/db_block_id.rs | 0 .../{ => madara}/client/db/src/db_metrics.rs | 0 .../{ => madara}/client/db/src/devnet_db.rs | 0 crates/{ => madara}/client/db/src/error.rs | 0 crates/{ => madara}/client/db/src/l1_db.rs | 0 crates/{ => madara}/client/db/src/lib.rs | 0 .../{ => madara}/client/db/src/mempool_db.rs | 0 .../client/db/src/rocksdb_options.rs | 0 .../client/db/src/rocksdb_snapshot.rs | 0 .../{ => madara}/client/db/src/snapshots.rs | 0 .../client/db/src/storage_updates.rs | 0 crates/{ => madara}/client/db/src/tests.rs | 0 .../client/db/src/tests/common/mod.rs | 0 .../client/db/src/tests/test_block.rs | 0 .../client/db/src/tests/test_open.rs | 0 crates/{ => madara}/client/devnet/Cargo.toml | 0 crates/{ => madara}/client/devnet/README.md | 2 +- .../client/devnet/src/balances.rs | 0 .../{ => madara}/client/devnet/src/classes.rs | 0 .../client/devnet/src/contracts.rs | 0 .../client/devnet/src/entrypoint.rs | 0 crates/{ => madara}/client/devnet/src/lib.rs | 6 +- .../devnet/src/predeployed_contracts.rs | 0 crates/{ => madara}/client/exec/Cargo.toml | 0 .../client/exec/src/block_context.rs | 0 .../exec/src/blockifier_state_adapter.rs | 0 crates/{ => madara}/client/exec/src/call.rs | 0 .../{ => madara}/client/exec/src/execution.rs | 0 crates/{ => madara}/client/exec/src/fee.rs | 0 crates/{ => madara}/client/exec/src/lib.rs | 0 crates/{ => madara}/client/exec/src/trace.rs | 0 .../client/exec/src/transaction.rs | 0 .../client/gateway/client/Cargo.toml | 0 .../client/gateway/client/src/builder.rs | 0 .../client/gateway/client/src/lib.rs | 0 .../client/gateway/client/src/methods.rs | 0 ...fe81a880746649b9aee7e0d842bf3f52378f9f8.gz | Bin ...b5656e3c3dd201b6df35d805d3f2988c69a1432.gz | Bin ...b7d34c7c5528f22730d56192b50c6bbfd338a64.gz | Bin ...7c11151f45498030748a950fdaf0b79ac3dc03f.gz | Bin ...4697a519274ac9c1a1fbf931bac40133a6b9c15.gz | Bin ...e70812129658c82c295ff0f8307b3fad4bf09a9.gz | Bin .../client/src/mocks/signature_block_0.gz | Bin .../client/src/mocks/signature_block_1.gz | Bin .../client/src/mocks/signature_block_2.gz | Bin .../src/mocks/state_update_and_block_0.gz | Bin .../src/mocks/state_update_and_block_1.gz | Bin .../src/mocks/state_update_and_block_2.gz | Bin .../gateway/client/src/request_builder.rs | 0 .../client/gateway/server/Cargo.toml | 0 .../client/gateway/server/src/error.rs | 0 .../client/gateway/server/src/handler.rs | 0 .../client/gateway/server/src/helpers.rs | 0 .../client/gateway/server/src/lib.rs | 0 .../client/gateway/server/src/router.rs | 0 .../client/gateway/server/src/service.rs | 0 crates/{ => madara}/client/mempool/Cargo.toml | 0 .../{ => madara}/client/mempool/src/header.rs | 0 .../mempool/src/inner/deployed_contracts.rs | 0 .../client/mempool/src/inner/limits.rs | 0 .../client/mempool/src/inner/mod.rs | 0 .../client/mempool/src/inner/nonce_chain.rs | 0 .../client/mempool/src/inner/proptest.rs | 0 .../client/mempool/src/inner/tx.rs | 0 crates/{ => madara}/client/mempool/src/l1.rs | 0 crates/{ => madara}/client/mempool/src/lib.rs | 0 .../client/mempool/src/metrics.rs | 0 crates/{ => madara}/client/mempool/src/tx.rs | 0 crates/{ => madara}/client/rpc/Cargo.toml | 0 crates/{ => madara}/client/rpc/src/RPC.md | 0 .../{ => madara}/client/rpc/src/constants.rs | 0 crates/{ => madara}/client/rpc/src/errors.rs | 0 crates/{ => madara}/client/rpc/src/lib.rs | 0 .../rpc/src/providers/forward_to_provider.rs | 0 .../client/rpc/src/providers/mempool.rs | 0 .../client/rpc/src/providers/mod.rs | 0 .../{ => madara}/client/rpc/src/test_utils.rs | 0 crates/{ => madara}/client/rpc/src/types.rs | 0 .../{ => madara}/client/rpc/src/utils/mod.rs | 0 .../client/rpc/src/versions/admin/mod.rs | 0 .../rpc/src/versions/admin/v0_1_0/api.rs | 0 .../src/versions/admin/v0_1_0/methods/mod.rs | 0 .../versions/admin/v0_1_0/methods/services.rs | 0 .../versions/admin/v0_1_0/methods/status.rs | 0 .../versions/admin/v0_1_0/methods/write.rs | 0 .../rpc/src/versions/admin/v0_1_0/mod.rs | 0 .../client/rpc/src/versions/mod.rs | 0 .../client/rpc/src/versions/user/mod.rs | 0 .../rpc/src/versions/user/v0_7_1/api.rs | 0 .../src/versions/user/v0_7_1/methods/mod.rs | 0 .../methods/read/block_hash_and_number.rs | 0 .../versions/user/v0_7_1/methods/read/call.rs | 0 .../user/v0_7_1/methods/read/estimate_fee.rs | 0 .../methods/read/estimate_message_fee.rs | 0 .../read/get_block_transaction_count.rs | 0 .../methods/read/get_block_with_receipts.rs | 0 .../methods/read/get_block_with_tx_hashes.rs | 0 .../v0_7_1/methods/read/get_block_with_txs.rs | 0 .../user/v0_7_1/methods/read/get_class.rs | 0 .../user/v0_7_1/methods/read/get_class_at.rs | 0 .../v0_7_1/methods/read/get_class_hash_at.rs | 0 .../user/v0_7_1/methods/read/get_events.rs | 0 .../user/v0_7_1/methods/read/get_nonce.rs | 0 .../v0_7_1/methods/read/get_state_update.rs | 0 .../v0_7_1/methods/read/get_storage_at.rs | 0 .../get_transaction_by_block_id_and_index.rs | 0 .../methods/read/get_transaction_by_hash.rs | 0 .../methods/read/get_transaction_receipt.rs | 0 .../methods/read/get_transaction_status.rs | 0 .../versions/user/v0_7_1/methods/read/lib.rs | 0 .../versions/user/v0_7_1/methods/read/mod.rs | 0 .../user/v0_7_1/methods/read/syncing.rs | 0 .../versions/user/v0_7_1/methods/trace/mod.rs | 0 .../methods/trace/simulate_transactions.rs | 0 .../methods/trace/trace_block_transactions.rs | 0 .../v0_7_1/methods/trace/trace_transaction.rs | 0 .../versions/user/v0_7_1/methods/write/mod.rs | 0 .../rpc/src/versions/user/v0_7_1/mod.rs | 0 .../rpc/src/versions/user/v0_8_0/api.rs | 0 .../src/versions/user/v0_8_0/methods/mod.rs | 0 .../v0_8_0/methods/read/get_compiled_casm.rs | 0 .../v0_8_0/methods/read/get_storage_proof.rs | 0 .../versions/user/v0_8_0/methods/read/mod.rs | 0 .../versions/user/v0_8_0/methods/ws/lib.rs | 0 .../versions/user/v0_8_0/methods/ws/mod.rs | 0 .../rpc/src/versions/user/v0_8_0/mod.rs | 0 .../client/rpc/src/versions/v0_8_0/api.rs | 0 .../rpc/src/versions/v0_8_0/methods/mod.rs | 0 .../src/versions/v0_8_0/methods/read/mod.rs | 0 .../client/settlement_client/Cargo.toml | 0 .../client/settlement_client/README.md | 0 .../client/settlement_client/src/client.rs | 0 .../client/settlement_client/src/error.rs | 0 .../client/settlement_client/src/eth/event.rs | 0 .../client/settlement_client/src/eth/mod.rs | 0 .../src/eth/starknet_core.json | 0 .../client/settlement_client/src/gas_price.rs | 0 .../client/settlement_client/src/lib.rs | 0 .../settlement_client/src/messaging/mod.rs | 0 .../settlement_client/src/messaging/tests.rs | 0 .../settlement_client/src/starknet/event.rs | 0 .../settlement_client/src/starknet/mod.rs | 0 .../test_contracts/appchain_test.cairo | 0 .../test_contracts/appchain_test.casm.json | 0 .../test_contracts/appchain_test.sierra.json | 0 .../test_contracts/messaging_test.cairo | 0 .../test_contracts/messaging_test.casm.json | 0 .../test_contracts/messaging_test.sierra.json | 0 .../settlement_client/src/starknet/utils.rs | 0 .../settlement_client/src/state_update.rs | 0 .../client/settlement_client/src/sync.rs | 0 .../client/settlement_client/src/utils.rs | 0 crates/{ => madara}/client/sync/Cargo.toml | 0 .../client/sync/src/fetch/fetchers.rs | 0 .../sync/src/fetch/fetchers_real_fgw_test.rs | 0 .../{ => madara}/client/sync/src/fetch/mod.rs | 0 crates/{ => madara}/client/sync/src/l2.rs | 0 crates/{ => madara}/client/sync/src/lib.rs | 0 .../client/sync/src/metrics/block_metrics.rs | 0 .../client/sync/src/metrics/mod.rs | 0 .../{ => madara}/client/sync/src/tests/mod.rs | 0 .../client/sync/src/tests/utils/gateway.rs | 0 .../client/sync/src/tests/utils/mod.rs | 0 .../sync/src/tests/utils/read_resource.rs | 0 .../client/sync/src/tests/utils/retry.rs | 0 crates/{ => madara}/client/sync/src/utils.rs | 0 .../client/sync/test-data/block_0.json | 0 .../client/sync/test-data/block_724130.json | 0 .../{ => madara}/client/telemetry/Cargo.toml | 0 crates/{ => madara}/client/telemetry/build.rs | 0 .../{ => madara}/client/telemetry/src/lib.rs | 0 .../client/telemetry/src/sysinfo.rs | 0 crates/{ => madara}/node/Cargo.toml | 0 crates/{ => madara}/node/build.rs | 0 crates/{ => madara}/node/src/cli/analytics.rs | 0 .../node/src/cli/block_production.rs | 0 .../node/src/cli/chain_config_overrides.rs | 0 crates/{ => madara}/node/src/cli/db.rs | 0 crates/{ => madara}/node/src/cli/gateway.rs | 0 crates/{ => madara}/node/src/cli/l1.rs | 0 crates/{ => madara}/node/src/cli/l2.rs | 0 crates/{ => madara}/node/src/cli/mod.rs | 0 crates/{ => madara}/node/src/cli/rpc.rs | 0 crates/{ => madara}/node/src/cli/telemetry.rs | 0 crates/{ => madara}/node/src/main.rs | 0 .../node/src/service/block_production.rs | 0 .../{ => madara}/node/src/service/database.rs | 0 .../{ => madara}/node/src/service/gateway.rs | 0 crates/{ => madara}/node/src/service/l1.rs | 0 crates/{ => madara}/node/src/service/l2.rs | 0 crates/{ => madara}/node/src/service/mod.rs | 0 .../node/src/service/rpc/metrics.rs | 0 .../node/src/service/rpc/middleware.rs | 0 .../{ => madara}/node/src/service/rpc/mod.rs | 0 .../node/src/service/rpc/server.rs | 0 crates/{ => madara}/node/src/util.rs | 0 .../{ => madara}/primitives/block/Cargo.toml | 0 .../primitives/block/src/header.rs | 0 .../{ => madara}/primitives/block/src/lib.rs | 0 .../primitives/chain_config/Cargo.toml | 0 .../resources/versioned_constants_13_0.json | 0 .../resources/versioned_constants_13_1.json | 0 .../resources/versioned_constants_13_1_1.json | 0 .../resources/versioned_constants_13_2.json | 0 .../chain_config/src/chain_config.rs | 7 +- .../primitives/chain_config/src/lib.rs | 0 .../chain_config/src/rpc_version.rs | 0 .../chain_config/src/starknet_version.rs | 0 .../{ => madara}/primitives/class/Cargo.toml | 0 .../class/resources/missed_classes.json | 0 .../primitives/class/src/class_hash.rs | 0 .../primitives/class/src/class_update.rs | 0 .../primitives/class/src/compile.rs | 0 .../primitives/class/src/convert.rs | 0 .../class/src/into_starknet_core.rs | 0 .../class/src/into_starknet_types.rs | 0 .../{ => madara}/primitives/class/src/lib.rs | 0 .../primitives/convert/Cargo.toml | 0 .../primitives/convert/src/felt.rs | 0 .../primitives/convert/src/hex_serde.rs | 0 .../primitives/convert/src/lib.rs | 0 .../primitives/convert/src/to_felt.rs | 0 .../primitives/gateway/Cargo.toml | 0 .../primitives/gateway/src/block.rs | 0 .../primitives/gateway/src/error.rs | 0 .../primitives/gateway/src/lib.rs | 0 .../primitives/gateway/src/receipt.rs | 0 .../primitives/gateway/src/state_update.rs | 0 .../primitives/gateway/src/test.rs | 0 .../primitives/gateway/src/transaction.rs | 0 .../gateway/src/user_transaction.rs | 0 .../{ => madara}/primitives/oracle/Cargo.toml | 0 .../{ => madara}/primitives/oracle/src/lib.rs | 0 .../primitives/oracle/src/pragma.rs | 0 .../primitives/receipt/Cargo.toml | 0 .../primitives/receipt/src/from_blockifier.rs | 0 .../primitives/receipt/src/lib.rs | 0 .../receipt/src/to_starknet_types.rs | 0 .../primitives/state_update/Cargo.toml | 0 .../state_update/src/into_starknet_types.rs | 0 .../primitives/state_update/src/lib.rs | 0 .../primitives/transactions/Cargo.toml | 0 .../transactions/src/compute_hash.rs | 0 .../transactions/src/from_blockifier.rs | 0 .../src/from_broadcasted_transaction.rs | 0 .../transactions/src/from_starknet_types.rs | 0 .../transactions/src/into_starknet_api.rs | 0 .../primitives/transactions/src/lib.rs | 0 .../transactions/src/to_blockifier.rs | 0 .../transactions/src/to_starknet_types.rs | 0 .../primitives/transactions/src/utils.rs | 0 .../{ => madara}/primitives/utils/Cargo.toml | 0 .../primitives/utils/src/crypto.rs | 0 .../{ => madara}/primitives/utils/src/lib.rs | 0 .../primitives/utils/src/parsers.rs | 0 .../primitives/utils/src/serde.rs | 0 .../primitives/utils/src/service.rs | 0 crates/{ => madara}/proc-macros/Cargo.toml | 0 crates/{ => madara}/proc-macros/src/lib.rs | 0 crates/{ => madara}/tests/Cargo.toml | 0 crates/{ => madara}/tests/src/devnet.rs | 0 crates/{ => madara}/tests/src/lib.rs | 0 crates/{ => madara}/tests/src/rpc/mod.rs | 0 crates/{ => madara}/tests/src/rpc/read.rs | 0 .../src/rpc/test_utils/class_program.txt | 0 .../src/rpc/test_utils/compiled_class.json | 0 .../src/rpc/test_utils/contract_class.json | 0 .../{ => madara}/tests/src/storage_proof.rs | 0 crates/{ => madara}/tests/test_devnet.yaml | 0 301 files changed, 85 insertions(+), 95 deletions(-) delete mode 100644 crates/client/mempool/proptest-regressions/inner.txt rename crates/{ => madara}/cairo-test-contracts/Cargo.toml (100%) rename crates/{ => madara}/cairo-test-contracts/build.rs (100%) rename crates/{ => madara}/cairo-test-contracts/src/lib.rs (68%) rename crates/{ => madara}/client/analytics/Cargo.toml (100%) rename crates/{ => madara}/client/analytics/src/lib.rs (100%) rename crates/{ => madara}/client/block_import/Cargo.toml (100%) rename crates/{ => madara}/client/block_import/src/lib.rs (100%) rename crates/{ => madara}/client/block_import/src/metrics.rs (100%) rename crates/{ => madara}/client/block_import/src/pre_validate.rs (100%) rename crates/{ => madara}/client/block_import/src/rayon.rs (100%) rename crates/{ => madara}/client/block_import/src/tests.rs (100%) rename crates/{ => madara}/client/block_import/src/tests/block_import_utils.rs (100%) rename crates/{ => madara}/client/block_import/src/types.rs (100%) rename crates/{ => madara}/client/block_import/src/verify_apply.rs (100%) rename crates/{ => madara}/client/block_import/src/verify_apply/classes.rs (100%) rename crates/{ => madara}/client/block_import/src/verify_apply/contracts.rs (100%) rename crates/{ => madara}/client/block_production/Cargo.toml (100%) rename crates/{ => madara}/client/block_production/src/close_block.rs (100%) rename crates/{ => madara}/client/block_production/src/finalize_execution_state.rs (100%) rename crates/{ => madara}/client/block_production/src/lib.rs (100%) rename crates/{ => madara}/client/block_production/src/metrics.rs (100%) rename crates/{ => madara}/client/block_production/src/re_add_finalized_to_blockifier.rs (100%) rename crates/{ => madara}/client/db/Cargo.toml (100%) rename crates/{ => madara}/client/db/docs/flat_storage.md (92%) rename crates/{ => madara}/client/db/docs/flat_storage.png (100%) rename crates/{ => madara}/client/db/docs/flat_storage_iterator.png (100%) rename crates/{ => madara}/client/db/src/block_db.rs (100%) rename crates/{ => madara}/client/db/src/bonsai_db.rs (100%) rename crates/{ => madara}/client/db/src/class_db.rs (100%) rename crates/{ => madara}/client/db/src/contract_db.rs (100%) rename crates/{ => madara}/client/db/src/db_block_id.rs (100%) rename crates/{ => madara}/client/db/src/db_metrics.rs (100%) rename crates/{ => madara}/client/db/src/devnet_db.rs (100%) rename crates/{ => madara}/client/db/src/error.rs (100%) rename crates/{ => madara}/client/db/src/l1_db.rs (100%) rename crates/{ => madara}/client/db/src/lib.rs (100%) rename crates/{ => madara}/client/db/src/mempool_db.rs (100%) rename crates/{ => madara}/client/db/src/rocksdb_options.rs (100%) rename crates/{ => madara}/client/db/src/rocksdb_snapshot.rs (100%) rename crates/{ => madara}/client/db/src/snapshots.rs (100%) rename crates/{ => madara}/client/db/src/storage_updates.rs (100%) rename crates/{ => madara}/client/db/src/tests.rs (100%) rename crates/{ => madara}/client/db/src/tests/common/mod.rs (100%) rename crates/{ => madara}/client/db/src/tests/test_block.rs (100%) rename crates/{ => madara}/client/db/src/tests/test_open.rs (100%) rename crates/{ => madara}/client/devnet/Cargo.toml (100%) rename crates/{ => madara}/client/devnet/README.md (98%) rename crates/{ => madara}/client/devnet/src/balances.rs (100%) rename crates/{ => madara}/client/devnet/src/classes.rs (100%) rename crates/{ => madara}/client/devnet/src/contracts.rs (100%) rename crates/{ => madara}/client/devnet/src/entrypoint.rs (100%) rename crates/{ => madara}/client/devnet/src/lib.rs (99%) rename crates/{ => madara}/client/devnet/src/predeployed_contracts.rs (100%) rename crates/{ => madara}/client/exec/Cargo.toml (100%) rename crates/{ => madara}/client/exec/src/block_context.rs (100%) rename crates/{ => madara}/client/exec/src/blockifier_state_adapter.rs (100%) rename crates/{ => madara}/client/exec/src/call.rs (100%) rename crates/{ => madara}/client/exec/src/execution.rs (100%) rename crates/{ => madara}/client/exec/src/fee.rs (100%) rename crates/{ => madara}/client/exec/src/lib.rs (100%) rename crates/{ => madara}/client/exec/src/trace.rs (100%) rename crates/{ => madara}/client/exec/src/transaction.rs (100%) rename crates/{ => madara}/client/gateway/client/Cargo.toml (100%) rename crates/{ => madara}/client/gateway/client/src/builder.rs (100%) rename crates/{ => madara}/client/gateway/client/src/lib.rs (100%) rename crates/{ => madara}/client/gateway/client/src/methods.rs (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/class_block_0_0x010455c752b86932ce552f2b0fe81a880746649b9aee7e0d842bf3f52378f9f8.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/class_block_1342_account_0x07595b4f7d50010ceb00230d8b5656e3c3dd201b6df35d805d3f2988c69a1432.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/class_block_1343_proxy_0x071c3c99f5cf76fc19945d4b8b7d34c7c5528f22730d56192b50c6bbfd338a64.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/class_block_18507_erc1155_0x04be7f1bace6f593abd8e56947c11151f45498030748a950fdaf0b79ac3dc03f.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/class_block_1981_erc20_0x07543f8eb21f10b1827a495084697a519274ac9c1a1fbf931bac40133a6b9c15.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/class_block_3125_erc721_0x074a7ed7f1236225600f355efe70812129658c82c295ff0f8307b3fad4bf09a9.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/signature_block_0.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/signature_block_1.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/signature_block_2.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/state_update_and_block_0.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/state_update_and_block_1.gz (100%) rename crates/{ => madara}/client/gateway/client/src/mocks/state_update_and_block_2.gz (100%) rename crates/{ => madara}/client/gateway/client/src/request_builder.rs (100%) rename crates/{ => madara}/client/gateway/server/Cargo.toml (100%) rename crates/{ => madara}/client/gateway/server/src/error.rs (100%) rename crates/{ => madara}/client/gateway/server/src/handler.rs (100%) rename crates/{ => madara}/client/gateway/server/src/helpers.rs (100%) rename crates/{ => madara}/client/gateway/server/src/lib.rs (100%) rename crates/{ => madara}/client/gateway/server/src/router.rs (100%) rename crates/{ => madara}/client/gateway/server/src/service.rs (100%) rename crates/{ => madara}/client/mempool/Cargo.toml (100%) rename crates/{ => madara}/client/mempool/src/header.rs (100%) rename crates/{ => madara}/client/mempool/src/inner/deployed_contracts.rs (100%) rename crates/{ => madara}/client/mempool/src/inner/limits.rs (100%) rename crates/{ => madara}/client/mempool/src/inner/mod.rs (100%) rename crates/{ => madara}/client/mempool/src/inner/nonce_chain.rs (100%) rename crates/{ => madara}/client/mempool/src/inner/proptest.rs (100%) rename crates/{ => madara}/client/mempool/src/inner/tx.rs (100%) rename crates/{ => madara}/client/mempool/src/l1.rs (100%) rename crates/{ => madara}/client/mempool/src/lib.rs (100%) rename crates/{ => madara}/client/mempool/src/metrics.rs (100%) rename crates/{ => madara}/client/mempool/src/tx.rs (100%) rename crates/{ => madara}/client/rpc/Cargo.toml (100%) rename crates/{ => madara}/client/rpc/src/RPC.md (100%) rename crates/{ => madara}/client/rpc/src/constants.rs (100%) rename crates/{ => madara}/client/rpc/src/errors.rs (100%) rename crates/{ => madara}/client/rpc/src/lib.rs (100%) rename crates/{ => madara}/client/rpc/src/providers/forward_to_provider.rs (100%) rename crates/{ => madara}/client/rpc/src/providers/mempool.rs (100%) rename crates/{ => madara}/client/rpc/src/providers/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/test_utils.rs (100%) rename crates/{ => madara}/client/rpc/src/types.rs (100%) rename crates/{ => madara}/client/rpc/src/utils/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/admin/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/admin/v0_1_0/api.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/admin/v0_1_0/methods/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/admin/v0_1_0/methods/services.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/admin/v0_1_0/methods/status.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/admin/v0_1_0/methods/write.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/admin/v0_1_0/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/api.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/block_hash_and_number.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/call.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_fee.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_message_fee.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_transaction_count.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_receipts.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_tx_hashes.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_txs.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_class.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_at.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_hash_at.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_events.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_nonce.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_state_update.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_storage_at.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_block_id_and_index.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_hash.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_receipt.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_status.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/lib.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/read/syncing.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/trace/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/trace/simulate_transactions.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_block_transactions.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_transaction.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/methods/write/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_7_1/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_8_0/api.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_8_0/methods/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_8_0/methods/read/get_compiled_casm.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_8_0/methods/read/get_storage_proof.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_8_0/methods/read/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_8_0/methods/ws/lib.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_8_0/methods/ws/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/user/v0_8_0/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/v0_8_0/api.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/v0_8_0/methods/mod.rs (100%) rename crates/{ => madara}/client/rpc/src/versions/v0_8_0/methods/read/mod.rs (100%) rename crates/{ => madara}/client/settlement_client/Cargo.toml (100%) rename crates/{ => madara}/client/settlement_client/README.md (100%) rename crates/{ => madara}/client/settlement_client/src/client.rs (100%) rename crates/{ => madara}/client/settlement_client/src/error.rs (100%) rename crates/{ => madara}/client/settlement_client/src/eth/event.rs (100%) rename crates/{ => madara}/client/settlement_client/src/eth/mod.rs (100%) rename crates/{ => madara}/client/settlement_client/src/eth/starknet_core.json (100%) rename crates/{ => madara}/client/settlement_client/src/gas_price.rs (100%) rename crates/{ => madara}/client/settlement_client/src/lib.rs (100%) rename crates/{ => madara}/client/settlement_client/src/messaging/mod.rs (100%) rename crates/{ => madara}/client/settlement_client/src/messaging/tests.rs (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/event.rs (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/mod.rs (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json (100%) rename crates/{ => madara}/client/settlement_client/src/starknet/utils.rs (100%) rename crates/{ => madara}/client/settlement_client/src/state_update.rs (100%) rename crates/{ => madara}/client/settlement_client/src/sync.rs (100%) rename crates/{ => madara}/client/settlement_client/src/utils.rs (100%) rename crates/{ => madara}/client/sync/Cargo.toml (100%) rename crates/{ => madara}/client/sync/src/fetch/fetchers.rs (100%) rename crates/{ => madara}/client/sync/src/fetch/fetchers_real_fgw_test.rs (100%) rename crates/{ => madara}/client/sync/src/fetch/mod.rs (100%) rename crates/{ => madara}/client/sync/src/l2.rs (100%) rename crates/{ => madara}/client/sync/src/lib.rs (100%) rename crates/{ => madara}/client/sync/src/metrics/block_metrics.rs (100%) rename crates/{ => madara}/client/sync/src/metrics/mod.rs (100%) rename crates/{ => madara}/client/sync/src/tests/mod.rs (100%) rename crates/{ => madara}/client/sync/src/tests/utils/gateway.rs (100%) rename crates/{ => madara}/client/sync/src/tests/utils/mod.rs (100%) rename crates/{ => madara}/client/sync/src/tests/utils/read_resource.rs (100%) rename crates/{ => madara}/client/sync/src/tests/utils/retry.rs (100%) rename crates/{ => madara}/client/sync/src/utils.rs (100%) rename crates/{ => madara}/client/sync/test-data/block_0.json (100%) rename crates/{ => madara}/client/sync/test-data/block_724130.json (100%) rename crates/{ => madara}/client/telemetry/Cargo.toml (100%) rename crates/{ => madara}/client/telemetry/build.rs (100%) rename crates/{ => madara}/client/telemetry/src/lib.rs (100%) rename crates/{ => madara}/client/telemetry/src/sysinfo.rs (100%) rename crates/{ => madara}/node/Cargo.toml (100%) rename crates/{ => madara}/node/build.rs (100%) rename crates/{ => madara}/node/src/cli/analytics.rs (100%) rename crates/{ => madara}/node/src/cli/block_production.rs (100%) rename crates/{ => madara}/node/src/cli/chain_config_overrides.rs (100%) rename crates/{ => madara}/node/src/cli/db.rs (100%) rename crates/{ => madara}/node/src/cli/gateway.rs (100%) rename crates/{ => madara}/node/src/cli/l1.rs (100%) rename crates/{ => madara}/node/src/cli/l2.rs (100%) rename crates/{ => madara}/node/src/cli/mod.rs (100%) rename crates/{ => madara}/node/src/cli/rpc.rs (100%) rename crates/{ => madara}/node/src/cli/telemetry.rs (100%) rename crates/{ => madara}/node/src/main.rs (100%) rename crates/{ => madara}/node/src/service/block_production.rs (100%) rename crates/{ => madara}/node/src/service/database.rs (100%) rename crates/{ => madara}/node/src/service/gateway.rs (100%) rename crates/{ => madara}/node/src/service/l1.rs (100%) rename crates/{ => madara}/node/src/service/l2.rs (100%) rename crates/{ => madara}/node/src/service/mod.rs (100%) rename crates/{ => madara}/node/src/service/rpc/metrics.rs (100%) rename crates/{ => madara}/node/src/service/rpc/middleware.rs (100%) rename crates/{ => madara}/node/src/service/rpc/mod.rs (100%) rename crates/{ => madara}/node/src/service/rpc/server.rs (100%) rename crates/{ => madara}/node/src/util.rs (100%) rename crates/{ => madara}/primitives/block/Cargo.toml (100%) rename crates/{ => madara}/primitives/block/src/header.rs (100%) rename crates/{ => madara}/primitives/block/src/lib.rs (100%) rename crates/{ => madara}/primitives/chain_config/Cargo.toml (100%) rename crates/{ => madara}/primitives/chain_config/resources/versioned_constants_13_0.json (100%) rename crates/{ => madara}/primitives/chain_config/resources/versioned_constants_13_1.json (100%) rename crates/{ => madara}/primitives/chain_config/resources/versioned_constants_13_1_1.json (100%) rename crates/{ => madara}/primitives/chain_config/resources/versioned_constants_13_2.json (100%) rename crates/{ => madara}/primitives/chain_config/src/chain_config.rs (98%) rename crates/{ => madara}/primitives/chain_config/src/lib.rs (100%) rename crates/{ => madara}/primitives/chain_config/src/rpc_version.rs (100%) rename crates/{ => madara}/primitives/chain_config/src/starknet_version.rs (100%) rename crates/{ => madara}/primitives/class/Cargo.toml (100%) rename crates/{ => madara}/primitives/class/resources/missed_classes.json (100%) rename crates/{ => madara}/primitives/class/src/class_hash.rs (100%) rename crates/{ => madara}/primitives/class/src/class_update.rs (100%) rename crates/{ => madara}/primitives/class/src/compile.rs (100%) rename crates/{ => madara}/primitives/class/src/convert.rs (100%) rename crates/{ => madara}/primitives/class/src/into_starknet_core.rs (100%) rename crates/{ => madara}/primitives/class/src/into_starknet_types.rs (100%) rename crates/{ => madara}/primitives/class/src/lib.rs (100%) rename crates/{ => madara}/primitives/convert/Cargo.toml (100%) rename crates/{ => madara}/primitives/convert/src/felt.rs (100%) rename crates/{ => madara}/primitives/convert/src/hex_serde.rs (100%) rename crates/{ => madara}/primitives/convert/src/lib.rs (100%) rename crates/{ => madara}/primitives/convert/src/to_felt.rs (100%) rename crates/{ => madara}/primitives/gateway/Cargo.toml (100%) rename crates/{ => madara}/primitives/gateway/src/block.rs (100%) rename crates/{ => madara}/primitives/gateway/src/error.rs (100%) rename crates/{ => madara}/primitives/gateway/src/lib.rs (100%) rename crates/{ => madara}/primitives/gateway/src/receipt.rs (100%) rename crates/{ => madara}/primitives/gateway/src/state_update.rs (100%) rename crates/{ => madara}/primitives/gateway/src/test.rs (100%) rename crates/{ => madara}/primitives/gateway/src/transaction.rs (100%) rename crates/{ => madara}/primitives/gateway/src/user_transaction.rs (100%) rename crates/{ => madara}/primitives/oracle/Cargo.toml (100%) rename crates/{ => madara}/primitives/oracle/src/lib.rs (100%) rename crates/{ => madara}/primitives/oracle/src/pragma.rs (100%) rename crates/{ => madara}/primitives/receipt/Cargo.toml (100%) rename crates/{ => madara}/primitives/receipt/src/from_blockifier.rs (100%) rename crates/{ => madara}/primitives/receipt/src/lib.rs (100%) rename crates/{ => madara}/primitives/receipt/src/to_starknet_types.rs (100%) rename crates/{ => madara}/primitives/state_update/Cargo.toml (100%) rename crates/{ => madara}/primitives/state_update/src/into_starknet_types.rs (100%) rename crates/{ => madara}/primitives/state_update/src/lib.rs (100%) rename crates/{ => madara}/primitives/transactions/Cargo.toml (100%) rename crates/{ => madara}/primitives/transactions/src/compute_hash.rs (100%) rename crates/{ => madara}/primitives/transactions/src/from_blockifier.rs (100%) rename crates/{ => madara}/primitives/transactions/src/from_broadcasted_transaction.rs (100%) rename crates/{ => madara}/primitives/transactions/src/from_starknet_types.rs (100%) rename crates/{ => madara}/primitives/transactions/src/into_starknet_api.rs (100%) rename crates/{ => madara}/primitives/transactions/src/lib.rs (100%) rename crates/{ => madara}/primitives/transactions/src/to_blockifier.rs (100%) rename crates/{ => madara}/primitives/transactions/src/to_starknet_types.rs (100%) rename crates/{ => madara}/primitives/transactions/src/utils.rs (100%) rename crates/{ => madara}/primitives/utils/Cargo.toml (100%) rename crates/{ => madara}/primitives/utils/src/crypto.rs (100%) rename crates/{ => madara}/primitives/utils/src/lib.rs (100%) rename crates/{ => madara}/primitives/utils/src/parsers.rs (100%) rename crates/{ => madara}/primitives/utils/src/serde.rs (100%) rename crates/{ => madara}/primitives/utils/src/service.rs (100%) rename crates/{ => madara}/proc-macros/Cargo.toml (100%) rename crates/{ => madara}/proc-macros/src/lib.rs (100%) rename crates/{ => madara}/tests/Cargo.toml (100%) rename crates/{ => madara}/tests/src/devnet.rs (100%) rename crates/{ => madara}/tests/src/lib.rs (100%) rename crates/{ => madara}/tests/src/rpc/mod.rs (100%) rename crates/{ => madara}/tests/src/rpc/read.rs (100%) rename crates/{ => madara}/tests/src/rpc/test_utils/class_program.txt (100%) rename crates/{ => madara}/tests/src/rpc/test_utils/compiled_class.json (100%) rename crates/{ => madara}/tests/src/rpc/test_utils/contract_class.json (100%) rename crates/{ => madara}/tests/src/storage_proof.rs (100%) rename crates/{ => madara}/tests/test_devnet.yaml (100%) diff --git a/Cargo.toml b/Cargo.toml index 3b0cf4346..7ccd93226 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,58 +1,58 @@ [workspace] members = [ - "crates/client/db", - "crates/client/exec", - "crates/client/sync", - "crates/client/settlement_client", - "crates/client/rpc", - "crates/client/gateway/client", - "crates/client/gateway/server", - "crates/client/analytics", - "crates/client/telemetry", - "crates/client/devnet", - "crates/client/mempool", - "crates/client/block_import", - "crates/node", - "crates/primitives/block", - "crates/primitives/convert", - "crates/primitives/transactions", - "crates/primitives/class", - "crates/primitives/gateway", - "crates/primitives/receipt", - "crates/primitives/state_update", - "crates/primitives/chain_config", - "crates/primitives/utils", - "crates/proc-macros", - "crates/tests", - "crates/cairo-test-contracts", - "crates/client/block_production", + "crates/madara/client/db", + "crates/madara/client/exec", + "crates/madara/client/sync", + "crates/madara/client/settlement_client", + "crates/madara/client/rpc", + "crates/madara/client/gateway/client", + "crates/madara/client/gateway/server", + "crates/madara/client/analytics", + "crates/madara/client/telemetry", + "crates/madara/client/devnet", + "crates/madara/client/mempool", + "crates/madara/client/block_import", + "crates/madara/node", + "crates/madara/primitives/block", + "crates/madara/primitives/convert", + "crates/madara/primitives/transactions", + "crates/madara/primitives/class", + "crates/madara/primitives/gateway", + "crates/madara/primitives/receipt", + "crates/madara/primitives/state_update", + "crates/madara/primitives/chain_config", + "crates/madara/primitives/utils", + "crates/madara/proc-macros", + "crates/madara/tests", + "crates/madara/cairo-test-contracts", + "crates/madara/client/block_production", ] resolver = "2" # Everything except test-related packages, so that they are not compiled when doing `cargo build`. default-members = [ - "crates/client/db", - "crates/client/exec", - "crates/client/sync", - "crates/client/settlement_client", - "crates/client/gateway/client", - "crates/client/gateway/server", - "crates/client/rpc", - "crates/client/telemetry", - "crates/client/devnet", - "crates/client/mempool", - "crates/client/block_import", - "crates/client/analytics", - "crates/node", - "crates/primitives/block", - "crates/primitives/convert", - "crates/primitives/transactions", - "crates/primitives/class", - "crates/primitives/gateway", - "crates/primitives/receipt", - "crates/primitives/state_update", - "crates/primitives/chain_config", - "crates/primitives/utils", - "crates/proc-macros", + "crates/madara/client/db", + "crates/madara/client/exec", + "crates/madara/client/sync", + "crates/madara/client/settlement_client", + "crates/madara/client/gateway/client", + "crates/madara/client/gateway/server", + "crates/madara/client/rpc", + "crates/madara/client/telemetry", + "crates/madara/client/devnet", + "crates/madara/client/mempool", + "crates/madara/client/block_import", + "crates/madara/client/analytics", + "crates/madara/node", + "crates/madara/primitives/block", + "crates/madara/primitives/convert", + "crates/madara/primitives/transactions", + "crates/madara/primitives/class", + "crates/madara/primitives/gateway", + "crates/madara/primitives/receipt", + "crates/madara/primitives/state_update", + "crates/madara/primitives/chain_config", + "crates/madara/primitives/utils", + "crates/madara/proc-macros", ] [workspace.lints.rust] @@ -104,37 +104,37 @@ bonsai-trie = { default-features = false, git = "https://github.com/madara-allia ] } # Madara proc macros -m-proc-macros = { path = "crates/proc-macros", default-features = false } +m-proc-macros = { path = "crates/madara/proc-macros", default-features = false } # Madara primtitives -mp-block = { path = "crates/primitives/block", default-features = false } -mp-convert = { path = "crates/primitives/convert", default-features = false } -mp-transactions = { path = "crates/primitives/transactions", default-features = false } -mp-class = { path = "crates/primitives/class", default-features = false } -mp-gateway = { path = "crates/primitives/gateway", default-features = false } -mp-receipt = { path = "crates/primitives/receipt", default-features = false } -mp-state-update = { path = "crates/primitives/state_update", default-features = false } -mp-utils = { path = "crates/primitives/utils", default-features = false } -mp-chain-config = { path = "crates/primitives/chain_config", default-features = false } -mp-oracle = { path = "crates/primitives/oracle", default-features = false } +mp-block = { path = "crates/madara/primitives/block", default-features = false } +mp-convert = { path = "crates/madara/primitives/convert", default-features = false } +mp-transactions = { path = "crates/madara/primitives/transactions", default-features = false } +mp-class = { path = "crates/madara/primitives/class", default-features = false } +mp-gateway = { path = "crates/madara/primitives/gateway", default-features = false } +mp-receipt = { path = "crates/madara/primitives/receipt", default-features = false } +mp-state-update = { path = "crates/madara/primitives/state_update", default-features = false } +mp-utils = { path = "crates/madara/primitives/utils", default-features = false } +mp-chain-config = { path = "crates/madara/primitives/chain_config", default-features = false } +mp-oracle = { path = "crates/madara/primitives/oracle", default-features = false } # Madara client -mc-analytics = { path = "crates/client/analytics" } -mc-telemetry = { path = "crates/client/telemetry" } -mc-db = { path = "crates/client/db" } -mc-exec = { path = "crates/client/exec" } -mc-rpc = { path = "crates/client/rpc" } -mc-gateway-client = { path = "crates/client/gateway/client" } -mc-gateway-server = { path = "crates/client/gateway/server" } -mc-sync = { path = "crates/client/sync" } -mc-settlement-client = { path = "crates/client/settlement_client" } -mc-mempool = { path = "crates/client/mempool" } -mc-block-production = { path = "crates/client/block_production" } -mc-block-import = { path = "crates/client/block_import" } -mc-devnet = { path = "crates/client/devnet" } +mc-analytics = { path = "crates/madara/client/analytics" } +mc-telemetry = { path = "crates/madara/client/telemetry" } +mc-db = { path = "crates/madara/client/db" } +mc-exec = { path = "crates/madara/client/exec" } +mc-rpc = { path = "crates/madara/client/rpc" } +mc-gateway-client = { path = "crates/madara/client/gateway/client" } +mc-gateway-server = { path = "crates/madara/client/gateway/server" } +mc-sync = { path = "crates/madara/client/sync" } +mc-settlement-client = { path = "crates/madara/client/settlement_client" } +mc-mempool = { path = "crates/madara/client/mempool" } +mc-block-production = { path = "crates/madara/client/block_production" } +mc-block-import = { path = "crates/madara/client/block_import" } +mc-devnet = { path = "crates/madara/client/devnet" } # Madara misc -m-cairo-test-contracts = { path = "crates/cairo-test-contracts" } +m-cairo-test-contracts = { path = "crates/madara/cairo-test-contracts" } # Starknet dependencies cairo-vm = "=1.0.1" diff --git a/crates/client/mempool/proptest-regressions/inner.txt b/crates/client/mempool/proptest-regressions/inner.txt deleted file mode 100644 index 3ab554f44..000000000 --- a/crates/client/mempool/proptest-regressions/inner.txt +++ /dev/null @@ -1,11 +0,0 @@ -# Seeds for failure cases proptest has generated in the past. It is -# automatically read and these particular cases re-run before any -# novel cases are generated. -# -# It is recommended to check this file in to source control so that -# everyone who runs the test benefits from these saved cases. -cc 606af7856ddbb4fa59d49993b59a603681411ecf692f02dab0c8ea234bacbf97 # shrinks to pb = MempoolInvariantsProblem([Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 207000000 },tx_hash=TransactionHash(0x0),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0x0),force=false)), Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 207000000 },tx_hash=TransactionHash(0x0),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0x1),force=false))]) -cc 29f49e0ef0eea98a11ffe4648dd6f160299f0841ab5033098dba809dcc974a40 # shrinks to pb = MempoolInvariantsProblem([Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x57b92afb0507883960ce6022d158e86e6f71ee6d5b8e56936872ffe0cd5b6cd),contract_address=ContractAddress(PatriciaKey(0x81)),nonce=Nonce(0x24),force=false)), Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x507230d365c6eb2de9b5cc6ef286a337887c9c3d814bab629169b4e2caff6ea),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0x0),force=false)), Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x507230d365c6eb2de9b5cc6ef286a337887c9c3d814bab629169b4e2caff6ea),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0x0),force=false)), Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x507230d365c6eb2de9b5cc6ef286a337887c9c3d814bab629169b4e2caff6ea),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0x0),force=false))]) -cc 1bcf72bf5e5a4c741ab6e6ed269c40b584ac0fd4ffa785e7826410b0d210d8ca # shrinks to pb = MempoolInvariantsProblem([Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 66000000 },tx_hash=TransactionHash(0x1295cbfdf4ed4e4ffdf8b661498fd2682235e3660388c0e1159a01d4b045d55),contract_address=ContractAddress(PatriciaKey(0x53)),nonce=Nonce(0x0),force=false)), Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x1295cbfdf4ed4e4ffdf8b661498fd2682235e3660388c0e1159a01d4b045d55),contract_address=ContractAddress(PatriciaKey(0x53)),nonce=Nonce(0x0),force=false))]) -cc 523d7eadd1091bd7fa740e368300a1db40f0021620f1ce4c2c171330f5b62857 # shrinks to pb = MempoolInvariantsProblem([Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x507230d365c6eb2de9b5cc6ef286a337887c9c3d814bab629169b4e2caff6ea),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0x0),force=false)), Insert(Insert(ty=Declare,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x507230d365c6eb2de9b5cc6ef286a337887c9c3d814bab629169b4e2caff6ea),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0x0),force=false)), Insert(Insert(ty=DeployAccount,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x1fc21bdea99da580a2ae18cd35e73807659ef33b93421601bfac0efeb6be459),contract_address=ContractAddress(PatriciaKey(0x7f)),nonce=Nonce(0x0),force=false)), Insert(Insert(ty=DeployAccount,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x156376e23be4af75f1114fa70a12b2f9ffd93ceea21d0d7f4ae45b72377762e),contract_address=ContractAddress(PatriciaKey(0x7f)),nonce=Nonce(0x1),force=true))]) -cc 8bb2a6bb05105d3c1e1795e5a6f1fd45f11d83e3cf509ba8f82104669617e6f5 # shrinks to pb = MempoolInvariantsProblem([Insert(Insert(ty=DeployAccount,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x3cd9a5152e98cdfa806a24a02d916b80e337c0e31012ff91ce1f69801da7b6e),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0xe4),force=false)), Insert(Insert(ty=DeployAccount,arrived_at=SystemTime { tv_sec: 0, tv_nsec: 0 },tx_hash=TransactionHash(0x3cd9a5152e98cdfa806a24a02d916b80e337c0e31012ff91ce1f69801da7b6e),contract_address=ContractAddress(PatriciaKey(0x0)),nonce=Nonce(0xe4),force=true))]) diff --git a/crates/cairo-test-contracts/Cargo.toml b/crates/madara/cairo-test-contracts/Cargo.toml similarity index 100% rename from crates/cairo-test-contracts/Cargo.toml rename to crates/madara/cairo-test-contracts/Cargo.toml diff --git a/crates/cairo-test-contracts/build.rs b/crates/madara/cairo-test-contracts/build.rs similarity index 100% rename from crates/cairo-test-contracts/build.rs rename to crates/madara/cairo-test-contracts/build.rs diff --git a/crates/cairo-test-contracts/src/lib.rs b/crates/madara/cairo-test-contracts/src/lib.rs similarity index 68% rename from crates/cairo-test-contracts/src/lib.rs rename to crates/madara/cairo-test-contracts/src/lib.rs index b4237ce0f..c89e65522 100644 --- a/crates/cairo-test-contracts/src/lib.rs +++ b/crates/madara/cairo-test-contracts/src/lib.rs @@ -2,4 +2,4 @@ //! tests need to be put in the `cairo-artifacts` folder at the root of the project`. pub const TEST_CONTRACT_SIERRA: &[u8] = - include_bytes!("../../../cairo/target/dev/madara_contracts_TestContract.contract_class.json"); + include_bytes!("../../../../cairo/target/dev/madara_contracts_TestContract.contract_class.json"); diff --git a/crates/client/analytics/Cargo.toml b/crates/madara/client/analytics/Cargo.toml similarity index 100% rename from crates/client/analytics/Cargo.toml rename to crates/madara/client/analytics/Cargo.toml diff --git a/crates/client/analytics/src/lib.rs b/crates/madara/client/analytics/src/lib.rs similarity index 100% rename from crates/client/analytics/src/lib.rs rename to crates/madara/client/analytics/src/lib.rs diff --git a/crates/client/block_import/Cargo.toml b/crates/madara/client/block_import/Cargo.toml similarity index 100% rename from crates/client/block_import/Cargo.toml rename to crates/madara/client/block_import/Cargo.toml diff --git a/crates/client/block_import/src/lib.rs b/crates/madara/client/block_import/src/lib.rs similarity index 100% rename from crates/client/block_import/src/lib.rs rename to crates/madara/client/block_import/src/lib.rs diff --git a/crates/client/block_import/src/metrics.rs b/crates/madara/client/block_import/src/metrics.rs similarity index 100% rename from crates/client/block_import/src/metrics.rs rename to crates/madara/client/block_import/src/metrics.rs diff --git a/crates/client/block_import/src/pre_validate.rs b/crates/madara/client/block_import/src/pre_validate.rs similarity index 100% rename from crates/client/block_import/src/pre_validate.rs rename to crates/madara/client/block_import/src/pre_validate.rs diff --git a/crates/client/block_import/src/rayon.rs b/crates/madara/client/block_import/src/rayon.rs similarity index 100% rename from crates/client/block_import/src/rayon.rs rename to crates/madara/client/block_import/src/rayon.rs diff --git a/crates/client/block_import/src/tests.rs b/crates/madara/client/block_import/src/tests.rs similarity index 100% rename from crates/client/block_import/src/tests.rs rename to crates/madara/client/block_import/src/tests.rs diff --git a/crates/client/block_import/src/tests/block_import_utils.rs b/crates/madara/client/block_import/src/tests/block_import_utils.rs similarity index 100% rename from crates/client/block_import/src/tests/block_import_utils.rs rename to crates/madara/client/block_import/src/tests/block_import_utils.rs diff --git a/crates/client/block_import/src/types.rs b/crates/madara/client/block_import/src/types.rs similarity index 100% rename from crates/client/block_import/src/types.rs rename to crates/madara/client/block_import/src/types.rs diff --git a/crates/client/block_import/src/verify_apply.rs b/crates/madara/client/block_import/src/verify_apply.rs similarity index 100% rename from crates/client/block_import/src/verify_apply.rs rename to crates/madara/client/block_import/src/verify_apply.rs diff --git a/crates/client/block_import/src/verify_apply/classes.rs b/crates/madara/client/block_import/src/verify_apply/classes.rs similarity index 100% rename from crates/client/block_import/src/verify_apply/classes.rs rename to crates/madara/client/block_import/src/verify_apply/classes.rs diff --git a/crates/client/block_import/src/verify_apply/contracts.rs b/crates/madara/client/block_import/src/verify_apply/contracts.rs similarity index 100% rename from crates/client/block_import/src/verify_apply/contracts.rs rename to crates/madara/client/block_import/src/verify_apply/contracts.rs diff --git a/crates/client/block_production/Cargo.toml b/crates/madara/client/block_production/Cargo.toml similarity index 100% rename from crates/client/block_production/Cargo.toml rename to crates/madara/client/block_production/Cargo.toml diff --git a/crates/client/block_production/src/close_block.rs b/crates/madara/client/block_production/src/close_block.rs similarity index 100% rename from crates/client/block_production/src/close_block.rs rename to crates/madara/client/block_production/src/close_block.rs diff --git a/crates/client/block_production/src/finalize_execution_state.rs b/crates/madara/client/block_production/src/finalize_execution_state.rs similarity index 100% rename from crates/client/block_production/src/finalize_execution_state.rs rename to crates/madara/client/block_production/src/finalize_execution_state.rs diff --git a/crates/client/block_production/src/lib.rs b/crates/madara/client/block_production/src/lib.rs similarity index 100% rename from crates/client/block_production/src/lib.rs rename to crates/madara/client/block_production/src/lib.rs diff --git a/crates/client/block_production/src/metrics.rs b/crates/madara/client/block_production/src/metrics.rs similarity index 100% rename from crates/client/block_production/src/metrics.rs rename to crates/madara/client/block_production/src/metrics.rs diff --git a/crates/client/block_production/src/re_add_finalized_to_blockifier.rs b/crates/madara/client/block_production/src/re_add_finalized_to_blockifier.rs similarity index 100% rename from crates/client/block_production/src/re_add_finalized_to_blockifier.rs rename to crates/madara/client/block_production/src/re_add_finalized_to_blockifier.rs diff --git a/crates/client/db/Cargo.toml b/crates/madara/client/db/Cargo.toml similarity index 100% rename from crates/client/db/Cargo.toml rename to crates/madara/client/db/Cargo.toml diff --git a/crates/client/db/docs/flat_storage.md b/crates/madara/client/db/docs/flat_storage.md similarity index 92% rename from crates/client/db/docs/flat_storage.md rename to crates/madara/client/db/docs/flat_storage.md index fea89c68f..136d2dca6 100644 --- a/crates/client/db/docs/flat_storage.md +++ b/crates/madara/client/db/docs/flat_storage.md @@ -6,14 +6,14 @@ We may want to remove that flat storage from bonsai-trie as it's not used and we Instead, we have implemented our own optimized lookup, which is implemented with a column that looks like this: -![schema flat_storage](./flat_storage.png) +![schema flat_storage](flat_storage.png) The trick here is to rely on the fact that rocksdb columns are sorted trees. The rocksdb `get` operation does not allow getting the value of (contract_1, key_1) at block 15 here, because the key has not been modified at that block. Instead, we use rocksdb iterators. -![schema flat_storage_iterator](./flat_storage_iterator.png) +![schema flat_storage_iterator](flat_storage_iterator.png) This allows us to get the most recent value for a (contract, key) at that block, by using a single rocksdb lookup. diff --git a/crates/client/db/docs/flat_storage.png b/crates/madara/client/db/docs/flat_storage.png similarity index 100% rename from crates/client/db/docs/flat_storage.png rename to crates/madara/client/db/docs/flat_storage.png diff --git a/crates/client/db/docs/flat_storage_iterator.png b/crates/madara/client/db/docs/flat_storage_iterator.png similarity index 100% rename from crates/client/db/docs/flat_storage_iterator.png rename to crates/madara/client/db/docs/flat_storage_iterator.png diff --git a/crates/client/db/src/block_db.rs b/crates/madara/client/db/src/block_db.rs similarity index 100% rename from crates/client/db/src/block_db.rs rename to crates/madara/client/db/src/block_db.rs diff --git a/crates/client/db/src/bonsai_db.rs b/crates/madara/client/db/src/bonsai_db.rs similarity index 100% rename from crates/client/db/src/bonsai_db.rs rename to crates/madara/client/db/src/bonsai_db.rs diff --git a/crates/client/db/src/class_db.rs b/crates/madara/client/db/src/class_db.rs similarity index 100% rename from crates/client/db/src/class_db.rs rename to crates/madara/client/db/src/class_db.rs diff --git a/crates/client/db/src/contract_db.rs b/crates/madara/client/db/src/contract_db.rs similarity index 100% rename from crates/client/db/src/contract_db.rs rename to crates/madara/client/db/src/contract_db.rs diff --git a/crates/client/db/src/db_block_id.rs b/crates/madara/client/db/src/db_block_id.rs similarity index 100% rename from crates/client/db/src/db_block_id.rs rename to crates/madara/client/db/src/db_block_id.rs diff --git a/crates/client/db/src/db_metrics.rs b/crates/madara/client/db/src/db_metrics.rs similarity index 100% rename from crates/client/db/src/db_metrics.rs rename to crates/madara/client/db/src/db_metrics.rs diff --git a/crates/client/db/src/devnet_db.rs b/crates/madara/client/db/src/devnet_db.rs similarity index 100% rename from crates/client/db/src/devnet_db.rs rename to crates/madara/client/db/src/devnet_db.rs diff --git a/crates/client/db/src/error.rs b/crates/madara/client/db/src/error.rs similarity index 100% rename from crates/client/db/src/error.rs rename to crates/madara/client/db/src/error.rs diff --git a/crates/client/db/src/l1_db.rs b/crates/madara/client/db/src/l1_db.rs similarity index 100% rename from crates/client/db/src/l1_db.rs rename to crates/madara/client/db/src/l1_db.rs diff --git a/crates/client/db/src/lib.rs b/crates/madara/client/db/src/lib.rs similarity index 100% rename from crates/client/db/src/lib.rs rename to crates/madara/client/db/src/lib.rs diff --git a/crates/client/db/src/mempool_db.rs b/crates/madara/client/db/src/mempool_db.rs similarity index 100% rename from crates/client/db/src/mempool_db.rs rename to crates/madara/client/db/src/mempool_db.rs diff --git a/crates/client/db/src/rocksdb_options.rs b/crates/madara/client/db/src/rocksdb_options.rs similarity index 100% rename from crates/client/db/src/rocksdb_options.rs rename to crates/madara/client/db/src/rocksdb_options.rs diff --git a/crates/client/db/src/rocksdb_snapshot.rs b/crates/madara/client/db/src/rocksdb_snapshot.rs similarity index 100% rename from crates/client/db/src/rocksdb_snapshot.rs rename to crates/madara/client/db/src/rocksdb_snapshot.rs diff --git a/crates/client/db/src/snapshots.rs b/crates/madara/client/db/src/snapshots.rs similarity index 100% rename from crates/client/db/src/snapshots.rs rename to crates/madara/client/db/src/snapshots.rs diff --git a/crates/client/db/src/storage_updates.rs b/crates/madara/client/db/src/storage_updates.rs similarity index 100% rename from crates/client/db/src/storage_updates.rs rename to crates/madara/client/db/src/storage_updates.rs diff --git a/crates/client/db/src/tests.rs b/crates/madara/client/db/src/tests.rs similarity index 100% rename from crates/client/db/src/tests.rs rename to crates/madara/client/db/src/tests.rs diff --git a/crates/client/db/src/tests/common/mod.rs b/crates/madara/client/db/src/tests/common/mod.rs similarity index 100% rename from crates/client/db/src/tests/common/mod.rs rename to crates/madara/client/db/src/tests/common/mod.rs diff --git a/crates/client/db/src/tests/test_block.rs b/crates/madara/client/db/src/tests/test_block.rs similarity index 100% rename from crates/client/db/src/tests/test_block.rs rename to crates/madara/client/db/src/tests/test_block.rs diff --git a/crates/client/db/src/tests/test_open.rs b/crates/madara/client/db/src/tests/test_open.rs similarity index 100% rename from crates/client/db/src/tests/test_open.rs rename to crates/madara/client/db/src/tests/test_open.rs diff --git a/crates/client/devnet/Cargo.toml b/crates/madara/client/devnet/Cargo.toml similarity index 100% rename from crates/client/devnet/Cargo.toml rename to crates/madara/client/devnet/Cargo.toml diff --git a/crates/client/devnet/README.md b/crates/madara/client/devnet/README.md similarity index 98% rename from crates/client/devnet/README.md rename to crates/madara/client/devnet/README.md index 8c25f4101..e4ad0a37e 100644 --- a/crates/client/devnet/README.md +++ b/crates/madara/client/devnet/README.md @@ -1,7 +1,7 @@ # Devnet predeployed contract addresses The devnet always has the predeployed contract addresses at these addresses, with these private keys. -They are OpenZeppelin contracts, see [cairo-artifacts](../../../cairo-artifacts/README.md). +They are OpenZeppelin contracts, see [cairo-artifacts](../../../../cairo-artifacts/README.md). They are also shown on node startup. ```sh diff --git a/crates/client/devnet/src/balances.rs b/crates/madara/client/devnet/src/balances.rs similarity index 100% rename from crates/client/devnet/src/balances.rs rename to crates/madara/client/devnet/src/balances.rs diff --git a/crates/client/devnet/src/classes.rs b/crates/madara/client/devnet/src/classes.rs similarity index 100% rename from crates/client/devnet/src/classes.rs rename to crates/madara/client/devnet/src/classes.rs diff --git a/crates/client/devnet/src/contracts.rs b/crates/madara/client/devnet/src/contracts.rs similarity index 100% rename from crates/client/devnet/src/contracts.rs rename to crates/madara/client/devnet/src/contracts.rs diff --git a/crates/client/devnet/src/entrypoint.rs b/crates/madara/client/devnet/src/entrypoint.rs similarity index 100% rename from crates/client/devnet/src/entrypoint.rs rename to crates/madara/client/devnet/src/entrypoint.rs diff --git a/crates/client/devnet/src/lib.rs b/crates/madara/client/devnet/src/lib.rs similarity index 99% rename from crates/client/devnet/src/lib.rs rename to crates/madara/client/devnet/src/lib.rs index 1be4f1929..4a90592b4 100644 --- a/crates/client/devnet/src/lib.rs +++ b/crates/madara/client/devnet/src/lib.rs @@ -52,19 +52,19 @@ impl StorageDiffs { // We allow ourselves to lie about the contract_address. This is because we want the UDC and the two ERC20 contracts to have well known addresses on every chain. /// Universal Deployer Contract. -const UDC_CLASS_DEFINITION: &[u8] = include_bytes!("../../../../cairo-artifacts/madara_contracts_UDC.json"); +const UDC_CLASS_DEFINITION: &[u8] = include_bytes!("../../../../../cairo-artifacts/madara_contracts_UDC.json"); const UDC_CONTRACT_ADDRESS: Felt = Felt::from_hex_unchecked("0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf"); const ERC20_CLASS_DEFINITION: &[u8] = - include_bytes!("../../../../cairo-artifacts/openzeppelin_ERC20Upgradeable.contract_class.json"); + include_bytes!("../../../../../cairo-artifacts/openzeppelin_ERC20Upgradeable.contract_class.json"); const ERC20_STRK_CONTRACT_ADDRESS: Felt = Felt::from_hex_unchecked("0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d"); const ERC20_ETH_CONTRACT_ADDRESS: Felt = Felt::from_hex_unchecked("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"); const ACCOUNT_CLASS_DEFINITION: &[u8] = - include_bytes!("../../../../cairo-artifacts/openzeppelin_AccountUpgradeable.contract_class.json"); + include_bytes!("../../../../../cairo-artifacts/openzeppelin_AccountUpgradeable.contract_class.json"); /// High level description of the genesis block. #[derive(Clone, Debug, Default)] diff --git a/crates/client/devnet/src/predeployed_contracts.rs b/crates/madara/client/devnet/src/predeployed_contracts.rs similarity index 100% rename from crates/client/devnet/src/predeployed_contracts.rs rename to crates/madara/client/devnet/src/predeployed_contracts.rs diff --git a/crates/client/exec/Cargo.toml b/crates/madara/client/exec/Cargo.toml similarity index 100% rename from crates/client/exec/Cargo.toml rename to crates/madara/client/exec/Cargo.toml diff --git a/crates/client/exec/src/block_context.rs b/crates/madara/client/exec/src/block_context.rs similarity index 100% rename from crates/client/exec/src/block_context.rs rename to crates/madara/client/exec/src/block_context.rs diff --git a/crates/client/exec/src/blockifier_state_adapter.rs b/crates/madara/client/exec/src/blockifier_state_adapter.rs similarity index 100% rename from crates/client/exec/src/blockifier_state_adapter.rs rename to crates/madara/client/exec/src/blockifier_state_adapter.rs diff --git a/crates/client/exec/src/call.rs b/crates/madara/client/exec/src/call.rs similarity index 100% rename from crates/client/exec/src/call.rs rename to crates/madara/client/exec/src/call.rs diff --git a/crates/client/exec/src/execution.rs b/crates/madara/client/exec/src/execution.rs similarity index 100% rename from crates/client/exec/src/execution.rs rename to crates/madara/client/exec/src/execution.rs diff --git a/crates/client/exec/src/fee.rs b/crates/madara/client/exec/src/fee.rs similarity index 100% rename from crates/client/exec/src/fee.rs rename to crates/madara/client/exec/src/fee.rs diff --git a/crates/client/exec/src/lib.rs b/crates/madara/client/exec/src/lib.rs similarity index 100% rename from crates/client/exec/src/lib.rs rename to crates/madara/client/exec/src/lib.rs diff --git a/crates/client/exec/src/trace.rs b/crates/madara/client/exec/src/trace.rs similarity index 100% rename from crates/client/exec/src/trace.rs rename to crates/madara/client/exec/src/trace.rs diff --git a/crates/client/exec/src/transaction.rs b/crates/madara/client/exec/src/transaction.rs similarity index 100% rename from crates/client/exec/src/transaction.rs rename to crates/madara/client/exec/src/transaction.rs diff --git a/crates/client/gateway/client/Cargo.toml b/crates/madara/client/gateway/client/Cargo.toml similarity index 100% rename from crates/client/gateway/client/Cargo.toml rename to crates/madara/client/gateway/client/Cargo.toml diff --git a/crates/client/gateway/client/src/builder.rs b/crates/madara/client/gateway/client/src/builder.rs similarity index 100% rename from crates/client/gateway/client/src/builder.rs rename to crates/madara/client/gateway/client/src/builder.rs diff --git a/crates/client/gateway/client/src/lib.rs b/crates/madara/client/gateway/client/src/lib.rs similarity index 100% rename from crates/client/gateway/client/src/lib.rs rename to crates/madara/client/gateway/client/src/lib.rs diff --git a/crates/client/gateway/client/src/methods.rs b/crates/madara/client/gateway/client/src/methods.rs similarity index 100% rename from crates/client/gateway/client/src/methods.rs rename to crates/madara/client/gateway/client/src/methods.rs diff --git a/crates/client/gateway/client/src/mocks/class_block_0_0x010455c752b86932ce552f2b0fe81a880746649b9aee7e0d842bf3f52378f9f8.gz b/crates/madara/client/gateway/client/src/mocks/class_block_0_0x010455c752b86932ce552f2b0fe81a880746649b9aee7e0d842bf3f52378f9f8.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/class_block_0_0x010455c752b86932ce552f2b0fe81a880746649b9aee7e0d842bf3f52378f9f8.gz rename to crates/madara/client/gateway/client/src/mocks/class_block_0_0x010455c752b86932ce552f2b0fe81a880746649b9aee7e0d842bf3f52378f9f8.gz diff --git a/crates/client/gateway/client/src/mocks/class_block_1342_account_0x07595b4f7d50010ceb00230d8b5656e3c3dd201b6df35d805d3f2988c69a1432.gz b/crates/madara/client/gateway/client/src/mocks/class_block_1342_account_0x07595b4f7d50010ceb00230d8b5656e3c3dd201b6df35d805d3f2988c69a1432.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/class_block_1342_account_0x07595b4f7d50010ceb00230d8b5656e3c3dd201b6df35d805d3f2988c69a1432.gz rename to crates/madara/client/gateway/client/src/mocks/class_block_1342_account_0x07595b4f7d50010ceb00230d8b5656e3c3dd201b6df35d805d3f2988c69a1432.gz diff --git a/crates/client/gateway/client/src/mocks/class_block_1343_proxy_0x071c3c99f5cf76fc19945d4b8b7d34c7c5528f22730d56192b50c6bbfd338a64.gz b/crates/madara/client/gateway/client/src/mocks/class_block_1343_proxy_0x071c3c99f5cf76fc19945d4b8b7d34c7c5528f22730d56192b50c6bbfd338a64.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/class_block_1343_proxy_0x071c3c99f5cf76fc19945d4b8b7d34c7c5528f22730d56192b50c6bbfd338a64.gz rename to crates/madara/client/gateway/client/src/mocks/class_block_1343_proxy_0x071c3c99f5cf76fc19945d4b8b7d34c7c5528f22730d56192b50c6bbfd338a64.gz diff --git a/crates/client/gateway/client/src/mocks/class_block_18507_erc1155_0x04be7f1bace6f593abd8e56947c11151f45498030748a950fdaf0b79ac3dc03f.gz b/crates/madara/client/gateway/client/src/mocks/class_block_18507_erc1155_0x04be7f1bace6f593abd8e56947c11151f45498030748a950fdaf0b79ac3dc03f.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/class_block_18507_erc1155_0x04be7f1bace6f593abd8e56947c11151f45498030748a950fdaf0b79ac3dc03f.gz rename to crates/madara/client/gateway/client/src/mocks/class_block_18507_erc1155_0x04be7f1bace6f593abd8e56947c11151f45498030748a950fdaf0b79ac3dc03f.gz diff --git a/crates/client/gateway/client/src/mocks/class_block_1981_erc20_0x07543f8eb21f10b1827a495084697a519274ac9c1a1fbf931bac40133a6b9c15.gz b/crates/madara/client/gateway/client/src/mocks/class_block_1981_erc20_0x07543f8eb21f10b1827a495084697a519274ac9c1a1fbf931bac40133a6b9c15.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/class_block_1981_erc20_0x07543f8eb21f10b1827a495084697a519274ac9c1a1fbf931bac40133a6b9c15.gz rename to crates/madara/client/gateway/client/src/mocks/class_block_1981_erc20_0x07543f8eb21f10b1827a495084697a519274ac9c1a1fbf931bac40133a6b9c15.gz diff --git a/crates/client/gateway/client/src/mocks/class_block_3125_erc721_0x074a7ed7f1236225600f355efe70812129658c82c295ff0f8307b3fad4bf09a9.gz b/crates/madara/client/gateway/client/src/mocks/class_block_3125_erc721_0x074a7ed7f1236225600f355efe70812129658c82c295ff0f8307b3fad4bf09a9.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/class_block_3125_erc721_0x074a7ed7f1236225600f355efe70812129658c82c295ff0f8307b3fad4bf09a9.gz rename to crates/madara/client/gateway/client/src/mocks/class_block_3125_erc721_0x074a7ed7f1236225600f355efe70812129658c82c295ff0f8307b3fad4bf09a9.gz diff --git a/crates/client/gateway/client/src/mocks/signature_block_0.gz b/crates/madara/client/gateway/client/src/mocks/signature_block_0.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/signature_block_0.gz rename to crates/madara/client/gateway/client/src/mocks/signature_block_0.gz diff --git a/crates/client/gateway/client/src/mocks/signature_block_1.gz b/crates/madara/client/gateway/client/src/mocks/signature_block_1.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/signature_block_1.gz rename to crates/madara/client/gateway/client/src/mocks/signature_block_1.gz diff --git a/crates/client/gateway/client/src/mocks/signature_block_2.gz b/crates/madara/client/gateway/client/src/mocks/signature_block_2.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/signature_block_2.gz rename to crates/madara/client/gateway/client/src/mocks/signature_block_2.gz diff --git a/crates/client/gateway/client/src/mocks/state_update_and_block_0.gz b/crates/madara/client/gateway/client/src/mocks/state_update_and_block_0.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/state_update_and_block_0.gz rename to crates/madara/client/gateway/client/src/mocks/state_update_and_block_0.gz diff --git a/crates/client/gateway/client/src/mocks/state_update_and_block_1.gz b/crates/madara/client/gateway/client/src/mocks/state_update_and_block_1.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/state_update_and_block_1.gz rename to crates/madara/client/gateway/client/src/mocks/state_update_and_block_1.gz diff --git a/crates/client/gateway/client/src/mocks/state_update_and_block_2.gz b/crates/madara/client/gateway/client/src/mocks/state_update_and_block_2.gz similarity index 100% rename from crates/client/gateway/client/src/mocks/state_update_and_block_2.gz rename to crates/madara/client/gateway/client/src/mocks/state_update_and_block_2.gz diff --git a/crates/client/gateway/client/src/request_builder.rs b/crates/madara/client/gateway/client/src/request_builder.rs similarity index 100% rename from crates/client/gateway/client/src/request_builder.rs rename to crates/madara/client/gateway/client/src/request_builder.rs diff --git a/crates/client/gateway/server/Cargo.toml b/crates/madara/client/gateway/server/Cargo.toml similarity index 100% rename from crates/client/gateway/server/Cargo.toml rename to crates/madara/client/gateway/server/Cargo.toml diff --git a/crates/client/gateway/server/src/error.rs b/crates/madara/client/gateway/server/src/error.rs similarity index 100% rename from crates/client/gateway/server/src/error.rs rename to crates/madara/client/gateway/server/src/error.rs diff --git a/crates/client/gateway/server/src/handler.rs b/crates/madara/client/gateway/server/src/handler.rs similarity index 100% rename from crates/client/gateway/server/src/handler.rs rename to crates/madara/client/gateway/server/src/handler.rs diff --git a/crates/client/gateway/server/src/helpers.rs b/crates/madara/client/gateway/server/src/helpers.rs similarity index 100% rename from crates/client/gateway/server/src/helpers.rs rename to crates/madara/client/gateway/server/src/helpers.rs diff --git a/crates/client/gateway/server/src/lib.rs b/crates/madara/client/gateway/server/src/lib.rs similarity index 100% rename from crates/client/gateway/server/src/lib.rs rename to crates/madara/client/gateway/server/src/lib.rs diff --git a/crates/client/gateway/server/src/router.rs b/crates/madara/client/gateway/server/src/router.rs similarity index 100% rename from crates/client/gateway/server/src/router.rs rename to crates/madara/client/gateway/server/src/router.rs diff --git a/crates/client/gateway/server/src/service.rs b/crates/madara/client/gateway/server/src/service.rs similarity index 100% rename from crates/client/gateway/server/src/service.rs rename to crates/madara/client/gateway/server/src/service.rs diff --git a/crates/client/mempool/Cargo.toml b/crates/madara/client/mempool/Cargo.toml similarity index 100% rename from crates/client/mempool/Cargo.toml rename to crates/madara/client/mempool/Cargo.toml diff --git a/crates/client/mempool/src/header.rs b/crates/madara/client/mempool/src/header.rs similarity index 100% rename from crates/client/mempool/src/header.rs rename to crates/madara/client/mempool/src/header.rs diff --git a/crates/client/mempool/src/inner/deployed_contracts.rs b/crates/madara/client/mempool/src/inner/deployed_contracts.rs similarity index 100% rename from crates/client/mempool/src/inner/deployed_contracts.rs rename to crates/madara/client/mempool/src/inner/deployed_contracts.rs diff --git a/crates/client/mempool/src/inner/limits.rs b/crates/madara/client/mempool/src/inner/limits.rs similarity index 100% rename from crates/client/mempool/src/inner/limits.rs rename to crates/madara/client/mempool/src/inner/limits.rs diff --git a/crates/client/mempool/src/inner/mod.rs b/crates/madara/client/mempool/src/inner/mod.rs similarity index 100% rename from crates/client/mempool/src/inner/mod.rs rename to crates/madara/client/mempool/src/inner/mod.rs diff --git a/crates/client/mempool/src/inner/nonce_chain.rs b/crates/madara/client/mempool/src/inner/nonce_chain.rs similarity index 100% rename from crates/client/mempool/src/inner/nonce_chain.rs rename to crates/madara/client/mempool/src/inner/nonce_chain.rs diff --git a/crates/client/mempool/src/inner/proptest.rs b/crates/madara/client/mempool/src/inner/proptest.rs similarity index 100% rename from crates/client/mempool/src/inner/proptest.rs rename to crates/madara/client/mempool/src/inner/proptest.rs diff --git a/crates/client/mempool/src/inner/tx.rs b/crates/madara/client/mempool/src/inner/tx.rs similarity index 100% rename from crates/client/mempool/src/inner/tx.rs rename to crates/madara/client/mempool/src/inner/tx.rs diff --git a/crates/client/mempool/src/l1.rs b/crates/madara/client/mempool/src/l1.rs similarity index 100% rename from crates/client/mempool/src/l1.rs rename to crates/madara/client/mempool/src/l1.rs diff --git a/crates/client/mempool/src/lib.rs b/crates/madara/client/mempool/src/lib.rs similarity index 100% rename from crates/client/mempool/src/lib.rs rename to crates/madara/client/mempool/src/lib.rs diff --git a/crates/client/mempool/src/metrics.rs b/crates/madara/client/mempool/src/metrics.rs similarity index 100% rename from crates/client/mempool/src/metrics.rs rename to crates/madara/client/mempool/src/metrics.rs diff --git a/crates/client/mempool/src/tx.rs b/crates/madara/client/mempool/src/tx.rs similarity index 100% rename from crates/client/mempool/src/tx.rs rename to crates/madara/client/mempool/src/tx.rs diff --git a/crates/client/rpc/Cargo.toml b/crates/madara/client/rpc/Cargo.toml similarity index 100% rename from crates/client/rpc/Cargo.toml rename to crates/madara/client/rpc/Cargo.toml diff --git a/crates/client/rpc/src/RPC.md b/crates/madara/client/rpc/src/RPC.md similarity index 100% rename from crates/client/rpc/src/RPC.md rename to crates/madara/client/rpc/src/RPC.md diff --git a/crates/client/rpc/src/constants.rs b/crates/madara/client/rpc/src/constants.rs similarity index 100% rename from crates/client/rpc/src/constants.rs rename to crates/madara/client/rpc/src/constants.rs diff --git a/crates/client/rpc/src/errors.rs b/crates/madara/client/rpc/src/errors.rs similarity index 100% rename from crates/client/rpc/src/errors.rs rename to crates/madara/client/rpc/src/errors.rs diff --git a/crates/client/rpc/src/lib.rs b/crates/madara/client/rpc/src/lib.rs similarity index 100% rename from crates/client/rpc/src/lib.rs rename to crates/madara/client/rpc/src/lib.rs diff --git a/crates/client/rpc/src/providers/forward_to_provider.rs b/crates/madara/client/rpc/src/providers/forward_to_provider.rs similarity index 100% rename from crates/client/rpc/src/providers/forward_to_provider.rs rename to crates/madara/client/rpc/src/providers/forward_to_provider.rs diff --git a/crates/client/rpc/src/providers/mempool.rs b/crates/madara/client/rpc/src/providers/mempool.rs similarity index 100% rename from crates/client/rpc/src/providers/mempool.rs rename to crates/madara/client/rpc/src/providers/mempool.rs diff --git a/crates/client/rpc/src/providers/mod.rs b/crates/madara/client/rpc/src/providers/mod.rs similarity index 100% rename from crates/client/rpc/src/providers/mod.rs rename to crates/madara/client/rpc/src/providers/mod.rs diff --git a/crates/client/rpc/src/test_utils.rs b/crates/madara/client/rpc/src/test_utils.rs similarity index 100% rename from crates/client/rpc/src/test_utils.rs rename to crates/madara/client/rpc/src/test_utils.rs diff --git a/crates/client/rpc/src/types.rs b/crates/madara/client/rpc/src/types.rs similarity index 100% rename from crates/client/rpc/src/types.rs rename to crates/madara/client/rpc/src/types.rs diff --git a/crates/client/rpc/src/utils/mod.rs b/crates/madara/client/rpc/src/utils/mod.rs similarity index 100% rename from crates/client/rpc/src/utils/mod.rs rename to crates/madara/client/rpc/src/utils/mod.rs diff --git a/crates/client/rpc/src/versions/admin/mod.rs b/crates/madara/client/rpc/src/versions/admin/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/admin/mod.rs rename to crates/madara/client/rpc/src/versions/admin/mod.rs diff --git a/crates/client/rpc/src/versions/admin/v0_1_0/api.rs b/crates/madara/client/rpc/src/versions/admin/v0_1_0/api.rs similarity index 100% rename from crates/client/rpc/src/versions/admin/v0_1_0/api.rs rename to crates/madara/client/rpc/src/versions/admin/v0_1_0/api.rs diff --git a/crates/client/rpc/src/versions/admin/v0_1_0/methods/mod.rs b/crates/madara/client/rpc/src/versions/admin/v0_1_0/methods/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/admin/v0_1_0/methods/mod.rs rename to crates/madara/client/rpc/src/versions/admin/v0_1_0/methods/mod.rs diff --git a/crates/client/rpc/src/versions/admin/v0_1_0/methods/services.rs b/crates/madara/client/rpc/src/versions/admin/v0_1_0/methods/services.rs similarity index 100% rename from crates/client/rpc/src/versions/admin/v0_1_0/methods/services.rs rename to crates/madara/client/rpc/src/versions/admin/v0_1_0/methods/services.rs diff --git a/crates/client/rpc/src/versions/admin/v0_1_0/methods/status.rs b/crates/madara/client/rpc/src/versions/admin/v0_1_0/methods/status.rs similarity index 100% rename from crates/client/rpc/src/versions/admin/v0_1_0/methods/status.rs rename to crates/madara/client/rpc/src/versions/admin/v0_1_0/methods/status.rs diff --git a/crates/client/rpc/src/versions/admin/v0_1_0/methods/write.rs b/crates/madara/client/rpc/src/versions/admin/v0_1_0/methods/write.rs similarity index 100% rename from crates/client/rpc/src/versions/admin/v0_1_0/methods/write.rs rename to crates/madara/client/rpc/src/versions/admin/v0_1_0/methods/write.rs diff --git a/crates/client/rpc/src/versions/admin/v0_1_0/mod.rs b/crates/madara/client/rpc/src/versions/admin/v0_1_0/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/admin/v0_1_0/mod.rs rename to crates/madara/client/rpc/src/versions/admin/v0_1_0/mod.rs diff --git a/crates/client/rpc/src/versions/mod.rs b/crates/madara/client/rpc/src/versions/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/mod.rs rename to crates/madara/client/rpc/src/versions/mod.rs diff --git a/crates/client/rpc/src/versions/user/mod.rs b/crates/madara/client/rpc/src/versions/user/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/mod.rs rename to crates/madara/client/rpc/src/versions/user/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/api.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/api.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/api.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/api.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/block_hash_and_number.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/block_hash_and_number.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/block_hash_and_number.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/block_hash_and_number.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/call.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/call.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/call.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/call.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_fee.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_fee.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_fee.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_fee.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_message_fee.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_message_fee.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_message_fee.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/estimate_message_fee.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_transaction_count.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_transaction_count.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_transaction_count.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_transaction_count.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_receipts.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_receipts.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_receipts.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_receipts.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_tx_hashes.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_tx_hashes.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_tx_hashes.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_tx_hashes.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_txs.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_txs.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_txs.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_block_with_txs.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_class.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_class.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_class.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_class.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_at.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_at.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_at.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_at.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_hash_at.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_hash_at.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_hash_at.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_class_hash_at.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_events.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_events.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_events.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_events.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_nonce.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_nonce.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_nonce.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_nonce.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_state_update.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_state_update.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_state_update.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_state_update.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_storage_at.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_storage_at.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_storage_at.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_storage_at.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_block_id_and_index.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_block_id_and_index.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_block_id_and_index.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_block_id_and_index.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_hash.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_hash.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_hash.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_by_hash.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_receipt.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_receipt.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_receipt.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_receipt.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_status.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_status.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_status.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/get_transaction_status.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/lib.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/lib.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/lib.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/lib.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/read/syncing.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/syncing.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/read/syncing.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/read/syncing.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/trace/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/trace/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/trace/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/trace/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/trace/simulate_transactions.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/trace/simulate_transactions.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/trace/simulate_transactions.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/trace/simulate_transactions.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_block_transactions.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_block_transactions.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_block_transactions.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_block_transactions.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_transaction.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_transaction.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_transaction.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/trace/trace_transaction.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/methods/write/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/methods/write/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/methods/write/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/methods/write/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_7_1/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_7_1/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_7_1/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_7_1/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_8_0/api.rs b/crates/madara/client/rpc/src/versions/user/v0_8_0/api.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_8_0/api.rs rename to crates/madara/client/rpc/src/versions/user/v0_8_0/api.rs diff --git a/crates/client/rpc/src/versions/user/v0_8_0/methods/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_8_0/methods/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_8_0/methods/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_8_0/methods/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_8_0/methods/read/get_compiled_casm.rs b/crates/madara/client/rpc/src/versions/user/v0_8_0/methods/read/get_compiled_casm.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_8_0/methods/read/get_compiled_casm.rs rename to crates/madara/client/rpc/src/versions/user/v0_8_0/methods/read/get_compiled_casm.rs diff --git a/crates/client/rpc/src/versions/user/v0_8_0/methods/read/get_storage_proof.rs b/crates/madara/client/rpc/src/versions/user/v0_8_0/methods/read/get_storage_proof.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_8_0/methods/read/get_storage_proof.rs rename to crates/madara/client/rpc/src/versions/user/v0_8_0/methods/read/get_storage_proof.rs diff --git a/crates/client/rpc/src/versions/user/v0_8_0/methods/read/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_8_0/methods/read/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_8_0/methods/read/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_8_0/methods/read/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_8_0/methods/ws/lib.rs b/crates/madara/client/rpc/src/versions/user/v0_8_0/methods/ws/lib.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_8_0/methods/ws/lib.rs rename to crates/madara/client/rpc/src/versions/user/v0_8_0/methods/ws/lib.rs diff --git a/crates/client/rpc/src/versions/user/v0_8_0/methods/ws/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_8_0/methods/ws/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_8_0/methods/ws/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_8_0/methods/ws/mod.rs diff --git a/crates/client/rpc/src/versions/user/v0_8_0/mod.rs b/crates/madara/client/rpc/src/versions/user/v0_8_0/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/user/v0_8_0/mod.rs rename to crates/madara/client/rpc/src/versions/user/v0_8_0/mod.rs diff --git a/crates/client/rpc/src/versions/v0_8_0/api.rs b/crates/madara/client/rpc/src/versions/v0_8_0/api.rs similarity index 100% rename from crates/client/rpc/src/versions/v0_8_0/api.rs rename to crates/madara/client/rpc/src/versions/v0_8_0/api.rs diff --git a/crates/client/rpc/src/versions/v0_8_0/methods/mod.rs b/crates/madara/client/rpc/src/versions/v0_8_0/methods/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/v0_8_0/methods/mod.rs rename to crates/madara/client/rpc/src/versions/v0_8_0/methods/mod.rs diff --git a/crates/client/rpc/src/versions/v0_8_0/methods/read/mod.rs b/crates/madara/client/rpc/src/versions/v0_8_0/methods/read/mod.rs similarity index 100% rename from crates/client/rpc/src/versions/v0_8_0/methods/read/mod.rs rename to crates/madara/client/rpc/src/versions/v0_8_0/methods/read/mod.rs diff --git a/crates/client/settlement_client/Cargo.toml b/crates/madara/client/settlement_client/Cargo.toml similarity index 100% rename from crates/client/settlement_client/Cargo.toml rename to crates/madara/client/settlement_client/Cargo.toml diff --git a/crates/client/settlement_client/README.md b/crates/madara/client/settlement_client/README.md similarity index 100% rename from crates/client/settlement_client/README.md rename to crates/madara/client/settlement_client/README.md diff --git a/crates/client/settlement_client/src/client.rs b/crates/madara/client/settlement_client/src/client.rs similarity index 100% rename from crates/client/settlement_client/src/client.rs rename to crates/madara/client/settlement_client/src/client.rs diff --git a/crates/client/settlement_client/src/error.rs b/crates/madara/client/settlement_client/src/error.rs similarity index 100% rename from crates/client/settlement_client/src/error.rs rename to crates/madara/client/settlement_client/src/error.rs diff --git a/crates/client/settlement_client/src/eth/event.rs b/crates/madara/client/settlement_client/src/eth/event.rs similarity index 100% rename from crates/client/settlement_client/src/eth/event.rs rename to crates/madara/client/settlement_client/src/eth/event.rs diff --git a/crates/client/settlement_client/src/eth/mod.rs b/crates/madara/client/settlement_client/src/eth/mod.rs similarity index 100% rename from crates/client/settlement_client/src/eth/mod.rs rename to crates/madara/client/settlement_client/src/eth/mod.rs diff --git a/crates/client/settlement_client/src/eth/starknet_core.json b/crates/madara/client/settlement_client/src/eth/starknet_core.json similarity index 100% rename from crates/client/settlement_client/src/eth/starknet_core.json rename to crates/madara/client/settlement_client/src/eth/starknet_core.json diff --git a/crates/client/settlement_client/src/gas_price.rs b/crates/madara/client/settlement_client/src/gas_price.rs similarity index 100% rename from crates/client/settlement_client/src/gas_price.rs rename to crates/madara/client/settlement_client/src/gas_price.rs diff --git a/crates/client/settlement_client/src/lib.rs b/crates/madara/client/settlement_client/src/lib.rs similarity index 100% rename from crates/client/settlement_client/src/lib.rs rename to crates/madara/client/settlement_client/src/lib.rs diff --git a/crates/client/settlement_client/src/messaging/mod.rs b/crates/madara/client/settlement_client/src/messaging/mod.rs similarity index 100% rename from crates/client/settlement_client/src/messaging/mod.rs rename to crates/madara/client/settlement_client/src/messaging/mod.rs diff --git a/crates/client/settlement_client/src/messaging/tests.rs b/crates/madara/client/settlement_client/src/messaging/tests.rs similarity index 100% rename from crates/client/settlement_client/src/messaging/tests.rs rename to crates/madara/client/settlement_client/src/messaging/tests.rs diff --git a/crates/client/settlement_client/src/starknet/event.rs b/crates/madara/client/settlement_client/src/starknet/event.rs similarity index 100% rename from crates/client/settlement_client/src/starknet/event.rs rename to crates/madara/client/settlement_client/src/starknet/event.rs diff --git a/crates/client/settlement_client/src/starknet/mod.rs b/crates/madara/client/settlement_client/src/starknet/mod.rs similarity index 100% rename from crates/client/settlement_client/src/starknet/mod.rs rename to crates/madara/client/settlement_client/src/starknet/mod.rs diff --git a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo b/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo similarity index 100% rename from crates/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo rename to crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo diff --git a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json b/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json similarity index 100% rename from crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json rename to crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json diff --git a/crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json b/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json similarity index 100% rename from crates/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json rename to crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo b/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo similarity index 100% rename from crates/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo rename to crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json b/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json similarity index 100% rename from crates/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json rename to crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json diff --git a/crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json b/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json similarity index 100% rename from crates/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json rename to crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json diff --git a/crates/client/settlement_client/src/starknet/utils.rs b/crates/madara/client/settlement_client/src/starknet/utils.rs similarity index 100% rename from crates/client/settlement_client/src/starknet/utils.rs rename to crates/madara/client/settlement_client/src/starknet/utils.rs diff --git a/crates/client/settlement_client/src/state_update.rs b/crates/madara/client/settlement_client/src/state_update.rs similarity index 100% rename from crates/client/settlement_client/src/state_update.rs rename to crates/madara/client/settlement_client/src/state_update.rs diff --git a/crates/client/settlement_client/src/sync.rs b/crates/madara/client/settlement_client/src/sync.rs similarity index 100% rename from crates/client/settlement_client/src/sync.rs rename to crates/madara/client/settlement_client/src/sync.rs diff --git a/crates/client/settlement_client/src/utils.rs b/crates/madara/client/settlement_client/src/utils.rs similarity index 100% rename from crates/client/settlement_client/src/utils.rs rename to crates/madara/client/settlement_client/src/utils.rs diff --git a/crates/client/sync/Cargo.toml b/crates/madara/client/sync/Cargo.toml similarity index 100% rename from crates/client/sync/Cargo.toml rename to crates/madara/client/sync/Cargo.toml diff --git a/crates/client/sync/src/fetch/fetchers.rs b/crates/madara/client/sync/src/fetch/fetchers.rs similarity index 100% rename from crates/client/sync/src/fetch/fetchers.rs rename to crates/madara/client/sync/src/fetch/fetchers.rs diff --git a/crates/client/sync/src/fetch/fetchers_real_fgw_test.rs b/crates/madara/client/sync/src/fetch/fetchers_real_fgw_test.rs similarity index 100% rename from crates/client/sync/src/fetch/fetchers_real_fgw_test.rs rename to crates/madara/client/sync/src/fetch/fetchers_real_fgw_test.rs diff --git a/crates/client/sync/src/fetch/mod.rs b/crates/madara/client/sync/src/fetch/mod.rs similarity index 100% rename from crates/client/sync/src/fetch/mod.rs rename to crates/madara/client/sync/src/fetch/mod.rs diff --git a/crates/client/sync/src/l2.rs b/crates/madara/client/sync/src/l2.rs similarity index 100% rename from crates/client/sync/src/l2.rs rename to crates/madara/client/sync/src/l2.rs diff --git a/crates/client/sync/src/lib.rs b/crates/madara/client/sync/src/lib.rs similarity index 100% rename from crates/client/sync/src/lib.rs rename to crates/madara/client/sync/src/lib.rs diff --git a/crates/client/sync/src/metrics/block_metrics.rs b/crates/madara/client/sync/src/metrics/block_metrics.rs similarity index 100% rename from crates/client/sync/src/metrics/block_metrics.rs rename to crates/madara/client/sync/src/metrics/block_metrics.rs diff --git a/crates/client/sync/src/metrics/mod.rs b/crates/madara/client/sync/src/metrics/mod.rs similarity index 100% rename from crates/client/sync/src/metrics/mod.rs rename to crates/madara/client/sync/src/metrics/mod.rs diff --git a/crates/client/sync/src/tests/mod.rs b/crates/madara/client/sync/src/tests/mod.rs similarity index 100% rename from crates/client/sync/src/tests/mod.rs rename to crates/madara/client/sync/src/tests/mod.rs diff --git a/crates/client/sync/src/tests/utils/gateway.rs b/crates/madara/client/sync/src/tests/utils/gateway.rs similarity index 100% rename from crates/client/sync/src/tests/utils/gateway.rs rename to crates/madara/client/sync/src/tests/utils/gateway.rs diff --git a/crates/client/sync/src/tests/utils/mod.rs b/crates/madara/client/sync/src/tests/utils/mod.rs similarity index 100% rename from crates/client/sync/src/tests/utils/mod.rs rename to crates/madara/client/sync/src/tests/utils/mod.rs diff --git a/crates/client/sync/src/tests/utils/read_resource.rs b/crates/madara/client/sync/src/tests/utils/read_resource.rs similarity index 100% rename from crates/client/sync/src/tests/utils/read_resource.rs rename to crates/madara/client/sync/src/tests/utils/read_resource.rs diff --git a/crates/client/sync/src/tests/utils/retry.rs b/crates/madara/client/sync/src/tests/utils/retry.rs similarity index 100% rename from crates/client/sync/src/tests/utils/retry.rs rename to crates/madara/client/sync/src/tests/utils/retry.rs diff --git a/crates/client/sync/src/utils.rs b/crates/madara/client/sync/src/utils.rs similarity index 100% rename from crates/client/sync/src/utils.rs rename to crates/madara/client/sync/src/utils.rs diff --git a/crates/client/sync/test-data/block_0.json b/crates/madara/client/sync/test-data/block_0.json similarity index 100% rename from crates/client/sync/test-data/block_0.json rename to crates/madara/client/sync/test-data/block_0.json diff --git a/crates/client/sync/test-data/block_724130.json b/crates/madara/client/sync/test-data/block_724130.json similarity index 100% rename from crates/client/sync/test-data/block_724130.json rename to crates/madara/client/sync/test-data/block_724130.json diff --git a/crates/client/telemetry/Cargo.toml b/crates/madara/client/telemetry/Cargo.toml similarity index 100% rename from crates/client/telemetry/Cargo.toml rename to crates/madara/client/telemetry/Cargo.toml diff --git a/crates/client/telemetry/build.rs b/crates/madara/client/telemetry/build.rs similarity index 100% rename from crates/client/telemetry/build.rs rename to crates/madara/client/telemetry/build.rs diff --git a/crates/client/telemetry/src/lib.rs b/crates/madara/client/telemetry/src/lib.rs similarity index 100% rename from crates/client/telemetry/src/lib.rs rename to crates/madara/client/telemetry/src/lib.rs diff --git a/crates/client/telemetry/src/sysinfo.rs b/crates/madara/client/telemetry/src/sysinfo.rs similarity index 100% rename from crates/client/telemetry/src/sysinfo.rs rename to crates/madara/client/telemetry/src/sysinfo.rs diff --git a/crates/node/Cargo.toml b/crates/madara/node/Cargo.toml similarity index 100% rename from crates/node/Cargo.toml rename to crates/madara/node/Cargo.toml diff --git a/crates/node/build.rs b/crates/madara/node/build.rs similarity index 100% rename from crates/node/build.rs rename to crates/madara/node/build.rs diff --git a/crates/node/src/cli/analytics.rs b/crates/madara/node/src/cli/analytics.rs similarity index 100% rename from crates/node/src/cli/analytics.rs rename to crates/madara/node/src/cli/analytics.rs diff --git a/crates/node/src/cli/block_production.rs b/crates/madara/node/src/cli/block_production.rs similarity index 100% rename from crates/node/src/cli/block_production.rs rename to crates/madara/node/src/cli/block_production.rs diff --git a/crates/node/src/cli/chain_config_overrides.rs b/crates/madara/node/src/cli/chain_config_overrides.rs similarity index 100% rename from crates/node/src/cli/chain_config_overrides.rs rename to crates/madara/node/src/cli/chain_config_overrides.rs diff --git a/crates/node/src/cli/db.rs b/crates/madara/node/src/cli/db.rs similarity index 100% rename from crates/node/src/cli/db.rs rename to crates/madara/node/src/cli/db.rs diff --git a/crates/node/src/cli/gateway.rs b/crates/madara/node/src/cli/gateway.rs similarity index 100% rename from crates/node/src/cli/gateway.rs rename to crates/madara/node/src/cli/gateway.rs diff --git a/crates/node/src/cli/l1.rs b/crates/madara/node/src/cli/l1.rs similarity index 100% rename from crates/node/src/cli/l1.rs rename to crates/madara/node/src/cli/l1.rs diff --git a/crates/node/src/cli/l2.rs b/crates/madara/node/src/cli/l2.rs similarity index 100% rename from crates/node/src/cli/l2.rs rename to crates/madara/node/src/cli/l2.rs diff --git a/crates/node/src/cli/mod.rs b/crates/madara/node/src/cli/mod.rs similarity index 100% rename from crates/node/src/cli/mod.rs rename to crates/madara/node/src/cli/mod.rs diff --git a/crates/node/src/cli/rpc.rs b/crates/madara/node/src/cli/rpc.rs similarity index 100% rename from crates/node/src/cli/rpc.rs rename to crates/madara/node/src/cli/rpc.rs diff --git a/crates/node/src/cli/telemetry.rs b/crates/madara/node/src/cli/telemetry.rs similarity index 100% rename from crates/node/src/cli/telemetry.rs rename to crates/madara/node/src/cli/telemetry.rs diff --git a/crates/node/src/main.rs b/crates/madara/node/src/main.rs similarity index 100% rename from crates/node/src/main.rs rename to crates/madara/node/src/main.rs diff --git a/crates/node/src/service/block_production.rs b/crates/madara/node/src/service/block_production.rs similarity index 100% rename from crates/node/src/service/block_production.rs rename to crates/madara/node/src/service/block_production.rs diff --git a/crates/node/src/service/database.rs b/crates/madara/node/src/service/database.rs similarity index 100% rename from crates/node/src/service/database.rs rename to crates/madara/node/src/service/database.rs diff --git a/crates/node/src/service/gateway.rs b/crates/madara/node/src/service/gateway.rs similarity index 100% rename from crates/node/src/service/gateway.rs rename to crates/madara/node/src/service/gateway.rs diff --git a/crates/node/src/service/l1.rs b/crates/madara/node/src/service/l1.rs similarity index 100% rename from crates/node/src/service/l1.rs rename to crates/madara/node/src/service/l1.rs diff --git a/crates/node/src/service/l2.rs b/crates/madara/node/src/service/l2.rs similarity index 100% rename from crates/node/src/service/l2.rs rename to crates/madara/node/src/service/l2.rs diff --git a/crates/node/src/service/mod.rs b/crates/madara/node/src/service/mod.rs similarity index 100% rename from crates/node/src/service/mod.rs rename to crates/madara/node/src/service/mod.rs diff --git a/crates/node/src/service/rpc/metrics.rs b/crates/madara/node/src/service/rpc/metrics.rs similarity index 100% rename from crates/node/src/service/rpc/metrics.rs rename to crates/madara/node/src/service/rpc/metrics.rs diff --git a/crates/node/src/service/rpc/middleware.rs b/crates/madara/node/src/service/rpc/middleware.rs similarity index 100% rename from crates/node/src/service/rpc/middleware.rs rename to crates/madara/node/src/service/rpc/middleware.rs diff --git a/crates/node/src/service/rpc/mod.rs b/crates/madara/node/src/service/rpc/mod.rs similarity index 100% rename from crates/node/src/service/rpc/mod.rs rename to crates/madara/node/src/service/rpc/mod.rs diff --git a/crates/node/src/service/rpc/server.rs b/crates/madara/node/src/service/rpc/server.rs similarity index 100% rename from crates/node/src/service/rpc/server.rs rename to crates/madara/node/src/service/rpc/server.rs diff --git a/crates/node/src/util.rs b/crates/madara/node/src/util.rs similarity index 100% rename from crates/node/src/util.rs rename to crates/madara/node/src/util.rs diff --git a/crates/primitives/block/Cargo.toml b/crates/madara/primitives/block/Cargo.toml similarity index 100% rename from crates/primitives/block/Cargo.toml rename to crates/madara/primitives/block/Cargo.toml diff --git a/crates/primitives/block/src/header.rs b/crates/madara/primitives/block/src/header.rs similarity index 100% rename from crates/primitives/block/src/header.rs rename to crates/madara/primitives/block/src/header.rs diff --git a/crates/primitives/block/src/lib.rs b/crates/madara/primitives/block/src/lib.rs similarity index 100% rename from crates/primitives/block/src/lib.rs rename to crates/madara/primitives/block/src/lib.rs diff --git a/crates/primitives/chain_config/Cargo.toml b/crates/madara/primitives/chain_config/Cargo.toml similarity index 100% rename from crates/primitives/chain_config/Cargo.toml rename to crates/madara/primitives/chain_config/Cargo.toml diff --git a/crates/primitives/chain_config/resources/versioned_constants_13_0.json b/crates/madara/primitives/chain_config/resources/versioned_constants_13_0.json similarity index 100% rename from crates/primitives/chain_config/resources/versioned_constants_13_0.json rename to crates/madara/primitives/chain_config/resources/versioned_constants_13_0.json diff --git a/crates/primitives/chain_config/resources/versioned_constants_13_1.json b/crates/madara/primitives/chain_config/resources/versioned_constants_13_1.json similarity index 100% rename from crates/primitives/chain_config/resources/versioned_constants_13_1.json rename to crates/madara/primitives/chain_config/resources/versioned_constants_13_1.json diff --git a/crates/primitives/chain_config/resources/versioned_constants_13_1_1.json b/crates/madara/primitives/chain_config/resources/versioned_constants_13_1_1.json similarity index 100% rename from crates/primitives/chain_config/resources/versioned_constants_13_1_1.json rename to crates/madara/primitives/chain_config/resources/versioned_constants_13_1_1.json diff --git a/crates/primitives/chain_config/resources/versioned_constants_13_2.json b/crates/madara/primitives/chain_config/resources/versioned_constants_13_2.json similarity index 100% rename from crates/primitives/chain_config/resources/versioned_constants_13_2.json rename to crates/madara/primitives/chain_config/resources/versioned_constants_13_2.json diff --git a/crates/primitives/chain_config/src/chain_config.rs b/crates/madara/primitives/chain_config/src/chain_config.rs similarity index 98% rename from crates/primitives/chain_config/src/chain_config.rs rename to crates/madara/primitives/chain_config/src/chain_config.rs index 38253aa16..262798382 100644 --- a/crates/primitives/chain_config/src/chain_config.rs +++ b/crates/madara/primitives/chain_config/src/chain_config.rs @@ -465,7 +465,8 @@ mod tests { // Change the current directory std::env::set_current_dir("../../../").expect("Failed to change directory"); let chain_config: ChainConfig = - ChainConfig::from_yaml(Path::new("configs/presets/mainnet.yaml")).expect("failed to get cfg"); + ChainConfig::from_yaml(Path::new("../../../../../configs/presets/mainnet.yaml")) + .expect("failed to get cfg"); assert_eq!(chain_config.chain_name, "Starknet Mainnet"); assert_eq!(chain_config.chain_id, ChainId::Mainnet); @@ -479,8 +480,8 @@ mod tests { // Check versioned constants // Load and parse the JSON file - let json_content = fs::read_to_string("crates/primitives/chain_config/resources/versioned_constants_13_0.json") - .expect("Failed to read JSON file"); + let json_content = + fs::read_to_string("../resources/versioned_constants_13_0.json").expect("Failed to read JSON file"); let json: Value = serde_json::from_str(&json_content).expect("Failed to parse JSON"); // Get the VersionedConstants for version 0.13.0 diff --git a/crates/primitives/chain_config/src/lib.rs b/crates/madara/primitives/chain_config/src/lib.rs similarity index 100% rename from crates/primitives/chain_config/src/lib.rs rename to crates/madara/primitives/chain_config/src/lib.rs diff --git a/crates/primitives/chain_config/src/rpc_version.rs b/crates/madara/primitives/chain_config/src/rpc_version.rs similarity index 100% rename from crates/primitives/chain_config/src/rpc_version.rs rename to crates/madara/primitives/chain_config/src/rpc_version.rs diff --git a/crates/primitives/chain_config/src/starknet_version.rs b/crates/madara/primitives/chain_config/src/starknet_version.rs similarity index 100% rename from crates/primitives/chain_config/src/starknet_version.rs rename to crates/madara/primitives/chain_config/src/starknet_version.rs diff --git a/crates/primitives/class/Cargo.toml b/crates/madara/primitives/class/Cargo.toml similarity index 100% rename from crates/primitives/class/Cargo.toml rename to crates/madara/primitives/class/Cargo.toml diff --git a/crates/primitives/class/resources/missed_classes.json b/crates/madara/primitives/class/resources/missed_classes.json similarity index 100% rename from crates/primitives/class/resources/missed_classes.json rename to crates/madara/primitives/class/resources/missed_classes.json diff --git a/crates/primitives/class/src/class_hash.rs b/crates/madara/primitives/class/src/class_hash.rs similarity index 100% rename from crates/primitives/class/src/class_hash.rs rename to crates/madara/primitives/class/src/class_hash.rs diff --git a/crates/primitives/class/src/class_update.rs b/crates/madara/primitives/class/src/class_update.rs similarity index 100% rename from crates/primitives/class/src/class_update.rs rename to crates/madara/primitives/class/src/class_update.rs diff --git a/crates/primitives/class/src/compile.rs b/crates/madara/primitives/class/src/compile.rs similarity index 100% rename from crates/primitives/class/src/compile.rs rename to crates/madara/primitives/class/src/compile.rs diff --git a/crates/primitives/class/src/convert.rs b/crates/madara/primitives/class/src/convert.rs similarity index 100% rename from crates/primitives/class/src/convert.rs rename to crates/madara/primitives/class/src/convert.rs diff --git a/crates/primitives/class/src/into_starknet_core.rs b/crates/madara/primitives/class/src/into_starknet_core.rs similarity index 100% rename from crates/primitives/class/src/into_starknet_core.rs rename to crates/madara/primitives/class/src/into_starknet_core.rs diff --git a/crates/primitives/class/src/into_starknet_types.rs b/crates/madara/primitives/class/src/into_starknet_types.rs similarity index 100% rename from crates/primitives/class/src/into_starknet_types.rs rename to crates/madara/primitives/class/src/into_starknet_types.rs diff --git a/crates/primitives/class/src/lib.rs b/crates/madara/primitives/class/src/lib.rs similarity index 100% rename from crates/primitives/class/src/lib.rs rename to crates/madara/primitives/class/src/lib.rs diff --git a/crates/primitives/convert/Cargo.toml b/crates/madara/primitives/convert/Cargo.toml similarity index 100% rename from crates/primitives/convert/Cargo.toml rename to crates/madara/primitives/convert/Cargo.toml diff --git a/crates/primitives/convert/src/felt.rs b/crates/madara/primitives/convert/src/felt.rs similarity index 100% rename from crates/primitives/convert/src/felt.rs rename to crates/madara/primitives/convert/src/felt.rs diff --git a/crates/primitives/convert/src/hex_serde.rs b/crates/madara/primitives/convert/src/hex_serde.rs similarity index 100% rename from crates/primitives/convert/src/hex_serde.rs rename to crates/madara/primitives/convert/src/hex_serde.rs diff --git a/crates/primitives/convert/src/lib.rs b/crates/madara/primitives/convert/src/lib.rs similarity index 100% rename from crates/primitives/convert/src/lib.rs rename to crates/madara/primitives/convert/src/lib.rs diff --git a/crates/primitives/convert/src/to_felt.rs b/crates/madara/primitives/convert/src/to_felt.rs similarity index 100% rename from crates/primitives/convert/src/to_felt.rs rename to crates/madara/primitives/convert/src/to_felt.rs diff --git a/crates/primitives/gateway/Cargo.toml b/crates/madara/primitives/gateway/Cargo.toml similarity index 100% rename from crates/primitives/gateway/Cargo.toml rename to crates/madara/primitives/gateway/Cargo.toml diff --git a/crates/primitives/gateway/src/block.rs b/crates/madara/primitives/gateway/src/block.rs similarity index 100% rename from crates/primitives/gateway/src/block.rs rename to crates/madara/primitives/gateway/src/block.rs diff --git a/crates/primitives/gateway/src/error.rs b/crates/madara/primitives/gateway/src/error.rs similarity index 100% rename from crates/primitives/gateway/src/error.rs rename to crates/madara/primitives/gateway/src/error.rs diff --git a/crates/primitives/gateway/src/lib.rs b/crates/madara/primitives/gateway/src/lib.rs similarity index 100% rename from crates/primitives/gateway/src/lib.rs rename to crates/madara/primitives/gateway/src/lib.rs diff --git a/crates/primitives/gateway/src/receipt.rs b/crates/madara/primitives/gateway/src/receipt.rs similarity index 100% rename from crates/primitives/gateway/src/receipt.rs rename to crates/madara/primitives/gateway/src/receipt.rs diff --git a/crates/primitives/gateway/src/state_update.rs b/crates/madara/primitives/gateway/src/state_update.rs similarity index 100% rename from crates/primitives/gateway/src/state_update.rs rename to crates/madara/primitives/gateway/src/state_update.rs diff --git a/crates/primitives/gateway/src/test.rs b/crates/madara/primitives/gateway/src/test.rs similarity index 100% rename from crates/primitives/gateway/src/test.rs rename to crates/madara/primitives/gateway/src/test.rs diff --git a/crates/primitives/gateway/src/transaction.rs b/crates/madara/primitives/gateway/src/transaction.rs similarity index 100% rename from crates/primitives/gateway/src/transaction.rs rename to crates/madara/primitives/gateway/src/transaction.rs diff --git a/crates/primitives/gateway/src/user_transaction.rs b/crates/madara/primitives/gateway/src/user_transaction.rs similarity index 100% rename from crates/primitives/gateway/src/user_transaction.rs rename to crates/madara/primitives/gateway/src/user_transaction.rs diff --git a/crates/primitives/oracle/Cargo.toml b/crates/madara/primitives/oracle/Cargo.toml similarity index 100% rename from crates/primitives/oracle/Cargo.toml rename to crates/madara/primitives/oracle/Cargo.toml diff --git a/crates/primitives/oracle/src/lib.rs b/crates/madara/primitives/oracle/src/lib.rs similarity index 100% rename from crates/primitives/oracle/src/lib.rs rename to crates/madara/primitives/oracle/src/lib.rs diff --git a/crates/primitives/oracle/src/pragma.rs b/crates/madara/primitives/oracle/src/pragma.rs similarity index 100% rename from crates/primitives/oracle/src/pragma.rs rename to crates/madara/primitives/oracle/src/pragma.rs diff --git a/crates/primitives/receipt/Cargo.toml b/crates/madara/primitives/receipt/Cargo.toml similarity index 100% rename from crates/primitives/receipt/Cargo.toml rename to crates/madara/primitives/receipt/Cargo.toml diff --git a/crates/primitives/receipt/src/from_blockifier.rs b/crates/madara/primitives/receipt/src/from_blockifier.rs similarity index 100% rename from crates/primitives/receipt/src/from_blockifier.rs rename to crates/madara/primitives/receipt/src/from_blockifier.rs diff --git a/crates/primitives/receipt/src/lib.rs b/crates/madara/primitives/receipt/src/lib.rs similarity index 100% rename from crates/primitives/receipt/src/lib.rs rename to crates/madara/primitives/receipt/src/lib.rs diff --git a/crates/primitives/receipt/src/to_starknet_types.rs b/crates/madara/primitives/receipt/src/to_starknet_types.rs similarity index 100% rename from crates/primitives/receipt/src/to_starknet_types.rs rename to crates/madara/primitives/receipt/src/to_starknet_types.rs diff --git a/crates/primitives/state_update/Cargo.toml b/crates/madara/primitives/state_update/Cargo.toml similarity index 100% rename from crates/primitives/state_update/Cargo.toml rename to crates/madara/primitives/state_update/Cargo.toml diff --git a/crates/primitives/state_update/src/into_starknet_types.rs b/crates/madara/primitives/state_update/src/into_starknet_types.rs similarity index 100% rename from crates/primitives/state_update/src/into_starknet_types.rs rename to crates/madara/primitives/state_update/src/into_starknet_types.rs diff --git a/crates/primitives/state_update/src/lib.rs b/crates/madara/primitives/state_update/src/lib.rs similarity index 100% rename from crates/primitives/state_update/src/lib.rs rename to crates/madara/primitives/state_update/src/lib.rs diff --git a/crates/primitives/transactions/Cargo.toml b/crates/madara/primitives/transactions/Cargo.toml similarity index 100% rename from crates/primitives/transactions/Cargo.toml rename to crates/madara/primitives/transactions/Cargo.toml diff --git a/crates/primitives/transactions/src/compute_hash.rs b/crates/madara/primitives/transactions/src/compute_hash.rs similarity index 100% rename from crates/primitives/transactions/src/compute_hash.rs rename to crates/madara/primitives/transactions/src/compute_hash.rs diff --git a/crates/primitives/transactions/src/from_blockifier.rs b/crates/madara/primitives/transactions/src/from_blockifier.rs similarity index 100% rename from crates/primitives/transactions/src/from_blockifier.rs rename to crates/madara/primitives/transactions/src/from_blockifier.rs diff --git a/crates/primitives/transactions/src/from_broadcasted_transaction.rs b/crates/madara/primitives/transactions/src/from_broadcasted_transaction.rs similarity index 100% rename from crates/primitives/transactions/src/from_broadcasted_transaction.rs rename to crates/madara/primitives/transactions/src/from_broadcasted_transaction.rs diff --git a/crates/primitives/transactions/src/from_starknet_types.rs b/crates/madara/primitives/transactions/src/from_starknet_types.rs similarity index 100% rename from crates/primitives/transactions/src/from_starknet_types.rs rename to crates/madara/primitives/transactions/src/from_starknet_types.rs diff --git a/crates/primitives/transactions/src/into_starknet_api.rs b/crates/madara/primitives/transactions/src/into_starknet_api.rs similarity index 100% rename from crates/primitives/transactions/src/into_starknet_api.rs rename to crates/madara/primitives/transactions/src/into_starknet_api.rs diff --git a/crates/primitives/transactions/src/lib.rs b/crates/madara/primitives/transactions/src/lib.rs similarity index 100% rename from crates/primitives/transactions/src/lib.rs rename to crates/madara/primitives/transactions/src/lib.rs diff --git a/crates/primitives/transactions/src/to_blockifier.rs b/crates/madara/primitives/transactions/src/to_blockifier.rs similarity index 100% rename from crates/primitives/transactions/src/to_blockifier.rs rename to crates/madara/primitives/transactions/src/to_blockifier.rs diff --git a/crates/primitives/transactions/src/to_starknet_types.rs b/crates/madara/primitives/transactions/src/to_starknet_types.rs similarity index 100% rename from crates/primitives/transactions/src/to_starknet_types.rs rename to crates/madara/primitives/transactions/src/to_starknet_types.rs diff --git a/crates/primitives/transactions/src/utils.rs b/crates/madara/primitives/transactions/src/utils.rs similarity index 100% rename from crates/primitives/transactions/src/utils.rs rename to crates/madara/primitives/transactions/src/utils.rs diff --git a/crates/primitives/utils/Cargo.toml b/crates/madara/primitives/utils/Cargo.toml similarity index 100% rename from crates/primitives/utils/Cargo.toml rename to crates/madara/primitives/utils/Cargo.toml diff --git a/crates/primitives/utils/src/crypto.rs b/crates/madara/primitives/utils/src/crypto.rs similarity index 100% rename from crates/primitives/utils/src/crypto.rs rename to crates/madara/primitives/utils/src/crypto.rs diff --git a/crates/primitives/utils/src/lib.rs b/crates/madara/primitives/utils/src/lib.rs similarity index 100% rename from crates/primitives/utils/src/lib.rs rename to crates/madara/primitives/utils/src/lib.rs diff --git a/crates/primitives/utils/src/parsers.rs b/crates/madara/primitives/utils/src/parsers.rs similarity index 100% rename from crates/primitives/utils/src/parsers.rs rename to crates/madara/primitives/utils/src/parsers.rs diff --git a/crates/primitives/utils/src/serde.rs b/crates/madara/primitives/utils/src/serde.rs similarity index 100% rename from crates/primitives/utils/src/serde.rs rename to crates/madara/primitives/utils/src/serde.rs diff --git a/crates/primitives/utils/src/service.rs b/crates/madara/primitives/utils/src/service.rs similarity index 100% rename from crates/primitives/utils/src/service.rs rename to crates/madara/primitives/utils/src/service.rs diff --git a/crates/proc-macros/Cargo.toml b/crates/madara/proc-macros/Cargo.toml similarity index 100% rename from crates/proc-macros/Cargo.toml rename to crates/madara/proc-macros/Cargo.toml diff --git a/crates/proc-macros/src/lib.rs b/crates/madara/proc-macros/src/lib.rs similarity index 100% rename from crates/proc-macros/src/lib.rs rename to crates/madara/proc-macros/src/lib.rs diff --git a/crates/tests/Cargo.toml b/crates/madara/tests/Cargo.toml similarity index 100% rename from crates/tests/Cargo.toml rename to crates/madara/tests/Cargo.toml diff --git a/crates/tests/src/devnet.rs b/crates/madara/tests/src/devnet.rs similarity index 100% rename from crates/tests/src/devnet.rs rename to crates/madara/tests/src/devnet.rs diff --git a/crates/tests/src/lib.rs b/crates/madara/tests/src/lib.rs similarity index 100% rename from crates/tests/src/lib.rs rename to crates/madara/tests/src/lib.rs diff --git a/crates/tests/src/rpc/mod.rs b/crates/madara/tests/src/rpc/mod.rs similarity index 100% rename from crates/tests/src/rpc/mod.rs rename to crates/madara/tests/src/rpc/mod.rs diff --git a/crates/tests/src/rpc/read.rs b/crates/madara/tests/src/rpc/read.rs similarity index 100% rename from crates/tests/src/rpc/read.rs rename to crates/madara/tests/src/rpc/read.rs diff --git a/crates/tests/src/rpc/test_utils/class_program.txt b/crates/madara/tests/src/rpc/test_utils/class_program.txt similarity index 100% rename from crates/tests/src/rpc/test_utils/class_program.txt rename to crates/madara/tests/src/rpc/test_utils/class_program.txt diff --git a/crates/tests/src/rpc/test_utils/compiled_class.json b/crates/madara/tests/src/rpc/test_utils/compiled_class.json similarity index 100% rename from crates/tests/src/rpc/test_utils/compiled_class.json rename to crates/madara/tests/src/rpc/test_utils/compiled_class.json diff --git a/crates/tests/src/rpc/test_utils/contract_class.json b/crates/madara/tests/src/rpc/test_utils/contract_class.json similarity index 100% rename from crates/tests/src/rpc/test_utils/contract_class.json rename to crates/madara/tests/src/rpc/test_utils/contract_class.json diff --git a/crates/tests/src/storage_proof.rs b/crates/madara/tests/src/storage_proof.rs similarity index 100% rename from crates/tests/src/storage_proof.rs rename to crates/madara/tests/src/storage_proof.rs diff --git a/crates/tests/test_devnet.yaml b/crates/madara/tests/test_devnet.yaml similarity index 100% rename from crates/tests/test_devnet.yaml rename to crates/madara/tests/test_devnet.yaml From 1d4d3a4e8159acdfb33ec01e3f26105b1a0e5f3e Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Thu, 16 Jan 2025 01:27:59 +0530 Subject: [PATCH 19/23] resolved comments --- Cargo.toml | 2 +- .../client/settlement_client/src/client.rs | 6 +- .../client/settlement_client/src/eth/event.rs | 1 - .../client/settlement_client/src/eth/mod.rs | 30 +--- .../client/settlement_client/src/gas_price.rs | 48 +++++-- .../settlement_client/src/messaging/tests.rs | 14 +- .../settlement_client/src/starknet/mod.rs | 42 ++---- .../settlement_client/src/state_update.rs | 28 ++-- .../client/settlement_client/src/sync.rs | 18 ++- crates/madara/client/sync/src/utils.rs | 13 -- crates/madara/node/src/main.rs | 37 +++-- crates/madara/node/src/service/l1.rs | 135 +++++++----------- crates/madara/node/src/service/mod.rs | 1 + .../chain_config/src/chain_config.rs | 10 +- 14 files changed, 158 insertions(+), 227 deletions(-) delete mode 100644 crates/madara/client/sync/src/utils.rs diff --git a/Cargo.toml b/Cargo.toml index 7ccd93226..68aa6ac4c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ members = [ "crates/madara/primitives/utils", "crates/madara/proc-macros", "crates/madara/tests", - "crates/madara/cairo-test-contracts", + "crates/madara/cairo-test-contracts", "crates/madara/client/block_production", ] resolver = "2" diff --git a/crates/madara/client/settlement_client/src/client.rs b/crates/madara/client/settlement_client/src/client.rs index f9066f457..3c652391c 100644 --- a/crates/madara/client/settlement_client/src/client.rs +++ b/crates/madara/client/settlement_client/src/client.rs @@ -22,9 +22,6 @@ pub trait ClientTrait: Send + Sync { // Get client type fn get_client_type(&self) -> ClientType; - // Basic getter functions - fn get_l1_block_metrics(&self) -> &L1BlockMetrics; - // Create a new instance of the client async fn new(config: Self::Config) -> anyhow::Result where @@ -33,7 +30,7 @@ pub trait ClientTrait: Send + Sync { // Get the latest block number async fn get_latest_block_number(&self) -> anyhow::Result; - // Get the block number of the last occurrence of a specific event + // Get the block number of the last occurrence of the state update event async fn get_last_event_block_number(&self) -> anyhow::Result; // Get the last verified block number @@ -55,6 +52,7 @@ pub trait ClientTrait: Send + Sync { &self, backend: Arc, ctx: ServiceContext, + l1_block_metrics: Arc, ) -> anyhow::Result<()>; // get gas prices diff --git a/crates/madara/client/settlement_client/src/eth/event.rs b/crates/madara/client/settlement_client/src/eth/event.rs index 04ad63b4f..a53b7e23b 100644 --- a/crates/madara/client/settlement_client/src/eth/event.rs +++ b/crates/madara/client/settlement_client/src/eth/event.rs @@ -129,7 +129,6 @@ mod eth_event_stream_tests { Ok(event_data) => { assert_eq!(event_data.block_number, 100); assert_eq!(event_data.event_index, Some(0u64)); - // Add more assertions as needed } _ => panic!("Expected successful event"), } diff --git a/crates/madara/client/settlement_client/src/eth/mod.rs b/crates/madara/client/settlement_client/src/eth/mod.rs index 4e09806a9..43891743f 100644 --- a/crates/madara/client/settlement_client/src/eth/mod.rs +++ b/crates/madara/client/settlement_client/src/eth/mod.rs @@ -40,23 +40,17 @@ const ERR_ARCHIVE: &str = pub struct EthereumClient { pub provider: Arc, pub l1_core_contract: StarknetCoreContractInstance, RootProvider>>, - pub l1_block_metrics: L1BlockMetrics, } #[derive(Clone)] pub struct EthereumClientConfig { pub url: Url, pub l1_core_address: Address, - pub l1_block_metrics: L1BlockMetrics, } impl Clone for EthereumClient { fn clone(&self) -> Self { - EthereumClient { - provider: Arc::clone(&self.provider), - l1_core_contract: self.l1_core_contract.clone(), - l1_block_metrics: self.l1_block_metrics.clone(), - } + EthereumClient { provider: Arc::clone(&self.provider), l1_core_contract: self.l1_core_contract.clone() } } } @@ -68,10 +62,6 @@ impl ClientTrait for EthereumClient { ClientType::ETH } - fn get_l1_block_metrics(&self) -> &L1BlockMetrics { - &self.l1_block_metrics - } - /// Create a new EthereumClient instance with the given RPC URL async fn new(config: EthereumClientConfig) -> anyhow::Result { let provider = ProviderBuilder::new().on_http(config.url); @@ -81,11 +71,7 @@ impl ClientTrait for EthereumClient { bail!("The L1 Core Contract could not be found. Check that the L2 chain matches the L1 RPC endpoint."); } let core_contract = StarknetCoreContract::new(config.l1_core_address, provider.clone()); - Ok(Self { - provider: Arc::new(provider), - l1_core_contract: core_contract, - l1_block_metrics: config.l1_block_metrics, - }) + Ok(Self { provider: Arc::new(provider), l1_core_contract: core_contract }) } /// Retrieves the latest Ethereum block number @@ -150,6 +136,7 @@ impl ClientTrait for EthereumClient { &self, backend: Arc, mut ctx: ServiceContext, + l1_block_metrics: Arc, ) -> anyhow::Result<()> { // Listen to LogStateUpdate (0x77552641) update and send changes continuously let event_filter = self.l1_core_contract.event_filter::(); @@ -163,7 +150,7 @@ impl ClientTrait for EthereumClient { let log = event_result.context("listening for events")?; let format_event: StateUpdate = convert_log_state_update(log.0.clone()).context("formatting event into an L1StateUpdate")?; - update_l1(&backend, format_event, self.get_l1_block_metrics())?; + update_l1(&backend, format_event, l1_block_metrics.clone())?; } Ok(()) @@ -248,7 +235,6 @@ pub mod eth_client_getter_test { primitives::U256, }; - use crate::gas_price::L1BlockMetrics; use serial_test::serial; use std::ops::Range; use std::sync::Mutex; @@ -322,9 +308,7 @@ pub mod eth_client_getter_test { let address = Address::parse_checksummed(CORE_CONTRACT_ADDRESS, None).unwrap(); let contract = StarknetCoreContract::new(address, provider.clone()); - let l1_block_metrics = L1BlockMetrics::register().unwrap(); - - EthereumClient { provider: Arc::new(provider), l1_core_contract: contract.clone(), l1_block_metrics } + EthereumClient { provider: Arc::new(provider), l1_core_contract: contract.clone() } } #[serial] @@ -337,10 +321,8 @@ pub mod eth_client_getter_test { let rpc_url: Url = anvil.endpoint_url(); let core_contract_address = Address::parse_checksummed(INVALID_CORE_CONTRACT_ADDRESS, None).unwrap(); - let l1_block_metrics = L1BlockMetrics::register().unwrap(); - let ethereum_client_config = - EthereumClientConfig { url: rpc_url, l1_core_address: core_contract_address, l1_block_metrics }; + let ethereum_client_config = EthereumClientConfig { url: rpc_url, l1_core_address: core_contract_address }; let new_client_result = EthereumClient::new(ethereum_client_config).await; assert!(new_client_result.is_err(), "EthereumClient::new should fail with an invalid core contract address"); diff --git a/crates/madara/client/settlement_client/src/gas_price.rs b/crates/madara/client/settlement_client/src/gas_price.rs index f6986799d..55b782cb9 100644 --- a/crates/madara/client/settlement_client/src/gas_price.rs +++ b/crates/madara/client/settlement_client/src/gas_price.rs @@ -62,11 +62,12 @@ pub async fn gas_price_worker_once( settlement_client: Arc>>, l1_gas_provider: &GasPriceProvider, gas_price_poll_ms: Duration, + l1_block_metrics: Arc, ) -> anyhow::Result<()> where S: Stream>> + Send + 'static, { - match update_gas_price(settlement_client, l1_gas_provider).await { + match update_gas_price(settlement_client, l1_gas_provider, l1_block_metrics).await { Ok(_) => tracing::trace!("Updated gas prices"), Err(e) => tracing::error!("Failed to update gas prices: {:?}", e), } @@ -91,6 +92,7 @@ pub async fn gas_price_worker( l1_gas_provider: GasPriceProvider, gas_price_poll_ms: Duration, mut ctx: ServiceContext, + l1_block_metrics: Arc, ) -> anyhow::Result<()> where S: Stream>> + Send + 'static, @@ -100,7 +102,13 @@ where interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip); while ctx.run_until_cancelled(interval.tick()).await.is_some() { - gas_price_worker_once(Arc::clone(&settlement_client), &l1_gas_provider, gas_price_poll_ms).await?; + gas_price_worker_once( + Arc::clone(&settlement_client), + &l1_gas_provider, + gas_price_poll_ms, + l1_block_metrics.clone(), + ) + .await?; } anyhow::Ok(()) @@ -109,6 +117,7 @@ where async fn update_gas_price( settlement_client: Arc>>, l1_gas_provider: &GasPriceProvider, + l1_block_metrics: Arc, ) -> anyhow::Result<()> where S: Stream>> + Send + 'static, @@ -144,19 +153,15 @@ where l1_gas_provider.update_last_update_timestamp(); // Update block number separately to avoid holding the lock for too long - update_l1_block_metrics( - settlement_client.get_latest_block_number().await?, - settlement_client.get_l1_block_metrics(), - l1_gas_provider, - ) - .await?; + update_l1_block_metrics(settlement_client.get_latest_block_number().await?, l1_block_metrics, l1_gas_provider) + .await?; Ok(()) } async fn update_l1_block_metrics( block_number: u64, - l1_block_metrics: &L1BlockMetrics, + l1_block_metrics: Arc, l1_gas_provider: &GasPriceProvider, ) -> anyhow::Result<()> { // Get the current gas price @@ -195,6 +200,8 @@ mod eth_client_gas_price_worker_test { let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str())); let l1_gas_provider = GasPriceProvider::new(); + let l1_block_metrics = L1BlockMetrics::register().expect("Failed to register L1 block metrics"); + // Spawn the gas_price_worker in a separate task let worker_handle: JoinHandle> = tokio::spawn({ let eth_client = eth_client.clone(); @@ -205,6 +212,7 @@ mod eth_client_gas_price_worker_test { l1_gas_provider, Duration::from_millis(200), ServiceContext::new_for_testing(), + Arc::new(l1_block_metrics), ) .await } @@ -239,11 +247,14 @@ mod eth_client_gas_price_worker_test { let eth_client = create_ethereum_client(Some(anvil.endpoint().as_str())); let l1_gas_provider = GasPriceProvider::new(); + let l1_block_metrics = L1BlockMetrics::register().expect("Failed to register L1 block metrics"); + // Run the worker for a short time let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), + Arc::new(l1_block_metrics), ); // Wait for the worker to complete @@ -264,11 +275,14 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.update_eth_l1_gas_price(20); l1_gas_provider.set_gas_price_sync_enabled(false); + let l1_block_metrics = L1BlockMetrics::register().expect("Failed to register L1 block metrics"); + // Run the worker for a short time let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), + Arc::new(l1_block_metrics), ); // Wait for the worker to complete @@ -289,11 +303,14 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.update_eth_l1_data_gas_price(20); l1_gas_provider.set_data_gas_price_sync_enabled(false); + let l1_block_metrics = L1BlockMetrics::register().expect("Failed to register L1 block metrics"); + // Run the worker for a short time let worker_handle = gas_price_worker_once::( Arc::new(Box::new(eth_client)), &l1_gas_provider, Duration::from_millis(200), + Arc::new(l1_block_metrics), ); // Wait for the worker to complete @@ -311,6 +328,7 @@ mod eth_client_gas_price_worker_test { let mock_server = MockServer::start(); let addr = format!("http://{}", mock_server.address()); let eth_client = create_ethereum_client(Some(&addr)); + let l1_block_metrics = L1BlockMetrics::register().expect("Failed to register L1 block metrics"); let mock = mock_server.mock(|when, then| { when.method("POST").path("/").json_body_obj(&serde_json::json!({ @@ -349,6 +367,7 @@ mod eth_client_gas_price_worker_test { l1_gas_provider.clone(), Duration::from_millis(200), ServiceContext::new_for_testing(), + Arc::new(l1_block_metrics), ), ) .await; @@ -379,11 +398,16 @@ mod eth_client_gas_price_worker_test { let l1_gas_provider = GasPriceProvider::new(); l1_gas_provider.update_last_update_timestamp(); + let l1_block_metrics = L1BlockMetrics::register().expect("Failed to register L1 block metrics"); // Update gas prices - update_gas_price::(Arc::new(Box::new(eth_client)), &l1_gas_provider) - .await - .expect("Failed to update gas prices"); + update_gas_price::( + Arc::new(Box::new(eth_client)), + &l1_gas_provider, + Arc::new(l1_block_metrics), + ) + .await + .expect("Failed to update gas prices"); // Access the updated gas prices let updated_prices = l1_gas_provider.get_gas_prices(); diff --git a/crates/madara/client/settlement_client/src/messaging/tests.rs b/crates/madara/client/settlement_client/src/messaging/tests.rs index 01935144e..2a4970429 100644 --- a/crates/madara/client/settlement_client/src/messaging/tests.rs +++ b/crates/madara/client/settlement_client/src/messaging/tests.rs @@ -1,7 +1,6 @@ #[cfg(test)] mod l2_messaging_test { use crate::client::ClientTrait; - use crate::gas_price::L1BlockMetrics; use crate::messaging::sync; use crate::starknet::utils::{ cancel_messaging_event, fire_messaging_event, prepare_starknet_client_messaging_test, MadaraProcess, @@ -51,11 +50,9 @@ mod l2_messaging_test { .expect("Failed to create database service"), ); - let l1_block_metrics = L1BlockMetrics::register().unwrap(); let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str()).unwrap(), l2_contract_address: deployed_contract_address, - l1_block_metrics, }) .await .unwrap(); @@ -272,7 +269,6 @@ mod l1_messaging_tests { use self::DummyContract::DummyContractInstance; use crate::client::ClientTrait; use crate::eth::{EthereumClient, StarknetCoreContract}; - use crate::gas_price::L1BlockMetrics; use crate::messaging::{sync, CommonMessagingEventData}; use alloy::{ hex::FromHex, @@ -410,9 +406,6 @@ mod l1_messaging_tests { MempoolLimits::for_testing(), )); - // Set up metrics service - let l1_block_metrics = L1BlockMetrics::register().unwrap(); - // Set up provider let rpc_url: Url = anvil.endpoint().parse().expect("issue while parsing"); let provider = ProviderBuilder::new().on_http(rpc_url); @@ -422,11 +415,8 @@ mod l1_messaging_tests { let core_contract = StarknetCoreContract::new(*contract.address(), provider.clone()); - let eth_client = EthereumClient { - provider: Arc::new(provider.clone()), - l1_core_contract: core_contract.clone(), - l1_block_metrics: l1_block_metrics.clone(), - }; + let eth_client = + EthereumClient { provider: Arc::new(provider.clone()), l1_core_contract: core_contract.clone() }; TestRunner { anvil, chain_config, db_service: db, dummy_contract: contract, eth_client, mempool } } diff --git a/crates/madara/client/settlement_client/src/starknet/mod.rs b/crates/madara/client/settlement_client/src/starknet/mod.rs index a631206ca..ff6865b27 100644 --- a/crates/madara/client/settlement_client/src/starknet/mod.rs +++ b/crates/madara/client/settlement_client/src/starknet/mod.rs @@ -29,23 +29,17 @@ pub mod utils; pub struct StarknetClient { pub provider: Arc>, pub l2_core_contract: Felt, - pub l1_block_metrics: L1BlockMetrics, } #[derive(Clone)] pub struct StarknetClientConfig { pub url: Url, pub l2_contract_address: Felt, - pub l1_block_metrics: L1BlockMetrics, } impl Clone for StarknetClient { fn clone(&self) -> Self { - StarknetClient { - provider: Arc::clone(&self.provider), - l2_core_contract: self.l2_core_contract, - l1_block_metrics: self.l1_block_metrics.clone(), - } + StarknetClient { provider: Arc::clone(&self.provider), l2_core_contract: self.l2_core_contract } } } @@ -60,10 +54,6 @@ impl ClientTrait for StarknetClient { ClientType::STARKNET } - fn get_l1_block_metrics(&self) -> &L1BlockMetrics { - &self.l1_block_metrics - } - async fn new(config: Self::Config) -> anyhow::Result where Self: Sized, @@ -72,11 +62,7 @@ impl ClientTrait for StarknetClient { // Check if l2 contract exists : // If contract is not there this will error out. provider.get_class_at(BlockId::Tag(BlockTag::Latest), config.l2_contract_address).await?; - Ok(Self { - provider: Arc::new(provider), - l2_core_contract: config.l2_contract_address, - l1_block_metrics: config.l1_block_metrics, - }) + Ok(Self { provider: Arc::new(provider), l2_core_contract: config.l2_contract_address }) } async fn get_latest_block_number(&self) -> anyhow::Result { @@ -154,6 +140,7 @@ impl ClientTrait for StarknetClient { &self, backend: Arc, mut ctx: ServiceContext, + l1_block_metrics: Arc, ) -> anyhow::Result<()> { loop { let events_response = ctx.run_until_cancelled(self.get_events( @@ -168,11 +155,11 @@ impl ClientTrait for StarknetClient { if let Some(event) = emitted_events.last() { let data = event; // Create a longer-lived binding let formatted_event = StateUpdate { - block_number: data.data[1].to_u64().expect("Unable to parse Felt result into u64"), + block_number: data.data[1].to_u64().ok_or(anyhow!("Block number conversion failed"))?, global_root: data.data[0], block_hash: data.data[2], }; - update_l1(&backend, formatted_event, self.get_l1_block_metrics())?; + update_l1(&backend, formatted_event, l1_block_metrics.clone())?; } } Some(Err(e)) => { @@ -213,7 +200,11 @@ impl ClientTrait for StarknetClient { ) .await?; // Ensure correct read call : u256 (0, 0) - assert_eq!(call_res.len(), 2, "l1_to_l2_message_cancellations should return only 2 values"); + if call_res.len() != 2 { + return Err(anyhow!( + "Call response invalid : l1_to_l2_message_cancellations should return only 2 values !!" + )); + } Ok(call_res[0]) } @@ -314,7 +305,6 @@ impl StarknetClient { #[cfg(test)] pub mod starknet_client_tests { use crate::client::ClientTrait; - use crate::gas_price::L1BlockMetrics; use crate::starknet::utils::{prepare_starknet_client_test, send_state_update, MADARA_PORT}; use crate::starknet::{StarknetClient, StarknetClientConfig}; use crate::state_update::StateUpdate; @@ -335,11 +325,9 @@ pub mod starknet_client_tests { #[tokio::test] async fn fail_create_new_client_contract_does_not_exists() -> anyhow::Result<()> { prepare_starknet_client_test().await?; - let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, l2_contract_address: Felt::from_str("0xdeadbeef")?, - l1_block_metrics, }) .await; assert!(starknet_client.is_err(), "Should fail to create a new client"); @@ -350,11 +338,9 @@ pub mod starknet_client_tests { #[tokio::test] async fn create_new_client_contract_exists_starknet_client() -> anyhow::Result<()> { let (_, deployed_address, _madara) = prepare_starknet_client_test().await?; - let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, l2_contract_address: deployed_address, - l1_block_metrics, }) .await; assert!(starknet_client.is_ok(), "Should not fail to create a new client"); @@ -365,11 +351,9 @@ pub mod starknet_client_tests { #[tokio::test] async fn get_last_event_block_number_works_starknet_client() -> anyhow::Result<()> { let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; - let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, l2_contract_address: deployed_address, - l1_block_metrics, }) .await?; @@ -406,11 +390,9 @@ pub mod starknet_client_tests { #[tokio::test] async fn get_last_verified_block_hash_works_starknet_client() -> anyhow::Result<()> { let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; - let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, l2_contract_address: deployed_address, - l1_block_metrics, }) .await?; @@ -435,11 +417,9 @@ pub mod starknet_client_tests { #[tokio::test] async fn get_last_state_root_works_starknet_client() -> anyhow::Result<()> { let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; - let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, l2_contract_address: deployed_address, - l1_block_metrics, }) .await?; @@ -464,11 +444,9 @@ pub mod starknet_client_tests { #[tokio::test] async fn get_last_verified_block_number_works_starknet_client() -> anyhow::Result<()> { let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; - let l1_block_metrics = L1BlockMetrics::register()?; let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, l2_contract_address: deployed_address, - l1_block_metrics, }) .await?; diff --git a/crates/madara/client/settlement_client/src/state_update.rs b/crates/madara/client/settlement_client/src/state_update.rs index b4aca5863..02fa7cf7b 100644 --- a/crates/madara/client/settlement_client/src/state_update.rs +++ b/crates/madara/client/settlement_client/src/state_update.rs @@ -1,14 +1,8 @@ use std::sync::Arc; -<<<<<<<< HEAD:crates/madara/client/settlement_client/src/state_update.rs use crate::client::ClientTrait; use crate::gas_price::L1BlockMetrics; use crate::messaging::CommonMessagingEventData; -use crate::utils::trim_hash; -======== -use crate::client::{L1BlockMetrics, StarknetCoreContract}; -use crate::{client::EthereumClient, utils::convert_log_state_update}; ->>>>>>>> 4d1c4b376e1dd2019397a9ee2828f98cda0e41dc:crates/madara/client/eth/src/state_update.rs use anyhow::Context; use futures::Stream; use mc_db::MadaraBackend; @@ -27,7 +21,7 @@ pub struct StateUpdate { pub fn update_l1( backend: &MadaraBackend, state_update: StateUpdate, - block_metrics: &L1BlockMetrics, + block_metrics: Arc, ) -> anyhow::Result<()> { tracing::info!( "🔄 Updated L1 head #{} ({}) with state root ({})", @@ -48,6 +42,7 @@ pub async fn state_update_worker( backend: Arc, settlement_client: Arc>>, ctx: ServiceContext, + l1_block_metrics: Arc, ) -> anyhow::Result<()> where S: Stream>> + Send + 'static, @@ -61,10 +56,10 @@ where #[cfg(not(test))] { let initial_state = settlement_client.get_initial_state().await.context("Getting initial ethereum state")?; - update_l1(&backend, initial_state, settlement_client.get_l1_block_metrics())?; + update_l1(&backend, initial_state, l1_block_metrics.clone())?; } - settlement_client.listen_for_update_state_events(backend, ctx).await?; + settlement_client.listen_for_update_state_events(backend, ctx, l1_block_metrics.clone()).await?; anyhow::Ok(()) } @@ -137,17 +132,14 @@ mod eth_client_event_subscription_test { .expect("Failed to create database service"), ); - // Set up metrics service - let l1_block_metrics = L1BlockMetrics::register().unwrap(); - let rpc_url: Url = anvil.endpoint().parse().expect("issue while parsing"); let provider = ProviderBuilder::new().on_http(rpc_url); let contract = DummyContract::deploy(provider.clone()).await.unwrap(); let core_contract = StarknetCoreContract::new(*contract.address(), provider.clone()); - let eth_client = - EthereumClient { provider: Arc::new(provider), l1_core_contract: core_contract.clone(), l1_block_metrics }; + let eth_client = EthereumClient { provider: Arc::new(provider), l1_core_contract: core_contract.clone() }; + let l1_block_metrics = L1BlockMetrics::register().unwrap(); // Start listening for state updates let listen_handle = { @@ -157,6 +149,7 @@ mod eth_client_event_subscription_test { Arc::clone(db.backend()), Arc::new(Box::new(eth_client)), ServiceContext::new_for_testing(), + Arc::new(l1_block_metrics), ) .await .unwrap() @@ -217,9 +210,6 @@ mod starknet_client_event_subscription_test { .expect("Failed to create database service"), ); - // Set up metrics service - let l1_block_metrics = L1BlockMetrics::register().unwrap(); - // Making Starknet client and start worker // ================================================ let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; @@ -227,10 +217,11 @@ mod starknet_client_event_subscription_test { let starknet_client = StarknetClient::new(StarknetClientConfig { url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, l2_contract_address: deployed_address, - l1_block_metrics, }) .await?; + let l1_block_metrics = L1BlockMetrics::register()?; + let listen_handle = { let db = Arc::clone(&db); tokio::spawn(async move { @@ -238,6 +229,7 @@ mod starknet_client_event_subscription_test { Arc::clone(db.backend()), Arc::new(Box::new(starknet_client)), ServiceContext::new_for_testing(), + Arc::new(l1_block_metrics), ) .await .expect("Failed to init state update worker.") diff --git a/crates/madara/client/settlement_client/src/sync.rs b/crates/madara/client/settlement_client/src/sync.rs index e066046b5..3b2358bcc 100644 --- a/crates/madara/client/settlement_client/src/sync.rs +++ b/crates/madara/client/settlement_client/src/sync.rs @@ -1,5 +1,5 @@ use crate::client::ClientTrait; -use crate::gas_price::gas_price_worker; +use crate::gas_price::{gas_price_worker, L1BlockMetrics}; use crate::messaging::{sync, CommonMessagingEventData}; use crate::state_update::state_update_worker; use futures::Stream; @@ -20,18 +20,30 @@ pub async fn sync_worker( gas_price_poll_ms: Duration, mempool: Arc, ctx: ServiceContext, + l1_block_metrics: Arc, ) -> anyhow::Result<()> where S: Stream>> + Send + 'static, { let mut join_set = tokio::task::JoinSet::new(); - join_set.spawn(state_update_worker(Arc::clone(&backend), settlement_client.clone(), ctx.clone())); + join_set.spawn(state_update_worker( + Arc::clone(&backend), + settlement_client.clone(), + ctx.clone(), + l1_block_metrics.clone(), + )); join_set.spawn(sync(settlement_client.clone(), Arc::clone(&backend), chain_id, mempool, ctx.clone())); if !gas_price_sync_disabled { - join_set.spawn(gas_price_worker(settlement_client.clone(), l1_gas_provider, gas_price_poll_ms, ctx.clone())); + join_set.spawn(gas_price_worker( + settlement_client.clone(), + l1_gas_provider, + gas_price_poll_ms, + ctx.clone(), + l1_block_metrics, + )); } while let Some(res) = join_set.join_next().await { diff --git a/crates/madara/client/sync/src/utils.rs b/crates/madara/client/sync/src/utils.rs deleted file mode 100644 index 04330745a..000000000 --- a/crates/madara/client/sync/src/utils.rs +++ /dev/null @@ -1,13 +0,0 @@ -use starknet_types_core::felt::Felt; - -pub fn trim_hash(hash: &Felt) -> String { - let hash_str = format!("{:#x}", hash); - - if hash_str.len() <= 12 { - hash_str.to_string() - } else { - let prefix = &hash_str[..6]; - let suffix = &hash_str[hash_str.len() - 6..]; - format!("{}...{}", prefix, suffix) - } -} diff --git a/crates/madara/node/src/main.rs b/crates/madara/node/src/main.rs index c5f6e6084..da936e1ce 100644 --- a/crates/madara/node/src/main.rs +++ b/crates/madara/node/src/main.rs @@ -6,6 +6,7 @@ mod service; mod util; use crate::cli::l1::MadaraSettlementLayer; +use crate::service::L1SyncConfig; use anyhow::{bail, Context}; use clap::Parser; use cli::RunCmd; @@ -18,6 +19,7 @@ use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; use mc_rpc::providers::{AddTransactionProvider, ForwardToProvider, MempoolAddTxProvider}; use mc_settlement_client::eth::event::EthereumEventStream; use mc_settlement_client::eth::EthereumClientConfig; +use mc_settlement_client::gas_price::L1BlockMetrics; use mc_settlement_client::starknet::event::StarknetEventStream; use mc_settlement_client::starknet::StarknetClientConfig; use mc_sync::fetch::fetchers::WarpUpdateConfig; @@ -168,28 +170,35 @@ async fn main() -> anyhow::Result<()> { mempool.load_txs_from_db().context("Loading mempool transactions")?; let mempool = Arc::new(mempool); + let l1_block_metrics = L1BlockMetrics::register().context("Initializing L1 Block Metrics")?; let service_l1_sync = match &run_cmd.l1_sync_params.settlement_layer { MadaraSettlementLayer::Eth => L1SyncService::::create( &run_cmd.l1_sync_params, - &service_db, - l1_gas_setter, - chain_config.chain_id.clone(), - chain_config.eth_core_contract_address.clone(), - run_cmd.is_sequencer(), - run_cmd.is_devnet(), - Arc::clone(&mempool), + L1SyncConfig { + db: &service_db, + l1_gas_provider: l1_gas_setter, + chain_id: chain_config.chain_id.clone(), + l1_core_address: chain_config.eth_core_contract_address.clone(), + authority: run_cmd.is_sequencer(), + devnet: run_cmd.is_devnet(), + mempool: Arc::clone(&mempool), + l1_block_metrics: Arc::new(l1_block_metrics), + }, ) .await .context("Initializing the l1 sync service")?, MadaraSettlementLayer::Starknet => L1SyncService::::create( &run_cmd.l1_sync_params, - &service_db, - l1_gas_setter, - chain_config.chain_id.clone(), - chain_config.eth_core_contract_address.clone(), - run_cmd.is_sequencer(), - run_cmd.is_devnet(), - Arc::clone(&mempool), + L1SyncConfig { + db: &service_db, + l1_gas_provider: l1_gas_setter, + chain_id: chain_config.chain_id.clone(), + l1_core_address: chain_config.eth_core_contract_address.clone(), + authority: run_cmd.is_sequencer(), + devnet: run_cmd.is_devnet(), + mempool: Arc::clone(&mempool), + l1_block_metrics: Arc::new(l1_block_metrics), + }, ) .await .context("Initializing the l1 sync service")?, diff --git a/crates/madara/node/src/service/l1.rs b/crates/madara/node/src/service/l1.rs index e89eed318..77e090c51 100644 --- a/crates/madara/node/src/service/l1.rs +++ b/crates/madara/node/src/service/l1.rs @@ -18,6 +18,24 @@ use std::str::FromStr; use std::sync::Arc; use std::time::Duration; +// Configuration struct to group related parameters +pub struct L1SyncConfig<'a> { + pub db: &'a DatabaseService, + pub l1_gas_provider: GasPriceProvider, + pub chain_id: ChainId, + pub l1_core_address: String, + pub authority: bool, + pub devnet: bool, + pub mempool: Arc, + pub l1_block_metrics: Arc, +} + +impl<'a> L1SyncConfig<'a> { + pub fn should_enable_sync(&self, config: &L1SyncParams) -> bool { + !config.l1_sync_disabled && (config.l1_endpoint.is_some() || !self.devnet) + } +} + pub struct L1SyncService where C: Clone, @@ -30,6 +48,7 @@ where gas_price_sync_disabled: bool, gas_price_poll: Duration, mempool: Arc, + l1_block_metrics: Arc, } pub type EthereumSyncService = L1SyncService; @@ -37,25 +56,13 @@ pub type StarknetSyncService = L1SyncService, - ) -> anyhow::Result { - let settlement_client = if !config.l1_sync_disabled && (config.l1_endpoint.is_some() || !devnet) { + pub async fn new(config: &L1SyncParams, sync_config: L1SyncConfig<'_>) -> anyhow::Result { + let settlement_client = if sync_config.should_enable_sync(config) { if let Some(l1_rpc_url) = &config.l1_endpoint { - let core_address = Address::from_str(l1_core_address.as_str())?; - let l1_block_metrics = L1BlockMetrics::register().expect("Registering metrics"); + let core_address = Address::from_str(sync_config.l1_core_address.as_str())?; let client = EthereumClient::new(EthereumClientConfig { url: l1_rpc_url.clone(), l1_core_address: core_address, - l1_block_metrics, }) .await .context("Creating ethereum client")?; @@ -73,36 +80,23 @@ impl EthereumSyncService { None }; - Self::create_service(config, db, settlement_client, l1_gas_provider, chain_id, authority, devnet, mempool).await + Self::create_service(config, sync_config, settlement_client).await } } // Implementation for Starknet impl StarknetSyncService { - #[allow(clippy::too_many_arguments)] - pub async fn new( - config: &L1SyncParams, - db: &DatabaseService, - l1_gas_provider: GasPriceProvider, - chain_id: ChainId, - l1_core_address: String, - authority: bool, - devnet: bool, - mempool: Arc, - ) -> anyhow::Result { - let settlement_client = if !config.l1_sync_disabled && (config.l1_endpoint.is_some() || !devnet) { + pub async fn new(config: &L1SyncParams, sync_config: L1SyncConfig<'_>) -> anyhow::Result { + let settlement_client = if sync_config.should_enable_sync(config) { if let Some(l1_rpc_url) = &config.l1_endpoint { - let core_address = Felt::from_str(l1_core_address.as_str())?; - let l1_block_metrics = L1BlockMetrics::register().expect("Registering metrics"); + let core_address = Felt::from_str(sync_config.l1_core_address.as_str())?; let client = StarknetClient::new(StarknetClientConfig { url: l1_rpc_url.clone(), l2_contract_address: core_address, - l1_block_metrics, }) .await .context("Creating starknet client")?; - // StarknetClientConfig, Arc>, Felt let client_converted: Box< dyn ClientTrait, > = Box::new(client); @@ -116,7 +110,7 @@ impl StarknetSyncService { None }; - Self::create_service(config, db, settlement_client, l1_gas_provider, chain_id, authority, devnet, mempool).await + Self::create_service(config, sync_config, settlement_client).await } } @@ -126,80 +120,47 @@ where C: Clone + 'static, S: Send + Stream>> + 'static, { - #[allow(clippy::too_many_arguments)] async fn create_service( config: &L1SyncParams, - db: &DatabaseService, + sync_config: L1SyncConfig<'_>, settlement_client: Option>>>, - l1_gas_provider: GasPriceProvider, - chain_id: ChainId, - authority: bool, - devnet: bool, - mempool: Arc, ) -> anyhow::Result { - let gas_price_sync_enabled = - authority && !devnet && (config.gas_price.is_none() || config.blob_gas_price.is_none()); + let gas_price_sync_enabled = sync_config.authority + && !sync_config.devnet + && (config.gas_price.is_none() || config.blob_gas_price.is_none()); let gas_price_poll = config.gas_price_poll; if gas_price_sync_enabled { let settlement_client = settlement_client.clone().context("L1 gas prices require the service to be enabled...")?; tracing::info!("⏳ Getting initial L1 gas prices"); - mc_settlement_client::gas_price::gas_price_worker_once(settlement_client, &l1_gas_provider, gas_price_poll) - .await - .context("Getting initial gas prices")?; + mc_settlement_client::gas_price::gas_price_worker_once( + settlement_client, + &sync_config.l1_gas_provider, + gas_price_poll, + sync_config.l1_block_metrics.clone(), + ) + .await + .context("Getting initial gas prices")?; } Ok(Self { - db_backend: Arc::clone(db.backend()), + db_backend: Arc::clone(sync_config.db.backend()), settlement_client, - l1_gas_provider, - chain_id, + l1_gas_provider: sync_config.l1_gas_provider, + chain_id: sync_config.chain_id, gas_price_sync_disabled: !gas_price_sync_enabled, gas_price_poll, - mempool, + mempool: sync_config.mempool, + l1_block_metrics: sync_config.l1_block_metrics, }) } // Factory method to create the appropriate service - #[allow(clippy::too_many_arguments)] - pub async fn create( - config: &L1SyncParams, - db: &DatabaseService, - l1_gas_provider: GasPriceProvider, - chain_id: ChainId, - l1_core_address: String, - authority: bool, - devnet: bool, - mempool: Arc, - ) -> anyhow::Result> { + pub async fn create(config: &L1SyncParams, sync_config: L1SyncConfig<'_>) -> anyhow::Result> { match config.settlement_layer { - MadaraSettlementLayer::Eth => Ok(Box::new( - EthereumSyncService::new( - config, - db, - l1_gas_provider, - chain_id, - l1_core_address, - authority, - devnet, - mempool, - ) - .await?, - )), - MadaraSettlementLayer::Starknet => Ok(Box::new( - StarknetSyncService::new( - config, - db, - l1_gas_provider, - chain_id, - l1_core_address, - authority, - devnet, - mempool, - ) - .await?, - )), + MadaraSettlementLayer::Eth => Ok(Box::new(EthereumSyncService::new(config, sync_config).await?)), + MadaraSettlementLayer::Starknet => Ok(Box::new(StarknetSyncService::new(config, sync_config).await?)), } } } @@ -219,6 +180,7 @@ where let gas_price_sync_disabled = self.gas_price_sync_disabled; let gas_price_poll = self.gas_price_poll; let mempool = Arc::clone(&self.mempool); + let l1_block_metrics = self.l1_block_metrics.clone(); runner.service_loop(move |ctx| { mc_settlement_client::sync::sync_worker( @@ -230,6 +192,7 @@ where gas_price_poll, mempool, ctx, + l1_block_metrics, ) }); } else { diff --git a/crates/madara/node/src/service/mod.rs b/crates/madara/node/src/service/mod.rs index 84a36057b..bd66212c0 100644 --- a/crates/madara/node/src/service/mod.rs +++ b/crates/madara/node/src/service/mod.rs @@ -6,6 +6,7 @@ mod rpc; pub use block_production::BlockProductionService; pub use gateway::GatewayService; +pub use l1::L1SyncConfig; pub use l1::L1SyncService; pub use l2::L2SyncService; pub use rpc::RpcService; diff --git a/crates/madara/primitives/chain_config/src/chain_config.rs b/crates/madara/primitives/chain_config/src/chain_config.rs index 4d37e1d3d..2b20ce30b 100644 --- a/crates/madara/primitives/chain_config/src/chain_config.rs +++ b/crates/madara/primitives/chain_config/src/chain_config.rs @@ -18,7 +18,6 @@ use blockifier::bouncer::{BouncerWeights, BuiltinCount}; use blockifier::{bouncer::BouncerConfig, versioned_constants::VersionedConstants}; use lazy_static::__Deref; use mp_utils::crypto::ZeroingPrivateKey; -use primitive_types::H160; use serde::de::{MapAccess, Visitor}; use serde::{Deserialize, Deserializer, Serialize}; use starknet_api::core::{ChainId, ContractAddress, PatriciaKey}; @@ -114,11 +113,11 @@ pub struct ChainConfig { pub sequencer_address: ContractAddress, /// The Starknet core contract address for the L1 watcher. - pub eth_core_contract_address: H160, + pub eth_core_contract_address: String, /// The Starknet SHARP verifier La address. Check out the [docs](https://docs.starknet.io/architecture-and-concepts/solidity-verifier/) /// for more information - pub eth_gps_statement_verifier: H160, + pub eth_gps_statement_verifier: String, /// Private key used by the node to sign blocks provided through the /// feeder gateway. This serves as a proof of origin and in the future @@ -551,10 +550,7 @@ mod tests { ) .unwrap() ); - assert_eq!( - chain_config.eth_core_contract_address, - H160::from_str("0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4").unwrap() - ); + assert_eq!(chain_config.eth_core_contract_address, "0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4"); } #[rstest] From fffd9dd5df0cd703f93a6ef5845014dabacf5e17 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Fri, 17 Jan 2025 16:40:57 +0530 Subject: [PATCH 20/23] refactor --- .../settlement_client/src/starknet/mod.rs | 53 ++++++++++--------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/crates/madara/client/settlement_client/src/starknet/mod.rs b/crates/madara/client/settlement_client/src/starknet/mod.rs index ff6865b27..4cee71795 100644 --- a/crates/madara/client/settlement_client/src/starknet/mod.rs +++ b/crates/madara/client/settlement_client/src/starknet/mod.rs @@ -15,10 +15,10 @@ use starknet_crypto::poseidon_hash_many; use starknet_providers::jsonrpc::HttpTransport; use starknet_providers::{JsonRpcClient, Provider}; use starknet_types_core::felt::Felt; +use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; use std::time::Duration; use tokio::time::sleep; -use tracing::{error, trace}; use url::Url; pub mod event; @@ -29,6 +29,7 @@ pub mod utils; pub struct StarknetClient { pub provider: Arc>, pub l2_core_contract: Felt, + pub processed_update_state_block: AtomicU64, } #[derive(Clone)] @@ -39,7 +40,11 @@ pub struct StarknetClientConfig { impl Clone for StarknetClient { fn clone(&self) -> Self { - StarknetClient { provider: Arc::clone(&self.provider), l2_core_contract: self.l2_core_contract } + StarknetClient { + provider: Arc::clone(&self.provider), + l2_core_contract: self.l2_core_contract, + processed_update_state_block: AtomicU64::new(self.processed_update_state_block.load(Ordering::Relaxed)), + } } } @@ -62,7 +67,11 @@ impl ClientTrait for StarknetClient { // Check if l2 contract exists : // If contract is not there this will error out. provider.get_class_at(BlockId::Tag(BlockTag::Latest), config.l2_contract_address).await?; - Ok(Self { provider: Arc::new(provider), l2_core_contract: config.l2_contract_address }) + Ok(Self { + provider: Arc::new(provider), + l2_core_contract: config.l2_contract_address, + processed_update_state_block: AtomicU64::new(0), // Keeping this as 0 initially when client is initialized. + }) } async fn get_latest_block_number(&self) -> anyhow::Result { @@ -142,36 +151,32 @@ impl ClientTrait for StarknetClient { mut ctx: ServiceContext, l1_block_metrics: Arc, ) -> anyhow::Result<()> { - loop { - let events_response = ctx.run_until_cancelled(self.get_events( + while let Some(events) = ctx + .run_until_cancelled(self.get_events( BlockId::Number(self.get_latest_block_number().await?), BlockId::Number(self.get_latest_block_number().await?), self.l2_core_contract, vec![get_selector_from_name("LogStateUpdate")?], - )); - - match events_response.await { - Some(Ok(emitted_events)) => { - if let Some(event) = emitted_events.last() { - let data = event; // Create a longer-lived binding - let formatted_event = StateUpdate { - block_number: data.data[1].to_u64().ok_or(anyhow!("Block number conversion failed"))?, - global_root: data.data[0], - block_hash: data.data[2], - }; - update_l1(&backend, formatted_event, l1_block_metrics.clone())?; - } - } - Some(Err(e)) => { - error!("Error processing event: {:?}", e); - } - None => { - trace!("Starknet Client : No event found"); + )) + .await + { + let events_fetched = events?; + if let Some(event) = events_fetched.last() { + let data = event; + let block_number = data.data[1].to_u64().ok_or(anyhow!("Block number conversion failed"))?; + + let current_processed = self.processed_update_state_block.load(Ordering::Relaxed); + if current_processed < block_number { + let formatted_event = + StateUpdate { block_number, global_root: data.data[0], block_hash: data.data[2] }; + update_l1(&backend, formatted_event, l1_block_metrics.clone())?; + self.processed_update_state_block.store(block_number, Ordering::Relaxed); } } sleep(Duration::from_millis(100)).await; } + Ok(()) } // We are returning here (0,0) because we are assuming that From 71c552491c715e1be415c292706294929733550f Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Tue, 21 Jan 2025 17:09:52 +0530 Subject: [PATCH 21/23] feat : added automock tests and resolved comments --- Cargo.lock | 11 +- .../src}/appchain_test.cairo | 0 cairo/src/lib.cairo | 2 + .../src}/messaging_test.cairo | 0 crates/madara/cairo-test-contracts/src/lib.rs | 4 + .../client/settlement_client/Cargo.toml | 6 +- .../client/settlement_client/src/client.rs | 34 +- .../client/settlement_client/src/eth/event.rs | 35 +- .../client/settlement_client/src/eth/mod.rs | 498 ++++- .../client/settlement_client/src/messaging.rs | 407 ++++ .../settlement_client/src/messaging/mod.rs | 217 -- .../settlement_client/src/messaging/tests.rs | 635 ------ .../settlement_client/src/starknet/event.rs | 82 +- .../settlement_client/src/starknet/mod.rs | 386 +++- .../test_contracts/appchain_test.casm.json | 948 -------- .../test_contracts/appchain_test.sierra.json | 659 ------ .../test_contracts/messaging_test.casm.json | 1987 ----------------- .../test_contracts/messaging_test.sierra.json | 1471 ------------ .../settlement_client/src/starknet/utils.rs | 15 +- .../settlement_client/src/state_update.rs | 198 -- crates/madara/node/src/service/l1.rs | 2 + 21 files changed, 1408 insertions(+), 6189 deletions(-) rename {crates/madara/client/settlement_client/src/starknet/test_contracts => cairo/src}/appchain_test.cairo (100%) rename {crates/madara/client/settlement_client/src/starknet/test_contracts => cairo/src}/messaging_test.cairo (100%) create mode 100644 crates/madara/client/settlement_client/src/messaging.rs delete mode 100644 crates/madara/client/settlement_client/src/messaging/mod.rs delete mode 100644 crates/madara/client/settlement_client/src/messaging/tests.rs delete mode 100644 crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json delete mode 100644 crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json delete mode 100644 crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json delete mode 100644 crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json diff --git a/Cargo.lock b/Cargo.lock index 8210ad13d..37d6277b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5839,10 +5839,13 @@ dependencies = [ "hex", "httpmock", "lazy_static", + "log", + "m-cairo-test-contracts", "matchers", "mc-analytics", "mc-db", "mc-mempool", + "mockall", "mp-chain-config", "mp-convert", "mp-transactions", @@ -5990,9 +5993,9 @@ dependencies = [ [[package]] name = "mockall" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c28b3fb6d753d28c20e826cd46ee611fda1cf3cde03a443a974043247c065a" +checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" dependencies = [ "cfg-if", "downcast", @@ -6004,9 +6007,9 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "341014e7f530314e9a1fdbc7400b244efea7122662c96bfa248c31da5bfb2020" +checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" dependencies = [ "cfg-if", "proc-macro2", diff --git a/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo b/cairo/src/appchain_test.cairo similarity index 100% rename from crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.cairo rename to cairo/src/appchain_test.cairo diff --git a/cairo/src/lib.cairo b/cairo/src/lib.cairo index 67958ac67..86f2244a8 100644 --- a/cairo/src/lib.cairo +++ b/cairo/src/lib.cairo @@ -1,3 +1,5 @@ pub mod test_account; pub mod hello; +pub mod appchain_test; +pub mod messaging_test; \ No newline at end of file diff --git a/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo b/cairo/src/messaging_test.cairo similarity index 100% rename from crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.cairo rename to cairo/src/messaging_test.cairo diff --git a/crates/madara/cairo-test-contracts/src/lib.rs b/crates/madara/cairo-test-contracts/src/lib.rs index c89e65522..cf068e711 100644 --- a/crates/madara/cairo-test-contracts/src/lib.rs +++ b/crates/madara/cairo-test-contracts/src/lib.rs @@ -3,3 +3,7 @@ pub const TEST_CONTRACT_SIERRA: &[u8] = include_bytes!("../../../../cairo/target/dev/madara_contracts_TestContract.contract_class.json"); +pub const APPCHAIN_CONTRACT_SIERRA: &[u8] = + include_bytes!("../../../../cairo/target/dev/madara_contracts_StateUpdateContract.contract_class.json"); +pub const MESSAGING_CONTRACT_SIERRA: &[u8] = + include_bytes!("../../../../cairo/target/dev/madara_contracts_MessagingContract.contract_class.json"); diff --git a/crates/madara/client/settlement_client/Cargo.toml b/crates/madara/client/settlement_client/Cargo.toml index 0030b09c0..2f54f6b40 100644 --- a/crates/madara/client/settlement_client/Cargo.toml +++ b/crates/madara/client/settlement_client/Cargo.toml @@ -39,7 +39,7 @@ assert_matches = "1.5.0" bigdecimal.workspace = true bitvec.workspace = true futures = { workspace = true, default-features = true } - +mockall.workspace = true regex = "1.10.5" serde = { workspace = true, default-features = true } serde_json = "1" @@ -63,6 +63,7 @@ url.workspace = true #Instrumentation async-trait = { workspace = true } hex = "0.4.3" +log = "0.4.22" matchers = "0.1.0" opentelemetry = { workspace = true, features = ["metrics", "logs"] } opentelemetry-appender-tracing = { workspace = true, default-features = false } @@ -84,7 +85,6 @@ tracing-subscriber = { workspace = true, features = ["env-filter"] } [features] default = [] - [dev-dependencies] rstest.workspace = true once_cell.workspace = true @@ -96,3 +96,5 @@ serial_test.workspace = true lazy_static.workspace = true mp-utils = { workspace = true, features = ["testing"] } mc-mempool = { workspace = true, features = ["testing"] } +# Compile the test contracts in test cfg. +m-cairo-test-contracts.workspace = true diff --git a/crates/madara/client/settlement_client/src/client.rs b/crates/madara/client/settlement_client/src/client.rs index 3c652391c..94d7cce00 100644 --- a/crates/madara/client/settlement_client/src/client.rs +++ b/crates/madara/client/settlement_client/src/client.rs @@ -2,9 +2,11 @@ use crate::gas_price::L1BlockMetrics; use crate::messaging::CommonMessagingEventData; use crate::state_update::StateUpdate; use async_trait::async_trait; +use futures::stream::BoxStream; use futures::Stream; use mc_db::l1_db::LastSyncedEventBlock; use mc_db::MadaraBackend; +use mockall::automock; use mp_utils::service::ServiceContext; use starknet_types_core::felt::Felt; use std::sync::Arc; @@ -14,6 +16,14 @@ pub enum ClientType { STARKNET, } +#[derive(Debug, Default, PartialEq)] +pub struct DummyConfig; +pub type DummyStream = BoxStream<'static, Option>>; + +#[automock( + type Config = DummyConfig; + type StreamType = DummyStream; +)] #[async_trait] pub trait ClientTrait: Send + Sync { // Configuration type used for initialization @@ -79,7 +89,25 @@ pub trait ClientTrait: Send + Sync { // ============================================================ // Stream Implementations : // ============================================================ - type StreamType: Stream>>; - async fn get_event_stream(&self, last_synced_event_block: LastSyncedEventBlock) - -> anyhow::Result; + + /// The type of Stream that will be returned by get_messaging_stream + /// - Stream: Represents an asynchronous sequence of values + /// - Item: Each element in the stream is wrapped in Option to handle potential gaps + /// - anyhow::Result: Each item is further wrapped in Result for error handling + /// - CommonMessagingEventData: The actual message data structure being streamed + type StreamType: Stream>> + Send; + + /// Retrieves a stream of messaging events starting from the last synced block + /// + /// # Arguments + /// * `last_synced_event_block` - Contains information about the last block that was + /// successfully processed, used as starting point for the new stream + /// + /// # Returns + /// * `anyhow::Result` - Returns the stream if successful, or an error + /// if stream creation fails + async fn get_messaging_stream( + &self, + last_synced_event_block: LastSyncedEventBlock, + ) -> anyhow::Result; } diff --git a/crates/madara/client/settlement_client/src/eth/event.rs b/crates/madara/client/settlement_client/src/eth/event.rs index a53b7e23b..66b244dfc 100644 --- a/crates/madara/client/settlement_client/src/eth/event.rs +++ b/crates/madara/client/settlement_client/src/eth/event.rs @@ -5,6 +5,7 @@ use alloy::rpc::types::Log; use alloy::transports::http::{Client, Http}; use anyhow::Error; use futures::Stream; +use starknet_types_core::felt::Felt; use std::pin::Pin; use std::task::{Context, Poll}; @@ -12,7 +13,7 @@ type StreamItem = Result<(LogMessageToL2, Log), alloy::sol_types::Error>; type StreamType = Pin + Send + 'static>>; pub struct EthereumEventStream { - stream: StreamType, + pub stream: StreamType, } impl EthereumEventStream { @@ -31,20 +32,26 @@ impl Stream for EthereumEventStream { Ok((event, log)) => { let event_data = (|| -> anyhow::Result { Ok(CommonMessagingEventData { - from: event.fromAddress.as_slice().into(), - to: event.toAddress.to_be_bytes_vec(), - selector: event.selector.to_be_bytes_vec(), - nonce: event.nonce.to_be_bytes_vec(), + from: Felt::from_bytes_be_slice(event.fromAddress.as_slice()), + to: Felt::from_bytes_be_slice(event.toAddress.to_be_bytes_vec().as_slice()), + selector: Felt::from_bytes_be_slice(event.selector.to_be_bytes_vec().as_slice()), + nonce: Felt::from_bytes_be_slice(event.nonce.to_be_bytes_vec().as_slice()), payload: { let mut payload_vec = vec![]; - event.payload.iter().for_each(|ele| payload_vec.push(ele.to_be_bytes_vec())); + event.payload.iter().for_each(|ele| { + payload_vec.push(Felt::from_bytes_be_slice(ele.to_be_bytes_vec().as_slice())) + }); payload_vec }, - fee: Some(event.fee.to_be_bytes_vec()), - transaction_hash: log - .transaction_hash - .ok_or_else(|| anyhow::anyhow!("Missing transaction hash"))? - .to_vec(), + fee: Some( + event.fee.try_into().map_err(|e| anyhow::anyhow!("Felt conversion error: {}", e))?, + ), + transaction_hash: Felt::from_bytes_be_slice( + log.transaction_hash + .ok_or_else(|| anyhow::anyhow!("Missing transaction hash"))? + .to_vec() + .as_slice(), + ), message_hash: None, block_number: log.block_number.ok_or_else(|| anyhow::anyhow!("Missing block number"))?, event_index: Some(log.log_index.ok_or_else(|| anyhow::anyhow!("Missing log index"))?), @@ -62,7 +69,7 @@ impl Stream for EthereumEventStream { } #[cfg(test)] -mod eth_event_stream_tests { +pub mod eth_event_stream_tests { use super::*; use alloy::primitives::{Address, LogData, B256, U256}; use futures::stream::iter; @@ -71,7 +78,7 @@ mod eth_event_stream_tests { use std::str::FromStr; // Helper function to create mock event - fn create_mock_event() -> LogMessageToL2 { + pub fn create_mock_event() -> LogMessageToL2 { LogMessageToL2 { fromAddress: Address::from_str("0x1234567890123456789012345678901234567890").unwrap(), toAddress: U256::from(1u64), @@ -83,7 +90,7 @@ mod eth_event_stream_tests { } // Helper function to create mock log - fn create_mock_log() -> Log { + pub fn create_mock_log() -> Log { Log { inner: alloy::primitives::Log { address: Address::from_str("0x1234567890123456789012345678901234567890").unwrap(), diff --git a/crates/madara/client/settlement_client/src/eth/mod.rs b/crates/madara/client/settlement_client/src/eth/mod.rs index 43891743f..3638c0e8b 100644 --- a/crates/madara/client/settlement_client/src/eth/mod.rs +++ b/crates/madara/client/settlement_client/src/eth/mod.rs @@ -6,7 +6,7 @@ use crate::eth::StarknetCoreContract::{LogMessageToL2, StarknetCoreContractInsta use crate::gas_price::L1BlockMetrics; use crate::messaging::CommonMessagingEventData; use crate::state_update::{update_l1, StateUpdate}; -use crate::utils::{convert_log_state_update, u256_to_felt}; +use crate::utils::{convert_log_state_update, felt_to_u256, u256_to_felt}; use alloy::eips::BlockNumberOrTag; use alloy::primitives::{keccak256, Address, B256, U256}; use alloy::providers::{Provider, ProviderBuilder, ReqwestProvider, RootProvider}; @@ -177,14 +177,20 @@ impl ClientTrait for EthereumClient { } fn get_messaging_hash(&self, event: &CommonMessagingEventData) -> anyhow::Result> { + let mut payload_vec = Vec::new(); + for ele in event.payload.clone() { + payload_vec.push(felt_to_u256(ele)); + } + + let from_address_start_index = event.from.to_bytes_be().as_slice().len().saturating_sub(20); let data = ( [0u8; 12], - event.from.clone(), - event.to.clone(), - event.nonce.clone(), - event.selector.clone(), + Address::from_slice(&event.from.to_bytes_be().as_slice()[from_address_start_index..]), + felt_to_u256(event.to), + felt_to_u256(event.nonce), + felt_to_u256(event.selector), U256::from(event.payload.len()), - event.payload.clone(), + payload_vec, ); Ok(keccak256(data.abi_encode_packed()).as_slice().to_vec()) } @@ -209,11 +215,8 @@ impl ClientTrait for EthereumClient { u256_to_felt(cancellation_timestamp._0) } - // ============================================================ - // Stream Implementations : - // ============================================================ type StreamType = EthereumEventStream; - async fn get_event_stream( + async fn get_messaging_stream( &self, last_synced_event_block: LastSyncedEventBlock, ) -> anyhow::Result { @@ -380,3 +383,478 @@ pub mod eth_client_getter_test { assert_eq!(block_number, L2_BLOCK_NUMBER, "verified block number not matching"); } } + +#[cfg(test)] +mod l1_messaging_tests { + + use std::{sync::Arc, time::Duration}; + + use self::DummyContract::DummyContractInstance; + use crate::client::ClientTrait; + use crate::eth::{EthereumClient, StarknetCoreContract}; + use crate::messaging::{sync, CommonMessagingEventData}; + use alloy::{ + hex::FromHex, + node_bindings::{Anvil, AnvilInstance}, + primitives::{Address, U256}, + providers::{ProviderBuilder, RootProvider}, + sol, + transports::http::{Client, Http}, + }; + use mc_db::DatabaseService; + use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; + use mp_chain_config::ChainConfig; + use mp_utils::service::ServiceContext; + use rstest::*; + use starknet_api::core::Nonce; + use starknet_types_core::felt::Felt; + use tempfile::TempDir; + use tracing_test::traced_test; + use url::Url; + + struct TestRunner { + #[allow(dead_code)] + anvil: AnvilInstance, // Not used but needs to stay in scope otherwise it will be dropped + chain_config: Arc, + db_service: Arc, + dummy_contract: DummyContractInstance, RootProvider>>, + eth_client: EthereumClient, + mempool: Arc, + } + + // LogMessageToL2 from https://etherscan.io/tx/0x21980d6674d33e50deee43c6c30ef3b439bd148249b4539ce37b7856ac46b843 + // bytecode is compiled DummyContractBasicTestCase + sol!( + #[derive(Debug)] + #[sol(rpc, bytecode="6080604052348015600e575f80fd5b506108258061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c80634185df151461004e57806390985ef9146100585780639be446bf14610076578063af56443a146100a6575b5f80fd5b6100566100c2565b005b61006061013b565b60405161006d9190610488565b60405180910390f35b610090600480360381019061008b91906104cf565b6101ac565b60405161009d9190610512565b60405180910390f35b6100c060048036038101906100bb9190610560565b6101d8565b005b5f6100cb6101f3565b905080604001518160200151825f015173ffffffffffffffffffffffffffffffffffffffff167fdb80dd488acf86d17c747445b0eabb5d57c541d3bd7b6b87af987858e5066b2b846060015185608001518660a0015160405161013093929190610642565b60405180910390a450565b5f806101456101f3565b9050805f015173ffffffffffffffffffffffffffffffffffffffff1681602001518260800151836040015184606001515185606001516040516020016101909695949392919061072a565b6040516020818303038152906040528051906020012091505090565b5f805f9054906101000a900460ff166101c5575f6101cb565b6366b4f1055b63ffffffff169050919050565b805f806101000a81548160ff02191690831515021790555050565b6101fb610429565b5f73ae0ee0a63a2ce6baeeffe56e7714fb4efe48d41990505f7f073314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b8290505f7f01b64b1b3b690b43b9b514fb81377518f4039cd3e4f4914d8a6bdf01d679fb1990505f600767ffffffffffffffff81111561027757610276610795565b5b6040519080825280602002602001820160405280156102a55781602001602082028036833780820191505090505b5090506060815f815181106102bd576102bc6107c2565b5b60200260200101818152505062195091816001815181106102e1576102e06107c2565b5b60200260200101818152505065231594f0c7ea81600281518110610308576103076107c2565b5b60200260200101818152505060058160038151811061032a576103296107c2565b5b602002602001018181525050624554488160048151811061034e5761034d6107c2565b5b60200260200101818152505073bdb193c166cfb7be2e51711c5648ebeef94063bb81600581518110610383576103826107c2565b5b6020026020010181815250507e7d79cd86ba27a2508a9ca55c8b3474ca082bc5173d0467824f07a32e9db888816006815181106103c3576103c26107c2565b5b6020026020010181815250505f662386f26fc1000090505f6040518060c001604052808773ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182815250965050505050505090565b6040518060c001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f8152602001606081526020015f81526020015f81525090565b5f819050919050565b61048281610470565b82525050565b5f60208201905061049b5f830184610479565b92915050565b5f80fd5b6104ae81610470565b81146104b8575f80fd5b50565b5f813590506104c9816104a5565b92915050565b5f602082840312156104e4576104e36104a1565b5b5f6104f1848285016104bb565b91505092915050565b5f819050919050565b61050c816104fa565b82525050565b5f6020820190506105255f830184610503565b92915050565b5f8115159050919050565b61053f8161052b565b8114610549575f80fd5b50565b5f8135905061055a81610536565b92915050565b5f60208284031215610575576105746104a1565b5b5f6105828482850161054c565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6105bd816104fa565b82525050565b5f6105ce83836105b4565b60208301905092915050565b5f602082019050919050565b5f6105f08261058b565b6105fa8185610595565b9350610605836105a5565b805f5b8381101561063557815161061c88826105c3565b9750610627836105da565b925050600181019050610608565b5085935050505092915050565b5f6060820190508181035f83015261065a81866105e6565b90506106696020830185610503565b6106766040830184610503565b949350505050565b5f819050919050565b610698610693826104fa565b61067e565b82525050565b5f81905092915050565b6106b1816104fa565b82525050565b5f6106c283836106a8565b60208301905092915050565b5f6106d88261058b565b6106e2818561069e565b93506106ed836105a5565b805f5b8381101561071d57815161070488826106b7565b975061070f836105da565b9250506001810190506106f0565b5085935050505092915050565b5f6107358289610687565b6020820191506107458288610687565b6020820191506107558287610687565b6020820191506107658286610687565b6020820191506107758285610687565b60208201915061078582846106ce565b9150819050979650505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffdfea2646970667358221220ddc41ccc2cc8b33e1f608fb6cabf9ead1150daa8798e94e03ce9cd61e0d9389164736f6c634300081a0033")] + contract DummyContract { + bool isCanceled; + event LogMessageToL2(address indexed _fromAddress, uint256 indexed _toAddress, uint256 indexed _selector, uint256[] payload, uint256 nonce, uint256 fee); + + struct MessageData { + address fromAddress; + uint256 toAddress; + uint256 selector; + uint256[] payload; + uint256 nonce; + uint256 fee; + } + + function getMessageData() internal pure returns (MessageData memory) { + address fromAddress = address(993696174272377493693496825928908586134624850969); + uint256 toAddress = 3256441166037631918262930812410838598500200462657642943867372734773841898370; + uint256 selector = 774397379524139446221206168840917193112228400237242521560346153613428128537; + uint256[] memory payload = new uint256[](7); + payload[0] = 96; + payload[1] = 1659025; + payload[2] = 38575600093162; + payload[3] = 5; + payload[4] = 4543560; + payload[5] = 1082959358903034162641917759097118582889062097851; + payload[6] = 221696535382753200248526706088340988821219073423817576256483558730535647368; + uint256 nonce = 10000000000000000; + uint256 fee = 0; + + return MessageData(fromAddress, toAddress, selector, payload, nonce, fee); + } + + function fireEvent() public { + MessageData memory data = getMessageData(); + emit LogMessageToL2(data.fromAddress, data.toAddress, data.selector, data.payload, data.nonce, data.fee); + } + + function l1ToL2MessageCancellations(bytes32 msgHash) external view returns (uint256) { + return isCanceled ? 1723134213 : 0; + } + + function setIsCanceled(bool value) public { + isCanceled = value; + } + + function getL1ToL2MsgHash() external pure returns (bytes32) { + MessageData memory data = getMessageData(); + return keccak256( + abi.encodePacked( + uint256(uint160(data.fromAddress)), + data.toAddress, + data.nonce, + data.selector, + data.payload.length, + data.payload + ) + ); + } + } + ); + + /// Common setup for tests + /// + /// This test performs the following steps: + /// 1. Sets up test environemment + /// 2. Starts worker + /// 3. Fires a Message event from the dummy contract + /// 4. Waits for event to be processed + /// 5. Assert that the worker handle the event with correct data + /// 6. Assert that the hash computed by the worker is correct + /// 7. TODO : Assert that the tx is succesfully submited to the mempool + /// 8. Assert that the event is successfully pushed to the db + /// 9. TODO : Assert that the tx was correctly executed + #[fixture] + async fn setup_test_env() -> TestRunner { + // Start Anvil instance + let anvil = Anvil::new().block_time(1).chain_id(1337).try_spawn().expect("failed to spawn anvil instance"); + println!("Anvil started and running at `{}`", anvil.endpoint()); + + // Set up chain info + let chain_config = Arc::new(ChainConfig::madara_test()); + + // Set up database paths + let temp_dir = TempDir::new().expect("issue while creating temporary directory"); + let base_path = temp_dir.path().join("data"); + let backup_dir = Some(temp_dir.path().join("backups")); + + // Initialize database service + let db = Arc::new( + DatabaseService::new(&base_path, backup_dir, false, chain_config.clone(), Default::default()) + .await + .expect("Failed to create database service"), + ); + + let l1_gas_setter = GasPriceProvider::new(); + let l1_data_provider: Arc = Arc::new(l1_gas_setter.clone()); + + let mempool = Arc::new(Mempool::new( + Arc::clone(db.backend()), + Arc::clone(&l1_data_provider), + MempoolLimits::for_testing(), + )); + + // Set up provider + let rpc_url: Url = anvil.endpoint().parse().expect("issue while parsing"); + let provider = ProviderBuilder::new().on_http(rpc_url); + + // Set up dummy contract + let contract = DummyContract::deploy(provider.clone()).await.unwrap(); + + let core_contract = StarknetCoreContract::new(*contract.address(), provider.clone()); + + let eth_client = + EthereumClient { provider: Arc::new(provider.clone()), l1_core_contract: core_contract.clone() }; + + TestRunner { anvil, chain_config, db_service: db, dummy_contract: contract, eth_client, mempool } + } + + /// Test the basic workflow of l1 -> l2 messaging + /// + /// This test performs the following steps: + /// 1. Sets up test environemment + /// 2. Starts worker + /// 3. Fires a Message event from the dummy contract + /// 4. Waits for event to be processed + /// 5. Assert that the worker handle the event with correct data + /// 6. Assert that the hash computed by the worker is correct + /// 7. TODO : Assert that the tx is succesfully submited to the mempool + /// 8. Assert that the event is successfully pushed to the db + /// 9. TODO : Assert that the tx was correctly executed + #[rstest] + #[traced_test] + #[tokio::test] + async fn e2e_test_basic_workflow(#[future] setup_test_env: TestRunner) { + let TestRunner { chain_config, db_service: db, dummy_contract: contract, eth_client, anvil: _anvil, mempool } = + setup_test_env.await; + + // Start worker + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(eth_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; + + let _ = contract.setIsCanceled(false).send().await; + // Send a Event and wait for processing, Panic if fail + let _ = contract.fireEvent().send().await.expect("Failed to fire event"); + tokio::time::sleep(Duration::from_secs(5)).await; + + // Assert that event was caught by the worker with correct data + // TODO: Maybe add some more assert + assert!(logs_contain("fromAddress: \"0xae0ee0a63a2ce6baeeffe56e7714fb4efe48d419\"")); + + // Assert the tx hash computed by the worker is correct + let event_hash = contract.getL1ToL2MsgHash().call().await.expect("failed to get hash")._0.to_string(); + assert!(logs_contain(&format!("event hash: {:?}", event_hash))); + + // TODO : Assert that the tx has been included in the mempool + + // Assert that the event is well stored in db + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_ne!(last_block.block_number, 0); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); + // TODO : Assert that the tx was correctly executed + + // Explicitly cancel the listen task, else it would be running in the background + worker_handle.abort(); + } + + /// Test the workflow of l1 -> l2 messaging with duplicate event + /// + /// This test performs the following steps: + /// 1. Sets up test environemment + /// 2. Starts worker + /// 3. Fires a Message event from the dummy contract + /// 4. Waits for event to be processed + /// 5. Assert that the event is well stored in db + /// 6. Fires a Message with the same event from the dummy contract + /// 7. Assert that the last event stored is the first one + #[rstest] + #[traced_test] + #[tokio::test] + async fn e2e_test_already_processed_event(#[future] setup_test_env: TestRunner) { + let TestRunner { chain_config, db_service: db, dummy_contract: contract, eth_client, anvil: _anvil, mempool } = + setup_test_env.await; + + // Start worker + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(eth_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; + + let _ = contract.setIsCanceled(false).send().await; + let _ = contract.fireEvent().send().await.expect("Failed to fire event"); + tokio::time::sleep(Duration::from_secs(5)).await; + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_ne!(last_block.block_number, 0); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); + + // Send the event a second time + let _ = contract.fireEvent().send().await.expect("Failed to fire event"); + tokio::time::sleep(Duration::from_secs(5)).await; + // Assert that the last event in db is still the same as it is already processed (same nonce) + assert_eq!( + last_block.block_number, + db.backend() + .messaging_last_synced_l1_block_with_event() + .expect("failed to retrieve block") + .unwrap() + .block_number + ); + assert!(logs_contain("Event already processed")); + + worker_handle.abort(); + } + + /// Test the workflow of l1 -> l2 messaging with message cancelled + /// + /// This test performs the following steps: + /// 1. Sets up test environemment + /// 2. Starts worker + /// 3. Fires a Message event from the dummy contract + /// 4. Waits for event to be processed + /// 5. Assert that the event is not stored in db + #[rstest] + #[traced_test] + #[tokio::test] + async fn e2e_test_message_canceled(#[future] setup_test_env: TestRunner) { + let TestRunner { chain_config, db_service: db, dummy_contract: contract, eth_client, anvil: _anvil, mempool } = + setup_test_env.await; + + // Start worker + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(eth_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; + + // Mock cancelled message + let _ = contract.setIsCanceled(true).send().await; + let _ = contract.fireEvent().send().await.expect("Failed to fire event"); + tokio::time::sleep(Duration::from_secs(5)).await; + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_eq!(last_block.block_number, 0); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + // cancelled message nonce should be inserted to avoid reprocessing + assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); + assert!(logs_contain("Message was cancelled in block at timestamp: 0x66b4f105")); + + worker_handle.abort(); + } + + /// Test taken from starknet.rs to ensure consistency + /// https://github.com/xJonathanLEI/starknet-rs/blob/2ddc69479d326ed154df438d22f2d720fbba746e/starknet-core/src/types/msg.rs#L96 + #[rstest] + #[tokio::test] + async fn test_msg_to_l2_hash() { + let TestRunner { + chain_config: _chain_config, + db_service: _db, + dummy_contract: _contract, + eth_client, + anvil: _anvil, + mempool: _mempool, + } = setup_test_env().await; + + let msg = eth_client + .get_messaging_hash(&CommonMessagingEventData { + from: Felt::from_bytes_be_slice( + Address::from_hex("c3511006C04EF1d78af4C8E0e74Ec18A6E64Ff9e").unwrap().0 .0.to_vec().as_slice(), + ), + to: Felt::from_hex("0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82").unwrap(), + selector: Felt::from_hex("0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5").unwrap(), + payload: vec![ + Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7").unwrap(), + Felt::from_hex("0x2c68af0bb140000").unwrap(), + Felt::from_hex("0x0").unwrap(), + ], + nonce: Felt::from_bytes_be_slice(U256::from(775628).to_be_bytes_vec().as_slice()), + fee: Some(u128::try_from(Felt::from_bytes_be_slice(U256::ZERO.to_be_bytes_vec().as_slice())).unwrap()), + transaction_hash: Felt::ZERO, + message_hash: None, + block_number: 0, + event_index: None, + }) + .expect("Failed to compute l1 to l2 msg hash"); + + let expected_hash = + <[u8; 32]>::from_hex("c51a543ef9563ad2545342b390b67edfcddf9886aa36846cf70382362fc5fab3").unwrap(); + + assert_eq!(msg, expected_hash); + } +} + +#[cfg(test)] +mod eth_client_event_subscription_test { + use super::*; + use std::{sync::Arc, time::Duration}; + + use crate::eth::event::EthereumEventStream; + use crate::eth::{EthereumClient, EthereumClientConfig, StarknetCoreContract}; + use crate::state_update::state_update_worker; + use alloy::{node_bindings::Anvil, providers::ProviderBuilder, sol}; + use mc_db::DatabaseService; + use mp_chain_config::ChainConfig; + use rstest::*; + use tempfile::TempDir; + use url::Url; + + sol!( + #[sol(rpc, bytecode="6080604052348015600e575f80fd5b506101618061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c80634185df151461002d575b5f80fd5b610035610037565b005b5f7f0639349b21e886487cd6b341de2050db8ab202d9c6b0e7a2666d598e5fcf81a690505f620a1caf90505f7f0279b69383ea92624c1ae4378ac7fae6428f47bbd21047ea0290c3653064188590507fd342ddf7a308dec111745b00315c14b7efb2bdae570a6856e088ed0c65a3576c8383836040516100b9939291906100f6565b60405180910390a1505050565b5f819050919050565b6100d8816100c6565b82525050565b5f819050919050565b6100f0816100de565b82525050565b5f6060820190506101095f8301866100cf565b61011660208301856100e7565b61012360408301846100cf565b94935050505056fea2646970667358221220fbc6fd165c86ed9af0c5fcab2830d4a72894fd6a98e9c16dbf9101c4c22e2f7d64736f6c634300081a0033")] + contract DummyContract { + event LogStateUpdate(uint256 globalRoot, int256 blockNumber, uint256 blockHash); + + function fireEvent() public { + uint256 globalRoot = 2814950447364693428789615812443623689251959344851195711990387747563915674022; + int256 blockNumber = 662703; + uint256 blockHash = 1119674286844400689540394420005977072742999649767515920196535047615668295813; + + emit LogStateUpdate(globalRoot, blockNumber, blockHash); + } + } + ); + + const L2_BLOCK_NUMBER: u64 = 662703; + const ANOTHER_ANVIL_PORT: u16 = 8548; + const EVENT_PROCESSING_TIME: u64 = 2; // Time to allow for event processing in seconds + + /// Test the event subscription and state update functionality + /// + /// This test performs the following steps: + /// 1. Sets up a mock Ethereum environment using Anvil + /// 2. Initializes necessary services (Database, Metrics) + /// 3. Deploys a dummy contract and sets up an Ethereum client + /// 4. Starts listening for state updates + /// 5. Fires an event from the dummy contract + /// 6. Waits for event processing and verifies the block number + #[rstest] + #[tokio::test] + async fn listen_and_update_state_when_event_fired_works() { + // Start Anvil instance + let anvil = Anvil::new() + .block_time(1) + .chain_id(1337) + .port(ANOTHER_ANVIL_PORT) + .try_spawn() + .expect("failed to spawn anvil instance"); + println!("Anvil started and running at `{}`", anvil.endpoint()); + + // Set up chain info + let chain_info = Arc::new(ChainConfig::madara_test()); + + // Set up database paths + let temp_dir = TempDir::new().expect("issue while creating temporary directory"); + let base_path = temp_dir.path().join("data"); + let backup_dir = Some(temp_dir.path().join("backups")); + + // Initialize database service + let db = Arc::new( + DatabaseService::new(&base_path, backup_dir, false, chain_info.clone(), Default::default()) + .await + .expect("Failed to create database service"), + ); + + let rpc_url: Url = anvil.endpoint().parse().expect("issue while parsing"); + let provider = ProviderBuilder::new().on_http(rpc_url); + + let contract = DummyContract::deploy(provider.clone()).await.unwrap(); + let core_contract = StarknetCoreContract::new(*contract.address(), provider.clone()); + + let eth_client = EthereumClient { provider: Arc::new(provider), l1_core_contract: core_contract.clone() }; + let l1_block_metrics = L1BlockMetrics::register().unwrap(); + + // Start listening for state updates + let listen_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + state_update_worker::( + Arc::clone(db.backend()), + Arc::new(Box::new(eth_client)), + ServiceContext::new_for_testing(), + Arc::new(l1_block_metrics), + ) + .await + .unwrap() + }) + }; + + let _ = contract.fireEvent().send().await.expect("Failed to fire event"); + + // Wait for event processing + tokio::time::sleep(Duration::from_secs(EVENT_PROCESSING_TIME)).await; + + // Verify the block number + let block_in_db = + db.backend().get_l1_last_confirmed_block().expect("Failed to get L1 last confirmed block number"); + + // Explicitly cancel the listen task, else it would be running in the background + listen_handle.abort(); + assert_eq!(block_in_db, Some(L2_BLOCK_NUMBER), "Block in DB does not match expected L2 block number"); + } +} diff --git a/crates/madara/client/settlement_client/src/messaging.rs b/crates/madara/client/settlement_client/src/messaging.rs new file mode 100644 index 000000000..c730e0ad9 --- /dev/null +++ b/crates/madara/client/settlement_client/src/messaging.rs @@ -0,0 +1,407 @@ +use crate::client::{ClientTrait, ClientType}; +use alloy::primitives::B256; +use futures::{Stream, StreamExt}; +use mc_db::l1_db::LastSyncedEventBlock; +use mc_db::MadaraBackend; +use mc_mempool::{Mempool, MempoolProvider}; +use mp_utils::service::ServiceContext; +use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; +use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; +use starknet_types_core::felt::Felt; +use std::sync::Arc; +use tracing::{error, info}; + +#[derive(Clone, Debug)] +pub struct CommonMessagingEventData { + pub from: Felt, + pub to: Felt, + pub selector: Felt, + pub nonce: Felt, + pub payload: Vec, + pub fee: Option, + pub transaction_hash: Felt, + pub message_hash: Option, + pub block_number: u64, + pub event_index: Option, +} + +pub async fn sync( + settlement_client: Arc>>, + backend: Arc, + chain_id: ChainId, + mempool: Arc, + mut ctx: ServiceContext, +) -> anyhow::Result<()> +where + S: Stream>> + Send + 'static, +{ + info!("⟠ Starting L1 Messages Syncing..."); + + let last_synced_event_block = match backend.messaging_last_synced_l1_block_with_event() { + Ok(Some(blk)) => blk, + Ok(None) => { + unreachable!("Should never be None") + } + Err(e) => { + error!("⟠ Madara Messaging DB unavailable: {:?}", e); + return Err(e.into()); + } + }; + + let stream = settlement_client.get_messaging_stream(last_synced_event_block).await?; + let mut event_stream = Box::pin(stream); + + while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { + if let Some(event) = event_result { + let event_data = event?; + let tx = parse_handle_message_transaction(&event_data)?; + let tx_nonce = tx.nonce; + + // Skip if already processed + if backend.has_l1_messaging_nonce(tx_nonce)? { + info!("Event already processed"); + return Ok(()); + } + + info!( + "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", + event_data.block_number, + format!("0x{}", event_data.transaction_hash.to_hex_string()), + format!("0x{}", event_data.transaction_hash.to_hex_string()), + ); + + // Check message hash and cancellation + let event_hash = settlement_client.get_messaging_hash(&event_data)?; + let converted_event_hash = match settlement_client.get_client_type() { + ClientType::ETH => B256::from_slice(event_hash.as_slice()).to_string(), + ClientType::STARKNET => Felt::from_bytes_be_slice(event_hash.as_slice()).to_hex_string(), + }; + info!("Checking for cancellation, event hash: {:?}", converted_event_hash); + + let cancellation_timestamp = settlement_client.get_l1_to_l2_message_cancellations(event_hash).await?; + if cancellation_timestamp != Felt::ZERO { + info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); + handle_cancelled_message(backend, tx_nonce)?; + return Ok(()); + } + + // Process message + match process_message(&backend, &event_data, &chain_id, mempool.clone()).await { + Ok(Some(tx_hash)) => { + info!( + "Message from block: {:?} submitted, transaction hash: {:?}", + event_data.block_number, tx_hash + ); + + let block_sent = + LastSyncedEventBlock::new(event_data.block_number, event_data.event_index.unwrap_or(0)); + backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; + } + Ok(None) => {} + Err(e) => { + error!( + "Unexpected error while processing Message from block: {:?}, error: {:?}", + event_data.block_number, e + ); + return Err(e); + } + } + } + } + Ok(()) +} + +fn handle_cancelled_message(backend: Arc, nonce: Nonce) -> anyhow::Result<()> { + match backend.has_l1_messaging_nonce(nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(nonce)?; + } + Ok(true) => {} + Err(e) => { + error!("Unexpected DB error: {:?}", e); + return Err(e.into()); + } + } + Ok(()) +} + +pub fn parse_handle_message_transaction(event: &CommonMessagingEventData) -> anyhow::Result { + let calldata: Calldata = { + let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); + calldata.push(event.from); + calldata.extend(event.payload.clone()); + Calldata(Arc::new(calldata)) + }; + + Ok(L1HandlerTransaction { + nonce: Nonce(event.nonce), + contract_address: ContractAddress(event.to.try_into()?), + entry_point_selector: EntryPointSelector(event.selector), + calldata, + version: TransactionVersion(Felt::ZERO), + }) +} + +async fn process_message( + backend: &MadaraBackend, + event: &CommonMessagingEventData, + _chain_id: &ChainId, + mempool: Arc, +) -> anyhow::Result> { + let transaction = parse_handle_message_transaction(event)?; + let tx_nonce = transaction.nonce; + let fees = event.fee; + + // Ensure that L1 message has not been executed + match backend.has_l1_messaging_nonce(tx_nonce) { + Ok(false) => { + backend.set_l1_messaging_nonce(tx_nonce)?; + } + Ok(true) => { + tracing::debug!("⟠ Event already processed: {:?}", transaction); + return Ok(None); + } + Err(e) => { + error!("⟠ Unexpected DB error: {:?}", e); + return Err(e.into()); + } + }; + + let res = mempool.accept_l1_handler_tx(transaction.into(), fees.unwrap_or(0))?; + + Ok(Some(res.transaction_hash)) +} + +#[cfg(test)] +mod messaging_module_tests { + use super::*; + use crate::client::{DummyConfig, DummyStream, MockClientTrait}; + use futures::stream; + use mc_db::DatabaseService; + use mc_mempool::{GasPriceProvider, L1DataProvider, MempoolLimits}; + use mp_chain_config::ChainConfig; + use rstest::{fixture, rstest}; + use starknet_types_core::felt::Felt; + use std::time::Duration; + use tempfile::TempDir; + use tokio::time::timeout; + + // Helper function to create a mock event + fn create_mock_event(block_number: u64, nonce: u64) -> CommonMessagingEventData { + CommonMessagingEventData { + block_number, + transaction_hash: Felt::from(1), + event_index: Some(0), + from: Felt::from(123), + to: Felt::from(456), + selector: Felt::from(789), + payload: vec![Felt::from(1), Felt::from(2)], + nonce: Felt::from(nonce), + fee: Some(1000), + message_hash: None, + } + } + + struct MessagingTestRunner { + client: MockClientTrait, + db: Arc, + mempool: Arc, + ctx: ServiceContext, + chain_config: Arc, + } + + #[fixture] + async fn setup_messaging_tests() -> MessagingTestRunner { + // Set up chain info + let chain_config = Arc::new(ChainConfig::madara_test()); + + // Set up database paths + let temp_dir = TempDir::new().expect("issue while creating temporary directory"); + let base_path = temp_dir.path().join("data"); + let backup_dir = Some(temp_dir.path().join("backups")); + + // Initialize database service + let db = Arc::new( + DatabaseService::new(&base_path, backup_dir, false, chain_config.clone(), Default::default()) + .await + .expect("Failed to create database service"), + ); + + let l1_gas_setter = GasPriceProvider::new(); + let l1_data_provider: Arc = Arc::new(l1_gas_setter.clone()); + + let mempool = Arc::new(Mempool::new( + Arc::clone(db.backend()), + Arc::clone(&l1_data_provider), + MempoolLimits::for_testing(), + )); + + // Create a new context for mocking the static new() method + let ctx = MockClientTrait::new_context(); + ctx.expect().returning(|_| Ok(MockClientTrait::default())); + let mock_client = MockClientTrait::new(DummyConfig).await.expect("Unable to init new mock client"); + + let ctx = ServiceContext::new_for_testing(); + + MessagingTestRunner { client: mock_client, db, mempool, ctx, chain_config } + } + + #[rstest] + #[tokio::test] + async fn test_sync_processes_new_message( + #[future] setup_messaging_tests: MessagingTestRunner, + ) -> anyhow::Result<()> { + let MessagingTestRunner { mut client, db, mempool, ctx, chain_config } = setup_messaging_tests.await; + + // Setup mock event + let mock_event = create_mock_event(100, 1); + let event_clone = mock_event.clone(); + + let backend = db.backend(); + + // Setup mock for last synced block + backend.messaging_update_last_synced_l1_block_with_event(LastSyncedEventBlock::new(99, 0))?; + + // Mock get_messaging_stream + client + .expect_get_messaging_stream() + .times(1) + .returning(move |_| Ok(Box::pin(stream::iter(vec![Some(Ok(mock_event.clone()))])))); + + // Mock get_messaging_hash + client.expect_get_messaging_hash().times(1).returning(|_| Ok(vec![0u8; 32])); + + // Mock get_client_type + client.expect_get_client_type().times(1).returning(|| ClientType::ETH); + + // Mock get_l1_to_l2_message_cancellations + client.expect_get_l1_to_l2_message_cancellations().times(1).returning(|_| Ok(Felt::ZERO)); + + let client: Arc>> = + Arc::new(Box::new(client)); + + timeout( + Duration::from_secs(1), + sync(client, backend.clone(), chain_config.chain_id.clone(), mempool.clone(), ctx), + ) + .await??; + + // Verify the message was processed + assert!(backend.has_l1_messaging_nonce(Nonce(event_clone.nonce))?); + + Ok(()) + } + + #[rstest] + #[tokio::test] + async fn test_sync_handles_cancelled_message( + #[future] setup_messaging_tests: MessagingTestRunner, + ) -> anyhow::Result<()> { + let MessagingTestRunner { mut client, db, mempool, ctx, chain_config } = setup_messaging_tests.await; + + let backend = db.backend(); + + // Setup mock event + let mock_event = create_mock_event(100, 1); + let event_clone = mock_event.clone(); + + // Setup mock for last synced block + backend.messaging_update_last_synced_l1_block_with_event(LastSyncedEventBlock::new(99, 0))?; + + // Mock get_messaging_stream + client + .expect_get_messaging_stream() + .times(1) + .returning(move |_| Ok(Box::pin(stream::iter(vec![Some(Ok(mock_event.clone()))])))); + + // Mock get_messaging_hash + client.expect_get_messaging_hash().times(1).returning(|_| Ok(vec![0u8; 32])); + + // Mock get_client_type + client.expect_get_client_type().times(1).returning(|| ClientType::ETH); + + // Mock get_l1_to_l2_message_cancellations - return non-zero to indicate cancellation + client.expect_get_l1_to_l2_message_cancellations().times(1).returning(|_| Ok(Felt::from(12345))); + + let client: Arc>> = + Arc::new(Box::new(client)); + + timeout( + Duration::from_secs(1), + sync(client, backend.clone(), chain_config.chain_id.clone(), mempool.clone(), ctx), + ) + .await??; + + // Verify the cancelled message was handled correctly + assert!(backend.has_l1_messaging_nonce(Nonce(event_clone.nonce))?); + + Ok(()) + } + + #[rstest] + #[tokio::test] + async fn test_sync_skips_already_processed_message( + #[future] setup_messaging_tests: MessagingTestRunner, + ) -> anyhow::Result<()> { + let MessagingTestRunner { mut client, db, mempool, ctx, chain_config } = setup_messaging_tests.await; + + let backend = db.backend(); + + // Setup mock event + let mock_event = create_mock_event(100, 1); + + // Pre-set the nonce as processed + backend.set_l1_messaging_nonce(Nonce(mock_event.nonce))?; + + // Setup mock for last synced block + backend.messaging_update_last_synced_l1_block_with_event(LastSyncedEventBlock::new(99, 0))?; + + // Mock get_messaging_stream + client + .expect_get_messaging_stream() + .times(1) + .returning(move |_| Ok(Box::pin(stream::iter(vec![Some(Ok(mock_event.clone()))])))); + + // Mock get_messaging_hash - should not be called + client.expect_get_messaging_hash().times(0); + + let client: Arc>> = + Arc::new(Box::new(client)); + + timeout( + Duration::from_secs(1), + sync(client, backend.clone(), chain_config.chain_id.clone(), mempool.clone(), ctx), + ) + .await??; + + Ok(()) + } + + #[rstest] + #[tokio::test] + async fn test_sync_handles_stream_errors( + #[future] setup_messaging_tests: MessagingTestRunner, + ) -> anyhow::Result<()> { + let MessagingTestRunner { mut client, db, mempool, ctx, chain_config } = setup_messaging_tests.await; + + let backend = db.backend(); + + // Setup mock for last synced block + backend.messaging_update_last_synced_l1_block_with_event(LastSyncedEventBlock::new(99, 0))?; + + // Mock get_messaging_stream to return error + client + .expect_get_messaging_stream() + .times(1) + .returning(move |_| Ok(Box::pin(stream::iter(vec![Some(Err(anyhow::anyhow!("Stream error")))])))); + + let client: Arc>> = + Arc::new(Box::new(client)); + + let result = sync(client, backend.clone(), chain_config.chain_id.clone(), mempool.clone(), ctx).await; + assert!(result.is_err()); + assert!(result.unwrap_err().to_string().contains("Stream error")); + + Ok(()) + } +} diff --git a/crates/madara/client/settlement_client/src/messaging/mod.rs b/crates/madara/client/settlement_client/src/messaging/mod.rs deleted file mode 100644 index 772deb573..000000000 --- a/crates/madara/client/settlement_client/src/messaging/mod.rs +++ /dev/null @@ -1,217 +0,0 @@ -#[cfg(test)] -mod tests; - -use crate::client::{ClientTrait, ClientType}; -use alloy::primitives::B256; -use futures::{Stream, StreamExt}; -use mc_db::l1_db::LastSyncedEventBlock; -use mc_db::MadaraBackend; -use mc_mempool::{Mempool, MempoolProvider}; -use mp_utils::service::ServiceContext; -use starknet_api::core::{ChainId, ContractAddress, EntryPointSelector, Nonce}; -use starknet_api::transaction::{Calldata, L1HandlerTransaction, TransactionVersion}; -use starknet_types_core::felt::Felt; -use std::sync::Arc; -use tracing::{error, info}; - -#[derive(Clone, Debug)] -pub struct CommonMessagingEventData { - pub from: Vec, - pub to: Vec, - pub selector: Vec, - pub nonce: Vec, - pub payload: Vec>, - pub fee: Option>, - pub transaction_hash: Vec, - pub message_hash: Option>, - pub block_number: u64, - pub event_index: Option, -} - -pub async fn sync( - settlement_client: Arc>>, - backend: Arc, - chain_id: ChainId, - mempool: Arc, - mut ctx: ServiceContext, -) -> anyhow::Result<()> -where - S: Stream>> + Send + 'static, -{ - info!("⟠ Starting L1 Messages Syncing..."); - - let last_synced_event_block = match backend.messaging_last_synced_l1_block_with_event() { - Ok(Some(blk)) => blk, - Ok(None) => { - unreachable!("Should never be None") - } - Err(e) => { - error!("⟠ Madara Messaging DB unavailable: {:?}", e); - return Err(e.into()); - } - }; - - let stream = settlement_client.get_event_stream(last_synced_event_block).await?; - let mut event_stream = Box::pin(stream); - - while let Some(Some(event_result)) = ctx.run_until_cancelled(event_stream.next()).await { - if let Some(event) = event_result { - let event_data = event?; - let tx = parse_handle_message_transaction(&event_data)?; - let tx_nonce = tx.nonce; - - // Skip if already processed - if backend.has_l1_messaging_nonce(tx_nonce)? { - info!("Event already processed"); - return Ok(()); - } - - info!( - "Processing Message from block: {:?}, transaction_hash: {:?}, fromAddress: {:?}", - event_data.block_number, - format!("0x{}", hex::encode(event_data.transaction_hash.clone().as_slice())), - format!("0x{}", hex::encode(event_data.from.as_slice())), - ); - - // Check message hash and cancellation - let event_hash = settlement_client.get_messaging_hash(&event_data)?; - let converted_event_hash = match settlement_client.get_client_type() { - ClientType::ETH => B256::from_slice(event_hash.as_slice()).to_string(), - ClientType::STARKNET => Felt::from_bytes_be_slice(event_hash.as_slice()).to_hex_string(), - }; - info!("Checking for cancellation, event hash: {:?}", converted_event_hash); - - let cancellation_timestamp = settlement_client.get_l1_to_l2_message_cancellations(event_hash).await?; - if cancellation_timestamp != Felt::ZERO { - info!("Message was cancelled in block at timestamp: {:?}", cancellation_timestamp); - handle_cancelled_message(backend, tx_nonce)?; - return Ok(()); - } - - // Process message - match process_message(&backend, &event_data, &chain_id, mempool.clone()).await { - Ok(Some(tx_hash)) => { - info!( - "Message from block: {:?} submitted, transaction hash: {:?}", - event_data.block_number, tx_hash - ); - - let block_sent = - LastSyncedEventBlock::new(event_data.block_number, event_data.event_index.unwrap_or(0)); - backend.messaging_update_last_synced_l1_block_with_event(block_sent)?; - } - Ok(None) => {} - Err(e) => { - error!( - "Unexpected error while processing Message from block: {:?}, error: {:?}", - event_data.block_number, e - ); - return Err(e); - } - } - } - } - Ok(()) -} - -fn handle_cancelled_message(backend: Arc, nonce: Nonce) -> anyhow::Result<()> { - match backend.has_l1_messaging_nonce(nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(nonce)?; - } - Ok(true) => {} - Err(e) => { - error!("Unexpected DB error: {:?}", e); - return Err(e.into()); - } - } - Ok(()) -} - -pub fn parse_handle_message_transaction(event: &CommonMessagingEventData) -> anyhow::Result { - // L1 from address. - let from_address = Felt::from_bytes_be_slice(event.from.as_slice()); - - // L2 contract to call. - let contract_address = Felt::from_bytes_be_slice(event.to.as_slice()); - - // Function of the contract to call. - let entry_point_selector = Felt::from_bytes_be_slice(event.selector.as_slice()); - - // L1 message nonce. - let nonce = Felt::from_bytes_be_slice(event.nonce.as_slice()); - - let event_payload: Vec = - event.payload.clone().into_iter().map(|ele| Felt::from_bytes_be_slice(ele.as_slice())).collect(); - - let calldata: Calldata = { - let mut calldata: Vec<_> = Vec::with_capacity(event.payload.len() + 1); - calldata.push(from_address); - calldata.extend(event_payload); - Calldata(Arc::new(calldata)) - }; - - Ok(L1HandlerTransaction { - nonce: Nonce(nonce), - contract_address: ContractAddress(contract_address.try_into()?), - entry_point_selector: EntryPointSelector(entry_point_selector), - calldata, - version: TransactionVersion(Felt::ZERO), - }) -} - -async fn process_message( - backend: &MadaraBackend, - event: &CommonMessagingEventData, - _chain_id: &ChainId, - mempool: Arc, -) -> anyhow::Result> { - let transaction = parse_handle_message_transaction(event)?; - let tx_nonce = transaction.nonce; - let fees = vec_to_u128_be(event.fee.clone().unwrap_or(vec![0])); - - // Ensure that L1 message has not been executed - match backend.has_l1_messaging_nonce(tx_nonce) { - Ok(false) => { - backend.set_l1_messaging_nonce(tx_nonce)?; - } - Ok(true) => { - tracing::debug!("⟠ Event already processed: {:?}", transaction); - return Ok(None); - } - Err(e) => { - error!("⟠ Unexpected DB error: {:?}", e); - return Err(e.into()); - } - }; - - let res = mempool.accept_l1_handler_tx(transaction.into(), fees.unwrap_or(0))?; - - Ok(Some(res.transaction_hash)) -} - -fn vec_to_u128_be(bytes: Vec) -> Option { - if bytes.len() > 16 { - return None; - } - // Pad with zeros if less than 16 bytes - let mut padded = vec![0u8; 16]; - padded[16 - bytes.len()..].copy_from_slice(&bytes); - Some(u128::from_be_bytes(padded.try_into().unwrap())) -} - -#[cfg(test)] -mod sync_utils_tests { - use crate::messaging::vec_to_u128_be; - use rstest::rstest; - - #[rstest] - #[case(vec![1, 2, 3, 4], Some(0x00000000000000000000000001020304))] - #[case(vec![], Some(0x00000000000000000000000000000000))] - #[case(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], Some(0x0102030405060708090a0b0c0d0e0f10))] - #[case(vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], None)] - fn vec_to_u128(#[case] bytes: Vec, #[case] expected: Option) { - let result = vec_to_u128_be(bytes); - assert_eq!(result, expected); - } -} diff --git a/crates/madara/client/settlement_client/src/messaging/tests.rs b/crates/madara/client/settlement_client/src/messaging/tests.rs deleted file mode 100644 index 2a4970429..000000000 --- a/crates/madara/client/settlement_client/src/messaging/tests.rs +++ /dev/null @@ -1,635 +0,0 @@ -#[cfg(test)] -mod l2_messaging_test { - use crate::client::ClientTrait; - use crate::messaging::sync; - use crate::starknet::utils::{ - cancel_messaging_event, fire_messaging_event, prepare_starknet_client_messaging_test, MadaraProcess, - StarknetAccount, MADARA_PORT, - }; - use crate::starknet::{StarknetClient, StarknetClientConfig}; - use mc_db::DatabaseService; - use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; - use mp_chain_config::ChainConfig; - use mp_utils::service::ServiceContext; - use rstest::{fixture, rstest}; - use starknet_api::core::Nonce; - use starknet_types_core::felt::Felt; - use std::sync::Arc; - use std::time::Duration; - use tempfile::TempDir; - use tracing_test::traced_test; - use url::Url; - - struct TestRunnerStarknet { - #[allow(dead_code)] - madara: MadaraProcess, // Not used but needs to stay in scope otherwise it will be dropped - account: StarknetAccount, - chain_config: Arc, - db_service: Arc, - deployed_address: Felt, - starknet_client: StarknetClient, - mempool: Arc, - } - - #[fixture] - async fn setup_test_env_starknet() -> TestRunnerStarknet { - let (account, deployed_contract_address, madara) = prepare_starknet_client_messaging_test().await.unwrap(); - - // Set up chain info - let chain_config = Arc::new(ChainConfig::madara_test()); - - // Set up database paths - let temp_dir = TempDir::new().expect("issue while creating temporary directory"); - let base_path = temp_dir.path().join("data"); - let backup_dir = Some(temp_dir.path().join("backups")); - - // Initialize database service - let db = Arc::new( - DatabaseService::new(&base_path, backup_dir, false, chain_config.clone(), Default::default()) - .await - .expect("Failed to create database service"), - ); - - let starknet_client = StarknetClient::new(StarknetClientConfig { - url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str()).unwrap(), - l2_contract_address: deployed_contract_address, - }) - .await - .unwrap(); - - let l1_gas_setter = GasPriceProvider::new(); - let l1_data_provider: Arc = Arc::new(l1_gas_setter.clone()); - - let mempool = Arc::new(Mempool::new( - Arc::clone(db.backend()), - Arc::clone(&l1_data_provider), - MempoolLimits::for_testing(), - )); - - TestRunnerStarknet { - madara, - account, - chain_config, - db_service: db, - deployed_address: deployed_contract_address, - starknet_client, - mempool, - } - } - - #[rstest] - #[traced_test] - #[tokio::test] - async fn e2e_test_basic_workflow_starknet( - #[future] setup_test_env_starknet: TestRunnerStarknet, - ) -> anyhow::Result<()> { - // Initial Setup - // ================================== - let TestRunnerStarknet { - madara: _madara, - account, - chain_config, - db_service: db, - deployed_address: deployed_contract_address, - starknet_client, - mempool, - } = setup_test_env_starknet.await; - - // Start worker handle - // ================================== - let worker_handle = { - let db = Arc::clone(&db); - tokio::spawn(async move { - sync( - Arc::new(Box::new(starknet_client)), - Arc::clone(db.backend()), - chain_config.chain_id.clone(), - mempool, - ServiceContext::new_for_testing(), - ) - .await - }) - }; - - // Firing the event - let fire_event_block_number = fire_messaging_event(&account, deployed_contract_address).await?; - tokio::time::sleep(Duration::from_secs(10)).await; - - // Log asserts - // =========== - assert!(logs_contain("fromAddress: \"0x07484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); - // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 - // expecting the same in logs - assert!(logs_contain("event hash: \"0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0\"")); - - // Assert that the event is well stored in db - let last_block = - db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); - assert_eq!(last_block.block_number, fire_event_block_number); - let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); - assert!(db.backend().has_l1_messaging_nonce(nonce)?); - - // Cancelling worker - worker_handle.abort(); - Ok(()) - } - - #[rstest] - #[traced_test] - #[tokio::test] - // This test is redundant now as the event poller will not return the same - // event twice with same nonce that's why added ignore here. - #[ignore] - async fn e2e_test_already_processed_event_starknet( - #[future] setup_test_env_starknet: TestRunnerStarknet, - ) -> anyhow::Result<()> { - // Initial Setup - // ================================== - let TestRunnerStarknet { - madara: _madara, - account, - chain_config, - db_service: db, - deployed_address: deployed_contract_address, - starknet_client, - mempool, - } = setup_test_env_starknet.await; - - // Start worker handle - // ================================== - let worker_handle = { - let db = Arc::clone(&db); - tokio::spawn(async move { - sync( - Arc::new(Box::new(starknet_client)), - Arc::clone(db.backend()), - chain_config.chain_id.clone(), - mempool, - ServiceContext::new_for_testing(), - ) - .await - }) - }; - - // Firing the event - let fire_event_block_number = fire_messaging_event(&account, deployed_contract_address).await?; - tokio::time::sleep(Duration::from_secs(10)).await; - - // Log asserts - // =========== - assert!(logs_contain("fromAddress: \"0x07484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); - // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 - // expecting the same in logs - assert!(logs_contain("event hash: \"0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0\"")); - - // Assert that the event is well stored in db - let last_block = - db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); - assert_eq!(last_block.block_number, fire_event_block_number); - let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); - assert!(db.backend().has_l1_messaging_nonce(nonce)?); - - // Firing the event second time - fire_messaging_event(&account, deployed_contract_address).await?; - tokio::time::sleep(Duration::from_secs(15)).await; - // Assert that the event processed was in last block only not in the latest block. - assert_eq!( - last_block.block_number, - db.backend() - .messaging_last_synced_l1_block_with_event() - .expect("failed to retrieve block") - .unwrap() - .block_number - ); - assert!(logs_contain("Event already processed")); - - // Cancelling worker - worker_handle.abort(); - Ok(()) - } - - #[rstest] - #[traced_test] - #[tokio::test] - async fn e2e_test_message_canceled_starknet( - #[future] setup_test_env_starknet: TestRunnerStarknet, - ) -> anyhow::Result<()> { - // Initial Setup - // ================================== - let TestRunnerStarknet { - madara: _madara, - account, - chain_config, - db_service: db, - deployed_address: deployed_contract_address, - starknet_client, - mempool, - } = setup_test_env_starknet.await; - - // Start worker handle - // ================================== - let worker_handle = { - let db = Arc::clone(&db); - tokio::spawn(async move { - sync( - Arc::new(Box::new(starknet_client)), - Arc::clone(db.backend()), - chain_config.chain_id.clone(), - mempool, - ServiceContext::new_for_testing(), - ) - .await - }) - }; - - cancel_messaging_event(&account, deployed_contract_address).await?; - // Firing cancelled event - fire_messaging_event(&account, deployed_contract_address).await?; - tokio::time::sleep(Duration::from_secs(15)).await; - - let last_block = - db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); - assert_eq!(last_block.block_number, 0); - let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); - // cancelled message nonce should be inserted to avoid reprocessing - assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); - assert!(logs_contain("Message was cancelled in block at timestamp: 0x66b4f105")); - - // Cancelling worker - worker_handle.abort(); - Ok(()) - } -} - -#[cfg(test)] -mod l1_messaging_tests { - - use std::{sync::Arc, time::Duration}; - - use self::DummyContract::DummyContractInstance; - use crate::client::ClientTrait; - use crate::eth::{EthereumClient, StarknetCoreContract}; - use crate::messaging::{sync, CommonMessagingEventData}; - use alloy::{ - hex::FromHex, - node_bindings::{Anvil, AnvilInstance}, - primitives::{Address, U256}, - providers::{ProviderBuilder, RootProvider}, - sol, - transports::http::{Client, Http}, - }; - use mc_db::DatabaseService; - use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; - use mp_chain_config::ChainConfig; - use mp_utils::service::ServiceContext; - use rstest::*; - use starknet_api::core::Nonce; - use starknet_types_core::felt::Felt; - use tempfile::TempDir; - use tracing_test::traced_test; - use url::Url; - - struct TestRunner { - #[allow(dead_code)] - anvil: AnvilInstance, // Not used but needs to stay in scope otherwise it will be dropped - chain_config: Arc, - db_service: Arc, - dummy_contract: DummyContractInstance, RootProvider>>, - eth_client: EthereumClient, - mempool: Arc, - } - - // LogMessageToL2 from https://etherscan.io/tx/0x21980d6674d33e50deee43c6c30ef3b439bd148249b4539ce37b7856ac46b843 - // bytecode is compiled DummyContractBasicTestCase - sol!( - #[derive(Debug)] - #[sol(rpc, bytecode="6080604052348015600e575f80fd5b506108258061001c5f395ff3fe608060405234801561000f575f80fd5b506004361061004a575f3560e01c80634185df151461004e57806390985ef9146100585780639be446bf14610076578063af56443a146100a6575b5f80fd5b6100566100c2565b005b61006061013b565b60405161006d9190610488565b60405180910390f35b610090600480360381019061008b91906104cf565b6101ac565b60405161009d9190610512565b60405180910390f35b6100c060048036038101906100bb9190610560565b6101d8565b005b5f6100cb6101f3565b905080604001518160200151825f015173ffffffffffffffffffffffffffffffffffffffff167fdb80dd488acf86d17c747445b0eabb5d57c541d3bd7b6b87af987858e5066b2b846060015185608001518660a0015160405161013093929190610642565b60405180910390a450565b5f806101456101f3565b9050805f015173ffffffffffffffffffffffffffffffffffffffff1681602001518260800151836040015184606001515185606001516040516020016101909695949392919061072a565b6040516020818303038152906040528051906020012091505090565b5f805f9054906101000a900460ff166101c5575f6101cb565b6366b4f1055b63ffffffff169050919050565b805f806101000a81548160ff02191690831515021790555050565b6101fb610429565b5f73ae0ee0a63a2ce6baeeffe56e7714fb4efe48d41990505f7f073314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b8290505f7f01b64b1b3b690b43b9b514fb81377518f4039cd3e4f4914d8a6bdf01d679fb1990505f600767ffffffffffffffff81111561027757610276610795565b5b6040519080825280602002602001820160405280156102a55781602001602082028036833780820191505090505b5090506060815f815181106102bd576102bc6107c2565b5b60200260200101818152505062195091816001815181106102e1576102e06107c2565b5b60200260200101818152505065231594f0c7ea81600281518110610308576103076107c2565b5b60200260200101818152505060058160038151811061032a576103296107c2565b5b602002602001018181525050624554488160048151811061034e5761034d6107c2565b5b60200260200101818152505073bdb193c166cfb7be2e51711c5648ebeef94063bb81600581518110610383576103826107c2565b5b6020026020010181815250507e7d79cd86ba27a2508a9ca55c8b3474ca082bc5173d0467824f07a32e9db888816006815181106103c3576103c26107c2565b5b6020026020010181815250505f662386f26fc1000090505f6040518060c001604052808773ffffffffffffffffffffffffffffffffffffffff16815260200186815260200185815260200184815260200183815260200182815250965050505050505090565b6040518060c001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f8152602001606081526020015f81526020015f81525090565b5f819050919050565b61048281610470565b82525050565b5f60208201905061049b5f830184610479565b92915050565b5f80fd5b6104ae81610470565b81146104b8575f80fd5b50565b5f813590506104c9816104a5565b92915050565b5f602082840312156104e4576104e36104a1565b5b5f6104f1848285016104bb565b91505092915050565b5f819050919050565b61050c816104fa565b82525050565b5f6020820190506105255f830184610503565b92915050565b5f8115159050919050565b61053f8161052b565b8114610549575f80fd5b50565b5f8135905061055a81610536565b92915050565b5f60208284031215610575576105746104a1565b5b5f6105828482850161054c565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6105bd816104fa565b82525050565b5f6105ce83836105b4565b60208301905092915050565b5f602082019050919050565b5f6105f08261058b565b6105fa8185610595565b9350610605836105a5565b805f5b8381101561063557815161061c88826105c3565b9750610627836105da565b925050600181019050610608565b5085935050505092915050565b5f6060820190508181035f83015261065a81866105e6565b90506106696020830185610503565b6106766040830184610503565b949350505050565b5f819050919050565b610698610693826104fa565b61067e565b82525050565b5f81905092915050565b6106b1816104fa565b82525050565b5f6106c283836106a8565b60208301905092915050565b5f6106d88261058b565b6106e2818561069e565b93506106ed836105a5565b805f5b8381101561071d57815161070488826106b7565b975061070f836105da565b9250506001810190506106f0565b5085935050505092915050565b5f6107358289610687565b6020820191506107458288610687565b6020820191506107558287610687565b6020820191506107658286610687565b6020820191506107758285610687565b60208201915061078582846106ce565b9150819050979650505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffdfea2646970667358221220ddc41ccc2cc8b33e1f608fb6cabf9ead1150daa8798e94e03ce9cd61e0d9389164736f6c634300081a0033")] - contract DummyContract { - bool isCanceled; - event LogMessageToL2(address indexed _fromAddress, uint256 indexed _toAddress, uint256 indexed _selector, uint256[] payload, uint256 nonce, uint256 fee); - - struct MessageData { - address fromAddress; - uint256 toAddress; - uint256 selector; - uint256[] payload; - uint256 nonce; - uint256 fee; - } - - function getMessageData() internal pure returns (MessageData memory) { - address fromAddress = address(993696174272377493693496825928908586134624850969); - uint256 toAddress = 3256441166037631918262930812410838598500200462657642943867372734773841898370; - uint256 selector = 774397379524139446221206168840917193112228400237242521560346153613428128537; - uint256[] memory payload = new uint256[](7); - payload[0] = 96; - payload[1] = 1659025; - payload[2] = 38575600093162; - payload[3] = 5; - payload[4] = 4543560; - payload[5] = 1082959358903034162641917759097118582889062097851; - payload[6] = 221696535382753200248526706088340988821219073423817576256483558730535647368; - uint256 nonce = 10000000000000000; - uint256 fee = 0; - - return MessageData(fromAddress, toAddress, selector, payload, nonce, fee); - } - - function fireEvent() public { - MessageData memory data = getMessageData(); - emit LogMessageToL2(data.fromAddress, data.toAddress, data.selector, data.payload, data.nonce, data.fee); - } - - function l1ToL2MessageCancellations(bytes32 msgHash) external view returns (uint256) { - return isCanceled ? 1723134213 : 0; - } - - function setIsCanceled(bool value) public { - isCanceled = value; - } - - function getL1ToL2MsgHash() external pure returns (bytes32) { - MessageData memory data = getMessageData(); - return keccak256( - abi.encodePacked( - uint256(uint160(data.fromAddress)), - data.toAddress, - data.nonce, - data.selector, - data.payload.length, - data.payload - ) - ); - } - } - ); - - /// Common setup for tests - /// - /// This test performs the following steps: - /// 1. Sets up test environemment - /// 2. Starts worker - /// 3. Fires a Message event from the dummy contract - /// 4. Waits for event to be processed - /// 5. Assert that the worker handle the event with correct data - /// 6. Assert that the hash computed by the worker is correct - /// 7. TODO : Assert that the tx is succesfully submited to the mempool - /// 8. Assert that the event is successfully pushed to the db - /// 9. TODO : Assert that the tx was correctly executed - #[fixture] - async fn setup_test_env() -> TestRunner { - // Start Anvil instance - let anvil = Anvil::new().block_time(1).chain_id(1337).try_spawn().expect("failed to spawn anvil instance"); - println!("Anvil started and running at `{}`", anvil.endpoint()); - - // Set up chain info - let chain_config = Arc::new(ChainConfig::madara_test()); - - // Set up database paths - let temp_dir = TempDir::new().expect("issue while creating temporary directory"); - let base_path = temp_dir.path().join("data"); - let backup_dir = Some(temp_dir.path().join("backups")); - - // Initialize database service - let db = Arc::new( - DatabaseService::new(&base_path, backup_dir, false, chain_config.clone(), Default::default()) - .await - .expect("Failed to create database service"), - ); - - let l1_gas_setter = GasPriceProvider::new(); - let l1_data_provider: Arc = Arc::new(l1_gas_setter.clone()); - - let mempool = Arc::new(Mempool::new( - Arc::clone(db.backend()), - Arc::clone(&l1_data_provider), - MempoolLimits::for_testing(), - )); - - // Set up provider - let rpc_url: Url = anvil.endpoint().parse().expect("issue while parsing"); - let provider = ProviderBuilder::new().on_http(rpc_url); - - // Set up dummy contract - let contract = DummyContract::deploy(provider.clone()).await.unwrap(); - - let core_contract = StarknetCoreContract::new(*contract.address(), provider.clone()); - - let eth_client = - EthereumClient { provider: Arc::new(provider.clone()), l1_core_contract: core_contract.clone() }; - - TestRunner { anvil, chain_config, db_service: db, dummy_contract: contract, eth_client, mempool } - } - - /// Test the basic workflow of l1 -> l2 messaging - /// - /// This test performs the following steps: - /// 1. Sets up test environemment - /// 2. Starts worker - /// 3. Fires a Message event from the dummy contract - /// 4. Waits for event to be processed - /// 5. Assert that the worker handle the event with correct data - /// 6. Assert that the hash computed by the worker is correct - /// 7. TODO : Assert that the tx is succesfully submited to the mempool - /// 8. Assert that the event is successfully pushed to the db - /// 9. TODO : Assert that the tx was correctly executed - #[rstest] - #[traced_test] - #[tokio::test] - async fn e2e_test_basic_workflow(#[future] setup_test_env: TestRunner) { - let TestRunner { chain_config, db_service: db, dummy_contract: contract, eth_client, anvil: _anvil, mempool } = - setup_test_env.await; - - // Start worker - let worker_handle = { - let db = Arc::clone(&db); - tokio::spawn(async move { - sync( - Arc::new(Box::new(eth_client)), - Arc::clone(db.backend()), - chain_config.chain_id.clone(), - mempool, - ServiceContext::new_for_testing(), - ) - .await - }) - }; - - let _ = contract.setIsCanceled(false).send().await; - // Send a Event and wait for processing, Panic if fail - let _ = contract.fireEvent().send().await.expect("Failed to fire event"); - tokio::time::sleep(Duration::from_secs(5)).await; - - // Assert that event was caught by the worker with correct data - // TODO: Maybe add some more assert - assert!(logs_contain("fromAddress: \"0xae0ee0a63a2ce6baeeffe56e7714fb4efe48d419\"")); - - // Assert the tx hash computed by the worker is correct - let event_hash = contract.getL1ToL2MsgHash().call().await.expect("failed to get hash")._0.to_string(); - assert!(logs_contain(&format!("event hash: {:?}", event_hash))); - - // TODO : Assert that the tx has been included in the mempool - - // Assert that the event is well stored in db - let last_block = - db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); - assert_ne!(last_block.block_number, 0); - let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); - assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); - // TODO : Assert that the tx was correctly executed - - // Explicitly cancel the listen task, else it would be running in the background - worker_handle.abort(); - } - - /// Test the workflow of l1 -> l2 messaging with duplicate event - /// - /// This test performs the following steps: - /// 1. Sets up test environemment - /// 2. Starts worker - /// 3. Fires a Message event from the dummy contract - /// 4. Waits for event to be processed - /// 5. Assert that the event is well stored in db - /// 6. Fires a Message with the same event from the dummy contract - /// 7. Assert that the last event stored is the first one - #[rstest] - #[traced_test] - #[tokio::test] - async fn e2e_test_already_processed_event(#[future] setup_test_env: TestRunner) { - let TestRunner { chain_config, db_service: db, dummy_contract: contract, eth_client, anvil: _anvil, mempool } = - setup_test_env.await; - - // Start worker - let worker_handle = { - let db = Arc::clone(&db); - tokio::spawn(async move { - sync( - Arc::new(Box::new(eth_client)), - Arc::clone(db.backend()), - chain_config.chain_id.clone(), - mempool, - ServiceContext::new_for_testing(), - ) - .await - }) - }; - - let _ = contract.setIsCanceled(false).send().await; - let _ = contract.fireEvent().send().await.expect("Failed to fire event"); - tokio::time::sleep(Duration::from_secs(5)).await; - let last_block = - db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); - assert_ne!(last_block.block_number, 0); - let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); - assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); - - // Send the event a second time - let _ = contract.fireEvent().send().await.expect("Failed to fire event"); - tokio::time::sleep(Duration::from_secs(5)).await; - // Assert that the last event in db is still the same as it is already processed (same nonce) - assert_eq!( - last_block.block_number, - db.backend() - .messaging_last_synced_l1_block_with_event() - .expect("failed to retrieve block") - .unwrap() - .block_number - ); - assert!(logs_contain("Event already processed")); - - worker_handle.abort(); - } - - /// Test the workflow of l1 -> l2 messaging with message cancelled - /// - /// This test performs the following steps: - /// 1. Sets up test environemment - /// 2. Starts worker - /// 3. Fires a Message event from the dummy contract - /// 4. Waits for event to be processed - /// 5. Assert that the event is not stored in db - #[rstest] - #[traced_test] - #[tokio::test] - async fn e2e_test_message_canceled(#[future] setup_test_env: TestRunner) { - let TestRunner { chain_config, db_service: db, dummy_contract: contract, eth_client, anvil: _anvil, mempool } = - setup_test_env.await; - - // Start worker - let worker_handle = { - let db = Arc::clone(&db); - tokio::spawn(async move { - sync( - Arc::new(Box::new(eth_client)), - Arc::clone(db.backend()), - chain_config.chain_id.clone(), - mempool, - ServiceContext::new_for_testing(), - ) - .await - }) - }; - - // Mock cancelled message - let _ = contract.setIsCanceled(true).send().await; - let _ = contract.fireEvent().send().await.expect("Failed to fire event"); - tokio::time::sleep(Duration::from_secs(5)).await; - let last_block = - db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); - assert_eq!(last_block.block_number, 0); - let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); - // cancelled message nonce should be inserted to avoid reprocessing - assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); - assert!(logs_contain("Message was cancelled in block at timestamp: 0x66b4f105")); - - worker_handle.abort(); - } - - /// Test taken from starknet.rs to ensure consistency - /// https://github.com/xJonathanLEI/starknet-rs/blob/2ddc69479d326ed154df438d22f2d720fbba746e/starknet-core/src/types/msg.rs#L96 - #[rstest] - #[tokio::test] - async fn test_msg_to_l2_hash() { - let TestRunner { - chain_config: _chain_config, - db_service: _db, - dummy_contract: _contract, - eth_client, - anvil: _anvil, - mempool: _mempool, - } = setup_test_env().await; - - let msg = eth_client - .get_messaging_hash(&CommonMessagingEventData { - from: Address::from_hex("c3511006C04EF1d78af4C8E0e74Ec18A6E64Ff9e").unwrap().0 .0.to_vec(), - to: Felt::from_hex("0x73314940630fd6dcda0d772d4c972c4e0a9946bef9dabf4ef84eda8ef542b82") - .unwrap() - .to_bytes_be() - .to_vec(), - selector: Felt::from_hex("0x2d757788a8d8d6f21d1cd40bce38a8222d70654214e96ff95d8086e684fbee5") - .unwrap() - .to_bytes_be() - .to_vec(), - payload: vec![ - Felt::from_hex("0x689ead7d814e51ed93644bc145f0754839b8dcb340027ce0c30953f38f55d7") - .unwrap() - .to_bytes_be() - .to_vec(), - Felt::from_hex("0x2c68af0bb140000").unwrap().to_bytes_be().to_vec(), - Felt::from_hex("0x0").unwrap().to_bytes_be().to_vec(), - ], - nonce: U256::from(775628).to_be_bytes_vec(), - fee: Some(U256::ZERO.to_be_bytes_vec()), - transaction_hash: vec![0], - message_hash: None, - block_number: 0, - event_index: None, - }) - .expect("Failed to compute l1 to l2 msg hash"); - - let expected_hash = - <[u8; 32]>::from_hex("c51a543ef9563ad2545342b390b67edfcddf9886aa36846cf70382362fc5fab3").unwrap(); - - assert_eq!(msg, expected_hash); - } -} diff --git a/crates/madara/client/settlement_client/src/starknet/event.rs b/crates/madara/client/settlement_client/src/starknet/event.rs index 8a4b215f4..4d8173bb1 100644 --- a/crates/madara/client/settlement_client/src/starknet/event.rs +++ b/crates/madara/client/settlement_client/src/starknet/event.rs @@ -1,5 +1,6 @@ use crate::messaging::CommonMessagingEventData; use futures::Stream; +use log::warn; use starknet_core::types::{BlockId, EmittedEvent, EventFilter}; use starknet_providers::jsonrpc::HttpTransport; use starknet_providers::{JsonRpcClient, Provider}; @@ -76,7 +77,7 @@ impl Stream for StarknetEventStream { let latest_block = provider.block_number().await?; for event in event_vec.clone() { - let event_nonce = event.data[4]; + let event_nonce = event.data[1]; if !processed_events.contains(&event_nonce) { return Ok((Some(event), filter)); } @@ -106,26 +107,26 @@ impl Stream for StarknetEventStream { // Update the filter self.filter = updated_filter; // Insert the event nonce before returning - self.processed_events.insert(event.data[4]); + self.processed_events.insert(event.data[1]); let event_data = event .block_number .ok_or_else(|| anyhow::anyhow!("Unable to get block number from event")) .map(|block_number| CommonMessagingEventData { - from: event.keys[2].to_bytes_be().to_vec(), - to: event.keys[3].to_bytes_be().to_vec(), - selector: event.data[0].to_bytes_be().to_vec(), - nonce: event.data[1].to_bytes_be().to_vec(), + from: event.keys[2], + to: event.keys[3], + selector: event.data[0], + nonce: event.data[1], payload: { let mut payload_array = vec![]; event.data.iter().skip(3).for_each(|data| { - payload_array.push(data.to_bytes_be().to_vec()); + payload_array.push(*data); }); payload_array }, fee: None, - transaction_hash: event.transaction_hash.to_bytes_be().to_vec(), - message_hash: Some(event.keys[1].to_bytes_be().to_vec()), + transaction_hash: event.transaction_hash, + message_hash: Some(event.keys[1]), block_number, event_index: None, }); @@ -142,7 +143,14 @@ impl Stream for StarknetEventStream { } Poll::Pending => Poll::Pending, }, - None => Poll::Ready(Some(None)), // Handle the case where future is None + None => { + // If the code comes here then this is an unexpected behaviour. + // Following scenarios can lead to this: + // - Not able to call the RPC and fetch events. + // - Connection Issues. + warn!("Starknet Event Stream : Unable to fetch events from starknet stream. Restart Sequencer."); + Poll::Ready(Some(None)) + } } } } @@ -229,16 +237,18 @@ mod starknet_event_stream_tests { block_number: Some(block_number), block_hash: Some(Felt::from_hex("0x5678").unwrap()), data: vec![ - Felt::from_hex("0x0001").unwrap(), // message_hash - Felt::from_hex("0x1111").unwrap(), // from - Felt::from_hex("0x2222").unwrap(), // to Felt::from_hex("0x3333").unwrap(), // selector Felt::from_hex(&format!("0x{:x}", nonce)).unwrap(), // nonce Felt::from_hex("0x5555").unwrap(), // len Felt::from_hex("0x6666").unwrap(), // payload[0] Felt::from_hex("0x7777").unwrap(), // payload[1] ], - keys: vec![], + keys: vec![ + Felt::from_hex("0x0001").unwrap(), // event key + Felt::from_hex("0x0001").unwrap(), // message_hash + Felt::from_hex("0x1111").unwrap(), // from + Felt::from_hex("0x2222").unwrap(), // to + ], } } @@ -320,4 +330,48 @@ mod starknet_event_stream_tests { events_mock.assert(); block_mock.assert(); } + + #[tokio::test] + #[rstest] + async fn test_multiple_events_in_single_block() { + let mock_server = MockStarknetServer::new(); + + // Create two events with different nonces but same block number + let test_event1 = create_test_event(1, 100); + let test_event2 = create_test_event(2, 100); + + // Setup mocks for events and block number + let events_mock = mock_server.mock_get_events(vec![test_event1.clone(), test_event2.clone()], None); + let block_mock = mock_server.mock_block_number(101); + + let mut stream = Box::pin(setup_stream(&mock_server)); + + if let Some(Some(Ok(event_data1))) = stream.next().await { + assert_eq!(event_data1.block_number, 100); + assert_eq!(event_data1.nonce, Felt::from_hex("0x1").unwrap()); + assert_eq!(event_data1.payload.len(), 2); + assert_eq!(event_data1.transaction_hash, test_event1.transaction_hash); + } else { + panic!("Expected first event"); + } + + if let Some(Some(Ok(event_data2))) = stream.next().await { + assert_eq!(event_data2.block_number, 100); + assert_eq!(event_data2.nonce, Felt::from_hex("0x2").unwrap()); + assert_eq!(event_data2.payload.len(), 2); + assert_eq!(event_data2.transaction_hash, test_event2.transaction_hash); + } else { + panic!("Expected second event"); + } + + // Verify that there are no more events + match stream.next().await { + Some(None) => { /* Expected */ } + _ => panic!("Expected None after processing all events"), + } + + // Verify mocks were called + events_mock.assert(); + block_mock.assert(); + } } diff --git a/crates/madara/client/settlement_client/src/starknet/mod.rs b/crates/madara/client/settlement_client/src/starknet/mod.rs index 4cee71795..12298c325 100644 --- a/crates/madara/client/settlement_client/src/starknet/mod.rs +++ b/crates/madara/client/settlement_client/src/starknet/mod.rs @@ -151,15 +151,18 @@ impl ClientTrait for StarknetClient { mut ctx: ServiceContext, l1_block_metrics: Arc, ) -> anyhow::Result<()> { - while let Some(events) = ctx - .run_until_cancelled(self.get_events( - BlockId::Number(self.get_latest_block_number().await?), - BlockId::Number(self.get_latest_block_number().await?), + let latest_block = self.get_latest_block_number().await?; + let selector = get_selector_from_name("LogStateUpdate")?; + let events_fetch = move || async move { + self.get_events( + BlockId::Number(latest_block), + BlockId::Number(latest_block), self.l2_core_contract, - vec![get_selector_from_name("LogStateUpdate")?], - )) - .await - { + vec![selector], + ) + }; + + while let Some(events) = ctx.run_until_cancelled(events_fetch().await).await { let events_fetched = events?; if let Some(event) = events_fetched.last() { let data = event; @@ -213,11 +216,8 @@ impl ClientTrait for StarknetClient { Ok(call_res[0]) } - // ============================================================ - // Stream Implementations : - // ============================================================ type StreamType = StarknetEventStream; - async fn get_event_stream( + async fn get_messaging_stream( &self, last_synced_event_block: LastSyncedEventBlock, ) -> anyhow::Result { @@ -270,15 +270,10 @@ impl StarknetClient { } fn event_to_felt_array(&self, event: &CommonMessagingEventData) -> Vec { - let mut felt_vec = vec![ - Felt::from_bytes_be_slice(event.from.as_slice()), - Felt::from_bytes_be_slice(event.to.as_slice()), - Felt::from_bytes_be_slice(event.selector.as_slice()), - Felt::from_bytes_be_slice(event.nonce.as_slice()), - ]; + let mut felt_vec = vec![event.from, event.to, event.selector, event.nonce]; felt_vec.push(Felt::from(event.payload.len())); event.payload.clone().into_iter().for_each(|felt| { - felt_vec.push(Felt::from_bytes_be_slice(felt.as_slice())); + felt_vec.push(felt); }); felt_vec @@ -500,3 +495,356 @@ pub mod starknet_client_tests { Err(anyhow::anyhow!("Max retries reached while polling for block {}", block_number)) } } + +#[cfg(test)] +mod l2_messaging_test { + use crate::client::ClientTrait; + use crate::messaging::sync; + use crate::starknet::utils::{ + cancel_messaging_event, fire_messaging_event, prepare_starknet_client_messaging_test, MadaraProcess, + StarknetAccount, MADARA_PORT, + }; + use crate::starknet::{StarknetClient, StarknetClientConfig}; + use mc_db::DatabaseService; + use mc_mempool::{GasPriceProvider, L1DataProvider, Mempool, MempoolLimits}; + use mp_chain_config::ChainConfig; + use mp_utils::service::ServiceContext; + use rstest::{fixture, rstest}; + use starknet_api::core::Nonce; + use starknet_types_core::felt::Felt; + use std::sync::Arc; + use std::time::Duration; + use tempfile::TempDir; + use tracing_test::traced_test; + use url::Url; + + struct TestRunnerStarknet { + #[allow(dead_code)] + madara: MadaraProcess, // Not used but needs to stay in scope otherwise it will be dropped + account: StarknetAccount, + chain_config: Arc, + db_service: Arc, + deployed_address: Felt, + starknet_client: StarknetClient, + mempool: Arc, + } + + #[fixture] + async fn setup_test_env_starknet() -> TestRunnerStarknet { + let (account, deployed_contract_address, madara) = prepare_starknet_client_messaging_test().await.unwrap(); + + // Set up chain info + let chain_config = Arc::new(ChainConfig::madara_test()); + + // Set up database paths + let temp_dir = TempDir::new().expect("issue while creating temporary directory"); + let base_path = temp_dir.path().join("data"); + let backup_dir = Some(temp_dir.path().join("backups")); + + // Initialize database service + let db = Arc::new( + DatabaseService::new(&base_path, backup_dir, false, chain_config.clone(), Default::default()) + .await + .expect("Failed to create database service"), + ); + + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str()).unwrap(), + l2_contract_address: deployed_contract_address, + }) + .await + .unwrap(); + + let l1_gas_setter = GasPriceProvider::new(); + let l1_data_provider: Arc = Arc::new(l1_gas_setter.clone()); + + let mempool = Arc::new(Mempool::new( + Arc::clone(db.backend()), + Arc::clone(&l1_data_provider), + MempoolLimits::for_testing(), + )); + + TestRunnerStarknet { + madara, + account, + chain_config, + db_service: db, + deployed_address: deployed_contract_address, + starknet_client, + mempool, + } + } + + #[rstest] + #[traced_test] + #[tokio::test] + async fn e2e_test_basic_workflow_starknet( + #[future] setup_test_env_starknet: TestRunnerStarknet, + ) -> anyhow::Result<()> { + // Initial Setup + // ================================== + let TestRunnerStarknet { + madara: _madara, + account, + chain_config, + db_service: db, + deployed_address: deployed_contract_address, + starknet_client, + mempool, + } = setup_test_env_starknet.await; + + // Start worker handle + // ================================== + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(starknet_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; + + // Firing the event + let fire_event_block_number = fire_messaging_event(&account, deployed_contract_address).await?; + tokio::time::sleep(Duration::from_secs(10)).await; + + // Log asserts + // =========== + assert!(logs_contain("fromAddress: \"0x07484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); + // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 + // expecting the same in logs + assert!(logs_contain("event hash: \"0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0\"")); + + // Assert that the event is well stored in db + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_eq!(last_block.block_number, fire_event_block_number); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + assert!(db.backend().has_l1_messaging_nonce(nonce)?); + + // Cancelling worker + worker_handle.abort(); + Ok(()) + } + + #[rstest] + #[traced_test] + #[tokio::test] + // This test is redundant now as the event poller will not return the same + // event twice with same nonce that's why added ignore here. + #[ignore] + async fn e2e_test_already_processed_event_starknet( + #[future] setup_test_env_starknet: TestRunnerStarknet, + ) -> anyhow::Result<()> { + // Initial Setup + // ================================== + let TestRunnerStarknet { + madara: _madara, + account, + chain_config, + db_service: db, + deployed_address: deployed_contract_address, + starknet_client, + mempool, + } = setup_test_env_starknet.await; + + // Start worker handle + // ================================== + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(starknet_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; + + // Firing the event + let fire_event_block_number = fire_messaging_event(&account, deployed_contract_address).await?; + tokio::time::sleep(Duration::from_secs(10)).await; + + // Log asserts + // =========== + assert!(logs_contain("fromAddress: \"0x07484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493\"")); + // hash calculated in the contract : 0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0 + // expecting the same in logs + assert!(logs_contain("event hash: \"0x210c8d7fdedf3e9d775ba12b12da86ea67878074a21b625e06dac64d5838ad0\"")); + + // Assert that the event is well stored in db + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_eq!(last_block.block_number, fire_event_block_number); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + assert!(db.backend().has_l1_messaging_nonce(nonce)?); + + // Firing the event second time + fire_messaging_event(&account, deployed_contract_address).await?; + tokio::time::sleep(Duration::from_secs(15)).await; + // Assert that the event processed was in last block only not in the latest block. + assert_eq!( + last_block.block_number, + db.backend() + .messaging_last_synced_l1_block_with_event() + .expect("failed to retrieve block") + .unwrap() + .block_number + ); + assert!(logs_contain("Event already processed")); + + // Cancelling worker + worker_handle.abort(); + Ok(()) + } + + #[rstest] + #[traced_test] + #[tokio::test] + async fn e2e_test_message_canceled_starknet( + #[future] setup_test_env_starknet: TestRunnerStarknet, + ) -> anyhow::Result<()> { + // Initial Setup + // ================================== + let TestRunnerStarknet { + madara: _madara, + account, + chain_config, + db_service: db, + deployed_address: deployed_contract_address, + starknet_client, + mempool, + } = setup_test_env_starknet.await; + + // Start worker handle + // ================================== + let worker_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + sync( + Arc::new(Box::new(starknet_client)), + Arc::clone(db.backend()), + chain_config.chain_id.clone(), + mempool, + ServiceContext::new_for_testing(), + ) + .await + }) + }; + + cancel_messaging_event(&account, deployed_contract_address).await?; + // Firing cancelled event + fire_messaging_event(&account, deployed_contract_address).await?; + tokio::time::sleep(Duration::from_secs(15)).await; + + let last_block = + db.backend().messaging_last_synced_l1_block_with_event().expect("failed to retrieve block").unwrap(); + assert_eq!(last_block.block_number, 0); + let nonce = Nonce(Felt::from_dec_str("10000000000000000").expect("failed to parse nonce string")); + // cancelled message nonce should be inserted to avoid reprocessing + assert!(db.backend().has_l1_messaging_nonce(nonce).unwrap()); + assert!(logs_contain("Message was cancelled in block at timestamp: 0x66b4f105")); + + // Cancelling worker + worker_handle.abort(); + Ok(()) + } +} + +#[cfg(test)] +mod starknet_client_event_subscription_test { + use crate::client::ClientTrait; + use crate::gas_price::L1BlockMetrics; + use crate::starknet::event::StarknetEventStream; + use crate::starknet::utils::{prepare_starknet_client_test, send_state_update, MADARA_PORT}; + use crate::starknet::{StarknetClient, StarknetClientConfig}; + use crate::state_update::{state_update_worker, StateUpdate}; + use mc_db::DatabaseService; + use mp_chain_config::ChainConfig; + use mp_utils::service::ServiceContext; + use rstest::rstest; + use starknet_types_core::felt::Felt; + use std::str::FromStr; + use std::sync::Arc; + use std::time::Duration; + use tempfile::TempDir; + use url::Url; + + #[rstest] + #[tokio::test] + async fn listen_and_update_state_when_event_fired_starknet_client() -> anyhow::Result<()> { + // Setting up the DB and l1 block metrics + // ================================================ + + let chain_info = Arc::new(ChainConfig::madara_test()); + + // Set up database paths + let temp_dir = TempDir::new().expect("issue while creating temporary directory"); + let base_path = temp_dir.path().join("data"); + let backup_dir = Some(temp_dir.path().join("backups")); + + // Initialize database service + let db = Arc::new( + DatabaseService::new(&base_path, backup_dir, false, chain_info.clone(), Default::default()) + .await + .expect("Failed to create database service"), + ); + + // Making Starknet client and start worker + // ================================================ + let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; + + let starknet_client = StarknetClient::new(StarknetClientConfig { + url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, + l2_contract_address: deployed_address, + }) + .await?; + + let l1_block_metrics = L1BlockMetrics::register()?; + + let listen_handle = { + let db = Arc::clone(&db); + tokio::spawn(async move { + state_update_worker::( + Arc::clone(db.backend()), + Arc::new(Box::new(starknet_client)), + ServiceContext::new_for_testing(), + Arc::new(l1_block_metrics), + ) + .await + .expect("Failed to init state update worker.") + }) + }; + + // Firing the state update event + send_state_update( + &account, + deployed_address, + StateUpdate { + block_number: 100, + global_root: Felt::from_str("0xbeef")?, + block_hash: Felt::from_str("0xbeef")?, + }, + ) + .await?; + + // Wait for this update to be registered in the DB. Approx 10 secs + tokio::time::sleep(Duration::from_secs(10)).await; + + // Verify the block number + let block_in_db = + db.backend().get_l1_last_confirmed_block().expect("Failed to get L2 last confirmed block number"); + + listen_handle.abort(); + assert_eq!(block_in_db, Some(100), "Block in DB does not match expected L3 block number"); + Ok(()) + } +} diff --git a/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json b/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json deleted file mode 100644 index c71143f0f..000000000 --- a/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json +++ /dev/null @@ -1,948 +0,0 @@ -{ - "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "2.8.0", - "bytecode": [ - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff97fff", - "0x10780017fff7fff", - "0xc0", - "0x4825800180007ffa", - "0x0", - "0x400280007ff97fff", - "0x482680017ff98000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482680017ffc8000", - "0x1", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x0", - "0x480280007ffc8000", - "0x10780017fff7fff", - "0x8", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0x98", - "0x48307ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482480017ffb8000", - "0x1", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x480080007ff88000", - "0x10780017fff7fff", - "0x8", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0x75", - "0x48307ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482480017ffb8000", - "0x1", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x480080007ff88000", - "0x10780017fff7fff", - "0x8", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0x52", - "0x48307ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x10", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127fed7fff8000", - "0x48127feb7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x250", - "0x482480017fff8000", - "0x24f", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007fe9", - "0xa370", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007fe87fff", - "0x10780017fff7fff", - "0x22", - "0x4824800180007fe9", - "0xa370", - "0x400080007fe97fff", - "0x482480017fe98000", - "0x1", - "0x48127ffe7fff8000", - "0x480a7ffb7fff8000", - "0x48127feb7fff8000", - "0x48127fef7fff8000", - "0x48127ff37fff8000", - "0x1104800180018000", - "0x1b6", - "0x20680017fff7ffd", - "0xc", - "0x40780017fff7fff", - "0x1", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ffb7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017fe68000", - "0x1", - "0x48127fe47fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4661696c656420746f20646573657269616c697a6520706172616d202333", - "0x400080007ffe7fff", - "0x48127fee7fff8000", - "0x48127fec7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4661696c656420746f20646573657269616c697a6520706172616d202332", - "0x400080007ffe7fff", - "0x48127ff37fff8000", - "0x48127ff17fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4661696c656420746f20646573657269616c697a6520706172616d202331", - "0x400080007ffe7fff", - "0x48127ff87fff8000", - "0x48127ff67fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff97fff", - "0x10780017fff7fff", - "0x98", - "0x4825800180007ffa", - "0x0", - "0x400280007ff97fff", - "0x482680017ff98000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x10", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127ffc7fff8000", - "0x48127ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x1bb", - "0x482480017fff8000", - "0x1ba", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007ff8", - "0x65b8", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007ff77fff", - "0x10780017fff7fff", - "0x63", - "0x4824800180007ff8", - "0x65b8", - "0x400080007ff87fff", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1", - "0x482480017ff68000", - "0x1", - "0x480680017fff8000", - "0x53746f7261676552656164", - "0x400280007ffb7fff", - "0x400280017ffb7ffb", - "0x400280027ffb7ffc", - "0x400280037ffb7ffd", - "0x480280057ffb8000", - "0x20680017fff7fff", - "0x42", - "0x480280047ffb8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a", - "0x480280067ffb8000", - "0x480680017fff8000", - "0x53746f7261676552656164", - "0x400280077ffb7fff", - "0x400280087ffb7ffb", - "0x400280097ffb7ffc", - "0x4002800a7ffb7ffd", - "0x4802800c7ffb8000", - "0x20680017fff7fff", - "0x2a", - "0x4802800b7ffb8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181", - "0x4802800d7ffb8000", - "0x480680017fff8000", - "0x53746f7261676552656164", - "0x4002800e7ffb7fff", - "0x4002800f7ffb7ffb", - "0x400280107ffb7ffc", - "0x400280117ffb7ffd", - "0x480280137ffb8000", - "0x20680017fff7fff", - "0x14", - "0x40780017fff7fff", - "0x1", - "0x48127ff67fff8000", - "0x400080007ffe7fff", - "0x48127ffb7fff8000", - "0x400080017ffd7fff", - "0x480280147ffb8000", - "0x400080027ffc7fff", - "0x48127fed7fff8000", - "0x480280127ffb8000", - "0x482680017ffb8000", - "0x15", - "0x480680017fff8000", - "0x0", - "0x48127ff87fff8000", - "0x482480017ff78000", - "0x3", - "0x208b7fff7fff7ffe", - "0x480280127ffb8000", - "0x482680017ffb8000", - "0x16", - "0x480280147ffb8000", - "0x480280157ffb8000", - "0x10780017fff7fff", - "0x12", - "0x40780017fff7fff", - "0x6", - "0x4802800b7ffb8000", - "0x482680017ffb8000", - "0xf", - "0x4802800d7ffb8000", - "0x4802800e7ffb8000", - "0x10780017fff7fff", - "0x9", - "0x40780017fff7fff", - "0xc", - "0x480280047ffb8000", - "0x482680017ffb8000", - "0x8", - "0x480280067ffb8000", - "0x480280077ffb8000", - "0x48127fed7fff8000", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017ff58000", - "0x1", - "0x48127ff37fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff97fff", - "0x10780017fff7fff", - "0x98", - "0x4825800180007ffa", - "0x0", - "0x400280007ff97fff", - "0x482680017ff98000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x10", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127ffc7fff8000", - "0x48127ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x10f", - "0x482480017fff8000", - "0x10e", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007ff8", - "0x6680", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007ff77fff", - "0x10780017fff7fff", - "0x63", - "0x4824800180007ff8", - "0x6680", - "0x400080007ff87fff", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1", - "0x480680017fff8000", - "0x0", - "0x482480017ff58000", - "0x1", - "0x480680017fff8000", - "0x53746f726167655772697465", - "0x400280007ffb7fff", - "0x400280017ffb7ffa", - "0x400280027ffb7ffb", - "0x400280037ffb7ffc", - "0x400280047ffb7ffd", - "0x480280067ffb8000", - "0x20680017fff7fff", - "0x3f", - "0x480280057ffb8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x53746f726167655772697465", - "0x400280077ffb7fff", - "0x400280087ffb7ffb", - "0x400280097ffb7ffc", - "0x4002800a7ffb7ffd", - "0x4002800b7ffb7ffe", - "0x4802800d7ffb8000", - "0x20680017fff7fff", - "0x25", - "0x4802800c7ffb8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x53746f726167655772697465", - "0x4002800e7ffb7fff", - "0x4002800f7ffb7ffb", - "0x400280107ffb7ffc", - "0x400280117ffb7ffd", - "0x400280127ffb7ffe", - "0x480280147ffb8000", - "0x20680017fff7fff", - "0xd", - "0x40780017fff7fff", - "0x1", - "0x48127ff07fff8000", - "0x480280137ffb8000", - "0x482680017ffb8000", - "0x15", - "0x480680017fff8000", - "0x0", - "0x48127ffb7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x480280137ffb8000", - "0x482680017ffb8000", - "0x17", - "0x480280157ffb8000", - "0x480280167ffb8000", - "0x10780017fff7fff", - "0x12", - "0x40780017fff7fff", - "0x6", - "0x4802800c7ffb8000", - "0x482680017ffb8000", - "0x10", - "0x4802800e7ffb8000", - "0x4802800f7ffb8000", - "0x10780017fff7fff", - "0x9", - "0x40780017fff7fff", - "0xc", - "0x480280057ffb8000", - "0x482680017ffb8000", - "0x9", - "0x480280077ffb8000", - "0x480280087ffb8000", - "0x48127fed7fff8000", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017ff58000", - "0x1", - "0x48127ff37fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1", - "0x480680017fff8000", - "0x53746f726167655772697465", - "0x400280007ffa7fff", - "0x400380017ffa7ff9", - "0x400280027ffa7ffd", - "0x400280037ffa7ffe", - "0x400380047ffa7ffc", - "0x480280067ffa8000", - "0x20680017fff7fff", - "0x6b", - "0x480280057ffa8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a", - "0x480680017fff8000", - "0x53746f726167655772697465", - "0x400280077ffa7fff", - "0x400280087ffa7ffc", - "0x400280097ffa7ffd", - "0x4002800a7ffa7ffe", - "0x4003800b7ffa7ffb", - "0x4802800d7ffa8000", - "0x20680017fff7fff", - "0x51", - "0x4802800c7ffa8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181", - "0x480680017fff8000", - "0x53746f726167655772697465", - "0x4002800e7ffa7fff", - "0x4002800f7ffa7ffc", - "0x400280107ffa7ffd", - "0x400280117ffa7ffe", - "0x400380127ffa7ffd", - "0x480280147ffa8000", - "0x20680017fff7fff", - "0x37", - "0x40780017fff7fff", - "0x1", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x0", - "0x480a7ffc7fff8000", - "0x480a7ffb7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x281848a2ead29305005a1178671c6a7d7780cb656c57678566ea8033dbfa001", - "0x400080007ff97fff", - "0x400080007ffa7ffc", - "0x400080017ffa7ffd", - "0x400080027ffa7ffe", - "0x480280137ffa8000", - "0x48127ff87fff8000", - "0x482480017ff78000", - "0x1", - "0x48127ff77fff8000", - "0x482480017ff68000", - "0x3", - "0x480680017fff8000", - "0x456d69744576656e74", - "0x400280157ffa7fff", - "0x400280167ffa7ffa", - "0x400280177ffa7ffb", - "0x400280187ffa7ffc", - "0x400280197ffa7ffd", - "0x4002801a7ffa7ffe", - "0x4802801c7ffa8000", - "0x20680017fff7fff", - "0xd", - "0x480a7ff87fff8000", - "0x4802801b7ffa8000", - "0x482680017ffa8000", - "0x1d", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x208b7fff7fff7ffe", - "0x480a7ff87fff8000", - "0x4802801b7ffa8000", - "0x482680017ffa8000", - "0x1f", - "0x480680017fff8000", - "0x1", - "0x4802801d7ffa8000", - "0x4802801e7ffa8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0xe", - "0x480a7ff87fff8000", - "0x480280137ffa8000", - "0x482680017ffa8000", - "0x17", - "0x480680017fff8000", - "0x1", - "0x480280157ffa8000", - "0x480280167ffa8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x13", - "0x480a7ff87fff8000", - "0x4802800c7ffa8000", - "0x482680017ffa8000", - "0x10", - "0x480680017fff8000", - "0x1", - "0x4802800e7ffa8000", - "0x4802800f7ffa8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x18", - "0x480a7ff87fff8000", - "0x480280057ffa8000", - "0x482680017ffa8000", - "0x9", - "0x480680017fff8000", - "0x1", - "0x480280077ffa8000", - "0x480280087ffa8000", - "0x208b7fff7fff7ffe" - ], - "bytecode_segment_lengths": [212, 172, 172, 130], - "hints": [ - [ - 0, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "FP", "offset": -6 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [80, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 99, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0xa370" }, - "rhs": { "Deref": { "register": "AP", "offset": -22 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [122, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [140, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [155, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [169, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [183, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [197, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 212, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "FP", "offset": -6 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [229, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 248, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x65b8" }, - "rhs": { "Deref": { "register": "AP", "offset": -7 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 272, - [ - { - "SystemCall": { - "system": { "Deref": { "register": "FP", "offset": -5 } } - } - } - ] - ], - [ - 287, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { "register": "FP", "offset": -5 }, - "b": { "Immediate": "0x7" } - } - } - } - } - ] - ], - [ - 302, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { "register": "FP", "offset": -5 }, - "b": { "Immediate": "0xe" } - } - } - } - } - ] - ], - [305, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [354, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [369, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 384, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "FP", "offset": -6 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [401, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 420, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x6680" }, - "rhs": { "Deref": { "register": "AP", "offset": -7 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 447, - [ - { - "SystemCall": { - "system": { "Deref": { "register": "FP", "offset": -5 } } - } - } - ] - ], - [ - 464, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { "register": "FP", "offset": -5 }, - "b": { "Immediate": "0x7" } - } - } - } - } - ] - ], - [ - 481, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { "register": "FP", "offset": -5 }, - "b": { "Immediate": "0xe" } - } - } - } - } - ] - ], - [484, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [526, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [541, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 567, - [ - { - "SystemCall": { - "system": { "Deref": { "register": "FP", "offset": -6 } } - } - } - ] - ], - [ - 582, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { "register": "FP", "offset": -6 }, - "b": { "Immediate": "0x7" } - } - } - } - } - ] - ], - [ - 597, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { "register": "FP", "offset": -6 }, - "b": { "Immediate": "0xe" } - } - } - } - } - ] - ], - [600, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [602, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 630, - [ - { - "SystemCall": { - "system": { - "BinOp": { - "op": "Add", - "a": { "register": "FP", "offset": -6 }, - "b": { "Immediate": "0x15" } - } - } - } - } - ] - ] - ], - "entry_points_by_type": { - "EXTERNAL": [ - { - "selector": "0x196a5f000a6df3bde4c611e5561aa002ac6cc04b4149c1f02f473b2ef445c76", - "offset": 0, - "builtins": ["range_check"] - }, - { - "selector": "0x3593f537ca0121e22c58378d40e0f5e2ba89b1c6d92a6990ab3066b68088f9c", - "offset": 212, - "builtins": ["range_check"] - } - ], - "L1_HANDLER": [], - "CONSTRUCTOR": [ - { - "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", - "offset": 384, - "builtins": ["range_check"] - } - ] - } -} diff --git a/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json b/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json deleted file mode 100644 index a3c87b4d9..000000000 --- a/crates/madara/client/settlement_client/src/starknet/test_contracts/appchain_test.sierra.json +++ /dev/null @@ -1,659 +0,0 @@ -{ - "sierra_program": [ - "0x1", - "0x6", - "0x0", - "0x2", - "0x8", - "0x0", - "0xcb", - "0x35", - "0x21", - "0x52616e6765436865636b", - "0x800000000000000100000000000000000000000000000000", - "0x436f6e7374", - "0x800000000000000000000000000000000000000000000002", - "0x1", - "0x2", - "0x281848a2ead29305005a1178671c6a7d7780cb656c57678566ea8033dbfa001", - "0x66656c74323532", - "0x800000000000000700000000000000000000000000000000", - "0x537472756374", - "0x800000000000000700000000000000000000000000000004", - "0x0", - "0x325aa8c5392af856b0b76eb1e9c925ca4854a32ad80c458af6e005fb4b6c83f", - "0x456e756d", - "0x800000000000000700000000000000000000000000000002", - "0x191f49c01d9820fa9a814bc69ef6cc6a88af08a0a74fd50c7687dab2294b39d", - "0x3", - "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", - "0x8", - "0x753332", - "0x53746f7261676541646472657373", - "0x53746f726167654261736541646472657373", - "0x145cc613954179acf89d43c94ed0e091828cbddcca83f5b408785785036d36d", - "0xa", - "0x4661696c656420746f20646573657269616c697a6520706172616d202331", - "0x4661696c656420746f20646573657269616c697a6520706172616d202332", - "0x4661696c656420746f20646573657269616c697a6520706172616d202333", - "0x4f7574206f6620676173", - "0x4172726179", - "0x800000000000000300000000000000000000000000000001", - "0x536e617073686f74", - "0x800000000000000700000000000000000000000000000001", - "0x10", - "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", - "0x11", - "0x12", - "0x800000000000000f00000000000000000000000000000001", - "0x36a29999818984cbedaf89ff3c5e77aa63ec49bdb2cf356962e80a4ce228308", - "0x800000000000000f00000000000000000000000000000003", - "0x14", - "0x15", - "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", - "0x800000000000000300000000000000000000000000000003", - "0x17", - "0x9e3a3a7f22220fe7534a6b09e607514c317ae36494e57214a99c6b1b05c29a", - "0x16", - "0x18", - "0x4275696c74696e436f737473", - "0x53797374656d", - "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", - "0x13", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x800000000000000700000000000000000000000000000003", - "0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511", - "0x426f78", - "0x4761734275696c74696e", - "0x55", - "0x7265766f6b655f61705f747261636b696e67", - "0x77697468647261775f676173", - "0x6272616e63685f616c69676e", - "0x7374727563745f6465636f6e737472756374", - "0x656e61626c655f61705f747261636b696e67", - "0x73746f72655f74656d70", - "0x61727261795f736e617073686f745f706f705f66726f6e74", - "0x756e626f78", - "0x72656e616d65", - "0x656e756d5f696e6974", - "0x1e", - "0x6a756d70", - "0x7374727563745f636f6e737472756374", - "0x656e756d5f6d61746368", - "0x64697361626c655f61705f747261636b696e67", - "0x64726f70", - "0x1f", - "0x61727261795f6e6577", - "0x636f6e73745f61735f696d6d656469617465", - "0x1d", - "0x61727261795f617070656e64", - "0x1c", - "0x20", - "0x1b", - "0x6765745f6275696c74696e5f636f737473", - "0x1a", - "0x77697468647261775f6761735f616c6c", - "0x66756e6374696f6e5f63616c6c", - "0x19", - "0x736e617073686f745f74616b65", - "0xf", - "0xe", - "0xd", - "0xc", - "0x73746f726167655f626173655f616464726573735f636f6e7374", - "0xa3e35b50432cd1669313bd75e434458dd8bc8d21437d2aa29d6c256f7b13d1", - "0xb", - "0x73746f726167655f616464726573735f66726f6d5f62617365", - "0x7", - "0x9", - "0x73746f726167655f726561645f73797363616c6c", - "0x27f5e07830ee1ad079cf8c8462d2edc585bda982dbded162e761eb7fd71d84a", - "0x3fd94528f836b27f28ba8d7c354705dfc5827b048ca48870ac47c9d5b9aa181", - "0x6", - "0x5", - "0x73746f726167655f77726974655f73797363616c6c", - "0x647570", - "0x4", - "0x656d69745f6576656e745f73797363616c6c", - "0x243", - "0xffffffffffffffff", - "0xaf", - "0x9f", - "0x22", - "0x8e", - "0x2c", - "0x23", - "0x24", - "0x25", - "0x26", - "0x27", - "0x28", - "0x31", - "0x29", - "0x2a", - "0x2b", - "0x7c", - "0x2d", - "0x2e", - "0x47", - "0x2f", - "0x30", - "0x32", - "0x33", - "0x34", - "0x35", - "0x36", - "0x37", - "0x38", - "0x6b", - "0x39", - "0x3a", - "0x3b", - "0x3c", - "0x3d", - "0x3e", - "0x3f", - "0x40", - "0x64", - "0x41", - "0x42", - "0x43", - "0x44", - "0x45", - "0x46", - "0x48", - "0x49", - "0x4a", - "0x4b", - "0x4c", - "0x4d", - "0x4e", - "0x4f", - "0x50", - "0x51", - "0x52", - "0x53", - "0x54", - "0x56", - "0x57", - "0x58", - "0x59", - "0x5a", - "0x5b", - "0x5c", - "0x5d", - "0x5e", - "0x5f", - "0x60", - "0x61", - "0x62", - "0x63", - "0x65", - "0x66", - "0x142", - "0xd2", - "0x135", - "0x128", - "0x122", - "0x11b", - "0x12c", - "0x1ba", - "0x165", - "0x1ad", - "0x1a0", - "0x19b", - "0x196", - "0x1a4", - "0x236", - "0x229", - "0x21c", - "0x212", - "0xbd", - "0x150", - "0x1c8", - "0x13fd", - "0x60504031105100c0f0e0605060506050d0c0b0a0908070606050403020100", - "0x31805170c0f0a0916091509140c0613050403060506050605120c0b0a0c06", - "0x2105201f06051e1d1c06060504031b06060504031a06060504031906060504", - "0xc250a29052805120c270a120c250a260c250a2405120c0f0a2305220c0f0a", - "0x4032f053305320c2b0e023109302f052e052d0c2b0e21052c05120c2b0a2a", - "0xc3e2405053d0c3c0c3b0c3a3902380605203729050605360c350e34060605", - "0x454405053f2305053f0c06440506430605054206050541060505400c05053f", - "0x54b060505494a050549230505490c4844050547050644050643290505460c", - "0x5053f05064f0506432f0505462c0505460605054e0605053f4d05054c0605", - "0x5495605054711110555280505460c545305053f0c524f05053f5105053f50", - "0x505495805054c0c064f050643330505462405054621050549210505572e05", - "0x5495e0505575e0505465d06055c240505495b05054c5a05054c5905054c29", - "0x5c6306055c0c626105053f1305053f6005054c0c5f180505425e05053d5e05", - "0x5680c676605054c2105053f6505053d650505496505055765050546640605", - "0x5054c690505476905053f69050549690505570c0669050643110505460605", - "0x5495605053f0c06560506432e0505460c6a2405053f1105053d1105056805", - "0x60c6065066d6669066c06050c06050c0c6c050c0c0c6b0506560506432805", - "0x61305650c69056c056905660c0c6c050c690c13056c051105110c0c6c050c", - "0x610c5a056c055b05130c5b056c051805600c0c6c050c060c5e05591861066c", - "0xc060c0c33050c5b0c21056c0559055e0c58056c056105180c59056c055a05", - "0x524055e0c58056c055e05180c24056c052305590c23056c050c5a0c0c6c05", - "0x54d2e29066c065805650c0c6c050c060c28056e33056c062105580c21056c", - "0x53056c055605610c56056c052f05130c2f056c052e05600c0c6c050c060c2c", - "0xc5a0c0c6c050c060c0c6f050c5b0c4f056c0553055e0c51056c052905180c", - "0x5580c4f056c0544055e0c51056c052c05180c44056c054d05590c4d056c05", - "0x6c050c060c7205716f00066c065105650c0c6c050c060c5005704a056c064f", - "0x6c050005180c75056c057405610c74056c057305130c73056c056f05600c0c", - "0x590c79056c050c5a0c0c6c050c060c0c78050c5b0c77056c0575055e0c7605", - "0x7c7b056c067705580c77056c057a055e0c76056c057205180c7a056c057905", - "0x6c050c210c0c6c050c060c80057f7e7d066c067605650c0c6c050c060c7105", - "0x330c0c6c054a05330c0c6c057b05330c0c6c057e05240c0c6c057d05230c0c", - "0x81062c0c78056c0578052e0c78056c050c290c81056c050c280c0c6c053305", - "0x660c85056c058405530c84056c05828306560c83056c050c2f0c82056c0578", - "0x585056c0585054d0c06056c0506054f0c66056c056605510c69056c056905", - "0x6c0586054a0c86056c050c440c0c6c058005230c0c6c050c060c8506666969", - "0xc0c6c050c210c0c6c050c060c8b8a06898887066c0686666911500c8605", - "0x2e0c06056c0506054f0c88056c058805510c87056c058705660c8c056c050c", - "0x4a338c068887606f0c7b056c057b052e0c4a056c054a052e0c33056c053305", - "0x6c059105730c0c6c050c060c93059291056c069005720c908f8e8d696c057b", - "0x56c059605760c0c6c059505750c9695066c059405740c94056c050c280c0c", - "0x6c058e05510c8d056c058d05660c7f056c059805790c98056c059705770c97", - "0xc0c6c050c060c7f8f8e8d69057f056c057f054d0c8f056c058f054f0c8e05", - "0x8f056c058f054f0c8e056c058e05510c8d056c058d05660c99056c05930553", - "0x57b05330c0c6c050c210c0c6c050c060c998f8e8d690599056c0599054d0c", - "0xc9b056c050c7a0c9a056c050c280c0c6c053305330c0c6c054a05330c0c6c", - "0x56c059c9d06560c9d056c050c2f0c9c056c059b9a062c0c9b056c059b052e", - "0x6c0506054f0c8b056c058b05510c8a056c058a05660c9f056c059e05530c9e", - "0x57b0c0c6c050c210c0c6c050c060c9f068b8a69059f056c059f054d0c0605", - "0x56c050c280c0c6c053305330c0c6c054a05330c0c6c057605230c0c6c0571", - "0x56c050c2f0ca2056c05a1a0062c0ca1056c05a1052e0ca1056c050c710ca0", - "0x56605510c69056c056905660ca5056c05a405530ca4056c05a2a306560ca3", - "0xc6c050c060ca50666696905a5056c05a5054d0c06056c0506054f0c66056c", - "0x50c280c0c6c055105230c0c6c053305330c0c6c0550057b0c0c6c050c210c", - "0x50c2f0ca7056c05a639062c0ca6056c05a6052e0ca6056c050c7d0c39056c", - "0x5510c69056c056905660caa056c05a905530ca9056c05a7a806560ca8056c", - "0x50c060caa0666696905aa056c05aa054d0c06056c0506054f0c66056c0566", - "0x7e0cab056c050c280c0c6c055805230c0c6c0528057b0c0c6c050c210c0c6c", - "0x560cae056c050c2f0cad056c05acab062c0cac056c05ac052e0cac056c050c", - "0x66056c056605510c69056c056905660cb0056c05af05530caf056c05adae06", - "0x5800c0c6c050c060cb00666696905b0056c05b0054d0c06056c0506054f0c", - "0xb2b1062c0cb2056c05b2052e0cb2056c050c7a0cb1056c050c280c0c6c0511", - "0x5660cb5056c05b405530cb4056c05b39206560c92056c050c2f0cb3056c05", - "0x6905b5056c05b5054d0c06056c0506054f0c60056c056005510c65056c0565", - "0xc0c6c050c060c606506b66669066c06050c06050c0c6c050c0c0cb5066065", - "0x50c060c5e05b71861066c061305650c69056c056905660c13056c05110511", - "0xc5a056c050c290c5b056c050c280c0c6c051805240c0c6c056105230c0c6c", - "0x56c05595806560c58056c050c2f0c59056c055a5b062c0c5a056c055a052e", - "0x6c0506054f0c66056c056605510c69056c056905660c23056c052105530c21", - "0x440c0c6c055e05230c0c6c050c060c23066669690523056c0523054d0c0605", - "0xc060c2e2906b82833066c0624666911500c24056c0524054a0c24056c050c", - "0x5605830c5356066c052f05820c2f056c052c05780c2c056c050c810c0c6c05", - "0x50c870c4d056c054f05860c4f056c055105850c51056c055305840c0c6c05", - "0x6c053305660c4d056c054d058a0c44056c054405880c0c6c050c690c44056c", - "0x6c050c8c0c0c6c050c060c73726f11b900504a116c064d440628698b0c3305", - "0x57705840c0c6c057605830c7776066c057505820c75056c057405780c7405", - "0x54a05510c71056c050c870c7b056c057a05860c7a056c057905850c79056c", - "0x4a698b0c00056c0500052e0c7b056c057b058a0c71056c057105880c4a056c", - "0x8305780c83056c050c8d0c0c6c050c060c82788111ba807e7d116c067b7150", - "0x5850c87056c058605840c0c6c058505830c8685066c058405820c84056c05", - "0x5880c7d056c057d05510c8b056c050c870c8a056c058805860c88056c0587", - "0x116c068a8b7e7d698b0c80056c0580052e0c8a056c058a058a0c8b056c058b", - "0x118e0c93056c050c280c0c6c050c210c0c6c050c060c91908f11bb8e8d8c", - "0x9897116c059605910c0c6c059505900c9695066c0594058f0c94056c058e80", - "0x59805130c9a056c059993062c0c99056c0599052e0c99056c059705130c7f", - "0x52e0c9d056c057f05130c9c056c059b9a062c0c9b056c059b052e0c9b056c", - "0xc0c6c059f05750ca09f066c059e05740c9e056c059d9c062c0c9d056c059d", - "0x33056c053305660ca3056c05a205790ca2056c05a105770ca1056c05a00576", - "0xca38d8c336905a3056c05a3054d0c8d056c058d054f0c8c056c058c05510c", - "0x90054f0ca4056c058f05510c0c6c058005330c0c6c050005330c0c6c050c06", - "0xc6c050005330c0c6c050c060c0cbc050c5b0c39056c059105930ca5056c05", - "0xc0cbc050c5b0c39056c058205930ca5056c0578054f0ca4056c058105510c", - "0x210c39056c057305930ca5056c0572054f0ca4056c056f05510c0c6c050c06", - "0x5660ca8056c05a705530ca7056c0539a606560ca6056c050c2f0c0c6c050c", - "0x6905a8056c05a8054d0ca5056c05a5054f0ca4056c05a405510c33056c0533", - "0x56c05aa052e0caa056c050c7a0ca9056c050c280c0c6c050c060ca8a5a433", - "0x5ad05530cad056c05abac06560cac056c050c2f0cab056c05aaa9062c0caa", - "0xae054d0c06056c0506054f0c2e056c052e05510c29056c052905660cae056c", - "0xcaf056c050c280c0c6c051105800c0c6c050c060cae062e296905ae056c05", - "0xcb2056c050c2f0cb1056c05b0af062c0cb0056c05b0052e0cb0056c050c7a", - "0x56c056005510c65056c056505660c92056c05b305530cb3056c05b1b20656", - "0x50c0c6c050c0c0c92066065690592056c0592054d0c06056c0506054f0c60", - "0x56905660c13056c051105110c0c6c050c060c606506bd6669066c06050c06", - "0x5240c0c6c056105230c0c6c050c060c5e05be1861066c061305650c69056c", - "0x5a5b062c0c5a056c055a052e0c5a056c050c290c5b056c050c280c0c6c0518", - "0x5660c23056c052105530c21056c05595806560c58056c050c2f0c59056c05", - "0x690523056c0523054d0c06056c0506054f0c66056c056605510c69056c0569", - "0x56c0524054a0c24056c050c440c0c6c055e05230c0c6c050c060c23066669", - "0x860c2c056c050c810c0c6c050c060c2e2906bf2833066c0624666911500c24", - "0x55305880c0c6c050c690c53056c050c870c56056c050c940c2f056c052c05", - "0x2866950c33056c053305660c56056c0556052e0c2f056c052f058a0c53056c", - "0x5005860c50056c050c8c0c0c6c050c060c4a444d11c04f51066c06562f5306", - "0x57205880c51056c055105510c72056c050c870c6f056c050c940c00056c05", - "0x73066c066f00724f5166950c6f056c056f052e0c00056c0500058a0c72056c", - "0x50c940c7a056c057905860c79056c050c8d0c0c6c050c060c77767511c174", - "0x57a058a0c71056c057105880c73056c057305510c71056c050c870c7b056c", - "0x60c78818011c27e7d066c067b7a71747366950c7b056c057b052e0c7a056c", - "0x58305750c8483066c058205740c82056c050c280c0c6c050c210c0c6c050c", - "0x53305660c87056c058605790c86056c058505770c85056c058405760c0c6c", - "0x7d33690587056c0587054d0c7e056c057e054f0c7d056c057d05510c33056c", - "0x56c057805930c8a056c0581054f0c88056c058005510c0c6c050c060c877e", - "0x930c8a056c0576054f0c88056c057505510c0c6c050c060c0cc3050c5b0c8b", - "0x544054f0c88056c054d05510c0c6c050c060c0cc3050c5b0c8b056c057705", - "0x6c058b8c06560c8c056c050c2f0c0c6c050c210c8b056c054a05930c8a056c", - "0x58a054f0c88056c058805510c33056c053305660c8e056c058d05530c8d05", - "0xc8f056c050c280c0c6c050c060c8e8a883369058e056c058e054d0c8a056c", - "0xc93056c050c2f0c91056c05908f062c0c90056c0590052e0c90056c050c7a", - "0x56c052e05510c29056c052905660c95056c059405530c94056c0591930656", - "0x800c0c6c050c060c95062e29690595056c0595054d0c06056c0506054f0c2e", - "0x96062c0c97056c0597052e0c97056c050c7a0c96056c050c280c0c6c051105", - "0x660c9a056c059905530c99056c05987f06560c7f056c050c2f0c98056c0597", - "0x59a056c059a054d0c06056c0506054f0c60056c056005510c65056c056505", - "0x6605960c61056c050c870c13056c056005860c60056c050c810c9a06606569", - "0x6c06181361060566950c13056c0513058a0c61056c056105880c1866066c05", - "0x870c23056c052105860c21056c050c8c0c0c6c050c060c58595a11c45b5e06", - "0xc24056c052405880c5e056c055e05510c3369066c056905960c24056c050c", - "0xc6c050c060c2f2c2e11c52928066c063323245b5e66950c23056c0523058a", - "0x4f65066c056505960c51056c050c870c53056c055605860c56056c050c8d0c", - "0x5351292866950c53056c0553058a0c51056c055105880c28056c052805510c", - "0x72056c050c280c6f056c050c280c0c6c050c060c00504a11c6444d066c064f", - "0x7505990c7675066c0574057f0c74056c057305980c73056c0565696611970c", - "0x56c050c9c0c0c6c050c060c77056c0576059b0c76056c0576059a0c0c6c05", - "0x7b059e0c7b77066c0577059d0c7a056c05796f062c0c79056c0579052e0c79", - "0x62c0c80056c057105130c0c6c057e05330c0c6c057d05330c7e7d71116c05", - "0x6c058205330c848382116c0578059e0c7877066c0577059d0c81056c058072", - "0x6c0577059e0c86056c058581062c0c85056c058305130c0c6c058405330c0c", - "0x8b86062c0c8b056c058a05130c0c6c058805330c0c6c058705330c8a888711", - "0x750c908f066c058c05740c0c6c058d05750c8e8d066c057a05740c8c056c05", - "0x9f0c4d056c054d05510c93056c059005760c91056c058e05760c0c6c058f05", - "0x98979611c79594066c069391444d69a00c93056c0593059f0c91056c059105", - "0xc9a056c059905a20c99056c057f1106a10c7f056c050c5a0c0c6c050c060c", - "0x9a056c059a05a30c95056c0595054f0c94056c059405510c0c056c050c0566", - "0x989b06560c9b056c050c2f0c0c6c051105a40c0c6c050c060c9a95940c6905", - "0x54f0c96056c059605510c0c056c050c05660c9d056c059c05a50c9c056c05", - "0x6c051105a40c0c6c050c060c9d97960c69059d056c059d05a30c97056c0597", - "0x560c9e056c050c2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c", - "0x4a056c054a05510c0c056c050c05660ca0056c059f05a50c9f056c05009e06", - "0x5a40c0c6c050c060ca0504a0c6905a0056c05a005a30c50056c0550054f0c", - "0x56c050c2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c6c0511", - "0x52e05510c0c056c050c05660ca3056c05a205a50ca2056c052fa106560ca1", - "0xc6c050c060ca32c2e0c6905a3056c05a305a30c2c056c052c054f0c2e056c", - "0xc2f0c0c6c056905330c0c6c056605330c0c6c056505330c0c6c051105a40c", - "0x510c0c056c050c05660c39056c05a505a50ca5056c0558a406560ca4056c05", - "0xc696939595a0c690539056c053905a30c59056c0559054f0c5a056c055a05", - "0x500c69c81106050c4f51500c692451500c690c1106050c4f51500c69245150", - "0x66691106050c5651500c690606062851500c60c91106050c4f51500c692451", - "0xca65" - ], - "sierra_program_debug_info": { - "type_names": [ - [0, "RangeCheck"], - [ - 1, - "Const" - ], - [2, "felt252"], - [3, "temp_cairo::StateUpdateContract::LogStateUpdate"], - [4, "temp_cairo::StateUpdateContract::Event"], - [5, "Const"], - [6, "Tuple"], - [7, "Const"], - [8, "u32"], - [9, "StorageAddress"], - [10, "StorageBaseAddress"], - [11, "core::starknet::storage::StoragePointer0Offset::"], - [ - 12, - "Const" - ], - [ - 13, - "Const" - ], - [ - 14, - "Const" - ], - [15, "Const"], - [16, "Array"], - [17, "Snapshot>"], - [18, "core::array::Span::"], - [19, "Tuple>"], - [20, "temp_cairo::StateUpdateContract::ContractState"], - [21, "Unit"], - [22, "Tuple"], - [23, "core::panics::Panic"], - [24, "Tuple>"], - [ - 25, - "core::panics::PanicResult::<(temp_cairo::StateUpdateContract::ContractState, ())>" - ], - [26, "BuiltinCosts"], - [27, "System"], - [ - 28, - "core::panics::PanicResult::<(core::array::Span::,)>" - ], - [ - 29, - "Const" - ], - [30, "core::option::Option::"], - [31, "Box"], - [32, "GasBuiltin"] - ], - "libfunc_names": [ - [0, "revoke_ap_tracking"], - [1, "withdraw_gas"], - [2, "branch_align"], - [3, "struct_deconstruct>"], - [4, "enable_ap_tracking"], - [5, "store_temp"], - [6, "array_snapshot_pop_front"], - [7, "unbox"], - [8, "rename"], - [9, "enum_init, 0>"], - [10, "store_temp>>"], - [11, "store_temp>"], - [12, "jump"], - [13, "struct_construct"], - [14, "enum_init, 1>"], - [15, "enum_match>"], - [16, "disable_ap_tracking"], - [17, "drop>>"], - [18, "drop>"], - [19, "drop"], - [20, "array_new"], - [ - 21, - "const_as_immediate>" - ], - [22, "store_temp"], - [23, "array_append"], - [24, "struct_construct"], - [25, "struct_construct>>"], - [ - 26, - "enum_init,)>, 1>" - ], - [27, "store_temp"], - [28, "store_temp"], - [ - 29, - "store_temp,)>>" - ], - [30, "get_builtin_costs"], - [31, "store_temp"], - [32, "withdraw_gas_all"], - [33, "struct_construct"], - [34, "function_call"], - [ - 35, - "enum_match>" - ], - [36, "drop>"], - [37, "snapshot_take>"], - [38, "drop>"], - [39, "struct_construct>"], - [40, "struct_construct>>"], - [ - 41, - "enum_init,)>, 0>" - ], - [42, "const_as_immediate>"], - [43, "drop"], - [ - 44, - "const_as_immediate>" - ], - [ - 45, - "const_as_immediate>" - ], - [ - 46, - "const_as_immediate>" - ], - [47, "drop>"], - [ - 48, - "storage_base_address_const<289565229787362368933081636443797405535488074065834425092593015835915391953>" - ], - [ - 49, - "struct_construct>" - ], - [ - 50, - "snapshot_take>" - ], - [ - 51, - "drop>" - ], - [ - 52, - "struct_deconstruct>" - ], - [53, "rename"], - [54, "storage_address_from_base"], - [55, "const_as_immediate>"], - [56, "store_temp"], - [57, "store_temp"], - [58, "storage_read_syscall"], - [ - 59, - "storage_base_address_const<1129664241071644691371073118594794953592340198277473102285062464307545102410>" - ], - [ - 60, - "storage_base_address_const<1804974537427402286278400303388660593172206410421526189703894999503593972097>" - ], - [61, "struct_construct>"], - [62, "snapshot_take>"], - [63, "drop>"], - [64, "struct_deconstruct>"], - [65, "store_temp>"], - [66, "const_as_immediate>"], - [67, "storage_write_syscall"], - [68, "dup"], - [69, "struct_construct"], - [70, "enum_init"], - [71, "snapshot_take"], - [72, "drop"], - [73, "store_temp"], - [74, "enum_match"], - [ - 75, - "const_as_immediate>" - ], - [76, "dup"], - [ - 77, - "struct_deconstruct" - ], - [78, "store_temp>"], - [79, "emit_event_syscall"], - [ - 80, - "struct_construct>" - ], - [ - 81, - "enum_init, 0>" - ], - [ - 82, - "store_temp>" - ], - [83, "drop"], - [ - 84, - "enum_init, 1>" - ] - ], - "user_func_names": [ - [0, "temp_cairo::StateUpdateContract::__wrapper__update_state"], - [1, "temp_cairo::StateUpdateContract::__wrapper__get_state"], - [2, "temp_cairo::StateUpdateContract::__wrapper__constructor"], - [3, "temp_cairo::StateUpdateContract::update_state"] - ] - }, - "contract_class_version": "0.1.0", - "entry_points_by_type": { - "EXTERNAL": [ - { - "selector": "0x196a5f000a6df3bde4c611e5561aa002ac6cc04b4149c1f02f473b2ef445c76", - "function_idx": 0 - }, - { - "selector": "0x3593f537ca0121e22c58378d40e0f5e2ba89b1c6d92a6990ab3066b68088f9c", - "function_idx": 1 - } - ], - "L1_HANDLER": [], - "CONSTRUCTOR": [ - { - "selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", - "function_idx": 2 - } - ] - }, - "abi": [ - { "type": "constructor", "name": "constructor", "inputs": [] }, - { - "type": "function", - "name": "update_state", - "inputs": [ - { "name": "block_number", "type": "core::felt252" }, - { "name": "state_root", "type": "core::felt252" }, - { "name": "block_hash", "type": "core::felt252" } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_state", - "inputs": [], - "outputs": [{ "type": "(core::felt252, core::felt252, core::felt252)" }], - "state_mutability": "view" - }, - { - "type": "event", - "name": "temp_cairo::StateUpdateContract::LogStateUpdate", - "kind": "struct", - "members": [ - { "name": "state_root", "type": "core::felt252", "kind": "data" }, - { "name": "block_number", "type": "core::felt252", "kind": "data" }, - { "name": "block_hash", "type": "core::felt252", "kind": "data" } - ] - }, - { - "type": "event", - "name": "temp_cairo::StateUpdateContract::Event", - "kind": "enum", - "variants": [ - { - "name": "LogStateUpdate", - "type": "temp_cairo::StateUpdateContract::LogStateUpdate", - "kind": "nested" - } - ] - } - ] -} diff --git a/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json b/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json deleted file mode 100644 index 662d21e45..000000000 --- a/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.casm.json +++ /dev/null @@ -1,1987 +0,0 @@ -{ - "prime": "0x800000000000011000000000000000000000000000000000000000000000001", - "compiler_version": "2.8.0", - "bytecode": [ - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff97fff", - "0x10780017fff7fff", - "0x93", - "0x4825800180007ffa", - "0x0", - "0x400280007ff97fff", - "0x482680017ff98000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x10", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127ffc7fff8000", - "0x48127ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x5b5", - "0x482480017fff8000", - "0x5b4", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007ff8", - "0x0", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007ff77fff", - "0x10780017fff7fff", - "0x5e", - "0x4824800180007ff8", - "0x0", - "0x400080007ff87fff", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x3dbe3dd8c2f721bc24e87bcb739063a10ee738cef090bc752bc0d5a29f10b72", - "0x400080007ffe7fff", - "0x480680017fff8000", - "0x1a055690d9db80000", - "0x400080017ffd7fff", - "0x480680017fff8000", - "0x0", - "0x400080027ffc7fff", - "0x480680017fff8000", - "0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493", - "0x48127ffb7fff8000", - "0x482480017ffa8000", - "0x3", - "0xa0680017fff8004", - "0xe", - "0x4824800180047ffc", - "0x800000000000000000000000000000000000000000000000000000000000000", - "0x484480017ffe8000", - "0x110000000000000000", - "0x48307ffe7fff8002", - "0x480080017fed7ffc", - "0x480080027fec7ffc", - "0x402480017ffb7ffd", - "0xffffffffffffffeeffffffffffffffff", - "0x400080037feb7ffd", - "0x10780017fff7fff", - "0x2e", - "0x484480017fff8001", - "0x8000000000000000000000000000000", - "0x48307fff80007ffb", - "0x480080017fee7ffd", - "0x480080027fed7ffd", - "0x402480017ffc7ffe", - "0xf8000000000000000000000000000000", - "0x400080037fec7ffe", - "0x40780017fff7fff", - "0x1", - "0x482480017feb8000", - "0x4", - "0x48127ff17fff8000", - "0x48127ff57fff8000", - "0x480680017fff8000", - "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - "0x480680017fff8000", - "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", - "0x48127ff37fff8000", - "0x48127ff37fff8000", - "0x480680017fff8000", - "0x2386f26fc10000", - "0x48127ff77fff8000", - "0x48127ff67fff8000", - "0x1104800180018000", - "0x2ab", - "0x20680017fff7ffd", - "0xa", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7074696f6e3a3a756e77726170206661696c65642e", - "0x400080007ffe7fff", - "0x482480017fe98000", - "0x4", - "0x48127fef7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017ff58000", - "0x1", - "0x48127ff37fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff87fff", - "0x10780017fff7fff", - "0x59", - "0x4825800180007ffa", - "0x0", - "0x400280007ff87fff", - "0x482680017ff88000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x11", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127ffc7fff8000", - "0x480a7ff97fff8000", - "0x48127ff97fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x50d", - "0x482480017fff8000", - "0x50c", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007ff8", - "0x5cda", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007ff77fff", - "0x10780017fff7fff", - "0x22", - "0x4824800180007ff8", - "0x5cda", - "0x400080007ff87fff", - "0x482480017ff88000", - "0x1", - "0x48127ffe7fff8000", - "0x480a7ff97fff8000", - "0x480a7ffb7fff8000", - "0x1104800180018000", - "0x254", - "0x20680017fff7ffd", - "0xd", - "0x40780017fff7fff", - "0x1", - "0x48127ff87fff8000", - "0x48127ff97fff8000", - "0x48127ff77fff8000", - "0x48127ff87fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ffa7fff8000", - "0x48127ff97fff8000", - "0x208b7fff7fff7ffe", - "0x48127ff97fff8000", - "0x48127ffa7fff8000", - "0x48127ff87fff8000", - "0x48127ff97fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017ff58000", - "0x1", - "0x480a7ff97fff8000", - "0x48127ff27fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff88000", - "0x1", - "0x480a7ff97fff8000", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff97fff", - "0x10780017fff7fff", - "0xd8", - "0x4825800180007ffa", - "0x0", - "0x400280007ff97fff", - "0x482680017ff98000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482680017ffc8000", - "0x1", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x0", - "0x480280007ffc8000", - "0x10780017fff7fff", - "0x8", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0xb0", - "0x48307ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x10", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127ff77fff8000", - "0x48127ff57fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x48b", - "0x482480017fff8000", - "0x48a", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007ff3", - "0x19fa", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007ff27fff", - "0x10780017fff7fff", - "0x80", - "0x4824800180007ff3", - "0x19fa", - "0x400080007ff37fff", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x3150ab9073ca993efcd1d4ab278c207ab86418914db765f88aa5d8e7bc5c79", - "0x482480017ff18000", - "0x1", - "0x480680017fff8000", - "0x53746f7261676552656164", - "0x400280007ffb7fff", - "0x400280017ffb7ffb", - "0x400280027ffb7ffc", - "0x400280037ffb7ffd", - "0x480280057ffb8000", - "0x20680017fff7fff", - "0x65", - "0x480280067ffb8000", - "0x480280047ffb8000", - "0x482680017ffb8000", - "0x7", - "0x20680017fff7ffd", - "0x2a", - "0x480680017fff8000", - "0x0", - "0xa0680017fff8000", - "0x16", - "0x480080007ff88003", - "0x480080017ff78003", - "0x4844800180017ffe", - "0x100000000000000000000000000000000", - "0x483080017ffd7ffb", - "0x482480017fff7ffd", - "0x800000000000010fffffffffffffffff7ffffffffffffef0000000000000001", - "0x20680017fff7ffc", - "0x6", - "0x402480017fff7ffd", - "0xffffffffffffffffffffffffffffffff", - "0x10780017fff7fff", - "0x4", - "0x402480017ffe7ffd", - "0xf7ffffffffffffef0000000000000000", - "0x400080027ff37ffd", - "0x20680017fff7ffe", - "0xe", - "0x402780017fff7fff", - "0x1", - "0x400080007ff87ffe", - "0x40780017fff7fff", - "0x5", - "0x482480017ff38000", - "0x1", - "0x48127ff87fff8000", - "0x480680017fff8000", - "0x0", - "0x10780017fff7fff", - "0x6", - "0x482480017ff38000", - "0x3", - "0x48127ffe7fff8000", - "0x48127ffc7fff8000", - "0x10780017fff7fff", - "0x28", - "0x480680017fff8000", - "0x66b4f105", - "0xa0680017fff8000", - "0x16", - "0x480080007ff88003", - "0x480080017ff78003", - "0x4844800180017ffe", - "0x100000000000000000000000000000000", - "0x483080017ffd7ffb", - "0x482480017fff7ffd", - "0x800000000000010fffffffffffffffff7ffffffffffffef0000000000000001", - "0x20680017fff7ffc", - "0x6", - "0x402480017fff7ffd", - "0xffffffffffffffffffffffffffffffff", - "0x10780017fff7fff", - "0x4", - "0x402480017ffe7ffd", - "0xf7ffffffffffffef0000000000000000", - "0x400080027ff37ffd", - "0x20680017fff7ffe", - "0xe", - "0x402780017fff7fff", - "0x1", - "0x400080007ff87ffe", - "0x40780017fff7fff", - "0x5", - "0x482480017ff38000", - "0x1", - "0x48127ff87fff8000", - "0x480680017fff8000", - "0x0", - "0x10780017fff7fff", - "0x6", - "0x482480017ff38000", - "0x3", - "0x48127ffe7fff8000", - "0x48127ffc7fff8000", - "0x40780017fff7fff", - "0x1", - "0x48127ffd7fff8000", - "0x48127ffd7fff8000", - "0x400080007ffd7ffe", - "0x400080017ffd7fff", - "0x48127ffa7fff8000", - "0x48127ff07fff8000", - "0x48127ff07fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x2", - "0x208b7fff7fff7ffe", - "0x48127ffd7fff8000", - "0x480280047ffb8000", - "0x482680017ffb8000", - "0x8", - "0x480680017fff8000", - "0x1", - "0x480280067ffb8000", - "0x480280077ffb8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017ff08000", - "0x1", - "0x48127fee7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4661696c656420746f20646573657269616c697a6520706172616d202331", - "0x400080007ffe7fff", - "0x48127ff87fff8000", - "0x48127ff67fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff97fff", - "0x10780017fff7fff", - "0x8d", - "0x4825800180007ffa", - "0x0", - "0x400280007ff97fff", - "0x482680017ff98000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482680017ffc8000", - "0x1", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x0", - "0x480a7ffc7fff8000", - "0x10780017fff7fff", - "0x8", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0x65", - "0x480080007fff8000", - "0x20680017fff7fff", - "0x6", - "0x480680017fff8000", - "0x1", - "0x10780017fff7fff", - "0x4", - "0x480680017fff8000", - "0x0", - "0x48307ffa80007ffb", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x10", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127ff57fff8000", - "0x48127ff37fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x396", - "0x482480017fff8000", - "0x395", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007ff1", - "0x1284", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007ff07fff", - "0x10780017fff7fff", - "0x2c", - "0x4824800180007ff1", - "0x1284", - "0x400080007ff17fff", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x3150ab9073ca993efcd1d4ab278c207ab86418914db765f88aa5d8e7bc5c79", - "0x48307ff580007ffd", - "0x482480017fed8000", - "0x1", - "0x480680017fff8000", - "0x53746f726167655772697465", - "0x400280007ffb7fff", - "0x400280017ffb7ff9", - "0x400280027ffb7ffb", - "0x400280037ffb7ffc", - "0x400280047ffb7ffd", - "0x480280067ffb8000", - "0x20680017fff7fff", - "0xd", - "0x40780017fff7fff", - "0x1", - "0x48127ffc7fff8000", - "0x480280057ffb8000", - "0x482680017ffb8000", - "0x7", - "0x480680017fff8000", - "0x0", - "0x48127ffb7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffd7fff8000", - "0x480280057ffb8000", - "0x482680017ffb8000", - "0x9", - "0x480680017fff8000", - "0x1", - "0x480280077ffb8000", - "0x480280087ffb8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017fee8000", - "0x1", - "0x48127fec7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4661696c656420746f20646573657269616c697a6520706172616d202331", - "0x400080007ffe7fff", - "0x48127ff87fff8000", - "0x48127ff67fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff98000", - "0x1", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ffa8000", - "0x100000000000000000000000000000000", - "0x400280007ff87fff", - "0x10780017fff7fff", - "0x5a", - "0x4825800180007ffa", - "0x0", - "0x400280007ff87fff", - "0x482680017ff88000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0x11", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x400080007ffe7fff", - "0x48127ffc7fff8000", - "0x480a7ff97fff8000", - "0x48127ff97fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0x312", - "0x482480017fff8000", - "0x311", - "0x480080007fff8000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007ff8", - "0xae6", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007ff77fff", - "0x10780017fff7fff", - "0x23", - "0x4824800180007ff8", - "0xae6", - "0x400080007ff87fff", - "0x482480017ff88000", - "0x1", - "0x48127ffe7fff8000", - "0x480a7ff97fff8000", - "0x1104800180018000", - "0xf3", - "0x20680017fff7ffd", - "0xf", - "0x40780017fff7fff", - "0x1", - "0x400080007fff7ffe", - "0x48127ff97fff8000", - "0x48127ffa7fff8000", - "0x48127ff87fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x48127ffa7fff8000", - "0x48127ffb7fff8000", - "0x48127ff97fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017ff58000", - "0x1", - "0x480a7ff97fff8000", - "0x48127ff27fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff88000", - "0x1", - "0x480a7ff97fff8000", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0x400380007ffd7ff6", - "0x400380017ffd7ff7", - "0x400380027ffd7ff8", - "0x48297ff980007ffa", - "0x400280037ffd7fff", - "0x480a7ff47fff8000", - "0x480a7ff57fff8000", - "0x480a7ff97fff8000", - "0x480a7ffa7fff8000", - "0x480a7ffc7fff8000", - "0x482680017ffd8000", - "0x4", - "0x1104800180018000", - "0x12d", - "0x20680017fff7ffd", - "0xb", - "0x400180007fff7ffb", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ffb7fff8000", - "0x482480017ffb8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x4", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x3dbe3dd8c2f721bc24e87bcb739063a10ee738cef090bc752bc0d5a29f10b72", - "0x400080007ffe7fff", - "0x480680017fff8000", - "0x1a055690d9db80000", - "0x400080017ffd7fff", - "0x480680017fff8000", - "0x0", - "0x400080027ffc7fff", - "0x400780017fff8003", - "0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493", - "0x40137ffc7fff8001", - "0x402580017ffc8002", - "0x3", - "0xa0680017fff8004", - "0xe", - "0x4825800180048003", - "0x800000000000000000000000000000000000000000000000000000000000000", - "0x484480017ffe8000", - "0x110000000000000000", - "0x48307ffe7fff8002", - "0x480280007ffa7ffc", - "0x480280017ffa7ffc", - "0x402480017ffb7ffd", - "0xffffffffffffffeeffffffffffffffff", - "0x400280027ffa7ffd", - "0x10780017fff7fff", - "0x6b", - "0x484480017fff8001", - "0x8000000000000000000000000000000", - "0x48317fff80008003", - "0x480280007ffa7ffd", - "0x480280017ffa7ffd", - "0x402480017ffc7ffe", - "0xf8000000000000000000000000000000", - "0x400280027ffa7ffe", - "0x482680017ffa8000", - "0x3", - "0x480a7ffb7fff8000", - "0x480a7ffc7fff8000", - "0x1104800180018000", - "0x6d", - "0x40137ffc7fff8000", - "0x20680017fff7ffd", - "0x51", - "0x40780017fff7fff", - "0x1", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x0", - "0x48127ffc7fff8000", - "0x480a80037fff8000", - "0x480680017fff8000", - "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - "0x480680017fff8000", - "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", - "0x480680017fff8000", - "0x2386f26fc10000", - "0x480a80017fff8000", - "0x480a80027fff8000", - "0x480680017fff8000", - "0x398697ad8745b865eefbaa4afad41e52876386afeeb69101604d297801076ef", - "0x400080007ff57fff", - "0x48127fef7fff8000", - "0x48127fef7fff8000", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x48127fec7fff8000", - "0x482480017feb8000", - "0x1", - "0x48127feb7fff8000", - "0x48127fea7fff8000", - "0x1104800180018000", - "0x109", - "0x20680017fff7ffb", - "0x23", - "0x480680017fff8000", - "0x456d69744576656e74", - "0x400280007ffd7fff", - "0x400280017ffd7ff9", - "0x400280027ffd7ffb", - "0x400280037ffd7ffc", - "0x400280047ffd7ffd", - "0x400280057ffd7ffe", - "0x480280077ffd8000", - "0x20680017fff7fff", - "0xe", - "0x48127ff77fff8000", - "0x480280067ffd8000", - "0x480a80007fff8000", - "0x482680017ffd8000", - "0x8", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x208b7fff7fff7ffe", - "0x48127ff77fff8000", - "0x480280067ffd8000", - "0x480a80007fff8000", - "0x482680017ffd8000", - "0xa", - "0x480680017fff8000", - "0x1", - "0x480280087ffd8000", - "0x480280097ffd8000", - "0x208b7fff7fff7ffe", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480a80007fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x480a80007fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7074696f6e3a3a756e77726170206661696c65642e", - "0x400080007ffe7fff", - "0x482680017ffa8000", - "0x3", - "0x480a7ffb7fff8000", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x3dbe3dd8c2f721bc24e87bcb739063a10ee738cef090bc752bc0d5a29f10b72", - "0x400080007ffe7fff", - "0x480680017fff8000", - "0x1a055690d9db80000", - "0x400080017ffd7fff", - "0x480680017fff8000", - "0x0", - "0x400080027ffc7fff", - "0x480680017fff8000", - "0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493", - "0x48127ffb7fff8000", - "0x482480017ffa8000", - "0x3", - "0xa0680017fff8004", - "0xe", - "0x4824800180047ffc", - "0x800000000000000000000000000000000000000000000000000000000000000", - "0x484480017ffe8000", - "0x110000000000000000", - "0x48307ffe7fff8002", - "0x480280007ffb7ffc", - "0x480280017ffb7ffc", - "0x402480017ffb7ffd", - "0xffffffffffffffeeffffffffffffffff", - "0x400280027ffb7ffd", - "0x10780017fff7fff", - "0x55", - "0x484480017fff8001", - "0x8000000000000000000000000000000", - "0x48307fff80007ffb", - "0x480280007ffb7ffd", - "0x480280017ffb7ffd", - "0x402480017ffc7ffe", - "0xf8000000000000000000000000000000", - "0x400280027ffb7ffe", - "0x40780017fff7fff", - "0x1", - "0x400080007fff7ff7", - "0x480680017fff8000", - "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - "0x400080017ffe7fff", - "0x480680017fff8000", - "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", - "0x400080027ffd7fff", - "0x480680017fff8000", - "0x2386f26fc10000", - "0x400080037ffc7fff", - "0x48307ff580007ff6", - "0x400080047ffb7fff", - "0x482680017ffb8000", - "0x3", - "0x480a7ffc7fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ff17fff8000", - "0x48127ff17fff8000", - "0x48127ff67fff8000", - "0x482480017ff58000", - "0x5", - "0x48127fed7fff8000", - "0x48127fed7fff8000", - "0x1104800180018000", - "0xad", - "0x20680017fff7ffc", - "0x27", - "0x1104800180018000", - "0x1c6", - "0x482480017fff8000", - "0x1c5", - "0x48127ff77fff8000", - "0x48127ff77fff8000", - "0x480a7ffd7fff8000", - "0x480080007ffc8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x48127ff37fff8000", - "0x48127ff37fff8000", - "0x1104800180018000", - "0x112", - "0x20680017fff7ffc", - "0xb", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7074696f6e3a3a756e77726170206661696c65642e", - "0x400080007ffe7fff", - "0x482680017ffb8000", - "0x3", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ff98000", - "0xfffffffffffffffffffffffffffff722", - "0x400280007ff87fff", - "0x10780017fff7fff", - "0x2f", - "0x4825800180007ff9", - "0x8de", - "0x400280007ff87fff", - "0x482680017ff88000", - "0x1", - "0x48297ffa80007ffb", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482680017ffa8000", - "0x1", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x480a7ffa7fff8000", - "0x10780017fff7fff", - "0x8", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0xe", - "0x480080007fff8000", - "0x400280007ffd7fff", - "0x48127ff97fff8000", - "0x48127ff77fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x480a7ffc7fff8000", - "0x482680017ffd8000", - "0x1", - "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffd7", - "0x208b7fff7fff7ffe", - "0x48127ffa7fff8000", - "0x48127ff87fff8000", - "0x480680017fff8000", - "0x0", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff88000", - "0x1", - "0x480a7ff97fff8000", - "0x480680017fff8000", - "0x1", - "0x48127ffb7fff8000", - "0x482480017ffa8000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x2", - "0x400380007ffb7ff3", - "0x400380017ffb7ff4", - "0x400380027ffb7ff5", - "0x400380007ffd7ff6", - "0x400380017ffd7ff7", - "0x48297ff880007ff9", - "0x400280027ffd7fff", - "0x480a7ff17fff8000", - "0x480a7ff27fff8000", - "0x480a7ff87fff8000", - "0x480a7ff97fff8000", - "0x480a7ffc7fff8000", - "0x482680017ffd8000", - "0x3", - "0x400b7ffa7fff8000", - "0x402780017ffb8001", - "0x3", - "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffac", - "0x20680017fff7ffd", - "0xb", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x480a80007fff8000", - "0x480a80017fff8000", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x208b7fff7fff7ffe", - "0x48127ffb7fff8000", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x480680017fff8000", - "0x0", - "0x48127ff97fff8000", - "0x48127ff97fff8000", - "0x208b7fff7fff7ffe", - "0xa0680017fff8000", - "0x7", - "0x482680017ff68000", - "0xfffffffffffffffffffffffffffff13c", - "0x400280007ff57fff", - "0x10780017fff7fff", - "0x64", - "0x4825800180007ff6", - "0xec4", - "0x400280007ff57fff", - "0x48297ffc80007ffd", - "0x48317fff80017ff7", - "0xa0680017fff7fff", - "0x7", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400280017ff57fff", - "0x10780017fff7fff", - "0xc", - "0x400280017ff57fff", - "0x482680017ff58000", - "0x2", - "0x48127ffb7fff8000", - "0x480680017fff8000", - "0x0", - "0x480a7ffa7fff8000", - "0x480a7ffb7fff8000", - "0x480a7ff77fff8000", - "0x208b7fff7fff7ffe", - "0x48297ff880007ff9", - "0xa0680017fff8000", - "0x6", - "0x48317ffe80007ff7", - "0x400280027ff57fff", - "0x10780017fff7fff", - "0x37", - "0x482680017ff78000", - "0x1", - "0x48307fff80007ffd", - "0x400280027ff57fff", - "0x482a7ff77ff88000", - "0x480080007fff8000", - "0x400280007ffb7fff", - "0x480680017fff8000", - "0x1", - "0x480a7ffa7fff8000", - "0x482680017ffb8000", - "0x1", - "0xa0680017fff8000", - "0x8", - "0x48327ffc7ff78000", - "0x4824800180007fff", - "0x100000000", - "0x400280037ff57fff", - "0x10780017fff7fff", - "0x13", - "0x48327ffc7ff78001", - "0x4824800180007fff", - "0xffffffffffffffffffffffff00000000", - "0x400280037ff57ffe", - "0x482680017ff58000", - "0x4", - "0x48127fee7fff8000", - "0x48127ffd7fff8000", - "0x480a7ff87fff8000", - "0x480a7ff97fff8000", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffbb", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x7533325f616464204f766572666c6f77", - "0x400080007ffe7fff", - "0x482680017ff58000", - "0x4", - "0x48127fec7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x496e646578206f7574206f6620626f756e6473", - "0x400080007ffe7fff", - "0x482680017ff58000", - "0x3", - "0x48127ff57fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff58000", - "0x1", - "0x480a7ff67fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x48127ffa7fff8000", - "0x482480017ff98000", - "0x1", - "0x208b7fff7fff7ffe", - "0x1104800180018000", - "0xa4", - "0x482480017fff8000", - "0xa3", - "0x480080007fff8000", - "0x480080037fff8000", - "0x482480017fff8000", - "0xc62", - "0xa0680017fff8000", - "0x8", - "0x48317ffe80007ff6", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400280007ff57fff", - "0x10780017fff7fff", - "0x85", - "0x48317ffe80007ff6", - "0x400280007ff57fff", - "0x482680017ff58000", - "0x1", - "0x48297ffc80007ffd", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482680017ffc8000", - "0x1", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x0", - "0x480a7ffc7fff8000", - "0x10780017fff7fff", - "0x8", - "0x480a7ffc7fff8000", - "0x480a7ffd7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0x5d", - "0x480080007fff8000", - "0x48307ffb80007ffc", - "0x20680017fff7fff", - "0x4", - "0x10780017fff7fff", - "0xa", - "0x482480017ffa8000", - "0x1", - "0x48127ffa7fff8000", - "0x480680017fff8000", - "0x0", - "0x48127ff77fff8000", - "0x10780017fff7fff", - "0x8", - "0x48127ffa7fff8000", - "0x48127ffa7fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x20680017fff7ffe", - "0x37", - "0x480080007fff8000", - "0x48327ff97ff98000", - "0x48327ffe7ffa8000", - "0x400280007ff77ffe", - "0x400280017ff77fff", - "0x400380027ff77ffb", - "0x482680017ff78000", - "0x6", - "0x480280037ff78000", - "0x480280047ff78000", - "0x480280057ff78000", - "0xa0680017fff8000", - "0x9", - "0x4824800180007feb", - "0x816", - "0x482480017fff8000", - "0x100000000000000000000000000000000", - "0x400080007fea7fff", - "0x10780017fff7fff", - "0x12", - "0x4824800180007feb", - "0x816", - "0x400080007feb7fff", - "0x482480017feb8000", - "0x1", - "0x48127ffe7fff8000", - "0x48127ff87fff8000", - "0x480a7ff87fff8000", - "0x48127ff77fff8000", - "0x48127ff77fff8000", - "0x48127ff77fff8000", - "0x48127fec7fff8000", - "0x48127fec7fff8000", - "0x1104800180018000", - "0x800000000000010ffffffffffffffffffffffffffffffffffffffffffffffa1", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482480017fe88000", - "0x1", - "0x48127fe67fff8000", - "0x48127ff57fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe", - "0x48327ffa7ff98000", - "0x482680017ffa8000", - "0x1", - "0x400280007ff77ffe", - "0x400280017ff77fff", - "0x400380027ff77ffb", - "0x48127ff27fff8000", - "0x48127ff07fff8000", - "0x482680017ff78000", - "0x6", - "0x480680017fff8000", - "0x0", - "0x48127ff67fff8000", - "0x48127ff67fff8000", - "0x480280037ff78000", - "0x208b7fff7fff7ffe", - "0x482680017ff98000", - "0x1", - "0x400280007ff77fff", - "0x400380017ff77ffa", - "0x400380027ff77ffb", - "0x48127ff97fff8000", - "0x48127ff77fff8000", - "0x482680017ff78000", - "0x6", - "0x480680017fff8000", - "0x0", - "0x48127ff77fff8000", - "0x48127ff77fff8000", - "0x480280037ff78000", - "0x208b7fff7fff7ffe", - "0x40780017fff7fff", - "0x1", - "0x480680017fff8000", - "0x4f7574206f6620676173", - "0x400080007ffe7fff", - "0x482680017ff58000", - "0x1", - "0x480a7ff67fff8000", - "0x480a7ff77fff8000", - "0x480680017fff8000", - "0x1", - "0x480680017fff8000", - "0x0", - "0x48127ff97fff8000", - "0x482480017ff88000", - "0x1", - "0x208b7fff7fff7ffe" - ], - "bytecode_segment_lengths": [ - 167, 110, 236, 161, 111, 32, 153, 128, 66, 43, 121, 164 - ], - "hints": [ - [ - 0, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "FP", "offset": -6 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [17, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 36, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "AP", "offset": -7 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [48, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 64, - [ - { - "TestLessThan": { - "lhs": { "Deref": { "register": "AP", "offset": -3 } }, - "rhs": { - "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" - }, - "dst": { "register": "AP", "offset": 4 } - } - } - ] - ], - [ - 68, - [ - { - "LinearSplit": { - "value": { "Deref": { "register": "AP", "offset": 3 } }, - "scalar": { "Immediate": "0x110000000000000000" }, - "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, - "x": { "register": "AP", "offset": -2 }, - "y": { "register": "AP", "offset": -1 } - } - } - ] - ], - [ - 78, - [ - { - "LinearSplit": { - "value": { "Deref": { "register": "AP", "offset": -4 } }, - "scalar": { "Immediate": "0x8000000000000000000000000000000" }, - "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, - "x": { "register": "AP", "offset": -1 }, - "y": { "register": "AP", "offset": 0 } - } - } - ] - ], - [86, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [122, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [137, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [152, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 167, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "FP", "offset": -6 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [184, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 204, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x5cda" }, - "rhs": { "Deref": { "register": "AP", "offset": -7 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [225, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [245, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [261, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 277, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "FP", "offset": -6 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [315, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 334, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x19fa" }, - "rhs": { "Deref": { "register": "AP", "offset": -12 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 358, - [ - { - "SystemCall": { - "system": { "Deref": { "register": "FP", "offset": -5 } } - } - } - ] - ], - [ - 369, - [ - { - "TestLessThan": { - "lhs": { "Deref": { "register": "AP", "offset": -1 } }, - "rhs": { "Immediate": "0x100000000000000000000000000000000" }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 371, - [ - { - "DivMod": { - "lhs": { "Deref": { "register": "AP", "offset": -2 } }, - "rhs": { "Immediate": "0x100000000000000000000000000000000" }, - "quotient": { "register": "AP", "offset": 3 }, - "remainder": { "register": "AP", "offset": 4 } - } - } - ] - ], - [ - 409, - [ - { - "TestLessThan": { - "lhs": { "Deref": { "register": "AP", "offset": -1 } }, - "rhs": { "Immediate": "0x100000000000000000000000000000000" }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 411, - [ - { - "DivMod": { - "lhs": { "Deref": { "register": "AP", "offset": -2 } }, - "rhs": { "Immediate": "0x100000000000000000000000000000000" }, - "quotient": { "register": "AP", "offset": 3 }, - "remainder": { "register": "AP", "offset": 4 } - } - } - ] - ], - [445, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [469, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [484, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [498, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 513, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "FP", "offset": -6 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [560, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 579, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x1284" }, - "rhs": { "Deref": { "register": "AP", "offset": -14 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 607, - [ - { - "SystemCall": { - "system": { "Deref": { "register": "FP", "offset": -5 } } - } - } - ] - ], - [610, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [630, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [645, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [659, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 674, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x0" }, - "rhs": { "Deref": { "register": "FP", "offset": -6 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [691, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 711, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0xae6" }, - "rhs": { "Deref": { "register": "AP", "offset": -7 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [731, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [753, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [769, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [819, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 835, - [ - { - "TestLessThan": { - "lhs": { "Deref": { "register": "FP", "offset": 3 } }, - "rhs": { - "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" - }, - "dst": { "register": "AP", "offset": 4 } - } - } - ] - ], - [ - 839, - [ - { - "LinearSplit": { - "value": { "Deref": { "register": "AP", "offset": 3 } }, - "scalar": { "Immediate": "0x110000000000000000" }, - "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, - "x": { "register": "AP", "offset": -2 }, - "y": { "register": "AP", "offset": -1 } - } - } - ] - ], - [ - 849, - [ - { - "LinearSplit": { - "value": { "Deref": { "register": "FP", "offset": 3 } }, - "scalar": { "Immediate": "0x8000000000000000000000000000000" }, - "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, - "x": { "register": "AP", "offset": -1 }, - "y": { "register": "AP", "offset": 0 } - } - } - ] - ], - [866, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [868, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 911, - [ - { - "SystemCall": { - "system": { "Deref": { "register": "FP", "offset": -3 } } - } - } - ] - ], - [954, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [970, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 986, - [ - { - "TestLessThan": { - "lhs": { "Deref": { "register": "AP", "offset": -3 } }, - "rhs": { - "Immediate": "0x800000000000000000000000000000000000000000000000000000000000000" - }, - "dst": { "register": "AP", "offset": 4 } - } - } - ] - ], - [ - 990, - [ - { - "LinearSplit": { - "value": { "Deref": { "register": "AP", "offset": 3 } }, - "scalar": { "Immediate": "0x110000000000000000" }, - "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, - "x": { "register": "AP", "offset": -2 }, - "y": { "register": "AP", "offset": -1 } - } - } - ] - ], - [ - 1000, - [ - { - "LinearSplit": { - "value": { "Deref": { "register": "AP", "offset": -4 } }, - "scalar": { "Immediate": "0x8000000000000000000000000000000" }, - "max_x": { "Immediate": "0xffffffffffffffffffffffffffffffff" }, - "x": { "register": "AP", "offset": -1 }, - "y": { "register": "AP", "offset": 0 } - } - } - ] - ], - [1008, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [1083, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 1098, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x8de" }, - "rhs": { "Deref": { "register": "FP", "offset": -7 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [1150, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 1207, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0xec4" }, - "rhs": { "Deref": { "register": "FP", "offset": -10 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 1219, - [ - { - "TestLessThan": { - "lhs": { "Deref": { "register": "AP", "offset": 0 } }, - "rhs": { "Immediate": "0x100000000" }, - "dst": { "register": "AP", "offset": -1 } - } - } - ] - ], - [ - 1237, - [ - { - "TestLessThan": { - "lhs": { "Deref": { "register": "FP", "offset": -9 } }, - "rhs": { "Deref": { "register": "AP", "offset": -1 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 1255, - [ - { - "TestLessThan": { - "lhs": { - "BinOp": { - "op": "Add", - "a": { "register": "FP", "offset": -9 }, - "b": { "Deref": { "register": "AP", "offset": -3 } } - } - }, - "rhs": { "Immediate": "0x100000000" }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [1280, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [1296, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [1312, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [ - 1336, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Deref": { "register": "AP", "offset": -1 } }, - "rhs": { "Deref": { "register": "FP", "offset": -10 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [ - 1402, - [ - { - "TestLessThanOrEqual": { - "lhs": { "Immediate": "0x816" }, - "rhs": { "Deref": { "register": "AP", "offset": -20 } }, - "dst": { "register": "AP", "offset": 0 } - } - } - ] - ], - [1427, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]], - [1475, [{ "AllocSegment": { "dst": { "register": "AP", "offset": 0 } } }]] - ], - "entry_points_by_type": { - "EXTERNAL": [ - { - "selector": "0x5de93e1525070ad9e62807a8b7eebf3c7fd7c60dd0a0ec728f9aa3b7c4146b", - "offset": 674, - "builtins": ["range_check", "poseidon"] - }, - { - "selector": "0x148fcde222e93109b646c02f8ed9babeb4fc5dd31b9de5026add8c3601acf9a", - "offset": 167, - "builtins": ["range_check", "poseidon"] - }, - { - "selector": "0x15811ea1dff18014ea6dad7ab86b6ae25e45829c0f8c717c9748a3208e4770e", - "offset": 277, - "builtins": ["range_check"] - }, - { - "selector": "0x21d33b226af0ea4fb717e4f9bff77bd7becd28c61f5bb8a3e3d6c7db1f0f4d8", - "offset": 513, - "builtins": ["range_check"] - }, - { - "selector": "0x3f9333bdab22b77e223157f7ef4f4b91598f4fac1ff161d34e59f646a54482c", - "offset": 0, - "builtins": ["range_check"] - } - ], - "L1_HANDLER": [], - "CONSTRUCTOR": [] - } -} diff --git a/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json b/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json deleted file mode 100644 index 2f2671266..000000000 --- a/crates/madara/client/settlement_client/src/starknet/test_contracts/messaging_test.sierra.json +++ /dev/null @@ -1,1471 +0,0 @@ -{ - "sierra_program": [ - "0x1", - "0x6", - "0x0", - "0x2", - "0x8", - "0x0", - "0x171", - "0x8f", - "0x44", - "0x52616e6765436865636b", - "0x800000000000000100000000000000000000000000000000", - "0x436f6e7374", - "0x800000000000000000000000000000000000000000000002", - "0x1", - "0x8", - "0x2", - "0x496e646578206f7574206f6620626f756e6473", - "0x7533325f616464204f766572666c6f77", - "0xe", - "0x4172726179", - "0x800000000000000300000000000000000000000000000001", - "0x536e617073686f74", - "0x800000000000000700000000000000000000000000000001", - "0x5", - "0x537472756374", - "0x800000000000000700000000000000000000000000000002", - "0x0", - "0x1baeba72e79e9db2587cf44fedb2f3700b2075a5e8e39a562584862c4b71f62", - "0x6", - "0x66656c74323532", - "0x800000000000000700000000000000000000000000000000", - "0x800000000000000700000000000000000000000000000003", - "0x2ee1e2b1b89f8c495f200e4956278a4d47395fe262f27b52e5865c9524c08c3", - "0x7", - "0x800000000000000f00000000000000000000000000000001", - "0x16a4c8d7c05909052238a862d8cc3e7975bf05a07b3a69c6b28951083a6d672", - "0x800000000000000300000000000000000000000000000003", - "0xa", - "0x456e756d", - "0x2a594b95e3522276fe0ac7ac7a7e4ad8c47eaa6223bc0fd6991aa683b7ee495", - "0x9", - "0xb", - "0x800000000000000700000000000000000000000000000004", - "0x753332", - "0x800000000000000300000000000000000000000000000004", - "0xf", - "0x7da71e1dc546b96d9fd53438ce53f427347947c6c30c6495690af26972951f", - "0x10", - "0x104eb68e98232f2362ae8fd62c9465a5910d805fa88b305d1f7721b8727f04", - "0x12", - "0x398697ad8745b865eefbaa4afad41e52876386afeeb69101604d297801076ef", - "0x436f6e747261637441646472657373", - "0x800000000000000300000000000000000000000000000007", - "0x3dd453aa05a2f3bf86ece4df9fed5c412d578aa6757891c1ad0b57b67790209", - "0x15", - "0x16", - "0x800000000000000300000000000000000000000000000002", - "0x368071f3dba81b34500453fd69db5f6c53faca6693aece4aa9f2a7bc2aa49bc", - "0x18", - "0x556e696e697469616c697a6564", - "0x800000000000000200000000000000000000000000000001", - "0x506f736569646f6e", - "0x1c", - "0x10203be321c62a7bd4c060d69539c1fbe065baa9e253c74d2cc48be163e259", - "0x1e", - "0x3288d594b9a45d15bb2fcb7903f06cdb06b27f0ba88186ec4cfaa98307cb972", - "0x426f78", - "0x29d7d57c04a880978e7b3689f6218e507f3be17588744b58dc17762447ad0e7", - "0x21", - "0x4661696c656420746f20646573657269616c697a6520706172616d202331", - "0x75313238", - "0x25e2ca4b84968c2d8b83ef476ca8549410346b00836ce79beaf538155990bb2", - "0x24", - "0x66b4f105", - "0x4e6f6e5a65726f", - "0x53746f7261676541646472657373", - "0x53746f726167654261736541646472657373", - "0x28a1868d4e0a4c6ae678a74db4e55a60b628ba8668dc128cf0c8e418d0a7945", - "0x2b", - "0x11c6d8087e00642489f92d2821ad6ebd6532ad1a3b6d12833da6d6810391511", - "0x21e8f4b48e39aab91b0f66e96b5501a78cf87c4e56e1214be3451bfd26b2a74", - "0x800000000000000f00000000000000000000000000000003", - "0x2e", - "0x1f952230aae2b27f93ec43fdad476d4b1b5586b5f667332ac43bf94a5b361ae", - "0x2f", - "0x4f7574206f6620676173", - "0x4f7074696f6e3a3a756e77726170206661696c65642e", - "0x74584e9f10ffb1a40aa5a3582e203f6758defc4a497d1a2d5a89f274a320e9", - "0x34", - "0x800000000000000300000000000000000000000000000006", - "0x346f115089c4077e357c839c5a87472e9797e47afb8541ce884b3a13c009605", - "0x36", - "0x2386f26fc10000", - "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", - "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - "0x7484e8e3af210b2ead47fa08c96f8d18b616169b350a8b75fe0dc4d2e01d493", - "0x1a055690d9db80000", - "0x3dbe3dd8c2f721bc24e87bcb739063a10ee738cef090bc752bc0d5a29f10b72", - "0x4275696c74696e436f737473", - "0x53797374656d", - "0x9931c641b913035ae674b400b61a51476d506bbe8bba2ff8a6272790aba9e6", - "0x33", - "0x496e70757420746f6f206c6f6e6720666f7220617267756d656e7473", - "0x4761734275696c74696e", - "0xbd", - "0x7265766f6b655f61705f747261636b696e67", - "0x77697468647261775f676173", - "0x6272616e63685f616c69676e", - "0x7374727563745f6465636f6e737472756374", - "0x73746f72655f74656d70", - "0x61727261795f736e617073686f745f706f705f66726f6e74", - "0x64726f70", - "0x61727261795f6e6577", - "0x636f6e73745f61735f696d6d656469617465", - "0x42", - "0x61727261795f617070656e64", - "0x7374727563745f636f6e737472756374", - "0x656e756d5f696e6974", - "0x41", - "0x43", - "0x40", - "0x6765745f6275696c74696e5f636f737473", - "0x3f", - "0x77697468647261775f6761735f616c6c", - "0x3e", - "0x3d", - "0x3c", - "0x3b", - "0x21adb5788e32c84f69a1863d85ef9394b7bf761a0ce1190f826984e5075c371", - "0x3a", - "0x39", - "0x38", - "0x736e617073686f745f74616b65", - "0x37", - "0x66756e6374696f6e5f63616c6c", - "0x3", - "0x656e756d5f6d61746368", - "0x35", - "0x32", - "0x31", - "0x30", - "0x656e61626c655f61705f747261636b696e67", - "0x756e626f78", - "0x72656e616d65", - "0x2d", - "0x6a756d70", - "0x64697361626c655f61705f747261636b696e67", - "0x73746f726167655f626173655f616464726573735f636f6e7374", - "0x3150ab9073ca993efcd1d4ab278c207ab86418914db765f88aa5d8e7bc5c79", - "0x2c", - "0x73746f726167655f616464726573735f66726f6d5f62617365", - "0x29", - "0x2a", - "0x73746f726167655f726561645f73797363616c6c", - "0x66656c743235325f69735f7a65726f", - "0x75313238735f66726f6d5f66656c74323532", - "0x27", - "0x28", - "0x26", - "0x25", - "0x647570", - "0x753132385f746f5f66656c74323532", - "0x23", - "0x22", - "0x20", - "0x626f6f6c5f6e6f745f696d706c", - "0x626f6f6c5f746f5f66656c74323532", - "0x73746f726167655f77726974655f73797363616c6c", - "0x1f", - "0x7374727563745f736e617073686f745f6465636f6e737472756374", - "0x636f6e74726163745f616464726573735f746f5f66656c74323532", - "0x61727261795f6c656e", - "0x7533325f746f5f66656c74323532", - "0x616c6c6f635f6c6f63616c", - "0x66696e616c697a655f6c6f63616c73", - "0x73746f72655f6c6f63616c", - "0x19", - "0x656e756d5f736e617073686f745f6d61746368", - "0x14", - "0x17", - "0x13", - "0x656d69745f6576656e745f73797363616c6c", - "0x1d", - "0x11", - "0xd", - "0xc", - "0x7533325f6f766572666c6f77696e675f737562", - "0x61727261795f676574", - "0x4", - "0x7533325f6f766572666c6f77696e675f616464", - "0x66656c743235325f616464", - "0x68616465735f7065726d75746174696f6e", - "0x4ec", - "0xffffffffffffffff", - "0x66", - "0x59", - "0x1a", - "0x1b", - "0x4b", - "0x45", - "0x46", - "0x47", - "0xbb", - "0x8a", - "0xad", - "0xa5", - "0x16f", - "0xd8", - "0xdd", - "0x15f", - "0xf1", - "0x152", - "0x48", - "0x49", - "0x149", - "0x4a", - "0x11c", - "0x114", - "0x4c", - "0x4d", - "0x118", - "0x4e", - "0x4f", - "0x12e", - "0x50", - "0x51", - "0x127", - "0x12b", - "0x52", - "0x53", - "0x54", - "0x55", - "0x56", - "0x57", - "0x58", - "0x5a", - "0x5b", - "0x5c", - "0x5d", - "0x5e", - "0x5f", - "0x60", - "0x61", - "0x62", - "0x63", - "0x64", - "0x65", - "0x67", - "0x68", - "0x69", - "0x6a", - "0x6b", - "0x6c", - "0x6d", - "0x6e", - "0x6f", - "0x70", - "0x71", - "0x1f4", - "0x189", - "0x18e", - "0x1e4", - "0x199", - "0x19e", - "0x1b0", - "0x1d6", - "0x1cd", - "0x24b", - "0x218", - "0x23d", - "0x235", - "0x72", - "0x73", - "0x74", - "0x297", - "0x75", - "0x76", - "0x77", - "0x78", - "0x79", - "0x7a", - "0x7b", - "0x7c", - "0x7d", - "0x7e", - "0x7f", - "0x304", - "0x80", - "0x2f9", - "0x81", - "0x82", - "0x83", - "0x84", - "0x85", - "0x86", - "0x87", - "0x88", - "0x89", - "0x2f0", - "0x8b", - "0x8c", - "0x2e5", - "0x8d", - "0x8e", - "0x8f", - "0x90", - "0x91", - "0x370", - "0x92", - "0x93", - "0x369", - "0x94", - "0x95", - "0x96", - "0x97", - "0x98", - "0x99", - "0x362", - "0x9a", - "0x9b", - "0x9c", - "0x9d", - "0x9e", - "0x3a8", - "0x38a", - "0x38f", - "0x39d", - "0x9f", - "0xa0", - "0x404", - "0xa1", - "0xa2", - "0xa3", - "0xa4", - "0x457", - "0xa6", - "0x41e", - "0xa7", - "0xa8", - "0xa9", - "0xaa", - "0xab", - "0x447", - "0xac", - "0xae", - "0x437", - "0xaf", - "0xb0", - "0xb1", - "0x4dc", - "0xb2", - "0x474", - "0x479", - "0x4ca", - "0x484", - "0x489", - "0x4b7", - "0xb3", - "0xb4", - "0xb5", - "0x4a5", - "0xb6", - "0xb7", - "0xb8", - "0xb9", - "0xba", - "0xbc", - "0xca", - "0x17d", - "0x202", - "0x25a", - "0x29e", - "0x315", - "0x37e", - "0x3b6", - "0x40b", - "0x467", - "0x2c1b", - "0x140e0a028100609038180a04018200e06028100605038180a04018080200", - "0x4834100301432050c0482e100b0542805098482210078141c0d03014180b", - "0x180a06028180a18090882021028800a1f090703c0f028740a1809070201b", - "0x484810108144e0513048381e1281414050781430121204030120d0402c23", - "0xb4242c08058562a038180a04018840a29028a0241c0f0940a0f0283c0a18", - "0xcc6405070345e0518848601e178141c0d078140c05030140c05170140c05", - "0x840a38028dc241c0f0180a18090442036028d066021a83c0a34198180a34", - "0xf87a070301408031281478051d8482e1e030141c3a128144a051c8482e1e", - "0x100606028388412039000a04019040e06028100640029000a3f0905c2016", - "0x4090120d0404a05030148e120b8788c052284822100b1102c430901c1405", - "0x1380e0602810064d038180a04018840a4c0292c241c0f0940a4a028602449", - "0x14a412288404205280149e120e0784a050781430120e04032050c0482210", - "0x100655038180a04019500e06028100653028381a060283c0a06028180a2e", - "0x1c0c050200cb0070301408030901c0c050200cae070301408032b01c0c05", - "0x18c246209184c0022f9780e06028100621029740a5c090703c022d858b459", - "0x14d20602814d03c02814ce1402814ce0602814cc1202814ca1902814c812", - "0x140a650281cdc05039b44205029b03a05029b00c05029ac0c0502994d405", - "0x14d27502814d27402814d212399c80a0532848e26e02814ca7002814ca6f", - "0x140a6c3d8140a693d0140a693c8140a69091e01e0502994ee05029a4ec05", - "0x14ce5002814c88102815000f3f814fc7d02814ca5302814ce5302814f853", - "0x140a690901cdc05039b4ba05029b03205029b01e050299c1e05029f04a05", - "0x14ce840281500143f814fc4a02814d83602814ca1902814ce8302814d282", - "0x2251005029942805029942407440140e6d030140a87030140a86092149805", - "0x14d88c038151612450180a0533a200a05400140e880281cda2502814d812", - "0x140a65478140a69092388c0502a1d1a05029911a050299d1a05029f11a05", - "0x1000a05438480a05439000a0532a500a0534849261249049229002814ca0a", - "0x140a984b8140a654b8140a674b8140a7c4b8140a6c4b0140a694a8140a67", - "0x1cda9b02814ca1203a6c0a0736a680a0534849324002814ce9702814c897", - "0x140a670901d3805039b53805029940a074e0140e6d4d8140a800281d3605", - "0xe00a05322800a0540064fe053f1280a05339280a053e0493e124f0493a9c", - "0x2900c0502a8c280502a605c050299c24a2170140a87298140aa13e8140a98", - "0x1f40a0533a040a05328480e810281cda5002814d8063f814fc1902814ca12", - "0x140aa7030140aa7092980c0502a941e0502a946c0502a940a07408140e6d", - "0x2a00a05328c80a05338c80a053e0480e320281cda2f02814d836028154e0f", - "0x1b024ad148140a64560140a80101fc0a7e558140a65550140a69190140aa9", - "0x74fe053f2b80a05338140e840281cda8402814ca1203a100a07369300a05", - "0x140a80109fc0a7e580140a65580140a6c050140a67138140a64578140a80", - "0x15300503a800a0736a800a05328480ea00281cda3802814d82002814c8b1", - "0x2600a07560140e6d560140a650901d5805039b45205029b05e0502a855605", - "0x180a05598640a054c2bc0a05328480eaf0281cda2702814d812590280a05", - "0x140a64038140a690281d5e05039b4fe05029a424b55a0140a691e0140a65", - "0x140a0534ac40a05328140eb10281cda7202814ce720281530125b8496cb0", - "0x1c0a120381424125c8142412092e160050299c2407588140e6d100140a6c", - "0x1568055a0480c055c814fe053f84824b9028480e120c8500eba07ad00eb9", - "0x2e40a200285024125c8142407090840a2e0e8800eb9038180a0f092d00ab9", - "0x1560050e84960055c8142420092c40ab9028480c12092e40a1d028642412", - "0x157205050940eb0090940ab9028496212050157205582c40e21092c00ab9", - "0x9c240f02ae40a0f0289424b402ae40ab402ad024af02ae40a27028282427", - "0x4824b9028480e125781c1eb45a0155e055c8155e05578480e055c8140e05", - "0xa41eb43faa8242902ae40a2902ab0242902ae40a121484824b9028840a14", - "0x2e40a121704956055c81424060904972050901c242f1701d76aa5601d7207", - "0x4978055c814242f092a00ab9028c956071084864055c81464050e8486405", - "0xd80a1d090d80ab90284956125e81572055e2a00e21092f00ab902af00a1d", - "0x1572051c0143a121c0157205090c824ae02ae40a365e81c42121b0157205", - "0x2e40a120384878055f27140075c81c70ac03af024ae02ae40aae02aa02438", - "0x2e40a125704880055c8142436092680ab9028497a124d8157205090182412", - "0x2500a9c0925528075c8152c05500492c055c8152eae20269380f1c0492e05", - "0x2540ab902a540a3c092a80ab902aa80a25092800ab902a800ab4090497205", - "0x2e40e4602a6824464823cfeb902a6d2aaa502d136124d81572054d8155012", - "0x497205260152e12261280eb902a340a400904972050901c2488028011a05", - "0x151e12410157205418152a12092e40a8402a5024834201d7205250152c12", - "0x2e40a9002894248f02ae40a8f02ad0245002ae40a5d02a40245d02ae40a82", - "0x480e122801d208f5a014a0055c814a005578480e055c8140e05138492005", - "0x2400ab902a400a250923c0ab902a3c0ab4092040ab902a200a0a090497205", - "0x2e40a120384902074823d6805408157205408155e12038157205038144e12", - "0x14fa050e848fa055c81424460914c0ab9028480c12092e40aae02a502412", - "0x1572053d9e80eb0091e80ab90284962123d81572053e94c0e21091f40ab9", - "0x9c24aa02ae40aaa02894243c02ae40a3c02ad0247702ae40a79028282479", - "0x4824b9028480e123b81d543c5a014ee055c814ee05578480e055c8140e05", - "0x14ea7603884247502ae40a7502874247502ae40a1246848ec055c8142406", - "0x1b80ab9029c00a0a091c00ab9029d0e40758048e4055c81424b1091d00ab9", - "0x155e12038157205038144e12178157205178144a12170157205170156812", - "0x480c12092e40a7f02a2024125c8142407091b80e2f172d00a6e02ae40a6e", - "0x157205379a80e21091bc0ab9029bc0a1d091bc0ab9028491a12350157205", - "0x2d024c102ae40ac00282824c002ae40a005f81d60125f8157205092c42400", - "0x158205578480e055c8140e051384832055c81432051284828055c8142805", - "0x1d84140781d7207038480e050904972050904824c10386428b402b040ab9", - "0x141e120781572050781568121001572055a014fe12092e40a12038480c19", - "0x1442050c84824b9028740a140904972050901c24b102b0c421d03ae40e20", - "0x1c4212050157205050143a120501572050908024b002ae40a120304824b9", - "0x155e05050495e055c8144a2703ac0242702ae40a12588484a055c81414b0", - "0x500ab9028500a25090140ab9028140a4a0903c0ab90283c0ab4090a40ab9", - "0x142407090a4fe140283c1e05148157205148155e123f81572053f8144e12", - "0x1fd5412560157205560155812560157205090a424125c81562050a04824b9", - "0x2d0243202ae40a122604824b9028480e12558bc0ec4172a80eb903ab0280f", - "0x14fe05138480a055c8140a05250485c055c8145c051284954055c8155405", - "0xe00ab903ab80a83092b86cbd5e2a01eb9028c8fe05172a81e84091fc0ab9", - "0x2700a96092700ab9028480c12092e40a3802a0824125c8142407092800ac5", - "0x1572054d0151e124d01572054d8152a12092e40a3c02a50249b1e01d7205", - "0x9424bd02ae40abd0292824a802ae40aa802ad0249702ae40a4002a402440", - "0x2f17aa8078152e055c8152e05578486c055c8146c051384978055c8157805", - "0x1494125401572055401568124b0157205500141412092e40a12038492e36", - "0x2e40a9602abc243602ae40a360289c24bc02ae40abc0289424bd02ae40abd", - "0x2e40a124684928055c81424060904972050901c24961b2f17aa8078152c05", - "0x4920055c81424b10923c0ab902a552807108492a055c8152a050e8492a05", - "0x14941217815720517815681246815720523014141223015720547a400eb0", - "0x2e40a8d02abc247f02ae40a7f0289c24ab02ae40aab02894240502ae40a05", - "0x2e40a120304824b902ad00a880904972050901c248d3faac0a2f078151a05", - "0x4898055c814948803884244a02ae40a4a02874244a02ae40a12468491005", - "0x640ab4092080ab902a0c0a0a0920c0ab90293108075804908055c81424b1", - "0x1572053f8144e12030157205030144a120281572050281494120c8157205", - "0x1424070284824b9028482412411fc0c050c83c0a8202ae40a8202abc247f", - "0x14245d090180ab9029fc0a7f0904972050901c24190a01d8c0f5a01d7207", - "0x2e40a120384842056387440075c81c0c050784968055c81568055a04824b9", - "0x1f4240a02ae40ab00294c24b002ae40ab102a0424b102ae40a1d029402412", - "0x4824b9028480e12093200a123d0484e055c81414053d8484a055c8144005", - "0x1452053d8484a055c81442053e84852055c8155e053b8495e055c8142479", - "0x49720556014ea12092e40a1203849540564ab00ab90389c0a760909c0ab9", - "0x142812092e40a123a04824b9028480e1255815942f1701d7207128141e12", - "0x7424a802ae40a121004864055c8142406090497205178143212092e40a2e", - "0x2f17a07580497a055c81424b1092f00ab902aa064071084950055c8155005", - "0x157205078144a125a01572055a01568125701572051b01414121b0157205", - "0x142407092b80e0f5a2d00aae02ae40aae02abc240702ae40a070289c240f", - "0x1470055604870055c8142429090497205558142812092e40a123a04824b9", - "0x48e412092e40a1203849363c03b2d38a003ae40e3807ad0feaa090e00ab9", - "0x2e40a97029a824964b81d720520014dc122001572054d014e0124d0157205", - "0x300248f02ae40a9502afc249502ae40a9402800249402ae40a96029bc2412", - "0x2e40aa002ad0248f02ae40a8f02b30249002ae40a9002b04249002ae40a12", - "0x4824b9028480e1242130947f672211a463fae40e8f4801d38b4668494005", - "0x2e40a8d0289c244602ae40a4602894248802ae40a880287424125c814245d", - "0x74248202ae40a125584824b9028480e1241815a0125c81d1005678491a05", - "0x4972050901c247d29a04fed1281740eb903a0940075f04904055c8150405", - "0x1ec0ad3091e40ab9029400ad3091e80ab9029740ab4091ec0ab902849a412", - "0x15a6123d0157205408156812092e40a120384824d402848f4123b8157205", - "0x2e40a7902b58247602ae40a7a02b54247702ae40a5302b4c247902ae40a7d", - "0x1506056c04824b9028480e120935c0a123d048e8055c814ee056b048ea05", - "0x1b8e0075c81ce4a003af8247202ae40a7202874247202ae40a126c84824b9", - "0x4980055c814e0055a0497e055c81424d20904972050901c2400379a8feda", - "0x4972050901c24126d814247a093300ab902afc0ad3093040ab9029b80ad3", - "0x15aa1266015720537815a61260815720500015a612600157205350156812", - "0x497205091d0247402ae40acc02b58247502ae40ac102b58247602ae40ac0", - "0x37824d25f01d720567815ba126781572053a1d40edc093340ab9028480c12", - "0x15a60570849a6d203ae40ad202b8024d202ae40ad202b7c24125c8157c05", - "0x3640ab902b600abb093600ab902b540ad60904972056b015c4126b3540eb9", - "0x35824125c815ba0571049bcdd03ae40ad202b8424dc02ae40ad96681c4212", - "0x3840a96093840ab902b81b80710849c0055c815be055d849be055c815bc05", - "0x157205718151e127181572055d8152a12092e40ae202a5024bb7101d7205", - "0x9c244602ae40a4602894247602ae40a7602ad024e502ae40ae402a4024e4", - "0x4824b9028480e1272a348c765a015ca055c815ca05578491a055c8151a05", - "0x2800ab4093a00ab902b9c0a0a0939c0ab902a11cc0758049cc055c81424b1", - "0x157205740155e12260157205260144e12250157205250144a12500157205", - "0x3a80ab9028491a127481572050901824125c8142407093a0984a502d00ae8", - "0x1d6012760157205092c424eb02ae40aea7481c4212750157205750143a12", - "0x1536051284878055c81478055a049dc055c815da0505049da055c815d6ec", - "0x1c24ee03a6c78b402bb80ab902bb80aaf0901c0ab90281c0a270926c0ab9", - "0x480c12092e40a250285024125c81554054b84824b902848e812092e40a12", - "0x15720577ae80e21093bc0ab902bbc0a1d093bc0ab902849c6125d0157205", - "0x2d024f302ae40af20282824f202ae40af07881d6012788157205092c424f0", - "0x15e605578480e055c8140e05138481e055c8141e051284968055c8156805", - "0x2e40a120304824b9029fc0a880904972050901c24f30383d68b402bcc0ab9", - "0x49ec055c815eaf40388424f502ae40af50287424f502ae40a1246849e805", - "0x500ab4093e40ab902be00a0a093e00ab902bd9ee0758049ee055c81424b1", - "0x1572057c8155e12038157205038144e120c81572050c8144a120a0157205", - "0x6428077d03d68075c81c0a120381424125c8142412093e40e190a2d00af9", - "0x1572055a0156812092e40a122e8480c055c814fe053f84824b9028480e12", - "0x2c40ab9028740ae40904972050901c242102bec3a2003ae40e060283c24b4", - "0x2e40a120384824fc02848f41205015720558815ca1258015720510014fa12", - "0x15ca1258015720510814fa1213815720512815cc12128157205091e42412", - "0x155e052804824b9028480e1214815faaf02ae40e0a02b9c240a02ae40a27", - "0x3f824b903aa80acf092a80ab902aa80a1d092a80ab902ab00a81092b00ab9", - "0x2ac0ae9092ac0ab9028bc0ae8090bc0ab902848f212092e40a12038485c05", - "0x14247909049720517015b012092e40a120384824ff02848f412190157205", - "0x2f40eb903ac00a0f090c80ab902af00ae9092f00ab902aa00aea092a00ab9", - "0xd80a190904972055e8142812092e40a123a04824b9028480e12570160036", - "0x143a1250015720509080243802ae40a120304824b9028c80aeb090497205", - "0x15383c03ac0243c02ae40a125884938055c81540380388424a002ae40aa0", - "0x3c0ab90283c0a25092d00ab902ad00ab4092680ab902a6c0a0a0926c0ab9", - "0x2e40a1203849340707ad168054d01572054d0155e12038157205038144e12", - "0x2e40a4002ab0244002ae40a121484824b902ab80a14090497205091d02412", - "0x1424720904972050901c24954a01e02964b81d72072003d687f550488005", - "0x2340ab902a3c0abf091180ab902a400aed092400ab9028c80aec0923c0ab9", - "0x1180a1d092340ab902a340acc092200ab902a200ac1092200ab9028498012", - "0x1fe044c2501d72072323510074b03ddc124b81572054b8156812230157205", - "0x25024812801d72052e8152c122e81572050901824125c8142407092090684", - "0x2e40a7d02a40247d02ae40a5302a3c245302ae40a8102a5424125c814a005", - "0x4898055c81498051384894055c8149405128492e055c8152e055a048f605", - "0x48f4055c81424b10904972050901c247b261292eb4029ec0ab9029ec0aaf", - "0x144a124b81572054b81568123b81572053c81414123c8157205411e80eb0", - "0x1dd06844bad00a7702ae40a7702abc248302ae40a830289c248402ae40a84", - "0x1d40ab9028491a123b01572050901824125c81464057584824b9028480e12", - "0x1d6012390157205092c4247402ae40a753b01c42123a81572053a8143a12", - "0x152a051284928055c81528055a048dc055c814e00505048e0055c814e872", - "0x1c246e03a5528b4029b80ab9029b80aaf0901c0ab90281c0a27092540ab9", - "0x480c12092e40ab00285024125c81452054b84824b902848e812092e40a12", - "0x157205379a80e21091bc0ab9029bc0a1d091bc0ab902849c612350157205", - "0x2d024c102ae40ac00282824c002ae40a005f81d60125f8157205092c42400", - "0x158205578480e055c8140e05138481e055c8141e051284968055c8156805", - "0x2e40a120304824b9029fc0a880904972050901c24c10383d68b402b040ab9", - "0x499e055c8159acc0388424cd02ae40acd0287424cd02ae40a12468499805", - "0x500ab40934c0ab902b480a0a093480ab902b3d7c07580497c055c81424b1", - "0x157205698155e12038157205038144e120c81572050c8144a120a0157205", - "0x183207818501e075c81c0e120381424125c81424120934c0e190a2d00ad3", - "0x1c4005078481e055c8141e055a04840055c81568053f84824b9028480e12", - "0x497205108143212092e40a1d0285024125c8142407092c40b04108740eb9", - "0x2960071084814055c81414050e84814055c8142420092c00ab9028480c12", - "0x1572055781414125781572051289c0eb00909c0ab9028496212128157205", - "0x9c241402ae40a1402894240502ae40a0502928240f02ae40a0f02ad02429", - "0x4972050901c24293f8500a0f0781452055c814520557848fe055c814fe05", - "0x501e7f5504958055c81558055604958055c8142429090497205588142812", - "0xc80aba090c80ab9028489812092e40a1203849562f03c145caa03ae40eac", - "0x157205170144a12550157205550156812092e40aa802bbc24bc5401d7205", - "0xe00af1090e15c365ead172055e0145caa5a3c0240502ae40a0502928242e", - "0x15720550015e4121e01572050901824125c8142407092700b06500157207", - "0x4824b9029000a940925c80075c81534054b04934055c815363c03884249b", - "0x2f40ab4092540ab902a500a90092500ab902a580a8f092580ab902a5c0a95", - "0x1572053f8144e121b01572051b0144a125701572055701494125e8157205", - "0x1538050504824b9028480e124a9fc6cae5e83c0a9502ae40a9502abc247f", - "0xd80ab9028d80a25092b80ab902ab80a4a092f40ab902af40ab40923c0ab9", - "0x1424070923cfe36572f41e05478157205478155e123f81572053f8144e12", - "0x1c4212230157205230143a1223015720509234249002ae40a120304824b9", - "0x1494050504894055c8151a8803ac0248802ae40a12588491a055c8148c90", - "0x2ac0ab902aac0a25090140ab9028140a4a090bc0ab9028bc0ab4091300ab9", - "0x14240709130feab028bc1e05260157205260155e123f81572053f8144e12", - "0x20c0a1d0920c0ab9028491a124201572050901824125c81568054404824b9", - "0x2e40a822e81d60122e8157205092c4248202ae40a834201c4212418157205", - "0x480a055c8140a052504832055c81432055a04902055c814a00505048a005", - "0x14320f02a040ab902a040aaf091fc0ab9029fc0a27090180ab9028180a25", - "0x501e0f5c81568057a049680703ae40a0702bcc24125c814247409204fe06", - "0x14ea12092e40a060285024125c81432053a84824b9028500a75090800c19", - "0x2e40a213f81c42121081572050e815ec120e815720507815ea12092e40a20", - "0x280af7090a55e27128281eb902ac00af4092c00e075c8140e05798496205", - "0x150212092e40a29029d424125c8155e050a04824b90289c0a75090497205", - "0xb80af4090b80e075c8140e057984954055c81558b10388424ac02ae40a25", - "0x1550050a04824b902aac0a7509049720517815ee125e2a064ab1783d7205", - "0x486c055c8157aaa0388424bd02ae40a3202a0424125c81578053a84824b9", - "0x4972051c015ee124d8f138a01c03d720557015e8125701c0eb90281c0af3", - "0x2e40a3c02be024125c81536053a84824b902a700a7509049720550014ea12", - "0x25c0ab902a5c0a1d0925c0ab9029000b07091000ab902a680af9092687807", - "0x94241202ae40a1202ad0249402ae40a3c02a54249602ae40a971b01c4212", - "0x1424b4848492c055c8152c055404928055c8152805840480a055c8140a05", - "0x10024125c8142407092340b0a2301572074801534124823d2a7f5c8152c94", - "0x48ba8241a10980f5c8140e057a04824b9029280a970912910075c8148c05", - "0x497205410142812092e40a83029d424125c81508053a84824b9029300af7", - "0x1e1612298157205091e4248102ae40a504401c42122801572052e8150212", - "0x151e05128492a055c8152a055a048f6055c814fa0586048fa055c814a681", - "0x140e058704824b9028480e123da3d2a7f029ec0ab9029ec0b0d0923c0ab9", - "0x491e055c8151e05128492a055c8152a055a048f4055c8151a058784824b9", - "0x480c055c8142511090500ab90284a20123d23d2a7f029e80ab9029e80b0d", - "0xb8242102ae40a120304824b902848e812092e40a12898483a055c8142512", - "0x2e40a121784960055c81562210388424b102ae40ab10287424b102ae40a12", - "0x484e055c81424ab090940ab90282960071084814055c81414050e8481405", - "0x740f14090800ab90284864120c8157205138940e210909c0ab90289c0a1d", - "0x2b00b1614abc0eb90388024075e04832055c814320603c54242002ae40a20", - "0x140a25092bc0ab902abc0ab4090b954075c81568055d04824b9028480e12", - "0x48640f558bd68b9028b80e0557ad1e012038157205038149412028157205", - "0x1824125c8142407092f00b1854015720719015e212078157205078500f17", - "0x4870055c8142436092b80ab9028497a121b01572050901824bd02ae40a12", - "0xf00ab9028654038570a538148c84938055c81550057904940055c81424ae", - "0x163a12092e40a9a02c7024404d01d72054d81636124d81572051e0163412", - "0x492c055c814251f0904972050901c249702ae40a4002c78244002ae40a40", - "0x144a121781572051781568124a01572054b2f40e21092580ab902a580a1d", - "0x2e40a3602aa0249402ae40a9402aa0249702ae40a9702c8024ab02ae40aab", - "0x2340b222301572074801586124823d2a7f5c8146c944baac5e0f908486c05", - "0x2200a96090497205260152e1226129107f5c8148c059184824b9028480e12", - "0x2e40a8202a50245d4101d7205250152c12092e40a8402a5024834201d7205", - "0x1d720740940fe8f5a490248102ae40a5d02a54245002ae40a8302a542412", - "0x2e40a775501e4c123b8157205091e424125c8142407091e4f47b3fc94fa53", - "0x48a6055c814a605128492a055c8152a055a048ea055c814ec0593848ec05", - "0x14d2a0f029d40ab9029d40b28091f40ab9029f40a270903c0ab90283c0a4a", - "0x1d00eb0091d00ab9028496212092e40aaa02bbc24125c8142407091d4fa0f", - "0x2e40a7b02894249502ae40a9502ad0247002ae40a7202ca4247202ae40a79", - "0x14e0055c814e00594048f4055c814f405138481e055c8141e0525048f605", - "0x1b80ab902a340b2909049720555015de12092e40a1203848e07a079ed2a0f", - "0x144e12078157205078149412478157205478144a124a81572054a8156812", - "0x4824b9028480e12371fc1e8f4a83c0a6e02ae40a6e02ca0247f02ae40a7f", - "0x1572055e0165212092e40a1902a5024125c81452057b84824b902aa80aef", - "0x9c240f02ae40a0f0292824ab02ae40aab02894242f02ae40a2f02ad0246a", - "0x4972050901c246a3f83d562f07814d4055c814d40594048fe055c814fe05", - "0x1572050901824125c81428059504824b9028640a940904972055a015de12", - "0x2c424bf02ae40a003781c4212000157205000143a1200015720509118246f", - "0x1558055a04998055c81582059484982055c8157ec003ac024c002ae40a12", - "0x1fc0ab9029fc0a270901c0ab90281c0a4a090140ab9028140a25092b00ab9", - "0x2e40a7f02bbc24125c814247409330fe0702ab01e05660157205660165012", - "0x2d00e210903c0ab90283c0a1d0903c0ab9028485c125a0157205090182412", - "0x2e40a190a01c42120c81572050c8143a120c8157205090bc241402ae40a0f", - "0x483a055c814400603884242002ae40a2002874242002ae40a12558480c05", - "0x8424075e0483a055c8143a055404842055c81442050e84842055c8142432", - "0x2e40ab002bd8242502ae40a120304824b9028480e120501656b05881d7207", - "0x4852055c81452050e84852055c81424bd092bc0ab90289c4a07108484e05", - "0x2b00e21092a80ab902aa80a1d092a80ab9028486c1256015720514abc0e21", - "0x2e40a2f1701c4212178157205178143a12178157205092b8242e02ae40aaa", - "0x2f40ab902af00b07092f00ab902aa00af9092a064075c8143a054b0495605", - "0x152c1257015720509300243602ae40abd5581c42125e81572055e8143a12", - "0x1540054a84824b902a700a94090f138075c81470054b049403803ae40a32", - "0x2b80ab902ab80ac1090140ab9028140a25092c40ab902ac40ab40926c0ab9", - "0x5258121e01572051e014fa121b01572051b01550124d81572054d8161012", - "0x142407092500b2e4b01572074b8165a124b901347f5c81478364dab80ab1", - "0x4824b902a400b3009119208f3fae40a9602cbc249502ae40a121484824b9", - "0x2e40a125584824b902a340a94092211a075c8151e054b04824b9029180a97", - "0x4906055c815084c251fe6212420157205092ac244c02ae40a12558489405", - "0x1c0a4a091000ab9029000a25092680ab902a680ab4092080ab902a200a95", - "0x1572054101610124181572054181664124a81572054a8155812038157205", - "0x166a7d02ae40e5302cd0245340940bab45c81504834a81c809a0a4cc2482", - "0x1e40b370904972053d01510123c9e80eb9029f40b360904972050901c247b", - "0x157205280144a122e81572052e81568123b01572053b81670123b8157205", - "0x142407091d902502ead00a7602ae40a7602ce4248102ae40a81029282450", - "0x48a0055c814a00512848ba055c814ba055a048ea055c814f6059d04824b9", - "0x4972050901c247540940bab4029d40ab9029d40b39092040ab902a040a4a", - "0x149412200157205200144a124d01572054d01568123a01572054a0167412", - "0x25024125c8142407091d00e404d2d00a7402ae40a7402ce4240702ae40a07", - "0x1c00ab9029c00a1d091c00ab9028488c123901572050901824125c8143a05", - "0x4e8246f02ae40a6e3501d6012350157205092c4246e02ae40a703901c4212", - "0x140e05250480a055c8140a051284814055c81414055a04800055c814de05", - "0x480e05090497205091d024000381414b4028000ab9028000b390901c0ab9", - "0x48ba1203015720503814fe12092e40a1203848321403cec1eb403ae40e05", - "0x142407090840b3c0e8800eb9038180a0f092d00ab902ad00ab4090497205", - "0x4814055c81562057284960055c81440053e84962055c8143a057204824b9", - "0x484e055c8144a05730484a055c81424790904972050901c24129e814247a", - "0x4852059f2bc0ab9038280ae7090280ab90289c0ae5092c00ab9028840a7d", - "0x2a80ab902ab00a81092b00ab902abc0a50090497205091d024125c8142407", - "0x2d0242f02ae40ab002a54242e02ae40aaa3f81c4212550157205550143a12", - "0x145c05540485e055c8145e05840481e055c8141e051284968055c8156805", - "0x4972050901c24a8192acfe05540c9567f5c8145c2f07ad16909090b80ab9", - "0x2f00ab902848f212092e40ab00285024125c81452054b84824b902848e812", - "0x9424b402ae40ab402ad0243602ae40abd02c3024bd02ae40abc3f81e1612", - "0x25024125c8142407090d81eb43f8146c055c8146c05868481e055c8141e05", - "0x4870055c814248d092b80ab9028480c12092e40a0702a2024125c814fe05", - "0x2700eb0092700ab90284962125001572051c2b80e21090e00ab9028e00a1d", - "0x2e40a1902894241402ae40a1402ad0249b02ae40a3c02c3c243c02ae40aa0", - "0x2e40a128984828055c81425110926c32143f81536055c8153605868483205", - "0x843a200305172050c81680120c81c0eb90281c0b3f090497205091d02412", - "0x2c40a7509049720510814ea12092e40a1d029d424125c81440057b84960b1", - "0x940ab902828fe071084814055c8140c054084824b902ac00a14090497205", - "0x155e053a8485e2e552b052af0a2e40a2702d0024270381d7205038167e12", - "0xbc0a1409049720517014ea12092e40aaa029d424125c81558053a84824b9", - "0x157205190940e21090c80ab902aac0af6092ac0ab9028a40af5090497205", - "0x2f40a75092714038570d97a145c8157805a0049780703ae40a0702cfc24a8", - "0x142812092e40aa0029d424125c81470053a84824b9028d80af7090497205", - "0x2e40a0702cfc240f02ae40a3c5401c42121e0157205570150212092e40a9c", - "0x1000af70904972054d014ea124aa512c972026828b902a6c0b400926c0e07", - "0x150212092e40a950285024125c81528053a84824b902a5c0a75090497205", - "0x1180b40091180e075c8140e059f84920055c8151eb403884248f02ae40a96", - "0x1280a7509049720544015ee12092e40a8d029d42483421309488468517205", - "0x84248202ae40a8402a0424125c81506050a04824b9029300a75090497205", - "0x49720528014ea123d1ecfa534094028b90281c0b40091740ab902a092007", - "0x2e40a7b029d424125c814fa053a84824b90294c0a7509049720540815ee12", - "0x48ec055c814ee0583848ee055c814f2057c848f27a03ae40a7a02be02412", - "0x1568123a01572053d0152a123a81572053b1740e21091d80ab9029d80a1d", - "0x2e40a7502aa0247402ae40a7402c20240502ae40a0502894241202ae40a12", - "0x153412371c0e47f5c814ea740284969090903c0ab90283c28078a848ea05", - "0x2fc0a97092fc00075c814d4052004824b9028480e1237816826a02ae40e6e", - "0x157205608168612608157205600001e7fa104980055c8142479090497205", - "0x1fc0acc02ae40acc02d10247002ae40a7002894247202ae40a7202ad024cc", - "0x156812668157205378168a12092e40a0f02a5024125c814240709330e072", - "0x499a70391fc0acd02ae40acd02d10247002ae40a7002894247202ae40a72", - "0x3e024125c8142407090800c07a306428075c81c0a120381424125c8142474", - "0x1582125881c0eb90281c0ac5090840ab9028740af9090741e075c8141e05", - "0x4824b9028480e12138940f48052c00eb90388562143fd1c242102ae40a21", - "0x2bc0ab902848f212092e40a7f02a2024125c8141e050a04824b9028280b30", - "0x4960055c81560055a04958055c8145205a504852055c8155e075a1fe9212", - "0x4824b9028480e1256065607f02ab00ab902ab00b4b090640ab9028640a25", - "0x1c0ac5090b80ab902aa80a7f092a8fe075c814fe05a604824b90289c0b30", - "0x53c24125c8142407092a00b4e192ac0eb9038bc5c253fd34242f0381d7205", - "0x157a050e8497a055c81578054084978055c81464052804864055c8146405", - "0x2b80ab902ab80ac1092b80ab90284988121b01572055ead00e21092f40ab9", - "0x142407090f13807a8a8070075c81d5c07559fea0121b01572051b0155012", - "0x4940055c81540056084832055c81432051284870055c81470055a04824b9", - "0xe0292c0903c0ab90283c0a7d090d80ab9028d80aa8091fc0ab9029fc0b08", - "0x1478059804824b9028480e1220269367f02901349b3fae40a0f1b1fd4019", - "0x1424060904972053f8151012092e40a3602a5024125c8141e050a04824b9", - "0x2500ab902a592e07108492c055c8152c050e8492c055c81425520925c0ab9", - "0x15681248015720547816a6124781572054a2540eb0092540ab9028496212", - "0x4920194e1fc0a9002ae40a9002d2c241902ae40a1902894249c02ae40a9c", - "0x4824b9029fc0a88090497205038166012092e40a0f0285024125c8142407", - "0x157205468143a1246815720509550244602ae40a120304824b902ad00a94", - "0x4898055c815104a03ac0244a02ae40a125884910055c8151a4603884248d", - "0x2100b4b090640ab9028640a25092a00ab902aa00ab4092100ab9029300b53", - "0x14fe054404824b90281c0b300904972050901c24840caa0fe05420157205", - "0x14248d0920c0ab9028480c12092e40a0f0285024125c81568054a04824b9", - "0x1400ab90284962122e81572054120c0e21092080ab902a080a1d092080ab9", - "0x94240602ae40a0602ad0245302ae40a8102d4c248102ae40a5d2801d6012", - "0x1424125c81424740914c40063f814a6055c814a605a584840055c8144005", - "0x843a7f5c8156805ab04824b9028480e12100180f550c8500eb9038142407", - "0x2c00a0f090500ab9028500ab40904972050917424b002ae40a0f029fc24b1", - "0x1414053e8495e055c8144a057204824b9028480e1213816ae250501d7207", - "0x1424790904972050901c2412ac014247a092b00ab902abc0ae5090a40ab9", - "0x2b00ab9028b80ae5090a40ab90289c0a7d090b80ab902aa80ae6092a80ab9", - "0x204243202ae40a2f0294024125c8142407092ac0b5917815720756015ce12", - "0x486c05ad2f578075c81c52050784950055c81550050e84950055c8146405", - "0x2e40aae02b94243802ae40abc029f424ae02ae40abd02b9024125c8142407", - "0x2e40a9c02b98249c02ae40a123c84824b9028480e120956c0a123d0494005", - "0x4936055c81470054a84940055c81478057284870055c8146c053e8487805", - "0x1534052804824b902848e812092e40a12038488005ae2680ab903a800ae7", - "0x1572054b0143a124a0157205540740f5d092580ab902a5c0a810925c0ab9", - "0x492a055c8152a050e84928055c81528050e8492a055c8152c2103d742496", - "0x151e0525049107f03ae40a7f02d7c248d232411eb45c81562954a01d695e", - "0x2340ab902a340a1d091180ab9029180a1d092400ab902a400a1d0923c0ab9", - "0x2348c903fcc424125c81424070920d0807b013094075c81d10190a1fd5412", - "0x157205478149412260157205260144a12250157205250156812410157205", - "0x4cc249b02ae40a9b02c20248202ae40a8202cc8247f02ae40a7f02ab0248f", - "0x4824b9028480e1229a04a05d5a014a6812817568b902a6d047f479309414", - "0x49720523014ea12092e40a7f02d8424125c81520053a84824b902a6c0a88", - "0x2e40a7b02874247b02ae40a1246848fa055c814240609049720546814ea12", - "0x1dc0ab9029e8f20758048f2055c81424b1091e80ab9029ecfa0710848f605", - "0x149412418157205418144a124201572054201568123b01572053b816c412", - "0x1d024125c8142407091d91e83422d00a7602ae40a7602d8c248f02ae40a8f", - "0x1d40ab902aa03a07ae84824b9029fc0b61090497205200152e12092e40a12", - "0x143a123a81572053a8143a123901572053a0840f5d091d00ab90284ac812", - "0x4824b9029a80a75091bcd46e382d17205589c8ea075a578247202ae40a72", - "0x500ab4092fc0ab9028000ac2090000ab9029b93607b284824b9029bc0a75", - "0x1572055f816c6123801572053801494120c81572050c8144a120a0157205", - "0x4824b902aac0a97090497205091d024125c8142407092fce0190a2d00abf", - "0x1582050e84982055c815801d03d7424c002ae40a12b204824b9029fc0b61", - "0x14ea12092e40acf029d424be67b3598b45c81562216081d695e093040ab9", - "0x2e40ad302b0824d302ae40acd6901eca12690157205148152a12092e40abe", - "0x4998055c81598052504832055c81432051284828055c81428055a049aa05", - "0x4824b90283c0a880904972050901c24d56606428b402b540ab902b540b63", - "0x3600ab9028491a126b01572050901824125c8156805b304824b9029fc0b61", - "0x1d60126e0157205092c424d902ae40ad86b01c42126c01572056c0143a12", - "0x144005128480c055c8140c055a049bc055c815ba05b1049ba055c815b2dc", - "0x2d162de038800cb402b780ab902b780b630901c0ab90281c0a4a090800ab9", - "0x48dc70378d8240f0c9c0de360903c247f03814246e381bc24b40c9c0de12", - "0x496819381bc24b4b39fc0e05091b8e06f092d032703784969095a1fc0e05", - "0x2d2d2b43f81c0a12371c0de360903c3270378d8240fb41fc0e05091b8e06f", - "0x142484380d8de1207928e036378481f6a3f81c0a12409bc247f079f4de12", - "0x1bc247f07864de125a5b0fe0702849403637849684a1b1bc24b4b5ad0fe07", - "0x64146f09052dcb43f81c0a12561bc247f0783d566f0903eda7f038142481", - "0x1424b11b1bc24b40cac0e43637848296f07ad0fe07028495e6f091fc280f", - "0x17007ad0fe07" - ], - "sierra_program_debug_info": { - "type_names": [ - [0, "RangeCheck"], - [1, "Const"], - [2, "Const"], - [3, "Const"], - [4, "Const"], - [5, "Array"], - [6, "Snapshot>"], - [7, "core::array::Span::"], - [8, "felt252"], - [9, "Tuple, felt252>"], - [10, "core::panics::Panic"], - [11, "Tuple>"], - [ - 12, - "core::panics::PanicResult::<(core::array::Span::, core::felt252)>" - ], - [13, "Tuple"], - [14, "u32"], - [15, "Unit"], - [16, "Tuple, u32, Unit>"], - [ - 17, - "core::panics::PanicResult::<(core::array::Array::, core::integer::u32, ())>" - ], - [18, "Tuple, Array, Unit>"], - [ - 19, - "core::panics::PanicResult::<(core::array::Array::, core::array::Array::, ())>" - ], - [ - 20, - "Const" - ], - [21, "ContractAddress"], - [22, "temp_cairo::messaging::MessagingContract::MessageSent"], - [23, "Snapshot"], - [24, "temp_cairo::messaging::MessagingContract::Event"], - [25, "Snapshot"], - [26, "Uninitialized"], - [27, "Uninitialized>"], - [28, "Poseidon"], - [29, "Uninitialized"], - [30, "Tuple"], - [31, "core::panics::PanicResult::<(core::felt252,)>"], - [32, "core::bool"], - [33, "Box"], - [34, "core::option::Option::>"], - [ - 35, - "Const" - ], - [36, "u128"], - [37, "core::integer::u256"], - [38, "Const"], - [39, "Const"], - [40, "NonZero"], - [41, "Const"], - [42, "StorageAddress"], - [43, "StorageBaseAddress"], - [44, "core::starknet::storage::StoragePointer0Offset::"], - [45, "core::option::Option::"], - [46, "temp_cairo::messaging::MessagingContract::ContractState"], - [ - 47, - "Tuple" - ], - [ - 48, - "core::panics::PanicResult::<(temp_cairo::messaging::MessagingContract::ContractState, ())>" - ], - [49, "Const"], - [ - 50, - "Const" - ], - [51, "Tuple>"], - [52, "Tuple, Unit>"], - [ - 53, - "core::panics::PanicResult::<(core::array::Array::, ())>" - ], - [54, "temp_cairo::messaging::MessageData"], - [55, "Snapshot"], - [56, "Const"], - [ - 57, - "Const" - ], - [ - 58, - "Const" - ], - [ - 59, - "Const" - ], - [60, "Const"], - [61, "Const"], - [ - 62, - "Const" - ], - [63, "BuiltinCosts"], - [64, "System"], - [ - 65, - "core::panics::PanicResult::<(core::array::Span::,)>" - ], - [ - 66, - "Const" - ], - [67, "GasBuiltin"] - ], - "libfunc_names": [ - [0, "revoke_ap_tracking"], - [1, "withdraw_gas"], - [2, "branch_align"], - [3, "struct_deconstruct>"], - [4, "store_temp"], - [5, "array_snapshot_pop_front"], - [6, "drop>>"], - [7, "drop>"], - [8, "array_new"], - [ - 9, - "const_as_immediate>" - ], - [10, "store_temp"], - [11, "array_append"], - [12, "struct_construct"], - [13, "struct_construct>>"], - [ - 14, - "enum_init,)>, 1>" - ], - [15, "store_temp"], - [16, "store_temp"], - [ - 17, - "store_temp,)>>" - ], - [18, "get_builtin_costs"], - [19, "store_temp"], - [20, "withdraw_gas_all"], - [ - 21, - "const_as_immediate>" - ], - [22, "const_as_immediate>"], - [23, "const_as_immediate>"], - [ - 24, - "const_as_immediate>" - ], - [25, "store_temp>"], - [26, "contract_address_try_from_felt252"], - [ - 27, - "const_as_immediate>" - ], - [ - 28, - "const_as_immediate>" - ], - [29, "const_as_immediate>"], - [30, "struct_construct"], - [31, "snapshot_take"], - [32, "drop"], - [33, "store_temp>"], - [ - 34, - "function_call" - ], - [ - 35, - "enum_match, ())>>" - ], - [36, "struct_deconstruct, Unit>>"], - [37, "drop"], - [38, "snapshot_take>"], - [39, "drop>"], - [40, "struct_construct>"], - [41, "struct_construct>>"], - [ - 42, - "enum_init,)>, 0>" - ], - [ - 43, - "const_as_immediate>" - ], - [44, "const_as_immediate>"], - [45, "drop>"], - [46, "store_temp"], - [ - 47, - "struct_construct" - ], - [ - 48, - "function_call" - ], - [ - 49, - "enum_match>" - ], - [ - 50, - "drop>" - ], - [51, "enable_ap_tracking"], - [52, "unbox"], - [53, "rename"], - [54, "enum_init, 0>"], - [55, "store_temp>>"], - [56, "store_temp>"], - [57, "jump"], - [58, "struct_construct"], - [59, "enum_init, 1>"], - [60, "enum_match>"], - [61, "drop"], - [62, "disable_ap_tracking"], - [ - 63, - "storage_base_address_const<87132271245367979733157522781602464771675853065476568805507240456934415481>" - ], - [ - 64, - "struct_construct>" - ], - [ - 65, - "snapshot_take>" - ], - [ - 66, - "drop>" - ], - [ - 67, - "struct_deconstruct>" - ], - [68, "rename"], - [69, "storage_address_from_base"], - [70, "const_as_immediate>"], - [71, "store_temp"], - [72, "store_temp"], - [73, "storage_read_syscall"], - [74, "felt252_is_zero"], - [75, "u128s_from_felt252"], - [76, "const_as_immediate>"], - [77, "store_temp"], - [78, "rename"], - [79, "rename"], - [80, "drop>"], - [81, "const_as_immediate>"], - [82, "struct_construct"], - [83, "snapshot_take"], - [84, "drop"], - [85, "store_temp"], - [86, "dup"], - [87, "struct_deconstruct"], - [88, "drop"], - [89, "u128_to_felt252"], - [ - 90, - "const_as_immediate>" - ], - [ - 91, - "enum_init>, 0>" - ], - [ - 92, - "store_temp>>" - ], - [ - 93, - "enum_init>, 1>" - ], - [ - 94, - "enum_match>>" - ], - [95, "enum_init"], - [96, "store_temp"], - [97, "enum_init"], - [98, "drop"], - [99, "bool_not_impl"], - [100, "bool_to_felt252"], - [101, "storage_write_syscall"], - [ - 102, - "snapshot_take" - ], - [103, "drop"], - [ - 104, - "function_call" - ], - [105, "enum_match>"], - [106, "struct_deconstruct>"], - [107, "dup>"], - [108, "struct_snapshot_deconstruct"], - [109, "rename"], - [110, "contract_address_to_felt252"], - [111, "drop"], - [112, "dup>>"], - [113, "array_len"], - [114, "u32_to_felt252"], - [115, "store_temp>"], - [ - 116, - "function_call>" - ], - [117, "struct_construct, Unit>>"], - [ - 118, - "enum_init, ())>, 0>" - ], - [ - 119, - "store_temp, ())>>" - ], - [120, "drop>"], - [ - 121, - "enum_init, ())>, 1>" - ], - [122, "alloc_local"], - [123, "alloc_local>"], - [124, "alloc_local"], - [125, "finalize_locals"], - [126, "store_local"], - [127, "store_local>"], - [128, "store_local"], - [ - 129, - "struct_construct" - ], - [130, "enum_init"], - [131, "snapshot_take"], - [132, "drop"], - [ - 133, - "store_temp>" - ], - [ - 134, - "enum_snapshot_match" - ], - [ - 135, - "const_as_immediate>" - ], - [ - 136, - "store_temp>" - ], - [ - 137, - "function_call" - ], - [ - 138, - "enum_match, core::array::Array::, ())>>" - ], - [139, "struct_deconstruct, Array, Unit>>"], - [140, "emit_event_syscall"], - [ - 141, - "struct_construct>" - ], - [ - 142, - "enum_init, 0>" - ], - [ - 143, - "store_temp>" - ], - [ - 144, - "enum_init, 1>" - ], - [145, "drop>"], - [ - 146, - "function_call" - ], - [ - 147, - "enum_match, core::integer::u32, ())>>" - ], - [148, "struct_deconstruct, u32, Unit>>"], - [149, "drop"], - [150, "struct_construct>"], - [151, "store_temp>"], - [152, "function_call"], - [ - 153, - "enum_match, core::felt252)>>" - ], - [ - 154, - "struct_deconstruct, felt252>>" - ], - [155, "struct_construct>"], - [156, "enum_init, 0>"], - [157, "store_temp>"], - [158, "enum_init, 1>"], - [ - 159, - "dup>" - ], - [ - 160, - "struct_snapshot_deconstruct" - ], - [161, "struct_construct, Array, Unit>>"], - [ - 162, - "enum_init, core::array::Array::, ())>, 0>" - ], - [ - 163, - "store_temp, core::array::Array::, ())>>" - ], - [ - 164, - "enum_init, core::array::Array::, ())>, 1>" - ], - [165, "dup"], - [166, "u32_overflowing_sub"], - [167, "struct_construct, u32, Unit>>"], - [ - 168, - "enum_init, core::integer::u32, ())>, 0>" - ], - [ - 169, - "store_temp, core::integer::u32, ())>>" - ], - [170, "dup>"], - [171, "array_get"], - [172, "store_temp>"], - [173, "const_as_immediate>"], - [174, "u32_overflowing_add"], - [ - 175, - "const_as_immediate>" - ], - [ - 176, - "enum_init, core::integer::u32, ())>, 1>" - ], - [ - 177, - "const_as_immediate>" - ], - [178, "struct_deconstruct>"], - [179, "felt252_add"], - [180, "hades_permutation"], - [181, "dup"], - [182, "drop"], - [ - 183, - "enum_init, core::felt252)>, 1>" - ], - [ - 184, - "store_temp, core::felt252)>>" - ], - [185, "const_as_immediate>"], - [ - 186, - "struct_construct, felt252>>" - ], - [ - 187, - "enum_init, core::felt252)>, 0>" - ], - [188, "drop>"] - ], - "user_func_names": [ - [ - 0, - "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__get_message_data" - ], - [ - 1, - "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__fire_event" - ], - [ - 2, - "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__l1_to_l2_message_cancellations" - ], - [ - 3, - "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__set_is_canceled" - ], - [ - 4, - "temp_cairo::messaging::MessagingContract::__wrapper__MessagingContract__get_l1_to_l2_msg_hash" - ], - [5, "temp_cairo::messaging::MessageDataSerde::serialize"], - [ - 6, - "temp_cairo::messaging::MessagingContract::MessagingContract::fire_event" - ], - [ - 7, - "temp_cairo::messaging::MessagingContract::MessagingContract::get_l1_to_l2_msg_hash" - ], - [ - 8, - "core::array::serialize_array_helper::" - ], - [ - 9, - "temp_cairo::messaging::MessagingContract::MessageSentIsEvent::append_keys_and_data" - ], - [ - 10, - "temp_cairo::messaging::MessagingContract::MessagingContract::get_l1_to_l2_msg_hash[expr55]" - ], - [11, "core::poseidon::_poseidon_hash_span_inner"] - ] - }, - "contract_class_version": "0.1.0", - "entry_points_by_type": { - "EXTERNAL": [ - { - "selector": "0x5de93e1525070ad9e62807a8b7eebf3c7fd7c60dd0a0ec728f9aa3b7c4146b", - "function_idx": 4 - }, - { - "selector": "0x148fcde222e93109b646c02f8ed9babeb4fc5dd31b9de5026add8c3601acf9a", - "function_idx": 1 - }, - { - "selector": "0x15811ea1dff18014ea6dad7ab86b6ae25e45829c0f8c717c9748a3208e4770e", - "function_idx": 2 - }, - { - "selector": "0x21d33b226af0ea4fb717e4f9bff77bd7becd28c61f5bb8a3e3d6c7db1f0f4d8", - "function_idx": 3 - }, - { - "selector": "0x3f9333bdab22b77e223157f7ef4f4b91598f4fac1ff161d34e59f646a54482c", - "function_idx": 0 - } - ], - "L1_HANDLER": [], - "CONSTRUCTOR": [] - }, - "abi": [ - { - "type": "impl", - "name": "MessagingContract", - "interface_name": "temp_cairo::messaging::IMessagingContract" - }, - { - "type": "struct", - "name": "temp_cairo::messaging::MessageData", - "members": [ - { - "name": "from_address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { "name": "to_address", "type": "core::felt252" }, - { "name": "selector", "type": "core::felt252" }, - { "name": "payload", "type": "core::array::Array::" }, - { "name": "nonce", "type": "core::felt252" } - ] - }, - { - "type": "struct", - "name": "core::integer::u256", - "members": [ - { "name": "low", "type": "core::integer::u128" }, - { "name": "high", "type": "core::integer::u128" } - ] - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { "name": "False", "type": "()" }, - { "name": "True", "type": "()" } - ] - }, - { - "type": "interface", - "name": "temp_cairo::messaging::IMessagingContract", - "items": [ - { - "type": "function", - "name": "get_message_data", - "inputs": [], - "outputs": [{ "type": "temp_cairo::messaging::MessageData" }], - "state_mutability": "view" - }, - { - "type": "function", - "name": "fire_event", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "l1_to_l2_message_cancellations", - "inputs": [{ "name": "msg_hash", "type": "core::felt252" }], - "outputs": [{ "type": "core::integer::u256" }], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_is_canceled", - "inputs": [{ "name": "value", "type": "core::bool" }], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_l1_to_l2_msg_hash", - "inputs": [], - "outputs": [{ "type": "core::felt252" }], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "temp_cairo::messaging::MessagingContract::MessageSent", - "kind": "struct", - "members": [ - { "name": "message_hash", "type": "core::felt252", "kind": "key" }, - { - "name": "from_address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "key" - }, - { "name": "to_address", "type": "core::felt252", "kind": "key" }, - { "name": "selector", "type": "core::felt252", "kind": "data" }, - { "name": "nonce", "type": "core::felt252", "kind": "data" }, - { - "name": "payload", - "type": "core::array::Array::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "temp_cairo::messaging::MessagingContract::Event", - "kind": "enum", - "variants": [ - { - "name": "MessageSent", - "type": "temp_cairo::messaging::MessagingContract::MessageSent", - "kind": "nested" - } - ] - } - ] -} diff --git a/crates/madara/client/settlement_client/src/starknet/utils.rs b/crates/madara/client/settlement_client/src/starknet/utils.rs index 9a176f1c4..efe37a603 100644 --- a/crates/madara/client/settlement_client/src/starknet/utils.rs +++ b/crates/madara/client/settlement_client/src/starknet/utils.rs @@ -16,6 +16,7 @@ use std::str::FromStr; use std::sync::Arc; use std::thread; +use m_cairo_test_contracts::{APPCHAIN_CONTRACT_SIERRA, MESSAGING_CONTRACT_SIERRA}; use std::time::Duration; use url::Url; @@ -23,10 +24,8 @@ pub const DEPLOYER_ADDRESS: &str = "0x055be462e718c4166d656d11f89e341115b8bc8238 pub const DEPLOYER_PRIVATE_KEY: &str = "0x077e56c6dc32d40a67f6f7e6625c8dc5e570abe49c0a24e9202e4ae906abcc07"; pub const UDC_ADDRESS: &str = "0x041a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf"; pub const MADARA_PORT: &str = "19944"; -pub const MADARA_BINARY_PATH: &str = "../../../test-artifacts/madara"; -pub const MADARA_CONFIG_PATH: &str = "../../../configs/presets/devnet.yaml"; -pub const APPCHAIN_CONTRACT_SIERRA_PATH: &str = "src/starknet/test_contracts/appchain_test.sierra.json"; -pub const MESSAGING_CONTRACT_SIERRA_PATH: &str = "src/starknet/test_contracts/messaging_test.sierra.json"; +pub const MADARA_BINARY_PATH: &str = "../../../../test-artifacts/madara"; +pub const MADARA_CONFIG_PATH: &str = "../../../../configs/presets/devnet.yaml"; // starkli class-hash crates/client/settlement_client/src/starknet/test_contracts/appchain_test.casm.json pub const APPCHAIN_CONTRACT_CASM_HASH: &str = "0x07f36e830605ddeb7c4c094639b628de297cbf61f45385b1fc3231029922b30b"; @@ -87,7 +86,7 @@ pub async fn prepare_starknet_client_test() -> anyhow::Result<(StarknetAccount, let madara = MadaraProcess::new(PathBuf::from(MADARA_BINARY_PATH))?; let account = starknet_account()?; let deployed_appchain_contract_address = - deploy_contract(&account, APPCHAIN_CONTRACT_SIERRA_PATH, APPCHAIN_CONTRACT_CASM_HASH).await?; + deploy_contract(&account, APPCHAIN_CONTRACT_SIERRA, APPCHAIN_CONTRACT_CASM_HASH).await?; Ok((account, deployed_appchain_contract_address, madara)) } @@ -95,7 +94,7 @@ pub async fn prepare_starknet_client_messaging_test() -> anyhow::Result<(Starkne let madara = MadaraProcess::new(PathBuf::from(MADARA_BINARY_PATH))?; let account = starknet_account()?; let deployed_appchain_contract_address = - deploy_contract(&account, MESSAGING_CONTRACT_SIERRA_PATH, MESSAGING_CONTRACT_CASM_HASH).await?; + deploy_contract(&account, MESSAGING_CONTRACT_SIERRA, MESSAGING_CONTRACT_CASM_HASH).await?; Ok((account, deployed_appchain_contract_address, madara)) } @@ -176,8 +175,8 @@ pub fn starknet_account() -> anyhow::Result { Ok(account) } -pub async fn deploy_contract(account: &StarknetAccount, sierra_path: &str, casm_hash: &str) -> anyhow::Result { - let contract_artifact: SierraClass = serde_json::from_reader(std::fs::File::open(sierra_path)?)?; +pub async fn deploy_contract(account: &StarknetAccount, sierra: &[u8], casm_hash: &str) -> anyhow::Result { + let contract_artifact: SierraClass = serde_json::from_slice(sierra)?; let flattened_class = contract_artifact.flatten()?; let result = account.declare_v2(Arc::new(flattened_class), Felt::from_str(casm_hash)?).send().await?; tokio::time::sleep(Duration::from_secs(5)).await; diff --git a/crates/madara/client/settlement_client/src/state_update.rs b/crates/madara/client/settlement_client/src/state_update.rs index 02fa7cf7b..ece528854 100644 --- a/crates/madara/client/settlement_client/src/state_update.rs +++ b/crates/madara/client/settlement_client/src/state_update.rs @@ -62,201 +62,3 @@ where settlement_client.listen_for_update_state_events(backend, ctx, l1_block_metrics.clone()).await?; anyhow::Ok(()) } - -#[cfg(test)] -mod eth_client_event_subscription_test { - use super::*; - use std::{sync::Arc, time::Duration}; - - use crate::eth::event::EthereumEventStream; - use crate::eth::{EthereumClient, EthereumClientConfig, StarknetCoreContract}; - use alloy::{node_bindings::Anvil, providers::ProviderBuilder, sol}; - use mc_db::DatabaseService; - use mp_chain_config::ChainConfig; - use rstest::*; - use tempfile::TempDir; - use url::Url; - - sol!( - #[sol(rpc, bytecode="6080604052348015600e575f80fd5b506101618061001c5f395ff3fe608060405234801561000f575f80fd5b5060043610610029575f3560e01c80634185df151461002d575b5f80fd5b610035610037565b005b5f7f0639349b21e886487cd6b341de2050db8ab202d9c6b0e7a2666d598e5fcf81a690505f620a1caf90505f7f0279b69383ea92624c1ae4378ac7fae6428f47bbd21047ea0290c3653064188590507fd342ddf7a308dec111745b00315c14b7efb2bdae570a6856e088ed0c65a3576c8383836040516100b9939291906100f6565b60405180910390a1505050565b5f819050919050565b6100d8816100c6565b82525050565b5f819050919050565b6100f0816100de565b82525050565b5f6060820190506101095f8301866100cf565b61011660208301856100e7565b61012360408301846100cf565b94935050505056fea2646970667358221220fbc6fd165c86ed9af0c5fcab2830d4a72894fd6a98e9c16dbf9101c4c22e2f7d64736f6c634300081a0033")] - contract DummyContract { - event LogStateUpdate(uint256 globalRoot, int256 blockNumber, uint256 blockHash); - - function fireEvent() public { - uint256 globalRoot = 2814950447364693428789615812443623689251959344851195711990387747563915674022; - int256 blockNumber = 662703; - uint256 blockHash = 1119674286844400689540394420005977072742999649767515920196535047615668295813; - - emit LogStateUpdate(globalRoot, blockNumber, blockHash); - } - } - ); - - const L2_BLOCK_NUMBER: u64 = 662703; - const ANOTHER_ANVIL_PORT: u16 = 8548; - const EVENT_PROCESSING_TIME: u64 = 2; // Time to allow for event processing in seconds - - /// Test the event subscription and state update functionality - /// - /// This test performs the following steps: - /// 1. Sets up a mock Ethereum environment using Anvil - /// 2. Initializes necessary services (Database, Metrics) - /// 3. Deploys a dummy contract and sets up an Ethereum client - /// 4. Starts listening for state updates - /// 5. Fires an event from the dummy contract - /// 6. Waits for event processing and verifies the block number - #[rstest] - #[tokio::test] - async fn listen_and_update_state_when_event_fired_works() { - // Start Anvil instance - let anvil = Anvil::new() - .block_time(1) - .chain_id(1337) - .port(ANOTHER_ANVIL_PORT) - .try_spawn() - .expect("failed to spawn anvil instance"); - println!("Anvil started and running at `{}`", anvil.endpoint()); - - // Set up chain info - let chain_info = Arc::new(ChainConfig::madara_test()); - - // Set up database paths - let temp_dir = TempDir::new().expect("issue while creating temporary directory"); - let base_path = temp_dir.path().join("data"); - let backup_dir = Some(temp_dir.path().join("backups")); - - // Initialize database service - let db = Arc::new( - DatabaseService::new(&base_path, backup_dir, false, chain_info.clone(), Default::default()) - .await - .expect("Failed to create database service"), - ); - - let rpc_url: Url = anvil.endpoint().parse().expect("issue while parsing"); - let provider = ProviderBuilder::new().on_http(rpc_url); - - let contract = DummyContract::deploy(provider.clone()).await.unwrap(); - let core_contract = StarknetCoreContract::new(*contract.address(), provider.clone()); - - let eth_client = EthereumClient { provider: Arc::new(provider), l1_core_contract: core_contract.clone() }; - let l1_block_metrics = L1BlockMetrics::register().unwrap(); - - // Start listening for state updates - let listen_handle = { - let db = Arc::clone(&db); - tokio::spawn(async move { - state_update_worker::( - Arc::clone(db.backend()), - Arc::new(Box::new(eth_client)), - ServiceContext::new_for_testing(), - Arc::new(l1_block_metrics), - ) - .await - .unwrap() - }) - }; - - let _ = contract.fireEvent().send().await.expect("Failed to fire event"); - - // Wait for event processing - tokio::time::sleep(Duration::from_secs(EVENT_PROCESSING_TIME)).await; - - // Verify the block number - let block_in_db = - db.backend().get_l1_last_confirmed_block().expect("Failed to get L1 last confirmed block number"); - - // Explicitly cancel the listen task, else it would be running in the background - listen_handle.abort(); - assert_eq!(block_in_db, Some(L2_BLOCK_NUMBER), "Block in DB does not match expected L2 block number"); - } -} - -#[cfg(test)] -mod starknet_client_event_subscription_test { - use crate::client::ClientTrait; - use crate::gas_price::L1BlockMetrics; - use crate::starknet::event::StarknetEventStream; - use crate::starknet::utils::{prepare_starknet_client_test, send_state_update, MADARA_PORT}; - use crate::starknet::{StarknetClient, StarknetClientConfig}; - use crate::state_update::{state_update_worker, StateUpdate}; - use mc_db::DatabaseService; - use mp_chain_config::ChainConfig; - use mp_utils::service::ServiceContext; - use rstest::rstest; - use starknet_types_core::felt::Felt; - use std::str::FromStr; - use std::sync::Arc; - use std::time::Duration; - use tempfile::TempDir; - use url::Url; - - #[rstest] - #[tokio::test] - async fn listen_and_update_state_when_event_fired_starknet_client() -> anyhow::Result<()> { - // Setting up the DB and l1 block metrics - // ================================================ - - let chain_info = Arc::new(ChainConfig::madara_test()); - - // Set up database paths - let temp_dir = TempDir::new().expect("issue while creating temporary directory"); - let base_path = temp_dir.path().join("data"); - let backup_dir = Some(temp_dir.path().join("backups")); - - // Initialize database service - let db = Arc::new( - DatabaseService::new(&base_path, backup_dir, false, chain_info.clone(), Default::default()) - .await - .expect("Failed to create database service"), - ); - - // Making Starknet client and start worker - // ================================================ - let (account, deployed_address, _madara) = prepare_starknet_client_test().await?; - - let starknet_client = StarknetClient::new(StarknetClientConfig { - url: Url::parse(format!("http://127.0.0.1:{}", MADARA_PORT).as_str())?, - l2_contract_address: deployed_address, - }) - .await?; - - let l1_block_metrics = L1BlockMetrics::register()?; - - let listen_handle = { - let db = Arc::clone(&db); - tokio::spawn(async move { - state_update_worker::( - Arc::clone(db.backend()), - Arc::new(Box::new(starknet_client)), - ServiceContext::new_for_testing(), - Arc::new(l1_block_metrics), - ) - .await - .expect("Failed to init state update worker.") - }) - }; - - // Firing the state update event - send_state_update( - &account, - deployed_address, - StateUpdate { - block_number: 100, - global_root: Felt::from_str("0xbeef")?, - block_hash: Felt::from_str("0xbeef")?, - }, - ) - .await?; - - // Wait for this update to be registered in the DB. Approx 10 secs - tokio::time::sleep(Duration::from_secs(10)).await; - - // Verify the block number - let block_in_db = - db.backend().get_l1_last_confirmed_block().expect("Failed to get L2 last confirmed block number"); - - listen_handle.abort(); - assert_eq!(block_in_db, Some(100), "Block in DB does not match expected L3 block number"); - Ok(()) - } -} diff --git a/crates/madara/node/src/service/l1.rs b/crates/madara/node/src/service/l1.rs index 77e090c51..84487d34c 100644 --- a/crates/madara/node/src/service/l1.rs +++ b/crates/madara/node/src/service/l1.rs @@ -157,6 +157,8 @@ where } // Factory method to create the appropriate service + // Add the if condition here : + // should_enable_sync pub async fn create(config: &L1SyncParams, sync_config: L1SyncConfig<'_>) -> anyhow::Result> { match config.settlement_layer { MadaraSettlementLayer::Eth => Ok(Box::new(EthereumSyncService::new(config, sync_config).await?)), From 79ef5abc43588f272139d5c5be65ea81300b2dd2 Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Tue, 21 Jan 2025 17:21:58 +0530 Subject: [PATCH 22/23] refactor --- Cargo.lock | 33 ++++++++++++++----- Cargo.toml | 1 + .../client/settlement_client/Cargo.toml | 1 + .../client/settlement_client/src/messaging.rs | 2 +- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 37d6277b4..691d3a830 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -650,6 +650,12 @@ version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +[[package]] +name = "arbitrary" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" + [[package]] name = "ark-ec" version = "0.4.2" @@ -5774,6 +5780,7 @@ dependencies = [ "opentelemetry_sdk", "proptest", "proptest-derive", + "proptest-state-machine", "reqwest 0.12.8", "rstest 0.18.2", "serde", @@ -7038,6 +7045,15 @@ dependencies = [ "syn 2.0.89", ] +[[package]] +name = "proptest-state-machine" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e943d140e09d07740fb496487c51fb8eb31c70389ac4a2e9dcd8a0d9fdf228d4" +dependencies = [ + "proptest", +] + [[package]] name = "prost" version = "0.13.3" @@ -7743,9 +7759,9 @@ dependencies = [ [[package]] name = "scc" -version = "2.2.4" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8d25269dd3a12467afe2e510f69fb0b46b698e5afb296b59f2145259deaf8e8" +checksum = "28e1c91382686d21b5ac7959341fcb9780fa7c03773646995a87c950fa7be640" dependencies = [ "sdd", ] @@ -7814,9 +7830,9 @@ dependencies = [ [[package]] name = "sdd" -version = "3.0.4" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49c1eeaf4b6a87c7479688c6d52b9f1153cedd3c489300564f932b065c6eab95" +checksum = "478f121bb72bbf63c52c93011ea1791dca40140dfe13f8336c4c5ac952c33aa9" [[package]] name = "sec1" @@ -8018,9 +8034,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b4b487fe2acf240a021cf57c6b2b4903b1e78ca0ecd862a71b71d2a51fed77d" +checksum = "1b258109f244e1d6891bf1053a55d63a5cd4f8f4c30cf9a1280989f80e7a1fa9" dependencies = [ "futures", "log", @@ -8032,9 +8048,9 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "3.1.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" +checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", @@ -8497,6 +8513,7 @@ name = "starknet-types-core" version = "0.1.7" source = "git+https://github.com/kasarlabs/types-rs.git?branch=feat-deserialize-v0.1.7#e5f3769150684d3c726951dd3f075815cdcdba5d" dependencies = [ + "arbitrary", "lambdaworks-crypto", "lambdaworks-math", "lazy_static", diff --git a/Cargo.toml b/Cargo.toml index a1e18887a..706301904 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -220,6 +220,7 @@ dotenv = "0.15.0" httpmock = "0.7.0" tempfile = "3.10.1" mockall = "0.13.0" +serial_test = "3.1.1" itertools = "0.13.0" regex = "1.10.5" bytes = "1.6.0" diff --git a/crates/madara/client/settlement_client/Cargo.toml b/crates/madara/client/settlement_client/Cargo.toml index 010d5c151..7590c89de 100644 --- a/crates/madara/client/settlement_client/Cargo.toml +++ b/crates/madara/client/settlement_client/Cargo.toml @@ -91,6 +91,7 @@ once_cell.workspace = true tempfile.workspace = true dotenv.workspace = true httpmock.workspace = true +serial_test.workspace = true tracing-test = "0.2.5" lazy_static.workspace = true mp-utils = { workspace = true, features = ["testing"] } diff --git a/crates/madara/client/settlement_client/src/messaging.rs b/crates/madara/client/settlement_client/src/messaging.rs index c730e0ad9..ec991f4dd 100644 --- a/crates/madara/client/settlement_client/src/messaging.rs +++ b/crates/madara/client/settlement_client/src/messaging.rs @@ -167,7 +167,7 @@ async fn process_message( } }; - let res = mempool.accept_l1_handler_tx(transaction.into(), fees.unwrap_or(0))?; + let res = mempool.tx_accept_l1_handler(transaction.into(), fees.unwrap_or(0))?; Ok(Some(res.transaction_hash)) } From 8657da3cf2e036981df7fddceb5c3a55f4ec965b Mon Sep 17 00:00:00 2001 From: Arun Jangra Date: Wed, 22 Jan 2025 10:34:21 +0530 Subject: [PATCH 23/23] refactor code and comments resolved --- .../settlement_client/src/starknet/event.rs | 4 +-- .../settlement_client/src/starknet/mod.rs | 27 ++++++++++--------- crates/madara/node/src/service/l1.rs | 20 +++++++------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/crates/madara/client/settlement_client/src/starknet/event.rs b/crates/madara/client/settlement_client/src/starknet/event.rs index 4d8173bb1..1a0230399 100644 --- a/crates/madara/client/settlement_client/src/starknet/event.rs +++ b/crates/madara/client/settlement_client/src/starknet/event.rs @@ -1,6 +1,6 @@ use crate::messaging::CommonMessagingEventData; use futures::Stream; -use log::warn; +use log::error; use starknet_core::types::{BlockId, EmittedEvent, EventFilter}; use starknet_providers::jsonrpc::HttpTransport; use starknet_providers::{JsonRpcClient, Provider}; @@ -148,7 +148,7 @@ impl Stream for StarknetEventStream { // Following scenarios can lead to this: // - Not able to call the RPC and fetch events. // - Connection Issues. - warn!("Starknet Event Stream : Unable to fetch events from starknet stream. Restart Sequencer."); + error!("Starknet Event Stream : Unable to fetch events from starknet stream. Restart Sequencer."); Poll::Ready(Some(None)) } } diff --git a/crates/madara/client/settlement_client/src/starknet/mod.rs b/crates/madara/client/settlement_client/src/starknet/mod.rs index 12298c325..5361272d7 100644 --- a/crates/madara/client/settlement_client/src/starknet/mod.rs +++ b/crates/madara/client/settlement_client/src/starknet/mod.rs @@ -151,18 +151,21 @@ impl ClientTrait for StarknetClient { mut ctx: ServiceContext, l1_block_metrics: Arc, ) -> anyhow::Result<()> { - let latest_block = self.get_latest_block_number().await?; - let selector = get_selector_from_name("LogStateUpdate")?; - let events_fetch = move || async move { - self.get_events( - BlockId::Number(latest_block), - BlockId::Number(latest_block), - self.l2_core_contract, - vec![selector], - ) - }; - - while let Some(events) = ctx.run_until_cancelled(events_fetch().await).await { + while let Some(events) = ctx + .run_until_cancelled(async { + let latest_block = self.get_latest_block_number().await?; + let selector = get_selector_from_name("LogStateUpdate")?; + + self.get_events( + BlockId::Number(latest_block), + BlockId::Number(latest_block), + self.l2_core_contract, + vec![selector], + ) + .await + }) + .await + { let events_fetched = events?; if let Some(event) = events_fetched.last() { let data = event; diff --git a/crates/madara/node/src/service/l1.rs b/crates/madara/node/src/service/l1.rs index 84487d34c..9a449771c 100644 --- a/crates/madara/node/src/service/l1.rs +++ b/crates/madara/node/src/service/l1.rs @@ -57,7 +57,7 @@ pub type StarknetSyncService = L1SyncService) -> anyhow::Result { - let settlement_client = if sync_config.should_enable_sync(config) { + let settlement_client = { if let Some(l1_rpc_url) = &config.l1_endpoint { let core_address = Address::from_str(sync_config.l1_core_address.as_str())?; let client = EthereumClient::new(EthereumClientConfig { @@ -76,8 +76,6 @@ impl EthereumSyncService { "No Ethereum endpoint provided. Use --l1-endpoint or disable with --no-l1-sync." ); } - } else { - None }; Self::create_service(config, sync_config, settlement_client).await @@ -87,7 +85,7 @@ impl EthereumSyncService { // Implementation for Starknet impl StarknetSyncService { pub async fn new(config: &L1SyncParams, sync_config: L1SyncConfig<'_>) -> anyhow::Result { - let settlement_client = if sync_config.should_enable_sync(config) { + let settlement_client = { if let Some(l1_rpc_url) = &config.l1_endpoint { let core_address = Felt::from_str(sync_config.l1_core_address.as_str())?; let client = StarknetClient::new(StarknetClientConfig { @@ -106,8 +104,6 @@ impl StarknetSyncService { "No Starknet endpoint provided. Use --l1-endpoint or disable with --no-l1-sync." ); } - } else { - None }; Self::create_service(config, sync_config, settlement_client).await @@ -157,12 +153,14 @@ where } // Factory method to create the appropriate service - // Add the if condition here : - // should_enable_sync pub async fn create(config: &L1SyncParams, sync_config: L1SyncConfig<'_>) -> anyhow::Result> { - match config.settlement_layer { - MadaraSettlementLayer::Eth => Ok(Box::new(EthereumSyncService::new(config, sync_config).await?)), - MadaraSettlementLayer::Starknet => Ok(Box::new(StarknetSyncService::new(config, sync_config).await?)), + if sync_config.should_enable_sync(config) { + match config.settlement_layer { + MadaraSettlementLayer::Eth => Ok(Box::new(EthereumSyncService::new(config, sync_config).await?)), + MadaraSettlementLayer::Starknet => Ok(Box::new(StarknetSyncService::new(config, sync_config).await?)), + } + } else { + Err(anyhow::anyhow!("❗ L1 Sync is disabled")) } } }