diff --git a/crates/services/gas_price_service/src/v0/service.rs b/crates/services/gas_price_service/src/v0/service.rs index 67e3f19a5d3..ed73b03063d 100644 --- a/crates/services/gas_price_service/src/v0/service.rs +++ b/crates/services/gas_price_service/src/v0/service.rs @@ -1,19 +1,11 @@ use crate::{ common::{ - gas_price_algorithm::SharedGasPriceAlgo, l2_block_source::L2BlockSource, updater_metadata::UpdaterMetadata, - utils::{ - BlockInfo, - Error as GasPriceError, - Result as GasPriceResult, - }, + utils::BlockInfo, }, ports::MetadataStorage, - v0::{ - metadata::V0Metadata, - uninitialized_task::SharedV0Algorithm, - }, + v0::uninitialized_task::SharedV0Algorithm, }; use anyhow::anyhow; use async_trait::async_trait; @@ -48,48 +40,15 @@ where pub fn new( l2_block_source: L2, metadata_storage: Metadata, - starting_metadata: V0Metadata, - ) -> GasPriceResult { - let V0Metadata { - min_exec_gas_price, - exec_gas_price_change_percent, - new_exec_price, - l2_block_fullness_threshold_percent, - l2_block_height, - } = starting_metadata; - - let algorithm_updater; - if let Some(old_metadata) = metadata_storage - .get_metadata(&l2_block_height.into()) - .map_err(|err| GasPriceError::CouldNotInitUpdater(anyhow::anyhow!(err)))? - { - algorithm_updater = match old_metadata { - UpdaterMetadata::V0(old) => AlgorithmUpdaterV0::new( - old.new_exec_price, - min_exec_gas_price, - exec_gas_price_change_percent, - old.l2_block_height, - l2_block_fullness_threshold_percent, - ), - }; - } else { - algorithm_updater = AlgorithmUpdaterV0::new( - new_exec_price, - min_exec_gas_price, - exec_gas_price_change_percent, - l2_block_height, - l2_block_fullness_threshold_percent, - ); - } - - let shared_algo = - SharedGasPriceAlgo::new_with_algorithm(algorithm_updater.algorithm()); - Ok(Self { + shared_algo: SharedV0Algorithm, + algorithm_updater: AlgorithmUpdaterV0, + ) -> Self { + Self { shared_algo, l2_block_source, metadata_storage, algorithm_updater, - }) + } } pub fn algorithm_updater(&self) -> &AlgorithmUpdaterV0 { @@ -235,6 +194,7 @@ mod tests { v0::{ metadata::V0Metadata, service::GasPriceServiceV0, + uninitialized_task::initialize_algorithm, }, }; use fuel_core_services::{ @@ -305,10 +265,15 @@ mod tests { l2_block_fullness_threshold_percent: 0, l2_block_height: 0, }; + let (algo_updater, shared_algo) = + initialize_algorithm(starting_metadata.clone(), &metadata_storage).unwrap(); - let service = - GasPriceServiceV0::new(l2_block_source, metadata_storage, starting_metadata) - .unwrap(); + let service = GasPriceServiceV0::new( + l2_block_source, + metadata_storage, + shared_algo, + algo_updater, + ); let read_algo = service.next_block_algorithm(); let service = ServiceRunner::new(service); let prev = read_algo.next_gas_price().await; diff --git a/crates/services/gas_price_service/src/v0/tests.rs b/crates/services/gas_price_service/src/v0/tests.rs index e3d956fe37b..7385ead94bc 100644 --- a/crates/services/gas_price_service/src/v0/tests.rs +++ b/crates/services/gas_price_service/src/v0/tests.rs @@ -14,6 +14,7 @@ use crate::{ v0::{ metadata::V0Metadata, service::GasPriceServiceV0, + uninitialized_task::initialize_algorithm, }, }; use anyhow::anyhow; @@ -129,10 +130,14 @@ async fn next_gas_price__affected_by_new_l2_block() { let metadata_storage = FakeMetadata::empty(); let starting_metadata = arb_metadata(); - let service = - GasPriceServiceV0::new(l2_block_source, metadata_storage, starting_metadata) - .unwrap(); - + let (algo_updater, shared_algo) = + initialize_algorithm(starting_metadata.clone(), &metadata_storage).unwrap(); + let service = GasPriceServiceV0::new( + l2_block_source, + metadata_storage, + shared_algo, + algo_updater, + ); let service = ServiceRunner::new(service); let shared = service.shared.clone(); let initial = shared.next_gas_price().await; @@ -166,10 +171,15 @@ async fn next__new_l2_block_saves_old_metadata() { }; let starting_metadata = arb_metadata(); + let (algo_updater, shared_algo) = + initialize_algorithm(starting_metadata.clone(), &metadata_storage).unwrap(); - let service = - GasPriceServiceV0::new(l2_block_source, metadata_storage, starting_metadata) - .unwrap(); + let service = GasPriceServiceV0::new( + l2_block_source, + metadata_storage, + shared_algo, + algo_updater, + ); // when let service = ServiceRunner::new(service); @@ -205,10 +215,16 @@ async fn new__if_exists_already_reload_old_values_with_overrides() { min_exec_gas_price: new_min_exec_gas_price, l2_block_height: original.l2_block_height().into(), }; + let (algo_updater, shared_algo) = + initialize_algorithm(new_metadata, &metadata_storage).unwrap(); // when - let service = - GasPriceServiceV0::new(l2_block_source, metadata_storage, new_metadata).unwrap(); + let service = GasPriceServiceV0::new( + l2_block_source, + metadata_storage, + shared_algo, + algo_updater, + ); // then let expected = original; @@ -217,14 +233,13 @@ async fn new__if_exists_already_reload_old_values_with_overrides() { } #[tokio::test] -async fn new__if_couldnt_fetch_metadata_should_fail() { +async fn initialize_algorithm__should_fail_if_cannot_fetch_metadata() { // given let metadata_storage = ErroringMetadata; - let l2_block_source = PendingL2BlockSource; // when let metadata = different_arb_metadata(); - let res = GasPriceServiceV0::new(l2_block_source, metadata_storage, metadata); + let res = initialize_algorithm(metadata, &metadata_storage); // then assert!(matches!(res, Err(GasPriceError::CouldNotInitUpdater(_)))); diff --git a/crates/services/gas_price_service/src/v0/uninitialized_task.rs b/crates/services/gas_price_service/src/v0/uninitialized_task.rs index 02d0a3eea20..3025c1d8c9b 100644 --- a/crates/services/gas_price_service/src/v0/uninitialized_task.rs +++ b/crates/services/gas_price_service/src/v0/uninitialized_task.rs @@ -9,7 +9,11 @@ use crate::{ gas_price_algorithm::SharedGasPriceAlgo, l2_block_source::FuelL2BlockSource, updater_metadata::UpdaterMetadata, - utils::BlockInfo, + utils::{ + BlockInfo, + Error as GasPriceError, + Result as GasPriceResult, + }, }, ports::{ GasPriceData, @@ -24,7 +28,9 @@ use crate::{ }; use fuel_core_services::{ stream::BoxStream, + RunnableService, ServiceRunner, + StateWatcher, }; use fuel_core_storage::{ kv_store::KeyValueInspect, @@ -45,13 +51,16 @@ pub use fuel_gas_price_algorithm::v0::AlgorithmV0; pub type SharedV0Algorithm = SharedGasPriceAlgo; -struct UninitializedTask { +pub struct UninitializedTask { pub config: GasPriceServiceConfig, pub genesis_block_height: BlockHeight, pub settings: SettingsProvider, pub gas_price_db: GasPriceStore, pub on_chain_db: L2DataStoreView, pub block_stream: BoxStream, + shared_algo: SharedV0Algorithm, + algo_updater: AlgorithmUpdaterV0, + metadata_storage: StructuredStorage, } fn get_default_metadata( @@ -72,7 +81,8 @@ impl where L2DataStore: L2Data, L2DataStoreView: AtomicView, - GasPriceStore: GasPriceData + Modifiable + KeyValueInspect, + GasPriceStore: + GasPriceData + Modifiable + KeyValueInspect + Clone, SettingsProvider: GasPriceSettingsProvider, { pub fn new( @@ -83,6 +93,19 @@ where gas_price_db: GasPriceStore, on_chain_db: L2DataStoreView, ) -> anyhow::Result { + let latest_block_height: u32 = on_chain_db + .latest_view()? + .latest_height() + .unwrap_or(genesis_block_height) + .into(); + + let metadata_storage = StructuredStorage::new(gas_price_db.clone()); + + let (algo_updater, shared_algo) = initialize_algorithm( + get_default_metadata(&config, latest_block_height), + &metadata_storage, + )?; + let task = Self { config, genesis_block_height, @@ -90,12 +113,15 @@ where gas_price_db, on_chain_db, block_stream, + algo_updater, + shared_algo, + metadata_storage, }; Ok(task) } pub fn init( - self, + mut self, ) -> anyhow::Result< GasPriceServiceV0< FuelL2BlockSource, @@ -124,22 +150,21 @@ where self.block_stream, ); - let mut metadata_storage = StructuredStorage::new(self.gas_price_db); - if BlockHeight::from(latest_block_height) == self.genesis_block_height || first_run { let service = GasPriceServiceV0::new( l2_block_source, - metadata_storage, - get_default_metadata(&self.config, latest_block_height), - )?; + self.metadata_storage, + self.shared_algo, + self.algo_updater, + ); Ok(service) } else { if latest_block_height > metadata_height { sync_gas_price_db_with_on_chain_storage( &self.settings, - &mut metadata_storage, + &mut self.metadata_storage, &self.on_chain_db, metadata_height, latest_block_height, @@ -148,14 +173,91 @@ where let service = GasPriceServiceV0::new( l2_block_source, - metadata_storage, - get_default_metadata(&self.config, latest_block_height), - )?; + self.metadata_storage, + self.shared_algo, + self.algo_updater, + ); Ok(service) } } } +#[async_trait::async_trait] +impl RunnableService + for UninitializedTask +where + L2DataStore: L2Data, + L2DataStoreView: AtomicView, + GasPriceStore: + GasPriceData + Modifiable + KeyValueInspect + Clone, + SettingsProvider: GasPriceSettingsProvider, +{ + const NAME: &'static str = "UninitializedGasPriceServiceV0"; + type SharedData = SharedV0Algorithm; + type Task = GasPriceServiceV0< + FuelL2BlockSource, + StructuredStorage, + >; + type TaskParams = (); + + fn shared_data(&self) -> Self::SharedData { + self.shared_algo.clone() + } + + async fn into_task( + self, + _state_watcher: &StateWatcher, + _params: Self::TaskParams, + ) -> anyhow::Result { + UninitializedTask::init(self) + } +} + +pub fn initialize_algorithm( + starting_metadata: V0Metadata, + metadata_storage: &Metadata, +) -> GasPriceResult<(AlgorithmUpdaterV0, SharedV0Algorithm)> +where + Metadata: MetadataStorage, +{ + let V0Metadata { + min_exec_gas_price, + exec_gas_price_change_percent, + new_exec_price, + l2_block_fullness_threshold_percent, + l2_block_height, + } = starting_metadata; + + let algorithm_updater; + if let Some(old_metadata) = metadata_storage + .get_metadata(&l2_block_height.into()) + .map_err(|err| GasPriceError::CouldNotInitUpdater(anyhow::anyhow!(err)))? + { + algorithm_updater = match old_metadata { + UpdaterMetadata::V0(old) => AlgorithmUpdaterV0::new( + old.new_exec_price, + min_exec_gas_price, + exec_gas_price_change_percent, + old.l2_block_height, + l2_block_fullness_threshold_percent, + ), + }; + } else { + algorithm_updater = AlgorithmUpdaterV0::new( + new_exec_price, + min_exec_gas_price, + exec_gas_price_change_percent, + l2_block_height, + l2_block_fullness_threshold_percent, + ); + } + + let shared_algo = + SharedGasPriceAlgo::new_with_algorithm(algorithm_updater.algorithm()); + + Ok((algorithm_updater, shared_algo)) +} + fn sync_gas_price_db_with_on_chain_storage< L2DataStore, L2DataStoreView, @@ -251,17 +353,13 @@ pub fn new_gas_price_service_v0< gas_price_db: GasPriceStore, on_chain_db: L2DataStoreView, ) -> anyhow::Result< - ServiceRunner< - GasPriceServiceV0< - FuelL2BlockSource, - StructuredStorage, - >, - >, + ServiceRunner>, > where L2DataStore: L2Data, L2DataStoreView: AtomicView, - GasPriceStore: GasPriceData + Modifiable + KeyValueInspect, + GasPriceStore: + GasPriceData + Modifiable + KeyValueInspect + Clone, SettingsProvider: GasPriceSettingsProvider, { let gas_price_init = UninitializedTask::new( @@ -272,6 +370,5 @@ where gas_price_db, on_chain_db, )?; - let gas_price_service_v0 = gas_price_init.init()?; - Ok(ServiceRunner::new(gas_price_service_v0)) + Ok(ServiceRunner::new(gas_price_init)) }