mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-08-27 04:11:08 +00:00
test(lee): add Deploy validation-failure and chained-call coverage
Adds tests for the remaining execute_deploy failure modes (invalid bytecode, wrong target account, wrong number of accounts) and a generic chained_call_forwarder test guest to exercise Deploy invoked via a chained call rather than only top-level. The chained-call test is #[ignore]d: it surfaces a real limitation, not a bug in the test. The forwarding program has to carry the deployed bytecode through its own instruction_data to build the chained call, which blows the interpreted 32M-cycle public-execution cap for any realistically-sized program — the native Deploy fast-path only covers the loader's own execution, not the caller's. Root cause is ChainedCall/Message still referencing programs by ProgramId rather than AccountId, which also means dispatch can't locate a Deploy-created (PDA-addressed) program at all. Tracked for marvin/program-as-account-3-1.
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
use lee_core::program::{
|
||||
AccountPostState, ChainedCall, ProgramId, ProgramInput, ProgramOutput, read_lee_inputs,
|
||||
};
|
||||
|
||||
/// Forwards a single chained call to `target_program_id` with `instruction_data`, passing
|
||||
/// through whatever `pre_states` this program itself was invoked with unchanged.
|
||||
///
|
||||
/// Exists purely as test infrastructure: lets a test exercise "program X invokes program Y via
|
||||
/// a chained call" for an arbitrary Y and instruction, without needing a purpose-built guest for
|
||||
/// every target program under test.
|
||||
type Instruction = (ProgramId, Vec<u32>);
|
||||
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
caller_program_id,
|
||||
pre_states,
|
||||
instruction: (target_program_id, instruction_data),
|
||||
},
|
||||
instruction_words,
|
||||
) = read_lee_inputs::<Instruction>();
|
||||
|
||||
let post_states = pre_states
|
||||
.iter()
|
||||
.map(|pre| AccountPostState::new(pre.account.clone()))
|
||||
.collect();
|
||||
|
||||
let chained_call = ChainedCall {
|
||||
program_id: target_program_id,
|
||||
instruction_data,
|
||||
pre_states: pre_states.clone(),
|
||||
pda_seeds: vec![],
|
||||
};
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
caller_program_id,
|
||||
instruction_words,
|
||||
pre_states,
|
||||
post_states,
|
||||
)
|
||||
.with_chained_calls(vec![chained_call])
|
||||
.write();
|
||||
}
|
||||
@@ -56,6 +56,19 @@ pub const fn pda_spend_proxy() -> Program {
|
||||
Program::new_unchecked(PDA_SPEND_PROXY_ID, Cow::Borrowed(PDA_SPEND_PROXY_ELF))
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn chained_call_forwarder() -> Program {
|
||||
use guests::{CHAINED_CALL_FORWARDER_ELF, CHAINED_CALL_FORWARDER_ID, CHAINED_CALL_FORWARDER_PATH};
|
||||
|
||||
let _unused = CHAINED_CALL_FORWARDER_PATH;
|
||||
|
||||
Program::new_unchecked(
|
||||
CHAINED_CALL_FORWARDER_ID,
|
||||
Cow::Borrowed(CHAINED_CALL_FORWARDER_ELF),
|
||||
)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn time_locked_transfer() -> Program {
|
||||
|
||||
Reference in New Issue
Block a user