diff --git a/crates/sui-core/src/authority/authority_per_epoch_store.rs b/crates/sui-core/src/authority/authority_per_epoch_store.rs index 4f0ca326b23fe..e6e7315ad7224 100644 --- a/crates/sui-core/src/authority/authority_per_epoch_store.rs +++ b/crates/sui-core/src/authority/authority_per_epoch_store.rs @@ -726,6 +726,7 @@ impl AuthorityPerEpochStore { epoch_id ); let epoch_start_configuration = Arc::new(epoch_start_configuration); + info!("epoch flags: {:?}", epoch_start_configuration.flags()); metrics.current_epoch.set(epoch_id as i64); metrics .current_voting_right diff --git a/crates/sui-core/src/state_accumulator.rs b/crates/sui-core/src/state_accumulator.rs index c849e3e86c821..f67f150839721 100644 --- a/crates/sui-core/src/state_accumulator.rs +++ b/crates/sui-core/src/state_accumulator.rs @@ -678,6 +678,10 @@ impl StateAccumulatorV2 { checkpoint_acc: Option, ) -> SuiResult { let _scope = monitored_scope("AccumulateRunningRoot"); + tracing::info!( + "accumulating running root for checkpoint {}", + checkpoint_seq_num + ); // For the last checkpoint of the epoch, this function will be called once by the // checkpoint builder, and again by checkpoint executor. diff --git a/crates/sui-e2e-tests/tests/reconfiguration_tests.rs b/crates/sui-e2e-tests/tests/reconfiguration_tests.rs index 85363a6c97af1..c21ace857d90c 100644 --- a/crates/sui-e2e-tests/tests/reconfiguration_tests.rs +++ b/crates/sui-e2e-tests/tests/reconfiguration_tests.rs @@ -710,6 +710,72 @@ async fn do_test_reconfig_with_committee_change_stress() { } } +#[cfg(msim)] +#[sim_test] +async fn test_epoch_flag_upgrade() { + use std::any; + + use std::sync::Mutex; + use sui_core::authority::epoch_start_configuration::EpochFlag; + use sui_core::authority::epoch_start_configuration::EpochStartConfigTrait; + use sui_macros::register_fail_point_arg; + + let initial_flags_nodes = Arc::new(Mutex::new(HashSet::new())); + register_fail_point_arg("initial_epoch_flags", move || { + // only alter flags on each node once + let current_node = sui_simulator::current_simnode_id(); + + // override flags on up to 2 nodes. + let mut initial_flags_nodes = initial_flags_nodes.lock().unwrap(); + if initial_flags_nodes.len() >= 2 || !initial_flags_nodes.insert(current_node) { + return None; + } + + // start with no flags set + Some(Vec::::new()) + }); + + let test_cluster = TestClusterBuilder::new() + .with_epoch_duration_ms(30000) + .build() + .await; + + let mut any_empty = false; + for node in test_cluster.all_node_handles() { + any_empty = any_empty + || node.with(|node| { + node.state() + .epoch_store_for_testing() + .epoch_start_config() + .flags() + .is_empty() + }); + } + assert!(any_empty); + + test_cluster.wait_for_epoch_all_nodes(1).await; + + let mut any_empty = false; + for node in test_cluster.all_node_handles() { + any_empty = any_empty + || node.with(|node| { + node.state() + .epoch_store_for_testing() + .epoch_start_config() + .flags() + .is_empty() + }); + } + assert!(!any_empty); + + sleep(Duration::from_secs(15)).await; + + test_cluster.stop_all_validators().await; + test_cluster.start_all_validators().await; + + test_cluster.wait_for_epoch_all_nodes(2).await; +} + #[cfg(msim)] #[sim_test] async fn safe_mode_reconfig_test() {