Skip to main content

hashiverse_lib/tools/
runtime_services.rs

1//! # Shared environment bundle for all protocol participants
2//!
3//! One struct — [`RuntimeServices`] — wraps every environment-dependent trait object
4//! that a client or server needs to participate in the protocol: the clock
5//! ([`TimeProvider`]), the network ([`TransportFactory`]), and the PoW engine
6//! ([`ParallelPowGenerator`]).
7//!
8//! Every layer of the crate takes its dependencies through a shared
9//! `Arc<RuntimeServices>` instead of reaching for concrete implementations directly.
10//! This is the seam that makes the in-memory integration tests work: swap the
11//! `TransportFactory` for [`MemTransportFactory`], the `TimeProvider` for a virtual
12//! clock, the `ParallelPowGenerator` for [`StubParallelPowGenerator`], and an entire
13//! hashiverse network can run deterministically inside a single test binary.
14
15use crate::tools::parallel_pow_generator::{ParallelPowGenerator, StubParallelPowGenerator};
16use crate::tools::time_provider::time_provider::{RealTimeProvider, TimeProvider};
17use crate::transport::transport::TransportFactory;
18use std::sync::Arc;
19use crate::transport::mem_transport::MemTransportFactory;
20
21/// The bundle of environment-dependent services that both clients and servers need to
22/// participate in the protocol.
23///
24/// Every layer of the crate — transport, protocol, client, server — takes its dependencies
25/// through a shared `RuntimeServices` rather than reaching out to concrete clock /
26/// network / PoW implementations directly. This is the seam that makes the in-memory
27/// integration tests possible: swap [`TransportFactory`] for an in-memory one, [`TimeProvider`]
28/// for a virtual clock, and [`ParallelPowGenerator`] for a single-threaded stub, and an entire
29/// hashiverse network can run deterministically inside a single test binary.
30///
31/// In production, [`crate::client::hashiverse_client::HashiverseClient`] and the server
32/// binary each construct a `RuntimeServices` with the real implementations of these traits
33/// and pass the same `Arc<RuntimeServices>` down through every constructor that needs it.
34#[derive(Clone)]
35pub struct RuntimeServices {
36    pub time_provider: Arc<dyn TimeProvider>,
37    pub transport_factory: Arc<dyn TransportFactory>,
38    pub pow_generator: Arc<dyn ParallelPowGenerator>,
39}
40
41impl RuntimeServices {
42    pub fn default_for_testing() -> Arc<Self> {
43        Arc::new(RuntimeServices {
44            time_provider: Arc::new(RealTimeProvider::default()),
45            transport_factory: MemTransportFactory::default(),
46            pow_generator: Arc::new(StubParallelPowGenerator::new()),
47        })
48    }
49}