Skip to content

Commit d229f73

Browse files
jpraynaudAlenar
authored andcommitted
Send signatures for immutable files and verify artifacts
1 parent c81ce26 commit d229f73

File tree

2 files changed

+124
-20
lines changed

2 files changed

+124
-20
lines changed

mithril-common/src/digesters/dummy_immutable_db_builder.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,18 @@ pub struct DummyImmutableDb {
2626

2727
impl DummyImmutableDb {
2828
/// Add an immutable chunk file and its primary & secondary to the dummy DB.
29-
pub fn add_immutable_file(&mut self) {
30-
let last_file_number = self.immutables_files.last().map(|f| f.number).unwrap_or(1);
31-
let mut new_files = write_immutable_trio(None, &self.dir, last_file_number + 1);
29+
pub fn add_immutable_file(&mut self) -> ImmutableFileNumber {
30+
let new_file_number = self.last_immutable_number().unwrap_or(0) + 1;
31+
let mut new_files = write_immutable_trio(None, &self.dir, new_file_number);
3232

3333
self.immutables_files.append(&mut new_files);
34+
35+
new_file_number
36+
}
37+
38+
/// Return the file number of the last immutable
39+
pub fn last_immutable_number(&self) -> Option<ImmutableFileNumber> {
40+
self.immutables_files.last().map(|f| f.number)
3441
}
3542
}
3643

mithril-test-lab/mithril-end-to-end/src/bin/load-aggregator/main.rs

Lines changed: 114 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,16 @@ use clap::Parser;
1212

1313
use indicatif::{ProgressBar, ProgressDrawTarget};
1414
use mithril_common::{
15-
digesters::DummyImmutablesDbBuilder,
15+
digesters::{
16+
CardanoImmutableDigester, DummyImmutableDb, DummyImmutablesDbBuilder, ImmutableDigester,
17+
},
1618
entities::{
17-
Epoch, PartyId, ProtocolMessage, ProtocolParameters, SignedEntityType, Signer,
18-
SingleSignatures,
19+
Beacon, Epoch, PartyId, ProtocolMessage, ProtocolMessagePartKey, ProtocolParameters,
20+
SignedEntityType, Signer, SingleSignatures,
1921
},
2022
messages::{
2123
CertificateListItemMessage, EpochSettingsMessage, MithrilStakeDistributionListItemMessage,
22-
RegisterSignatureMessage, RegisterSignerMessage,
24+
RegisterSignatureMessage, RegisterSignerMessage, SnapshotListItemMessage,
2325
},
2426
test_utils::{MithrilFixture, MithrilFixtureBuilder},
2527
StdResult,
@@ -213,7 +215,10 @@ pub async fn wait_for_pending_certificate(
213215
}
214216

215217
#[async_recursion]
216-
async fn request_first_list_item<I>(url: &str) -> Result<I, String>
218+
async fn request_first_list_item_with_expected_size<I>(
219+
url: &str,
220+
expected_size: usize,
221+
) -> Result<I, String>
217222
where
218223
for<'a> I: Deserialize<'a> + Sync + Send + Clone,
219224
{
@@ -222,8 +227,12 @@ where
222227
match reqwest::get(url).await {
223228
Ok(response) => match response.status() {
224229
StatusCode::OK => match response.json::<Vec<I>>().await.as_deref() {
225-
Ok([first_item, ..]) => Ok(first_item.to_owned()),
226-
Ok(&[]) => request_first_list_item::<I>(url).await,
230+
Ok(list) if list.len() == expected_size => Ok(list.first().unwrap().clone()),
231+
Ok(list) if list.len() > expected_size => Err(format!(
232+
"Invalid size, expected {expected_size}, got {}",
233+
list.len()
234+
)),
235+
Ok(_) => request_first_list_item_with_expected_size::<I>(url, expected_size).await,
227236
Err(err) => Err(format!("Invalid list body : {err}")),
228237
},
229238
s if s.is_server_error() => {
@@ -234,7 +243,7 @@ where
234243
warn!("{message}");
235244
Err(message)
236245
}
237-
_ => request_first_list_item::<I>(url).await,
246+
_ => request_first_list_item_with_expected_size::<I>(url, expected_size).await,
238247
},
239248
Err(err) => Err(format!("Request to `{url}` failed: {err}")),
240249
}
@@ -271,15 +280,59 @@ pub async fn precompute_mithril_stake_distribution_signatures(
271280
)
272281
}
273282

274-
/// Wait for certificates
283+
/// Compute all signers single signatures for the given fixture
284+
pub async fn compute_immutable_files_signatures(
285+
immutable_db: &DummyImmutableDb,
286+
epoch: Epoch,
287+
signers_fixture: &MithrilFixture,
288+
timeout: Duration,
289+
) -> StdResult<(Beacon, Vec<SingleSignatures>)> {
290+
spin_while_waiting!(
291+
{
292+
let beacon = Beacon::new(
293+
"devnet".to_string(),
294+
*epoch,
295+
// Minus one because the last immutable isn't "finished"
296+
immutable_db.last_immutable_number().unwrap() - 1,
297+
);
298+
let digester = CardanoImmutableDigester::new(None, slog_scope::logger());
299+
let digest = digester.compute_digest(&immutable_db.dir, &beacon).await?;
300+
let signers_fixture = signers_fixture.clone();
301+
302+
let signatures = tokio::task::spawn_blocking(move || -> Vec<SingleSignatures> {
303+
let mithril_stake_distribution_message = {
304+
let mut message = ProtocolMessage::new();
305+
message.set_message_part(ProtocolMessagePartKey::SnapshotDigest, digest);
306+
message.set_message_part(
307+
ProtocolMessagePartKey::NextAggregateVerificationKey,
308+
signers_fixture.compute_and_encode_avk(),
309+
);
310+
311+
message
312+
};
313+
314+
signers_fixture.sign_all(&mithril_stake_distribution_message)
315+
})
316+
.await?;
317+
318+
Ok((beacon, signatures))
319+
},
320+
timeout,
321+
format!("Precompute signatures for CardanoImmutableFiles signed entity"),
322+
format!("Precomputing signatures timeout after {timeout:?}")
323+
)
324+
}
325+
326+
/// Wait for the given number of certificates, return the latest certificate
275327
pub async fn wait_for_certificates(
276328
aggregator: &Aggregator,
329+
total: usize,
277330
timeout: Duration,
278331
) -> StdResult<CertificateListItemMessage> {
279332
let url = &format!("{}/certificates", aggregator.endpoint());
280333
spin_while_waiting!(
281334
{
282-
request_first_list_item::<CertificateListItemMessage>(url)
335+
request_first_list_item_with_expected_size::<CertificateListItemMessage>(url, total)
283336
.await
284337
.map_err(|e| e.into())
285338
},
@@ -300,12 +353,32 @@ pub async fn wait_for_mithril_stake_distribution_artifacts(
300353
);
301354
spin_while_waiting!(
302355
{
303-
request_first_list_item::<MithrilStakeDistributionListItemMessage>(url)
356+
request_first_list_item_with_expected_size::<MithrilStakeDistributionListItemMessage>(
357+
url, 1,
358+
)
359+
.await
360+
.map_err(|e| e.into())
361+
},
362+
timeout,
363+
format!("Waiting for mithril stake distribution artifacts"),
364+
format!("Aggregator did not get a response after {timeout:?} from '{url}'")
365+
)
366+
}
367+
368+
/// Wait for Cardano Immutable Files artifacts
369+
pub async fn wait_for_immutable_files_artifacts(
370+
aggregator: &Aggregator,
371+
timeout: Duration,
372+
) -> StdResult<SnapshotListItemMessage> {
373+
let url = &format!("{}/artifact/snapshots", aggregator.endpoint());
374+
spin_while_waiting!(
375+
{
376+
request_first_list_item_with_expected_size::<SnapshotListItemMessage>(url, 1)
304377
.await
305378
.map_err(|e| e.into())
306379
},
307380
timeout,
308-
format!("Waiting for mithril stake distribution artifacts"),
381+
format!("Waiting for immutable files artifacts"),
309382
format!("Aggregator did not get a response after {timeout:?} from '{url}'")
310383
)
311384
}
@@ -638,10 +711,6 @@ async fn bootstrap_aggregator(
638711
Ok(aggregator)
639712
}
640713

641-
fn add_new_immutable_file(aggregator: &Aggregator) -> StdResult<()> {
642-
todo!()
643-
}
644-
645714
#[tokio::main(flavor = "multi_thread")]
646715
async fn main() -> StdResult<()> {
647716
let opts = MainOpts::parse();
@@ -695,7 +764,7 @@ async fn main() -> StdResult<()> {
695764
assert_eq!(0, errors);
696765

697766
info!(">> Wait for certificates to be available...");
698-
wait_for_certificates(&aggregator, Duration::from_secs(30)).await?;
767+
wait_for_certificates(&aggregator, 1, Duration::from_secs(30)).await?;
699768

700769
info!(">> Wait for artifacts to be available...");
701770
wait_for_mithril_stake_distribution_artifacts(&aggregator, Duration::from_secs(30)).await?;
@@ -706,6 +775,34 @@ async fn main() -> StdResult<()> {
706775
info!(">> Wait for pending certificate to be available");
707776
wait_for_pending_certificate(&aggregator, Duration::from_secs(30)).await?;
708777

778+
info!(">> Compute the immutable files signature");
779+
let (current_beacon, immutable_files_signatures) = compute_immutable_files_signatures(
780+
&immutable_db,
781+
current_epoch,
782+
&signers_fixture,
783+
Duration::from_secs(30),
784+
)
785+
.await
786+
.unwrap();
787+
788+
info!(
789+
">> Send the Signer Signatures payloads for CardanoImmutableFiles({:?})",
790+
current_beacon
791+
);
792+
let errors = register_signatures_to_aggregator(
793+
&aggregator,
794+
&immutable_files_signatures,
795+
SignedEntityType::CardanoImmutableFilesFull(current_beacon),
796+
)
797+
.await?;
798+
assert_eq!(0, errors);
799+
800+
info!(">> Wait for certificates to be available...");
801+
wait_for_certificates(&aggregator, 2, Duration::from_secs(30)).await?;
802+
803+
info!(">> Wait for artifacts to be available...");
804+
wait_for_immutable_files_artifacts(&aggregator, Duration::from_secs(30)).await?;
805+
709806
info!(">> All steps executed successfully, stopping all tasks...");
710807

711808
aggregator.stop().await.unwrap();

0 commit comments

Comments
 (0)