use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum RecoveryGovernanceAction {
ApprovePartitionHealing { partition_id: String },
ApproveQuorumReformation { reformed_quorum_root: [u8; 32] },
ApproveRecoveryCheckpoint { checkpoint_id: String },
ApproveFederationMigration { target_federation_id: String },
RejectRecoveryState { reason: String },
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RecoveryGovernanceEvent {
pub action: RecoveryGovernanceAction,
pub authorizer_id: String,
pub epoch: u64,
pub signature: alloc::vec::Vec<u8>,
}
impl RecoveryGovernanceEvent {
#[must_use]
pub fn is_structurally_valid(&self) -> bool {
if self.authorizer_id.is_empty() {
return false;
}
if self.signature.is_empty() {
return false;
}
match &self.action {
RecoveryGovernanceAction::ApprovePartitionHealing { partition_id } => {
!partition_id.is_empty()
}
RecoveryGovernanceAction::ApproveQuorumReformation {
reformed_quorum_root,
} => *reformed_quorum_root != [0; 32],
RecoveryGovernanceAction::ApproveRecoveryCheckpoint { checkpoint_id } => {
!checkpoint_id.is_empty()
}
RecoveryGovernanceAction::ApproveFederationMigration {
target_federation_id,
} => !target_federation_id.is_empty(),
RecoveryGovernanceAction::RejectRecoveryState { reason } => !reason.is_empty(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn valid_recovery_governance_event() {
let ev = RecoveryGovernanceEvent {
action: RecoveryGovernanceAction::ApprovePartitionHealing {
partition_id: "part-01".into(),
},
authorizer_id: "gov-auth-1".into(),
epoch: 5,
signature: vec![0xDE, 0xAD, 0xBE, 0xEF],
};
assert!(ev.is_structurally_valid());
}
#[test]
fn invalid_event_empty_signature() {
let ev = RecoveryGovernanceEvent {
action: RecoveryGovernanceAction::ApprovePartitionHealing {
partition_id: "part-01".into(),
},
authorizer_id: "gov-auth-1".into(),
epoch: 5,
signature: vec![],
};
assert!(!ev.is_structurally_valid());
}
#[test]
fn invalid_event_empty_partition_id() {
let ev = RecoveryGovernanceEvent {
action: RecoveryGovernanceAction::ApprovePartitionHealing {
partition_id: "".into(),
},
authorizer_id: "gov-auth-1".into(),
epoch: 5,
signature: vec![0xDE, 0xAD],
};
assert!(!ev.is_structurally_valid());
}
}