Validation Error (Insufficient Fee Amount) during predicate call

Validation Error (Insufficient Fee Amount) during predicate call

Hello guys! In continuing to rewrite spark predicate-based CLOB on the fuel testnet beta4 toolchain I ran into a new problem:

Our predicate test that worked on the beta3 version of testnet now crashes at the point of canceling or fulfilling an order. For example, in the case of filling an order, the predicate just checks if it can authorize this transaction, while intups and outputs are set by the taker on the client side. The following code generates the order fulfillment transaction:

   pub async fn fulfill_order(
        wallet: &WalletUnlocked,
        predicate: &Predicate,
        owner_address: &Bech32Address,
        asset0: AssetId,
        amount0: u64,
        asset1: AssetId,
        amount1: u64,
    ) -> Result<FuelCallResponse<()>, fuels::prelude::Error> {
        let provider = wallet.provider().unwrap();

        let mut inputs = vec![];
        // let balance = predicate.get_asset_balance(&asset0).await.unwrap_or(0);
        let mut inputs_predicate = predicate
            .clone()
            .set_provider(provider.clone())
            .get_asset_inputs_for_amount(asset0, 1, None)
            .await
            .unwrap();
        inputs.append(&mut inputs_predicate);
        let mut inputs_from_taker = wallet
            .get_asset_inputs_for_amount(asset1, amount1, None)
            .await
            .unwrap();
        inputs.append(&mut inputs_from_taker);

        // Output for the asked coin transferred from the taker to the receiver
        let mut outputs = vec![];
        let mut output_to_maker =
            wallet.get_asset_outputs_for_amount(owner_address, asset1, amount1);
        outputs.append(&mut output_to_maker);

        // Output for the offered coin transferred from the predicate to the order taker
        let mut output_to_taker =
            predicate.get_asset_outputs_for_amount(wallet.address(), asset0, amount0);
        outputs.append(&mut output_to_taker);

        let script_call = ScriptCallHandler::new(
            vec![],
            UnresolvedBytes::default(),
            wallet.clone(),
            provider.clone(),
            Default::default(),
        )
        .with_inputs(inputs)
        .with_outputs(outputs)
        .tx_params(TxParameters::default().set_gas_price(1));

        script_call.call().await // ⚠️ the code fails here
    }

The error:

The test crashes with an error on line script_call.call().await with the error 'error in build: ValidationError(InsufficientFeeAmount { expected: 1, provided: 0 })'

Full test call output (without composability labs sign)

>>> cargo test --package spark_sdk --test tests -- local_tests::cancel_order_test::cancel_order_test --exact --nocapture
    Finished test [unoptimized + debuginfo] target(s) in 0.59s
     Running tests/harness.rs (target/debug/deps/tests-d74b2c3608147c5f)

running 1 test
                                                                   
🏁 Fulfill Order Test 🏁 

admin_address = 0x09c0b2d1a486c439a87bcba6b46a7a1a23f3897cc83a94521a96da5c23bc58db
alice_address = 0x5d99ee966b42cd8fc7bdd1364b389153a9e78b42b7d4a691470674e817888d4e
bob_address = 0xbdaad6a89e073e177895b3e5a9ccd15806749eda134a6438dae32fc5b6601f3f

USDC AssetId (asset0) = 0x4984a80a2b1462ad5c4660179be1218830f0bc190acdc7d7ef1474f8e08b768c
UNI AssetId (asset1) = 0x3c09e86c28d183421aad14384525541825c46054022884e01d88e6ff1a4ae1ef
amount0 = 1000 USDC
amount1 = 200 UNI
Price = 200000000 UNI/USDC
Alice minting 1000 USDC
Bob minting 200 UNI

Predicate root = Bech32Address { hrp: "fuel", hash: abe0c10302c5cb6d64cc08a2a280f7c17edce7a2341f6970f0242affbf6d494a }

proxyAddress = "0x85209e12d0b17845da69c43ff885f7a59f42af427cbe4beb35452b6c7412fe11"
Alice transfers 1000 USDC to predicate

thread 'local_tests::fulfill_order_test::fulfill_order_test' panicked at 'error in build: ValidationError(InsufficientFeeAmount { expected: 1, provided: 0 })', /Users/alexey/.cargo/registry/src/index.crates.io-6f17d22bba15001f/fuels-core-0.47.0/src/types/transaction_builders.rs:226:1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
test local_tests::fulfill_order_test::fulfill_order_test ... FAILED

failures:

failures:
    local_tests::fulfill_order_test::fulfill_order_test

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.63s

error: test failed, to rerun pass `-p spark_sdk --test tests`

How to reproduce the problem

git clone https://github.com/compolabs/spark-rs.git  
cd spark-rs   
git checkout beta-4  
cd limit-order-predicate  && forc build  && cd ..
cd proxy-contract && forc build  && cd ..
cargo test --package spark_sdk --test tests -- local_tests::fulfill_order_test::fulfill_order_test --exact --nocapture

Toolchain

Default host: aarch64-apple-darwin
fuelup home: /Users/alexey/.fuelup

installed toolchains
--------------------
beta-3-aarch64-apple-darwin
beta-4-rc.2-aarch64-apple-darwin
latest-aarch64-apple-darwin (default)
hotfix
my-custom-toolchain

active toolchain
-----------------
latest-aarch64-apple-darwin (default)
  forc : 0.44.1
    - forc-client
      - forc-deploy : 0.44.1
      - forc-run : 0.44.1
    - forc-doc : 0.44.1
    - forc-explore : 0.28.1
    - forc-fmt : 0.44.1
    - forc-index : 0.20.7
    - forc-lsp : 0.44.1
    - forc-tx : 0.44.1
    - forc-wallet : 0.3.0
  fuel-core : 0.20.4
  fuel-core-keygen : Error getting version string
  fuel-indexer : 0.20.7

fuels versions
---------------
forc : 0.45
forc-wallet : 0.45

Not sure if this is the root of your problem, but your beta-4 branch still seems to connect to the beta-3 network:

Bro, the testnet tests are commented and still on fuels-rs v0.41.1, I gonna fix it state after local tests that work on local node

Check how I running the test with the error

cargo test --package spark_sdk --test tests -- local_tests::fulfill_order_test::fulfill_order_test --exact --nocapture

Right now I rewrite only local_tests::fulfill_order_test, local_tests::cancel_order_test and local_tests::create_order_test

I will rewrite next local_tests::partial_fulfill_order_test, local_tests::recreate_order_test and all testnet tests

@fuel

Cannot recreate following the given steps.

Getting the following error:

thread 'local_tests::fulfill_order_test::fulfill_order_test' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidData("file 'tests/artefacts/factory/token-factory.bin' does not exist")', ...

It would seem I’m missing the token-factory.bin file.

My bad, this file has been on gitigniore, try again please

@fuel We’re pretty sure this is a regression with fuels-rs v0.47.0. We’re working on confirming and solving the issue.

In the meantime, you can implement a workaround.

The issue is with our estimation mechanisms when using predicates – in order to circumvent it we have to have some gas present in inputs before we run call() on the ScriptCallHandler

A simple workaround for your case would be:

  1. Change init_wallets so that each wallet gets more than 1 coin. Set it to at least 2:
pub async fn init_wallets() -> Vec<WalletUnlocked> {
    let config = WalletsConfig::new(Some(5), Some(2), Some(1_000_000_000));
    launch_custom_provider_and_get_wallets(config, None, None).await
}
  1. Add enough base asset to inputs and add the change output:
// in `fulfill_order`
        let base_asset = wallet
            .get_asset_inputs_for_amount(BASE_ASSET_ID, 10)
            .await?;
        inputs.extend(base_asset);

        let change = Output::change(wallet.address().into(), 0, BASE_ASSET_ID);
        outputs.push(change);

        let script_call = ScriptCallHandler::new(
            vec![],
            UnresolvedBytes::default(),
            wallet.clone(),
            provider.clone(),
            Default::default(),
        )
        .with_inputs(inputs)
        .with_outputs(outputs)

Your test should now pass. We’ll work on a fix asap.

1 Like

Hi there!

You can follow up the fix here. :palm_tree:

This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.