diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 920fe55659..d97a4f400b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,8 +19,9 @@ env: FUEL_CORE_VERSION: 0.20.6 RUST_VERSION: 1.72.1 FORC_VERSION: 0.46.0 - FORC_PATCH_BRANCH: "" + FORC_PATCH_BRANCH: "xunilrj/fix-implicit-std-env-vars" FORC_PATCH_REVISION: "" + FORC_IMPLICIT_STD_GIT_BRANCH: "xunilrj/fix-implicit-std-env-vars" jobs: setup-test-projects: diff --git a/.github/workflows/scripts/verify_tag.sh b/.github/workflows/scripts/verify_tag.sh index 4db9db2868..5020195e32 100755 --- a/.github/workflows/scripts/verify_tag.sh +++ b/.github/workflows/scripts/verify_tag.sh @@ -25,7 +25,7 @@ fi # strip preceeding 'v' if it exists on tag REF=${REF/#v} -TOML_VERSION=$(cat $MANIFEST | dasel -r toml 'workspace.package.version') +TOML_VERSION=$(cat $MANIFEST | dasel -r toml -w plain 'workspace.package.version') if [ "$TOML_VERSION" != "$REF" ]; then err "Crate version $TOML_VERSION, doesn't match tag version $REF" diff --git a/Cargo.toml b/Cargo.toml index 05b37a89b6..06b18cd06a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ readme = "README.md" license = "Apache-2.0" repository = "https://github.com/FuelLabs/fuels-rs" rust-version = "1.72.1" -version = "0.49.0" +version = "0.50.1" [workspace.dependencies] Inflector = "0.11.4" @@ -87,13 +87,13 @@ fuel-types = { version = "0.35.4", default-features = false } fuel-vm = "0.35.4" # Workspace projects -fuels = { version = "0.49.0", path = "./packages/fuels" } -fuels-accounts = { version = "0.49.0", path = "./packages/fuels-accounts", default-features = false } -fuels-code-gen = { version = "0.49.0", path = "./packages/fuels-code-gen", default-features = false } -fuels-core = { version = "0.49.0", path = "./packages/fuels-core", default-features = false } -fuels-macros = { version = "0.49.0", path = "./packages/fuels-macros", default-features = false } -fuels-programs = { version = "0.49.0", path = "./packages/fuels-programs", default-features = false } -fuels-test-helpers = { version = "0.49.0", path = "./packages/fuels-test-helpers", default-features = false } +fuels = { version = "0.50.1", path = "./packages/fuels" } +fuels-accounts = { version = "0.50.1", path = "./packages/fuels-accounts", default-features = false } +fuels-code-gen = { version = "0.50.1", path = "./packages/fuels-code-gen", default-features = false } +fuels-core = { version = "0.50.1", path = "./packages/fuels-core", default-features = false } +fuels-macros = { version = "0.50.1", path = "./packages/fuels-macros", default-features = false } +fuels-programs = { version = "0.50.1", path = "./packages/fuels-programs", default-features = false } +fuels-test-helpers = { version = "0.50.1", path = "./packages/fuels-test-helpers", default-features = false } [patch.crates-io] fuel-core = { git = "https://github.com/FuelLabs/fuel-core", branch = "master" } diff --git a/docs/src/connecting/short-lived.md b/docs/src/connecting/short-lived.md index 31d6f1ca8d..f7dd9d7f97 100644 --- a/docs/src/connecting/short-lived.md +++ b/docs/src/connecting/short-lived.md @@ -27,7 +27,7 @@ let wallet = launch_provider_and_get_wallet().await?; The `fuel-core-lib` feature allows us to run a `fuel-core` node without installing the `fuel-core` binary on the local machine. Using the `fuel-core-lib` feature flag entails downloading all the dependencies needed to run the fuel-core node. ```rust,ignore -fuels = { version = "0.49.0", features = ["fuel-core-lib"] } +fuels = { version = "0.50.1", features = ["fuel-core-lib"] } ``` ### RocksDb @@ -35,5 +35,5 @@ fuels = { version = "0.49.0", features = ["fuel-core-lib"] } The `rocksdb` is an additional feature that, when combined with `fuel-core-lib`, provides persistent storage capabilities while using `fuel-core` as a library. ```rust,ignore -fuels = { version = "0.49.0", features = ["rocksdb"] } +fuels = { version = "0.50.1", features = ["rocksdb"] } ``` diff --git a/examples/contracts/src/lib.rs b/examples/contracts/src/lib.rs index 4b1c6f367d..6735d35b89 100644 --- a/examples/contracts/src/lib.rs +++ b/examples/contracts/src/lib.rs @@ -103,7 +103,7 @@ mod tests { .await?; // ANCHOR_END: contract_call_cost_estimation - assert_eq!(transaction_cost.gas_used, 397); + assert_eq!(transaction_cost.gas_used, 470); Ok(()) } @@ -649,7 +649,7 @@ mod tests { .await?; // ANCHOR_END: multi_call_cost_estimation - assert_eq!(transaction_cost.gas_used, 618); + assert_eq!(transaction_cost.gas_used, 693); Ok(()) } diff --git a/packages/fuels-accounts/src/accounts_utils.rs b/packages/fuels-accounts/src/accounts_utils.rs index 300e495cb8..eb515e19b6 100644 --- a/packages/fuels-accounts/src/accounts_utils.rs +++ b/packages/fuels-accounts/src/accounts_utils.rs @@ -4,7 +4,7 @@ use fuels_core::{ constants::BASE_ASSET_ID, types::{ bech32::Bech32Address, - errors::{error, Error, Result}, + errors::{error, Result}, input::Input, transaction_builders::TransactionBuilder, }, diff --git a/packages/fuels-accounts/src/provider.rs b/packages/fuels-accounts/src/provider.rs index 629d6a61b9..237a20601f 100644 --- a/packages/fuels-accounts/src/provider.rs +++ b/packages/fuels-accounts/src/provider.rs @@ -307,7 +307,7 @@ impl Provider { TxStatus::Revert { receipts, reason, - id: revert_id, + revert_id, } } TransactionStatus::Submitted { .. } => TxStatus::Submitted, @@ -384,7 +384,7 @@ impl Provider { Some(reason) => TxStatus::Revert { receipts, reason, - id: 0, + revert_id: 0, }, None => TxStatus::Success { receipts }, } diff --git a/packages/fuels-accounts/src/provider/retry_util.rs b/packages/fuels-accounts/src/provider/retry_util.rs index 3847fecfcf..631ba81a21 100644 --- a/packages/fuels-accounts/src/provider/retry_util.rs +++ b/packages/fuels-accounts/src/provider/retry_util.rs @@ -1,6 +1,6 @@ use std::{fmt::Debug, future::Future, num::NonZeroU32, time::Duration}; -use fuels_core::types::errors::{error, Error, Result as SdkResult}; +use fuels_core::types::errors::{error, Result as SdkResult}; /// A set of strategies to control retry intervals between attempts. /// diff --git a/packages/fuels-accounts/src/provider/retryable_client.rs b/packages/fuels-accounts/src/provider/retryable_client.rs index 89db3c1e30..fae7610239 100644 --- a/packages/fuels-accounts/src/provider/retryable_client.rs +++ b/packages/fuels-accounts/src/provider/retryable_client.rs @@ -8,10 +8,7 @@ use fuel_core_client::client::{ }; use fuel_tx::{Receipt, Transaction, TxId, UtxoId}; use fuel_types::{Address, AssetId, BlockHeight, ContractId, MessageId, Nonce}; -use fuels_core::{ - error, - types::errors::{Error, Result}, -}; +use fuels_core::{error, types::errors::Result}; use crate::provider::{retry_util, RetryConfig}; diff --git a/packages/fuels-core/src/codec/abi_decoder.rs b/packages/fuels-core/src/codec/abi_decoder.rs index 1b5cc8cd43..16afa156a2 100644 --- a/packages/fuels-core/src/codec/abi_decoder.rs +++ b/packages/fuels-core/src/codec/abi_decoder.rs @@ -52,14 +52,19 @@ impl ABIDecoder { /// /// let decoder = ABIDecoder::default(); /// - /// let token = decoder.decode(&ParamType::U8, &[0, 0, 0, 0, 0, 0, 0, 7]).unwrap(); + /// let token = decoder.decode(&ParamType::U64, &[0, 0, 0, 0, 0, 0, 0, 7]).unwrap(); /// - /// assert_eq!(u8::from_token(token).unwrap(), 7u8); + /// assert_eq!(u64::from_token(token).unwrap(), 7u64); /// ``` pub fn decode(&self, param_type: &ParamType, bytes: &[u8]) -> Result { BoundedDecoder::new(self.config).decode(param_type, bytes) } + /// Decode data from one of the receipt returns. + pub fn decode_receipt_return(&self, param_type: &ParamType, bytes: &[u8]) -> Result { + BoundedDecoder::new(self.config).decode(param_type, bytes) + } + /// Same as `decode` but decodes multiple `ParamType`s in one go. /// # Examples /// ``` @@ -68,7 +73,7 @@ impl ABIDecoder { /// use fuels_core::types::Token; /// /// let decoder = ABIDecoder::default(); - /// let data: &[u8] = &[0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8]; + /// let data: &[u8] = &[7, 8]; /// /// let tokens = decoder.decode_multiple(&[ParamType::U8, ParamType::U8], &data).unwrap(); /// @@ -114,7 +119,7 @@ mod tests { ]; let data = [ 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, // u32 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, // u8 + 0xff, // u8 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, // u16 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // u64 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, @@ -141,9 +146,7 @@ mod tests { #[test] fn decode_bool() -> Result<()> { let types = vec![ParamType::Bool, ParamType::Bool]; - let data = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x00, - ]; + let data = [0x01, 0x0]; let decoded = ABIDecoder::default().decode_multiple(&types, &data)?; @@ -215,9 +218,7 @@ mod tests { fn decode_array() -> Result<()> { // Create a parameter type for u8[2]. let types = vec![ParamType::Array(Box::new(ParamType::U8), 2)]; - let data = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2a, - ]; + let data = [0xff, 0x2a]; let decoded = ABIDecoder::default().decode_multiple(&types, &data)?; @@ -234,7 +235,7 @@ mod tests { // } let data = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ]; let param_type = ParamType::Struct { fields: vec![ParamType::U8, ParamType::Bool], @@ -366,8 +367,8 @@ mod tests { }; let data = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ]; let decoded = ABIDecoder::default().decode(&nested_struct, &data)?; @@ -416,26 +417,23 @@ mod tests { let u8_arr = ParamType::Array(Box::new(ParamType::U8), 2); let b256 = ParamType::B256; - let s = ParamType::StringArray(3); - let ss = ParamType::StringSlice; - let types = [nested_struct, u8_arr, b256, s, ss]; + let types = [nested_struct, u8_arr, b256]; let bytes = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, // foo.x == 10u16 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, // foo.y.a == true - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, // foo.b.0 == 1u8 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, // foo.b.1 == 2u8 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, // u8[2].0 == 1u8 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, // u8[2].0 == 2u8 - 0xd5, 0x57, 0x9c, 0x46, 0xdf, 0xcc, 0x7f, 0x18, // b256 - 0x20, 0x70, 0x13, 0xe6, 0x5b, 0x44, 0xe4, 0xcb, // b256 - 0x4e, 0x2c, 0x22, 0x98, 0xf4, 0xac, 0x45, 0x7b, // b256 - 0xa8, 0xf8, 0x27, 0x43, 0xf3, 0x1e, 0x93, 0xb, // b256 - 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, // str[3] - 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, // str data - 0x61, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x73, // str data - 0x65, 0x6e, 0x74, 0x65, 0x6e, 0x63, 0x65, // str data + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, // u16 + 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // bool + 0x1, 0x2, // array[u8] + 0x1, 0x2, // array[u8] + 0xd5, 0x57, 0x9c, 0x46, 0xdf, 0xcc, 0x7f, 0x18, // b256 start + 0x20, 0x70, 0x13, 0xe6, 0x5b, 0x44, 0xe4, 0xcb, // + 0x4e, 0x2c, 0x22, 0x98, 0xf4, 0xac, 0x45, 0x7b, // + 0xa8, 0xf8, 0x27, 0x43, 0xf3, 0x1e, 0x93, + 0xb, // b256 end + // 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, // "foo" + // 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, // + // 0x61, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x73, // + // 0x65, 0x6e, 0x74, 0x65, 0x6e, 0x63, 0x65, // ]; let decoded = ABIDecoder::default().decode_multiple(&types, &bytes)?; @@ -457,14 +455,7 @@ mod tests { 0xf3, 0x1e, 0x93, 0xb, ]); - let ss = Token::StringSlice(StaticStringToken::new( - "This is a full sentence".into(), - None, - )); - - let s = Token::StringArray(StaticStringToken::new("foo".into(), Some(3))); - - let expected: Vec = vec![foo, u8_arr, b256, s, ss]; + let expected: Vec = vec![foo, u8_arr, b256]; assert_eq!(decoded, expected); Ok(()) @@ -555,13 +546,6 @@ mod tests { assert!(matches!(result, Err(Error::InvalidType(_)))); } - #[test] - pub fn multiply_overflow_vector() { - let param_type = Vec::<[(); usize::MAX]>::param_type(); - let result = ABIDecoder::default().decode(¶m_type, &[]); - assert!(matches!(result, Err(Error::InvalidData(_)))); - } - #[test] pub fn multiply_overflow_arith() { let mut param_type: ParamType = U16; diff --git a/packages/fuels-core/src/codec/abi_decoder/bounded_decoder.rs b/packages/fuels-core/src/codec/abi_decoder/bounded_decoder.rs index 788b7f780c..f0e8b63b43 100644 --- a/packages/fuels-core/src/codec/abi_decoder/bounded_decoder.rs +++ b/packages/fuels-core/src/codec/abi_decoder/bounded_decoder.rs @@ -1,14 +1,13 @@ use std::{convert::TryInto, str}; -use fuel_types::bytes::padded_len_usize; - use crate::{ codec::DecoderConfig, constants::WORD_SIZE, + round_up_to_word_alignment, traits::Tokenizable, types::{ enum_variants::EnumVariants, - errors::{error, Error, Result}, + errors::{error, Result}, param_types::ParamType, StaticStringToken, Token, U256, }, @@ -37,9 +36,25 @@ impl BoundedDecoder { } } - pub(crate) fn decode(&mut self, param_type: &ParamType, bytes: &[u8]) -> Result { + pub fn decode(&mut self, param_type: &ParamType, bytes: &[u8]) -> Result { param_type.validate_is_decodable(self.config.max_depth)?; - Ok(self.decode_param(param_type, bytes)?.token) + match param_type { + // Unit, U8 and Bool are returned as u64 from receipt "Return" + ParamType::Unit => Ok(Token::Unit), + ParamType::U8 => Self::decode_u64(bytes).map(|r| { + Token::U8(match r.token { + Token::U64(v) => v as u8, + _ => unreachable!("decode_u64 returning unexpected token"), + }) + }), + ParamType::Bool => Self::decode_u64(bytes).map(|r| { + Token::Bool(match r.token { + Token::U64(v) => v != 0, + _ => unreachable!("decode_u64 returning unexpected token"), + }) + }), + _ => self.decode_param(param_type, bytes).map(|x| x.token), + } } pub(crate) fn decode_multiple( @@ -130,7 +145,17 @@ impl BoundedDecoder { } fn decode_tuple(&mut self, param_types: &[ParamType], bytes: &[u8]) -> Result { - let (tokens, bytes_read) = self.decode_params(param_types, bytes)?; + let mut tokens = vec![]; + + let mut bytes_read = 0; + + for param_type in param_types.iter() { + // padding has to be taken into account + bytes_read = round_up_to_word_alignment(bytes_read); + let res = self.decode_param(param_type, skip(bytes, bytes_read)?)?; + bytes_read += res.bytes_read; + tokens.push(res.token); + } Ok(Decoded { token: Token::Tuple(tokens), @@ -139,7 +164,17 @@ impl BoundedDecoder { } fn decode_struct(&mut self, param_types: &[ParamType], bytes: &[u8]) -> Result { - let (tokens, bytes_read) = self.decode_params(param_types, bytes)?; + let mut tokens = vec![]; + + let mut bytes_read = 0; + + for param_type in param_types.iter() { + // padding has to be taken into account + bytes_read = round_up_to_word_alignment(bytes_read); + let res = self.decode_param(param_type, skip(bytes, bytes_read)?)?; + bytes_read += res.bytes_read; + tokens.push(res.token); + } Ok(Decoded { token: Token::Struct(tokens), @@ -209,13 +244,12 @@ impl BoundedDecoder { } fn decode_string_array(bytes: &[u8], length: usize) -> Result { - let encoded_len = padded_len_usize(length); - let encoded_str = peek(bytes, encoded_len)?; + let encoded_str = peek(bytes, length)?; - let decoded = str::from_utf8(&encoded_str[..length])?; + let decoded = str::from_utf8(encoded_str)?; let result = Decoded { token: Token::StringArray(StaticStringToken::new(decoded.into(), Some(length))), - bytes_read: encoded_len, + bytes_read: round_up_to_word_alignment(length), }; Ok(result) } @@ -233,7 +267,7 @@ impl BoundedDecoder { let result = Decoded { token: Token::Bool(b), - bytes_read: WORD_SIZE, + bytes_read: 1, }; Ok(result) @@ -277,17 +311,17 @@ impl BoundedDecoder { fn decode_u8(bytes: &[u8]) -> Result { Ok(Decoded { token: Token::U8(peek_u8(bytes)?), - bytes_read: WORD_SIZE, + bytes_read: 1, }) } fn decode_unit(bytes: &[u8]) -> Result { // We don't need the data, we're doing this purely as a bounds // check. - peek_fixed::(bytes)?; + peek_fixed::<1>(bytes)?; Ok(Decoded { token: Token::Unit, - bytes_read: WORD_SIZE, + bytes_read: 1, }) } @@ -299,33 +333,33 @@ impl BoundedDecoder { /// * `data`: slice of encoded data on whose beginning we're expecting an encoded enum /// * `variants`: all types that this particular enum type could hold fn decode_enum(&mut self, bytes: &[u8], variants: &EnumVariants) -> Result { - let enum_width = variants.compute_encoding_width_of_enum()?; + let enum_width_in_bytes = variants + .compute_enum_width_in_bytes() + .ok_or(error!(InvalidData, "Error calculating enum width in bytes"))?; - let discriminant = peek_u32(bytes)? as u8; + let discriminant = peek_u64(bytes)?; let selected_variant = variants.param_type_of_variant(discriminant)?; - let skip_extra = variants + let skip_extra_in_bytes = variants .heap_type_variant() .and_then(|(heap_discriminant, heap_type)| { - (heap_discriminant == discriminant).then_some(heap_type.compute_encoding_width()) + (heap_discriminant == discriminant).then_some(heap_type.compute_encoding_in_bytes()) }) - .transpose()? + .unwrap_or_default() .unwrap_or_default(); + let bytes_to_skip = enum_width_in_bytes + - selected_variant + .compute_encoding_in_bytes() + .ok_or(error!(InvalidData, "Error calculating enum width in bytes"))? + + skip_extra_in_bytes; - let words_to_skip = enum_width - selected_variant.compute_encoding_width()? + skip_extra; - let bytes_to_skip = words_to_skip.checked_mul(WORD_SIZE).ok_or_else(|| { - error!( - InvalidData, - "Overflow error while decoding enum {variants:?}" - ) - })?; let enum_content_bytes = skip(bytes, bytes_to_skip)?; let result = self.decode_token_in_enum(enum_content_bytes, variants, selected_variant)?; let selector = Box::new((discriminant, result.token, variants.clone())); Ok(Decoded { token: Token::Enum(selector), - bytes_read: enum_width * WORD_SIZE, + bytes_read: enum_width_in_bytes, }) } @@ -426,8 +460,8 @@ fn peek_u16(bytes: &[u8]) -> Result { fn peek_u8(bytes: &[u8]) -> Result { const BYTES: usize = std::mem::size_of::(); - let slice = peek_fixed::(bytes)?; - let bytes = slice[WORD_SIZE - BYTES..] + let slice = peek_fixed::<1>(bytes)?; + let bytes = slice[1 - BYTES..] .try_into() .expect("peek_u8: You must use a slice containing exactly 1B."); Ok(u8::from_be_bytes(bytes)) diff --git a/packages/fuels-core/src/codec/abi_encoder.rs b/packages/fuels-core/src/codec/abi_encoder.rs index b37369c000..b4eb411cd4 100644 --- a/packages/fuels-core/src/codec/abi_encoder.rs +++ b/packages/fuels-core/src/codec/abi_encoder.rs @@ -1,44 +1,76 @@ use fuel_types::bytes::padded_len_usize; -use itertools::Itertools; use crate::{ constants::WORD_SIZE, + round_up_to_word_alignment, types::{ errors::Result, - pad_string, pad_u16, pad_u32, pad_u8, + pad_u16, pad_u32, unresolved_bytes::{Data, UnresolvedBytes}, EnumSelector, StaticStringToken, Token, U256, }, }; +/// Insert zero following the padding strategy +#[derive(Clone, Copy)] +pub enum InsertPadding { + /// Zeros are inserted on the left until it fills an integer quantity of words + Left, + /// Zeros are inserted on the right until it fills an integer quantity of words + Right, +} + pub struct ABIEncoder; impl ABIEncoder { /// Encodes `Token`s in `args` following the ABI specs defined /// [here](https://github.com/FuelLabs/fuel-specs/blob/master/specs/protocol/abi.md) pub fn encode(args: &[Token]) -> Result { - let data = Self::encode_tokens(args)?; + let data = if args.len() == 1 { + match args[0] { + Token::Bool(arg_bool) => vec![Self::encode_bool_as_u64(arg_bool)], + Token::U8(arg_u8) => vec![Self::encode_u8_as_u64(arg_u8)], + _ => Self::encode_tokens(args, true)?, + } + } else { + Self::encode_tokens(args, true)? + }; Ok(UnresolvedBytes::new(data)) } - fn encode_tokens(tokens: &[Token]) -> Result> { - tokens - .iter() - .map(Self::encode_token) - .flatten_ok() - .collect::>>() + fn encode_tokens(tokens: &[Token], word_aligned: bool) -> Result> { + let mut offset_in_bytes = 0; + let mut data = vec![]; + + for token in tokens.iter() { + let mut new_data = Self::encode_token(token)?; + offset_in_bytes += new_data.iter().map(|x| x.size_in_bytes()).sum::(); + + data.append(&mut new_data); + + if word_aligned { + let padding = + vec![0u8; round_up_to_word_alignment(offset_in_bytes) - offset_in_bytes]; + if !padding.is_empty() { + offset_in_bytes += padding.len(); + data.push(Data::Inline(padding)); + } + } + } + + Ok(data) } fn encode_token(arg: &Token) -> Result> { let encoded_token = match arg { - Token::U8(arg_u8) => vec![Self::encode_u8(*arg_u8)], + Token::Bool(arg_bool) => vec![Self::encode_bool_as_byte(*arg_bool)], + Token::U8(arg_u8) => vec![Self::encode_u8_as_byte(*arg_u8)], Token::U16(arg_u16) => vec![Self::encode_u16(*arg_u16)], Token::U32(arg_u32) => vec![Self::encode_u32(*arg_u32)], Token::U64(arg_u64) => vec![Self::encode_u64(*arg_u64)], Token::U128(arg_u128) => vec![Self::encode_u128(*arg_u128)], Token::U256(arg_u256) => vec![Self::encode_u256(*arg_u256)], - Token::Bool(arg_bool) => vec![Self::encode_bool(*arg_bool)], Token::B256(arg_bits256) => vec![Self::encode_b256(arg_bits256)], Token::Array(arg_array) => Self::encode_array(arg_array)?, Token::Vector(data) => Self::encode_vector(data)?, @@ -58,27 +90,31 @@ impl ABIEncoder { } fn encode_unit() -> Data { - Data::Inline(vec![0; WORD_SIZE]) + Data::Inline(vec![0u8]) } fn encode_tuple(arg_tuple: &[Token]) -> Result> { - Self::encode_tokens(arg_tuple) + Self::encode_tokens(arg_tuple, true) } fn encode_struct(subcomponents: &[Token]) -> Result> { - Self::encode_tokens(subcomponents) + Self::encode_tokens(subcomponents, true) } fn encode_array(arg_array: &[Token]) -> Result> { - Self::encode_tokens(arg_array) + Self::encode_tokens(arg_array, false) } fn encode_b256(arg_bits256: &[u8; 32]) -> Data { Data::Inline(arg_bits256.to_vec()) } - fn encode_bool(arg_bool: bool) -> Data { - Data::Inline(pad_u8(u8::from(arg_bool)).to_vec()) + fn encode_bool_as_byte(arg_bool: bool) -> Data { + Data::Inline(vec![u8::from(arg_bool)]) + } + + fn encode_bool_as_u64(arg_bool: bool) -> Data { + Data::Inline(vec![0, 0, 0, 0, 0, 0, 0, u8::from(arg_bool)]) } fn encode_u128(arg_u128: u128) -> Data { @@ -103,8 +139,12 @@ impl ABIEncoder { Data::Inline(pad_u16(arg_u16).to_vec()) } - fn encode_u8(arg_u8: u8) -> Data { - Data::Inline(pad_u8(arg_u8).to_vec()) + fn encode_u8_as_byte(arg_u8: u8) -> Data { + Data::Inline(vec![arg_u8]) + } + + fn encode_u8_as_u64(arg_u8: u8) -> Data { + Data::Inline(vec![0, 0, 0, 0, 0, 0, 0, arg_u8]) } fn encode_enum(selector: &EnumSelector) -> Result> { @@ -115,7 +155,7 @@ impl ABIEncoder { // Enums that contain only Units as variants have only their discriminant encoded. if !variants.only_units_inside() { let variant_param_type = variants.param_type_of_variant(*discriminant)?; - let padding_amount = variants.compute_padding_amount(variant_param_type)?; + let padding_amount = variants.compute_padding_amount_in_bytes(variant_param_type)?; encoded_enum.push(Data::Inline(vec![0; padding_amount])); @@ -126,12 +166,12 @@ impl ABIEncoder { Ok(encoded_enum) } - fn encode_discriminant(discriminant: u8) -> Data { - Self::encode_u8(discriminant) + fn encode_discriminant(discriminant: u64) -> Data { + Self::encode_u64(discriminant) } fn encode_vector(data: &[Token]) -> Result> { - let encoded_data = Self::encode_tokens(data)?; + let encoded_data = Self::encode_tokens(data, false)?; let cap = data.len() as u64; let len = data.len() as u64; @@ -169,7 +209,9 @@ impl ABIEncoder { } fn encode_string_array(arg_string: &StaticStringToken) -> Result { - Ok(Data::Inline(pad_string(arg_string.get_encodable_str()?))) + Ok(Data::Inline(crate::types::pad_string( + arg_string.get_encodable_str()?, + ))) } fn encode_bytes(mut data: Vec) -> Result> { @@ -382,7 +424,9 @@ mod tests { let args: Vec = vec![first, second]; let expected_encoded_abi = [ - 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, // u32::MAX + 0x1, // true + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ]; let expected_function_selector = [0x0, 0x0, 0x0, 0x0, 0xf5, 0x40, 0x73, 0x2b]; @@ -468,10 +512,7 @@ mod tests { let args: Vec = vec![arg_array]; - let expected_encoded_abi = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, - ]; + let expected_encoded_abi = [0x1, 0x2, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0]; let expected_function_selector = [0x0, 0x0, 0x0, 0x0, 0x2c, 0x5a, 0x10, 0x2e]; @@ -509,7 +550,7 @@ mod tests { let expected_encoded_abi = [ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x66, 0x75, 0x6c, 0x6c, - 0x20, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x00, + 0x20, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x0, ]; let expected_function_selector = [0x0, 0x0, 0x0, 0x0, 0xd5, 0x6e, 0x76, 0x51]; @@ -597,7 +638,10 @@ mod tests { let args: Vec = vec![arg]; let expected_encoded_abi = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, + 0x1, // 1u8 + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // padding + 0x1, // true + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // padding ]; let expected_function_selector = [0x0, 0x0, 0x0, 0x0, 0xa8, 0x1e, 0x8d, 0xd7]; @@ -701,12 +745,6 @@ mod tests { let deeper_enum_token = Token::StringArray(StaticStringToken::new("0123456789".into(), Some(10))); - let str_enc = vec![ - b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, - ]; - let deeper_enum_discriminant_enc = vec![0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1]; - /* struct StructA { some_enum: DeeperEnum @@ -730,7 +768,6 @@ mod tests { Token::Enum(Box::new((1, deeper_enum_token, deeper_enum_variants))), Token::U32(11332), ]); - let some_number_enc = vec![0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x44]; /* enum TopLevelEnum { @@ -744,19 +781,17 @@ mod tests { let top_level_enum_variants = EnumVariants::new(types)?; let top_level_enum_token = Token::Enum(Box::new((0, struct_a_token, top_level_enum_variants))); - let top_lvl_discriminant_enc = vec![0x0; 8]; let encoded = ABIEncoder::encode(slice::from_ref(&top_level_enum_token))?.resolve(0); let correct_encoding: Vec = [ - top_lvl_discriminant_enc, - deeper_enum_discriminant_enc, - str_enc, - some_number_enc, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TopLevelEnum::v1 discriminant + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // DeeperEnum::v2 discriminant + b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', // str[10] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // DeeperEnum padding + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x44, // StructA.some_number ] - .into_iter() - .flatten() - .collect(); + .into(); assert_eq!(hex::encode(correct_encoding), hex::encode(encoded)); Ok(()) @@ -797,8 +832,11 @@ mod tests { ])]; let expected_encoded_abi = [ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, // 10u16 + 0x1, // true + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // padding + 0x1, 0x2, // [1u8, 2u8] + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // padding ]; let expected_function_selector = [0x0, 0x0, 0x0, 0x0, 0xea, 0x0a, 0xfd, 0x23]; @@ -881,18 +919,22 @@ mod tests { let expected_encoded_abi = [ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, // foo.x == 10u16 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, // foo.y.a == true - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, // foo.b.0 == 1u8 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, // foo.b.1 == 2u8 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, // u8[2].0 == 1u8 - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, // u8[2].0 == 2u8 - 0xd5, 0x57, 0x9c, 0x46, 0xdf, 0xcc, 0x7f, 0x18, // b256 + 0x1, // foo.y.a == true + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // foo.y.a padding + 0x1, // foo.y.b.0 == 1u8 + 0x2, // foo.y.b.1 == 2u8 + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, // foo.y.a + 0x1, // u8[2].0 == 1u8 + 0x2, // u8[2].0 == 2u8 + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd5, 0x57, 0x9c, 0x46, 0xdf, 0xcc, 0x7f, + 0x18, // b256 0x20, 0x70, 0x13, 0xe6, 0x5b, 0x44, 0xe4, 0xcb, // b256 0x4e, 0x2c, 0x22, 0x98, 0xf4, 0xac, 0x45, 0x7b, // b256 0xa8, 0xf8, 0x27, 0x43, 0xf3, 0x1e, 0x93, 0xb, // b256 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, // str[23] 0x61, 0x20, 0x66, 0x75, 0x6c, 0x6c, 0x20, 0x73, // str[23] - 0x65, 0x6e, 0x74, 0x65, 0x6e, 0x63, 0x65, 0x0, // str[23] + 0x65, 0x6e, 0x74, 0x65, 0x6e, 0x63, 0x65, // str[23] + 0x0, ]; let expected_function_selector = [0x0, 0x0, 0x0, 0x0, 0x10, 0x93, 0xb2, 0x12]; @@ -1086,14 +1128,8 @@ mod tests { let vec1_len = [0, 0, 0, 0, 0, 0, 0, 1]; let vec1_data = [0, 0, 0, 0, 0, 0, 0, 5]; - let expected = chain!( - vec1_ptr, - vec1_cap, - vec1_len, - [0, 0, 0, 0, 0, 0, 0, 9], - vec1_data - ) - .collect::>(); + let expected = + chain!(vec1_ptr, vec1_cap, vec1_len, [9], [0; 7], vec1_data).collect::>(); assert_eq!(result, expected); @@ -1120,7 +1156,7 @@ mod tests { .to_vec(); let vec2_cap = [0, 0, 0, 0, 0, 0, 0, 2]; let vec2_len = [0, 0, 0, 0, 0, 0, 0, 2]; - let vec2_data = [0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6]; + let vec2_data = [5, 6]; let vec1_data = chain!(vec2_ptr, vec2_cap, vec2_len, vec2_data).collect::>(); diff --git a/packages/fuels-core/src/codec/logs.rs b/packages/fuels-core/src/codec/logs.rs index c97ebfb325..02c791129a 100644 --- a/packages/fuels-core/src/codec/logs.rs +++ b/packages/fuels-core/src/codec/logs.rs @@ -8,7 +8,7 @@ use std::{ use fuel_tx::{ContractId, Receipt}; use crate::{ - codec::{try_from_bytes, DecoderConfig}, + codec::DecoderConfig, traits::{Parameterize, Tokenizable}, types::{ errors::{error, Error, Result}, @@ -16,6 +16,8 @@ use crate::{ }, }; +use super::ABIDecoder; + #[derive(Clone)] pub struct LogFormatter { formatter: fn(DecoderConfig, &[u8]) -> Result, @@ -35,7 +37,9 @@ impl LogFormatter { bytes: &[u8], ) -> Result { Self::can_decode_log_with_type::()?; - Ok(format!("{:?}", try_from_bytes::(bytes, decoder_config)?)) + let token = + ABIDecoder::new(decoder_config).decode_receipt_return(&T::param_type(), bytes)?; + Ok(format!("{:?}", T::from_token(token)?)) } fn can_decode_log_with_type() -> Result<()> { @@ -185,10 +189,12 @@ impl LogDecoder { receipts .iter() .extract_log_id_and_data() - .filter_map(|(log_id, data)| { - target_ids - .contains(&log_id) - .then_some(try_from_bytes(&data, self.decoder_config)) + .filter_map(|(log_id, bytes)| { + target_ids.contains(&log_id).then(|| { + let token = ABIDecoder::new(self.decoder_config) + .decode_receipt_return(&T::param_type(), &bytes)?; + T::from_token(token) + }) }) .collect() } diff --git a/packages/fuels-core/src/traits/tokenizable.rs b/packages/fuels-core/src/traits/tokenizable.rs index 2413089fd0..e87d3b8657 100644 --- a/packages/fuels-core/src/traits/tokenizable.rs +++ b/packages/fuels-core/src/traits/tokenizable.rs @@ -3,7 +3,7 @@ use fuel_types::{Address, AssetId, ContractId}; use crate::{ traits::Parameterize, types::{ - errors::{error, Error, Result}, + errors::{error, Result}, param_types::ParamType, AsciiString, Bits256, Bytes, RawSlice, SizedAsciiString, StaticStringToken, Token, }, @@ -381,8 +381,8 @@ where fn from_token(token: Token) -> Result { if let Token::Enum(enum_selector) = token { match *enum_selector { - (0u8, _, _) => Ok(None), - (1u8, token, _) => Ok(Option::::Some(T::from_token(token)?)), + (0, _, _) => Ok(None), + (1, token, _) => Ok(Option::::Some(T::from_token(token)?)), (_, _, _) => Err(error!( InstantiationError, "Could not construct Option from enum_selector. Received: {:?}", enum_selector @@ -397,8 +397,8 @@ where } fn into_token(self) -> Token { let (dis, tok) = match self { - None => (0u8, Token::Unit), - Some(value) => (1u8, value.into_token()), + None => (0, Token::Unit), + Some(value) => (1, value.into_token()), }; if let ParamType::Enum { variants, .. } = Self::param_type() { let selector = (dis, tok, variants); @@ -417,8 +417,8 @@ where fn from_token(token: Token) -> Result { if let Token::Enum(enum_selector) = token { match *enum_selector { - (0u8, token, _) => Ok(std::result::Result::::Ok(T::from_token(token)?)), - (1u8, token, _) => Ok(std::result::Result::::Err(E::from_token(token)?)), + (0, token, _) => Ok(std::result::Result::::Ok(T::from_token(token)?)), + (1, token, _) => Ok(std::result::Result::::Err(E::from_token(token)?)), (_, _, _) => Err(error!( InstantiationError, "Could not construct Result from enum_selector. Received: {:?}", enum_selector @@ -433,8 +433,8 @@ where } fn into_token(self) -> Token { let (dis, tok) = match self { - Ok(value) => (0u8, value.into_token()), - Err(value) => (1u8, value.into_token()), + Ok(value) => (0, value.into_token()), + Err(value) => (1, value.into_token()), }; if let ParamType::Enum { variants, .. } = Self::param_type() { let selector = (dis, tok, variants); diff --git a/packages/fuels-core/src/types.rs b/packages/fuels-core/src/types.rs index b1236dfae4..a20d7cdcc1 100644 --- a/packages/fuels-core/src/types.rs +++ b/packages/fuels-core/src/types.rs @@ -22,7 +22,7 @@ mod wrappers; pub type ByteArray = [u8; 8]; pub type Selector = ByteArray; -pub type EnumSelector = (u8, Token, EnumVariants); +pub type EnumSelector = (u64, Token, EnumVariants); #[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)] pub struct StaticStringToken { @@ -108,13 +108,6 @@ impl Default for Token { } } -/// Converts a u8 to a right aligned array of 8 bytes. -pub fn pad_u8(value: u8) -> ByteArray { - let mut padded = ByteArray::default(); - padded[7] = value; - padded -} - /// Converts a u16 to a right aligned array of 8 bytes. pub fn pad_u16(value: u16) -> ByteArray { let mut padded = ByteArray::default(); diff --git a/packages/fuels-core/src/types/core/bits.rs b/packages/fuels-core/src/types/core/bits.rs index 8234232b6a..7271f2b1a0 100644 --- a/packages/fuels-core/src/types/core/bits.rs +++ b/packages/fuels-core/src/types/core/bits.rs @@ -1,7 +1,7 @@ use fuel_types::AssetId; use fuels_macros::{Parameterize, Tokenizable, TryFrom}; -use crate::types::errors::{error, Error, Result}; +use crate::types::errors::{error, Result}; // A simple wrapper around [u8; 32] representing the `b256` type. Exists // mainly so that we may differentiate `Parameterize` and `Tokenizable` diff --git a/packages/fuels-core/src/types/core/u256.rs b/packages/fuels-core/src/types/core/u256.rs index b948002d09..dcca899eb2 100644 --- a/packages/fuels-core/src/types/core/u256.rs +++ b/packages/fuels-core/src/types/core/u256.rs @@ -6,7 +6,7 @@ use uint::construct_uint; use crate::{ traits::{Parameterize, Tokenizable}, types::{ - errors::{error, Error, Result as FuelsResult}, + errors::{error, Result as FuelsResult}, param_types::ParamType, Token, }, diff --git a/packages/fuels-core/src/types/enum_variants.rs b/packages/fuels-core/src/types/enum_variants.rs index b083b1abaa..9e6e6cd0c1 100644 --- a/packages/fuels-core/src/types/enum_variants.rs +++ b/packages/fuels-core/src/types/enum_variants.rs @@ -1,9 +1,10 @@ use crate::{ - constants::{ENUM_DISCRIMINANT_WORD_WIDTH, WORD_SIZE}, + constants::ENUM_DISCRIMINANT_BYTE_WIDTH, types::{ - errors::{error, Error, Result}, + errors::{error, Result}, param_types::ParamType, }, + utils::round_up_to_word_alignment, }; #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] @@ -23,7 +24,7 @@ impl EnumVariants { &self.param_types } - pub fn param_type_of_variant(&self, discriminant: u8) -> Result<&ParamType> { + pub fn param_type_of_variant(&self, discriminant: u64) -> Result<&ParamType> { self.param_types.get(discriminant as usize).ok_or_else(|| { error!( InvalidData, @@ -33,11 +34,11 @@ impl EnumVariants { }) } - pub fn heap_type_variant(&self) -> Option<(u8, &ParamType)> { + pub fn heap_type_variant(&self) -> Option<(u64, &ParamType)> { self.param_types() .iter() .enumerate() - .find_map(|(d, p)| p.is_extra_receipt_needed(false).then_some((d as u8, p))) + .find_map(|(d, p)| p.is_extra_receipt_needed(false).then_some((d as u64, p))) } pub fn only_units_inside(&self) -> bool { @@ -46,33 +47,34 @@ impl EnumVariants { .all(|param_type| *param_type == ParamType::Unit) } - /// Calculates how many WORDs are needed to encode an enum. - pub fn compute_encoding_width_of_enum(&self) -> Result { + /// Calculates how many bytes are needed to encode an enum. + pub fn compute_enum_width_in_bytes(&self) -> Option { if self.only_units_inside() { - return Ok(ENUM_DISCRIMINANT_WORD_WIDTH); + return Some(ENUM_DISCRIMINANT_BYTE_WIDTH); } - self.param_types() - .iter() - .map(|p| p.compute_encoding_width()) - .collect::>>()? - .iter() - .max() - .map(|width| width + ENUM_DISCRIMINANT_WORD_WIDTH) - .ok_or_else(|| { - error!( - InvalidData, - "EnumVariants was empty, must have at least one variant" - ) - }) + + let width = self.param_types().iter().try_fold(0, |a, p| { + let size = p.compute_encoding_in_bytes()?; + Some(a.max(size)) + })?; + + Some(round_up_to_word_alignment(width) + ENUM_DISCRIMINANT_BYTE_WIDTH) } /// Determines the padding needed for the provided enum variant (based on the width of the /// biggest variant) and returns it. - pub fn compute_padding_amount(&self, variant_param_type: &ParamType) -> Result { - let biggest_variant_width = - self.compute_encoding_width_of_enum()? - ENUM_DISCRIMINANT_WORD_WIDTH; - let variant_width = variant_param_type.compute_encoding_width()?; - Ok((biggest_variant_width - variant_width) * WORD_SIZE) + pub fn compute_padding_amount_in_bytes(&self, variant_param_type: &ParamType) -> Result { + let enum_width = self + .compute_enum_width_in_bytes() + .ok_or(error!(InvalidData, "Error calculating enum width in bytes"))?; + let biggest_variant_width = enum_width - ENUM_DISCRIMINANT_BYTE_WIDTH; + let variant_width = variant_param_type + .compute_encoding_in_bytes() + .ok_or(error!( + InvalidData, + "Error calculating padding amount in bytes" + ))?; + Ok(biggest_variant_width - variant_width) } } diff --git a/packages/fuels-core/src/types/errors.rs b/packages/fuels-core/src/types/errors.rs index 0a402bc618..8299ef460d 100644 --- a/packages/fuels-core/src/types/errors.rs +++ b/packages/fuels-core/src/types/errors.rs @@ -49,7 +49,7 @@ pub type Result = std::result::Result; #[macro_export] macro_rules! error { ($err_variant:ident, $fmt_str: literal $(,$arg: expr)*) => { - Error::$err_variant(format!($fmt_str,$($arg),*)) + $crate::types::errors::Error::$err_variant(format!($fmt_str,$($arg),*)) } } pub use error; diff --git a/packages/fuels-core/src/types/param_types.rs b/packages/fuels-core/src/types/param_types.rs index 080f0e7852..a09c12ada7 100644 --- a/packages/fuels-core/src/types/param_types.rs +++ b/packages/fuels-core/src/types/param_types.rs @@ -4,10 +4,10 @@ use fuel_abi_types::{ abi::program::{TypeApplication, TypeDeclaration}, utils::{extract_array_len, extract_generic_name, extract_str_len, has_tuple_format}, }; -use itertools::{chain, Itertools}; +use itertools::chain; use crate::{ - constants::WORD_SIZE, + round_up_to_word_alignment, types::{ enum_variants::EnumVariants, errors::{error, Error, Result}, @@ -67,10 +67,10 @@ impl ParamType { param_type: &ParamType, available_bytes: usize, ) -> Result { - let encoding_width = param_type.compute_encoding_width()?; - let memory_size = encoding_width - .checked_mul(WORD_SIZE) - .ok_or_else(|| error!(InvalidData, "Overflow error while encoding {param_type:?}"))?; + let memory_size = param_type.compute_encoding_in_bytes().ok_or(error!( + InvalidType, + "Cannot calculate the number of elements." + ))?; if memory_size == 0 { return Err(error!( InvalidType, @@ -164,65 +164,36 @@ impl ParamType { } /// Compute the inner memory size of a containing heap type (`Bytes` or `Vec`s). - pub fn heap_inner_element_size(&self, top_level_type: bool) -> Result> { + pub fn heap_inner_element_size(&self, top_level_type: bool) -> Option { match &self { - ParamType::Vector(inner_param_type) => { - let width = inner_param_type.compute_encoding_width()?; - width - .checked_mul(WORD_SIZE) - .map(Some) - .ok_or_else(|| error!(InvalidData, "overflow while multiplying")) - } + ParamType::Vector(inner_param_type) => inner_param_type.compute_encoding_in_bytes(), // `Bytes` type is byte-packed in the VM, so it's the size of an u8 - ParamType::Bytes | ParamType::String => Ok(Some(std::mem::size_of::())), - ParamType::RawSlice if !top_level_type => { - ParamType::U64.compute_encoding_width().map(Some) - } - ParamType::StringSlice if !top_level_type => Ok(Some(std::mem::size_of::())), - _ => Ok(None), + ParamType::Bytes | ParamType::String => Some(std::mem::size_of::()), + ParamType::StringSlice if !top_level_type => ParamType::U8.compute_encoding_in_bytes(), + ParamType::RawSlice if !top_level_type => ParamType::U64.compute_encoding_in_bytes(), + _ => None, } } - /// Calculates the number of `WORD`s the VM expects this parameter to be encoded in. - pub fn compute_encoding_width(&self) -> Result { - const fn count_words(bytes: usize) -> usize { - let q = bytes / WORD_SIZE; - let r = bytes % WORD_SIZE; - match r == 0 { - true => q, - false => q + 1, - } - } - + /// Calculates the number of bytes the VM expects this parameter to be encoded in. + pub fn compute_encoding_in_bytes(&self) -> Option { match &self { - ParamType::Unit - | ParamType::U8 - | ParamType::U16 - | ParamType::U32 - | ParamType::U64 - | ParamType::Bool => Ok(1), - ParamType::U128 | ParamType::RawSlice | ParamType::StringSlice => Ok(2), - ParamType::Vector(_) | ParamType::Bytes | ParamType::String => Ok(3), - ParamType::U256 | ParamType::B256 => Ok(4), - ParamType::Array(param, count) => param - .compute_encoding_width()? - .checked_mul(*count) - .ok_or_else(|| { - error!( - InvalidData, - "overflow while calculating encoding width for Array({param:?}, {count})" - ) - }), - ParamType::StringArray(len) => Ok(count_words(*len)), - ParamType::Struct { fields, .. } => fields - .iter() - .map(|param_type| param_type.compute_encoding_width()) - .process_results(|iter| iter.sum()), - ParamType::Enum { variants, .. } => variants.compute_encoding_width_of_enum(), - ParamType::Tuple(params) => params - .iter() - .map(|param_type| param_type.compute_encoding_width()) - .process_results(|iter| iter.sum()), + ParamType::Unit | ParamType::U8 | ParamType::Bool => Some(1), + ParamType::U16 | ParamType::U32 | ParamType::U64 => Some(8), + ParamType::U128 | ParamType::RawSlice | ParamType::StringSlice => Some(16), + ParamType::U256 | ParamType::B256 => Some(32), + ParamType::Vector(_) | ParamType::Bytes | ParamType::String => Some(24), + ParamType::Array(param, count) => { + param.compute_encoding_in_bytes()?.checked_mul(*count) + } + ParamType::StringArray(len) => Some(round_up_to_word_alignment(*len)), + ParamType::Tuple(fields) | ParamType::Struct { fields, .. } => { + fields.iter().try_fold(0, |a, param_type| { + let size = round_up_to_word_alignment(param_type.compute_encoding_in_bytes()?); + Some(a + size) + }) + } + ParamType::Enum { variants, .. } => variants.compute_enum_width_in_bytes(), } } @@ -648,12 +619,12 @@ impl<'a> fmt::Debug for DebugWithDepth<'a> { #[cfg(test)] mod tests { - use super::*; + use crate::constants::WORD_SIZE; use crate::{codec::DecoderConfig, types::param_types::ParamType}; - const WIDTH_OF_B256: usize = 4; - const WIDTH_OF_U32: usize = 1; + const WIDTH_OF_B256: usize = 32; + const WIDTH_OF_U32: usize = 8; const WIDTH_OF_BOOL: usize = 1; #[test] @@ -661,7 +632,7 @@ mod tests { const NUM_ELEMENTS: usize = 11; let param = ParamType::Array(Box::new(ParamType::B256), NUM_ELEMENTS); - let width = param.compute_encoding_width().unwrap(); + let width = param.compute_encoding_in_bytes().unwrap(); let expected = NUM_ELEMENTS * WIDTH_OF_B256; assert_eq!(expected, width); @@ -672,14 +643,13 @@ mod tests { const NUM_ASCII_CHARS: usize = 9; let param = ParamType::StringArray(NUM_ASCII_CHARS); - let width = param.compute_encoding_width().unwrap(); + let width = param.compute_encoding_in_bytes().unwrap(); - // 2 WORDS or 16 B are enough to fit 9 ascii chars - assert_eq!(2, width); + assert_eq!(16, width); } #[test] - fn structs_are_just_all_elements_combined() { + fn structs_are_all_elements_combined_with_padding() { let inner_struct = ParamType::Struct { fields: vec![ParamType::U32, ParamType::U32], generics: vec![], @@ -690,10 +660,11 @@ mod tests { generics: vec![], }; - let width = a_struct.compute_encoding_width().unwrap(); + let width = a_struct.compute_encoding_in_bytes().unwrap(); const INNER_STRUCT_WIDTH: usize = WIDTH_OF_U32 * 2; - const EXPECTED_WIDTH: usize = WIDTH_OF_B256 + WIDTH_OF_BOOL + INNER_STRUCT_WIDTH; + const EXPECTED_WIDTH: usize = + WIDTH_OF_B256 + round_up_to_word_alignment(WIDTH_OF_BOOL) + INNER_STRUCT_WIDTH; assert_eq!(EXPECTED_WIDTH, width); } @@ -710,10 +681,10 @@ mod tests { generics: vec![], }; - let width = param.compute_encoding_width().unwrap(); + let width = param.compute_encoding_in_bytes().unwrap(); const INNER_STRUCT_SIZE: usize = WIDTH_OF_B256; - const EXPECTED_WIDTH: usize = INNER_STRUCT_SIZE + 1; + const EXPECTED_WIDTH: usize = INNER_STRUCT_SIZE + WORD_SIZE; assert_eq!(EXPECTED_WIDTH, width); Ok(()) } @@ -723,7 +694,7 @@ mod tests { let inner_tuple = ParamType::Tuple(vec![ParamType::B256]); let param = ParamType::Tuple(vec![ParamType::U32, inner_tuple]); - let width = param.compute_encoding_width().unwrap(); + let width = param.compute_encoding_in_bytes().unwrap(); const INNER_TUPLE_WIDTH: usize = WIDTH_OF_B256; const EXPECTED_WIDTH: usize = WIDTH_OF_U32 + INNER_TUPLE_WIDTH; diff --git a/packages/fuels-core/src/types/transaction_builders.rs b/packages/fuels-core/src/types/transaction_builders.rs index 190a47493b..9097161f4d 100644 --- a/packages/fuels-core/src/types/transaction_builders.rs +++ b/packages/fuels-core/src/types/transaction_builders.rs @@ -20,7 +20,7 @@ use crate::{ bech32::Bech32Address, coin::Coin, coin_type::CoinType, - errors::{error, Error, Result}, + errors::{error, Result}, input::Input, message::Message, transaction::{CreateTransaction, ScriptTransaction, Transaction, TxParameters}, diff --git a/packages/fuels-core/src/types/tx_status.rs b/packages/fuels-core/src/types/tx_status.rs index 7b6f7b7cc0..e6d7ca5e78 100644 --- a/packages/fuels-core/src/types/tx_status.rs +++ b/packages/fuels-core/src/types/tx_status.rs @@ -2,7 +2,11 @@ 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, }; +#[cfg(feature = "std")] +use fuel_core_client::client::types::TransactionStatus as ClientTransactionStatus; use fuel_tx::Receipt; +#[cfg(feature = "std")] +use fuel_vm::state::ProgramState; use crate::{ codec::LogDecoder, @@ -21,7 +25,7 @@ pub enum TxStatus { Revert { receipts: Vec, reason: String, - id: u64, + revert_id: u64, }, } @@ -32,7 +36,7 @@ impl TxStatus { Self::Revert { receipts, reason, - id, + revert_id: id, } => Self::map_revert_error(receipts, reason, *id, log_decoder), _ => Ok(()), } @@ -83,3 +87,30 @@ impl TxStatus { } } } +#[cfg(feature = "std")] +impl From for TxStatus { + fn from(client_status: ClientTransactionStatus) -> Self { + match client_status { + ClientTransactionStatus::Submitted { .. } => TxStatus::Submitted {}, + ClientTransactionStatus::Success { .. } => TxStatus::Success { receipts: vec![] }, + ClientTransactionStatus::Failure { + reason, + program_state, + .. + } => { + let revert_id = program_state + .and_then(|state| match state { + ProgramState::Revert(revert_id) => Some(revert_id), + _ => None, + }) + .expect("Transaction failed without a `revert_id`"); + TxStatus::Revert { + receipts: vec![], + reason, + revert_id, + } + } + ClientTransactionStatus::SqueezedOut { reason } => TxStatus::SqueezedOut { reason }, + } + } +} diff --git a/packages/fuels-core/src/types/unresolved_bytes.rs b/packages/fuels-core/src/types/unresolved_bytes.rs index c3d82027c4..02198f98b7 100644 --- a/packages/fuels-core/src/types/unresolved_bytes.rs +++ b/packages/fuels-core/src/types/unresolved_bytes.rs @@ -8,6 +8,14 @@ pub enum Data { // should be left behind to point to it. Dynamic(Vec), } +impl Data { + pub(crate) fn size_in_bytes(&self) -> usize { + match self { + Data::Inline(data) => data.len(), + Data::Dynamic(_) => 8, + } + } +} // To get the final encoded bytes, we need to know the address at which these // bytes are going to be loaded at. Once the address is given to `resolve` diff --git a/packages/fuels-core/src/types/wrappers/transaction_response.rs b/packages/fuels-core/src/types/wrappers/transaction_response.rs index 6d8f64d914..87118be29a 100644 --- a/packages/fuels-core/src/types/wrappers/transaction_response.rs +++ b/packages/fuels-core/src/types/wrappers/transaction_response.rs @@ -10,23 +10,16 @@ use fuel_tx::Transaction; use fuel_types::Bytes32; use crate::types::transaction::{CreateTransaction, ScriptTransaction, TransactionType}; +use crate::types::tx_status::TxStatus; #[derive(Debug, Clone)] pub struct TransactionResponse { pub transaction: TransactionType, - pub status: TransactionStatus, + pub status: TxStatus, pub block_id: Option, pub time: Option>, } -#[derive(Debug, Clone)] -pub enum TransactionStatus { - Submitted(), - Success(), - Failure(), - SqueezedOut(), -} - impl From for TransactionResponse { fn from(client_response: ClientTransactionResponse) -> Self { let block_id = match &client_response.status { @@ -63,14 +56,3 @@ impl From for TransactionResponse { } } } - -impl From for TransactionStatus { - fn from(client_status: ClientTransactionStatus) -> Self { - match client_status { - ClientTransactionStatus::Submitted { .. } => TransactionStatus::Submitted(), - ClientTransactionStatus::Success { .. } => TransactionStatus::Success(), - ClientTransactionStatus::Failure { .. } => TransactionStatus::Failure(), - ClientTransactionStatus::SqueezedOut { .. } => TransactionStatus::SqueezedOut(), - } - } -} diff --git a/packages/fuels-core/src/utils.rs b/packages/fuels-core/src/utils.rs index 3c6f9d3a61..0805e8200d 100644 --- a/packages/fuels-core/src/utils.rs +++ b/packages/fuels-core/src/utils.rs @@ -1,2 +1,7 @@ pub mod constants; pub mod offsets; + +use constants::WORD_SIZE; +pub const fn round_up_to_word_alignment(bytes_len: usize) -> usize { + (bytes_len + (WORD_SIZE - 1)) - ((bytes_len + (WORD_SIZE - 1)) % WORD_SIZE) +} diff --git a/packages/fuels-core/src/utils/constants.rs b/packages/fuels-core/src/utils/constants.rs index 76228dbc9c..6fe33a0915 100644 --- a/packages/fuels-core/src/utils/constants.rs +++ b/packages/fuels-core/src/utils/constants.rs @@ -1,7 +1,7 @@ use fuel_tx::Word; use fuel_types::AssetId; -pub const ENUM_DISCRIMINANT_WORD_WIDTH: usize = 1; +pub const ENUM_DISCRIMINANT_BYTE_WIDTH: usize = 8; pub const WORD_SIZE: usize = core::mem::size_of::(); // ANCHOR: default_call_parameters diff --git a/packages/fuels-macros/src/derive/utils.rs b/packages/fuels-macros/src/derive/utils.rs index 04407a63d4..27bee2a5f0 100644 --- a/packages/fuels-macros/src/derive/utils.rs +++ b/packages/fuels-macros/src/derive/utils.rs @@ -52,8 +52,13 @@ pub(crate) struct VariantInfo { } pub(crate) enum ExtractedVariant { - Normal { info: VariantInfo, discriminant: u8 }, - Ignored { info: VariantInfo }, + Normal { + info: VariantInfo, + discriminant: u64, + }, + Ignored { + info: VariantInfo, + }, } pub(crate) fn extract_variants( diff --git a/packages/fuels-macros/tests/ui/derive/tokenizable/enum_size_not_supported.rs b/packages/fuels-macros/tests/ui/derive/tokenizable/enum_size_not_supported.rs deleted file mode 100644 index ba8f0244dd..0000000000 --- a/packages/fuels-macros/tests/ui/derive/tokenizable/enum_size_not_supported.rs +++ /dev/null @@ -1,264 +0,0 @@ -use fuels_macros::Tokenizable; - -#[derive(Tokenizable)] -enum MaxedOutVariantsEnum { - Variant0(u8), - Variant1(u8), - Variant2(u8), - Variant3(u8), - Variant4(u8), - Variant5(u8), - Variant6(u8), - Variant7(u8), - Variant8(u8), - Variant9(u8), - Variant10(u8), - Variant11(u8), - Variant12(u8), - Variant13(u8), - Variant14(u8), - Variant15(u8), - Variant16(u8), - Variant17(u8), - Variant18(u8), - Variant19(u8), - Variant20(u8), - Variant21(u8), - Variant22(u8), - Variant23(u8), - Variant24(u8), - Variant25(u8), - Variant26(u8), - Variant27(u8), - Variant28(u8), - Variant29(u8), - Variant30(u8), - Variant31(u8), - Variant32(u8), - Variant33(u8), - Variant34(u8), - Variant35(u8), - Variant36(u8), - Variant37(u8), - Variant38(u8), - Variant39(u8), - Variant40(u8), - Variant41(u8), - Variant42(u8), - Variant43(u8), - Variant44(u8), - Variant45(u8), - Variant46(u8), - Variant47(u8), - Variant48(u8), - Variant49(u8), - Variant50(u8), - Variant51(u8), - Variant52(u8), - Variant53(u8), - Variant54(u8), - Variant55(u8), - Variant56(u8), - Variant57(u8), - Variant58(u8), - Variant59(u8), - Variant60(u8), - Variant61(u8), - Variant62(u8), - Variant63(u8), - Variant64(u8), - Variant65(u8), - Variant66(u8), - Variant67(u8), - Variant68(u8), - Variant69(u8), - Variant70(u8), - Variant71(u8), - Variant72(u8), - Variant73(u8), - Variant74(u8), - Variant75(u8), - Variant76(u8), - Variant77(u8), - Variant78(u8), - Variant79(u8), - Variant80(u8), - Variant81(u8), - Variant82(u8), - Variant83(u8), - Variant84(u8), - Variant85(u8), - Variant86(u8), - Variant87(u8), - Variant88(u8), - Variant89(u8), - Variant90(u8), - Variant91(u8), - Variant92(u8), - Variant93(u8), - Variant94(u8), - Variant95(u8), - Variant96(u8), - Variant97(u8), - Variant98(u8), - Variant99(u8), - Variant100(u8), - Variant101(u8), - Variant102(u8), - Variant103(u8), - Variant104(u8), - Variant105(u8), - Variant106(u8), - Variant107(u8), - Variant108(u8), - Variant109(u8), - Variant110(u8), - Variant111(u8), - Variant112(u8), - Variant113(u8), - Variant114(u8), - Variant115(u8), - Variant116(u8), - Variant117(u8), - Variant118(u8), - Variant119(u8), - Variant120(u8), - Variant121(u8), - Variant122(u8), - Variant123(u8), - Variant124(u8), - Variant125(u8), - Variant126(u8), - Variant127(u8), - Variant128(u8), - Variant129(u8), - Variant130(u8), - Variant131(u8), - Variant132(u8), - Variant133(u8), - Variant134(u8), - Variant135(u8), - Variant136(u8), - Variant137(u8), - Variant138(u8), - Variant139(u8), - Variant140(u8), - Variant141(u8), - Variant142(u8), - Variant143(u8), - Variant144(u8), - Variant145(u8), - Variant146(u8), - Variant147(u8), - Variant148(u8), - Variant149(u8), - Variant150(u8), - Variant151(u8), - Variant152(u8), - Variant153(u8), - Variant154(u8), - Variant155(u8), - Variant156(u8), - Variant157(u8), - Variant158(u8), - Variant159(u8), - Variant160(u8), - Variant161(u8), - Variant162(u8), - Variant163(u8), - Variant164(u8), - Variant165(u8), - Variant166(u8), - Variant167(u8), - Variant168(u8), - Variant169(u8), - Variant170(u8), - Variant171(u8), - Variant172(u8), - Variant173(u8), - Variant174(u8), - Variant175(u8), - Variant176(u8), - Variant177(u8), - Variant178(u8), - Variant179(u8), - Variant180(u8), - Variant181(u8), - Variant182(u8), - Variant183(u8), - Variant184(u8), - Variant185(u8), - Variant186(u8), - Variant187(u8), - Variant188(u8), - Variant189(u8), - Variant190(u8), - Variant191(u8), - Variant192(u8), - Variant193(u8), - Variant194(u8), - Variant195(u8), - Variant196(u8), - Variant197(u8), - Variant198(u8), - Variant199(u8), - Variant200(u8), - Variant201(u8), - Variant202(u8), - Variant203(u8), - Variant204(u8), - Variant205(u8), - Variant206(u8), - Variant207(u8), - Variant208(u8), - Variant209(u8), - Variant210(u8), - Variant211(u8), - Variant212(u8), - Variant213(u8), - Variant214(u8), - Variant215(u8), - Variant216(u8), - Variant217(u8), - Variant218(u8), - Variant219(u8), - Variant220(u8), - Variant221(u8), - Variant222(u8), - Variant223(u8), - Variant224(u8), - Variant225(u8), - Variant226(u8), - Variant227(u8), - Variant228(u8), - Variant229(u8), - Variant230(u8), - Variant231(u8), - Variant232(u8), - Variant233(u8), - Variant234(u8), - Variant235(u8), - Variant236(u8), - Variant237(u8), - Variant238(u8), - Variant239(u8), - Variant240(u8), - Variant241(u8), - Variant242(u8), - Variant243(u8), - Variant244(u8), - Variant245(u8), - Variant246(u8), - Variant247(u8), - Variant248(u8), - Variant249(u8), - Variant250(u8), - Variant251(u8), - Variant252(u8), - Variant253(u8), - Variant254(u8), - Variant255(u8), - Variant256(u8), -} - -fn main() {} diff --git a/packages/fuels-macros/tests/ui/derive/tokenizable/enum_size_not_supported.stderr b/packages/fuels-macros/tests/ui/derive/tokenizable/enum_size_not_supported.stderr deleted file mode 100644 index 0e8f7e02d9..0000000000 --- a/packages/fuels-macros/tests/ui/derive/tokenizable/enum_size_not_supported.stderr +++ /dev/null @@ -1,5 +0,0 @@ -error: Enums can not have more than 256 variants - --> tests/ui/derive/tokenizable/enum_size_not_supported.rs:261:5 - | -261 | Variant256(u8), - | ^^^^^^^^^^ diff --git a/packages/fuels-programs/src/call_utils.rs b/packages/fuels-programs/src/call_utils.rs index 57030e8ff0..9ebc573beb 100644 --- a/packages/fuels-programs/src/call_utils.rs +++ b/packages/fuels-programs/src/call_utils.rs @@ -367,8 +367,22 @@ fn extract_heap_data(param_type: &ParamType) -> Result Result> { - let Some(inner_type_byte_size) = param_type.heap_inner_element_size(top_level_type)? else { + let Some(inner_type_byte_size) = param_type.heap_inner_element_size(top_level_type) else { return Ok(vec![]); }; diff --git a/packages/fuels-programs/src/receipt_parser.rs b/packages/fuels-programs/src/receipt_parser.rs index 3d8a6cdbcc..0cc166f4a3 100644 --- a/packages/fuels-programs/src/receipt_parser.rs +++ b/packages/fuels-programs/src/receipt_parser.rs @@ -49,7 +49,7 @@ impl ReceiptParser { .extract_raw_data(output_param, &contract_id) .ok_or_else(|| Self::missing_receipts_error(output_param))?; - self.decoder.decode(output_param, &data) + self.decoder.decode_receipt_return(output_param, &data) } fn missing_receipts_error(output_param: &ParamType) -> Error { @@ -189,9 +189,7 @@ mod tests { use super::*; const RECEIPT_VAL: u64 = 225; - const RECEIPT_DATA: &[u8; 24] = &[ - 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, - ]; + const RECEIPT_DATA: &[u8; 3] = &[8, 8, 3]; const DECODED_DATA: &[u8; 3] = &[8, 8, 3]; fn target_contract() -> ContractId { diff --git a/packages/fuels-test-helpers/src/service.rs b/packages/fuels-test-helpers/src/service.rs index ccf3eb9591..162769b9f3 100644 --- a/packages/fuels-test-helpers/src/service.rs +++ b/packages/fuels-test-helpers/src/service.rs @@ -5,7 +5,7 @@ use fuel_core::service::FuelService as CoreFuelService; #[cfg(feature = "fuel-core-lib")] use fuel_core_services::Service; use fuel_core_services::State; -use fuels_core::types::errors::{error, Error, Result}; +use fuels_core::types::errors::{error, Result}; #[cfg(not(feature = "fuel-core-lib"))] use crate::fuel_bin_service::FuelService as BinFuelService; diff --git a/packages/fuels/tests/bindings.rs b/packages/fuels/tests/bindings.rs index 4623241fcd..5db87fd589 100644 --- a/packages/fuels/tests/bindings.rs +++ b/packages/fuels/tests/bindings.rs @@ -250,10 +250,7 @@ async fn compile_bindings_bool_array_input() -> Result<()> { hex::encode(encoded_args) ); - assert_eq!( - "000000000c228226000000000000000100000000000000000000000000000001", - encoded - ); + assert_eq!("000000000c2282260100010000000000", encoded); Ok(()) } @@ -566,10 +563,7 @@ async fn compile_bindings_struct_input() -> Result<()> { hex::encode(encoded_args) ); - assert_eq!( - "000000008d4ab9b0000000000000000a00000000000000026675656c00000000", - encoded - ); + assert_eq!("000000008d4ab9b00a020000000000006675656c00000000", encoded); Ok(()) } @@ -676,7 +670,7 @@ async fn compile_bindings_nested_struct_input() -> Result<()> { hex::encode(encoded_args) ); - assert_eq!("0000000088bf8a1b000000000000000a0000000000000001", encoded); + assert_eq!("0000000088bf8a1b000000000000000a0100000000000000", encoded); Ok(()) } diff --git a/packages/fuels/tests/bindings/sharing_types/contract_a/src/main.sw b/packages/fuels/tests/bindings/sharing_types/contract_a/src/main.sw index 9c03bd907f..09700c33b2 100644 --- a/packages/fuels/tests/bindings/sharing_types/contract_a/src/main.sw +++ b/packages/fuels/tests/bindings/sharing_types/contract_a/src/main.sw @@ -15,9 +15,17 @@ enum EnumSameNameButDifferentInternals { } abi MyContract { - fn uses_shared_type(arg1: SharedStruct2, arg2: SharedEnum) -> (SharedStruct2, SharedEnum); - fn uses_types_that_share_only_names(arg1: StructSameNameButDifferentInternals, arg2: EnumSameNameButDifferentInternals) -> (StructSameNameButDifferentInternals, EnumSameNameButDifferentInternals); - fn uses_shared_type_inside_owned_one(arg1: UniqueStructToContractA>) -> UniqueStructToContractA>; + fn uses_shared_type( + arg1: SharedStruct2, + arg2: SharedEnum, + ) -> (SharedStruct2, SharedEnum); + fn uses_types_that_share_only_names( + arg1: StructSameNameButDifferentInternals, + arg2: EnumSameNameButDifferentInternals, + ) -> (StructSameNameButDifferentInternals, EnumSameNameButDifferentInternals); + fn uses_shared_type_inside_owned_one( + arg1: UniqueStructToContractA>, + ) -> UniqueStructToContractA>; } impl MyContract for Contract { diff --git a/packages/fuels/tests/bindings/sharing_types/contract_b/src/main.sw b/packages/fuels/tests/bindings/sharing_types/contract_b/src/main.sw index 2b21195f6e..b3192469a9 100644 --- a/packages/fuels/tests/bindings/sharing_types/contract_b/src/main.sw +++ b/packages/fuels/tests/bindings/sharing_types/contract_b/src/main.sw @@ -15,9 +15,17 @@ enum EnumSameNameButDifferentInternals { } abi MyContract { - fn uses_shared_type(arg1: SharedStruct2, arg2: SharedEnum) -> (SharedStruct2, SharedEnum); - fn uses_types_that_share_only_names(arg1: StructSameNameButDifferentInternals, arg2: EnumSameNameButDifferentInternals) -> (StructSameNameButDifferentInternals, EnumSameNameButDifferentInternals); - fn uses_shared_type_inside_owned_one(arg1: UniqueStructToContractB>) -> UniqueStructToContractB>; + fn uses_shared_type( + arg1: SharedStruct2, + arg2: SharedEnum, + ) -> (SharedStruct2, SharedEnum); + fn uses_types_that_share_only_names( + arg1: StructSameNameButDifferentInternals, + arg2: EnumSameNameButDifferentInternals, + ) -> (StructSameNameButDifferentInternals, EnumSameNameButDifferentInternals); + fn uses_shared_type_inside_owned_one( + arg1: UniqueStructToContractB>, + ) -> UniqueStructToContractB>; } impl MyContract for Contract { diff --git a/packages/fuels/tests/contracts.rs b/packages/fuels/tests/contracts.rs index 4bec9fb5dd..189bb331c4 100644 --- a/packages/fuels/tests/contracts.rs +++ b/packages/fuels/tests/contracts.rs @@ -280,9 +280,9 @@ async fn test_contract_call_fee_estimation() -> Result<()> { let tolerance = 0.2; let expected_min_gas_price = 0; // This is the default min_gas_price from the ConsensusParameters - let expected_gas_used = 476; + let expected_gas_used = 564; let expected_metered_bytes_size = 712; - let expected_total_fee = 333; + let expected_total_fee = 342; let estimated_transaction_cost = contract_instance .methods() diff --git a/packages/fuels/tests/contracts/lib_contract_caller/src/main.sw b/packages/fuels/tests/contracts/lib_contract_caller/src/main.sw index c8849a57b9..c517b41090 100644 --- a/packages/fuels/tests/contracts/lib_contract_caller/src/main.sw +++ b/packages/fuels/tests/contracts/lib_contract_caller/src/main.sw @@ -6,7 +6,11 @@ use std::constants::ZERO_B256; abi ContractCaller { fn increment_from_contract(contract_id: ContractId, value: u64) -> u64; - fn increment_from_contracts(contract_id: ContractId, contract_id2: ContractId, value: u64) -> u64; + fn increment_from_contracts( + contract_id: ContractId, + contract_id2: ContractId, + value: u64, + ) -> u64; fn mint_then_increment_from_contract(contract_id: ContractId, amount: u64, address: Address); fn require_from_contract(contract_id: ContractId); } diff --git a/packages/fuels/tests/contracts/liquidity_pool/src/main.sw b/packages/fuels/tests/contracts/liquidity_pool/src/main.sw index e33b0516d4..c923f56bf5 100644 --- a/packages/fuels/tests/contracts/liquidity_pool/src/main.sw +++ b/packages/fuels/tests/contracts/liquidity_pool/src/main.sw @@ -20,7 +20,9 @@ abi LiquidityPool { fn withdraw(recipient: Address); } -const BASE_TOKEN: AssetId = AssetId::from(0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c); +const BASE_TOKEN: AssetId = AssetId::from( + 0x9ae5b658754e096e4d681c548daf46354495a437cc61492599e33fc64dcdc30c, +); impl LiquidityPool for Contract { #[payable] diff --git a/packages/fuels/tests/contracts/low_level_caller/src/main.sw b/packages/fuels/tests/contracts/low_level_caller/src/main.sw index f7e5639cd8..a535c6428e 100644 --- a/packages/fuels/tests/contracts/low_level_caller/src/main.sw +++ b/packages/fuels/tests/contracts/low_level_caller/src/main.sw @@ -5,7 +5,12 @@ use std::low_level_call::{call_with_function_selector, CallParams}; use std::bytes::Bytes; abi MyCallerContract { - fn call_low_level_call(target: ContractId, function_selector: Bytes, calldata: Bytes, single_value_type_arg: bool); + fn call_low_level_call( + target: ContractId, + function_selector: Bytes, + calldata: Bytes, + single_value_type_arg: bool, + ); } impl MyCallerContract for Contract { @@ -22,7 +27,13 @@ impl MyCallerContract for Contract { gas: 10_000, }; - call_with_function_selector(target, function_selector, calldata, single_value_type_arg, call_params); + call_with_function_selector( + target, + function_selector, + calldata, + single_value_type_arg, + call_params, + ); } // ANCHOR_END: low_level_call_contract } diff --git a/packages/fuels/tests/contracts/revert_transaction_error/src/main.sw b/packages/fuels/tests/contracts/revert_transaction_error/src/main.sw index ba03370153..920a7bfde8 100644 --- a/packages/fuels/tests/contracts/revert_transaction_error/src/main.sw +++ b/packages/fuels/tests/contracts/revert_transaction_error/src/main.sw @@ -6,7 +6,10 @@ abi MyContract { impl MyContract for Contract { fn make_transaction_fail(input: u64) -> u64 { - revert(input); + // Work around DCE and revert + if true { + revert(input); + } 42 } } diff --git a/packages/fuels/tests/from_token.rs b/packages/fuels/tests/from_token.rs index 7ea3504741..51c653f2dc 100644 --- a/packages/fuels/tests/from_token.rs +++ b/packages/fuels/tests/from_token.rs @@ -98,7 +98,7 @@ async fn create_struct_from_decoded_tokens() -> Result<()> { hex::encode(encoded_args) ); - assert_eq!("00000000cb0b2f05000000000000000a0000000000000001", encoded); + assert_eq!("00000000cb0b2f050a000000000000000100000000000000", encoded); Ok(()) } @@ -213,6 +213,6 @@ async fn create_nested_struct_from_decoded_tokens() -> Result<()> { hex::encode(encoded_args) ); - assert_eq!("0000000088bf8a1b000000000000000a0000000000000001", encoded); + assert_eq!("0000000088bf8a1b000000000000000a0100000000000000", encoded); Ok(()) } diff --git a/packages/fuels/tests/providers.rs b/packages/fuels/tests/providers.rs index 4c2a7c76ae..5be5518539 100644 --- a/packages/fuels/tests/providers.rs +++ b/packages/fuels/tests/providers.rs @@ -368,7 +368,7 @@ async fn test_gas_forwarded_defaults_to_tx_limit() -> Result<()> { ); // The gas used by the script to call a contract and forward remaining gas limit. - let gas_used_by_script = 169; + let gas_used_by_script = 171; let gas_limit = 225_883; let response = contract_instance .methods() diff --git a/packages/fuels/tests/types/contracts/bytes/src/main.sw b/packages/fuels/tests/types/contracts/bytes/src/main.sw index c7f9a6d04b..84ff054e93 100644 --- a/packages/fuels/tests/types/contracts/bytes/src/main.sw +++ b/packages/fuels/tests/types/contracts/bytes/src/main.sw @@ -31,20 +31,40 @@ abi MyContract { impl MyContract for Contract { fn accept_bytes(bytes: Bytes) { - require(bytes == expected_bytes(), "given bytes didn't match the expected bytes"); + require( + bytes == expected_bytes(), + "given bytes didn't match the expected bytes", + ); } fn accept_nested_bytes(wrapper: Wrapper>) { if let SomeEnum::Second(enum_bytes) = wrapper.inner_enum { - require(enum_bytes == expected_bytes(), "wrapper.inner_enum didn't carry the expected bytes"); + require( + enum_bytes == expected_bytes(), + "wrapper.inner_enum didn't carry the expected bytes", + ); } else { require(false, "enum was not of variant Second"); } let inner_vec = wrapper.inner; - require(inner_vec.len() == 2, "Expected wrapper.inner vector to have 2 elements"); - require(inner_vec.get(0).unwrap() == expected_bytes(), "wrapper.inner[0] didn't match expectation"); - require(inner_vec.get(1).unwrap() == expected_bytes(), "wrapper.inner[1] didn't match expectation"); + require( + inner_vec + .len() == 2, + "Expected wrapper.inner vector to have 2 elements", + ); + require( + inner_vec + .get(0) + .unwrap() == expected_bytes(), + "wrapper.inner[0] didn't match expectation", + ); + require( + inner_vec + .get(1) + .unwrap() == expected_bytes(), + "wrapper.inner[1] didn't match expectation", + ); } fn return_bytes(len: u8) -> Bytes { diff --git a/packages/fuels/tests/types/contracts/evm_address/src/main.sw b/packages/fuels/tests/types/contracts/evm_address/src/main.sw index 6abd15413f..278686f085 100644 --- a/packages/fuels/tests/types/contracts/evm_address/src/main.sw +++ b/packages/fuels/tests/types/contracts/evm_address/src/main.sw @@ -10,13 +10,17 @@ abi EvmTest { impl EvmTest for Contract { fn evm_address_as_input(evm_addr: EvmAddress) -> bool { - let evm_addr2 = EvmAddress::from(0x1616060606060606060606060606060606060606060606060606060606060606); + let evm_addr2 = EvmAddress::from( + 0x1616060606060606060606060606060606060606060606060606060606060606, + ); evm_addr == evm_addr2 } fn evm_address_from_literal() -> EvmAddress { - EvmAddress::from(0x0606060606060606060606060606060606060606060606060606060606060606) + EvmAddress::from( + 0x0606060606060606060606060606060606060606060606060606060606060606, + ) } fn evm_address_from_argument(raw_address: b256) -> EvmAddress { diff --git a/packages/fuels/tests/types/contracts/generics/src/main.sw b/packages/fuels/tests/types/contracts/generics/src/main.sw index 672810f4b7..69491e40cf 100644 --- a/packages/fuels/tests/types/contracts/generics/src/main.sw +++ b/packages/fuels/tests/types/contracts/generics/src/main.sw @@ -61,9 +61,18 @@ impl Hash for str[3] { } abi MyContract { - fn unused_generic_args(arg_1: StructOneUnusedGenericParam, arg_2: EnumOneUnusedGenericParam); - fn two_unused_generic_args(arg_1: StructTwoUnusedGenericParams, arg_2: EnumTwoUnusedGenericParams); - fn used_and_unused_generic_args(arg_1: StructUsedAndUnusedGenericParams, arg_2: EnumUsedAndUnusedGenericParams) -> (StructUsedAndUnusedGenericParams, EnumUsedAndUnusedGenericParams); + fn unused_generic_args( + arg_1: StructOneUnusedGenericParam, + arg_2: EnumOneUnusedGenericParam, + ); + fn two_unused_generic_args( + arg_1: StructTwoUnusedGenericParams, + arg_2: EnumTwoUnusedGenericParams, + ); + fn used_and_unused_generic_args( + arg_1: StructUsedAndUnusedGenericParams, + arg_2: EnumUsedAndUnusedGenericParams, + ) -> (StructUsedAndUnusedGenericParams, EnumUsedAndUnusedGenericParams); fn struct_w_generic(arg1: SimpleGeneric) -> SimpleGeneric; fn struct_delegating_generic(arg1: PassTheGenericOn) -> PassTheGenericOn; fn struct_w_generic_in_array(arg1: StructWArrayGeneric) -> StructWArrayGeneric; @@ -91,7 +100,10 @@ impl MyContract for Contract { if let EnumUsedAndUnusedGenericParams::Two(val) = arg_2 { assert_eq(val, 11u8); } else { - require(false, "Expected the variant EnumUsedAndUnusedGenericParams::Two"); + require( + false, + "Expected the variant EnumUsedAndUnusedGenericParams::Two", + ); } ( StructUsedAndUnusedGenericParams { field: 12u8 }, @@ -115,7 +127,9 @@ impl MyContract for Contract { }, }; - assert(sha256(from_str_array(expected.one.single_generic_param)) == sha256(from_str_array(arg1.one.single_generic_param))); + assert( + sha256(from_str_array(expected.one.single_generic_param)) == sha256(from_str_array(arg1.one.single_generic_param)), + ); expected } diff --git a/packages/fuels/tests/types/contracts/heap_type_in_enums/src/main.sw b/packages/fuels/tests/types/contracts/heap_type_in_enums/src/main.sw index 941d637f97..5c329c6332 100644 --- a/packages/fuels/tests/types/contracts/heap_type_in_enums/src/main.sw +++ b/packages/fuels/tests/types/contracts/heap_type_in_enums/src/main.sw @@ -115,7 +115,9 @@ impl MyContract for Contract { } fn would_raise_a_memory_overflow() -> Result { - Result::Err(0x1111111111111111111111111111111111111111111111111111111111111111) + Result::Err( + 0x1111111111111111111111111111111111111111111111111111111111111111, + ) } fn returns_a_heap_type_too_deep() -> Result { diff --git a/packages/fuels/tests/types/contracts/raw_slice/src/main.sw b/packages/fuels/tests/types/contracts/raw_slice/src/main.sw index 7ea541fc69..04084fef65 100644 --- a/packages/fuels/tests/types/contracts/raw_slice/src/main.sw +++ b/packages/fuels/tests/types/contracts/raw_slice/src/main.sw @@ -20,9 +20,24 @@ abi RawSliceContract { fn validate_raw_slice(input: raw_slice) { let vec: Vec = Vec::from(input); require(vec.len() == 3, "raw slice len is not 3"); - require(vec.get(2).unwrap() == 42, "expected 3rd slice entry to be 42"); - require(vec.get(1).unwrap() == 41, "expected 2nd slice entry to be 41"); - require(vec.get(0).unwrap() == 40, "expected 1st slice entry to be 40"); + require( + vec + .get(2) + .unwrap() == 42, + "expected 3rd slice entry to be 42", + ); + require( + vec + .get(1) + .unwrap() == 41, + "expected 2nd slice entry to be 41", + ); + require( + vec + .get(0) + .unwrap() == 40, + "expected 1st slice entry to be 40", + ); } fn validate_vec(vec: Vec) { diff --git a/packages/fuels/tests/types/contracts/tuples/src/main.sw b/packages/fuels/tests/types/contracts/tuples/src/main.sw index 14e7a70f57..0b8ffebd8d 100644 --- a/packages/fuels/tests/types/contracts/tuples/src/main.sw +++ b/packages/fuels/tests/types/contracts/tuples/src/main.sw @@ -42,7 +42,9 @@ impl MyContract for Contract { name: __to_str_array("Jane"), }); assert(input.0 == expected.0); - assert(sha256(from_str_array(input.1.name)) == sha256(from_str_array(expected.1.name))); + assert( + sha256(from_str_array(input.1.name)) == sha256(from_str_array(expected.1.name)), + ); expected } diff --git a/packages/fuels/tests/types/contracts/u128/src/main.sw b/packages/fuels/tests/types/contracts/u128/src/main.sw index a67f3e1396..5af007c3fc 100644 --- a/packages/fuels/tests/types/contracts/u128/src/main.sw +++ b/packages/fuels/tests/types/contracts/u128/src/main.sw @@ -22,7 +22,10 @@ impl MyContract for Contract { fn u128_in_enum_input(some_enum: SomeEnum) { if let SomeEnum::B(some_u128) = some_enum { let expected_u128 = U128::from((3, 3)); - require(some_u128 == expected_u128, "given u128 didn't match the expected u128"); + require( + some_u128 == expected_u128, + "given u128 didn't match the expected u128", + ); } else { require(false, "enum was not of variant B: u128"); } diff --git a/packages/fuels/tests/types/contracts/u256/src/main.sw b/packages/fuels/tests/types/contracts/u256/src/main.sw index db72b2b8db..f930777e6c 100644 --- a/packages/fuels/tests/types/contracts/u256/src/main.sw +++ b/packages/fuels/tests/types/contracts/u256/src/main.sw @@ -15,19 +15,25 @@ abi MyContract { } impl MyContract for Contract { + #[allow(deprecated)] fn u256_sum_and_ret(arg: U256) -> U256 { arg + U256::from((3, 4, 5, 6)) } + #[allow(deprecated)] fn u256_in_enum_input(some_enum: SomeEnum) { if let SomeEnum::B(some_u256) = some_enum { let expected_u256 = U256::from((2, 3, 4, 5)); - require(some_u256 == expected_u256, "given u256 didn't match the expected u256"); + require( + some_u256 == expected_u256, + "given u256 didn't match the expected u256", + ); } else { require(false, "enum was not of variant B: u256"); } } + #[allow(deprecated)] fn u256_in_enum_output() -> SomeEnum { SomeEnum::B(U256::from((1, 2, 3, 4))) } diff --git a/packages/fuels/tests/types/contracts/vector_output/src/main.sw b/packages/fuels/tests/types/contracts/vector_output/src/main.sw index 6b8dec3347..87393105f1 100644 --- a/packages/fuels/tests/types/contracts/vector_output/src/main.sw +++ b/packages/fuels/tests/types/contracts/vector_output/src/main.sw @@ -61,10 +61,13 @@ impl VectorsOutputContract for Contract { fn enum_in_vec() -> Vec { let mut vec: Vec = Vec::new(); - vec.push(Pasta::Tortelini(Bimbam { - bim: 1111, - bam: 2222_u32, - })); + vec + .push( + Pasta::Tortelini(Bimbam { + bim: 1111, + bam: 2222_u32, + }), + ); vec.push(Pasta::Rigatoni(1987)); vec.push(Pasta::Spaghetti(true)); vec diff --git a/packages/fuels/tests/types/predicates/address/src/main.sw b/packages/fuels/tests/types/predicates/address/src/main.sw index c431b853e0..1d2275732f 100644 --- a/packages/fuels/tests/types/predicates/address/src/main.sw +++ b/packages/fuels/tests/types/predicates/address/src/main.sw @@ -1,7 +1,9 @@ predicate; fn main(input: Address) -> bool { - let expected_addr = Address::from(0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a); + let expected_addr = Address::from( + 0xef86afa9696cf0dc6385e2c407a6e159a1103cefb7e2ae0636fb33d3cb2a9e4a, + ); input == expected_addr } diff --git a/packages/fuels/tests/types/predicates/predicate_tuples/src/main.sw b/packages/fuels/tests/types/predicates/predicate_tuples/src/main.sw index 3426226ce6..d4d2e6dfa4 100644 --- a/packages/fuels/tests/types/predicates/predicate_tuples/src/main.sw +++ b/packages/fuels/tests/types/predicates/predicate_tuples/src/main.sw @@ -14,7 +14,8 @@ fn main(input_tuple: (u64, TestStruct, TestEnum), number: u64) -> bool { let (u64_number, test_struct, test_enum) = input_tuple; if let TestEnum::Value(enum_value) = test_enum { - return u64_number == 16 && test_struct.value == 32u32 && enum_value == 64 && number == 128; + return u64_number == 16 && test_struct + .value == 32u32 && enum_value == 64 && number == 128; } false diff --git a/packages/fuels/tests/types/predicates/predicate_u256/src/main.sw b/packages/fuels/tests/types/predicates/predicate_u256/src/main.sw index 09d54b0d1f..59bb293a08 100644 --- a/packages/fuels/tests/types/predicates/predicate_u256/src/main.sw +++ b/packages/fuels/tests/types/predicates/predicate_u256/src/main.sw @@ -2,6 +2,7 @@ predicate; use std::u256::U256; +#[allow(deprecated)] fn main(arg: U256) -> bool { arg == U256::from((10, 11, 12, 13)) } diff --git a/packages/fuels/tests/types/predicates/predicate_vectors/src/main.sw b/packages/fuels/tests/types/predicates/predicate_vectors/src/main.sw index d8b1292cd8..ceb9650aa1 100644 --- a/packages/fuels/tests/types/predicates/predicate_vectors/src/main.sw +++ b/packages/fuels/tests/types/predicates/predicate_vectors/src/main.sw @@ -26,16 +26,25 @@ fn main( result = result && (u32_vec.get(1).unwrap() == 4u32); - result = result && (vec_in_vec.get(0).unwrap().get(1).unwrap() == 2u32); + result = result && (vec_in_vec + .get(0) + .unwrap() + .get(1) + .unwrap() == 2u32); result = result && (struct_in_vec.get(0).unwrap().a == 8u32); - result = result && (vec_in_struct.a.get(1).unwrap() == 16u32); + result = result && (vec_in_struct + .a + .get(1) + .unwrap() == 16u32); let array: [u64; 2] = array_in_vec.get(1).unwrap(); result = result && (array[0] == 32u64); - result = result && (vec_in_array[0].get(1).unwrap() == 64u32); + result = result && (vec_in_array[0] + .get(1) + .unwrap() == 64u32); if let SomeEnum::A(some_vec) = vec_in_enum { result = result && (some_vec.get(2).unwrap() == 128u32); @@ -50,12 +59,21 @@ fn main( result = false; } - result = result && (tuple_in_vec.get(1).unwrap().0 == 128u32); + result = result && (tuple_in_vec + .get(1) + .unwrap().0 == 128u32); let (tuple_a, _) = vec_in_tuple; result = result && (tuple_a.get(1).unwrap() == 64u32); - result = result && (vec_in_a_vec_in_a_struct_in_a_vec.get(1).unwrap().a.get(1).unwrap().get(1).unwrap() == 32u32); + result = result && (vec_in_a_vec_in_a_struct_in_a_vec + .get(1) + .unwrap() + .a + .get(1) + .unwrap() + .get(1) + .unwrap() == 32u32); result } diff --git a/packages/fuels/tests/types/scripts/script_bytes/src/main.sw b/packages/fuels/tests/types/scripts/script_bytes/src/main.sw index 17870256bd..f41dc63c7a 100644 --- a/packages/fuels/tests/types/scripts/script_bytes/src/main.sw +++ b/packages/fuels/tests/types/scripts/script_bytes/src/main.sw @@ -25,13 +25,30 @@ fn expected_bytes() -> Bytes { fn main(_arg: u64, wrapper: Wrapper>) { if let SomeEnum::Second(enum_bytes) = wrapper.inner_enum { - require(enum_bytes == expected_bytes(), "wrapper.inner_enum didn't carry the expected bytes") + require( + enum_bytes == expected_bytes(), + "wrapper.inner_enum didn't carry the expected bytes", + ) } else { require(false, "enum was not of variant Second"); } let inner_vec = wrapper.inner; - require(inner_vec.len() == 2, "Expected wrapper.inner vector to have 2 elements"); - require(inner_vec.get(0).unwrap() == expected_bytes(), "wrapper.inner[0] didn't match expectation"); - require(inner_vec.get(1).unwrap() == expected_bytes(), "wrapper.inner[1] didn't match expectation"); + require( + inner_vec + .len() == 2, + "Expected wrapper.inner vector to have 2 elements", + ); + require( + inner_vec + .get(0) + .unwrap() == expected_bytes(), + "wrapper.inner[0] didn't match expectation", + ); + require( + inner_vec + .get(1) + .unwrap() == expected_bytes(), + "wrapper.inner[1] didn't match expectation", + ); } diff --git a/packages/fuels/tests/types/scripts/script_raw_slice/src/main.sw b/packages/fuels/tests/types/scripts/script_raw_slice/src/main.sw index 255b412872..2d888eeb5a 100644 --- a/packages/fuels/tests/types/scripts/script_raw_slice/src/main.sw +++ b/packages/fuels/tests/types/scripts/script_raw_slice/src/main.sw @@ -14,9 +14,24 @@ struct Wrapper { fn validate_raw_slice(input: raw_slice) { let vec: Vec = Vec::from(input); require(vec.len() == 3, "raw slice len is not 3"); - require(vec.get(2).unwrap() == 42, "expected 3rd slice entry to be 42"); - require(vec.get(1).unwrap() == 41, "expected 2nd slice entry to be 41"); - require(vec.get(0).unwrap() == 40, "expected 1st slice entry to be 40"); + require( + vec + .get(2) + .unwrap() == 42, + "expected 3rd slice entry to be 42", + ); + require( + vec + .get(1) + .unwrap() == 41, + "expected 2nd slice entry to be 41", + ); + require( + vec + .get(0) + .unwrap() == 40, + "expected 1st slice entry to be 40", + ); } fn validate_vec(vec: Vec) { diff --git a/packages/fuels/tests/types/scripts/script_u256/src/main.sw b/packages/fuels/tests/types/scripts/script_u256/src/main.sw index 32cc5d5e05..8a827b42fb 100644 --- a/packages/fuels/tests/types/scripts/script_u256/src/main.sw +++ b/packages/fuels/tests/types/scripts/script_u256/src/main.sw @@ -2,6 +2,7 @@ script; use std::u256::U256; +#[allow(deprecated)] fn main(arg: U256) -> U256 { arg + U256::from((6, 7, 8, 9)) } diff --git a/packages/fuels/tests/types/scripts/script_vectors/src/main.sw b/packages/fuels/tests/types/scripts/script_vectors/src/main.sw index 10d6118d38..d305879803 100644 --- a/packages/fuels/tests/types/scripts/script_vectors/src/main.sw +++ b/packages/fuels/tests/types/scripts/script_vectors/src/main.sw @@ -28,15 +28,18 @@ fn main( } { let mut exp_vec_in_vec = Vec::new(); - exp_vec_in_vec.push(vec_from([0u32, 1u32, 2u32])); + exp_vec_in_vec + .push(vec_from([0u32, 1u32, 2u32])); exp_vec_in_vec.push(vec_from([0u32, 1u32, 2u32])); require(vec_in_vec == exp_vec_in_vec, "vec_in_vec err"); } { let mut exp_struct_in_vec = Vec::new(); - exp_struct_in_vec.push(SomeStruct { a: 0u32 }); - exp_struct_in_vec.push(SomeStruct { a: 1u32 }); + exp_struct_in_vec + .push(SomeStruct { a: 0u32 }); + exp_struct_in_vec + .push(SomeStruct { a: 1u32 }); require(struct_in_vec == exp_struct_in_vec, "struct_in_vec err"); } @@ -49,8 +52,10 @@ fn main( } { let mut exp_array_in_vec = Vec::new(); - exp_array_in_vec.push([0, 1]); - exp_array_in_vec.push([0, 1]); + exp_array_in_vec + .push([0, 1]); + exp_array_in_vec + .push([0, 1]); require(array_in_vec == exp_array_in_vec, "array_in_vec err"); } @@ -67,15 +72,19 @@ fn main( } { let mut exp_enum_in_vec = Vec::new(); - exp_enum_in_vec.push(SomeEnum::a(0u32)); - exp_enum_in_vec.push(SomeEnum::a(1u32)); + exp_enum_in_vec + .push(SomeEnum::a(0u32)); + exp_enum_in_vec + .push(SomeEnum::a(1u32)); require(enum_in_vec == exp_enum_in_vec, "enum_in_vec err"); } { let mut exp_tuple_in_vec = Vec::new(); - exp_tuple_in_vec.push((0u32, 0u32)); - exp_tuple_in_vec.push((1u32, 1u32)); + exp_tuple_in_vec + .push((0u32, 0u32)); + exp_tuple_in_vec + .push((1u32, 1u32)); require(tuple_in_vec == exp_tuple_in_vec, "tuple_in_vec err"); } @@ -90,12 +99,15 @@ fn main( let mut inner_vec_1 = Vec::new(); let inner_inner_vec_1 = vec_from([0u32, 1u32, 2u32]); - inner_vec_1.push(inner_inner_vec_1); + inner_vec_1 + .push(inner_inner_vec_1); let inner_inner_vec_2 = vec_from([3u32, 4u32, 5u32]); - inner_vec_1.push(inner_inner_vec_2); + inner_vec_1 + .push(inner_inner_vec_2); - exp_vec_in_a_vec_in_a_struct_in_a_vec.push(SomeStruct { a: inner_vec_1 }); + exp_vec_in_a_vec_in_a_struct_in_a_vec + .push(SomeStruct { a: inner_vec_1 }); let mut inner_vec_2 = Vec::new(); @@ -105,9 +117,13 @@ fn main( let inner_inner_vec_4 = vec_from([9u32, 10u32, 11u32]); inner_vec_2.push(inner_inner_vec_4); - exp_vec_in_a_vec_in_a_struct_in_a_vec.push(SomeStruct { a: inner_vec_2 }); + exp_vec_in_a_vec_in_a_struct_in_a_vec + .push(SomeStruct { a: inner_vec_2 }); - require(vec_in_a_vec_in_a_struct_in_a_vec == exp_vec_in_a_vec_in_a_struct_in_a_vec, "vec_in_a_vec_in_a_struct_in_a_vec err"); + require( + vec_in_a_vec_in_a_struct_in_a_vec == exp_vec_in_a_vec_in_a_struct_in_a_vec, + "vec_in_a_vec_in_a_struct_in_a_vec err", + ); } true diff --git a/packages/fuels/tests/types_contracts.rs b/packages/fuels/tests/types_contracts.rs index 27cc7c47a7..f2ac7ce160 100644 --- a/packages/fuels/tests/types_contracts.rs +++ b/packages/fuels/tests/types_contracts.rs @@ -2072,8 +2072,10 @@ async fn test_heap_type_in_enums() -> Result<()> { let contract_methods = contract_instance.methods(); let resp = contract_methods.returns_bytes_result(true).call().await?; + dbg!(&resp); let expected = Ok(Bytes(vec![1, 1, 1, 1])); assert_eq!(resp.value, expected); + let resp = contract_methods.returns_bytes_result(false).call().await?; let expected = Err(TestError::Something([255u8, 255u8, 255u8, 255u8, 255u8])); assert_eq!(resp.value, expected); @@ -2081,6 +2083,7 @@ async fn test_heap_type_in_enums() -> Result<()> { let resp = contract_methods.returns_vec_result(true).call().await?; let expected = Ok(vec![2, 2, 2, 2, 2]); assert_eq!(resp.value, expected); + let resp = contract_methods.returns_vec_result(false).call().await?; let expected = Err(TestError::Else(7777)); assert_eq!(resp.value, expected); @@ -2088,6 +2091,7 @@ async fn test_heap_type_in_enums() -> Result<()> { let resp = contract_methods.returns_string_result(true).call().await?; let expected = Ok("Hello World".to_string()); assert_eq!(resp.value, expected); + let resp = contract_methods.returns_string_result(false).call().await?; let expected = Err(TestError::Else(3333)); assert_eq!(resp.value, expected); @@ -2095,6 +2099,7 @@ async fn test_heap_type_in_enums() -> Result<()> { let resp = contract_methods.returns_str_result(true).call().await?; let expected = Ok("Hello World".try_into()?); assert_eq!(resp.value, expected); + let resp = contract_methods.returns_string_result(false).call().await?; let expected = Err(TestError::Else(3333)); assert_eq!(resp.value, expected); @@ -2102,24 +2107,28 @@ async fn test_heap_type_in_enums() -> Result<()> { let resp = contract_methods.returns_bytes_option(true).call().await?; let expected = Some(Bytes(vec![1, 1, 1, 1])); assert_eq!(resp.value, expected); + let resp = contract_methods.returns_bytes_option(false).call().await?; assert!(resp.value.is_none()); let resp = contract_methods.returns_vec_option(true).call().await?; let expected = Some(vec![2, 2, 2, 2, 2]); assert_eq!(resp.value, expected); + let resp = contract_methods.returns_vec_option(false).call().await?; assert!(resp.value.is_none()); let resp = contract_methods.returns_string_option(true).call().await?; let expected = Some("Hello World".to_string()); assert_eq!(resp.value, expected); + let resp = contract_methods.returns_string_option(false).call().await?; assert!(resp.value.is_none()); let resp = contract_methods.returns_str_option(true).call().await?; let expected = Some("Hello World".try_into()?); assert_eq!(resp.value, expected); + let resp = contract_methods.returns_string_option(false).call().await?; assert!(resp.value.is_none());