use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DisasterRecoveryCheckpoint {
pub checkpoint_id: String,
pub snapshot_hash: [u8; 32],
pub recovery_epoch: u64,
pub federation_state_hash: [u8; 32],
}
impl DisasterRecoveryCheckpoint {
#[must_use]
pub fn is_valid(&self) -> bool {
if self.checkpoint_id.is_empty() {
return false;
}
if self.snapshot_hash == [0; 32] || self.federation_state_hash == [0; 32] {
return false;
}
true
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn valid_disaster_recovery_checkpoint() {
let cp = DisasterRecoveryCheckpoint {
checkpoint_id: "dr-01".into(),
snapshot_hash: [1; 32],
recovery_epoch: 42,
federation_state_hash: [2; 32],
};
assert!(cp.is_valid());
}
#[test]
fn invalid_dr_checkpoint_empty_id() {
let cp = DisasterRecoveryCheckpoint {
checkpoint_id: "".into(),
snapshot_hash: [1; 32],
recovery_epoch: 42,
federation_state_hash: [2; 32],
};
assert!(!cp.is_valid());
}
#[test]
fn invalid_dr_checkpoint_zeroed_hash() {
let cp = DisasterRecoveryCheckpoint {
checkpoint_id: "dr-01".into(),
snapshot_hash: [0; 32],
recovery_epoch: 42,
federation_state_hash: [2; 32],
};
assert!(!cp.is_valid());
}
}