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.
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)withn != 0is 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:
Note that
env::exittakes au8, 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!/expectfor things that are genuinely "should never happen" (malformed account data the program itself wrote, etc.). Charging full budget there is fine.