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