Skip to main content

tetcore_kernel/
lib.rs

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}