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
//! Rolling Integrity Checkpoints
//!
//! Provides boundary markers for continuous runtime integrity streams.
//! Checkpoints allow verifiers to safely prune historical deltas while
//! maintaining a cryptographic lineage (the `integrity_root`) that anchors
//! all subsequent attestations.
use crate::digest::TypedDigest;
use alloc::string::String;
/// A bounded slice of runtime integrity history summarized into a single anchor.
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct IntegrityCheckpoint {
/// Unique identifier for this checkpoint.
pub checkpoint_id: String,
/// The sequence number where this checkpoint begins.
pub start_sequence: u64,
/// The sequence number where this checkpoint ends.
pub end_sequence: u64,
/// The canonical rolling hash representing the terminal state of `end_sequence`.
pub integrity_root: TypedDigest,
/// The Unix timestamp when this checkpoint was generated.
pub timestamp: u64,
}
impl IntegrityCheckpoint {
/// Validates that a proposed child checkpoint logically follows this checkpoint.
pub fn verify_linkage(&self, child: &IntegrityCheckpoint) -> Result<(), &'static str> {
if child.start_sequence != self.end_sequence + 1 {
return Err("checkpoint sequence continuity broken");
}
if child.timestamp < self.timestamp {
return Err("checkpoint timestamps must be monotonic");
}
Ok(())
}
/// Safely evaluates whether this checkpoint is eligible for pruning based
/// on a strict verifier retention policy limit.
#[must_use]
pub fn is_prunable(
&self,
oldest_retained_sequence: u64,
current_timestamp: u64,
max_age_secs: u64,
) -> bool {
// Must be older than the retained sequence boundary
if self.end_sequence >= oldest_retained_sequence {
return false;
}
// Must exceed the maximum permitted age
if current_timestamp.saturating_sub(self.timestamp) < max_age_secs {
return false;
}
true
}
}