Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions e2e/tests/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2880,3 +2880,45 @@ async fn test_returned_method_descriptors_are_valid() -> Result<()> {

Ok(())
}

#[tokio::test]
async fn test_max_fee_estimation_tolerance() -> Result<()> {
setup_program_test!(
Wallets("wallet"),
Abigen(Contract(
name = "TestContract",
project = "e2e/sway/contracts/contract_test"
)),
Deploy(
name = "contract_instance",
contract = "TestContract",
wallet = "wallet",
random_salt = false,
),
);

// Test with default tolerance
let contract_methods = contract_instance.methods();
let response_default = contract_methods.get_single(5).call().await?;
assert_eq!(response_default.value, 5);

// Test with custom tolerance (lower than default)
let custom_tolerance = 0.1; // 10% tolerance
let response_custom = contract_methods
.get_single(5)
.with_max_fee_estimation_tolerance(custom_tolerance)
.call()
.await?;
assert_eq!(response_custom.value, 5);

// Test with custom tolerance (higher than default)
let high_tolerance = 1.0; // 100% tolerance
let response_high = contract_methods
.get_single(5)
.with_max_fee_estimation_tolerance(high_tolerance)
.call()
.await?;
assert_eq!(response_high.value, 5);

Ok(())
}
16 changes: 16 additions & 0 deletions packages/fuels-programs/src/calls/call_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub struct CallHandler<A, C, T> {
cached_tx_id: Option<Bytes32>,
variable_output_policy: VariableOutputPolicy,
unresolved_signers: Vec<Arc<dyn Signer + Send + Sync>>,
max_fee_estimation_tolerance: f32,
}

impl<A, C, T> CallHandler<A, C, T> {
Expand Down Expand Up @@ -85,6 +86,17 @@ impl<A, C, T> CallHandler<A, C, T> {
self.unresolved_signers.push(Arc::new(signer));
self
}

/// Sets the max fee estimation tolerance for a given transaction.
/// This tolerance is used as a buffer when estimating the maximum fee.
/// Note that this is a builder method, i.e. use it as a chain:
/// ```ignore
/// my_contract_instance.my_method(...).with_max_fee_estimation_tolerance(0.25).call()
/// ```
pub fn with_max_fee_estimation_tolerance(mut self, max_fee_estimation_tolerance: f32) -> Self {
self.max_fee_estimation_tolerance = max_fee_estimation_tolerance;
self
}
}

impl<A, C, T> CallHandler<A, C, T>
Expand Down Expand Up @@ -123,6 +135,7 @@ where
consensus_parameters,
asset_inputs,
&self.account,
self.max_fee_estimation_tolerance,
)?;

tb.add_signers(&self.unresolved_signers)?;
Expand Down Expand Up @@ -317,6 +330,7 @@ where
cached_tx_id: None,
variable_output_policy: VariableOutputPolicy::default(),
unresolved_signers: vec![],
max_fee_estimation_tolerance: crate::DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE,
}
}

Expand Down Expand Up @@ -405,6 +419,7 @@ where
cached_tx_id: None,
variable_output_policy: VariableOutputPolicy::default(),
unresolved_signers: vec![],
max_fee_estimation_tolerance: crate::DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE,
}
}

Expand Down Expand Up @@ -438,6 +453,7 @@ where
cached_tx_id: None,
variable_output_policy: VariableOutputPolicy::default(),
unresolved_signers: vec![],
max_fee_estimation_tolerance: crate::DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE,
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub trait TransactionTuner: sealed::Sealed {
consensus_parameters: &ConsensusParameters,
asset_input: Vec<Input>,
account: &T,
max_fee_estimation_tolerance: f32,
) -> Result<ScriptTransactionBuilder>;

async fn build_tx<T: Account>(
Expand All @@ -51,6 +52,7 @@ impl TransactionTuner for ContractCall {
consensus_parameters: &ConsensusParameters,
asset_input: Vec<Input>,
account: &T,
max_fee_estimation_tolerance: f32,
) -> Result<ScriptTransactionBuilder> {
transaction_builder_from_contract_calls(
std::slice::from_ref(self),
Expand All @@ -59,6 +61,7 @@ impl TransactionTuner for ContractCall {
consensus_parameters,
asset_input,
account,
max_fee_estimation_tolerance,
)
}

Expand All @@ -84,6 +87,7 @@ impl TransactionTuner for ScriptCall {
_: &ConsensusParameters,
_: Vec<Input>,
_account: &T,
max_fee_estimation_tolerance: f32,
) -> Result<ScriptTransactionBuilder> {
let (inputs, outputs) = self.prepare_inputs_outputs()?;

Expand All @@ -95,7 +99,7 @@ impl TransactionTuner for ScriptCall {
.with_inputs(inputs)
.with_outputs(outputs)
.with_gas_estimation_tolerance(DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE)
.with_max_fee_estimation_tolerance(DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE))
.with_max_fee_estimation_tolerance(max_fee_estimation_tolerance))
}

async fn build_tx<T: Account>(
Expand Down Expand Up @@ -128,6 +132,7 @@ impl TransactionTuner for Vec<ContractCall> {
consensus_parameters: &ConsensusParameters,
asset_input: Vec<Input>,
account: &T,
max_fee_estimation_tolerance: f32,
) -> Result<ScriptTransactionBuilder> {
validate_contract_calls(self)?;

Expand All @@ -138,6 +143,7 @@ impl TransactionTuner for Vec<ContractCall> {
consensus_parameters,
asset_input,
account,
max_fee_estimation_tolerance,
)
}

Expand Down
3 changes: 2 additions & 1 deletion packages/fuels-programs/src/calls/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub(crate) fn transaction_builder_from_contract_calls(
consensus_parameters: &ConsensusParameters,
asset_inputs: Vec<Input>,
account: &impl Account,
max_fee_estimation_tolerance: f32,
) -> Result<ScriptTransactionBuilder> {
let calls_instructions_len = compute_calls_instructions_len(calls);
let data_offset = call_script_data_offset(consensus_parameters, calls_instructions_len)?;
Expand All @@ -63,7 +64,7 @@ pub(crate) fn transaction_builder_from_contract_calls(
.with_inputs(inputs)
.with_outputs(outputs)
.with_gas_estimation_tolerance(DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE)
.with_max_fee_estimation_tolerance(DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE))
.with_max_fee_estimation_tolerance(max_fee_estimation_tolerance))
}

/// Creates a [`ScriptTransaction`] from contract calls. The internal [Transaction] is
Expand Down
12 changes: 11 additions & 1 deletion packages/fuels-programs/src/executable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,16 @@ impl Executable<Loader> {
pub async fn upload_blob(
&self,
account: impl fuels_accounts::Account,
) -> Result<Option<TxResponse>> {
self.upload_blob_with_tolerance(account, DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE).await
}

/// If not previously uploaded, uploads a blob containing the original executable code minus the data section,
/// using the specified max fee estimation tolerance.
pub async fn upload_blob_with_tolerance(
&self,
account: impl fuels_accounts::Account,
max_fee_estimation_tolerance: f32,
) -> Result<Option<TxResponse>> {
let blob = self.blob();
let provider = account.try_provider()?;
Expand All @@ -178,7 +188,7 @@ impl Executable<Loader> {

let mut tb = BlobTransactionBuilder::default()
.with_blob(self.blob())
.with_max_fee_estimation_tolerance(DEFAULT_MAX_FEE_ESTIMATION_TOLERANCE);
.with_max_fee_estimation_tolerance(max_fee_estimation_tolerance);

account
.adjust_for_fee(&mut tb, 0)
Expand Down