File size: 3,452 Bytes
1d3f990 | 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 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | //! Rollback manager — WORM checkpoint restoration
use anyhow::Result;
use std::collections::VecDeque;
use serde::{Deserialize, Serialize};
/// WORM checkpoint for rollback
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WormCheckpoint {
pub id: String,
pub ip: usize,
pub step_count: u64,
pub mutation_log_len: usize,
pub timestamp: u64,
pub memory_snapshot: Vec<i64>,
}
/// Manages WORM checkpoints for rollback on proof failure
pub struct RollbackManager {
checkpoints: VecDeque<WormCheckpoint>,
max_checkpoints: usize,
}
impl RollbackManager {
pub fn new(max_checkpoints: usize) -> Self {
Self {
checkpoints: VecDeque::new(),
max_checkpoints,
}
}
/// Add a new WORM checkpoint
pub fn add_checkpoint(&mut self, checkpoint: WormCheckpoint) {
self.checkpoints.push_back(checkpoint);
// Keep only the most recent N checkpoints
while self.checkpoints.len() > self.max_checkpoints {
self.checkpoints.pop_front();
}
}
/// Get the most recent valid checkpoint
pub fn last_valid_checkpoint(&self) -> Option<WormCheckpoint> {
self.checkpoints.back().cloned()
}
/// Get all checkpoints
pub fn all_checkpoints(&self) -> Vec<WormCheckpoint> {
self.checkpoints.iter().cloned().collect()
}
/// Restore to a checkpoint
pub fn rollback(&self, _checkpoint: &WormCheckpoint) -> Result<()> {
// In a real implementation, this would restore memory state
// For now, just verify the checkpoint is valid
Ok(())
}
pub fn checkpoint_count(&self) -> usize {
self.checkpoints.len()
}
}
impl Default for RollbackManager {
fn default() -> Self {
Self::new(100)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rollback_manager_creation() {
let mgr = RollbackManager::new(10);
assert_eq!(mgr.checkpoint_count(), 0);
}
#[test]
fn test_add_checkpoint() {
let mut mgr = RollbackManager::new(10);
let cp = WormCheckpoint {
id: "cp1".into(),
ip: 0,
step_count: 0,
mutation_log_len: 0,
timestamp: 0,
memory_snapshot: vec![],
};
mgr.add_checkpoint(cp);
assert_eq!(mgr.checkpoint_count(), 1);
}
#[test]
fn test_last_checkpoint() {
let mut mgr = RollbackManager::new(10);
let cp = WormCheckpoint {
id: "cp1".into(),
ip: 0,
step_count: 0,
mutation_log_len: 0,
timestamp: 0,
memory_snapshot: vec![],
};
mgr.add_checkpoint(cp.clone());
let last = mgr.last_valid_checkpoint();
assert_eq!(last.unwrap().id, "cp1");
}
#[test]
fn test_max_checkpoints_limit() {
let mut mgr = RollbackManager::new(3);
for i in 0..5 {
let cp = WormCheckpoint {
id: format!("cp{}", i),
ip: 0,
step_count: 0,
mutation_log_len: 0,
timestamp: 0,
memory_snapshot: vec![],
};
mgr.add_checkpoint(cp);
}
assert_eq!(mgr.checkpoint_count(), 3);
}
}
|