Skip to content

Commit d5bf900

Browse files
committed
refactor(aggregator): implement TryFrom<CertificateRecord> for Certificate
1 parent cddd9df commit d5bf900

File tree

3 files changed

+51
-32
lines changed

3 files changed

+51
-32
lines changed

mithril-aggregator/src/database/record/certificate.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,10 @@ impl TryFrom<Certificate> for CertificateRecord {
161161
}
162162
}
163163

164-
impl From<CertificateRecord> for Certificate {
165-
fn from(other: CertificateRecord) -> Self {
164+
impl TryFrom<CertificateRecord> for Certificate {
165+
type Error = StdError;
166+
167+
fn try_from(other: CertificateRecord) -> Result<Self, Self::Error> {
166168
let certificate_metadata = CertificateMetadata::new(
167169
other.network,
168170
other.protocol_version,
@@ -174,27 +176,29 @@ impl From<CertificateRecord> for Certificate {
174176
let (previous_hash, signature) = match other.parent_certificate_id {
175177
None => (
176178
String::new(),
177-
CertificateSignature::GenesisSignature(other.signature.try_into().unwrap()),
179+
CertificateSignature::GenesisSignature(other.signature.try_into()?),
178180
),
179181
Some(parent_certificate_id) => (
180182
parent_certificate_id,
181183
CertificateSignature::MultiSignature(
182184
other.signed_entity_type,
183-
other.signature.try_into().unwrap(),
185+
other.signature.try_into()?,
184186
),
185187
),
186188
};
187189

188-
Certificate {
190+
let certificate = Certificate {
189191
hash: other.certificate_id,
190192
previous_hash,
191193
epoch: other.epoch,
192194
metadata: certificate_metadata,
193195
signed_message: other.protocol_message.compute_hash(),
194196
protocol_message: other.protocol_message,
195-
aggregate_verification_key: other.aggregate_verification_key.try_into().unwrap(),
197+
aggregate_verification_key: other.aggregate_verification_key.try_into()?,
196198
signature,
197-
}
199+
};
200+
201+
Ok(certificate)
198202
}
199203
}
200204

@@ -400,7 +404,7 @@ mod tests {
400404
}
401405
let mut certificates_new: Vec<Certificate> = Vec::new();
402406
for certificate_record in certificate_records {
403-
certificates_new.push(certificate_record.into());
407+
certificates_new.push(certificate_record.try_into().unwrap());
404408
}
405409
assert_eq!(certificates.certificates_chained, certificates_new);
406410
}
@@ -409,7 +413,7 @@ mod tests {
409413
fn converting_certificate_record_to_certificate_should_not_recompute_hash() {
410414
let expected_hash = "my_hash";
411415
let record = CertificateRecord::dummy_genesis(expected_hash, Epoch(1));
412-
let certificate: Certificate = record.into();
416+
let certificate: Certificate = record.try_into().unwrap();
413417

414418
assert_eq!(expected_hash, &certificate.hash);
415419
}

mithril-aggregator/src/database/repository/certificate_repository.rs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use anyhow::anyhow;
44
use async_trait::async_trait;
55
use sqlite::ConnectionThreadSafe;
66

7-
use mithril_common::StdResult;
87
use mithril_common::certificate_chain::{CertificateRetriever, CertificateRetrieverError};
98
use mithril_common::entities::{Certificate, Epoch};
9+
use mithril_common::{StdError, StdResult};
1010
use mithril_persistence::sqlite::ConnectionExtensions;
1111

1212
use crate::database::query::{
@@ -30,49 +30,56 @@ impl CertificateRepository {
3030
/// Return the certificate corresponding to the given hash if any.
3131
pub async fn get_certificate<T>(&self, hash: &str) -> StdResult<Option<T>>
3232
where
33-
T: From<CertificateRecord>,
33+
T: TryFrom<CertificateRecord>,
34+
T::Error: Into<StdError>,
3435
{
3536
let record = self
3637
.connection
3738
.fetch_first(GetCertificateRecordQuery::by_certificate_id(hash))?;
3839

39-
Ok(record.map(|c| c.into()))
40+
record.map(|c| c.try_into().map_err(Into::into)).transpose()
4041
}
4142

4243
/// Return the latest certificates.
4344
pub async fn get_latest_certificates<T>(&self, last_n: usize) -> StdResult<Vec<T>>
4445
where
45-
T: From<CertificateRecord>,
46+
T: TryFrom<CertificateRecord>,
47+
T::Error: Into<StdError>,
4648
{
4749
let cursor = self.connection.fetch(GetCertificateRecordQuery::all())?;
4850

49-
Ok(cursor.take(last_n).map(|v| v.into()).collect())
51+
cursor
52+
.take(last_n)
53+
.map(|c| c.try_into().map_err(Into::into))
54+
.collect()
5055
}
5156

5257
/// Return the latest genesis certificate.
5358
pub async fn get_latest_genesis_certificate<T>(&self) -> StdResult<Option<T>>
5459
where
55-
T: From<CertificateRecord>,
60+
T: TryFrom<CertificateRecord>,
61+
T::Error: Into<StdError>,
5662
{
5763
let record = self
5864
.connection
5965
.fetch_first(GetCertificateRecordQuery::all_genesis())?;
6066

61-
Ok(record.map(|c| c.into()))
67+
record.map(|c| c.try_into().map_err(Into::into)).transpose()
6268
}
6369

6470
/// Return the first certificate signed per epoch as the reference
6571
/// certificate for this Epoch. This will be the parent certificate for all
6672
/// other certificates issued within this Epoch.
6773
pub async fn get_master_certificate_for_epoch<T>(&self, epoch: Epoch) -> StdResult<Option<T>>
6874
where
69-
T: From<CertificateRecord>,
75+
T: TryFrom<CertificateRecord>,
76+
T::Error: Into<StdError>,
7077
{
7178
let record = self
7279
.connection
7380
.fetch_first(MasterCertificateQuery::for_epoch(epoch))?;
7481

75-
Ok(record.map(|c| c.into()))
82+
record.map(|c| c.try_into().map_err(Into::into)).transpose()
7683
}
7784

7885
/// Create a new certificate in the database.
@@ -86,7 +93,7 @@ impl CertificateRepository {
8693
panic!("No entity returned by the persister, certificate = {certificate:#?}")
8794
});
8895

89-
Ok(record.into())
96+
record.try_into()
9097
}
9198

9299
/// Create many certificates at once in the database.
@@ -105,7 +112,7 @@ impl CertificateRepository {
105112
let new_certificates =
106113
self.connection.fetch(InsertCertificateRecordQuery::many(records))?;
107114

108-
Ok(new_certificates.map(|cert| cert.into()).collect())
115+
new_certificates.map(|cert| cert.try_into()).collect::<StdResult<_>>()
109116
}
110117

111118
/// Create, or replace if they already exist, many certificates at once in the database.
@@ -125,7 +132,7 @@ impl CertificateRepository {
125132
.connection
126133
.fetch(InsertOrReplaceCertificateRecordQuery::many(records))?;
127134

128-
Ok(new_certificates.map(|cert| cert.into()).collect())
135+
new_certificates.map(|cert| cert.try_into()).collect::<StdResult<_>>()
129136
}
130137

131138
/// Delete all the given certificates from the database
@@ -335,7 +342,7 @@ mod tests {
335342
async fn get_master_certificate_one_cert_in_current_epoch_recorded_returns_that_one() {
336343
let connection = Arc::new(main_db_connection().unwrap());
337344
let certificate = CertificateRecord::dummy_genesis("1", Epoch(1));
338-
let expected_certificate: Certificate = certificate.clone().into();
345+
let expected_certificate: Certificate = certificate.clone().try_into().unwrap();
339346
insert_certificate_records(&connection, vec![certificate]);
340347

341348
let repository: CertificateRepository = CertificateRepository::new(connection);
@@ -357,7 +364,8 @@ mod tests {
357364
CertificateRecord::dummy_db_snapshot("2", "1", Epoch(1), 2),
358365
CertificateRecord::dummy_db_snapshot("3", "1", Epoch(1), 3),
359366
];
360-
let expected_certificate: Certificate = certificates.first().unwrap().clone().into();
367+
let expected_certificate: Certificate =
368+
certificates.first().unwrap().clone().try_into().unwrap();
361369
insert_certificate_records(&connection, certificates);
362370

363371
let repository: CertificateRepository = CertificateRepository::new(connection);
@@ -379,7 +387,8 @@ mod tests {
379387
CertificateRecord::dummy_db_snapshot("2", "1", Epoch(1), 2),
380388
CertificateRecord::dummy_db_snapshot("3", "1", Epoch(1), 3),
381389
];
382-
let expected_certificate: Certificate = certificates.first().unwrap().clone().into();
390+
let expected_certificate: Certificate =
391+
certificates.first().unwrap().clone().try_into().unwrap();
383392
insert_certificate_records(&connection, certificates);
384393

385394
let repository: CertificateRepository = CertificateRepository::new(connection);
@@ -402,7 +411,8 @@ mod tests {
402411
CertificateRecord::dummy_db_snapshot("3", "1", Epoch(1), 3),
403412
CertificateRecord::dummy_db_snapshot("4", "1", Epoch(2), 4),
404413
];
405-
let expected_certificate: Certificate = certificates.last().unwrap().clone().into();
414+
let expected_certificate: Certificate =
415+
certificates.last().unwrap().clone().try_into().unwrap();
406416
insert_certificate_records(&connection, certificates);
407417

408418
let repository: CertificateRepository = CertificateRepository::new(connection);
@@ -427,7 +437,8 @@ mod tests {
427437
CertificateRecord::dummy_db_snapshot("5", "4", Epoch(2), 5),
428438
CertificateRecord::dummy_db_snapshot("6", "4", Epoch(2), 6),
429439
];
430-
let expected_certificate: Certificate = certificates.get(3).unwrap().clone().into();
440+
let expected_certificate: Certificate =
441+
certificates.get(3).unwrap().clone().try_into().unwrap();
431442
insert_certificate_records(&connection, certificates);
432443

433444
let repository: CertificateRepository = CertificateRepository::new(connection);
@@ -469,7 +480,8 @@ mod tests {
469480
CertificateRecord::dummy_db_snapshot("3", "1", Epoch(1), 3),
470481
CertificateRecord::dummy_genesis("4", Epoch(1)),
471482
];
472-
let expected_certificate: Certificate = certificates.last().unwrap().clone().into();
483+
let expected_certificate: Certificate =
484+
certificates.last().unwrap().clone().try_into().unwrap();
473485
insert_certificate_records(&connection, certificates);
474486

475487
let repository: CertificateRepository = CertificateRepository::new(connection);
@@ -494,7 +506,8 @@ mod tests {
494506
CertificateRecord::dummy_db_snapshot("5", "1", Epoch(2), 5),
495507
CertificateRecord::dummy_genesis("6", Epoch(2)),
496508
];
497-
let expected_certificate: Certificate = certificates.last().unwrap().clone().into();
509+
let expected_certificate: Certificate =
510+
certificates.last().unwrap().clone().try_into().unwrap();
498511
insert_certificate_records(&connection, certificates);
499512

500513
let repository: CertificateRepository = CertificateRepository::new(connection);
@@ -517,7 +530,8 @@ mod tests {
517530
CertificateRecord::dummy_db_snapshot("3", "1", Epoch(1), 3),
518531
CertificateRecord::dummy_genesis("4", Epoch(2)),
519532
];
520-
let expected_certificate: Certificate = certificates.last().unwrap().clone().into();
533+
let expected_certificate: Certificate =
534+
certificates.last().unwrap().clone().try_into().unwrap();
521535
insert_certificate_records(&connection, certificates);
522536

523537
let repository: CertificateRepository = CertificateRepository::new(connection);
@@ -578,7 +592,8 @@ mod tests {
578592
CertificateRecord::dummy_db_snapshot("3", "1", Epoch(1), 3),
579593
];
580594
insert_certificate_records(&connection, records.clone());
581-
let certificates: Vec<Certificate> = records.into_iter().map(|c| c.into()).collect();
595+
let certificates: Vec<Certificate> =
596+
records.into_iter().map(|c| c.try_into().unwrap()).collect();
582597

583598
// Delete all records except the first
584599
repository

mithril-aggregator/src/tools/certificates_hash_migrator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ mod test {
254254
fn dummy_genesis(certificate_hash: &str, time_point: TimePoint) -> Certificate {
255255
let certificate = CertificateRecord::dummy_genesis(certificate_hash, time_point.epoch);
256256

257-
certificate.into()
257+
certificate.try_into().unwrap()
258258
}
259259

260260
fn dummy_certificate(
@@ -272,7 +272,7 @@ mod test {
272272
.unwrap(),
273273
);
274274

275-
certificate.into()
275+
certificate.try_into().unwrap()
276276
}
277277

278278
fn signed_entity_for_certificate(certificate: &Certificate) -> Option<SignedEntityRecord> {

0 commit comments

Comments
 (0)