147 Commits
Author SHA1 Message Date
Artem Gureev 68d00d5ed0 chore(lee): clear post-migration residue and pin the remaining failure reasons 2026-08-23 15:49:18 +04:00
agureev 30db8fa2f8 chore: docs + artifacts 2026-08-23 14:29:48 +04:00
Artem Gureev f904c5f7f4 perf(lee): build journal frames in one exact-sized buffer 2026-08-23 09:35:41 +00:00
Artem Gureev df9ac94ab3 docs(lee): frame prefix counts payload bytes, not frames 2026-08-23 09:35:41 +00:00
Artem Gureev 1e913284d8 refactor(lee): replace LeeInputHeader with ProgramInput<InstructionData> 2026-08-23 09:35:41 +00:00
agureev cce1753bb0 docs: reformat 2026-08-23 09:35:41 +00:00
Artem Gureev c09b1ed778 test(lee): assert failure reasons in should-fail proving tests 2026-08-23 09:35:41 +00:00
Artem Gureev 4683dbb0f4 test(lee): pin public message hash with non-empty instruction data 2026-08-23 09:35:41 +00:00
Artem Gureev 6c8170042c test(lee): cover journal frame byte-equality, instruction echo, and malformed frames 2026-08-23 09:35:41 +00:00
Artem Gureev 1e52f6a694 fix(lee): propagate malformed circuit journal frame instead of panicking 2026-08-23 09:35:41 +00:00
Artem Gureev 695ebf439d chore: prune unused serde/risc0-zkvm deps after borsh migration 2026-08-23 09:35:41 +00:00
agureev cf36a7dec9 chore: fmt + artifacts 2026-08-23 09:35:41 +00:00
Artem Gureev 5a3edc3c10 test(lee): pass exact-typed instructions to strict-decode failure tests 2026-08-23 09:35:41 +00:00
Artem Gureev 75543534ee fix(lee): clear pre-existing clippy lints in journal-frame code (from_frame doc, to_owned) 2026-08-23 09:35:41 +00:00
Artem Gureev 12dabb9341 refactor: rename remaining instruction_words to instruction_data across programs, tests, tools, ffi 2026-08-23 09:35:41 +00:00
Artem Gureev 3010d1f7a5 refactor(lee): make Program::write_inputs take &self for program identity 2026-08-23 09:35:23 +00:00
Artem Gureev 26ae1c1598 docs(lee): correct LeeInputHeader doc to borsh instruction decoding 2026-08-23 09:35:23 +00:00
Artem Gureev 9cc22d2e7d fix(lee): reject malformed program journal frames instead of panicking 2026-08-23 09:35:23 +00:00
Artem Gureev d35ac281c3 fix(cycle_bench): route guest-input write through Program::write_inputs 2026-08-23 09:35:23 +00:00
Artem Gureev 1bbeaa5c8b chore(lee): retire stale risc0-serde comments and dead round-trip tests 2026-08-23 09:35:23 +00:00
Artem Gureev 96661b4a78 refactor(lee): finish borsh instruction-data cutover in tests and tools 2026-08-23 09:35:23 +00:00
Artem Gureev 5a393d2bff refactor!: carry zkVM instruction_data as borsh bytes end-to-end 2026-08-23 09:35:23 +00:00
Artem Gureev 3e2319f711 refactor(lee_core): drop redundant serde from PublicAction and circuit output 2026-08-23 09:13:07 +00:00
Artem Gureev d5e0e61b34 refactor(lee): route host I/O and circuit recursion through borsh frames 2026-08-23 09:13:07 +00:00
Artem Gureev c86b903737 refactor(lee_core): commit program output as a borsh frame 2026-08-23 09:13:07 +00:00
Artem Gureev 52ebea0d2a refactor(lee_core): decode guest program inputs from a borsh frame 2026-08-23 09:13:07 +00:00
Artem Gureev 1f33856be3 chore(lee_core): derive borsh on zkVM I/O envelope types 2026-08-23 09:13:07 +00:00
Artem Gureev d3698c512c feat(lee_core): add length-prefixed frame helpers for the zkVM boundary 2026-08-23 09:13:07 +00:00
jonesmarvin8 96c8577db8 refactor(lee): fold program storage into public_state (#723)
V03State.programs is gone; deployed programs now live directly in public_state, keyed by AccountId::from(program_id) same as any other account. insert_program sets program_owner to a new reserved sentinel, PROGRAM_STORAGE_OWNER, instead of leaving it at the default.

That ownership choice is load-bearing now in a way it wasn't before: once program accounts share the same map as everything else, they're reachable through ordinary dispatch, so program_owner determines whether they're claimable/writable. Left unclaimed, a program invocation could legitimately claim a program's storage account via the normal claim path and then rewrite its elf; self-ownership has the same flaw, since it authorizes exactly the program whose own invocation would touch its own storage account. The reserved sentinel makes every program account unwritable by construction, since no real chained_call.program_id will ever derive to it.

Also centralizes the program-ownership check behind V03State::get_program and applies the program_owner AccountId migration to code added after the earlier rebase.
2026-08-18 12:44:06 -04:00
jonesmarvin8andClaude Sonnet 5 2ba1ecd609 refactor!(lee): Change program_owner: ProgramId to AccountId (#722)
* feat(lee): store deployed programs as Account-shaped state, keyed by AccountId

Program-as-Account migration, first slice: V03State.programs becomes
HashMap<AccountId, Account> instead of HashMap<ProgramId, Program>,
with the elf held directly in Account.data. The map key is derived
from ProgramId via a new 1:1 From<ProgramId> for AccountId conversion
(both types are exactly 32 bytes) rather than a hash, since ProgramId
is already content-derived from the elf.

Account.program_owner stays ProgramId-typed everywhere - this only
changes how deployed programs are stored and looked up host-side, not
the dispatch/authorization model any guest program logic depends on.
Dispatch resolves a ChainedCall's program_id by converting to
AccountId, fetching the Account, and reconstructing a Program via
new_unchecked for execution.

DATA_MAX_LENGTH is raised from 100 KiB to 700 KiB to fit real program
elfs (observed 375 KB-631 KB) directly in Account.data; noted in its
docstring as a rough placeholder pending real transaction/block-size
budget analysis.

* fix(lee): store deployed programs as Account-shaped state, correct SeenShard cap

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>

* address PR #720 review nits

- Use FIXME instead of TODO for the temporary ProgramId->AccountId
  conversion, per review convention for patches guaranteed to be
  fixed later.
- Derive cross_zone_inbox's MAX_DELIVERIES from DATA_MAX_LENGTH
  instead of a hand-recomputed literal, so it stays in sync
  automatically the next time the cap changes.

* feat(lee): migrate Account.program_owner from ProgramId to AccountId

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.

* chore(lee): rebuild artifacts after rebase, drop unused base58 dep

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.

* docs(lee): trim DEFAULT_PROGRAM_OWNER and From<AccountId> for ProgramId docs

* test(lee): add known-answer tests for ProgramId/AccountId conversion, rebuild artifacts

* fix(lee): apply program_owner AccountId migration to code added after rebase

dev grew new program_owner call sites (sequencer_stake genesis/config
handling, committee_discovery, a new selective_pda_delegator test
program, and related tests) after this branch's ProgramId->AccountId
migration commit was originally written, so they predated the .into()
sweep and didn't conflict during the rebase - they just still assumed
the old ProgramId-typed field. Converts all of them, fixes a stray
unseparated hex literal clippy caught along the way, and rebuilds
artifacts against the fixed source.

* chore(lee): regenerate test fixture after rebasing onto dev

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 11:26:57 -04:00
jonesmarvin8andClaude Sonnet 5 d52c76e2b5 refactor(lee): change programs shape (#720)
* feat(lee): store deployed programs as Account-shaped state, keyed by AccountId

Program-as-Account migration, first slice: V03State.programs becomes
HashMap<AccountId, Account> instead of HashMap<ProgramId, Program>,
with the elf held directly in Account.data. The map key is derived
from ProgramId via a new 1:1 From<ProgramId> for AccountId conversion
(both types are exactly 32 bytes) rather than a hash, since ProgramId
is already content-derived from the elf.

Account.program_owner stays ProgramId-typed everywhere - this only
changes how deployed programs are stored and looked up host-side, not
the dispatch/authorization model any guest program logic depends on.
Dispatch resolves a ChainedCall's program_id by converting to
AccountId, fetching the Account, and reconstructing a Program via
new_unchecked for execution.

DATA_MAX_LENGTH is raised from 100 KiB to 700 KiB to fit real program
elfs (observed 375 KB-631 KB) directly in Account.data; noted in its
docstring as a rough placeholder pending real transaction/block-size
budget analysis.

* fix(lee): store deployed programs as Account-shaped state, correct SeenShard cap

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>

* address PR #720 review nits

- Use FIXME instead of TODO for the temporary ProgramId->AccountId
  conversion, per review convention for patches guaranteed to be
  fixed later.
- Derive cross_zone_inbox's MAX_DELIVERIES from DATA_MAX_LENGTH
  instead of a hand-recomputed literal, so it stays in sync
  automatically the next time the cap changes.

* chore: regenerate artifacts after rebasing onto dev

Binary program artifacts and the prebuilt sequencer DB dump were left
as rebase-conflict placeholders; regenerated via `just build-artifacts`
against the fully rebased source.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 10:06:42 -04:00
Artem Gureev f83cf9b300 perf(lee): extend the caller set for the child authorization scope 2026-08-17 17:29:56 +00:00
Artem Gureev 49a8d00260 doc: correct globally_authorized scope description 2026-08-17 17:29:56 +00:00
Artem Gureev 05c72e2863 doc: fix stale function name in comment 2026-08-17 17:29:56 +00:00
Artem Gureev f707d5e8fb refactor(lee): dedup test, function naming 2026-08-17 17:23:39 +00:00
Artem Gureev f828026df9 fix(lee): authorize caller-seeded public PDAs at first sight 2026-08-17 17:23:39 +00:00
agureev c77313b5ca fix(lee): check private PDA authorization on first sight 2026-08-17 17:23:39 +00:00
agureev 79c43dc5a0 fix!(lee): scope private PDA authorization to the callee subtree
BREAKING!

Before: authorized private PDAs remain authorized for the rest of the
calls after.

After: the authorized preivate PDAs remain authorized for the rest of
the callee subtree.
2026-08-17 17:23:39 +00:00
jonesmarvin8andClaude Sonnet 5 2a7a586a59 refactor(key-protocol)!: introduce constitent domain separators for key protocol (#717)
* feat(key_protocol): version-independent domain separators for normal keys

Introduce a /LEE-Keys/v1/... namespace for account key derivation
(private and public), distinct from LEE protocol versioning
(/LEE/v0.3/...). This lets the key derivation protocol evolve
independently of the transaction/message format version, so a LEE
version bump doesn't silently rotate or orphan user keys.

Covers master/child private and public key derivation, authorization
and viewing secret keys, and nullifier secret/public key derivation
(the latter also used by the privacy-preserving guest circuit).
Pinned regression tests updated to match the new derivation outputs.

* chore(artifacts): rebuild guest ELFs and test fixture for key protocol change

Regenerated via just build-artifacts after the /LEE-Keys/v1/... domain
separator migration touched lee_core::nullifier, which every guest
program links against, and changed derived account IDs embedded in
the prebuilt sequencer fixture.

* test(testnet_initial_state): update pinned private-account values for new key domain separators

initial_priv_accounts_private_keys() derives from fixed SSK roots
through the key_protocol chain the /LEE-Keys/v1/... migration changed,
so the derived viewing secret keys and account addresses shifted even
though the SSK roots themselves didn't. Public account addresses are
unaffected since they sign with a raw PrivateKey outside this chain.

* chore(artifacts): rebuild guest ELFs and test fixture after dev rebase

The rebase onto dev conflicted on these binaries (dev had independently
rebuilt them since this branch diverged). Conflicts were resolved
provisionally during the rebase and are now replaced with a fresh
build-artifacts run against the fully merged tree.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 10:08:12 -04:00
Sergio Chouhy b1eb69322c fix(integration_tests): multi sequencer now builds the state with two accredited keys from channel creation 2026-08-13 18:47:50 -03:00
agureev 1f7a4c4162 doc: fix typo 2026-08-10 12:32:57 +04:00
Artem Gureev 5a1524dcb9 refactor(lee): update stale domain for keytree parent 2026-08-07 17:13:41 +04:00
Artem Gureev 279a9b8313 feat!(lee): derive private authorization from an authorization secret key
BREAKING!

Before: Providing `nsk` was the same as authorizing a regular private
account.

After: A separate `ask` is required, making unauthorized private
updates possible.
2026-08-07 10:41:56 +00:00
Artem Gureev fc8f7f2d42 refactor(lee): verbose key domains and the ask key chain 2026-08-07 10:40:04 +00:00
Artem Gureev ca23f12f7a refactor(lee): keep the authorization precondition match wildcard-free 2026-08-05 11:43:02 +04:00
agureev d05035eb9e refactor(lee): refactor private kinds 2026-08-04 15:55:09 +04:00
agureev ccb426960f Merge remote-tracking branch 'origin/dev' into artem/bundle-actions 2026-08-04 14:21:00 +04:00
Roman 54743142e9 test: bridge guard account flags modification 2026-07-31 17:56:00 -03:00
agureev 0e957b5c08 chore: docs for PrivateAction commitment field 2026-07-31 00:47:04 +04:00
agureev dbcdbb29f3 Merge remote-tracking branch 'origin/dev' into artem/bundle-actions 2026-07-31 00:16:31 +04:00