mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-05-13 03:30:05 +00:00
fmt
This commit is contained in:
parent
d4334c4694
commit
f722d257a3
@ -12,14 +12,15 @@ use integration_tests::{
|
||||
};
|
||||
use log::info;
|
||||
use nssa::{
|
||||
AccountId, ProgramId,
|
||||
privacy_preserving_transaction::circuit::ProgramWithDependencies,
|
||||
AccountId, ProgramId, privacy_preserving_transaction::circuit::ProgramWithDependencies,
|
||||
program::Program,
|
||||
};
|
||||
use nssa_core::{NullifierPublicKey, encryption::ViewingPublicKey, program::PdaSeed};
|
||||
use tokio::test;
|
||||
use wallet::{PrivacyPreservingAccount, WalletCore};
|
||||
use wallet::cli::{Command, account::AccountSubcommand};
|
||||
use wallet::{
|
||||
PrivacyPreservingAccount, WalletCore,
|
||||
cli::{Command, account::AccountSubcommand},
|
||||
};
|
||||
|
||||
/// Funds a private PDA via the proxy program with a chained call to auth_transfer.
|
||||
///
|
||||
@ -211,7 +212,10 @@ async fn private_pda_family_members_receive_and_spend() -> Result<()> {
|
||||
verify_commitment_is_in_state(commitment_1.clone(), ctx.sequencer_client()).await,
|
||||
"alice_pda_1 commitment not in state after receive"
|
||||
);
|
||||
assert_ne!(commitment_0, commitment_1, "distinct identifiers must yield distinct commitments");
|
||||
assert_ne!(
|
||||
commitment_0, commitment_1,
|
||||
"distinct identifiers must yield distinct commitments"
|
||||
);
|
||||
|
||||
// ── Spend ─────────────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@ -116,7 +116,10 @@ impl KeyTreeNode for ChildKeysPrivate {
|
||||
|
||||
fn account_ids(&self) -> impl Iterator<Item = nssa::AccountId> {
|
||||
let npk = self.value.0.nullifier_public_key;
|
||||
self.value.1.iter().map(move |(kind, _)| nssa::AccountId::for_private_account(&npk, kind))
|
||||
self.value
|
||||
.1
|
||||
.iter()
|
||||
.map(move |(kind, _)| nssa::AccountId::for_private_account(&npk, kind))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -66,9 +66,10 @@ impl NSSAUserData {
|
||||
let mut check_res = true;
|
||||
for (account_id, entry) in accounts_keys_map {
|
||||
let npk = &entry.key_chain.nullifier_public_key;
|
||||
let any_match = entry.accounts.iter().any(|(kind, _)| {
|
||||
nssa::AccountId::for_private_account(npk, kind) == *account_id
|
||||
});
|
||||
let any_match = entry
|
||||
.accounts
|
||||
.iter()
|
||||
.any(|(kind, _)| nssa::AccountId::for_private_account(npk, kind) == *account_id);
|
||||
if !any_match {
|
||||
println!("No matching entry found for account_id {account_id}");
|
||||
check_res = false;
|
||||
@ -170,8 +171,10 @@ impl NSSAUserData {
|
||||
// Check default accounts
|
||||
if let Some(entry) = self.default_user_private_accounts.get(&account_id) {
|
||||
let npk = &entry.key_chain.nullifier_public_key;
|
||||
if let Some((kind, account)) =
|
||||
entry.accounts.iter().find(|(kind, _)| nssa::AccountId::for_private_account(npk, kind) == account_id)
|
||||
if let Some((kind, account)) = entry
|
||||
.accounts
|
||||
.iter()
|
||||
.find(|(kind, _)| nssa::AccountId::for_private_account(npk, kind) == account_id)
|
||||
{
|
||||
return Some((entry.key_chain.clone(), account.clone(), kind.identifier()));
|
||||
}
|
||||
@ -181,8 +184,11 @@ impl NSSAUserData {
|
||||
if let Some(node) = self.private_key_tree.get_node(account_id) {
|
||||
let key_chain = &node.value.0;
|
||||
let npk = &key_chain.nullifier_public_key;
|
||||
if let Some((kind, account)) =
|
||||
node.value.1.iter().find(|(kind, _)| nssa::AccountId::for_private_account(npk, kind) == account_id)
|
||||
if let Some((kind, account)) = node
|
||||
.value
|
||||
.1
|
||||
.iter()
|
||||
.find(|(kind, _)| nssa::AccountId::for_private_account(npk, kind) == account_id)
|
||||
{
|
||||
return Some((key_chain.clone(), account.clone(), kind.identifier()));
|
||||
}
|
||||
|
||||
@ -91,10 +91,12 @@ impl InputAccountIdentity {
|
||||
#[must_use]
|
||||
pub fn npk_if_private_pda(&self) -> Option<(NullifierPublicKey, Identifier)> {
|
||||
match self {
|
||||
Self::PrivatePdaInit { npk, identifier, .. } => Some((*npk, *identifier)),
|
||||
Self::PrivatePdaUpdate { nsk, identifier, .. } => {
|
||||
Some((NullifierPublicKey::from(nsk), *identifier))
|
||||
}
|
||||
Self::PrivatePdaInit {
|
||||
npk, identifier, ..
|
||||
} => Some((*npk, *identifier)),
|
||||
Self::PrivatePdaUpdate {
|
||||
nsk, identifier, ..
|
||||
} => Some((NullifierPublicKey::from(nsk), *identifier)),
|
||||
Self::Public
|
||||
| Self::PrivateAuthorizedInit { .. }
|
||||
| Self::PrivateAuthorizedUpdate { .. }
|
||||
|
||||
@ -8,11 +8,7 @@ use serde::{Deserialize, Serialize};
|
||||
#[cfg(feature = "host")]
|
||||
pub use shared_key_derivation::{EphemeralPublicKey, EphemeralSecretKey, ViewingPublicKey};
|
||||
|
||||
use crate::{
|
||||
Commitment,
|
||||
account::Account,
|
||||
program::PrivateAccountKind,
|
||||
};
|
||||
use crate::{Commitment, account::Account, program::PrivateAccountKind};
|
||||
#[cfg(feature = "host")]
|
||||
pub mod shared_key_derivation;
|
||||
|
||||
@ -126,7 +122,10 @@ impl EncryptionScheme {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{account::{Account, AccountId}, program::PdaSeed};
|
||||
use crate::{
|
||||
account::{Account, AccountId},
|
||||
program::PdaSeed,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn encrypt_same_length_for_account_and_pda() {
|
||||
|
||||
@ -11,8 +11,8 @@ pub use commitment::{
|
||||
compute_digest_for_path,
|
||||
};
|
||||
pub use encryption::{EncryptionScheme, SharedSecretKey};
|
||||
pub use program::PrivateAccountKind;
|
||||
pub use nullifier::{Identifier, Nullifier, NullifierPublicKey, NullifierSecretKey};
|
||||
pub use program::PrivateAccountKind;
|
||||
|
||||
pub mod account;
|
||||
mod circuit_io;
|
||||
|
||||
@ -84,7 +84,11 @@ impl PrivateAccountKind {
|
||||
bytes[1..17].copy_from_slice(&identifier.to_le_bytes());
|
||||
// bytes[17..81] are zero padding
|
||||
}
|
||||
Self::Pda { program_id, seed, identifier } => {
|
||||
Self::Pda {
|
||||
program_id,
|
||||
seed,
|
||||
identifier,
|
||||
} => {
|
||||
bytes[0] = 0x01;
|
||||
for (i, &word) in program_id.iter().enumerate() {
|
||||
bytes[1 + i * 4..1 + (i + 1) * 4].copy_from_slice(&word.to_le_bytes());
|
||||
@ -107,13 +111,16 @@ impl PrivateAccountKind {
|
||||
0x01 => {
|
||||
let mut program_id = [0u32; 8];
|
||||
for (i, word) in program_id.iter_mut().enumerate() {
|
||||
*word = u32::from_le_bytes(
|
||||
bytes[1 + i * 4..1 + (i + 1) * 4].try_into().unwrap(),
|
||||
);
|
||||
*word =
|
||||
u32::from_le_bytes(bytes[1 + i * 4..1 + (i + 1) * 4].try_into().unwrap());
|
||||
}
|
||||
let seed = PdaSeed::new(bytes[33..65].try_into().unwrap());
|
||||
let identifier = Identifier::from_le_bytes(bytes[65..81].try_into().unwrap());
|
||||
Some(Self::Pda { program_id, seed, identifier })
|
||||
Some(Self::Pda {
|
||||
program_id,
|
||||
seed,
|
||||
identifier,
|
||||
})
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
@ -180,9 +187,11 @@ impl AccountId {
|
||||
pub fn for_private_account(npk: &NullifierPublicKey, kind: &PrivateAccountKind) -> Self {
|
||||
match kind {
|
||||
PrivateAccountKind::Regular(identifier) => Self::from((npk, *identifier)),
|
||||
PrivateAccountKind::Pda { program_id, seed, identifier } => {
|
||||
Self::for_private_pda(program_id, seed, npk, *identifier)
|
||||
}
|
||||
PrivateAccountKind::Pda {
|
||||
program_id,
|
||||
seed,
|
||||
identifier,
|
||||
} => Self::for_private_pda(program_id, seed, npk, *identifier),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -952,8 +961,8 @@ mod tests {
|
||||
let npk = NullifierPublicKey([3; 32]);
|
||||
let identifier: Identifier = u128::MAX;
|
||||
let expected = AccountId::new([
|
||||
59, 239, 182, 97, 14, 220, 96, 115, 238, 133, 143, 33, 234, 82, 237, 255, 148, 110,
|
||||
54, 124, 98, 159, 245, 101, 146, 182, 150, 54, 37, 62, 25, 17,
|
||||
59, 239, 182, 97, 14, 220, 96, 115, 238, 133, 143, 33, 234, 82, 237, 255, 148, 110, 54,
|
||||
124, 98, 159, 245, 101, 146, 182, 150, 54, 37, 62, 25, 17,
|
||||
]);
|
||||
assert_eq!(
|
||||
AccountId::for_private_pda(&program_id, &seed, &npk, identifier),
|
||||
|
||||
@ -462,7 +462,11 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
decrypt_kind(&output, &shared_secret, 0),
|
||||
PrivateAccountKind::Pda { program_id: program.id(), seed, identifier },
|
||||
PrivateAccountKind::Pda {
|
||||
program_id: program.id(),
|
||||
seed,
|
||||
identifier
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -593,7 +597,10 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(decrypt_kind(&output, &ssk, 0), PrivateAccountKind::Regular(identifier));
|
||||
assert_eq!(
|
||||
decrypt_kind(&output, &ssk, 0),
|
||||
PrivateAccountKind::Regular(identifier)
|
||||
);
|
||||
}
|
||||
|
||||
/// `PrivateUnauthorized` with a non-default identifier produces a ciphertext that decrypts
|
||||
@ -606,7 +613,11 @@ mod tests {
|
||||
let ssk = SharedSecretKey::new(&[55; 32], &keys.vpk());
|
||||
|
||||
let sender = AccountWithMetadata::new(
|
||||
Account { program_owner: program.id(), balance: 1, ..Account::default() },
|
||||
Account {
|
||||
program_owner: program.id(),
|
||||
balance: 1,
|
||||
..Account::default()
|
||||
},
|
||||
true,
|
||||
AccountId::new([0; 32]),
|
||||
);
|
||||
@ -628,7 +639,10 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(decrypt_kind(&output, &ssk, 0), PrivateAccountKind::Regular(identifier));
|
||||
assert_eq!(
|
||||
decrypt_kind(&output, &ssk, 0),
|
||||
PrivateAccountKind::Regular(identifier)
|
||||
);
|
||||
}
|
||||
|
||||
/// `PrivateAuthorizedUpdate` with a non-default identifier produces a ciphertext that decrypts
|
||||
@ -640,7 +654,11 @@ mod tests {
|
||||
let identifier: u128 = 99;
|
||||
let ssk = SharedSecretKey::new(&[55; 32], &keys.vpk());
|
||||
let account_id = AccountId::from((&keys.npk(), identifier));
|
||||
let account = Account { program_owner: program.id(), balance: 1, ..Account::default() };
|
||||
let account = Account {
|
||||
program_owner: program.id(),
|
||||
balance: 1,
|
||||
..Account::default()
|
||||
};
|
||||
let commitment = Commitment::new(&account_id, &account);
|
||||
let mut commitment_set = CommitmentSet::with_capacity(1);
|
||||
commitment_set.extend(std::slice::from_ref(&commitment));
|
||||
@ -664,7 +682,10 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(decrypt_kind(&output, &ssk, 0), PrivateAccountKind::Regular(identifier));
|
||||
assert_eq!(
|
||||
decrypt_kind(&output, &ssk, 0),
|
||||
PrivateAccountKind::Regular(identifier)
|
||||
);
|
||||
}
|
||||
|
||||
/// `PrivatePdaUpdate` with a non-default identifier produces a ciphertext that decrypts
|
||||
@ -681,8 +702,11 @@ mod tests {
|
||||
|
||||
let auth_transfer_id = auth_transfer.id();
|
||||
let pda_id = AccountId::for_private_pda(&program.id(), &seed, &npk, identifier);
|
||||
let pda_account =
|
||||
Account { program_owner: auth_transfer_id, balance: 1, ..Account::default() };
|
||||
let pda_account = Account {
|
||||
program_owner: auth_transfer_id,
|
||||
balance: 1,
|
||||
..Account::default()
|
||||
};
|
||||
let pda_commitment = Commitment::new(&pda_id, &pda_account);
|
||||
let mut commitment_set = CommitmentSet::with_capacity(1);
|
||||
commitment_set.extend(std::slice::from_ref(&pda_commitment));
|
||||
@ -691,8 +715,10 @@ mod tests {
|
||||
let recipient_pre =
|
||||
AccountWithMetadata::new(Account::default(), true, AccountId::new([0; 32]));
|
||||
|
||||
let program_with_deps =
|
||||
ProgramWithDependencies::new(program.clone(), [(auth_transfer_id, auth_transfer)].into());
|
||||
let program_with_deps = ProgramWithDependencies::new(
|
||||
program.clone(),
|
||||
[(auth_transfer_id, auth_transfer)].into(),
|
||||
);
|
||||
|
||||
let (output, _) = execute_and_prove(
|
||||
vec![pda_pre, recipient_pre],
|
||||
@ -712,7 +738,11 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
decrypt_kind(&output, &ssk, 0),
|
||||
PrivateAccountKind::Pda { program_id: program.id(), seed, identifier },
|
||||
PrivateAccountKind::Pda {
|
||||
program_id: program.id(),
|
||||
seed,
|
||||
identifier
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +253,13 @@ pub mod tests {
|
||||
let esk = [3; 32];
|
||||
let shared_secret = SharedSecretKey::new(&esk, &vpk);
|
||||
let epk = EphemeralPublicKey::from_scalar(esk);
|
||||
let ciphertext = EncryptionScheme::encrypt(&account, &PrivateAccountKind::Regular(0), &shared_secret, &commitment, 2);
|
||||
let ciphertext = EncryptionScheme::encrypt(
|
||||
&account,
|
||||
&PrivateAccountKind::Regular(0),
|
||||
&shared_secret,
|
||||
&commitment,
|
||||
2,
|
||||
);
|
||||
let encrypted_account_data =
|
||||
EncryptedAccountData::new(ciphertext.clone(), &npk, &vpk, epk.clone());
|
||||
|
||||
|
||||
@ -168,7 +168,6 @@ impl Program {
|
||||
elf: PINATA_TOKEN_ELF.to_vec(),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -343,7 +342,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[must_use]
|
||||
pub fn changer_claimer() -> Self {
|
||||
use test_program_methods::{CHANGER_CLAIMER_ELF, CHANGER_CLAIMER_ID};
|
||||
|
||||
@ -4341,7 +4341,7 @@ pub mod tests {
|
||||
let alice_shared_0 = SharedSecretKey::new(&[10; 32], &alice_keys.vpk());
|
||||
let alice_shared_1 = SharedSecretKey::new(&[11; 32], &alice_keys.vpk());
|
||||
|
||||
// Fund alice_pda_0
|
||||
// Fund alice_pda_0
|
||||
{
|
||||
let funder_account = state.get_account_by_id(funder_id);
|
||||
let funder_nonce = funder_account.nonce;
|
||||
@ -4365,12 +4365,15 @@ pub mod tests {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![funder_id],
|
||||
vec![funder_nonce],
|
||||
vec![(alice_npk, alice_keys.vpk(), EphemeralPublicKey::from_scalar([10; 32]))],
|
||||
vec![(
|
||||
alice_npk,
|
||||
alice_keys.vpk(),
|
||||
EphemeralPublicKey::from_scalar([10; 32]),
|
||||
)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
let witness_set =
|
||||
WitnessSet::for_message(&message, proof, &[&funder_keys.signing_key]);
|
||||
let witness_set = WitnessSet::for_message(&message, proof, &[&funder_keys.signing_key]);
|
||||
state
|
||||
.transition_from_privacy_preserving_transaction(
|
||||
&PrivacyPreservingTransaction::new(message, witness_set),
|
||||
@ -4380,7 +4383,7 @@ pub mod tests {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
// Fund alice_pda_1
|
||||
// Fund alice_pda_1
|
||||
{
|
||||
let funder_account = state.get_account_by_id(funder_id);
|
||||
let funder_nonce = funder_account.nonce;
|
||||
@ -4404,12 +4407,15 @@ pub mod tests {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![funder_id],
|
||||
vec![funder_nonce],
|
||||
vec![(alice_npk, alice_keys.vpk(), EphemeralPublicKey::from_scalar([11; 32]))],
|
||||
vec![(
|
||||
alice_npk,
|
||||
alice_keys.vpk(),
|
||||
EphemeralPublicKey::from_scalar([11; 32]),
|
||||
)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
let witness_set =
|
||||
WitnessSet::for_message(&message, proof, &[&funder_keys.signing_key]);
|
||||
let witness_set = WitnessSet::for_message(&message, proof, &[&funder_keys.signing_key]);
|
||||
state
|
||||
.transition_from_privacy_preserving_transaction(
|
||||
&PrivacyPreservingTransaction::new(message, witness_set),
|
||||
@ -4451,7 +4457,11 @@ pub mod tests {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![recipient_id],
|
||||
vec![Nonce(0)],
|
||||
vec![(alice_npk, alice_keys.vpk(), EphemeralPublicKey::from_scalar([10; 32]))],
|
||||
vec![(
|
||||
alice_npk,
|
||||
alice_keys.vpk(),
|
||||
EphemeralPublicKey::from_scalar([10; 32]),
|
||||
)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
@ -4491,7 +4501,11 @@ pub mod tests {
|
||||
let message = Message::try_from_circuit_output(
|
||||
vec![recipient_id],
|
||||
vec![],
|
||||
vec![(alice_npk, alice_keys.vpk(), EphemeralPublicKey::from_scalar([11; 32]))],
|
||||
vec![(
|
||||
alice_npk,
|
||||
alice_keys.vpk(),
|
||||
EphemeralPublicKey::from_scalar([11; 32]),
|
||||
)],
|
||||
output,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@ -6,7 +6,7 @@ use std::{
|
||||
use nssa_core::{
|
||||
Commitment, CommitmentSetDigest, DUMMY_COMMITMENT_HASH, EncryptionScheme, Identifier,
|
||||
InputAccountIdentity, MembershipProof, Nullifier, NullifierPublicKey, NullifierSecretKey,
|
||||
PrivateAccountKind, PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput,
|
||||
PrivacyPreservingCircuitInput, PrivacyPreservingCircuitOutput, PrivateAccountKind,
|
||||
SharedSecretKey,
|
||||
account::{Account, AccountId, AccountWithMetadata, Nonce},
|
||||
compute_digest_for_path,
|
||||
@ -25,8 +25,8 @@ struct ExecutionState {
|
||||
block_validity_window: BlockValidityWindow,
|
||||
timestamp_validity_window: TimestampValidityWindow,
|
||||
/// Positions (in `pre_states`) of private-PDA accounts whose supplied npk has been bound to
|
||||
/// their `AccountId` via a proven `AccountId::for_private_pda(program_id, seed, npk, identifier)`
|
||||
/// check.
|
||||
/// their `AccountId` via a proven `AccountId::for_private_pda(program_id, seed, npk,
|
||||
/// identifier)` check.
|
||||
/// Two proof paths populate this set: a `Claim::Pda(seed)` in a program's `post_state` on
|
||||
/// that `pre_state`, or a caller's `ChainedCall.pda_seeds` entry matching that `pre_state`
|
||||
/// under the private derivation. Binding is an idempotent property, not an event: the same
|
||||
@ -35,7 +35,8 @@ struct ExecutionState {
|
||||
/// not `assert!(insert)`. After the main loop, every private-PDA position must appear in this
|
||||
/// map; otherwise the npk is unbound and the circuit rejects.
|
||||
/// The stored `(ProgramId, PdaSeed)` is the owner program and seed, used in
|
||||
/// `compute_circuit_output` to construct `PrivateAccountKind::Pda { program_id, seed, identifier }`.
|
||||
/// `compute_circuit_output` to construct `PrivateAccountKind::Pda { program_id, seed,
|
||||
/// identifier }`.
|
||||
private_pda_bound_positions: HashMap<usize, (ProgramId, PdaSeed)>,
|
||||
/// Across the whole transaction, each `(program_id, seed)` pair may resolve to at most one
|
||||
/// `AccountId`. A seed under a program can derive a family of accounts, one public PDA and
|
||||
@ -210,7 +211,9 @@ impl ExecutionState {
|
||||
for (pos, account_identity) in account_identities.iter().enumerate() {
|
||||
if account_identity.is_private_pda() {
|
||||
assert!(
|
||||
execution_state.private_pda_bound_positions.contains_key(&pos),
|
||||
execution_state
|
||||
.private_pda_bound_positions
|
||||
.contains_key(&pos),
|
||||
"private PDA pre_state at position {pos} has no proven (seed, npk) binding via Claim::Pda or caller pda_seeds"
|
||||
);
|
||||
}
|
||||
@ -361,12 +364,14 @@ impl ExecutionState {
|
||||
.expect(
|
||||
"private PDA pre_state must have an npk in the position map",
|
||||
);
|
||||
let pda = AccountId::for_private_pda(&program_id, &seed, npk, *identifier);
|
||||
let pda =
|
||||
AccountId::for_private_pda(&program_id, &seed, npk, *identifier);
|
||||
assert_eq!(
|
||||
pre_account_id, pda,
|
||||
"Invalid private PDA claim for account {pre_account_id}"
|
||||
);
|
||||
self.private_pda_bound_positions.insert(pre_state_position, (program_id, seed));
|
||||
self.private_pda_bound_positions
|
||||
.insert(pre_state_position, (program_id, seed));
|
||||
assert_family_binding(
|
||||
&mut self.pda_family_binding,
|
||||
program_id,
|
||||
@ -459,7 +464,8 @@ fn resolve_authorization_and_record_bindings(
|
||||
if AccountId::for_public_pda(&caller, seed) == pre_account_id {
|
||||
return Some((*seed, false, caller));
|
||||
}
|
||||
if let Some((npk, identifier)) = private_pda_npk_by_position.get(&pre_state_position)
|
||||
if let Some((npk, identifier)) =
|
||||
private_pda_npk_by_position.get(&pre_state_position)
|
||||
&& AccountId::for_private_pda(&caller, seed, npk, *identifier) == pre_account_id
|
||||
{
|
||||
return Some((*seed, true, caller));
|
||||
@ -614,7 +620,11 @@ fn compute_circuit_output(
|
||||
new_nonce,
|
||||
);
|
||||
}
|
||||
InputAccountIdentity::PrivatePdaInit { npk: _, ssk, identifier } => {
|
||||
InputAccountIdentity::PrivatePdaInit {
|
||||
npk: _,
|
||||
ssk,
|
||||
identifier,
|
||||
} => {
|
||||
// The npk-to-account_id binding is established upstream in
|
||||
// `validate_and_sync_states` via `Claim::Pda(seed)` or a caller `pda_seeds`
|
||||
// match. Here we only enforce the init pre-conditions. The supplied npk on
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
use nssa_core::{
|
||||
account::AccountWithMetadata,
|
||||
program::{AccountPostState, ChainedCall, PdaSeed, ProgramId, ProgramInput, ProgramOutput, read_nssa_inputs},
|
||||
program::{
|
||||
AccountPostState, ChainedCall, PdaSeed, ProgramId, ProgramInput, ProgramOutput,
|
||||
read_nssa_inputs,
|
||||
},
|
||||
};
|
||||
use risc0_zkvm::serde::to_vec;
|
||||
|
||||
@ -8,14 +11,13 @@ use risc0_zkvm::serde::to_vec;
|
||||
///
|
||||
/// The `is_fund` flag selects the operating mode:
|
||||
///
|
||||
/// - `false` (Spend): pre_states = [pda (authorized), recipient].
|
||||
/// Debits the PDA. The PDA-to-npk binding is established via `pda_seeds` in the chained
|
||||
/// call to auth_transfer.
|
||||
/// - `false` (Spend): pre_states = [pda (authorized), recipient]. Debits the PDA. The PDA-to-npk
|
||||
/// binding is established via `pda_seeds` in the chained call to auth_transfer.
|
||||
///
|
||||
/// - `true` (Fund): pre_states = [sender (authorized), pda (foreign/uninitialized)].
|
||||
/// Credits the PDA. A direct call to auth_transfer cannot bind the PDA because auth_transfer
|
||||
/// uses `Claim::Authorized`, not `Claim::Pda`. Routing through this proxy establishes the
|
||||
/// binding via `pda_seeds` in the chained call.
|
||||
/// - `true` (Fund): pre_states = [sender (authorized), pda (foreign/uninitialized)]. Credits the
|
||||
/// PDA. A direct call to auth_transfer cannot bind the PDA because auth_transfer uses
|
||||
/// `Claim::Authorized`, not `Claim::Pda`. Routing through this proxy establishes the binding via
|
||||
/// `pda_seeds` in the chained call.
|
||||
type Instruction = (PdaSeed, u128, ProgramId, bool);
|
||||
|
||||
fn main() {
|
||||
|
||||
@ -90,7 +90,10 @@ impl WalletChainStore {
|
||||
data.account_id(),
|
||||
UserPrivateAccountData {
|
||||
key_chain: data.key_chain,
|
||||
accounts: vec![(PrivateAccountKind::Regular(data.identifier), data.account)],
|
||||
accounts: vec![(
|
||||
PrivateAccountKind::Regular(data.identifier),
|
||||
data.account,
|
||||
)],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@ -283,8 +283,11 @@ impl WalletCore {
|
||||
.0
|
||||
.nullifier_public_key;
|
||||
let account_id = AccountId::from((&npk, identifier));
|
||||
self.storage
|
||||
.insert_private_account_data(account_id, &PrivateAccountKind::Regular(identifier), Account::default());
|
||||
self.storage.insert_private_account_data(
|
||||
account_id,
|
||||
&PrivateAccountKind::Regular(identifier),
|
||||
Account::default(),
|
||||
);
|
||||
(account_id, cci)
|
||||
}
|
||||
|
||||
@ -545,9 +548,16 @@ impl WalletCore {
|
||||
PrivateAccountKind::Regular(identifier) => {
|
||||
nssa::AccountId::from((npk, *identifier))
|
||||
}
|
||||
PrivateAccountKind::Pda { program_id, seed, identifier } => {
|
||||
nssa::AccountId::for_private_pda(program_id, seed, npk, *identifier)
|
||||
}
|
||||
PrivateAccountKind::Pda {
|
||||
program_id,
|
||||
seed,
|
||||
identifier,
|
||||
} => nssa::AccountId::for_private_pda(
|
||||
program_id,
|
||||
seed,
|
||||
npk,
|
||||
*identifier,
|
||||
),
|
||||
};
|
||||
(account_id, kind, res_acc)
|
||||
})
|
||||
|
||||
@ -198,23 +198,19 @@ impl AccountManager {
|
||||
.iter()
|
||||
.map(|state| match state {
|
||||
State::Public { .. } => InputAccountIdentity::Public,
|
||||
State::Private(pre) if pre.is_pda => {
|
||||
match (pre.nsk, pre.proof.clone()) {
|
||||
(Some(nsk), Some(membership_proof)) => {
|
||||
InputAccountIdentity::PrivatePdaUpdate {
|
||||
ssk: pre.ssk,
|
||||
nsk,
|
||||
membership_proof,
|
||||
identifier: pre.identifier,
|
||||
}
|
||||
}
|
||||
_ => InputAccountIdentity::PrivatePdaInit {
|
||||
npk: pre.npk,
|
||||
ssk: pre.ssk,
|
||||
identifier: pre.identifier,
|
||||
},
|
||||
}
|
||||
}
|
||||
State::Private(pre) if pre.is_pda => match (pre.nsk, pre.proof.clone()) {
|
||||
(Some(nsk), Some(membership_proof)) => InputAccountIdentity::PrivatePdaUpdate {
|
||||
ssk: pre.ssk,
|
||||
nsk,
|
||||
membership_proof,
|
||||
identifier: pre.identifier,
|
||||
},
|
||||
_ => InputAccountIdentity::PrivatePdaInit {
|
||||
npk: pre.npk,
|
||||
ssk: pre.ssk,
|
||||
identifier: pre.identifier,
|
||||
},
|
||||
},
|
||||
State::Private(pre) => match (pre.nsk, pre.proof.clone()) {
|
||||
(Some(nsk), Some(membership_proof)) => {
|
||||
InputAccountIdentity::PrivateAuthorizedUpdate {
|
||||
@ -321,4 +317,3 @@ async fn private_acc_preparation(
|
||||
is_pda,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user