//! //! An example for stateless functions. //! use once_cell::sync::Lazy; use ovr_ruc::*; use serde::{Deserialize, Serialize}; use std::{ mem, sync::{mpsc::channel, Mutex}, thread, }; use vsdb::{ BranchName, MapxVs, OrphanVs, ValueEnDe, VecxVs, VersionName, VersionNameOwned, Vs, VsMgmt, }; type Amount = u64; type Address = Vec; type ConsensusInt = i128; #[derive(Vs, Clone, Debug, Serialize, Deserialize)] struct WorldState { transactions: VecxVs, balances: MapxVs, a_consensus_int: OrphanVs, } const MASTER_BRANCH: &str = "master"; const PRE_CHECK_BRANCH: &str = "pre_check"; const FORMAL_CHECK_BRANCH: &str = "formal_check"; static WORLD_STATE: Lazy> = Lazy::new(|| Mutex::new(WorldState::load_or_init().unwrap())); static WORLD_STATE_SNAP_0: Lazy> = Lazy::new(|| { let mut snap0 = WORLD_STATE.lock().unwrap().clone(); pnk!(snap0.reset_branch(PRE_CHECK_BRANCH)); Mutex::new(snap0) }); static WORLD_STATE_SNAP_1: Lazy> = Lazy::new(|| { let mut snap1 = WORLD_STATE.lock().unwrap().clone(); pnk!(snap1.reset_branch(FORMAL_CHECK_BRANCH)); Mutex::new(snap1) }); static MEM_POOL: Lazy>> = Lazy::new(|| Mutex::new(vec![])); fn random_version() -> VersionNameOwned { VersionNameOwned( (1_0000_0000 + rand::random::() / 2) .to_be_bytes() .to_vec(), ) } fn transaction_pre_check(tx: Transaction) { let mut snap0 = WORLD_STATE_SNAP_0.lock().unwrap(); snap0.push_version(&tx.hash()).unwrap(); if snap0.apply_transaction(&tx).is_ok() { MEM_POOL.lock().unwrap().push(tx); } else { snap0.version_pop().unwrap(); } } fn begin_block() { let mut snap0 = WORLD_STATE_SNAP_0.lock().unwrap(); pnk!(snap0.reset_branch(PRE_CHECK_BRANCH)); let mut snap1 = WORLD_STATE_SNAP_1.lock().unwrap(); pnk!(snap1.reset_branch(FORMAL_CHECK_BRANCH)); } fn transaction_formal_check_all() { let mut snap1 = WORLD_STATE_SNAP_1.lock().unwrap().clone(); for tx in mem::take(&mut *MEM_POOL.lock().unwrap()).into_iter() { snap1.push_version(&tx.hash()).unwrap(); if snap1.apply_transaction(&tx).is_err() { snap1.version_pop().unwrap(); } } } fn end_block() { let mut snap1 = WORLD_STATE_SNAP_1.lock().unwrap(); snap1.merge_branch(FORMAL_CHECK_BRANCH).unwrap(); } impl WorldState { // sample code fn load_or_init() -> Result { let mut ws = WorldState { transactions: VecxVs::new(), balances: MapxVs::new(), a_consensus_int: OrphanVs::new(), }; if !ws.branch_is_found(MASTER_BRANCH) { ws.push_version(b"init version").c(d!())?; ws.new_branch(MASTER_BRANCH).c(d!())?; } ws.set_default_branch(MASTER_BRANCH).c(d!())?; ws.push_version(b"init version 2").c(d!())?; ws.new_branch(PRE_CHECK_BRANCH).c(d!())?; ws.new_branch(FORMAL_CHECK_BRANCH).c(d!())?; Ok(ws) } fn apply_transaction(&mut self, tx: &Transaction) -> Result<()> { self.a_very_complex_function_will_change_state(tx).c(d!()) } // sample code fn a_very_complex_function_will_change_state( &mut self, tx: &Transaction, ) -> Result<()> { if tx.from.get(0).is_some() { Ok(()) } else { // .......... Err(eg!("error occur")) } } fn branch_is_found(&self, branch: &str) -> bool { let br = BranchName(branch.as_bytes()); self.branch_exists(br) } fn new_branch(&mut self, branch: &str) -> Result<()> { let br = BranchName(branch.as_bytes()); self.branch_create(br, random_version().as_deref(), false) .c(d!()) } fn delete_branch(&mut self, branch: &str) -> Result<()> { let br = BranchName(branch.as_bytes()); self.branch_remove(br).c(d!()) } fn merge_branch(&mut self, branch: &str) -> Result<()> { let br = BranchName(branch.as_bytes()); self.branch_merge_to(br, BranchName(MASTER_BRANCH.as_bytes())) .c(d!()) } fn set_default_branch(&mut self, branch: &str) -> Result<()> { let br = BranchName(branch.as_bytes()); self.branch_set_default(br).c(d!()) } fn reset_branch(&mut self, branch: &str) -> Result<()> { self.set_default_branch(MASTER_BRANCH) .c(d!()) .and_then(|_| self.delete_branch(branch).c(d!())) .and_then(|_| self.new_branch(branch).c(d!())) .and_then(|_| self.set_default_branch(branch).c(d!())) } fn push_version(&mut self, version: &[u8]) -> Result<()> { let ver = VersionName(version); self.version_create(ver).c(d!()) } } #[derive(Default, Clone, Debug, Serialize, Deserialize)] struct Transaction { from: Address, to: Address, amount: Amount, } impl Transaction { fn hash(&self) -> Vec { // assume this is a hash function self.encode().to_vec() } } impl Transaction { fn new(amount: Amount) -> Self { Self { from: vec![], to: vec![], amount, } } } fn main() { let (sender, reveiver) = channel(); thread::spawn(move || { loop { for tx in reveiver.iter() { transaction_pre_check(tx); } } }); (0..10).for_each(|i| sender.send(Transaction::new(i)).unwrap()); sleep_ms!(60); begin_block(); transaction_formal_check_all(); end_block(); }