diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index d85d2150abbb..0ead49f61bdf 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -8,6 +8,7 @@ use crate::{ validate_merge_neurons_before_commit, }, split_neuron::{SplitNeuronEffect, calculate_split_neuron_effect}, + voting_power_snapshots::VotingPowerSnapshots, }, heap_governance_data::{ HeapGovernanceData, XdrConversionRate, initialize_governance, reassemble_governance_proto, @@ -1355,6 +1356,8 @@ impl Governance { governance.heap_data.neuron_id_to_pre_clamp_dissolve_state = governance .neuron_store .clamp_dissolve_delay_for_all_neurons_or_panic(now); + + VOTING_POWER_SNAPSHOTS.with_borrow_mut(VotingPowerSnapshots::clear); } governance diff --git a/rs/nns/governance/src/governance/voting_power_snapshots.rs b/rs/nns/governance/src/governance/voting_power_snapshots.rs index fd2f0071a89d..d2951f1a351b 100644 --- a/rs/nns/governance/src/governance/voting_power_snapshots.rs +++ b/rs/nns/governance/src/governance/voting_power_snapshots.rs @@ -5,7 +5,7 @@ use crate::{ pb::v1::{Ballot, NeuronIdToVotingPowerMap, VotingPowerTotal}, }; -use ic_cdk::eprintln; +use ic_cdk::{eprintln, println}; use ic_nervous_system_common::ONE_MONTH_SECONDS; use ic_stable_structures::{ DefaultMemoryImpl, StableBTreeMap, Storable, memory_manager::VirtualMemory, storable::Bound, @@ -202,6 +202,14 @@ impl VotingPowerSnapshots { voting_power_map, totals_with_minimum_total_potential_voting_power, )); + println!( + "{}Voting power spike detected at timestamp {}, total potential voting power: {}, \ + minimum total potential voting power: {}", + LOG_PREFIX, + timestamp_with_minimum_total_potential_voting_power, + total_potential_voting_power, + totals_with_minimum_total_potential_voting_power.total_potential_voting_power + ); Some(( timestamp_with_minimum_total_potential_voting_power, previous_voting_power_snapshot, @@ -214,6 +222,13 @@ impl VotingPowerSnapshots { .last_key_value() .map(|(timestamp, _)| timestamp) } + + /// Clears the voting power snapshots. + // TODO(NNS1-4323): Remove this method after Mission 70 is fully deployed. + pub(crate) fn clear(&mut self) { + self.neuron_id_to_voting_power_maps.clear_new(); + self.voting_power_totals.clear_new(); + } } impl Storable for NeuronIdToVotingPowerMap { diff --git a/rs/nns/governance/src/governance/voting_power_snapshots_tests.rs b/rs/nns/governance/src/governance/voting_power_snapshots_tests.rs index 7f8b9a7b3f19..c1ac267c6902 100644 --- a/rs/nns/governance/src/governance/voting_power_snapshots_tests.rs +++ b/rs/nns/governance/src/governance/voting_power_snapshots_tests.rs @@ -113,3 +113,32 @@ fn test_record_voting_power_snapshot() { None, ); } + +// TODO(NNS1-4323): Remove this test after Mission 70 is fully deployed. +#[test] +fn test_clear() { + let memory_manager = MemoryManager::init(DefaultMemoryImpl::default()); + let mut snapshots = VotingPowerSnapshots::new( + memory_manager.get(MemoryId::new(0)), + memory_manager.get(MemoryId::new(1)), + ); + + // Record a few snapshots. + for i in 1..=3 { + snapshots.record_voting_power_snapshot(i, voting_power_snapshot(vec![90, 10], 100 + i)); + } + + // Verify that snapshots are present. + assert_eq!(snapshots.latest_snapshot_timestamp_seconds(), Some(3)); + + // Clear the snapshots. + snapshots.clear(); + + // Verify that everything is empty. + assert_eq!(snapshots.latest_snapshot_timestamp_seconds(), None); + assert_eq!( + snapshots.previous_ballots_if_voting_power_spike_detected(u64::MAX, 10), + None + ); + assert!(!snapshots.is_latest_snapshot_a_spike(10)); +}