Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reorganize signer dependencies #1908

Merged
merged 14 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mithril-signer/benches/mktree_store_sqlite.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use mithril_common::crypto_helper::{MKTree, MKTreeNode};
use mithril_signer::MKTreeStoreSqlite;
use mithril_signer::store::MKTreeStoreSqlite;

// Shortcuts for magnitudes: K for thousand, M for million
const K: usize = 1_000;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use mithril_common::entities::{
use mithril_common::StdResult;
use mithril_persistence::database::repository::CardanoTransactionRepository;

use crate::{HighestTransactionBlockNumberGetter, TransactionPruner, TransactionStore};
use crate::services::{HighestTransactionBlockNumberGetter, TransactionPruner, TransactionStore};

#[async_trait]
impl TransactionStore for CardanoTransactionRepository {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,78 +1,71 @@
use std::fs;
use std::sync::Arc;
use std::time::Duration;

use anyhow::{anyhow, Context};
use async_trait::async_trait;
use std::{fs, sync::Arc, time::Duration};
use tokio::sync::Mutex;

use mithril_common::{
api_version::APIVersionProvider,
cardano_block_scanner::CardanoBlockScanner,
cardano_transactions_preloader::CardanoTransactionsPreloader,
chain_observer::{CardanoCliRunner, ChainObserver, ChainObserverBuilder, ChainObserverType},
chain_reader::PallasChainReader,
crypto_helper::{OpCert, ProtocolPartyId, SerDeShelleyFileFormat},
digesters::{
cache::{ImmutableFileDigestCacheProvider, JsonImmutableFileDigestCacheProviderBuilder},
CardanoImmutableDigester, ImmutableDigester, ImmutableFileObserver,
ImmutableFileSystemObserver,
},
era::{EraChecker, EraReader},
signable_builder::{
CardanoImmutableFilesFullSignableBuilder, CardanoStakeDistributionSignableBuilder,
CardanoTransactionsSignableBuilder, MithrilSignableBuilderService,
MithrilStakeDistributionSignableBuilder, SignableBuilderService,
},
signed_entity_type_lock::SignedEntityTypeLock,
MithrilTickerService, StdResult, TickerService,
use mithril_common::api_version::APIVersionProvider;
use mithril_common::cardano_block_scanner::CardanoBlockScanner;
use mithril_common::cardano_transactions_preloader::CardanoTransactionsPreloader;
use mithril_common::chain_observer::{
CardanoCliRunner, ChainObserver, ChainObserverBuilder, ChainObserverType,
};
use mithril_common::chain_reader::PallasChainReader;
use mithril_common::crypto_helper::{OpCert, ProtocolPartyId, SerDeShelleyFileFormat};
use mithril_common::digesters::cache::{
ImmutableFileDigestCacheProvider, JsonImmutableFileDigestCacheProviderBuilder,
};
use mithril_persistence::{
database::{repository::CardanoTransactionRepository, ApplicationNodeType, SqlMigration},
sqlite::{ConnectionBuilder, SqliteConnection, SqliteConnectionPool},
store::{adapter::SQLiteAdapter, StakeStore},
use mithril_common::digesters::{
CardanoImmutableDigester, ImmutableFileObserver, ImmutableFileSystemObserver,
};
use mithril_common::era::{EraChecker, EraReader};
use mithril_common::signable_builder::{
CardanoImmutableFilesFullSignableBuilder, CardanoStakeDistributionSignableBuilder,
CardanoTransactionsSignableBuilder, MithrilSignableBuilderService,
MithrilStakeDistributionSignableBuilder,
};
use mithril_common::signed_entity_type_lock::SignedEntityTypeLock;
use mithril_common::{MithrilTickerService, StdResult, TickerService};

use crate::{
aggregator_client::AggregatorClient, metrics::MetricsService, single_signer::SingleSigner,
use mithril_persistence::database::repository::CardanoTransactionRepository;
use mithril_persistence::database::{ApplicationNodeType, SqlMigration};
use mithril_persistence::sqlite::{ConnectionBuilder, SqliteConnection, SqliteConnectionPool};
use mithril_persistence::store::adapter::SQLiteAdapter;
use mithril_persistence::store::StakeStore;

use crate::dependency_injection::SignerDependencyContainer;
use crate::services::{
AggregatorHTTPClient, CardanoTransactionsImporter,
CardanoTransactionsPreloaderActivationSigner, Configuration, MKTreeStoreSqlite,
MithrilSingleSigner, ProtocolInitializerStore, ProtocolInitializerStorer, SignerUpkeepService,
CardanoTransactionsPreloaderActivationSigner, MithrilSingleSigner, SignerUpkeepService,
TransactionsImporterByChunk, TransactionsImporterWithPruner, TransactionsImporterWithVacuum,
UpkeepService, HTTP_REQUEST_TIMEOUT_DURATION, SQLITE_FILE, SQLITE_FILE_CARDANO_TRANSACTION,
};
use crate::store::{MKTreeStoreSqlite, ProtocolInitializerStore};
use crate::{
Configuration, MetricsService, HTTP_REQUEST_TIMEOUT_DURATION, SQLITE_FILE,
SQLITE_FILE_CARDANO_TRANSACTION,
};

type StakeStoreService = Arc<StakeStore>;
type CertificateHandlerService = Arc<dyn AggregatorClient>;
type ChainObserverService = Arc<dyn ChainObserver>;
type DigesterService = Arc<dyn ImmutableDigester>;
type SingleSignerService = Arc<dyn SingleSigner>;
type TimePointProviderService = Arc<dyn TickerService>;
type ProtocolInitializerStoreService = Arc<dyn ProtocolInitializerStorer>;

/// The ServiceBuilder is intended to manage Services instance creation.
/// The `DependenciesBuilder` is intended to manage Services instance creation.
///
/// The goal of this is to put all this code out of the way of business code.
#[async_trait]
pub trait ServiceBuilder {
/// Create a SignerService instance.
async fn build(&self) -> StdResult<SignerServices>;
}

/// Create a SignerService instance for Production environment.
pub struct ProductionServiceBuilder<'a> {
pub struct DependenciesBuilder<'a> {
config: &'a Configuration,
chain_observer_builder: fn(&Configuration) -> StdResult<ChainObserverService>,
chain_observer_builder: fn(&Configuration) -> StdResult<Arc<dyn ChainObserver>>,
immutable_file_observer_builder:
fn(&Configuration) -> StdResult<Arc<dyn ImmutableFileObserver>>,
}

impl<'a> ProductionServiceBuilder<'a> {
/// Create a new production service builder.
impl<'a> DependenciesBuilder<'a> {
/// Create a new `DependenciesBuilder`.
pub fn new(config: &'a Configuration) -> Self {
let chain_observer_builder: fn(&Configuration) -> StdResult<ChainObserverService> =
let chain_observer_builder: fn(&Configuration) -> StdResult<Arc<dyn ChainObserver>> =
|config: &Configuration| {
let chain_observer_type = ChainObserverType::Pallas;
let cardano_cli_path = &config.cardano_cli_path;
let cardano_node_socket_path = &config.cardano_node_socket_path;
let cardano_network = &config.get_network().with_context(|| {
"Production Service Builder can not get Cardano network while building the chain observer"
"Dependencies Builder can not get Cardano network while building the chain observer"
})?;
let cardano_cli_runner = &CardanoCliRunner::new(
cardano_cli_path.to_owned(),
Expand Down Expand Up @@ -121,7 +114,7 @@ impl<'a> ProductionServiceBuilder<'a> {
/// Override default chain observer builder.
pub fn override_chain_observer_builder(
&mut self,
builder: fn(&Configuration) -> StdResult<ChainObserverService>,
builder: fn(&Configuration) -> StdResult<Arc<dyn ChainObserver>>,
) -> &mut Self {
self.chain_observer_builder = builder;

Expand Down Expand Up @@ -182,12 +175,9 @@ impl<'a> ProductionServiceBuilder<'a> {

Ok(connection)
}
}

#[async_trait]
impl<'a> ServiceBuilder for ProductionServiceBuilder<'a> {
/// Build a Services for the Production environment.
async fn build(&self) -> StdResult<SignerServices> {
/// Build dependencies for the Production environment.
pub async fn build(&self) -> StdResult<SignerDependencyContainer> {
if !self.config.data_stores_directory.exists() {
fs::create_dir_all(self.config.data_stores_directory.clone()).with_context(|| {
format!(
Expand Down Expand Up @@ -331,7 +321,7 @@ impl<'a> ServiceBuilder for ProductionServiceBuilder<'a> {
cardano_transactions_builder,
cardano_stake_distribution_signable_builder,
));
let metrics_service = Arc::new(MetricsService::new().unwrap());
let metrics_service = Arc::new(MetricsService::new()?);
let preloader_activation =
CardanoTransactionsPreloaderActivationSigner::new(aggregator_client.clone());
let cardano_transactions_preloader = Arc::new(CardanoTransactionsPreloader::new(
Expand All @@ -349,7 +339,7 @@ impl<'a> ServiceBuilder for ProductionServiceBuilder<'a> {
slog_scope::logger(),
));

let services = SignerServices {
let services = SignerDependencyContainer {
ticker_service,
certificate_handler: aggregator_client,
chain_observer,
Expand All @@ -371,54 +361,6 @@ impl<'a> ServiceBuilder for ProductionServiceBuilder<'a> {
}
}

/// This structure groups all the services required by the state machine.
pub struct SignerServices {
/// Time point provider service
pub ticker_service: TimePointProviderService,

/// Stake store service
pub stake_store: StakeStoreService,

/// Certificate handler service
pub certificate_handler: CertificateHandlerService,

/// Chain Observer service
pub chain_observer: ChainObserverService,

/// Digester service
pub digester: DigesterService,

/// SingleSigner service
pub single_signer: SingleSignerService,

/// ProtocolInitializer store
pub protocol_initializer_store: ProtocolInitializerStoreService,

/// Era checker service
pub era_checker: Arc<EraChecker>,

/// Era reader service
pub era_reader: Arc<EraReader>,

/// API version provider
pub api_version_provider: Arc<APIVersionProvider>,

/// Signable Builder Service
pub signable_builder_service: Arc<dyn SignableBuilderService>,

/// Metrics service
pub metrics_service: Arc<MetricsService>,

/// Signed entity type lock
pub signed_entity_type_lock: Arc<SignedEntityTypeLock>,

/// Cardano transactions preloader
pub cardano_transactions_preloader: Arc<CardanoTransactionsPreloader>,

/// Upkeep service
pub upkeep_service: Arc<dyn UpkeepService>,
}

#[cfg(test)]
mod tests {
use std::path::PathBuf;
Expand All @@ -443,16 +385,16 @@ mod tests {
};

assert!(!stores_dir.exists());
let chain_observer_builder: fn(&Configuration) -> StdResult<ChainObserverService> =
let chain_observer_builder: fn(&Configuration) -> StdResult<Arc<dyn ChainObserver>> =
|_config| Ok(Arc::new(FakeObserver::new(Some(TimePoint::dummy()))));
let immutable_file_observer_builder: fn(
&Configuration,
)
-> StdResult<Arc<dyn ImmutableFileObserver>> =
|_config: &Configuration| Ok(Arc::new(DumbImmutableFileObserver::default()));

let mut service_builder = ProductionServiceBuilder::new(&config);
service_builder
let mut dependencies_builder = DependenciesBuilder::new(&config);
dependencies_builder
.override_chain_observer_builder(chain_observer_builder)
.override_immutable_file_observer_builder(immutable_file_observer_builder)
.build()
Expand Down
71 changes: 71 additions & 0 deletions mithril-signer/src/dependency_injection/containers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use std::sync::Arc;

use mithril_common::api_version::APIVersionProvider;
use mithril_common::cardano_transactions_preloader::CardanoTransactionsPreloader;
use mithril_common::chain_observer::ChainObserver;
use mithril_common::digesters::ImmutableDigester;
use mithril_common::era::{EraChecker, EraReader};
use mithril_common::signable_builder::SignableBuilderService;
use mithril_common::signed_entity_type_lock::SignedEntityTypeLock;
use mithril_common::TickerService;
use mithril_persistence::store::StakeStore;

use crate::services::{AggregatorClient, SingleSigner, UpkeepService};
use crate::store::ProtocolInitializerStorer;
use crate::MetricsService;

type StakeStoreService = Arc<StakeStore>;
type CertificateHandlerService = Arc<dyn AggregatorClient>;
type ChainObserverService = Arc<dyn ChainObserver>;
type DigesterService = Arc<dyn ImmutableDigester>;
type SingleSignerService = Arc<dyn SingleSigner>;
type TimePointProviderService = Arc<dyn TickerService>;
type ProtocolInitializerStoreService = Arc<dyn ProtocolInitializerStorer>;

/// This structure groups all the dependencies required by the state machine.
pub struct SignerDependencyContainer {
/// Time point provider service
pub ticker_service: TimePointProviderService,

/// Stake store service
pub stake_store: StakeStoreService,

/// Certificate handler service
pub certificate_handler: CertificateHandlerService,

/// Chain Observer service
pub chain_observer: ChainObserverService,

/// Digester service
pub digester: DigesterService,

/// SingleSigner service
pub single_signer: SingleSignerService,

/// ProtocolInitializer store
pub protocol_initializer_store: ProtocolInitializerStoreService,

/// Era checker service
pub era_checker: Arc<EraChecker>,

/// Era reader service
pub era_reader: Arc<EraReader>,

/// API version provider
pub api_version_provider: Arc<APIVersionProvider>,

/// Signable Builder Service
pub signable_builder_service: Arc<dyn SignableBuilderService>,

/// Metrics service
pub metrics_service: Arc<MetricsService>,

/// Signed entity type lock
pub signed_entity_type_lock: Arc<SignedEntityTypeLock>,

/// Cardano transactions preloader
pub cardano_transactions_preloader: Arc<CardanoTransactionsPreloader>,

/// Upkeep service
pub upkeep_service: Arc<dyn UpkeepService>,
}
20 changes: 20 additions & 0 deletions mithril-signer/src/dependency_injection/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! Dependency injection module.
//!
//! This module provides tools to initialize and share resources and services
//! amongst different threads.
//!
//! It takes all its inputs from the configuration which should combine inputs from:
//!
//! * environment
//! * command line
//! * configuration files
//! * default values
//!
//! The Builder ensure every service has required dependencies to build and
//! provide services containers for each sub process.

mod builder;
mod containers;

pub use builder::*;
pub use containers::*;
25 changes: 3 additions & 22 deletions mithril-signer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,21 @@
//! See the [Mithril documentation](https://mithril.network/doc/manual/developer-docs/nodes/mithril-signer)
//! for more information on how it works.

mod aggregator_client;
mod cardano_transactions_importer;
mod cardano_transactions_preloader_checker;
mod configuration;
pub mod database;
pub mod dependency_injection;
mod message_adapters;
pub mod metrics;
mod mktree_store_sqlite;
mod protocol_initializer_store;
mod runtime;
mod single_signer;
mod transactions_importer_by_chunk;
mod transactions_importer_with_pruner;
mod transactions_importer_with_vacuum;
mod upkeep_service;
pub mod services;
pub mod store;

#[cfg(test)]
pub use aggregator_client::dumb::DumbAggregatorClient;
pub use aggregator_client::*;
pub use cardano_transactions_importer::*;
pub use cardano_transactions_preloader_checker::*;
pub use configuration::{Configuration, DefaultConfiguration};
pub use message_adapters::{
FromEpochSettingsAdapter, FromPendingCertificateMessageAdapter, ToRegisterSignerMessageAdapter,
};
pub use metrics::*;
pub use mktree_store_sqlite::*;
pub use protocol_initializer_store::{ProtocolInitializerStore, ProtocolInitializerStorer};
pub use runtime::*;
pub use single_signer::*;
pub use transactions_importer_by_chunk::*;
pub use transactions_importer_with_pruner::*;
pub use transactions_importer_with_vacuum::*;
pub use upkeep_service::*;

/// HTTP request timeout duration in milliseconds
const HTTP_REQUEST_TIMEOUT_DURATION: u64 = 30000;
Expand Down
Loading
Loading