Skip to content

Fail via env::exit(code) instead of panicking so reverts are metered correctly #356

Description

@erhant

LEZ will soon support handling non-zero exit codes from the guest program (see logos-blockchain/logos-execution-zone#837).

Right now, all programs fail by panicking; a guest panic bails out of the zkVM executor and drops the session, so the host does not learn how many cycles ran and charges the transaction its full declared gas_limit. We would instead like to charge for the consumed cycles (like how EVM works in reverted tx'es).

With the LEZ change, a program that fails via risc0_zkvm::guest::env::exit(n) with n != 0 is treated as a revert exactly like a panic (state discarded, nonce advanced, fee charged) but now that the executor keeps the session, the payer is charged the cycles that were actually metered rather than the whole budget.

We should replace panic-based failures on expected error paths with a non-zero exit:

// before
let new_balance = sender.balance.checked_sub(amount).expect("Insufficient balance");

// after
let Some(new_balance) = sender.balance.checked_sub(amount) else {
    env::exit(ERR_INSUFFICIENT_BALANCE);
};

Note that env::exit takes a u8, so error codes are 1..=255. A small per-program enum / consts module is enough; there is no cross-program registry.

We can keep panic!/expect for things that are genuinely "should never happen" (malformed account data the program itself wrote, etc.). Charging full budget there is fine.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions