mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-04-03 09:43:45 +00:00
Merge pull request #426 from logos-blockchain/moudy/feat-self-program-id
add self_program_id
This commit is contained in:
commit
42a2f04cd5
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.
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,6 +19,7 @@ fn main() {
|
||||
// Read inputs
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: greeting,
|
||||
},
|
||||
@ -50,5 +51,11 @@ fn main() {
|
||||
// with the NSSA program rules.
|
||||
// WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be
|
||||
// called to commit the output.
|
||||
ProgramOutput::new(instruction_data, vec![pre_state], vec![post_state]).write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_data,
|
||||
vec![pre_state],
|
||||
vec![post_state],
|
||||
)
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ fn main() {
|
||||
// Read inputs
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: greeting,
|
||||
},
|
||||
@ -57,5 +58,11 @@ fn main() {
|
||||
// with the NSSA program rules.
|
||||
// WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be
|
||||
// called to commit the output.
|
||||
ProgramOutput::new(instruction_data, vec![pre_state], vec![post_state]).write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_data,
|
||||
vec![pre_state],
|
||||
vec![post_state],
|
||||
)
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -66,6 +66,7 @@ fn main() {
|
||||
// Read input accounts.
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (function_id, data),
|
||||
},
|
||||
@ -85,5 +86,5 @@ fn main() {
|
||||
|
||||
// WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be
|
||||
// called to commit the output.
|
||||
ProgramOutput::new(instruction_words, pre_states, post_states).write();
|
||||
ProgramOutput::new(self_program_id, instruction_words, pre_states, post_states).write();
|
||||
}
|
||||
|
||||
@ -27,6 +27,7 @@ fn main() {
|
||||
// Read inputs
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (),
|
||||
},
|
||||
@ -55,7 +56,12 @@ fn main() {
|
||||
// Write the outputs.
|
||||
// WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be
|
||||
// called to commit the output.
|
||||
ProgramOutput::new(instruction_data, vec![pre_state], vec![post_state])
|
||||
.with_chained_calls(vec![chained_call])
|
||||
.write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_data,
|
||||
vec![pre_state],
|
||||
vec![post_state],
|
||||
)
|
||||
.with_chained_calls(vec![chained_call])
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ fn main() {
|
||||
// Read inputs
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (),
|
||||
},
|
||||
@ -68,7 +69,12 @@ fn main() {
|
||||
// Write the outputs.
|
||||
// WARNING: constructing a `ProgramOutput` has no effect on its own. `.write()` must be
|
||||
// called to commit the output.
|
||||
ProgramOutput::new(instruction_data, vec![pre_state], vec![post_state])
|
||||
.with_chained_calls(vec![chained_call])
|
||||
.write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_data,
|
||||
vec![pre_state],
|
||||
vec![post_state],
|
||||
)
|
||||
.with_chained_calls(vec![chained_call])
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ pub const MAX_NUMBER_CHAINED_CALLS: usize = 10;
|
||||
pub type ProgramId = [u32; 8];
|
||||
pub type InstructionData = Vec<u32>;
|
||||
pub struct ProgramInput<T> {
|
||||
pub self_program_id: ProgramId,
|
||||
pub pre_states: Vec<AccountWithMetadata>,
|
||||
pub instruction: T,
|
||||
}
|
||||
@ -281,6 +282,8 @@ 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 instruction data the program received to produce this output.
|
||||
pub instruction_data: InstructionData,
|
||||
/// The account pre states the program received to produce this output.
|
||||
@ -297,11 +300,13 @@ pub struct ProgramOutput {
|
||||
|
||||
impl ProgramOutput {
|
||||
pub const fn new(
|
||||
self_program_id: ProgramId,
|
||||
instruction_data: InstructionData,
|
||||
pre_states: Vec<AccountWithMetadata>,
|
||||
post_states: Vec<AccountPostState>,
|
||||
) -> Self {
|
||||
Self {
|
||||
self_program_id,
|
||||
instruction_data,
|
||||
pre_states,
|
||||
post_states,
|
||||
@ -415,11 +420,13 @@ pub fn compute_authorized_pdas(
|
||||
/// Reads the NSSA inputs from the guest environment.
|
||||
#[must_use]
|
||||
pub fn read_nssa_inputs<T: DeserializeOwned>() -> (ProgramInput<T>, InstructionData) {
|
||||
let self_program_id: ProgramId = 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,
|
||||
pre_states,
|
||||
instruction,
|
||||
},
|
||||
@ -620,7 +627,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn program_output_try_with_block_validity_window_range() {
|
||||
let output = ProgramOutput::new(vec![], vec![], vec![])
|
||||
let output = ProgramOutput::new(DEFAULT_PROGRAM_ID, vec![], vec![], vec![])
|
||||
.try_with_block_validity_window(10_u64..100)
|
||||
.unwrap();
|
||||
assert_eq!(output.block_validity_window.start(), Some(10));
|
||||
@ -629,24 +636,24 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn program_output_with_block_validity_window_range_from() {
|
||||
let output =
|
||||
ProgramOutput::new(vec![], vec![], vec![]).with_block_validity_window(10_u64..);
|
||||
let output = ProgramOutput::new(DEFAULT_PROGRAM_ID, 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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn program_output_with_block_validity_window_range_to() {
|
||||
let output =
|
||||
ProgramOutput::new(vec![], vec![], vec![]).with_block_validity_window(..100_u64);
|
||||
let output = ProgramOutput::new(DEFAULT_PROGRAM_ID, 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));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn program_output_try_with_block_validity_window_empty_range_fails() {
|
||||
let result =
|
||||
ProgramOutput::new(vec![], vec![], vec![]).try_with_block_validity_window(5_u64..5);
|
||||
let result = ProgramOutput::new(DEFAULT_PROGRAM_ID, vec![], vec![], vec![])
|
||||
.try_with_block_validity_window(5_u64..5);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
|
||||
@ -158,7 +158,7 @@ fn execute_and_prove_program(
|
||||
) -> Result<Receipt, NssaError> {
|
||||
// Write inputs to the program
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
Program::write_inputs(pre_states, instruction_data, &mut env_builder)?;
|
||||
Program::write_inputs(program.id(), pre_states, instruction_data, &mut env_builder)?;
|
||||
let env = env_builder.build().unwrap();
|
||||
|
||||
// Prove the program
|
||||
|
||||
@ -58,7 +58,7 @@ impl Program {
|
||||
// Write inputs to the program
|
||||
let mut env_builder = ExecutorEnv::builder();
|
||||
env_builder.session_limit(Some(MAX_NUM_CYCLES_PUBLIC_EXECUTION));
|
||||
Self::write_inputs(pre_states, instruction_data, &mut env_builder)?;
|
||||
Self::write_inputs(self.id, pre_states, instruction_data, &mut env_builder)?;
|
||||
let env = env_builder.build().unwrap();
|
||||
|
||||
// Execute the program (without proving)
|
||||
@ -78,13 +78,20 @@ impl Program {
|
||||
|
||||
/// Writes inputs to `env_builder` in the order expected by the programs.
|
||||
pub(crate) fn write_inputs(
|
||||
program_id: ProgramId,
|
||||
pre_states: &[AccountWithMetadata],
|
||||
instruction_data: &[u32],
|
||||
env_builder: &mut ExecutorEnvBuilder,
|
||||
) -> Result<(), NssaError> {
|
||||
env_builder
|
||||
.write(&program_id)
|
||||
.map_err(|e| NssaError::ProgramWriteInputFailed(e.to_string()))?;
|
||||
let pre_states = pre_states.to_vec();
|
||||
env_builder
|
||||
.write(&(pre_states, instruction_data))
|
||||
.write(&pre_states)
|
||||
.map_err(|e| NssaError::ProgramWriteInputFailed(e.to_string()))?;
|
||||
env_builder
|
||||
.write(&instruction_data)
|
||||
.map_err(|e| NssaError::ProgramWriteInputFailed(e.to_string()))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -184,6 +184,12 @@ impl PublicTransaction {
|
||||
);
|
||||
}
|
||||
|
||||
// Verify that the program output's self_program_id matches the expected program ID.
|
||||
ensure!(
|
||||
program_output.self_program_id == chained_call.program_id,
|
||||
NssaError::InvalidProgramBehavior
|
||||
);
|
||||
|
||||
// Verify execution corresponds to a well-behaved program.
|
||||
// See the # Programs section for the definition of the `validate_execution` method.
|
||||
ensure!(
|
||||
|
||||
@ -14,6 +14,7 @@ use nssa_core::program::{ProgramInput, ProgramOutput, read_nssa_inputs};
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction,
|
||||
},
|
||||
@ -152,7 +153,12 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
ProgramOutput::new(instruction_words, pre_states_clone, post_states)
|
||||
.with_chained_calls(chained_calls)
|
||||
.write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
pre_states_clone,
|
||||
post_states,
|
||||
)
|
||||
.with_chained_calls(chained_calls)
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ use nssa_core::program::{ProgramInput, ProgramOutput, read_nssa_inputs};
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction,
|
||||
},
|
||||
@ -56,7 +57,12 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
ProgramOutput::new(instruction_words, pre_states_clone, post_states)
|
||||
.with_chained_calls(chained_calls)
|
||||
.write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
pre_states_clone,
|
||||
post_states,
|
||||
)
|
||||
.with_chained_calls(chained_calls)
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -67,6 +67,7 @@ fn main() {
|
||||
// Read input accounts.
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: balance_to_move,
|
||||
},
|
||||
@ -84,5 +85,5 @@ fn main() {
|
||||
_ => panic!("invalid params"),
|
||||
};
|
||||
|
||||
ProgramOutput::new(instruction_words, pre_states, post_states).write();
|
||||
ProgramOutput::new(self_program_id, instruction_words, pre_states, post_states).write();
|
||||
}
|
||||
|
||||
@ -46,6 +46,7 @@ fn main() {
|
||||
// It is expected to receive only two accounts: [pinata_account, winner_account]
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: solution,
|
||||
},
|
||||
@ -79,6 +80,7 @@ fn main() {
|
||||
.expect("Overflow when adding prize to winner");
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pinata, winner],
|
||||
vec![
|
||||
|
||||
@ -52,6 +52,7 @@ fn main() {
|
||||
// winner_token_holding]
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: solution,
|
||||
},
|
||||
@ -97,6 +98,7 @@ fn main() {
|
||||
.with_pda_seeds(vec![PdaSeed::new([0; 32])]);
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![
|
||||
pinata_definition,
|
||||
|
||||
@ -107,6 +107,13 @@ impl ExecutionState {
|
||||
|_: Infallible| unreachable!("Infallible error is never constructed"),
|
||||
);
|
||||
|
||||
// Verify that the program output's self_program_id matches the expected program ID.
|
||||
// This ensures the proof commits to which program produced the output.
|
||||
assert_eq!(
|
||||
program_output.self_program_id, chained_call.program_id,
|
||||
"Program output self_program_id does not match chained call program_id"
|
||||
);
|
||||
|
||||
// Check that the program is well behaved.
|
||||
// See the # Programs section for the definition of the `validate_execution` method.
|
||||
let execution_valid = validate_execution(
|
||||
|
||||
@ -12,6 +12,7 @@ use token_program::core::Instruction;
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction,
|
||||
},
|
||||
@ -81,5 +82,11 @@ fn main() {
|
||||
}
|
||||
};
|
||||
|
||||
ProgramOutput::new(instruction_words, pre_states_clone, post_states).write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
pre_states_clone,
|
||||
post_states,
|
||||
)
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ type Instruction = u128;
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: balance_to_burn,
|
||||
},
|
||||
@ -20,6 +21,7 @@ fn main() {
|
||||
account_post.balance = account_post.balance.saturating_sub(balance_to_burn);
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![AccountPostState::new(account_post)],
|
||||
|
||||
@ -13,6 +13,7 @@ type Instruction = (u128, ProgramId, u32, Option<PdaSeed>);
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (balance, auth_transfer_id, num_chain_calls, pda_seed),
|
||||
},
|
||||
@ -55,6 +56,7 @@ fn main() {
|
||||
}
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![sender_pre.clone(), recipient_pre.clone()],
|
||||
vec![
|
||||
|
||||
@ -6,6 +6,7 @@ type Instruction = (Option<Vec<u8>>, bool);
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (data_opt, should_claim),
|
||||
},
|
||||
@ -33,5 +34,11 @@ fn main() {
|
||||
AccountPostState::new(account_post)
|
||||
};
|
||||
|
||||
ProgramOutput::new(instruction_words, vec![pre], vec![post_state]).write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![post_state],
|
||||
)
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ type Instruction = ();
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (),
|
||||
},
|
||||
@ -17,5 +18,11 @@ fn main() {
|
||||
|
||||
let account_post = AccountPostState::new_claimed(pre.account.clone(), Claim::Authorized);
|
||||
|
||||
ProgramOutput::new(instruction_words, vec![pre], vec![account_post]).write();
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![account_post],
|
||||
)
|
||||
.write();
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ type Instruction = Vec<u8>;
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: data,
|
||||
},
|
||||
@ -23,6 +24,7 @@ fn main() {
|
||||
.expect("provided data should fit into data limit");
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![AccountPostState::new_claimed(
|
||||
|
||||
@ -6,7 +6,14 @@ use nssa_core::{
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
..
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let Ok([pre]) = <[_; 1]>::try_from(pre_states) else {
|
||||
return;
|
||||
@ -15,6 +22,7 @@ fn main() {
|
||||
let account_pre = pre.account.clone();
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![
|
||||
|
||||
@ -14,6 +14,7 @@ type Instruction = (u128, ProgramId);
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (balance, transfer_program_id),
|
||||
},
|
||||
@ -40,6 +41,7 @@ fn main() {
|
||||
};
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![sender.clone(), receiver.clone()],
|
||||
vec![
|
||||
|
||||
@ -3,7 +3,14 @@ use nssa_core::program::{AccountPostState, ProgramInput, ProgramOutput, read_nss
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
..
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let Ok([pre]) = <[_; 1]>::try_from(pre_states) else {
|
||||
return;
|
||||
@ -17,6 +24,7 @@ fn main() {
|
||||
.expect("Balance overflow");
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![AccountPostState::new(account_post)],
|
||||
|
||||
@ -3,7 +3,14 @@ use nssa_core::program::{AccountPostState, ProgramInput, ProgramOutput, read_nss
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
..
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let Ok([pre1, pre2]) = <[_; 2]>::try_from(pre_states) else {
|
||||
return;
|
||||
@ -12,6 +19,7 @@ fn main() {
|
||||
let account_pre1 = pre1.account.clone();
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre1, pre2],
|
||||
vec![AccountPostState::new(account_pre1)],
|
||||
|
||||
@ -64,6 +64,7 @@ fn main() {
|
||||
// Read input accounts.
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: balance_to_move,
|
||||
},
|
||||
@ -80,5 +81,5 @@ fn main() {
|
||||
}
|
||||
_ => panic!("invalid params"),
|
||||
};
|
||||
ProgramOutput::new(instruction_data, pre_states, post_states).write();
|
||||
ProgramOutput::new(self_program_id, instruction_data, pre_states, post_states).write();
|
||||
}
|
||||
|
||||
@ -3,7 +3,14 @@ use nssa_core::program::{AccountPostState, ProgramInput, ProgramOutput, read_nss
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
..
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let Ok([pre]) = <[_; 1]>::try_from(pre_states) else {
|
||||
return;
|
||||
@ -14,6 +21,7 @@ fn main() {
|
||||
account_post.nonce.public_account_nonce_increment();
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![AccountPostState::new(account_post)],
|
||||
|
||||
@ -3,11 +3,18 @@ use nssa_core::program::{AccountPostState, ProgramInput, ProgramOutput, read_nss
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
..
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let post_states = pre_states
|
||||
.iter()
|
||||
.map(|account| AccountPostState::new(account.account.clone()))
|
||||
.collect();
|
||||
ProgramOutput::new(instruction_words, pre_states, post_states).write();
|
||||
ProgramOutput::new(self_program_id, instruction_words, pre_states, post_states).write();
|
||||
}
|
||||
|
||||
@ -3,7 +3,14 @@ use nssa_core::program::{AccountPostState, ProgramInput, ProgramOutput, read_nss
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
..
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let Ok([pre]) = <[_; 1]>::try_from(pre_states) else {
|
||||
return;
|
||||
@ -14,6 +21,7 @@ fn main() {
|
||||
account_post.program_owner = [0, 1, 2, 3, 4, 5, 6, 7];
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![AccountPostState::new(account_post)],
|
||||
|
||||
@ -5,6 +5,7 @@ type Instruction = u128;
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: balance,
|
||||
},
|
||||
@ -27,6 +28,7 @@ fn main() {
|
||||
.expect("Overflow when adding balance");
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![sender_pre, receiver_pre],
|
||||
vec![
|
||||
|
||||
@ -8,6 +8,7 @@ type Instruction = (BlockValidityWindow, TimestampValidityWindow);
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (block_validity_window, timestamp_validity_window),
|
||||
},
|
||||
@ -21,6 +22,7 @@ fn main() {
|
||||
let post = pre.account.clone();
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![AccountPostState::new(post)],
|
||||
|
||||
@ -16,6 +16,7 @@ type Instruction = (BlockValidityWindow, ProgramId, BlockValidityWindow);
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
self_program_id,
|
||||
pre_states,
|
||||
instruction: (block_validity_window, chained_program_id, chained_block_validity_window),
|
||||
},
|
||||
@ -38,6 +39,7 @@ fn main() {
|
||||
};
|
||||
|
||||
ProgramOutput::new(
|
||||
self_program_id,
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![AccountPostState::new(post)],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user