1use std::sync::{Arc, Mutex};
6use std::time::{SystemTime, UNIX_EPOCH};
7use std::collections::HashMap;
8
9#[derive(Clone)]
11pub struct RuntimeBlockchain {
12 chain: Arc<Mutex<Vec<Block>>>,
13 difficulty: usize,
14 pending_transactions: Arc<Mutex<Vec<Transaction>>>,
15}
16
17#[derive(Clone, Debug)]
18pub struct Block {
19 pub index: u64,
20 pub timestamp: u128,
21 pub transactions: Vec<Transaction>,
22 pub previous_hash: String,
23 pub hash: String,
24 pub nonce: u64,
25}
26
27#[derive(Clone, Debug)]
28pub struct Transaction {
29 pub tx_type: TransactionType,
30 pub data: String,
31 pub timestamp: u128,
32}
33
34#[derive(Clone, Debug)]
35pub enum TransactionType {
36 TaskSpawned,
37 TaskCompleted,
38 ThreadScaled,
39 AnomalyDetected,
40 ConfigChanged,
41 Custom(String),
42}
43
44impl RuntimeBlockchain {
45 pub fn new(difficulty: usize) -> Self {
46 let genesis = Block::genesis();
47
48 Self {
49 chain: Arc::new(Mutex::new(vec![genesis])),
50 difficulty,
51 pending_transactions: Arc::new(Mutex::new(Vec::new())),
52 }
53 }
54
55 pub fn add_transaction(&self, tx_type: TransactionType, data: String) {
57 let mut pending = self.pending_transactions.lock().unwrap();
58 pending.push(Transaction {
59 tx_type,
60 data,
61 timestamp: Self::current_timestamp(),
62 });
63 }
64
65 pub fn mine_block(&self) -> Block {
67 let mut pending = self.pending_transactions.lock().unwrap();
68 let transactions = pending.drain(..).collect();
69 drop(pending);
70
71 let mut chain = self.chain.lock().unwrap();
72 let previous_block = chain.last().unwrap();
73
74 let mut block = Block {
75 index: previous_block.index + 1,
76 timestamp: Self::current_timestamp(),
77 transactions,
78 previous_hash: previous_block.hash.clone(),
79 hash: String::new(),
80 nonce: 0,
81 };
82
83 let target = "0".repeat(self.difficulty);
85 while !block.calculate_hash().starts_with(&target) {
86 block.nonce += 1;
87 }
88
89 block.hash = block.calculate_hash();
90 chain.push(block.clone());
91
92 block
93 }
94
95 pub fn verify(&self) -> bool {
97 let chain = self.chain.lock().unwrap();
98
99 for i in 1..chain.len() {
100 let current = &chain[i];
101 let previous = &chain[i - 1];
102
103 if current.hash != current.calculate_hash() {
105 return false;
106 }
107
108 if current.previous_hash != previous.hash {
110 return false;
111 }
112
113 let target = "0".repeat(self.difficulty);
115 if !current.hash.starts_with(&target) {
116 return false;
117 }
118 }
119
120 true
121 }
122
123 pub fn stats(&self) -> BlockchainStats {
125 let chain = self.chain.lock().unwrap();
126 let pending = self.pending_transactions.lock().unwrap();
127
128 let total_transactions: usize = chain.iter()
129 .map(|b| b.transactions.len())
130 .sum();
131
132 let block_count = chain.len();
133 let pending_count = pending.len();
134 drop(chain);
135 drop(pending);
136
137 let is_valid = self.verify();
138
139 BlockchainStats {
140 block_count,
141 total_transactions,
142 pending_transactions: pending_count,
143 difficulty: self.difficulty,
144 is_valid,
145 }
146 }
147
148 pub fn recent_blocks(&self, count: usize) -> Vec<Block> {
150 let chain = self.chain.lock().unwrap();
151 let start = if chain.len() > count { chain.len() - count } else { 0 };
152 chain[start..].to_vec()
153 }
154
155 pub fn search_transactions(&self, tx_type: &str) -> Vec<Transaction> {
157 let chain = self.chain.lock().unwrap();
158 chain.iter()
159 .flat_map(|block| &block.transactions)
160 .filter(|tx| match &tx.tx_type {
161 TransactionType::TaskSpawned => tx_type == "TaskSpawned",
162 TransactionType::TaskCompleted => tx_type == "TaskCompleted",
163 TransactionType::ThreadScaled => tx_type == "ThreadScaled",
164 TransactionType::AnomalyDetected => tx_type == "AnomalyDetected",
165 TransactionType::ConfigChanged => tx_type == "ConfigChanged",
166 TransactionType::Custom(name) => tx_type == name,
167 })
168 .cloned()
169 .collect()
170 }
171
172 fn current_timestamp() -> u128 {
173 SystemTime::now()
174 .duration_since(UNIX_EPOCH)
175 .unwrap()
176 .as_millis()
177 }
178}
179
180impl Block {
181 fn genesis() -> Self {
182 Self {
183 index: 0,
184 timestamp: 0,
185 transactions: vec![],
186 previous_hash: "0".to_string(),
187 hash: "genesis".to_string(),
188 nonce: 0,
189 }
190 }
191
192 fn calculate_hash(&self) -> String {
193 let data = format!(
194 "{}{}{}{}{}",
195 self.index,
196 self.timestamp,
197 self.transactions.len(),
198 self.previous_hash,
199 self.nonce
200 );
201
202 let mut hash: u64 = 5381;
204 for byte in data.bytes() {
205 hash = hash.wrapping_mul(33).wrapping_add(byte as u64);
206 }
207
208 format!("{:016x}", hash)
209 }
210}
211
212#[derive(Debug, Clone)]
213pub struct BlockchainStats {
214 pub block_count: usize,
215 pub total_transactions: usize,
216 pub pending_transactions: usize,
217 pub difficulty: usize,
218 pub is_valid: bool,
219}
220
221impl std::fmt::Display for Block {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 write!(
224 f,
225 "Block[#{}, txs={}, hash={}...{}]",
226 self.index,
227 self.transactions.len(),
228 &self.hash[..8],
229 &self.hash[self.hash.len()-4..]
230 )
231 }
232}
233
234impl std::fmt::Display for BlockchainStats {
235 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
236 write!(
237 f,
238 "BlockchainStats[blocks={}, txs={}, pending={}, valid={}]",
239 self.block_count, self.total_transactions, self.pending_transactions, self.is_valid
240 )
241 }
242}
243
244#[derive(Clone)]
246pub struct ConsensusManager {
247 nodes: Arc<Mutex<HashMap<String, NodeState>>>,
248 quorum_size: usize,
249}
250
251#[derive(Clone, Debug)]
252#[allow(dead_code)]
253struct NodeState {
254 node_id: String,
255 last_vote: u64,
256 reputation: f64,
257}
258
259impl ConsensusManager {
260 pub fn new(quorum_size: usize) -> Self {
261 Self {
262 nodes: Arc::new(Mutex::new(HashMap::new())),
263 quorum_size,
264 }
265 }
266
267 pub fn register_node(&self, node_id: String) {
269 let mut nodes = self.nodes.lock().unwrap();
270 nodes.insert(node_id.clone(), NodeState {
271 node_id,
272 last_vote: 0,
273 reputation: 1.0,
274 });
275 }
276
277 pub fn vote(&self, _decision: &str) -> bool {
279 let nodes = self.nodes.lock().unwrap();
280 nodes.len() >= self.quorum_size
281 }
282
283 pub fn stats(&self) -> ConsensusStats {
285 let nodes = self.nodes.lock().unwrap();
286 let avg_reputation = if !nodes.is_empty() {
287 nodes.values().map(|n| n.reputation).sum::<f64>() / nodes.len() as f64
288 } else {
289 0.0
290 };
291
292 ConsensusStats {
293 total_nodes: nodes.len(),
294 quorum_size: self.quorum_size,
295 avg_reputation,
296 }
297 }
298}
299
300#[derive(Debug, Clone)]
301pub struct ConsensusStats {
302 pub total_nodes: usize,
303 pub quorum_size: usize,
304 pub avg_reputation: f64,
305}
306
307
308
309
310