Skip to content

Commit

Permalink
Merge pull request #1571 from input-output-hk/ensemble/1536/provide-l…
Browse files Browse the repository at this point in the history
…atest-immutable-file-number-with-certified-ctx

Provide latest immutable file number with certified ctx
  • Loading branch information
sfauvel authored Mar 19, 2024
2 parents 9622126 + 98e7ee5 commit a52e282
Show file tree
Hide file tree
Showing 227 changed files with 2,945 additions and 4,324 deletions.
81 changes: 64 additions & 17 deletions mithril-aggregator/src/http_server/routes/proof_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ fn proof_cardano_transaction(
}

mod handlers {
use mithril_common::{
entities::{CardanoTransactionsSnapshot, SignedEntity},
messages::CardanoTransactionsProofsMessage,
StdResult,
};
use reqwest::StatusCode;
use slog_scope::{debug, warn};
use std::{convert::Infallible, sync::Arc};
Expand Down Expand Up @@ -72,23 +77,9 @@ mod handlers {
"proof_cardano_transaction::error"
) {
Some(signed_entity) => {
let transactions_set_proofs = unwrap_to_internal_server_error!(
prover_service
.compute_transactions_proofs(
&signed_entity.artifact.beacon,
transaction_hashes.as_slice(),
)
.await,
"proof_cardano_transaction::error"
);

let message = unwrap_to_internal_server_error!(
ToCardanoTransactionsProofsMessageAdapter::try_adapt(
&signed_entity.certificate_id,
transactions_set_proofs,
transaction_hashes,
),
"proof_cardano_transaction::error"
build_response_message(prover_service, signed_entity, transaction_hashes).await,
"proof_cardano_transaction"
);
Ok(reply::json(&message, StatusCode::OK))
}
Expand All @@ -98,14 +89,34 @@ mod handlers {
}
}
}

pub async fn build_response_message(
prover_service: Arc<dyn ProverService>,
signed_entity: SignedEntity<CardanoTransactionsSnapshot>,
transaction_hashes: Vec<String>,
) -> StdResult<CardanoTransactionsProofsMessage> {
let transactions_set_proofs = prover_service
.compute_transactions_proofs(
&signed_entity.artifact.beacon,
transaction_hashes.as_slice(),
)
.await?;
let message = ToCardanoTransactionsProofsMessageAdapter::try_adapt(
signed_entity,
transactions_set_proofs,
transaction_hashes,
)?;

Ok(message)
}
}

#[cfg(test)]
mod tests {
use super::*;
use std::vec;

use mithril_common::test_utils::apispec::APISpec;
use mithril_common::{entities::Beacon, test_utils::apispec::APISpec};

use anyhow::anyhow;
use mithril_common::entities::{
Expand Down Expand Up @@ -136,6 +147,42 @@ mod tests {
.and(routes(dependency_manager).with(cors))
}

#[tokio::test]
async fn build_response_message_return_immutable_file_number_from_artifact_beacon() {
// Arrange
let mut mock_prover_service = MockProverService::new();
mock_prover_service
.expect_compute_transactions_proofs()
.returning(|_, _| Ok(vec![CardanoTransactionsSetProof::dummy()]));

let cardano_transactions_snapshot = {
let merkle_root = String::new();
let beacon = Beacon {
immutable_file_number: 2309,
..Beacon::default()
};
CardanoTransactionsSnapshot::new(merkle_root, beacon)
};

let signed_entity = SignedEntity::<CardanoTransactionsSnapshot> {
artifact: cardano_transactions_snapshot,
..SignedEntity::<CardanoTransactionsSnapshot>::dummy()
};

// Action
let transaction_hashes = vec![];
let message = handlers::build_response_message(
Arc::new(mock_prover_service),
signed_entity,
transaction_hashes,
)
.await
.unwrap();

// Assert
assert_eq!(message.latest_immutable_file_number, 2309)
}

#[tokio::test]
async fn proof_cardano_transaction_ok() {
let config = Configuration::new_sample();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use mithril_common::entities::{CardanoTransactionsSnapshot, SignedEntity};
use mithril_common::messages::CardanoTransactionsSetProofMessagePart;
use mithril_common::{
entities::{CardanoTransactionsSetProof, TransactionHash},
Expand All @@ -11,7 +12,7 @@ pub struct ToCardanoTransactionsProofsMessageAdapter;
impl ToCardanoTransactionsProofsMessageAdapter {
/// Turn an entity instance into message.
pub fn try_adapt(
certificate_hash: &str,
signed_entity: SignedEntity<CardanoTransactionsSnapshot>,
transactions_set_proofs: Vec<CardanoTransactionsSetProof>,
transaction_hashes_to_certify: Vec<TransactionHash>,
) -> StdResult<CardanoTransactionsProofsMessage> {
Expand All @@ -21,9 +22,10 @@ impl ToCardanoTransactionsProofsMessageAdapter {
);

Ok(CardanoTransactionsProofsMessage::new(
certificate_hash,
&signed_entity.certificate_id,
try_adapt_set_proof_message(transactions_set_proofs)?,
transactions_hashes_not_certified,
signed_entity.artifact.beacon.immutable_file_number,
))
}
}
Expand Down Expand Up @@ -76,30 +78,33 @@ mod tests {
let transactions_hashes_certified = &transaction_hashes[0..5];
let transactions_hashes_non_certified = &transaction_hashes[5..];

let mut transactions_set_proofs = Vec::new();
for transaction_hashes_in_chunk in transactions_hashes_certified.chunks(2) {
let mk_proof = MKProof::from_leaves(transaction_hashes_in_chunk).unwrap();
transactions_set_proofs.push(CardanoTransactionsSetProof::new(
transaction_hashes_in_chunk.to_vec(),
mk_proof,
))
}
let transactions_set_proofs = transactions_hashes_certified
.chunks(2)
.map(|transaction_hashes_in_chunk| {
let mk_proof = MKProof::from_leaves(transaction_hashes_in_chunk).unwrap();
CardanoTransactionsSetProof::new(transaction_hashes_in_chunk.to_vec(), mk_proof)
})
.collect::<Vec<_>>();

let signed_entity = SignedEntity::<CardanoTransactionsSnapshot>::dummy();

let certificate_hash = "certificate_hash";
let message = ToCardanoTransactionsProofsMessageAdapter::try_adapt(
certificate_hash,
signed_entity.clone(),
transactions_set_proofs.clone(),
transaction_hashes.to_vec(),
)
.unwrap();
let transactions_set_proofs = transactions_set_proofs

let transactions_set_proof_message_part = transactions_set_proofs
.into_iter()
.map(|p| p.try_into().unwrap())
.collect();

let expected_message = CardanoTransactionsProofsMessage::new(
certificate_hash,
transactions_set_proofs,
&signed_entity.certificate_id,
transactions_set_proof_message_part,
transactions_hashes_non_certified.to_vec(),
signed_entity.artifact.beacon.immutable_file_number,
);
assert_eq!(expected_message, message);
}
Expand Down
8 changes: 6 additions & 2 deletions mithril-client/src/cardano_transaction_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,12 @@ mod tests {
let mut aggregator_client = MockAggregatorHTTPClient::new();
let certificate_hash = "cert-hash-123".to_string();
let set_proof = CardanoTransactionsSetProof::dummy();
let transactions_proofs =
CardanoTransactionsProofs::new(&certificate_hash, vec![set_proof.clone()], vec![]);
let transactions_proofs = CardanoTransactionsProofs::new(
&certificate_hash,
vec![set_proof.clone()],
vec![],
99999,
);
let expected_transactions_proofs = transactions_proofs.clone();
aggregator_client
.expect_get_content()
Expand Down
5 changes: 5 additions & 0 deletions mithril-client/tests/extensions/fake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ mod proof {
proof: ProtocolMkProof::new(proof.clone()).to_json_hex().unwrap(),
}],
non_certified_transactions: vec![],
latest_immutable_file_number: 9999,
})
.unwrap();

Expand All @@ -175,6 +176,10 @@ mod proof {
ProtocolMessagePartKey::CardanoTransactionsMerkleRoot,
proof.root().to_hex(),
);
cert.protocol_message.set_message_part(
ProtocolMessagePartKey::LatestImmutableFileNumber,
9999.to_string(),
);
cert.signed_message = cert.protocol_message.compute_hash();
cert
};
Expand Down
87 changes: 74 additions & 13 deletions mithril-common/src/entities/protocol_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ pub enum ProtocolMessagePartKey {
/// aka AVK(n-1)
#[serde(rename = "next_aggregate_verification_key")]
NextAggregateVerificationKey,

/// The ProtocolMessage part key associated to the latest immutable file number signed
#[serde(rename = "latest_immutable_file_number")]
LatestImmutableFileNumber,
}

impl Display for ProtocolMessagePartKey {
Expand All @@ -26,6 +30,7 @@ impl Display for ProtocolMessagePartKey {
Self::SnapshotDigest => write!(f, "snapshot_digest"),
Self::NextAggregateVerificationKey => write!(f, "next_aggregate_verification_key"),
Self::CardanoTransactionsMerkleRoot => write!(f, "cardano_transactions_merkle_root"),
Self::LatestImmutableFileNumber => write!(f, "latest_immutable_file_number"),
}
}
}
Expand Down Expand Up @@ -83,32 +88,88 @@ mod tests {
use super::*;

#[test]
fn test_protocol_message_compute_hash() {
let hash_expected = "71dee1e558cd647cdbc219a24b766940f568e7e8287c30a8292209ef11666e03";

let mut protocol_message = ProtocolMessage::new();
protocol_message.set_message_part(
ProtocolMessagePartKey::SnapshotDigest,
"snapshot-digest-123".to_string(),
);
protocol_message.set_message_part(
ProtocolMessagePartKey::NextAggregateVerificationKey,
"next-avk-123".to_string(),
);
assert_eq!(hash_expected, protocol_message.compute_hash());
fn test_protocol_message_compute_hash_include_next_aggregate_verification_key() {
let protocol_message = build_protocol_message_reference();
let hash_expected = protocol_message.compute_hash();

let mut protocol_message_modified = protocol_message.clone();
protocol_message_modified.set_message_part(
ProtocolMessagePartKey::NextAggregateVerificationKey,
"next-avk-456".to_string(),
);

assert_ne!(hash_expected, protocol_message_modified.compute_hash());
}

#[test]
fn test_protocol_message_compute_hash_include_snapshot_digest() {
let protocol_message = build_protocol_message_reference();
let hash_expected = protocol_message.compute_hash();

let mut protocol_message_modified = protocol_message.clone();
protocol_message_modified.set_message_part(
ProtocolMessagePartKey::SnapshotDigest,
"snapshot-digest-456".to_string(),
);

assert_ne!(hash_expected, protocol_message_modified.compute_hash());
}

#[test]
fn test_protocol_message_compute_hash_include_cardano_transactions_merkle_root() {
let protocol_message = build_protocol_message_reference();
let hash_expected = protocol_message.compute_hash();

let mut protocol_message_modified = protocol_message.clone();
protocol_message_modified.set_message_part(
ProtocolMessagePartKey::CardanoTransactionsMerkleRoot,
"ctx-merke-root-456".to_string(),
);

assert_ne!(hash_expected, protocol_message_modified.compute_hash());
}

#[test]
fn test_protocol_message_compute_hash_include_lastest_immutable_file_number() {
let protocol_message = build_protocol_message_reference();
let hash_expected = protocol_message.compute_hash();

let mut protocol_message_modified = protocol_message.clone();
protocol_message_modified.set_message_part(
ProtocolMessagePartKey::LatestImmutableFileNumber,
"latest-immutable-file-number-456".to_string(),
);

assert_ne!(hash_expected, protocol_message_modified.compute_hash());
}

#[test]
fn test_protocol_message_compute_hash_the_same_hash_with_same_protocol_message() {
assert_eq!(
build_protocol_message_reference().compute_hash(),
build_protocol_message_reference().compute_hash()
);
}

fn build_protocol_message_reference() -> ProtocolMessage {
let mut protocol_message = ProtocolMessage::new();
protocol_message.set_message_part(
ProtocolMessagePartKey::SnapshotDigest,
"snapshot-digest-123".to_string(),
);
protocol_message.set_message_part(
ProtocolMessagePartKey::NextAggregateVerificationKey,
"next-avk-123".to_string(),
);
protocol_message.set_message_part(
ProtocolMessagePartKey::CardanoTransactionsMerkleRoot,
"ctx-merkle-root-123".to_string(),
);
protocol_message.set_message_part(
ProtocolMessagePartKey::LatestImmutableFileNumber,
"latest-immutable-file-number-123".to_string(),
);

protocol_message
}
}
Loading

0 comments on commit a52e282

Please sign in to comment.