Skip to content

Commit

Permalink
Add Signed Entity Type to Pending Certificate
Browse files Browse the repository at this point in the history
  • Loading branch information
jpraynaud committed Apr 19, 2023
1 parent 3cf962a commit 372bfa5
Show file tree
Hide file tree
Showing 14 changed files with 81 additions and 30 deletions.
3 changes: 1 addition & 2 deletions mithril-aggregator/src/certifier_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use async_trait::async_trait;
use chrono::Utc;
use mithril_common::crypto_helper::{key_encode_hex, PROTOCOL_VERSION};
use mithril_common::entities::{
Certificate, CertificateMetadata, Epoch, ProtocolMessage, SignedEntityType, SignerWithStake,
SingleSignatures,
Certificate, CertificateMetadata, Epoch, ProtocolMessage, SignedEntityType, SingleSignatures,
};
use mithril_common::StdResult;
use slog::Logger;
Expand Down
2 changes: 1 addition & 1 deletion mithril-aggregator/src/database/provider/open_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ impl OpenMessageWithSingleSignatures {
pub fn get_signers_id(&self) -> Vec<PartyId> {
self.single_signatures
.iter()
.map(|sig| sig.party_id)
.map(|sig| sig.party_id.to_owned())
.collect()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ impl ToCertificatePendingMessageAdapter {
pub fn adapt(certificate_pending: CertificatePending) -> CertificatePendingMessage {
CertificatePendingMessage {
beacon: certificate_pending.beacon,
signed_entity_type: serde_json::to_string(&certificate_pending.signed_entity_type)
.unwrap(),
protocol_parameters: certificate_pending.protocol_parameters,
next_protocol_parameters: certificate_pending.next_protocol_parameters,
signers: Self::adapt_signers(certificate_pending.signers),
Expand Down Expand Up @@ -55,7 +57,7 @@ mod tests {
let certificate_pending = CertificatePending {
signers,
next_signers,
..Default::default()
..fake_data::certificate_pending()
};
let message = ToCertificatePendingMessageAdapter::adapt(certificate_pending);

Expand Down
17 changes: 13 additions & 4 deletions mithril-aggregator/src/runtime/runner.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use async_trait::async_trait;
use chrono::Utc;
use mithril_common::crypto_helper::key_decode_hex;
use mithril_common::crypto_helper::ProtocolMultiSignature;
use mithril_common::entities::Epoch;
use mithril_common::entities::PartyId;
Expand Down Expand Up @@ -117,6 +118,7 @@ pub trait AggregatorRunnerTrait: Sync + Send {
async fn create_new_pending_certificate_from_multisigner(
&self,
beacon: Beacon,
signed_entity_type: &SignedEntityType,
) -> Result<CertificatePending, Box<dyn StdError + Sync + Send>>;

/// Return the actual working certificate from the multisigner.
Expand Down Expand Up @@ -433,6 +435,7 @@ impl AggregatorRunnerTrait for AggregatorRunner {
async fn create_new_pending_certificate_from_multisigner(
&self,
beacon: Beacon,
signed_entity_type: &SignedEntityType,
) -> Result<CertificatePending, Box<dyn StdError + Sync + Send>> {
debug!("RUNNER: create new pending certificate from multisigner");
let multi_signer = self.dependencies.multi_signer.read().await;
Expand Down Expand Up @@ -469,6 +472,7 @@ impl AggregatorRunnerTrait for AggregatorRunner {

let pending_certificate = CertificatePending::new(
beacon,
signed_entity_type.to_owned(),
protocol_parameters.into(),
next_protocol_parameters.into(),
signers,
Expand Down Expand Up @@ -564,7 +568,8 @@ impl AggregatorRunnerTrait for AggregatorRunner {
.create_certificate(signed_entity_type)
.await?;

Ok(certificate)
// TODO: Quickfix, this function should be renamed to create_certificate and retrun a Result<Certificate>
Ok(certificate.map(|c| key_decode_hex(&c.multi_signature).unwrap()))
}

async fn create_snapshot_archive(
Expand Down Expand Up @@ -745,7 +750,8 @@ pub mod tests {
};
use mithril_common::digesters::DumbImmutableFileObserver;
use mithril_common::entities::{
Beacon, CertificatePending, HexEncodedKey, ProtocolMessage, StakeDistribution,
Beacon, CertificatePending, HexEncodedKey, ProtocolMessage, SignedEntityType,
StakeDistribution,
};
use mithril_common::store::StakeStorer;
use mithril_common::test_utils::MithrilFixtureBuilder;
Expand Down Expand Up @@ -961,6 +967,7 @@ pub mod tests {
let runner = AggregatorRunner::new(config, deps.clone());
let beacon = runner.get_beacon_from_chain().await.unwrap();
runner.update_beacon(&beacon).await.unwrap();
let signed_entity_type = SignedEntityType::dummy();

let fixture = MithrilFixtureBuilder::default().with_signers(5).build();
let current_signers = fixture.signers_with_stake()[1..3].to_vec();
Expand All @@ -974,13 +981,14 @@ pub mod tests {
.await;

let mut certificate = runner
.create_new_pending_certificate_from_multisigner(beacon.clone())
.create_new_pending_certificate_from_multisigner(beacon.clone(), &signed_entity_type)
.await
.unwrap();
certificate.signers.sort_by_key(|s| s.party_id.clone());
certificate.next_signers.sort_by_key(|s| s.party_id.clone());
let mut expected = CertificatePending::new(
beacon,
signed_entity_type,
protocol_parameters.clone(),
protocol_parameters,
current_signers.into_iter().map(|s| s.into()).collect(),
Expand All @@ -999,6 +1007,7 @@ pub mod tests {
let runner = AggregatorRunner::new(config, deps.clone());
let beacon = runner.get_beacon_from_chain().await.unwrap();
runner.update_beacon(&beacon).await.unwrap();
let signed_entity_type = SignedEntityType::dummy();

let fixture = MithrilFixtureBuilder::default().with_signers(5).build();

Expand Down Expand Up @@ -1031,7 +1040,7 @@ pub mod tests {
.unwrap();

let certificate_pending = runner
.create_new_pending_certificate_from_multisigner(beacon.clone())
.create_new_pending_certificate_from_multisigner(beacon.clone(), &signed_entity_type)
.await
.unwrap();

Expand Down
13 changes: 9 additions & 4 deletions mithril-aggregator/src/runtime/state_machine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::runtime::{AggregatorRunnerTrait, RuntimeError, WorkingCertificate};

use mithril_common::entities::Beacon;
use mithril_common::entities::{Beacon, SignedEntityType};
use slog_scope::{crit, info, trace, warn};
use std::fmt::Display;
use std::sync::Arc;
Expand Down Expand Up @@ -324,6 +324,8 @@ impl AggregatorRuntime {
new_beacon: Beacon,
) -> Result<SigningState, RuntimeError> {
trace!("launching transition from READY to SIGNING state");
// TODO: Temporary, we need to compute the signed entity type from the current open message
let signed_entity_type = SignedEntityType::CardanoImmutableFilesFull(new_beacon.clone());
self.runner.update_beacon(&new_beacon).await?;

let digester_result = self.runner.compute_digest(&new_beacon).await?;
Expand All @@ -332,7 +334,10 @@ impl AggregatorRuntime {
.await?;
let certificate_pending = self
.runner
.create_new_pending_certificate_from_multisigner(new_beacon.clone())
.create_new_pending_certificate_from_multisigner(
new_beacon.clone(),
&signed_entity_type,
)
.await?;
self.runner
.save_pending_certificate(certificate_pending.clone())
Expand Down Expand Up @@ -584,9 +589,9 @@ mod tests {
.returning(|_| Ok(()));
runner
.expect_create_new_pending_certificate_from_multisigner()
.with(predicate::eq(fake_data::beacon()))
//.with(predicate::eq(fake_data::beacon()))
.once()
.returning(|_| Ok(fake_data::certificate_pending()));
.returning(|_, _| Ok(fake_data::certificate_pending()));
runner
.expect_create_new_working_certificate()
.once()
Expand Down
5 changes: 4 additions & 1 deletion mithril-aggregator/src/store/pending_certificate_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ impl CertificatePendingStore {
mod test {
use super::*;

use mithril_common::entities::Beacon;
use mithril_common::entities::{Beacon, SignedEntityType};
use mithril_common::store::adapter::DumbStoreAdapter;
use mithril_common::test_utils::fake_data;

Expand All @@ -67,6 +67,7 @@ mod test {
let beacon = Beacon::new("testnet".to_string(), 0, 0);
let certificate_pending = CertificatePending::new(
beacon.clone(),
SignedEntityType::dummy(),
fake_data::protocol_parameters(),
fake_data::protocol_parameters(),
fake_data::signers(4),
Expand Down Expand Up @@ -100,8 +101,10 @@ mod test {
async fn save_certificate_pending_once() {
let store = get_certificate_pending_store(false).await;
let beacon = Beacon::new("testnet".to_string(), 0, 1);
let signed_entity_type = SignedEntityType::dummy();
let certificate_pending = CertificatePending::new(
beacon,
signed_entity_type,
fake_data::protocol_parameters(),
fake_data::protocol_parameters(),
fake_data::signers(1),
Expand Down
9 changes: 8 additions & 1 deletion mithril-common/src/entities/certificate_pending.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
use crate::entities::{Beacon, PartyId, ProtocolParameters, Signer};
use serde::{Deserialize, Serialize};

use super::SignedEntityType;

/// CertificatePending represents a pending certificate in the process of production
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct CertificatePending {
/// Current Beacon
pub beacon: Beacon,

/// Signed entity type
pub signed_entity_type: SignedEntityType,

/// Current Protocol parameters
#[serde(rename = "protocol")]
pub protocol_parameters: ProtocolParameters,
Expand All @@ -26,13 +31,15 @@ impl CertificatePending {
/// CertificatePending factory
pub fn new(
beacon: Beacon,
signed_entity_type: SignedEntityType,
protocol_parameters: ProtocolParameters,
next_protocol_parameters: ProtocolParameters,
signers: Vec<Signer>,
next_signers: Vec<Signer>,
) -> CertificatePending {
CertificatePending {
beacon,
signed_entity_type,
protocol_parameters,
next_protocol_parameters,
signers,
Expand Down
3 changes: 2 additions & 1 deletion mithril-common/src/entities/signed_entity_type.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use serde::{Deserialize, Serialize};
use strum_macros::Display;

use crate::{sqlite::HydrationError, StdError};
Expand All @@ -19,7 +20,7 @@ const ENTITY_TYPE_CARDANO_IMMUTABLE_FILES_FULL: usize = 2;
/// are identified by their discriminant (i.e. index in the enum), thus the
/// modification of this type should only ever consist of appending new
/// variants.
#[derive(Display, Debug, Clone, PartialEq, Eq)]
#[derive(Display, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[strum(serialize_all = "PascalCase")]
pub enum SignedEntityType {
/// Mithril stake distribution
Expand Down
20 changes: 14 additions & 6 deletions mithril-common/src/messages/certificate_pending.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
crypto_helper::KESPeriod,
entities::{
Beacon, HexEncodedOpCert, HexEncodedVerificationKey, HexEncodedVerificationKeySignature,
PartyId, ProtocolParameters,
PartyId, ProtocolParameters, SignedEntityType,
},
};

Expand All @@ -14,6 +14,10 @@ pub struct CertificatePendingMessage {
/// Current Beacon
pub beacon: Beacon,

/// Signed entity type
#[serde(rename = "entity_type")]
pub signed_entity_type: String,

/// Current Protocol parameters
#[serde(rename = "protocol")]
pub protocol_parameters: ProtocolParameters,
Expand All @@ -34,6 +38,7 @@ impl CertificatePendingMessage {
pub fn dummy() -> Self {
Self {
beacon: Beacon::default(),
signed_entity_type: serde_json::to_string(&SignedEntityType::dummy()).unwrap(),
protocol_parameters: ProtocolParameters {
k: 5,
m: 100,
Expand Down Expand Up @@ -101,12 +106,14 @@ mod tests {
use super::*;

fn golden_message() -> CertificatePendingMessage {
let beacon = Beacon {
network: "preview".to_string(),
epoch: Epoch(86),
immutable_file_number: 1728,
};
CertificatePendingMessage {
beacon: Beacon {
network: "preview".to_string(),
epoch: Epoch(86),
immutable_file_number: 1728,
},
beacon: beacon.clone(),
signed_entity_type: serde_json::to_string(&SignedEntityType::CardanoImmutableFilesFull(beacon)).unwrap(),
protocol_parameters: ProtocolParameters {
k: 5,
m: 100,
Expand All @@ -126,6 +133,7 @@ mod tests {
fn test_v1() {
let json = r#"{
"beacon": {"network": "preview", "epoch": 86, "immutable_file_number": 1728 },
"entity_type": "{\"CardanoImmutableFilesFull\":{\"network\":\"preview\",\"epoch\":86,\"immutable_file_number\":1728}}",
"protocol": {"k": 5, "m": 100, "phi_f": 0.65 },
"next_protocol": {"k": 50, "m": 1000, "phi_f": 0.65 },
"signers": [{"party_id": "123", "verification_key": "7b22766b223a5b3134332c3136312c3235352c34382c37382c35372c3230342c3232302c32352c3232312c3136342c3235322c3234382c31342c35362c3132362c3138362c3133352c3232382c3138382c3134352c3138312c35322c3230302c39372c39392c3231332c34362c302c3139392c3139332c38392c3138372c38382c32392c3133352c3137332c3234342c38362c33362c38332c35342c36372c3136342c362c3133372c39342c37322c362c3130352c3132382c3132382c39332c34382c3137362c31312c342c3234362c3133382c34382c3138302c3133332c39302c3134322c3139322c32342c3139332c3131312c3134322c33312c37362c3131312c3131302c3233342c3135332c39302c3230382c3139322c33312c3132342c39352c3130322c34392c3135382c39392c35322c3232302c3136352c39342c3235312c36382c36392c3132312c31362c3232342c3139345d2c22706f70223a5b3136382c35302c3233332c3139332c31352c3133362c36352c37322c3132332c3134382c3132392c3137362c33382c3139382c3230392c34372c32382c3230342c3137362c3134342c35372c3235312c34322c32382c36362c37362c38392c39372c3135382c36332c35342c3139382c3139342c3137362c3133352c3232312c31342c3138352c3139372c3232352c3230322c39382c3234332c37342c3233332c3232352c3134332c3135312c3134372c3137372c3137302c3131372c36362c3136352c36362c36322c33332c3231362c3233322c37352c36382c3131342c3139352c32322c3130302c36352c34342c3139382c342c3136362c3130322c3233332c3235332c3234302c35392c3137352c36302c3131372c3134322c3131342c3134302c3132322c31372c38372c3131302c3138372c312c31372c31302c3139352c3135342c31332c3234392c38362c35342c3232365d7d"}],
Expand Down
7 changes: 6 additions & 1 deletion mithril-common/src/test_utils/fake_data.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Fake data builders for testing.
use crate::entities::{
CertificateMetadata, LotteryIndex, ProtocolMessage, ProtocolMessagePartKey, SingleSignatures,
CertificateMetadata, LotteryIndex, ProtocolMessage, ProtocolMessagePartKey, SignedEntityType,
SingleSignatures,
};
use crate::{crypto_helper, entities};

Expand Down Expand Up @@ -53,6 +54,9 @@ pub fn certificate_pending() -> entities::CertificatePending {
// Beacon
let beacon = beacon();

// Signed entity type
let signed_entity_type = SignedEntityType::dummy();

// Protocol parameters
let next_protocol_parameters = protocol_parameters();
let protocol_parameters = protocol_parameters();
Expand All @@ -65,6 +69,7 @@ pub fn certificate_pending() -> entities::CertificatePending {
// Certificate pending
entities::CertificatePending::new(
beacon,
signed_entity_type,
protocol_parameters,
next_protocol_parameters,
current_signers,
Expand Down
6 changes: 5 additions & 1 deletion mithril-signer/src/certificate_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,11 @@ impl CertificateHandler for CertificateHandlerHTTPClient {
match response {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<CertificatePendingMessage>().await {
Ok(message) => Ok(Some(FromPendingCertificateMessageAdapter::adapt(message))),
Ok(message) => Ok(Some(
FromPendingCertificateMessageAdapter::adapt(message).map_err(|err| {
CertificateHandlerError::JsonParseFailed(err.to_string())
})?,
)),
Err(err) => Err(CertificateHandlerError::JsonParseFailed(err.to_string())),
},
StatusCode::PRECONDITION_FAILED => Err(self.handle_api_error(&response)),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
use mithril_common::{
entities::{CertificatePending, Signer},
messages::{CertificatePendingMessage, SignerMessage},
StdResult,
};

/// Adapter to turn [CertificatePendingMessage] instances into [CertificatePending].
pub struct FromPendingCertificateMessageAdapter;

impl FromPendingCertificateMessageAdapter {
/// Adapter method
pub fn adapt(message: CertificatePendingMessage) -> CertificatePending {
CertificatePending {
pub fn adapt(message: CertificatePendingMessage) -> StdResult<CertificatePending> {
Ok(CertificatePending {
beacon: message.beacon,
signed_entity_type: serde_json::from_str(&message.signed_entity_type)?,
protocol_parameters: message.protocol_parameters,
next_protocol_parameters: message.next_protocol_parameters,
signers: Self::adapt_signers(message.signers),
next_signers: Self::adapt_signers(message.next_signers),
}
})
}

fn adapt_signers(signer_messages: Vec<SignerMessage>) -> Vec<Signer> {
Expand All @@ -40,7 +42,7 @@ mod tests {
fn adapt_ok() {
let message = CertificatePendingMessage::dummy();
let epoch = message.beacon.epoch;
let certificate_pending = FromPendingCertificateMessageAdapter::adapt(message);
let certificate_pending = FromPendingCertificateMessageAdapter::adapt(message).unwrap();

assert_eq!(epoch, certificate_pending.beacon.epoch);
}
Expand All @@ -49,7 +51,7 @@ mod tests {
fn adapt_signers() {
let mut message = CertificatePendingMessage::dummy();
message.signers = vec![SignerMessage::dummy(), SignerMessage::dummy()];
let certificate_pending = FromPendingCertificateMessageAdapter::adapt(message);
let certificate_pending = FromPendingCertificateMessageAdapter::adapt(message).unwrap();

assert_eq!(2, certificate_pending.signers.len());
assert_eq!(1, certificate_pending.next_signers.len());
Expand Down
Loading

0 comments on commit 372bfa5

Please sign in to comment.