From d2b44adeb30e239e8881dee13bbd12e6c1527752 Mon Sep 17 00:00:00 2001 From: moana Date: Mon, 23 Dec 2024 16:15:28 +0100 Subject: [PATCH 1/2] vm: Add code documentation --- vm/src/execute.rs | 34 ++++++++-- vm/src/host_queries.rs | 138 ++++++++++++++++++++++++++++++++++++----- vm/src/lib.rs | 132 ++++++++++++++++++++++++++++++++------- 3 files changed, 262 insertions(+), 42 deletions(-) diff --git a/vm/src/execute.rs b/vm/src/execute.rs index 6d6900e06a..0ea09ee9f1 100644 --- a/vm/src/execute.rs +++ b/vm/src/execute.rs @@ -11,8 +11,12 @@ use dusk_core::transfer::{ }; use piecrust::{CallReceipt, Error, Session}; -/// Executes a transaction, returning the receipt of the call and the gas spent. -/// The following steps are performed: +/// Executes a transaction in the provided session. +/// +/// This function processes the transaction, invoking smart contracts or +/// updating state. +/// +/// During the execution the following steps are performed: /// /// 1. Check if the transaction contains contract deployment data, and if so, /// verifies if gas limit is enough for deployment and if the gas price is @@ -45,6 +49,19 @@ use piecrust::{CallReceipt, Error, Session}; /// related to deployment, as it is either discarded or it charges the /// full gas limit. It might be re-executed only if some other transaction /// failed to fit the block. +/// +/// # Arguments +/// * `session` - A mutable reference to the session executing the transaction. +/// * `tx` - The transaction to execute. +/// * `gas_per_deploy_byte` - The amount of gas points charged for each byte in +/// a contract-deployment bytecode. +/// * `min_deploy_points` - The minimum gas points charged for a contract +/// deployment. +/// * `min_deploy_gas_price` - The minimum gas price set for a contract +/// deployment +/// +/// # Returns +/// A result indicating success or failure. pub fn execute( session: &mut Session, tx: &Transaction, @@ -176,10 +193,15 @@ fn verify_bytecode_hash(bytecode: &ContractBytecode) -> bool { bytecode.hash == computed } -/// Generate a [`ContractId`] address from: -/// - slice of bytes, -/// - nonce -/// - owner +/// Generates a unique identifier for a smart contract. +/// +/// # Arguments +/// * 'bytes` - The contract bytecode. +/// * `nonce` - A unique nonce. +/// * `owner` - The contract-owner. +/// +/// # Returns +/// A unique [`ContractId`]. /// /// # Panics /// Panics if [blake2b-hasher] doesn't produce a [`CONTRACT_ID_BYTES`] diff --git a/vm/src/host_queries.rs b/vm/src/host_queries.rs index 424812efed..7a3a9a1e58 100644 --- a/vm/src/host_queries.rs +++ b/vm/src/host_queries.rs @@ -29,22 +29,66 @@ use rkyv::{Archive, Deserialize, Serialize}; use crate::cache; -/// Compute the blake2b hash of the given scalars, returning the resulting -/// scalar. The hash is computed in such a way that it will always return a -/// valid scalar. +/// Computes a cryptographic hash of a byte vector. +/// +/// This function uses the BLS12-381 scalar field to generate a deterministic +/// hash from the provided byte array. The result is a [`BlsScalar`], making it +/// suitable for cryptographic operations like zero-knowledge proofs and digital +/// signatures. +/// +/// # Arguments +/// * `bytes` - A vector of bytes representing the input data to be hashed. +/// +/// # Returns +/// A [`BlsScalar`] representing the cryptographic hash of the input bytes. +/// +/// # References +/// For more details about BLS12-381 and its scalar operations, refer to: +/// . pub fn hash(bytes: Vec) -> BlsScalar { BlsScalar::hash_to_scalar(&bytes[..]) } -/// Compute the poseidon hash of the given scalars +/// Computes the Poseidon hash of a vector of scalar values. +/// +/// This function uses the Poseidon252 hashing algorithm to produce a +/// cryptographic hash. Poseidon is designed for efficiency in zk-SNARK +/// applications and operates over finite fields, making it well-suited for +/// blockchain and cryptographic use cases. +/// +/// # Arguments +/// * `scalars` - A vector of [`BlsScalar`] values to be hashed. The input +/// values represent the data to be hashed into a single scalar output. +/// +/// # Returns +/// A [`BlsScalar`] representing the Poseidon hash of the input values. +/// +/// # References +/// For more details about Poseidon and its implementation, refer to: +/// . pub fn poseidon_hash(scalars: Vec) -> BlsScalar { PoseidonHash::digest(Domain::Other, &scalars)[0] } -/// Verify a Plonk proof is valid for a given circuit type and public inputs +/// Verifies a PLONK zero-knowledge proof. +/// +/// This function verifies a proof generated by a PLONK proving system. It takes +/// in the verifier's key data, the proof itself, and the public inputs required +/// for verification. PLONK is a highly-efficient proof system used in +/// zk-SNARKs. +/// +/// # Arguments +/// * `verifier_data` - A serialized representation of the verifier key. +/// * `proof` - A serialized representation of the proof to be verified. +/// * `public_inputs` - A vector of [`BlsScalar`] representing the public inputs +/// for the proof. /// -/// # Panics -/// This will panic if `verifier_data` or `proof` are not valid. +/// # Returns +/// A boolean indicating whether the proof is valid (`true`) or invalid +/// (`false`). +/// +/// # References +/// . pub fn verify_plonk( verifier_data: Vec, proof: Vec, @@ -57,13 +101,24 @@ pub fn verify_plonk( verifier.verify(&proof, &public_inputs[..]).is_ok() } -/// Verify that a Groth16 proof in the BN254 pairing is valid for a given -/// circuit and inputs. +/// Verifies a Groth16 zk-SNARK proof over the BN254 curve. +/// +/// This function verifies a proof generated using the Groth16 proving system. +/// It takes in the prepared verifying key, the proof itself, and the public +/// inputs. +/// +/// # Arguments +/// * `pvk` - A serialized representation of the prepared verifying key. +/// * `proof` - A serialized representation of the Groth16 proof. +/// * `inputs` - A serialized vector of public inputs for the proof. /// -/// `proof` and `inputs` should be in compressed form, while `pvk` uncompressed. +/// # Returns +/// A boolean indicating whether the proof is valid (`true`) or invalid +/// (`false`). /// -/// # Panics -/// This will panic if `pvk`, `proof` or `inputs` are not valid. +/// # References +/// For more details about Groth16 and its implementation, refer to: +/// . pub fn verify_groth16_bn254( pvk: Vec, proof: Vec, @@ -80,7 +135,24 @@ pub fn verify_groth16_bn254( .expect("verifying proof should succeed") } -/// Verify a schnorr signature is valid for the given public key and message +/// Verifies a Schnorr signature. +/// +/// This function verifies a Schnorr signature using the Jubjub elliptic curve. +/// It takes in the message, the public key of the signer, and the signature to +/// verify the validity of the signature. +/// +/// # Arguments +/// * `msg` - A [`BlsScalar`] representing the hashed message. +/// * `pk` - A [`SchnorrPublicKey`] representing the signer's public key. +/// * `sig` - A [`SchnorrSignature`] representing the signature to be verified. +/// +/// # Returns +/// A boolean indicating whether the signature is valid (`true`) or invalid +/// (`false`). +/// +/// # References +/// For more details about Schnorr signatures and their implementation, refer +/// to: . pub fn verify_schnorr( msg: BlsScalar, pk: SchnorrPublicKey, @@ -89,12 +161,48 @@ pub fn verify_schnorr( pk.verify(&sig, msg).is_ok() } -/// Verify a BLS signature is valid for the given public key and message +/// Verifies a BLS signature. +/// +/// This function verifies a BLS signature using the BLS12-381 elliptic curve. +/// It takes in the message, the signer's public key, and the signature to +/// validate the integrity of the signed data. +/// +/// # Arguments +/// * `msg` - A vector of bytes representing the original message. +/// * `pk` - A [`BlsPublicKey`] representing the signer's public key. +/// * `sig` - A [`BlsSignature`] representing the signature to be verified. +/// +/// # Returns +/// A boolean indicating whether the signature is valid (`true`) or invalid +/// (`false`). +/// +/// # References +/// For more details about BLS signatures and their implementation, refer to: +/// . pub fn verify_bls(msg: Vec, pk: BlsPublicKey, sig: BlsSignature) -> bool { pk.verify(&sig, &msg).is_ok() } -/// Verify a BLS signature is valid for the given public key and message +/// Verifies a BLS multi-signature. +/// +/// This function verifies a multi-signature created using the BLS signature +/// scheme over the BLS12-381 elliptic curve. It validates the integrity of the +/// message signed by multiple participants. +/// +/// # Arguments +/// * `msg` - A vector of bytes representing the original message. +/// * `keys` - A vector of [`BlsPublicKey`] instances representing the +/// participants' public keys. +/// * `sig` - A [`MultisigSignature`] representing the combined multi-signature +/// to be verified. +/// +/// # Returns +/// A boolean indicating whether the multi-signature is valid (`true`) or +/// invalid (`false`). +/// +/// # References +/// For more details about BLS multi-signatures and their implementation, refer +/// to: . pub fn verify_bls_multisig( msg: Vec, keys: Vec, diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 444c1fb2bc..85594729a3 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -36,8 +36,12 @@ pub(crate) mod cache; mod execute; pub mod host_queries; -/// Dusk VM is a [`PiecrustVM`] enriched with the host functions specified in -/// Dusk's ABI. +/// The Virtual Machine (VM) for executing smart contracts in the Dusk Network. +/// +/// The `VM` struct serves as the core for managing the network's state, +/// executing smart contracts, and interfacing with host functions. It supports +/// both persistent and ephemeral sessions for handling transactions, contract +/// queries and contract deployments. pub struct VM(PiecrustVM); impl From for VM { @@ -53,14 +57,28 @@ impl Debug for VM { } impl VM { - /// Creates a new `VM`, reading the given directory for existing commits - /// and bytecode. + /// Creates a new instance of the virtual machine. /// - /// The directory will be used to save any future session commits made by - /// this `VM` instance. + /// This method initializes the VM with a given root directory and + /// registers the necessary host-queries for contract execution. + /// + /// # Arguments + /// * `root_dir` - The path to the root directory for the VM's state + /// storage. This directory will be used to save any future session + /// commits made by this `VM` instance. + /// + /// # Returns + /// A new `VM` instance. /// /// # Errors /// If the directory contains unparseable or inconsistent data. + /// + /// # Examples + /// ```rust + /// use dusk_vm::VM; + /// + /// let vm = VM::new("/path/to/root_dir"); + /// ``` pub fn new( root_dir: impl AsRef + Into, ) -> Result { @@ -69,26 +87,69 @@ impl VM { Ok(vm) } - /// Creates a new `VM` using a new temporary directory. + /// Creates an ephemeral VM instance. /// - /// Any session commits made by this machine should be considered discarded - /// once this `VM` instance drops. + /// This method initializes a VM that operates in memory without persisting + /// state. It is useful for testing or temporary computations. + /// + /// # Returns + /// A new ephemeral `VM` instance. /// /// # Errors /// If creating a temporary directory fails. + /// + /// # Examples + /// ```rust + /// use dusk_vm::VM; + /// + /// let vm = VM::ephemeral(); + /// ``` pub fn ephemeral() -> Result { let mut vm: Self = PiecrustVM::ephemeral()?.into(); vm.register_host_queries(); Ok(vm) } - /// Spawn a [`Session`] on top of the given `commit`, given the `chain_id` - /// and `block_height`. + /// Creates a new session for transaction execution. + /// + /// This method initializes a session with a specific base state commit, + /// chain identifier, and block height. Sessions allow for isolated + /// transaction execution without directly affecting the persistent VM + /// state until finalized. + /// + /// # Arguments + /// * `base` - A 32-byte array representing the base state from which the + /// session begins. + /// * `chain_id` - The identifier of the network. + /// * `block_height` - The current block height at which the session is + /// created. + /// + /// # Returns + /// A `Result` containing a `Session` instance for executing transactions, + /// or an error if the session cannot be initialized. /// /// # Errors /// If base commit is provided but does not exist. /// - /// [`Session`]: Session + /// # Examples + /// ```rust + /// use dusk_vm::VM; + /// + /// const CHAIN_ID: u8 = 42; + /// + /// // create a genesis session + /// let vm = VM::ephemeral().unwrap(); + /// let session = vm.genesis_session(CHAIN_ID); + /// + /// // [...] apply changes to the network through the running session + /// + /// // commit the changes + /// let base = session.commit().unwrap(); + /// + /// // spawn a new session on top of the base-commit + /// let block_height = 21; + /// let session = vm.session(base, CHAIN_ID, block_height).unwrap(); + /// ``` pub fn session( &self, base: [u8; 32], @@ -103,8 +164,28 @@ impl VM { ) } - /// Spawn a new genesis-[`Session`] given the `chain_id` with a - /// `block_height` of 0. + /// Initializes a session for setting up the genesis block. + /// + /// This method creates a session specifically for defining the genesis + /// block, which serves as the starting state of the network. The + /// genesis session uses the specified chain ID. + /// + /// # Arguments + /// * `chain_id` - The identifier of the blockchain chain for which the + /// genesis state is initialized. + /// + /// # Returns + /// A `Session` instance for defining the genesis block. + /// + /// # Examples + /// ```rust + /// use dusk_vm::VM; + /// + /// const CHAIN_ID: u8 = 42; + /// + /// let vm = VM::ephemeral().unwrap(); + /// let genesis_session = vm.genesis_session(CHAIN_ID); + /// ``` pub fn genesis_session(&self, chain_id: u8) -> Session { self.0 .session( @@ -119,28 +200,37 @@ impl VM { .expect("Creating a genesis session should always succeed") } - /// Return all existing commits. + /// Retrieves all pending commits in the VM. + /// + /// This method fetches unfinalized state changes for inspection or + /// processing. + /// + /// # Returns + /// A vector of commits. pub fn commits(&self) -> Vec<[u8; 32]> { self.0.commits() } - /// Deletes the given commit from disk. + /// Deletes a specified commit from the VM. + /// + /// # Arguments + /// * `commit` - The commit to be deleted. pub fn delete_commit(&self, root: [u8; 32]) -> Result<(), Error> { self.0.delete_commit(root) } - /// Finalizes the given commit on disk. + /// Finalizes a specified commit, applying its state changes permanently. + /// + /// # Arguments + /// * `commit` - The commit to be finalized. pub fn finalize_commit(&self, root: [u8; 32]) -> Result<(), Error> { self.0.finalize_commit(root) } - /// Return the root directory of the virtual machine. + /// Returns the root directory of the VM. /// /// This is either the directory passed in by using [`new`], or the /// temporary directory created using [`ephemeral`]. - /// - /// [`new`]: VM::new - /// [`ephemeral`]: VM::ephemeral pub fn root_dir(&self) -> &Path { self.0.root_dir() } From df203e4c951bb0e7084edea9c7ebec693838482c Mon Sep 17 00:00:00 2001 From: moana Date: Mon, 23 Dec 2024 16:16:08 +0100 Subject: [PATCH 2/2] vm: Add Readme --- vm/README.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/vm/README.md b/vm/README.md index ad121e6e4a..3e42a1af5b 100644 --- a/vm/README.md +++ b/vm/README.md @@ -2,8 +2,31 @@ [![Repository](https://img.shields.io/badge/github-rusk--abi-blueviolet?logo=github)](https://github.com/dusk-network/dusk-vm) [![Documentation](https://img.shields.io/badge/docs-rusk--abi-blue?logo=rust)](https://docs.rs/dusk-vm/) -## Dusk VM +# Dusk VM -The VM to execute smart contracts on the Dusk network. +The Dusk VM is a virtual machine designed for **Dusk**, enabling secure and efficient execution of smart contracts, state transitions, and cryptographic operations tailored for zero-knowledge-based applications. + +It serves as the execution engine of the Dusk Blockchain, leveraging advanced cryptographic primitives and frameworks to support privacy-preserving, compliant and scalable decentralized applications. + +## Features + +- **State Management**: Manage blockchain state using sessions for isolated transaction execution and finalization. +- **Cryptographic Support**: Offers built-in support for hashing (Poseidon), signature verification (BLS, Schnorr), and proof validation (PLONK, Groth16). +- **Virtual Machine for zk-SNARK Applications**: Optimized for privacy-preserving computations. + +## Installation + +Add `dusk-vm` to your `Cargo.toml`: + +```toml +[dependencies] +dusk-vm = "0.x" # Replace with the latest version +``` + +## Documentation + +For detailed usage and API examples, refer to the [crate documentation on docs.rs](https://docs.rs/dusk-vm/). + +## License License: MPL-2.0