diff --git a/CHANGELOG.md b/CHANGELOG.md index 7030ae1a34f..ef1c6916c1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ As a minor extension, we have adopted a slightly different versioning convention - **UNSTABLE** Cardano transactions certification: - Optimize the performances of the computation of the proof with a Merkle map. - Handle rollback events from the Cardano chain by removing stale data. + - Preload Cardano transactions and Block Range Roots at signer & aggregator startup. - Crates versions: diff --git a/Cargo.lock b/Cargo.lock index 1a01c61e138..d3c3935e00d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3531,7 +3531,7 @@ dependencies = [ [[package]] name = "mithril-aggregator" -version = "0.5.22" +version = "0.5.23" dependencies = [ "anyhow", "async-trait", @@ -3687,7 +3687,7 @@ dependencies = [ [[package]] name = "mithril-common" -version = "0.4.17" +version = "0.4.18" dependencies = [ "anyhow", "async-trait", @@ -3832,7 +3832,7 @@ dependencies = [ [[package]] name = "mithril-signer" -version = "0.2.144" +version = "0.2.145" dependencies = [ "anyhow", "async-trait", diff --git a/mithril-aggregator/Cargo.toml b/mithril-aggregator/Cargo.toml index 0530178c8c7..cee5742cb54 100644 --- a/mithril-aggregator/Cargo.toml +++ b/mithril-aggregator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-aggregator" -version = "0.5.22" +version = "0.5.23" description = "A Mithril Aggregator server" authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-aggregator/src/commands/serve_command.rs b/mithril-aggregator/src/commands/serve_command.rs index e0e83b49099..fcb8aad12bd 100644 --- a/mithril-aggregator/src/commands/serve_command.rs +++ b/mithril-aggregator/src/commands/serve_command.rs @@ -119,6 +119,16 @@ impl ServeCommand { let mut join_set = JoinSet::new(); join_set.spawn(async move { runtime.run().await.map_err(|e| e.to_string()) }); + // start the cardano transactions preloader + let cardano_transactions_preloader = dependencies_builder + .create_cardano_transactions_preloader() + .await + .with_context(|| { + "Dependencies Builder can not create cardano transactions preloader" + })?; + let preload_task = + tokio::spawn(async move { cardano_transactions_preloader.preload().await }); + // start the HTTP server let (shutdown_tx, shutdown_rx) = oneshot::channel(); let routes = dependencies_builder @@ -180,6 +190,10 @@ impl ServeCommand { join_set.shutdown().await; let _ = shutdown_tx.send(()); + if !preload_task.is_finished() { + preload_task.abort(); + } + info!("Event store is finishing..."); event_store_thread.await.unwrap(); println!("Services stopped, exiting."); diff --git a/mithril-aggregator/src/dependency_injection/builder.rs b/mithril-aggregator/src/dependency_injection/builder.rs index 649b8c54d9e..63f93397b7e 100644 --- a/mithril-aggregator/src/dependency_injection/builder.rs +++ b/mithril-aggregator/src/dependency_injection/builder.rs @@ -14,6 +14,7 @@ use warp::Filter; use mithril_common::{ api_version::APIVersionProvider, cardano_block_scanner::{BlockScanner, CardanoBlockScanner}, + cardano_transactions_preloader::CardanoTransactionsPreloader, certificate_chain::{CertificateVerifier, MithrilCertificateVerifier}, chain_observer::{CardanoCliRunner, ChainObserver, ChainObserverBuilder, FakeObserver}, crypto_helper::{ @@ -32,7 +33,7 @@ use mithril_common::{ signable_builder::{ CardanoImmutableFilesFullSignableBuilder, CardanoTransactionsSignableBuilder, MithrilSignableBuilderService, MithrilStakeDistributionSignableBuilder, - SignableBuilderService, + SignableBuilderService, TransactionsImporter, }, signed_entity_type_lock::SignedEntityTypeLock, MithrilTickerService, TickerService, @@ -210,6 +211,12 @@ pub struct DependenciesBuilder { /// Prover service pub prover_service: Option>, + + /// Signed Entity Type Lock + pub signed_entity_type_lock: Option>, + + /// Transactions Importer + pub transactions_importer: Option>, } impl DependenciesBuilder { @@ -256,6 +263,8 @@ impl DependenciesBuilder { signed_entity_storer: None, message_service: None, prover_service: None, + signed_entity_type_lock: None, + transactions_importer: None, } } @@ -1028,12 +1037,7 @@ impl DependenciesBuilder { &self.configuration.db_directory, self.get_logger().await?, )); - let transactions_importer = Arc::new(CardanoTransactionsImporter::new( - self.get_block_scanner().await?, - self.get_transaction_repository().await?, - &self.configuration.db_directory, - self.get_logger().await?, - )); + let transactions_importer = self.get_transactions_importer().await?; let block_range_root_retriever = self.get_transaction_repository().await?; let cardano_transactions_builder = Arc::new(CardanoTransactionsSignableBuilder::new( transactions_importer, @@ -1149,6 +1153,38 @@ impl DependenciesBuilder { Ok(self.signed_entity_storer.as_ref().cloned().unwrap()) } + async fn build_signed_entity_lock(&mut self) -> Result> { + let signed_entity_type_lock = Arc::new(SignedEntityTypeLock::default()); + Ok(signed_entity_type_lock) + } + + async fn get_signed_entity_lock(&mut self) -> Result> { + if self.signed_entity_type_lock.is_none() { + self.signed_entity_type_lock = Some(self.build_signed_entity_lock().await?); + } + + Ok(self.signed_entity_type_lock.as_ref().cloned().unwrap()) + } + + async fn build_transactions_importer(&mut self) -> Result> { + let transactions_importer = Arc::new(CardanoTransactionsImporter::new( + self.get_block_scanner().await?, + self.get_transaction_repository().await?, + &self.configuration.db_directory, + self.get_logger().await?, + )); + + Ok(transactions_importer) + } + + async fn get_transactions_importer(&mut self) -> Result> { + if self.transactions_importer.is_none() { + self.transactions_importer = Some(self.build_transactions_importer().await?); + } + + Ok(self.transactions_importer.as_ref().cloned().unwrap()) + } + /// Return an unconfigured [DependencyContainer] pub async fn build_dependency_container(&mut self) -> Result { let dependency_manager = DependencyContainer { @@ -1189,7 +1225,7 @@ impl DependenciesBuilder { block_scanner: self.get_block_scanner().await?, transaction_store: self.get_transaction_repository().await?, prover_service: self.get_prover_service().await?, - signed_entity_type_lock: Arc::new(SignedEntityTypeLock::default()), + signed_entity_type_lock: self.get_signed_entity_lock().await?, }; Ok(dependency_manager) @@ -1233,6 +1269,23 @@ impl DependenciesBuilder { Ok(router::routes(dependency_container)) } + /// Create a [CardanoTransactionsPreloader] instance. + pub async fn create_cardano_transactions_preloader( + &mut self, + ) -> Result> { + let cardano_transactions_preloader = CardanoTransactionsPreloader::new( + self.get_signed_entity_lock().await?, + self.get_transactions_importer().await?, + self.configuration + .cardano_transactions_signing_config + .security_parameter, + self.get_chain_observer().await?, + self.get_logger().await?, + ); + + Ok(Arc::new(cardano_transactions_preloader)) + } + /// Create dependencies for genesis commands pub async fn create_genesis_container(&mut self) -> Result { let network = self.configuration.get_network().with_context(|| { diff --git a/mithril-aggregator/src/dependency_injection/containers.rs b/mithril-aggregator/src/dependency_injection/containers.rs index 8f65d2d0042..b950ac6d11e 100644 --- a/mithril-aggregator/src/dependency_injection/containers.rs +++ b/mithril-aggregator/src/dependency_injection/containers.rs @@ -1,7 +1,6 @@ use std::sync::Arc; use tokio::sync::RwLock; -use mithril_common::entities::SignedEntityConfig; use mithril_common::{ api_version::APIVersionProvider, cardano_block_scanner::BlockScanner, @@ -9,7 +8,7 @@ use mithril_common::{ chain_observer::ChainObserver, crypto_helper::ProtocolGenesisVerifier, digesters::{ImmutableDigester, ImmutableFileObserver}, - entities::{Epoch, ProtocolParameters, SignerWithStake, StakeDistribution}, + entities::{Epoch, ProtocolParameters, SignedEntityConfig, SignerWithStake, StakeDistribution}, era::{EraChecker, EraReader}, signable_builder::SignableBuilderService, signed_entity_type_lock::SignedEntityTypeLock, diff --git a/mithril-common/Cargo.toml b/mithril-common/Cargo.toml index 04cff021c19..79580018fb4 100644 --- a/mithril-common/Cargo.toml +++ b/mithril-common/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-common" -version = "0.4.17" +version = "0.4.18" description = "Common types, interfaces, and utilities for Mithril nodes." authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-common/src/cardano_transactions_preloader.rs b/mithril-common/src/cardano_transactions_preloader.rs new file mode 100644 index 00000000000..cef1fa24b34 --- /dev/null +++ b/mithril-common/src/cardano_transactions_preloader.rs @@ -0,0 +1,211 @@ +//! # Cardano Transaction Preloader +//! +//! This module provides a preload mechanism for Cardano Transaction signed entity, allowing +//! to compute in advance the Transactions & Block Range Root to be signed. + +use std::sync::Arc; + +use anyhow::Context; +use slog::{debug, info, Logger}; + +use crate::chain_observer::ChainObserver; +use crate::entities::{BlockNumber, SignedEntityTypeDiscriminants}; +use crate::signable_builder::TransactionsImporter; +use crate::signed_entity_type_lock::SignedEntityTypeLock; +use crate::StdResult; + +/// Preload mechanism for Cardano Transaction signed entity, allowing +/// to compute in advance the Transactions & Block Range Root to be signed. +pub struct CardanoTransactionsPreloader { + signed_entity_type_lock: Arc, + importer: Arc, + security_parameter: BlockNumber, + chain_observer: Arc, + logger: Logger, +} + +impl CardanoTransactionsPreloader { + /// Create a new instance of `CardanoTransactionPreloader`. + pub fn new( + signed_entity_type_lock: Arc, + importer: Arc, + security_parameter: BlockNumber, + chain_observer: Arc, + logger: Logger, + ) -> Self { + Self { + signed_entity_type_lock, + importer, + security_parameter, + chain_observer, + logger, + } + } + + /// Preload the Cardano Transactions by running the importer up to the current chain block number. + pub async fn preload(&self) -> StdResult<()> { + info!(self.logger, "🔥 Preload Cardano Transactions - Started"); + debug!(self.logger, "🔥 Locking signed entity type"; "entity_type" => "CardanoTransactions"); + self.signed_entity_type_lock + .lock(SignedEntityTypeDiscriminants::CardanoTransactions) + .await; + + let preload_result = self.do_preload().await; + + debug!(self.logger, "🔥 Releasing signed entity type"; "entity_type" => "CardanoTransactions"); + self.signed_entity_type_lock + .release(SignedEntityTypeDiscriminants::CardanoTransactions) + .await; + info!(self.logger, "🔥 Preload Cardano Transactions - Finished"); + + preload_result + } + + async fn do_preload(&self) -> StdResult<()> { + let chain_point = self + .chain_observer + .get_current_chain_point() + .await? + .with_context(|| { + "No chain point yielded by the chain observer, is your cardano node ready?" + })?; + let up_to_block_number = chain_point + .block_number + .saturating_sub(self.security_parameter); + self.importer.import(up_to_block_number).await?; + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use async_trait::async_trait; + use mockall::predicate::eq; + + use crate::chain_observer::FakeObserver; + use crate::entities::{BlockNumber, ChainPoint, TimePoint}; + use crate::signable_builder::MockTransactionsImporter; + use crate::test_utils::TestLogger; + + use super::*; + + struct ImporterWithSignedEntityTypeLockCheck { + signed_entity_type_lock: Arc, + } + #[async_trait] + impl TransactionsImporter for ImporterWithSignedEntityTypeLockCheck { + async fn import(&self, _up_to_beacon: BlockNumber) -> StdResult<()> { + assert!( + self.signed_entity_type_lock + .is_locked(SignedEntityTypeDiscriminants::CardanoTransactions) + .await + ); + Ok(()) + } + } + + #[tokio::test] + async fn call_its_inner_importer() { + let chain_block_number = 5000; + let security_parameter = 542; + let chain_observer = FakeObserver::new(Some(TimePoint { + chain_point: ChainPoint { + block_number: chain_block_number, + ..ChainPoint::dummy() + }, + ..TimePoint::dummy() + })); + let expected_parsed_block_number = chain_block_number - security_parameter; + + let mut importer = MockTransactionsImporter::new(); + importer + .expect_import() + .times(1) + .with(eq(expected_parsed_block_number)) + .returning(|_| Ok(())); + + let preloader = CardanoTransactionsPreloader::new( + Arc::new(SignedEntityTypeLock::default()), + Arc::new(importer), + security_parameter, + Arc::new(chain_observer), + TestLogger::stdout(), + ); + + preloader.preload().await.unwrap(); + } + + #[tokio::test] + async fn fail_if_chain_point_is_not_available() { + let chain_observer = FakeObserver::new(None); + let mut importer = MockTransactionsImporter::new(); + importer.expect_import().never(); + + let preloader = CardanoTransactionsPreloader::new( + Arc::new(SignedEntityTypeLock::default()), + Arc::new(importer), + 0, + Arc::new(chain_observer), + TestLogger::stdout(), + ); + + preloader + .preload() + .await + .expect_err("should raise an error when chain point is not available"); + } + + #[tokio::test] + async fn should_lock_entity_type_while_preloading() { + let signed_entity_type_lock = Arc::new(SignedEntityTypeLock::default()); + + let preloader = CardanoTransactionsPreloader::new( + signed_entity_type_lock.clone(), + Arc::new(ImporterWithSignedEntityTypeLockCheck { + signed_entity_type_lock: signed_entity_type_lock.clone(), + }), + 0, + Arc::new(FakeObserver::new(Some(TimePoint::dummy()))), + TestLogger::stdout(), + ); + + assert!( + !signed_entity_type_lock + .is_locked(SignedEntityTypeDiscriminants::CardanoTransactions) + .await + ); + + preloader.preload().await.unwrap(); + + assert!( + !signed_entity_type_lock + .is_locked(SignedEntityTypeDiscriminants::CardanoTransactions) + .await + ); + } + + #[tokio::test] + async fn should_release_locked_entity_type_when_preloading_fail() { + let signed_entity_type_lock = Arc::new(SignedEntityTypeLock::default()); + let chain_observer = FakeObserver::new(None); + + let preloader = CardanoTransactionsPreloader::new( + signed_entity_type_lock.clone(), + Arc::new(ImporterWithSignedEntityTypeLockCheck { + signed_entity_type_lock: signed_entity_type_lock.clone(), + }), + 0, + Arc::new(chain_observer), + TestLogger::stdout(), + ); + + preloader.preload().await.unwrap_err(); + + assert!( + !signed_entity_type_lock + .is_locked(SignedEntityTypeDiscriminants::CardanoTransactions) + .await + ); + } +} diff --git a/mithril-common/src/lib.rs b/mithril-common/src/lib.rs index 48df3e58179..e0b715968fc 100644 --- a/mithril-common/src/lib.rs +++ b/mithril-common/src/lib.rs @@ -72,6 +72,7 @@ cfg_fs! { pub mod digesters; pub mod cardano_block_scanner; pub mod chain_reader; + pub mod cardano_transactions_preloader; pub use ticker_service::{TickerService, MithrilTickerService}; } diff --git a/mithril-signer/Cargo.toml b/mithril-signer/Cargo.toml index 10953b356bb..f34698119ad 100644 --- a/mithril-signer/Cargo.toml +++ b/mithril-signer/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mithril-signer" -version = "0.2.144" +version = "0.2.145" description = "A Mithril Signer" authors = { workspace = true } edition = { workspace = true } diff --git a/mithril-signer/src/configuration.rs b/mithril-signer/src/configuration.rs index ac1590ee2b4..3964b3544cf 100644 --- a/mithril-signer/src/configuration.rs +++ b/mithril-signer/src/configuration.rs @@ -40,6 +40,10 @@ pub struct Configuration { /// be considered final, preventing any further rollback `[default: 2160]`. pub network_security_parameter: BlockNumber, + /// Blocks offset, from the tip of the chain, to exclude during the cardano transactions preload + /// `[default: 3000]`. + pub preload_security_parameter: BlockNumber, + /// Aggregator endpoint #[example = "`https://aggregator.pre-release-preview.api.mithril.network/aggregator`"] pub aggregator_endpoint: String, @@ -121,6 +125,7 @@ impl Configuration { network: "devnet".to_string(), network_magic: Some(42), network_security_parameter: 2160, + preload_security_parameter: 30, party_id: Some(party_id), run_interval: 5000, data_stores_directory: PathBuf::new(), @@ -204,6 +209,9 @@ pub struct DefaultConfiguration { /// Transaction pruning toggle pub enable_transaction_pruning: bool, + + /// Preload security parameter + pub preload_security_parameter: BlockNumber, } impl DefaultConfiguration { @@ -219,6 +227,7 @@ impl Default for DefaultConfiguration { metrics_server_ip: "0.0.0.0".to_string(), metrics_server_port: 9090, network_security_parameter: 2160, // 2160 is the mainnet value + preload_security_parameter: 3000, enable_transaction_pruning: true, } } @@ -256,6 +265,11 @@ impl Source for DefaultConfiguration { into_value(myself.network_security_parameter), ); + result.insert( + "preload_security_parameter".to_string(), + into_value(myself.preload_security_parameter), + ); + result.insert( "enable_transaction_pruning".to_string(), into_value(myself.enable_transaction_pruning), diff --git a/mithril-signer/src/main.rs b/mithril-signer/src/main.rs index efdf7723832..79b7f41485b 100644 --- a/mithril-signer/src/main.rs +++ b/mithril-signer/src/main.rs @@ -1,7 +1,6 @@ use anyhow::{anyhow, Context}; use clap::{CommandFactory, Parser, Subcommand}; use config::{Map, Value}; -use mithril_doc::{Documenter, DocumenterDefault, StructDoc}; use slog::{o, Drain, Level, Logger}; use slog_scope::{crit, debug}; @@ -15,7 +14,7 @@ use tokio::{ }; use mithril_common::StdResult; -use mithril_doc::GenerateDocCommands; +use mithril_doc::{Documenter, DocumenterDefault, GenerateDocCommands, StructDoc}; use mithril_signer::{ Configuration, DefaultConfiguration, MetricsServer, ProductionServiceBuilder, ServiceBuilder, SignerRunner, SignerState, StateMachine, @@ -165,8 +164,10 @@ async fn main() -> StdResult<()> { .with_context(|| "services initialization error")?; let metrics_service = services.metrics_service.clone(); + let cardano_transaction_preloader = services.cardano_transactions_preloader.clone(); debug!("Started"; "run_mode" => &args.run_mode, "config" => format!("{config:?}")); + let state_machine = StateMachine::new( SignerState::Init, Box::new(SignerRunner::new(config.clone(), services)), @@ -183,6 +184,8 @@ async fn main() -> StdResult<()> { .map(|_| None) }); + let preload_task = tokio::spawn(async move { cardano_transaction_preloader.preload().await }); + let (metrics_server_shutdown_tx, metrics_server_shutdown_rx) = oneshot::channel(); if config.enable_metrics_server { join_set.spawn(async move { @@ -236,6 +239,10 @@ async fn main() -> StdResult<()> { .send(()) .map_err(|e| anyhow!("Metrics server shutdown signal could not be sent: {e:?}"))?; + if !preload_task.is_finished() { + preload_task.abort(); + } + join_set.shutdown().await; debug!("Stopping"; "shutdown_reason" => shutdown_reason); diff --git a/mithril-signer/src/runtime/runner.rs b/mithril-signer/src/runtime/runner.rs index 3005293c990..526a4ba5fac 100644 --- a/mithril-signer/src/runtime/runner.rs +++ b/mithril-signer/src/runtime/runner.rs @@ -459,6 +459,7 @@ mod tests { use mithril_common::{ api_version::APIVersionProvider, cardano_block_scanner::DumbBlockScanner, + cardano_transactions_preloader::CardanoTransactionsPreloader, chain_observer::{ChainObserver, FakeObserver}, crypto_helper::{MKMap, MKMapNode, MKTreeNode, ProtocolInitializer}, digesters::{DumbImmutableDigester, DumbImmutableFileObserver}, @@ -547,7 +548,7 @@ mod tests { Arc::new(MithrilStakeDistributionSignableBuilder::default()); let transaction_parser = Arc::new(DumbBlockScanner::new()); let transaction_store = Arc::new(MockTransactionStore::new()); - let transaction_importer = Arc::new(CardanoTransactionsImporter::new( + let transactions_importer = Arc::new(CardanoTransactionsImporter::new( transaction_parser.clone(), transaction_store.clone(), Path::new(""), @@ -555,7 +556,7 @@ mod tests { )); let block_range_root_retriever = Arc::new(MockBlockRangeRootRetrieverImpl::new()); let cardano_transactions_builder = Arc::new(CardanoTransactionsSignableBuilder::new( - transaction_importer, + transactions_importer.clone(), block_range_root_retriever, slog_scope::logger(), )); @@ -565,6 +566,15 @@ mod tests { cardano_transactions_builder, )); let metrics_service = Arc::new(MetricsService::new().unwrap()); + let signed_entity_type_lock = Arc::new(SignedEntityTypeLock::default()); + let security_parameter = 0; + let cardano_transactions_preloader = Arc::new(CardanoTransactionsPreloader::new( + signed_entity_type_lock.clone(), + transactions_importer.clone(), + security_parameter, + chain_observer.clone(), + slog_scope::logger(), + )); SignerServices { stake_store: Arc::new(StakeStore::new(Box::new(DumbStoreAdapter::new()), None)), @@ -582,7 +592,8 @@ mod tests { api_version_provider, signable_builder_service, metrics_service, - signed_entity_type_lock: Arc::new(SignedEntityTypeLock::default()), + signed_entity_type_lock, + cardano_transactions_preloader, } } diff --git a/mithril-signer/src/runtime/signer_services.rs b/mithril-signer/src/runtime/signer_services.rs index dc71ced0b65..389ab803ef7 100644 --- a/mithril-signer/src/runtime/signer_services.rs +++ b/mithril-signer/src/runtime/signer_services.rs @@ -5,6 +5,7 @@ use std::{fs, sync::Arc, time::Duration}; use mithril_common::{ api_version::APIVersionProvider, cardano_block_scanner::CardanoBlockScanner, + cardano_transactions_preloader::CardanoTransactionsPreloader, chain_observer::{CardanoCliRunner, ChainObserver, ChainObserverBuilder, ChainObserverType}, crypto_helper::{OpCert, ProtocolPartyId, SerDeShelleyFileFormat}, digesters::{ @@ -202,6 +203,7 @@ impl<'a> ServiceBuilder for ProductionServiceBuilder<'a> { ) .await?; + let signed_entity_type_lock = Arc::new(SignedEntityTypeLock::default()); let protocol_initializer_store = Arc::new(ProtocolInitializerStore::new( Box::new(SQLiteAdapter::new( "protocol_initializer", @@ -284,7 +286,7 @@ impl<'a> ServiceBuilder for ProductionServiceBuilder<'a> { )); let block_range_root_retriever = transaction_store.clone(); let cardano_transactions_builder = Arc::new(CardanoTransactionsSignableBuilder::new( - transactions_importer, + transactions_importer.clone(), block_range_root_retriever, slog_scope::logger(), )); @@ -294,6 +296,13 @@ impl<'a> ServiceBuilder for ProductionServiceBuilder<'a> { cardano_transactions_builder, )); let metrics_service = Arc::new(MetricsService::new().unwrap()); + let cardano_transactions_preloader = Arc::new(CardanoTransactionsPreloader::new( + signed_entity_type_lock.clone(), + transactions_importer.clone(), + self.config.preload_security_parameter, + chain_observer.clone(), + slog_scope::logger(), + )); let services = SignerServices { ticker_service, @@ -308,7 +317,8 @@ impl<'a> ServiceBuilder for ProductionServiceBuilder<'a> { api_version_provider, signable_builder_service, metrics_service, - signed_entity_type_lock: Arc::new(SignedEntityTypeLock::default()), + signed_entity_type_lock, + cardano_transactions_preloader, }; Ok(services) @@ -355,6 +365,9 @@ pub struct SignerServices { /// Signed entity type lock pub signed_entity_type_lock: Arc, + + /// Cardano transactions preloader + pub cardano_transactions_preloader: Arc, } #[cfg(test)] diff --git a/mithril-signer/tests/test_extensions/state_machine_tester.rs b/mithril-signer/tests/test_extensions/state_machine_tester.rs index 7fbeecccaf6..c5ff8aa46dd 100644 --- a/mithril-signer/tests/test_extensions/state_machine_tester.rs +++ b/mithril-signer/tests/test_extensions/state_machine_tester.rs @@ -9,6 +9,7 @@ use thiserror::Error; use mithril_common::{ api_version::APIVersionProvider, cardano_block_scanner::{DumbBlockScanner, ScannedBlock}, + cardano_transactions_preloader::CardanoTransactionsPreloader, chain_observer::{ChainObserver, FakeObserver}, digesters::{DumbImmutableDigester, DumbImmutableFileObserver, ImmutableFileObserver}, entities::{ @@ -110,14 +111,15 @@ impl StateMachineTester { chain_observer.clone(), immutable_observer.clone(), )); + let cardano_transactions_signing_config = CardanoTransactionsSigningConfig { + security_parameter: 0, + step: 30, + }; let certificate_handler = Arc::new(FakeAggregator::new( SignedEntityConfig { allowed_discriminants: SignedEntityTypeDiscriminants::all(), network: config.get_network().unwrap(), - cardano_transactions_signing_config: CardanoTransactionsSigningConfig { - security_parameter: 0, - step: 30, - }, + cardano_transactions_signing_config: cardano_transactions_signing_config.clone(), }, ticker_service.clone(), )); @@ -163,7 +165,7 @@ impl StateMachineTester { let transaction_store = Arc::new(CardanoTransactionRepository::new( transaction_sqlite_connection, )); - let transaction_importer = Arc::new(CardanoTransactionsImporter::new( + let transactions_importer = Arc::new(CardanoTransactionsImporter::new( block_scanner.clone(), transaction_store.clone(), Path::new(""), @@ -171,7 +173,7 @@ impl StateMachineTester { )); let block_range_root_retriever = transaction_store.clone(); let cardano_transactions_builder = Arc::new(CardanoTransactionsSignableBuilder::new( - transaction_importer, + transactions_importer.clone(), block_range_root_retriever, slog_scope::logger(), )); @@ -182,6 +184,15 @@ impl StateMachineTester { )); let metrics_service = Arc::new(MetricsService::new().unwrap()); let expected_metrics_service = Arc::new(MetricsService::new().unwrap()); + let signed_entity_type_lock = Arc::new(SignedEntityTypeLock::default()); + let security_parameter = 0; + let cardano_transactions_preloader = Arc::new(CardanoTransactionsPreloader::new( + signed_entity_type_lock.clone(), + transactions_importer.clone(), + security_parameter, + chain_observer.clone(), + slog_scope::logger(), + )); let services = SignerServices { certificate_handler: certificate_handler.clone(), @@ -197,6 +208,7 @@ impl StateMachineTester { signable_builder_service, metrics_service: metrics_service.clone(), signed_entity_type_lock: Arc::new(SignedEntityTypeLock::default()), + cardano_transactions_preloader, }; // set up stake distribution chain_observer