-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement gas price updater for service (#1972)
Part of: #1955 The updater has two ports it owns: - `L2BlockSource` - `MetadataStorage` `L2BlockSource` is for getting the latest block as they are committed and using that to update the gas price algorithm. `MetadataStorage` is for maintaining the state of the updater in the case the service shuts down or needs to be restarted. For now it just naively stores the `AlgorithmUpdaterV1`, and just the most recent version. I don't know if we need to consider storing older versions of it for the scenario we need to roll back the chain. I started adding the DA Record stuff, but we're not using it so we can YAGNI it for now, otherwise it would just be implementing a bunch of adapters that don't do anything. This implements the service without any live adapters for the ports. Will follow this up with another PR that actually implements the ports. ## Checklist - [ ] Breaking changes are clearly marked as such in the PR description and changelog - [x] New behavior is reflected in tests - [ ] [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 [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? --------- Co-authored-by: human <[email protected]> Co-authored-by: Green Baneling <[email protected]>
- Loading branch information
1 parent
f5ac3a4
commit ac65224
Showing
8 changed files
with
383 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
137 changes: 137 additions & 0 deletions
137
crates/services/gas_price_service/src/fuel_gas_price_updater.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
use crate::UpdateAlgorithm; | ||
use fuel_core_types::fuel_types::BlockHeight; | ||
use fuel_gas_price_algorithm::{ | ||
AlgorithmUpdaterV1, | ||
AlgorithmV1, | ||
RecordedBlock, | ||
}; | ||
|
||
#[cfg(test)] | ||
mod tests; | ||
|
||
pub struct FuelGasPriceUpdater<L2, Metadata> { | ||
inner: AlgorithmUpdaterV1, | ||
l2_block_source: L2, | ||
metadata_storage: Metadata, | ||
} | ||
|
||
#[derive(Debug, thiserror::Error)] | ||
pub enum Error { | ||
#[error("Failed to find L2 block at height {block_height:?}: {source_error:?}")] | ||
CouldNotFetchL2Block { | ||
block_height: BlockHeight, | ||
source_error: anyhow::Error, | ||
}, | ||
#[error("Failed to find DA records: {0:?}")] | ||
CouldNotFetchDARecord(anyhow::Error), | ||
} | ||
|
||
type Result<T> = std::result::Result<T, Error>; | ||
|
||
// Info required about the l2 block for the gas price algorithm | ||
#[derive(Debug, Clone)] | ||
pub struct BlockInfo { | ||
// Block height | ||
pub height: u32, | ||
// Fullness of block gas usage vs max block gas | ||
pub fullness: (u64, u64), | ||
// Block size in bytes | ||
pub block_bytes: u64, | ||
// Gas price of the block | ||
pub gas_price: u64, | ||
} | ||
#[async_trait::async_trait] | ||
pub trait L2BlockSource: Send + Sync { | ||
async fn get_l2_block(&self, height: BlockHeight) -> Result<BlockInfo>; | ||
} | ||
|
||
#[async_trait::async_trait] | ||
pub trait DARecordSource: Send + Sync { | ||
async fn get_da_record(&self) -> Result<Vec<RecordedBlock>>; | ||
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub enum UpdaterMetadata { | ||
V1(AlgorithmUpdaterV1), | ||
} | ||
|
||
impl From<UpdaterMetadata> for AlgorithmUpdaterV1 { | ||
fn from(metadata: UpdaterMetadata) -> Self { | ||
match metadata { | ||
UpdaterMetadata::V1(v1) => v1, | ||
} | ||
} | ||
} | ||
|
||
impl From<AlgorithmUpdaterV1> for UpdaterMetadata { | ||
fn from(v1: AlgorithmUpdaterV1) -> Self { | ||
UpdaterMetadata::V1(v1) | ||
} | ||
} | ||
|
||
#[async_trait::async_trait] | ||
pub trait MetadataStorage: Send + Sync { | ||
async fn get_metadata(&self) -> Result<Option<UpdaterMetadata>>; | ||
async fn set_metadata(&self, metadata: UpdaterMetadata) -> Result<()>; | ||
} | ||
|
||
impl<L2, Metadata> FuelGasPriceUpdater<L2, Metadata> | ||
where | ||
Metadata: MetadataStorage, | ||
{ | ||
pub async fn init( | ||
init_metadata: UpdaterMetadata, | ||
l2_block_source: L2, | ||
metadata_storage: Metadata, | ||
) -> Result<Self> { | ||
let inner = metadata_storage | ||
.get_metadata() | ||
.await? | ||
.unwrap_or(init_metadata) | ||
.into(); | ||
let updater = Self { | ||
inner, | ||
l2_block_source, | ||
metadata_storage, | ||
}; | ||
Ok(updater) | ||
} | ||
} | ||
|
||
#[async_trait::async_trait] | ||
impl<L2, Metadata> UpdateAlgorithm for FuelGasPriceUpdater<L2, Metadata> | ||
where | ||
L2: L2BlockSource, | ||
Metadata: MetadataStorage + Send + Sync, | ||
{ | ||
type Algorithm = AlgorithmV1; | ||
|
||
fn start(&self, _for_block: BlockHeight) -> Self::Algorithm { | ||
self.inner.algorithm() | ||
} | ||
|
||
async fn next(&mut self) -> anyhow::Result<Self::Algorithm> { | ||
tokio::select! { | ||
l2_block = self.l2_block_source.get_l2_block(self.inner.l2_block_height.into()) => { | ||
tracing::info!("Received L2 block: {:?}", l2_block); | ||
let l2_block = l2_block?; | ||
let BlockInfo { | ||
height, | ||
fullness, | ||
block_bytes, | ||
gas_price, | ||
} = l2_block; | ||
self.inner.update_l2_block_data( | ||
height, | ||
fullness, | ||
block_bytes, | ||
gas_price, | ||
)?; | ||
self.metadata_storage | ||
.set_metadata(self.inner.clone().into()) | ||
.await?; | ||
Ok(self.inner.algorithm()) | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.