diff --git a/Cargo.toml b/Cargo.toml index e18551268..bd71f4f59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,3 +102,9 @@ fuels-core = { version = "0.49.0", path = "./packages/fuels-core", default-featu 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 } + +[patch.crates-io] +fuel-core = { git = "https://github.com/FuelLabs/fuel-core", branch = "master" } +fuel-core-chain-config = { git = "https://github.com/FuelLabs/fuel-core", branch = "master" } +fuel-core-client = { git = "https://github.com/FuelLabs/fuel-core", branch = "master" } +fuel-core-types = { git = "https://github.com/FuelLabs/fuel-core", branch = "master" } diff --git a/packages/fuels-programs/src/call_utils.rs b/packages/fuels-programs/src/call_utils.rs index 1354a96c8..6ea88f9f1 100644 --- a/packages/fuels-programs/src/call_utils.rs +++ b/packages/fuels-programs/src/call_utils.rs @@ -228,9 +228,9 @@ pub(crate) fn get_instructions( /// Returns script data, consisting of the following items in the given order: /// 1. Amount to be forwarded `(1 * `[`WORD_SIZE`]`)` /// 2. Asset ID to be forwarded ([`AssetId::LEN`]) -/// 3. Contract ID ([`ContractId::LEN`]); -/// 4. Function selector `(1 * `[`WORD_SIZE`]`)` -/// 5. Gas to be forwarded `(1 * `[`WORD_SIZE`]`)` +/// 3. Gas to be forwarded `(1 * `[`WORD_SIZE`]`)` - Optional +/// 4. Contract ID ([`ContractId::LEN`]); +/// 5. Function selector `(1 * `[`WORD_SIZE`]`)` /// 6. Calldata offset (optional) `(1 * `[`WORD_SIZE`]`)` /// 7. Encoded arguments (optional) (variable length) pub(crate) fn build_script_data_from_contract_calls( @@ -246,28 +246,28 @@ pub(crate) fn build_script_data_from_contract_calls( for call in calls { let gas_forwarded = call.call_parameters.gas_forwarded(); - let call_param_offsets = CallOpcodeParamsOffset { - amount_offset: segment_offset, - asset_id_offset: segment_offset + WORD_SIZE, - call_data_offset: segment_offset + WORD_SIZE + AssetId::LEN, - gas_forwarded_offset: gas_forwarded - .map(|_| segment_offset + WORD_SIZE + AssetId::LEN + ContractId::LEN + WORD_SIZE), - }; - param_offsets.push(call_param_offsets); - script_data.extend(call.call_parameters.amount().to_be_bytes()); script_data.extend(call.call_parameters.asset_id().iter()); - script_data.extend(call.contract_id.hash().as_ref()); - script_data.extend(call.encoded_selector); let gas_forwarded_size = gas_forwarded .map(|gf| { - script_data.extend(gf.to_be_bytes()); + script_data.extend((gf as Word).to_be_bytes()); WORD_SIZE }) .unwrap_or_default(); + script_data.extend(call.contract_id.hash().as_ref()); + script_data.extend(call.encoded_selector); + + let call_param_offsets = CallOpcodeParamsOffset { + amount_offset: segment_offset, + asset_id_offset: segment_offset + WORD_SIZE, + gas_forwarded_offset: gas_forwarded.map(|_| segment_offset + WORD_SIZE + AssetId::LEN), + call_data_offset: segment_offset + WORD_SIZE + AssetId::LEN + gas_forwarded_size, + }; + param_offsets.push(call_param_offsets); + // If the method call takes custom inputs or has more than // one argument, we need to calculate the `call_data_offset`, // which points to where the data for the custom types start in the @@ -278,9 +278,9 @@ pub(crate) fn build_script_data_from_contract_calls( let custom_input_offset = segment_offset + WORD_SIZE // amount size + AssetId::LEN + + gas_forwarded_size + ContractId::LEN + WORD_SIZE // encoded_selector size - + gas_forwarded_size + WORD_SIZE; // custom_input_offset size script_data.extend((custom_input_offset as Word).to_be_bytes()); @@ -289,7 +289,7 @@ pub(crate) fn build_script_data_from_contract_calls( segment_offset }; - let bytes = call.encoded_args.resolve(encoded_args_start_offset as u64); + let bytes = call.encoded_args.resolve(encoded_args_start_offset as Word); script_data.extend(bytes); // the data segment that holds the parameters for the next call @@ -609,7 +609,6 @@ mod test { async fn test_script_data() { // Arrange const SELECTOR_LEN: usize = WORD_SIZE; - const GAS_FORWARDED_SIZE: usize = WORD_SIZE; const NUM_CALLS: usize = 3; let contract_ids = vec![ @@ -678,19 +677,16 @@ mod test { } // Calls 1 and 3 have their input arguments after the selector - let call_1_arg_offset = - param_offsets[0].call_data_offset + ContractId::LEN + SELECTOR_LEN + GAS_FORWARDED_SIZE; + let call_1_arg_offset = param_offsets[0].call_data_offset + ContractId::LEN + SELECTOR_LEN; let call_1_arg = script_data[call_1_arg_offset..call_1_arg_offset + WORD_SIZE].to_vec(); assert_eq!(call_1_arg, args[0].resolve(0)); - let call_3_arg_offset = - param_offsets[2].call_data_offset + ContractId::LEN + SELECTOR_LEN + GAS_FORWARDED_SIZE; + let call_3_arg_offset = param_offsets[2].call_data_offset + ContractId::LEN + SELECTOR_LEN; let call_3_arg = script_data[call_3_arg_offset..call_3_arg_offset + WORD_SIZE].to_vec(); assert_eq!(call_3_arg, args[2].resolve(0)); // Call 2 has custom inputs and custom_input_offset - let call_2_arg_offset = - param_offsets[1].call_data_offset + ContractId::LEN + SELECTOR_LEN + GAS_FORWARDED_SIZE; + let call_2_arg_offset = param_offsets[1].call_data_offset + ContractId::LEN + SELECTOR_LEN; let custom_input_offset = script_data[call_2_arg_offset..call_2_arg_offset + WORD_SIZE].to_vec(); assert_eq!( @@ -698,11 +694,8 @@ mod test { (call_2_arg_offset + WORD_SIZE).to_be_bytes() ); - let custom_input_offset = param_offsets[1].call_data_offset - + ContractId::LEN - + SELECTOR_LEN - + GAS_FORWARDED_SIZE - + WORD_SIZE; + let custom_input_offset = + param_offsets[1].call_data_offset + ContractId::LEN + SELECTOR_LEN + WORD_SIZE; let custom_input = script_data[custom_input_offset..custom_input_offset + WORD_SIZE].to_vec(); assert_eq!(custom_input, args[1].resolve(0)); diff --git a/packages/fuels-test-helpers/src/fuel_bin_service.rs b/packages/fuels-test-helpers/src/fuel_bin_service.rs index f1e66d7f4..ce5d37f79 100644 --- a/packages/fuels-test-helpers/src/fuel_bin_service.rs +++ b/packages/fuels-test-helpers/src/fuel_bin_service.rs @@ -136,7 +136,9 @@ impl FuelService { config_file: NamedTempFile::new()?, }; + let addr = extended_config.config.addr; let handle = run_node(extended_config).await?; + server_health_check(addr).await?; Ok(FuelService { bound_address, @@ -150,7 +152,9 @@ impl FuelService { } } -async fn server_health_check(client: &FuelClient) -> FuelResult<()> { +async fn server_health_check(address: SocketAddr) -> FuelResult<()> { + let client = FuelClient::from(address); + let mut attempts = 5; let mut healthy = client.health().await.unwrap_or(false); let between_attempts = Duration::from_millis(300); @@ -205,11 +209,9 @@ async fn run_node(mut extended_config: ExtendedConfig) -> FuelResult Ok(()) } + +#[tokio::test] +async fn test_arguments_with_gas_forwarded() -> Result<()> { + setup_program_test!( + Wallets("wallet"), + Abigen( + Contract( + name = "TestContract", + project = "packages/fuels/tests/contracts/contract_test" + ), + Contract( + name = "VectorOutputContract", + project = "packages/fuels/tests/types/contracts/vectors" + ) + ), + Deploy( + name = "contract_instance", + contract = "TestContract", + wallet = "wallet" + ), + Deploy( + name = "contract_instance_2", + contract = "VectorOutputContract", + wallet = "wallet" + ), + ); + + let x = 128; + let vec_input = vec![0, 1, 2]; + { + let response = contract_instance + .methods() + .get_single(x) + .call_params(CallParameters::default().with_gas_forwarded(1024))? + .call() + .await?; + + assert_eq!(response.value, x); + } + { + contract_instance_2 + .methods() + .u32_vec(vec_input.clone()) + .call_params(CallParameters::default().with_gas_forwarded(1024))? + .call() + .await?; + } + { + let call_handler_1 = contract_instance.methods().get_single(x); + let call_handler_2 = contract_instance_2.methods().u32_vec(vec_input); + + let mut multi_call_handler = MultiContractCallHandler::new(wallet.clone()); + + multi_call_handler + .add_call(call_handler_1) + .add_call(call_handler_2); + + let (value, _): (u64, ()) = multi_call_handler.call().await?.value; + + assert_eq!(value, x); + } + + Ok(()) +} diff --git a/packages/fuels/tests/providers.rs b/packages/fuels/tests/providers.rs index e0c40248a..286981a3c 100644 --- a/packages/fuels/tests/providers.rs +++ b/packages/fuels/tests/providers.rs @@ -605,7 +605,6 @@ async fn test_get_gas_used() -> Result<()> { } #[tokio::test] -#[ignore] async fn testnet_hello_world() -> Result<()> { // Note that this test might become flaky. // This test depends on: