lsp_max/runtime/control_plane/kernel/
refused_quarantined_replayed.rs1use crate::runtime::control_plane::admission::{
2 CandidateData, GraphAdmissionError, GraphAdmissionLaw, QuarantinedData, RefusedData,
3 ReplayedData, CANDIDATE, QUARANTINED, REFUSED, REPLAYED,
4};
5use crate::runtime::control_plane::receipts::{Blake3Hash, CryptographicReceipt};
6use crate::runtime::{ChainError, Machine, TypestateKernel};
7use ed25519_dalek::Signer;
8
9impl TypestateKernel<GraphAdmissionLaw, REFUSED, RefusedData>
13 for Machine<GraphAdmissionLaw, REFUSED, RefusedData>
14{
15 type Input = ();
16 type OutputPhase = REFUSED;
17 type OutputData = RefusedData;
18 type Receipt = CryptographicReceipt;
19
20 fn validate(&self, _input: &Self::Input) -> Result<(), GraphAdmissionError> {
21 Err(GraphAdmissionError::ParsingFailed(
22 "Already refused".to_string(),
23 ))
24 }
25
26 fn select(&self, _input: &Self::Input) -> Self::OutputPhase {
27 REFUSED
28 }
29
30 fn admit(
31 self,
32 input: Self::Input,
33 ) -> Result<Machine<GraphAdmissionLaw, Self::OutputPhase, Self::OutputData>, GraphAdmissionError>
34 {
35 self.validate(&input)?;
36 Ok(self)
37 }
38
39 fn receipt(&self) -> Self::Receipt {
40 let mut receipt = CryptographicReceipt {
41 prev_hash: Blake3Hash([0u8; 32]),
42 discipline_id: uuid::Uuid::nil(),
43 law_id: uuid::Uuid::nil(),
44 consequence_hash: Blake3Hash([0u8; 32]),
45 sequence: 2,
46 signature: [0u8; 64],
47 };
48 let payload_hash = receipt.compute_payload_hash();
49 let signing_key = ed25519_dalek::SigningKey::from_bytes(&[0u8; 32]);
50 receipt.signature = signing_key.sign(&payload_hash.0).to_bytes();
51 receipt
52 }
53
54 fn exit(self) -> RefusedData {
55 self.data
56 }
57
58 fn replay(history: Vec<Self::Receipt>) -> Result<Self, ChainError> {
59 if history.len() < 3 {
60 return Err(ChainError::InsufficientHistory {
61 required: 3,
62 got: history.len(),
63 });
64 }
65 let signing_key = ed25519_dalek::SigningKey::from_bytes(&[0u8; 32]);
66 let verifying_key = signing_key.verifying_key();
67 crate::runtime::control_plane::receipts::verify_receipt_chain(
68 &history,
69 &verifying_key,
70 &history[0].prev_hash,
71 )
72 .map_err(|e| ChainError::HashMismatch {
73 index: 2,
74 expected: "Valid signature".to_string(),
75 got: e.to_string(),
76 })?;
77
78 Ok(Machine::new(
79 REFUSED,
80 RefusedData {
81 report: crate::runtime::control_plane::invariants::VerificationReport {
82 is_success: false,
83 diagnostics: Vec::new(),
84 execution_time_ms: 0,
85 },
86 },
87 ))
88 }
89}
90
91impl TypestateKernel<GraphAdmissionLaw, QUARANTINED, QuarantinedData>
95 for Machine<GraphAdmissionLaw, QUARANTINED, QuarantinedData>
96{
97 type Input = String; type OutputPhase = CANDIDATE;
99 type OutputData = CandidateData;
100 type Receipt = CryptographicReceipt;
101
102 fn validate(&self, _input: &Self::Input) -> Result<(), GraphAdmissionError> {
103 Ok(())
104 }
105
106 fn select(&self, _input: &Self::Input) -> Self::OutputPhase {
107 CANDIDATE
108 }
109
110 fn admit(
111 self,
112 input: Self::Input,
113 ) -> Result<Machine<GraphAdmissionLaw, Self::OutputPhase, Self::OutputData>, GraphAdmissionError>
114 {
115 self.validate(&input)?;
116 Ok(self.into_candidate(input))
117 }
118
119 fn receipt(&self) -> Self::Receipt {
120 let mut receipt = CryptographicReceipt {
121 prev_hash: Blake3Hash([0u8; 32]),
122 discipline_id: uuid::Uuid::nil(),
123 law_id: uuid::Uuid::nil(),
124 consequence_hash: Blake3Hash([0u8; 32]),
125 sequence: 2,
126 signature: [0u8; 64],
127 };
128 let payload_hash = receipt.compute_payload_hash();
129 let signing_key = ed25519_dalek::SigningKey::from_bytes(&[0u8; 32]);
130 receipt.signature = signing_key.sign(&payload_hash.0).to_bytes();
131 receipt
132 }
133
134 fn exit(self) -> QuarantinedData {
135 self.data
136 }
137
138 fn replay(history: Vec<Self::Receipt>) -> Result<Self, ChainError> {
139 if history.len() < 3 {
140 return Err(ChainError::InsufficientHistory {
141 required: 3,
142 got: history.len(),
143 });
144 }
145 let signing_key = ed25519_dalek::SigningKey::from_bytes(&[0u8; 32]);
146 let verifying_key = signing_key.verifying_key();
147 crate::runtime::control_plane::receipts::verify_receipt_chain(
148 &history,
149 &verifying_key,
150 &history[0].prev_hash,
151 )
152 .map_err(|e| ChainError::HashMismatch {
153 index: 2,
154 expected: "Valid signature".to_string(),
155 got: e.to_string(),
156 })?;
157
158 Ok(Machine::new(
159 QUARANTINED,
160 QuarantinedData {
161 elements: Vec::new(),
162 quads: Vec::new(),
163 missing_dependencies: Vec::new(),
164 },
165 ))
166 }
167}
168
169impl TypestateKernel<GraphAdmissionLaw, REPLAYED, ReplayedData>
173 for Machine<GraphAdmissionLaw, REPLAYED, ReplayedData>
174{
175 type Input = ();
176 type OutputPhase = REPLAYED;
177 type OutputData = ReplayedData;
178 type Receipt = CryptographicReceipt;
179
180 fn validate(&self, _input: &Self::Input) -> Result<(), GraphAdmissionError> {
181 Err(GraphAdmissionError::ParsingFailed(
182 "Already replayed".to_string(),
183 ))
184 }
185
186 fn select(&self, _input: &Self::Input) -> Self::OutputPhase {
187 REPLAYED
188 }
189
190 fn admit(
191 self,
192 input: Self::Input,
193 ) -> Result<Machine<GraphAdmissionLaw, Self::OutputPhase, Self::OutputData>, GraphAdmissionError>
194 {
195 self.validate(&input)?;
196 Ok(self)
197 }
198
199 fn receipt(&self) -> Self::Receipt {
200 self.data.receipt.clone()
201 }
202
203 fn exit(self) -> ReplayedData {
204 self.data
205 }
206
207 fn replay(history: Vec<Self::Receipt>) -> Result<Self, ChainError> {
208 if history.len() < 3 {
209 return Err(ChainError::InsufficientHistory {
210 required: 3,
211 got: history.len(),
212 });
213 }
214 let signing_key = ed25519_dalek::SigningKey::from_bytes(&[0u8; 32]);
215 let verifying_key = signing_key.verifying_key();
216 crate::runtime::control_plane::receipts::verify_receipt_chain(
217 &history,
218 &verifying_key,
219 &history[0].prev_hash,
220 )
221 .map_err(|e| ChainError::HashMismatch {
222 index: 2,
223 expected: "Valid signature".to_string(),
224 got: e.to_string(),
225 })?;
226
227 Ok(Machine::new(
228 REPLAYED,
229 ReplayedData {
230 graph_name: oxigraph::model::GraphName::DefaultGraph,
231 receipt: history[2].clone(),
232 },
233 ))
234 }
235}