Skip to content

Transaction Execution

View as Markdown

Transaction execution in Thru follows a structured four-phase pipeline that ensures consistency, security, and resource management. Each phase has specific responsibilities and failure conditions.

  1. Transaction Validation

    This phase occurs before a transaction can be included in a block. Validation failures result in invalid blocks and consensus rejection.

    Signature Verification

    • Transaction signature must be valid for the fee payer’s public key
    • Ed25519 signature verification on transaction payload

    Account Structure Validation

    • Account addresses must be properly sorted (read-write accounts in ascending order, then read-only accounts in ascending order - see transaction format)
    • No duplicate account addresses across any account lists
    • Total account count must not exceed TN_TXN_MAX_ACCOUNTS limit
    • Fee payer and program accounts must be distinct

    Transaction Format Validation

    • Transaction version must be supported
    • Transaction flags must be valid
    • Transaction size must not exceed MTU limits
  2. Pre-Execution

    Pre-execution prepares the transaction context and performs economic checks. If any pre-execution check fails, the transaction is rejected and VM execution does not occur. Even so, some state changes (nonce advancement, fee collection) may occur during this phase that do persist.

    Temporal Validation

    • Current block slot must be ≥ transaction’s start_slot
    • Current block slot must be < transaction’s expiry_slot

    Fee Payer Account Setup

    • Fee payer account must exist or be created with a valid state proof
    • State proof validation (if present):
      • Cryptographic proof verification against current state root
      • Proof type must be CREATION or EXISTING
      • Proof path must represent valid Merkle tree path

    Nonce Processing

    • Transaction nonce must exactly match fee payer’s current nonce
    • Nonce is advanced immediately upon validation

    Fee Processing

    • Fee payer balance must be sufficient for transaction fee
    • Transaction fee is collected after nonce advancement
  3. VM Execution

    The virtual machine executes the transaction’s program with strict resource limits and safety constraints.

    Program Validation

    • Program account must exist and be marked as executable
    • Program data must be valid bytecode

    Resource Constraints

    • Compute Units: Execution must not exceed requested_compute_units (see compute units)
    • Memory: VM memory access must stay within allocated segments

    VM Execution Environment

    • Program runs in isolated VM with segmented memory (tn_vm_base.h:TN_VM_SEG_*)
    • System calls provide controlled access to accounts and blockchain state
    • Execution can terminate with success or various fault conditions:
      • TN_VM_SUCCESS: Normal completion
      • TN_VM_FAULT_REVERT: Program-initiated revert
      • TN_VM_FAULT_SIGCU: Compute units exhausted
      • TN_VM_FAULT_SIGSU: State units exhausted

    State Unit Calculation State units are computed based on account data size changes:

    state_bytes_net = max(0, bytes_added - bytes_removed)
    state_units_consumed = ceil(state_bytes_net / TN_RUNTIME_PAGE_SZ)
  4. Post-Execution

    Post-execution finalizes state changes and handles compressed account proofs.

    State Unit Validation

    • State Units: After VM execution, state size changes are calculated and must not exceed requested_state_units (see state units)
    • Transactions that exceed state unit limits are failed with TN_VM_FAULT_SIGSU

    State Finalization

    • Account state changes are committed to storage if execution succeeded
    • Failed executions preserve nonce advancement and fee collection only

    Account Compression Processing

    • Accounts that are compressed during execution are removed from the active state set

The execution result includes:

  • execution_result: VM exit code
  • compute_units_consumed: Actual compute units used
  • state_units_consumed: State units consumed by account changes
  • user_error_code: Program-specific error information
  • error_program_acc_idx: Account index of the program that caused the error, useful for identifying the faulting program in cross-program invocation (CPI) scenarios
  • Memory fault details (if applicable)

For detailed error codes and their descriptions, see Runtime Errors.