From ff822786ae70e68c4de53ecfa62fa40523ddafa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Fri, 14 Nov 2025 17:11:39 +0400 Subject: [PATCH 1/4] Remove gas limits in `forc test` --- forc-test/src/lib.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/forc-test/src/lib.rs b/forc-test/src/lib.rs index ba7e31819dc..7178498da03 100644 --- a/forc-test/src/lib.rs +++ b/forc-test/src/lib.rs @@ -19,6 +19,7 @@ use pkg::{Built, BuiltPackage}; use rand::{Rng, SeedableRng}; use rayon::prelude::*; use std::str::FromStr; +use std::u64; use std::{collections::HashMap, fs, path::PathBuf, sync::Arc}; use sway_core::{BuildTarget, IrCli}; use sway_types::Span; @@ -705,7 +706,9 @@ pub(crate) fn maxed_consensus_params(gas_costs_values: GasCostsValues) -> Consen let script_params = ScriptParameters::DEFAULT .with_max_script_length(u64::MAX) .with_max_script_data_length(u64::MAX); - let tx_params = TxParameters::DEFAULT.with_max_size(u64::MAX); + let tx_params = TxParameters::DEFAULT + .with_max_size(u64::MAX) + .with_max_gas_per_tx(u64::MAX); let contract_params = ContractParameters::DEFAULT .with_contract_max_size(u64::MAX) .with_max_storage_slots(u64::MAX); @@ -714,6 +717,7 @@ pub(crate) fn maxed_consensus_params(gas_costs_values: GasCostsValues) -> Consen tx_params, contract_params, gas_costs: gas_costs_values.into(), + block_gas_limit: u64::MAX, ..Default::default() }) } From 9e79bbb971bdb73a914c447ca2b36ea7d0b8cff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Fri, 14 Nov 2025 17:24:29 +0400 Subject: [PATCH 2/4] Fix Clippy issues --- forc-test/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/forc-test/src/lib.rs b/forc-test/src/lib.rs index 7178498da03..d62274400e8 100644 --- a/forc-test/src/lib.rs +++ b/forc-test/src/lib.rs @@ -19,7 +19,6 @@ use pkg::{Built, BuiltPackage}; use rand::{Rng, SeedableRng}; use rayon::prelude::*; use std::str::FromStr; -use std::u64; use std::{collections::HashMap, fs, path::PathBuf, sync::Arc}; use sway_core::{BuildTarget, IrCli}; use sway_types::Span; From c7ca4be6519debeeefe6931f459567db5d933ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Mon, 1 Dec 2025 16:57:24 +0400 Subject: [PATCH 3/4] Add `--no-gas-limit` CLI option --- forc-plugins/forc-debug/src/server/mod.rs | 3 +- forc-test/src/execute.rs | 4 +- forc-test/src/lib.rs | 60 ++++++++++++++++++----- forc/src/cli/commands/test.rs | 14 +++++- test/src/e2e_vm_tests/harness.rs | 3 +- 5 files changed, 68 insertions(+), 16 deletions(-) diff --git a/forc-plugins/forc-debug/src/server/mod.rs b/forc-plugins/forc-debug/src/server/mod.rs index 27e7bab1e5d..5b4f7faddda 100644 --- a/forc-plugins/forc-debug/src/server/mod.rs +++ b/forc-plugins/forc-debug/src/server/mod.rs @@ -20,7 +20,7 @@ use forc_pkg::{ use forc_test::{ execute::{DebugResult, TestExecutor}, setup::TestSetup, - BuiltTests, + BuiltTests, TestGasLimit, }; use fuel_tx::GasCostsValues; use serde::{Deserialize, Serialize}; @@ -252,6 +252,7 @@ impl DapServer { // TODO: (GAS-COSTS) Provide gas costs values here, similar like in `forc test`. // See: https://github.com/FuelLabs/sway/issues/7472 GasCostsValues::default(), + TestGasLimit::default(), ) .ok() }) diff --git a/forc-test/src/execute.rs b/forc-test/src/execute.rs index f182246e1a2..b0ad8a7a24e 100644 --- a/forc-test/src/execute.rs +++ b/forc-test/src/execute.rs @@ -1,6 +1,7 @@ use crate::ecal::EcalSyscallHandler; use crate::maxed_consensus_params; use crate::setup::TestSetup; +use crate::TestGasLimit; use crate::TestResult; use crate::TEST_METADATA_SEED; use forc_pkg::PkgTestEntry; @@ -50,6 +51,7 @@ impl TestExecutor { test_entry: &PkgTestEntry, name: String, gas_costs_values: GasCostsValues, + gas_limit: TestGasLimit, ) -> anyhow::Result { let storage = test_setup.storage().clone(); @@ -76,7 +78,7 @@ impl TestExecutor { let mut tx_builder = tx::TransactionBuilder::script(bytecode.to_vec(), script_input_data); - let params = maxed_consensus_params(gas_costs_values); + let params = maxed_consensus_params(gas_costs_values, gas_limit); tx_builder .with_params(params) diff --git a/forc-test/src/lib.rs b/forc-test/src/lib.rs index feb45dc65f3..1ec1f187973 100644 --- a/forc-test/src/lib.rs +++ b/forc-test/src/lib.rs @@ -81,6 +81,14 @@ pub struct TestResult { pub ecal: Box, } +#[derive(Default, Debug, Clone, Copy)] +pub enum TestGasLimit { + #[default] + Default, + Unlimited, + Limited(u64), +} + const TEST_METADATA_SEED: u64 = 0x7E57u64; /// A mapping from each member package of a build plan to its compiled contract dependencies. type ContractDependencyMap = HashMap>>; @@ -265,7 +273,7 @@ impl PackageWithDeploymentToTest { // We are not concerned about gas costs of contract deployments for tests, // only the gas costs of test executions. So, we can simply provide the // default, built-in, gas costs values here. - let params = maxed_consensus_params(GasCostsValues::default()); + let params = maxed_consensus_params(GasCostsValues::default(), TestGasLimit::default()); let storage = vm::storage::MemoryStorage::default(); let interpreter_params = InterpreterParams::new(gas_price, params.clone()); let mut interpreter: vm::prelude::Interpreter<_, _, _, vm::interpreter::NotSupportedEcal> = @@ -433,6 +441,7 @@ impl<'a> PackageTests { test_runners: &rayon::ThreadPool, test_filter: Option<&TestFilter>, gas_costs_values: GasCostsValues, + gas_limit: TestGasLimit, ) -> anyhow::Result { let pkg_with_tests = self.built_pkg_with_tests(); let tests = test_runners.install(|| { @@ -467,6 +476,7 @@ impl<'a> PackageTests { test_entry, name, gas_costs_values.clone(), + gas_limit, )? .execute() }) @@ -663,6 +673,7 @@ impl BuiltTests { test_runner_count: TestRunnerCount, test_filter: Option, gas_costs_values: GasCostsValues, + gas_limit: TestGasLimit, ) -> anyhow::Result { let test_runners = match test_runner_count { TestRunnerCount::Manual(runner_count) => rayon::ThreadPoolBuilder::new() @@ -670,7 +681,13 @@ impl BuiltTests { .build(), TestRunnerCount::Auto => rayon::ThreadPoolBuilder::new().build(), }?; - run_tests(self, &test_runners, test_filter, gas_costs_values) + run_tests( + self, + &test_runners, + test_filter, + gas_costs_values, + gas_limit, + ) } } @@ -684,13 +701,19 @@ pub fn build(opts: TestOpts) -> anyhow::Result { /// Returns a `ConsensusParameters` which has maximum length/size allowance for scripts, contracts, /// and transactions. -pub(crate) fn maxed_consensus_params(gas_costs_values: GasCostsValues) -> ConsensusParameters { +pub(crate) fn maxed_consensus_params( + gas_costs_values: GasCostsValues, + gas_limit: TestGasLimit, +) -> ConsensusParameters { let script_params = ScriptParameters::DEFAULT .with_max_script_length(u64::MAX) .with_max_script_data_length(u64::MAX); - let tx_params = TxParameters::DEFAULT - .with_max_size(u64::MAX) - .with_max_gas_per_tx(u64::MAX); + let tx_params = match gas_limit { + TestGasLimit::Default => TxParameters::DEFAULT, + TestGasLimit::Unlimited => TxParameters::DEFAULT.with_max_gas_per_tx(u64::MAX), + TestGasLimit::Limited(limit) => TxParameters::DEFAULT.with_max_gas_per_tx(limit), + } + .with_max_size(u64::MAX); let contract_params = ContractParameters::DEFAULT .with_contract_max_size(u64::MAX) .with_max_storage_slots(u64::MAX); @@ -753,18 +776,28 @@ fn run_tests( test_runners: &rayon::ThreadPool, test_filter: Option, gas_costs_values: GasCostsValues, + gas_limit: TestGasLimit, ) -> anyhow::Result { match built { BuiltTests::Package(pkg) => { - let tested_pkg = - pkg.run_tests(test_runners, test_filter.as_ref(), gas_costs_values.clone())?; + let tested_pkg = pkg.run_tests( + test_runners, + test_filter.as_ref(), + gas_costs_values.clone(), + gas_limit, + )?; Ok(Tested::Package(Box::new(tested_pkg))) } BuiltTests::Workspace(workspace) => { let tested_pkgs = workspace .into_iter() .map(|pkg| { - pkg.run_tests(test_runners, test_filter.as_ref(), gas_costs_values.clone()) + pkg.run_tests( + test_runners, + test_filter.as_ref(), + gas_costs_values.clone(), + gas_limit, + ) }) .collect::>>()?; Ok(Tested::Workspace(tested_pkgs)) @@ -778,7 +811,7 @@ mod tests { use fuel_tx::GasCostsValues; - use crate::{build, BuiltTests, TestFilter, TestOpts, TestResult}; + use crate::{build, BuiltTests, TestFilter, TestGasLimit, TestOpts, TestResult}; /// Name of the folder containing required data for tests to run, such as an example forc /// project. @@ -816,7 +849,12 @@ mod tests { ) -> anyhow::Result> { let built_tests = test_package_built_tests(package_name)?; let test_runner_count = crate::TestRunnerCount::Auto; - let tested = built_tests.run(test_runner_count, test_filter, GasCostsValues::default())?; + let tested = built_tests.run( + test_runner_count, + test_filter, + GasCostsValues::default(), + TestGasLimit::default(), + )?; match tested { crate::Tested::Package(tested_pkg) => Ok(tested_pkg.tests), crate::Tested::Workspace(_) => { diff --git a/forc/src/cli/commands/test.rs b/forc/src/cli/commands/test.rs index 7f3d841c729..e9042894743 100644 --- a/forc/src/cli/commands/test.rs +++ b/forc/src/cli/commands/test.rs @@ -2,7 +2,9 @@ use crate::cli::{self, shared::IrCliOpt}; use ansiterm::Colour; use clap::Parser; use forc_pkg as pkg; -use forc_test::{GasCostsSource, TestFilter, TestResult, TestRunnerCount, TestedPackage}; +use forc_test::{ + GasCostsSource, TestFilter, TestGasLimit, TestResult, TestRunnerCount, TestedPackage, +}; use forc_tracing::println_action_green; use forc_util::{ tx_utils::{decode_fuel_vm_log_data, format_log_receipts}, @@ -68,6 +70,9 @@ pub struct Command { /// [possible values: built-in, mainnet, testnet, ] #[clap(long)] pub gas_costs: Option, + /// Remove gas limit for test executions. + #[clap(long)] + pub no_gas_limit: bool, } /// The set of options provided for controlling output of a test. @@ -107,6 +112,11 @@ pub(crate) fn exec(cmd: Command) -> ForcResult<()> { .as_ref() .unwrap_or(&GasCostsSource::BuiltIn) .provide_gas_costs()?; + let gas_limit = if cmd.no_gas_limit { + TestGasLimit::Unlimited + } else { + TestGasLimit::Default + }; let opts = opts_from_cmd(cmd); let built_tests = forc_test::build(opts)?; let start = std::time::Instant::now(); @@ -123,7 +133,7 @@ pub(crate) fn exec(cmd: Command) -> ForcResult<()> { formatted_test_count_string(num_tests_ignored) ), ); - let tested = built_tests.run(test_runner_count, test_filter, gas_costs_values)?; + let tested = built_tests.run(test_runner_count, test_filter, gas_costs_values, gas_limit)?; let duration = start.elapsed(); // Eventually we'll print this in a fancy manner, but this will do for testing. diff --git a/test/src/e2e_vm_tests/harness.rs b/test/src/e2e_vm_tests/harness.rs index ca65ecd0230..45532c886e3 100644 --- a/test/src/e2e_vm_tests/harness.rs +++ b/test/src/e2e_vm_tests/harness.rs @@ -9,7 +9,7 @@ use forc_client::{ NodeTarget, }; use forc_pkg::{BuildProfile, Built, BuiltPackage, PrintOpts}; -use forc_test::ecal::EcalSyscallHandler; +use forc_test::{ecal::EcalSyscallHandler, TestGasLimit}; use fuel_tx::TransactionBuilder; use fuel_vm::checked_transaction::builder::TransactionBuilderExt; use fuel_vm::fuel_tx::{self, consensus_parameters::ConsensusParametersV1}; @@ -366,6 +366,7 @@ pub(crate) async fn compile_and_run_unit_tests( forc_test::TestRunnerCount::Auto, test_filter, run_config.gas_costs_values.clone(), + TestGasLimit::default(), )?; match tested { forc_test::Tested::Package(tested_pkg) => Ok(vec![*tested_pkg]), From 4e47b31266bbcc5907c607644fcd9d656d577a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Ron=C4=8Devi=C4=87?= Date: Mon, 1 Dec 2025 17:05:10 +0400 Subject: [PATCH 4/4] Add `SHW` to `.typos.toml` --- .typos.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/.typos.toml b/.typos.toml index 067f201e0d3..1732c77736f 100644 --- a/.typos.toml +++ b/.typos.toml @@ -12,6 +12,7 @@ extend-ignore-identifiers-re = [ "ALOC", "Aloc", "aloc", + "SHW", ] extend-ignore-re = [