Skip to content

Feat(e2e): support multiple aggregators in the e2e tests #2378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Mar 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ed6d240
feat(e2e): update e2e test command line arguments
jpraynaud Mar 10, 2025
33087c3
feat(e2e): 'MithrilInfrastructure' supports multiple aggregators
jpraynaud Mar 11, 2025
38cfb9d
refactor(e2e): implement interior mutability for 'Aggregator', 'RunOn…
jpraynaud Mar 12, 2025
fda11d1
refactor(relay): support for dialing to peer in relays of e2e test
jpraynaud Mar 13, 2025
a0cf5fa
refactor(e2e): enhance 'MithrilInfrastructure' support for multiple a…
jpraynaud Mar 13, 2025
42a89d5
feat(e2e): 'RunOnly' supports multiple aggregators
jpraynaud Mar 13, 2025
ce1b227
feat(e2e): 'Spec' supports multiple aggregators
jpraynaud Mar 13, 2025
8148e06
feat(e2e): runner supports multiple aggregators
jpraynaud Mar 13, 2025
30046b6
refactor(e2e): enhance naming of aggregators and associated relays
jpraynaud Mar 14, 2025
79c3370
refactor(e2e): enhance assertions checks
jpraynaud Mar 14, 2025
1f87495
fix(common): enhance Certificate display implementation
jpraynaud Mar 17, 2025
6de2a9d
fix(aggregator): integration test for slave uses evolving Mithril sta…
jpraynaud Mar 17, 2025
6162009
fix(common): avoid too low stake in random stake distribution
jpraynaud Mar 17, 2025
808d5ac
fix(aggregator): slave signer registration stabilization
jpraynaud Mar 17, 2025
b5ab3dc
feat(relay): implement signer relay modes
jpraynaud Mar 18, 2025
e31065a
refactor(e2e): use signer relay modes in e2e test
jpraynaud Mar 18, 2025
e2ab3d1
refactor(ci): update e2e tests in CI to use the signer relay modes
jpraynaud Mar 18, 2025
c886ea6
refactor(e2e): better naming for aggregators in e2e tests
jpraynaud Mar 18, 2025
4afa4e3
fix(e2e): delegate stakes only from the first aggregator
jpraynaud Mar 18, 2025
93421e9
refactor(e2e): remove distinction master/slave aggregator
jpraynaud Mar 19, 2025
5d6ba69
fix(e2e): make genesis bootstrap error retryable
jpraynaud Mar 19, 2025
ac3755a
fix(e2e): flakiness in the genesis bootstrap of slave aggregators
jpraynaud Mar 20, 2025
a302d26
refactor(e2e): enhance assertions logs with aggregator name
jpraynaud Mar 20, 2025
550a47d
fix(ci): wrong format for next era in some e2e scenarios
jpraynaud Mar 21, 2025
7e1ee64
fix(e2e): era switch done on multiple aggregators
jpraynaud Mar 21, 2025
2f3dd88
refactor(aggregator): simplify slave aggregator integration test
jpraynaud Mar 21, 2025
8715c9f
refactor(e2e): better parameter handling with clap
jpraynaud Mar 21, 2025
6d28b9e
chore(e2e): apply review comments
jpraynaud Mar 21, 2025
fded200
refactor(e2e): avoid rwlock of option in specs
Alenar Mar 21, 2025
52fb6ee
refactor(e2e): simplify chain observer usage
Alenar Mar 21, 2025
61ce264
refactor(e2e): remove dependency to 'mithril-relay'
jpraynaud Mar 24, 2025
9913eb7
refactor(relay): create function converting mpsc transmission result …
jpraynaud Mar 24, 2025
1a1bdbc
feat(relay): add tests for signer relay passthrough/p2p modes
jpraynaud Mar 25, 2025
db589f3
refactor(aggregator): slave synchronizer updates the next signers in …
jpraynaud Mar 27, 2025
bff5187
fix(relay): aggregator relay accepts 202 codes
jpraynaud Mar 27, 2025
2830aaf
fix(e2e): improve protocol parameters to remove flakiness
jpraynaud Mar 27, 2025
3fa9f42
fix(e2e): do not use passive relays by default
jpraynaud Mar 27, 2025
3b9d45c
refactor(e2e): run aggregators on full nodes
jpraynaud Mar 26, 2025
e442474
chore: upgrade crate versions
jpraynaud Mar 27, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -303,14 +303,22 @@ jobs:
extra_args: [""]

include:
# Include a test for the P2P mode
- mode: "p2p"
# Include a test for partial decentralization with master/slave signer registration and P2P signature registration
- mode: "master-slave"
era: ${{ fromJSON(needs.build-ubuntu-X64.outputs.eras)[0] }}
next_era: [""]
cardano_node_version: "10.2.1"
hard_fork_latest_era_at_epoch: 0
run_id: "#1"
extra_args: "--use-p2p-network"
extra_args: "--number-of-aggregators=2 --use-relays --relay-signer-registration-mode=passthrough --relay-signature-registration-mode=p2p"
# Include a test for full dedentralization P2P signer registration and P2P signature registration
- mode: "decentralized"
era: ${{ fromJSON(needs.build-ubuntu-X64.outputs.eras)[0] }}
next_era: ""
cardano_node_version: "10.1.4"
hard_fork_latest_era_at_epoch: 0
run_id: "#1"
extra_args: "--number-of-aggregators=2 --use-relays --relay-signer-registration-mode=p2p --relay-signature-registration-mode=p2p"
# Include a test for the era switch without regenesis
- mode: "std"
era: ${{ fromJSON(needs.build-ubuntu-X64.outputs.eras)[0] }}
Expand Down
37 changes: 30 additions & 7 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.7.25"
version = "0.7.26"
description = "A Mithril Aggregator server"
authors = { workspace = true }
edition = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ impl DependenciesBuilder {
&mut self,
) -> Result<Arc<MithrilSignerRegistrationSlave>> {
let registerer = MithrilSignerRegistrationSlave::new(
self.get_epoch_service().await?,
self.get_verification_key_store().await?,
self.get_signer_store().await?,
self.get_signer_registration_verifier().await?,
Expand Down
12 changes: 5 additions & 7 deletions mithril-aggregator/src/runtime/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ impl AggregatorRuntime {
info!(self.logger, "→ Trying to transition to READY"; "last_time_point" => ?last_time_point);

let can_try_transition_from_idle_to_ready = if self.config.is_slave {
println!("Checking if slave aggregator is at the same epoch as master");
self.runner
.is_slave_aggregator_at_same_epoch_as_master(&last_time_point)
.await?
Expand Down Expand Up @@ -265,18 +264,17 @@ impl AggregatorRuntime {
self.runner
.update_stake_distribution(&new_time_point)
.await?;
if self.config.is_slave {
self.runner
.synchronize_slave_aggregator_signer_registration()
.await?;
}
self.runner.inform_new_epoch(new_time_point.epoch).await?;

self.runner.upkeep(new_time_point.epoch).await?;
self.runner
.open_signer_registration_round(&new_time_point)
.await?;
self.runner.update_epoch_settings().await?;
if self.config.is_slave {
self.runner
.synchronize_slave_aggregator_signer_registration()
.await?;
}
self.runner.precompute_epoch_data().await?;
}

Expand Down
79 changes: 78 additions & 1 deletion mithril-aggregator/src/services/epoch_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pub trait EpochService: Sync + Send {
/// Note: must be called after `inform_epoch`.
async fn update_epoch_settings(&mut self) -> StdResult<()>;

/// Update the next signers with stake for the next epoch.
async fn update_next_signers_with_stake(&mut self) -> StdResult<()>;

/// Inform the service that it can precompute data for its current epoch.
///
/// Note: must be called after `inform_epoch`.
Expand Down Expand Up @@ -383,6 +386,27 @@ impl EpochService for MithrilEpochService {
self.insert_future_epoch_settings(data.epoch).await
}

async fn update_next_signers_with_stake(&mut self) -> StdResult<()> {
debug!(self.logger, ">> update_next_signers_with_stake");

let data = self.unwrap_data().with_context(|| {
"can't update next signers with stake if inform_epoch has not been called first"
})?;

let next_signer_retrieval_epoch = data.epoch.offset_to_next_signer_retrieval_epoch();
let next_signers_with_stake = self
.get_signers_with_stake_at_epoch(next_signer_retrieval_epoch)
.await?;

self.epoch_data.as_mut().unwrap().next_signers_with_stake = next_signers_with_stake;

self.precompute_epoch_data()
.await
.with_context(|| "Epoch service failed to precompute epoch data")?;

Ok(())
}

async fn precompute_epoch_data(&mut self) -> StdResult<()> {
debug!(self.logger, ">> precompute_epoch_data");

Expand Down Expand Up @@ -523,6 +547,7 @@ pub(crate) struct FakeEpochService {
inform_epoch_error: bool,
update_epoch_settings_error: bool,
precompute_epoch_data_error: bool,
update_next_signers_with_stake_error: bool,
}

#[cfg(test)]
Expand Down Expand Up @@ -615,6 +640,7 @@ impl FakeEpochServiceBuilder {
inform_epoch_error: false,
update_epoch_settings_error: false,
precompute_epoch_data_error: false,
update_next_signers_with_stake_error: false,
}
}
}
Expand Down Expand Up @@ -660,19 +686,21 @@ impl FakeEpochService {
inform_epoch_error: false,
update_epoch_settings_error: false,
precompute_epoch_data_error: false,
update_next_signers_with_stake_error: false,
}
}

#[allow(dead_code)]
pub fn toggle_errors(
&mut self,
inform_epoch: bool,
update_protocol_parameters: bool,
precompute_epoch: bool,
update_next_signers_with_stake: bool,
) {
self.inform_epoch_error = inform_epoch;
self.update_epoch_settings_error = update_protocol_parameters;
self.precompute_epoch_data_error = precompute_epoch;
self.update_next_signers_with_stake_error = update_next_signers_with_stake;
}

fn unwrap_data(&self) -> Result<&EpochData, EpochServiceError> {
Expand Down Expand Up @@ -714,6 +742,13 @@ impl EpochService for FakeEpochService {
Ok(())
}

async fn update_next_signers_with_stake(&mut self) -> StdResult<()> {
if self.update_next_signers_with_stake_error {
anyhow::bail!("update_next_signers_with_stake fake error");
}
Ok(())
}

fn cardano_era(&self) -> StdResult<CardanoEra> {
Ok(self.unwrap_data()?.cardano_era.clone())
}
Expand Down Expand Up @@ -1213,6 +1248,48 @@ mod tests {
assert!(service.computed_epoch_data.is_none());
}

#[tokio::test]
async fn update_next_signers_with_stake_succeeds() {
let fixture = MithrilFixtureBuilder::default().with_signers(3).build();
let next_fixture = MithrilFixtureBuilder::default().with_signers(5).build();
let next_avk = next_fixture.compute_avk();
let epoch = Epoch(4);
let mut service = EpochServiceBuilder {
next_signers_with_stake: next_fixture.signers_with_stake().clone(),
..EpochServiceBuilder::new(epoch, fixture.clone())
}
.build()
.await;
service
.inform_epoch(epoch)
.await
.expect("inform_epoch should not fail");
service.epoch_data = Some(EpochData {
next_signers_with_stake: vec![],
..service.epoch_data.unwrap()
});
service.computed_epoch_data = None;

service
.update_next_signers_with_stake()
.await
.expect("update_next_signers_with_stake should not fail");

let expected_next_signers_with_stake = next_fixture.signers_with_stake();
assert_eq!(
expected_next_signers_with_stake,
service.epoch_data.unwrap().next_signers_with_stake
);

assert_eq!(
next_avk,
service
.computed_epoch_data
.unwrap()
.next_aggregate_verification_key
);
}

#[tokio::test]
async fn update_epoch_settings_insert_future_epoch_settings_in_the_store() {
let future_protocol_parameters = ProtocolParameters::new(6, 89, 0.124);
Expand Down
8 changes: 6 additions & 2 deletions mithril-aggregator/src/services/signer_registration/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ pub enum SignerRegistrationError {
#[error("signer already registered")]
ExistingSigner(Box<SignerWithStake>),

/// Store error.
/// Store.
#[error("store error")]
StoreError(#[source] StdError),
Store(#[source] StdError),

/// Epoch service.
#[error("epoch service error")]
EpochService(#[source] StdError),

/// Signer registration failed.
#[error("signer registration failed")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ impl SignerRegisterer for MithrilSignerRegistrationMaster {
registration_round.epoch
)
})
.map_err(|e| SignerRegistrationError::StoreError(anyhow!(e)))?
.map_err(|e| SignerRegistrationError::Store(anyhow!(e)))?
{
Some(_) => Err(SignerRegistrationError::ExistingSigner(Box::new(
signer_save,
Expand Down
Loading