diff --git a/nssa/core/src/account/commitment.rs b/nssa/core/src/account/commitment.rs
index 5bb7532..a0bcfee 100644
--- a/nssa/core/src/account/commitment.rs
+++ b/nssa/core/src/account/commitment.rs
@@ -1,2 +1,2 @@
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Commitment([u8; 32]);
diff --git a/nssa/core/src/account/nullifier.rs b/nssa/core/src/account/nullifier.rs
index 3280f19..4479af0 100644
--- a/nssa/core/src/account/nullifier.rs
+++ b/nssa/core/src/account/nullifier.rs
@@ -1,2 +1,2 @@
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Nullifier([u8; 32]);
diff --git a/nssa/src/privacy_preserving_transaction/message.rs b/nssa/src/privacy_preserving_transaction/message.rs
index edea889..1585be1 100644
--- a/nssa/src/privacy_preserving_transaction/message.rs
+++ b/nssa/src/privacy_preserving_transaction/message.rs
@@ -7,10 +7,10 @@ struct EncryptedAccountData;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Message {
- public_addresses: Vec
,
- nonces: Vec,
- public_post_states: Vec,
- encrypted_private_post_states: Vec,
- new_commitments: Vec,
- new_nullifiers: Vec,
+ pub(crate) public_addresses: Vec,
+ pub(crate) nonces: Vec,
+ pub(crate) public_post_states: Vec,
+ pub(crate) encrypted_private_post_states: Vec,
+ pub(crate) new_commitments: Vec,
+ pub(crate) new_nullifiers: Vec,
}
diff --git a/nssa/src/privacy_preserving_transaction/mod.rs b/nssa/src/privacy_preserving_transaction/mod.rs
index 898d27c..2d3bba3 100644
--- a/nssa/src/privacy_preserving_transaction/mod.rs
+++ b/nssa/src/privacy_preserving_transaction/mod.rs
@@ -1,3 +1,5 @@
mod transaction;
mod message;
mod witness_set;
+
+pub use transaction::PrivacyPreservingTransaction;
diff --git a/nssa/src/privacy_preserving_transaction/transaction.rs b/nssa/src/privacy_preserving_transaction/transaction.rs
index 7322c75..0640454 100644
--- a/nssa/src/privacy_preserving_transaction/transaction.rs
+++ b/nssa/src/privacy_preserving_transaction/transaction.rs
@@ -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, 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 {
+ self.witness_set
+ .signatures_and_public_keys()
+ .iter()
+ .map(|(_, public_key)| Address::from_public_key(public_key))
+ .collect()
+ }
+}
diff --git a/nssa/src/privacy_preserving_transaction/witness_set.rs b/nssa/src/privacy_preserving_transaction/witness_set.rs
index 132bb49..6a65cb6 100644
--- a/nssa/src/privacy_preserving_transaction/witness_set.rs
+++ b/nssa/src/privacy_preserving_transaction/witness_set.rs
@@ -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
+ }
+}
diff --git a/nssa/src/state.rs b/nssa/src/state.rs
index 3060185..3e266d8 100644
--- a/nssa/src/state.rs
+++ b/nssa/src/state.rs
@@ -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);
+
+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;
pub struct V01State {
public_state: HashMap,
+ private_state: (CommitmentSet, NullifierSet),
builtin_programs: HashMap,
}
@@ -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()
}