From d8b860207d3f9bbab33b3e50b72999b6674be9a8 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 14 Jun 2022 01:56:46 +0000 Subject: [PATCH] zcash_client_backend: Remove account from `UnifiedFullViewingKey` The account number is not stored in the ZIP 316 UFVK encoding, and in general won't necessarily be known (e.g. if a UFVK is being imported into a wallet). `zcash_client_sqlite::wallet::init::init_accounts_table` reverts to its previous behaviour of requiring the provided `&[UnifiedFullViewingKey]` to be indexed by account number. --- zcash_client_backend/src/keys.rs | 21 +--------- zcash_client_sqlite/src/lib.rs | 1 - zcash_client_sqlite/src/wallet.rs | 4 +- zcash_client_sqlite/src/wallet/init.rs | 14 ++----- zcash_client_sqlite/src/wallet/transact.rs | 46 ++++++++-------------- 5 files changed, 24 insertions(+), 62 deletions(-) diff --git a/zcash_client_backend/src/keys.rs b/zcash_client_backend/src/keys.rs index f4a599247..9b0b89889 100644 --- a/zcash_client_backend/src/keys.rs +++ b/zcash_client_backend/src/keys.rs @@ -107,7 +107,6 @@ impl UnifiedSpendingKey { pub fn to_unified_full_viewing_key(&self) -> UnifiedFullViewingKey { UnifiedFullViewingKey { - account: self.account, #[cfg(feature = "transparent-inputs")] transparent: Some(self.transparent.to_account_pubkey()), sapling: Some(sapling::ExtendedFullViewingKey::from(&self.sapling)), @@ -137,7 +136,6 @@ impl UnifiedSpendingKey { #[derive(Clone, Debug)] #[doc(hidden)] pub struct UnifiedFullViewingKey { - account: AccountId, #[cfg(feature = "transparent-inputs")] transparent: Option, // TODO: This type is invalid for a UFVK; create a `sapling::DiversifiableFullViewingKey` @@ -149,7 +147,6 @@ pub struct UnifiedFullViewingKey { impl UnifiedFullViewingKey { /// Construct a new unified full viewing key, if the required components are present. pub fn new( - account: AccountId, #[cfg(feature = "transparent-inputs")] transparent: Option, sapling: Option, ) -> Option { @@ -157,7 +154,6 @@ impl UnifiedFullViewingKey { None } else { Some(UnifiedFullViewingKey { - account, #[cfg(feature = "transparent-inputs")] transparent, sapling, @@ -167,11 +163,7 @@ impl UnifiedFullViewingKey { /// Attempts to decode the given string as an encoding of a `UnifiedFullViewingKey` /// for the given network. - pub fn decode( - params: &P, - encoding: &str, - account: AccountId, - ) -> Result { + pub fn decode(params: &P, encoding: &str) -> Result { encoding .strip_prefix("DONOTUSEUFVK") .and_then(|data| hex::decode(data).ok()) @@ -199,7 +191,6 @@ impl UnifiedFullViewingKey { }; Some(Self { - account, #[cfg(feature = "transparent-inputs")] transparent, sapling, @@ -227,12 +218,6 @@ impl UnifiedFullViewingKey { format!("DONOTUSEUFVK{}", hex::encode(&ufvk)) } - /// Returns the ZIP32 account identifier to which all component - /// keys are related. - pub fn account(&self) -> AccountId { - self.account - } - /// Returns the transparent component of the unified key at the /// BIP44 path `m/44'/'/'`. #[cfg(feature = "transparent-inputs")] @@ -370,7 +355,6 @@ mod tests { let transparent = { None }; let ufvk = UnifiedFullViewingKey::new( - account, #[cfg(feature = "transparent-inputs")] transparent, sapling, @@ -378,8 +362,7 @@ mod tests { .unwrap(); let encoding = ufvk.encode(&MAIN_NETWORK); - let decoded = UnifiedFullViewingKey::decode(&MAIN_NETWORK, &encoding, account).unwrap(); - assert_eq!(decoded.account, ufvk.account); + let decoded = UnifiedFullViewingKey::decode(&MAIN_NETWORK, &encoding).unwrap(); #[cfg(feature = "transparent-inputs")] assert_eq!( decoded.transparent.map(|t| t.serialize()), diff --git a/zcash_client_sqlite/src/lib.rs b/zcash_client_sqlite/src/lib.rs index a1fbe4d44..425757c54 100644 --- a/zcash_client_sqlite/src/lib.rs +++ b/zcash_client_sqlite/src/lib.rs @@ -802,7 +802,6 @@ mod tests { let taddr = None; let ufvk = UnifiedFullViewingKey::new( - account, #[cfg(feature = "transparent-inputs")] tkey, Some(extfvk.clone()), diff --git a/zcash_client_sqlite/src/wallet.rs b/zcash_client_sqlite/src/wallet.rs index 23fd17604..aa7f1b14b 100644 --- a/zcash_client_sqlite/src/wallet.rs +++ b/zcash_client_sqlite/src/wallet.rs @@ -208,7 +208,7 @@ pub(crate) fn get_unified_full_viewing_keys( let acct: u32 = row.get(0)?; let account = AccountId::from(acct); let ufvk_str: String = row.get(1)?; - let ufvk = UnifiedFullViewingKey::decode(&wdb.params, &ufvk_str, account) + let ufvk = UnifiedFullViewingKey::decode(&wdb.params, &ufvk_str) .map_err(SqliteClientError::CorruptedData); Ok((account, ufvk)) @@ -240,7 +240,7 @@ pub fn is_valid_account_extfvk( .prepare("SELECT ufvk FROM accounts WHERE account = ?")? .query_row(&[u32::from(account).to_sql()?], |row| { row.get(0).map(|ufvk_str: String| { - UnifiedFullViewingKey::decode(&wdb.params, &ufvk_str, account) + UnifiedFullViewingKey::decode(&wdb.params, &ufvk_str) .map_err(SqliteClientError::CorruptedData) }) }) diff --git a/zcash_client_sqlite/src/wallet/init.rs b/zcash_client_sqlite/src/wallet/init.rs index 7ec505cc0..d589f8ba0 100644 --- a/zcash_client_sqlite/src/wallet/init.rs +++ b/zcash_client_sqlite/src/wallet/init.rs @@ -180,7 +180,7 @@ pub fn init_wallet_db

(wdb: &WalletDb

) -> Result<(), rusqlite::Error> { /// let account = AccountId::from(0); /// let extsk = sapling::spending_key(&seed, Network::TestNetwork.coin_type(), account); /// let extfvk = ExtendedFullViewingKey::from(&extsk); -/// let ufvk = UnifiedFullViewingKey::new(account, None, Some(extfvk)).unwrap(); +/// let ufvk = UnifiedFullViewingKey::new(None, Some(extfvk)).unwrap(); /// init_accounts_table(&db_data, &[ufvk]).unwrap(); /// # } /// ``` @@ -199,7 +199,7 @@ pub fn init_accounts_table( // Insert accounts atomically wdb.conn.execute("BEGIN IMMEDIATE", NO_PARAMS)?; - for key in keys.iter() { + for (account, key) in (0u32..).zip(keys) { let ufvk_str: String = key.encode(&wdb.params); let address_str: String = key.default_address().0.encode(&wdb.params); #[cfg(feature = "transparent-inputs")] @@ -214,12 +214,7 @@ pub fn init_accounts_table( wdb.conn.execute( "INSERT INTO accounts (account, ufvk, address, transparent_address) VALUES (?, ?, ?, ?)", - params![ - u32::from(key.account()), - ufvk_str, - address_str, - taddress_str, - ], + params![account, ufvk_str, address_str, taddress_str], )?; } wdb.conn.execute("COMMIT", NO_PARAMS)?; @@ -328,7 +323,6 @@ mod tests { #[cfg(feature = "transparent-inputs")] let ufvk = UnifiedFullViewingKey::new( - account, Some( transparent::AccountPrivKey::from_seed(&network(), &seed, account) .unwrap() @@ -339,7 +333,7 @@ mod tests { .unwrap(); #[cfg(not(feature = "transparent-inputs"))] - let ufvk = UnifiedFullViewingKey::new(account, Some(extfvk)).unwrap(); + let ufvk = UnifiedFullViewingKey::new(Some(extfvk)).unwrap(); init_accounts_table(&db_data, &[ufvk.clone()]).unwrap(); diff --git a/zcash_client_sqlite/src/wallet/transact.rs b/zcash_client_sqlite/src/wallet/transact.rs index c6ea61916..ef1aa6067 100644 --- a/zcash_client_sqlite/src/wallet/transact.rs +++ b/zcash_client_sqlite/src/wallet/transact.rs @@ -219,24 +219,14 @@ mod tests { transparent::AccountPrivKey::from_seed(&network(), &[1u8; 32], AccountId::from(1)) .unwrap(); [ - UnifiedFullViewingKey::new( - AccountId::from(0), - Some(tsk0.to_account_pubkey()), - Some(extfvk0), - ) - .unwrap(), - UnifiedFullViewingKey::new( - AccountId::from(1), - Some(tsk1.to_account_pubkey()), - Some(extfvk1), - ) - .unwrap(), + UnifiedFullViewingKey::new(Some(tsk0.to_account_pubkey()), Some(extfvk0)).unwrap(), + UnifiedFullViewingKey::new(Some(tsk1.to_account_pubkey()), Some(extfvk1)).unwrap(), ] }; #[cfg(not(feature = "transparent-inputs"))] let ufvks = [ - UnifiedFullViewingKey::new(AccountId::from(0), Some(extfvk0)).unwrap(), - UnifiedFullViewingKey::new(AccountId::from(1), Some(extfvk1)).unwrap(), + UnifiedFullViewingKey::new(Some(extfvk0)).unwrap(), + UnifiedFullViewingKey::new(Some(extfvk1)).unwrap(), ]; init_accounts_table(&db_data, &ufvks).unwrap(); @@ -288,9 +278,9 @@ mod tests { let extfvk = ExtendedFullViewingKey::from(&extsk); #[cfg(feature = "transparent-inputs")] - let ufvk = UnifiedFullViewingKey::new(AccountId::from(0), None, Some(extfvk)).unwrap(); + let ufvk = UnifiedFullViewingKey::new(None, Some(extfvk)).unwrap(); #[cfg(not(feature = "transparent-inputs"))] - let ufvk = UnifiedFullViewingKey::new(AccountId::from(0), Some(extfvk)).unwrap(); + let ufvk = UnifiedFullViewingKey::new(Some(extfvk)).unwrap(); init_accounts_table(&db_data, &[ufvk]).unwrap(); let to = extsk.default_address().1.into(); @@ -331,9 +321,9 @@ mod tests { let extsk = sapling::spending_key(&[0u8; 32], network().coin_type(), AccountId::from(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); #[cfg(feature = "transparent-inputs")] - let ufvk = UnifiedFullViewingKey::new(AccountId::from(0), None, Some(extfvk)).unwrap(); + let ufvk = UnifiedFullViewingKey::new(None, Some(extfvk)).unwrap(); #[cfg(not(feature = "transparent-inputs"))] - let ufvk = UnifiedFullViewingKey::new(AccountId::from(0), Some(extfvk)).unwrap(); + let ufvk = UnifiedFullViewingKey::new(Some(extfvk)).unwrap(); init_accounts_table(&db_data, &[ufvk]).unwrap(); let to = extsk.default_address().1.into(); @@ -379,10 +369,9 @@ mod tests { let extsk = sapling::spending_key(&[0u8; 32], network().coin_type(), AccountId::from(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); #[cfg(feature = "transparent-inputs")] - let ufvk = - UnifiedFullViewingKey::new(AccountId::from(0), None, Some(extfvk.clone())).unwrap(); + let ufvk = UnifiedFullViewingKey::new(None, Some(extfvk.clone())).unwrap(); #[cfg(not(feature = "transparent-inputs"))] - let ufvk = UnifiedFullViewingKey::new(AccountId::from(0), Some(extfvk.clone())).unwrap(); + let ufvk = UnifiedFullViewingKey::new(Some(extfvk.clone())).unwrap(); init_accounts_table(&db_data, &[ufvk]).unwrap(); // Add funds to the wallet in a single note @@ -523,10 +512,9 @@ mod tests { let extsk = sapling::spending_key(&[0u8; 32], network().coin_type(), AccountId::from(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); #[cfg(feature = "transparent-inputs")] - let ufvk = - UnifiedFullViewingKey::new(AccountId::from(0), None, Some(extfvk.clone())).unwrap(); + let ufvk = UnifiedFullViewingKey::new(None, Some(extfvk.clone())).unwrap(); #[cfg(not(feature = "transparent-inputs"))] - let ufvk = UnifiedFullViewingKey::new(AccountId::from(0), Some(extfvk.clone())).unwrap(); + let ufvk = UnifiedFullViewingKey::new(Some(extfvk.clone())).unwrap(); init_accounts_table(&db_data, &[ufvk]).unwrap(); // Add funds to the wallet in a single note @@ -653,10 +641,9 @@ mod tests { let extsk = sapling::spending_key(&[0u8; 32], network.coin_type(), AccountId::from(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); #[cfg(feature = "transparent-inputs")] - let ufvk = - UnifiedFullViewingKey::new(AccountId::from(0), None, Some(extfvk.clone())).unwrap(); + let ufvk = UnifiedFullViewingKey::new(None, Some(extfvk.clone())).unwrap(); #[cfg(not(feature = "transparent-inputs"))] - let ufvk = UnifiedFullViewingKey::new(AccountId::from(0), Some(extfvk.clone())).unwrap(); + let ufvk = UnifiedFullViewingKey::new(Some(extfvk.clone())).unwrap(); init_accounts_table(&db_data, &[ufvk]).unwrap(); // Add funds to the wallet in a single note @@ -764,10 +751,9 @@ mod tests { let extsk = sapling::spending_key(&[0u8; 32], network().coin_type(), AccountId::from(0)); let extfvk = ExtendedFullViewingKey::from(&extsk); #[cfg(feature = "transparent-inputs")] - let ufvk = - UnifiedFullViewingKey::new(AccountId::from(0), None, Some(extfvk.clone())).unwrap(); + let ufvk = UnifiedFullViewingKey::new(None, Some(extfvk.clone())).unwrap(); #[cfg(not(feature = "transparent-inputs"))] - let ufvk = UnifiedFullViewingKey::new(AccountId::from(0), Some(extfvk.clone())).unwrap(); + let ufvk = UnifiedFullViewingKey::new(Some(extfvk.clone())).unwrap(); init_accounts_table(&db_data, &[ufvk]).unwrap(); // Add funds to the wallet in a single note