Add tests for keystore storage and retrieval of UFVKs.

This commit is contained in:
Kris Nuttycombe 2021-12-14 10:09:35 -07:00
parent 0dcdc28a38
commit 700b98f0b0
4 changed files with 46 additions and 4 deletions

View File

@ -14,6 +14,8 @@
#define MAKE_STRING(x) std::string((x), (x)+sizeof(x))
using namespace libzcash;
const uint32_t SLIP44_TESTNET_TYPE = 1;
TEST(KeystoreTests, StoreAndRetrieveMnemonicSeed) {
@ -514,4 +516,33 @@ TEST(KeystoreTests, StoreAndRetrieveSpendingKeyInEncryptedStore) {
ASSERT_EQ(1, addrs.count(addr));
ASSERT_EQ(1, addrs.count(addr2));
}
TEST(KeystoreTests, StoreAndRetrieveUFVK) {
SelectParams(CBaseChainParams::TESTNET);
CBasicKeyStore keyStore;
auto seed = MnemonicSeed::Random(SLIP44_TESTNET_TYPE);
auto usk = ZcashdUnifiedSpendingKey::ForAccount(seed, SLIP44_TESTNET_TYPE, 0);
EXPECT_TRUE(usk.has_value());
auto zufvk = usk.value().ToFullViewingKey();
auto ufvk = UnifiedFullViewingKey::FromZcashdUFVK(zufvk);
auto ufvkid = ufvk.GetKeyID(Params());
EXPECT_TRUE(keyStore.AddUnifiedFullViewingKey(ufvkid, zufvk));
EXPECT_EQ(keyStore.GetUnifiedFullViewingKey(ufvkid).value(), zufvk);
auto addrPair = zufvk.FindAddress(diversifier_index_t(0), {ReceiverType::Sapling});
EXPECT_TRUE(addrPair.first.GetSaplingReceiver().has_value());
auto saplingReceiver = addrPair.first.GetSaplingReceiver().value();
auto saplingIvk = zufvk.GetSaplingKey().value().fvk.in_viewing_key();
keyStore.AddSaplingIncomingViewingKey(saplingIvk, saplingReceiver);
auto ufvkmeta = keyStore.GetUFVKMetadataForReceiver(saplingReceiver);
EXPECT_TRUE(ufvkmeta.has_value());
EXPECT_EQ(ufvkmeta.value().first, ufvkid);
EXPECT_FALSE(ufvkmeta.value().second.has_value());
}
#endif

View File

@ -298,12 +298,20 @@ bool CBasicKeyStore::AddUnifiedFullViewingKey(
{
LOCK(cs_KeyStore);
// Add the Sapling component of the UFVK to the wallet.
auto saplingKey = ufvk.GetSaplingKey();
if (saplingKey.has_value()) {
auto ivk = saplingKey.value().fvk.in_viewing_key();
mapSaplingKeyUnified.insert(std::make_pair(ivk, keyId));
}
// We can't reasonably add the transparent component here, because
// of the way that transparent addresses are generated from the
// P2PHK part of the unified address. Instead, whenever a new
// unified address is generated, the keys associated with the
// transparent part of the address must be added to the keystore.
// Add the UFVK by key identifier.
mapUnifiedFullViewingKeys.insert({keyId, ufvk});
return true;

View File

@ -80,8 +80,7 @@ std::optional<UnifiedAddress> ZcashdUnifiedFullViewingKey::Address(
}
UnifiedAddress ua;
if (saplingKey.has_value() &&
std::find(receiverTypes.begin(), receiverTypes.end(), ReceiverType::Sapling) != receiverTypes.end()) {
if (saplingKey.has_value() && receiverTypes.count(ReceiverType::Sapling) > 0) {
auto saplingAddress = saplingKey.value().Address(j);
if (saplingAddress.has_value()) {
ua.AddReceiver(saplingAddress.value());
@ -90,8 +89,7 @@ std::optional<UnifiedAddress> ZcashdUnifiedFullViewingKey::Address(
}
}
if (transparentKey.has_value() &&
std::find(receiverTypes.begin(), receiverTypes.end(), ReceiverType::P2PKH) != receiverTypes.end()) {
if (transparentKey.has_value() && receiverTypes.count(ReceiverType::P2PKH) > 0) {
const auto& tkey = transparentKey.value();
auto childIndex = j.ToTransparentChildIndex();
if (!childIndex.has_value()) return std::nullopt;

View File

@ -84,6 +84,11 @@ public:
const std::set<ReceiverType>& receiverTypes) const;
std::pair<UnifiedAddress, diversifier_index_t> FindAddress(const diversifier_index_t& j) const;
friend bool operator==(const ZcashdUnifiedFullViewingKey& a, const ZcashdUnifiedFullViewingKey& b)
{
return a.transparentKey == b.transparentKey && a.saplingKey == b.saplingKey;
}
};
/**