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

Provide latest immutable file number with certified ctx #1571

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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(
jpraynaud marked this conversation as resolved.
Show resolved Hide resolved
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
Loading