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}