//! A tiny, in-memory, append-only blockchain for user-as-node mode. //! Not secure; for demonstration and API plumbing only. use serde::{Deserialize, Serialize}; use anarchy_core::external_utils::sha3_256_hex; use std::sync::{Arc, Mutex}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Block { pub index: u64, pub data: String, pub prev_hash: String, pub hash: String, } #[derive(Clone, Default)] pub struct Chain(Arc>>); impl Chain { pub fn new() -> Self { let mut c = Vec::new(); let genesis = Block { index: 0, data: "genesis".into(), prev_hash: "".into(), hash: hash_block(0, "genesis", ""), }; c.push(genesis); Self(Arc::new(Mutex::new(c))) } pub fn push(&self, data: String) -> Block { let mut g = self.0.lock().unwrap(); let index = g.len() as u64; let prev_hash = g.last().map(|b| b.hash.clone()).unwrap_or_default(); let hash = hash_block(index, &data, &prev_hash); let b = Block { index, data, prev_hash, hash }; g.push(b.clone()); b } pub fn list(&self) -> Vec { self.0.lock().unwrap().clone() } } fn hash_block(index: u64, data: &str, prev_hash: &str) -> String { let mut bytes = Vec::with_capacity(8 + data.len() + prev_hash.len()); bytes.extend_from_slice(&index.to_le_bytes()); bytes.extend_from_slice(data.as_bytes()); bytes.extend_from_slice(prev_hash.as_bytes()); sha3_256_hex(&bytes) }