Skip to content

Commit

Permalink
Add optional gas_price argument to dry_run_opt (#1924)
Browse files Browse the repository at this point in the history
This PR adds a optional `gas_price` argument to the `dry_run` endpoint.
This is needed by the SDK to make fee estimations without setting the
`max_fee` policy.

BREAKING CHANGE:
- `dry_run_opt` has a new argument: `gas_price: Option<u64>`

## Checklist
- [x] Breaking changes are clearly marked as such in the PR description
and changelog
- [ ] New behavior is reflected in tests
- [x] [The specification](https://github.com/FuelLabs/fuel-specs/)
matches the implemented behavior (link update PR if changes are needed)

### Before requesting review
- [x] I have reviewed the code myself
- [ ] I have created follow-up issues caused by this PR and linked them
here

### After merging, notify other teams

- [x] [Rust SDK](https://github.com/FuelLabs/fuels-rs/)
- [x] [Ts SDK](https://github.com/FuelLabs/fuels-ts/)
- [ ] [Platform
documentation](https://github.com/FuelLabs/devrel-requests/issues/new?assignees=&labels=new+request&projects=&template=NEW-REQUEST.yml&title=%5BRequest%5D%3A+)
(for out-of-organization contributors, the person merging the PR will do
this)

---------

Co-authored-by: MujkicA <ahmedmujkic2@gmail.com>
Co-authored-by: segfault-magnet <ahmed.sagdati.ets@gmail.com>
Co-authored-by: Green Baneling <XgreenX9999@gmail.com>
  • Loading branch information
4 people authored Jun 4, 2024
1 parent 0463dfd commit a80261d
Show file tree
Hide file tree
Showing 12 changed files with 96 additions and 14 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]

### Changed

#### Breaking

- [#1924](https://github.com/FuelLabs/fuel-core/pull/1924): `dry_run_opt` has new `gas_price: Option<u64>` argument

### Added
- [#1929](https://github.com/FuelLabs/fuel-core/pull/1929): Added support of customization of the state transition version in the `ChainConfig`.

Expand Down
2 changes: 1 addition & 1 deletion bin/e2e-test-client/src/tests/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ async fn _dry_runs(
let query = ctx
.alice
.client
.dry_run_opt(transactions, Some(false))
.dry_run_opt(transactions, Some(false), None)
.await;
println!(
"Received the response for the query number {i} for {}ms",
Expand Down
2 changes: 1 addition & 1 deletion crates/client/assets/schema.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ type Mutation {
"""
Execute a dry-run of multiple transactions using a fork of current state, no changes are committed.
"""
dryRun(txs: [HexString!]!, utxoValidation: Boolean): [DryRunTransactionExecutionStatus!]!
dryRun(txs: [HexString!]!, utxoValidation: Boolean, gasPrice: U64): [DryRunTransactionExecutionStatus!]!
"""
Submits transaction to the `TxPool`.

Expand Down
4 changes: 3 additions & 1 deletion crates/client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ impl FuelClient {
&self,
txs: &[Transaction],
) -> io::Result<Vec<TransactionExecutionStatus>> {
self.dry_run_opt(txs, None).await
self.dry_run_opt(txs, None, None).await
}

/// Dry run with options to override the node behavior
Expand All @@ -395,6 +395,7 @@ impl FuelClient {
txs: &[Transaction],
// Disable utxo input checks (exists, unspent, and valid signature)
utxo_validation: Option<bool>,
gas_price: Option<u64>,
) -> io::Result<Vec<TransactionExecutionStatus>> {
let txs = txs
.iter()
Expand All @@ -404,6 +405,7 @@ impl FuelClient {
schema::tx::DryRun::build(DryRunArg {
txs,
utxo_validation,
gas_price: gas_price.map(|gp| gp.into()),
});
let tx_statuses = self.query(query).await.map(|r| r.dry_run)?;
tx_statuses
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
source: crates/client/src/client/schema/tx.rs
expression: query.query
---
mutation($txs: [HexString!]!, $utxoValidation: Boolean) {
dryRun(txs: $txs, utxoValidation: $utxoValidation) {
mutation($txs: [HexString!]!, $utxoValidation: Boolean, $gasPrice: U64) {
dryRun(txs: $txs, utxoValidation: $utxoValidation, gasPrice: $gasPrice) {
id
status {
__typename
Expand Down
6 changes: 4 additions & 2 deletions crates/client/src/client/schema/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ pub struct EstimatePredicates {
pub struct DryRunArg {
pub txs: Vec<HexString>,
pub utxo_validation: Option<bool>,
pub gas_price: Option<U64>,
}

#[derive(cynic::QueryFragment, Clone, Debug)]
Expand All @@ -379,7 +380,7 @@ pub struct DryRunArg {
variables = "DryRunArg"
)]
pub struct DryRun {
#[arguments(txs: $txs, utxoValidation: $utxo_validation)]
#[arguments(txs: $txs, utxoValidation: $utxo_validation, gasPrice: $gas_price)]
pub dry_run: Vec<DryRunTransactionExecutionStatus>,
}

Expand Down Expand Up @@ -467,7 +468,8 @@ pub mod tests {
let tx = fuel_tx::Transaction::default_test_tx();
let query = DryRun::build(DryRunArg {
txs: vec![HexString(Bytes(tx.to_bytes()))],
utxo_validation: None,
utxo_validation: Some(true),
gas_price: Some(123u64.into()),
});
insta::assert_snapshot!(query.query)
}
Expand Down
1 change: 1 addition & 0 deletions crates/fuel-core/src/graphql_api/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ pub trait BlockProducerPort: Send + Sync {
transactions: Vec<Transaction>,
height: Option<BlockHeight>,
utxo_validation: Option<bool>,
gas_price: Option<u64>,
) -> anyhow::Result<Vec<TransactionExecutionStatus>>;
}

Expand Down
10 changes: 9 additions & 1 deletion crates/fuel-core/src/schema/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ use types::{
Transaction,
};

use super::scalars::U64;

pub mod input;
pub mod output;
pub mod receipt;
Expand Down Expand Up @@ -247,6 +249,7 @@ impl TxMutation {
// This allows for non-existent inputs to be used without signature validation
// for read-only calls.
utxo_validation: Option<bool>,
gas_price: Option<U64>,
) -> async_graphql::Result<Vec<DryRunTransactionExecutionStatus>> {
let block_producer = ctx.data_unchecked::<BlockProducer>();
let params = ctx
Expand All @@ -262,7 +265,12 @@ impl TxMutation {
}

let tx_statuses = block_producer
.dry_run_txs(transactions, None, utxo_validation)
.dry_run_txs(
transactions,
None,
utxo_validation,
gas_price.map(|x| x.into()),
)
.await?;
let tx_statuses = tx_statuses
.into_iter()
Expand Down
3 changes: 2 additions & 1 deletion crates/fuel-core/src/service/adapters/graphql_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,10 @@ impl BlockProducerPort for BlockProducerAdapter {
transactions: Vec<Transaction>,
height: Option<BlockHeight>,
utxo_validation: Option<bool>,
gas_price: Option<u64>,
) -> anyhow::Result<Vec<TransactionExecutionStatus>> {
self.block_producer
.dry_run(transactions, height, utxo_validation)
.dry_run(transactions, height, utxo_validation, gas_price)
.await
}
}
Expand Down
6 changes: 3 additions & 3 deletions crates/services/producer/src/block_producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ where
transactions: Vec<Transaction>,
height: Option<BlockHeight>,
utxo_validation: Option<bool>,
gas_price: Option<u64>,
) -> anyhow::Result<Vec<TransactionExecutionStatus>> {
let height = height.unwrap_or_else(|| {
self.view_provider
Expand All @@ -218,9 +219,8 @@ where
.expect("It is impossible to overflow the current block height")
});

let gas_price = self
.gas_price_provider
.gas_price(height.into())
let gas_price = gas_price
.or_else(|| self.gas_price_provider.gas_price(height.into()))
.ok_or(anyhow!("No gas price found for height {height:?}"))?;

// The dry run execution should use the state of the blockchain based on the
Expand Down
62 changes: 62 additions & 0 deletions tests/tests/gas_price.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#![allow(non_snake_case)]

use crate::helpers::{
TestContext,
TestSetupBuilder,
};

use fuel_core::{
chain_config::{
CoinConfig,
Expand All @@ -22,6 +27,7 @@ use fuel_core_client::client::{
FuelClient,
};
use fuel_core_types::{
fuel_asm::*,
fuel_crypto::{
coins_bip32::ecdsa::signature::rand_core::SeedableRng,
SecretKey,
Expand All @@ -32,6 +38,7 @@ use fuel_core_types::{
TransactionBuilder,
UtxoId,
},
services::executor::TransactionExecutionResult,
};
use rand::prelude::StdRng;

Expand Down Expand Up @@ -144,3 +151,58 @@ async fn estimate_gas_price__should_be_static() {
let actual = u64::from(gas_price);
assert_eq!(expected, actual);
}

#[tokio::test]
async fn dry_run_opt_with_zero_gas_price() {
let tx = TransactionBuilder::script(
op::ret(RegId::ONE).to_bytes().into_iter().collect(),
vec![],
)
.add_random_fee_input()
.script_gas_limit(1000)
.max_fee_limit(600000)
.finalize_as_transaction();

let mut test_builder = TestSetupBuilder::new(2322u64);
test_builder.min_gas_price = 1;
let TestContext {
client,
srv: _dont_drop,
..
} = test_builder.finalize().await;

let TransactionExecutionResult::Success {
total_fee,
total_gas,
..
} = client
.dry_run_opt(&[tx.clone()], Some(false), None)
.await
.unwrap()
.pop()
.unwrap()
.result
else {
panic!("dry run should have succeeded");
};

let TransactionExecutionResult::Success {
total_fee: total_fee_zero_gas_price,
total_gas: total_gas_zero_gas_price,
..
} = client
.dry_run_opt(&[tx], Some(false), Some(0))
.await
.unwrap()
.pop()
.unwrap()
.result
else {
panic!("dry run should have succeeded");
};

assert_ne!(total_fee, total_fee_zero_gas_price);
assert_eq!(total_fee_zero_gas_price, 0);

assert_eq!(total_gas, total_gas_zero_gas_price);
}
4 changes: 2 additions & 2 deletions tests/tests/tx/utxo_validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ async fn dry_run_override_utxo_validation() {

let tx_statuses = context
.client
.dry_run_opt(&[tx], Some(false))
.dry_run_opt(&[tx], Some(false), None)
.await
.unwrap();
let log = tx_statuses
Expand Down Expand Up @@ -217,7 +217,7 @@ async fn dry_run_no_utxo_validation_override() {
let client = TestSetupBuilder::new(2322).finalize().await.client;

// verify that the client validated the inputs and failed the tx
let res = client.dry_run_opt(&[tx], None).await;
let res = client.dry_run_opt(&[tx], None, None).await;
assert!(res.is_err());
}

Expand Down

0 comments on commit a80261d

Please sign in to comment.