A new Fuels Rust SDK 0.65.0 charges extra token amount for token transfer

Checkout GitHub - compolabs/orderbook-contract at feat-fuels-rs-0.65.0
forc build --release
cargo test --release
2 tests fail after 0.64.0 → 0.65.0 move

Pls next time describe smth like this

Issue Report

Description

Hello, I am experiencing the following problem: A new Fuels Rust SDK 0.65.0 charges extra token amount for token transfer.

Steps to Reproduce

  1. Run forc build --release

  2. Run cargo test --release

  3. Note that 2 tests fail after moving from version 0.64.0 to 0.65.0.

Expected Behavior

The token transfer should not charge an extra token amount and all tests should pass as they did with version 0.64.0.

Actual Behavior

After updating to version 0.65.0, two tests fail due to an extra token amount being charged for token transfers.

Fuelup Toolchain

SDK Version

0.65.0

Repository

Checkout GitHub - compolabs/orderbook-contract at feat-fuels-rs-0.65.0

You have fuel-core-lib enabled on your SDK dependency, which means that alongside the SDK you’re going to get the fuel node (the one SDK was developed against) built-in.

By changing the SDK from 0.64 to 0.65 the built-in fuel node version changes from 0.28.0 to 0.31.0.

The owner whose balance you’re checking after you’ve made a deposit is also the one who covers the transaction costs. The old node determined that the gas price at this point in time should be 0, while the new one sets it to 1.

This has an impact on your assertions because you are now charged 1 BASE_ASSET for your transaction due to the change in gas price.

You can see this in action yourself by tweaking your deposit code a bit to print the tx estimation:

    pub async fn deposit(
        &self,
        amount: u64,
        asset: AssetId,
    ) -> anyhow::Result<FuelCallResponse<()>> {
        let call_params = CallParameters::new(amount, asset, 1_000_000);
        let tx_policies = TxPolicies::default().with_script_gas_limit(1_000_000);

        let call = self
            .instance
            .methods()
            .deposit()
            .with_tx_policies(tx_policies)
            .call_params(call_params)?;

        let estimation: TransactionCost = call.estimate_transaction_cost(None, None).await?;
        eprintln!("Estimated cost: {estimation:#?}");

        Ok(call.call().await?)
    }

fuels 0.64.0 (alongside fuel-core 0.28.0) prints:

Estimated cost: TransactionCost {
    gas_price: 0,
    gas_used: 8970,
    metered_bytes_size: 816,
    total_fee: 0,
}

while fuels 0.65.0 (alongside fuel-core 0.31.0) gives:

Estimated cost: TransactionCost {
    gas_price: 1,
    gas_used: 9259,
    metered_bytes_size: 816,
    total_fee: 1,
}

Resulting in your BASE_ASSET balance being 1 short.

Thank you. Appreciate your help! Fixed and the tests work.

Now have additional problem on testnet network.
The code is on same branch with the latest commit.

Steps to reproduce:
Run the command from project root
./target/release/spark-cli core deposit
–asset-type base
–amount 1
–rpc “testnet.fuel.network”
–contract-id 0x495ddb1f05cda78fc26f349ace74889781943de7499ebd6cca4698284411df0e

Transaction fails with error:
Error: provider: io error: Response errors; InsufficientMaxFee { max_fee_from_policies: 28468, max_fee_from_gas_price: 28469 }

Deposit func:
pub async fn deposit(&self, amount: u64, asset: AssetId) → anyhow::Result<CallResponse<()>> {
let call_params = CallParameters::new(amount, asset, 1_000_000);
let tx_policies = TxPolicies::default()
.with_script_gas_limit(1_000_000)
.with_tip(1);

    Ok(self
        .instance
        .methods()
        .deposit()
        .with_tx_policies(tx_policies)
        .call_params(call_params)?
        .call()
        .await?)
}

Something is missed with function call?

Will share with the Rust Sdk team and will keep you posted

@dcpp You’re welcome.

We’re tracking the issue here, should be resolved in the next release.

In the meantime I suggest you set the max fee manually to avoid any flakiness:

        let tx_policies = TxPolicies::default().with_max_fee(29000);

You can also stop setting the script gas limit if you want, the estimation now includes a tolerance so any flakiness that used to be there should be gone.

Also another thing I noticed while reproducing, there are a few places where AssetId::BASE is used. This is pending removal or at least feature-gating behind a test-only flag.

The base asset is no longer guaranteed to be all zeroes. So best thing is whenever you need the base asset id you ask for it via a provider:

        let base_asset_id = provider.base_asset_id();

@segfault-magnet I 've set to let tx_policies = TxPolicies::default().with_max_fee(29000);
But it doesn’t help (( The same error:
Error: provider: io error: Response errors; InsufficientMaxFee { max_fee_from_policies: 28468, max_fee_from_gas_price: 28469 }

It probably comes from a different place (ie a different contract call), the reproduction example above passed when I was testing it yesterday.

In any case, try using 0.65.1 that was released yesterday and remove the max fee from the tx policies. Let me know how it goes.