104 Commits

Author SHA1 Message Date
Moudy
e5b77a27d5 refactor: localize private_pda_npk_by_position and extract authorization helper
Addresses the following review comments from @Arjentix:

- "I think we can move this into `derive_from_outputs()`"
  (on the position → npk map construction in main())
  I moved the construction inside ExecutionState::derive_from_outputs
  and stored the map as a field of ExecutionState. derive_from_outputs
  now takes `private_account_keys` directly and builds the map as part
  of state initialization. main() no longer owns the intermediate
  structure. validate_and_sync_states reads the npk through
  self.private_pda_npk_by_position.

- "Let's move this whole `is_authorized` computation into a separate
  function. This became really bulky"
  I extracted the caller-seeds resolution, family-binding recording,
  and is_authorized computation into a free function
  `resolve_authorization_and_record_bindings`. It takes the three
  field borrows it needs (`&mut pda_family_binding`, `&mut
  private_pda_bound_positions`, `&private_pda_npk_by_position`), same
  shape as `assert_family_binding`. A method would have conflicted
  with the `&mut self.post_states` borrow held by the Occupied match
  arm; the free function lets rustc split-borrow the self fields.
2026-04-22 15:55:35 +02:00
Moudy
0183eac5cc refactor: unify PDA AccountId construction via AccountId::for_{public,private}_pda
Addresses the following review comment:

- "I think this should be a constructor `AccountId::for_private_pda`.
  Consider also removing the existing `impl From<(ProgramId, Seed)> for
  AccountId` for public pdas in favor of a `AccountId::for_public_pda`
  to have a unified way of constructing pdas"

I replaced `impl From<(&ProgramId, &PdaSeed)> for AccountId` with
`AccountId::for_public_pda(program_id: &ProgramId, seed: &PdaSeed) ->
Self` and replaced the free function `private_pda_account_id(...)`
with `AccountId::for_private_pda(program_id: &ProgramId, seed:
&PdaSeed, npk: &NullifierPublicKey) -> Self`. Both live in an inherent
`impl AccountId` block in nssa/core/src/program.rs next to the PDA
derivation logic. Migrated all call sites across nssa/core,
nssa/src/state.rs, nssa/src/validated_state_diff.rs,
program_methods/guest/src/bin/privacy_preserving_circuit.rs,
programs/amm/core, programs/associated_token_account/core, the example
tail-call binary, and the ATA tutorial doc. Test function names that
referenced the old free function were also renamed
(private_pda_account_id_* to for_private_pda_*).
2026-04-21 12:35:19 +02:00
Moudy
68d43d7f2b test: exercise callee authorization in private-PDA delegation tests
Addresses the following review comments:

- "Shouldn't we use a program that checks authorization in this test as
  callee? If not, I'm not sure if we are fully testing what the test
  docs describe (namely, that the callee got the input account with
  is_authorized=true). Maybe add a variant of the noop that checks the
  input account is authorized."
  I added test_program_methods/guest/src/bin/auth_asserting_noop.rs:
  same shape as noop.rs except it asserts pre.is_authorized == true for
  every pre_state before echoing the post_states. Any unauthorized
  pre_state panics the guest, failing the whole circuit proof. I added
  Program::auth_asserting_noop() as the matching helper. In
  caller_pda_seeds_authorize_private_pda_for_callee and
  caller_pda_seeds_with_wrong_seed_rejects_private_pda_for_callee, I
  swapped Program::noop() for Program::auth_asserting_noop() as the
  callee. The positive test now proves the callee actually sees
  is_authorized=true, not just that the circuit's consistency check did
  not reject. The negative test doubles its evidence, both the
  circuit's authorization reconciliation and the callee guest would now
  reject a wrong-seed delegation.

- "This branching logic is only correct because we are not supporting
  non-authorized private accounts with non-default values. Likely to be
  changed in the future. I'm sure there's use cases for this. For
  example the multisig program if ran completely private it would need
  a private non-default and non-authorized input account."
  Agreed. Supporting this needs wallet-supplied `(seed, owner)` side
  input so the npk-to-account_id binding can be re-verified for an
  existing private PDA without a fresh Claim::Pda or a caller
  pda_seeds match. I handled this in the second PR. I added a
  TODO(private-pdas-pr-2/3) marker on the `else` branch in
  privacy_preserving_circuit.rs:3 => { ... } so the constraint is
  visible to future maintainers, along with a comment noting the
  multisig use case.
2026-04-21 02:08:02 +02:00
Moudy
d22c142a37 fix: rebuild artifacts 2026-04-21 01:44:29 +02:00
Moudy
e8b17eef27 refactor: rename mask3 to private_pda in tests and circuit
Addresses the following review comments:

- "I'd rename all mask_3 references in test names and variables to a
  private pda wording. If in the future we change the mask number for
  the private pda, this naming will silently get outdated."
  I renamed all tests and the local variable mask3_account to
  private_pda_account.

- "Let's use more descriptive names. `mask3` is not very meaningful."
  I renamed all `mask3` into `private_pda`. Panic messages and .expect
  strings updated to match. Doc comments that factually describe the
  encoding (e.g. "mask-3 account" meaning "an account whose visibility
  mask is 3") are left as-is since they are accurate and remain stable
  until the mask value itself changes.

- "..._panics" to "..._fails"
  Covered above. The tests assert Err(CircuitProvingError), so
  execute_and_prove returns an Err, the test process itself never
  panics.

- "we can return `Some((*seed, true, caller))` to avoid having to unwrap
  the `caller_program_id` again in line 290"
  I changed matched_caller_seed from Option<(PdaSeed, bool)> to
  Option<(PdaSeed, bool, ProgramId)>, return the `caller` captured by
  the enclosing and_then from each match arm, and dropped the .expect
  at the consumer site. Bundled with the rename since both touch the
  same branch and a single guest ELF rebuild covers them.
2026-04-21 01:43:57 +02:00
Moudy
d5f97c3de4 fix: rebuild artifacts 2026-04-17 15:38:50 +02:00
Moudy
d3577f02bc fix: reject multiple family members under same (program, seed) in one tx 2026-04-17 15:36:20 +02:00
Moudy
f9a5a7635e refactor: make programs privacy-agnostic in the privacy circuit 2026-04-17 07:29:40 +02:00
Moudy
48478ca21e fix: rebuild artifacts 2026-04-16 20:12:39 +02:00
Moudy
4b09aae852 fix: doc backticks and rebuild artifacts 2026-04-16 19:26:27 +02:00
Moudy
bbb0aae17a fix: rebuild artifacts 2026-04-16 19:02:54 +02:00
Moudy
93c6921eaf Merge remote-tracking branch 'origin/main' into moudy/feat-private-pdas
# Conflicts:
#	artifacts/program_methods/amm.bin
#	artifacts/program_methods/associated_token_account.bin
#	artifacts/program_methods/authenticated_transfer.bin
#	artifacts/program_methods/clock.bin
#	artifacts/program_methods/pinata.bin
#	artifacts/program_methods/pinata_token.bin
#	artifacts/program_methods/privacy_preserving_circuit.bin
#	artifacts/program_methods/token.bin
#	artifacts/test_program_methods/burner.bin
#	artifacts/test_program_methods/chain_caller.bin
#	artifacts/test_program_methods/changer_claimer.bin
#	artifacts/test_program_methods/claimer.bin
#	artifacts/test_program_methods/clock_chain_caller.bin
#	artifacts/test_program_methods/data_changer.bin
#	artifacts/test_program_methods/extra_output.bin
#	artifacts/test_program_methods/flash_swap_callback.bin
#	artifacts/test_program_methods/flash_swap_initiator.bin
#	artifacts/test_program_methods/malicious_authorization_changer.bin
#	artifacts/test_program_methods/malicious_caller_program_id.bin
#	artifacts/test_program_methods/malicious_self_program_id.bin
#	artifacts/test_program_methods/minter.bin
#	artifacts/test_program_methods/missing_output.bin
#	artifacts/test_program_methods/modified_transfer.bin
#	artifacts/test_program_methods/nonce_changer.bin
#	artifacts/test_program_methods/noop.bin
#	artifacts/test_program_methods/pinata_cooldown.bin
#	artifacts/test_program_methods/program_owner_changer.bin
#	artifacts/test_program_methods/simple_balance_transfer.bin
#	artifacts/test_program_methods/time_locked_transfer.bin
#	artifacts/test_program_methods/validity_window.bin
#	artifacts/test_program_methods/validity_window_chain_caller.bin
#	nssa/core/src/program.rs
#	nssa/src/state.rs
2026-04-16 18:25:57 +02:00
Moudy
ac09e785a9 fix: rebuild artifacts 2026-04-16 18:07:46 +02:00
Moudy
f1b2c04f3d fix: rebuild artifacts 2026-04-16 17:38:41 +02:00
Moudy
661ef7c4e9 fix: rebuild artifacts 2026-04-16 16:54:02 +02:00
Moudy
e08c8f93b4 fix: rebuild artifacts 2026-04-16 00:23:08 +02:00
Moudy
8b9cc5accf fix: rebuild artifacts 2026-04-15 23:29:13 +02:00
Moudy
4bdb1e7a22 fix: rebuild artifacts for CI 2026-04-15 21:31:33 +02:00
Moudy
b0c10ee5a2 fix: cargo fmt, add #[must_use] to private_pda_account_id, rebuild artifacts 2026-04-15 21:10:22 +02:00
Daniil Polyakov
699e91363e feat: introduce more descriptive error messages for public execution 2026-04-13 21:25:18 +03:00
Moudy
7e1268f53f fix: rebuild artifacts 2026-04-07 20:57:38 +02:00
Moudy
56ee93b5b7 merge main into feat-caller-program-id-and-flash-swap 2026-04-07 19:44:55 +02:00
Moudy
b22a989fbc merge main into feat-caller-program-id-and-flash-swap 2026-04-07 19:27:27 +02:00
Sergio Chouhy
1ba80f7631 count mandatory clock tx in max_block_size 2026-04-06 21:34:03 -03:00
Sergio Chouhy
ed1926b38a use Timestamp instead of u64 2026-04-06 13:21:39 -03:00
Sergio Chouhy
015999b3a5 add clock usage example programs 2026-04-04 00:23:43 -03:00
Moudy
5273c9e076 fix: rebuild artifacts 2026-04-04 00:44:50 +02:00
Moudy
324750e618 fix: remove unfulfilled large_enum_variant expect, add backticks in docs, rebuild artifacts 2026-04-04 00:04:40 +02:00
Sergio Chouhy
34de497d4d add test 2026-04-03 18:44:28 -03:00
Moudy
dca3d1a18d fix: rebuild artifacts 2026-04-03 23:36:36 +02:00
Moudy
bc0583368d fix: set is_authorized on PDA accounts in flash swap chained calls 2026-04-03 15:18:23 +02:00
Moudy
74e16db68f fix: apply formatting and rebuild artifacts 2026-04-03 01:17:42 +02:00
Moudy
88e3b368c3 fix: rebuild artifacts 2026-04-03 00:58:11 +02:00
Moudy
d105a51c04 fix: rebuild artifacts 2026-04-03 00:58:11 +02:00
Moudy
65166e8fcc fix: rebuild artifacts 2026-04-03 00:58:11 +02:00
Sergio Chouhy
4d5010f044 Merge branch 'main' into schouhy/add-block-context-system-accounts 2026-04-02 19:48:55 -03:00
Sergio Chouhy
b525447e2d refactor so that indexer checks clock constraints 2026-04-02 18:30:10 -03:00
Sergio Chouhy
29d66d2c2d small refactor 2026-04-02 17:40:58 -03:00
Moudy
67bb1809de fix: rebuild artifacts 2026-04-02 20:38:02 +02:00
Andrea Franz
7d75eb2d59 chore(programs/amm): rename Swap to SwapExactInput 2026-04-02 16:10:12 +02:00
Sergio Chouhy
3c5a1c9d0a Merge branch 'main' into schouhy/add-block-context-system-accounts 2026-03-31 20:53:10 -03:00
Moudy
e3edabcaa2 rebuild artifacts after ValidityWindow struct change 2026-03-31 15:47:43 +02:00
Moudy
12bdc256d4 rebuild artifacts 2026-03-31 14:55:37 +02:00
Moudy
be2b2db1f5 rebuild artifacts after rebase onto main 2026-03-31 13:58:53 +02:00
Moudy
d861f2018c rebuild artifacts with validity_window field in ProgramOutput 2026-03-31 13:47:03 +02:00
Sergio Chouhy
867d8dac90 artifacts 2026-03-31 01:57:57 -03:00
Sergio Chouhy
d8ffa22b81 add more clock accounts 2026-03-31 01:39:02 -03:00
Sergio Chouhy
7078e403ed add timestamp to clock 2026-03-30 23:50:54 -03:00
Daniil Polyakov
6780f1c9a4 feat: protect from public pda griefing attacks 2026-03-28 01:23:57 +03:00
Sergio Chouhy
73fdc1d70c artifacts 2026-03-26 18:30:03 -03:00