1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
//! Temporal Ambiguity Evidence
//!
//! Provides the mechanism for verifiers to report observed violations
//! in temporal synchronization, such as skew limit breaches, monotonic
//! logical clock failures, or out-of-order epoch progressions.
use crate::{digest::TypedDigest, federation_time::HybridLogicalClock};
use serde::{Deserialize, Serialize};
/// Cryptographic evidence that a verifier or component has violated
/// temporal convergence rules.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct TemporalAmbiguityEvidence {
/// The ID of the verifier observing the violation.
pub observing_verifier_id: String,
/// The ID of the verifier that committed the violation.
pub violating_verifier_id: String,
/// The clock reading that triggered the violation.
pub violating_clock: HybridLogicalClock,
/// The reference clock against which the violation was measured.
pub reference_clock: HybridLogicalClock,
/// A description of the violation type (e.g., "`ExceedsSkew`", "`NonMonotonic`").
pub violation_type: String,
/// Optional hash of the associated event/state.
pub event_hash: Option<TypedDigest>,
/// Cryptographic signature of the observer over this evidence.
#[serde(with = "serde_bytes")]
pub observer_signature: Vec<u8>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn temporal_ambiguity_evidence_serialize() {
let ev = TemporalAmbiguityEvidence {
observing_verifier_id: "v1".into(),
violating_verifier_id: "v2".into(),
violating_clock: HybridLogicalClock {
logical_counter: 10,
physical_timestamp: 2000,
signature: vec![0x11],
},
reference_clock: HybridLogicalClock {
logical_counter: 10,
physical_timestamp: 1000,
signature: vec![0x22],
},
violation_type: "ExceedsSkew".into(),
event_hash: None,
observer_signature: vec![0xFF],
};
// Assert it roundtrips
let mut bytes = alloc::vec::Vec::new();
ciborium::into_writer(&ev, &mut bytes).unwrap();
let decoded: TemporalAmbiguityEvidence = ciborium::from_reader(bytes.as_slice()).unwrap();
assert_eq!(ev, decoded);
}
}