diff --git a/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin b/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin index e8d8f7f3a..7b2ab3318 100644 Binary files a/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin and b/artifacts/lee/privacy_preserving_circuit/privacy_preserving_circuit.bin differ diff --git a/artifacts/lez/programs/amm.bin b/artifacts/lez/programs/amm.bin index a945c0c3b..340bacbf4 100644 Binary files a/artifacts/lez/programs/amm.bin and b/artifacts/lez/programs/amm.bin differ diff --git a/artifacts/lez/programs/associated_token_account.bin b/artifacts/lez/programs/associated_token_account.bin index 0e3c31ccb..3dfee7d04 100644 Binary files a/artifacts/lez/programs/associated_token_account.bin and b/artifacts/lez/programs/associated_token_account.bin differ diff --git a/artifacts/lez/programs/authenticated_transfer.bin b/artifacts/lez/programs/authenticated_transfer.bin index e2163b8aa..fae0687dd 100644 Binary files a/artifacts/lez/programs/authenticated_transfer.bin and b/artifacts/lez/programs/authenticated_transfer.bin differ diff --git a/artifacts/lez/programs/bridge.bin b/artifacts/lez/programs/bridge.bin index 2c98b0061..ea59667b3 100644 Binary files a/artifacts/lez/programs/bridge.bin and b/artifacts/lez/programs/bridge.bin differ diff --git a/artifacts/lez/programs/bridge_lock.bin b/artifacts/lez/programs/bridge_lock.bin index ea0b6d035..a5276bccf 100644 Binary files a/artifacts/lez/programs/bridge_lock.bin and b/artifacts/lez/programs/bridge_lock.bin differ diff --git a/artifacts/lez/programs/clock.bin b/artifacts/lez/programs/clock.bin index c8c9e508d..9c00efb3d 100644 Binary files a/artifacts/lez/programs/clock.bin and b/artifacts/lez/programs/clock.bin differ diff --git a/artifacts/lez/programs/cross_zone_inbox.bin b/artifacts/lez/programs/cross_zone_inbox.bin index c45e3f60d..43d7abb91 100644 Binary files a/artifacts/lez/programs/cross_zone_inbox.bin and b/artifacts/lez/programs/cross_zone_inbox.bin differ diff --git a/artifacts/lez/programs/cross_zone_outbox.bin b/artifacts/lez/programs/cross_zone_outbox.bin index d181e1b7b..1a2d16efe 100644 Binary files a/artifacts/lez/programs/cross_zone_outbox.bin and b/artifacts/lez/programs/cross_zone_outbox.bin differ diff --git a/artifacts/lez/programs/faucet.bin b/artifacts/lez/programs/faucet.bin index 7457c46c5..0dd638529 100644 Binary files a/artifacts/lez/programs/faucet.bin and b/artifacts/lez/programs/faucet.bin differ diff --git a/artifacts/lez/programs/pinata.bin b/artifacts/lez/programs/pinata.bin index c423888de..26502dbaf 100644 Binary files a/artifacts/lez/programs/pinata.bin and b/artifacts/lez/programs/pinata.bin differ diff --git a/artifacts/lez/programs/pinata_token.bin b/artifacts/lez/programs/pinata_token.bin index 12fd77796..1612df804 100644 Binary files a/artifacts/lez/programs/pinata_token.bin and b/artifacts/lez/programs/pinata_token.bin differ diff --git a/artifacts/lez/programs/ping_receiver.bin b/artifacts/lez/programs/ping_receiver.bin index c2578b4ed..671e83813 100644 Binary files a/artifacts/lez/programs/ping_receiver.bin and b/artifacts/lez/programs/ping_receiver.bin differ diff --git a/artifacts/lez/programs/ping_sender.bin b/artifacts/lez/programs/ping_sender.bin index 43b51c500..8fb035ea9 100644 Binary files a/artifacts/lez/programs/ping_sender.bin and b/artifacts/lez/programs/ping_sender.bin differ diff --git a/artifacts/lez/programs/token.bin b/artifacts/lez/programs/token.bin index f8b2106f6..6f71ac24b 100644 Binary files a/artifacts/lez/programs/token.bin and b/artifacts/lez/programs/token.bin differ diff --git a/artifacts/lez/programs/vault.bin b/artifacts/lez/programs/vault.bin index 19a25d0a0..6af4f35b5 100644 Binary files a/artifacts/lez/programs/vault.bin and b/artifacts/lez/programs/vault.bin differ diff --git a/artifacts/lez/programs/wrapped_token.bin b/artifacts/lez/programs/wrapped_token.bin index d429276ad..2d872d5ad 100644 Binary files a/artifacts/lez/programs/wrapped_token.bin and b/artifacts/lez/programs/wrapped_token.bin differ 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 b958b6033..0b2731b23 100644 --- a/lee/privacy_preserving_circuit/src/execution_state.rs +++ b/lee/privacy_preserving_circuit/src/execution_state.rs @@ -130,7 +130,7 @@ impl ExecutionState { let mut program_outputs_iter = program_outputs.into_iter(); let mut chain_calls_counter = 0; - while let Some((chained_call, caller_program_id)) = chained_calls.pop_front() { + while let Some((chained_call, caller_account_id)) = chained_calls.pop_front() { assert!( chain_calls_counter <= MAX_NUMBER_CHAINED_CALLS, "Max chained calls depth is exceeded" @@ -161,20 +161,20 @@ 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_program_id, - "Program output caller_program_id does not match actual caller" + program_output.caller_account_id, caller_account_id, + "Program output caller_account_id does not match actual caller" ); // Check that the program is well behaved. @@ -189,13 +189,14 @@ impl ExecutionState { } for next_call in program_output.chained_calls.iter().rev() { - chained_calls.push_front((next_call.clone(), Some(current_program_id))); + chained_calls + .push_front((next_call.clone(), Some(chained_call.program_account_id))); } execution_state.validate_and_sync_states( account_identities, current_program_id, - caller_program_id, + caller_account_id, &chained_call.pda_seeds, program_output.pre_states, program_output.post_states, @@ -254,7 +255,7 @@ impl ExecutionState { &mut self, account_identities: &[InputAccountIdentity], program_id: ProgramId, - caller_program_id: Option, + caller_account_id: Option, caller_pda_seeds: &[PdaSeed], output_pre_states: Vec, output_post_states: Vec, @@ -301,7 +302,7 @@ impl ExecutionState { &mut self.authorized_accounts, pre_account_id, pre_state_position, - caller_program_id, + caller_account_id, caller_pda_seeds, previous_is_authorized, ); @@ -536,7 +537,7 @@ fn bind_private_pda_position( /// previously-seen authorization or a matching caller seed (under the public or private /// derivation). When a caller seed matches, also records the `(caller, seed) → account_id` /// family binding and, for the private form, marks the position in -/// `private_pda_bound_positions`. Only reachable when `caller_program_id.is_some()`, +/// `private_pda_bound_positions`. Only reachable when `caller_account_id.is_some()`, /// top-level flows have no caller-emitted seeds, so binding at top level must come from the /// claim path. Free function so callers can pass individual `&mut self.*` field borrows /// without holding a borrow on the surrounding struct's other fields. @@ -551,12 +552,16 @@ fn resolve_authorization_and_record_bindings( authorized_accounts: &mut HashSet, pre_account_id: AccountId, pre_state_position: usize, - caller_program_id: Option, + caller_account_id: Option, caller_pda_seeds: &[PdaSeed], previous_is_authorized: bool, ) -> bool { + // 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`/`for_private_pda`'s derivation formula is pinned to the caller's actual + // image id, not its dispatch-facing `AccountId`. let matched_caller_seed: Option<(PdaSeed, bool, ProgramId)> = - caller_program_id.and_then(|caller| { + caller_account_id.map(ProgramId::from).and_then(|caller| { caller_pda_seeds.iter().find_map(|seed| { if AccountId::for_public_pda(&caller, seed) == pre_account_id { return Some((*seed, false, caller)); diff --git a/lee/state_machine/core/src/program/mod.rs b/lee/state_machine/core/src/program/mod.rs index 4eb1416ff..c647876b0 100644 --- a/lee/state_machine/core/src/program/mod.rs +++ b/lee/state_machine/core/src/program/mod.rs @@ -50,8 +50,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, } @@ -240,7 +240,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, } @@ -462,11 +462,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. @@ -483,15 +483,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, @@ -664,12 +664,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)) @@ -679,15 +684,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 fe09fed01..df72d2e98 100644 --- a/lee/state_machine/src/validated_state_diff/mod.rs +++ b/lee/state_machine/src/validated_state_diff/mod.rs @@ -98,7 +98,7 @@ impl ValidatedStateDiff { }; let initial_caller_data = CallerData { - program_id: None, + caller_account_id: None, authorized_accounts: signer_account_ids.iter().copied().collect(), }; @@ -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, } ); @@ -288,7 +290,7 @@ impl ValidatedStateDiff { chained_calls.push_front(( new_call, CallerData { - program_id: Some(program_id), + caller_account_id: Some(chained_call.program_account_id), authorized_accounts: authorized_accounts.clone(), }, )); @@ -481,7 +483,7 @@ impl ValidatedStateDiff { #[derive(Debug)] struct CallerData { - program_id: Option, + caller_account_id: Option, authorized_accounts: HashSet, } 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 4a4ea65da..098cde2a7 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), }, @@ -37,8 +37,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 f31a8c8d2..4042e862c 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 d7ee0432d..33eef99e3 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 60171bd77..be899d405 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 096ad80d9..646c9c248 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::{ 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, @@ -51,8 +51,8 @@ fn main() { /// Delivers a finalized peer message to its target program, no-op on replay. 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, @@ -62,6 +62,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"); @@ -158,8 +163,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, @@ -170,8 +175,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, @@ -181,7 +186,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 @@ -191,8 +196,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!( @@ -211,8 +215,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 74a450e6f..fcf07485b 100644 --- a/lez/programs/ping_receiver/src/main.rs +++ b/lez/programs/ping_receiver/src/main.rs @@ -1,6 +1,6 @@ use cross_zone_inbox_core::inbox_source_marker_account_id; use lee_core::{ - account::{Account, AccountWithMetadata}, + account::{Account, AccountId, AccountWithMetadata}, program::{AccountPostState, Claim, ProgramId, ProgramInput, ProgramOutput, read_lee_inputs}, }; use ping_core::{ @@ -11,8 +11,8 @@ use ping_core::{ fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -21,15 +21,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, @@ -38,12 +38,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"); @@ -56,8 +61,8 @@ fn record( let cfg = ReceiverConfig::from_bytes(&config.account.data.clone().into_inner()) .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 @@ -82,8 +87,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![ @@ -98,14 +103,14 @@ fn record( /// 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" ); @@ -114,7 +119,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 @@ -123,8 +128,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!( @@ -145,8 +149,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 014c93749..134d4b9d6 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 = read_outbox(&config.account.data.clone().into_inner()) @@ -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 4fc6b314d..7b9fc3c3b 100644 --- a/lez/programs/wrapped_token/src/main.rs +++ b/lez/programs/wrapped_token/src/main.rs @@ -11,8 +11,8 @@ use wrapped_token_core::{ fn main() { let ( ProgramInput { - self_program_id, - caller_program_id, + self_account_id, + caller_account_id, pre_states, instruction, }, @@ -21,16 +21,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, @@ -39,13 +39,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"); @@ -60,8 +65,8 @@ fn mint( let cfg = WrappedTokenConfig::from_bytes(&config.account.data.clone().into_inner()) .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 @@ -102,8 +107,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![ @@ -118,14 +123,14 @@ fn mint( /// 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" ); @@ -134,7 +139,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 @@ -145,8 +150,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!( @@ -165,8 +169,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_fixtures/fixtures/prebuilt_sequencer_db.dump b/test_fixtures/fixtures/prebuilt_sequencer_db.dump index 75c9f9c23..78761fbd6 100644 Binary files a/test_fixtures/fixtures/prebuilt_sequencer_db.dump and b/test_fixtures/fixtures/prebuilt_sequencer_db.dump differ 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 87e26223a..6568eff61 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), }, @@ -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/test_programs/guest/src/bin/pinata_cooldown.rs b/test_programs/guest/src/bin/pinata_cooldown.rs index 160fba21a..03d57c805 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 8746ef846..163b8ec8a 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()?;