Add Orchard components to unified spending keys

Co-authored-by: Jack Grigg <jack@z.cash>
This commit is contained in:
Kris Nuttycombe 2022-02-18 19:00:00 -06:00 committed by Jack Grigg
parent 258f0fc72f
commit 225c78f3ab
4 changed files with 41 additions and 3 deletions

View File

@ -195,6 +195,16 @@ TEST(Keys, DeriveUnifiedFullViewingKeys)
if (test.size() == 1) continue; // comment
try {
// [
// t_key_bytes,
// sapling_fvk_bytes,
// orchard_fvk_bytes,
// unknown_fvk_typecode,
// unknown_fvk_bytes,
// unified_fvk,
// root_seed,
// account,
// ],
auto seed_hex = test[6].get_str();
auto seed_data = ParseHex(seed_hex);
RawHDSeed raw_seed(seed_data.begin(), seed_data.end());
@ -244,6 +254,24 @@ TEST(Keys, DeriveUnifiedFullViewingKeys)
auto key = libzcash::SaplingDiversifiableFullViewingKey::Read(ss);
EXPECT_EQ(key, saplingKey);
}
if (!test[2].isNull()) {
auto expectedHex = test[2].get_str();
// Ensure that the serialized Orchard fvk matches the test data.
auto orchardKey = ufvk.GetOrchardKey().value();
CDataStream ssEncode(SER_NETWORK, PROTOCOL_VERSION);
ssEncode << orchardKey;
EXPECT_EQ(ssEncode.size(), 96);
auto skeyHex = HexStr(ssEncode.begin(), ssEncode.end());
EXPECT_EQ(expectedHex, skeyHex);
// Ensure that parsing the test data derives the correct dfvk
auto data = ParseHex(expectedHex);
ASSERT_EQ(data.size(), 96);
CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
auto key = libzcash::OrchardFullViewingKey::Read(ss);
EXPECT_EQ(key, orchardKey);
}
// Enable the following after Orchard keys are supported.
//{
// auto fvk_data = ParseHex(test[5].get_str());

View File

@ -576,7 +576,8 @@ std::optional<libzcash::ZcashdUnifiedSpendingKey>
throw std::runtime_error("CWallet::GenerateUnifiedSpendingKeyForAccount(): Failed to add Sapling change address to the wallet.");
};
// TODO ORCHARD: Add Orchard component to the wallet
// Add Orchard spending key to the wallet
orchardWallet.AddSpendingKey(usk.value().GetOrchardKey());
auto zufvk = ZcashdUnifiedFullViewingKey::FromUnifiedFullViewingKey(Params(), ufvk);
if (!CCryptoKeyStore::AddUnifiedFullViewingKey(zufvk)) {

View File

@ -39,7 +39,9 @@ std::optional<ZcashdUnifiedSpendingKey> ZcashdUnifiedSpendingKey::ForAccount(
auto saplingKey = SaplingExtendedSpendingKey::ForAccount(seed, bip44CoinType, accountId);
return ZcashdUnifiedSpendingKey(transparentKey.value(), saplingKey.first);
auto orchardKey = OrchardSpendingKey::ForAccount(seed, bip44CoinType, accountId);
return ZcashdUnifiedSpendingKey(transparentKey.value(), saplingKey.first, orchardKey);
}
UnifiedFullViewingKey ZcashdUnifiedSpendingKey::ToFullViewingKey() const {
@ -47,6 +49,7 @@ UnifiedFullViewingKey ZcashdUnifiedSpendingKey::ToFullViewingKey() const {
builder.AddTransparentKey(transparentKey.ToAccountPubKey());
builder.AddSaplingKey(saplingKey.ToXFVK());
builder.AddOrchardKey(orchardKey.ToFullViewingKey());
// This call to .value() is safe as ZcashdUnifiedSpendingKey values are always
// constructed to contain all required components.

View File

@ -248,10 +248,12 @@ class ZcashdUnifiedSpendingKey {
private:
transparent::AccountKey transparentKey;
SaplingExtendedSpendingKey saplingKey;
OrchardSpendingKey orchardKey;
ZcashdUnifiedSpendingKey(
transparent::AccountKey tkey,
SaplingExtendedSpendingKey skey): transparentKey(tkey), saplingKey(skey) {}
SaplingExtendedSpendingKey skey,
OrchardSpendingKey okey): transparentKey(tkey), saplingKey(skey), orchardKey(okey) {}
public:
static std::optional<ZcashdUnifiedSpendingKey> ForAccount(
const HDSeed& seed,
@ -266,6 +268,10 @@ public:
return saplingKey;
}
const OrchardSpendingKey& GetOrchardKey() const {
return orchardKey;
}
UnifiedFullViewingKey ToFullViewingKey() const;
};