diff --git a/state-chain/cf-integration-tests/src/authorities.rs b/state-chain/cf-integration-tests/src/authorities.rs index e27af1d5cf..0307f015dd 100644 --- a/state-chain/cf-integration-tests/src/authorities.rs +++ b/state-chain/cf-integration-tests/src/authorities.rs @@ -59,10 +59,10 @@ pub fn fund_authorities_and_join_auction( /// by going through the correct sequence in sync. #[test] fn authority_rotates_with_correct_sequence() { - const EPOCH_DURATION_BLOCKS: u32 = 1000; + const EPOCH_BLOCKS: u32 = 1000; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_DURATION_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -162,7 +162,7 @@ fn authorities_earn_rewards_for_authoring_blocks() { // set const MAX_AUTHORITIES: AuthorityCount = 3; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -206,7 +206,7 @@ fn genesis_nodes_rotated_out_accumulate_rewards_correctly() { // set const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -273,7 +273,7 @@ fn authority_rotation_can_succeed_after_aborted_by_safe_mode() { const EPOCH_BLOCKS: u32 = 1000; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -328,7 +328,7 @@ fn authority_rotation_cannot_be_aborted_after_key_handover_and_completes_even_on const EPOCH_BLOCKS: u32 = 1000; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -371,7 +371,7 @@ fn authority_rotation_can_recover_after_keygen_fails() { const EPOCH_BLOCKS: u32 = 1000; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -424,7 +424,7 @@ fn authority_rotation_can_recover_after_key_handover_fails() { const EPOCH_BLOCKS: u32 = 1000; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -502,7 +502,7 @@ fn can_move_through_multiple_epochs() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -524,7 +524,7 @@ fn cant_rotate_if_previous_rotation_is_pending() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -559,7 +559,7 @@ fn waits_for_governance_when_apicall_fails() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { diff --git a/state-chain/cf-integration-tests/src/broadcasting.rs b/state-chain/cf-integration-tests/src/broadcasting.rs index 5b4754ba64..4f1b61210f 100644 --- a/state-chain/cf-integration-tests/src/broadcasting.rs +++ b/state-chain/cf-integration-tests/src/broadcasting.rs @@ -12,10 +12,10 @@ use state_chain_runtime::{ #[test] fn bitcoin_broadcast_delay_works() { - const EPOCH_DURATION_BLOCKS: u32 = 200; + const EPOCH_BLOCKS: u32 = 200; const MAX_AUTHORITIES: AuthorityCount = 150; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_DURATION_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { diff --git a/state-chain/cf-integration-tests/src/funding.rs b/state-chain/cf-integration-tests/src/funding.rs index 68e793d5a6..00a8997198 100644 --- a/state-chain/cf-integration-tests/src/funding.rs +++ b/state-chain/cf-integration-tests/src/funding.rs @@ -22,10 +22,10 @@ use state_chain_runtime::{ // We have a set of nodes that are funded and can redeem in the redeeming period and // not redeem when out of the period fn cannot_redeem_funds_out_of_redemption_period() { - const EPOCH_DURATION_BLOCKS: u32 = 100; + const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 3; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_DURATION_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -68,7 +68,7 @@ fn cannot_redeem_funds_out_of_redemption_period() { } let end_of_redemption_period = - EPOCH_DURATION_BLOCKS * REDEMPTION_PERIOD_AS_PERCENTAGE as u32 / 100; + EPOCH_BLOCKS * REDEMPTION_PERIOD_AS_PERCENTAGE as u32 / 100; // Move to end of the redemption period System::set_block_number(end_of_redemption_period + 1); // We will try to redeem @@ -125,7 +125,7 @@ fn cannot_redeem_funds_out_of_redemption_period() { fn funded_node_is_added_to_backups() { const EPOCH_BLOCKS: u32 = 10_000_000; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) // As we run a rotation at genesis we will need accounts to support // having 5 authorities as the default is 3 (Alice, Bob and Charlie) .accounts(vec![ @@ -149,7 +149,7 @@ fn backup_reward_is_calculated_linearly() { const MAX_AUTHORITIES: u32 = 10; const NUM_BACKUPS: u32 = 20; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -194,7 +194,7 @@ fn can_calculate_account_apy() { const MAX_AUTHORITIES: u32 = 10; const NUM_BACKUPS: u32 = 20; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -246,7 +246,7 @@ fn apy_can_be_above_100_percent() { const MAX_AUTHORITIES: u32 = 2; const NUM_BACKUPS: u32 = 2; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -282,7 +282,7 @@ fn backup_rewards_event_gets_emitted_on_heartbeat_interval() { const NUM_BACKUPS: u32 = 20; const MAX_AUTHORITIES: u32 = 100; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .accounts( (0..MAX_AUTHORITIES as u8) .map(|i| (AccountId32::from([i; 32]), AccountRole::Validator, GENESIS_BALANCE)) diff --git a/state-chain/cf-integration-tests/src/genesis.rs b/state-chain/cf-integration-tests/src/genesis.rs index 231e3b88c3..94ed0b3828 100644 --- a/state-chain/cf-integration-tests/src/genesis.rs +++ b/state-chain/cf-integration-tests/src/genesis.rs @@ -14,7 +14,7 @@ use state_chain_runtime::{ }; pub const GENESIS_BALANCE: FlipBalance = TOTAL_ISSUANCE / 100; -const EPOCH_DURATION: u32 = 1000; +const BLOCKS_PER_EPOCH: u32 = 1000; pub fn with_test_defaults() -> ExtBuilder { ExtBuilder::default() @@ -26,7 +26,7 @@ pub fn with_test_defaults() -> ExtBuilder { (AccountId::from(LIQUIDITY_PROVIDER), AccountRole::LiquidityProvider, GENESIS_BALANCE), ]) .root(AccountId::from(ERIN)) - .epoch_duration(EPOCH_DURATION) + .blocks_per_epoch(BLOCKS_PER_EPOCH) } #[test] @@ -62,8 +62,8 @@ fn state_of_genesis_is_as_expected() { } assert_eq!( - Validator::epoch_duration(), - EPOCH_DURATION, + Validator::blocks_per_epoch(), + BLOCKS_PER_EPOCH, "epochs will not rotate automatically from genesis" ); diff --git a/state-chain/cf-integration-tests/src/mock_runtime.rs b/state-chain/cf-integration-tests/src/mock_runtime.rs index 41a70ad56d..56251afa19 100644 --- a/state-chain/cf-integration-tests/src/mock_runtime.rs +++ b/state-chain/cf-integration-tests/src/mock_runtime.rs @@ -67,7 +67,7 @@ use cf_primitives::{ pub struct ExtBuilder { pub genesis_accounts: Vec<(AccountId, AccountRole, FlipBalance)>, root: Option, - epoch_duration: BlockNumber, + blocks_per_epoch: BlockNumber, max_authorities: AuthorityCount, min_authorities: AuthorityCount, } @@ -79,7 +79,7 @@ impl Default for ExtBuilder { min_authorities: 1, genesis_accounts: Default::default(), root: Default::default(), - epoch_duration: Default::default(), + blocks_per_epoch: Default::default(), } } } @@ -103,8 +103,8 @@ impl ExtBuilder { self } - pub fn epoch_duration(mut self, epoch_duration: BlockNumber) -> Self { - self.epoch_duration = epoch_duration; + pub fn blocks_per_epoch(mut self, blocks_per_epoch: BlockNumber) -> Self { + self.blocks_per_epoch = blocks_per_epoch; self } @@ -184,7 +184,7 @@ impl ExtBuilder { }) .collect(), genesis_backups: Default::default(), - epoch_duration: self.epoch_duration, + blocks_per_epoch: self.blocks_per_epoch, bond: self .genesis_accounts .iter() diff --git a/state-chain/cf-integration-tests/src/network.rs b/state-chain/cf-integration-tests/src/network.rs index 8ac59a2d6b..8b03627874 100644 --- a/state-chain/cf-integration-tests/src/network.rs +++ b/state-chain/cf-integration-tests/src/network.rs @@ -691,7 +691,7 @@ impl Network { /// Move to the last block of the epoch - next block will start Authority rotation pub fn move_to_the_end_of_epoch(&mut self) { let current_block = System::block_number(); - let target = Validator::current_epoch_started_at() + Validator::epoch_duration(); + let target = Validator::current_epoch_started_at() + Validator::blocks_per_epoch(); if target > current_block { self.move_forward_blocks(target - current_block - 1) } diff --git a/state-chain/cf-integration-tests/src/new_epoch.rs b/state-chain/cf-integration-tests/src/new_epoch.rs index f5161b16d5..932bc06447 100644 --- a/state-chain/cf-integration-tests/src/new_epoch.rs +++ b/state-chain/cf-integration-tests/src/new_epoch.rs @@ -17,9 +17,9 @@ use state_chain_runtime::{ #[test] fn auction_repeats_after_failure_because_of_liveness() { - const EPOCH_DURATION_BLOCKS: BlockNumber = 1000; + const EPOCH_BLOCKS: BlockNumber = 1000; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_DURATION_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) // As we run a rotation at genesis we will need accounts to support // having 5 authorities as the default is 3 (Alice, Bob and Charlie) .accounts(vec![ @@ -107,7 +107,7 @@ fn epoch_rotates() { const EPOCH_BLOCKS: BlockNumber = 1000; const MAX_SET_SIZE: AuthorityCount = 5; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .min_authorities(MAX_SET_SIZE) .build() .execute_with(|| { @@ -247,7 +247,7 @@ fn can_consolidate_bitcoin_utxos() { const MAX_AUTHORITIES: AuthorityCount = 5; const CONSOLIDATION_SIZE: u32 = 2; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .build() .execute_with(|| { let (mut testnet, _, _) = diff --git a/state-chain/cf-integration-tests/src/solana.rs b/state-chain/cf-integration-tests/src/solana.rs index b1b521c7be..e4aa87e81b 100644 --- a/state-chain/cf-integration-tests/src/solana.rs +++ b/state-chain/cf-integration-tests/src/solana.rs @@ -149,10 +149,10 @@ fn schedule_deposit_to_swap( #[test] fn can_build_solana_batch_all() { - const EPOCH_DURATION_BLOCKS: u32 = 100; + const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_DURATION_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .with_additional_accounts(&[ (DORIS, AccountRole::LiquidityProvider, 5 * FLIPPERINOS_PER_FLIP), @@ -225,7 +225,7 @@ fn can_rotate_solana_vault() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -284,7 +284,7 @@ fn can_send_solana_ccm() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .with_additional_accounts(&[ (DORIS, AccountRole::LiquidityProvider, 5 * FLIPPERINOS_PER_FLIP), @@ -363,7 +363,7 @@ fn solana_ccm_fails_with_invalid_input() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .with_additional_accounts(&[ (DORIS, AccountRole::LiquidityProvider, 5 * FLIPPERINOS_PER_FLIP), @@ -528,7 +528,7 @@ fn failed_ccm_does_not_consume_durable_nonce() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .with_additional_accounts(&[ (DORIS, AccountRole::LiquidityProvider, 5 * FLIPPERINOS_PER_FLIP), @@ -590,7 +590,7 @@ fn solana_resigning() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .with_additional_accounts(&[ (DORIS, AccountRole::LiquidityProvider, 5 * FLIPPERINOS_PER_FLIP), @@ -666,7 +666,7 @@ fn solana_ccm_execution_error_can_trigger_fallback() { const EPOCH_BLOCKS: u32 = 100; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .with_additional_accounts(&[ (DORIS, AccountRole::LiquidityProvider, 5 * FLIPPERINOS_PER_FLIP), diff --git a/state-chain/cf-integration-tests/src/swapping.rs b/state-chain/cf-integration-tests/src/swapping.rs index f9cc1e5310..180b5b798d 100644 --- a/state-chain/cf-integration-tests/src/swapping.rs +++ b/state-chain/cf-integration-tests/src/swapping.rs @@ -767,10 +767,10 @@ fn ethereum_ccm_can_calculate_gas_limits() { #[test] fn can_resign_failed_ccm() { - const EPOCH_DURATION_BLOCKS: u32 = 1000; + const EPOCH_BLOCKS: u32 = 1000; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_DURATION_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -882,7 +882,7 @@ fn can_handle_failed_vault_transfer() { const EPOCH_BLOCKS: u32 = 1000; const MAX_AUTHORITIES: AuthorityCount = 10; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { diff --git a/state-chain/cf-integration-tests/src/witnessing.rs b/state-chain/cf-integration-tests/src/witnessing.rs index 38cb8884d6..c29545c429 100644 --- a/state-chain/cf-integration-tests/src/witnessing.rs +++ b/state-chain/cf-integration-tests/src/witnessing.rs @@ -16,10 +16,10 @@ use pallet_cf_witnesser::{CallHash, CallHashExecuted, WitnessDeadline}; #[test] fn can_punish_failed_witnesser() { - const EPOCH_DURATION_BLOCKS: u32 = 1000; + const EPOCH_BLOCKS: u32 = 1000; const MAX_AUTHORITIES: AuthorityCount = 50; super::genesis::with_test_defaults() - .epoch_duration(EPOCH_DURATION_BLOCKS) + .blocks_per_epoch(EPOCH_BLOCKS) .max_authorities(MAX_AUTHORITIES) .build() .execute_with(|| { @@ -46,7 +46,7 @@ fn can_punish_failed_witnesser() { assert_ok!(Reputation::set_penalty( pallet_cf_governance::RawOrigin::GovernanceApproval.into(), Offence::FailedToWitnessInTime, - Penalty { reputation: -100, suspension: EPOCH_DURATION_BLOCKS }, + Penalty { reputation: -100, suspension: EPOCH_BLOCKS }, )); // Before the deadline is set, no one has been reported. diff --git a/state-chain/custom-rpc/src/lib.rs b/state-chain/custom-rpc/src/lib.rs index da9083e12a..c0f6fe8305 100644 --- a/state-chain/custom-rpc/src/lib.rs +++ b/state-chain/custom-rpc/src/lib.rs @@ -1,4 +1,4 @@ -use crate::{boost_pool_rpc::BoostPoolFeesRpc, monitoring::RpcEpochStateV2}; +use crate::boost_pool_rpc::BoostPoolFeesRpc; use boost_pool_rpc::BoostPoolDetailsRpc; use cf_amm::{ common::{Amount as AmmAmount, PoolPairsMap, Side, Tick}, @@ -46,7 +46,7 @@ use state_chain_runtime::{ chainflip::{BlockUpdate, Offence}, constants::common::TX_FEE_MULTIPLIER, monitoring_apis::{ - ActivateKeysBroadcastIds, AuthoritiesInfo, BtcUtxos, ExternalChainsBlockHeight, + ActivateKeysBroadcastIds, AuthoritiesInfo, BtcUtxos, EpochState, ExternalChainsBlockHeight, FeeImbalance, FlipSupply, LastRuntimeUpgradeInfo, MonitoringData, OpenDepositChannels, PendingBroadcasts, PendingTssCeremonies, RedemptionsInfo, SolanaNonces, }, @@ -67,6 +67,25 @@ use std::{ pub mod monitoring; pub mod order_fills; +#[derive(Serialize, Deserialize, Clone)] +pub struct RpcEpochState { + pub blocks_per_epoch: u32, + pub current_epoch_started_at: u32, + pub current_epoch_index: u32, + pub min_active_bid: Option, + pub rotation_phase: String, +} +impl From for RpcEpochState { + fn from(rotation_state: EpochState) -> Self { + Self { + blocks_per_epoch: rotation_state.blocks_per_epoch, + current_epoch_started_at: rotation_state.current_epoch_started_at, + current_epoch_index: rotation_state.current_epoch_index, + rotation_phase: rotation_state.rotation_phase, + min_active_bid: rotation_state.min_active_bid.map(Into::into), + } + } +} #[derive(Serialize, Deserialize, Clone)] pub struct RpcRedemptionsInfo { pub total_balance: NumberOrHex, @@ -98,7 +117,7 @@ impl From for RpcFlipSupply { pub struct RpcMonitoringData { pub external_chains_height: ExternalChainsBlockHeight, pub btc_utxos: BtcUtxos, - pub epoch: RpcEpochStateV2, + pub epoch: RpcEpochState, pub pending_redemptions: RpcRedemptionsInfo, pub pending_broadcasts: PendingBroadcasts, pub pending_tss: PendingTssCeremonies, @@ -345,7 +364,7 @@ type RpcSuspensions = Vec<(Offence, Vec<(u32, state_chain_runtime::AccountId)>)> #[derive(Serialize, Deserialize, Clone)] pub struct RpcAuctionState { - epoch_duration: u32, + blocks_per_epoch: u32, current_epoch_started_at: u32, redemption_period_as_percentage: u8, min_funding: NumberOrHex, @@ -356,7 +375,7 @@ pub struct RpcAuctionState { impl From for RpcAuctionState { fn from(auction_state: AuctionState) -> Self { Self { - epoch_duration: auction_state.epoch_duration, + blocks_per_epoch: auction_state.blocks_per_epoch, current_epoch_started_at: auction_state.current_epoch_started_at, redemption_period_as_percentage: auction_state.redemption_period_as_percentage, min_funding: auction_state.min_funding.into(), diff --git a/state-chain/custom-rpc/src/monitoring.rs b/state-chain/custom-rpc/src/monitoring.rs index cdcf430f51..8973af24f8 100644 --- a/state-chain/custom-rpc/src/monitoring.rs +++ b/state-chain/custom-rpc/src/monitoring.rs @@ -1,10 +1,8 @@ use super::pass_through; use crate::{BlockT, CustomRpc, RpcAccountInfoV2, RpcFeeImbalance, RpcMonitoringData, RpcResult}; use cf_chains::{dot::PolkadotAccountId, sol::SolAddress}; -use cf_utilities::rpc::NumberOrHex; use jsonrpsee::proc_macros::rpc; use sc_client_api::{BlockchainEvents, HeaderBackend}; -use serde::{Deserialize, Serialize}; use sp_core::{bounded_vec::BoundedVec, ConstU32}; use state_chain_runtime::{ chainflip::Offence, @@ -14,44 +12,6 @@ use state_chain_runtime::{ PendingTssCeremonies, RedemptionsInfo, SolanaNonces, }, }; -impl From for RpcEpochState { - fn from(rotation_state: EpochState) -> Self { - Self { - epoch_duration: rotation_state.epoch_duration, - current_epoch_started_at: rotation_state.current_epoch_started_at, - current_epoch_index: rotation_state.current_epoch_index, - rotation_phase: rotation_state.rotation_phase, - min_active_bid: rotation_state.min_active_bid.map(Into::into), - } - } -} -#[derive(Serialize, Deserialize, Clone)] -pub struct RpcEpochState { - pub epoch_duration: u32, - pub current_epoch_started_at: u32, - pub current_epoch_index: u32, - pub min_active_bid: Option, - pub rotation_phase: String, -} - -// Temporary struct to hold the deprecated blocks_per_epoch field. -// Can be deleted after v1.7 is released (meaning: after the version is bumped to 1.8). -#[derive(Serialize, Deserialize, Clone)] -pub struct RpcEpochStateV2 { - #[deprecated( - since = "1.8.0", - note = "This field is deprecated and will be removed in v1.8. Use blocks_per_epoch instead." - )] - blocks_per_epoch: u32, - #[serde(flatten)] - epoch_state: RpcEpochState, -} - -impl From for RpcEpochStateV2 { - fn from(epoch_state: EpochState) -> Self { - Self { blocks_per_epoch: epoch_state.epoch_duration, epoch_state: epoch_state.into() } - } -} #[rpc(server, client, namespace = "cf_monitoring")] pub trait MonitoringApi { @@ -72,7 +32,7 @@ pub trait MonitoringApi { at: Option, ) -> RpcResult>; #[method(name = "epoch_state")] - fn cf_epoch_state(&self, at: Option) -> RpcResult; + fn cf_epoch_state(&self, at: Option) -> RpcResult; #[method(name = "redemptions")] fn cf_redemptions(&self, at: Option) -> RpcResult; #[method(name = "pending_broadcasts")] @@ -141,7 +101,7 @@ where cf_btc_utxos() -> BtcUtxos, cf_dot_aggkey() -> PolkadotAccountId, cf_suspended_validators() -> Vec<(Offence, u32)>, - cf_epoch_state() -> RpcEpochStateV2 [map: RpcEpochStateV2::from], + cf_epoch_state() -> EpochState, cf_redemptions() -> RedemptionsInfo, cf_pending_broadcasts_count() -> PendingBroadcasts, cf_pending_tss_ceremonies_count() -> PendingTssCeremonies, diff --git a/state-chain/node/src/chain_spec.rs b/state-chain/node/src/chain_spec.rs index cfc0c2247a..126ed02d02 100644 --- a/state-chain/node/src/chain_spec.rs +++ b/state-chain/node/src/chain_spec.rs @@ -547,7 +547,7 @@ fn testnet_genesis( genesis_funding_amount: u128, minimum_funding: u128, redemption_tax: u128, - epoch_duration: BlockNumber, + blocks_per_epoch: BlockNumber, redemption_ttl_secs: u64, current_authority_emission_inflation_perbill: u32, backup_node_emission_inflation_perbill: u32, @@ -659,7 +659,7 @@ fn testnet_genesis( } }) .collect::<_>(), - epoch_duration, + blocks_per_epoch, redemption_period_as_percentage, backup_reward_node_percentage: Percent::from_percent(33), bond: all_accounts diff --git a/state-chain/pallets/cf-validator/src/lib.rs b/state-chain/pallets/cf-validator/src/lib.rs index 368899ef06..405c9ad786 100644 --- a/state-chain/pallets/cf-validator/src/lib.rs +++ b/state-chain/pallets/cf-validator/src/lib.rs @@ -69,7 +69,7 @@ pub enum PalletConfigUpdate { type RuntimeRotationState = RotationState<::ValidatorId, ::Amount>; -pub const PALLET_VERSION: StorageVersion = StorageVersion::new(5); +pub const PALLET_VERSION: StorageVersion = StorageVersion::new(4); // Might be better to add the enum inside a struct rather than struct inside enum #[derive(Clone, PartialEq, Eq, Default, Encode, Decode, TypeInfo, RuntimeDebugNoBound)] @@ -174,10 +174,10 @@ pub mod pallet { #[pallet::getter(fn current_epoch_started_at)] pub type CurrentEpochStartedAt = StorageValue<_, BlockNumberFor, ValueQuery>; - /// The amount of blocks in an epoch. + /// The duration of an epoch in blocks. #[pallet::storage] - #[pallet::getter(fn epoch_duration)] - pub type EpochDuration = StorageValue<_, BlockNumberFor, ValueQuery>; + #[pallet::getter(fn blocks_per_epoch)] + pub type BlocksPerEpoch = StorageValue<_, BlockNumberFor, ValueQuery>; /// Current epoch index. #[pallet::storage] @@ -379,8 +379,8 @@ pub mod pallet { let mut weight = Weight::zero(); // Check expiry of epoch and store last expired. - if let Some(epoch_to_expire) = EpochExpiries::::take(block_number) { - Self::expire_epochs_up_to(epoch_to_expire); + if let Some(epoch_index) = EpochExpiries::::take(block_number) { + weight.saturating_accrue(Self::expire_epoch(epoch_index)); } weight.saturating_accrue(Self::punish_missed_authorship_slots()); @@ -389,7 +389,7 @@ pub mod pallet { weight.saturating_accrue(match CurrentRotationPhase::::get() { RotationPhase::Idle => { if block_number.saturating_sub(CurrentEpochStartedAt::::get()) >= - EpochDuration::::get() { + BlocksPerEpoch::::get() { if T::RotationBroadcastsPending::rotation_broadcasts_pending() { Self::deposit_event(Event::PreviousRotationStillPending); T::ValidatorWeightInfo::rotation_phase_idle() @@ -536,7 +536,7 @@ pub mod pallet { }, PalletConfigUpdate::EpochDuration { blocks } => { ensure!(blocks > 0, Error::::InvalidEpochDuration); - EpochDuration::::set(blocks.into()); + BlocksPerEpoch::::set(blocks.into()); }, PalletConfigUpdate::AuctionParameters { parameters } => { Self::try_update_auction_parameters(parameters)?; @@ -820,7 +820,7 @@ pub mod pallet { pub struct GenesisConfig { pub genesis_authorities: BTreeSet>, pub genesis_backups: BackupMap, - pub epoch_duration: BlockNumberFor, + pub blocks_per_epoch: BlockNumberFor, pub bond: T::Amount, pub redemption_period_as_percentage: Percent, pub backup_reward_node_percentage: Percent, @@ -835,7 +835,7 @@ pub mod pallet { Self { genesis_authorities: Default::default(), genesis_backups: Default::default(), - epoch_duration: Zero::zero(), + blocks_per_epoch: Zero::zero(), bond: Default::default(), redemption_period_as_percentage: Zero::zero(), backup_reward_node_percentage: Zero::zero(), @@ -856,7 +856,7 @@ pub mod pallet { fn build(&self) { use cf_primitives::GENESIS_EPOCH; LastExpiredEpoch::::set(Default::default()); - EpochDuration::::set(self.epoch_duration); + BlocksPerEpoch::::set(self.blocks_per_epoch); CurrentRotationPhase::::set(RotationPhase::Idle); RedemptionPeriodAsPercentage::::set(self.redemption_period_as_percentage); BackupRewardNodePercentage::::set(self.backup_reward_node_percentage); @@ -988,7 +988,7 @@ impl Pallet { // Set the expiry block number for the old epoch. EpochExpiries::::insert( - frame_system::Pallet::::current_block_number() + EpochDuration::::get(), + frame_system::Pallet::::current_block_number() + BlocksPerEpoch::::get(), old_epoch, ); @@ -1013,6 +1013,7 @@ impl Pallet { } fn expire_epoch(epoch: EpochIndex) -> Weight { + LastExpiredEpoch::::set(epoch); let mut num_expired_authorities = 0; for authority in EpochHistory::::epoch_authorities(epoch).iter() { num_expired_authorities += 1; @@ -1033,18 +1034,6 @@ impl Pallet { T::ValidatorWeightInfo::expire_epoch(num_expired_authorities) } - fn expire_epochs_up_to(latest_epoch_to_expire: EpochIndex) -> Weight { - let mut weight = Weight::zero(); - LastExpiredEpoch::::mutate(|last_expired_epoch| { - let first_unexpired_epoch = *last_expired_epoch + 1; - for epoch in first_unexpired_epoch..=latest_epoch_to_expire { - weight.saturating_accrue(Self::expire_epoch(epoch)); - } - *last_expired_epoch = latest_epoch_to_expire; - }); - weight - } - /// Does all state updates related to the *new* epoch. Is also called at genesis to initialise /// pallet state. Should not update any external state that is not managed by the validator /// pallet, ie. should not call `on_new_epoch`. Also does not need to concern itself with @@ -1329,7 +1318,7 @@ impl Pallet { // current_block > start + ((epoch * epoch%_can_redeem)) CurrentEpochStartedAt::::get() - .saturating_add(RedemptionPeriodAsPercentage::::get() * EpochDuration::::get()) <= + .saturating_add(RedemptionPeriodAsPercentage::::get() * BlocksPerEpoch::::get()) <= frame_system::Pallet::::current_block_number() } } @@ -1434,14 +1423,14 @@ impl pallet_session::SessionManager> for Pallet { impl EstimateNextSessionRotation> for Pallet { fn average_session_length() -> BlockNumberFor { - Self::epoch_duration() + Self::blocks_per_epoch() } fn estimate_current_session_progress(now: BlockNumberFor) -> (Option, Weight) { ( Some(Permill::from_rational( now.saturating_sub(CurrentEpochStartedAt::::get()), - EpochDuration::::get(), + BlocksPerEpoch::::get(), )), T::DbWeight::get().reads(2), ) @@ -1451,7 +1440,7 @@ impl EstimateNextSessionRotation> for Pallet { _now: BlockNumberFor, ) -> (Option>, Weight) { ( - Some(CurrentEpochStartedAt::::get() + EpochDuration::::get()), + Some(CurrentEpochStartedAt::::get() + BlocksPerEpoch::::get()), T::DbWeight::get().reads(2), ) } diff --git a/state-chain/pallets/cf-validator/src/migrations.rs b/state-chain/pallets/cf-validator/src/migrations.rs index 505e9353a8..ea45a36cbf 100644 --- a/state-chain/pallets/cf-validator/src/migrations.rs +++ b/state-chain/pallets/cf-validator/src/migrations.rs @@ -2,10 +2,8 @@ use crate::Pallet; use cf_runtime_upgrade_utilities::{PlaceholderMigration, VersionedMigration}; mod delete_old_epoch_data; -mod rename_blocks_per_epoch; pub type PalletMigration = ( VersionedMigration, delete_old_epoch_data::Migration, 3, 4>, - VersionedMigration, rename_blocks_per_epoch::BlocksPerEpochMigration, 4, 5>, - PlaceholderMigration, 5>, + PlaceholderMigration, 4>, ); diff --git a/state-chain/pallets/cf-validator/src/migrations/rename_blocks_per_epoch.rs b/state-chain/pallets/cf-validator/src/migrations/rename_blocks_per_epoch.rs deleted file mode 100644 index a34cab7424..0000000000 --- a/state-chain/pallets/cf-validator/src/migrations/rename_blocks_per_epoch.rs +++ /dev/null @@ -1,66 +0,0 @@ -use crate::*; -use frame_support::{pallet_prelude::Weight, traits::OnRuntimeUpgrade}; - -#[cfg(feature = "try-runtime")] -use codec::{Decode, Encode}; -#[cfg(feature = "try-runtime")] -use frame_support::sp_runtime::DispatchError; - -pub mod old { - use super::*; - - #[frame_support::storage_alias] - pub type BlocksPerEpoch = StorageValue, ValueQuery>; -} - -pub struct BlocksPerEpochMigration(sp_std::marker::PhantomData); - -// Rename BlocksPerEpoch -> EpochDuration -impl OnRuntimeUpgrade for BlocksPerEpochMigration { - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result, DispatchError> { - Ok(old::BlocksPerEpoch::::get().encode()) - } - - fn on_runtime_upgrade() -> Weight { - EpochDuration::::put(old::BlocksPerEpoch::::take()); - Weight::zero() - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade(state: Vec) -> Result<(), DispatchError> { - assert_eq!( - EpochDuration::::get(), - BlockNumberFor::::decode(&mut &state[..]).unwrap() - ); - assert!(!old::BlocksPerEpoch::::exists()); - Ok(()) - } -} - -#[cfg(test)] -mod migration_tests { - use crate::mock::Test; - - use self::mock::new_test_ext; - - use super::*; - - #[test] - fn test_migration() { - new_test_ext().execute_with(|| { - old::BlocksPerEpoch::::put(100); - assert_ne!(EpochDuration::::get(), 100); - - #[cfg(feature = "try-runtime")] - let state: Vec = BlocksPerEpochMigration::::pre_upgrade().unwrap(); - - BlocksPerEpochMigration::::on_runtime_upgrade(); - - #[cfg(feature = "try-runtime")] - BlocksPerEpochMigration::::post_upgrade(state).unwrap(); - - assert_eq!(EpochDuration::::get(), 100); - }); - } -} diff --git a/state-chain/pallets/cf-validator/src/mock.rs b/state-chain/pallets/cf-validator/src/mock.rs index d7aae8c343..b79d0b2a34 100644 --- a/state-chain/pallets/cf-validator/src/mock.rs +++ b/state-chain/pallets/cf-validator/src/mock.rs @@ -190,7 +190,7 @@ cf_test_utilities::impl_test_helpers! { validator_pallet: ValidatorPalletConfig { genesis_authorities: BTreeSet::from(GENESIS_AUTHORITIES), genesis_backups: Default::default(), - epoch_duration: EPOCH_DURATION, + blocks_per_epoch: EPOCH_DURATION, bond: GENESIS_BOND, redemption_period_as_percentage: REDEMPTION_PERCENTAGE_AT_GENESIS, backup_reward_node_percentage: Percent::from_percent(34), diff --git a/state-chain/pallets/cf-validator/src/tests.rs b/state-chain/pallets/cf-validator/src/tests.rs index 47c52750aa..9b6e9e794d 100644 --- a/state-chain/pallets/cf-validator/src/tests.rs +++ b/state-chain/pallets/cf-validator/src/tests.rs @@ -1263,33 +1263,25 @@ fn validator_registration_and_deregistration() { #[test] fn validator_deregistration_after_expired_epoch() { new_test_ext().execute_with(|| { - const RETIRING_VALIDATOR: u64 = GENESIS_AUTHORITIES[0]; - const REMAINING_AUTHORITIES: [u64; 2] = [GENESIS_AUTHORITIES[1], GENESIS_AUTHORITIES[2]]; - const BOND: u128 = 100; - - ValidatorPallet::transition_to_next_epoch(REMAINING_AUTHORITIES.to_vec(), BOND); - - assert_noop!( - ValidatorPallet::deregister_as_validator(RuntimeOrigin::signed(RETIRING_VALIDATOR),), - Error::::StillBidding - ); - - assert_ok!(ValidatorPallet::stop_bidding(RuntimeOrigin::signed(RETIRING_VALIDATOR))); + assert_ok!(ValidatorPallet::register_as_validator(RuntimeOrigin::signed(ALICE),)); + ValidatorPallet::transition_to_next_epoch(vec![1, ALICE], 100); + let first_epoch_to_expire = ValidatorPallet::current_epoch(); + // Can't deregister assert_noop!( - ValidatorPallet::deregister_as_validator(RuntimeOrigin::signed(RETIRING_VALIDATOR),), + ValidatorPallet::deregister_as_validator(RuntimeOrigin::signed(ALICE),), Error::::StillKeyHolder ); - ValidatorPallet::transition_to_next_epoch(REMAINING_AUTHORITIES.to_vec(), BOND); - ValidatorPallet::transition_to_next_epoch(REMAINING_AUTHORITIES.to_vec(), BOND); + ValidatorPallet::transition_to_next_epoch(vec![1, ALICE], 100); + let second_epoch_to_expire = ValidatorPallet::current_epoch(); + ValidatorPallet::transition_to_next_epoch(vec![1, 2], 100); - ValidatorPallet::expire_epochs_up_to(ValidatorPallet::current_epoch() - 1); + ValidatorPallet::expire_epoch(second_epoch_to_expire); + ValidatorPallet::expire_epoch(first_epoch_to_expire); // Now you can deregister - assert_ok!(ValidatorPallet::deregister_as_validator(RuntimeOrigin::signed( - RETIRING_VALIDATOR - ),)); + assert_ok!(ValidatorPallet::deregister_as_validator(RuntimeOrigin::signed(ALICE),)); }); } @@ -1371,7 +1363,7 @@ fn can_determine_is_auction_phase() { // In Idle phase, must be within certain % of epoch progress. CurrentEpochStartedAt::::set(1_000); - EpochDuration::::set(100); + BlocksPerEpoch::::set(100); RedemptionPeriodAsPercentage::::set(Percent::from_percent(85)); // First block of auction phase = 1_000 + 100 * 85% = 1085 @@ -1454,7 +1446,7 @@ fn can_update_all_config_items() { assert_ne!(RegistrationBondPercentage::::get(), NEW_REGISTRATION_BOND_PERCENTAGE); assert_ne!(AuthoritySetMinSize::::get(), NEW_AUTHORITY_SET_MIN_SIZE); assert_ne!(BackupRewardNodePercentage::::get(), NEW_BACKUP_REWARD_NODE_PERCENTAGE); - assert_ne!(EpochDuration::::get(), NEW_EPOCH_DURATION as u64); + assert_ne!(BlocksPerEpoch::::get(), NEW_EPOCH_DURATION as u64); assert_ne!(AuctionParameters::::get(), NEW_AUCTION_PARAMETERS); assert_ne!(MinimumReportedCfeVersion::::get(), NEW_MINIMUM_REPORTED_CFE_VERSION); assert_ne!( @@ -1503,7 +1495,7 @@ fn can_update_all_config_items() { assert_eq!(RegistrationBondPercentage::::get(), NEW_REGISTRATION_BOND_PERCENTAGE); assert_eq!(AuthoritySetMinSize::::get(), NEW_AUTHORITY_SET_MIN_SIZE); assert_eq!(BackupRewardNodePercentage::::get(), NEW_BACKUP_REWARD_NODE_PERCENTAGE); - assert_eq!(EpochDuration::::get(), NEW_EPOCH_DURATION as u64); + assert_eq!(BlocksPerEpoch::::get(), NEW_EPOCH_DURATION as u64); assert_eq!(AuctionParameters::::get(), NEW_AUCTION_PARAMETERS); assert_eq!(MinimumReportedCfeVersion::::get(), NEW_MINIMUM_REPORTED_CFE_VERSION); assert_eq!( @@ -1523,26 +1515,3 @@ fn can_update_all_config_items() { ); }); } - -#[test] -fn should_expire_all_previous_epochs() { - new_test_ext().execute_with(|| { - const ID: u64 = 1; - const BOND: u128 = 100; - ValidatorPallet::transition_to_next_epoch(vec![ID], BOND); - let first_epoch = ValidatorPallet::current_epoch(); - ValidatorPallet::transition_to_next_epoch(vec![ID], BOND); - let second_epoch = ValidatorPallet::current_epoch(); - ValidatorPallet::transition_to_next_epoch(vec![ID], BOND); - let third_epoch = ValidatorPallet::current_epoch(); - - assert_eq!( - HistoricalActiveEpochs::::get(ID), - vec![first_epoch, second_epoch, third_epoch] - ); - - ValidatorPallet::expire_epochs_up_to(second_epoch); - - assert_eq!(HistoricalActiveEpochs::::get(ID), vec![third_epoch]); - }); -} diff --git a/state-chain/runtime/src/lib.rs b/state-chain/runtime/src/lib.rs index e885b094f0..f4a85ef508 100644 --- a/state-chain/runtime/src/lib.rs +++ b/state-chain/runtime/src/lib.rs @@ -616,7 +616,7 @@ impl pallet_aura::Config for Runtime { } parameter_types! { - pub storage BlocksPerEpoch: u64 = Validator::epoch_duration().into(); + pub storage BlocksPerEpoch: u64 = Validator::blocks_per_epoch().into(); } type KeyOwnerIdentification = @@ -1389,7 +1389,7 @@ impl_runtime_apis! { Environment::current_release_version() } fn cf_epoch_duration() -> u32 { - Validator::epoch_duration() + Validator::blocks_per_epoch() } fn cf_current_epoch_started_at() -> u32 { Validator::current_epoch_started_at() @@ -1492,7 +1492,7 @@ impl_runtime_apis! { .ok() .map(|auction_outcome| auction_outcome.bond); AuctionState { - epoch_duration: Validator::epoch_duration(), + blocks_per_epoch: Validator::blocks_per_epoch(), current_epoch_started_at: Validator::current_epoch_started_at(), redemption_period_as_percentage: Validator::redemption_period_as_percentage().deconstruct(), min_funding: MinimumFunding::::get().unique_saturated_into(), @@ -2164,7 +2164,7 @@ impl_runtime_apis! { .ok() .map(|auction_outcome| auction_outcome.bond); EpochState { - epoch_duration: Validator::epoch_duration(), + blocks_per_epoch: Validator::blocks_per_epoch(), current_epoch_started_at: Validator::current_epoch_started_at(), current_epoch_index: Validator::current_epoch(), min_active_bid, diff --git a/state-chain/runtime/src/monitoring_apis.rs b/state-chain/runtime/src/monitoring_apis.rs index 921ec02836..9ee775c74a 100644 --- a/state-chain/runtime/src/monitoring_apis.rs +++ b/state-chain/runtime/src/monitoring_apis.rs @@ -30,7 +30,7 @@ pub struct BtcUtxos { #[derive(Serialize, Deserialize, Encode, Decode, Eq, PartialEq, TypeInfo, Debug, Clone)] pub struct EpochState { - pub epoch_duration: u32, + pub blocks_per_epoch: u32, pub current_epoch_started_at: u32, pub current_epoch_index: u32, pub min_active_bid: Option, diff --git a/state-chain/runtime/src/runtime_apis.rs b/state-chain/runtime/src/runtime_apis.rs index 9ea27cb05c..536ebc0bfd 100644 --- a/state-chain/runtime/src/runtime_apis.rs +++ b/state-chain/runtime/src/runtime_apis.rs @@ -107,7 +107,7 @@ pub struct RuntimeApiPenalty { #[derive(Encode, Decode, Eq, PartialEq, TypeInfo)] pub struct AuctionState { - pub epoch_duration: u32, + pub blocks_per_epoch: u32, pub current_epoch_started_at: u32, pub redemption_period_as_percentage: u8, pub min_funding: u128,