Skip to content

Commit f95f565

Browse files
authored
Merge pull request #440 from input-output-hk/greg/439/signer_documentation
add code doc & factor service initialization
2 parents c9bb429 + c36d05d commit f95f565

File tree

9 files changed

+168
-55
lines changed

9 files changed

+168
-55
lines changed

mithril-signer/src/certificate_handler.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,31 @@ use mithril_common::{
1313
#[cfg(test)]
1414
use mockall::automock;
1515

16+
/// Error structure for the Certificate Handler.
1617
#[derive(Error, Debug)]
1718
pub enum CertificateHandlerError {
19+
/// The aggregator host has returned a technical error.
1820
#[error("remote server technical error: '{0}'")]
1921
RemoteServerTechnical(String),
2022

23+
/// The aggregator host responded it cannot fulfill our request.
2124
#[error("remote server logical error: '{0}'")]
2225
RemoteServerLogical(String),
2326

27+
/// Could not reach aggregator.
2428
#[error("remote server unreachable: '{0}'")]
2529
RemoteServerUnreachable(String),
2630

31+
/// Could not parse response.
2732
#[error("json parsing failed: '{0}'")]
2833
JsonParseFailed(String),
2934

35+
/// Mostly network errors.
3036
#[error("io error: {0}")]
3137
IOError(#[from] io::Error),
3238
}
3339

40+
/// Trait for mocking and testing a `CertificateHandler`
3441
#[cfg_attr(test, automock)]
3542
#[async_trait]
3643
pub trait CertificateHandler: Sync + Send {
@@ -39,10 +46,10 @@ pub trait CertificateHandler: Sync + Send {
3946
&self,
4047
) -> Result<Option<CertificatePending>, CertificateHandlerError>;
4148

42-
/// Registers signer with the aggregator
49+
/// Registers signer with the aggregator.
4350
async fn register_signer(&self, signer: &Signer) -> Result<(), CertificateHandlerError>;
4451

45-
/// Registers single signatures with the aggregator
52+
/// Registers single signatures with the aggregator.
4653
async fn register_signatures(
4754
&self,
4855
signatures: &SingleSignatures,
@@ -138,12 +145,16 @@ impl CertificateHandler for CertificateHandlerHTTPClient {
138145
}
139146
}
140147

148+
/// This certificate handler is intended to be used by test services.
149+
/// It actually does not communicate with an aggregator host but mimics this behavior.
150+
/// It is driven by a Tester that controls the CertificatePending it can return and it can return its internal state for testing.
141151
pub struct DumbCertificateHandler {
142152
certificate_pending: RwLock<Option<CertificatePending>>,
143153
last_registered_signer: RwLock<Option<Signer>>,
144154
}
145155

146156
impl DumbCertificateHandler {
157+
/// Instanciate a new DumbCertificateHandler.
147158
pub fn new() -> Self {
148159
Self {
149160
certificate_pending: RwLock::new(None),
@@ -160,6 +171,7 @@ impl DumbCertificateHandler {
160171
*signer = None;
161172
}
162173

174+
/// Return the last signer that called with the `register` method.
163175
pub async fn get_last_registered_signer(&self) -> Option<Signer> {
164176
self.last_registered_signer.read().await.clone()
165177
}

mithril-signer/src/entities.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub struct Config {
3838
}
3939

4040
impl Config {
41+
/// Return the CardanoNetwork value from the configuration.
4142
pub fn get_network(&self) -> Result<CardanoNetwork, ConfigError> {
4243
match self.network.to_lowercase().as_str() {
4344
"mainnet" => Ok(CardanoNetwork::MainNet),

mithril-signer/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
#![warn(missing_docs)]
2+
//! Mithril Signer crate documentation
3+
//!
4+
//! This crate is used by Cardano nodes to participate to Mithril signatures.
5+
//! It proposes tools to communicate with Mithril aggregators and to issue Single Signatures.
6+
//! See the [Mithril documentation](https://mithril.network/doc/manual/developer-docs/nodes/mithril-signer) for more information on how it works.
7+
18
use std::error::Error as StdError;
29

310
mod certificate_handler;

mithril-signer/src/main.rs

Lines changed: 5 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
use clap::Parser;
2-
use mithril_common::BeaconProviderImpl;
32
use slog::{o, Drain, Level, Logger};
43
use slog_scope::debug;
54
use std::env;
65
use std::error::Error;
76
use std::sync::Arc;
87
use std::time::Duration;
98

10-
use mithril_common::chain_observer::{CardanoCliChainObserver, CardanoCliRunner};
11-
use mithril_common::digesters::{CardanoImmutableDigester, ImmutableFileSystemObserver};
12-
use mithril_common::store::adapter::JsonFileStoreAdapter;
13-
use mithril_common::store::StakeStore;
149
use mithril_signer::{
15-
CertificateHandlerHTTPClient, Config, MithrilSingleSigner, ProtocolInitializerStore,
16-
SignerRunner, SignerServices, SignerState, StateMachine,
10+
Config, ProductionServiceBuilder, ServiceBuilder, SignerRunner, SignerState, StateMachine,
1711
};
1812

1913
/// CLI args
@@ -69,45 +63,12 @@ async fn main() -> Result<(), Box<dyn Error>> {
6963
.map_err(|e| format!("configuration deserialize error: {}", e))?;
7064
debug!("Started"; "run_mode" => &run_mode, "config" => format!("{:?}", config));
7165

72-
let protocol_initializer_store = Arc::new(ProtocolInitializerStore::new(Box::new(
73-
JsonFileStoreAdapter::new(config.data_stores_directory.join("protocol_initializer_db"))?,
74-
)));
75-
let single_signer = Arc::new(MithrilSingleSigner::new(config.party_id.clone()));
76-
let certificate_handler = Arc::new(CertificateHandlerHTTPClient::new(
77-
config.aggregator_endpoint.clone(),
78-
));
79-
let digester = Arc::new(CardanoImmutableDigester::new(
80-
config.db_directory.clone(),
81-
slog_scope::logger(),
82-
));
83-
let stake_store = Arc::new(StakeStore::new(Box::new(JsonFileStoreAdapter::new(
84-
config.data_stores_directory.join("stake_db"),
85-
)?)));
86-
let chain_observer = Arc::new(CardanoCliChainObserver::new(Box::new(
87-
CardanoCliRunner::new(
88-
config.cardano_cli_path.clone(),
89-
config.cardano_node_socket_path.clone(),
90-
config.get_network()?,
91-
),
92-
)));
93-
let beacon_provider = Arc::new(BeaconProviderImpl::new(
94-
chain_observer.clone(),
95-
Arc::new(ImmutableFileSystemObserver::new(&config.db_directory)),
96-
config.get_network()?.to_owned(),
97-
));
98-
99-
let services = SignerServices {
100-
beacon_provider,
101-
certificate_handler,
102-
chain_observer,
103-
digester,
104-
single_signer,
105-
stake_store,
106-
protocol_initializer_store,
107-
};
10866
let mut state_machine = StateMachine::new(
10967
SignerState::Unregistered,
110-
Box::new(SignerRunner::new(config.clone(), services)),
68+
Box::new(SignerRunner::new(
69+
config.clone(),
70+
ProductionServiceBuilder::new(&config).build()?,
71+
)),
11172
Duration::from_millis(config.run_interval),
11273
);
11374
state_machine.run().await

mithril-signer/src/protocol_initializer_store.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,35 @@ pub enum ProtocolInitializerStoreError {
1515
}
1616

1717
#[async_trait]
18+
/// Store the ProtocolInitializer used for each Epoch. This is useful because
19+
/// protocol parameters and stake distribution change over time.
1820
pub trait ProtocolInitializerStorer: Sync + Send {
21+
/// Save a protocol initializer for the given Epoch.
1922
async fn save_protocol_initializer(
2023
&self,
2124
epoch: Epoch,
2225
protocol_initializer: ProtocolInitializer,
2326
) -> Result<Option<ProtocolInitializer>, ProtocolInitializerStoreError>;
2427

28+
/// Fetch a protocol initializer if any saved for the given Epoch.
2529
async fn get_protocol_initializer(
2630
&self,
2731
epoch: Epoch,
2832
) -> Result<Option<ProtocolInitializer>, ProtocolInitializerStoreError>;
2933

34+
/// Return the list of the N last saved protocol initializers if any.
3035
async fn get_last_protocol_initializer(
3136
&self,
3237
last: usize,
3338
) -> Result<Vec<(Epoch, ProtocolInitializer)>, ProtocolInitializerStoreError>;
3439
}
40+
/// Implementation of the ProtocolInitializerStorer
3541
pub struct ProtocolInitializerStore {
3642
adapter: RwLock<Adapter>,
3743
}
3844

3945
impl ProtocolInitializerStore {
46+
/// Create a new ProtocolInitializerStore.
4047
pub fn new(adapter: Adapter) -> Self {
4148
Self {
4249
adapter: RwLock::new(adapter),

mithril-signer/src/runtime/runner.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,73 +20,91 @@ use crate::{Config, MithrilProtocolInitializerBuilder};
2020

2121
use super::signer_services::SignerServices;
2222

23+
/// This trait is mainly intended for mocking.
2324
#[async_trait]
2425
pub trait Runner {
26+
/// Fetch the current pending certificate if any.
2527
async fn get_pending_certificate(
2628
&self,
2729
) -> Result<Option<CertificatePending>, Box<dyn StdError + Sync + Send>>;
2830

31+
/// Fetch the current beacon from the Cardano node.
2932
async fn get_current_beacon(&self) -> Result<Beacon, Box<dyn StdError + Sync + Send>>;
3033

34+
/// Register the signer verification key to the aggregator.
3135
async fn register_signer_to_aggregator(
3236
&self,
3337
epoch: Epoch,
3438
protocol_parameters: &ProtocolParameters,
3539
) -> Result<(), Box<dyn StdError + Sync + Send>>;
3640

41+
/// Read the stake distribution and store it.
3742
async fn update_stake_distribution(
3843
&self,
3944
epoch: Epoch,
4045
) -> Result<(), Box<dyn StdError + Sync + Send>>;
4146

47+
/// Check if all prerequisites for signing are met.
4248
async fn can_i_sign(
4349
&self,
4450
pending_certificate: &CertificatePending,
4551
) -> Result<bool, Box<dyn StdError + Sync + Send>>;
4652

53+
/// From a list of signers, associate them with the stake read on the
54+
/// Cardano node.
4755
async fn associate_signers_with_stake(
4856
&self,
4957
epoch: Epoch,
5058
signers: &[Signer],
5159
) -> Result<Vec<SignerWithStake>, Box<dyn StdError + Sync + Send>>;
5260

61+
/// Create the message to be signed with the single signature.
5362
async fn compute_message(
5463
&self,
5564
beacon: &Beacon,
5665
next_signers: &[SignerWithStake],
5766
) -> Result<ProtocolMessage, Box<dyn StdError + Sync + Send>>;
5867

68+
/// Create the single signature.
5969
async fn compute_single_signature(
6070
&self,
6171
epoch: Epoch,
6272
message: &ProtocolMessage,
6373
signers: &[SignerWithStake],
6474
) -> Result<Option<SingleSignatures>, Box<dyn StdError + Sync + Send>>;
6575

76+
/// Send the single signature to the aggregator in order to be aggregated.
6677
async fn send_single_signature(
6778
&self,
6879
maybe_signature: Option<SingleSignatures>,
6980
) -> Result<(), Box<dyn StdError + Sync + Send>>;
7081
}
7182

83+
/// This type represents the errors thrown from the Runner.
7284
#[derive(Debug, Clone, PartialEq, Eq, Error)]
7385
pub enum RuntimeError {
86+
/// Value was expected from a subsystem but None was returned.
7487
#[error("No value returned by the subsystem for `{0}`.")]
7588
NoValueError(String),
89+
/// Could not associate my node with a stake.
7690
#[error("No stake associated with myself.")]
7791
NoStakeForSelf(),
92+
/// Could not find the stake for one of the signers.
7893
#[error("No stake associated with this signer, party_id: {0}.")]
7994
NoStakeForSigner(PartyId),
95+
/// General subsystem error
8096
#[error("Subsystem unavailable: {0}.")]
8197
SubsystemUnavailable(String),
8298
}
8399

100+
/// Controller methods for the Signer's state machine.
84101
pub struct SignerRunner {
85102
config: Config,
86103
services: SignerServices,
87104
}
88105

89106
impl SignerRunner {
107+
/// Create a new Runner instance.
90108
pub fn new(config: Config, services: SignerServices) -> Self {
91109
Self { services, config }
92110
}

0 commit comments

Comments
 (0)