From 90a3ee7812801d1469a92543d50b03d009fc89c9 Mon Sep 17 00:00:00 2001 From: Marvin Jones Date: Fri, 14 Aug 2026 16:43:59 -0400 Subject: [PATCH] refactor(lee): migrate program self/caller identity from ProgramId to AccountId 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. --- .../methods/guest/src/bin/hello_world.rs | 8 ++-- .../src/bin/hello_world_with_authorization.rs | 8 ++-- .../src/bin/hello_world_with_move_function.rs | 8 ++-- .../methods/guest/src/bin/simple_tail_call.rs | 8 ++-- .../guest/src/bin/tail_call_with_pda.rs | 8 ++-- .../src/execution_state.rs | 15 +++--- lee/state_machine/core/src/program/mod.rs | 39 +++++++++------- lee/state_machine/core/src/program/tests.rs | 10 ++-- lee/state_machine/src/error.rs | 4 +- .../circuit/mod.rs | 12 ++--- lee/state_machine/src/program/mod.rs | 16 +++---- .../src/state/tests/flash_swap.rs | 8 ++-- .../src/validated_state_diff/mod.rs | 22 +++++---- .../guest/src/bin/auth_asserting_noop.rs | 8 ++-- .../test_methods/guest/src/bin/burner.rs | 8 ++-- .../guest/src/bin/chain_caller.rs | 8 ++-- .../guest/src/bin/changer_claimer.rs | 8 ++-- .../test_methods/guest/src/bin/claimer.rs | 8 ++-- .../guest/src/bin/data_changer.rs | 8 ++-- .../guest/src/bin/dropped_account.rs | 8 ++-- .../guest/src/bin/extra_output.rs | 8 ++-- .../guest/src/bin/flash_swap_callback.rs | 12 ++--- .../guest/src/bin/flash_swap_initiator.rs | 42 ++++++++--------- .../bin/malicious_authorization_changer.rs | 8 ++-- .../src/bin/malicious_caller_program_id.rs | 12 ++--- .../guest/src/bin/malicious_injector.rs | 8 ++-- .../guest/src/bin/malicious_launderer.rs | 8 ++-- .../src/bin/malicious_self_program_id.rs | 10 ++-- .../test_methods/guest/src/bin/minter.rs | 8 ++-- .../guest/src/bin/missing_output.rs | 8 ++-- .../guest/src/bin/modified_transfer.rs | 8 ++-- .../guest/src/bin/nonce_changer.rs | 8 ++-- .../test_methods/guest/src/bin/noop.rs | 8 ++-- .../test_methods/guest/src/bin/pda_claimer.rs | 8 ++-- .../guest/src/bin/pda_spend_proxy.rs | 8 ++-- .../guest/src/bin/private_pda_delegator.rs | 10 ++-- .../guest/src/bin/program_owner_changer.rs | 8 ++-- .../guest/src/bin/simple_balance_transfer.rs | 12 ++--- .../guest/src/bin/simple_transfer_proxy.rs | 12 ++--- .../guest/src/bin/two_pda_claimer.rs | 8 ++-- .../guest/src/bin/validity_window.rs | 8 ++-- .../src/bin/validity_window_chain_caller.rs | 8 ++-- lez/programs/amm/src/main.rs | 8 ++-- .../associated_token_account/src/main.rs | 8 ++-- .../authenticated_transfer/src/main.rs | 8 ++-- lez/programs/bridge/src/main.rs | 16 +++---- lez/programs/bridge_lock/src/main.rs | 45 +++++++++--------- lez/programs/clock/src/main.rs | 9 ++-- lez/programs/cross_zone_inbox/src/main.rs | 42 +++++++++-------- .../cross_zone_outbox/core/src/lib.rs | 2 +- lez/programs/cross_zone_outbox/src/main.rs | 19 +++++--- lez/programs/faucet/src/main.rs | 14 +++--- lez/programs/pinata/src/main.rs | 8 ++-- lez/programs/pinata_token/src/main.rs | 8 ++-- lez/programs/ping_receiver/src/main.rs | 46 ++++++++++--------- lez/programs/ping_sender/src/main.rs | 39 ++++++++-------- lez/programs/token/src/main.rs | 8 ++-- lez/programs/vault/src/main.rs | 8 ++-- lez/programs/wrapped_token/src/main.rs | 44 ++++++++++-------- test_programs/guest/src/bin/chain_caller.rs | 8 ++-- test_programs/guest/src/bin/claimer.rs | 8 ++-- .../guest/src/bin/clock_chain_caller.rs | 8 ++-- .../guest/src/bin/faucet_chain_caller.rs | 8 ++-- .../guest/src/bin/pda_spend_proxy.rs | 8 ++-- .../guest/src/bin/pinata_cooldown.rs | 8 ++-- .../guest/src/bin/simple_balance_transfer.rs | 12 ++--- .../guest/src/bin/time_locked_transfer.rs | 8 ++-- tools/cycle_bench/src/main.rs | 6 +-- 68 files changed, 442 insertions(+), 416 deletions(-) diff --git a/examples/program_deployment/methods/guest/src/bin/hello_world.rs b/examples/program_deployment/methods/guest/src/bin/hello_world.rs index 0cb7f349f..37a5a5129 100644 --- a/examples/program_deployment/methods/guest/src/bin/hello_world.rs +++ b/examples/program_deployment/methods/guest/src/bin/hello_world.rs @@ -19,8 +19,8 @@ fn main() { // Read inputs let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: greeting, }, @@ -53,8 +53,8 @@ fn main() { // WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be // called to commit the output. ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_data, vec![pre_state], vec![post_state], diff --git a/examples/program_deployment/methods/guest/src/bin/hello_world_with_authorization.rs b/examples/program_deployment/methods/guest/src/bin/hello_world_with_authorization.rs index a9b238cef..025799cc4 100644 --- a/examples/program_deployment/methods/guest/src/bin/hello_world_with_authorization.rs +++ b/examples/program_deployment/methods/guest/src/bin/hello_world_with_authorization.rs @@ -19,8 +19,8 @@ fn main() { // Read inputs let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: greeting, }, @@ -60,8 +60,8 @@ fn main() { // WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be // called to commit the output. ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_data, vec![pre_state], vec![post_state], diff --git a/examples/program_deployment/methods/guest/src/bin/hello_world_with_move_function.rs b/examples/program_deployment/methods/guest/src/bin/hello_world_with_move_function.rs index ebb146ecc..ab0ed6505 100644 --- a/examples/program_deployment/methods/guest/src/bin/hello_world_with_move_function.rs +++ b/examples/program_deployment/methods/guest/src/bin/hello_world_with_move_function.rs @@ -66,8 +66,8 @@ fn main() { // Read input accounts. let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (function_id, data), }, @@ -88,8 +88,8 @@ fn main() { // WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be // called to commit the output. ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, post_states, diff --git a/examples/program_deployment/methods/guest/src/bin/simple_tail_call.rs b/examples/program_deployment/methods/guest/src/bin/simple_tail_call.rs index d076192e5..f743f8cf5 100644 --- a/examples/program_deployment/methods/guest/src/bin/simple_tail_call.rs +++ b/examples/program_deployment/methods/guest/src/bin/simple_tail_call.rs @@ -27,8 +27,8 @@ fn main() { // Read inputs let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (), }, @@ -58,8 +58,8 @@ fn main() { // WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be // called to commit the output. ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_data, vec![pre_state], vec![post_state], diff --git a/examples/program_deployment/methods/guest/src/bin/tail_call_with_pda.rs b/examples/program_deployment/methods/guest/src/bin/tail_call_with_pda.rs index 1d6cad3b2..5ee2e410e 100644 --- a/examples/program_deployment/methods/guest/src/bin/tail_call_with_pda.rs +++ b/examples/program_deployment/methods/guest/src/bin/tail_call_with_pda.rs @@ -32,8 +32,8 @@ fn main() { // Read inputs let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (), }, @@ -70,8 +70,8 @@ fn main() { // WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be // called to commit the output. ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_data, vec![pre_state], vec![post_state], diff --git a/lee/privacy_preserving_circuit/src/execution_state.rs b/lee/privacy_preserving_circuit/src/execution_state.rs index d492ee3fe..d39649cd6 100644 --- a/lee/privacy_preserving_circuit/src/execution_state.rs +++ b/lee/privacy_preserving_circuit/src/execution_state.rs @@ -168,20 +168,21 @@ impl ExecutionState { |_: Infallible| unreachable!("Infallible error is never constructed"), ); - // Verify that the program output's self_program_id matches the expected program ID. + // Verify that the program output's self_account_id matches the expected program ID. // This ensures the proof commits to which program produced the output. assert_eq!( - program_output.self_program_id, current_program_id, - "Program output self_program_id does not match chained call program_id" + program_output.self_account_id, chained_call.program_account_id, + "Program output self_account_id does not match chained call program_account_id" ); - // Verify that the program output's caller_program_id matches the actual caller. + // Verify that the program output's caller_account_id matches the actual caller. // This prevents a malicious user from privately executing an internal function - // by spoofing caller_program_id (e.g. passing caller_program_id = self_program_id + // by spoofing caller_account_id (e.g. passing caller_account_id = self_account_id // to bypass access control checks). assert_eq!( - program_output.caller_program_id, caller_data.program_id, - "Program output caller_program_id does not match actual caller" + program_output.caller_account_id, + caller_data.program_id.map(AccountId::from), + "Program output caller_account_id does not match actual caller" ); // Check that the program is well behaved. diff --git a/lee/state_machine/core/src/program/mod.rs b/lee/state_machine/core/src/program/mod.rs index 68a77d1ee..e8c6c6796 100644 --- a/lee/state_machine/core/src/program/mod.rs +++ b/lee/state_machine/core/src/program/mod.rs @@ -54,8 +54,8 @@ impl From for ProgramId { pub type InstructionData = Vec; pub struct ProgramInput { - pub self_program_id: ProgramId, - pub caller_program_id: Option, + pub self_account_id: AccountId, + pub caller_account_id: Option, pub pre_states: Vec, pub instruction: T, } @@ -250,7 +250,7 @@ pub struct ChainedCall { /// The instruction data to pass. pub instruction_data: InstructionData, /// PDA seeds authorized for the callee. For each seed, the callee is authorized to - /// mutate the `AccountId` derived from `(caller_program_id, seed)`, regardless of + /// mutate the `AccountId` derived from `(caller_account_id, seed)`, regardless of /// whether the account is public or private. pub pda_seeds: Vec, } @@ -472,11 +472,11 @@ pub struct InvalidWindow; #[cfg_attr(any(feature = "host", test), derive(Debug, PartialEq, Eq))] #[must_use = "ProgramOutput does nothing unless written"] pub struct ProgramOutput { - /// The program ID of the program that produced this output. - pub self_program_id: ProgramId, - /// The program ID of the caller that invoked this program via a chained call, + /// The `AccountId` of the program that produced this output. + pub self_account_id: AccountId, + /// The `AccountId` of the caller that invoked this program via a chained call, /// or `None` if this is a top-level call. - pub caller_program_id: Option, + pub caller_account_id: Option, /// The instruction data the program received to produce this output. pub instruction_data: InstructionData, /// The account pre states the program received to produce this output. @@ -493,15 +493,15 @@ pub struct ProgramOutput { impl ProgramOutput { pub const fn new( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, instruction_data: InstructionData, pre_states: Vec, post_states: Vec, ) -> Self { Self { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_data, pre_states, post_states, @@ -674,12 +674,17 @@ pub enum ExecutionValidationError { /// `pre_state`. #[must_use] pub fn compute_public_authorized_pdas( - caller_program_id: Option, + caller_account_id: Option, pda_seeds: &[PdaSeed], ) -> HashSet { - let Some(caller) = caller_program_id else { + let Some(caller) = caller_account_id else { return HashSet::new(); }; + // Recover the real `ProgramId` (RISC0 image id): on this branch every program account lives + // at the direct `AccountId::from(program_id)` bijection, so this round-trip is exact. + // `for_public_pda`'s derivation formula is pinned to the caller's actual image id, not its + // dispatch-facing `AccountId`. + let caller = ProgramId::from(caller); pda_seeds .iter() .map(|seed| AccountId::for_public_pda(&caller, seed)) @@ -689,15 +694,15 @@ pub fn compute_public_authorized_pdas( /// Reads the LEE inputs from the guest environment. #[must_use] pub fn read_lee_inputs() -> (ProgramInput, InstructionData) { - let self_program_id: ProgramId = env::read(); - let caller_program_id: Option = env::read(); + let self_account_id: AccountId = env::read(); + let caller_account_id: Option = env::read(); let pre_states: Vec = env::read(); let instruction_words: InstructionData = env::read(); let instruction = T::deserialize(&mut Deserializer::new(instruction_words.as_ref())).unwrap(); ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, diff --git a/lee/state_machine/core/src/program/tests.rs b/lee/state_machine/core/src/program/tests.rs index 138545d3f..69f036721 100644 --- a/lee/state_machine/core/src/program/tests.rs +++ b/lee/state_machine/core/src/program/tests.rs @@ -99,7 +99,7 @@ fn validity_window_from_range_full() { #[test] fn program_output_try_with_block_validity_window_range() { - let output = ProgramOutput::new(DEFAULT_PROGRAM_ID, None, vec![], vec![], vec![]) + let output = ProgramOutput::new(DEFAULT_PROGRAM_ID.into(), None, vec![], vec![], vec![]) .try_with_block_validity_window(10_u64..100) .unwrap(); assert_eq!(output.block_validity_window.start(), Some(10)); @@ -108,7 +108,7 @@ fn program_output_try_with_block_validity_window_range() { #[test] fn program_output_with_block_validity_window_range_from() { - let output = ProgramOutput::new(DEFAULT_PROGRAM_ID, None, vec![], vec![], vec![]) + let output = ProgramOutput::new(DEFAULT_PROGRAM_ID.into(), None, vec![], vec![], vec![]) .with_block_validity_window(10_u64..); assert_eq!(output.block_validity_window.start(), Some(10)); assert_eq!(output.block_validity_window.end(), None); @@ -116,7 +116,7 @@ fn program_output_with_block_validity_window_range_from() { #[test] fn program_output_with_block_validity_window_range_to() { - let output = ProgramOutput::new(DEFAULT_PROGRAM_ID, None, vec![], vec![], vec![]) + let output = ProgramOutput::new(DEFAULT_PROGRAM_ID.into(), None, vec![], vec![], vec![]) .with_block_validity_window(..100_u64); assert_eq!(output.block_validity_window.start(), None); assert_eq!(output.block_validity_window.end(), Some(100)); @@ -124,7 +124,7 @@ fn program_output_with_block_validity_window_range_to() { #[test] fn program_output_try_with_block_validity_window_empty_range_fails() { - let result = ProgramOutput::new(DEFAULT_PROGRAM_ID, None, vec![], vec![], vec![]) + let result = ProgramOutput::new(DEFAULT_PROGRAM_ID.into(), None, vec![], vec![], vec![]) .try_with_block_validity_window(5_u64..5); assert!(result.is_err()); } @@ -326,7 +326,7 @@ fn for_private_account_dispatches_correctly() { fn compute_public_authorized_pdas_with_seeds() { let caller: ProgramId = [1; 8]; let seed = PdaSeed::new([2; 32]); - let result = compute_public_authorized_pdas(Some(caller), &[seed]); + let result = compute_public_authorized_pdas(Some(caller.into()), &[seed]); let expected = AccountId::for_public_pda(&caller, &seed); assert!(result.contains(&expected)); assert_eq!(result.len(), 1); diff --git a/lee/state_machine/src/error.rs b/lee/state_machine/src/error.rs index c87940a46..235f6e441 100644 --- a/lee/state_machine/src/error.rs +++ b/lee/state_machine/src/error.rs @@ -107,8 +107,8 @@ pub enum InvalidProgramBehaviorError { #[error("Caller program ID mismatch: expected {expected:?}, actual {actual:?}")] MismatchedCallerProgramId { - expected: Option, - actual: Option, + expected: Option, + actual: Option, }, #[error(transparent)] diff --git a/lee/state_machine/src/privacy_preserving_transaction/circuit/mod.rs b/lee/state_machine/src/privacy_preserving_transaction/circuit/mod.rs index 42b6903a5..1d97b46c3 100644 --- a/lee/state_machine/src/privacy_preserving_transaction/circuit/mod.rs +++ b/lee/state_machine/src/privacy_preserving_transaction/circuit/mod.rs @@ -103,14 +103,14 @@ pub fn execute_and_prove_with_padded_inputs( let mut chained_calls = VecDeque::from_iter([(initial_call, initial_program, None)]); let mut chain_calls_counter = 0; - while let Some((chained_call, program, caller_program_id)) = chained_calls.pop_front() { + while let Some((chained_call, program, caller_account_id)) = chained_calls.pop_front() { if chain_calls_counter >= MAX_NUMBER_CHAINED_CALLS { return Err(LeeError::MaxChainedCallsDepthExceeded); } let inner_receipt = execute_and_prove_program( program, - caller_program_id, + caller_account_id, &chained_call.pre_states, &chained_call.instruction_data, )?; @@ -136,7 +136,7 @@ pub fn execute_and_prove_with_padded_inputs( chained_calls.push_front(( new_call, next_program, - Some(ProgramId::from(chained_call.program_account_id)), + Some(chained_call.program_account_id), )); } @@ -173,15 +173,15 @@ pub fn execute_and_prove_with_padded_inputs( fn execute_and_prove_program( program: &Program, - caller_program_id: Option, + caller_account_id: Option, pre_states: &[AccountWithMetadata], instruction_data: &InstructionData, ) -> Result { // Write inputs to the program let mut env_builder = ExecutorEnv::builder(); Program::write_inputs( - program.id(), - caller_program_id, + AccountId::from(program.id()), + caller_account_id, pre_states, instruction_data, &mut env_builder, diff --git a/lee/state_machine/src/program/mod.rs b/lee/state_machine/src/program/mod.rs index d481c1fad..ab3cf69cf 100644 --- a/lee/state_machine/src/program/mod.rs +++ b/lee/state_machine/src/program/mod.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use borsh::{BorshDeserialize, BorshSerialize}; use lee_core::{ - account::AccountWithMetadata, + account::{AccountId, AccountWithMetadata}, program::{InstructionData, ProgramId, ProgramOutput}, }; use risc0_zkvm::{ExecutorEnv, ExecutorEnvBuilder, default_executor, serde::to_vec}; @@ -54,7 +54,7 @@ impl Program { pub(crate) fn execute( &self, - caller_program_id: Option, + caller_account_id: Option, pre_states: &[AccountWithMetadata], instruction_data: &InstructionData, ) -> Result { @@ -62,8 +62,8 @@ impl Program { let mut env_builder = ExecutorEnv::builder(); env_builder.session_limit(Some(MAX_NUM_CYCLES_PUBLIC_EXECUTION)); Self::write_inputs( - self.id, - caller_program_id, + AccountId::from(self.id), + caller_account_id, pre_states, instruction_data, &mut env_builder, @@ -87,17 +87,17 @@ impl Program { /// Writes inputs to `env_builder` in the order expected by the programs. pub(crate) fn write_inputs( - program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: &[AccountWithMetadata], instruction_data: &[u32], env_builder: &mut ExecutorEnvBuilder, ) -> Result<(), LeeError> { env_builder - .write(&program_id) + .write(&self_account_id) .map_err(|e| LeeError::ProgramWriteInputFailed(e.to_string()))?; env_builder - .write(&caller_program_id) + .write(&caller_account_id) .map_err(|e| LeeError::ProgramWriteInputFailed(e.to_string()))?; let pre_states = pre_states.to_vec(); env_builder diff --git a/lee/state_machine/src/state/tests/flash_swap.rs b/lee/state_machine/src/state/tests/flash_swap.rs index bd8700964..e1b79cae3 100644 --- a/lee/state_machine/src/state/tests/flash_swap.rs +++ b/lee/state_machine/src/state/tests/flash_swap.rs @@ -160,7 +160,7 @@ fn flash_swap_self_call_targets_correct_program() { #[test] fn flash_swap_standalone_invariant_check_rejected() { // Calling InvariantCheck directly (not as a chained self-call) should fail - // because caller_program_id will be None. + // because caller_account_id will be None. let initiator = crate::test_methods::flash_swap_initiator(); let token = crate::test_methods::simple_balance_transfer(); @@ -192,7 +192,7 @@ fn flash_swap_standalone_invariant_check_rejected() { let result = state.transition_from_public_transaction(&tx, 1, 0); assert!( result.is_err(), - "standalone InvariantCheck should be rejected (caller_program_id is None)" + "standalone InvariantCheck should be rejected (caller_account_id is None)" ); } @@ -214,7 +214,7 @@ fn malicious_self_program_id_rejected_in_public_execution() { let result = state.transition_from_public_transaction(&tx, 1, 0); assert!( result.is_err(), - "program with wrong self_program_id in output should be rejected" + "program with wrong self_account_id in output should be rejected" ); } @@ -236,6 +236,6 @@ fn malicious_caller_program_id_rejected_in_public_execution() { let result = state.transition_from_public_transaction(&tx, 1, 0); assert!( result.is_err(), - "program with spoofed caller_program_id in output should be rejected" + "program with spoofed caller_account_id in output should be rejected" ); } diff --git a/lee/state_machine/src/validated_state_diff/mod.rs b/lee/state_machine/src/validated_state_diff/mod.rs index 92875e8a1..a7b23f3fe 100644 --- a/lee/state_machine/src/validated_state_diff/mod.rs +++ b/lee/state_machine/src/validated_state_diff/mod.rs @@ -130,7 +130,7 @@ impl ValidatedStateDiff { chained_call.instruction_data ); let mut program_output = program.execute( - caller_data.program_id, + caller_data.caller_account_id, &chained_call.pre_states, &chained_call.instruction_data, )?; @@ -139,8 +139,10 @@ impl ValidatedStateDiff { chained_call.program_account_id, program_output ); - let authorized_pdas = - compute_public_authorized_pdas(caller_data.program_id, &chained_call.pda_seeds); + let authorized_pdas = compute_public_authorized_pdas( + caller_data.caller_account_id, + &chained_call.pda_seeds, + ); // Account is authorized if it is either in the caller's authorized accounts or in the // list of PDAs the caller has authorized. @@ -181,21 +183,21 @@ impl ValidatedStateDiff { ); } - // Verify that the program output's self_program_id matches the expected program ID. + // Verify that the program output's self_account_id matches the expected program ID. ensure!( - AccountId::from(program_output.self_program_id) == chained_call.program_account_id, + program_output.self_account_id == chained_call.program_account_id, InvalidProgramBehaviorError::MismatchedProgramId { expected: chained_call.program_account_id, - actual: AccountId::from(program_output.self_program_id) + actual: program_output.self_account_id } ); - // Verify that the program output's caller_program_id matches the actual caller. + // Verify that the program output's caller_account_id matches the actual caller. ensure!( - program_output.caller_program_id == caller_data.program_id, + program_output.caller_account_id == caller_data.caller_account_id, InvalidProgramBehaviorError::MismatchedCallerProgramId { - expected: caller_data.program_id, - actual: program_output.caller_program_id, + expected: caller_data.caller_account_id, + actual: program_output.caller_account_id, } ); diff --git a/lee/state_machine/test_methods/guest/src/bin/auth_asserting_noop.rs b/lee/state_machine/test_methods/guest/src/bin/auth_asserting_noop.rs index 91983c1d4..e90fe49e9 100644 --- a/lee/state_machine/test_methods/guest/src/bin/auth_asserting_noop.rs +++ b/lee/state_machine/test_methods/guest/src/bin/auth_asserting_noop.rs @@ -9,8 +9,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, .. }, @@ -30,8 +30,8 @@ fn main() { .map(|account| AccountPostState::new(account.account.clone())) .collect(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, post_states, diff --git a/lee/state_machine/test_methods/guest/src/bin/burner.rs b/lee/state_machine/test_methods/guest/src/bin/burner.rs index 4cbf61a2f..c8a1fc78a 100644 --- a/lee/state_machine/test_methods/guest/src/bin/burner.rs +++ b/lee/state_machine/test_methods/guest/src/bin/burner.rs @@ -5,8 +5,8 @@ type Instruction = u128; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: balance_to_burn, }, @@ -22,8 +22,8 @@ fn main() { account_post.balance = account_post.balance.saturating_sub(balance_to_burn); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![AccountPostState::new(account_post)], diff --git a/lee/state_machine/test_methods/guest/src/bin/chain_caller.rs b/lee/state_machine/test_methods/guest/src/bin/chain_caller.rs index 7227d905b..eaacd725e 100644 --- a/lee/state_machine/test_methods/guest/src/bin/chain_caller.rs +++ b/lee/state_machine/test_methods/guest/src/bin/chain_caller.rs @@ -12,8 +12,8 @@ type Instruction = (u128, ProgramId, u32, Option); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (balance, simple_transfer_id, num_chain_calls, pda_seed), }, @@ -56,8 +56,8 @@ fn main() { } ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![sender_pre.clone(), recipient_pre.clone()], vec![ diff --git a/lee/state_machine/test_methods/guest/src/bin/changer_claimer.rs b/lee/state_machine/test_methods/guest/src/bin/changer_claimer.rs index 0d3c0df80..ce66c67a9 100644 --- a/lee/state_machine/test_methods/guest/src/bin/changer_claimer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/changer_claimer.rs @@ -6,8 +6,8 @@ type Instruction = (Option>, bool); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (data_opt, should_claim), }, @@ -36,8 +36,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![post_state], diff --git a/lee/state_machine/test_methods/guest/src/bin/claimer.rs b/lee/state_machine/test_methods/guest/src/bin/claimer.rs index b0efe9925..1f98b899d 100644 --- a/lee/state_machine/test_methods/guest/src/bin/claimer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/claimer.rs @@ -5,8 +5,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (), }, @@ -20,8 +20,8 @@ fn main() { let account_post = AccountPostState::new_claimed(pre.account.clone(), Claim::Authorized); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![account_post], diff --git a/lee/state_machine/test_methods/guest/src/bin/data_changer.rs b/lee/state_machine/test_methods/guest/src/bin/data_changer.rs index 4ab30a618..19a8448de 100644 --- a/lee/state_machine/test_methods/guest/src/bin/data_changer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/data_changer.rs @@ -6,8 +6,8 @@ type Instruction = Vec; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: data, }, @@ -25,8 +25,8 @@ fn main() { .expect("provided data should fit into data limit"); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![AccountPostState::new_claimed( diff --git a/lee/state_machine/test_methods/guest/src/bin/dropped_account.rs b/lee/state_machine/test_methods/guest/src/bin/dropped_account.rs index 348eefa85..41fbc4268 100644 --- a/lee/state_machine/test_methods/guest/src/bin/dropped_account.rs +++ b/lee/state_machine/test_methods/guest/src/bin/dropped_account.rs @@ -10,8 +10,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, .. }, @@ -25,8 +25,8 @@ fn main() { let account_pre1 = pre1.account.clone(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre1], vec![AccountPostState::new(account_pre1)], diff --git a/lee/state_machine/test_methods/guest/src/bin/extra_output.rs b/lee/state_machine/test_methods/guest/src/bin/extra_output.rs index 6c9ee9ed2..881282289 100644 --- a/lee/state_machine/test_methods/guest/src/bin/extra_output.rs +++ b/lee/state_machine/test_methods/guest/src/bin/extra_output.rs @@ -8,8 +8,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, .. }, @@ -23,8 +23,8 @@ fn main() { let account_pre = pre.account.clone(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![ diff --git a/lee/state_machine/test_methods/guest/src/bin/flash_swap_callback.rs b/lee/state_machine/test_methods/guest/src/bin/flash_swap_callback.rs index 78c75d3c7..52c81ee3f 100644 --- a/lee/state_machine/test_methods/guest/src/bin/flash_swap_callback.rs +++ b/lee/state_machine/test_methods/guest/src/bin/flash_swap_callback.rs @@ -17,9 +17,9 @@ //! will fail (vault balance < initial), causing full atomic rollback. This simulates a malicious //! or buggy callback that does not repay the flash loan. //! -//! # Note on `caller_program_id` +//! # Note on `caller_account_id` //! -//! This program does not enforce any access control on `caller_program_id`. +//! This program does not enforce any access control on `caller_account_id`. //! It is designed to be called by the flash swap initiator but could in principle be //! called by any program. In production, a callback would typically verify the caller //! if it needs to trust the context it is called from. @@ -41,8 +41,8 @@ pub struct CallbackInstruction { fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, // not enforced in this callback + self_account_id, + caller_account_id, // not enforced in this callback pre_states, instruction, }, @@ -79,8 +79,8 @@ fn main() { // The callback itself makes no direct state changes, accounts pass through unchanged. // All mutations go through the token program via chained calls. ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![vault_pre.clone(), receiver_pre.clone()], vec![ diff --git a/lee/state_machine/test_methods/guest/src/bin/flash_swap_initiator.rs b/lee/state_machine/test_methods/guest/src/bin/flash_swap_initiator.rs index 03910ec82..76c2b6cbf 100644 --- a/lee/state_machine/test_methods/guest/src/bin/flash_swap_initiator.rs +++ b/lee/state_machine/test_methods/guest/src/bin/flash_swap_initiator.rs @@ -1,5 +1,5 @@ //! Flash swap initiator, demonstrates the "prep → callback → assert" pattern using -//! generalized multi tail-calls with `self_program_id` and `caller_program_id`. +//! generalized multi tail-calls with `self_account_id` and `caller_account_id`. //! //! # Pattern //! @@ -14,16 +14,16 @@ //! - `Initiate` (external): the top-level entrypoint. Emits 3 chained calls: //! 1. Token transfer out (vault → receiver) //! 2. User callback (arbitrary logic, e.g. arbitrage) -//! 3. Self-call to `InvariantCheck` (using `self_program_id` to reference itself) +//! 3. Self-call to `InvariantCheck` (using `self_account_id` to reference itself) //! //! - `InvariantCheck` (internal): enforces that the vault balance was restored after the callback. -//! Uses `caller_program_id == Some(self_program_id)` to prevent standalone calls (this is the +//! Uses `caller_account_id == Some(self_account_id)` to prevent standalone calls (this is the //! visibility enforcement mechanism). //! //! # What this demonstrates //! -//! - `self_program_id`: enables a program to chain back to itself (step 3 above) -//! - `caller_program_id`: enables a program to restrict which callers can invoke an instruction +//! - `self_account_id`: enables a program to chain back to itself (step 3 above) +//! - `caller_account_id`: enables a program to restrict which callers can invoke an instruction //! - Computed intermediate states: the initiator computes expected intermediate account states from //! the `pre_states` and amount, keeping the instruction minimal. //! - Atomic rollback: if the callback doesn't return funds, the invariant check fails, and all @@ -35,7 +35,7 @@ //! - `flash_swap_successful`: full round-trip, funds returned, state unchanged //! - `flash_swap_callback_keeps_funds_rollback`: callback keeps funds, full rollback //! - `flash_swap_self_call_targets_correct_program`: zero-amount self-call isolation test -//! - `flash_swap_standalone_invariant_check_rejected`: `caller_program_id` access control +//! - `flash_swap_standalone_invariant_check_rejected`: `caller_account_id` access control use lee_core::program::{ AccountPostState, ChainedCall, PdaSeed, ProgramId, ProgramInput, ProgramOutput, read_lee_inputs, @@ -62,17 +62,17 @@ pub enum FlashSwapInstruction { /// Internal: verify the vault invariant holds after callback execution. /// /// Access control: only callable as a chained call from this program itself. - /// This is enforced by checking `caller_program_id == Some(self_program_id)`. + /// This is enforced by checking `caller_account_id == Some(self_account_id)`. /// Any attempt to call this instruction as a standalone top-level transaction - /// will be rejected because `caller_program_id` will be `None`. + /// will be rejected because `caller_account_id` will be `None`. InvariantCheck { min_vault_balance: u128 }, } fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -141,7 +141,7 @@ fn main() { }; // Chained call 3: Self-call to enforce the invariant. - // Uses `self_program_id` to reference this program, the key feature that enables + // Uses `self_account_id` to reference this program, the key feature that enables // the "prep → callback → assert" pattern without a separate checker program. // If the callback did not return funds, vault_after_callback.balance < // min_vault_balance and this call will panic, rolling back the entire @@ -152,7 +152,7 @@ fn main() { }) .expect("invariant instruction serialization"); let call_3 = ChainedCall { - program_account_id: self_program_id.into(), // self-referential chained call + program_account_id: self_account_id, // self-referential chained call pre_states: vec![vault_after_callback], instruction_data: invariant_instruction, pda_seeds: vec![], @@ -161,8 +161,8 @@ fn main() { // The initiator itself makes no direct state changes. // All mutations happen inside the chained calls (token transfers). ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![vault_pre.clone(), receiver_pre.clone()], vec![ @@ -177,12 +177,12 @@ fn main() { FlashSwapInstruction::InvariantCheck { min_vault_balance } => { // Visibility enforcement: `InvariantCheck` is an internal instruction. // It must only be called as a chained call from this program itself (via `Initiate`). - // When called as a top-level transaction, `caller_program_id` is `None` → panics. - // When called as a chained call from `Initiate`, `caller_program_id` is - // `Some(self_program_id)` → passes. + // When called as a top-level transaction, `caller_account_id` is `None` → panics. + // When called as a chained call from `Initiate`, `caller_account_id` is + // `Some(self_account_id)` → passes. assert_eq!( - caller_program_id, - Some(self_program_id), + caller_account_id, + Some(self_account_id), "InvariantCheck is an internal instruction: must be called by flash_swap_initiator \ via a chained call", ); @@ -203,8 +203,8 @@ fn main() { // Pass-through: no state changes in the invariant check step. ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![vault.clone()], vec![AccountPostState::new(vault.account)], diff --git a/lee/state_machine/test_methods/guest/src/bin/malicious_authorization_changer.rs b/lee/state_machine/test_methods/guest/src/bin/malicious_authorization_changer.rs index 19e7362cb..33b98f534 100644 --- a/lee/state_machine/test_methods/guest/src/bin/malicious_authorization_changer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/malicious_authorization_changer.rs @@ -14,8 +14,8 @@ type Instruction = (u128, ProgramId); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (balance, transfer_program_id), }, @@ -42,8 +42,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![sender.clone(), receiver.clone()], vec![ diff --git a/lee/state_machine/test_methods/guest/src/bin/malicious_caller_program_id.rs b/lee/state_machine/test_methods/guest/src/bin/malicious_caller_program_id.rs index 171ad6935..c2b28c6a3 100644 --- a/lee/state_machine/test_methods/guest/src/bin/malicious_caller_program_id.rs +++ b/lee/state_machine/test_methods/guest/src/bin/malicious_caller_program_id.rs @@ -7,8 +7,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id: _, // ignore the actual caller + self_account_id, + caller_account_id: _, // ignore the actual caller pre_states, instruction: (), }, @@ -20,12 +20,12 @@ fn main() { .map(|a| AccountPostState::new(a.account.clone())) .collect(); - // Deliberately output wrong caller_program_id. - // A real caller_program_id is None for a top-level call, so we spoof Some(DEFAULT_PROGRAM_ID) + // Deliberately output wrong caller_account_id. + // A real caller_account_id is None for a top-level call, so we spoof Some(DEFAULT_PROGRAM_ID) // to simulate a program claiming it was invoked by another program when it was not. ProgramOutput::new( - self_program_id, - Some(DEFAULT_PROGRAM_ID), // WRONG: should be None for a top-level call + self_account_id, + Some(DEFAULT_PROGRAM_ID.into()), // WRONG: should be None for a top-level call instruction_words, pre_states, post_states, diff --git a/lee/state_machine/test_methods/guest/src/bin/malicious_injector.rs b/lee/state_machine/test_methods/guest/src/bin/malicious_injector.rs index a83752fd0..d5c54d439 100644 --- a/lee/state_machine/test_methods/guest/src/bin/malicious_injector.rs +++ b/lee/state_machine/test_methods/guest/src/bin/malicious_injector.rs @@ -32,8 +32,8 @@ type Instruction = ( fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: ( @@ -89,8 +89,8 @@ fn main() { .expect("serialization is infallible"); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, post_states, diff --git a/lee/state_machine/test_methods/guest/src/bin/malicious_launderer.rs b/lee/state_machine/test_methods/guest/src/bin/malicious_launderer.rs index cc1fdd7d8..3c7a043ca 100644 --- a/lee/state_machine/test_methods/guest/src/bin/malicious_launderer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/malicious_launderer.rs @@ -6,8 +6,8 @@ type Instruction = (ProgramId, u128); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (simple_transfer_id, amount), }, @@ -26,8 +26,8 @@ fn main() { risc0_zkvm::serde::to_vec(&amount).expect("serialization is infallible"); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![], vec![], diff --git a/lee/state_machine/test_methods/guest/src/bin/malicious_self_program_id.rs b/lee/state_machine/test_methods/guest/src/bin/malicious_self_program_id.rs index da719514f..43ed6d153 100644 --- a/lee/state_machine/test_methods/guest/src/bin/malicious_self_program_id.rs +++ b/lee/state_machine/test_methods/guest/src/bin/malicious_self_program_id.rs @@ -7,8 +7,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id: _, // ignore the correct ID - caller_program_id, + self_account_id: _, // ignore the correct ID + caller_account_id, pre_states, instruction: (), }, @@ -20,10 +20,10 @@ fn main() { .map(|a| AccountPostState::new(a.account.clone())) .collect(); - // Deliberately output wrong self_program_id + // Deliberately output wrong self_account_id ProgramOutput::new( - DEFAULT_PROGRAM_ID, // WRONG: should be self_program_id - caller_program_id, + DEFAULT_PROGRAM_ID.into(), // WRONG: should be self_account_id + caller_account_id, instruction_words, pre_states, post_states, diff --git a/lee/state_machine/test_methods/guest/src/bin/minter.rs b/lee/state_machine/test_methods/guest/src/bin/minter.rs index a71c32007..38c2a5417 100644 --- a/lee/state_machine/test_methods/guest/src/bin/minter.rs +++ b/lee/state_machine/test_methods/guest/src/bin/minter.rs @@ -5,8 +5,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, .. }, @@ -25,8 +25,8 @@ fn main() { .expect("Balance overflow"); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![AccountPostState::new(account_post)], diff --git a/lee/state_machine/test_methods/guest/src/bin/missing_output.rs b/lee/state_machine/test_methods/guest/src/bin/missing_output.rs index e8c53a345..0f9a59f9c 100644 --- a/lee/state_machine/test_methods/guest/src/bin/missing_output.rs +++ b/lee/state_machine/test_methods/guest/src/bin/missing_output.rs @@ -5,8 +5,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, .. }, @@ -20,8 +20,8 @@ fn main() { let account_pre1 = pre1.account.clone(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre1, pre2], vec![AccountPostState::new(account_pre1)], diff --git a/lee/state_machine/test_methods/guest/src/bin/modified_transfer.rs b/lee/state_machine/test_methods/guest/src/bin/modified_transfer.rs index c3fe096ae..6fe7dccd7 100644 --- a/lee/state_machine/test_methods/guest/src/bin/modified_transfer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/modified_transfer.rs @@ -64,8 +64,8 @@ fn main() { // Read input accounts. let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: balance_to_move, }, @@ -83,8 +83,8 @@ fn main() { _ => panic!("invalid params"), }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_data, pre_states, post_states, diff --git a/lee/state_machine/test_methods/guest/src/bin/nonce_changer.rs b/lee/state_machine/test_methods/guest/src/bin/nonce_changer.rs index 9b00fc834..7a27ec529 100644 --- a/lee/state_machine/test_methods/guest/src/bin/nonce_changer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/nonce_changer.rs @@ -5,8 +5,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, .. }, @@ -22,8 +22,8 @@ fn main() { account_post.nonce.public_account_nonce_increment(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![AccountPostState::new(account_post)], diff --git a/lee/state_machine/test_methods/guest/src/bin/noop.rs b/lee/state_machine/test_methods/guest/src/bin/noop.rs index 09bd1cca9..4c4d626c4 100644 --- a/lee/state_machine/test_methods/guest/src/bin/noop.rs +++ b/lee/state_machine/test_methods/guest/src/bin/noop.rs @@ -5,8 +5,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, .. }, @@ -18,8 +18,8 @@ fn main() { .map(|account| AccountPostState::new(account.account.clone())) .collect(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, post_states, diff --git a/lee/state_machine/test_methods/guest/src/bin/pda_claimer.rs b/lee/state_machine/test_methods/guest/src/bin/pda_claimer.rs index 2571aadfa..5a8572147 100644 --- a/lee/state_machine/test_methods/guest/src/bin/pda_claimer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/pda_claimer.rs @@ -7,8 +7,8 @@ type Instruction = PdaSeed; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: seed, }, @@ -22,8 +22,8 @@ fn main() { let account_post = AccountPostState::new_claimed(pre.account.clone(), Claim::Pda(seed)); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![account_post], diff --git a/lee/state_machine/test_methods/guest/src/bin/pda_spend_proxy.rs b/lee/state_machine/test_methods/guest/src/bin/pda_spend_proxy.rs index 497119cc1..525027e0c 100644 --- a/lee/state_machine/test_methods/guest/src/bin/pda_spend_proxy.rs +++ b/lee/state_machine/test_methods/guest/src/bin/pda_spend_proxy.rs @@ -12,8 +12,8 @@ type Instruction = (PdaSeed, u128, ProgramId); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (seed, amount, simple_transfer_id), }, @@ -38,8 +38,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![first, second], vec![first_post, second_post], diff --git a/lee/state_machine/test_methods/guest/src/bin/private_pda_delegator.rs b/lee/state_machine/test_methods/guest/src/bin/private_pda_delegator.rs index 20fea644e..af5a0f19c 100644 --- a/lee/state_machine/test_methods/guest/src/bin/private_pda_delegator.rs +++ b/lee/state_machine/test_methods/guest/src/bin/private_pda_delegator.rs @@ -14,8 +14,8 @@ type Instruction = (PdaSeed, PdaSeed, ProgramId); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (claim_seed, delegated_seed, callee_program_id), }, @@ -30,7 +30,7 @@ fn main() { let mut pre_for_callee = pre.clone(); pre_for_callee.is_authorized = true; - pre_for_callee.account.program_owner = self_program_id.into(); + pre_for_callee.account.program_owner = self_account_id; let chained_call = ChainedCall { program_account_id: callee_program_id.into(), @@ -40,8 +40,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![claimed], diff --git a/lee/state_machine/test_methods/guest/src/bin/program_owner_changer.rs b/lee/state_machine/test_methods/guest/src/bin/program_owner_changer.rs index cc3b99369..43c1070b0 100644 --- a/lee/state_machine/test_methods/guest/src/bin/program_owner_changer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/program_owner_changer.rs @@ -5,8 +5,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, .. }, @@ -22,8 +22,8 @@ fn main() { account_post.program_owner = [0, 1, 2, 3, 4, 5, 6, 7].into(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![AccountPostState::new(account_post)], diff --git a/lee/state_machine/test_methods/guest/src/bin/simple_balance_transfer.rs b/lee/state_machine/test_methods/guest/src/bin/simple_balance_transfer.rs index addc4a191..dd5dc75f9 100644 --- a/lee/state_machine/test_methods/guest/src/bin/simple_balance_transfer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/simple_balance_transfer.rs @@ -5,8 +5,8 @@ type Instruction = u128; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: balance, }, @@ -18,8 +18,8 @@ fn main() { AccountPostState::new_claimed_if_default(account_pre.account, Claim::Authorized); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, vec![account_post], @@ -44,8 +44,8 @@ fn main() { .expect("Overflow when adding balance"); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![sender_pre, receiver_pre], vec![ diff --git a/lee/state_machine/test_methods/guest/src/bin/simple_transfer_proxy.rs b/lee/state_machine/test_methods/guest/src/bin/simple_transfer_proxy.rs index ce6b11d17..84d960b8d 100644 --- a/lee/state_machine/test_methods/guest/src/bin/simple_transfer_proxy.rs +++ b/lee/state_machine/test_methods/guest/src/bin/simple_transfer_proxy.rs @@ -32,8 +32,8 @@ type Instruction = (PdaSeed, ProgramId, u128, bool); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (pda_seed, simple_transfer_id, amount, is_withdraw), }, @@ -63,8 +63,8 @@ fn main() { .with_pda_seeds(vec![pda_seed]); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, vec![pda_post, recipient_post], @@ -87,8 +87,8 @@ fn main() { .with_pda_seeds(vec![pda_seed]); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, vec![pda_post], diff --git a/lee/state_machine/test_methods/guest/src/bin/two_pda_claimer.rs b/lee/state_machine/test_methods/guest/src/bin/two_pda_claimer.rs index 57df37d52..acb0b2ff9 100644 --- a/lee/state_machine/test_methods/guest/src/bin/two_pda_claimer.rs +++ b/lee/state_machine/test_methods/guest/src/bin/two_pda_claimer.rs @@ -11,8 +11,8 @@ type Instruction = PdaSeed; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: seed, }, @@ -27,8 +27,8 @@ fn main() { let claim_b = AccountPostState::new_claimed(pre_b.account.clone(), Claim::Pda(seed)); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre_a, pre_b], vec![claim_a, claim_b], diff --git a/lee/state_machine/test_methods/guest/src/bin/validity_window.rs b/lee/state_machine/test_methods/guest/src/bin/validity_window.rs index ad7ecbb7b..f3dcf8972 100644 --- a/lee/state_machine/test_methods/guest/src/bin/validity_window.rs +++ b/lee/state_machine/test_methods/guest/src/bin/validity_window.rs @@ -8,8 +8,8 @@ type Instruction = (BlockValidityWindow, TimestampValidityWindow); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (block_validity_window, timestamp_validity_window), }, @@ -23,8 +23,8 @@ fn main() { let post = pre.account.clone(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![AccountPostState::new(post)], diff --git a/lee/state_machine/test_methods/guest/src/bin/validity_window_chain_caller.rs b/lee/state_machine/test_methods/guest/src/bin/validity_window_chain_caller.rs index 63c131797..59052132a 100644 --- a/lee/state_machine/test_methods/guest/src/bin/validity_window_chain_caller.rs +++ b/lee/state_machine/test_methods/guest/src/bin/validity_window_chain_caller.rs @@ -16,8 +16,8 @@ type Instruction = (BlockValidityWindow, ProgramId, BlockValidityWindow); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (block_validity_window, chained_program_id, chained_block_validity_window), }, @@ -40,8 +40,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![AccountPostState::new(post)], diff --git a/lez/programs/amm/src/main.rs b/lez/programs/amm/src/main.rs index 9d4afc638..df5a6d4e4 100644 --- a/lez/programs/amm/src/main.rs +++ b/lez/programs/amm/src/main.rs @@ -14,8 +14,8 @@ use lee_core::program::{ProgramInput, ProgramOutput, read_lee_inputs}; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -155,8 +155,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states_clone, post_states, diff --git a/lez/programs/associated_token_account/src/main.rs b/lez/programs/associated_token_account/src/main.rs index 2eaa2f3cb..7797242c6 100644 --- a/lez/programs/associated_token_account/src/main.rs +++ b/lez/programs/associated_token_account/src/main.rs @@ -4,8 +4,8 @@ use lee_core::program::{ProgramInput, ProgramOutput, read_lee_inputs}; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -59,8 +59,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states_clone, post_states, diff --git a/lez/programs/authenticated_transfer/src/main.rs b/lez/programs/authenticated_transfer/src/main.rs index 746ad5928..71b6b0be1 100644 --- a/lez/programs/authenticated_transfer/src/main.rs +++ b/lez/programs/authenticated_transfer/src/main.rs @@ -65,8 +65,8 @@ fn main() { // Read input accounts. let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -89,8 +89,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, post_states, diff --git a/lez/programs/bridge/src/main.rs b/lez/programs/bridge/src/main.rs index 1c8f3ca2f..ffc7652dd 100644 --- a/lez/programs/bridge/src/main.rs +++ b/lez/programs/bridge/src/main.rs @@ -16,8 +16,8 @@ fn unchanged_post_states( fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -25,7 +25,7 @@ fn main() { ) = read_lee_inputs::(); assert!( - caller_program_id.is_none(), + caller_account_id.is_none(), "Bridge cannot be invoked through chain calls" ); @@ -44,7 +44,7 @@ fn main() { assert_eq!( bridge.account_id, - bridge_core::compute_bridge_account_id(self_program_id), + bridge_core::compute_bridge_account_id(self_account_id.into()), "First account must be bridge PDA" ); @@ -56,7 +56,7 @@ fn main() { assert_eq!( receipt.account_id, - bridge_core::deposit_receipt_account_id(self_program_id, l1_deposit_op_id), + bridge_core::deposit_receipt_account_id(self_account_id.into(), l1_deposit_op_id), "Third account must be the deposit-receipt PDA" ); @@ -115,7 +115,7 @@ fn main() { // assert_eq!( // bridge.account_id, - // bridge_core::compute_bridge_account_id(self_program_id), + // bridge_core::compute_bridge_account_id(self_account_id.into()), // "Second account must be bridge PDA" // ); @@ -137,8 +137,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states_clone, post_states, diff --git a/lez/programs/bridge_lock/src/main.rs b/lez/programs/bridge_lock/src/main.rs index 4e6e7b7b9..852cac6f6 100644 --- a/lez/programs/bridge_lock/src/main.rs +++ b/lez/programs/bridge_lock/src/main.rs @@ -4,7 +4,7 @@ use bridge_lock_core::{ }; use cross_zone_outbox_core::Instruction as OutboxInstruction; use lee_core::{ - account::{Account, AccountWithMetadata}, + account::{Account, AccountId, AccountWithMetadata}, program::{ AccountPostState, ChainedCall, Claim, ProgramId, ProgramInput, ProgramOutput, read_lee_inputs, @@ -15,8 +15,8 @@ use wrapped_token_core::{Instruction as WrappedInstruction, MAX_MINT_AMOUNT}; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -24,7 +24,7 @@ fn main() { ) = read_lee_inputs::(); assert!( - caller_program_id.is_none(), + caller_account_id.is_none(), "bridge_lock is only invoked as a top-level user transaction" ); @@ -37,8 +37,8 @@ fn main() { payload, ordinal, } => lock( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, amount, @@ -52,8 +52,8 @@ fn main() { outbox_program_id, target_program_id, } => init_config( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, outbox_program_id, @@ -67,8 +67,8 @@ fn main() { reason = "the emission fields are passed through verbatim" )] fn lock( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, amount: u128, @@ -78,6 +78,11 @@ fn lock( payload: Vec, ordinal: u32, ) { + // Recover the real `ProgramId` (RISC0 image id): on this branch every program account lives + // at the direct `AccountId::from(program_id)` bijection, so this round-trip is exact. Needed + // for the PDA-derivation helpers below, which are pinned to the actual image id. + let self_program_id = ProgramId::from(self_account_id); + // pre_states: [config PDA, holder holding (authorized), escrow PDA, outbox PDA]. let [config, holder, escrow, outbox] = <[AccountWithMetadata; 4]>::try_from(pre_states) .expect("Lock requires config, holder, escrow, and outbox accounts"); @@ -131,8 +136,7 @@ fn lock( // genuine holding: a caller cannot substitute an account owned by some other // program to emit the mint without an actual lock. assert_eq!( - holder.account.program_owner, - self_program_id.into(), + holder.account.program_owner, self_account_id, "holder account must be a bridge_lock holding" ); assert_eq!( @@ -179,8 +183,8 @@ fn lock( let config_post = AccountPostState::new(config.account.clone()); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![config, holder, escrow, outbox.clone()], vec![ @@ -197,8 +201,8 @@ fn lock( /// Writes the outbox program and the mint target into the config PDA exactly once /// at genesis. fn init_config( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, outbox_program_id: ProgramId, @@ -209,7 +213,7 @@ fn init_config( .expect("InitConfig requires the config account"); assert_eq!( config.account_id, - config_account_id(self_program_id), + config_account_id(self_account_id.into()), "account must be the bridge-lock config PDA" ); // Init-once, idempotent under genesis replay: a `default` config is a first @@ -218,8 +222,7 @@ fn init_config( // `new_claimed_if_default` alone would not stop a later self-owned rewrite. if config.account != Account::default() { assert_eq!( - config.account.program_owner, - self_program_id.into(), + config.account.program_owner, self_account_id, "bridge-lock config PDA is owned by another program" ); assert_eq!( @@ -238,8 +241,8 @@ fn init_config( AccountPostState::new_claimed_if_default(config_account, Claim::Pda(config_seed())); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![config], vec![config_post], diff --git a/lez/programs/clock/src/main.rs b/lez/programs/clock/src/main.rs index 7bb2c9aa3..54cf62bd5 100644 --- a/lez/programs/clock/src/main.rs +++ b/lez/programs/clock/src/main.rs @@ -39,8 +39,8 @@ fn update_if_multiple( fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: timestamp, }, @@ -60,7 +60,6 @@ fn main() { } // Verify all clock accounts are owned by this program (assigned at genesis). - let self_account_id: lee_core::account::AccountId = self_program_id.into(); if pre_01.account.program_owner != self_account_id || pre_10.account.program_owner != self_account_id || pre_50.account.program_owner != self_account_id @@ -85,8 +84,8 @@ fn main() { let (pre_50, post_50) = update_if_multiple(pre_50, 50, current_block_id, &updated_data); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre_01, pre_10, pre_50], vec![post_01, post_10, post_50], diff --git a/lez/programs/cross_zone_inbox/src/main.rs b/lez/programs/cross_zone_inbox/src/main.rs index feba302bd..bc0357648 100644 --- a/lez/programs/cross_zone_inbox/src/main.rs +++ b/lez/programs/cross_zone_inbox/src/main.rs @@ -4,7 +4,7 @@ use cross_zone_inbox_core::{ }; use cross_zone_marker_core::inbox_source_marker_account_id; use lee_core::{ - account::{Account, AccountWithMetadata}, + account::{Account, AccountId, AccountWithMetadata}, program::{ AccountPostState, ChainedCall, Claim, ProgramId, ProgramInput, ProgramOutput, read_lee_inputs, @@ -18,8 +18,8 @@ fn unchanged(pre: &AccountWithMetadata) -> AccountPostState { fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -27,21 +27,21 @@ fn main() { ) = read_lee_inputs::(); assert!( - caller_program_id.is_none(), + caller_account_id.is_none(), "Inbox is only invoked as a top-level sequencer-origin transaction" ); match instruction { Instruction::Dispatch(msg) => dispatch( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, &msg, ), Instruction::InitConfig(config) => init_config( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, &config, @@ -65,8 +65,8 @@ fn main() { /// mind. User-deployed programs are reachable too, and were written with no /// expectation of an inbox caller at all. fn dispatch( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, msg: &CrossZoneMessage, @@ -76,6 +76,11 @@ fn dispatch( "l1_inclusion_witness must be None in v1" ); + // Recover the real `ProgramId` (RISC0 image id): on this branch every program account lives + // at the direct `AccountId::from(program_id)` bijection, so this round-trip is exact. Needed + // for the PDA-derivation helpers below, which are pinned to the actual image id. + let self_program_id = ProgramId::from(self_account_id); + // pre_states layout: [config, seen_shard, source marker, then the target accounts]. let mut accounts = pre_states.into_iter(); let config = accounts.next().expect("config account required"); @@ -170,8 +175,8 @@ fn dispatch( output_pre_states.extend(target_accounts); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, output_pre_states, post_states, @@ -182,8 +187,8 @@ fn dispatch( /// Writes the inbox config into the config PDA exactly once at genesis. fn init_config( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, config: &InboxConfig, @@ -193,7 +198,7 @@ fn init_config( .expect("InitConfig requires the config account"); assert_eq!( config_meta.account_id, - inbox_config_account_id(self_program_id), + inbox_config_account_id(self_account_id.into()), "account must be the inbox config PDA" ); // Init-once, idempotent under genesis replay: a `default` config is a first @@ -203,8 +208,7 @@ fn init_config( // rewriting its own config data on a later call. if config_meta.account != Account::default() { assert_eq!( - config_meta.account.program_owner, - self_program_id.into(), + config_meta.account.program_owner, self_account_id, "inbox config PDA is owned by another program" ); assert_eq!( @@ -223,8 +227,8 @@ fn init_config( AccountPostState::new_claimed_if_default(config_account, Claim::Pda(inbox_config_seed())); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![config_meta], vec![config_post], diff --git a/lez/programs/cross_zone_outbox/core/src/lib.rs b/lez/programs/cross_zone_outbox/core/src/lib.rs index 66f5dc111..5fa219139 100644 --- a/lez/programs/cross_zone_outbox/core/src/lib.rs +++ b/lez/programs/cross_zone_outbox/core/src/lib.rs @@ -73,7 +73,7 @@ impl OutboxRecord { /// destination zone, and a per-emitter per-zone ordinal. /// /// `emitter` is the program that called `Emit`, which the guest takes from -/// `caller_program_id` rather than from the instruction. Without it in the +/// `caller_account_id` rather than from the instruction. Without it in the /// address two programs share a slot and one overwrites the other. #[must_use] pub fn outbox_pda( diff --git a/lez/programs/cross_zone_outbox/src/main.rs b/lez/programs/cross_zone_outbox/src/main.rs index a4b674df1..520e0274c 100644 --- a/lez/programs/cross_zone_outbox/src/main.rs +++ b/lez/programs/cross_zone_outbox/src/main.rs @@ -1,14 +1,14 @@ use cross_zone_outbox_core::{Instruction, OutboxRecord, outbox_pda, outbox_pda_seed}; use lee_core::{ account::{Account, AccountWithMetadata}, - program::{AccountPostState, Claim, ProgramInput, ProgramOutput, read_lee_inputs}, + program::{AccountPostState, Claim, ProgramId, ProgramInput, ProgramOutput, read_lee_inputs}, }; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -20,7 +20,7 @@ fn main() { // immediate chained caller, not the top-level program that cross-zone // discovery names; the two coincide only while every emitter refuses to be // called by another program, which both do today. - let Some(emitter) = caller_program_id else { + let Some(emitter) = caller_account_id.map(ProgramId::from) else { panic!("Outbox is only callable through a chain call from a user program"); }; @@ -45,7 +45,12 @@ fn main() { assert_eq!( outbox.account_id, - outbox_pda(self_program_id, emitter, &target_zone, ordinal), + outbox_pda( + ProgramId::from(self_account_id), + emitter, + &target_zone, + ordinal + ), "Account must be the outbox PDA for (emitter, target_zone, ordinal)" ); @@ -86,8 +91,8 @@ fn main() { ); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![outbox], vec![post], diff --git a/lez/programs/faucet/src/main.rs b/lez/programs/faucet/src/main.rs index 11bbbce74..295cb7b89 100644 --- a/lez/programs/faucet/src/main.rs +++ b/lez/programs/faucet/src/main.rs @@ -15,8 +15,8 @@ fn unchanged_post_states( fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -24,7 +24,7 @@ fn main() { ) = read_lee_inputs::(); assert!( - caller_program_id.is_none(), + caller_account_id.is_none(), "Faucet cannot be invoked through chain calls" ); @@ -43,7 +43,7 @@ fn main() { assert_eq!( faucet.account_id, - faucet_core::compute_faucet_account_id(self_program_id), + faucet_core::compute_faucet_account_id(self_account_id.into()), "First account must be faucet PDA" ); @@ -69,7 +69,7 @@ fn main() { assert_eq!( faucet.account_id, - faucet_core::compute_faucet_account_id(self_program_id), + faucet_core::compute_faucet_account_id(self_account_id.into()), "First account must be faucet PDA" ); @@ -88,8 +88,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states_clone, post_states, diff --git a/lez/programs/pinata/src/main.rs b/lez/programs/pinata/src/main.rs index cb8df9316..5b8e02c66 100644 --- a/lez/programs/pinata/src/main.rs +++ b/lez/programs/pinata/src/main.rs @@ -46,8 +46,8 @@ fn main() { // It is expected to receive only two accounts: [pinata_account, winner_account] let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: solution, }, @@ -81,8 +81,8 @@ fn main() { .expect("Overflow when adding prize to winner"); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pinata, winner], vec![ diff --git a/lez/programs/pinata_token/src/main.rs b/lez/programs/pinata_token/src/main.rs index 784112cb8..73fd97076 100644 --- a/lez/programs/pinata_token/src/main.rs +++ b/lez/programs/pinata_token/src/main.rs @@ -52,8 +52,8 @@ fn main() { // winner_token_holding] let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: solution, }, @@ -99,8 +99,8 @@ fn main() { .with_pda_seeds(vec![PdaSeed::new([0; 32])]); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![ pinata_definition, diff --git a/lez/programs/ping_receiver/src/main.rs b/lez/programs/ping_receiver/src/main.rs index b9e90b6c4..46dd96d13 100644 --- a/lez/programs/ping_receiver/src/main.rs +++ b/lez/programs/ping_receiver/src/main.rs @@ -1,6 +1,6 @@ use cross_zone_marker_core::inbox_source_marker_account_id; use lee_core::{ - account::{Account, AccountWithMetadata}, + account::{Account, AccountId, AccountWithMetadata}, program::{ AccountPostState, Claim, DEFAULT_PROGRAM_OWNER, ProgramId, ProgramInput, ProgramOutput, read_lee_inputs, @@ -14,8 +14,8 @@ use ping_core::{ fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -24,15 +24,15 @@ fn main() { match instruction { ReceiverInstruction::Record { payload } => record( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, payload, ), ReceiverInstruction::InitConfig(config) => init_config( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, &config, @@ -54,12 +54,17 @@ fn main() { } fn record( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, payload: Vec, ) { + // Recover the real `ProgramId` (RISC0 image id): on this branch every program account lives + // at the direct `AccountId::from(program_id)` bijection, so this round-trip is exact. Needed + // for the PDA-derivation helpers below, which are pinned to the actual image id. + let self_program_id = ProgramId::from(self_account_id); + // pre_states: [source marker, config PDA, record PDA]. let [marker, config, record] = <[AccountWithMetadata; 3]>::try_from(pre_states) .expect("Record requires the source marker, config, and record accounts"); @@ -72,8 +77,8 @@ fn record( let cfg = ReceiverConfig::from_bytes(&config.account.data) .expect("config account holds a receiver config"); assert_eq!( - caller_program_id, - Some(cfg.deliverer), + caller_account_id, + Some(cfg.deliverer.into()), "Record is only callable by the authorized deliverer (the cross-zone inbox)" ); // Which peer sent it is this program's own business. Without this the record @@ -98,8 +103,8 @@ fn record( AccountPostState::new_claimed_if_default(post_account, Claim::Pda(ping_record_seed())); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![marker.clone(), config.clone(), record], vec![ @@ -256,14 +261,14 @@ fn update_sources( /// Writes the deliverer and the authorized peer sources into the config PDA /// exactly once at genesis. fn init_config( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, config_value: &ReceiverConfig, ) { assert!( - caller_program_id.is_none(), + caller_account_id.is_none(), "InitConfig is a top-level genesis transaction" ); @@ -272,7 +277,7 @@ fn init_config( .expect("InitConfig requires the config account"); assert_eq!( config.account_id, - receiver_config_account_id(self_program_id), + receiver_config_account_id(self_account_id.into()), "account must be the receiver config PDA" ); // Init-once, idempotent under genesis replay: a `default` config is a first @@ -281,8 +286,7 @@ fn init_config( // `new_claimed_if_default` alone would not stop a later self-owned rewrite. if config.account != Account::default() { assert_eq!( - config.account.program_owner, - self_program_id.into(), + config.account.program_owner, self_account_id, "receiver config PDA is owned by another program" ); assert_eq!( @@ -303,8 +307,8 @@ fn init_config( ); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![config], vec![config_post], diff --git a/lez/programs/ping_sender/src/main.rs b/lez/programs/ping_sender/src/main.rs index f9682745b..fdb3f7b6b 100644 --- a/lez/programs/ping_sender/src/main.rs +++ b/lez/programs/ping_sender/src/main.rs @@ -1,6 +1,6 @@ use cross_zone_outbox_core::Instruction as OutboxInstruction; use lee_core::{ - account::{Account, AccountWithMetadata}, + account::{Account, AccountId, AccountWithMetadata}, program::{ AccountPostState, ChainedCall, Claim, ProgramId, ProgramInput, ProgramOutput, read_lee_inputs, @@ -13,8 +13,8 @@ use ping_core::{ fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -22,7 +22,7 @@ fn main() { ) = read_lee_inputs::(); assert!( - caller_program_id.is_none(), + caller_account_id.is_none(), "ping_sender is only invoked as a top-level user transaction" ); @@ -34,8 +34,8 @@ fn main() { payload, ordinal, } => send( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, target_zone, @@ -45,8 +45,8 @@ fn main() { ordinal, ), SenderInstruction::InitConfig { outbox_program_id } => init_config( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, outbox_program_id, @@ -59,8 +59,8 @@ fn main() { reason = "the emission fields are passed through verbatim" )] fn send( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, target_zone: [u8; 32], @@ -78,7 +78,7 @@ fn send( // skip the real outbox and leave no record of itself. assert_eq!( config.account_id, - sender_config_account_id(self_program_id), + sender_config_account_id(self_account_id.into()), "first account must be the ping-sender config PDA" ); let outbox_program_id = @@ -99,8 +99,8 @@ fn send( let config_post = AccountPostState::new(config.account.clone()); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![config, outbox.clone()], vec![config_post, AccountPostState::new(outbox.account)], @@ -111,8 +111,8 @@ fn send( /// Writes the outbox program id into the config PDA exactly once at genesis. fn init_config( - self_program_id: ProgramId, - caller_program_id: Option, + self_account_id: AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, outbox_program_id: ProgramId, @@ -122,7 +122,7 @@ fn init_config( .expect("InitConfig requires the config account"); assert_eq!( config.account_id, - sender_config_account_id(self_program_id), + sender_config_account_id(self_account_id.into()), "account must be the ping-sender config PDA" ); // Init-once, idempotent under genesis replay: a `default` config is a first @@ -131,8 +131,7 @@ fn init_config( // `new_claimed_if_default` alone would not stop a later self-owned rewrite. if config.account != Account::default() { assert_eq!( - config.account.program_owner, - self_program_id.into(), + config.account.program_owner, self_account_id, "ping-sender config PDA is owned by another program" ); assert_eq!( @@ -151,8 +150,8 @@ fn init_config( AccountPostState::new_claimed_if_default(config_account, Claim::Pda(sender_config_seed())); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![config], vec![config_post], diff --git a/lez/programs/token/src/main.rs b/lez/programs/token/src/main.rs index 6e5cb8df1..84bb5fe56 100644 --- a/lez/programs/token/src/main.rs +++ b/lez/programs/token/src/main.rs @@ -12,8 +12,8 @@ use token_program::core::Instruction; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -84,8 +84,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states_clone, post_states, diff --git a/lez/programs/vault/src/main.rs b/lez/programs/vault/src/main.rs index 929248665..34a06cf20 100644 --- a/lez/programs/vault/src/main.rs +++ b/lez/programs/vault/src/main.rs @@ -22,8 +22,8 @@ fn unchanged_post_states( fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -83,8 +83,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states_clone, post_states, diff --git a/lez/programs/wrapped_token/src/main.rs b/lez/programs/wrapped_token/src/main.rs index 311ef2614..19c82aa10 100644 --- a/lez/programs/wrapped_token/src/main.rs +++ b/lez/programs/wrapped_token/src/main.rs @@ -14,8 +14,8 @@ use wrapped_token_core::{ fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -24,16 +24,16 @@ fn main() { match instruction { Instruction::Mint { recipient, amount } => mint( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, recipient, amount, ), Instruction::InitConfig(config) => init_config( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction_words, &config, @@ -55,13 +55,18 @@ fn main() { } fn mint( - self_program_id: lee_core::program::ProgramId, - caller_program_id: Option, + self_account_id: lee_core::account::AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, recipient: [u8; 32], amount: u128, ) { + // Recover the real `ProgramId` (RISC0 image id): on this branch every program account lives + // at the direct `AccountId::from(program_id)` bijection, so this round-trip is exact. Needed + // for the PDA-derivation helpers below, which are pinned to the actual image id. + let self_program_id = lee_core::program::ProgramId::from(self_account_id); + // pre_states: [source marker, config PDA, recipient holding PDA]. let [marker, config, holding] = <[AccountWithMetadata; 3]>::try_from(pre_states) .expect("Mint requires the source marker, config, and recipient holding accounts"); @@ -76,8 +81,8 @@ fn mint( let cfg = WrappedTokenConfig::from_bytes(&config.account.data) .expect("config account holds a wrapped-token config"); assert_eq!( - caller_program_id, - Some(cfg.minter), + caller_account_id, + Some(cfg.minter.into()), "Mint is only callable by the authorized minter (the cross-zone inbox)" ); // The inbox vouches only that the message arrived; which peer sent it is this @@ -118,8 +123,8 @@ fn mint( let config_post = AccountPostState::new(config.account.clone()); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![marker.clone(), config, holding], vec![ @@ -276,14 +281,14 @@ fn update_sources( /// Writes the minter and the authorized peer sources into the config PDA exactly /// once at genesis. fn init_config( - self_program_id: lee_core::program::ProgramId, - caller_program_id: Option, + self_account_id: lee_core::account::AccountId, + caller_account_id: Option, pre_states: Vec, instruction_words: Vec, config_value: &WrappedTokenConfig, ) { assert!( - caller_program_id.is_none(), + caller_account_id.is_none(), "InitConfig is a top-level genesis transaction" ); @@ -292,7 +297,7 @@ fn init_config( .expect("InitConfig requires the config account"); assert_eq!( config.account_id, - config_account_id(self_program_id), + config_account_id(self_account_id.into()), "account must be the wrapped-token config PDA" ); // Init-once, idempotent under genesis replay: a `default` config is a first @@ -303,8 +308,7 @@ fn init_config( // rewriting its own config data on a later call. if config.account != Account::default() { assert_eq!( - config.account.program_owner, - self_program_id.into(), + config.account.program_owner, self_account_id, "wrapped-token config PDA is owned by another program" ); assert_eq!( @@ -323,8 +327,8 @@ fn init_config( AccountPostState::new_claimed_if_default(config_account, Claim::Pda(config_seed())); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![config], vec![config_post], diff --git a/test_programs/guest/src/bin/chain_caller.rs b/test_programs/guest/src/bin/chain_caller.rs index 155bf8fcf..b4b932dc3 100644 --- a/test_programs/guest/src/bin/chain_caller.rs +++ b/test_programs/guest/src/bin/chain_caller.rs @@ -13,8 +13,8 @@ type Instruction = (u128, ProgramId, u32, Option); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (balance, auth_transfer_id, num_chain_calls, pda_seed), }, @@ -57,8 +57,8 @@ fn main() { } ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![sender_pre.clone(), recipient_pre.clone()], vec![ diff --git a/test_programs/guest/src/bin/claimer.rs b/test_programs/guest/src/bin/claimer.rs index b0efe9925..1f98b899d 100644 --- a/test_programs/guest/src/bin/claimer.rs +++ b/test_programs/guest/src/bin/claimer.rs @@ -5,8 +5,8 @@ type Instruction = (); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (), }, @@ -20,8 +20,8 @@ fn main() { let account_post = AccountPostState::new_claimed(pre.account.clone(), Claim::Authorized); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pre], vec![account_post], diff --git a/test_programs/guest/src/bin/clock_chain_caller.rs b/test_programs/guest/src/bin/clock_chain_caller.rs index 43303308f..6bcdbcfb5 100644 --- a/test_programs/guest/src/bin/clock_chain_caller.rs +++ b/test_programs/guest/src/bin/clock_chain_caller.rs @@ -14,8 +14,8 @@ type Instruction = (ProgramId, Timestamp); // (clock_program_id, timestamp) fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (clock_program_id, timestamp), }, @@ -35,8 +35,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, post_states, diff --git a/test_programs/guest/src/bin/faucet_chain_caller.rs b/test_programs/guest/src/bin/faucet_chain_caller.rs index d71c50bab..f0f73cb65 100644 --- a/test_programs/guest/src/bin/faucet_chain_caller.rs +++ b/test_programs/guest/src/bin/faucet_chain_caller.rs @@ -12,8 +12,8 @@ type Instruction = (ProgramId, ProgramId, AccountId, u128); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (faucet_program_id, vault_program_id, recipient_id, amount), }, @@ -41,8 +41,8 @@ fn main() { }]; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, post_states, diff --git a/test_programs/guest/src/bin/pda_spend_proxy.rs b/test_programs/guest/src/bin/pda_spend_proxy.rs index 6bea40bd1..7af8c86de 100644 --- a/test_programs/guest/src/bin/pda_spend_proxy.rs +++ b/test_programs/guest/src/bin/pda_spend_proxy.rs @@ -12,8 +12,8 @@ type Instruction = (PdaSeed, u128, ProgramId); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (seed, amount, auth_transfer_id), }, @@ -39,8 +39,8 @@ fn main() { }; ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![first, second], vec![first_post, second_post], diff --git a/test_programs/guest/src/bin/pinata_cooldown.rs b/test_programs/guest/src/bin/pinata_cooldown.rs index 24e572dc7..a58df94cb 100644 --- a/test_programs/guest/src/bin/pinata_cooldown.rs +++ b/test_programs/guest/src/bin/pinata_cooldown.rs @@ -48,8 +48,8 @@ impl PinataState { fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (), }, @@ -102,8 +102,8 @@ fn main() { let clock_post = clock_pre.account.clone(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![pinata, winner, clock_pre], vec![ diff --git a/test_programs/guest/src/bin/simple_balance_transfer.rs b/test_programs/guest/src/bin/simple_balance_transfer.rs index addc4a191..dd5dc75f9 100644 --- a/test_programs/guest/src/bin/simple_balance_transfer.rs +++ b/test_programs/guest/src/bin/simple_balance_transfer.rs @@ -5,8 +5,8 @@ type Instruction = u128; fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: balance, }, @@ -18,8 +18,8 @@ fn main() { AccountPostState::new_claimed_if_default(account_pre.account, Claim::Authorized); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, pre_states, vec![account_post], @@ -44,8 +44,8 @@ fn main() { .expect("Overflow when adding balance"); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![sender_pre, receiver_pre], vec![ diff --git a/test_programs/guest/src/bin/time_locked_transfer.rs b/test_programs/guest/src/bin/time_locked_transfer.rs index 76391b892..f07b58e9a 100644 --- a/test_programs/guest/src/bin/time_locked_transfer.rs +++ b/test_programs/guest/src/bin/time_locked_transfer.rs @@ -18,8 +18,8 @@ type Instruction = (u128, u64); fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction: (amount, deadline), }, @@ -58,8 +58,8 @@ fn main() { let clock_post = clock_pre.account.clone(); ProgramOutput::new( - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, instruction_words, vec![sender_pre, receiver_pre, clock_pre], vec![ diff --git a/tools/cycle_bench/src/main.rs b/tools/cycle_bench/src/main.rs index 97e0efdc7..4c965367f 100644 --- a/tools/cycle_bench/src/main.rs +++ b/tools/cycle_bench/src/main.rs @@ -203,7 +203,7 @@ impl Case { pre_states, instruction_words, } = self; - let caller_program_id: Option = None; + let caller_account_id: Option = None; // One warmup pass discarded, then `exec_iters` samples. The executor has // large per-call setup overhead (ELF parsing, env init); reporting both @@ -215,7 +215,7 @@ impl Case { let mut env_builder = ExecutorEnv::builder(); env_builder .write(&program.id())? - .write(&caller_program_id)? + .write(&caller_account_id)? .write(&pre_states)? .write(&instruction_words)?; let env = env_builder.build()?; @@ -241,7 +241,7 @@ impl Case { let mut env_builder = ExecutorEnv::builder(); env_builder .write(&program.id())? - .write(&caller_program_id)? + .write(&caller_account_id)? .write(&pre_states)? .write(&instruction_words)?; let env = env_builder.build()?;