diff --git a/packages/fuels-accounts/src/provider.rs b/packages/fuels-accounts/src/provider.rs index 438dd4395b..59c4b8354b 100644 --- a/packages/fuels-accounts/src/provider.rs +++ b/packages/fuels-accounts/src/provider.rs @@ -290,32 +290,27 @@ impl Provider { Ok(self.client.node_info().await?.into()) } - pub async fn checked_dry_run(&self, tx: T) -> Result> { + pub async fn checked_dry_run(&self, tx: T) -> Result { let receipts = self.dry_run(tx).await?; - Self::has_script_succeeded(&receipts)?; - - Ok(receipts) + Ok(Self::tx_status_from_receipts(receipts)) } - fn has_script_succeeded(receipts: &[Receipt]) -> Result<()> { - receipts - .iter() - .find_map(|receipt| match receipt { - Receipt::ScriptResult { result, .. } - if *result != ScriptExecutionResult::Success => - { - Some(format!("{result:?}")) - } - _ => None, - }) - .map(|error_message| { - Err(Error::RevertTransactionError { - reason: error_message, - revert_id: 0, - receipts: receipts.to_owned(), - }) - }) - .unwrap_or(Ok(())) + fn tx_status_from_receipts(receipts: Vec) -> TxStatus { + let revert_reason = receipts.iter().find_map(|receipt| match receipt { + Receipt::ScriptResult { result, .. } if *result != ScriptExecutionResult::Success => { + Some(format!("{result:?}")) + } + _ => None, + }); + + match revert_reason { + Some(reason) => TxStatus::Revert { + receipts, + reason, + id: 0, + }, + None => TxStatus::Success { receipts }, + } } pub async fn dry_run(&self, tx: T) -> Result> { diff --git a/packages/fuels-core/src/codec/logs.rs b/packages/fuels-core/src/codec/logs.rs index 98930dd293..a541384cda 100644 --- a/packages/fuels-core/src/codec/logs.rs +++ b/packages/fuels-core/src/codec/logs.rs @@ -5,10 +5,6 @@ use std::{ iter::FilterMap, }; -use fuel_abi_types::error_codes::{ - FAILED_ASSERT_EQ_SIGNAL, FAILED_ASSERT_SIGNAL, FAILED_REQUIRE_SIGNAL, - FAILED_SEND_MESSAGE_SIGNAL, FAILED_TRANSFER_TO_ADDRESS_SIGNAL, -}; use fuel_tx::{ContractId, Receipt}; use crate::{ @@ -208,38 +204,6 @@ impl<'a, I: Iterator> ExtractLogIdData for I { } } -/// Map the provided `RevertTransactionError` based on the `revert_id`. -/// If applicable, decode the logged types from the receipt. -pub fn map_revert_error(mut err: Error, log_decoder: &LogDecoder) -> Error { - if let Error::RevertTransactionError { - revert_id, - ref receipts, - ref mut reason, - } = err - { - match revert_id { - FAILED_REQUIRE_SIGNAL => { - *reason = log_decoder.decode_last_log(receipts).unwrap_or_else(|err| { - format!("failed to decode log from require revert: {err}") - }) - } - FAILED_ASSERT_EQ_SIGNAL => { - *reason = match log_decoder.decode_last_two_logs(receipts) { - Ok((lhs, rhs)) => format!( - "assertion failed: `(left == right)`\n left: `{lhs:?}`\n right: `{rhs:?}`" - ), - Err(err) => format!("failed to decode log from assert_eq revert: {err}"), - }; - } - FAILED_ASSERT_SIGNAL => *reason = "assertion failed.".into(), - FAILED_SEND_MESSAGE_SIGNAL => *reason = "failed to send message.".into(), - FAILED_TRANSFER_TO_ADDRESS_SIGNAL => *reason = "failed transfer to address.".into(), - _ => {} - } - } - err -} - pub fn log_formatters_lookup( log_id_log_formatter_pairs: Vec<(u64, LogFormatter)>, contract_id: ContractId, diff --git a/packages/fuels-programs/src/contract.rs b/packages/fuels-programs/src/contract.rs index c60f74dc58..18976e7ac0 100644 --- a/packages/fuels-programs/src/contract.rs +++ b/packages/fuels-programs/src/contract.rs @@ -11,7 +11,7 @@ use fuel_tx::{ }; use fuels_accounts::{provider::TransactionCost, Account}; use fuels_core::{ - codec::{map_revert_error, ABIEncoder, DecoderConfig, LogDecoder}, + codec::{ABIEncoder, DecoderConfig, LogDecoder}, constants::{BASE_ASSET_ID, DEFAULT_CALL_PARAMS_AMOUNT}, traits::{Parameterize, Tokenizable}, types::{ @@ -579,9 +579,7 @@ where /// Call a contract's method on the node, in a state-modifying manner. pub async fn call(mut self) -> Result> { - self.call_or_simulate(false) - .await - .map_err(|err| map_revert_error(err, &self.log_decoder)) + self.call_or_simulate(false).await } pub async fn submit(mut self) -> Result> { @@ -610,9 +608,7 @@ where /// blockchain is *not* modified but simulated. /// pub async fn simulate(&mut self) -> Result> { - self.call_or_simulate(true) - .await - .map_err(|err| map_revert_error(err, &self.log_decoder)) + self.call_or_simulate(true).await } async fn call_or_simulate(&mut self, simulate: bool) -> Result> { @@ -621,15 +617,13 @@ where self.cached_tx_id = Some(tx.id(provider.chain_id())); - let receipts = if simulate { + let tx_status = if simulate { provider.checked_dry_run(tx).await? } else { let tx_id = provider.send_transaction_and_await_commit(tx).await?; - provider - .tx_status(&tx_id) - .await? - .take_receipts_checked(Some(&self.log_decoder))? + provider.tx_status(&tx_id).await? }; + let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; self.get_response(receipts) } @@ -867,9 +861,7 @@ impl MultiContractCallHandler { /// Call contract methods on the node, in a state-modifying manner. pub async fn call(&mut self) -> Result> { - self.call_or_simulate(false) - .await - .map_err(|err| map_revert_error(err, &self.log_decoder)) + self.call_or_simulate(false).await } pub async fn submit(mut self) -> Result> { @@ -900,9 +892,7 @@ impl MultiContractCallHandler { /// /// [call]: Self::call pub async fn simulate(&mut self) -> Result> { - self.call_or_simulate(true) - .await - .map_err(|err| map_revert_error(err, &self.log_decoder)) + self.call_or_simulate(true).await } async fn call_or_simulate( @@ -914,15 +904,13 @@ impl MultiContractCallHandler { self.cached_tx_id = Some(tx.id(provider.chain_id())); - let receipts = if simulate { + let tx_status = if simulate { provider.checked_dry_run(tx).await? } else { let tx_id = provider.send_transaction_and_await_commit(tx).await?; - provider - .tx_status(&tx_id) - .await? - .take_receipts_checked(Some(&self.log_decoder))? + provider.tx_status(&tx_id).await? }; + let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; self.get_response(receipts) } @@ -932,7 +920,7 @@ impl MultiContractCallHandler { let provider = self.account.try_provider()?; let tx = self.build_tx().await?; - provider.checked_dry_run(tx).await?; + provider.checked_dry_run(tx).await?.check(None)?; Ok(()) } diff --git a/packages/fuels-programs/src/script_calls.rs b/packages/fuels-programs/src/script_calls.rs index e521de9e09..748f38cef2 100644 --- a/packages/fuels-programs/src/script_calls.rs +++ b/packages/fuels-programs/src/script_calls.rs @@ -7,7 +7,7 @@ use fuels_accounts::{ Account, }; use fuels_core::{ - codec::{map_revert_error, DecoderConfig, LogDecoder}, + codec::{DecoderConfig, LogDecoder}, constants::BASE_ASSET_ID, offsets::base_offset_script, traits::{Parameterize, Tokenizable}, @@ -240,24 +240,20 @@ where let tx = self.build_tx().await?; self.cached_tx_id = Some(tx.id(self.provider.chain_id())); - let receipts = if simulate { + let tx_status = if simulate { self.provider.checked_dry_run(tx).await? } else { let tx_id = self.provider.send_transaction_and_await_commit(tx).await?; - self.provider - .tx_status(&tx_id) - .await? - .take_receipts_checked(Some(&self.log_decoder))? + self.provider.tx_status(&tx_id).await? }; + let receipts = tx_status.take_receipts_checked(Some(&self.log_decoder))?; self.get_response(receipts) } /// Call a script on the node, in a state-modifying manner. pub async fn call(mut self) -> Result> { - self.call_or_simulate(false) - .await - .map_err(|err| map_revert_error(err, &self.log_decoder)) + self.call_or_simulate(false).await } pub async fn submit(mut self) -> Result> { @@ -286,9 +282,7 @@ where /// /// [`call`]: Self::call pub async fn simulate(&mut self) -> Result> { - self.call_or_simulate(true) - .await - .map_err(|err| map_revert_error(err, &self.log_decoder)) + self.call_or_simulate(true).await } /// Get a scripts's estimated cost diff --git a/packages/fuels/tests/providers.rs b/packages/fuels/tests/providers.rs index b1eccb27a1..1012667731 100644 --- a/packages/fuels/tests/providers.rs +++ b/packages/fuels/tests/providers.rs @@ -65,7 +65,9 @@ async fn test_provider_launch_and_connect() -> Result<()> { Ok(()) } +// Ignored until https://github.com/FuelLabs/fuel-core/issues/1384 is resolved #[tokio::test] +#[ignore] async fn test_network_error() -> Result<()> { abigen!(Contract( name = "MyContract",