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.
Rebases marvin/program-as-account-2 onto the updated
marvin/program-as-account (SeenShard cap fix), regenerating program
and circuit artifacts plus the sequencer test fixture to match.
Also removes lez/wallet's now-unused base58 dependency, dead since
AccountId gained its own Display/FromStr base58 encoding.
Account.program_owner is now AccountId-typed instead of ProgramId,
via a new bijective From<ProgramId> for AccountId / From<AccountId>
for ProgramId conversion pair (pure byte reinterpretation, not a
hash - both types are exactly 32 bytes). Adds DEFAULT_PROGRAM_OWNER
as the AccountId-typed counterpart to DEFAULT_PROGRAM_ID, used at
every program_owner comparison/claim site instead of an inline
AccountId::default().
Touches every call site across lee_core, lee (including the
guest-side privacy-preserving circuit), all 16 deployed guest
programs, wallet/wallet-ffi, indexer_ffi/indexer_service/
indexer_service_protocol, sequencer_core, testnet_initial_state,
system_accounts, cross_zone, storage, cycle_bench, and
integration_tests - mostly mechanical .into() conversions, plus two
simplifications: wallet's manual base58 encode/decode of
program_owner was dead code once it's AccountId (which already has
Display/FromStr), and the FFI crates' program_owner field now reuses
the existing generic FfiBytes32 wrapper instead of the now-unused
FfiProgramId one.
Rebuilds every guest ELF artifact and the prebuilt sequencer test
fixture via just build-artifacts, since execute_and_prove runs
against the checked-in precompiled privacy_preserving_circuit.bin,
which isn't rebuilt automatically by cargo test/check.
Corrects lee/state_machine internals for the Program-as-Account migration
and fixes SeenShard::MAX_DELIVERIES, which was still calibrated for the
old 100 KiB DATA_MAX_LENGTH instead of the current 700 KiB cap. Rebuilds
program artifacts and the sequencer test fixture to match.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Every guest moved, not only the ones whose source changed: adding real
dependencies (borsh to two cores, cross_zone_inbox_core to two targets) changes
the build graph, and with it the metadata hash of every crate in the guest build.
Piece A moved only three because it added a dev-dependency, which the guest build
never sees.
* refactor: rename PrivateUnauthorized to PrivateForeignInit
The account_identity's is_authorized flag no longer determines
authorization for this variant, so keep the name tied to what
actually distinguishes it: no nsk, only npk (a foreign account init).
* chore: rebuild guest artifacts and bump spin to clear yanked advisory
Regenerate ELF artifacts after the PrivateForeignInit rename in lee_core
(compiled into every guest program), and update spin 0.9.8 -> 0.9.9 since
0.9.8 was yanked from crates.io, per cargo deny check advisories.
* test: align is_authorized with PrivateForeignInit's flipped semantics
Recipient pre-states built for PrivateForeignInit now need is_authorized:
true to match the assertion in output.rs. Also rewrites the boundary test
that checked the old invalid case to check the new one, and updates
stale "unauthorized" wording left over from the PrivateUnauthorized name.
* chore: rebuild guest artifacts
Reproducible across repeated local builds; likely toolchain drift since
the prior artifact commit rather than a source change, since no
guest-relevant source or Cargo.lock changed in between.
* fix(tests): align integration tests with PrivateForeignInit and regenerate fixture
prove_init_with_commitment_root (private.rs) and build_privacy_transaction
(tps.rs) still built PrivateForeignInit recipients with is_authorized: false,
same stale-semantics bug fixed earlier in the lee crate's own tests.
The prebuilt sequencer DB dump embeds program IDs derived from guest ELF
bytes, which shifted once the PrivateForeignInit rename changed lee_core
(compiled into every guest program). The stale dump caused widespread
"Unknown program" failures across integration test suites that exercise
deployed programs (wallet_ffi, auth_transfer, bridge, amm, token, pinata,
ata, indexer state-consistency checks). Regenerated via
`just regenerate-test-fixture`.
* fix(tests): rename leftover PrivateUnauthorized to PrivateForeignInit and regenerate fixture
* test: align is_authorized with PrivateForeignInit's flipped semantics
* chore: regenerate test fixture after rebase onto dev
* chore: regenerate test fixture after rebase onto dev
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Integrates origin/main (per-program-crate refactor) and re-homes the cross-zone messaging feature onto it.
BREAKING CHANGE: Genesis state root changes. This registers six builtin programs
(cross_zone_outbox, cross_zone_inbox, ping_sender, ping_receiver, bridge_lock,
wrapped_token) and seeds their genesis accounts (the wrapped_token authorized
minter config, the per-zone inbox config, and optional bridge-lock holdings).
Building the new cores alongside the existing builtins also enables serde/alloc
for the shared programs build, regenerating every builtin program image id. All
nodes must upgrade together.
* 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
* refactor(privacy_preserving_circuit): extract functions for readability
* refactor(privacy_preserving_circuit): address PR review comments
Bundle shared handle_* arguments into PrivateOutputHandler struct in
output.rs and fix misplaced docstring on resolve_external_seed in
execution_state.rs.
* feat: update commitment mechanism for new private account (#546)
* refactor(privacy_preserving_circuit): extract functions for readability
* feat: update commitment mechanism for new private accounts
Allow init accounts to optionally use a real membership proof for
DUMMY_COMMITMENT instead of hardcoding DUMMY_COMMITMENT_HASH as the
CommitmentSetDigest. The wallet fetches the proof from the sequencer
and passes it through the circuit.
* fix: address clippy lints and fix integration test visibility
* add tests
* refactor: removed duplicated code
* refactor: simplify init nullifier mechanism
Replace Option<MembershipProof> with Option<CommitmentSetDigest> on init
variants (PrivateAuthorizedInit, PrivateUnauthorized, PrivatePdaInit).
The circuit now receives the commitment tree root directly instead of
recomputing it from a Merkle proof.
* refactor: use CommitmentSetDigest directly instead of Option for init commitment root
Address PR #546 review feedback: the circuit now accepts CommitmentSetDigest
directly on init variants (PrivateAuthorizedInit, PrivateUnauthorized,
PrivatePdaInit), with callers providing DUMMY_COMMITMENT_HASH as the default.
Also fixes duplicate resolve_external_seed from rebase and rebuilds artifacts.
* style: run cargo +nightly fmt