# Storage The **Storage** component is the memory of the blockchain. It is responsible for holding the state of the world (who owns what). ## Current Architecture (v0.3.0) In this iteration, pETHit transitioned from a generic Key-Value store to an **Account-based Model**. ### 1. The Account Model Instead of storing arbitrary strings, the state is now a collection of **Accounts**. Each account is defined by: ```rust #[derive(Debug, Clone, Default, PartialEq, Eq, RlpEncodable, RlpDecodable)] pub struct Account { pub nonce: u64, // Counters replay attacks (how many txs this account has sent) pub balance: U256, // The currency balance } ``` ### 2. The Storage Engine (`SimpleStorage`) Currently, the "database" is an in-memory `HashMap` wrapper. * **Keys:** Ethereum Addresses (`[u8; 20]`). * **Values:** RLP-Encoded bytes of the `Account` struct. While the logic operates on `Account` structs in Rust memory, the underlying storage mimics a raw disk database by serializing data into bytes (RLP) before inserting it into the map. ### 3. Thread Safety (`SharedStorage`) Since the Storage is accessed by multiple components simultaneously (the **RPC** reads accounts, the **Miner** updates balances), it is wrapped in a thread-safe container: `Arc<Mutex<SimpleStorage>>`. ## API / Usage The Storage crate exposes the following public interface for other crates (Node, Execution, RPC) to use. ### Structs ```rust // The fundamental unit of state pub struct Account { ... } // The thread-safe wrapper pub struct SharedStorage { ... } ``` ### Public Methods #### `new()` Creates a new, empty storage instance. ```rust let db = SharedStorage::new(); ``` #### `set_account(address, account)` Updates or inserts an account into the state. It handles the serialization (RLP encoding) internally. ```rust let acc = Account { nonce: 1, balance: U256::from(100) }; db.set_account(address, acc); ``` #### `get_account(address) -> Account` Retrieves an account. * If the account exists, it deserializes the bytes and returns the `Account` struct. * If the account does **not** exist, it returns a `Default` account (Nonce: 0, Balance: 0). ```rust let acc = db.get_account(address); println!("Balance: {}", acc.balance); ``` #### `update(closure)` Allows for batch updates or complex logic while holding the lock. This is primarily used by the Miner to execute a block of transactions safely. ```rust db.update(|inner_db| { // Perform multiple set/get operations here while the lock is held }); ``` ## Evolution Log ### v0.1.0: The Key-Value Store * **Structure:** `HashMap<Vec<u8>, Vec<u8>>`. * **Logic:** A simple wrapper around a standard HashMap. It treated all data as raw bytes. Keys were arbitrary strings (e.g., "user1"), and values were arbitrary strings. ### v0.2.0: Integration * No major structural changes. * Integrated into the `Node` and shared via `Arc<Mutex<>>`. ### v0.3.0: The Identity Update * **Schema Change:** Replaced generic byte vectors with the `Account` struct. * **Serialization:** Introduced **RLP (Recursive Length Prefix)** encoding. Data is now serialized before being stored in the map. * **Logic Change:** The `get` method now returns a default (empty) account instead of `None` if an address is not found, simplifying the execution logic.