Skip to content

Commit

Permalink
Merge pull request #703 from input-output-hk/jpraynaud/698-add-snapsh…
Browse files Browse the repository at this point in the history
…ot-list-message

Add snapshot list message and adapter
  • Loading branch information
jpraynaud authored Jan 23, 2023
2 parents f8ee73d + 954d19d commit df6024f
Show file tree
Hide file tree
Showing 17 changed files with 206 additions and 22 deletions.
8 changes: 4 additions & 4 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.2.7"
version = "0.2.8"
description = "A Mithril Aggregator server"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
7 changes: 5 additions & 2 deletions mithril-aggregator/src/http_server/routes/snapshot_routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ fn snapshot_digest(
mod handlers {
use crate::http_server::routes::reply;
use crate::http_server::SERVER_BASE_PATH;
use crate::message_adapters::ToSnapshotMessageAdapter;
use crate::message_adapters::{ToSnapshotListMessageAdapter, ToSnapshotMessageAdapter};
use crate::{Configuration, SnapshotStore};
use slog_scope::{debug, warn};
use std::convert::Infallible;
Expand All @@ -72,7 +72,10 @@ mod handlers {
debug!("⇄ HTTP SERVER: snapshots");

match snapshot_store.list_snapshots().await {
Ok(snapshots) => Ok(reply::json(&snapshots, StatusCode::OK)),
Ok(snapshots) => Ok(reply::json(
&ToSnapshotListMessageAdapter::adapt(snapshots),
StatusCode::OK,
)),
Err(err) => {
warn!("snapshots::error"; "error" => ?err);
Ok(reply::internal_server_error(err.to_string()))
Expand Down
2 changes: 2 additions & 0 deletions mithril-aggregator/src/message_adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ mod from_register_signer;
mod to_certificate_message;
mod to_certificate_pending_message;
mod to_epoch_settings_message;
mod to_snapshot_list_message;
mod to_snasphot_message;

pub use from_register_signature::FromRegisterSingleSignatureAdapter;
pub use from_register_signer::FromRegisterSignerAdapter;
pub use to_certificate_message::ToCertificateMessageAdapter;
pub use to_certificate_pending_message::ToCertificatePendingMessageAdapter;
pub use to_epoch_settings_message::ToEpochSettingsMessageAdapter;
pub use to_snapshot_list_message::ToSnapshotListMessageAdapter;
pub use to_snasphot_message::ToSnapshotMessageAdapter;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use mithril_common::entities::Snapshot;
use mithril_common::messages::{SnapshotListItemMessage, SnapshotListMessage};

/// Adapter to convert a list of [Snapshot] to [SnapshotListMessage] instances
pub struct ToSnapshotListMessageAdapter;

impl ToSnapshotListMessageAdapter {
/// Method to trigger the conversion
pub fn adapt(snapshots: Vec<Snapshot>) -> SnapshotListMessage {
snapshots
.into_iter()
.map(|snapshot| SnapshotListItemMessage {
digest: snapshot.digest,
beacon: snapshot.beacon,
certificate_hash: snapshot.certificate_hash,
size: snapshot.size,
created_at: snapshot.created_at,
locations: snapshot.locations,
})
.collect()
}
}

#[cfg(test)]
mod tests {
use mithril_common::test_utils::fake_data;

use super::*;

#[test]
fn adapt_ok() {
let mut snapshot = fake_data::snapshots(1)[0].to_owned();
snapshot.digest = "digest123".to_string();
let snapshot_list_message = ToSnapshotListMessageAdapter::adapt(vec![snapshot]);

assert_eq!("digest123".to_string(), snapshot_list_message[0].digest);
}
}
2 changes: 1 addition & 1 deletion mithril-client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-client"
version = "0.2.4"
version = "0.2.5"
description = "A Mithril Client"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
10 changes: 6 additions & 4 deletions mithril-client/src/aggregator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ use thiserror::Error;
use mithril_common::{
certificate_chain::{CertificateRetriever, CertificateRetrieverError},
entities::{Certificate, Snapshot},
messages::{CertificateMessage, SnapshotMessage},
messages::{CertificateMessage, SnapshotListMessage, SnapshotMessage},
MITHRIL_API_VERSION,
};

use crate::{FromCertificateMessageAdapter, FromSnapshotMessageAdapter};
use crate::{
FromCertificateMessageAdapter, FromSnapshotListMessageAdapter, FromSnapshotMessageAdapter,
};

/// [AggregatorHandler] related errors.
#[derive(Error, Debug)]
Expand Down Expand Up @@ -173,8 +175,8 @@ impl AggregatorHandler for AggregatorHTTPClient {

match response {
Ok(response) => match response.status() {
StatusCode::OK => match response.json::<Vec<Snapshot>>().await {
Ok(snapshots) => Ok(snapshots),
StatusCode::OK => match response.json::<SnapshotListMessage>().await {
Ok(snapshots) => Ok(FromSnapshotListMessageAdapter::adapt(snapshots)),
Err(err) => Err(AggregatorHandlerError::JsonParseFailed(err.to_string())),
},
StatusCode::PRECONDITION_FAILED => Err(self.handle_api_error(&response)),
Expand Down
4 changes: 3 additions & 1 deletion mithril-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ mod runtime;

pub use aggregator::{AggregatorHTTPClient, AggregatorHandler, AggregatorHandlerError};
pub use entities::Config;
pub use message_adapters::{FromCertificateMessageAdapter, FromSnapshotMessageAdapter};
pub use message_adapters::{
FromCertificateMessageAdapter, FromSnapshotListMessageAdapter, FromSnapshotMessageAdapter,
};
pub use runtime::{Runtime, RuntimeError};

pub use runtime::convert_to_field_items;
37 changes: 37 additions & 0 deletions mithril-client/src/message_adapters/from_snapshot_list_message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use mithril_common::entities::Snapshot;
use mithril_common::messages::SnapshotListMessage;

/// Adapter to convert [SnapshotListMessage] to [SnapshotList] instances
pub struct FromSnapshotListMessageAdapter;

impl FromSnapshotListMessageAdapter {
/// Method to trigger the conversion
pub fn adapt(snapshot_list_message: SnapshotListMessage) -> Vec<Snapshot> {
snapshot_list_message
.into_iter()
.map(|snapshot_list_item_message| Snapshot {
digest: snapshot_list_item_message.digest,
beacon: snapshot_list_item_message.beacon,
certificate_hash: snapshot_list_item_message.certificate_hash,
size: snapshot_list_item_message.size,
created_at: snapshot_list_item_message.created_at,
locations: snapshot_list_item_message.locations,
})
.collect()
}
}

#[cfg(test)]
mod tests {
use mithril_common::messages::SnapshotListItemMessage;

use super::*;

#[test]
fn adapt_ok() {
let snapshot_list_message: SnapshotListMessage = vec![SnapshotListItemMessage::dummy()];
let snapshot_list = FromSnapshotListMessageAdapter::adapt(snapshot_list_message.clone());

assert_eq!(snapshot_list_message[0].digest, snapshot_list[0].digest);
}
}
2 changes: 2 additions & 0 deletions mithril-client/src/message_adapters/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod from_certificate_message_adapter;
mod from_snapshot_list_message;
mod from_snapshot_message;

pub use from_certificate_message_adapter::FromCertificateMessageAdapter;
pub use from_snapshot_list_message::FromSnapshotListMessageAdapter;
pub use from_snapshot_message::FromSnapshotMessageAdapter;
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.2.7"
version = "0.2.8"
authors = { workspace = true }
edition = { workspace = true }
documentation = { workspace = true }
Expand Down
2 changes: 0 additions & 2 deletions mithril-common/src/messages/certificate.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
use serde::{Deserialize, Serialize};

// TODO: We should probably not rely on entities when defining the message
use crate::entities::{Beacon, CertificateMetadata, ProtocolMessage};

#[cfg(any(test, feature = "test_only"))]
// TODO: We should probably not rely on entities when defining the message
use crate::entities::{ProtocolMessagePartKey, ProtocolParameters, SignerWithStake};

/// Message structure of a certificate
Expand Down
2 changes: 2 additions & 0 deletions mithril-common/src/messages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ mod epoch_settings;
mod register_signature;
mod register_signer;
mod snapshot;
mod snapshot_list;

pub use certificate::CertificateMessage;
pub use certificate_pending::{CertificatePendingMessage, SignerMessage};
pub use epoch_settings::EpochSettingsMessage;
pub use register_signature::RegisterSignatureMessage;
pub use register_signer::RegisterSignerMessage;
pub use snapshot::SnapshotMessage;
pub use snapshot_list::{SnapshotListItemMessage, SnapshotListMessage};
2 changes: 0 additions & 2 deletions mithril-common/src/messages/snapshot.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use serde::{Deserialize, Serialize};

// TODO: We should probably not rely on entities when defining the message
use crate::entities::Beacon;

// TODO: We should probably not rely on entities when defining the message
#[cfg(any(test, feature = "test_only"))]
use crate::entities::Epoch;
/// Message structure of a snapshot
Expand Down
96 changes: 96 additions & 0 deletions mithril-common/src/messages/snapshot_list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
use serde::{Deserialize, Serialize};

use crate::entities::Beacon;

#[cfg(any(test, feature = "test_only"))]
use crate::entities::Epoch;

/// Message structure of a snapshot list
pub type SnapshotListMessage = Vec<SnapshotListItemMessage>;

/// Message structure of a snapshot list item
#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)]
pub struct SnapshotListItemMessage {
/// Digest that is signed by the signer participants
pub digest: String,

/// Mithril beacon on the Cardano chain
pub beacon: Beacon,

/// Hash of the associated certificate
pub certificate_hash: String,

/// Size of the snapshot file in Bytes
pub size: u64,

/// Date and time at which the snapshot was created
pub created_at: String,

/// Locations where the binary content of the snapshot can be retrieved
pub locations: Vec<String>,
}

impl SnapshotListItemMessage {
#[cfg(any(test, feature = "test_only"))]
/// Return a dummy test entity (test-only).
pub fn dummy() -> Self {
Self {
digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6".to_string(),
beacon: Beacon {
network: "preview".to_string(),
epoch: Epoch(86),
immutable_file_number: 1728,
},
certificate_hash: "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb"
.to_string(),
size: 807803196,
created_at: "2023-01-19T13:43:05.618857482Z".to_string(),
locations: vec!["https://host/certificate.tar.gz".to_string()],
}
}
}

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

fn golden_message() -> SnapshotListMessage {
vec![SnapshotListItemMessage {
digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6".to_string(),
beacon: Beacon {
network: "preview".to_string(),
epoch: Epoch(86),
immutable_file_number: 1728,
},
certificate_hash: "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb"
.to_string(),
size: 807803196,
created_at: "2023-01-19T13:43:05.618857482Z".to_string(),
locations: vec!["https://host/certificate.tar.gz".to_string()],
}]
}

// Test the retro compatibility with possible future upgrades.
#[test]
fn test_v1() {
let json = r#"[{
"digest": "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6",
"beacon": {
"network": "preview",
"epoch": 86,
"immutable_file_number": 1728
},
"certificate_hash": "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb",
"size": 807803196,
"created_at": "2023-01-19T13:43:05.618857482Z",
"locations": [
"https://host/certificate.tar.gz"
]
}]"#;
let message: SnapshotListMessage = serde_json::from_str(json).expect(
"This JSON is expected to be succesfully parsed into a SnapshotListMessage instance.",
);

assert_eq!(golden_message(), message);
}
}
2 changes: 1 addition & 1 deletion mithril-signer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-signer"
version = "0.2.5"
version = "0.2.6"
description = "A Mithril Signer"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
10 changes: 7 additions & 3 deletions openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,7 @@ paths:
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Snapshot"
$ref: "#/components/schemas/SnapshotListMessage"
"412":
description: API version mismatch
default:
Expand Down Expand Up @@ -613,6 +611,12 @@ components:
"genesis_signature": "",
}

SnapshotListMessage:
description: SnapshotListMessage represents a list of snapshots
type: array
items:
$ref: "#/components/schemas/Snapshot"

Snapshot:
description: Snapshot represents a snapshot file and its metadata
type: object
Expand Down

0 comments on commit df6024f

Please sign in to comment.