From 900cd50741c64e34046909671602eff76d9fd13c Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Wed, 22 Dec 2021 13:57:37 -0700 Subject: [PATCH] Rename `ZcashdUnifiedSpendingKeyMetadata` -> `ZcashdUnifiedAccount` Also, fix a couple of minor documentation issues and make UA generation tests a little more robust. --- src/keystore.h | 14 ++++++++++---- src/rust/include/librustzcash.h | 5 +---- src/rust/src/rustzcash.rs | 3 +-- src/wallet/gtest/test_wallet.cpp | 5 ++++- src/wallet/wallet.cpp | 10 +++++----- src/wallet/wallet.h | 8 ++++---- src/wallet/walletdb.cpp | 18 +++++++++++++----- src/wallet/walletdb.h | 12 ++++++------ 8 files changed, 44 insertions(+), 31 deletions(-) diff --git a/src/keystore.h b/src/keystore.h index 662b49bcc..140baf7a9 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -107,6 +107,16 @@ public: const libzcash::ZcashdUnifiedFullViewingKey &ufvk ) = 0; + /** + * Add the transparent component of the unified address, if any, + * to the keystore to make it possible to identify the unified + * full viewing key from which a transparent address was derived. + * It is not necessary for implementations to add shielded address + * components to the keystore because those will be automatically + * reconstructed when scanning the chain with a shielded incoming + * viewing key upon discovery of the address as having received + * funds. + */ virtual void AddUnifiedAddress( const libzcash::UFVKId& keyId, const std::pair& ua @@ -347,10 +357,6 @@ public: virtual bool AddUnifiedFullViewingKey( const libzcash::ZcashdUnifiedFullViewingKey &ufvk); - /** - * Add the transparent component of the unified address, if any, - * to the keystore to make it possible to identify the - */ virtual void AddUnifiedAddress( const libzcash::UFVKId& keyId, const std::pair& ua); diff --git a/src/rust/include/librustzcash.h b/src/rust/include/librustzcash.h index 8f6e29679..b10e3e380 100644 --- a/src/rust/include/librustzcash.h +++ b/src/rust/include/librustzcash.h @@ -358,15 +358,12 @@ extern "C" { * to obtain the diversifier index `j` at which the diversivier was * derived. * - * Returns `true` if the diversifier decrypted successfully to an index, - * `false` otherwise. - * * Arguments: * - dk: [c_uchar; 32] the byte representation of a Sapling diversifier key * - addr: [c_uchar; 11] the bytes of the diversifier * - j_ret: [c_uchar; 11] array that will store the resulting diversifier index */ - bool librustzcash_sapling_diversifier_index( + void librustzcash_sapling_diversifier_index( const unsigned char *dk, const unsigned char *d, unsigned char *j_ret diff --git a/src/rust/src/rustzcash.rs b/src/rust/src/rustzcash.rs index 6deb08ce9..6f138608c 100644 --- a/src/rust/src/rustzcash.rs +++ b/src/rust/src/rustzcash.rs @@ -1136,14 +1136,13 @@ pub extern "C" fn librustzcash_sapling_diversifier_index( dk: *const [c_uchar; 32], d: *const [c_uchar; 11], j_ret: *mut [c_uchar; 11], -) -> bool { +) { let dk = zip32::DiversifierKey(unsafe { *dk }); let diversifier = sapling::Diversifier(unsafe { *d }); let j_ret = unsafe { &mut *j_ret }; let j = dk.diversifier_index(&diversifier); j_ret.copy_from_slice(&j.0); - true } #[no_mangle] diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index a0b1a6c40..3e9349c7c 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -2205,9 +2205,12 @@ TEST(WalletTests, GenerateUnifiedAddress) { bool success = std::holds_alternative>(uaResult); EXPECT_TRUE(success); - auto zufvk = skpair.first.ToFullViewingKey(); + auto ufvk = skpair.first.ToFullViewingKey(); auto addrpair = std::get>(uaResult); EXPECT_TRUE(addrpair.first.GetSaplingReceiver().has_value()); + EXPECT_EQ( + addrpair.first.GetSaplingReceiver(), + ufvk.GetSaplingKey().value().Address(addrpair.second.GetDiversifierIndex())); auto u4r = wallet.GetUnifiedForReceiver(addrpair.first.GetSaplingReceiver().value()); EXPECT_EQ(u4r, addrpair.first); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b5c0b4455..a77929962 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -423,7 +423,7 @@ bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingExtendedFullVi return false; } -std::pair CWallet::GenerateNewUnifiedSpendingKey() { +std::pair CWallet::GenerateNewUnifiedSpendingKey() { AssertLockHeld(cs_wallet); if (!mnemonicHDChain.has_value()) { @@ -448,7 +448,7 @@ std::pair CWallet::G } } -std::optional> +std::optional> CWallet::GenerateUnifiedSpendingKeyForAccount(libzcash::AccountId accountId) { AssertLockHeld(cs_wallet); // mapUnifiedSpendingKeyMeta @@ -463,7 +463,7 @@ std::optional mapSproutZKeyMetadata; std::map mapSaplingZKeyMetadata; - std::map, ZcashdUnifiedSpendingKeyMetadata> mapUnifiedSpendingKeyMeta; + std::map, ZcashdUnifiedAccount> mapUnifiedSpendingKeyMeta; std::map mapUnifiedFullViewingKeyMeta; typedef std::map MasterKeyMap; @@ -1168,12 +1168,12 @@ public: //! Generate the unified spending key from the wallet's mnemonic seed //! for the next unused account identifier. - std::pair + std::pair GenerateNewUnifiedSpendingKey(); //! Generate the next available unified spending key from the wallet's //! mnemonic seed. - std::optional> + std::optional> GenerateUnifiedSpendingKeyForAccount(libzcash::AccountId accountId); //! Retrieves the UFVK derived from the wallet's mnemonic seed for the specified account. @@ -1192,7 +1192,7 @@ public: bool AddUnifiedFullViewingKey(const libzcash::UnifiedFullViewingKey &ufvk); bool LoadUnifiedFullViewingKey(const libzcash::UnifiedFullViewingKey &ufvk); - bool LoadUnifiedKeyMetadata(const ZcashdUnifiedSpendingKeyMetadata &skmeta); + bool LoadUnifiedAccount(const ZcashdUnifiedAccount &skmeta); bool LoadUnifiedAddressMetadata(const ZcashdUnifiedAddressMetadata &addrmeta); /** diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index ed0a01268..712227c47 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -221,11 +221,11 @@ bool CWalletDB::EraseSaplingExtendedFullViewingKey( // Unified address & key storage // -bool CWalletDB::WriteUnifiedSpendingKeyMetadata(const ZcashdUnifiedSpendingKeyMetadata& keymeta) +bool CWalletDB::WriteUnifiedAccount(const ZcashdUnifiedAccount& keymeta) { nWalletDBUpdateCounter++; auto ufvkId = keymeta.GetKeyID(); - return Write(std::make_pair(std::string("unifiedskmeta"), ufvkId), keymeta); + return Write(std::make_pair(std::string("unifiedaccount"), keymeta), 0x00); } bool CWalletDB::WriteUnifiedFullViewingKey(const libzcash::UnifiedFullViewingKey& ufvk) @@ -686,10 +686,18 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, return false; } } - else if (strType == "unifiedskmeta") + else if (strType == "unifiedaccount") { - auto keymeta = ZcashdUnifiedSpendingKeyMetadata::Read(ssValue); - if (!pwallet->LoadUnifiedKeyMetadata(keymeta)) { + auto acct = ZcashdUnifiedAccount::Read(ssKey); + + uint8_t value; + ssValue >> value; + if (value != 0x00) { + strErr = "Error reading wallet database: invalid unified account value."; + return false; + } + + if (!pwallet->LoadUnifiedAccount(acct)) { strErr = "Error reading wallet database: account ID mismatch for unified spending key."; return false; }; diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 4310c58ad..e3928d798 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -172,16 +172,16 @@ public: } }; -class ZcashdUnifiedSpendingKeyMetadata { +class ZcashdUnifiedAccount { private: libzcash::SeedFingerprint seedFp; uint32_t bip44CoinType; libzcash::AccountId accountId; libzcash::UFVKId ufvkId; - ZcashdUnifiedSpendingKeyMetadata() {} + ZcashdUnifiedAccount() {} public: - ZcashdUnifiedSpendingKeyMetadata( + ZcashdUnifiedAccount( libzcash::SeedFingerprint seedFp, uint32_t bip44CoinType, libzcash::AccountId accountId, @@ -216,8 +216,8 @@ public: } template - static ZcashdUnifiedSpendingKeyMetadata Read(Stream& stream) { - ZcashdUnifiedSpendingKeyMetadata meta; + static ZcashdUnifiedAccount Read(Stream& stream) { + ZcashdUnifiedAccount meta; stream >> meta; return meta; } @@ -386,7 +386,7 @@ public: /// Unified key support. - bool WriteUnifiedSpendingKeyMetadata(const ZcashdUnifiedSpendingKeyMetadata& keymeta); + bool WriteUnifiedAccount(const ZcashdUnifiedAccount& keymeta); bool WriteUnifiedFullViewingKey(const libzcash::UnifiedFullViewingKey& ufvk); bool WriteUnifiedAddressMetadata(const ZcashdUnifiedAddressMetadata& addrmeta);