mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-08-25 11:21:12 +00:00
refactor(lee): migrate program self/caller identity from ProgramId to AccountId
ProgramInput/ProgramOutput.self_program_id/caller_program_id, and the dispatcher's CallerData.program_id, now carry AccountId (renamed to self_account_id/caller_account_id) instead of ProgramId. These fields are self-reported/cross-checked dispatch bookkeeping, not RISC0 image identity, and AccountId already crosses the guest/host boundary this way via every pre_state.account_id. ProgramId is now confined to what's actually image-id-keyed: env::verify, Program.id (from compute_image_id()), and the for_public_pda/for_private_pda derivation formulas, each recovering the real ProgramId from AccountId via the existing bijection exactly where needed. Rebuilds artifacts and the prebuilt sequencer db fixture to match.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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],
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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<ProgramId>,
|
||||
caller_account_id: Option<AccountId>,
|
||||
caller_pda_seeds: &[PdaSeed],
|
||||
output_pre_states: Vec<AccountWithMetadata>,
|
||||
output_post_states: Vec<AccountPostState>,
|
||||
@@ -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<AccountId>,
|
||||
pre_account_id: AccountId,
|
||||
pre_state_position: usize,
|
||||
caller_program_id: Option<ProgramId>,
|
||||
caller_account_id: Option<AccountId>,
|
||||
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));
|
||||
|
||||
@@ -50,8 +50,8 @@ impl From<AccountId> for ProgramId {
|
||||
|
||||
pub type InstructionData = Vec<u32>;
|
||||
pub struct ProgramInput<T> {
|
||||
pub self_program_id: ProgramId,
|
||||
pub caller_program_id: Option<ProgramId>,
|
||||
pub self_account_id: AccountId,
|
||||
pub caller_account_id: Option<AccountId>,
|
||||
pub pre_states: Vec<AccountWithMetadata>,
|
||||
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<PdaSeed>,
|
||||
}
|
||||
@@ -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<ProgramId>,
|
||||
pub caller_account_id: Option<AccountId>,
|
||||
/// 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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
instruction_data: InstructionData,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
post_states: Vec<AccountPostState>,
|
||||
) -> 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<ProgramId>,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pda_seeds: &[PdaSeed],
|
||||
) -> HashSet<AccountId> {
|
||||
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<T: DeserializeOwned>() -> (ProgramInput<T>, InstructionData) {
|
||||
let self_program_id: ProgramId = env::read();
|
||||
let caller_program_id: Option<ProgramId> = env::read();
|
||||
let self_account_id: AccountId = env::read();
|
||||
let caller_account_id: Option<AccountId> = env::read();
|
||||
let pre_states: Vec<AccountWithMetadata> = 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,
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -107,8 +107,8 @@ pub enum InvalidProgramBehaviorError {
|
||||
|
||||
#[error("Caller program ID mismatch: expected {expected:?}, actual {actual:?}")]
|
||||
MismatchedCallerProgramId {
|
||||
expected: Option<ProgramId>,
|
||||
actual: Option<ProgramId>,
|
||||
expected: Option<AccountId>,
|
||||
actual: Option<AccountId>,
|
||||
},
|
||||
|
||||
#[error(transparent)]
|
||||
|
||||
@@ -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<ProgramId>,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: &[AccountWithMetadata],
|
||||
instruction_data: &InstructionData,
|
||||
) -> Result<Receipt, LeeError> {
|
||||
// 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,
|
||||
|
||||
@@ -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<ProgramId>,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: &[AccountWithMetadata],
|
||||
instruction_data: &InstructionData,
|
||||
) -> Result<ProgramOutput, LeeError> {
|
||||
@@ -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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
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
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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<ProgramId>,
|
||||
caller_account_id: Option<AccountId>,
|
||||
authorized_accounts: HashSet<AccountId>,
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -12,8 +12,8 @@ type Instruction = (u128, ProgramId, u32, Option<PdaSeed>);
|
||||
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![
|
||||
|
||||
@@ -6,8 +6,8 @@ type Instruction = (Option<Vec<u8>>, 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],
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -6,8 +6,8 @@ type Instruction = Vec<u8>;
|
||||
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(
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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![],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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)],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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::<Instruction>();
|
||||
|
||||
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,
|
||||
|
||||
@@ -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::<Instruction>();
|
||||
|
||||
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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
amount: u128,
|
||||
@@ -78,6 +78,11 @@ fn lock(
|
||||
payload: Vec<u8>,
|
||||
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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
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],
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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::<Instruction>();
|
||||
|
||||
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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
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],
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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::<Instruction>();
|
||||
|
||||
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,
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
payload: Vec<u8>,
|
||||
) {
|
||||
// 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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
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],
|
||||
|
||||
@@ -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::<SenderInstruction>();
|
||||
|
||||
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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
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<ProgramId>,
|
||||
self_account_id: AccountId,
|
||||
caller_account_id: Option<AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
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],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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<lee_core::program::ProgramId>,
|
||||
self_account_id: lee_core::account::AccountId,
|
||||
caller_account_id: Option<lee_core::account::AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
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<lee_core::program::ProgramId>,
|
||||
self_account_id: lee_core::account::AccountId,
|
||||
caller_account_id: Option<lee_core::account::AccountId>,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
instruction_words: Vec<u32>,
|
||||
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],
|
||||
|
||||
Binary file not shown.
@@ -13,8 +13,8 @@ type Instruction = (u128, ProgramId, u32, Option<PdaSeed>);
|
||||
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![
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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],
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -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![
|
||||
|
||||
@@ -203,7 +203,7 @@ impl Case {
|
||||
pre_states,
|
||||
instruction_words,
|
||||
} = self;
|
||||
let caller_program_id: Option<ProgramId> = None;
|
||||
let caller_account_id: Option<ProgramId> = 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()?;
|
||||
|
||||
Reference in New Issue
Block a user