Skip to content

Commit 770cccd

Browse files
committed
ledger/tx-logic: document tx_partially_applied
1 parent c20a40c commit 770cccd

File tree

1 file changed

+206
-0
lines changed

1 file changed

+206
-0
lines changed

ledger/src/scan_state/transaction_logic/transaction_partially_applied.rs

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,44 @@
1+
//! Two-phase transaction application
2+
//!
3+
//! This module implements the two-phase transaction application model used in Mina.
4+
//! This approach enables efficient proof generation, particularly for zkApp commands.
5+
//!
6+
//! # Application Phases
7+
//!
8+
//! ## First Pass
9+
//!
10+
//! The first pass ([`apply_transaction_first_pass`]) performs:
11+
//! - Transaction validation (nonces, balances, permissions)
12+
//! - Fee payment
13+
//! - For zkApp commands: applies fee payer and begins account update processing
14+
//! - For other transactions: completes the entire application
15+
//! - Records the previous ledger hash
16+
//!
17+
//! ## Second Pass
18+
//!
19+
//! The second pass ([`apply_transaction_second_pass`]) performs:
20+
//! - For zkApp commands: completes account update processing and emits events/actions
21+
//! - For other transactions: simply packages the results from first pass
22+
//!
23+
//! # Key Types
24+
//!
25+
//! - [`TransactionPartiallyApplied`]: Intermediate state between passes
26+
//! - [`ZkappCommandPartiallyApplied`]: zkApp-specific intermediate state
27+
//! - [`FullyApplied`]: Wrapper for non-zkApp transactions that complete in first pass
28+
//!
29+
//! # Fee Transfers and Coinbase
30+
//!
31+
//! Fee transfers and coinbase transactions also use helper functions in this module:
32+
//! - [`apply_fee_transfer`]: Distributes fees to block producers
33+
//! - [`apply_coinbase`]: Handles block rewards and optional fee transfers
34+
//! - [`process_fee_transfer`]: Core logic for fee distribution with permission checks
35+
//!
36+
//! Both transactions have structured failure status to indicate which part failed:
37+
//! - Single transfer: `[[failure]]`
38+
//! - Two transfers both fail: `[[failure1]; [failure2]]`
39+
//! - First succeeds, second fails: `[[]; [failure2]]`
40+
//! - First fails, second succeeds: `[[failure1]; []]`
41+
142
use super::{
243
transaction_applied::{CoinbaseApplied, FeeTransferApplied},
344
*,
@@ -46,6 +87,106 @@ where
4687
}
4788
}
4889

90+
/// Applies the first pass of transaction application.
91+
///
92+
/// This function performs the initial phase of transaction processing, which includes
93+
/// validation, fee payment, and partial application. The behavior differs based on
94+
/// transaction type:
95+
///
96+
/// # Transaction Type Handling
97+
///
98+
/// - **Signed Commands** (payments, stake delegations): Fully applied in the first pass.
99+
/// The result is wrapped in [`FullyApplied`] since no second pass work is needed.
100+
///
101+
/// - **zkApp Commands**: Partially applied. The first pass:
102+
/// - Validates the zkApp command structure and permissions
103+
/// - Applies the fee payer account update
104+
/// - Begins processing the first phase of account updates
105+
/// - Records intermediate state in [`ZkappCommandPartiallyApplied`]
106+
///
107+
/// - **Fee Transfers**: Fully applied in the first pass, distributing fees to block
108+
/// producers according to the protocol rules.
109+
///
110+
/// - **Coinbase**: Fully applied in the first pass, crediting block rewards and any
111+
/// associated fee transfers to the designated accounts.
112+
///
113+
/// # Ledger State Changes
114+
///
115+
/// The ledger is mutated during the first pass as follows:
116+
///
117+
/// - **Signed Commands**:
118+
/// - Fee payer balance decreased by fee amount
119+
/// - Fee payer nonce incremented
120+
/// - Fee payer receipt chain hash updated
121+
/// - Fee payer timing updated based on vesting schedule
122+
/// - For payments: sender balance decreased, receiver balance increased
123+
/// - For payments: new account created if receiver doesn't exist
124+
/// - For stake delegations: delegate field updated
125+
///
126+
/// - **zkApp Commands**:
127+
/// - Fee payer account fully updated (balance, nonce, receipt chain, timing)
128+
/// - First phase account updates applied to ledger
129+
/// - New accounts may be created
130+
///
131+
/// - **Fee Transfers**:
132+
/// - Receiver account balances increased by fee amounts
133+
/// - Timing updated when balances increase
134+
/// - New accounts created if receivers don't exist
135+
///
136+
/// - **Coinbase**:
137+
/// - Block producer balance increased by reward amount
138+
/// - Fee transfer recipient balance increased (if applicable)
139+
/// - Timing updated when balances increase
140+
/// - New accounts created if recipients don't exist
141+
///
142+
/// # Parameters
143+
///
144+
/// - `constraint_constants`: Protocol constants including account creation fees and limits
145+
/// - `global_slot`: Current global slot number for timing validation
146+
/// - `txn_state_view`: View of the protocol state for validating transaction preconditions
147+
/// - `ledger`: Mutable reference to the ledger being updated
148+
/// - `transaction`: The transaction to apply
149+
///
150+
/// # Returns
151+
///
152+
/// Returns a [`TransactionPartiallyApplied`] containing either:
153+
/// - [`FullyApplied`] result for transactions that complete in first pass
154+
/// - [`ZkappCommandPartiallyApplied`] for zkApp commands needing second pass
155+
///
156+
/// # Errors
157+
///
158+
/// Returns an error if:
159+
/// - Transaction validation fails (invalid nonce, insufficient balance, etc.)
160+
/// - Fee payment fails
161+
/// - Account permissions are insufficient
162+
/// - Timing constraints are violated
163+
///
164+
/// ## Error Side Effects
165+
///
166+
/// When an error occurs, the ledger state depends on where the error occurred:
167+
///
168+
/// - **Errors during fee payment** (invalid nonce, nonexistent fee payer): Ledger
169+
/// remains completely unchanged.
170+
///
171+
/// - **Errors after fee payment** (insufficient balance for payment, permission
172+
/// errors): The fee has already been charged to ensure network compensation. The
173+
/// fee payer's account will have: balance decreased by fee, nonce incremented,
174+
/// receipt chain hash updated. However, the actual payment/operation is NOT
175+
/// performed.
176+
///
177+
/// # Tests
178+
///
179+
/// Test coverage (in `ledger/tests/test_transaction_logic_first_pass.rs`):
180+
///
181+
/// - [`test_apply_payment_success`]: successful payment with ledger state verification
182+
/// - [`test_apply_payment_insufficient_balance`]: payment exceeding sender balance
183+
/// - [`test_apply_payment_invalid_nonce`]: payment with incorrect nonce
184+
/// - [`test_apply_payment_nonexistent_fee_payer`]: payment from nonexistent account
185+
///
186+
/// [`test_apply_payment_success`]: ../../tests/test_transaction_logic_first_pass.rs
187+
/// [`test_apply_payment_insufficient_balance`]: ../../tests/test_transaction_logic_first_pass.rs
188+
/// [`test_apply_payment_invalid_nonce`]: ../../tests/test_transaction_logic_first_pass.rs
189+
/// [`test_apply_payment_nonexistent_fee_payer`]: ../../tests/test_transaction_logic_first_pass.rs
49190
pub fn apply_transaction_first_pass<L>(
50191
constraint_constants: &ConstraintConstants,
51192
global_slot: Slot,
@@ -108,6 +249,71 @@ where
108249
}
109250
}
110251

252+
/// Completes the second pass of transaction application.
253+
///
254+
/// This function finalizes transaction processing by completing any remaining work
255+
/// from the first pass. The behavior differs based on transaction type:
256+
///
257+
/// # Transaction Type Handling
258+
///
259+
/// - **Signed Commands**: No additional work needed. Simply unwraps the [`FullyApplied`]
260+
/// result from the first pass and packages it into a [`TransactionApplied`].
261+
///
262+
/// - **zkApp Commands**: Completes the second phase of application:
263+
/// - Processes the second phase of account updates
264+
/// - Emits events and actions from the zkApp execution
265+
/// - Updates the zkApp's on-chain state
266+
/// - Validates all preconditions are satisfied
267+
///
268+
/// - **Fee Transfers**: No additional work needed. Simply packages the first pass result.
269+
///
270+
/// - **Coinbase**: No additional work needed. Simply packages the first pass result.
271+
///
272+
/// # Ledger State Changes
273+
///
274+
/// The ledger is mutated during the second pass only for zkApp commands:
275+
///
276+
/// - **Signed Commands**: No ledger changes (all modifications completed in first pass)
277+
///
278+
/// - **zkApp Commands**:
279+
/// - Second phase account updates applied
280+
/// - Account balances modified based on zkApp logic
281+
/// - Account app state fields updated
282+
/// - Account permissions may be modified
283+
/// - Action state and event sequence numbers updated
284+
/// - New accounts may be created
285+
///
286+
/// - **Fee Transfers**: No ledger changes (all modifications completed in first pass)
287+
///
288+
/// - **Coinbase**: No ledger changes (all modifications completed in first pass)
289+
///
290+
/// # Parameters
291+
///
292+
/// - `constraint_constants`: Protocol constants including account creation fees and limits
293+
/// - `ledger`: Mutable reference to the ledger being updated
294+
/// - `partial_transaction`: The partially applied transaction from the first pass
295+
///
296+
/// # Returns
297+
///
298+
/// Returns a [`TransactionApplied`] containing the complete application result with:
299+
/// - Previous ledger hash (recorded during first pass)
300+
/// - Full transaction status (Applied or Failed with specific error codes)
301+
/// - Account updates and new account information
302+
/// - Events and actions (for zkApp commands)
303+
///
304+
/// # Errors
305+
///
306+
/// Returns an error if:
307+
/// - Second phase zkApp account updates fail
308+
/// - zkApp preconditions fail during second pass
309+
/// - Account permissions are insufficient
310+
///
311+
/// # Notes
312+
///
313+
/// For non-zkApp transactions, this function performs minimal work since the first
314+
/// pass already completed the application. The two-phase model exists primarily to
315+
/// enable efficient zkApp proof generation where different account updates can be
316+
/// processed in separate circuit phases.
111317
pub fn apply_transaction_second_pass<L>(
112318
constraint_constants: &ConstraintConstants,
113319
ledger: &mut L,

0 commit comments

Comments
 (0)