Privacy-preserving circuit:
- Add ProgramImageClaim, letting a Deploy-created program's real image_id be
anchored to its account for privacy-circuit env::verify, with the sequencer
independently re-deriving the real image_id via get_program to authenticate
the claim (journal reconstruction, same pattern as public_actions pre-states).
- Fix compute_public_authorized_pdas and the private circuit's
resolve_authorization_and_record_bindings to use the caller's real recovered
image_id instead of bijection-guessing it from the caller's account_id, which
was wrong for Deploy-created callers.
Program storage:
- V03State::insert_program (used by both genesis's with_programs and live
ProgramDeploymentTransaction execution) now always writes the Deploy
two-account shape (ProgramData header + segment), not the legacy
PROGRAM_STORAGE_OWNER raw-elf shape. The header stays at the existing
bijection address so no dispatch-address reference needed to change; only
the segment (never a caller-facing address) moves to its PDA.
- Drop the now-redundant ProgramAlreadyExists pre-check in
ProgramDeploymentTransaction validation; PDA claiming already prevents
redeploying an account.
- Migrate remaining tests off ProgramDeploymentTransaction onto native Deploy
(sequencer_core, integration_tests' auth_transfer and block_size_limit),
adding a shared deploy_targets/deploy_transaction/encoded_tx_size helper.
Rebuild artifacts and the prebuilt test fixture for the circuit and program
storage changes.
Deploy is not intended to ever run privately, and public dispatch
already always takes the native fast-path for it, so the guest ELF
had no real execution path left. Removes lez/programs/loader's guest
binary crate, its [[bin]] wiring, programs::loader(), and the
now-pointless guest-vs-native equivalence test along with the
test-only Program::execute_for_test it depended on.
loader_core (Instruction, ProgramData, execute_deploy) stays — native
dispatch still calls it directly. Deploy is now honestly just native
dispatch logic with a program-shaped interface, not a program with a
guest binary nobody executes.
Introduces a new loader_program/loader_core crate pair implementing a
Deploy instruction that claims a program's ProgramData PDA account
(image_id, segment_number, update_auth, elf_segment), unifying
deployment with ordinary PublicTransaction dispatch instead of the
separate ProgramDeploymentTransaction path.
Measured against every real program in this repo, computing a
program's image_id inside the zkVM costs ~1,400-1,500 cycles per byte
of deployed bytecode, pushing real deployments to 500M-900M cycles
against the 32M public-execution cap (vs. ~27ms natively, since
ProgramDeploymentTransaction's equivalent check runs as a plain host
function today). To keep the unified dispatch path viable, Deploy is
special-cased in from_public_transaction: calls targeting the reserved
RESERVED_DEPLOYMENT_PROGRAM_ACCOUNT_ID run loader_core::execute_deploy
natively instead of through the interpreted guest executor, wrapped in
catch_unwind since the shared execute_deploy logic validates via
assert!/expect() like every other guest program, relying on that
boundary instead of the zkVM's own panic-to-Result conversion.
The loader guest binary is kept buildable and covered by a test that
runs it for real and asserts its output matches the native path
exactly, so the two can't silently drift apart.
ProgramInput/ProgramOutput.self_program_id/caller_program_id, and the
dispatcher's CallerData.program_id, now carry AccountId (renamed to
self_account_id/caller_account_id) instead of ProgramId. These fields
are self-reported/cross-checked dispatch bookkeeping, not RISC0 image
identity, and AccountId already crosses the guest/host boundary this
way via every pre_state.account_id.
ProgramId is now confined to what's actually image-id-keyed:
env::verify, Program.id (from compute_image_id()), and the
for_public_pda/for_private_pda derivation formulas, each recovering
the real ProgramId from AccountId via the existing bijection exactly
where needed.
Rebuilds artifacts and the prebuilt sequencer db fixture to match.
* refactor(lee): split large modules into directories and extract tests
Split state.rs, program.rs, circuit.rs, validated_state_diff.rs,
merkle_tree, and core/program.rs into module directories with separate
test files. State tests are further split into themed files (genesis,
authenticated_transfer, circuit, claiming, etc.). Extract
authenticate_public_transaction_signers helper in validated_state_diff
to remove duplicated authentication logic.
* chore: rebuild artifacts