Merge branch 'main' into marvin/public_keys

This commit is contained in:
jonesmarvin8
2026-02-10 09:19:45 -05:00
143 changed files with 9066 additions and 4341 deletions
+3
View File
@@ -2,6 +2,7 @@
name = "nssa"
version = "0.1.0"
edition = "2024"
license = { workspace = true }
[dependencies]
nssa_core = { workspace = true, features = ["host"] }
@@ -23,7 +24,9 @@ risc0-build = "3.0.3"
risc0-binfmt = "3.0.2"
[dev-dependencies]
token_core.workspace = true
test_program_methods.workspace = true
env_logger.workspace = true
hex-literal = "1.0.0"
test-case = "3.3.1"
+1
View File
@@ -2,6 +2,7 @@
name = "nssa_core"
version = "0.1.0"
edition = "2024"
license = { workspace = true }
[dependencies]
risc0-zkvm.workspace = true
+4
View File
@@ -68,6 +68,10 @@ impl AccountId {
pub fn value(&self) -> &[u8; 32] {
&self.value
}
pub fn into_value(self) -> [u8; 32] {
self.value
}
}
impl AsRef<[u8]> for AccountId {
+4 -1
View File
@@ -5,7 +5,10 @@ use serde::{Deserialize, Serialize};
use crate::{NullifierPublicKey, account::Account};
#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
#[cfg_attr(any(feature = "host", test), derive(Debug, Clone, PartialEq, Eq, Hash))]
#[cfg_attr(
any(feature = "host", test),
derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)
)]
pub struct Commitment(pub(super) [u8; 32]);
/// A commitment to all zero data.
+20
View File
@@ -69,6 +69,11 @@ impl Commitment {
self.0
}
#[cfg(feature = "host")]
pub fn from_byte_array(bytes: [u8; 32]) -> Self {
Self(bytes)
}
#[cfg(feature = "host")]
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaCoreError> {
let mut bytes = [0u8; 32];
@@ -89,6 +94,11 @@ impl Nullifier {
self.0
}
#[cfg(feature = "host")]
pub fn from_byte_array(bytes: [u8; 32]) -> Self {
Self(bytes)
}
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaCoreError> {
let mut bytes = [0u8; 32];
cursor.read_exact(&mut bytes)?;
@@ -106,6 +116,16 @@ impl Ciphertext {
bytes
}
#[cfg(feature = "host")]
pub fn into_inner(self) -> Vec<u8> {
self.0
}
#[cfg(feature = "host")]
pub fn from_inner(inner: Vec<u8>) -> Self {
Self(inner)
}
#[cfg(feature = "host")]
pub fn from_cursor(cursor: &mut Cursor<&[u8]>) -> Result<Self, NssaCoreError> {
let mut u32_bytes = [0; 4];
+4 -1
View File
@@ -42,7 +42,10 @@ impl From<&NullifierSecretKey> for NullifierPublicKey {
pub type NullifierSecretKey = [u8; 32];
#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize)]
#[cfg_attr(any(feature = "host", test), derive(Debug, Clone, PartialEq, Eq, Hash))]
#[cfg_attr(
any(feature = "host", test),
derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)
)]
pub struct Nullifier(pub(super) [u8; 32]);
impl Nullifier {
+27 -7
View File
@@ -20,8 +20,7 @@ pub struct ProgramInput<T> {
/// Each program can derive up to `2^256` unique account IDs by choosing different
/// seeds. PDAs allow programs to control namespaced account identifiers without
/// collisions between programs.
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)]
#[cfg_attr(any(feature = "host", test), derive(Debug))]
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
pub struct PdaSeed([u8; 32]);
impl PdaSeed {
@@ -65,23 +64,44 @@ impl From<(&ProgramId, &PdaSeed)> for AccountId {
}
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
#[cfg_attr(any(feature = "host", test), derive(Debug,))]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
pub struct ChainedCall {
/// The program ID of the program to execute
pub program_id: ProgramId,
pub pre_states: Vec<AccountWithMetadata>,
/// The instruction data to pass
pub instruction_data: InstructionData,
pub pre_states: Vec<AccountWithMetadata>,
pub pda_seeds: Vec<PdaSeed>,
}
impl ChainedCall {
/// Creates a new chained call serializing the given instruction.
pub fn new<I: Serialize>(
program_id: ProgramId,
pre_states: Vec<AccountWithMetadata>,
instruction: &I,
) -> Self {
Self {
program_id,
pre_states,
instruction_data: risc0_zkvm::serde::to_vec(instruction)
.expect("Serialization to Vec<u32> should not fail"),
pda_seeds: Vec::new(),
}
}
pub fn with_pda_seeds(mut self, pda_seeds: Vec<PdaSeed>) -> Self {
self.pda_seeds = pda_seeds;
self
}
}
/// Represents the final state of an `Account` after a program execution.
/// A post state may optionally request that the executing program
/// becomes the owner of the account (a “claim”). This is used to signal
/// that the program intends to take ownership of the account.
#[derive(Serialize, Deserialize, Clone)]
#[cfg_attr(any(feature = "host", test), derive(Debug, PartialEq, Eq))]
#[derive(Debug, Serialize, Deserialize, Clone)]
#[cfg_attr(any(feature = "host", test), derive(PartialEq, Eq))]
pub struct AccountPostState {
account: Account,
claim: bool,
+1 -1
View File
@@ -14,7 +14,7 @@ mod state;
pub use nssa_core::{
SharedSecretKey,
account::{Account, AccountId},
account::{Account, AccountId, Data},
encryption::EphemeralPublicKey,
program::ProgramId,
};
+2
View File
@@ -1,3 +1,4 @@
use borsh::{BorshDeserialize, BorshSerialize};
use sha2::{Digest, Sha256};
mod default_values;
@@ -20,6 +21,7 @@ fn hash_value(value: &Value) -> Node {
}
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
#[derive(BorshSerialize, BorshDeserialize)]
pub struct MerkleTree {
nodes: Vec<Node>,
capacity: usize,
@@ -20,6 +20,16 @@ use crate::{
#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct Proof(pub(crate) Vec<u8>);
impl Proof {
pub fn into_inner(self) -> Vec<u8> {
self.0
}
pub fn from_inner(inner: Vec<u8>) -> Self {
Self(inner)
}
}
#[derive(Clone)]
pub struct ProgramWithDependencies {
pub program: Program,
@@ -45,12 +45,12 @@ impl EncryptedAccountData {
#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct Message {
pub(crate) public_account_ids: Vec<AccountId>,
pub(crate) nonces: Vec<Nonce>,
pub(crate) public_post_states: Vec<Account>,
pub public_account_ids: Vec<AccountId>,
pub nonces: Vec<Nonce>,
pub public_post_states: Vec<Account>,
pub encrypted_private_post_states: Vec<EncryptedAccountData>,
pub new_commitments: Vec<Commitment>,
pub(crate) new_nullifiers: Vec<(Nullifier, CommitmentSetDigest)>,
pub new_nullifiers: Vec<(Nullifier, CommitmentSetDigest)>,
}
impl Message {
@@ -16,7 +16,7 @@ use crate::{
#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct PrivacyPreservingTransaction {
pub message: Message,
witness_set: WitnessSet,
pub witness_set: WitnessSet,
}
impl PrivacyPreservingTransaction {
@@ -46,4 +46,18 @@ impl WitnessSet {
pub fn proof(&self) -> &Proof {
&self.proof
}
pub fn into_raw_parts(self) -> (Vec<(Signature, PublicKey)>, Proof) {
(self.signatures_and_public_keys, self.proof)
}
pub fn from_raw_parts(
signatures_and_public_keys: Vec<(Signature, PublicKey)>,
proof: Proof,
) -> Self {
Self {
signatures_and_public_keys,
proof,
}
}
}
+2 -1
View File
@@ -1,3 +1,4 @@
use borsh::{BorshDeserialize, BorshSerialize};
use nssa_core::{
account::AccountWithMetadata,
program::{InstructionData, ProgramId, ProgramOutput},
@@ -14,7 +15,7 @@ use crate::{
/// TODO: Make this variable when fees are implemented
const MAX_NUM_CYCLES_PUBLIC_EXECUTION: u64 = 1024 * 1024 * 32; // 32M cycles
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(Clone, Debug, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct Program {
id: ProgramId,
elf: Vec<u8>,
@@ -9,4 +9,8 @@ impl Message {
pub fn new(bytecode: Vec<u8>) -> Self {
Self { bytecode }
}
pub fn into_bytecode(self) -> Vec<u8> {
self.bytecode
}
}
@@ -14,6 +14,10 @@ impl ProgramDeploymentTransaction {
Self { message }
}
pub fn into_message(self) -> Message {
self.message
}
pub(crate) fn validate_and_produce_public_state_diff(
&self,
state: &V02State,
+4 -4
View File
@@ -9,10 +9,10 @@ use crate::{AccountId, error::NssaError, program::Program};
#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct Message {
pub(crate) program_id: ProgramId,
pub(crate) account_ids: Vec<AccountId>,
pub(crate) nonces: Vec<Nonce>,
pub(crate) instruction_data: InstructionData,
pub program_id: ProgramId,
pub account_ids: Vec<AccountId>,
pub nonces: Vec<Nonce>,
pub instruction_data: InstructionData,
}
impl Message {
@@ -37,6 +37,16 @@ impl WitnessSet {
pub fn signatures_and_public_keys(&self) -> &[(Signature, PublicKey)] {
&self.signatures_and_public_keys
}
pub fn into_raw_parts(self) -> Vec<(Signature, PublicKey)> {
self.signatures_and_public_keys
}
pub fn from_raw_parts(signatures_and_public_keys: Vec<(Signature, PublicKey)>) -> Self {
Self {
signatures_and_public_keys,
}
}
}
#[cfg(test)]
+1 -1
View File
@@ -8,7 +8,7 @@ use rand::{RngCore, rngs::OsRng};
#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
pub struct Signature {
value: [u8; 64],
pub value: [u8; 64],
}
impl Signature {
+119 -147
View File
@@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet};
use std::collections::{BTreeSet, HashMap, HashSet};
use borsh::{BorshDeserialize, BorshSerialize};
use nssa_core::{
Commitment, CommitmentSetDigest, DUMMY_COMMITMENT, MembershipProof, Nullifier,
account::{Account, AccountId},
@@ -15,6 +16,8 @@ use crate::{
pub const MAX_NUMBER_CHAINED_CALLS: usize = 10;
#[derive(BorshSerialize, BorshDeserialize)]
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
pub(crate) struct CommitmentSet {
merkle_tree: MerkleTree,
commitments: HashMap<Commitment, usize>,
@@ -60,8 +63,49 @@ impl CommitmentSet {
}
}
type NullifierSet = HashSet<Nullifier>;
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
struct NullifierSet(BTreeSet<Nullifier>);
impl NullifierSet {
fn new() -> Self {
Self(BTreeSet::new())
}
fn extend(&mut self, new_nullifiers: Vec<Nullifier>) {
self.0.extend(new_nullifiers);
}
fn contains(&self, nullifier: &Nullifier) -> bool {
self.0.contains(nullifier)
}
}
impl BorshSerialize for NullifierSet {
fn serialize<W: std::io::Write>(&self, writer: &mut W) -> std::io::Result<()> {
self.0.iter().collect::<Vec<_>>().serialize(writer)
}
}
impl BorshDeserialize for NullifierSet {
fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
let vec = Vec::<Nullifier>::deserialize_reader(reader)?;
let mut set = BTreeSet::new();
for n in vec {
if !set.insert(n) {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,
"duplicate nullifier in NullifierSet",
));
}
}
Ok(Self(set))
}
}
#[derive(BorshSerialize, BorshDeserialize)]
#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
pub struct V02State {
public_state: HashMap<AccountId, Account>,
private_state: (CommitmentSet, NullifierSet),
@@ -273,6 +317,7 @@ pub mod tests {
encryption::{EphemeralPublicKey, IncomingViewingPublicKey, Scalar},
program::{PdaSeed, ProgramId},
};
use token_core::{TokenDefinition, TokenHolding};
use crate::{
PublicKey, PublicTransaction, V02State,
@@ -2284,53 +2329,6 @@ pub mod tests {
));
}
// TODO: repeated code needs to be cleaned up
// from token.rs (also repeated in amm.rs)
const TOKEN_DEFINITION_DATA_SIZE: usize = 55;
const TOKEN_HOLDING_DATA_SIZE: usize = 49;
struct TokenDefinition {
account_type: u8,
name: [u8; 6],
total_supply: u128,
metadata_id: AccountId,
}
struct TokenHolding {
account_type: u8,
definition_id: AccountId,
balance: u128,
}
impl TokenDefinition {
fn into_data(self) -> Data {
let mut bytes = Vec::<u8>::new();
bytes.extend_from_slice(&[self.account_type]);
bytes.extend_from_slice(&self.name);
bytes.extend_from_slice(&self.total_supply.to_le_bytes());
bytes.extend_from_slice(&self.metadata_id.to_bytes());
if bytes.len() != TOKEN_DEFINITION_DATA_SIZE {
panic!("Invalid Token Definition data");
}
Data::try_from(bytes).expect("Token definition data size must fit into data")
}
}
impl TokenHolding {
fn into_data(self) -> Data {
let mut bytes = [0; TOKEN_HOLDING_DATA_SIZE];
bytes[0] = self.account_type;
bytes[1..33].copy_from_slice(&self.definition_id.to_bytes());
bytes[33..].copy_from_slice(&self.balance.to_le_bytes());
bytes
.to_vec()
.try_into()
.expect("33 bytes should fit into Data")
}
}
// TODO repeated code should ultimately be removed;
fn compute_pool_pda(
amm_program_id: ProgramId,
@@ -2703,8 +2701,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::user_token_a_holding_init(),
}),
@@ -2716,8 +2713,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::user_token_b_holding_init(),
}),
@@ -2749,11 +2745,10 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: 0u8,
name: [1u8; 6],
data: Data::from(&TokenDefinition::Fungible {
name: String::from("test"),
total_supply: BalanceForTests::token_a_supply(),
metadata_id: AccountId::new([0; 32]),
metadata_id: None,
}),
nonce: 0,
}
@@ -2763,11 +2758,10 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: 0u8,
name: [1u8; 6],
data: Data::from(&TokenDefinition::Fungible {
name: String::from("test"),
total_supply: BalanceForTests::token_b_supply(),
metadata_id: AccountId::new([0; 32]),
metadata_id: None,
}),
nonce: 0,
}
@@ -2777,11 +2771,10 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: 0u8,
name: [1u8; 6],
data: Data::from(&TokenDefinition::Fungible {
name: String::from("LP Token"),
total_supply: BalanceForTests::token_lp_supply(),
metadata_id: AccountId::new([0; 32]),
metadata_id: None,
}),
nonce: 0,
}
@@ -2791,8 +2784,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::vault_a_balance_init(),
}),
@@ -2804,8 +2796,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::vault_b_balance_init(),
}),
@@ -2817,8 +2808,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_lp_definition_id(),
balance: BalanceForTests::user_token_lp_holding_init(),
}),
@@ -2830,8 +2820,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::vault_a_balance_swap_1(),
}),
@@ -2843,8 +2832,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::vault_b_balance_swap_1(),
}),
@@ -2876,8 +2864,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::user_token_a_holding_swap_1(),
}),
@@ -2889,8 +2876,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::user_token_b_holding_swap_1(),
}),
@@ -2902,8 +2888,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::vault_a_balance_swap_2(),
}),
@@ -2915,8 +2900,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::vault_b_balance_swap_2(),
}),
@@ -2948,8 +2932,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::user_token_a_holding_swap_2(),
}),
@@ -2961,8 +2944,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::user_token_b_holding_swap_2(),
}),
@@ -2974,8 +2956,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::vault_a_balance_add(),
}),
@@ -2987,8 +2968,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::vault_b_balance_add(),
}),
@@ -3020,8 +3000,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::user_token_a_holding_add(),
}),
@@ -3033,8 +3012,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::user_token_b_holding_add(),
}),
@@ -3046,8 +3024,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_lp_definition_id(),
balance: BalanceForTests::user_token_lp_holding_add(),
}),
@@ -3059,11 +3036,10 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: 0u8,
name: [1u8; 6],
data: Data::from(&TokenDefinition::Fungible {
name: String::from("LP Token"),
total_supply: BalanceForTests::token_lp_supply_add(),
metadata_id: AccountId::new([0; 32]),
metadata_id: None,
}),
nonce: 0,
}
@@ -3073,8 +3049,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::vault_a_balance_remove(),
}),
@@ -3086,8 +3061,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::vault_b_balance_remove(),
}),
@@ -3119,8 +3093,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::user_token_a_holding_remove(),
}),
@@ -3132,8 +3105,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::user_token_b_holding_remove(),
}),
@@ -3145,8 +3117,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_lp_definition_id(),
balance: BalanceForTests::user_token_lp_holding_remove(),
}),
@@ -3158,11 +3129,10 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: 0u8,
name: [1u8; 6],
data: Data::from(&TokenDefinition::Fungible {
name: String::from("LP Token"),
total_supply: BalanceForTests::token_lp_supply_remove(),
metadata_id: AccountId::new([0; 32]),
metadata_id: None,
}),
nonce: 0,
}
@@ -3172,11 +3142,10 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: 0u8,
name: [1u8; 6],
data: Data::from(&TokenDefinition::Fungible {
name: String::from("LP Token"),
total_supply: 0,
metadata_id: AccountId::new([0; 32]),
metadata_id: None,
}),
nonce: 0,
}
@@ -3186,8 +3155,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: 0,
}),
@@ -3199,8 +3167,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: 0,
}),
@@ -3232,8 +3199,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_a_definition_id(),
balance: BalanceForTests::user_token_a_holding_new_definition(),
}),
@@ -3245,8 +3211,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_b_definition_id(),
balance: BalanceForTests::user_token_b_holding_new_definition(),
}),
@@ -3258,8 +3223,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_lp_definition_id(),
balance: BalanceForTests::user_token_a_holding_new_definition(),
}),
@@ -3271,11 +3235,10 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenDefinition::into_data(TokenDefinition {
account_type: 0u8,
name: [1u8; 6],
data: Data::from(&TokenDefinition::Fungible {
name: String::from("LP Token"),
total_supply: BalanceForTests::vault_a_balance_init(),
metadata_id: AccountId::new([0; 32]),
metadata_id: None,
}),
nonce: 0,
}
@@ -3305,8 +3268,7 @@ pub mod tests {
Account {
program_owner: Program::token().id(),
balance: 0u128,
data: TokenHolding::into_data(TokenHolding {
account_type: 1u8,
data: Data::from(&TokenHolding::Fungible {
definition_id: IdForTests::token_lp_definition_id(),
balance: 0,
}),
@@ -4071,13 +4033,13 @@ pub mod tests {
let pinata_token_holding_id = AccountId::from((&pinata_token.id(), &PdaSeed::new([0; 32])));
let winner_token_holding_id = AccountId::new([3; 32]);
let mut expected_winner_account_data = [0; 49];
expected_winner_account_data[0] = 1;
expected_winner_account_data[1..33].copy_from_slice(pinata_token_definition_id.value());
expected_winner_account_data[33..].copy_from_slice(&150u128.to_le_bytes());
let expected_winner_account_holding = token_core::TokenHolding::Fungible {
definition_id: pinata_token_definition_id,
balance: 150,
};
let expected_winner_token_holding_post = Account {
program_owner: token.id(),
data: expected_winner_account_data.to_vec().try_into().unwrap(),
data: Data::from(&expected_winner_account_holding),
..Account::default()
};
@@ -4087,10 +4049,10 @@ pub mod tests {
// Execution of the token program to create new token for the pinata token
// definition and supply accounts
let total_supply: u128 = 10_000_000;
// instruction: [0x00 || total_supply (little-endian 16 bytes) || name (6 bytes)]
let mut instruction = vec![0; 23];
instruction[1..17].copy_from_slice(&total_supply.to_le_bytes());
instruction[17..].copy_from_slice(b"PINATA");
let instruction = token_core::Instruction::NewFungibleDefinition {
name: String::from("PINATA"),
total_supply,
};
let message = public_transaction::Message::try_new(
token.id(),
vec![pinata_token_definition_id, pinata_token_holding_id],
@@ -4102,9 +4064,8 @@ pub mod tests {
let tx = PublicTransaction::new(message, witness_set);
state.transition_from_public_transaction(&tx).unwrap();
// Execution of the token program transfer just to initialize the winner token account
let mut instruction = vec![0; 23];
instruction[0] = 2;
// Execution of winner's token holding account initialization
let instruction = token_core::Instruction::InitializeAccount;
let message = public_transaction::Message::try_new(
token.id(),
vec![pinata_token_definition_id, winner_token_holding_id],
@@ -4528,4 +4489,15 @@ pub mod tests {
// Assert - should fail because the malicious program tries to manipulate is_authorized
assert!(matches!(result, Err(NssaError::CircuitProvingError(_))));
}
#[test]
fn test_state_serialization_roundtrip() {
let account_id_1 = AccountId::new([1; 32]);
let account_id_2 = AccountId::new([2; 32]);
let initial_data = [(account_id_1, 100u128), (account_id_2, 151u128)];
let state = V02State::new_with_genesis_accounts(&initial_data, &[]).with_test_programs();
let bytes = borsh::to_vec(&state).unwrap();
let state_from_bytes: V02State = borsh::from_slice(&bytes).unwrap();
assert_eq!(state, state_from_bytes);
}
}