Implement OVK selection for z_sendmany.
This commit is contained in:
parent
bdcb12e445
commit
3ddbe1fa06
|
@ -103,6 +103,22 @@ UnifiedFullViewingKeyPtr* unified_full_viewing_key_from_components(
|
||||||
const unsigned char* t_key,
|
const unsigned char* t_key,
|
||||||
const unsigned char* sapling_key);
|
const unsigned char* sapling_key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive the internal and external OVKs for the binary encoding
|
||||||
|
* of a transparent FVK (the concatenated bytes of the serialized
|
||||||
|
* `(ChainCode, CPubKey)` pair.)
|
||||||
|
*
|
||||||
|
* Returns `true` if `t_key` was successfully deserialized,
|
||||||
|
* in which case `internal_ovk_ret` and `external_ovk_ret` (which
|
||||||
|
* should both point to 32-byte arrays) will have been updated
|
||||||
|
* with the appropriate key bytes; otherwise, this procedure
|
||||||
|
* returns `false` and the return values are unmodified.
|
||||||
|
*/
|
||||||
|
bool transparent_key_ovks(
|
||||||
|
const unsigned char* t_key,
|
||||||
|
unsigned char* internal_ovk_ret,
|
||||||
|
unsigned char* external_ovk_ret);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -261,8 +261,8 @@ uint256 AsyncRPCOperation_sendmany::main_impl() {
|
||||||
LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(txOutputAmounts_.z_outputs_total));
|
LogPrint("zrpcunsafe", "%s: private output: %s\n", getId(), FormatMoney(txOutputAmounts_.z_outputs_total));
|
||||||
LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(fee_));
|
LogPrint("zrpc", "%s: fee: %s\n", getId(), FormatMoney(fee_));
|
||||||
|
|
||||||
auto ovks = this->SelectOVKs();
|
|
||||||
auto selectorAccountId = pwalletMain->FindAccountForSelector(ztxoSelector_);
|
auto selectorAccountId = pwalletMain->FindAccountForSelector(ztxoSelector_);
|
||||||
|
auto ovks = this->SelectOVKs(spendable, selectorAccountId);
|
||||||
std::visit(match {
|
std::visit(match {
|
||||||
[&](const CKeyID& keyId) {
|
[&](const CKeyID& keyId) {
|
||||||
auto accountId = selectorAccountId.value_or(ZCASH_LEGACY_ACCOUNT);
|
auto accountId = selectorAccountId.value_or(ZCASH_LEGACY_ACCOUNT);
|
||||||
|
@ -415,10 +415,64 @@ uint256 AsyncRPCOperation_sendmany::main_impl() {
|
||||||
return tx.GetHash();
|
return tx.GetHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<uint256, uint256> AsyncRPCOperation_sendmany::SelectOVKs() const {
|
std::pair<uint256, uint256> AsyncRPCOperation_sendmany::SelectOVKs(
|
||||||
//TODO
|
const SpendableInputs& spendable, std::optional<AccountId> accountId) const {
|
||||||
uint256 internalOVK;
|
uint256 internalOVK;
|
||||||
uint256 externalOVK;
|
uint256 externalOVK;
|
||||||
|
if (!spendable.saplingNoteEntries.empty()) {
|
||||||
|
std::visit(match {
|
||||||
|
[&](const libzcash::SaplingPaymentAddress& addr) {
|
||||||
|
libzcash::SaplingExtendedSpendingKey extsk;
|
||||||
|
assert(pwalletMain->GetSaplingExtendedSpendingKey(addr, extsk));
|
||||||
|
auto extfvk = extsk.ToXFVK();
|
||||||
|
externalOVK = extfvk.fvk.ovk;
|
||||||
|
internalOVK = extfvk.GetInternalDFVK().fvk.ovk;
|
||||||
|
},
|
||||||
|
[&](const AccountZTXOPattern& acct) {
|
||||||
|
auto ufvk = pwalletMain->GetUnifiedFullViewingKeyByAccount(acct.GetAccountId()).value();
|
||||||
|
auto dfvk = ufvk.GetSaplingKey().value();
|
||||||
|
externalOVK = dfvk.fvk.ovk;
|
||||||
|
internalOVK = dfvk.GetInternalDFVK().fvk.ovk;
|
||||||
|
},
|
||||||
|
[&](const auto& other) {
|
||||||
|
throw std::runtime_error("unreachable");
|
||||||
|
}
|
||||||
|
}, this->ztxoSelector_.GetPattern());
|
||||||
|
} else if (!spendable.utxos.empty()) {
|
||||||
|
std::optional<transparent::AccountPubKey> tfvk;
|
||||||
|
std::visit(match {
|
||||||
|
[&](const CKeyID& keyId) {
|
||||||
|
tfvk = pwalletMain->GetLegacyAccountKey().ToAccountPubKey();
|
||||||
|
},
|
||||||
|
[&](const CScriptID& keyId) {
|
||||||
|
tfvk = pwalletMain->GetLegacyAccountKey().ToAccountPubKey();
|
||||||
|
},
|
||||||
|
[&](const AccountZTXOPattern& acct) {
|
||||||
|
// by the time we're here, we know that the UFVK exists for this account
|
||||||
|
auto ufvk = pwalletMain->GetUnifiedFullViewingKeyByAccount(acct.GetAccountId()).value();
|
||||||
|
tfvk = ufvk.GetTransparentKey().value();
|
||||||
|
},
|
||||||
|
[&](const auto& other) {
|
||||||
|
//unreachable
|
||||||
|
}
|
||||||
|
}, this->ztxoSelector_.GetPattern());
|
||||||
|
assert(tfvk.has_value());
|
||||||
|
|
||||||
|
auto ovks = tfvk.value().GetOVKsForShielding();
|
||||||
|
internalOVK = ovks.first;
|
||||||
|
externalOVK = ovks.second;
|
||||||
|
} else if (!spendable.sproutNoteEntries.empty()) {
|
||||||
|
// use the legacy transparent account OVKs when sending from Sprout
|
||||||
|
auto tfvk = pwalletMain->GetLegacyAccountKey().ToAccountPubKey();
|
||||||
|
auto ovks = tfvk.GetOVKsForShielding();
|
||||||
|
internalOVK = ovks.first;
|
||||||
|
externalOVK = ovks.second;
|
||||||
|
} else {
|
||||||
|
// This should be unreachable; it is left in place as a guard to ensure
|
||||||
|
// that when new input types are added to SpendableInputs in the future
|
||||||
|
// that we do not accidentally return the all-zeros OVK.
|
||||||
|
throw std::runtime_error("No spendable inputs.");
|
||||||
|
}
|
||||||
|
|
||||||
return std::make_pair(internalOVK, externalOVK);
|
return std::make_pair(internalOVK, externalOVK);
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,10 +83,9 @@ private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the internal and external OVKs to use in transaction construction, given
|
* Compute the internal and external OVKs to use in transaction construction, given
|
||||||
* the payment source and the set of types that correspond to outputs selected for
|
* the spendable inputs.
|
||||||
* being spent in the transaction.
|
|
||||||
*/
|
*/
|
||||||
std::pair<uint256, uint256> SelectOVKs() const;
|
std::pair<uint256, uint256> SelectOVKs(const SpendableInputs& spendable, std::optional<AccountId> accountId) const;
|
||||||
|
|
||||||
static CAmount DefaultDustThreshold();
|
static CAmount DefaultDustThreshold();
|
||||||
|
|
||||||
|
|
|
@ -260,27 +260,13 @@ CPubKey CWallet::GenerateNewKey()
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
AssertLockHeld(cs_wallet); // mapKeyMetadata
|
||||||
|
|
||||||
auto seedOpt = GetMnemonicSeed();
|
|
||||||
if (!seedOpt.has_value()) {
|
|
||||||
throw std::runtime_error(
|
|
||||||
"CWallet::GenerateNewKey(): Wallet does not have a mnemonic seed.");
|
|
||||||
}
|
|
||||||
auto seed = seedOpt.value();
|
|
||||||
|
|
||||||
if (!mnemonicHDChain.has_value()) {
|
if (!mnemonicHDChain.has_value()) {
|
||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
"CWallet::GenerateNewKey(): Wallet is missing mnemonic seed metadata.");
|
"CWallet::GenerateNewKey(): Wallet is missing mnemonic seed metadata.");
|
||||||
}
|
}
|
||||||
CHDChain& hdChain = mnemonicHDChain.value();
|
CHDChain& hdChain = mnemonicHDChain.value();
|
||||||
|
|
||||||
// All mnemonic seeds are checked at construction to ensure that we can obtain
|
transparent::AccountKey accountKey = this->GetLegacyAccountKey();
|
||||||
// a valid spending key for the account ZCASH_LEGACY_ACCOUNT;
|
|
||||||
// therefore, the `value()` call here is safe.
|
|
||||||
transparent::AccountKey accountKey = transparent::AccountKey::ForAccount(
|
|
||||||
seed,
|
|
||||||
BIP44CoinType(),
|
|
||||||
ZCASH_LEGACY_ACCOUNT).value();
|
|
||||||
|
|
||||||
std::optional<CPubKey> pubkey = std::nullopt;
|
std::optional<CPubKey> pubkey = std::nullopt;
|
||||||
do {
|
do {
|
||||||
auto index = hdChain.GetLegacyTKeyCounter();
|
auto index = hdChain.GetLegacyTKeyCounter();
|
||||||
|
@ -288,7 +274,10 @@ CPubKey CWallet::GenerateNewKey()
|
||||||
hdChain.IncrementLegacyTKeyCounter();
|
hdChain.IncrementLegacyTKeyCounter();
|
||||||
if (key.has_value()) {
|
if (key.has_value()) {
|
||||||
auto keyPath = transparent::AccountKey::KeyPath(BIP44CoinType(), ZCASH_LEGACY_ACCOUNT, true, index);
|
auto keyPath = transparent::AccountKey::KeyPath(BIP44CoinType(), ZCASH_LEGACY_ACCOUNT, true, index);
|
||||||
pubkey = AddTransparentSecretKey(seed.Fingerprint(), std::make_pair(key.value(), keyPath));
|
pubkey = AddTransparentSecretKey(
|
||||||
|
hdChain.GetSeedFingerprint(),
|
||||||
|
std::make_pair(key.value(), keyPath)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// if we did not successfully generate a key, try again.
|
// if we did not successfully generate a key, try again.
|
||||||
} while (!pubkey.has_value());
|
} while (!pubkey.has_value());
|
||||||
|
@ -423,6 +412,24 @@ bool CWallet::AddCryptedSaplingSpendingKey(const libzcash::SaplingExtendedFullVi
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libzcash::transparent::AccountKey CWallet::GetLegacyAccountKey() const {
|
||||||
|
auto seedOpt = GetMnemonicSeed();
|
||||||
|
if (!seedOpt.has_value()) {
|
||||||
|
throw std::runtime_error(
|
||||||
|
"CWallet::GenerateNewKey(): Wallet does not have a mnemonic seed.");
|
||||||
|
}
|
||||||
|
auto seed = seedOpt.value();
|
||||||
|
|
||||||
|
// All mnemonic seeds are checked at construction to ensure that we can obtain
|
||||||
|
// a valid spending key for the account ZCASH_LEGACY_ACCOUNT;
|
||||||
|
// therefore, the `value()` call here is safe.
|
||||||
|
return transparent::AccountKey::ForAccount(
|
||||||
|
seed,
|
||||||
|
BIP44CoinType(),
|
||||||
|
ZCASH_LEGACY_ACCOUNT).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<ZcashdUnifiedSpendingKey, libzcash::AccountId> CWallet::GenerateNewUnifiedSpendingKey() {
|
std::pair<ZcashdUnifiedSpendingKey, libzcash::AccountId> CWallet::GenerateNewUnifiedSpendingKey() {
|
||||||
AssertLockHeld(cs_wallet);
|
AssertLockHeld(cs_wallet);
|
||||||
|
|
||||||
|
@ -6142,81 +6149,6 @@ std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSproutKeyForPaymentAddress
|
|
||||||
|
|
||||||
std::optional<libzcash::SproutSpendingKey> GetSproutKeyForPaymentAddress::operator()(
|
|
||||||
const CKeyID &zaddr) const
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
std::optional<libzcash::SproutSpendingKey> GetSproutKeyForPaymentAddress::operator()(
|
|
||||||
const CScriptID &zaddr) const
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
std::optional<libzcash::SproutSpendingKey> GetSproutKeyForPaymentAddress::operator()(
|
|
||||||
const libzcash::SproutPaymentAddress &zaddr) const
|
|
||||||
{
|
|
||||||
libzcash::SproutSpendingKey k;
|
|
||||||
if (m_wallet->GetSproutSpendingKey(zaddr, k)) {
|
|
||||||
return k;
|
|
||||||
} else {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::optional<libzcash::SproutSpendingKey> GetSproutKeyForPaymentAddress::operator()(
|
|
||||||
const libzcash::SaplingPaymentAddress &zaddr) const
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
std::optional<libzcash::SproutSpendingKey> GetSproutKeyForPaymentAddress::operator()(
|
|
||||||
const libzcash::UnifiedAddress &uaddr) const
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetSaplingKeyForPaymentAddress
|
|
||||||
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> GetSaplingKeyForPaymentAddress::operator()(
|
|
||||||
const CKeyID &zaddr) const
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> GetSaplingKeyForPaymentAddress::operator()(
|
|
||||||
const CScriptID &zaddr) const
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> GetSaplingKeyForPaymentAddress::operator()(
|
|
||||||
const libzcash::SproutPaymentAddress &zaddr) const
|
|
||||||
{
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> GetSaplingKeyForPaymentAddress::operator()(
|
|
||||||
const libzcash::SaplingPaymentAddress &zaddr) const
|
|
||||||
{
|
|
||||||
libzcash::SaplingExtendedSpendingKey extsk;
|
|
||||||
if (m_wallet->GetSaplingExtendedSpendingKey(zaddr, extsk)) {
|
|
||||||
return extsk;
|
|
||||||
} else {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> GetSaplingKeyForPaymentAddress::operator()(
|
|
||||||
const libzcash::UnifiedAddress &uaddr) const
|
|
||||||
{
|
|
||||||
for (const libzcash::Receiver& receiver: uaddr) {
|
|
||||||
auto saplingAddr = std::get_if<SaplingPaymentAddress>(&receiver);
|
|
||||||
if (saplingAddr != nullptr) {
|
|
||||||
libzcash::SaplingExtendedSpendingKey extsk;
|
|
||||||
if (m_wallet->GetSaplingExtendedSpendingKey(*saplingAddr, extsk)) {
|
|
||||||
return extsk;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddViewingKeyToWallet
|
// AddViewingKeyToWallet
|
||||||
|
|
||||||
KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SproutViewingKey &vkey) const {
|
KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SproutViewingKey &vkey) const {
|
||||||
|
|
|
@ -1399,9 +1399,13 @@ public:
|
||||||
const std::vector<unsigned char> &vchCryptedSecret);
|
const std::vector<unsigned char> &vchCryptedSecret);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Unified keys & addresses
|
// Unified keys, addresses, and accounts
|
||||||
//
|
//
|
||||||
|
|
||||||
|
//! Obtain the account key for the legacy account by deriving it from
|
||||||
|
//! the wallet's mnemonic seed.
|
||||||
|
libzcash::transparent::AccountKey GetLegacyAccountKey() const;
|
||||||
|
|
||||||
//! Generate the unified spending key from the wallet's mnemonic seed
|
//! Generate the unified spending key from the wallet's mnemonic seed
|
||||||
//! for the next unused account identifier.
|
//! for the next unused account identifier.
|
||||||
std::pair<libzcash::ZcashdUnifiedSpendingKey, libzcash::AccountId>
|
std::pair<libzcash::ZcashdUnifiedSpendingKey, libzcash::AccountId>
|
||||||
|
@ -1766,34 +1770,6 @@ public:
|
||||||
std::optional<libzcash::ViewingKey> operator()(const libzcash::UnifiedAddress &uaddr) const;
|
std::optional<libzcash::ViewingKey> operator()(const libzcash::UnifiedAddress &uaddr) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GetSproutKeyForPaymentAddress
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
CWallet *m_wallet;
|
|
||||||
public:
|
|
||||||
GetSproutKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
|
|
||||||
|
|
||||||
std::optional<libzcash::SproutSpendingKey> operator()(const CKeyID &zaddr) const;
|
|
||||||
std::optional<libzcash::SproutSpendingKey> operator()(const CScriptID &zaddr) const;
|
|
||||||
std::optional<libzcash::SproutSpendingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
|
|
||||||
std::optional<libzcash::SproutSpendingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
|
||||||
std::optional<libzcash::SproutSpendingKey> operator()(const libzcash::UnifiedAddress &uaddr) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GetSaplingKeyForPaymentAddress
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
CWallet *m_wallet;
|
|
||||||
public:
|
|
||||||
GetSaplingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
|
|
||||||
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> operator()(const CKeyID &zaddr) const;
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> operator()(const CScriptID &zaddr) const;
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
|
|
||||||
std::optional<libzcash::SaplingExtendedSpendingKey> operator()(const libzcash::UnifiedAddress &uaddr) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum PaymentAddressSource {
|
enum PaymentAddressSource {
|
||||||
Random,
|
Random,
|
||||||
LegacyHDSeed,
|
LegacyHDSeed,
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
// file COPYING or https://www.opensource.org/licenses/mit-license.php .
|
||||||
|
|
||||||
|
#include <rust/unified_keys.h>
|
||||||
|
|
||||||
|
#include "streams.h"
|
||||||
#include "transparent.h"
|
#include "transparent.h"
|
||||||
|
|
||||||
namespace libzcash {
|
namespace libzcash {
|
||||||
|
@ -33,6 +36,23 @@ std::optional<CKeyID> AccountPubKey::GetChangeAddress(const diversifier_index_t&
|
||||||
return changeKey.value().GetID();
|
return changeKey.value().GetID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<uint256, uint256> AccountPubKey::GetOVKsForShielding() const {
|
||||||
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ss << pubkey;
|
||||||
|
assert(ss.size() == 65);
|
||||||
|
CSerializeData ss_bytes(ss.begin(), ss.end());
|
||||||
|
|
||||||
|
uint256 internalOVK;
|
||||||
|
uint256 externalOVK;
|
||||||
|
|
||||||
|
assert(transparent_key_ovks(
|
||||||
|
reinterpret_cast<unsigned char*>(ss_bytes.data()),
|
||||||
|
internalOVK.begin(),
|
||||||
|
externalOVK.begin()));
|
||||||
|
|
||||||
|
return std::make_pair(internalOVK, externalOVK);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<std::pair<CKeyID, diversifier_index_t>> AccountPubKey::FindChangeAddress(diversifier_index_t j) const {
|
std::optional<std::pair<CKeyID, diversifier_index_t>> AccountPubKey::FindChangeAddress(diversifier_index_t j) const {
|
||||||
while (true) {
|
while (true) {
|
||||||
auto childIndex = j.ToTransparentChildIndex();
|
auto childIndex = j.ToTransparentChildIndex();
|
||||||
|
|
|
@ -41,6 +41,12 @@ public:
|
||||||
*/
|
*/
|
||||||
std::optional<std::pair<CKeyID, diversifier_index_t>> FindChangeAddress(diversifier_index_t j) const;
|
std::optional<std::pair<CKeyID, diversifier_index_t>> FindChangeAddress(diversifier_index_t j) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the internal and external OVKs for shielding from transparent
|
||||||
|
* addresses derived from this key.
|
||||||
|
*/
|
||||||
|
std::pair<uint256, uint256> GetOVKsForShielding() const;
|
||||||
|
|
||||||
friend bool operator==(const AccountPubKey& a, const AccountPubKey& b)
|
friend bool operator==(const AccountPubKey& a, const AccountPubKey& b)
|
||||||
{
|
{
|
||||||
return a.pubkey == b.pubkey;
|
return a.pubkey == b.pubkey;
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include "zcash/Address.hpp"
|
#include "zcash/Address.hpp"
|
||||||
#include "unified.h"
|
#include "unified.h"
|
||||||
|
|
||||||
|
#include <rust/unified_keys.h>
|
||||||
|
|
||||||
using namespace libzcash;
|
using namespace libzcash;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -126,9 +128,11 @@ std::optional<RecipientAddress> ZcashdUnifiedFullViewingKey::GetChangeAddress(co
|
||||||
std::optional<RecipientAddress> addr;
|
std::optional<RecipientAddress> addr;
|
||||||
std::visit(match {
|
std::visit(match {
|
||||||
[&](const TransparentChangeRequest& req) {
|
[&](const TransparentChangeRequest& req) {
|
||||||
auto changeKey = this->GetTransparentChangeAddress(req.GetIndex());
|
if (transparentKey.has_value()) {
|
||||||
if (changeKey.has_value()) {
|
auto changeAddr = transparentKey.value().GetChangeAddress(req.GetIndex());
|
||||||
addr = changeKey.value();
|
if (changeAddr.has_value()) {
|
||||||
|
addr = changeAddr.value();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[&](const SaplingChangeRequest& req) {
|
[&](const SaplingChangeRequest& req) {
|
||||||
|
@ -141,38 +145,3 @@ std::optional<RecipientAddress> ZcashdUnifiedFullViewingKey::GetChangeAddress(co
|
||||||
}, req);
|
}, req);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<CKeyID> ZcashdUnifiedFullViewingKey::GetTransparentChangeAddress(const diversifier_index_t& j) const {
|
|
||||||
if (transparentKey.has_value()) {
|
|
||||||
auto childIndex = j.ToTransparentChildIndex();
|
|
||||||
if (!childIndex.has_value()) return std::nullopt;
|
|
||||||
|
|
||||||
auto changeKey = transparentKey.value().DeriveInternal(childIndex.value());
|
|
||||||
if (!changeKey.has_value()) return std::nullopt;
|
|
||||||
|
|
||||||
return changeKey.value().GetID();
|
|
||||||
} else {
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//std::optional<std::pair<uint256, uint256>> ZcashdUnifiedFullViewingKey::GetTransparentOVKsForShielding() const {
|
|
||||||
// if (transparentKey.has_value()) {
|
|
||||||
// CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
// ss << transparentKey.value().GetPubKey();
|
|
||||||
// assert(ss.size() == 65);
|
|
||||||
// CSerializeData ss_bytes(ss.begin(), ss.end());
|
|
||||||
//
|
|
||||||
// uint256 internalOVK;
|
|
||||||
// uint256 externalOVK;
|
|
||||||
//
|
|
||||||
// assert(transparent_key_ovks(
|
|
||||||
// reinterpret_cast<unsigned char*>(ss_bytes.data()),
|
|
||||||
// internalOVK.begin(),
|
|
||||||
// externalOVK.begin()));
|
|
||||||
//
|
|
||||||
// return std::make_pair(internalOVK, externalOVK);
|
|
||||||
// } else {
|
|
||||||
// return std::nullopt;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
|
@ -195,13 +195,6 @@ public:
|
||||||
*/
|
*/
|
||||||
std::optional<RecipientAddress> GetChangeAddress(const ChangeRequest& req) const;
|
std::optional<RecipientAddress> GetChangeAddress(const ChangeRequest& req) const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the transparent change address for this UFVK a the given diversifier
|
|
||||||
* index, if the UFVK has a transparent component and it is possible to derive
|
|
||||||
* an address at this index.
|
|
||||||
*/
|
|
||||||
std::optional<CKeyID> GetTransparentChangeAddress(const diversifier_index_t& j) const;
|
|
||||||
|
|
||||||
friend bool operator==(const ZcashdUnifiedFullViewingKey& a, const ZcashdUnifiedFullViewingKey& b)
|
friend bool operator==(const ZcashdUnifiedFullViewingKey& a, const ZcashdUnifiedFullViewingKey& b)
|
||||||
{
|
{
|
||||||
return a.transparentKey == b.transparentKey && a.saplingKey == b.saplingKey;
|
return a.transparentKey == b.transparentKey && a.saplingKey == b.saplingKey;
|
||||||
|
|
|
@ -126,7 +126,7 @@ libzcash::SaplingPaymentAddress SaplingDiversifiableFullViewingKey::DefaultAddre
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
libzcash::SaplingPaymentAddress SaplingDiversifiableFullViewingKey::GetChangeAddress() const {
|
libzcash::SaplingDiversifiableFullViewingKey SaplingDiversifiableFullViewingKey::GetInternalDFVK() const {
|
||||||
CDataStream ss_fvk(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss_fvk(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ss_fvk << fvk;
|
ss_fvk << fvk;
|
||||||
CSerializeData fvk_bytes(ss_fvk.begin(), ss_fvk.end());
|
CSerializeData fvk_bytes(ss_fvk.begin(), ss_fvk.end());
|
||||||
|
@ -141,7 +141,11 @@ libzcash::SaplingPaymentAddress SaplingDiversifiableFullViewingKey::GetChangeAdd
|
||||||
|
|
||||||
CDataStream ss_fvk_ret(fvk_bytes_ret, SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ss_fvk_ret(fvk_bytes_ret, SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ss_fvk_ret >> internalDFVK.fvk;
|
ss_fvk_ret >> internalDFVK.fvk;
|
||||||
|
return internalDFVK;
|
||||||
|
}
|
||||||
|
|
||||||
|
libzcash::SaplingPaymentAddress SaplingDiversifiableFullViewingKey::GetChangeAddress() const {
|
||||||
|
auto internalDFVK = this->GetInternalDFVK();
|
||||||
return internalDFVK.DefaultAddress();
|
return internalDFVK.DefaultAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,8 @@ public:
|
||||||
return std::make_pair(addr.value(), j);
|
return std::make_pair(addr.value(), j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SaplingDiversifiableFullViewingKey GetInternalDFVK() const;
|
||||||
|
|
||||||
libzcash::SaplingPaymentAddress DefaultAddress() const;
|
libzcash::SaplingPaymentAddress DefaultAddress() const;
|
||||||
|
|
||||||
libzcash::SaplingPaymentAddress GetChangeAddress() const;
|
libzcash::SaplingPaymentAddress GetChangeAddress() const;
|
||||||
|
|
Loading…
Reference in New Issue