Skip to content

Commit

Permalink
chore(gas_price_service): refactor usage of async_trait impls to impr…
Browse files Browse the repository at this point in the history
…ove performance (#2632)

## Linked Issues/PRs
<!-- List of related issues/PRs -->
- none

## Description
<!-- List of detailed changes -->
reduces heap allocs by removing usage of `async_trait` for small types
being passed around in gas price service adapters. should improve
performance because no `Pin<Box<Future>>>` for small values which can be
efficiently allocated on the stack instead.

microbenchmarks yield performance increase of $$\approx 82.57\\% \%$$
for `get_l2_block`

makes `GasPriceProvider` sync

breaking:
consumers of the `L2BlockSource` and `GasPriceProvider` traits, which is
most likely just us at this point


## Checklist
- [x] Breaking changes are clearly marked as such in the PR description
and changelog
- [x] 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
- [x] I have created follow-up issues caused by this PR and linked them
here

### After merging, notify other teams

[Add or remove entries as needed]

- [ ] [Rust SDK](https://github.com/FuelLabs/fuels-rs/)
- [ ] [Sway compiler](https://github.com/FuelLabs/sway/)
- [ ] [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)
- [ ] Someone else?
  • Loading branch information
rymnc authored Jan 27, 2025
1 parent 75d6c5a commit 902f772
Show file tree
Hide file tree
Showing 12 changed files with 19 additions and 27 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- [2630](https://github.com/FuelLabs/fuel-core/pull/2630): Removed some noisy `tracing::info!` logs

### Fixed
- [2632](https://github.com/FuelLabs/fuel-core/pull/2632): Improved performance of certain async trait impls in the gas price service.

## [Version 0.41.4]

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,15 @@ impl<A, Height, GasPrice> FuelGasPriceProvider<A, Height, GasPrice> {
}
}

#[async_trait::async_trait]
impl<A> ProducerGasPriceProvider for FuelGasPriceProvider<A, u32, u64>
where
A: GasPriceAlgorithm + Send + Sync,
{
async fn production_gas_price(&self) -> anyhow::Result<u64> {
fn production_gas_price(&self) -> anyhow::Result<u64> {
Ok(self.algorithm.next_gas_price())
}

async fn dry_run_gas_price(&self) -> anyhow::Result<u64> {
fn dry_run_gas_price(&self) -> anyhow::Result<u64> {
let price = self.latest_gas_price.inner_next_gas_price();
Ok(price)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ use fuel_core_gas_price_service::{
};
use fuel_core_producer::block_producer::gas_price::GasPriceProvider;

#[tokio::test]
async fn production_gas_price__if_requested_block_height_is_latest_return_gas_price() {
#[test]
fn production_gas_price__if_requested_block_height_is_latest_return_gas_price() {
// given
let price = 33;
let algo = StaticAlgorithm::new(price);
let gas_price_provider = build_provider(algo.clone(), 0, price, 10);

// when
let expected_price = algo.next_gas_price();
let actual_price = gas_price_provider.production_gas_price().await.unwrap();
let actual_price = gas_price_provider.production_gas_price().unwrap();

// then
assert_eq!(expected_price, actual_price);
}

#[tokio::test]
async fn _dry_run_gas_price__calculates_correctly_based_on_percentage() {
#[test]
fn dry_run_gas_price__calculates_correctly_based_on_percentage() {
// given
let height = 123;
let price = 33;
Expand All @@ -30,7 +30,7 @@ async fn _dry_run_gas_price__calculates_correctly_based_on_percentage() {
let gas_price_provider = build_provider(algo.clone(), height, price, percentage);

// when
let actual = gas_price_provider.dry_run_gas_price().await.unwrap();
let actual = gas_price_provider.dry_run_gas_price().unwrap();

// then
let change_amount = price.saturating_mul(percentage as u64).saturating_div(100);
Expand Down
5 changes: 2 additions & 3 deletions crates/fuel-core/src/service/adapters/producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,12 @@ impl fuel_core_producer::ports::BlockProducerDatabase for OnChainIterableKeyValu
}
}

#[async_trait::async_trait]
impl GasPriceProvider for StaticGasPrice {
async fn production_gas_price(&self) -> anyhow::Result<u64> {
fn production_gas_price(&self) -> anyhow::Result<u64> {
Ok(self.gas_price)
}

async fn dry_run_gas_price(&self) -> anyhow::Result<u64> {
fn dry_run_gas_price(&self) -> anyhow::Result<u64> {
Ok(self.gas_price)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ use fuel_core_types::{
fuel_types::BlockHeight,
services::block_importer::SharedImportResult,
};
use std::future::Future;
use tokio_stream::StreamExt;

#[async_trait::async_trait]
pub trait L2BlockSource: Send + Sync {
async fn get_l2_block(&mut self) -> GasPriceResult<BlockInfo>;
fn get_l2_block(&mut self) -> impl Future<Output = GasPriceResult<BlockInfo>> + Send;
}

pub struct FuelL2BlockSource<Settings> {
Expand All @@ -46,7 +46,6 @@ impl<Settings> FuelL2BlockSource<Settings> {
}
}

#[async_trait::async_trait]
impl<Settings> L2BlockSource for FuelL2BlockSource<Settings>
where
Settings: GasPriceSettingsProvider + Send + Sync,
Expand Down
1 change: 0 additions & 1 deletion crates/services/gas_price_service/src/v0/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ mod tests {
l2_block: mpsc::Receiver<BlockInfo>,
}

#[async_trait::async_trait]
impl L2BlockSource for FakeL2BlockSource {
async fn get_l2_block(&mut self) -> GasPriceResult<BlockInfo> {
let block = self.l2_block.recv().await.unwrap();
Expand Down
1 change: 0 additions & 1 deletion crates/services/gas_price_service/src/v0/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ struct FakeL2BlockSource {
l2_block: Receiver<BlockInfo>,
}

#[async_trait::async_trait]
impl L2BlockSource for FakeL2BlockSource {
async fn get_l2_block(&mut self) -> GasPriceResult<BlockInfo> {
let block = self.l2_block.recv().await.unwrap();
Expand Down
1 change: 0 additions & 1 deletion crates/services/gas_price_service/src/v1/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,6 @@ mod tests {
l2_block: mpsc::Receiver<BlockInfo>,
}

#[async_trait::async_trait]
impl L2BlockSource for FakeL2BlockSource {
async fn get_l2_block(&mut self) -> GasPriceResult<BlockInfo> {
let block = self.l2_block.recv().await.unwrap();
Expand Down
1 change: 0 additions & 1 deletion crates/services/gas_price_service/src/v1/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ struct FakeL2BlockSource {
l2_block: Receiver<BlockInfo>,
}

#[async_trait::async_trait]
impl L2BlockSource for FakeL2BlockSource {
async fn get_l2_block(&mut self) -> GasPriceResult<BlockInfo> {
let block = self.l2_block.recv().await.unwrap();
Expand Down
2 changes: 0 additions & 2 deletions crates/services/producer/src/block_producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,14 +247,12 @@ where
async fn production_gas_price(&self) -> anyhow::Result<u64> {
self.gas_price_provider
.production_gas_price()
.await
.map_err(|e| anyhow!("No gas price found: {e:?}"))
}

async fn dry_run_gas_price(&self) -> anyhow::Result<u64> {
self.gas_price_provider
.dry_run_gas_price()
.await
.map_err(|e| anyhow!("No gas price found: {e:?}"))
}
}
Expand Down
5 changes: 2 additions & 3 deletions crates/services/producer/src/block_producer/gas_price.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use fuel_core_types::blockchain::header::ConsensusParametersVersion;
use std::sync::Arc;

#[async_trait::async_trait]
/// Interface for retrieving the gas price for a block
pub trait GasPriceProvider {
/// The gas price for all transactions in the block.
async fn production_gas_price(&self) -> anyhow::Result<u64>;
fn production_gas_price(&self) -> anyhow::Result<u64>;

async fn dry_run_gas_price(&self) -> anyhow::Result<u64>;
fn dry_run_gas_price(&self) -> anyhow::Result<u64>;
}

/// Interface for retrieving the consensus parameters.
Expand Down
5 changes: 2 additions & 3 deletions crates/services/producer/src/block_producer/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,13 @@ impl MockProducerGasPrice {
}
}

#[async_trait::async_trait]
impl GasPriceProvider for MockProducerGasPrice {
async fn production_gas_price(&self) -> anyhow::Result<u64> {
fn production_gas_price(&self) -> anyhow::Result<u64> {
self.gas_price
.ok_or_else(|| anyhow::anyhow!("Gas price not provided"))
}

async fn dry_run_gas_price(&self) -> anyhow::Result<u64> {
fn dry_run_gas_price(&self) -> anyhow::Result<u64> {
self.gas_price
.ok_or_else(|| anyhow::anyhow!("Gas price not provided"))
}
Expand Down

0 comments on commit 902f772

Please sign in to comment.