add transition_from_privacy_preserving_transaction method and relevant scaffolding

This commit is contained in:
Sergio Chouhy 2025-08-14 15:34:21 -03:00
parent a694e705ea
commit 507988832f
7 changed files with 109 additions and 12 deletions

View File

@ -1,2 +1,2 @@
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Commitment([u8; 32]);

View File

@ -1,2 +1,2 @@
#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Nullifier([u8; 32]);

View File

@ -7,10 +7,10 @@ struct EncryptedAccountData;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Message {
public_addresses: Vec<Address>,
nonces: Vec<Nonce>,
public_post_states: Vec<Account>,
encrypted_private_post_states: Vec<EncryptedAccountData>,
new_commitments: Vec<Commitment>,
new_nullifiers: Vec<Nullifier>,
pub(crate) public_addresses: Vec<Address>,
pub(crate) nonces: Vec<Nonce>,
pub(crate) public_post_states: Vec<Account>,
pub(crate) encrypted_private_post_states: Vec<EncryptedAccountData>,
pub(crate) new_commitments: Vec<Commitment>,
pub(crate) new_nullifiers: Vec<Nullifier>,
}

View File

@ -1,3 +1,5 @@
mod transaction;
mod message;
mod witness_set;
pub use transaction::PrivacyPreservingTransaction;

View File

@ -1,3 +1,10 @@
use std::collections::HashMap;
use nssa_core::account::Account;
use crate::error::NssaError;
use crate::{Address, V01State};
use super::message::Message;
use super::witness_set::WitnessSet;
@ -7,4 +14,27 @@ pub struct PrivacyPreservingTransaction {
witness_set: WitnessSet,
}
impl PrivacyPreservingTransaction {
pub(crate) fn validate(
&self,
arg: &mut V01State,
) -> Result<HashMap<Address, Account>, NssaError> {
todo!()
}
pub fn message(&self) -> &Message {
&self.message
}
pub fn witness_set(&self) -> &WitnessSet {
&self.witness_set
}
pub(crate) fn signer_addresses(&self) -> Vec<Address> {
self.witness_set
.signatures_and_public_keys()
.iter()
.map(|(_, public_key)| Address::from_public_key(public_key))
.collect()
}
}

View File

@ -1,2 +1,21 @@
use crate::{privacy_preserving_transaction::message::Message, PrivateKey, PublicKey, Signature};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct WitnessSet;
pub struct WitnessSet {
pub(super) signatures_and_public_keys: Vec<(Signature, PublicKey)>,
}
impl WitnessSet {
pub fn for_message(message: &Message, private_keys: &[&PrivateKey]) -> Self {
todo!()
}
pub fn is_valid_for(&self, message: &Message) -> bool {
todo!()
}
pub fn signatures_and_public_keys(&self) -> &[(Signature, PublicKey)] {
&self.signatures_and_public_keys
}
}

View File

@ -1,14 +1,31 @@
use crate::{
address::Address, error::NssaError, program::Program, public_transaction::PublicTransaction,
address::Address, error::NssaError,
privacy_preserving_transaction::PrivacyPreservingTransaction, program::Program,
public_transaction::PublicTransaction,
};
use nssa_core::{
account::Account,
account::{Account, Commitment, Nullifier},
program::{DEFAULT_PROGRAM_ID, ProgramId},
};
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
struct CommitmentSet(HashSet<Commitment>);
impl CommitmentSet {
fn extend(&mut self, commitments: &[Commitment]) {
self.0.extend(commitments)
}
fn set_commitment(&self) -> [u8; 32] {
// TODO: implement
[0; 32]
}
}
type NullifierSet = HashSet<Nullifier>;
pub struct V01State {
public_state: HashMap<Address, Account>,
private_state: (CommitmentSet, NullifierSet),
builtin_programs: HashMap<ProgramId, Program>,
}
@ -31,6 +48,7 @@ impl V01State {
let mut this = Self {
public_state,
private_state: (CommitmentSet(HashSet::new()), NullifierSet::new()),
builtin_programs: HashMap::new(),
};
@ -67,6 +85,34 @@ impl V01State {
Ok(())
}
pub fn transition_from_privacy_preserving_transaction(
&mut self,
tx: &PrivacyPreservingTransaction,
) -> Result<(), NssaError> {
// 1. Verify the transaction satisfies acceptance criteria
let public_state_diff = tx.validate(self)?;
let message = tx.message();
// 2. Add new commitments
self.private_state.0.extend(message.new_commitments);
// 3. Add new nullifiers
self.private_state.1.extend(message.new_nullifiers);
// 4. Update public accounts
for (address, post) in public_state_diff.into_iter() {
let current_account = self.get_account_by_address_mut(address);
*current_account = post;
}
// // 5. Increment nonces
for address in tx.signer_addresses() {
let current_account = self.get_account_by_address_mut(address);
current_account.nonce += 1;
}
Ok(())
}
fn get_account_by_address_mut(&mut self, address: Address) -> &mut Account {
self.public_state.entry(address).or_default()
}