From a1477067bff479059828c2502d321a1f8d4ece2d Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Sun, 6 Aug 2023 17:01:40 +0530 Subject: [PATCH 1/5] feat(sozo): output block number after successful migration --- crates/dojo-world/src/migration/mod.rs | 22 +++++++++++++++--- crates/sozo/src/ops/migration/mod.rs | 31 +++++++++++++++++++++----- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/crates/dojo-world/src/migration/mod.rs b/crates/dojo-world/src/migration/mod.rs index 2dfc660e6a..4ef039b41a 100644 --- a/crates/dojo-world/src/migration/mod.rs +++ b/crates/dojo-world/src/migration/mod.rs @@ -10,7 +10,7 @@ use starknet::accounts::{Account, AccountError, Call, ConnectedAccount, SingleOw use starknet::core::types::contract::{CompiledClass, SierraClass}; use starknet::core::types::{ BlockId, BlockTag, DeclareTransactionResult, FieldElement, FlattenedSierraClass, - InvokeTransactionResult, StarknetError, + InvokeTransactionResult, StarknetError, TransactionReceipt, }; use starknet::core::utils::{ get_contract_address, get_selector_from_name, CairoShortStringToFeltError, @@ -33,6 +33,7 @@ pub struct DeployOutput { pub transaction_hash: FieldElement, pub contract_address: FieldElement, pub declare: Option, + pub block_number: u64, } #[derive(Debug)] @@ -181,11 +182,16 @@ pub trait Deployable: Declarable + Sync { .await .map_err(MigrationError::Migrator)?; - let _ = TransactionWaiter::new(transaction_hash, account.provider()) + let txn = TransactionWaiter::new(transaction_hash, account.provider()) .await .map_err(MigrationError::WaitingError)?; - Ok(DeployOutput { transaction_hash, contract_address, declare }) + Ok(DeployOutput { + transaction_hash, + contract_address, + declare, + block_number: get_block_number(&txn), + }) } fn salt(&self) -> FieldElement; @@ -216,3 +222,13 @@ fn get_compiled_class_hash(artifact_path: &PathBuf) -> Result { let compiled_class: CompiledClass = serde_json::from_str(&res)?; Ok(compiled_class.class_hash()?) } + +fn get_block_number(tx: &TransactionReceipt) -> u64 { + match tx { + TransactionReceipt::Invoke(tx) => tx.block_number, + TransactionReceipt::L1Handler(tx) => tx.block_number, + TransactionReceipt::Declare(tx) => tx.block_number, + TransactionReceipt::Deploy(tx) => tx.block_number, + TransactionReceipt::DeployAccount(tx) => tx.block_number, + } +} diff --git a/crates/sozo/src/ops/migration/mod.rs b/crates/sozo/src/ops/migration/mod.rs index ba4522fa41..40e273d35d 100644 --- a/crates/sozo/src/ops/migration/mod.rs +++ b/crates/sozo/src/ops/migration/mod.rs @@ -10,7 +10,7 @@ use dojo_world::utils::TransactionWaiter; use scarb::core::Config; use starknet::accounts::{Account, ConnectedAccount, SingleOwnerAccount}; use starknet::core::types::{ - BlockId, BlockTag, FieldElement, InvokeTransactionResult, StarknetError, + BlockId, BlockTag, FieldElement, InvokeTransactionResult, StarknetError, TransactionReceipt, }; use starknet::core::utils::cairo_short_string_to_felt; use starknet::providers::jsonrpc::HttpTransport; @@ -68,13 +68,14 @@ where println!(" "); - execute_strategy(&strategy, &account, config) + let block_height = execute_strategy(&strategy, &account, config) .await .map_err(|e| anyhow!(e)) .with_context(|| "Problem trying to migrate.")?; config.ui().print(format!( - "\nšŸŽ‰ Successfully migrated World at address {}", + "\nšŸŽ‰ Successfully migrated World on block #{} at address {}", + block_height.expect("because world address always exists there is always a deployment so this cannot be none"), bold_message(format!( "{:#x}", strategy.world_address().expect("world address must exist") @@ -196,15 +197,17 @@ where Ok(migration) } +// returns the block number at which new/updated world contract if deployed async fn execute_strategy( strategy: &MigrationStrategy, migrator: &SingleOwnerAccount, ws_config: &Config, -) -> Result<()> +) -> Result> where P: Provider + Sync + Send + 'static, S: Signer + Sync + Send + 'static, { + let mut block_height_world = None; match &strategy.executor { Some(executor) => { ws_config.ui().print_header("# Executor"); @@ -236,10 +239,14 @@ where .set_executor(executor.contract_address) .await?; - let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) + let txn = TransactionWaiter::new(transaction_hash, migrator.provider()) .await .map_err(MigrationError::::Error>::WaitingError); + if let Ok(txn) = txn { + block_height_world = Some(get_block_number(&txn)); + } + ws_config.ui().print_hidden_sub(format!("Updated at: {transaction_hash:#x}")); } @@ -272,6 +279,8 @@ where "Deploy transaction: {:#x}", val.transaction_hash )); + + block_height_world = Some(val.block_number); Ok(()) } @@ -291,7 +300,7 @@ where register_components(strategy, migrator, ws_config).await?; register_systems(strategy, migrator, ws_config).await?; - Ok(()) + Ok(block_height_world) } async fn register_components( @@ -413,3 +422,13 @@ where Ok(Some(RegisterOutput { transaction_hash, declare_output })) } + +fn get_block_number(tx: &TransactionReceipt) -> u64 { + match tx { + TransactionReceipt::Invoke(tx) => tx.block_number, + TransactionReceipt::L1Handler(tx) => tx.block_number, + TransactionReceipt::Declare(tx) => tx.block_number, + TransactionReceipt::Deploy(tx) => tx.block_number, + TransactionReceipt::DeployAccount(tx) => tx.block_number, + } +} From 3ea18d7065d003552a5bde845a45d17d31ce9a76 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Mon, 7 Aug 2023 22:29:26 +0530 Subject: [PATCH 2/5] update logic --- crates/sozo/src/ops/migration/mod.rs | 36 +++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/crates/sozo/src/ops/migration/mod.rs b/crates/sozo/src/ops/migration/mod.rs index 40e273d35d..92ead9817e 100644 --- a/crates/sozo/src/ops/migration/mod.rs +++ b/crates/sozo/src/ops/migration/mod.rs @@ -75,7 +75,7 @@ where config.ui().print(format!( "\nšŸŽ‰ Successfully migrated World on block #{} at address {}", - block_height.expect("because world address always exists there is always a deployment so this cannot be none"), + block_height.expect("Atleast one of the contract should be upgraded"), bold_message(format!( "{:#x}", strategy.world_address().expect("world address must exist") @@ -197,7 +197,7 @@ where Ok(migration) } -// returns the block number at which new/updated world contract if deployed +// returns the block number at which migration happened async fn execute_strategy( strategy: &MigrationStrategy, migrator: &SingleOwnerAccount, @@ -207,7 +207,7 @@ where P: Provider + Sync + Send + 'static, S: Signer + Sync + Send + 'static, { - let mut block_height_world = None; + let mut block_height = None; match &strategy.executor { Some(executor) => { ws_config.ui().print_header("# Executor"); @@ -241,11 +241,9 @@ where let txn = TransactionWaiter::new(transaction_hash, migrator.provider()) .await - .map_err(MigrationError::::Error>::WaitingError); + .map_err(|_| anyhow!("Transaction execution failed"))?; - if let Ok(txn) = txn { - block_height_world = Some(get_block_number(&txn)); - } + block_height = Some(get_block_number(&txn)); ws_config.ui().print_hidden_sub(format!("Updated at: {transaction_hash:#x}")); } @@ -279,8 +277,8 @@ where "Deploy transaction: {:#x}", val.transaction_hash )); - - block_height_world = Some(val.block_number); + + block_height = Some(val.block_number); Ok(()) } @@ -297,16 +295,17 @@ where None => {} }; - register_components(strategy, migrator, ws_config).await?; - register_systems(strategy, migrator, ws_config).await?; + register_components(strategy, migrator, ws_config, &mut block_height).await?; + register_systems(strategy, migrator, ws_config, &mut block_height).await?; - Ok(block_height_world) + Ok(block_height) } async fn register_components( strategy: &MigrationStrategy, migrator: &SingleOwnerAccount, ws_config: &Config, + block_height: &mut Option, ) -> Result> where P: Provider + Sync + Send + 'static, @@ -354,9 +353,11 @@ where .await .map_err(|e| anyhow!("Failed to register components to World: {e}"))?; - let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) + let txn = TransactionWaiter::new(transaction_hash, migrator.provider()) .await - .map_err(MigrationError::::Error>::WaitingError); + .map_err(|_| anyhow!("Transaction execution failed"))?; + + *block_height = Some(get_block_number(&txn)); ws_config.ui().print_hidden_sub(format!("registered at: {transaction_hash:#x}")); @@ -367,6 +368,7 @@ async fn register_systems( strategy: &MigrationStrategy, migrator: &SingleOwnerAccount, ws_config: &Config, + block_height: &mut Option, ) -> Result> where P: Provider + Sync + Send + 'static, @@ -414,9 +416,11 @@ where .await .map_err(|e| anyhow!("Failed to register systems to World: {e}"))?; - let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) + let txn = TransactionWaiter::new(transaction_hash, migrator.provider()) .await - .map_err(MigrationError::::Error>::WaitingError); + .map_err(|_| anyhow!("Transaction execution failed"))?; + + *block_height = Some(get_block_number(&txn)); ws_config.ui().print_hidden_sub(format!("registered at: {transaction_hash:#x}")); From 258953d23c467305f0a65b7e423970687379b370 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Mon, 7 Aug 2023 22:39:57 +0530 Subject: [PATCH 3/5] remove duplication --- crates/dojo-world/src/migration/mod.rs | 16 +++------------- crates/dojo-world/src/utils.rs | 12 +++++++++++- crates/sozo/src/ops/migration/mod.rs | 20 +++++--------------- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/crates/dojo-world/src/migration/mod.rs b/crates/dojo-world/src/migration/mod.rs index 4ef039b41a..d928a282a2 100644 --- a/crates/dojo-world/src/migration/mod.rs +++ b/crates/dojo-world/src/migration/mod.rs @@ -10,7 +10,7 @@ use starknet::accounts::{Account, AccountError, Call, ConnectedAccount, SingleOw use starknet::core::types::contract::{CompiledClass, SierraClass}; use starknet::core::types::{ BlockId, BlockTag, DeclareTransactionResult, FieldElement, FlattenedSierraClass, - InvokeTransactionResult, StarknetError, TransactionReceipt, + InvokeTransactionResult, StarknetError, }; use starknet::core::utils::{ get_contract_address, get_selector_from_name, CairoShortStringToFeltError, @@ -19,7 +19,7 @@ use starknet::providers::{Provider, ProviderError}; use starknet::signers::Signer; use thiserror::Error; -use crate::utils::{TransactionWaiter, TransactionWaitingError}; +use crate::utils::{block_number_from_receipt, TransactionWaiter, TransactionWaitingError}; pub mod class; pub mod contract; @@ -190,7 +190,7 @@ pub trait Deployable: Declarable + Sync { transaction_hash, contract_address, declare, - block_number: get_block_number(&txn), + block_number: block_number_from_receipt(&txn), }) } @@ -222,13 +222,3 @@ fn get_compiled_class_hash(artifact_path: &PathBuf) -> Result { let compiled_class: CompiledClass = serde_json::from_str(&res)?; Ok(compiled_class.class_hash()?) } - -fn get_block_number(tx: &TransactionReceipt) -> u64 { - match tx { - TransactionReceipt::Invoke(tx) => tx.block_number, - TransactionReceipt::L1Handler(tx) => tx.block_number, - TransactionReceipt::Declare(tx) => tx.block_number, - TransactionReceipt::Deploy(tx) => tx.block_number, - TransactionReceipt::DeployAccount(tx) => tx.block_number, - } -} diff --git a/crates/dojo-world/src/utils.rs b/crates/dojo-world/src/utils.rs index c55d3adf8d..eaa3b76802 100644 --- a/crates/dojo-world/src/utils.rs +++ b/crates/dojo-world/src/utils.rs @@ -153,7 +153,7 @@ where } } -fn transaction_status_from_receipt(receipt: &TransactionReceipt) -> TransactionStatus { +pub fn transaction_status_from_receipt(receipt: &TransactionReceipt) -> TransactionStatus { match receipt { TransactionReceipt::Invoke(receipt) => receipt.status, TransactionReceipt::Deploy(receipt) => receipt.status, @@ -163,6 +163,16 @@ fn transaction_status_from_receipt(receipt: &TransactionReceipt) -> TransactionS } } +pub fn block_number_from_receipt(tx: &TransactionReceipt) -> u64 { + match tx { + TransactionReceipt::Invoke(tx) => tx.block_number, + TransactionReceipt::L1Handler(tx) => tx.block_number, + TransactionReceipt::Declare(tx) => tx.block_number, + TransactionReceipt::Deploy(tx) => tx.block_number, + TransactionReceipt::DeployAccount(tx) => tx.block_number, + } +} + #[cfg(test)] mod tests { use assert_matches::assert_matches; diff --git a/crates/sozo/src/ops/migration/mod.rs b/crates/sozo/src/ops/migration/mod.rs index 92ead9817e..f4608be246 100644 --- a/crates/sozo/src/ops/migration/mod.rs +++ b/crates/sozo/src/ops/migration/mod.rs @@ -6,11 +6,11 @@ use dojo_world::manifest::{Manifest, ManifestError}; use dojo_world::migration::strategy::{prepare_for_migration, MigrationStrategy}; use dojo_world::migration::world::WorldDiff; use dojo_world::migration::{Declarable, Deployable, MigrationError, RegisterOutput, StateDiff}; -use dojo_world::utils::TransactionWaiter; +use dojo_world::utils::{block_number_from_receipt, TransactionWaiter}; use scarb::core::Config; use starknet::accounts::{Account, ConnectedAccount, SingleOwnerAccount}; use starknet::core::types::{ - BlockId, BlockTag, FieldElement, InvokeTransactionResult, StarknetError, TransactionReceipt, + BlockId, BlockTag, FieldElement, InvokeTransactionResult, StarknetError, }; use starknet::core::utils::cairo_short_string_to_felt; use starknet::providers::jsonrpc::HttpTransport; @@ -243,7 +243,7 @@ where .await .map_err(|_| anyhow!("Transaction execution failed"))?; - block_height = Some(get_block_number(&txn)); + block_height = Some(block_number_from_receipt(&txn)); ws_config.ui().print_hidden_sub(format!("Updated at: {transaction_hash:#x}")); } @@ -357,7 +357,7 @@ where .await .map_err(|_| anyhow!("Transaction execution failed"))?; - *block_height = Some(get_block_number(&txn)); + *block_height = Some(block_number_from_receipt(&txn)); ws_config.ui().print_hidden_sub(format!("registered at: {transaction_hash:#x}")); @@ -420,19 +420,9 @@ where .await .map_err(|_| anyhow!("Transaction execution failed"))?; - *block_height = Some(get_block_number(&txn)); + *block_height = Some(block_number_from_receipt(&txn)); ws_config.ui().print_hidden_sub(format!("registered at: {transaction_hash:#x}")); Ok(Some(RegisterOutput { transaction_hash, declare_output })) } - -fn get_block_number(tx: &TransactionReceipt) -> u64 { - match tx { - TransactionReceipt::Invoke(tx) => tx.block_number, - TransactionReceipt::L1Handler(tx) => tx.block_number, - TransactionReceipt::Declare(tx) => tx.block_number, - TransactionReceipt::Deploy(tx) => tx.block_number, - TransactionReceipt::DeployAccount(tx) => tx.block_number, - } -} From 44718640bcc5f02f1f6bfe657fead020dec2f2da Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Wed, 9 Aug 2023 16:36:54 +0530 Subject: [PATCH 4/5] only return block number when world contract is migrated --- crates/sozo/src/ops/migration/mod.rs | 46 +++++++++++++++------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/crates/sozo/src/ops/migration/mod.rs b/crates/sozo/src/ops/migration/mod.rs index f4608be246..2e78f2378d 100644 --- a/crates/sozo/src/ops/migration/mod.rs +++ b/crates/sozo/src/ops/migration/mod.rs @@ -6,7 +6,7 @@ use dojo_world::manifest::{Manifest, ManifestError}; use dojo_world::migration::strategy::{prepare_for_migration, MigrationStrategy}; use dojo_world::migration::world::WorldDiff; use dojo_world::migration::{Declarable, Deployable, MigrationError, RegisterOutput, StateDiff}; -use dojo_world::utils::{block_number_from_receipt, TransactionWaiter}; +use dojo_world::utils::TransactionWaiter; use scarb::core::Config; use starknet::accounts::{Account, ConnectedAccount, SingleOwnerAccount}; use starknet::core::types::{ @@ -73,14 +73,24 @@ where .map_err(|e| anyhow!(e)) .with_context(|| "Problem trying to migrate.")?; - config.ui().print(format!( - "\nšŸŽ‰ Successfully migrated World on block #{} at address {}", - block_height.expect("Atleast one of the contract should be upgraded"), - bold_message(format!( - "{:#x}", - strategy.world_address().expect("world address must exist") - )) - )); + if let Some(block_height) = block_height { + config.ui().print(format!( + "\nšŸŽ‰ Successfully migrated World on block #{} at address {}", + block_height, + bold_message(format!( + "{:#x}", + strategy.world_address().expect("world address must exist") + )) + )); + } else { + config.ui().print(format!( + "\nšŸŽ‰ Successfully migrated World at address {}", + bold_message(format!( + "{:#x}", + strategy.world_address().expect("world address must exist") + )) + )); + } } Ok(()) @@ -239,12 +249,10 @@ where .set_executor(executor.contract_address) .await?; - let txn = TransactionWaiter::new(transaction_hash, migrator.provider()) + let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) .await .map_err(|_| anyhow!("Transaction execution failed"))?; - block_height = Some(block_number_from_receipt(&txn)); - ws_config.ui().print_hidden_sub(format!("Updated at: {transaction_hash:#x}")); } @@ -295,8 +303,8 @@ where None => {} }; - register_components(strategy, migrator, ws_config, &mut block_height).await?; - register_systems(strategy, migrator, ws_config, &mut block_height).await?; + register_components(strategy, migrator, ws_config).await?; + register_systems(strategy, migrator, ws_config).await?; Ok(block_height) } @@ -305,7 +313,6 @@ async fn register_components( strategy: &MigrationStrategy, migrator: &SingleOwnerAccount, ws_config: &Config, - block_height: &mut Option, ) -> Result> where P: Provider + Sync + Send + 'static, @@ -353,12 +360,10 @@ where .await .map_err(|e| anyhow!("Failed to register components to World: {e}"))?; - let txn = TransactionWaiter::new(transaction_hash, migrator.provider()) + let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) .await .map_err(|_| anyhow!("Transaction execution failed"))?; - *block_height = Some(block_number_from_receipt(&txn)); - ws_config.ui().print_hidden_sub(format!("registered at: {transaction_hash:#x}")); Ok(Some(RegisterOutput { transaction_hash, declare_output })) @@ -368,7 +373,6 @@ async fn register_systems( strategy: &MigrationStrategy, migrator: &SingleOwnerAccount, ws_config: &Config, - block_height: &mut Option, ) -> Result> where P: Provider + Sync + Send + 'static, @@ -416,12 +420,10 @@ where .await .map_err(|e| anyhow!("Failed to register systems to World: {e}"))?; - let txn = TransactionWaiter::new(transaction_hash, migrator.provider()) + let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) .await .map_err(|_| anyhow!("Transaction execution failed"))?; - *block_height = Some(block_number_from_receipt(&txn)); - ws_config.ui().print_hidden_sub(format!("registered at: {transaction_hash:#x}")); Ok(Some(RegisterOutput { transaction_hash, declare_output })) From 78676ff92a0a42088dc2dc7458301db3a5d32897 Mon Sep 17 00:00:00 2001 From: lambda-0x <0xlambda@protonmail.com> Date: Fri, 11 Aug 2023 10:57:33 +0530 Subject: [PATCH 5/5] return concrete error --- crates/sozo/src/ops/migration/mod.rs | 33 +++++++++++++++++++--------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/crates/sozo/src/ops/migration/mod.rs b/crates/sozo/src/ops/migration/mod.rs index 2e78f2378d..819206204d 100644 --- a/crates/sozo/src/ops/migration/mod.rs +++ b/crates/sozo/src/ops/migration/mod.rs @@ -207,7 +207,8 @@ where Ok(migration) } -// returns the block number at which migration happened +// returns the Some(block number) at which migration world is deployed, returns none if world was +// not redeployed async fn execute_strategy( strategy: &MigrationStrategy, migrator: &SingleOwnerAccount, @@ -249,9 +250,13 @@ where .set_executor(executor.contract_address) .await?; - let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) - .await - .map_err(|_| anyhow!("Transaction execution failed"))?; + let _ = + TransactionWaiter::new(transaction_hash, migrator.provider()).await.map_err( + MigrationError::< + as Account>::SignError, +

::Error, + >::WaitingError, + )?; ws_config.ui().print_hidden_sub(format!("Updated at: {transaction_hash:#x}")); } @@ -360,9 +365,13 @@ where .await .map_err(|e| anyhow!("Failed to register components to World: {e}"))?; - let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) - .await - .map_err(|_| anyhow!("Transaction execution failed"))?; + let _ = + TransactionWaiter::new(transaction_hash, migrator.provider()).await.map_err( + MigrationError::< + as Account>::SignError, +

::Error, + >::WaitingError, + )?; ws_config.ui().print_hidden_sub(format!("registered at: {transaction_hash:#x}")); @@ -420,9 +429,13 @@ where .await .map_err(|e| anyhow!("Failed to register systems to World: {e}"))?; - let _ = TransactionWaiter::new(transaction_hash, migrator.provider()) - .await - .map_err(|_| anyhow!("Transaction execution failed"))?; + let _ = + TransactionWaiter::new(transaction_hash, migrator.provider()).await.map_err( + MigrationError::< + as Account>::SignError, +

::Error, + >::WaitingError, + )?; ws_config.ui().print_hidden_sub(format!("registered at: {transaction_hash:#x}"));