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

Refactor: signable builder services compute full protocol message #1942

Merged
merged 33 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a81db87
feat: introduce SignableSeedBuilder trait
jpraynaud Sep 20, 2024
01e6ac8
feat: make SignableBuilder service use SignableSeedBuilder
jpraynaud Sep 20, 2024
1e0afa7
chore: adapt CardanoTransactionsSignableBuilder to updated SignableBu…
jpraynaud Sep 20, 2024
e4d4a4e
chore: adapt CardanoImmutableFilesFullSignableBuilder to updated Sign…
jpraynaud Sep 20, 2024
ca183be
chore: adapt CardanoStakeDistributionSignableBuilder to updated Signa…
jpraynaud Sep 20, 2024
5e3a66c
chore: adapt MithrilStakeDistributionSignableBuilder to updated Signa…
jpraynaud Sep 20, 2024
6a7b554
feat: add SignableSeedBuilderService in aggregator
jpraynaud Sep 20, 2024
0336a6c
feat: wire SignableSeedBuilderService in aggregator DI
jpraynaud Sep 20, 2024
8fffd14
chore: remove ad hoc signature of next avk for protocol message in ag…
jpraynaud Sep 20, 2024
1e12457
chore: remove ad hoc signature of next avk for protocol message in ag…
jpraynaud Sep 20, 2024
8aa4db1
feat: add SignableSeedBuilderService in signer
jpraynaud Sep 20, 2024
6459e95
feat: wire SignableSeedBuilderService in signer DI
jpraynaud Sep 20, 2024
aed8c61
chore: remove ad hoc signature of next avk for protocol message in si…
jpraynaud Sep 20, 2024
e3059bf
chore: remove ad hoc signature of next avk for protocol message in si…
jpraynaud Sep 20, 2024
a06a6d1
test: add missing test for SignableSeedBuilder in aggregator
jpraynaud Sep 23, 2024
0e3b172
test: add missing test for SignableSeedBuilder in signer
jpraynaud Sep 23, 2024
637868b
refactor: add Mock DI container in SignableBuilderService tests
jpraynaud Sep 23, 2024
f080739
chore: apply review comments
jpraynaud Sep 24, 2024
88ae081
refactor: migrate EpochService mock in epoch service
jpraynaud Sep 24, 2024
e30164e
refactor: remove seed protocol message from signable builder
jpraynaud Sep 24, 2024
64dca07
refactor: make signable seed builder use an existing protocol message
jpraynaud Sep 24, 2024
8af7ef7
refactor: make signable seed builder compute protocol message part va…
jpraynaud Sep 24, 2024
695f694
refactor: rename 'SignableSeedBuilderService' to 'AggregatorSignableS…
jpraynaud Sep 24, 2024
cc2d75f
refactor: rename 'SignableSeedBuilderService' to 'SignerSignableSeedB…
jpraynaud Sep 24, 2024
16a3ea0
fixup refactor: make signable seed builder compute protocol message p…
jpraynaud Sep 24, 2024
5c196f5
refactor: move SignableSeedBuilder in a dedicated 'signable_builder' …
jpraynaud Sep 24, 2024
917a18c
refactor: move SignableSeedBuilder in a dedicated 'signable_builder' …
jpraynaud Sep 24, 2024
c2a0f0e
fix: handle merge conflicts with main branch
jpraynaud Sep 24, 2024
bdc3ad6
refactor: remove mentions to SignableSeedBuilder service in aggregato…
jpraynaud Sep 24, 2024
aecd8e3
refactor: remove unused custom mock implementation in SignabeBuilder …
jpraynaud Sep 24, 2024
f4c22a1
refactor: rename 'mock' sub module of Epoch Service in 'mock_epoch_se…
jpraynaud Sep 24, 2024
46bfc03
docs: update CHANGELOG
jpraynaud Sep 24, 2024
71fef49
chore: bump crates versions
jpraynaud Sep 24, 2024
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: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ As a minor extension, we have adopted a slightly different versioning convention

- Support for signing the protocol parameters in the Genesis certificate.

- Refactor the builder of the protocol messages to be signed.

- Crates versions:

| Crate | Version |
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mithril-aggregator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-aggregator"
version = "0.5.67"
version = "0.5.68"
description = "A Mithril Aggregator server"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
41 changes: 33 additions & 8 deletions mithril-aggregator/src/dependency_injection/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ use mithril_common::{
signable_builder::{
CardanoImmutableFilesFullSignableBuilder, CardanoStakeDistributionSignableBuilder,
CardanoTransactionsSignableBuilder, MithrilSignableBuilderService,
MithrilStakeDistributionSignableBuilder, SignableBuilderService, TransactionsImporter,
MithrilStakeDistributionSignableBuilder, SignableBuilderService, SignableSeedBuilder,
TransactionsImporter,
},
signed_entity_type_lock::SignedEntityTypeLock,
MithrilTickerService, TickerService,
Expand All @@ -66,11 +67,11 @@ use crate::{
event_store::{EventMessage, EventStore, TransmitterService},
http_server::routes::router,
services::{
AggregatorUpkeepService, BufferedCertifierService, CardanoTransactionsImporter,
CertifierService, MessageService, MithrilCertifierService, MithrilEpochService,
MithrilMessageService, MithrilProverService, MithrilSignedEntityService,
MithrilStakeDistributionService, ProverService, SignedEntityService,
StakeDistributionService, UpkeepService,
AggregatorSignableSeedBuilder, AggregatorUpkeepService, BufferedCertifierService,
CardanoTransactionsImporter, CertifierService, MessageService, MithrilCertifierService,
MithrilEpochService, MithrilMessageService, MithrilProverService,
MithrilSignedEntityService, MithrilStakeDistributionService, ProverService,
SignedEntityService, StakeDistributionService, UpkeepService,
},
tools::{CExplorerSignerRetriever, GcpFileUploader, GenesisToolsDependency, SignersImporter},
AggregatorConfig, AggregatorRunner, AggregatorRuntime, CertificatePendingStore,
Expand Down Expand Up @@ -202,6 +203,9 @@ pub struct DependenciesBuilder {
/// Signer Store
pub signer_store: Option<Arc<SignerStore>>,

/// Signable Seed Builder
pub signable_seed_builder: Option<Arc<dyn SignableSeedBuilder>>,

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

Expand Down Expand Up @@ -274,6 +278,7 @@ impl DependenciesBuilder {
stake_distribution_service: None,
ticker_service: None,
signer_store: None,
signable_seed_builder: None,
signable_builder_service: None,
signed_entity_service: None,
certifier_service: None,
Expand Down Expand Up @@ -1079,6 +1084,7 @@ impl DependenciesBuilder {
}

async fn build_signable_builder_service(&mut self) -> Result<Arc<dyn SignableBuilderService>> {
let seed_signable_builder = self.get_signable_seed_builder().await?;
let mithril_stake_distribution_builder =
Arc::new(MithrilStakeDistributionSignableBuilder::default());
let immutable_signable_builder = Arc::new(CardanoImmutableFilesFullSignableBuilder::new(
Expand All @@ -1099,6 +1105,7 @@ impl DependenciesBuilder {
CardanoStakeDistributionSignableBuilder::new(self.get_stake_store().await?),
);
let signable_builder_service = Arc::new(MithrilSignableBuilderService::new(
seed_signable_builder,
mithril_stake_distribution_builder,
immutable_signable_builder,
cardano_transactions_builder,
Expand All @@ -1119,11 +1126,29 @@ impl DependenciesBuilder {
Ok(self.signable_builder_service.as_ref().cloned().unwrap())
}

async fn build_signable_seed_builder(&mut self) -> Result<Arc<dyn SignableSeedBuilder>> {
let signable_seed_builder_service = Arc::new(AggregatorSignableSeedBuilder::new(
self.get_epoch_service().await?,
));

Ok(signable_seed_builder_service)
}

/// [SignableSeedBuilder] service
pub async fn get_signable_seed_builder(&mut self) -> Result<Arc<dyn SignableSeedBuilder>> {
if self.signable_seed_builder.is_none() {
self.signable_seed_builder = Some(self.build_signable_seed_builder().await?);
}

Ok(self.signable_seed_builder.as_ref().cloned().unwrap())
}

async fn build_signed_entity_service(&mut self) -> Result<Arc<dyn SignedEntityService>> {
let signed_entity_storer = self.build_signed_entity_storer().await?;
let epoch_service = self.get_epoch_service().await?;
let mithril_stake_distribution_artifact_builder =
Arc::new(MithrilStakeDistributionArtifactBuilder::new(epoch_service));
let mithril_stake_distribution_artifact_builder = Arc::new(
MithrilStakeDistributionArtifactBuilder::new(epoch_service.clone()),
);
let snapshotter = self.build_snapshotter().await?;
let snapshot_uploader = self.build_snapshot_uploader().await?;
let cardano_node_version = Version::parse(&self.configuration.cardano_node_version)
Expand Down
15 changes: 3 additions & 12 deletions mithril-aggregator/src/runtime/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::sync::Arc;
use std::time::Duration;

use mithril_common::entities::{
Certificate, CertificatePending, Epoch, ProtocolMessage, ProtocolMessagePartKey,
SignedEntityConfig, SignedEntityType, Signer, TimePoint,
Certificate, CertificatePending, Epoch, ProtocolMessage, SignedEntityConfig, SignedEntityType,
Signer, TimePoint,
};
use mithril_common::StdResult;
use mithril_persistence::store::StakeStorer;
Expand Down Expand Up @@ -284,22 +284,13 @@ impl AggregatorRunnerTrait for AggregatorRunner {
signed_entity_type: &SignedEntityType,
) -> StdResult<ProtocolMessage> {
debug!("RUNNER: compute protocol message");
let mut protocol_message = self
let protocol_message = self
.dependencies
.signable_builder_service
.compute_protocol_message(signed_entity_type.to_owned())
.await
.with_context(|| format!("Runner can not compute protocol message for signed entity type: '{signed_entity_type}'"))?;

let epoch_service = self.dependencies.epoch_service.read().await;
protocol_message.set_message_part(
ProtocolMessagePartKey::NextAggregateVerificationKey,
epoch_service
.next_aggregate_verification_key()?
.to_json_hex()
.with_context(|| "convert next avk to json hex failure")?,
);

Ok(protocol_message)
}

Expand Down
2 changes: 2 additions & 0 deletions mithril-aggregator/src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod certifier;
mod epoch_service;
mod message;
mod prover;
mod signable_builder;
mod signed_entity;
mod stake_distribution;
mod upkeep;
Expand All @@ -23,6 +24,7 @@ pub use certifier::*;
pub use epoch_service::*;
pub use message::*;
pub use prover::*;
pub use signable_builder::*;
pub use signed_entity::*;
pub use stake_distribution::*;
pub use upkeep::*;
3 changes: 3 additions & 0 deletions mithril-aggregator/src/services/signable_builder/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod signable_seed_builder;

pub use signable_seed_builder::*;
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! ## AggregatorSignableSeedBuilder
//!
//! This service is responsible for computing the seed protocol message
//! that is used by the [SignableBuilder] to compute the final protocol message.
//!
use anyhow::Context;
use async_trait::async_trait;
use std::sync::Arc;
use tokio::sync::RwLock;

use mithril_common::{
entities::ProtocolMessagePartValue, signable_builder::SignableSeedBuilder, StdResult,
};

use crate::services::EpochService;

/// SignableSeedBuilder aggregator implementation
pub struct AggregatorSignableSeedBuilder {
epoch_service: Arc<RwLock<dyn EpochService>>,
}

impl AggregatorSignableSeedBuilder {
/// AggregatorSignableSeedBuilder factory
pub fn new(epoch_service: Arc<RwLock<dyn EpochService>>) -> Self {
Self { epoch_service }
}
}

#[async_trait]
impl SignableSeedBuilder for AggregatorSignableSeedBuilder {
async fn compute_next_aggregate_verification_key_protocol_message_part_value(
&self,
) -> StdResult<ProtocolMessagePartValue> {
let epoch_service = self.epoch_service.read().await;
let next_aggregate_verification_key = (*epoch_service)
.next_aggregate_verification_key()?
.to_json_hex()
.with_context(|| "convert next avk to json hex failure")?
.to_string();

Ok(next_aggregate_verification_key)
}
}

#[cfg(test)]
mod tests {
use mithril_common::{entities::Epoch, test_utils::MithrilFixtureBuilder};

use crate::services::FakeEpochService;

use super::*;

#[tokio::test]
async fn test_compute_next_aggregate_verification_key_protocol_message_value() {
let epoch = Epoch(5);
let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
let next_fixture = MithrilFixtureBuilder::default().with_signers(4).build();
let expected_next_aggregate_verification_key = next_fixture.compute_and_encode_avk();
let epoch_service = Arc::new(RwLock::new(FakeEpochService::with_data(
epoch,
&fixture.protocol_parameters(),
&next_fixture.protocol_parameters(),
&next_fixture.protocol_parameters(),
&fixture.signers_with_stake(),
&next_fixture.signers_with_stake(),
)));
let signable_seed_builder = AggregatorSignableSeedBuilder::new(epoch_service);

let next_aggregate_verification_key = signable_seed_builder
.compute_next_aggregate_verification_key_protocol_message_part_value()
.await
.unwrap();

assert_eq!(
next_aggregate_verification_key,
expected_next_aggregate_verification_key
);
}
}
18 changes: 3 additions & 15 deletions mithril-aggregator/tests/test_extensions/runtime_tester.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use mithril_common::{
digesters::{DumbImmutableDigester, DumbImmutableFileObserver},
entities::{
BlockNumber, Certificate, CertificateSignature, ChainPoint, Epoch, ImmutableFileNumber,
ProtocolMessagePartKey, SignedEntityType, SignedEntityTypeDiscriminants,
SingleSignatureAuthenticationStatus, SlotNumber, Snapshot, StakeDistribution, TimePoint,
SignedEntityType, SignedEntityTypeDiscriminants, SingleSignatureAuthenticationStatus,
SlotNumber, Snapshot, StakeDistribution, TimePoint,
},
era::{adapters::EraReaderDummyAdapter, EraMarker, EraReader, SupportedEra},
test_utils::{
Expand Down Expand Up @@ -417,24 +417,12 @@ impl RuntimeTester {
.build_current_signed_entity_type(discriminant)
.await?;

// Code copied from `AggregatorRunner::compute_protocol_message`
// Todo: Refactor this code to avoid code duplication by making the signable_builder_service
// able to retrieve the next avk by itself.
let mut message = self
let message = self
.dependencies
.signable_builder_service
.compute_protocol_message(signed_entity_type.clone())
.await?;

let epoch_service = self.dependencies.epoch_service.read().await;
message.set_message_part(
ProtocolMessagePartKey::NextAggregateVerificationKey,
epoch_service
.next_aggregate_verification_key()?
.to_json_hex()
.with_context(|| "convert next avk to json hex failure")?,
);

for signer_fixture in signers {
if let Some(mut single_signatures) = signer_fixture.sign(&message) {
if authentication_status == SingleSignatureAuthenticationStatus::Authenticated {
Expand Down
2 changes: 1 addition & 1 deletion mithril-common/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-common"
version = "0.4.57"
version = "0.4.58"
description = "Common types, interfaces, and utilities for Mithril nodes."
authors = { workspace = true }
edition = { workspace = true }
Expand Down
17 changes: 15 additions & 2 deletions mithril-common/src/signable_builder/interface.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use async_trait::async_trait;
use std::fmt::Debug;

use crate::{entities::ProtocolMessage, StdResult};
use crate::{
entities::{ProtocolMessage, ProtocolMessagePartValue},
StdResult,
};

#[cfg(test)]
use mockall::automock;
Expand All @@ -16,7 +19,7 @@ pub trait Artifact: Debug + Send + Sync {
fn get_id(&self) -> String;
}

/// SignableBuilder is trait for building a protocol message for a beacon
/// SignableBuilder is a trait for building a protocol message for a beacon
#[cfg_attr(test, automock)]
#[async_trait]
pub trait SignableBuilder<U>: Send + Sync
Expand All @@ -26,3 +29,13 @@ where
/// Compute a protocol message
async fn compute_protocol_message(&self, beacon: U) -> StdResult<ProtocolMessage>;
}

/// SignableSeedBuilder is a trait for building seed protocol message part values
#[cfg_attr(test, automock)]
#[async_trait]
pub trait SignableSeedBuilder: Send + Sync {
/// Compute next aggregate verification key protocol message part value
async fn compute_next_aggregate_verification_key_protocol_message_part_value(
&self,
) -> StdResult<ProtocolMessagePartValue>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub struct MithrilStakeDistributionSignableBuilder {}

#[async_trait]
impl SignableBuilder<Epoch> for MithrilStakeDistributionSignableBuilder {
// We just need to return an empty protocol message as the next AVK will be appended by the signing engine automatically
async fn compute_protocol_message(&self, _beacon: Epoch) -> StdResult<ProtocolMessage> {
Ok(ProtocolMessage::new())
}
Expand Down
Loading
Loading