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);
    }
}