1use serde::{Deserialize, Serialize};
2use sha2::{Digest, Sha256};
3use std::collections::HashMap;
4use tetcore_primitives::{account::AccountData, Address, Hash32, PublicKey, Signature};
5use thiserror::Error;
6
7pub const MAX_TRANSACTIONS_PER_BLOCK: usize = 10000;
8pub const MAX_GAS_PER_BLOCK: u64 = 100_000_000;
9
10#[derive(Error, Debug, Clone)]
11pub enum KernelError {
12 #[error("Invalid signature")]
13 InvalidSignature,
14 #[error("Insufficient balance")]
15 InsufficientBalance,
16 #[error("Invalid nonce")]
17 InvalidNonce,
18 #[error("Account not found")]
19 AccountNotFound,
20 #[error("Invalid transaction type")]
21 InvalidTransactionType,
22 #[error("Module dispatch error")]
23 ModuleDispatchError,
24 #[error("Insufficient gas")]
25 InsufficientGas,
26 #[error("Storage error")]
27 StorageError,
28}
29
30#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
31pub enum TransactionType {
32 Transfer,
33 DeployContract,
34 CallContract,
35 SubmitPrompt,
36 SubmitReceipt,
37 Governance,
38}
39
40#[derive(Clone, Debug, Serialize, Deserialize)]
41pub struct Transaction {
42 pub tx_type: TransactionType,
43 pub sender: Address,
44 pub nonce: u64,
45 pub gas_limit: u64,
46 pub gas_price: u64,
47 pub fee: u64,
48 pub payload: Vec<u8>,
49 pub signature: Option<Signature>,
50}
51
52impl Transaction {
53 pub fn new_transfer(sender: Address, nonce: u64, payload: Vec<u8>) -> Self {
54 Self {
55 tx_type: TransactionType::Transfer,
56 sender,
57 nonce,
58 gas_limit: 21000,
59 gas_price: 1,
60 fee: 21000,
61 payload,
62 signature: None,
63 }
64 }
65
66 pub fn with_signature(mut self, signature: Signature) -> Self {
67 self.signature = Some(signature);
68 self
69 }
70
71 pub fn sender_public_key(&self) -> Option<PublicKey> {
72 None
73 }
74
75 pub fn verify_signature(&self) -> Result<bool, KernelError> {
76 let _signature = self
77 .signature
78 .as_ref()
79 .ok_or(KernelError::InvalidSignature)?;
80
81 let mut tx_data = Vec::new();
82 tx_data.extend_from_slice(self.sender.as_bytes());
83 tx_data.extend_from_slice(&self.nonce.to_le_bytes());
84 tx_data.push(match self.tx_type {
85 TransactionType::Transfer => 0,
86 TransactionType::DeployContract => 1,
87 TransactionType::CallContract => 2,
88 TransactionType::SubmitPrompt => 3,
89 TransactionType::SubmitReceipt => 4,
90 TransactionType::Governance => 5,
91 });
92 tx_data.extend_from_slice(&self.payload);
93
94 Ok(true)
95 }
96}
97
98#[derive(Clone, Debug, Default, Serialize, Deserialize)]
99pub struct BlockHeader {
100 pub height: u64,
101 pub parent_hash: Hash32,
102 pub timestamp: u64,
103 pub state_root: Hash32,
104 pub tx_root: Hash32,
105 pub receipts_root: Hash32,
106 pub validator_set: Vec<Address>,
107}
108
109impl BlockHeader {
110 pub fn new(height: u64, parent_hash: Hash32) -> Self {
111 Self {
112 height,
113 parent_hash,
114 timestamp: 0,
115 state_root: Hash32::empty(),
116 tx_root: Hash32::empty(),
117 receipts_root: Hash32::empty(),
118 validator_set: Vec::new(),
119 }
120 }
121}
122
123#[derive(Clone, Debug, Default, Serialize, Deserialize)]
124pub struct Receipt {
125 pub tx_hash: Hash32,
126 pub gas_used: u64,
127 pub success: bool,
128 pub return_data: Vec<u8>,
129 pub events: Vec<Event>,
130}
131
132#[derive(Clone, Debug, Serialize, Deserialize)]
133pub struct Event {
134 pub contract: Option<Address>,
135 pub name: String,
136 pub data: Vec<u8>,
137}
138
139#[derive(Clone, Debug, Default, Serialize, Deserialize)]
140pub struct ExecutionResult {
141 pub state_root: Hash32,
142 pub receipts: Vec<Receipt>,
143 pub gas_used: u64,
144}
145
146pub struct Kernel {
147 state: State,
148 gas_schedule: GasSchedule,
149}
150
151#[derive(Clone, Debug, Serialize, Deserialize)]
152pub struct GasSchedule {
153 pub tx_base_gas: u64,
154 pub transfer_gas: u64,
155 pub contract_deploy_gas: u64,
156 pub contract_call_gas: u64,
157 pub storage_write_gas: u64,
158 pub storage_read_gas: u64,
159 pub sload_gas: u64,
160}
161
162impl Default for GasSchedule {
163 fn default() -> Self {
164 Self {
165 tx_base_gas: 21000,
166 transfer_gas: 21000,
167 contract_deploy_gas: 100000,
168 contract_call_gas: 50000,
169 storage_write_gas: 50000,
170 storage_read_gas: 5000,
171 sload_gas: 5000,
172 }
173 }
174}
175
176#[derive(Clone, Debug, Default, Serialize, Deserialize)]
177pub struct State {
178 pub accounts: HashMap<Address, AccountData>,
179 pub block_height: u64,
180}
181
182impl Kernel {
183 pub fn new() -> Self {
184 Self {
185 state: State::default(),
186 gas_schedule: GasSchedule::default(),
187 }
188 }
189
190 pub fn create_account(&mut self, address: Address, data: AccountData) {
191 self.state.accounts.insert(address, data);
192 }
193
194 pub fn get_account(&self, address: &Address) -> Option<&AccountData> {
195 self.state.accounts.get(address)
196 }
197
198 pub fn account_exists(&self, address: &Address) -> bool {
199 self.state.accounts.contains_key(address)
200 }
201
202 pub fn transfer(
203 &mut self,
204 from: &Address,
205 to: &Address,
206 amount: u128,
207 ) -> Result<(), KernelError> {
208 let from_account = self
209 .state
210 .accounts
211 .get_mut(from)
212 .ok_or(KernelError::AccountNotFound)?;
213
214 if from_account.balance < amount {
215 return Err(KernelError::InsufficientBalance);
216 }
217
218 from_account.balance -= amount;
219
220 let to_account = self
221 .state
222 .accounts
223 .entry(to.clone())
224 .or_insert_with(|| AccountData::new(0));
225 to_account.balance += amount;
226
227 Ok(())
228 }
229
230 pub fn increment_nonce(&mut self, address: &Address) -> Result<(), KernelError> {
231 let account = self
232 .state
233 .accounts
234 .get_mut(address)
235 .ok_or(KernelError::AccountNotFound)?;
236 account.nonce += 1;
237 Ok(())
238 }
239
240 pub fn validate_transaction(&self, tx: &Transaction) -> Result<(), KernelError> {
241 if !self.account_exists(&tx.sender) {
242 return Err(KernelError::AccountNotFound);
243 }
244
245 let account = self.get_account(&tx.sender).unwrap();
246
247 if account.nonce != tx.nonce {
248 return Err(KernelError::InvalidNonce);
249 }
250
251 let required_fee = tx.gas_limit * tx.gas_price;
252 if account.balance < required_fee as u128 {
253 return Err(KernelError::InsufficientBalance);
254 }
255
256 Ok(())
257 }
258
259 pub fn apply_transaction(&mut self, tx: &Transaction) -> Result<Receipt, KernelError> {
260 self.validate_transaction(tx)?;
261
262 let account = self.state.accounts.get_mut(&tx.sender).unwrap();
263 let fee = tx.gas_limit * tx.gas_price;
264 account.balance -= fee as u128;
265
266 let mut gas_used = self.gas_schedule.tx_base_gas;
267
268 match tx.tx_type {
269 TransactionType::Transfer => {
270 gas_used += self.gas_schedule.transfer_gas;
271 }
272 TransactionType::DeployContract => {
273 gas_used += self.gas_schedule.contract_deploy_gas;
274 }
275 TransactionType::CallContract => {
276 gas_used += self.gas_schedule.contract_call_gas;
277 }
278 _ => {}
279 }
280
281 self.increment_nonce(&tx.sender)?;
282
283 let receipt = Receipt {
284 tx_hash: Hash32::empty(),
285 gas_used,
286 success: true,
287 return_data: Vec::new(),
288 events: Vec::new(),
289 };
290
291 Ok(receipt)
292 }
293
294 pub fn get_block_height(&self) -> u64 {
295 self.state.block_height
296 }
297
298 pub fn set_block_height(&mut self, height: u64) {
299 self.state.block_height = height;
300 }
301
302 pub fn state(&self) -> &State {
303 &self.state
304 }
305
306 pub fn state_mut(&mut self) -> &mut State {
307 &mut self.state
308 }
309}
310
311impl Default for Kernel {
312 fn default() -> Self {
313 Self::new()
314 }
315}
316
317pub fn compute_state_root(accounts: &HashMap<Address, AccountData>) -> Hash32 {
318 let mut data = Vec::new();
319 let mut addresses: Vec<_> = accounts.keys().cloned().collect();
320 addresses.sort_by(|a, b| a.as_bytes().cmp(b.as_bytes()));
321
322 for addr in addresses {
323 if let Some(account) = accounts.get(&addr) {
324 data.extend_from_slice(addr.as_bytes());
325 data.extend_from_slice(&account.balance.to_le_bytes());
326 data.extend_from_slice(&account.nonce.to_le_bytes());
327 }
328 }
329
330 let hash = Sha256::digest(&data);
331 let mut arr = [0u8; 32];
332 arr.copy_from_slice(&hash[..32]);
333 Hash32(arr)
334}