diff --git a/dependencies_graph.dot b/dependencies_graph.dot index a91a7edff..71e46879a 100644 --- a/dependencies_graph.dot +++ b/dependencies_graph.dot @@ -30,11 +30,11 @@ digraph { 28 [ label = "nomos-da-verifier" shape = box] 29 [ label = "nomos-storage" shape = box] 30 [ label = "nomos-mempool" shape = box] - 31 [ label = "nomos-tracing-service" shape = box] - 32 [ label = "nomos-time" shape = box] - 33 [ label = "nomos-da-dispersal" shape = box] - 34 [ label = "nomos-da-indexer" shape = box] - 35 [ label = "nomos-mantle-core" shape = box] + 31 [ label = "nomos-mantle-core" shape = box] + 32 [ label = "nomos-tracing-service" shape = box] + 33 [ label = "nomos-time" shape = box] + 34 [ label = "nomos-da-dispersal" shape = box] + 35 [ label = "nomos-da-indexer" shape = box] 36 [ label = "nomos-node" shape = box] 37 [ label = "nomos-system-sig" shape = box] 38 [ label = "executor-http-client" shape = box] @@ -50,11 +50,11 @@ digraph { 6 -> 36 [ ] 7 -> 8 [ ] 7 -> 3 [ ] - 9 -> 33 [ ] 9 -> 34 [ ] + 9 -> 35 [ ] 10 -> 11 [ ] 10 -> 30 [ ] - 10 -> 32 [ ] + 10 -> 33 [ ] 11 -> 14 [ ] 11 -> 16 [ ] 11 -> 17 [ ] @@ -83,16 +83,16 @@ digraph { 28 -> 29 [ ] 29 -> 3 [ ] 30 -> 18 [ ] + 30 -> 31 [ ] 30 -> 30 [ color = blue] 30 -> 16 [ ] - 30 -> 31 [ color = blue] - 31 -> 27 [ ] - 32 -> 0 [ ] - 33 -> 30 [ ] - 34 -> 10 [ ] - 35 -> 26 [ ] + 30 -> 32 [ color = blue] + 31 -> 26 [ ] + 32 -> 27 [ ] + 33 -> 0 [ ] + 34 -> 30 [ ] + 35 -> 10 [ ] 36 -> 9 [ ] - 36 -> 35 [ ] 36 -> 37 [ ] 38 -> 19 [ ] 40 -> 38 [ ] diff --git a/nodes/nomos-executor/executor/Cargo.toml b/nodes/nomos-executor/executor/Cargo.toml index 18d840be2..743d4a1bd 100644 --- a/nodes/nomos-executor/executor/Cargo.toml +++ b/nodes/nomos-executor/executor/Cargo.toml @@ -43,6 +43,7 @@ nomos-network = { workspace = true, features = ["libp2p"] } nomos-node = { workspace = true } nomos-storage = { workspace = true, features = ["rocksdb-backend"] } nomos-time = { workspace = true } +nomos-utils = { workspace = true } overwatch = { workspace = true } rand = "0.8" rand_chacha = "0.3" diff --git a/nodes/nomos-executor/executor/src/lib.rs b/nodes/nomos-executor/executor/src/lib.rs index d556055cc..72e0d7429 100644 --- a/nodes/nomos-executor/executor/src/lib.rs +++ b/nodes/nomos-executor/executor/src/lib.rs @@ -39,6 +39,7 @@ use nomos_node::{ NomosDaMembership, RocksBackend, SystemSig, Wire, MB16, }; use nomos_time::backends::NtpTimeBackend; +use nomos_utils::noop_service::NoService; use overwatch::derive_services; use rand_chacha::ChaCha20Rng; @@ -266,4 +267,5 @@ pub struct NomosExecutor { http: ApiService, storage: StorageService, system_sig: SystemSigService, + no_service: NoService, } diff --git a/nodes/nomos-executor/executor/src/main.rs b/nodes/nomos-executor/executor/src/main.rs index 5f649fa98..d14e20a34 100644 --- a/nodes/nomos-executor/executor/src/main.rs +++ b/nodes/nomos-executor/executor/src/main.rs @@ -82,6 +82,7 @@ async fn main() -> Result<()> { topic: String::from(CL_TOPIC), id: ::hash, }, + processor: (), recovery_path: config.mempool.cl_pool_recovery_path, }, da_mempool: DaMempoolSettings { @@ -109,6 +110,7 @@ async fn main() -> Result<()> { initial_locators_mapping: HashMap::default(), }, }, + no_service: (), }, None, ) diff --git a/nodes/nomos-node/node/Cargo.toml b/nodes/nomos-node/node/Cargo.toml index 1a28f9aa8..cdc27f25d 100644 --- a/nodes/nomos-node/node/Cargo.toml +++ b/nodes/nomos-node/node/Cargo.toml @@ -49,6 +49,7 @@ nomos-system-sig = { workspace = true } nomos-time = { workspace = true, features = ["ntp", "serde"] } nomos-tracing = { workspace = true } nomos-tracing-service = { workspace = true } +nomos-utils = { workspace = true } overwatch = { workspace = true } rand_chacha = "0.3" serde = "1" diff --git a/nodes/nomos-node/node/src/lib.rs b/nodes/nomos-node/node/src/lib.rs index 474b78f47..b453af26d 100644 --- a/nodes/nomos-node/node/src/lib.rs +++ b/nodes/nomos-node/node/src/lib.rs @@ -47,6 +47,7 @@ pub use nomos_system_sig::SystemSig; use nomos_time::backends::NtpTimeBackend; #[cfg(feature = "tracing")] pub use nomos_tracing_service::Tracing; +use nomos_utils::noop_service::NoService; use overwatch::derive_services; use rand_chacha::ChaCha20Rng; use serde::{de::DeserializeOwned, Serialize}; @@ -241,4 +242,5 @@ pub struct Nomos { http: ApiService, storage: StorageService, system_sig: SystemSigService, + no_service: NoService, } diff --git a/nodes/nomos-node/node/src/main.rs b/nodes/nomos-node/node/src/main.rs index ef96317c4..8c1c721ff 100644 --- a/nodes/nomos-node/node/src/main.rs +++ b/nodes/nomos-node/node/src/main.rs @@ -82,6 +82,7 @@ async fn main() -> Result<()> { topic: String::from(nomos_node::CL_TOPIC), id: ::hash, }, + processor: (), recovery_path: config.mempool.cl_pool_recovery_path, }, da_mempool: nomos_mempool::DaMempoolSettings { @@ -108,6 +109,7 @@ async fn main() -> Result<()> { initial_locators_mapping: HashMap::default(), }, }, + no_service: (), }, None, ) diff --git a/nomos-mantle/src/lib.rs b/nomos-mantle/src/lib.rs index 4eb92e2f8..a0460bca5 100644 --- a/nomos-mantle/src/lib.rs +++ b/nomos-mantle/src/lib.rs @@ -1,3 +1,3 @@ mod gas; -mod ops; +pub mod ops; pub mod tx; diff --git a/nomos-services/mempool/Cargo.toml b/nomos-services/mempool/Cargo.toml index 5a0237a44..ff8c193c7 100644 --- a/nomos-services/mempool/Cargo.toml +++ b/nomos-services/mempool/Cargo.toml @@ -22,7 +22,9 @@ linked-hash-map = { version = "0.5.6", optional = true, features = ["serde nomos-core = { workspace = true } nomos-da-network-core = { workspace = true } nomos-da-sampling = { workspace = true } +nomos-mantle-core = { workspace = true } nomos-network = { workspace = true } +nomos-utils = { workspace = true } overwatch = { workspace = true } rand = { version = "0.8" } serde = { version = "1.0", features = ["derive"] } diff --git a/nomos-services/mempool/src/backend/mockpool/mod.rs b/nomos-services/mempool/src/backend/mockpool/mod.rs index 3b3683f22..8965a0a2e 100644 --- a/nomos-services/mempool/src/backend/mockpool/mod.rs +++ b/nomos-services/mempool/src/backend/mockpool/mod.rs @@ -228,7 +228,7 @@ where BlockId: Ord + Copy, { type Error = Infallible; - type Settings = TxMempoolSettings<(), ()>; + type Settings = TxMempoolSettings<(), (), ()>; fn from_settings(_settings: &Self::Settings) -> Result { Ok(::new(())) diff --git a/nomos-services/mempool/src/lib.rs b/nomos-services/mempool/src/lib.rs index 0a81e7e7f..40d8bdccb 100644 --- a/nomos-services/mempool/src/lib.rs +++ b/nomos-services/mempool/src/lib.rs @@ -1,8 +1,8 @@ pub mod backend; pub mod da; pub mod network; +pub mod processor; pub mod tx; -pub mod verify; use std::fmt::{Debug, Error, Formatter}; diff --git a/nomos-services/mempool/src/processor/mod.rs b/nomos-services/mempool/src/processor/mod.rs new file mode 100644 index 000000000..f2573d39a --- /dev/null +++ b/nomos-services/mempool/src/processor/mod.rs @@ -0,0 +1,23 @@ +pub mod noop; +pub mod tx; + +use std::error::Error; + +use overwatch::services::{relay::OutboundRelay, ServiceData}; + +#[async_trait::async_trait] +pub trait PayloadProcessor { + type Payload; + type Settings; + type Error: Error; + + type DaSamplingService: ServiceData; + + fn new( + settings: Self::Settings, + outbound_relay: OutboundRelay<::Message>, + ) -> Self; + + /// Executes required procedures before adding payload to the pool. + async fn process(&self, payload: &Self::Payload) -> Result<(), Vec>; +} diff --git a/nomos-services/mempool/src/processor/noop.rs b/nomos-services/mempool/src/processor/noop.rs new file mode 100644 index 000000000..9413abfd1 --- /dev/null +++ b/nomos-services/mempool/src/processor/noop.rs @@ -0,0 +1,31 @@ +use std::{convert::Infallible, marker::PhantomData}; + +use overwatch::services::{relay::OutboundRelay, ServiceData}; + +use super::PayloadProcessor; + +pub type NoOpPayloadProcessor = PhantomData<(Service, Payload)>; + +#[async_trait::async_trait] +impl PayloadProcessor for NoOpPayloadProcessor +where + Payload: Send + Sync, + Service: ServiceData + Send + Sync, +{ + type Payload = Payload; + type Settings = (); + type Error = Infallible; + + type DaSamplingService = Service; + + fn new( + (): Self::Settings, + _: OutboundRelay<::Message>, + ) -> Self { + Self + } + + async fn process(&self, _: &Self::Payload) -> Result<(), Vec> { + Ok(()) + } +} diff --git a/nomos-services/mempool/src/processor/tx.rs b/nomos-services/mempool/src/processor/tx.rs new file mode 100644 index 000000000..75bd3780e --- /dev/null +++ b/nomos-services/mempool/src/processor/tx.rs @@ -0,0 +1,81 @@ +use std::error::Error; + +use futures::{stream::FuturesUnordered, StreamExt}; +use nomos_core::da::BlobId; +use nomos_da_sampling::DaSamplingServiceMsg; +use nomos_mantle_core::{ops::Op, tx::SignedMantleTx}; +use overwatch::services::{relay::OutboundRelay, ServiceData}; + +use super::PayloadProcessor; + +#[derive(thiserror::Error, Debug)] +pub enum SignedTxProcessorError { + #[error("Error from sampling relay {0}")] + Sampling(Box), +} + +impl SignedTxProcessorError { + fn sampling_error(err: impl Error + Send + 'static) -> Self { + Self::Sampling(Box::new(err)) + } +} + +pub struct SignedTxProcessor +where + SamplingService: ServiceData, +{ + sampling_relay: OutboundRelay<::Message>, +} + +#[async_trait::async_trait] +impl PayloadProcessor for SignedTxProcessor +where + SamplingService: ServiceData> + Send + Sync, +{ + type Payload = SignedMantleTx; + type Settings = (); + type Error = SignedTxProcessorError; + + type DaSamplingService = SamplingService; + + fn new( + (): Self::Settings, + sampling_relay: OutboundRelay<::Message>, + ) -> Self { + Self { sampling_relay } + } + + async fn process(&self, payload: &Self::Payload) -> Result<(), Vec> { + let all_futures: FuturesUnordered<_> = payload + .mantle_tx + .ops + .iter() + .filter_map(|op| { + if let Op::Blob(blob_op) = op { + Some(async { + self.sampling_relay + .send(DaSamplingServiceMsg::TriggerSampling { + blob_id: blob_op.blob, + }) + .await + .map_err(|(e, _)| SignedTxProcessorError::sampling_error(e)) + }) + } else { + None + } + }) + .collect(); + + let errors: Vec = StreamExt::collect::>(all_futures) + .await + .into_iter() + .filter_map(Result::err) + .collect(); + + if errors.is_empty() { + Ok(()) + } else { + Err(errors) + } + } +} diff --git a/nomos-services/mempool/src/tx/service.rs b/nomos-services/mempool/src/tx/service.rs index e9d6644ff..ca661c9d9 100644 --- a/nomos-services/mempool/src/tx/service.rs +++ b/nomos-services/mempool/src/tx/service.rs @@ -12,6 +12,7 @@ use std::{ use futures::StreamExt as _; use nomos_network::{message::BackendNetworkMsg, NetworkService}; +use nomos_utils::noop_service::NoService; use overwatch::{ services::{relay::OutboundRelay, AsServiceId, ServiceCore, ServiceData}, OpaqueServiceResourcesHandle, @@ -27,24 +28,34 @@ use services_utils::{ use crate::{ backend::{MemPool, RecoverableMempool}, network::NetworkAdapter as NetworkAdapterTrait, + processor::{noop::NoOpPayloadProcessor, PayloadProcessor}, tx::{settings::TxMempoolSettings, state::TxMempoolState}, MempoolMetrics, MempoolMsg, }; +type NoProcessor = NoOpPayloadProcessor; + /// A tx mempool service that uses a [`JsonFileBackend`] as a recovery /// mechanism. pub type TxMempoolService = GenericTxMempoolService< Pool, NetworkAdapter, + NoProcessor<>::Payload>, JsonFileBackend< TxMempoolState< ::RecoveryState, ::Settings, >::Settings, + >::Payload, + > as PayloadProcessor>::Settings, >, TxMempoolSettings< ::Settings, >::Settings, + >::Payload, + > as PayloadProcessor>::Settings, >, >, RuntimeServiceId, @@ -52,26 +63,35 @@ pub type TxMempoolService = GenericTxMem /// A generic tx mempool service which wraps around a mempool, a network /// adapter, and a recovery backend. -pub struct GenericTxMempoolService -where +pub struct GenericTxMempoolService< + Pool, + NetworkAdapter, + Processor, + RecoveryBackend, + RuntimeServiceId, +> where Pool: RecoverableMempool, Pool::Settings: Clone, NetworkAdapter: NetworkAdapterTrait, NetworkAdapter::Settings: Clone, + Processor: PayloadProcessor, + Processor::Settings: Clone, RecoveryBackend: RecoveryBackendTrait, { pool: Pool, service_resources_handle: OpaqueServiceResourcesHandle, - _phantom: PhantomData<(NetworkAdapter, RecoveryBackend)>, + _phantom: PhantomData<(NetworkAdapter, Processor, RecoveryBackend)>, } -impl - GenericTxMempoolService +impl + GenericTxMempoolService where Pool: RecoverableMempool, Pool::Settings: Clone, NetworkAdapter: NetworkAdapterTrait, NetworkAdapter::Settings: Clone, + Processor: PayloadProcessor, + Processor::Settings: Clone, RecoveryBackend: RecoveryBackendTrait, { pub const fn new( @@ -86,24 +106,33 @@ where } } -impl ServiceData - for GenericTxMempoolService +impl ServiceData + for GenericTxMempoolService where Pool: RecoverableMempool, Pool::Settings: Clone, NetworkAdapter: NetworkAdapterTrait, NetworkAdapter::Settings: Clone, + Processor: PayloadProcessor, + Processor::Settings: Clone, RecoveryBackend: RecoveryBackendTrait, { - type Settings = TxMempoolSettings; - type State = TxMempoolState; + type Settings = + TxMempoolSettings; + type State = TxMempoolState< + Pool::RecoveryState, + Pool::Settings, + NetworkAdapter::Settings, + Processor::Settings, + >; type StateOperator = RecoveryOperator; type Message = MempoolMsg; } #[async_trait::async_trait] -impl ServiceCore - for GenericTxMempoolService +impl + ServiceCore + for GenericTxMempoolService where Pool: RecoverableMempool + Send, Pool::RecoveryState: Debug + Send + Sync, @@ -114,6 +143,10 @@ where NetworkAdapter: NetworkAdapterTrait + Send, NetworkAdapter::Settings: Clone + Send + Sync + 'static, + Processor: PayloadProcessor + Send, + Processor::Settings: Clone + Send + Sync, + Processor::DaSamplingService: ServiceData, + <::DaSamplingService as ServiceData>::Message: Send + 'static, RecoveryBackend: RecoveryBackendTrait + Send, RuntimeServiceId: Display + Debug @@ -121,7 +154,8 @@ where + Send + 'static + AsServiceId - + AsServiceId>, + + AsServiceId> + + AsServiceId, { fn init( service_resources_handle: OpaqueServiceResourcesHandle, @@ -164,6 +198,13 @@ where .payload_stream() .await; + let sampling_relay = self + .service_resources_handle + .overwatch_handle + .relay::() + .await + .expect("Relay connection with sampling service should succeed"); + self.service_resources_handle.status_updater.notify_ready(); tracing::info!( "Service '{}' is ready.", @@ -177,16 +218,30 @@ where ) .await?; + let processor = Processor::new( + self.service_resources_handle + .settings_handle + .notifier() + .get_updated_settings() + .processor, + sampling_relay, + ); + loop { tokio::select! { // Queue for relay messages Some(relay_msg) = self.service_resources_handle.inbound_relay.recv() => { self.handle_mempool_message(relay_msg, network_service_relay.clone()); } - Some((key, item )) = network_items.next() => { - self.pool.add_item(key, item).unwrap_or_else(|e| { + Some((key, item)) = network_items.next() => { + if let Err(e) =processor.process(&item).await { + tracing::debug!("could not process item from network due to: {e:?}"); + continue; + } + if let Err(e) = self.pool.add_item(key, item) { tracing::debug!("could not add item to the pool due to: {e}"); - }); + continue; + } tracing::info!(counter.tx_mempool_pending_items = self.pool.pending_item_count()); self.service_resources_handle.state_updater.update(Some(self.pool.save().into())); } @@ -195,14 +250,16 @@ where } } -impl - GenericTxMempoolService +impl + GenericTxMempoolService where Pool: RecoverableMempool, Pool::Item: Clone + Send + 'static, Pool::Settings: Clone, NetworkAdapter: NetworkAdapterTrait + Send, NetworkAdapter::Settings: Clone + Send + 'static, + Processor: PayloadProcessor, + Processor::Settings: Clone, RecoveryBackend: RecoveryBackendTrait, RuntimeServiceId: 'static, { diff --git a/nomos-services/mempool/src/tx/settings.rs b/nomos-services/mempool/src/tx/settings.rs index afaae6652..6a2b17383 100644 --- a/nomos-services/mempool/src/tx/settings.rs +++ b/nomos-services/mempool/src/tx/settings.rs @@ -5,17 +5,19 @@ use services_utils::overwatch::recovery::backends::FileBackendSettings; /// Settings for the tx mempool service. #[derive(Clone, Debug, Default, Serialize, Deserialize)] -pub struct TxMempoolSettings { +pub struct TxMempoolSettings { /// The mempool settings. pub pool: PoolSettings, /// The network adapter settings. pub network_adapter: NetworkAdapterSettings, + /// The mempool payload processor settings. + pub processor: ProcessorSettings, /// The recovery file path, for the service's [`RecoveryOperator`]. pub recovery_path: PathBuf, } -impl FileBackendSettings - for TxMempoolSettings +impl FileBackendSettings + for TxMempoolSettings { fn recovery_file(&self) -> &PathBuf { &self.recovery_path diff --git a/nomos-services/mempool/src/tx/state.rs b/nomos-services/mempool/src/tx/state.rs index 2bfb85f7e..23b407a43 100644 --- a/nomos-services/mempool/src/tx/state.rs +++ b/nomos-services/mempool/src/tx/state.rs @@ -7,23 +7,23 @@ use crate::TxMempoolSettings; /// State that is maintained across service restarts. #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct TxMempoolState { +pub struct TxMempoolState { /// The (optional) pool snapshot. pub(crate) pool: Option, #[serde(skip)] - _phantom: PhantomData<(PoolSettings, NetworkSettings)>, + _phantom: PhantomData<(PoolSettings, NetworkSettings, ProcessorSettings)>, } -impl - TxMempoolState +impl + TxMempoolState { pub const fn pool(&self) -> Option<&PoolState> { self.pool.as_ref() } } -impl From - for TxMempoolState +impl From + for TxMempoolState { fn from(value: PoolState) -> Self { Self { @@ -33,11 +33,11 @@ impl From } } -impl ServiceState - for TxMempoolState +impl ServiceState + for TxMempoolState { type Error = Infallible; - type Settings = TxMempoolSettings; + type Settings = TxMempoolSettings; fn from_settings(_settings: &Self::Settings) -> Result { Ok(Self { diff --git a/nomos-services/mempool/src/verify/mod.rs b/nomos-services/mempool/src/verify/mod.rs deleted file mode 100644 index 6686b409f..000000000 --- a/nomos-services/mempool/src/verify/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -#[async_trait::async_trait] -pub trait MempoolVerificationProvider { - type Payload; - type Parameters; - type Settings: Clone; - - // TODO: Payload verification parameters most likely will come from another - // Overwatch service. Once it's decided, update the `new` method to require - // service relay as parameter. - fn new(settings: Self::Settings) -> Self; - - async fn get_parameters(&self, payload: &Self::Payload) -> Self::Parameters; -} diff --git a/nomos-services/mempool/tests/mock.rs b/nomos-services/mempool/tests/mock.rs index 77920ff5d..f39a886b1 100644 --- a/nomos-services/mempool/tests/mock.rs +++ b/nomos-services/mempool/tests/mock.rs @@ -10,7 +10,11 @@ use nomos_core::{ }; use nomos_mempool::{ backend::mockpool::MockPool, - network::adapters::mock::{MockAdapter, MOCK_TX_CONTENT_TOPIC}, + network::{ + adapters::mock::{MockAdapter, MOCK_TX_CONTENT_TOPIC}, + NetworkAdapter, + }, + processor::noop::NoOpPayloadProcessor, tx::{service::GenericTxMempoolService, state::TxMempoolState}, MempoolMsg, TxMempoolSettings, }; @@ -21,6 +25,7 @@ use nomos_network::{ NetworkService, }; use nomos_tracing_service::{Tracing, TracingSettings}; +use nomos_utils::noop_service::NoService; use overwatch::overwatch::OverwatchRunner; use overwatch_derive::*; use rand::distributions::{Alphanumeric, DistString as _}; @@ -29,13 +34,16 @@ use services_utils::{ traits::FromSettings as _, }; +type NoProcessor = NoOpPayloadProcessor; + type MockRecoveryBackend = JsonFileBackend< - TxMempoolState, MockTxId>, (), ()>, - TxMempoolSettings<(), ()>, + TxMempoolState, MockTxId>, (), (), ()>, + TxMempoolSettings<(), (), ()>, >; type MockMempoolService = GenericTxMempoolService< MockPool, MockTxId>, MockAdapter, + NoProcessor< as NetworkAdapter>::Payload>, MockRecoveryBackend, RuntimeServiceId, >; @@ -45,6 +53,7 @@ struct MockPoolNode { logging: Tracing, network: NetworkService, mockpool: MockMempoolService, + no_service: NoService, } fn run_with_recovery_teardown(recovery_path: &Path, run: impl Fn()) { @@ -57,6 +66,7 @@ fn get_test_random_path() -> PathBuf { } #[test] +#[expect(clippy::too_many_lines, reason = "self contained test")] fn test_mock_mempool() { let recovery_file_path = get_test_random_path(); run_with_recovery_teardown(&recovery_file_path, || { @@ -93,9 +103,11 @@ fn test_mock_mempool() { mockpool: TxMempoolSettings { pool: (), network_adapter: (), + processor: (), recovery_path: recovery_file_path.clone(), }, logging: TracingSettings::default(), + no_service: (), }; let app = OverwatchRunner::::run(settings, None) .map_err(|e| eprintln!("Error encountered: {e}")) @@ -157,6 +169,7 @@ fn test_mock_mempool() { let recovery_backend = MockRecoveryBackend::from_settings(&TxMempoolSettings { pool: (), network_adapter: (), + processor: (), recovery_path: recovery_file_path.clone(), }); let recovered_state = recovery_backend diff --git a/nomos-utils/Cargo.toml b/nomos-utils/Cargo.toml index 684b1e4d4..a14ba8454 100644 --- a/nomos-utils/Cargo.toml +++ b/nomos-utils/Cargo.toml @@ -8,8 +8,10 @@ version = "0.1.0" workspace = true [dependencies] +async-trait = "0.1" const-hex = "1" humantime = { version = "2.1", optional = true } +overwatch = { workspace = true } rand = "0.8" rand_chacha = "0.3" serde = { version = "1.0", optional = true, features = ["derive"] } diff --git a/nomos-utils/src/lib.rs b/nomos-utils/src/lib.rs index bb9a0aca1..eed0ad7af 100644 --- a/nomos-utils/src/lib.rs +++ b/nomos-utils/src/lib.rs @@ -1,5 +1,6 @@ pub mod fisheryates; pub mod math; +pub mod noop_service; #[cfg(feature = "time")] pub mod bounded_duration; diff --git a/nomos-utils/src/noop_service.rs b/nomos-utils/src/noop_service.rs new file mode 100644 index 000000000..b8a9092b8 --- /dev/null +++ b/nomos-utils/src/noop_service.rs @@ -0,0 +1,32 @@ +use overwatch::{ + services::{ + state::{NoOperator, NoState}, + AsServiceId, ServiceCore, ServiceData, + }, + OpaqueServiceResourcesHandle, +}; + +pub struct NoService; + +impl ServiceData for NoService { + type Settings = (); + type State = NoState; + type StateOperator = NoOperator; + type Message = (); +} + +#[async_trait::async_trait] +impl ServiceCore for NoService +where + RuntimeServiceId: AsServiceId, +{ + fn init( + _: OpaqueServiceResourcesHandle, + _: Self::State, + ) -> Result { + Ok(Self) + } + async fn run(self) -> Result<(), overwatch::DynError> { + Ok(()) + } +}