Skip to content

Ledger: automatically generates documentation for zkapps #1268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion ledger/src/generators/zkapp_command.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
//! zkApp Command Generation for Testing
//!
//! This module provides utilities for generating zkApp commands for testing purposes.
//! It includes functions to create valid and invalid zkApp transactions with various
//! configurations, account updates, and preconditions.
//!
//! The generators support:
//! - Creating arbitrary zkApp commands with configurable parameters
//! - Generating both valid and invalid transactions for testing edge cases
//! - Setting up complex account update hierarchies
//! - Testing various authorization scenarios
//! - Generating invalid preconditions for failure testing
//!
//! These generators are essential for comprehensive testing of the zkApp
//! implementation against the Mina Protocol specification.

use std::{
collections::{
hash_map::Entry::{Occupied, Vacant},
Expand Down Expand Up @@ -50,7 +66,12 @@ use super::{Failure, NotPermitedOf, Role};
// /// Value when we run `dune runtest src/lib/staged_ledger -f`
// const ACCOUNT_CREATION_FEE: Fee = Fee::from_u64(1000000000);

/// <https://github.com/MinaProtocol/mina/blob/2ff0292b637684ce0372e7b8e23ec85404dc5091/src/lib/mina_generators/zkapp_command_generators.ml#L443>
/// Generates invalid protocol state preconditions for testing failure cases.
///
/// This function creates preconditions that are guaranteed to fail validation
/// against the current protocol state, allowing testing of zkApp rejection scenarios.
///
/// Reference: <https://github.com/MinaProtocol/mina/blob/2ff0292b637684ce0372e7b8e23ec85404dc5091/src/lib/mina_generators/zkapp_command_generators.ml#L443>
fn gen_invalid_protocol_state_precondition(psv: &ProtocolStateView) -> ZkAppPreconditions {
enum Tamperable {
BlockchainLength,
Expand Down Expand Up @@ -1312,16 +1333,30 @@ fn gen_fee_payer(
}
}

/// Parameters for generating zkApp commands in tests.
///
/// This struct contains all the configuration needed to generate
/// realistic zkApp commands for testing various scenarios.
pub struct GenZkappCommandParams<'a> {
/// Global slot for the transaction (affects timing preconditions)
pub global_slot: Option<Slot>,
/// Optional failure mode to generate invalid transactions
pub failure: Option<&'a Failure>,
/// Maximum number of account updates to generate
pub max_account_updates: Option<usize>,
/// Maximum number of token-related updates to generate
pub max_token_updates: Option<usize>,
/// Keypair for the fee payer account
pub fee_payer_keypair: &'a Keypair,
/// Map of public keys to keypairs for signing
pub keymap: &'a HashMap<HashableCompressedPubKey, Keypair>,
/// Optional table tracking account states across generations
pub account_state_tbl: Option<&'a mut HashMap<AccountId, (Account, Role)>>,
/// Ledger state for account lookups and modifications
pub ledger: Mask,
/// Protocol state view for precondition generation
pub protocol_state_view: Option<&'a ProtocolStateView>,
/// Optional verification key for zkApp accounts
pub vk: Option<&'a VerificationKeyWire>,
}

Expand Down
42 changes: 39 additions & 3 deletions ledger/src/scan_state/transaction_logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1224,10 +1224,20 @@ pub mod zkapp_command {
}
}

/// <https://github.com/MinaProtocol/mina/blob/2ee6e004ba8c6a0541056076aab22ea162f7eb3a/src/lib/mina_base/zkapp_basic.ml#L100>
/// Represents a field update in a zkApp account update.
///
/// This enum allows zkApp account updates to either:
/// - Set a field to a new value
/// - Keep the current value unchanged
///
/// This is used throughout zkApp account updates for optional field modifications.
///
/// Reference: <https://github.com/MinaProtocol/mina/blob/2ee6e004ba8c6a0541056076aab22ea162f7eb3a/src/lib/mina_base/zkapp_basic.ml#L100>
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SetOrKeep<T: Clone> {
/// Set the field to this new value
Set(T),
/// Keep the current value unchanged
Keep,
}

Expand Down Expand Up @@ -1879,15 +1889,28 @@ pub mod zkapp_command {
}
}

/// <https://github.com/MinaProtocol/mina/blob/2ee6e004ba8c6a0541056076aab22ea162f7eb3a/src/lib/mina_base/zkapp_precondition.ml#L977>
/// Preconditions on the protocol state that must hold for a zkApp to execute.
///
/// These preconditions allow zkApps to ensure certain blockchain state conditions
/// are met before their transaction executes. All specified conditions must be
/// satisfied or the transaction will fail.
///
/// Reference: <https://github.com/MinaProtocol/mina/blob/2ee6e004ba8c6a0541056076aab22ea162f7eb3a/src/lib/mina_base/zkapp_precondition.ml#L977>
#[derive(Debug, Clone, PartialEq)]
pub struct ZkAppPreconditions {
/// Required hash of the snarked ledger
pub snarked_ledger_hash: Hash<Fp>,
/// Required range for blockchain length
pub blockchain_length: Numeric<Length>,
/// Required range for minimum window density
pub min_window_density: Numeric<Length>,
/// Required range for total currency in circulation
pub total_currency: Numeric<Amount>,
/// Required range for global slot since genesis
pub global_slot_since_genesis: Numeric<Slot>,
/// Required conditions on staking epoch data
pub staking_epoch_data: EpochData,
/// Required conditions on next epoch data
pub next_epoch_data: EpochData,
}

Expand Down Expand Up @@ -3582,11 +3605,24 @@ pub mod zkapp_command {
pub authorization: Signature,
}

/// <https://github.com/MinaProtocol/mina/blob/2ee6e004ba8c6a0541056076aab22ea162f7eb3a/src/lib/mina_base/zkapp_command.ml#L959>
/// A zkApp command represents a complete zkApp transaction.
///
/// This contains all the information needed to execute a zkApp transaction:
/// - The fee payer who pays transaction fees and signs the transaction
/// - A forest of account updates to be applied atomically
/// - An optional memo for the transaction
///
/// The account updates are processed in a specific order using a call stack,
/// ensuring that permissions and authorization are properly enforced.
///
/// Reference: <https://github.com/MinaProtocol/mina/blob/2ee6e004ba8c6a0541056076aab22ea162f7eb3a/src/lib/mina_base/zkapp_command.ml#L959>
#[derive(Debug, Clone, PartialEq)]
pub struct ZkAppCommand {
/// Account that pays fees and provides base authorization
pub fee_payer: FeePayer,
/// Tree of account updates to be processed
pub account_updates: CallForest<AccountUpdate>,
/// Optional memo attached to the transaction
pub memo: Memo,
}

Expand Down
56 changes: 56 additions & 0 deletions ledger/src/zkapps/intefaces.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
//! zkApp Application Interfaces
//!
//! This module defines the trait interfaces that abstract over the different
//! implementations of zkApp processing (SNARK vs non-SNARK modes).
//!
//! The interfaces follow the Mina Protocol zkApp specification and provide
//! clean abstractions for:
//! - Witness generation and constraint handling
//! - Account operations and state management
//! - Ledger operations and inclusion proofs
//! - Boolean logic and arithmetic operations
//! - Authorization and permission checking
//!
//! These interfaces allow the same zkApp logic to work in both:
//! - Circuit mode: Generating constraints for SNARK proofs
//! - Non-circuit mode: Direct execution for validation

use std::marker::PhantomData;

use mina_hasher::Fp;
Expand All @@ -23,16 +40,23 @@ use crate::{
AccountId, AuthRequired, MyCow, ReceiptChainHash, TokenId, ZkAppAccount,
};

/// Core trait for witness generation in zkApp circuits.
///
/// This trait abstracts the process of generating witnesses (private inputs)
/// for the zkApp circuit. In circuit mode, this tracks variables and adds
/// constraints. In non-circuit mode, this is essentially a no-op.
pub trait WitnessGenerator<F: FieldWitness>
where
Self: Sized,
{
type Bool: BoolInterface;

/// Add a value to the witness with constraint checking
fn exists<T>(&mut self, data: T) -> T
where
T: ToFieldElements<F> + Check<F>;

/// Add a value to the witness without constraint checking
fn exists_no_check<T>(&mut self, data: T) -> T
where
T: ToFieldElements<F>;
Expand Down Expand Up @@ -62,6 +86,10 @@ where
}
}

/// Handler trait for zkApp-specific operations.
///
/// This trait defines the operations that are specific to zkApp processing
/// and may have different implementations in SNARK vs non-SNARK modes.
pub trait ZkappHandler {
type Z: ZkappApplication;
type AccountUpdate: AccountUpdateInterface;
Expand Down Expand Up @@ -283,6 +311,10 @@ where
type StackFrame: StackFrameInterface;
}

/// Interface for global blockchain state operations.
///
/// This trait provides access to global state that persists across
/// zkApp command processing, including ledger states and fee tracking.
pub trait GlobalStateInterface {
type Ledger;
type W: WitnessGenerator<Fp>;
Expand Down Expand Up @@ -329,6 +361,11 @@ pub trait LocalStateInterface {
fn add_new_failure_status_bucket(local: &mut zkapp_logic::LocalState<Self::Z>);
}

/// Interface for zkApp account updates.
///
/// An account update represents a single modification to an account
/// within a zkApp transaction. This trait provides access to the
/// account update data and methods for authorization checking.
pub trait AccountUpdateInterface
where
Self: Sized,
Expand Down Expand Up @@ -406,6 +443,11 @@ pub trait TxnVersionInterface {
fn older_than_current(version: TxnVersion, w: &mut Self::W) -> Self::Bool;
}

/// Interface for boolean operations in zkApp circuits.
///
/// This trait abstracts boolean logic operations that work in both
/// circuit and non-circuit modes. In circuit mode, these operations
/// generate constraints. In non-circuit mode, they perform direct evaluation.
pub trait BoolInterface
where
Self: Sized,
Expand Down Expand Up @@ -444,6 +486,10 @@ pub trait TransactionCommitmentInterface {
) -> Fp;
}

/// Interface for account data and operations.
///
/// This trait provides access to account state and methods for
/// modifying account properties like balance, permissions, app state, etc.
pub trait AccountInterface
where
Self: Sized,
Expand Down Expand Up @@ -480,6 +526,10 @@ where
fn set_last_action_slot(&mut self, slot: Self::GlobalSlot);
}

/// Interface for ledger operations in zkApp processing.
///
/// This trait provides the ledger operations needed for zkApp execution,
/// including account retrieval, modification, and inclusion proof verification.
pub trait LedgerInterface: LedgerIntf + Clone {
type W: WitnessGenerator<Fp>;
type AccountUpdate: AccountUpdateInterface;
Expand Down Expand Up @@ -574,6 +624,12 @@ pub trait BranchInterface {
F: FnOnce(&mut Self::W) -> T;
}

/// Main trait that ties together all zkApp interfaces.
///
/// This trait defines the complete type system for zkApp processing,
/// specifying all the associated types and their relationships.
/// It serves as the central abstraction that allows the same zkApp
/// logic to work in both circuit and non-circuit modes.
pub trait ZkappApplication
where
Self: Sized,
Expand Down
Loading
Loading