wallet: Store Sapling key metadata indexed by ivk

Closes #3426.
This commit is contained in:
Jack Grigg 2018-08-27 16:47:17 +01:00
parent e2416930ea
commit a4ac4fc3f4
No known key found for this signature in database
GPG Key ID: 1B8D649257DB0829
3 changed files with 17 additions and 9 deletions

View File

@ -554,8 +554,10 @@ class AddSpendingKeyToWallet : public boost::static_visitor<bool>
{ {
private: private:
CWallet *m_wallet; CWallet *m_wallet;
const Consensus::Params &params;
public: public:
AddSpendingKeyToWallet(CWallet *wallet) : m_wallet(wallet) {} AddSpendingKeyToWallet(CWallet *wallet, const Consensus::Params &params) :
m_wallet(wallet), params(params) {}
bool operator()(const libzcash::SproutSpendingKey &sk) const { bool operator()(const libzcash::SproutSpendingKey &sk) const {
auto addr = sk.address(); auto addr = sk.address();
@ -577,6 +579,7 @@ public:
bool operator()(const libzcash::SaplingSpendingKey &sk) const { bool operator()(const libzcash::SaplingSpendingKey &sk) const {
auto fvk = sk.full_viewing_key(); auto fvk = sk.full_viewing_key();
auto ivk = fvk.in_viewing_key();
auto addr = sk.default_address(); auto addr = sk.default_address();
{ {
// Don't throw error in case a key is already there // Don't throw error in case a key is already there
@ -589,7 +592,10 @@ public:
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding spending key to wallet"); throw JSONRPCError(RPC_WALLET_ERROR, "Error adding spending key to wallet");
} }
m_wallet->mapSaplingZKeyMetadata[addr].nCreateTime = 1; // Sapling addresses can't have been used in transactions prior to activation.
m_wallet->mapSaplingZKeyMetadata[ivk].nCreateTime = std::max(
1, // In case a code fork sets Sapling to always be active
params.vUpgrades[Consensus::UPGRADE_SAPLING].nActivationHeight);
return false; return false;
} }
@ -674,7 +680,8 @@ UniValue z_importkey(const UniValue& params, bool fHelp)
} }
// Sapling support // Sapling support
auto keyAlreadyExists = boost::apply_visitor(AddSpendingKeyToWallet(pwalletMain), spendingkey); auto keyAlreadyExists = boost::apply_visitor(
AddSpendingKeyToWallet(pwalletMain, Params().GetConsensus()), spendingkey);
if (keyAlreadyExists && fIgnoreExistingKey) { if (keyAlreadyExists && fIgnoreExistingKey) {
return NullUniValue; return NullUniValue;
} }

View File

@ -107,6 +107,7 @@ SaplingPaymentAddress CWallet::GenerateNewSaplingZKey()
auto sk = SaplingSpendingKey::random(); auto sk = SaplingSpendingKey::random();
auto fvk = sk.full_viewing_key(); auto fvk = sk.full_viewing_key();
auto ivk = fvk.in_viewing_key();
auto addr = sk.default_address(); auto addr = sk.default_address();
// Check for collision, even though it is unlikely to ever occur // Check for collision, even though it is unlikely to ever occur
@ -116,7 +117,7 @@ SaplingPaymentAddress CWallet::GenerateNewSaplingZKey()
// Create new metadata // Create new metadata
int64_t nCreationTime = GetTime(); int64_t nCreationTime = GetTime();
mapSaplingZKeyMetadata[addr] = CKeyMetadata(nCreationTime); mapSaplingZKeyMetadata[ivk] = CKeyMetadata(nCreationTime);
if (!AddSaplingZKey(sk, addr)) { if (!AddSaplingZKey(sk, addr)) {
throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed"); throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed");

View File

@ -846,7 +846,7 @@ public:
std::set<int64_t> setKeyPool; std::set<int64_t> setKeyPool;
std::map<CKeyID, CKeyMetadata> mapKeyMetadata; std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
std::map<libzcash::SproutPaymentAddress, CKeyMetadata> mapZKeyMetadata; std::map<libzcash::SproutPaymentAddress, CKeyMetadata> mapZKeyMetadata;
std::map<libzcash::SaplingPaymentAddress, CKeyMetadata> mapSaplingZKeyMetadata; std::map<libzcash::SaplingIncomingViewingKey, CKeyMetadata> mapSaplingZKeyMetadata;
typedef std::map<unsigned int, CMasterKey> MasterKeyMap; typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
MasterKeyMap mapMasterKeys; MasterKeyMap mapMasterKeys;