mirror of
https://git.hush.is/hush/hush3.git
synced 2025-11-13 00:05:05 -05:00
Add Sapling Add/Have/Get to keystore
This commit is contained in:
parent
cea065e3d4
commit
efb7662d4a
@ -93,6 +93,16 @@ bool CBasicKeyStore::AddSpendingKey(const libzcash::SproutSpendingKey &sk)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Sapling
|
||||||
|
bool CBasicKeyStore::AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk)
|
||||||
|
{
|
||||||
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
auto fvk = sk.full_viewing_key();
|
||||||
|
mapSaplingSpendingKeys[fvk] = sk;
|
||||||
|
//! TODO: Note decryptors for Sapling
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CBasicKeyStore::AddViewingKey(const libzcash::SproutViewingKey &vk)
|
bool CBasicKeyStore::AddViewingKey(const libzcash::SproutViewingKey &vk)
|
||||||
{
|
{
|
||||||
LOCK(cs_SpendingKeyStore);
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
|||||||
@ -55,6 +55,13 @@ public:
|
|||||||
virtual bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const =0;
|
virtual bool HaveSpendingKey(const libzcash::SproutPaymentAddress &address) const =0;
|
||||||
virtual bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0;
|
virtual bool GetSpendingKey(const libzcash::SproutPaymentAddress &address, libzcash::SproutSpendingKey& skOut) const =0;
|
||||||
virtual void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const =0;
|
virtual void GetPaymentAddresses(std::set<libzcash::SproutPaymentAddress> &setAddress) const =0;
|
||||||
|
|
||||||
|
//! Add a Sapling spending key to the store.
|
||||||
|
virtual bool AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk) =0;
|
||||||
|
|
||||||
|
//! Check whether a Sapling spending key corresponding to a given Sapling viewing key is present in the store.
|
||||||
|
virtual bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const =0;
|
||||||
|
virtual bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey& skOut) const =0;
|
||||||
|
|
||||||
//! Support for viewing keys
|
//! Support for viewing keys
|
||||||
virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk) =0;
|
virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk) =0;
|
||||||
@ -70,6 +77,9 @@ typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutSpendingKey> Sp
|
|||||||
typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutViewingKey> ViewingKeyMap;
|
typedef std::map<libzcash::SproutPaymentAddress, libzcash::SproutViewingKey> ViewingKeyMap;
|
||||||
typedef std::map<libzcash::SproutPaymentAddress, ZCNoteDecryption> NoteDecryptorMap;
|
typedef std::map<libzcash::SproutPaymentAddress, ZCNoteDecryption> NoteDecryptorMap;
|
||||||
|
|
||||||
|
typedef std::map<libzcash::SaplingFullViewingKey, libzcash::SaplingSpendingKey> SaplingSpendingKeyMap;
|
||||||
|
typedef std::map<libzcash::SaplingIncomingViewingKey, libzcash::SaplingFullViewingKey> SaplingFullViewingKeyMap;
|
||||||
|
|
||||||
/** Basic key store, that keeps keys in an address->secret map */
|
/** Basic key store, that keeps keys in an address->secret map */
|
||||||
class CBasicKeyStore : public CKeyStore
|
class CBasicKeyStore : public CKeyStore
|
||||||
{
|
{
|
||||||
@ -80,6 +90,8 @@ protected:
|
|||||||
SpendingKeyMap mapSpendingKeys;
|
SpendingKeyMap mapSpendingKeys;
|
||||||
ViewingKeyMap mapViewingKeys;
|
ViewingKeyMap mapViewingKeys;
|
||||||
NoteDecryptorMap mapNoteDecryptors;
|
NoteDecryptorMap mapNoteDecryptors;
|
||||||
|
|
||||||
|
SaplingSpendingKeyMap mapSaplingSpendingKeys;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
|
bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
|
||||||
@ -182,6 +194,32 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Sapling
|
||||||
|
bool AddSaplingSpendingKey(const libzcash::SaplingSpendingKey &sk);
|
||||||
|
bool HaveSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk) const
|
||||||
|
{
|
||||||
|
bool result;
|
||||||
|
{
|
||||||
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
result = (mapSaplingSpendingKeys.count(fvk) > 0);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
bool GetSaplingSpendingKey(const libzcash::SaplingFullViewingKey &fvk, libzcash::SaplingSpendingKey &skOut) const
|
||||||
|
{
|
||||||
|
{
|
||||||
|
LOCK(cs_SpendingKeyStore);
|
||||||
|
|
||||||
|
SaplingSpendingKeyMap::const_iterator mi = mapSaplingSpendingKeys.find(fvk);
|
||||||
|
if (mi != mapSaplingSpendingKeys.end())
|
||||||
|
{
|
||||||
|
skOut = mi->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk);
|
virtual bool AddViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
|
virtual bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
|
|||||||
@ -7,9 +7,42 @@
|
|||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test covers Sapling methods on CWallet
|
||||||
|
* GenerateNewSaplingZKey()
|
||||||
|
*/
|
||||||
|
TEST(wallet_zkeys_tests, store_and_load_sapling_zkeys) {
|
||||||
|
CWallet wallet;
|
||||||
|
|
||||||
|
// wallet should be empty
|
||||||
|
// std::set<libzcash::SaplingPaymentAddress> addrs;
|
||||||
|
// wallet.GetSaplingPaymentAddresses(addrs);
|
||||||
|
// ASSERT_EQ(0, addrs.size());
|
||||||
|
|
||||||
|
// wallet should have one key
|
||||||
|
auto saplingAddr = wallet.GenerateNewSaplingZKey();
|
||||||
|
// ASSERT_NE(boost::get<libzcash::SaplingPaymentAddress>(&address), nullptr);
|
||||||
|
// auto sapling_addr = boost::get<libzcash::SaplingPaymentAddress>(saplingAddr);
|
||||||
|
// wallet.GetSaplingPaymentAddresses(addrs);
|
||||||
|
// ASSERT_EQ(1, addrs.size());
|
||||||
|
|
||||||
|
auto sk = libzcash::SaplingSpendingKey::random();
|
||||||
|
auto full_viewing_key = sk.full_viewing_key();
|
||||||
|
ASSERT_TRUE(wallet.AddSaplingSpendingKey(sk));
|
||||||
|
|
||||||
|
// verify wallet has spending key for the address
|
||||||
|
ASSERT_TRUE(wallet.HaveSaplingSpendingKey(full_viewing_key));
|
||||||
|
|
||||||
|
// check key is the same
|
||||||
|
libzcash::SaplingSpendingKey keyOut;
|
||||||
|
wallet.GetSaplingSpendingKey(full_viewing_key, keyOut);
|
||||||
|
ASSERT_EQ(sk, keyOut);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test covers methods on CWallet
|
* This test covers methods on CWallet
|
||||||
* GenerateNewZKey()
|
* GenerateNewZKey()
|
||||||
|
* GenerateNewSaplingZKey()
|
||||||
* AddZKey()
|
* AddZKey()
|
||||||
* LoadZKey()
|
* LoadZKey()
|
||||||
* LoadZKeyMetadata()
|
* LoadZKeyMetadata()
|
||||||
|
|||||||
@ -100,8 +100,64 @@ libzcash::PaymentAddress CWallet::GenerateNewZKey()
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! TODO: Should be Sapling address format, SaplingPaymentAddress
|
||||||
|
// Generate a new Sapling spending key and return its public payment address
|
||||||
|
SaplingPaymentAddress CWallet::GenerateNewSaplingZKey()
|
||||||
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
||||||
|
auto sk = SaplingSpendingKey::random();
|
||||||
|
auto fvk = sk.full_viewing_key();
|
||||||
|
auto addrOpt = sk.default_address();
|
||||||
|
if (addrOpt){
|
||||||
|
auto addr = addrOpt.value();
|
||||||
|
// Check for collision, even though it is unlikely to ever occur
|
||||||
|
if (CCryptoKeyStore::HaveSaplingSpendingKey(fvk))
|
||||||
|
throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): Collision detected");
|
||||||
|
|
||||||
|
// Create new metadata
|
||||||
|
int64_t nCreationTime = GetTime();
|
||||||
|
mapSaplingZKeyMetadata[addr] = CKeyMetadata(nCreationTime);
|
||||||
|
|
||||||
|
if (!AddSaplingZKey(sk)) {
|
||||||
|
throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): AddSaplingZKey failed");
|
||||||
|
}
|
||||||
|
// return default sapling payment address.
|
||||||
|
return addr;
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("CWallet::GenerateNewSaplingZKey(): default_address() did not return address");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add spending key to keystore
|
||||||
|
// TODO: persist to disk
|
||||||
|
bool CWallet::AddSaplingZKey(const libzcash::SaplingSpendingKey &sk)
|
||||||
|
{
|
||||||
|
AssertLockHeld(cs_wallet); // mapSaplingZKeyMetadata
|
||||||
|
auto addr = sk.default_address();
|
||||||
|
|
||||||
|
if (!CCryptoKeyStore::AddSaplingSpendingKey(sk)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// // check if we need to remove from viewing keys
|
||||||
|
// if (HaveViewingKey(addr)) {
|
||||||
|
// RemoveViewingKey(key.viewing_key());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!fFileBacked) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// if (!IsCrypted()) {
|
||||||
|
// return CWalletDB(strWalletFile).WriteSaplingZKey(addr,
|
||||||
|
// sk,
|
||||||
|
// mapSaplingZKeyMetadata[addr]);
|
||||||
|
// }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Add spending key to keystore and persist to disk
|
// Add spending key to keystore and persist to disk
|
||||||
// TODO: Add Sapling support
|
|
||||||
bool CWallet::AddZKey(const libzcash::SproutSpendingKey &key)
|
bool CWallet::AddZKey(const libzcash::SproutSpendingKey &key)
|
||||||
{
|
{
|
||||||
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
AssertLockHeld(cs_wallet); // mapZKeyMetadata
|
||||||
@ -176,7 +232,7 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
|
|||||||
bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
|
bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
|
||||||
const vector<unsigned char> &vchCryptedSecret)
|
const vector<unsigned char> &vchCryptedSecret)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
|
if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
|
||||||
return false;
|
return false;
|
||||||
if (!fFileBacked)
|
if (!fFileBacked)
|
||||||
@ -516,7 +572,7 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er
|
|||||||
} catch (const boost::filesystem::filesystem_error&) {
|
} catch (const boost::filesystem::filesystem_error&) {
|
||||||
// failure is ok (well, not really, but it's not worse than what we started with)
|
// failure is ok (well, not really, but it's not worse than what we started with)
|
||||||
}
|
}
|
||||||
|
|
||||||
// try again
|
// try again
|
||||||
if (!bitdb.Open(GetDataDir())) {
|
if (!bitdb.Open(GetDataDir())) {
|
||||||
// if it still fails, it probably means we can't even create the database env
|
// if it still fails, it probably means we can't even create the database env
|
||||||
@ -525,14 +581,14 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetBoolArg("-salvagewallet", false))
|
if (GetBoolArg("-salvagewallet", false))
|
||||||
{
|
{
|
||||||
// Recover readable keypairs:
|
// Recover readable keypairs:
|
||||||
if (!CWalletDB::Recover(bitdb, walletFile, true))
|
if (!CWalletDB::Recover(bitdb, walletFile, true))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (boost::filesystem::exists(GetDataDir() / walletFile))
|
if (boost::filesystem::exists(GetDataDir() / walletFile))
|
||||||
{
|
{
|
||||||
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
|
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
|
||||||
@ -546,7 +602,7 @@ bool CWallet::Verify(const string& walletFile, string& warningString, string& er
|
|||||||
if (r == CDBEnv::RECOVER_FAIL)
|
if (r == CDBEnv::RECOVER_FAIL)
|
||||||
errorString += _("wallet.dat corrupt, salvage failed");
|
errorString += _("wallet.dat corrupt, salvage failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2523,7 +2579,7 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nC
|
|||||||
|
|
||||||
CReserveKey reservekey(this);
|
CReserveKey reservekey(this);
|
||||||
CWalletTx wtx;
|
CWalletTx wtx;
|
||||||
|
|
||||||
if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
|
if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -2590,7 +2646,7 @@ bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wt
|
|||||||
if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
|
if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) {
|
||||||
max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
|
max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discourage fee sniping.
|
// Discourage fee sniping.
|
||||||
//
|
//
|
||||||
// However because of a off-by-one-error in previous versions we need to
|
// However because of a off-by-one-error in previous versions we need to
|
||||||
@ -3062,7 +3118,7 @@ bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark old keypool keys as used,
|
* Mark old keypool keys as used,
|
||||||
* and generate all new keys
|
* and generate all new keys
|
||||||
*/
|
*/
|
||||||
bool CWallet::NewKeyPool()
|
bool CWallet::NewKeyPool()
|
||||||
{
|
{
|
||||||
@ -3767,7 +3823,7 @@ void CWallet::GetFilteredNotes(
|
|||||||
if (ignoreUnspendable && !HaveSpendingKey(pa)) {
|
if (ignoreUnspendable && !HaveSpendingKey(pa)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip locked notes
|
// skip locked notes
|
||||||
if (IsLockedNote(jsop)) {
|
if (IsLockedNote(jsop)) {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -786,6 +786,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;
|
||||||
|
|
||||||
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
|
||||||
MasterKeyMap mapMasterKeys;
|
MasterKeyMap mapMasterKeys;
|
||||||
@ -977,6 +978,14 @@ public:
|
|||||||
bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
|
bool RemoveViewingKey(const libzcash::SproutViewingKey &vk);
|
||||||
//! Adds a viewing key to the store, without saving it to disk (used by LoadWallet)
|
//! Adds a viewing key to the store, without saving it to disk (used by LoadWallet)
|
||||||
bool LoadViewingKey(const libzcash::SproutViewingKey &dest);
|
bool LoadViewingKey(const libzcash::SproutViewingKey &dest);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sapling ZKeys
|
||||||
|
*/
|
||||||
|
//! Generates new Sapling key
|
||||||
|
libzcash::SaplingPaymentAddress GenerateNewSaplingZKey();
|
||||||
|
//! Adds Sapling spending key to the store, and saves it to disk
|
||||||
|
bool AddSaplingZKey(const libzcash::SaplingSpendingKey &key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Increment the next transaction order id
|
* Increment the next transaction order id
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user