Skip to main content

tetcore_node/
lib.rs

1use std::collections::HashMap;
2use tetcore_kernel::{compute_state_root, BlockHeader, Kernel, Receipt, Transaction};
3use tetcore_primitives::{account::AccountData, Address, Hash32};
4use tetcore_runtime::Runtime;
5use tetcore_vm::TVM;
6use thiserror::Error;
7
8#[derive(Error, Debug, Clone)]
9pub enum NodeError {
10    #[error("Block validation failed")]
11    BlockValidationFailed,
12    #[error("Transaction pool error")]
13    TransactionPoolError,
14    #[error("Consensus error")]
15    ConsensusError,
16    #[error("Storage error")]
17    StorageError,
18}
19
20#[derive(Clone, Debug)]
21pub struct Block {
22    pub header: BlockHeader,
23    pub transactions: Vec<Transaction>,
24    pub receipts: Vec<Receipt>,
25}
26
27impl Block {
28    pub fn new(header: BlockHeader, transactions: Vec<Transaction>) -> Self {
29        Self {
30            header,
31            transactions,
32            receipts: Vec::new(),
33        }
34    }
35
36    pub fn validate(&self) -> Result<(), NodeError> {
37        if self.transactions.is_empty() {
38            return Err(NodeError::BlockValidationFailed);
39        }
40        Ok(())
41    }
42}
43
44pub struct TransactionPool {
45    pending: Vec<Transaction>,
46}
47
48impl TransactionPool {
49    pub fn new() -> Self {
50        Self {
51            pending: Vec::new(),
52        }
53    }
54
55    pub fn add_transaction(&mut self, tx: Transaction) {
56        self.pending.push(tx);
57    }
58
59    pub fn get_transactions(&self) -> &Vec<Transaction> {
60        &self.pending
61    }
62
63    pub fn clear(&mut self) {
64        self.pending.clear();
65    }
66
67    pub fn remove_executed(&mut self, _executed_count: usize) {}
68}
69
70impl Default for TransactionPool {
71    fn default() -> Self {
72        Self::new()
73    }
74}
75
76pub struct ChainStorage {
77    blocks: HashMap<u64, Block>,
78    state: HashMap<Address, AccountData>,
79    current_height: u64,
80}
81
82impl ChainStorage {
83    pub fn new() -> Self {
84        Self {
85            blocks: HashMap::new(),
86            state: HashMap::new(),
87            current_height: 0,
88        }
89    }
90
91    pub fn get_block(&self, height: u64) -> Option<&Block> {
92        self.blocks.get(&height)
93    }
94
95    pub fn insert_block(&mut self, block: Block) {
96        let height = block.header.height;
97        self.blocks.insert(height, block);
98        if height > self.current_height {
99            self.current_height = height;
100        }
101    }
102
103    pub fn get_state(&self, address: &Address) -> Option<&AccountData> {
104        self.state.get(address)
105    }
106
107    pub fn set_state(&mut self, address: Address, account: AccountData) {
108        self.state.insert(address, account);
109    }
110
111    pub fn get_all_state(&self) -> &HashMap<Address, AccountData> {
112        &self.state
113    }
114
115    pub fn current_height(&self) -> u64 {
116        self.current_height
117    }
118
119    pub fn get_genesis_hash(&self) -> Option<Hash32> {
120        self.blocks.get(&0).map(|b| b.header.state_root.clone())
121    }
122}
123
124impl Default for ChainStorage {
125    fn default() -> Self {
126        Self::new()
127    }
128}
129
130pub enum NodeMode {
131    Client,
132    Validator,
133    InferenceOperator,
134    Relay,
135}
136
137pub struct TetcoreNode {
138    kernel: Kernel,
139    runtime: Runtime,
140    tvm: TVM,
141    tx_pool: TransactionPool,
142    chain: ChainStorage,
143    mode: NodeMode,
144    my_address: Option<Address>,
145}
146
147impl TetcoreNode {
148    pub fn new(mode: NodeMode) -> Self {
149        Self {
150            kernel: Kernel::new(),
151            runtime: Runtime::new(),
152            tvm: TVM::new(),
153            tx_pool: TransactionPool::new(),
154            chain: ChainStorage::new(),
155            mode,
156            my_address: None,
157        }
158    }
159
160    pub fn set_my_address(&mut self, address: Address) {
161        self.my_address = Some(address);
162    }
163
164    pub fn create_genesis_block(&mut self) -> Block {
165        let header = BlockHeader::new(0, Hash32::empty());
166        Block::new(header, Vec::new())
167    }
168
169    pub fn initialize_genesis(&mut self, accounts: Vec<(Address, u128)>) {
170        for (address, balance) in accounts {
171            let account = AccountData::new(balance);
172            self.chain.set_state(address, account.clone());
173            self.kernel.create_account(address, account);
174        }
175
176        let genesis = self.create_genesis_block();
177        self.chain.insert_block(genesis);
178    }
179
180    pub fn submit_transaction(&mut self, tx: Transaction) -> Result<(), NodeError> {
181        self.kernel
182            .validate_transaction(&tx)
183            .map_err(|_| NodeError::TransactionPoolError)?;
184        self.tx_pool.add_transaction(tx);
185        Ok(())
186    }
187
188    pub fn produce_block(&mut self) -> Result<Block, NodeError> {
189        let parent_height = self.chain.current_height();
190        let parent_hash = self
191            .chain
192            .get_block(parent_height)
193            .map(|b| b.header.state_root.clone())
194            .unwrap_or_else(Hash32::empty);
195
196        let mut header = BlockHeader::new(parent_height + 1, parent_hash);
197
198        let transactions: Vec<Transaction> = self.tx_pool.get_transactions().clone();
199
200        for tx in &transactions {
201            if self.kernel.apply_transaction(tx).is_ok() {
202                if let Some(account) = self.chain.get_state(&tx.sender).cloned() {
203                    let mut updated = account.clone();
204                    updated.balance = updated.balance.saturating_sub(21000);
205                    self.chain.set_state(tx.sender, updated);
206                }
207            }
208        }
209
210        let accounts = self.chain.get_all_state().clone();
211        header.state_root = compute_state_root(&accounts);
212
213        self.tx_pool.clear();
214
215        let mut block = Block::new(header, transactions);
216        block
217            .validate()
218            .map_err(|_| NodeError::BlockValidationFailed)?;
219
220        Ok(block)
221    }
222
223    pub fn import_block(&mut self, block: Block) -> Result<(), NodeError> {
224        block
225            .validate()
226            .map_err(|_| NodeError::BlockValidationFailed)?;
227
228        for tx in &block.transactions {
229            self.kernel.apply_transaction(tx).ok();
230        }
231
232        self.chain.insert_block(block);
233
234        Ok(())
235    }
236
237    pub fn get_account(&self, address: &Address) -> Option<AccountData> {
238        self.chain.get_state(address).cloned()
239    }
240
241    pub fn get_runtime(&self) -> &Runtime {
242        &self.runtime
243    }
244
245    pub fn get_runtime_mut(&mut self) -> &mut Runtime {
246        &mut self.runtime
247    }
248
249    pub fn get_tvm(&self) -> &TVM {
250        &self.tvm
251    }
252
253    pub fn get_tvm_mut(&mut self) -> &mut TVM {
254        &mut self.tvm
255    }
256
257    pub fn mode(&self) -> &NodeMode {
258        &self.mode
259    }
260
261    pub fn chain(&self) -> &ChainStorage {
262        &self.chain
263    }
264
265    pub fn chain_mut(&mut self) -> &mut ChainStorage {
266        &mut self.chain
267    }
268}