Skip to content

Commit

Permalink
Merge pull request #2204 from input-output-hk/jpraynaud/2174-digests-…
Browse files Browse the repository at this point in the history
…route-cardano-database-aggregator

Feat: immutable file digests route for `CardanoDatabase` artifacts aggregator
  • Loading branch information
jpraynaud authored Jan 9, 2025
2 parents ed0e96f + b3cb0d1 commit ed1e290
Show file tree
Hide file tree
Showing 29 changed files with 1,234 additions and 240 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ As a minor extension, we have adopted a slightly different versioning convention
- **UNSTABLE** Cardano database incremental certification:

- Implement the artifact routes of the aggregator for the signed entity type `CardanoDatabase`.
- Implement the immutable file digests route in the aggregator.
- Implement the artifact ancillary builder in the aggregator.

- Crates versions:
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.6.9"
version = "0.6.10"
description = "A Mithril Aggregator server"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
12 changes: 12 additions & 0 deletions mithril-aggregator/src/database/migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -880,5 +880,17 @@ drop table pending_certificate;
alter table new_pending_certificate rename to pending_certificate;
"#,
),
// Migration 34
// Add the `immutable_file_digest` table.
SqlMigration::new(
34,
r#"
create table immutable_file_digest (
immutable_file_name text not null,
digest text not null,
primary key (immutable_file_name)
);
"#,
),
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use mithril_persistence::sqlite::{Query, WhereCondition};

use crate::database::record::ImmutableFileDigestRecord;

/// Query to delete [ImmutableFileDigestRecord] from the sqlite database
pub struct DeleteImmutableFileDigestQuery {
condition: WhereCondition,
}

impl DeleteImmutableFileDigestQuery {
pub fn all() -> Self {
Self {
condition: WhereCondition::default(),
}
}
}

impl Query for DeleteImmutableFileDigestQuery {
type Entity = ImmutableFileDigestRecord;

fn filters(&self) -> WhereCondition {
self.condition.clone()
}

fn get_definition(&self, condition: &str) -> String {
let projection = Self::Entity::expand_projection("immutable_file_digest");

format!("delete from immutable_file_digest where {condition} returning {projection}")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
use sqlite::Value;

use mithril_common::{entities::ImmutableFileName, StdResult};
use mithril_persistence::sqlite::{Query, WhereCondition};

use crate::database::record::ImmutableFileDigestRecord;

/// Simple queries to retrieve [ImmutableFileDigestRecord] from the sqlite database.
pub struct GetImmutableFileDigestQuery {
condition: WhereCondition,
}

impl GetImmutableFileDigestQuery {
pub fn by_immutable_file_name(immutable_file_name: &ImmutableFileName) -> StdResult<Self> {
let condition = WhereCondition::new(
"immutable_file_name = ?*",
vec![Value::String(immutable_file_name.to_string())],
);

Ok(Self { condition })
}

pub fn all() -> Self {
Self {
condition: WhereCondition::default(),
}
}
}

impl Query for GetImmutableFileDigestQuery {
type Entity = ImmutableFileDigestRecord;

fn filters(&self) -> WhereCondition {
self.condition.clone()
}

fn get_definition(&self, condition: &str) -> String {
let projection = Self::Entity::expand_projection("immutable_file_digest");

format!(
"select {projection} from immutable_file_digest where {condition} order by rowid desc"
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
mod delete_immutable_file_digest;
mod get_immutable_file_digest;
mod upsert_immutable_file_digest;

pub use delete_immutable_file_digest::*;
pub use get_immutable_file_digest::*;
pub use upsert_immutable_file_digest::*;
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use sqlite::Value;

use mithril_common::entities::ImmutableFileName;
use mithril_common::StdResult;
use mithril_persistence::sqlite::{Query, WhereCondition};

use crate::database::record::ImmutableFileDigestRecord;

/// Query to upsert [ImmutableFileDigestRecord] in the sqlite database
pub struct UpsertImmutableFileDigestQuery {
condition: WhereCondition,
}

impl UpsertImmutableFileDigestQuery {
pub fn one(immutable_file_name: &ImmutableFileName, digest: &str) -> StdResult<Self> {
let expression = "(immutable_file_name, digest) values (?*, ?*)";
let parameters = vec![
Value::String(immutable_file_name.to_string()),
Value::String(digest.to_string()),
];

Ok(Self {
condition: WhereCondition::new(expression, parameters),
})
}
}

impl Query for UpsertImmutableFileDigestQuery {
type Entity = ImmutableFileDigestRecord;

fn filters(&self) -> WhereCondition {
self.condition.clone()
}

fn get_definition(&self, condition: &str) -> String {
let projection = Self::Entity::expand_projection("immutable_file_digest");

format!(
r#"
insert into immutable_file_digest {condition}
on conflict (immutable_file_name) do update set digest = excluded.digest
returning {projection}
"#
)
}
}
2 changes: 2 additions & 0 deletions mithril-aggregator/src/database/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
mod buffered_single_signature;
mod certificate;
mod epoch_settings;
mod immutable_file_digest;
mod open_message;
mod pending_certificate;
mod signed_entity;
Expand All @@ -13,6 +14,7 @@ mod stake_pool;
pub use buffered_single_signature::*;
pub use certificate::*;
pub use epoch_settings::*;
pub use immutable_file_digest::*;
pub use open_message::*;
pub use pending_certificate::*;
pub use signed_entity::*;
Expand Down
57 changes: 57 additions & 0 deletions mithril-aggregator/src/database/record/immutable_file_digest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use sqlite::Row;

use mithril_common::entities::{HexEncodedDigest, ImmutableFileName};
use mithril_persistence::sqlite::{HydrationError, Projection, SourceAlias, SqLiteEntity};

/// ImmutableFileDigestRecord is the record that stores the digest of an immutable file.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct ImmutableFileDigestRecord {
/// Immutable file name
pub immutable_file_name: ImmutableFileName,

/// Digest of an immutable file
pub digest: HexEncodedDigest,
}

impl ImmutableFileDigestRecord {
/// Construct a [Projection] that will allow to hydrate this `CertificatePendingRecord` and expend table alias.
pub fn expand_projection(table: &str) -> String {
let aliases = SourceAlias::new(&[("{:immutable_file_digest:}", table)]);
Self::get_projection().expand(aliases)
}

#[cfg(test)]
/// Create a dumb ImmutableFileDigestRecord instance mainly for test purposes
pub fn dummy() -> Self {
Self {
immutable_file_name: "123.chunk".to_string(),
digest: "dummy_digest".to_string(),
}
}
}

impl SqLiteEntity for ImmutableFileDigestRecord {
fn hydrate(row: Row) -> Result<Self, HydrationError>
where
Self: Sized,
{
let immutable_file_name = row.read::<&str, _>(0).to_string();
let digest = row.read::<&str, _>(1).to_string();

Ok(Self {
immutable_file_name,
digest,
})
}

fn get_projection() -> Projection {
Projection::from(&[
(
"immutable_file_name",
"{:immutable_file_digest:}.immutable_file_name",
"text",
),
("digest", "{:immutable_file_digest:}.digest", "text"),
])
}
}
2 changes: 2 additions & 0 deletions mithril-aggregator/src/database/record/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod buffered_single_signature_record;
mod certificate;
mod certificate_pending;
mod epoch_settings;
mod immutable_file_digest;
mod open_message;
mod open_message_with_single_signatures;
mod signed_entity;
Expand All @@ -16,6 +17,7 @@ pub use buffered_single_signature_record::*;
pub use certificate::*;
pub use certificate_pending::*;
pub use epoch_settings::*;
pub use immutable_file_digest::*;
pub use open_message::*;
pub use open_message_with_single_signatures::*;
pub use signed_entity::*;
Expand Down
Loading

0 comments on commit ed1e290

Please sign in to comment.