diff --git a/lez/wallet/src/lib.rs b/lez/wallet/src/lib.rs index 7dece16a..1c5f9f82 100644 --- a/lez/wallet/src/lib.rs +++ b/lez/wallet/src/lib.rs @@ -514,21 +514,25 @@ impl WalletCore { tx: &lee::privacy_preserving_transaction::PrivacyPreservingTransaction, acc_decode_mask: &[AccDecodeData], ) -> Result<()> { - for (output_index, acc_decode_data) in acc_decode_mask.iter().enumerate() { + for acc_decode_data in acc_decode_mask { match acc_decode_data { AccDecodeData::Decode(secret, acc_account_id) => { - let acc_ead = tx.message.encrypted_private_post_states[output_index].clone(); - let acc_comm = tx.message.new_commitments[output_index].clone(); - - let (kind, res_acc) = lee_core::EncryptionScheme::decrypt( - &acc_ead.ciphertext, - secret, - &acc_comm, - output_index - .try_into() - .expect("Output index is expected to fit in u32"), - ) - .unwrap(); + let (kind, res_acc) = tx + .message + .encrypted_private_post_states + .iter() + .find_map(|encrypted_data| { + tx.message.new_commitments.iter().find_map(|commitment| { + let (kind, res_acc) = lee_core::EncryptionScheme::decrypt( + &encrypted_data.ciphertext, + secret, + commitment, + )?; + (Commitment::new(acc_account_id, &res_acc) == *commitment) + .then_some((kind, res_acc)) + }) + }) + .expect("Self-sent account output expected to be decodable"); println!("Received new acc {res_acc:#?}"); @@ -745,26 +749,20 @@ impl WalletCore { tx.message() .encrypted_private_post_states .iter() - .enumerate() - .filter(move |(_, encrypted_data)| encrypted_data.view_tag == view_tag) - .filter_map(move |(ciph_id, encrypted_data)| { - let ciphertext = &encrypted_data.ciphertext; - let commitment = &new_commitments[ciph_id]; + .filter(move |encrypted_data| encrypted_data.view_tag == view_tag) + .filter_map(move |encrypted_data| { let shared_secret = key_chain.calculate_shared_secret_receiver(&encrypted_data.epk)?; - - lee_core::EncryptionScheme::decrypt( - ciphertext, - &shared_secret, - commitment, - ciph_id - .try_into() - .expect("Ciphertext ID is expected to fit in u32"), - ) - .map(|(kind, res_acc)| { - let npk = &key_chain.nullifier_public_key; + let npk = &key_chain.nullifier_public_key; + new_commitments.iter().find_map(|commitment| { + let (kind, res_acc) = lee_core::EncryptionScheme::decrypt( + &encrypted_data.ciphertext, + &shared_secret, + commitment, + )?; let account_id = lee::AccountId::for_private_account(npk, &kind); - (account_id, kind, res_acc) + (Commitment::new(&account_id, &res_acc) == *commitment) + .then_some((account_id, kind, res_acc)) }) }) .collect::>() @@ -823,12 +821,7 @@ impl WalletCore { for (account_id, npk, vpk, vsk) in shared_keys { let view_tag = EncryptedAccountData::compute_view_tag(&npk, &vpk); - for (ciph_id, encrypted_data) in tx - .message() - .encrypted_private_post_states - .iter() - .enumerate() - { + for encrypted_data in &tx.message().encrypted_private_post_states { if encrypted_data.view_tag != view_tag { continue; } @@ -838,16 +831,17 @@ impl WalletCore { else { continue; }; - let commitment = &tx.message.new_commitments[ciph_id]; - if let Some((_kind, new_acc)) = lee_core::EncryptionScheme::decrypt( - &encrypted_data.ciphertext, - &shared_secret, - commitment, - ciph_id - .try_into() - .expect("Ciphertext ID is expected to fit in u32"), - ) { + let matched = tx.message.new_commitments.iter().find_map(|commitment| { + let (_kind, new_acc) = lee_core::EncryptionScheme::decrypt( + &encrypted_data.ciphertext, + &shared_secret, + commitment, + )?; + (Commitment::new(&account_id, &new_acc) == *commitment).then_some(new_acc) + }); + + if let Some(new_acc) = matched { info!("Synced shared account {account_id:#?} with new state {new_acc:#?}"); self.storage .key_chain_mut()