# NSSA Node Specs - [1. Introduction](#introduction) - [2. Background](#background) - [2.1. Nescience State-Separation Architecture (NSSA)](#nssa) - [2.2. Zero-Knowledge Virtual Machine (zkVM)](#zkvm) - [3. Objectives](#objectives) - [4. Architecture Overview](#overview) - [4.1. Full Node Implementation](#full) - [4.2. Sandbox Node Implementation](#sandbox) - [5. Detailed Specifications](#details) - [5.1. Core Components](#core) - [5.1.1. Accounts](#acc) - [5.1.2. UTXO Management](#utxo) - [5.1.3. Virtual Machine (VM)](#vm) - [5.1.4. Zero-Knowledge Virtual Machine (zkVM)](#zkvm1) - [5.1.5. Networking Layer](#network) - [5.1.6. Sequencer](#sequencer) - [5.1.7. Mempool](#mempool) - [5.1.8. Consensus Mechanism](#consensus) - [5.1.9. Storage](#storage) - [5.2. Execution Types](#execution) - [5.2.1. Public Execution](#public) - [5.2.2. Private Execution](#private) - [5.2.3. Shielded Execution](#shielded) - [5.2.4. Deshielded Execution](#deshielded) - [6. Implementation Details ](#implementation) - [6.1. General Introduction and Required Crates](#general) - [6.2. Full Node Implementation](#full1) - [6.2.1. Accounts Module](#acc1) - [6.2.2. UTXO Management Module](#utxo1) - [6.2.3. VM Module](#vm1) - [6.2.4. ZkVM Module](#zkvm1) - [6.2.5. Networking Layer](#network1) - [6.2.6. Sequencer](#sequencer1) - [6.2.7. Mempool](#mempool1) - [6.2.8. Consensus Mechanism](#consensus1) - [6.2.9. Storage Module](#storage1) - [6.3. Sandbox Node Implementation](#sandbox1) - [6.3.1. In-Memory Storage](#storage2) - [6.3.2. Mock Peer-to-Peer Communication](#p2p) - [6.3.3. Simplified Sequencer](#sequencer2) - [6.3.4. zkVM Integration](#zkvm2) - [6.3.5. Simplified Mempool](#mempool2) ## <div id='introduction'/> 1. Introduction The Nescience State-Separation Architecture (NSSA) introduces a novel approach to privacy management in blockchain technology. Unlike traditional systems where privacy levels are hardcoded by developers, NSSA allows users to dynamically select their desired privacy level, offering a range of execution types from fully public to highly private. This architecture leverages zero-knowledge proofs and advanced cryptographic methods to ensure that transactions are both secure and confidential. This RFC outlines the design and implementation of a Nescience node that integrates a Zero-Knowledge Virtual Machine (zkVM) to enable these selective privacy features. The document provides a detailed breakdown of the architecture, components, and implementation strategies, along with a sandbox approach for initial testing and validation. ## <div id= 'background'/> 2. Background ### <div id="nssa"></a> 2.1. Nescience State-Separation Architecture (NSSA) NSSA is designed to overcome the limitations of existing hybrid execution platforms, where privacy settings are predefined by developers, leaving users with limited flexibility. In many current systems, users have no choice but to adhere to the privacy levels set by the application developers, which may not align with their personal needs or regulatory requirements. NSSA addresses this by allowing users to choose their privacy level for each transaction, providing a more personalized and flexible approach to privacy. The architecture supports four types of executions: - Public Execution: Fully transparent, all transaction details are visible on the public blockchain. - Private Execution: Transactions are confidential, with details only available to the involved parties. - Shielded Execution: Interactions between the public and private states, adding a layer of privacy for certain transaction outputs. - Deshielded Execution: Allows previously private information to be made public, enabling selective disclosure for auditing or compliance purposes. ### <div id="zkvm"></a> 2.2. Zero-Knowledge Virtual Machine (zkVM) The zkVM is a key component of NSSA, enabling private transactions by allowing users to prove the correctness of a transaction without revealing the underlying data. It is critical for implementing the private, shielded, and deshielded execution types in NSSA. The used zkVM should be designed to be recursive-friendly, supporting the aggregation of multiple proofs into a single proof, which optimizes performance and scalability. Additionally, the zkVM should be lightweight, ensuring it can run efficiently on standard hardware without requiring excessive computational resources. ## <div id="objectives"></a> 3. Objectives The primary objective of this RFC is to define the design and implementation details for a Nescience node that integrates a zkVM within the Nescience State-Separation Architecture. This document serves as a comprehensive guide for engineers and developers, providing the necessary specifications and implementation strategies to build and deploy a fully functioning Nescience node. The key objectives are: - Selective Privacy Implementation: To provide users with the ability to select their privacy level on a per-transaction basis, utilizing the various execution types supported by NSSA. - zkVM Integration: To integrate a recursive-friendly, privacy-preserving zkVM that can handle the generation and verification of ZKPs efficiently. - Scalability and Performance: To ensure that the node architecture is scalable and performs well under high transaction volumes, while maintaining the integrity and security of the blockchain. - Modular Design: To design the node with modular components, making it easier to extend, maintain, and integrate with other blockchain systems. - Testnet and Mainnet Readiness: To create a node that is fully capable of operating in both testnet and mainnet environments, with appropriate deployment strategies for each. ## <div id="overview"></a> 4. Architecture Overview ### <div id="full"></a> 4.1. Full Node Implementation The Nescience full node is designed to participate in a peer-to-peer (P2P) network, where it maintains the blockchain state, validates transactions, participates in consensus, and interacts with other nodes to propagate blocks and transactions across the network. The key components of the full node include: - Accounts Module: Manages user accounts, including key generation, balance tracking, and UTXO management. - UTXO Management: Handles the creation, storage, and consumption of UTXOs, ensuring that each UTXO can only be spent once. - Virtual Machine (VM): Executes transactions and smart contracts within the node, applying state changes to the blockchain. - Zero-Knowledge Virtual Machine (zkVM): Generates and verifies zero-knowledge proofs for private, shielded, and deshielded transactions. - Networking Layer: Facilitates P2P communication between nodes, including transaction and block propagation. - Sequencer: A specialized component that organizes transactions into blocks, validates zk-proofs, and participates in the consensus process. - Mempool: A local storage area for pending transactions that have not yet been included in a block. - Consensus Mechanism: Ensures that all nodes agree on the state of the blockchain, using algorithms like Proof-of-Stake (PoS) or Practical Byzantine Fault Tolerance (PBFT). - Storage: Provides persistent storage for blockchain data, including UTXOs, nullifiers, and state trees. ### <div id="sandbox"></a> 4.2. Sandbox Node Implementation To simplify the development and testing process, a sandbox node implementation is proposed. The sandbox environment simulates the blockchain's functionality within a controlled, single-machine environment. This approach allows for focused testing of core components without the complexity of P2P networking or consensus mechanisms. The key components of the sandbox node include: - In-Memory Storage: Uses in-memory data structures to simulate blockchain state, UTXOs, and transaction pools. - Mock P2P Communication: Simulates P2P interactions within the same process, enabling the testing of transaction flows and state updates. - Deterministic Execution: Ensures that transactions and state updates occur in a predefined order, making it easier to debug and analyze the system. - zkVM Integration: The zkVM is fully integrated within the sandbox, allowing for the generation and verification of ZKPs in a controlled environment. - Simplified Sequencer: Implements a basic block creation mechanism without the need for full consensus, focusing instead on transaction validation and state updates. - Testing and Debugging Tools: Provides extensive logging and debugging features to help developers identify and resolve issues during development. - Stable environment: Offers a reliable and consistent environment with fewer bugs and errors. ## <div id="details"></a> 5. Detailed Specifications ### <div id="core "></a> 5.1. Core Components #### <div id="acc"></a> 5.1.1. Accounts The Accounts module is responsible for managing user identities, keys, balances, and associated state. Each account holds a set of cryptographic keys used for signing transactions, generating addresses, and managing UTXOs. The Accounts module also tracks both public and private balances, allowing users to interact with the blockchain in different privacy modes. Key Elements: - Spending Key: A core secret key used to derive private keys and control UTXOs. It never interacts with the public state to ensure security. - Private Keys: Used for signing transactions, generating commitments, and creating pseudorandom functions. Composed of multiple parts, including the random seed, commitment part, and signature part. - Public Keys: Derived from the private keys, used for verifying signatures and commitments. They include verification keys for signatures and keys for generating pseudorandom functions. - Viewing Key: Allows decryption of incoming and outgoing transactions without granting spending authority, preserving privacy while offering transaction visibility. - Addresses: There are public addresses for transparent transactions and private addresses for confidential transactions. Private addresses are not visible on-chain and can be generated as needed to enhance privacy. Interactions: - UTXO Management: Accounts manage UTXOs by spending them through transactions, creating new UTXOs, and generating necessary cryptographic proofs. - VM and zkVM: The private and public keys are used within the VM and zkVM to sign transactions and generate/verify proofs. #### <div id="utxo"></a> 5.1.2. UTXO Management UTXO management handles the lifecycle of UTXOs, from their creation to their eventual consumption. The UTXO model ensures that every output can only be spent once, preventing double-spending and maintaining the integrity of the blockchain. Key Elements: - UTXO Structure: Each UTXO contains a value, owner’s address, optional nullifier (to mark it as spent), and an ephemeral key for secure transaction details encryption. - Nullifier: A cryptographic hash that marks a UTXO as spent. Stored in the Nullifier Tree, it ensures that the same UTXO cannot be reused in future transactions. - Ephemeral Key: Generated using the sender’s spending key and the UTXO’s nullifier, it is used to encrypt transaction details securely. Processes: - Creation: UTXOs are created as outputs of transactions. The details are encrypted and committed to the blockchain. - Consumption: When a UTXO is used in a transaction, it is marked as spent by generating a nullifier, which is then added to the Nullifier Tree to prevent reuse. - Storage: UTXOs are stored in a sparse Merkle tree, enabling efficient verification and retrieval. Interactions: - Accounts: UTXOs are tied to accounts, with the owner’s public key used to determine ownership. - zkVM: UTXOs are involved in ZKP generation to prove ownership and correctness without revealing transaction details. #### <div id="vm"></a> 5.1.3. Virtual Machine (VM) The VM is responsible for executing transactions and smart contracts within the Nescience node. It processes the logic of each transaction, applying the necessary state changes to the blockchain. Key Elements: - Execution Engine: Processes transactions by validating inputs, updating states, and applying any smart contract logic. - State Management: Manages the current state of the blockchain, including account balances, smart contract storage, and UTXO states. Processes: - Transaction Execution: The VM validates each transaction, ensuring that inputs are valid, signatures are correct, and that state transitions follow the rules. - State Updates: After execution, the VM updates the blockchain state, including balances, UTXO consumption, and contract storage. Interactions: - zkVM: The VM interacts closely with the zkVM when processing transactions that require ZKPs, ensuring that the privacy-preserving aspects of the transaction are maintained. - Storage: The VM reads from and writes to the blockchain’s state, ensuring that all changes are persistently stored. #### <div id="zkvm1"></a> 5.1.4. Zero-Knowledge Virtual Machine (zkVM) The zkVM is a specialized component designed to generate and verify ZKPs. It ensures that private, shielded, and deshielded transactions are processed without revealing sensitive information. Key Elements: - Proof Generation: Generates zk-SNARKs for transactions, allowing users to prove transaction validity without revealing details. - Proof Verification: Verifies the zk-SNARKs, ensuring that the proofs are correct and that the transaction can be included in a block. - Recursive Proofs: Supports recursive operations, enabling multiple proofs to be aggregated into a single proof for efficiency. Processes: - Private Execution: The zkVM handles the generation of proofs that validate private transactions. - Shielded/Deshielded Execution: In shielded and deshielded executions, the zkVM ensures that certain details are kept confidential while selectively revealing others as necessary. Interactions: - VM: The zkVM interacts with the VM to ensure that transactions are executed correctly while maintaining privacy. - Sequencer: Works with the sequencer to validate proofs and include them in blocks. #### <div id="network"></a> 5.1.5. Networking Layer The Networking Layer facilitates communication between nodes in the Nescience network, enabling them to share transactions, propagate blocks, and participate in consensus. Key Elements: - P2P Communication: Allows nodes to discover peers, propagate transactions and blocks, and synchronize their state with the network. - Gossip Protocol: Used to broadcast information to all nodes in the network efficiently. Processes: - Transaction Propagation: When a node receives a transaction, it propagates it to other nodes to ensure that it is included in the blockchain. - Block Broadcasting: After a block is created, it is broadcasted to other nodes to be validated and added to their local chains. Interactions: - Sequencer: The networking layer works closely with the sequencer to ensure that new blocks are disseminated throughout the network. - Mempool: Transactions in the mempool are shared across the network until they are included in a block. #### <div id="sequencer"></a> 5.1.6. Sequencer The sequencer is responsible for organizing transactions into blocks, validating ZKPs, and ensuring that blocks are added to the blockchain in the correct order. Key Elements: - Block Creation: Collects transactions from the mempool, validates them, and organizes them into a block. - Proof Validation: Verifies zk-SNARKs and other proofs before including them in the block. - Consensus Participation: Participates in the consensus process to ensure that the block is accepted by the network. Processes: - Block Formation: The sequencer aggregates validated transactions into a block and prepares it for broadcasting. - Consensus Engagement: Engages in the consensus protocol to gain network approval for the block. Interactions: - Networking Layer: Works with the networking layer to propagate the newly created blocks across the network. - VM and zkVM: Ensures that all transactions and proofs within a block are valid before including them. #### <div id="mempool"></a> 5.1.7. Mempool The mempool is a temporary storage area for transactions that have been received by the node but not yet included in a block. Key Elements: - Transaction Queue: A queue of pending transactions that are waiting to be validated and included in the blockchain. - Priority Management: Manages the order in which transactions are included in blocks, typically based on transaction fees or other criteria. Processes: - Transaction Storage: Stores incoming transactions until they are selected by the sequencer for inclusion in a block. - Transaction Removal: Removes transactions from the mempool once they are included in a block. Interactions: - Networking Layer: Receives transactions from the network and stores them in the mempool. - Sequencer: Supplies the sequencer with transactions for block creation. #### <div id="consensus"></a> 5.1.8. Consensus Mechanism The consensus mechanism ensures that all nodes in the network agree on the state of the blockchain. It prevents double-spending, forks, and other inconsistencies. Key Elements: - Consensus Algorithm: Determines how nodes agree on the next block to add to the blockchain. This could be Proof-of-Stake (PoS), Practical Byzantine Fault Tolerance (PBFT), or another consensus algorithm. - Voting and Finality: Mechanisms for nodes to vote on proposed blocks and ensure that once a block is accepted, it is final and cannot be changed. Processes: - Block Proposal: Nodes propose new blocks to be added to the blockchain. - Voting and Agreement: Nodes vote on proposed blocks, and the consensus algorithm determines which block is accepted. Interactions: - Sequencer: Works with the sequencer to validate and finalize blocks. - Networking Layer: Communicates with other nodes to participate in the consensus process. #### <div id="storage"></a> 5.1.9. Storage The storage component provides persistent storage for all blockchain data, including the blockchain state, UTXOs, nullifiers, and transaction history. Key Elements: - Blockchain State: Stores the current state of the blockchain, including account balances, contract storage, and UTXO states. UTXO and Nullifier Trees: Stores the UTXO and nullifier trees, allowing for efficient retrieval and verification. - Block Storage: Keeps a record of all blocks in the blockchain, allowing for historical lookup and verification. Processes: - Data Persistence: Ensures that all blockchain data is stored persistently and can be retrieved as needed. - State Updates: Updates the stored state based on transactions and blocks. Interactions: - VM and zkVM: Reads from and writes to the blockchain state during transaction execution. - Sequencer: Accesses storage to retrieve transaction history and state for block creation. ### <div id="execution"></a> 5.2. Execution Types #### <div id="public"></a> 5.2.1. Public Execution Public executions are fully transparent transactions where all details are visible on the blockchain. They do not require ZKPs and are typically used for interactions that do not involve sensitive information. Key Elements: - Transparency: All transaction details, including sender, receiver, and amount, are public. - No ZKPs: Does not involve ZKPs, simplifying the transaction process. #### <div id="private"></a> 5.2.2. Private Execution Private executions ensure that transaction details are confidential, visible only to the involved parties. These transactions use zk-SNARKs to prove validity without revealing sensitive information. Key Elements: - Confidentiality: Transaction details are encrypted and hidden from the public. - ZKPs: Requires zk-SNARKs to prove the transaction’s validity without revealing details. #### <div id="shielded"></a> 5.2.3. Shielded Execution Shielded executions allow interactions between public and private states, creating a layer of privacy for specific outputs. These executions are used when some details need to remain private while others are public. Key Elements: - Selective Privacy: Certain aspects of the transaction are kept private, while others are public. - Partial ZKPs: Uses zk-SNARKs to hide specific details while allowing some information to be visible. #### <div id="deshielded"></a> 5.2.4. Deshielded Execution Deshielded executions reveal previously private information to the public state. This type of execution is used for compliance or auditing purposes where selective disclosure is required. Key Elements: - Selective Disclosure: Previously private information is made public as needed. - ZKPs with Disclosure: Uses zk-SNARKs to ensure the integrity of the transaction while revealing certain details. ## <div id="implementation"></a> 6. Implementation Details In this section, we will cover the necessary implementation details for building the Full Node and the Sandbox Node of the Nescience state separation architecture using Rust. ### <div id="general"></a> 6.1. General Introduction and Required Crates Rust is the chosen language due to its emphasis on memory safety, speed, and concurrency, which is crucial for implementing a secure and scalable blockchain. In what follows, some of the core dependencies and libraries: 1. Cryptography: - '[ring](https://crates.io/crates/ring)': Provides support for cryptographic operations such as key generation, digital signatures, and hash functions. - '[secrecy](https://crates.io/crates/secrecy)': To wrap sensitive data, ensuring that it is securely zeroed out from memory when no longer needed. - '[bip39](https://crates.io/crates/bip39)' & '[bip32](https://crates.io/crates/bip32)': Hierarchical key derivation allowing a single seed to generate multiple keys. - '[arkworks-rs](https://github.com/arkworks-rs)': A cryptography framework specifically designed for zk-SNARKs. We'll use it for proof generation and verification. - '[blake2](https://crates.io/crates/blake2)': Efficient cryptographic hash function used in UTXO commitments and nullifier calculations. 2. State and Storage: - '[sled](https://crates.io/crates/sled)': Embedded key-value store that provides durable storage for UTXO sets, nullifiers, and blockchain states. - '[serde](https://crates.io/crates/serde)' & '[bincode](https://crates.io/crates/bincode)': Serialization libraries to efficiently store and retrieve data, especially for blockchain state (blocks, transactions, UTXOs). - '[hashmap](https://doc.rust-lang.org/stable/std/collections/struct.HashMap.html)' & '[hashset](https://doc.rust-lang.org/std/collections/struct.HashSet.html)': To store UTXOs and track nullifiers ensuring that each nullifier is unique and can be checked quickly to prevent double-spending. 3. Networking: - '[libp2p](https://github.com/libp2p/rust-libp2p)': Provides decentralized peer-to-peer (P2P) communication, enabling transaction propagation, block gossiping, and consensus-related communication. - '[tokio](https://crates.io/crates/tokio)': Asynchronous runtime that handles network I/O, peer communication, and concurrent tasks, which is essential for the full node to operate smoothly in a decentralized network. - '[futures](https://crates.io/crates/futures)': Helps manage asynchronous code in Rust, ensuring smooth scheduling of tasks. 4. ZKPs: -'[arkworks-rs](https://github.com/arkworks-rs)': Used for generating and verifying zk-SNARKs in the Nescience state-separation architecture. - '[rand](https://crates.io/crates/rand)': To generate random numbers required during proof construction and cryptographic key generation. 5. Merkle Tree Structures: - '[merkle-light](https://crates.io/crates/merkle_light)': Efficient implementation of sparse Merkle trees for managing UTXO states and nullifiers, allowing for efficient proof generation and verification. 6. Logging and Debugging: - '[log](https://crates.io/crates/log)' & '[env_logger](https://crates.io/crates/env_logger)': Standard logging utilities to track node behavior during development and in production environments. - '[tracing](https://crates.io/crates/tracing)': More advanced logging that can also track distributed systems, especially useful for debugging P2P networks. ### <div id="full1"></a> 6.2 Full Node Implementation The full node implementation encompasses several key components that are responsible for managing accounts, processing transactions, maintaining the state of the blockchain, ensuring network consensus, and handling ZKP generation and verification. #### <div id="acc1"></a> 6.2.1. Accounts Module - Key Management: We can use 'ring' for secure key generation (spending keys, private keys, and public keys). - Address Generation: Addresses are derived from public keys using a cryptographic hash function like 'blake2'. - Balance Management: Separate tracking for public and private balances. For private balances, UTXO-based accounting is used, while for public balances, an account-based model is used. ```rust use secrecy::Secret; use ring::signature::Ed25519KeyPair; use blake2::Blake2b; pub struct Account { pub spending_key: Secret<[u8; 32]>, pub private_key: Vec<u8>, pub public_key: Vec<u8>, pub public_balance: u64, // Account-based balance (public) pub private_utxos: Vec<UTXO>, // UTXO-based (private) pub addresses: Vec<Address>, } ``` #### <div id="utxo1"></a> 6.2.2. UTXO Management Module - UTXO Structure: Each UTXO contains value, owner, and potentially an ephemeral key for shielding transactions. - Nullifier Management: Nullifiers are created when UTXOs are consumed to prevent their reuse. ```rust pub struct UTXO { pub value: u64, pub owner: Address, pub nullifier: Option<Nullifier>, pub ephemeral_key: Option<EphemeralKey>, } pub struct UTXOManager { pub utxos: HashMap<String, UTXO>, pub nullifiers: HashSet<String>, } ``` #### <div id="vm1"></a> 6.2.3. VM Module - State Management: A global state is maintained within the VM, which is updated as transactions are processed. - Execution Logic: The VM handles different types of execution (public, private, shielded, deshielded). ```rust pub struct VM { pub global_state: HashMap<String, u64>, // Account balances and other global state } ``` #### <div id="zkvm1"></a> 6.2.4. ZkVM Module - zk-SNARK Proof Generation: Using 'arkworks-r's, we can generate ZKPs that attest to the validity of transactions. - Proof Verification: zkVM verifies the proofs to ensure transaction correctness while preserving privacy. ```rust pub struct zkVM { pub prover: Prover<Bls12_381>, pub verifier: Verifier<Bls12_381>, } ``` #### <div id="network1"></a> 6.2.5. Networking Layer - libp2p Integration: We can implement P2P communication using the 'libp2p' crate for gossiping transactions and blocks. - Message Handling: We can use async message handlers for non-blocking communication between nodes. #### <div id="sequencer1"></a> 6.2.6. Sequencer - Block Creation: Pulls transactions from the mempool and packages them into blocks. - Block Validation: Ensures that all transactions within a block are valid before appending it to the blockchain. ```rust pub struct Sequencer { pub mempool: Vec<Transaction>, } ``` #### <div id="mempool1"></a> 6.2.7. Mempool - Transaction Queue: Implements a priority queue based on transaction fees or timestamps. - Synchronization: Ensures that the mempool is synchronized across nodes through P2P messaging. ```rust pub struct Mempool { pub transactions: Vec<Transaction>, } ``` #### <div id="consensus1"></a> 6.2.8. Consensus Mechanism - PoS Implementation: Validator nodes vote on blocks, and the block with the majority of votes is added to the chain. - Finality: Ensures finality once a block is added to the chain by reaching consensus. ```rust pub struct Consensus { pub validators: Vec<Validator>, } ``` #### <div id="storage1"></a> 6.2.9. Storage Module - 'sled': An embedded database is used to store blockchain state (UTXOs, nullifiers, blocks) on disk. - Serialization: We can use 'serde' and 'bincode' to serialize data before storing it. ### <div id="sandbox1"></a> 6.3. Sandbox Node Implementation The Sandbox Node is designed to provide a simplified environment for testing and debugging core functionalities without the complexity of a full P2P network or distributed consensus. The sandbox allows developers to run multiple instances of the node on a single machine, simulating a networked environment, but without the overhead of actual network communication. The sandbox focuses on the core components, such as UTXO management, transaction execution, and zero-knowledge proof handling. It’s ideal for rapid prototyping and ensuring core modules work as expected before transitioning to the more complex Full Node. #### <div id="storage2"></a> 6.3.1. In-Memory Storage - UTXO Storage: We can use a 'hashmap' where the key is the UTXO ID, and the value is the UTXO itself. This allows for quick lookup, addition, and deletion of UTXOs. - Nullifier Storage: Use a 'hashset' to store nullifiers, ensuring that spent UTXOs cannot be reused. ```rust use std::collections::{HashMap, HashSet}; pub struct SandboxStorage { pub utxos: HashMap<String, UTXO>, pub nullifiers: HashSet<String>, pub blocks: Vec<Block>, } ``` #### <div id="p2p"></a> 6.3.2. Mock Peer-to-Peer Communication - Message Passing: We can use 'tokio::sync::mpsc' channels to simulate message passing between nodes. This allows transactions and blocks to be broadcast between sandbox nodes. - Simulated Latency: We can add simulated network delays using 'tokio::time::sleep' to mimic real-world network conditions. ```rust use tokio::sync::mpsc::{Sender, Receiver}; use tokio::time::{sleep, Duration}; async fn simulate_p2p(tx: Sender<Transaction>, rx: Receiver<Block>) { loop { if let Some(block) = rx.recv().await { println!("Simulated receiving block: {:?}", block); sleep(Duration::from_millis(100)).await; // Simulate processing the received block } } } async fn simulate_transaction_broadcast(tx: &Sender<Transaction>, transaction: Transaction) { println!("Simulating broadcast of transaction: {:?}", transaction); tx.send(transaction).await.unwrap(); } ``` #### <div id="sequencer2"></a> 6.3.3. Simplified Sequencer - Transaction Validation: The sequencer validates transactions (e.g., checking UTXO ownership, signatures) before including them in blocks. - Block Creation: Once a set of transactions is validated, the sequencer creates a new block and adds it to the local chain. ```rust pub struct SandboxSequencer { pub mempool: Vec<Transaction>, pub storage: SandboxStorage, } ``` #### <div id="zkvm2"></a> 6.3.4. zkVM Integration - Proof Generation: Create ZKPs for transactions using 'arkworks-rs'. - Proof Verification: Validate zk-SNARK proofs before including transactions in blocks. #### <div id="mempool2"></a> 6.3.5. Simplified Mempool - Transaction Storage: The mempool is typically implemented as a 'Vec' or 'VecDeque', which stores transactions in the order they are received. - Transaction Removal: After a transaction has been included in a block by the sequencer, it is removed from the mempool. - Simplified State: Since the mempool is local, it can share its state with the other components (sequencer, VM, and storage) without the need for complex synchronization mechanisms or consistency checks. ```rust pub struct SandboxMempool { pub transactions: Vec<Transaction>, // Pending transactions waiting to be included in a block } ```