Skip to content

Commit e28d2a6

Browse files
jpraynaudAlenar
authored andcommitted
Add clean bootstrap phase and optimize performances
1 parent a289123 commit e28d2a6

File tree

2 files changed

+136
-58
lines changed

2 files changed

+136
-58
lines changed

mithril-common/src/test_utils/mithril_fixture.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,24 @@ impl MithrilFixture {
178178
}
179179
}
180180

181+
impl From<MithrilFixture> for Vec<Signer> {
182+
fn from(fixture: MithrilFixture) -> Self {
183+
fixture.signers()
184+
}
185+
}
186+
187+
impl From<MithrilFixture> for Vec<SignerWithStake> {
188+
fn from(fixture: MithrilFixture) -> Self {
189+
fixture.signers_with_stake()
190+
}
191+
}
192+
193+
impl From<MithrilFixture> for Vec<SignerFixture> {
194+
fn from(fixture: MithrilFixture) -> Self {
195+
fixture.signers_fixture()
196+
}
197+
}
198+
181199
impl SignerFixture {
182200
/// Sign the given protocol message.
183201
pub fn sign(&self, protocol_message: &ProtocolMessage) -> Option<SingleSignatures> {

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

Lines changed: 118 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ use indicatif::{ProgressBar, ProgressDrawTarget};
1414
use mithril_common::{
1515
digesters::DummyImmutablesDbBuilder,
1616
entities::{
17-
Epoch, PartyId, ProtocolMessage, ProtocolParameters, SignedEntityType, SingleSignatures,
17+
Epoch, PartyId, ProtocolMessage, ProtocolParameters, SignedEntityType, Signer,
18+
SingleSignatures,
1819
},
1920
messages::{
2021
CertificateListItemMessage, EpochSettingsMessage, MithrilStakeDistributionListItemMessage,
@@ -28,12 +29,13 @@ use mithril_end_to_end::{Aggregator, BftNode};
2829
use reqwest::StatusCode;
2930
use serde::Deserialize;
3031
use slog::Level;
31-
use slog_scope::{info, warn};
32+
use slog_scope::{debug, info, warn};
3233
use thiserror::Error;
3334
use tokio::{select, task::JoinSet, time::sleep};
3435

3536
macro_rules! spin_while_waiting {
3637
($block:block, $timeout:expr, $wait_message:expr, $timeout_message:expr) => {{
38+
info!("⇄ {}", $wait_message);
3739
let progress_bar = ProgressBar::new_spinner().with_message($wait_message);
3840

3941
let spinner = async move {
@@ -94,12 +96,12 @@ pub fn generate_signer_data(
9496

9597
/// Generate signer registration message
9698
pub fn generate_register_signer_message(
97-
signers_fixture: &MithrilFixture,
99+
signers: &[Signer],
98100
epoch: Epoch,
99101
) -> Vec<RegisterSignerMessage> {
100-
signers_fixture
101-
.signers()
102-
.into_iter()
102+
signers
103+
.iter()
104+
.cloned()
103105
.map(|signer| RegisterSignerMessage {
104106
epoch: Some(epoch),
105107
party_id: signer.party_id,
@@ -279,10 +281,10 @@ pub async fn wait_for_mithril_stake_distribution_artifacts(
279281

280282
pub async fn register_signers_to_aggregator(
281283
aggregator: &Aggregator,
282-
signers_fixture: &MithrilFixture,
284+
signers: &[Signer],
283285
epoch: Epoch,
284286
) -> StdResult<usize> {
285-
let register_messages = generate_register_signer_message(signers_fixture, epoch);
287+
let register_messages = generate_register_signer_message(signers, epoch);
286288

287289
let mut join_set: JoinSet<StdResult<()>> = JoinSet::new();
288290
let progress_bar = ProgressBar::with_draw_target(
@@ -391,6 +393,7 @@ pub fn write_epoch(mock_epoch_file_path: &Path, epoch: Epoch) {
391393
let mock_epoch_file = File::create(mock_epoch_file_path).unwrap();
392394
write!(&mock_epoch_file, "{}", *epoch)
393395
.expect("Writing the epoch into a file for the mock cardano cli failed");
396+
debug!("New Epoch: {epoch}");
394397
}
395398

396399
#[derive(Debug, Parser)]
@@ -417,7 +420,7 @@ pub struct MainOpts {
417420
pub mithril_era: String,
418421

419422
/// Aggregator HTTP port
420-
#[arg(short = 'p', long, default_value = "8888")]
423+
#[arg(short = 'p', long, default_value = "8080")]
421424
server_port: u32,
422425

423426
/// Log level
@@ -503,38 +506,28 @@ impl AggregatorParameters {
503506

504507
Ok(aggregator_parameters)
505508
}
506-
}
507509

508-
#[tokio::main]
509-
async fn main() -> StdResult<()> {
510-
let opts = MainOpts::parse();
511-
let _logger = init_logger(&opts);
512-
let args = AggregatorParameters::new(&opts)?;
513-
let mock_stake_distribution_file_path = args.work_dir.join("stake_distribution.json");
514-
let mock_epoch_file_path = args.work_dir.join("epoch.txt");
515-
let mut current_epoch = Epoch(1);
516-
info!(">> Starting stress test with options: {opts:?}");
517-
518-
info!(">> Creation of the Signer Key Registrations payloads");
519-
let signers_fixture =
520-
generate_signer_data(opts.num_signers, ProtocolParameters::new(5, 100, 0.65));
510+
fn mock_stake_distribution_file_path(&self) -> PathBuf {
511+
self.work_dir.join("stake_distribution.json")
512+
}
521513

522-
info!(">> Precompute message & signatures for MithrilStakeDistribution signed entity");
523-
let mithril_stake_distribution_message = {
524-
let mut message = ProtocolMessage::new();
525-
message.set_message_part(
526-
mithril_common::entities::ProtocolMessagePartKey::NextAggregateVerificationKey,
527-
signers_fixture.compute_and_encode_avk(),
528-
);
514+
fn mock_epoch_file_path(&self) -> PathBuf {
515+
self.work_dir.join("epoch.txt")
516+
}
517+
}
529518

530-
message
531-
};
532-
let mithril_stake_distribution_signatures: Vec<SingleSignatures> = signers_fixture
533-
.signers_fixture()
534-
.iter()
535-
// filter map to exclude signers that could not sign because they lost the lottery
536-
.filter_map(|s| s.sign(&mithril_stake_distribution_message))
537-
.collect();
519+
/// Bootstrap an aggregator and made it compute its genesis certificate
520+
async fn bootstrap_aggregator(
521+
args: &AggregatorParameters,
522+
signers_fixture: &MithrilFixture,
523+
current_epoch: &mut Epoch,
524+
) -> StdResult<Aggregator> {
525+
// let genesis_signers = {
526+
// let mut signers = signers_fixture.signers();
527+
// // Up to 100 signers for the genesis certificate to avoid registration round errors
528+
// signers.truncate(100);
529+
// signers
530+
// };
538531

539532
info!(">> Launch Aggregator");
540533
let mut aggregator = Aggregator::new(
@@ -547,62 +540,129 @@ async fn main() -> StdResult<()> {
547540
)
548541
.unwrap();
549542

550-
write_epoch(&mock_epoch_file_path, current_epoch);
551-
write_stake_distribution(&mock_stake_distribution_file_path, &signers_fixture);
543+
write_epoch(&args.mock_epoch_file_path(), *current_epoch);
544+
write_stake_distribution(&args.mock_stake_distribution_file_path(), signers_fixture);
552545

553-
aggregator.change_run_interval(Duration::from_secs(6));
554-
aggregator
555-
.set_mock_cardano_cli_file_path(&mock_stake_distribution_file_path, &mock_epoch_file_path);
546+
// Extremely large interval since for the two following start only the http_server part
547+
// of the aggregator is relevant since we need to send signer registrations.
548+
aggregator.change_run_interval(Duration::from_secs(20000));
549+
aggregator.set_mock_cardano_cli_file_path(
550+
&args.mock_stake_distribution_file_path(),
551+
&args.mock_epoch_file_path(),
552+
);
556553
aggregator.set_protocol_parameters(&signers_fixture.protocol_parameters());
557-
aggregator.serve().unwrap();
558554

555+
info!(
556+
">> Starting the aggregator with a large run interval to call the http_server\
557+
without being bothered by the state machine cycles"
558+
);
559+
aggregator.serve().unwrap();
559560
wait_for_http_response(
560561
&format!("{}/epoch-settings", aggregator.endpoint()),
561562
Duration::from_secs(10),
562563
"Waiting for the aggregator to start",
563564
)
564565
.await?;
565566

566-
info!(">> Send the Signer Key Registrations payloads");
567+
info!(">> Send the Signer Key Registrations payloads for the genesis signers");
567568
let errors =
568-
register_signers_to_aggregator(&aggregator, &signers_fixture, current_epoch + 1).await?;
569+
register_signers_to_aggregator(&aggregator, &signers_fixture.signers(), *current_epoch + 1)
570+
.await?;
569571
assert_eq!(0, errors);
572+
aggregator.stop().await.unwrap();
570573

571574
info!(">> Move one epoch forward in order to issue the genesis certificate");
572-
current_epoch += 1;
573-
write_epoch(&mock_epoch_file_path, current_epoch);
574-
wait_for_epoch_settings_at_epoch(&aggregator, Duration::from_secs(10), current_epoch).await?;
575+
*current_epoch += 1;
576+
write_epoch(&args.mock_epoch_file_path(), *current_epoch);
577+
578+
info!(">> Restarting the aggregator still with a large run interval");
579+
aggregator.serve().unwrap();
580+
wait_for_http_response(
581+
&format!("{}/epoch-settings", aggregator.endpoint()),
582+
Duration::from_secs(10),
583+
"Waiting for the aggregator to start",
584+
)
585+
.await?;
586+
587+
info!(">> Send the Signer Key Registrations payloads for next genesis signers");
588+
let errors =
589+
register_signers_to_aggregator(&aggregator, &signers_fixture.signers(), *current_epoch + 1)
590+
.await?;
591+
assert_eq!(0, errors);
592+
aggregator.stop().await.unwrap();
593+
575594
{
576595
info!(">> Compute genesis certificate");
577596
let mut genesis_aggregator = Aggregator::copy_configuration(&aggregator);
578597
genesis_aggregator
579598
.bootstrap_genesis()
580599
.await
581600
.expect("Genesis aggregator should be able to bootstrap genesis");
582-
583-
sleep(Duration::from_secs(10)).await;
584601
}
585602

586-
info!(">> Send the Signer Key Registrations payloads");
587-
let errors =
588-
register_signers_to_aggregator(&aggregator, &signers_fixture, current_epoch + 1).await?;
589-
assert_eq!(0, errors);
603+
info!(">> Restart aggregator with a normal run interval");
604+
aggregator.change_run_interval(Duration::from_secs(3));
605+
aggregator.serve().unwrap();
606+
607+
wait_for_http_response(
608+
&format!("{}/epoch-settings", aggregator.endpoint()),
609+
Duration::from_secs(10),
610+
"Waiting for the aggregator to restart",
611+
)
612+
.await?;
613+
614+
info!(">> Aggregator bootrapped");
615+
616+
Ok(aggregator)
617+
}
618+
619+
#[tokio::main(flavor = "multi_thread", worker_threads = 20)]
620+
async fn main() -> StdResult<()> {
621+
let opts = MainOpts::parse();
622+
let _logger = init_logger(&opts);
623+
let args = AggregatorParameters::new(&opts)?;
624+
let mut current_epoch = Epoch(1);
625+
info!(">> Starting stress test with options: {opts:?}");
626+
627+
info!(">> Creation of the Signer Key Registrations payloads");
628+
let signers_fixture =
629+
generate_signer_data(opts.num_signers, ProtocolParameters::new(5, 100, 0.65));
630+
631+
info!(">> Precompute message & signatures for MithrilStakeDistribution signed entity");
632+
let mithril_stake_distribution_message = {
633+
let mut message = ProtocolMessage::new();
634+
message.set_message_part(
635+
mithril_common::entities::ProtocolMessagePartKey::NextAggregateVerificationKey,
636+
signers_fixture.compute_and_encode_avk(),
637+
);
638+
639+
message
640+
};
641+
let mithril_stake_distribution_signatures: Vec<SingleSignatures> = signers_fixture
642+
.signers_fixture()
643+
.iter()
644+
// filter map to exclude signers that could not sign because they lost the lottery
645+
.filter_map(|s| s.sign(&mithril_stake_distribution_message))
646+
.collect();
647+
648+
let mut aggregator = bootstrap_aggregator(&args, &signers_fixture, &mut current_epoch).await?;
590649

591650
info!(">> Move one epoch forward in order to start creating certificates");
592651
current_epoch += 1;
593-
write_epoch(&mock_epoch_file_path, current_epoch);
652+
write_epoch(&args.mock_epoch_file_path(), current_epoch);
594653
wait_for_epoch_settings_at_epoch(&aggregator, Duration::from_secs(10), current_epoch).await?;
595654

596655
info!(">> Send the Signer Key Registrations payloads");
597656
let errors =
598-
register_signers_to_aggregator(&aggregator, &signers_fixture, current_epoch + 1).await?;
657+
register_signers_to_aggregator(&aggregator, &signers_fixture.signers(), current_epoch + 1)
658+
.await?;
599659
assert_eq!(0, errors);
600660

601661
info!(">> Wait for pending certificate to be available");
602662
wait_for_pending_certificate(&aggregator, Duration::from_secs(30)).await?;
603663

604664
info!(
605-
">> Send the Signer Signatures Registrations payloads for MithrilStakeDistribution({:?})",
665+
">> Send the Signer Signatures payloads for MithrilStakeDistribution({:?})",
606666
current_epoch
607667
);
608668
let errors = register_signatures_to_aggregator(

0 commit comments

Comments
 (0)