use crate::byzantine_quorum::QuorumCertificate;
use alloc::string::String;
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct FederationSyncState {
pub federation_id: String,
pub latest_state_hash: [u8; 32],
pub latest_policy_epoch: u64,
pub latest_revocation_epoch: u64,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct FederationSyncProof {
pub sync_hash: [u8; 32],
pub quorum_certificate: QuorumCertificate,
}
impl FederationSyncState {
#[must_use]
pub fn compute_hash(&self) -> [u8; 32] {
use sha3::{Digest, Sha3_256};
let mut hasher = Sha3_256::new();
hasher.update(self.federation_id.as_bytes());
hasher.update(self.latest_state_hash);
hasher.update(self.latest_policy_epoch.to_be_bytes());
hasher.update(self.latest_revocation_epoch.to_be_bytes());
hasher.finalize().into()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sync_state_hash_determinism() {
let state1 = FederationSyncState {
federation_id: "fed-A".into(),
latest_state_hash: [0xAA; 32],
latest_policy_epoch: 1,
latest_revocation_epoch: 2,
};
let state2 = FederationSyncState {
federation_id: "fed-A".into(),
latest_state_hash: [0xAA; 32],
latest_policy_epoch: 1,
latest_revocation_epoch: 2,
};
assert_eq!(state1.compute_hash(), state2.compute_hash());
let state3 = FederationSyncState {
federation_id: "fed-A".into(),
latest_state_hash: [0xBB; 32], latest_policy_epoch: 1,
latest_revocation_epoch: 2,
};
assert_ne!(state1.compute_hash(), state3.compute_hash());
}
}