Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional gas_price argument to dry_run_opt #1924

Merged
merged 17 commits into from
Jun 4, 2024
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
Loading