From a486657ffe69b24603452065a0357e75c2a2c699 Mon Sep 17 00:00:00 2001 From: hal3e Date: Fri, 31 May 2024 15:57:18 +0200 Subject: [PATCH 01/13] Work in progress --- packages/fuels-core/src/types/tx_status.rs | 41 +++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index 7f90ac478d..fa6b3ca902 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -19,6 +19,8 @@ use crate::{ pub enum TxStatus { Success { receipts: Vec, + total_gas: u64, + total_fee: u64, }, Submitted, SqueezedOut { @@ -28,6 +30,8 @@ pub enum TxStatus { receipts: Vec, reason: String, revert_id: u64, + total_gas: u64, + total_fee: u64, }, } @@ -41,6 +45,7 @@ impl TxStatus { receipts, reason, revert_id: id, + .. } => Self::map_revert_error(receipts, reason, *id, log_decoder), _ => Ok(()), } @@ -86,7 +91,7 @@ impl TxStatus { pub fn take_receipts(self) -> Vec { match self { - TxStatus::Success { receipts } | TxStatus::Revert { receipts, .. } => receipts, + TxStatus::Success { receipts, .. } | TxStatus::Revert { receipts, .. } => receipts, _ => vec![], } } @@ -97,11 +102,22 @@ impl From for TxStatus { fn from(client_status: ClientTransactionStatus) -> Self { match client_status { ClientTransactionStatus::Submitted { .. } => TxStatus::Submitted {}, - ClientTransactionStatus::Success { receipts, .. } => TxStatus::Success { receipts }, + ClientTransactionStatus::Success { + receipts, + total_gas, + total_fee, + .. + } => TxStatus::Success { + receipts, + total_gas, + total_fee, + }, ClientTransactionStatus::Failure { reason, program_state, receipts, + total_gas, + total_fee, .. } => { let revert_id = program_state @@ -114,6 +130,8 @@ impl From for TxStatus { receipts, reason, revert_id, + total_gas, + total_fee, } } ClientTransactionStatus::SqueezedOut { reason } => TxStatus::SqueezedOut { reason }, @@ -125,9 +143,22 @@ impl From for TxStatus { impl From for TxStatus { fn from(value: TransactionExecutionStatus) -> Self { match value.result { - TransactionExecutionResult::Success { receipts, .. } => Self::Success { receipts }, + TransactionExecutionResult::Success { + receipts, + total_gas, + total_fee, + .. + } => Self::Success { + receipts, + total_gas, + total_fee, + }, TransactionExecutionResult::Failed { - result, receipts, .. + result, + receipts, + total_gas, + total_fee, + .. } => { let revert_id = result .and_then(|result| match result { @@ -140,6 +171,8 @@ impl From for TxStatus { receipts, reason, revert_id, + total_gas, + total_fee, } } } From 038d8b23d0241afb0a96d6dbecff7c88d0b25f6b Mon Sep 17 00:00:00 2001 From: hal3e Date: Tue, 14 Jan 2025 23:59:00 +0100 Subject: [PATCH 02/13] feat: use `total_gas` and `total_fee` from tx status --- e2e/tests/contracts.rs | 4 +- e2e/tests/providers.rs | 2 +- e2e/tests/scripts.rs | 2 +- examples/contracts/src/lib.rs | 6 +- packages/fuels-accounts/src/provider.rs | 16 +---- packages/fuels-core/src/types/tx_status.rs | 14 +++++ .../src/types/wrappers/transaction.rs | 44 ------------- .../fuels-programs/src/calls/call_handler.rs | 62 +++++++++---------- .../fuels-programs/src/contract/loader.rs | 5 +- packages/fuels-programs/src/responses/call.rs | 26 +------- .../fuels-programs/src/responses/submit.rs | 14 ++--- 11 files changed, 59 insertions(+), 136 deletions(-) diff --git a/e2e/tests/contracts.rs b/e2e/tests/contracts.rs index ff7758c48c..82090c7e54 100644 --- a/e2e/tests/contracts.rs +++ b/e2e/tests/contracts.rs @@ -291,7 +291,7 @@ async fn test_contract_call_fee_estimation() -> Result<()> { let gas_limit = 800; let tolerance = Some(0.2); let block_horizon = Some(1); - let expected_gas_used = 960; + let expected_gas_used = 8462; let expected_metered_bytes_size = 824; let estimated_transaction_cost = contract_instance @@ -1730,7 +1730,7 @@ async fn contract_custom_call_no_signatures_strategy() -> Result<()> { let tx_status = provider.tx_status(&tx_id).await?; - let response = call_handler.get_response_from(tx_status)?; + let response = call_handler.get_response(tx_status)?; assert_eq!(counter, response.value); diff --git a/e2e/tests/providers.rs b/e2e/tests/providers.rs index f8d9cdcdac..b585b159f3 100644 --- a/e2e/tests/providers.rs +++ b/e2e/tests/providers.rs @@ -1205,7 +1205,7 @@ async fn tx_with_witness_data() -> Result<()> { let status = provider.send_transaction_and_await_commit(tx).await?; match status { - TxStatus::Success { receipts } => { + TxStatus::Success { receipts, .. } => { let ret: u64 = receipts .into_iter() .find_map(|receipt| match receipt { diff --git a/e2e/tests/scripts.rs b/e2e/tests/scripts.rs index a416b02b0e..342de4de86 100644 --- a/e2e/tests/scripts.rs +++ b/e2e/tests/scripts.rs @@ -322,7 +322,7 @@ async fn test_script_transaction_builder() -> Result<()> { tokio::time::sleep(Duration::from_millis(500)).await; let tx_status = provider.tx_status(&tx_id).await?; - let response = script_call_handler.get_response_from(tx_status)?; + let response = script_call_handler.get_response(tx_status)?; assert_eq!(response.value, "hello"); // ANCHOR_END: script_call_tb diff --git a/examples/contracts/src/lib.rs b/examples/contracts/src/lib.rs index f0e9a309a6..5ff6f5514f 100644 --- a/examples/contracts/src/lib.rs +++ b/examples/contracts/src/lib.rs @@ -118,7 +118,7 @@ mod tests { .await?; // ANCHOR_END: contract_call_cost_estimation - let expected_gas = 2669; + let expected_gas = 8921; assert_eq!(transaction_cost.gas_used, expected_gas); @@ -633,7 +633,7 @@ mod tests { .await?; // ANCHOR_END: multi_call_cost_estimation - let expected_gas = 4168; + let expected_gas = 10997; assert_eq!(transaction_cost.gas_used, expected_gas); @@ -893,7 +893,7 @@ mod tests { let tx_status = provider.tx_status(&tx_id).await?; - let response = call_handler.get_response_from(tx_status)?; + let response = call_handler.get_response(tx_status)?; assert_eq!(counter, response.value); // ANCHOR_END: contract_call_tb diff --git a/packages/fuels-accounts/src/provider.rs b/packages/fuels-accounts/src/provider.rs index 0e92238ff3..b97c89f84b 100644 --- a/packages/fuels-accounts/src/provider.rs +++ b/packages/fuels-accounts/src/provider.rs @@ -223,8 +223,6 @@ impl Provider { .validate_predicates(&consensus_parameters, latest_block_height)?; } - self.validate_transaction(tx.clone()).await?; - Ok(tx) } @@ -241,17 +239,6 @@ impl Provider { .into()) } - async fn validate_transaction(&self, tx: T) -> Result<()> { - let tolerance = 0.0; - let TransactionCost { gas_used, .. } = self - .estimate_transaction_cost(tx.clone(), Some(tolerance), None) - .await?; - - tx.validate_gas(gas_used)?; - - Ok(()) - } - #[cfg(not(feature = "coin-cache"))] async fn submit(&self, tx: T) -> Result { Ok(self.uncached_client().submit(&tx.into()).await?) @@ -747,8 +734,7 @@ impl Provider { tx: T, tolerance: f64, ) -> Result { - let receipts = self.dry_run_opt(tx, false, None).await?.take_receipts(); - let gas_used = self.get_script_gas_used(&receipts); + let gas_used = self.dry_run_opt(tx, false, None).await?.total_gas(); Ok((gas_used as f64 * (1.0 + tolerance)) as u64) } diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index 67b4d64e48..c288a1c7bd 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -51,6 +51,20 @@ impl TxStatus { } } + pub fn total_gas(&self) -> u64 { + match self { + TxStatus::Success { total_gas, .. } | TxStatus::Revert { total_gas, .. } => *total_gas, + _ => 0, + } + } + + pub fn total_fee(&self) -> u64 { + match self { + TxStatus::Success { total_fee, .. } | TxStatus::Revert { total_fee, .. } => *total_fee, + _ => 0, + } + } + fn map_revert_error( receipts: &[Receipt], reason: &str, diff --git a/packages/fuels-core/src/types/wrappers/transaction.rs b/packages/fuels-core/src/types/wrappers/transaction.rs index bc414d41f1..c7a67e2af2 100644 --- a/packages/fuels-core/src/types/wrappers/transaction.rs +++ b/packages/fuels-core/src/types/wrappers/transaction.rs @@ -202,10 +202,6 @@ pub trait EstimablePredicates: sealed::Sealed { ) -> Result<()>; } -pub trait GasValidation: sealed::Sealed { - fn validate_gas(&self, _gas_used: u64) -> Result<()>; -} - pub trait ValidatablePredicates: sealed::Sealed { /// If a transaction contains predicates, we can verify that these predicates validate, ie /// that they return `true` @@ -223,7 +219,6 @@ pub trait Transaction: + Into + EstimablePredicates + ValidatablePredicates - + GasValidation + Clone + Debug + sealed::Sealed @@ -646,45 +641,6 @@ impl EstimablePredicates for BlobTransaction { } } -impl GasValidation for CreateTransaction { - fn validate_gas(&self, _gas_used: u64) -> Result<()> { - Ok(()) - } -} - -impl GasValidation for UploadTransaction { - fn validate_gas(&self, _gas_used: u64) -> Result<()> { - Ok(()) - } -} - -impl GasValidation for UpgradeTransaction { - fn validate_gas(&self, _gas_used: u64) -> Result<()> { - Ok(()) - } -} - -impl GasValidation for BlobTransaction { - fn validate_gas(&self, _gas_used: u64) -> Result<()> { - Ok(()) - } -} - -impl GasValidation for ScriptTransaction { - fn validate_gas(&self, gas_used: u64) -> Result<()> { - if gas_used > *self.tx.script_gas_limit() { - return Err(error_transaction!( - Validation, - "script_gas_limit({}) is lower than the estimated gas_used({})", - self.tx.script_gas_limit(), - gas_used - )); - } - - Ok(()) - } -} - impl ScriptTransaction { pub fn script(&self) -> &Vec { self.tx.script() diff --git a/packages/fuels-programs/src/calls/call_handler.rs b/packages/fuels-programs/src/calls/call_handler.rs index 21d0302b6f..dcde8b0674 100644 --- a/packages/fuels-programs/src/calls/call_handler.rs +++ b/packages/fuels-programs/src/calls/call_handler.rs @@ -1,6 +1,6 @@ use core::{fmt::Debug, marker::PhantomData}; -use fuel_tx::{AssetId, Bytes32, Receipt}; +use fuel_tx::{AssetId, Bytes32}; use fuels_accounts::{provider::TransactionCost, Account}; use fuels_core::{ codec::{ABIEncoder, DecoderConfig, EncoderConfig, LogDecoder}, @@ -172,9 +172,7 @@ where let tx_status = provider.send_transaction_and_await_commit(tx).await?; - let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; - - self.get_response(receipts) + self.get_response(tx_status) } pub async fn submit(mut self) -> Result> { @@ -205,30 +203,29 @@ where let tx = self.build_tx().await?; provider.dry_run(tx).await? }; - let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; - self.get_response(receipts) + self.get_response(tx_status) } /// Create a [`CallResponse`] from call receipts - pub fn get_response(&self, receipts: Vec) -> Result> { + pub fn get_response(&self, tx_status: TxStatus) -> Result> { + let gas_used = tx_status.total_gas(); + let total_fee = tx_status.total_fee(); + + let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; + let token = self .call .parse_call(&receipts, self.decoder_config, &T::param_type())?; - Ok(CallResponse::new( - T::from_token(token)?, + Ok(CallResponse { + value: T::from_token(token)?, receipts, - self.log_decoder.clone(), - self.cached_tx_id, - )) - } - - /// Create a [`CallResponse`] from `TxStatus` - pub fn get_response_from(&self, tx_status: TxStatus) -> Result> { - let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; - - self.get_response(receipts) + gas_used, + total_fee, + log_decoder: self.log_decoder.clone(), + tx_id: self.cached_tx_id, + }) } pub async fn determine_missing_contracts(mut self, max_attempts: Option) -> Result { @@ -434,8 +431,7 @@ where let tx_status = provider.send_transaction_and_await_commit(tx).await?; - let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; - self.get_response(receipts) + self.get_response(tx_status) } pub async fn submit(mut self) -> Result, ()>> { @@ -472,9 +468,8 @@ where let tx = self.build_tx().await?; provider.dry_run(tx).await? }; - let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; - self.get_response(receipts) + self.get_response(tx_status) } /// Simulates a call without needing to resolve the generic for the return type @@ -490,8 +485,12 @@ where /// Create a [`CallResponse`] from call receipts pub fn get_response( &self, - receipts: Vec, + tx_status: TxStatus, ) -> Result> { + let gas_used = tx_status.total_gas(); + let total_fee = tx_status.total_fee(); + + let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; let mut receipt_parser = ReceiptParser::new(&receipts, self.decoder_config); let final_tokens = self @@ -501,14 +500,15 @@ where .collect::>>()?; let tokens_as_tuple = Token::Tuple(final_tokens); - let response = CallResponse::::new( - T::from_token(tokens_as_tuple)?, - receipts, - self.log_decoder.clone(), - self.cached_tx_id, - ); - Ok(response) + Ok(CallResponse { + value: T::from_token(tokens_as_tuple)?, + receipts, + gas_used, + total_fee, + log_decoder: self.log_decoder.clone(), + tx_id: self.cached_tx_id, + }) } /// Simulates the call and attempts to resolve missing contract outputs. diff --git a/packages/fuels-programs/src/contract/loader.rs b/packages/fuels-programs/src/contract/loader.rs index 4744b21757..1c5f1c8516 100644 --- a/packages/fuels-programs/src/contract/loader.rs +++ b/packages/fuels-programs/src/contract/loader.rs @@ -147,10 +147,7 @@ impl Contract> { tx_status_response.check(None)?; } Err(err) => { - if !err - .to_string() - .contains("Execution error: BlobIdAlreadyUploaded") - { + if !err.to_string().contains("BlobId is already taken") { return Err(err); } } diff --git a/packages/fuels-programs/src/responses/call.rs b/packages/fuels-programs/src/responses/call.rs index 91ebcf102c..d84bed4ba2 100644 --- a/packages/fuels-programs/src/responses/call.rs +++ b/packages/fuels-programs/src/responses/call.rs @@ -16,37 +16,13 @@ pub struct CallResponse { pub value: D, pub receipts: Vec, pub gas_used: u64, + pub total_fee: u64, pub log_decoder: LogDecoder, pub tx_id: Option, } // ANCHOR_END: call_response impl CallResponse { - /// Get the gas used from ScriptResult receipt - fn get_gas_used(receipts: &[Receipt]) -> u64 { - receipts - .iter() - .rfind(|r| matches!(r, Receipt::ScriptResult { .. })) - .expect("could not retrieve ScriptResult") - .gas_used() - .expect("could not retrieve gas used from ScriptResult") - } - - pub fn new( - value: D, - receipts: Vec, - log_decoder: LogDecoder, - tx_id: Option, - ) -> Self { - Self { - value, - gas_used: Self::get_gas_used(&receipts), - receipts, - log_decoder, - tx_id, - } - } - pub fn decode_logs(&self) -> LogResult { self.log_decoder.decode_logs(&self.receipts) } diff --git a/packages/fuels-programs/src/responses/submit.rs b/packages/fuels-programs/src/responses/submit.rs index 0f23193290..3f085f43c6 100644 --- a/packages/fuels-programs/src/responses/submit.rs +++ b/packages/fuels-programs/src/responses/submit.rs @@ -54,12 +54,9 @@ where pub async fn response(self) -> Result> { let provider = self.call_handler.account.try_provider()?; - let receipts = provider - .tx_status(&self.tx_id) - .await? - .take_receipts_checked(Some(&self.call_handler.log_decoder))?; + let tx_status = provider.tx_status(&self.tx_id).await?; - self.call_handler.get_response(receipts) + self.call_handler.get_response(tx_status) } pub fn tx_id(&self) -> Bytes32 { @@ -78,12 +75,9 @@ impl SubmitResponse, ()> { pub async fn response(self) -> Result> { let provider = self.call_handler.account.try_provider()?; - let receipts = provider - .tx_status(&self.tx_id) - .await? - .take_receipts_checked(Some(&self.call_handler.log_decoder))?; + let tx_status = provider.tx_status(&self.tx_id).await?; - self.call_handler.get_response(receipts) + self.call_handler.get_response(tx_status) } pub fn tx_id(&self) -> Bytes32 { From ed3fd56ae2813637f7d0b0dcdd6a041c14d2b216 Mon Sep 17 00:00:00 2001 From: hal3e Date: Wed, 15 Jan 2025 09:26:42 +0100 Subject: [PATCH 03/13] update total_fee calc --- packages/fuels-accounts/src/provider.rs | 34 ++++++++----------- .../fuels-programs/src/calls/call_handler.rs | 4 +-- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/packages/fuels-accounts/src/provider.rs b/packages/fuels-accounts/src/provider.rs index b97c89f84b..bba28304cf 100644 --- a/packages/fuels-accounts/src/provider.rs +++ b/packages/fuels-accounts/src/provider.rs @@ -698,7 +698,7 @@ impl Provider { pub async fn estimate_transaction_cost( &self, - mut tx: T, + tx: T, tolerance: Option, block_horizon: Option, ) -> Result { @@ -706,39 +706,33 @@ impl Provider { let tolerance = tolerance.unwrap_or(DEFAULT_GAS_ESTIMATION_TOLERANCE); let EstimateGasPrice { gas_price, .. } = self.estimate_gas_price(block_horizon).await?; + let tx_status = self.dry_run_opt(tx.clone(), false, None).await?; - let gas_used = self - .get_gas_used_with_tolerance(tx.clone(), tolerance) - .await?; - - if tx.is_using_predicates() { - tx.estimate_predicates(self, None).await?; - } - - let transaction_fee = tx - .clone() - .fee_checked_from_tx(&self.consensus_parameters().await?, gas_price) - .expect("Error calculating TransactionFee"); + let gas_used = self.gas_used_with_tolerance(&tx_status, tolerance).await?; + let total_fee = self.total_fee_with_tolerance(&tx_status, tolerance).await?; Ok(TransactionCost { gas_price, gas_used, metered_bytes_size: tx.metered_bytes_size() as u64, - total_fee: transaction_fee.max_fee(), + total_fee, }) } // Increase estimated gas by the provided tolerance - async fn get_gas_used_with_tolerance( - &self, - tx: T, - tolerance: f64, - ) -> Result { - let gas_used = self.dry_run_opt(tx, false, None).await?.total_gas(); + async fn gas_used_with_tolerance(&self, tx_status: &TxStatus, tolerance: f64) -> Result { + let gas_used = tx_status.total_gas(); Ok((gas_used as f64 * (1.0 + tolerance)) as u64) } + // Increase estimated total fee by the provided tolerance + async fn total_fee_with_tolerance(&self, tx_status: &TxStatus, tolerance: f64) -> Result { + let fee = tx_status.total_fee(); + + Ok((fee as f64 * (1.0 + tolerance)) as u64) + } + fn get_script_gas_used(&self, receipts: &[Receipt]) -> u64 { receipts .iter() diff --git a/packages/fuels-programs/src/calls/call_handler.rs b/packages/fuels-programs/src/calls/call_handler.rs index dcde8b0674..5df81e5d0a 100644 --- a/packages/fuels-programs/src/calls/call_handler.rs +++ b/packages/fuels-programs/src/calls/call_handler.rs @@ -207,7 +207,7 @@ where self.get_response(tx_status) } - /// Create a [`CallResponse`] from call receipts + /// Create a [`CallResponse`] from `TxStatus` pub fn get_response(&self, tx_status: TxStatus) -> Result> { let gas_used = tx_status.total_gas(); let total_fee = tx_status.total_fee(); @@ -482,7 +482,7 @@ where Ok(()) } - /// Create a [`CallResponse`] from call receipts + /// Create a [`CallResponse`] from `TxStatus` pub fn get_response( &self, tx_status: TxStatus, From ffb3d11a7580072650a8449f56e49bfcf388bbff Mon Sep 17 00:00:00 2001 From: hal3e Date: Thu, 16 Jan 2025 16:55:21 +0100 Subject: [PATCH 04/13] resolve all TODOs --- e2e/tests/configurables.rs | 6 +- e2e/tests/contracts.rs | 28 ++--- e2e/tests/logs.rs | 10 +- e2e/tests/predicates.rs | 117 +++++++----------- e2e/tests/providers.rs | 13 +- e2e/tests/scripts.rs | 4 +- e2e/tests/storage.rs | 4 +- e2e/tests/types_contracts.rs | 2 +- e2e/tests/wallets.rs | 16 +-- examples/contracts/src/lib.rs | 39 +++--- examples/cookbook/src/lib.rs | 2 +- examples/wallets/src/lib.rs | 2 +- packages/fuels-accounts/src/account.rs | 7 +- .../src/setup_program_test/code_gen.rs | 2 +- .../fuels-programs/src/contract/loader.rs | 9 +- .../fuels-programs/src/contract/regular.rs | 21 ++-- packages/fuels-programs/src/executable.rs | 19 ++- 17 files changed, 136 insertions(+), 165 deletions(-) diff --git a/e2e/tests/configurables.rs b/e2e/tests/configurables.rs index d9a002d56b..2dbd4a8e6a 100644 --- a/e2e/tests/configurables.rs +++ b/e2e/tests/configurables.rs @@ -13,7 +13,7 @@ async fn contract_default_configurables() -> Result<()> { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/configurables/out/release/configurables.bin", LoadConfiguration::default(), )? @@ -125,7 +125,7 @@ async fn contract_configurables() -> Result<()> { .with_STRUCT(new_struct.clone())? .with_ENUM(new_enum.clone())?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/configurables/out/release/configurables.bin", LoadConfiguration::default().with_configurables(configurables), )? @@ -192,7 +192,7 @@ async fn contract_manual_configurables() -> Result<()> { .with_STRUCT(new_struct.clone())? .with_ENUM(new_enum.clone())?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/configurables/out/release/configurables.bin", LoadConfiguration::default(), )? diff --git a/e2e/tests/contracts.rs b/e2e/tests/contracts.rs index eafb0253f2..2eff20b434 100644 --- a/e2e/tests/contracts.rs +++ b/e2e/tests/contracts.rs @@ -678,7 +678,7 @@ async fn setup_output_variable_estimation_test() -> Result<( let wallet_config = WalletsConfig::new(Some(3), None, None); let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, None).await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/token_ops/out/release/token_ops.bin", LoadConfiguration::default(), )? @@ -1750,7 +1750,7 @@ async fn contract_encoder_config_is_applied() -> Result<()> { )), Wallets("wallet") ); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -1959,7 +1959,7 @@ async fn simulations_can_be_made_without_coins() -> Result<()> { let wallets = setup_node_with_high_price().await?; let wallet = wallets.first().expect("has wallet"); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -1990,7 +1990,7 @@ async fn simulations_can_be_made_without_coins_multicall() -> Result<()> { let wallets = setup_node_with_high_price().await?; let wallet = wallets.first().expect("has wallet"); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -2049,7 +2049,7 @@ async fn contract_call_with_non_zero_base_asset_id_and_tip() -> Result<()> { let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, Some(config)).await?; let wallet = wallets.first().expect("has wallet"); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -2230,7 +2230,7 @@ async fn blob_contract_deployment() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; - let contract_id = contract + let (contract_id, _) = contract .convert_to_loader(100_000)? .deploy_if_not_exists(&wallets[0], TxPolicies::default()) .await?; @@ -2258,7 +2258,7 @@ async fn regular_contract_can_be_deployed() -> Result<()> { let contract_binary = "sway/contracts/contract_test/out/release/contract_test.bin"; // when - let contract_id = Contract::load_from(contract_binary, LoadConfiguration::default())? + let (contract_id, _) = Contract::load_from(contract_binary, LoadConfiguration::default())? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; @@ -2289,7 +2289,7 @@ async fn unuploaded_loader_can_be_deployed_directly() -> Result<()> { let contract_binary = "sway/contracts/huge_contract/out/release/huge_contract.bin"; - let contract_id = Contract::load_from(contract_binary, LoadConfiguration::default())? + let (contract_id, _) = Contract::load_from(contract_binary, LoadConfiguration::default())? .convert_to_loader(1024)? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; @@ -2325,7 +2325,7 @@ async fn unuploaded_loader_can_upload_blobs_separately_then_deploy() -> Result<( // if this were an example for the user we'd just call `deploy` on the contract above // this way we are testing that the blobs were really deployed above, otherwise the following // would fail - let contract_id = Contract::loader_from_blob_ids( + let (contract_id, _) = Contract::loader_from_blob_ids( blob_ids.to_vec(), contract.salt(), contract.storage_slots().to_vec(), @@ -2361,7 +2361,7 @@ async fn loader_blob_already_uploaded_not_an_issue() -> Result<()> { .await?; // this will try to upload the blobs but skip upon encountering an error - let contract_id = contract + let (contract_id, _) = contract .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; @@ -2391,14 +2391,14 @@ async fn loader_works_via_proxy() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; - let contract_id = contract + let (contract_id, _) = contract .convert_to_loader(100)? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_binary = "sway/contracts/proxy/out/release/proxy.bin"; - let proxy_id = Contract::load_from(contract_binary, LoadConfiguration::default())? + let (proxy_id, _) = Contract::load_from(contract_binary, LoadConfiguration::default())? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; @@ -2442,7 +2442,7 @@ async fn loader_storage_works_via_proxy() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; let contract_storage_slots = contract.storage_slots().to_vec(); - let contract_id = contract + let (contract_id, _) = contract .convert_to_loader(100)? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; @@ -2452,7 +2452,7 @@ async fn loader_storage_works_via_proxy() -> Result<()> { let combined_storage_slots = [&contract_storage_slots, proxy_contract.storage_slots()].concat(); - let proxy_id = proxy_contract + let (proxy_id, _) = proxy_contract .with_storage_slots(combined_storage_slots) .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; diff --git a/e2e/tests/logs.rs b/e2e/tests/logs.rs index 664333c0a9..d6a4d2e333 100644 --- a/e2e/tests/logs.rs +++ b/e2e/tests/logs.rs @@ -382,7 +382,7 @@ async fn test_multi_call_contract_with_contract_logs() -> Result<()> { ), ); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "./sway/logs/contract_logs/out/release/contract_logs.bin", LoadConfiguration::default(), )? @@ -737,7 +737,7 @@ async fn test_contract_with_contract_logs() -> Result<()> { ) ); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "./sway/logs/contract_logs/out/release/contract_logs.bin", LoadConfiguration::default(), )? @@ -1020,7 +1020,7 @@ async fn test_contract_require_from_contract() -> Result<()> { ) ); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "./sway/contracts/lib_contract/out/release/lib_contract.bin", LoadConfiguration::default(), )? @@ -1074,7 +1074,7 @@ async fn test_multi_call_contract_require_from_contract() -> Result<()> { ), ); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "./sway/contracts/lib_contract/out/release/lib_contract.bin", LoadConfiguration::default(), )? @@ -1166,7 +1166,7 @@ async fn test_loader_script_require_from_loader_contract() -> Result<()> { let contract_binary = "sway/contracts/lib_contract/out/release/lib_contract.bin"; let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; - let contract_id = contract + let (contract_id, _) = contract .convert_to_loader(100_000)? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; diff --git a/e2e/tests/predicates.rs b/e2e/tests/predicates.rs index 3acd777e74..5761723785 100644 --- a/e2e/tests/predicates.rs +++ b/e2e/tests/predicates.rs @@ -115,7 +115,7 @@ async fn transfer_coins_and_messages_to_predicate() -> Result<()> { let num_coins = 16; let num_messages = 32; let amount = 64; - let total_balance = (num_coins + num_messages) * amount; + let balance_to_send = ((num_coins + num_messages) * amount) - 1; let mut wallet = WalletUnlocked::new_random(None); @@ -130,25 +130,18 @@ async fn transfer_coins_and_messages_to_predicate() -> Result<()> { Predicate::load_from("sway/predicates/basic_predicate/out/release/basic_predicate.bin")? .with_provider(provider.clone()); - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; wallet .transfer( predicate.address(), - total_balance - expected_fee, + balance_to_send, asset_id, TxPolicies::default(), ) .await?; // The predicate has received the funds - assert_address_balance( - predicate.address(), - &provider, - asset_id, - total_balance - expected_fee, - ) - .await; + assert_address_balance(predicate.address(), &provider, asset_id, balance_to_send).await; + Ok(()) } @@ -173,12 +166,11 @@ async fn spend_predicate_coins_messages_basic() -> Result<()> { predicate.set_provider(provider.clone()); - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; + let amount_to_send = predicate_balance - 1; predicate .transfer( receiver.address(), - predicate_balance - expected_fee, + amount_to_send, asset_id, TxPolicies::default(), ) @@ -192,7 +184,7 @@ async fn spend_predicate_coins_messages_basic() -> Result<()> { receiver.address(), &provider, asset_id, - receiver_balance + predicate_balance - expected_fee, + receiver_balance + amount_to_send, ) .await; @@ -221,12 +213,12 @@ async fn pay_with_predicate() -> Result<()> { let num_coins = 4; let num_messages = 8; let amount = 16; - let (provider, _predicate_balance, _receiver, _receiver_balance, _asset_id, _) = + let (provider, predicate_balance, _receiver, _receiver_balance, _asset_id, _) = setup_predicate_test(predicate.address(), num_coins, num_messages, amount).await?; predicate.set_provider(provider.clone()); - let contract_id = Contract::load_from( + let (contract_id, deploy_tx_status) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -234,34 +226,27 @@ async fn pay_with_predicate() -> Result<()> { .await?; let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); - let tx_policies = TxPolicies::default() - .with_tip(1) - .with_script_gas_limit(1_000_000); - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; let consensus_parameters = provider.consensus_parameters().await?; + let deploy_fee = deploy_tx_status.unwrap().total_fee(); assert_eq!( predicate .get_asset_balance(consensus_parameters.base_asset_id()) .await?, - 192 - expected_fee + predicate_balance - deploy_fee ); let response = contract_methods .initialize_counter(42) // Build the ABI call - .with_tx_policies(tx_policies) .call() .await?; assert_eq!(42, response.value); - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 2; assert_eq!( predicate .get_asset_balance(consensus_parameters.base_asset_id()) .await?, - 191 - expected_fee + predicate_balance - deploy_fee - response.total_fee ); Ok(()) @@ -291,12 +276,12 @@ async fn pay_with_predicate_vector_data() -> Result<()> { let num_coins = 4; let num_messages = 8; let amount = 16; - let (provider, _predicate_balance, _receiver, _receiver_balance, _asset_id, _) = + let (provider, predicate_balance, _receiver, _receiver_balance, _asset_id, _) = setup_predicate_test(predicate.address(), num_coins, num_messages, amount).await?; predicate.set_provider(provider.clone()); - let contract_id = Contract::load_from( + let (contract_id, deploy_tx_status) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -304,34 +289,24 @@ async fn pay_with_predicate_vector_data() -> Result<()> { .await?; let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); - let tx_policies = TxPolicies::default() - .with_tip(1) - .with_script_gas_limit(1_000_000); - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; let consensus_parameters = provider.consensus_parameters().await?; + let deploy_fee = deploy_tx_status.unwrap().total_fee(); assert_eq!( predicate .get_asset_balance(consensus_parameters.base_asset_id()) .await?, - 192 - expected_fee + predicate_balance - deploy_fee ); - let response = contract_methods - .initialize_counter(42) - .with_tx_policies(tx_policies) - .call() - .await?; + let response = contract_methods.initialize_counter(42).call().await?; - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 2; assert_eq!(42, response.value); assert_eq!( predicate .get_asset_balance(consensus_parameters.base_asset_id()) .await?, - 191 - expected_fee + predicate_balance - deploy_fee - response.total_fee ); Ok(()) @@ -359,7 +334,7 @@ async fn predicate_contract_transfer() -> Result<()> { predicate.set_provider(provider.clone()); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -501,15 +476,13 @@ async fn predicate_transfer_with_signed_resources() -> Result<()> { let tx = tb.build(&provider).await?; - provider.send_transaction_and_await_commit(tx).await?; + let tx_status = provider.send_transaction_and_await_commit(tx).await?; - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; assert_address_balance( predicate.address(), &provider, asset_id, - predicate_balance + wallet_balance - expected_fee, + predicate_balance + wallet_balance - tx_status.total_fee(), ) .await; @@ -543,12 +516,12 @@ async fn contract_tx_and_call_params_with_predicate() -> Result<()> { let num_coins = 1; let num_messages = 1; let amount = 1000; - let (provider, _predicate_balance, _receiver, _receiver_balance, _asset_id, _) = + let (provider, predicate_balance, _receiver, _receiver_balance, _asset_id, _) = setup_predicate_test(predicate.address(), num_coins, num_messages, amount).await?; predicate.set_provider(provider.clone()); - let contract_id = Contract::load_from( + let (contract_id, deploy_tx_status) = Contract::load_from( "./sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -573,11 +546,11 @@ async fn contract_tx_and_call_params_with_predicate() -> Result<()> { .call() .await?; - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 2; + let deploy_fee = deploy_tx_status.unwrap().total_fee(); + let call_fee = response.total_fee; assert_eq!( predicate.get_asset_balance(&AssetId::zeroed()).await?, - 1800 - expected_fee + predicate_balance - deploy_fee - call_params_amount - call_fee ); } { @@ -628,7 +601,7 @@ async fn diff_asset_predicate_payment() -> Result<()> { predicate.set_provider(provider.clone()); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "./sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -685,12 +658,11 @@ async fn predicate_default_configurables() -> Result<()> { predicate.set_provider(provider.clone()); - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; + let amount_to_send = predicate_balance - 1; predicate .transfer( receiver.address(), - predicate_balance - expected_fee, + amount_to_send, asset_id, TxPolicies::default(), ) @@ -704,7 +676,7 @@ async fn predicate_default_configurables() -> Result<()> { receiver.address(), &provider, asset_id, - receiver_balance + predicate_balance - expected_fee, + receiver_balance + amount_to_send, ) .await; @@ -752,12 +724,11 @@ async fn predicate_configurables() -> Result<()> { predicate.set_provider(provider.clone()); - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; - predicate + let amount_to_send = predicate_balance - 1; + let (_tx_id, tx_status) = predicate .transfer( receiver.address(), - predicate_balance - expected_fee, + amount_to_send, asset_id, TxPolicies::default(), ) @@ -767,11 +738,12 @@ async fn predicate_configurables() -> Result<()> { assert_address_balance(predicate.address(), &provider, asset_id, 0).await; // Funds were transferred + let fee = tx_status.total_fee(); assert_address_balance( receiver.address(), &provider, asset_id, - receiver_balance + predicate_balance - expected_fee, + receiver_balance + predicate_balance - fee, ) .await; @@ -928,16 +900,15 @@ async fn predicate_can_access_manually_added_witnesses() -> Result<()> { tx.append_witness(witness.into())?; tx.append_witness(witness2.into())?; - provider.send_transaction_and_await_commit(tx).await?; + let tx_status = provider.send_transaction_and_await_commit(tx).await?; - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; + let fee = tx_status.total_fee(); // The predicate has spent the funds assert_address_balance( predicate.address(), &provider, asset_id, - predicate_balance - amount_to_send - expected_fee, + predicate_balance - amount_to_send - fee, ) .await; @@ -1219,14 +1190,16 @@ async fn predicate_configurables_in_blobs() -> Result<()> { predicate.set_provider(provider.clone()); - loader.upload_blob(extra_wallet).await?; + loader + .upload_blob(extra_wallet) + .await? + .expect("has tx_status"); - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; + let amount_to_send = predicate_balance - 1; predicate .transfer( receiver.address(), - predicate_balance - expected_fee, + amount_to_send, asset_id, TxPolicies::default(), ) @@ -1240,7 +1213,7 @@ async fn predicate_configurables_in_blobs() -> Result<()> { receiver.address(), &provider, asset_id, - receiver_balance + predicate_balance - expected_fee, + receiver_balance + amount_to_send, ) .await; diff --git a/e2e/tests/providers.rs b/e2e/tests/providers.rs index b585b159f3..c70c1877ee 100644 --- a/e2e/tests/providers.rs +++ b/e2e/tests/providers.rs @@ -35,7 +35,7 @@ async fn test_provider_launch_and_connect() -> Result<()> { let provider = setup_test_provider(coins, vec![], None, None).await?; wallet.set_provider(provider.clone()); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -176,7 +176,7 @@ async fn test_input_message_pays_fee() -> Result<()> { abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json" )); - let contract_id = Contract::load_from( + let (contract_id, deploy_tx_status) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -194,9 +194,9 @@ async fn test_input_message_pays_fee() -> Result<()> { assert_eq!(42, response.value); let balance = wallet.get_asset_balance(base_asset_id).await?; - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 2; - assert_eq!(balance, DEFAULT_COIN_AMOUNT - expected_fee); + let deploy_fee = deploy_tx_status.unwrap().total_fee(); + let call_fee = response.total_fee; + assert_eq!(balance, DEFAULT_COIN_AMOUNT - deploy_fee - call_fee); Ok(()) } @@ -263,6 +263,7 @@ async fn can_set_custom_block_time() -> Result<()> { assert_eq!(blocks[1].header.time.unwrap().timestamp(), 20); assert_eq!(blocks[2].header.time.unwrap().timestamp(), 40); assert_eq!(blocks[3].header.time.unwrap().timestamp(), 60); + Ok(()) } @@ -1244,7 +1245,7 @@ async fn contract_call_with_impersonation() -> Result<()> { abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json" )); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? diff --git a/e2e/tests/scripts.rs b/e2e/tests/scripts.rs index b2ce6cbadd..fbe7f14ea0 100644 --- a/e2e/tests/scripts.rs +++ b/e2e/tests/scripts.rs @@ -528,14 +528,14 @@ async fn loader_script_calling_loader_proxy() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; - let contract_id = contract + let (contract_id, _) = contract .convert_to_loader(100)? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; let contract_binary = "sway/contracts/proxy/out/release/proxy.bin"; - let proxy_id = Contract::load_from(contract_binary, LoadConfiguration::default())? + let (proxy_id, _) = Contract::load_from(contract_binary, LoadConfiguration::default())? .convert_to_loader(100)? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; diff --git a/e2e/tests/storage.rs b/e2e/tests/storage.rs index 554b7123a1..3410dab304 100644 --- a/e2e/tests/storage.rs +++ b/e2e/tests/storage.rs @@ -19,7 +19,7 @@ async fn test_storage_initialization() -> Result<()> { let storage_vec = vec![storage_slot.clone()]; let storage_configuration = StorageConfiguration::default().add_slot_overrides(storage_vec); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/storage/out/release/storage.bin", LoadConfiguration::default().with_storage_configuration(storage_configuration), )? @@ -48,7 +48,7 @@ async fn test_init_storage_automatically() -> Result<()> { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/contracts/storage/out/release/storage.bin", LoadConfiguration::default(), )? diff --git a/e2e/tests/types_contracts.rs b/e2e/tests/types_contracts.rs index e4e7dd3aba..21742b32b6 100644 --- a/e2e/tests/types_contracts.rs +++ b/e2e/tests/types_contracts.rs @@ -76,7 +76,7 @@ async fn call_with_structs() -> Result<()> { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "sway/types/contracts/complex_types_contract/out/release/complex_types_contract.bin", LoadConfiguration::default(), )? diff --git a/e2e/tests/wallets.rs b/e2e/tests/wallets.rs index e945b4d550..345ac8135e 100644 --- a/e2e/tests/wallets.rs +++ b/e2e/tests/wallets.rs @@ -226,7 +226,7 @@ async fn test_transfer() -> Result<()> { wallet_1.set_provider(provider.clone()); wallet_2.set_provider(provider); - let _receipts = wallet_1 + let _ = wallet_1 .transfer( wallet_2.address(), amount / 2, @@ -262,7 +262,7 @@ async fn send_transfer_transactions() -> Result<()> { // Transfer 1 from wallet 1 to wallet 2. const SEND_AMOUNT: u64 = 1; let base_asset_id = AssetId::zeroed(); - let (tx_id, _receipts) = wallet_1 + let (tx_id, _tx_status) = wallet_1 .transfer(wallet_2.address(), SEND_AMOUNT, base_asset_id, tx_policies) .await?; @@ -307,7 +307,7 @@ async fn transfer_coins_with_change() -> Result<()> { // Transfer 2 from wallet 1 to wallet 2. const SEND_AMOUNT: u64 = 2; - let _receipts = wallet_1 + let (_tx_id, tx_status) = wallet_1 .transfer( wallet_2.address(), SEND_AMOUNT, @@ -321,14 +321,10 @@ async fn transfer_coins_with_change() -> Result<()> { .get_spendable_resources(base_asset_id, 1, None) .await?; - // TODO: https://github.com/FuelLabs/fuels-rs/issues/1394 - let expected_fee = 1; // Assert that we've sent 2 from wallet 1, resulting in an amount of 3 in wallet 1. let resulting_amount = wallet_1_final_coins.first().unwrap(); - assert_eq!( - resulting_amount.amount(), - AMOUNT - SEND_AMOUNT - expected_fee - ); + let fee = tx_status.total_fee(); + assert_eq!(resulting_amount.amount(), AMOUNT - SEND_AMOUNT - fee); let wallet_2_final_coins = wallet_2.get_coins(base_asset_id).await?; assert_eq!(wallet_2_final_coins.len(), 1); @@ -415,7 +411,7 @@ async fn transfer_coins_of_non_base_asset() -> Result<()> { wallet_2.set_provider(provider); const SEND_AMOUNT: u64 = 200; - let _receipts = wallet_1 + let _ = wallet_1 .transfer( wallet_2.address(), SEND_AMOUNT, diff --git a/examples/contracts/src/lib.rs b/examples/contracts/src/lib.rs index 5ff6f5514f..101ea72524 100644 --- a/examples/contracts/src/lib.rs +++ b/examples/contracts/src/lib.rs @@ -45,7 +45,7 @@ mod tests { // This will load and deploy your contract binary to the chain so that its ID can // be used to initialize the instance - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -99,7 +99,7 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -132,7 +132,7 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let contract_id_1 = Contract::load_from( + let (contract_id_1, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -162,7 +162,7 @@ mod tests { .with_script_gas_limit(1_000_000) .with_maturity(0); - let contract_id_2 = Contract::load_from( + let (contract_id_2, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", configuration, )? @@ -233,7 +233,7 @@ mod tests { let wallets = launch_custom_provider_and_get_wallets(WalletsConfig::default(), None, None).await?; - let contract_id_1 = Contract::load_from( + let (contract_id_1, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -251,7 +251,7 @@ mod tests { assert_eq!(42, response.value); - let contract_id_2 = Contract::load_from( + let (contract_id_2, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default().with_salt([1; 32]), )? @@ -283,7 +283,7 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -352,7 +352,7 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/token_ops/out/release/token_ops\ .bin", LoadConfiguration::default(), @@ -414,11 +414,12 @@ mod tests { )? .deploy(&wallet, TxPolicies::default()) .await? + .0 .into(); let bin_path = "../../e2e/sway/contracts/lib_contract_caller/out/release/lib_contract_caller.bin"; - let caller_contract_id = Contract::load_from(bin_path, LoadConfiguration::default())? + let (caller_contract_id, _) = Contract::load_from(bin_path, LoadConfiguration::default())? .deploy(&wallet, TxPolicies::default()) .await?; @@ -513,7 +514,7 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -551,7 +552,7 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -609,7 +610,7 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -654,7 +655,7 @@ mod tests { let wallet_1 = wallets.pop().unwrap(); let wallet_2 = wallets.pop().unwrap(); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -963,7 +964,7 @@ mod tests { let provider = setup_test_provider(coins, vec![], Some(node_config), None).await?; wallet.set_provider(provider.clone()); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -1060,14 +1061,14 @@ mod tests { already_uploaded_blobs.insert(blob_id); } - let contract_id = Contract::loader_from_blob_ids(all_blob_ids, random_salt(), vec![])? + let (contract_id, _) = Contract::loader_from_blob_ids(all_blob_ids, random_salt(), vec![])? .deploy(&wallet, TxPolicies::default()) .await?; // ANCHOR_END: manual_blob_upload_then_deploy // ANCHOR: deploy_via_loader let max_words_per_blob = 10_000; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( contract_binary, LoadConfiguration::default().with_salt(random_salt()), )? @@ -1078,7 +1079,7 @@ mod tests { // ANCHOR: auto_convert_to_loader let max_words_per_blob = 10_000; - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( contract_binary, LoadConfiguration::default().with_salt(random_salt()), )? @@ -1087,7 +1088,7 @@ mod tests { // ANCHOR_END: auto_convert_to_loader // ANCHOR: upload_blobs_then_deploy - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( contract_binary, LoadConfiguration::default().with_salt(random_salt()), )? @@ -1134,7 +1135,7 @@ mod tests { .map(|chunk| Blob::new(chunk.to_vec())) .collect(); - let contract_id = Contract::loader_from_blobs(blobs, random_salt(), vec![])? + let (contract_id, _) = Contract::loader_from_blobs(blobs, random_salt(), vec![])? .deploy(&wallet, TxPolicies::default()) .await?; // ANCHOR_END: manual_blobs_then_deploy diff --git a/examples/cookbook/src/lib.rs b/examples/cookbook/src/lib.rs index e0c0e19b14..9911e7de67 100644 --- a/examples/cookbook/src/lib.rs +++ b/examples/cookbook/src/lib.rs @@ -51,7 +51,7 @@ mod tests { // ANCHOR_END: liquidity_wallet // ANCHOR: liquidity_deploy - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/liquidity_pool/out/release/liquidity_pool.bin", LoadConfiguration::default(), )? diff --git a/examples/wallets/src/lib.rs b/examples/wallets/src/lib.rs index dff23836b1..fd9c2c9f73 100644 --- a/examples/wallets/src/lib.rs +++ b/examples/wallets/src/lib.rs @@ -180,7 +180,7 @@ mod tests { .pop() .unwrap(); - let contract_id = Contract::load_from( + let (contract_id, _) = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? diff --git a/packages/fuels-accounts/src/account.rs b/packages/fuels-accounts/src/account.rs index 2090364e2b..7b4a96c40e 100644 --- a/packages/fuels-accounts/src/account.rs +++ b/packages/fuels-accounts/src/account.rs @@ -15,6 +15,7 @@ use fuels_core::types::{ transaction::{Transaction, TxPolicies}, transaction_builders::{BuildableTransaction, ScriptTransactionBuilder, TransactionBuilder}, transaction_response::TransactionResponse, + tx_status::TxStatus, }; use crate::{ @@ -167,7 +168,7 @@ pub trait Account: ViewOnlyAccount { amount: u64, asset_id: AssetId, tx_policies: TxPolicies, - ) -> Result<(TxId, Vec)> { + ) -> Result<(TxId, TxStatus)> { let provider = self.try_provider()?; let inputs = self @@ -194,9 +195,7 @@ pub trait Account: ViewOnlyAccount { let tx_status = provider.send_transaction_and_await_commit(tx).await?; - let receipts = tx_status.take_receipts_checked(None)?; - - Ok((tx_id, receipts)) + Ok((tx_id, tx_status)) } /// Unconditionally transfers `balance` of type `asset_id` to diff --git a/packages/fuels-macros/src/setup_program_test/code_gen.rs b/packages/fuels-macros/src/setup_program_test/code_gen.rs index a98a2911c2..6e256f023e 100644 --- a/packages/fuels-macros/src/setup_program_test/code_gen.rs +++ b/packages/fuels-macros/src/setup_program_test/code_gen.rs @@ -154,7 +154,7 @@ fn contract_deploying_code( ) .expect("Failed to load the contract"); - let contract_id = loaded_contract.deploy_if_not_exists( + let (contract_id, _) = loaded_contract.deploy_if_not_exists( &#wallet_name, ::fuels::types::transaction::TxPolicies::default() ) diff --git a/packages/fuels-programs/src/contract/loader.rs b/packages/fuels-programs/src/contract/loader.rs index 1c5f1c8516..b2b5dd63f5 100644 --- a/packages/fuels-programs/src/contract/loader.rs +++ b/packages/fuels-programs/src/contract/loader.rs @@ -9,6 +9,7 @@ use fuels_core::{ errors::{error, Result}, transaction::TxPolicies, transaction_builders::{Blob, BlobId, BlobTransactionBuilder, TransactionBuilder}, + tx_status::TxStatus, }, }; @@ -164,7 +165,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result { + ) -> Result<(Bech32ContractId, TxStatus)> { self.upload_blobs(account, tx_policies) .await? .deploy(account, tx_policies) @@ -177,7 +178,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result { + ) -> Result<(Bech32ContractId, Option)> { self.upload_blobs(account, tx_policies) .await? .deploy_if_not_exists(account, tx_policies) @@ -253,7 +254,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result { + ) -> Result<(Bech32ContractId, TxStatus)> { Contract::regular(self.code(), self.salt, self.storage_slots) .deploy(account, tx_policies) .await @@ -263,7 +264,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result { + ) -> Result<(Bech32ContractId, Option)> { Contract::regular(self.code(), self.salt, self.storage_slots) .deploy_if_not_exists(account, tx_policies) .await diff --git a/packages/fuels-programs/src/contract/regular.rs b/packages/fuels-programs/src/contract/regular.rs index 8c54a410bd..3c7bda9931 100644 --- a/packages/fuels-programs/src/contract/regular.rs +++ b/packages/fuels-programs/src/contract/regular.rs @@ -10,6 +10,7 @@ use fuels_core::{ errors::Result, transaction::TxPolicies, transaction_builders::{Blob, CreateTransactionBuilder}, + tx_status::TxStatus, }, Configurables, }; @@ -138,7 +139,7 @@ impl Contract { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result { + ) -> Result<(Bech32ContractId, TxStatus)> { let contract_id = self.contract_id(); let state_root = self.state_root(); let salt = self.salt; @@ -161,12 +162,10 @@ impl Contract { let tx = tb.build(provider).await?; - provider - .send_transaction_and_await_commit(tx) - .await? - .check(None)?; + let tx_status = provider.send_transaction_and_await_commit(tx).await?; + tx_status.check(None)?; - Ok(contract_id.into()) + Ok((contract_id.into(), tx_status)) } /// Deploys a compiled contract to a running node if a contract with @@ -175,13 +174,15 @@ impl Contract { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result { + ) -> Result<(Bech32ContractId, Option)> { let contract_id = Bech32ContractId::from(self.contract_id()); let provider = account.try_provider()?; if provider.contract_exists(&contract_id).await? { - Ok(contract_id) + Ok((contract_id, None)) } else { - self.deploy(account, tx_policies).await + let (contract_id, tx_status) = self.deploy(account, tx_policies).await?; + + Ok((contract_id, Some(tx_status))) } } @@ -208,7 +209,7 @@ impl Contract { account: &impl Account, tx_policies: TxPolicies, max_words_per_blob: usize, - ) -> Result { + ) -> Result<(Bech32ContractId, TxStatus)> { let provider = account.try_provider()?; let max_contract_size = provider .consensus_parameters() diff --git a/packages/fuels-programs/src/executable.rs b/packages/fuels-programs/src/executable.rs index 4703997520..e7dc0dcb97 100644 --- a/packages/fuels-programs/src/executable.rs +++ b/packages/fuels-programs/src/executable.rs @@ -2,6 +2,7 @@ use fuels_core::{ types::{ errors::Result, transaction_builders::{Blob, BlobTransactionBuilder}, + tx_status::TxStatus, }, Configurables, }; @@ -143,28 +144,26 @@ impl Executable { } /// Uploads a blob containing the original executable code minus the data section. - pub async fn upload_blob(&self, account: impl fuels_accounts::Account) -> Result<()> { + pub async fn upload_blob( + &self, + account: impl fuels_accounts::Account, + ) -> Result> { let blob = self.blob(); let provider = account.try_provider()?; if provider.blob_exists(blob.id()).await? { - return Ok(()); + return Ok(None); } let mut tb = BlobTransactionBuilder::default().with_blob(self.blob()); - account.adjust_for_fee(&mut tb, 0).await?; - account.add_witnesses(&mut tb)?; let tx = tb.build(provider).await?; + let tx_status = provider.send_transaction_and_await_commit(tx).await?; + tx_status.check(None)?; - provider - .send_transaction_and_await_commit(tx) - .await? - .check(None)?; - - Ok(()) + Ok(Some(tx_status)) } } From 441a85d8b82bcd388df213283f7a165cebf809f0 Mon Sep 17 00:00:00 2001 From: hal3e Date: Wed, 5 Feb 2025 12:47:30 +0100 Subject: [PATCH 05/13] Work in progress --- packages/fuels-accounts/src/account.rs | 53 +++++++++++++++---- packages/fuels-core/src/types/tx_status.rs | 2 +- .../fuels-programs/src/contract/loader.rs | 12 ++--- .../fuels-programs/src/contract/regular.rs | 37 ++++++++----- packages/fuels-programs/src/executable.rs | 26 +++++++-- packages/fuels-programs/src/responses/call.rs | 2 +- 6 files changed, 96 insertions(+), 36 deletions(-) diff --git a/packages/fuels-accounts/src/account.rs b/packages/fuels-accounts/src/account.rs index 9883c173f1..0c0441403a 100644 --- a/packages/fuels-accounts/src/account.rs +++ b/packages/fuels-accounts/src/account.rs @@ -15,7 +15,6 @@ use fuels_core::types::{ transaction::{Transaction, TxPolicies}, transaction_builders::{BuildableTransaction, ScriptTransactionBuilder, TransactionBuilder}, transaction_response::TransactionResponse, - tx_status::TxStatus, }; use crate::{ @@ -26,6 +25,23 @@ use crate::{ provider::{Provider, ResourceFilter}, }; +#[derive(Clone, Debug)] +pub struct TransferResponse { + pub receipts: Vec, + pub gas_used: u64, + pub total_fee: u64, + pub tx_id: TxId, +} + +#[derive(Clone, Debug)] +pub struct WithdrawToBaseResponse { + pub receipts: Vec, + pub gas_used: u64, + pub total_fee: u64, + pub tx_id: TxId, + pub nonce: Nonce, +} + #[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait ViewOnlyAccount: std::fmt::Debug + Send + Sync + Clone { fn address(&self) -> &Bech32Address; @@ -170,7 +186,7 @@ pub trait Account: ViewOnlyAccount { amount: u64, asset_id: AssetId, tx_policies: TxPolicies, - ) -> Result<(TxId, TxStatus)> { + ) -> Result { let provider = self.try_provider()?; let inputs = self @@ -197,7 +213,12 @@ pub trait Account: ViewOnlyAccount { let tx_status = provider.send_transaction_and_await_commit(tx).await?; - Ok((tx_id, tx_status)) + Ok(TransferResponse { + gas_used: tx_status.total_gas(), + total_fee: tx_status.total_fee(), + receipts: tx_status.take_receipts_checked(None)?, + tx_id, + }) } /// Unconditionally transfers `balance` of type `asset_id` to @@ -215,7 +236,7 @@ pub trait Account: ViewOnlyAccount { balance: u64, asset_id: AssetId, tx_policies: TxPolicies, - ) -> Result<(String, Vec)> { + ) -> Result { let provider = self.try_provider()?; let zeroes = Bytes32::zeroed(); @@ -256,11 +277,15 @@ pub trait Account: ViewOnlyAccount { let consensus_parameters = provider.consensus_parameters().await?; let tx_id = tx.id(consensus_parameters.chain_id()); - let tx_status = provider.send_transaction_and_await_commit(tx).await?; - let receipts = tx_status.take_receipts_checked(None)?; + let tx_status = provider.send_transaction_and_await_commit(tx).await?; - Ok((tx_id.to_string(), receipts)) + Ok(TransferResponse { + gas_used: tx_status.total_gas(), + total_fee: tx_status.total_fee(), + receipts: tx_status.take_receipts_checked(None)?, + tx_id, + }) } /// Withdraws an amount of the base asset to @@ -271,7 +296,7 @@ pub trait Account: ViewOnlyAccount { to: &Bech32Address, amount: u64, tx_policies: TxPolicies, - ) -> Result<(TxId, Nonce, Vec)> { + ) -> Result { let provider = self.try_provider()?; let consensus_parameters = provider.consensus_parameters().await?; @@ -291,16 +316,24 @@ pub trait Account: ViewOnlyAccount { self.adjust_for_fee(&mut tb, amount).await?; let tx = tb.build(provider).await?; - let tx_id = tx.id(consensus_parameters.chain_id()); + let tx_status = provider.send_transaction_and_await_commit(tx).await?; + let gas_used = tx_status.total_gas(); + let total_fee = tx_status.total_fee(); let receipts = tx_status.take_receipts_checked(None)?; let nonce = extract_message_nonce(&receipts) .expect("MessageId could not be retrieved from tx receipts."); - Ok((tx_id, nonce, receipts)) + Ok(WithdrawToBaseResponse { + receipts, + gas_used, + total_fee, + tx_id, + nonce, + }) } } diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index c288a1c7bd..3dec59bf68 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -6,7 +6,7 @@ use fuel_abi_types::error_codes::{ use fuel_core_client::client::types::TransactionStatus as ClientTransactionStatus; #[cfg(feature = "std")] use fuel_core_types::services::executor::{TransactionExecutionResult, TransactionExecutionStatus}; -use fuel_tx::Receipt; +use fuel_tx::{Receipt, TxId}; #[cfg(feature = "std")] use fuel_vm::state::ProgramState; diff --git a/packages/fuels-programs/src/contract/loader.rs b/packages/fuels-programs/src/contract/loader.rs index d9fa4f0aa4..b53972cd1b 100644 --- a/packages/fuels-programs/src/contract/loader.rs +++ b/packages/fuels-programs/src/contract/loader.rs @@ -5,17 +5,15 @@ use fuels_accounts::Account; use fuels_core::{ constants::WORD_SIZE, types::{ - bech32::Bech32ContractId, errors::{error, Result}, transaction::TxPolicies, transaction_builders::{Blob, BlobId, BlobTransactionBuilder, TransactionBuilder}, - tx_status::TxStatus, }, }; use crate::{assembly::contract_call::loader_contract_asm, DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE}; -use super::{compute_contract_id_and_state_root, Contract, Regular}; +use super::{compute_contract_id_and_state_root, Contract, DeployResponse, Regular}; #[derive(Debug, Clone)] pub struct BlobsUploaded { @@ -160,7 +158,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result<(Bech32ContractId, TxStatus)> { + ) -> Result { self.upload_blobs(account, tx_policies) .await? .deploy(account, tx_policies) @@ -173,7 +171,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result<(Bech32ContractId, Option)> { + ) -> Result> { self.upload_blobs(account, tx_policies) .await? .deploy_if_not_exists(account, tx_policies) @@ -249,7 +247,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result<(Bech32ContractId, TxStatus)> { + ) -> Result { Contract::regular(self.code(), self.salt, self.storage_slots) .deploy(account, tx_policies) .await @@ -259,7 +257,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result<(Bech32ContractId, Option)> { + ) -> Result> { Contract::regular(self.code(), self.salt, self.storage_slots) .deploy_if_not_exists(account, tx_policies) .await diff --git a/packages/fuels-programs/src/contract/regular.rs b/packages/fuels-programs/src/contract/regular.rs index 3cef83b04a..8606e803c3 100644 --- a/packages/fuels-programs/src/contract/regular.rs +++ b/packages/fuels-programs/src/contract/regular.rs @@ -1,6 +1,6 @@ use std::{default::Default, fmt::Debug, path::Path}; -use fuel_tx::{Bytes32, ContractId, Salt, StorageSlot}; +use fuel_tx::{Bytes32, ContractId, Receipt, Salt, StorageSlot, TxId}; use fuels_accounts::Account; use fuels_core::{ constants::WORD_SIZE, @@ -8,9 +8,8 @@ use fuels_core::{ types::{ bech32::Bech32ContractId, errors::Result, - transaction::TxPolicies, + transaction::{Transaction, TxPolicies}, transaction_builders::{Blob, CreateTransactionBuilder}, - tx_status::TxStatus, }, Configurables, }; @@ -22,6 +21,15 @@ use super::{ Loader, StorageConfiguration, }; +#[derive(Clone, Debug)] +pub struct DeployResponse { + pub receipts: Vec, + pub gas_used: u64, + pub total_fee: u64, + pub tx_id: TxId, + pub contract_id: Bech32ContractId, +} + // In a mod so that we eliminate the footgun of getting the private `code` field without applying // configurables mod code_types { @@ -141,7 +149,7 @@ impl Contract { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result<(Bech32ContractId, TxStatus)> { + ) -> Result { let contract_id = self.contract_id(); let state_root = self.state_root(); let salt = self.salt; @@ -161,13 +169,20 @@ impl Contract { account.adjust_for_fee(&mut tb, 0).await?; let provider = account.try_provider()?; + let consensus_parameters = provider.consensus_parameters().await?; let tx = tb.build(provider).await?; + let tx_id = tx.id(consensus_parameters.chain_id()); let tx_status = provider.send_transaction_and_await_commit(tx).await?; - tx_status.check(None)?; - Ok((contract_id.into(), tx_status)) + Ok(DeployResponse { + gas_used: tx_status.total_gas(), + total_fee: tx_status.total_fee(), + receipts: tx_status.take_receipts_checked(None)?, + tx_id, + contract_id: contract_id.into(), + }) } /// Deploys a compiled contract to a running node if a contract with @@ -176,15 +191,13 @@ impl Contract { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result<(Bech32ContractId, Option)> { + ) -> Result> { let contract_id = Bech32ContractId::from(self.contract_id()); let provider = account.try_provider()?; if provider.contract_exists(&contract_id).await? { - Ok((contract_id, None)) + Ok(None) } else { - let (contract_id, tx_status) = self.deploy(account, tx_policies).await?; - - Ok((contract_id, Some(tx_status))) + Ok(Some(self.deploy(account, tx_policies).await?)) } } @@ -211,7 +224,7 @@ impl Contract { account: &impl Account, tx_policies: TxPolicies, max_words_per_blob: usize, - ) -> Result<(Bech32ContractId, TxStatus)> { + ) -> Result { let provider = account.try_provider()?; let max_contract_size = provider .consensus_parameters() diff --git a/packages/fuels-programs/src/executable.rs b/packages/fuels-programs/src/executable.rs index 26bbd9763e..dc315f5764 100644 --- a/packages/fuels-programs/src/executable.rs +++ b/packages/fuels-programs/src/executable.rs @@ -1,8 +1,9 @@ +use fuel_tx::{Receipt, TxId}; use fuels_core::{ types::{ errors::Result, + transaction::Transaction, transaction_builders::{Blob, BlobTransactionBuilder}, - tx_status::TxStatus, }, Configurables, }; @@ -28,6 +29,14 @@ impl Regular { } } +#[derive(Clone, Debug)] +pub struct UploadBlobResponse { + pub receipts: Vec, + pub gas_used: u64, + pub total_fee: u64, + pub tx_id: TxId, +} + /// Used to transform Script or Predicate code into a loader variant, where the code is uploaded as /// a blob and the binary itself is substituted with code that will load the blob code and apply /// the given configurables to the Script/Predicate. @@ -146,13 +155,14 @@ impl Executable { .expect("checked before turning into a Executable") } - /// Uploads a blob containing the original executable code minus the data section. + /// If not previously uploaded, uploads a blob containing the original executable code minus the data section. pub async fn upload_blob( &self, account: impl fuels_accounts::Account, - ) -> Result> { + ) -> Result> { let blob = self.blob(); let provider = account.try_provider()?; + let consensus_parameters = provider.consensus_parameters().await?; if provider.blob_exists(blob.id()).await? { return Ok(None); @@ -166,10 +176,16 @@ impl Executable { account.add_witnesses(&mut tb)?; let tx = tb.build(provider).await?; + let tx_id = tx.id(consensus_parameters.chain_id()); + let tx_status = provider.send_transaction_and_await_commit(tx).await?; - tx_status.check(None)?; - Ok(Some(tx_status)) + Ok(Some(UploadBlobResponse { + gas_used: tx_status.total_gas(), + total_fee: tx_status.total_fee(), + receipts: tx_status.take_receipts_checked(None)?, + tx_id, + })) } } diff --git a/packages/fuels-programs/src/responses/call.rs b/packages/fuels-programs/src/responses/call.rs index d84bed4ba2..523a9fdbf9 100644 --- a/packages/fuels-programs/src/responses/call.rs +++ b/packages/fuels-programs/src/responses/call.rs @@ -10,7 +10,7 @@ use fuels_core::{ /// [`CallResponse`] is a struct that is returned by a call to the contract or script. Its value /// field holds the decoded typed value returned by the contract's method. The other field holds all /// the receipts returned by the call. -#[derive(Debug)] +#[derive(Clone, Debug)] // ANCHOR: call_response pub struct CallResponse { pub value: D, From 23b648041ca00647ba036071c7be993607ff96ac Mon Sep 17 00:00:00 2001 From: hal3e Date: Wed, 5 Feb 2025 15:03:45 +0100 Subject: [PATCH 06/13] update types --- e2e/tests/configurables.rs | 15 ++- e2e/tests/contracts.rs | 78 ++++++++----- e2e/tests/logs.rs | 26 +++-- e2e/tests/predicates.rs | 53 +++++---- e2e/tests/providers.rs | 32 ++--- e2e/tests/scripts.rs | 12 +- e2e/tests/storage.rs | 10 +- e2e/tests/types_contracts.rs | 5 +- e2e/tests/types_predicates.rs | 15 ++- e2e/tests/wallets.rs | 8 +- examples/contracts/src/lib.rs | 110 ++++++++++-------- examples/cookbook/src/lib.rs | 5 +- examples/wallets/src/lib.rs | 12 +- packages/fuels-accounts/src/account.rs | 38 +++--- packages/fuels-core/src/types/tx_status.rs | 17 +++ .../src/setup_program_test/code_gen.rs | 4 +- .../fuels-programs/src/calls/call_handler.rs | 22 ++-- .../fuels-programs/src/contract/loader.rs | 4 +- .../fuels-programs/src/contract/regular.rs | 27 +++-- packages/fuels-programs/src/executable.rs | 16 +-- packages/fuels-programs/src/responses/call.rs | 14 +-- 21 files changed, 299 insertions(+), 224 deletions(-) diff --git a/e2e/tests/configurables.rs b/e2e/tests/configurables.rs index 2dbd4a8e6a..3bfb29997b 100644 --- a/e2e/tests/configurables.rs +++ b/e2e/tests/configurables.rs @@ -13,12 +13,13 @@ async fn contract_default_configurables() -> Result<()> { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/configurables/out/release/configurables.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet.clone()); @@ -125,12 +126,13 @@ async fn contract_configurables() -> Result<()> { .with_STRUCT(new_struct.clone())? .with_ENUM(new_enum.clone())?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/configurables/out/release/configurables.bin", LoadConfiguration::default().with_configurables(configurables), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet.clone()); // ANCHOR_END: contract_configurables @@ -192,13 +194,14 @@ async fn contract_manual_configurables() -> Result<()> { .with_STRUCT(new_struct.clone())? .with_ENUM(new_enum.clone())?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/configurables/out/release/configurables.bin", LoadConfiguration::default(), )? .with_configurables(configurables) .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet.clone()); diff --git a/e2e/tests/contracts.rs b/e2e/tests/contracts.rs index a86482f2d5..56470899c5 100644 --- a/e2e/tests/contracts.rs +++ b/e2e/tests/contracts.rs @@ -341,6 +341,7 @@ async fn contract_call_has_same_estimated_and_used_gas() -> Result<()> { .initialize_counter(42) .call() .await? + .tx .gas_used; assert_eq!(estimated_gas_used, gas_used); @@ -378,7 +379,11 @@ async fn mult_call_has_same_estimated_and_used_gas() -> Result<()> { .await? .gas_used; - let gas_used = multi_call_handler.call::<(u64, [u64; 2])>().await?.gas_used; + let gas_used = multi_call_handler + .call::<(u64, [u64; 2])>() + .await? + .tx + .gas_used; assert_eq!(estimated_gas_used, gas_used); Ok(()) @@ -679,12 +684,13 @@ async fn setup_output_variable_estimation_test() -> Result<( let wallet_config = WalletsConfig::new(Some(3), None, None); let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, None).await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/token_ops/out/release/token_ops.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallets[0], TxPolicies::default()) - .await?; + .await? + .contract_id; let mint_asset_id = contract_id.asset_id(&Bits256::zeroed()); let addresses = wallets @@ -1751,12 +1757,13 @@ async fn contract_encoder_config_is_applied() -> Result<()> { )), Wallets("wallet") ); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let instance = TestContract::new(contract_id.clone(), wallet.clone()); @@ -1960,12 +1967,13 @@ async fn simulations_can_be_made_without_coins() -> Result<()> { let wallets = setup_node_with_high_price().await?; let wallet = wallets.first().expect("has wallet"); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let provider = wallet.provider().cloned(); let no_funds_wallet = WalletUnlocked::new_random(provider); @@ -1991,12 +1999,13 @@ async fn simulations_can_be_made_without_coins_multicall() -> Result<()> { let wallets = setup_node_with_high_price().await?; let wallet = wallets.first().expect("has wallet"); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let provider = wallet.provider().cloned(); let no_funds_wallet = WalletUnlocked::new_random(provider); @@ -2050,12 +2059,13 @@ async fn contract_call_with_non_zero_base_asset_id_and_tip() -> Result<()> { let wallets = launch_custom_provider_and_get_wallets(wallet_config, None, Some(config)).await?; let wallet = wallets.first().expect("has wallet"); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet.clone()); @@ -2228,10 +2238,11 @@ async fn blob_contract_deployment() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; - let (contract_id, _) = contract + let contract_id = contract .convert_to_loader(100_000)? .deploy_if_not_exists(&wallets[0], TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallets[0].clone()); @@ -2256,9 +2267,10 @@ async fn regular_contract_can_be_deployed() -> Result<()> { let contract_binary = "sway/contracts/contract_test/out/release/contract_test.bin"; // when - let (contract_id, _) = Contract::load_from(contract_binary, LoadConfiguration::default())? + let contract_id = Contract::load_from(contract_binary, LoadConfiguration::default())? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // then let contract_instance = MyContract::new(contract_id, wallet); @@ -2287,10 +2299,11 @@ async fn unuploaded_loader_can_be_deployed_directly() -> Result<()> { let contract_binary = "sway/contracts/huge_contract/out/release/huge_contract.bin"; - let (contract_id, _) = Contract::load_from(contract_binary, LoadConfiguration::default())? + let contract_id = Contract::load_from(contract_binary, LoadConfiguration::default())? .convert_to_loader(1024)? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet); @@ -2323,13 +2336,15 @@ async fn unuploaded_loader_can_upload_blobs_separately_then_deploy() -> Result<( // if this were an example for the user we'd just call `deploy` on the contract above // this way we are testing that the blobs were really deployed above, otherwise the following // would fail - let (contract_id, _) = Contract::loader_from_blob_ids( + + let contract_id = Contract::loader_from_blob_ids( blob_ids.to_vec(), contract.salt(), contract.storage_slots().to_vec(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet); let response = contract_instance.methods().something().call().await?.value; @@ -2359,9 +2374,10 @@ async fn loader_blob_already_uploaded_not_an_issue() -> Result<()> { .await?; // this will try to upload the blobs but skip upon encountering an error - let (contract_id, _) = contract + let contract_id = contract .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet); let response = contract_instance.methods().something().call().await?.value; @@ -2389,16 +2405,18 @@ async fn loader_works_via_proxy() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; - let (contract_id, _) = contract + let contract_id = contract .convert_to_loader(100)? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_binary = "sway/contracts/proxy/out/release/proxy.bin"; - let (proxy_id, _) = Contract::load_from(contract_binary, LoadConfiguration::default())? + let proxy_id = Contract::load_from(contract_binary, LoadConfiguration::default())? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let proxy = MyProxy::new(proxy_id, wallet.clone()); proxy @@ -2440,20 +2458,22 @@ async fn loader_storage_works_via_proxy() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; let contract_storage_slots = contract.storage_slots().to_vec(); - let (contract_id, _) = contract + let contract_id = contract .convert_to_loader(100)? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_binary = "sway/contracts/proxy/out/release/proxy.bin"; let proxy_contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; let combined_storage_slots = [&contract_storage_slots, proxy_contract.storage_slots()].concat(); - let (proxy_id, _) = proxy_contract + let proxy_id = proxy_contract .with_storage_slots(combined_storage_slots) .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let proxy = MyProxy::new(proxy_id, wallet.clone()); proxy diff --git a/e2e/tests/logs.rs b/e2e/tests/logs.rs index d6a4d2e333..1883853e91 100644 --- a/e2e/tests/logs.rs +++ b/e2e/tests/logs.rs @@ -382,12 +382,13 @@ async fn test_multi_call_contract_with_contract_logs() -> Result<()> { ), ); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "./sway/logs/contract_logs/out/release/contract_logs.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id.clone(), wallet.clone()); @@ -737,12 +738,13 @@ async fn test_contract_with_contract_logs() -> Result<()> { ) ); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "./sway/logs/contract_logs/out/release/contract_logs.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id.clone(), wallet.clone()); @@ -828,6 +830,7 @@ async fn test_script_logs_with_contract_logs() -> Result<()> { { let num_contract_logs = response + .tx .receipts .iter() .filter(|receipt| matches!(receipt, Receipt::LogData { id, .. } | Receipt::Log { id, .. } if *id == contract_id)) @@ -1020,12 +1023,13 @@ async fn test_contract_require_from_contract() -> Result<()> { ) ); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "./sway/contracts/lib_contract/out/release/lib_contract.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id.clone(), wallet.clone()); @@ -1074,12 +1078,13 @@ async fn test_multi_call_contract_require_from_contract() -> Result<()> { ), ); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "./sway/contracts/lib_contract/out/release/lib_contract.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let lib_contract_instance = MyContract::new(contract_id.clone(), wallet.clone()); @@ -1166,10 +1171,11 @@ async fn test_loader_script_require_from_loader_contract() -> Result<()> { let contract_binary = "sway/contracts/lib_contract/out/release/lib_contract.bin"; let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; - let (contract_id, _) = contract + let contract_id = contract .convert_to_loader(100_000)? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet); let mut script_instance = script_instance; diff --git a/e2e/tests/predicates.rs b/e2e/tests/predicates.rs index 731afdeb12..12c1397e16 100644 --- a/e2e/tests/predicates.rs +++ b/e2e/tests/predicates.rs @@ -218,17 +218,18 @@ async fn pay_with_predicate() -> Result<()> { predicate.set_provider(provider.clone()); - let (contract_id, deploy_tx_status) = Contract::load_from( + let deploy_response = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; - let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); + let contract_methods = + MyContract::new(deploy_response.contract_id.clone(), predicate.clone()).methods(); let consensus_parameters = provider.consensus_parameters().await?; - let deploy_fee = deploy_tx_status.unwrap().total_fee(); + let deploy_fee = deploy_response.tx.unwrap().total_fee; assert_eq!( predicate .get_asset_balance(consensus_parameters.base_asset_id()) @@ -246,7 +247,7 @@ async fn pay_with_predicate() -> Result<()> { predicate .get_asset_balance(consensus_parameters.base_asset_id()) .await?, - predicate_balance - deploy_fee - response.total_fee + predicate_balance - deploy_fee - response.tx.total_fee ); Ok(()) @@ -281,17 +282,18 @@ async fn pay_with_predicate_vector_data() -> Result<()> { predicate.set_provider(provider.clone()); - let (contract_id, deploy_tx_status) = Contract::load_from( + let deploy_response = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; - let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); + let contract_methods = + MyContract::new(deploy_response.contract_id.clone(), predicate.clone()).methods(); let consensus_parameters = provider.consensus_parameters().await?; - let deploy_fee = deploy_tx_status.unwrap().total_fee(); + let deploy_fee = deploy_response.tx.unwrap().total_fee; assert_eq!( predicate .get_asset_balance(consensus_parameters.base_asset_id()) @@ -306,7 +308,7 @@ async fn pay_with_predicate_vector_data() -> Result<()> { predicate .get_asset_balance(consensus_parameters.base_asset_id()) .await?, - predicate_balance - deploy_fee - response.total_fee + predicate_balance - deploy_fee - response.tx.total_fee ); Ok(()) @@ -334,12 +336,13 @@ async fn predicate_contract_transfer() -> Result<()> { predicate.set_provider(provider.clone()); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&predicate, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_balances = provider.get_contract_balances(&contract_id).await?; assert!(contract_balances.is_empty()); @@ -395,7 +398,7 @@ async fn predicate_transfer_to_base_layer() -> Result<()> { Address::from_str("0x4710162c2e3a95a6faff05139150017c9e38e5e280432d546fae345d6ce6d8fe")?; let base_layer_address = Bech32Address::from(base_layer_address); - let (tx_id, msg_nonce, _receipts) = predicate + let withdraw_response = predicate .withdraw_to_base_layer(&base_layer_address, amount, TxPolicies::default()) .await?; @@ -404,7 +407,12 @@ async fn predicate_transfer_to_base_layer() -> Result<()> { let proof = predicate .try_provider()? - .get_message_proof(&tx_id, &msg_nonce, None, Some(2)) + .get_message_proof( + &withdraw_response.tx.id, + &withdraw_response.nonce, + None, + Some(2), + ) .await?; assert_eq!(proof.amount, amount); @@ -520,15 +528,15 @@ async fn contract_tx_and_call_params_with_predicate() -> Result<()> { predicate.set_provider(provider.clone()); - let (contract_id, deploy_tx_status) = Contract::load_from( + let deploy_response = Contract::load_from( "./sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&predicate, TxPolicies::default()) .await?; - println!("Contract deployed @ {contract_id}"); - let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); + let contract_methods = + MyContract::new(deploy_response.contract_id.clone(), predicate.clone()).methods(); let tx_policies = TxPolicies::default().with_tip(100); @@ -538,15 +546,15 @@ async fn contract_tx_and_call_params_with_predicate() -> Result<()> { .with_asset_id(AssetId::zeroed()); { - let response = contract_methods + let call_response = contract_methods .get_msg_amount() .with_tx_policies(tx_policies) .call_params(call_params.clone())? .call() .await?; - let deploy_fee = deploy_tx_status.unwrap().total_fee(); - let call_fee = response.total_fee; + let deploy_fee = deploy_response.tx.unwrap().total_fee; + let call_fee = call_response.tx.total_fee; assert_eq!( predicate.get_asset_balance(&AssetId::zeroed()).await?, predicate_balance - deploy_fee - call_params_amount - call_fee @@ -600,12 +608,13 @@ async fn diff_asset_predicate_payment() -> Result<()> { predicate.set_provider(provider.clone()); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "./sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&predicate, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_methods = MyContract::new(contract_id.clone(), predicate.clone()).methods(); @@ -724,7 +733,7 @@ async fn predicate_configurables() -> Result<()> { predicate.set_provider(provider.clone()); let amount_to_send = predicate_balance - 1; - let (_tx_id, tx_status) = predicate + let tx_response = predicate .transfer( receiver.address(), amount_to_send, @@ -737,7 +746,7 @@ async fn predicate_configurables() -> Result<()> { assert_address_balance(predicate.address(), &provider, asset_id, 0).await; // Funds were transferred - let fee = tx_status.total_fee(); + let fee = tx_response.total_fee; assert_address_balance( receiver.address(), &provider, diff --git a/e2e/tests/providers.rs b/e2e/tests/providers.rs index 3fe667a6cb..8cd18166eb 100644 --- a/e2e/tests/providers.rs +++ b/e2e/tests/providers.rs @@ -35,12 +35,13 @@ async fn test_provider_launch_and_connect() -> Result<()> { let provider = setup_test_provider(coins, vec![], None, None).await?; wallet.set_provider(provider.clone()); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance_connected = MyContract::new(contract_id.clone(), wallet.clone()); @@ -176,26 +177,26 @@ async fn test_input_message_pays_fee() -> Result<()> { abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json" )); - let (contract_id, deploy_tx_status) = Contract::load_from( + let deploy_response = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) .await?; - let contract_instance = MyContract::new(contract_id, wallet.clone()); + let contract_instance = MyContract::new(deploy_response.contract_id, wallet.clone()); - let response = contract_instance + let call_response = contract_instance .methods() .initialize_counter(42) .call() .await?; - assert_eq!(42, response.value); + assert_eq!(42, call_response.value); let balance = wallet.get_asset_balance(base_asset_id).await?; - let deploy_fee = deploy_tx_status.unwrap().total_fee(); - let call_fee = response.total_fee; + let deploy_fee = deploy_response.tx.unwrap().total_fee; + let call_fee = call_response.tx.total_fee; assert_eq!(balance, DEFAULT_COIN_AMOUNT - deploy_fee - call_fee); Ok(()) @@ -347,6 +348,7 @@ async fn test_gas_forwarded_defaults_to_tx_limit() -> Result<()> { .await?; let gas_forwarded = response + .tx .receipts .iter() .find(|r| matches!(r, Receipt::Call { .. })) @@ -407,6 +409,7 @@ async fn test_amount_and_asset_forwarding() -> Result<()> { assert_eq!(response.value, 1_000_000); let call_response = response + .tx .receipts .iter() .find(|&r| matches!(r, Receipt::Call { .. })); @@ -444,6 +447,7 @@ async fn test_amount_and_asset_forwarding() -> Result<()> { assert_eq!(response.value, 0); let call_response = response + .tx .receipts .iter() .find(|&r| matches!(r, Receipt::Call { .. })); @@ -587,6 +591,7 @@ async fn test_get_gas_used() -> Result<()> { .initialize_counter(42) .call() .await? + .tx .gas_used; assert!(gas_used > 0); @@ -603,13 +608,13 @@ async fn test_parse_block_time() -> Result<()> { let tx_policies = TxPolicies::default().with_script_gas_limit(2000); let wallet_2 = WalletUnlocked::new_random(None).lock(); - let (tx_id, _) = wallet + let tx_response = wallet .transfer(wallet_2.address(), 100, asset_id, tx_policies) .await?; let tx_response = wallet .try_provider()? - .get_transaction_by_id(&tx_id) + .get_transaction_by_id(&tx_response.id) .await? .unwrap(); assert!(tx_response.time.is_some()); @@ -1112,7 +1117,7 @@ async fn tx_respects_policies() -> Result<()> { .await?; let tx_response = provider - .get_transaction_by_id(&response.tx_id.unwrap()) + .get_transaction_by_id(&response.tx.id.unwrap()) .await? .expect("tx should exist"); let script = match tx_response.transaction { @@ -1246,12 +1251,13 @@ async fn contract_call_with_impersonation() -> Result<()> { abi = "e2e/sway/contracts/contract_test/out/release/contract_test-abi.json" )); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, impersonator.clone()); diff --git a/e2e/tests/scripts.rs b/e2e/tests/scripts.rs index ee733682a2..65fca7ebc8 100644 --- a/e2e/tests/scripts.rs +++ b/e2e/tests/scripts.rs @@ -65,7 +65,7 @@ async fn script_call_has_same_estimated_and_used_gas() -> Result<()> { .await? .gas_used; - let gas_used = script_instance.main(a, b).call().await?.gas_used; + let gas_used = script_instance.main(a, b).call().await?.tx.gas_used; assert_eq!(estimated_gas_used, gas_used); @@ -595,17 +595,19 @@ async fn loader_script_calling_loader_proxy() -> Result<()> { let contract = Contract::load_from(contract_binary, LoadConfiguration::default())?; - let (contract_id, _) = contract + let contract_id = contract .convert_to_loader(100)? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_binary = "sway/contracts/proxy/out/release/proxy.bin"; - let (proxy_id, _) = Contract::load_from(contract_binary, LoadConfiguration::default())? + let proxy_id = Contract::load_from(contract_binary, LoadConfiguration::default())? .convert_to_loader(100)? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let proxy = MyProxy::new(proxy_id.clone(), wallet.clone()); proxy diff --git a/e2e/tests/storage.rs b/e2e/tests/storage.rs index 3410dab304..8dbf21c3d9 100644 --- a/e2e/tests/storage.rs +++ b/e2e/tests/storage.rs @@ -19,12 +19,13 @@ async fn test_storage_initialization() -> Result<()> { let storage_vec = vec![storage_slot.clone()]; let storage_configuration = StorageConfiguration::default().add_slot_overrides(storage_vec); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/storage/out/release/storage.bin", LoadConfiguration::default().with_storage_configuration(storage_configuration), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_instance = MyContract::new(contract_id, wallet.clone()); @@ -48,12 +49,13 @@ async fn test_init_storage_automatically() -> Result<()> { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/contracts/storage/out/release/storage.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); { diff --git a/e2e/tests/types_contracts.rs b/e2e/tests/types_contracts.rs index 21742b32b6..cd2809bba7 100644 --- a/e2e/tests/types_contracts.rs +++ b/e2e/tests/types_contracts.rs @@ -76,12 +76,13 @@ async fn call_with_structs() -> Result<()> { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "sway/types/contracts/complex_types_contract/out/release/complex_types_contract.bin", LoadConfiguration::default(), )? .deploy_if_not_exists(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_methods = MyContract::new(contract_id, wallet).methods(); diff --git a/e2e/tests/types_predicates.rs b/e2e/tests/types_predicates.rs index 3ea61c5c4f..8890e962eb 100644 --- a/e2e/tests/types_predicates.rs +++ b/e2e/tests/types_predicates.rs @@ -13,20 +13,25 @@ async fn assert_predicate_spendable(data: Vec, project_path: impl AsRef Result<()> { // Transfer 1 from wallet 1 to wallet 2. const SEND_AMOUNT: u64 = 1; let base_asset_id = AssetId::zeroed(); - let (tx_id, _tx_status) = wallet_1 + let tx_response = wallet_1 .transfer(wallet_2.address(), SEND_AMOUNT, base_asset_id, tx_policies) .await?; // Assert that the transaction was properly configured. let res = wallet_1 .try_provider()? - .get_transaction_by_id(&tx_id) + .get_transaction_by_id(&tx_response.id) .await? .unwrap(); @@ -304,7 +304,7 @@ async fn transfer_coins_with_change() -> Result<()> { // Transfer 2 from wallet 1 to wallet 2. const SEND_AMOUNT: u64 = 2; - let (_tx_id, tx_status) = wallet_1 + let tx_response = wallet_1 .transfer( wallet_2.address(), SEND_AMOUNT, @@ -320,7 +320,7 @@ async fn transfer_coins_with_change() -> Result<()> { // Assert that we've sent 2 from wallet 1, resulting in an amount of 3 in wallet 1. let resulting_amount = wallet_1_final_coins.first().unwrap(); - let fee = tx_status.total_fee(); + let fee = tx_response.total_fee; assert_eq!(resulting_amount.amount(), AMOUNT - SEND_AMOUNT - fee); let wallet_2_final_coins = wallet_2.get_coins(base_asset_id).await?; diff --git a/examples/contracts/src/lib.rs b/examples/contracts/src/lib.rs index f8d2035cc8..62189b5815 100644 --- a/examples/contracts/src/lib.rs +++ b/examples/contracts/src/lib.rs @@ -45,12 +45,13 @@ mod tests { // This will load and deploy your contract binary to the chain so that its ID can // be used to initialize the instance - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; println!("Contract deployed @ {contract_id}"); // ANCHOR_END: deploy_contract @@ -99,12 +100,13 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR: contract_call_cost_estimation let contract_instance = MyContract::new(contract_id, wallet); @@ -132,14 +134,13 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id_1, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; - - println!("Contract deployed @ {contract_id_1}"); + .await? + .contract_id; // ANCHOR: deploy_with_parameters // Optional: Add `Salt` @@ -162,17 +163,18 @@ mod tests { .with_script_gas_limit(1_000_000) .with_maturity(0); - let (contract_id_2, _) = Contract::load_from( + let contract_id_2 = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", configuration, )? .deploy(&wallet, tx_policies) - .await?; + .await? + .contract_id; println!("Contract deployed @ {contract_id_2}"); // ANCHOR_END: deploy_with_parameters - assert_ne!(contract_id_1, contract_id_2); + assert_ne!(contract_id, contract_id_2); // ANCHOR: use_deployed_contract // This will generate your contract's methods onto `MyContract`. @@ -233,15 +235,15 @@ mod tests { let wallets = launch_custom_provider_and_get_wallets(WalletsConfig::default(), None, None).await?; - let (contract_id_1, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallets[0], TxPolicies::default()) - .await?; + .await? + .contract_id; - println!("Contract deployed @ {contract_id_1}"); - let contract_instance_1 = MyContract::new(contract_id_1, wallets[0].clone()); + let contract_instance_1 = MyContract::new(contract_id, wallets[0].clone()); let response = contract_instance_1 .methods() @@ -251,14 +253,14 @@ mod tests { assert_eq!(42, response.value); - let (contract_id_2, _) = Contract::load_from( + let contract_id_2 = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default().with_salt([1; 32]), )? .deploy(&wallets[1], TxPolicies::default()) - .await?; + .await? + .contract_id; - println!("Contract deployed @ {contract_id_2}"); let contract_instance_2 = MyContract::new(contract_id_2, wallets[1].clone()); let response = contract_instance_2 @@ -283,14 +285,14 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; - println!("Contract deployed @ {contract_id}"); // ANCHOR: tx_policies let contract_methods = MyContract::new(contract_id.clone(), wallet.clone()).methods(); @@ -352,15 +354,15 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/token_ops/out/release/token_ops\ .bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; - println!("Contract deployed @ {contract_id}"); let contract_methods = MyContract::new(contract_id.clone(), wallet.clone()).methods(); // ANCHOR: simulate // you would mint 100 coins if the transaction wasn't simulated @@ -414,14 +416,15 @@ mod tests { )? .deploy(&wallet, TxPolicies::default()) .await? - .0 + .contract_id .into(); let bin_path = "../../e2e/sway/contracts/lib_contract_caller/out/release/lib_contract_caller.bin"; - let (caller_contract_id, _) = Contract::load_from(bin_path, LoadConfiguration::default())? + let caller_contract_id = Contract::load_from(bin_path, LoadConfiguration::default())? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_methods = MyContract::new(caller_contract_id.clone(), wallet.clone()).methods(); @@ -514,12 +517,13 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); @@ -552,12 +556,13 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR: multi_call_prepare let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); @@ -610,12 +615,13 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_methods = MyContract::new(contract_id, wallet.clone()).methods(); @@ -655,12 +661,13 @@ mod tests { let wallet_1 = wallets.pop().unwrap(); let wallet_2 = wallets.pop().unwrap(); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet_1, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR: connect_wallet // Create contract instance with wallet_1 @@ -964,12 +971,13 @@ mod tests { let provider = setup_test_provider(coins, vec![], Some(node_config), None).await?; wallet.set_provider(provider.clone()); - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR: contract_call_impersonation // create impersonator for an address @@ -1061,34 +1069,37 @@ mod tests { already_uploaded_blobs.insert(blob_id); } - let (contract_id, _) = Contract::loader_from_blob_ids(all_blob_ids, random_salt(), vec![])? + let contract_id = Contract::loader_from_blob_ids(all_blob_ids, random_salt(), vec![])? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR_END: manual_blob_upload_then_deploy // ANCHOR: deploy_via_loader let max_words_per_blob = 10_000; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( contract_binary, LoadConfiguration::default().with_salt(random_salt()), )? .convert_to_loader(max_words_per_blob)? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR_END: deploy_via_loader // ANCHOR: auto_convert_to_loader let max_words_per_blob = 10_000; - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( contract_binary, LoadConfiguration::default().with_salt(random_salt()), )? .smart_deploy(&wallet, TxPolicies::default(), max_words_per_blob) - .await?; + .await? + .contract_id; // ANCHOR_END: auto_convert_to_loader // ANCHOR: upload_blobs_then_deploy - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( contract_binary, LoadConfiguration::default().with_salt(random_salt()), )? @@ -1096,7 +1107,8 @@ mod tests { .upload_blobs(&wallet, TxPolicies::default()) .await? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR_END: upload_blobs_then_deploy let wallet = main_wallet.clone(); @@ -1135,9 +1147,10 @@ mod tests { .map(|chunk| Blob::new(chunk.to_vec())) .collect(); - let (contract_id, _) = Contract::loader_from_blobs(blobs, random_salt(), vec![])? + let contract_id = Contract::loader_from_blobs(blobs, random_salt(), vec![])? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR_END: manual_blobs_then_deploy // ANCHOR: estimate_max_blob_size @@ -1172,7 +1185,8 @@ mod tests { .initialize_counter(42) .call() .await? - .tx_id + .tx + .id .unwrap(); let provider: &Provider = wallet.try_provider()?; diff --git a/examples/cookbook/src/lib.rs b/examples/cookbook/src/lib.rs index 62776be101..34735759ba 100644 --- a/examples/cookbook/src/lib.rs +++ b/examples/cookbook/src/lib.rs @@ -51,12 +51,13 @@ mod tests { // ANCHOR_END: liquidity_wallet // ANCHOR: liquidity_deploy - let (contract_id, _) = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/liquidity_pool/out/release/liquidity_pool.bin", LoadConfiguration::default(), )? .deploy(wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; let contract_methods = MyContract::new(contract_id.clone(), wallet.clone()).methods(); // ANCHOR_END: liquidity_deploy diff --git a/examples/wallets/src/lib.rs b/examples/wallets/src/lib.rs index aa36669ea2..076dd9ea30 100644 --- a/examples/wallets/src/lib.rs +++ b/examples/wallets/src/lib.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod tests { - use fuels::prelude::*; + use fuels::{prelude::*, programs::contract::DeployResponse}; #[tokio::test] async fn create_random_wallet() -> Result<()> { @@ -135,7 +135,7 @@ mod tests { // Transfer the base asset with amount 1 from wallet 1 to wallet 2 let transfer_amount = 1; let asset_id = Default::default(); - let (_tx_id, _receipts) = wallets[0] + let _res = wallets[0] .transfer( wallets[1].address(), transfer_amount, @@ -180,7 +180,7 @@ mod tests { .pop() .unwrap(); - let (contract_id, _) = Contract::load_from( + let DeployResponse { contract_id, .. } = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -198,7 +198,7 @@ mod tests { // Transfer an amount of 300 to the contract let amount = 300; let asset_id = random_asset_id; - let (_tx_id, _receipts) = wallet + let _res = wallet .force_transfer_to_contract(&contract_id, amount, asset_id, TxPolicies::default()) .await?; @@ -369,7 +369,7 @@ mod tests { )?; let base_layer_address = Bech32Address::from(base_layer_address); // Transfer an amount of 1000 to the specified base layer address - let (tx_id, msg_id, _receipts) = wallet + let response = wallet .withdraw_to_base_layer(&base_layer_address, amount, TxPolicies::default()) .await?; @@ -378,7 +378,7 @@ mod tests { // Retrieve a message proof from the provider let proof = wallet .try_provider()? - .get_message_proof(&tx_id, &msg_id, None, Some(2)) + .get_message_proof(&response.tx.id, &response.nonce, None, Some(2)) .await?; // Verify the amount and recipient diff --git a/packages/fuels-accounts/src/account.rs b/packages/fuels-accounts/src/account.rs index 0c0441403a..c2e0eb5d3d 100644 --- a/packages/fuels-accounts/src/account.rs +++ b/packages/fuels-accounts/src/account.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use async_trait::async_trait; use fuel_core_client::client::pagination::{PaginatedResult, PaginationRequest}; -use fuel_tx::{Output, Receipt, TxId, TxPointer, UtxoId}; +use fuel_tx::{Output, TxPointer, UtxoId}; use fuel_types::{AssetId, Bytes32, ContractId, Nonce}; use fuels_core::types::{ bech32::{Bech32Address, Bech32ContractId}, @@ -15,6 +15,7 @@ use fuels_core::types::{ transaction::{Transaction, TxPolicies}, transaction_builders::{BuildableTransaction, ScriptTransactionBuilder, TransactionBuilder}, transaction_response::TransactionResponse, + tx_status::TxResponse, }; use crate::{ @@ -25,20 +26,9 @@ use crate::{ provider::{Provider, ResourceFilter}, }; -#[derive(Clone, Debug)] -pub struct TransferResponse { - pub receipts: Vec, - pub gas_used: u64, - pub total_fee: u64, - pub tx_id: TxId, -} - #[derive(Clone, Debug)] pub struct WithdrawToBaseResponse { - pub receipts: Vec, - pub gas_used: u64, - pub total_fee: u64, - pub tx_id: TxId, + pub tx: TxResponse, pub nonce: Nonce, } @@ -186,7 +176,7 @@ pub trait Account: ViewOnlyAccount { amount: u64, asset_id: AssetId, tx_policies: TxPolicies, - ) -> Result { + ) -> Result { let provider = self.try_provider()?; let inputs = self @@ -213,11 +203,11 @@ pub trait Account: ViewOnlyAccount { let tx_status = provider.send_transaction_and_await_commit(tx).await?; - Ok(TransferResponse { + Ok(TxResponse { gas_used: tx_status.total_gas(), total_fee: tx_status.total_fee(), receipts: tx_status.take_receipts_checked(None)?, - tx_id, + id: tx_id, }) } @@ -236,7 +226,7 @@ pub trait Account: ViewOnlyAccount { balance: u64, asset_id: AssetId, tx_policies: TxPolicies, - ) -> Result { + ) -> Result { let provider = self.try_provider()?; let zeroes = Bytes32::zeroed(); @@ -280,11 +270,11 @@ pub trait Account: ViewOnlyAccount { let tx_status = provider.send_transaction_and_await_commit(tx).await?; - Ok(TransferResponse { + Ok(TxResponse { gas_used: tx_status.total_gas(), total_fee: tx_status.total_fee(), receipts: tx_status.take_receipts_checked(None)?, - tx_id, + id: tx_id, }) } @@ -328,10 +318,12 @@ pub trait Account: ViewOnlyAccount { .expect("MessageId could not be retrieved from tx receipts."); Ok(WithdrawToBaseResponse { - receipts, - gas_used, - total_fee, - tx_id, + tx: TxResponse { + receipts, + gas_used, + total_fee, + id: tx_id, + }, nonce, }) } diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index 3dec59bf68..b3d5bf69fd 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -12,9 +12,26 @@ use fuel_vm::state::ProgramState; use crate::{ codec::LogDecoder, + sealed::Sealed, types::errors::{transaction::Reason, Error, Result}, }; +impl Sealed for TxId {} +impl Sealed for Option {} + +pub trait TxResponseType: Sealed {} + +impl TxResponseType for TxId {} +impl TxResponseType for Option {} + +#[derive(Clone, Debug)] +pub struct TxResponse { + pub receipts: Vec, + pub gas_used: u64, + pub total_fee: u64, + pub id: T, +} + #[derive(Debug, Clone)] pub enum TxStatus { Success { diff --git a/packages/fuels-macros/src/setup_program_test/code_gen.rs b/packages/fuels-macros/src/setup_program_test/code_gen.rs index 6e256f023e..b651918ee0 100644 --- a/packages/fuels-macros/src/setup_program_test/code_gen.rs +++ b/packages/fuels-macros/src/setup_program_test/code_gen.rs @@ -154,14 +154,14 @@ fn contract_deploying_code( ) .expect("Failed to load the contract"); - let (contract_id, _) = loaded_contract.deploy_if_not_exists( + let response = loaded_contract.deploy_if_not_exists( &#wallet_name, ::fuels::types::transaction::TxPolicies::default() ) .await .expect("Failed to deploy the contract"); - #contract_struct_name::new(contract_id, #wallet_name.clone()) + #contract_struct_name::new(response.contract_id, #wallet_name.clone()) }; } }) diff --git a/packages/fuels-programs/src/calls/call_handler.rs b/packages/fuels-programs/src/calls/call_handler.rs index 5df81e5d0a..dd173b9903 100644 --- a/packages/fuels-programs/src/calls/call_handler.rs +++ b/packages/fuels-programs/src/calls/call_handler.rs @@ -15,7 +15,7 @@ use fuels_core::{ BuildableTransaction, ScriptBuildStrategy, ScriptTransactionBuilder, VariableOutputPolicy, }, - tx_status::TxStatus, + tx_status::{TxResponse, TxStatus}, Selector, Token, }, }; @@ -220,11 +220,13 @@ where Ok(CallResponse { value: T::from_token(token)?, - receipts, - gas_used, - total_fee, log_decoder: self.log_decoder.clone(), - tx_id: self.cached_tx_id, + tx: TxResponse { + receipts, + gas_used, + total_fee, + id: self.cached_tx_id, + }, }) } @@ -503,11 +505,13 @@ where Ok(CallResponse { value: T::from_token(tokens_as_tuple)?, - receipts, - gas_used, - total_fee, log_decoder: self.log_decoder.clone(), - tx_id: self.cached_tx_id, + tx: TxResponse { + receipts, + gas_used, + total_fee, + id: self.cached_tx_id, + }, }) } diff --git a/packages/fuels-programs/src/contract/loader.rs b/packages/fuels-programs/src/contract/loader.rs index b53972cd1b..efa8087a13 100644 --- a/packages/fuels-programs/src/contract/loader.rs +++ b/packages/fuels-programs/src/contract/loader.rs @@ -171,7 +171,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result> { + ) -> Result { self.upload_blobs(account, tx_policies) .await? .deploy_if_not_exists(account, tx_policies) @@ -257,7 +257,7 @@ impl Contract> { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result> { + ) -> Result { Contract::regular(self.code(), self.salt, self.storage_slots) .deploy_if_not_exists(account, tx_policies) .await diff --git a/packages/fuels-programs/src/contract/regular.rs b/packages/fuels-programs/src/contract/regular.rs index 8606e803c3..ec69104df1 100644 --- a/packages/fuels-programs/src/contract/regular.rs +++ b/packages/fuels-programs/src/contract/regular.rs @@ -1,6 +1,6 @@ use std::{default::Default, fmt::Debug, path::Path}; -use fuel_tx::{Bytes32, ContractId, Receipt, Salt, StorageSlot, TxId}; +use fuel_tx::{Bytes32, ContractId, Salt, StorageSlot}; use fuels_accounts::Account; use fuels_core::{ constants::WORD_SIZE, @@ -10,6 +10,7 @@ use fuels_core::{ errors::Result, transaction::{Transaction, TxPolicies}, transaction_builders::{Blob, CreateTransactionBuilder}, + tx_status::TxResponse, }, Configurables, }; @@ -23,10 +24,7 @@ use super::{ #[derive(Clone, Debug)] pub struct DeployResponse { - pub receipts: Vec, - pub gas_used: u64, - pub total_fee: u64, - pub tx_id: TxId, + pub tx: Option, pub contract_id: Bech32ContractId, } @@ -177,10 +175,12 @@ impl Contract { let tx_status = provider.send_transaction_and_await_commit(tx).await?; Ok(DeployResponse { - gas_used: tx_status.total_gas(), - total_fee: tx_status.total_fee(), - receipts: tx_status.take_receipts_checked(None)?, - tx_id, + tx: Some(TxResponse { + gas_used: tx_status.total_gas(), + total_fee: tx_status.total_fee(), + receipts: tx_status.take_receipts_checked(None)?, + id: tx_id, + }), contract_id: contract_id.into(), }) } @@ -191,13 +191,16 @@ impl Contract { self, account: &impl Account, tx_policies: TxPolicies, - ) -> Result> { + ) -> Result { let contract_id = Bech32ContractId::from(self.contract_id()); let provider = account.try_provider()?; if provider.contract_exists(&contract_id).await? { - Ok(None) + Ok(DeployResponse { + tx: None, + contract_id, + }) } else { - Ok(Some(self.deploy(account, tx_policies).await?)) + self.deploy(account, tx_policies).await } } diff --git a/packages/fuels-programs/src/executable.rs b/packages/fuels-programs/src/executable.rs index dc315f5764..aa4a172515 100644 --- a/packages/fuels-programs/src/executable.rs +++ b/packages/fuels-programs/src/executable.rs @@ -1,9 +1,9 @@ -use fuel_tx::{Receipt, TxId}; use fuels_core::{ types::{ errors::Result, transaction::Transaction, transaction_builders::{Blob, BlobTransactionBuilder}, + tx_status::TxResponse, }, Configurables, }; @@ -29,14 +29,6 @@ impl Regular { } } -#[derive(Clone, Debug)] -pub struct UploadBlobResponse { - pub receipts: Vec, - pub gas_used: u64, - pub total_fee: u64, - pub tx_id: TxId, -} - /// Used to transform Script or Predicate code into a loader variant, where the code is uploaded as /// a blob and the binary itself is substituted with code that will load the blob code and apply /// the given configurables to the Script/Predicate. @@ -159,7 +151,7 @@ impl Executable { pub async fn upload_blob( &self, account: impl fuels_accounts::Account, - ) -> Result> { + ) -> Result> { let blob = self.blob(); let provider = account.try_provider()?; let consensus_parameters = provider.consensus_parameters().await?; @@ -180,11 +172,11 @@ impl Executable { let tx_status = provider.send_transaction_and_await_commit(tx).await?; - Ok(Some(UploadBlobResponse { + Ok(Some(TxResponse { gas_used: tx_status.total_gas(), total_fee: tx_status.total_fee(), receipts: tx_status.take_receipts_checked(None)?, - tx_id, + id: tx_id, })) } } diff --git a/packages/fuels-programs/src/responses/call.rs b/packages/fuels-programs/src/responses/call.rs index 523a9fdbf9..246b0aa16b 100644 --- a/packages/fuels-programs/src/responses/call.rs +++ b/packages/fuels-programs/src/responses/call.rs @@ -1,10 +1,10 @@ use std::fmt::Debug; -use fuel_tx::{Bytes32, Receipt}; +use fuel_tx::TxId; use fuels_core::{ codec::{LogDecoder, LogResult}, traits::{Parameterize, Tokenizable}, - types::errors::Result, + types::{errors::Result, tx_status::TxResponse}, }; /// [`CallResponse`] is a struct that is returned by a call to the contract or script. Its value @@ -14,20 +14,18 @@ use fuels_core::{ // ANCHOR: call_response pub struct CallResponse { pub value: D, - pub receipts: Vec, - pub gas_used: u64, - pub total_fee: u64, + pub tx: TxResponse>, pub log_decoder: LogDecoder, - pub tx_id: Option, } // ANCHOR_END: call_response impl CallResponse { pub fn decode_logs(&self) -> LogResult { - self.log_decoder.decode_logs(&self.receipts) + self.log_decoder.decode_logs(&self.tx.receipts) } pub fn decode_logs_with_type(&self) -> Result> { - self.log_decoder.decode_logs_with_type::(&self.receipts) + self.log_decoder + .decode_logs_with_type::(&self.tx.receipts) } } From f2b4506198032a20d52a6125e15da6a2686e140a Mon Sep 17 00:00:00 2001 From: hal3e Date: Wed, 5 Feb 2025 15:15:49 +0100 Subject: [PATCH 07/13] change var names --- examples/contracts/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/contracts/src/lib.rs b/examples/contracts/src/lib.rs index 62189b5815..991e6d04b4 100644 --- a/examples/contracts/src/lib.rs +++ b/examples/contracts/src/lib.rs @@ -134,7 +134,7 @@ mod tests { let wallet = launch_provider_and_get_wallet().await?; - let contract_id = Contract::load_from( + let contract_id_1 = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -174,7 +174,7 @@ mod tests { println!("Contract deployed @ {contract_id_2}"); // ANCHOR_END: deploy_with_parameters - assert_ne!(contract_id, contract_id_2); + assert_ne!(contract_id_1, contract_id_2); // ANCHOR: use_deployed_contract // This will generate your contract's methods onto `MyContract`. @@ -235,7 +235,7 @@ mod tests { let wallets = launch_custom_provider_and_get_wallets(WalletsConfig::default(), None, None).await?; - let contract_id = Contract::load_from( + let contract_id_1 = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? @@ -243,7 +243,7 @@ mod tests { .await? .contract_id; - let contract_instance_1 = MyContract::new(contract_id, wallets[0].clone()); + let contract_instance_1 = MyContract::new(contract_id_1, wallets[0].clone()); let response = contract_instance_1 .methods() From 1c09a660e1e025721b233c23235ba7aec274db5f Mon Sep 17 00:00:00 2001 From: hal3e Date: Thu, 6 Feb 2025 16:08:17 +0100 Subject: [PATCH 08/13] refactor --- examples/wallets/src/lib.rs | 7 ++++--- packages/fuels-accounts/src/account.rs | 2 +- packages/fuels-core/src/types.rs | 1 + packages/fuels-core/src/types/tx_response.rs | 19 +++++++++++++++++++ packages/fuels-core/src/types/tx_status.rs | 19 +------------------ .../fuels-programs/src/calls/call_handler.rs | 3 ++- .../fuels-programs/src/contract/regular.rs | 2 +- packages/fuels-programs/src/executable.rs | 2 +- packages/fuels-programs/src/responses/call.rs | 2 +- 9 files changed, 31 insertions(+), 26 deletions(-) create mode 100644 packages/fuels-core/src/types/tx_response.rs diff --git a/examples/wallets/src/lib.rs b/examples/wallets/src/lib.rs index 076dd9ea30..f9e1094365 100644 --- a/examples/wallets/src/lib.rs +++ b/examples/wallets/src/lib.rs @@ -1,6 +1,6 @@ #[cfg(test)] mod tests { - use fuels::{prelude::*, programs::contract::DeployResponse}; + use fuels::prelude::*; #[tokio::test] async fn create_random_wallet() -> Result<()> { @@ -180,12 +180,13 @@ mod tests { .pop() .unwrap(); - let DeployResponse { contract_id, .. } = Contract::load_from( + let contract_id = Contract::load_from( "../../e2e/sway/contracts/contract_test/out/release/contract_test.bin", LoadConfiguration::default(), )? .deploy(&wallet, TxPolicies::default()) - .await?; + .await? + .contract_id; // ANCHOR: wallet_contract_transfer // Check the current balance of the contract with id 'contract_id' diff --git a/packages/fuels-accounts/src/account.rs b/packages/fuels-accounts/src/account.rs index c2e0eb5d3d..e024e429ed 100644 --- a/packages/fuels-accounts/src/account.rs +++ b/packages/fuels-accounts/src/account.rs @@ -15,7 +15,7 @@ use fuels_core::types::{ transaction::{Transaction, TxPolicies}, transaction_builders::{BuildableTransaction, ScriptTransactionBuilder, TransactionBuilder}, transaction_response::TransactionResponse, - tx_status::TxResponse, + tx_response::TxResponse, }; use crate::{ diff --git a/packages/fuels-core/src/types.rs b/packages/fuels-core/src/types.rs index 484fd12399..512695330c 100644 --- a/packages/fuels-core/src/types.rs +++ b/packages/fuels-core/src/types.rs @@ -14,6 +14,7 @@ pub mod errors; pub mod param_types; mod token; pub mod transaction_builders; +pub mod tx_response; pub mod tx_status; mod wrappers; pub use dry_runner::*; diff --git a/packages/fuels-core/src/types/tx_response.rs b/packages/fuels-core/src/types/tx_response.rs new file mode 100644 index 0000000000..0077b480f3 --- /dev/null +++ b/packages/fuels-core/src/types/tx_response.rs @@ -0,0 +1,19 @@ +use fuel_tx::{Receipt, TxId}; + +use crate::sealed::Sealed; + +#[derive(Clone, Debug)] +pub struct TxResponse { + pub receipts: Vec, + pub gas_used: u64, + pub total_fee: u64, + pub id: T, +} + +impl Sealed for TxId {} +impl Sealed for Option {} + +pub trait TxResponseType: Sealed {} + +impl TxResponseType for TxId {} +impl TxResponseType for Option {} diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index b3d5bf69fd..c288a1c7bd 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -6,32 +6,15 @@ use fuel_abi_types::error_codes::{ use fuel_core_client::client::types::TransactionStatus as ClientTransactionStatus; #[cfg(feature = "std")] use fuel_core_types::services::executor::{TransactionExecutionResult, TransactionExecutionStatus}; -use fuel_tx::{Receipt, TxId}; +use fuel_tx::Receipt; #[cfg(feature = "std")] use fuel_vm::state::ProgramState; use crate::{ codec::LogDecoder, - sealed::Sealed, types::errors::{transaction::Reason, Error, Result}, }; -impl Sealed for TxId {} -impl Sealed for Option {} - -pub trait TxResponseType: Sealed {} - -impl TxResponseType for TxId {} -impl TxResponseType for Option {} - -#[derive(Clone, Debug)] -pub struct TxResponse { - pub receipts: Vec, - pub gas_used: u64, - pub total_fee: u64, - pub id: T, -} - #[derive(Debug, Clone)] pub enum TxStatus { Success { diff --git a/packages/fuels-programs/src/calls/call_handler.rs b/packages/fuels-programs/src/calls/call_handler.rs index dd173b9903..efc1888286 100644 --- a/packages/fuels-programs/src/calls/call_handler.rs +++ b/packages/fuels-programs/src/calls/call_handler.rs @@ -15,7 +15,8 @@ use fuels_core::{ BuildableTransaction, ScriptBuildStrategy, ScriptTransactionBuilder, VariableOutputPolicy, }, - tx_status::{TxResponse, TxStatus}, + tx_response::TxResponse, + tx_status::TxStatus, Selector, Token, }, }; diff --git a/packages/fuels-programs/src/contract/regular.rs b/packages/fuels-programs/src/contract/regular.rs index ec69104df1..f3febccfc2 100644 --- a/packages/fuels-programs/src/contract/regular.rs +++ b/packages/fuels-programs/src/contract/regular.rs @@ -10,7 +10,7 @@ use fuels_core::{ errors::Result, transaction::{Transaction, TxPolicies}, transaction_builders::{Blob, CreateTransactionBuilder}, - tx_status::TxResponse, + tx_response::TxResponse, }, Configurables, }; diff --git a/packages/fuels-programs/src/executable.rs b/packages/fuels-programs/src/executable.rs index aa4a172515..e4cb443e82 100644 --- a/packages/fuels-programs/src/executable.rs +++ b/packages/fuels-programs/src/executable.rs @@ -3,7 +3,7 @@ use fuels_core::{ errors::Result, transaction::Transaction, transaction_builders::{Blob, BlobTransactionBuilder}, - tx_status::TxResponse, + tx_response::TxResponse, }, Configurables, }; diff --git a/packages/fuels-programs/src/responses/call.rs b/packages/fuels-programs/src/responses/call.rs index 246b0aa16b..e9676968bc 100644 --- a/packages/fuels-programs/src/responses/call.rs +++ b/packages/fuels-programs/src/responses/call.rs @@ -4,7 +4,7 @@ use fuel_tx::TxId; use fuels_core::{ codec::{LogDecoder, LogResult}, traits::{Parameterize, Tokenizable}, - types::{errors::Result, tx_status::TxResponse}, + types::{errors::Result, tx_response::TxResponse}, }; /// [`CallResponse`] is a struct that is returned by a call to the contract or script. Its value From f9f6f7b015dce581950596945dc579c9130f2247 Mon Sep 17 00:00:00 2001 From: hal3e Date: Tue, 11 Feb 2025 14:59:14 +0100 Subject: [PATCH 09/13] pr comments --- e2e/tests/contracts.rs | 29 +++++---- e2e/tests/logs.rs | 2 +- e2e/tests/predicates.rs | 38 +++++++----- e2e/tests/providers.rs | 35 +++++------ e2e/tests/scripts.rs | 8 +-- e2e/tests/types_predicates.rs | 18 ++++-- e2e/tests/wallets.rs | 27 +++++---- examples/contracts/src/lib.rs | 15 +++-- examples/wallets/src/lib.rs | 2 +- packages/fuels-accounts/src/account.rs | 33 ++++------- packages/fuels-accounts/src/provider.rs | 30 ++++------ packages/fuels-core/src/types/tx_response.rs | 21 ++----- packages/fuels-core/src/types/tx_status.rs | 59 ++++++++++++++----- .../fuels-programs/src/calls/call_handler.rs | 35 ++++------- .../fuels-programs/src/contract/regular.rs | 20 +++---- packages/fuels-programs/src/executable.rs | 6 +- packages/fuels-programs/src/responses/call.rs | 9 +-- 17 files changed, 200 insertions(+), 187 deletions(-) diff --git a/e2e/tests/contracts.rs b/e2e/tests/contracts.rs index 6afa84c3fc..9434db6577 100644 --- a/e2e/tests/contracts.rs +++ b/e2e/tests/contracts.rs @@ -292,7 +292,8 @@ async fn test_contract_call_fee_estimation() -> Result<()> { let gas_limit = 800; let tolerance = Some(0.2); let block_horizon = Some(1); - let expected_gas_used = 8463; + let expected_script_gas = 800; + let expected_total_gas = 8463; let expected_metered_bytes_size = 824; let estimated_transaction_cost = contract_instance @@ -302,7 +303,8 @@ async fn test_contract_call_fee_estimation() -> Result<()> { .estimate_transaction_cost(tolerance, block_horizon) .await?; - assert_eq!(estimated_transaction_cost.gas_used, expected_gas_used); + assert_eq!(estimated_transaction_cost.script_gas, expected_script_gas); + assert_eq!(estimated_transaction_cost.total_gas, expected_total_gas); assert_eq!( estimated_transaction_cost.metered_bytes_size, expected_metered_bytes_size @@ -331,20 +333,20 @@ async fn contract_call_has_same_estimated_and_used_gas() -> Result<()> { let tolerance = Some(0.0); let block_horizon = Some(1); - let estimated_gas_used = contract_methods + let estimated_total_gas = contract_methods .initialize_counter(42) .estimate_transaction_cost(tolerance, block_horizon) .await? - .gas_used; + .total_gas; let gas_used = contract_methods .initialize_counter(42) .call() .await? - .tx - .gas_used; + .tx_status + .total_gas; - assert_eq!(estimated_gas_used, gas_used); + assert_eq!(estimated_total_gas, gas_used); Ok(()) } @@ -374,18 +376,19 @@ async fn mult_call_has_same_estimated_and_used_gas() -> Result<()> { let tolerance = Some(0.0); let block_horizon = Some(1); - let estimated_gas_used = multi_call_handler + let estimated_total_gas = multi_call_handler .estimate_transaction_cost(tolerance, block_horizon) .await? - .gas_used; + .total_gas; - let gas_used = multi_call_handler + let total_gas = multi_call_handler .call::<(u64, [u64; 2])>() .await? - .tx - .gas_used; + .tx_status + .total_gas; + + assert_eq!(estimated_total_gas, total_gas); - assert_eq!(estimated_gas_used, gas_used); Ok(()) } diff --git a/e2e/tests/logs.rs b/e2e/tests/logs.rs index 1883853e91..676b674fb0 100644 --- a/e2e/tests/logs.rs +++ b/e2e/tests/logs.rs @@ -830,7 +830,7 @@ async fn test_script_logs_with_contract_logs() -> Result<()> { { let num_contract_logs = response - .tx + .tx_status .receipts .iter() .filter(|receipt| matches!(receipt, Receipt::LogData { id, .. } | Receipt::Log { id, .. } if *id == contract_id)) diff --git a/e2e/tests/predicates.rs b/e2e/tests/predicates.rs index 00521dfac1..29e6ad68c7 100644 --- a/e2e/tests/predicates.rs +++ b/e2e/tests/predicates.rs @@ -166,18 +166,27 @@ async fn spend_predicate_coins_messages_basic() -> Result<()> { predicate.set_provider(provider.clone()); - let amount_to_send = predicate_balance - 1; - predicate + let amount_to_send = 128; + let fee = predicate .transfer( receiver.address(), amount_to_send, asset_id, TxPolicies::default(), ) - .await?; + .await? + .tx_status + .total_fee; // The predicate has spent the funds - assert_address_balance(predicate.address(), &provider, asset_id, 0).await; + let predicate_current_balance = predicate_balance - amount_to_send - fee; + assert_address_balance( + predicate.address(), + &provider, + asset_id, + predicate_current_balance, + ) + .await; // Funds were transferred assert_address_balance( @@ -229,7 +238,7 @@ async fn pay_with_predicate() -> Result<()> { MyContract::new(deploy_response.contract_id.clone(), predicate.clone()).methods(); let consensus_parameters = provider.consensus_parameters().await?; - let deploy_fee = deploy_response.tx.unwrap().total_fee; + let deploy_fee = deploy_response.tx_status.unwrap().total_fee; assert_eq!( predicate .get_asset_balance(consensus_parameters.base_asset_id()) @@ -247,7 +256,7 @@ async fn pay_with_predicate() -> Result<()> { predicate .get_asset_balance(consensus_parameters.base_asset_id()) .await?, - predicate_balance - deploy_fee - response.tx.total_fee + predicate_balance - deploy_fee - response.tx_status.total_fee ); Ok(()) @@ -293,7 +302,7 @@ async fn pay_with_predicate_vector_data() -> Result<()> { MyContract::new(deploy_response.contract_id.clone(), predicate.clone()).methods(); let consensus_parameters = provider.consensus_parameters().await?; - let deploy_fee = deploy_response.tx.unwrap().total_fee; + let deploy_fee = deploy_response.tx_status.unwrap().total_fee; assert_eq!( predicate .get_asset_balance(consensus_parameters.base_asset_id()) @@ -308,7 +317,7 @@ async fn pay_with_predicate_vector_data() -> Result<()> { predicate .get_asset_balance(consensus_parameters.base_asset_id()) .await?, - predicate_balance - deploy_fee - response.tx.total_fee + predicate_balance - deploy_fee - response.tx_status.total_fee ); Ok(()) @@ -408,7 +417,7 @@ async fn predicate_transfer_to_base_layer() -> Result<()> { let proof = predicate .try_provider()? .get_message_proof( - &withdraw_response.tx.id, + &withdraw_response.tx_id, &withdraw_response.nonce, None, Some(2), @@ -553,8 +562,8 @@ async fn contract_tx_and_call_params_with_predicate() -> Result<()> { .call() .await?; - let deploy_fee = deploy_response.tx.unwrap().total_fee; - let call_fee = call_response.tx.total_fee; + let deploy_fee = deploy_response.tx_status.unwrap().total_fee; + let call_fee = call_response.tx_status.total_fee; assert_eq!( predicate.get_asset_balance(&AssetId::zeroed()).await?, predicate_balance - deploy_fee - call_params_amount - call_fee @@ -733,20 +742,21 @@ async fn predicate_configurables() -> Result<()> { predicate.set_provider(provider.clone()); let amount_to_send = predicate_balance - 1; - let tx_response = predicate + let fee = predicate .transfer( receiver.address(), amount_to_send, asset_id, TxPolicies::default(), ) - .await?; + .await? + .tx_status + .total_fee; // The predicate has spent the funds assert_address_balance(predicate.address(), &provider, asset_id, 0).await; // Funds were transferred - let fee = tx_response.total_fee; assert_address_balance( receiver.address(), &provider, diff --git a/e2e/tests/providers.rs b/e2e/tests/providers.rs index 923f061e14..6663588b4d 100644 --- a/e2e/tests/providers.rs +++ b/e2e/tests/providers.rs @@ -12,7 +12,7 @@ use fuels::{ coin_type::CoinType, message::Message, transaction_builders::{BuildableTransaction, ScriptTransactionBuilder}, - tx_status::TxStatus, + tx_status::{Success, TxStatus}, Bits256, }, }; @@ -195,8 +195,8 @@ async fn test_input_message_pays_fee() -> Result<()> { assert_eq!(42, call_response.value); let balance = wallet.get_asset_balance(base_asset_id).await?; - let deploy_fee = deploy_response.tx.unwrap().total_fee; - let call_fee = call_response.tx.total_fee; + let deploy_fee = deploy_response.tx_status.unwrap().total_fee; + let call_fee = call_response.tx_status.total_fee; assert_eq!(balance, DEFAULT_COIN_AMOUNT - deploy_fee - call_fee); Ok(()) @@ -361,7 +361,7 @@ async fn test_gas_forwarded_defaults_to_tx_limit() -> Result<()> { .await?; let gas_forwarded = response - .tx + .tx_status .receipts .iter() .find(|r| matches!(r, Receipt::Call { .. })) @@ -422,7 +422,7 @@ async fn test_amount_and_asset_forwarding() -> Result<()> { assert_eq!(response.value, 1_000_000); let call_response = response - .tx + .tx_status .receipts .iter() .find(|&r| matches!(r, Receipt::Call { .. })); @@ -460,7 +460,7 @@ async fn test_amount_and_asset_forwarding() -> Result<()> { assert_eq!(response.value, 0); let call_response = response - .tx + .tx_status .receipts .iter() .find(|&r| matches!(r, Receipt::Call { .. })); @@ -505,18 +505,18 @@ async fn test_gas_errors() -> Result<()> { ); // Test running out of gas. Gas price as `None` will be 0. - let gas_limit = 100; + let gas_limit = 42; let contract_instance_call = contract_instance .methods() .initialize_counter(42) // Build the ABI call .with_tx_policies(TxPolicies::default().with_script_gas_limit(gas_limit)); // Test that the call will use more gas than the gas limit - let gas_used = contract_instance_call + let total_gas = contract_instance_call .estimate_transaction_cost(None, None) .await? - .gas_used; - assert!(gas_used > gas_limit); + .total_gas; + assert!(total_gas > gas_limit); let response = contract_instance_call .call() @@ -599,15 +599,16 @@ async fn test_get_gas_used() -> Result<()> { ), ); - let gas_used = contract_instance + let total_gas = contract_instance .methods() .initialize_counter(42) .call() .await? - .tx - .gas_used; + .tx_status + .total_gas; + + assert!(total_gas > 0); - assert!(gas_used > 0); Ok(()) } @@ -627,7 +628,7 @@ async fn test_parse_block_time() -> Result<()> { let tx_response = wallet .try_provider()? - .get_transaction_by_id(&tx_response.id) + .get_transaction_by_id(&tx_response.tx_id) .await? .unwrap(); assert!(tx_response.time.is_some()); @@ -1132,7 +1133,7 @@ async fn tx_respects_policies() -> Result<()> { .await?; let tx_response = provider - .get_transaction_by_id(&response.tx.id.unwrap()) + .get_transaction_by_id(&response.tx_id.unwrap()) .await? .expect("tx should exist"); let script = match tx_response.transaction { @@ -1228,7 +1229,7 @@ async fn tx_with_witness_data() -> Result<()> { let status = provider.send_transaction_and_await_commit(tx).await?; match status { - TxStatus::Success { receipts, .. } => { + TxStatus::Success(Success { receipts, .. }) => { let ret: u64 = receipts .into_iter() .find_map(|receipt| match receipt { diff --git a/e2e/tests/scripts.rs b/e2e/tests/scripts.rs index 00874263e2..5f2cdc4e43 100644 --- a/e2e/tests/scripts.rs +++ b/e2e/tests/scripts.rs @@ -59,15 +59,15 @@ async fn script_call_has_same_estimated_and_used_gas() -> Result<()> { let a = 4u64; let b = 2u32; - let estimated_gas_used = script_instance + let estimated_total_gas = script_instance .main(a, b) .estimate_transaction_cost(tolerance, block_horizon) .await? - .gas_used; + .total_gas; - let gas_used = script_instance.main(a, b).call().await?.tx.gas_used; + let total_gas = script_instance.main(a, b).call().await?.tx_status.total_gas; - assert_eq!(estimated_gas_used, gas_used); + assert_eq!(estimated_total_gas, total_gas); Ok(()) } diff --git a/e2e/tests/types_predicates.rs b/e2e/tests/types_predicates.rs index 8890e962eb..aae9c4e10f 100644 --- a/e2e/tests/types_predicates.rs +++ b/e2e/tests/types_predicates.rs @@ -18,18 +18,24 @@ async fn assert_predicate_spendable(data: Vec, project_path: impl AsRef Result<()> { #[tokio::test] async fn send_transfer_transactions() -> Result<()> { - const AMOUNT: u64 = 5; - let (wallet_1, wallet_2) = setup_transfer_test(AMOUNT).await?; + let amount = 5; + let (wallet_1, wallet_2) = setup_transfer_test(amount).await?; // Configure transaction policies let tip = 2; @@ -270,16 +270,22 @@ async fn send_transfer_transactions() -> Result<()> { .with_script_gas_limit(script_gas_limit); // Transfer 1 from wallet 1 to wallet 2. - const SEND_AMOUNT: u64 = 1; + let amount_to_send = 1; let base_asset_id = AssetId::zeroed(); - let tx_response = wallet_1 - .transfer(wallet_2.address(), SEND_AMOUNT, base_asset_id, tx_policies) - .await?; + let tx_id = wallet_1 + .transfer( + wallet_2.address(), + amount_to_send, + base_asset_id, + tx_policies, + ) + .await? + .tx_id; // Assert that the transaction was properly configured. let res = wallet_1 .try_provider()? - .get_transaction_by_id(&tx_response.id) + .get_transaction_by_id(&tx_id) .await? .unwrap(); @@ -317,14 +323,16 @@ async fn transfer_coins_with_change() -> Result<()> { // Transfer 2 from wallet 1 to wallet 2. const SEND_AMOUNT: u64 = 2; - let tx_response = wallet_1 + let fee = wallet_1 .transfer( wallet_2.address(), SEND_AMOUNT, AssetId::zeroed(), TxPolicies::default(), ) - .await?; + .await? + .tx_status + .total_fee; let base_asset_id = AssetId::zeroed(); let wallet_1_final_coins = wallet_1 @@ -333,7 +341,6 @@ async fn transfer_coins_with_change() -> Result<()> { // Assert that we've sent 2 from wallet 1, resulting in an amount of 3 in wallet 1. let resulting_amount = wallet_1_final_coins.first().unwrap(); - let fee = tx_response.total_fee; assert_eq!(resulting_amount.amount(), AMOUNT - SEND_AMOUNT - fee); let wallet_2_final_coins = wallet_2.get_coins(base_asset_id).await?; diff --git a/examples/contracts/src/lib.rs b/examples/contracts/src/lib.rs index 6dc1230b28..f6df8e024c 100644 --- a/examples/contracts/src/lib.rs +++ b/examples/contracts/src/lib.rs @@ -120,9 +120,11 @@ mod tests { .await?; // ANCHOR_END: contract_call_cost_estimation - let expected_gas = 9068; + let expected_script_gas = 2816; + let expected_total_gas = 9068; - assert_eq!(transaction_cost.gas_used, expected_gas); + assert_eq!(transaction_cost.script_gas, expected_script_gas); + assert_eq!(transaction_cost.total_gas, expected_total_gas); Ok(()) } @@ -643,9 +645,11 @@ mod tests { .await?; // ANCHOR_END: multi_call_cost_estimation - let expected_gas = 11231; + let expected_script_gas = 4402; + let expected_total_gas = 11231; - assert_eq!(transaction_cost.gas_used, expected_gas); + assert_eq!(transaction_cost.script_gas, expected_script_gas); + assert_eq!(transaction_cost.total_gas, expected_total_gas); Ok(()) } @@ -1188,8 +1192,7 @@ mod tests { .initialize_counter(42) .call() .await? - .tx - .id + .tx_id .unwrap(); let provider: &Provider = wallet.try_provider()?; diff --git a/examples/wallets/src/lib.rs b/examples/wallets/src/lib.rs index f9e1094365..398faf1687 100644 --- a/examples/wallets/src/lib.rs +++ b/examples/wallets/src/lib.rs @@ -379,7 +379,7 @@ mod tests { // Retrieve a message proof from the provider let proof = wallet .try_provider()? - .get_message_proof(&response.tx.id, &response.nonce, None, Some(2)) + .get_message_proof(&response.tx_id, &response.nonce, None, Some(2)) .await?; // Verify the amount and recipient diff --git a/packages/fuels-accounts/src/account.rs b/packages/fuels-accounts/src/account.rs index e024e429ed..2fd537252b 100644 --- a/packages/fuels-accounts/src/account.rs +++ b/packages/fuels-accounts/src/account.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use async_trait::async_trait; use fuel_core_client::client::pagination::{PaginatedResult, PaginationRequest}; -use fuel_tx::{Output, TxPointer, UtxoId}; +use fuel_tx::{Output, TxId, TxPointer, UtxoId}; use fuel_types::{AssetId, Bytes32, ContractId, Nonce}; use fuels_core::types::{ bech32::{Bech32Address, Bech32ContractId}, @@ -16,6 +16,7 @@ use fuels_core::types::{ transaction_builders::{BuildableTransaction, ScriptTransactionBuilder, TransactionBuilder}, transaction_response::TransactionResponse, tx_response::TxResponse, + tx_status::Success, }; use crate::{ @@ -28,7 +29,8 @@ use crate::{ #[derive(Clone, Debug)] pub struct WithdrawToBaseResponse { - pub tx: TxResponse, + pub tx_status: Success, + pub tx_id: TxId, pub nonce: Nonce, } @@ -204,10 +206,8 @@ pub trait Account: ViewOnlyAccount { let tx_status = provider.send_transaction_and_await_commit(tx).await?; Ok(TxResponse { - gas_used: tx_status.total_gas(), - total_fee: tx_status.total_fee(), - receipts: tx_status.take_receipts_checked(None)?, - id: tx_id, + tx_status: tx_status.take_success_checked(None)?, + tx_id, }) } @@ -271,10 +271,8 @@ pub trait Account: ViewOnlyAccount { let tx_status = provider.send_transaction_and_await_commit(tx).await?; Ok(TxResponse { - gas_used: tx_status.total_gas(), - total_fee: tx_status.total_fee(), - receipts: tx_status.take_receipts_checked(None)?, - id: tx_id, + tx_status: tx_status.take_success_checked(None)?, + tx_id, }) } @@ -309,21 +307,14 @@ pub trait Account: ViewOnlyAccount { let tx_id = tx.id(consensus_parameters.chain_id()); let tx_status = provider.send_transaction_and_await_commit(tx).await?; + let success = tx_status.take_success_checked(None)?; - let gas_used = tx_status.total_gas(); - let total_fee = tx_status.total_fee(); - let receipts = tx_status.take_receipts_checked(None)?; - - let nonce = extract_message_nonce(&receipts) + let nonce = extract_message_nonce(&success.receipts) .expect("MessageId could not be retrieved from tx receipts."); Ok(WithdrawToBaseResponse { - tx: TxResponse { - receipts, - gas_used, - total_fee, - id: tx_id, - }, + tx_status: success, + tx_id, nonce, }) } diff --git a/packages/fuels-accounts/src/provider.rs b/packages/fuels-accounts/src/provider.rs index 9f6c12410a..e3b21fb853 100644 --- a/packages/fuels-accounts/src/provider.rs +++ b/packages/fuels-accounts/src/provider.rs @@ -62,9 +62,10 @@ const NUM_RESULTS_PER_REQUEST: i32 = 100; // ANCHOR: transaction_cost pub struct TransactionCost { pub gas_price: u64, - pub gas_used: u64, pub metered_bytes_size: u64, pub total_fee: u64, + pub script_gas: u64, + pub total_gas: u64, } // ANCHOR_END: transaction_cost @@ -716,32 +717,25 @@ impl Provider { let EstimateGasPrice { gas_price, .. } = self.estimate_gas_price(block_horizon).await?; let tx_status = self.dry_run_opt(tx.clone(), false, None).await?; - let gas_used = self.gas_used_with_tolerance(&tx_status, tolerance).await?; - let total_fee = self.total_fee_with_tolerance(&tx_status, tolerance).await?; + let total_gas = Self::apply_tolerance(tx_status.total_gas(), tolerance); + let total_fee = Self::apply_tolerance(tx_status.total_fee(), tolerance); + + let receipts = tx_status.take_receipts(); Ok(TransactionCost { gas_price, - gas_used, metered_bytes_size: tx.metered_bytes_size() as u64, total_fee, + total_gas, + script_gas: Self::get_script_gas_used(&receipts), }) } - // Increase estimated gas by the provided tolerance - async fn gas_used_with_tolerance(&self, tx_status: &TxStatus, tolerance: f64) -> Result { - let gas_used = tx_status.total_gas(); - - Ok((gas_used as f64 * (1.0 + tolerance)).ceil() as u64) - } - - // Increase estimated total fee by the provided tolerance - async fn total_fee_with_tolerance(&self, tx_status: &TxStatus, tolerance: f64) -> Result { - let fee = tx_status.total_fee(); - - Ok((fee as f64 * (1.0 + tolerance)) as u64) + fn apply_tolerance(value: u64, tolerance: f64) -> u64 { + (value as f64 * (1.0 + tolerance)).ceil() as u64 } - fn get_script_gas_used(&self, receipts: &[Receipt]) -> u64 { + fn get_script_gas_used(receipts: &[Receipt]) -> u64 { receipts .iter() .rfind(|r| matches!(r, Receipt::ScriptResult { .. })) @@ -839,7 +833,7 @@ impl DryRunner for Provider { .expect("should have only one element"); let receipts = tx_execution_status.result.receipts(); - let script_gas = self.get_script_gas_used(receipts); + let script_gas = Self::get_script_gas_used(receipts); let variable_outputs = receipts .iter() diff --git a/packages/fuels-core/src/types/tx_response.rs b/packages/fuels-core/src/types/tx_response.rs index 0077b480f3..e298fd4f41 100644 --- a/packages/fuels-core/src/types/tx_response.rs +++ b/packages/fuels-core/src/types/tx_response.rs @@ -1,19 +1,8 @@ -use fuel_tx::{Receipt, TxId}; - -use crate::sealed::Sealed; +use super::tx_status::Success; +use fuel_tx::TxId; #[derive(Clone, Debug)] -pub struct TxResponse { - pub receipts: Vec, - pub gas_used: u64, - pub total_fee: u64, - pub id: T, +pub struct TxResponse { + pub tx_status: Success, + pub tx_id: TxId, } - -impl Sealed for TxId {} -impl Sealed for Option {} - -pub trait TxResponseType: Sealed {} - -impl TxResponseType for TxId {} -impl TxResponseType for Option {} diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index c288a1c7bd..cff041e832 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -15,13 +15,16 @@ use crate::{ types::errors::{transaction::Reason, Error, Result}, }; +#[derive(Debug, Clone)] +pub struct Success { + pub receipts: Vec, + pub total_gas: u64, + pub total_fee: u64, +} + #[derive(Debug, Clone)] pub enum TxStatus { - Success { - receipts: Vec, - total_gas: u64, - total_fee: u64, - }, + Success(Success), Submitted, SqueezedOut { reason: String, @@ -46,21 +49,43 @@ impl TxStatus { reason, revert_id: id, .. - } => Self::map_revert_error(receipts, reason, *id, log_decoder), + } => Err(Self::map_revert_error(receipts, reason, *id, log_decoder)), _ => Ok(()), } } + pub fn take_success_checked(self, log_decoder: Option<&LogDecoder>) -> Result { + match self { + Self::SqueezedOut { reason } => { + Err(Error::Transaction(Reason::SqueezedOut(reason.clone()))) + } + Self::Revert { + receipts, + reason, + revert_id: id, + .. + } => Err(Self::map_revert_error(&receipts, &reason, id, log_decoder)), + Self::Submitted => Err(Error::Transaction(Reason::SqueezedOut( + "can not take `success` status from `Submitted` transaction".to_owned(), + ))), + Self::Success(success) => Ok(success), + } + } + pub fn total_gas(&self) -> u64 { match self { - TxStatus::Success { total_gas, .. } | TxStatus::Revert { total_gas, .. } => *total_gas, + TxStatus::Success(Success { total_gas, .. }) | TxStatus::Revert { total_gas, .. } => { + *total_gas + } _ => 0, } } pub fn total_fee(&self) -> u64 { match self { - TxStatus::Success { total_fee, .. } | TxStatus::Revert { total_fee, .. } => *total_fee, + TxStatus::Success(Success { total_fee, .. }) | TxStatus::Revert { total_fee, .. } => { + *total_fee + } _ => 0, } } @@ -70,7 +95,7 @@ impl TxStatus { reason: &str, id: u64, log_decoder: Option<&LogDecoder>, - ) -> Result<()> { + ) -> Error { let reason = match (id, log_decoder) { (FAILED_REQUIRE_SIGNAL, Some(log_decoder)) => log_decoder .decode_last_log(receipts) @@ -104,11 +129,11 @@ impl TxStatus { _ => reason.to_string(), }; - Err(Error::Transaction(Reason::Reverted { + Error::Transaction(Reason::Reverted { reason, revert_id: id, receipts: receipts.to_vec(), - })) + }) } pub fn take_receipts_checked(self, log_decoder: Option<&LogDecoder>) -> Result> { @@ -118,7 +143,9 @@ impl TxStatus { pub fn take_receipts(self) -> Vec { match self { - TxStatus::Success { receipts, .. } | TxStatus::Revert { receipts, .. } => receipts, + TxStatus::Success(Success { receipts, .. }) | TxStatus::Revert { receipts, .. } => { + receipts + } _ => vec![], } } @@ -134,11 +161,11 @@ impl From for TxStatus { total_gas, total_fee, .. - } => TxStatus::Success { + } => TxStatus::Success(Success { receipts, total_gas, total_fee, - }, + }), ClientTransactionStatus::Failure { reason, program_state, @@ -175,11 +202,11 @@ impl From for TxStatus { total_gas, total_fee, .. - } => Self::Success { + } => Self::Success(Success { receipts, total_gas, total_fee, - }, + }), TransactionExecutionResult::Failed { result, receipts, diff --git a/packages/fuels-programs/src/calls/call_handler.rs b/packages/fuels-programs/src/calls/call_handler.rs index efc1888286..3b4c7469b8 100644 --- a/packages/fuels-programs/src/calls/call_handler.rs +++ b/packages/fuels-programs/src/calls/call_handler.rs @@ -15,7 +15,6 @@ use fuels_core::{ BuildableTransaction, ScriptBuildStrategy, ScriptTransactionBuilder, VariableOutputPolicy, }, - tx_response::TxResponse, tx_status::TxStatus, Selector, Token, }, @@ -210,24 +209,17 @@ where /// Create a [`CallResponse`] from `TxStatus` pub fn get_response(&self, tx_status: TxStatus) -> Result> { - let gas_used = tx_status.total_gas(); - let total_fee = tx_status.total_fee(); + let success = tx_status.take_success_checked(Some(&self.log_decoder))?; - let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; - - let token = self - .call - .parse_call(&receipts, self.decoder_config, &T::param_type())?; + let token = + self.call + .parse_call(&success.receipts, self.decoder_config, &T::param_type())?; Ok(CallResponse { value: T::from_token(token)?, log_decoder: self.log_decoder.clone(), - tx: TxResponse { - receipts, - gas_used, - total_fee, - id: self.cached_tx_id, - }, + tx_id: self.cached_tx_id, + tx_status: success, }) } @@ -490,11 +482,8 @@ where &self, tx_status: TxStatus, ) -> Result> { - let gas_used = tx_status.total_gas(); - let total_fee = tx_status.total_fee(); - - let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; - let mut receipt_parser = ReceiptParser::new(&receipts, self.decoder_config); + let success = tx_status.take_success_checked(Some(&self.log_decoder))?; + let mut receipt_parser = ReceiptParser::new(&success.receipts, self.decoder_config); let final_tokens = self .call @@ -507,12 +496,8 @@ where Ok(CallResponse { value: T::from_token(tokens_as_tuple)?, log_decoder: self.log_decoder.clone(), - tx: TxResponse { - receipts, - gas_used, - total_fee, - id: self.cached_tx_id, - }, + tx_id: self.cached_tx_id, + tx_status: success, }) } diff --git a/packages/fuels-programs/src/contract/regular.rs b/packages/fuels-programs/src/contract/regular.rs index f3febccfc2..42158c8a20 100644 --- a/packages/fuels-programs/src/contract/regular.rs +++ b/packages/fuels-programs/src/contract/regular.rs @@ -1,6 +1,6 @@ use std::{default::Default, fmt::Debug, path::Path}; -use fuel_tx::{Bytes32, ContractId, Salt, StorageSlot}; +use fuel_tx::{Bytes32, ContractId, Salt, StorageSlot, TxId}; use fuels_accounts::Account; use fuels_core::{ constants::WORD_SIZE, @@ -10,7 +10,7 @@ use fuels_core::{ errors::Result, transaction::{Transaction, TxPolicies}, transaction_builders::{Blob, CreateTransactionBuilder}, - tx_response::TxResponse, + tx_status::Success, }, Configurables, }; @@ -24,7 +24,8 @@ use super::{ #[derive(Clone, Debug)] pub struct DeployResponse { - pub tx: Option, + pub tx_status: Option, + pub tx_id: Option, pub contract_id: Bech32ContractId, } @@ -170,17 +171,13 @@ impl Contract { let consensus_parameters = provider.consensus_parameters().await?; let tx = tb.build(provider).await?; - let tx_id = tx.id(consensus_parameters.chain_id()); + let tx_id = Some(tx.id(consensus_parameters.chain_id())); let tx_status = provider.send_transaction_and_await_commit(tx).await?; Ok(DeployResponse { - tx: Some(TxResponse { - gas_used: tx_status.total_gas(), - total_fee: tx_status.total_fee(), - receipts: tx_status.take_receipts_checked(None)?, - id: tx_id, - }), + tx_status: Some(tx_status.take_success_checked(None)?), + tx_id, contract_id: contract_id.into(), }) } @@ -196,7 +193,8 @@ impl Contract { let provider = account.try_provider()?; if provider.contract_exists(&contract_id).await? { Ok(DeployResponse { - tx: None, + tx_status: None, + tx_id: None, contract_id, }) } else { diff --git a/packages/fuels-programs/src/executable.rs b/packages/fuels-programs/src/executable.rs index e4cb443e82..ad1743520a 100644 --- a/packages/fuels-programs/src/executable.rs +++ b/packages/fuels-programs/src/executable.rs @@ -173,10 +173,8 @@ impl Executable { let tx_status = provider.send_transaction_and_await_commit(tx).await?; Ok(Some(TxResponse { - gas_used: tx_status.total_gas(), - total_fee: tx_status.total_fee(), - receipts: tx_status.take_receipts_checked(None)?, - id: tx_id, + tx_status: tx_status.take_success_checked(None)?, + tx_id, })) } } diff --git a/packages/fuels-programs/src/responses/call.rs b/packages/fuels-programs/src/responses/call.rs index e9676968bc..f8041e7559 100644 --- a/packages/fuels-programs/src/responses/call.rs +++ b/packages/fuels-programs/src/responses/call.rs @@ -4,7 +4,7 @@ use fuel_tx::TxId; use fuels_core::{ codec::{LogDecoder, LogResult}, traits::{Parameterize, Tokenizable}, - types::{errors::Result, tx_response::TxResponse}, + types::{errors::Result, tx_status::Success}, }; /// [`CallResponse`] is a struct that is returned by a call to the contract or script. Its value @@ -14,18 +14,19 @@ use fuels_core::{ // ANCHOR: call_response pub struct CallResponse { pub value: D, - pub tx: TxResponse>, + pub tx_status: Success, + pub tx_id: Option, pub log_decoder: LogDecoder, } // ANCHOR_END: call_response impl CallResponse { pub fn decode_logs(&self) -> LogResult { - self.log_decoder.decode_logs(&self.tx.receipts) + self.log_decoder.decode_logs(&self.tx_status.receipts) } pub fn decode_logs_with_type(&self) -> Result> { self.log_decoder - .decode_logs_with_type::(&self.tx.receipts) + .decode_logs_with_type::(&self.tx_status.receipts) } } From fa755cb491b673d944e726d6d7f385c1344eb18f Mon Sep 17 00:00:00 2001 From: hal3e Date: Tue, 11 Feb 2025 15:22:42 +0100 Subject: [PATCH 10/13] update docs --- docs/src/calling-contracts/cost-estimation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/src/calling-contracts/cost-estimation.md b/docs/src/calling-contracts/cost-estimation.md index 696cea4341..5860007f55 100644 --- a/docs/src/calling-contracts/cost-estimation.md +++ b/docs/src/calling-contracts/cost-estimation.md @@ -6,6 +6,8 @@ With the function `estimate_transaction_cost(tolerance: Option, block_horiz {{#include ../../../packages/fuels-accounts/src/provider.rs:transaction_cost}} ``` +> **Note** `script_gas` reefers to the part of the gas spent on the script execution. + Below are examples that show how to get the estimated transaction cost from single and multi call transactions. ```rust,ignore From 4389fc0509692e25833ee98b54870498167c25ed Mon Sep 17 00:00:00 2001 From: hal3e Date: Fri, 14 Feb 2025 16:51:53 +0100 Subject: [PATCH 11/13] Update docs/src/calling-contracts/cost-estimation.md Co-authored-by: Ahmed Sagdati <37515857+segfault-magnet@users.noreply.github.com> --- docs/src/calling-contracts/cost-estimation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/calling-contracts/cost-estimation.md b/docs/src/calling-contracts/cost-estimation.md index 5860007f55..10eca39fa6 100644 --- a/docs/src/calling-contracts/cost-estimation.md +++ b/docs/src/calling-contracts/cost-estimation.md @@ -6,7 +6,7 @@ With the function `estimate_transaction_cost(tolerance: Option, block_horiz {{#include ../../../packages/fuels-accounts/src/provider.rs:transaction_cost}} ``` -> **Note** `script_gas` reefers to the part of the gas spent on the script execution. +> **Note** `script_gas` refers to the part of the gas spent on the script execution. Below are examples that show how to get the estimated transaction cost from single and multi call transactions. From 13f9638c3a90a5c2136becde5908457aa76b63c5 Mon Sep 17 00:00:00 2001 From: hal3e Date: Fri, 14 Feb 2025 19:28:46 +0100 Subject: [PATCH 12/13] pr comments --- packages/fuels-core/src/types/tx_status.rs | 65 ++++++++++++---------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index cff041e832..666c06fc0b 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -18,53 +18,59 @@ use crate::{ #[derive(Debug, Clone)] pub struct Success { pub receipts: Vec, + pub total_fee: u64, pub total_gas: u64, +} + +#[derive(Debug, Clone)] +pub struct SqueezedOut { + pub reason: String, +} + +#[derive(Debug, Clone)] +pub struct Revert { + pub reason: String, + pub receipts: Vec, + pub revert_id: u64, pub total_fee: u64, + pub total_gas: u64, } #[derive(Debug, Clone)] pub enum TxStatus { Success(Success), Submitted, - SqueezedOut { - reason: String, - }, - Revert { - receipts: Vec, - reason: String, - revert_id: u64, - total_gas: u64, - total_fee: u64, - }, + SqueezedOut(SqueezedOut), + Revert(Revert), } impl TxStatus { pub fn check(&self, log_decoder: Option<&LogDecoder>) -> Result<()> { match self { - Self::SqueezedOut { reason } => { + Self::SqueezedOut(SqueezedOut { reason }) => { Err(Error::Transaction(Reason::SqueezedOut(reason.clone()))) } - Self::Revert { + Self::Revert(Revert { receipts, reason, revert_id: id, .. - } => Err(Self::map_revert_error(receipts, reason, *id, log_decoder)), + }) => Err(Self::map_revert_error(receipts, reason, *id, log_decoder)), _ => Ok(()), } } pub fn take_success_checked(self, log_decoder: Option<&LogDecoder>) -> Result { match self { - Self::SqueezedOut { reason } => { + Self::SqueezedOut(SqueezedOut { reason }) => { Err(Error::Transaction(Reason::SqueezedOut(reason.clone()))) } - Self::Revert { + Self::Revert(Revert { receipts, reason, revert_id: id, .. - } => Err(Self::map_revert_error(&receipts, &reason, id, log_decoder)), + }) => Err(Self::map_revert_error(&receipts, &reason, id, log_decoder)), Self::Submitted => Err(Error::Transaction(Reason::SqueezedOut( "can not take `success` status from `Submitted` transaction".to_owned(), ))), @@ -74,18 +80,16 @@ impl TxStatus { pub fn total_gas(&self) -> u64 { match self { - TxStatus::Success(Success { total_gas, .. }) | TxStatus::Revert { total_gas, .. } => { - *total_gas - } + TxStatus::Success(Success { total_gas, .. }) + | TxStatus::Revert(Revert { total_gas, .. }) => *total_gas, _ => 0, } } pub fn total_fee(&self) -> u64 { match self { - TxStatus::Success(Success { total_fee, .. }) | TxStatus::Revert { total_fee, .. } => { - *total_fee - } + TxStatus::Success(Success { total_fee, .. }) + | TxStatus::Revert(Revert { total_fee, .. }) => *total_fee, _ => 0, } } @@ -143,9 +147,8 @@ impl TxStatus { pub fn take_receipts(self) -> Vec { match self { - TxStatus::Success(Success { receipts, .. }) | TxStatus::Revert { receipts, .. } => { - receipts - } + TxStatus::Success(Success { receipts, .. }) + | TxStatus::Revert(Revert { receipts, .. }) => receipts, _ => vec![], } } @@ -180,15 +183,17 @@ impl From for TxStatus { _ => None, }) .expect("Transaction failed without a `revert_id`"); - TxStatus::Revert { + TxStatus::Revert(Revert { receipts, reason, revert_id, total_gas, total_fee, - } + }) + } + ClientTransactionStatus::SqueezedOut { reason } => { + TxStatus::SqueezedOut(SqueezedOut { reason }) } - ClientTransactionStatus::SqueezedOut { reason } => TxStatus::SqueezedOut { reason }, } } } @@ -221,13 +226,13 @@ impl From for TxStatus { }) .expect("Transaction failed without a `revert_id`"); let reason = TransactionExecutionResult::reason(&receipts, &result); - Self::Revert { + Self::Revert(Revert { receipts, reason, revert_id, total_gas, total_fee, - } + }) } } } From b58623202acbad229c2838b3e97e593d29e7c02d Mon Sep 17 00:00:00 2001 From: hal3e Date: Mon, 24 Feb 2025 11:08:46 +0100 Subject: [PATCH 13/13] pr comments --- e2e/tests/predicates.rs | 2 +- packages/fuels-core/src/types/tx_status.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/e2e/tests/predicates.rs b/e2e/tests/predicates.rs index 29e6ad68c7..3c11e72c9b 100644 --- a/e2e/tests/predicates.rs +++ b/e2e/tests/predicates.rs @@ -115,7 +115,7 @@ async fn transfer_coins_and_messages_to_predicate() -> Result<()> { let num_coins = 16; let num_messages = 32; let amount = 64; - let balance_to_send = ((num_coins + num_messages) * amount) - 1; + let balance_to_send = 42; let mut wallet = WalletUnlocked::new_random(None); diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index 666c06fc0b..daf65addb3 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -71,8 +71,8 @@ impl TxStatus { revert_id: id, .. }) => Err(Self::map_revert_error(&receipts, &reason, id, log_decoder)), - Self::Submitted => Err(Error::Transaction(Reason::SqueezedOut( - "can not take `success` status from `Submitted` transaction".to_owned(), + Self::Submitted => Err(Error::Transaction(Reason::Other( + "transactions was not yet included".to_owned(), ))), Self::Success(success) => Ok(success), }