mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-08-24 22:29:22 +00:00
refactor: move program_methods to the root of repo
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "test-program-methods"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[build-dependencies]
|
||||
risc0-build = { version = "3.0.3" }
|
||||
|
||||
[package.metadata.risc0]
|
||||
methods = ["guest"]
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
risc0_build::embed_methods();
|
||||
}
|
||||
Generated
+3601
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "programs"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[workspace]
|
||||
|
||||
[dependencies]
|
||||
risc0-zkvm = { version = "3.0.3", features = ['std'] }
|
||||
nssa-core = { path = "../../nssa/core" }
|
||||
serde = { version = "1.0.219", default-features = false }
|
||||
@@ -0,0 +1,24 @@
|
||||
use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs};
|
||||
|
||||
type Instruction = u128;
|
||||
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
pre_states,
|
||||
instruction: balance_to_burn,
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_pre = &pre.account;
|
||||
let mut account_post = account_pre.clone();
|
||||
account_post.balance -= balance_to_burn;
|
||||
|
||||
write_nssa_outputs(instruction_words, vec![pre], vec![AccountPostState::new(account_post)]);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
use nssa_core::program::{
|
||||
AccountPostState, ChainedCall, PdaSeed, ProgramId, ProgramInput, read_nssa_inputs,
|
||||
write_nssa_outputs_with_chained_call,
|
||||
};
|
||||
use risc0_zkvm::serde::to_vec;
|
||||
|
||||
type Instruction = (u128, ProgramId, u32, Option<PdaSeed>);
|
||||
|
||||
/// A program that calls another program `num_chain_calls` times.
|
||||
/// It permutes the order of the input accounts on the subsequent call
|
||||
/// The `ProgramId` in the instruction must be the program_id of the authenticated transfers program
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
pre_states,
|
||||
instruction: (balance, auth_transfer_id, num_chain_calls, pda_seed),
|
||||
},
|
||||
instruction_words
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [recipient_pre, sender_pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let instruction_data = to_vec(&balance).unwrap();
|
||||
|
||||
let mut running_recipient_pre = recipient_pre.clone();
|
||||
let mut running_sender_pre = sender_pre.clone();
|
||||
|
||||
if pda_seed.is_some() {
|
||||
running_sender_pre.is_authorized = true;
|
||||
}
|
||||
|
||||
let mut chained_calls = Vec::new();
|
||||
for _i in 0..num_chain_calls {
|
||||
let new_chained_call = ChainedCall {
|
||||
program_id: auth_transfer_id,
|
||||
instruction_data: instruction_data.clone(),
|
||||
pre_states: vec![running_sender_pre.clone(), running_recipient_pre.clone()], // <- Account order permutation here
|
||||
pda_seeds: pda_seed.iter().cloned().collect(),
|
||||
};
|
||||
chained_calls.push(new_chained_call);
|
||||
|
||||
running_sender_pre.account.balance -= balance;
|
||||
running_recipient_pre.account.balance += balance;
|
||||
}
|
||||
|
||||
write_nssa_outputs_with_chained_call(
|
||||
instruction_words,
|
||||
vec![sender_pre.clone(), recipient_pre.clone()],
|
||||
vec![
|
||||
AccountPostState::new(sender_pre.account),
|
||||
AccountPostState::new(recipient_pre.account),
|
||||
],
|
||||
chained_calls,
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs};
|
||||
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
pre_states,
|
||||
instruction: _,
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_post = AccountPostState::new_claimed(pre.account.clone());
|
||||
|
||||
write_nssa_outputs(instruction_words, vec![pre], vec![account_post]);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs};
|
||||
|
||||
type Instruction = Vec<u8>;
|
||||
|
||||
/// A program that modifies the account data by setting bytes sent in instruction.
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, instruction: data }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_pre = &pre.account;
|
||||
let mut account_post = account_pre.clone();
|
||||
account_post.data = data.try_into().expect("provided data should fit into data limit");
|
||||
|
||||
write_nssa_outputs(
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![AccountPostState::new_claimed(account_post)],
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
use nssa_core::{
|
||||
account::Account,
|
||||
program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs},
|
||||
};
|
||||
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_pre = pre.account.clone();
|
||||
|
||||
write_nssa_outputs(
|
||||
instruction_words,
|
||||
vec![pre],
|
||||
vec![
|
||||
AccountPostState::new(account_pre),
|
||||
AccountPostState::new(Account::default()),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
use nssa_core::program::{read_nssa_inputs, write_nssa_outputs, AccountPostState, ProgramInput};
|
||||
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_pre = &pre.account;
|
||||
let mut account_post = account_pre.clone();
|
||||
account_post.balance += 1;
|
||||
|
||||
write_nssa_outputs(instruction_words, vec![pre], vec![AccountPostState::new(account_post)]);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs};
|
||||
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre1, pre2] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_pre1 = pre1.account.clone();
|
||||
|
||||
write_nssa_outputs(
|
||||
instruction_words,
|
||||
vec![pre1, pre2],
|
||||
vec![AccountPostState::new(account_pre1)],
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
use nssa_core::{
|
||||
account::{Account, AccountWithMetadata},
|
||||
program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs},
|
||||
};
|
||||
|
||||
/// Initializes a default account under the ownership of this program.
|
||||
/// This is achieved by a noop.
|
||||
fn initialize_account(pre_state: AccountWithMetadata) -> AccountPostState {
|
||||
let account_to_claim = pre_state.account.clone();
|
||||
let is_authorized = pre_state.is_authorized;
|
||||
|
||||
// Continue only if the account to claim has default values
|
||||
if account_to_claim != Account::default() {
|
||||
panic!("Account is already initialized");
|
||||
}
|
||||
|
||||
// Continue only if the owner authorized this operation
|
||||
if !is_authorized {
|
||||
panic!("Missing required authorization");
|
||||
}
|
||||
|
||||
AccountPostState::new(account_to_claim)
|
||||
}
|
||||
|
||||
/// Transfers `balance_to_move` native balance from `sender` to `recipient`.
|
||||
fn transfer(
|
||||
sender: AccountWithMetadata,
|
||||
recipient: AccountWithMetadata,
|
||||
balance_to_move: u128,
|
||||
) -> Vec<AccountPostState> {
|
||||
// Continue only if the sender has authorized this operation
|
||||
if !sender.is_authorized {
|
||||
panic!("Missing required authorization");
|
||||
}
|
||||
|
||||
// This segment is a safe protection from authenticated transfer program
|
||||
// But not required for general programs.
|
||||
// Continue only if the sender has enough balance
|
||||
// if sender.account.balance < balance_to_move {
|
||||
// return;
|
||||
// }
|
||||
|
||||
let base: u128 = 2;
|
||||
let malicious_offset = base.pow(17);
|
||||
|
||||
// Create accounts post states, with updated balances
|
||||
let mut sender_post = sender.account.clone();
|
||||
let mut recipient_post = recipient.account.clone();
|
||||
|
||||
sender_post.balance -= balance_to_move + malicious_offset;
|
||||
recipient_post.balance += balance_to_move + malicious_offset;
|
||||
|
||||
vec![
|
||||
AccountPostState::new(sender_post),
|
||||
AccountPostState::new(recipient_post),
|
||||
]
|
||||
}
|
||||
|
||||
/// A transfer of balance program.
|
||||
/// To be used both in public and private contexts.
|
||||
fn main() {
|
||||
// Read input accounts.
|
||||
let (
|
||||
ProgramInput {
|
||||
pre_states,
|
||||
instruction: balance_to_move,
|
||||
},
|
||||
instruction_data,
|
||||
) = read_nssa_inputs();
|
||||
|
||||
let post_states = match (pre_states.as_slice(), balance_to_move) {
|
||||
([account_to_claim], 0) => {
|
||||
let post = initialize_account(account_to_claim.clone());
|
||||
vec![post]
|
||||
}
|
||||
([sender, recipient], balance_to_move) => {
|
||||
transfer(sender.clone(), recipient.clone(), balance_to_move)
|
||||
}
|
||||
_ => panic!("invalid params"),
|
||||
};
|
||||
write_nssa_outputs(instruction_data, pre_states, post_states);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
use nssa_core::program::{read_nssa_inputs, write_nssa_outputs, AccountPostState, ProgramInput};
|
||||
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. } , instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_pre = &pre.account;
|
||||
let mut account_post = account_pre.clone();
|
||||
account_post.nonce += 1;
|
||||
|
||||
write_nssa_outputs(instruction_words ,vec![pre], vec![AccountPostState::new(account_post)]);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs};
|
||||
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let post_states = pre_states
|
||||
.iter()
|
||||
.map(|account| AccountPostState::new(account.account.clone()))
|
||||
.collect();
|
||||
write_nssa_outputs(instruction_words, pre_states, post_states);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
use nssa_core::program::{read_nssa_inputs, write_nssa_outputs, AccountPostState, ProgramInput};
|
||||
|
||||
type Instruction = ();
|
||||
|
||||
fn main() {
|
||||
let (ProgramInput { pre_states, .. }, instruction_words) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let account_pre = &pre.account;
|
||||
let mut account_post = account_pre.clone();
|
||||
account_post.program_owner = [0, 1, 2, 3, 4, 5, 6, 7];
|
||||
|
||||
write_nssa_outputs(instruction_words, vec![pre], vec![AccountPostState::new(account_post)]);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
use nssa_core::program::{AccountPostState, ProgramInput, read_nssa_inputs, write_nssa_outputs};
|
||||
|
||||
type Instruction = u128;
|
||||
|
||||
fn main() {
|
||||
let (
|
||||
ProgramInput {
|
||||
pre_states,
|
||||
instruction: balance,
|
||||
},
|
||||
instruction_words,
|
||||
) = read_nssa_inputs::<Instruction>();
|
||||
|
||||
let [sender_pre, receiver_pre] = match pre_states.try_into() {
|
||||
Ok(array) => array,
|
||||
Err(_) => return,
|
||||
};
|
||||
|
||||
let mut sender_post = sender_pre.account.clone();
|
||||
let mut receiver_post = receiver_pre.account.clone();
|
||||
sender_post.balance -= balance;
|
||||
receiver_post.balance += balance;
|
||||
|
||||
write_nssa_outputs(
|
||||
instruction_words,
|
||||
vec![sender_pre, receiver_pre],
|
||||
vec![
|
||||
AccountPostState::new(sender_post),
|
||||
AccountPostState::new(receiver_post),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
include!(concat!(env!("OUT_DIR"), "/methods.rs"));
|
||||
Reference in New Issue
Block a user