diff --git a/programs/validator-history/Cargo.toml b/programs/validator-history/Cargo.toml index b813a273..bd681120 100644 --- a/programs/validator-history/Cargo.toml +++ b/programs/validator-history/Cargo.toml @@ -20,6 +20,7 @@ no-log-ix-name = [] cpi = ["no-entrypoint"] default = ["custom-heap"] custom-heap = [] +testnet = [] [dependencies] anchor-lang = "0.28.0" diff --git a/programs/validator-history/src/instructions/copy_cluster_info.rs b/programs/validator-history/src/instructions/copy_cluster_info.rs index a6d7310d..397fcde7 100644 --- a/programs/validator-history/src/instructions/copy_cluster_info.rs +++ b/programs/validator-history/src/instructions/copy_cluster_info.rs @@ -60,8 +60,7 @@ pub fn handle_copy_cluster_info(ctx: Context) -> Result<()> { }; let start_slot = epoch_schedule.get_first_slot_in_epoch(epoch.into()); - let end_slot = epoch_schedule.get_last_slot_in_epoch(epoch.into()); - let (num_blocks, _) = confirmed_blocks_in_epoch(start_slot, end_slot, *slot_history)?; + let (num_blocks, _) = confirmed_blocks_in_epoch(start_slot, clock.slot, *slot_history)?; cluster_history_account.set_blocks(epoch, num_blocks)?; cluster_history_account.set_epoch_start_timestamp(epoch, epoch_start_timestamp)?; @@ -95,11 +94,13 @@ pub fn confirmed_blocks_in_epoch( .ok_or(ValidatorHistoryError::ArithmeticError)?, ) .ok_or(ValidatorHistoryError::ArithmeticError)? + .min(end_slot) }; let last_full_block_slot = end_slot .checked_sub(end_slot % BITVEC_BLOCK_SIZE) - .ok_or(ValidatorHistoryError::ArithmeticError)?; + .ok_or(ValidatorHistoryError::ArithmeticError)? + .max(first_full_block_slot); // First and last slots, in partial blocks for i in (start_slot..first_full_block_slot).chain(last_full_block_slot..=end_slot) { diff --git a/tests/tests/test_cluster_history.rs b/tests/tests/test_cluster_history.rs index b900112f..97242c97 100644 --- a/tests/tests/test_cluster_history.rs +++ b/tests/tests/test_cluster_history.rs @@ -74,13 +74,15 @@ async fn test_copy_cluster_info() { .await .expect("clock"); - assert!(clock.epoch == 1); assert!(account.history.idx == 1); assert!(account.history.arr[0].epoch == 0); assert!(account.history.arr[0].total_blocks == 3); + assert!(clock.epoch == 1); + assert!(clock.slot == 32); + assert!(clock.slot == latest_slot); + assert!(account.cluster_history_last_update_slot == latest_slot); assert!(account.history.arr[1].epoch == 1); - assert!(account.history.arr[1].total_blocks == 2); - assert_eq!(account.cluster_history_last_update_slot, latest_slot) + assert!(account.history.arr[1].total_blocks == 1); } #[tokio::test] @@ -170,7 +172,7 @@ async fn test_cluster_history_compute_limit() { assert!(account.history.arr[0].epoch as u64 == clock.epoch - 1); assert!(account.history.arr[0].total_blocks == 216_000); assert!(account.history.arr[1].epoch as u64 == clock.epoch); - assert!(account.history.arr[1].total_blocks == 216_000); + assert!(account.history.arr[1].total_blocks == 1); } // Non-fixture test to ensure that the SlotHistory partial slot logic works @@ -183,6 +185,18 @@ fn test_confirmed_blocks_in_epoch_partial_blocks() { // First partial block: 50 -> 64 // Full block: 64 -> 127 // Last partial block: 128 -> 149 - let (num_blocks, _) = confirmed_blocks_in_epoch(50, 149, slot_history).unwrap(); + let (num_blocks, _) = confirmed_blocks_in_epoch(50, 149, slot_history.clone()).unwrap(); assert_eq!(num_blocks, 100); + + let (num_blocks, _) = confirmed_blocks_in_epoch(50, 99, slot_history.clone()).unwrap(); + assert_eq!(num_blocks, 50); + + let (num_blocks, _) = confirmed_blocks_in_epoch(64, 127, slot_history.clone()).unwrap(); + assert_eq!(num_blocks, 64); + + let (num_blocks, _) = confirmed_blocks_in_epoch(64, 64, slot_history.clone()).unwrap(); + assert_eq!(num_blocks, 1); + + let (num_blocks, _) = confirmed_blocks_in_epoch(100, 149, slot_history.clone()).unwrap(); + assert_eq!(num_blocks, 50); }