}
}
+contains(DEBUG, 1) {
+ QMAKE_CXXFLAGS_RELEASE -= -O2
+ QMAKE_CFLAGS_RELEASE -= -O2
+
+ QMAKE_CFLAGS += -g -O0
+ QMAKE_CXXCFLAGS += -g -O0
+}
+
!win32 {
# for extra security against potential buffer overflows: enable GCCs Stack Smashing Protection
QMAKE_CXXFLAGS *= -fstack-protector-all --param ssp-buffer-size=1
Dbc* pcursor = db.GetCursor();
if (pcursor) {
- size_t pszSkipLen = strlen(pszSkip);
while (fSuccess)
{
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
fSuccess = false;
break;
}
- if (pszSkip &&
- strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), pszSkipLen)) == 0)
- continue;
+
+ if (pszSkip != NULL)
+ {
+ size_t pszSkipLen = strlen(pszSkip);
+ if (strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), pszSkipLen)) == 0)
+ continue;
+ }
+
if (strncmp(&ssKey[0], "\x07version", 8) == 0)
{
// Update version:
// CMalleableKeyView
+CMalleableKeyView::CMalleableKeyView(const std::string &strMalleableKey)
+{
+ SetString(strMalleableKey);
+}
+
CMalleableKeyView::CMalleableKeyView(const CMalleableKey &b)
{
if (b.vchSecretL.size() != 32)
public:
CMalleableKeyView() { nVersion = 0; };
CMalleableKeyView(const CMalleableKey &b);
+ CMalleableKeyView(const std::string &strMalleableKey);
CMalleableKeyView(const CMalleableKeyView &b);
CMalleableKeyView& operator=(const CMalleableKey &b);
return true;
}
-bool CBasicKeyStore::AddMalleableKey(const CMalleableKey& mKey)
+bool CBasicKeyStore::AddMalleableKey(const CMalleableKeyView& keyView, const CSecret& vchSecretH)
{
{
LOCK(cs_KeyStore);
- mapMalleableKeys[CMalleableKeyView(mKey)] = mKey;
+ mapMalleableKeys[CMalleableKeyView(keyView)] = vchSecretH;
}
return true;
}
return true;
}
+bool CCryptoKeyStore::AddMalleableKey(const CMalleableKeyView& keyView, const CSecret &vchSecretH)
+{
+ {
+ LOCK(cs_KeyStore);
+ if (!SetCrypted())
+ return CBasicKeyStore::AddMalleableKey(keyView, vchSecretH);
+
+ if (IsLocked())
+ return false;
+
+ CKey keyH;
+ keyH.SetSecret(vchSecretH, true);
+
+ std::vector<unsigned char> vchCryptedSecretH;
+ if (!EncryptSecret(vMasterKey, vchSecretH, keyH.GetPubKey().GetHash(), vchCryptedSecretH))
+ return false;
+
+ if (!AddCryptedMalleableKey(keyView, vchCryptedSecretH))
+ return false;
+ }
+ return true;
+}
bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
{
return true;
}
+bool CCryptoKeyStore::AddCryptedMalleableKey(const CMalleableKeyView& keyView, const std::vector<unsigned char> &vchCryptedSecretH)
+{
+ {
+ LOCK(cs_KeyStore);
+ if (!SetCrypted())
+ return false;
+
+ mapCryptedMalleableKeys[CMalleableKeyView(keyView)] = vchCryptedSecretH;
+ }
+ return true;
+}
+
+bool CCryptoKeyStore::CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const
+{
+ {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted())
+ return CBasicKeyStore::CreatePrivKey(pubKeyVariant, R, privKey);
+
+ for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
+ {
+ if (mi->first.CheckKeyVariant(R, pubKeyVariant))
+ {
+ const CPubKey H = mi->first.GetMalleablePubKey().GetH();
+
+ CSecret vchSecretH;
+ if (!DecryptSecret(vMasterKey, mi->second, H.GetHash(), vchSecretH))
+ return false;
+ if (vchSecretH.size() != 32)
+ return false;
+
+ CMalleableKey mKey = mi->first.GetMalleableKey(vchSecretH);
+ return mKey.CheckKeyVariant(R, pubKeyVariant, privKey);;
+ }
+ }
+
+ }
+ return true;
+}
+
+bool CCryptoKeyStore::GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const
+{
+ {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted())
+ return CBasicKeyStore::GetMalleableKey(keyView, mKey);
+ CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.find(keyView);
+ if (mi != mapCryptedMalleableKeys.end())
+ {
+ const CPubKey H = keyView.GetMalleablePubKey().GetH();
+
+ CSecret vchSecretH;
+ if (!DecryptSecret(vMasterKey, mi->second, H.GetHash(), vchSecretH))
+ return false;
+
+ if (vchSecretH.size() != 32)
+ return false;
+ mKey = mi->first.GetMalleableKey(vchSecretH);
+
+ return true;
+ }
+ }
+ return false;
+}
+
bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
{
{
return false;
}
mapKeys.clear();
+
+ BOOST_FOREACH(MalleableKeyMap::value_type& mKey, mapMalleableKeys)
+ {
+ const CPubKey vchPubKeyH = mKey.first.GetMalleablePubKey().GetH();
+ std::vector<unsigned char> vchCryptedSecretH;
+ if (!EncryptSecret(vMasterKeyIn, mKey.second, vchPubKeyH.GetHash(), vchCryptedSecretH))
+ return false;
+ if (!AddCryptedMalleableKey(mKey.first, vchCryptedSecretH))
+ return false;
+ }
+ mapMalleableKeys.clear();
}
return true;
}
}
mapCryptedKeys.clear();
+
+ CryptedMalleableKeyMap::const_iterator mi2 = mapCryptedMalleableKeys.begin();
+ for(; mi2 != mapCryptedMalleableKeys.end(); ++mi2)
+ {
+ const CPubKey vchPubKeyH = mi2->first.GetMalleablePubKey().GetH();
+
+ CSecret vchSecretH;
+ if(!DecryptSecret(vMasterKeyIn, mi2->second, vchPubKeyH.GetHash(), vchSecretH))
+ return false;
+ if (vchSecretH.size() != 32)
+ return false;
+
+ if (!CBasicKeyStore::AddMalleableKey(mi2->first, vchSecretH))
+ return false;
+ }
+ mapCryptedMalleableKeys.clear();
}
return true;
virtual bool AddKey(const CKey& key) =0;
// Add a malleable key to store.
- virtual bool AddMalleableKey(const CMalleableKey& mKey) =0;
+ virtual bool AddMalleableKey(const CMalleableKeyView &keyView, const CSecret &vchSecretH) =0;
virtual bool GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const =0;
// Check whether a key corresponding to a given address is present in the store.
typedef std::map<CKeyID, std::pair<CSecret, bool> > KeyMap;
typedef std::map<CScriptID, CScript > ScriptMap;
typedef std::set<CScript> WatchOnlySet;
-typedef std::map<CMalleableKeyView, CMalleableKey> MalleableKeyMap;
+typedef std::map<CMalleableKeyView, CSecret> MalleableKeyMap;
/** Basic key store, that keeps keys in an address->secret map */
class CBasicKeyStore : public CKeyStore
public:
bool AddKey(const CKey& key);
- bool AddMalleableKey(const CMalleableKey& mKey);
+ bool AddMalleableKey(const CMalleableKeyView& keyView, const CSecret &vchSecretH);
bool GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const
{
{
MalleableKeyMap::const_iterator mi = mapMalleableKeys.find(keyView);
if (mi != mapMalleableKeys.end())
{
- mKey = mi->second;
+ mKey = mi->first.GetMalleableKey(mi->second);
return true;
}
}
LOCK(cs_KeyStore);
for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
{
- if (mi->second.CheckKeyVariant(R, pubKeyVariant, privKey))
- return true;
+ if (mi->first.CheckKeyVariant(R, pubKeyVariant))
+ {
+ CMalleableKey mKey = mi->first.GetMalleableKey(mi->second);
+ return mKey.CheckKeyVariant(R, pubKeyVariant, privKey);
+ }
}
}
return false;
void ListMalleableViews(std::list<CMalleableKeyView> &malleableViewList) const
{
malleableViewList.clear();
-
{
LOCK(cs_KeyStore);
for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++)
};
typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
+typedef std::map<CMalleableKeyView, std::vector<unsigned char> > CryptedMalleableKeyMap;
/** Keystore which keeps the private keys encrypted.
* It derives from the basic key store, which is used if no encryption is active.
{
private:
CryptedKeyMap mapCryptedKeys;
+ CryptedMalleableKeyMap mapCryptedMalleableKeys;
CKeyingMaterial vMasterKey;
bool Lock();
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
+ virtual bool AddCryptedMalleableKey(const CMalleableKeyView& keyView, const std::vector<unsigned char> &vchCryptedSecretH);
+
bool AddKey(const CKey& key);
+ bool AddMalleableKey(const CMalleableKeyView& keyView, const CSecret &vchSecretH);
bool HaveKey(const CKeyID &address) const
{
{
}
}
+ bool GetMalleableKey(const CMalleableKeyView &keyView, CMalleableKey &mKey) const;
+
+ bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const
+ {
+ {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted())
+ return CBasicKeyStore::CheckOwnership(pubKeyVariant, R);
+ for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
+ {
+ if (mi->first.CheckKeyVariant(R, pubKeyVariant))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R, CMalleableKeyView &view) const
+ {
+ {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted())
+ return CBasicKeyStore::CheckOwnership(pubKeyVariant, R, view);
+ for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
+ {
+ if (mi->first.CheckKeyVariant(R, pubKeyVariant))
+ {
+ view = mi->first;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const;
+
+ void ListMalleableViews(std::list<CMalleableKeyView> &malleableViewList) const
+ {
+ malleableViewList.clear();
+ {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted())
+ return CBasicKeyStore::ListMalleableViews(malleableViewList);
+ for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
+ malleableViewList.push_back(CMalleableKeyView(mi->first));
+ }
+ }
+
+ bool GetMalleableView(const CMalleablePubKey &mpk, CMalleableKeyView &view)
+ {
+ const CKeyID &mpkID = mpk.GetID();
+ {
+ LOCK(cs_KeyStore);
+ if (!IsCrypted())
+ return CBasicKeyStore::GetMalleableView(mpk, view);
+ for (CryptedMalleableKeyMap::const_iterator mi = mapCryptedMalleableKeys.begin(); mi != mapCryptedMalleableKeys.end(); mi++)
+ if (mi->first.GetID() == mpkID)
+ {
+ view = CMalleableKeyView(mi->first);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
/* Wallet status (encrypted, locked) changed.
* Note: Called without locks held.
*/
return DoS(10, error("CTransaction::CheckTransaction() : vin empty"));
if (vout.empty())
return DoS(10, error("CTransaction::CheckTransaction() : vout empty"));
- // Time (prevent mempool memory exhaustion attack)
- // Comes into force since 20 December 2015.
- if (nTime > 1450569600 && nTime > FutureDrift(GetAdjustedTime()))
- return DoS(10, error("CTransaction::CheckTransaction() : timestamp is too far into the future"));
// Size limits
if (::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
return DoS(100, error("CTransaction::CheckTransaction() : size limits failed"));
if (pfMissingInputs)
*pfMissingInputs = false;
+ // Time (prevent mempool memory exhaustion attack)
+ if (tx.nTime > FutureDrift(GetAdjustedTime()))
+ return tx.DoS(10, error("CTxMemPool::accept() : transaction timestamp is too far in the future"));
+
if (!tx.CheckTransaction())
return error("CTxMemPool::accept() : CheckTransaction failed");
int64_t nMedianTimePast = pindexPrev->GetMedianTimePast();
int nMaxOffset = 12 * nOneHour; // 12 hours
- if (pindexPrev->nTime < 1450569600)
- nMaxOffset = nOneWeek; // One week until 20 Dec, 2015
+ if (fTestNet || pindexPrev->nTime < 1450569600)
+ nMaxOffset = 7 * nOneWeek; // One week (permanently on testNet or until 20 Dec, 2015 on mainNet)
// Check timestamp against prev
if (GetBlockTime() <= nMedianTimePast || FutureDrift(GetBlockTime()) < pindexPrev->GetBlockTime())
itemOutput->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked);
// address
+/*
CTxDestination outputAddress;
QString sAddress = "";
if(ExtractDestination(out.tx->vout[out.i].scriptPubKey, outputAddress))
if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed())
nInputSize = 180;
}
+*/
+ QString sAddress = "";
+ txnouttype whichType;
+ std::vector<valtype> vSolutions;
+ if (Solver(out.tx->vout[out.i].scriptPubKey, whichType, vSolutions))
+ {
+ CTxDestination address;
+ if (whichType == TX_PUBKEY)
+ {
+ // Pay-to-Pubkey
+ CPubKey pubKey = CPubKey(vSolutions[0]);
+ address = pubKey.GetID();
+ sAddress = CBitcoinAddress(address).ToString().c_str();
+
+ if (!pubKey.IsCompressed())
+ nInputSize = 180;
+ }
+ else if (whichType == TX_PUBKEYHASH)
+ {
+ // Pay-to-PubkeyHash
+ address = CKeyID(uint160(vSolutions[0]));
+ sAddress = CBitcoinAddress(address).ToString().c_str();
+
+ CPubKey pubkey;
+ CKeyID *keyid = boost::get< CKeyID >(&address);
+ if (keyid && model->getPubKey(*keyid, pubkey) && !pubkey.IsCompressed())
+ nInputSize = 180;
+ }
+ else if (whichType == TX_SCRIPTHASH)
+ {
+ // Pay-to-ScriptHash
+ address = CScriptID(uint160(vSolutions[0]));
+ sAddress = CBitcoinAddress(address).ToString().c_str();
+ }
+ else if (whichType == TX_PUBKEY_DROP)
+ {
+ // Pay-to-Pubkey-R
+ CMalleableKeyView view;
+ pwalletMain->CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view);
+ sAddress = view.GetMalleablePubKey().ToString().c_str();
+ }
+
+ // if listMode or change => show bitcoin address. In tree mode, address is not shown again for direct wallet address outputs
+ if (!treeMode || (!(sAddress == sWalletAddress)))
+ itemOutput->setText(COLUMN_ADDRESS, sAddress);
+ }
// label
if (!(sAddress == sWalletAddress)) // change
#include "wallet.h"
#include "base58.h"
+extern CWallet* pwalletMain;
+
/* Return positive answer if transaction should be shown in list.
*/
bool TransactionRecord::showTransaction(const CWalletTx &wtx)
if(wallet->IsMine(txout))
{
TransactionRecord sub(hash, nTime);
- CTxDestination address;
sub.idx = parts.size(); // sequence number
sub.credit = txout.nValue;
- if (ExtractDestination(txout.scriptPubKey, address) && IsMine(*wallet, address))
+
+ std::string address;
+ if (pwalletMain->ExtractAddress(txout.scriptPubKey, address))
{
- // Received by Bitcoin Address
sub.type = TransactionRecord::RecvWithAddress;
- sub.address = CBitcoinAddress(address).ToString();
+ sub.address = address;
}
else
{
sub.type = TransactionRecord::RecvFromOther;
sub.address = mapValue["from"];
}
+
if (wtx.IsCoinBase())
{
// Generated (proof-of-work)
cout = COutput(&wallet->mapWallet[cout.tx->vin[0].prevout.hash], cout.tx->vin[0].prevout.n, 0, true);
}
- CTxDestination address;
- if(!out.fSpendable || !ExtractDestination(cout.tx->vout[cout.i].scriptPubKey, address))
+ std::string address;
+ if(!out.fSpendable || !wallet->ExtractAddress(cout.tx->vout[cout.i].scriptPubKey, address))
continue;
- mapCoins[CBitcoinAddress(address).ToString().c_str()].push_back(out);
+
+ mapCoins[address.c_str()].push_back(out);
}
}
"importprivkey <novacoinprivkey> [label] [rescan=true]\n"
"Adds a private key (as returned by dumpprivkey) to your wallet.");
+ EnsureWalletIsUnlocked();
+
string strSecret = params[0].get_str();
string strLabel = "";
if (params.size() > 1)
"dumpmalleablekey <Key view>\n"
"Dump the private and public key pairs, which correspond to provided key view.\n");
+ EnsureWalletIsUnlocked();
+
CMalleableKey mKey;
CMalleableKeyView keyView;
keyView.SetString(params[0].get_str());
"importmalleablekey <Key data>\n"
"Imports the private key pair into your wallet.\n");
+
+ EnsureWalletIsUnlocked();
+
CMalleableKey mKey;
bool fSuccess = mKey.SetString(params[0].get_str());
bool CWallet::AddMalleableKey(const CMalleableKey& mKey)
{
CMalleableKeyView keyView = CMalleableKeyView(mKey);
- if (!CCryptoKeyStore::AddMalleableKey(mKey))
+ CSecret vchSecretH = mKey.GetSecretH();
+ if (!CCryptoKeyStore::AddMalleableKey(keyView, vchSecretH))
return false;
if (!fFileBacked)
return true;
if (!IsCrypted())
- return CWalletDB(strWalletFile).WriteMalleableKey(keyView, mKey, mapMalleableKeyMetadata[keyView]);
+ return CWalletDB(strWalletFile).WriteMalleableKey(keyView, vchSecretH, mapMalleableKeyMetadata[keyView]);
+ return true;
+}
+
+bool CWallet::AddCryptedMalleableKey(const CMalleableKeyView& keyView, const std::vector<unsigned char> &vchCryptedSecretH)
+{
+ if (!CCryptoKeyStore::AddCryptedMalleableKey(keyView, vchCryptedSecretH))
+ return false;
+
+ if (!fFileBacked)
+ return true;
+
+ {
+ LOCK(cs_wallet);
+ if (pwalletdbEncryption)
+ return pwalletdbEncryption->WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapMalleableKeyMetadata[keyView]);
+ else
+ return CWalletDB(strWalletFile).WriteCryptedMalleableKey(keyView, vchCryptedSecretH, mapMalleableKeyMetadata[keyView]);
+ }
+
return true;
}
mi++;
}
+ MalleableKeyMap::const_iterator mi2 = mapMalleableKeys.begin();
+ while (mi2 != mapMalleableKeys.end())
+ {
+ const CSecret &vchSecretH = mi2->second;
+ const CMalleableKeyView &keyView = mi2->first;
+ pwalletdbDecryption->EraseCryptedMalleableKey(keyView);
+ pwalletdbDecryption->WriteMalleableKey(keyView, vchSecretH, mapMalleableKeyMetadata[keyView]);
+ mi2++;
+ }
+
// Erase master keys
MasterKeyMap::const_iterator mk = mapMasterKeys.begin();
while (mk != mapMasterKeys.end())
for(list<uint256>::const_iterator it = orphans.begin(); it != orphans.end(); ++it)
EraseFromWallet(*it);
}
+
+bool CWallet::ExtractAddress(const CScript& scriptPubKey, std::string& addressRet)
+{
+ vector<valtype> vSolutions;
+ txnouttype whichType;
+ if (!Solver(scriptPubKey, whichType, vSolutions))
+ return false;
+
+ if (whichType == TX_PUBKEY)
+ {
+ addressRet = CBitcoinAddress(CPubKey(vSolutions[0]).GetID()).ToString();
+ return true;
+ }
+ if (whichType == TX_PUBKEY_DROP)
+ {
+ // Pay-to-Pubkey-R
+ CMalleableKeyView view;
+ if (!CheckOwnership(CPubKey(vSolutions[0]), CPubKey(vSolutions[1]), view))
+ return false;
+
+ addressRet = view.GetMalleablePubKey().ToString();
+ return true;
+ }
+ else if (whichType == TX_PUBKEYHASH)
+ {
+ addressRet = CBitcoinAddress(CKeyID(uint160(vSolutions[0]))).ToString();
+ return true;
+ }
+ else if (whichType == TX_SCRIPTHASH)
+ {
+ addressRet = CBitcoinAddress(CScriptID(uint160(vSolutions[0]))).ToString();
+ return true;
+ }
+ // Multisig txns have more than one address...
+ return false;
+}
bool LoadMalleableKeyMetadata(const CMalleableKeyView &keyView, const CKeyMetadata &metadata);
// Load malleable key without saving it to disk (used by LoadWallet)
- bool LoadMalleableKey(const CMalleableKey &mKey) { return CCryptoKeyStore::AddMalleableKey(mKey); }
+ bool LoadMalleableKey(const CMalleableKeyView &keyView, const CSecret &vchSecretH) { return CCryptoKeyStore::AddMalleableKey(keyView, vchSecretH); }
+ bool LoadCryptedMalleableKey(const CMalleableKeyView &keyView, const std::vector<unsigned char> &vchCryptedSecretH) { return CCryptoKeyStore::AddCryptedMalleableKey(keyView, vchCryptedSecretH); }
bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
// Adds an encrypted key to the store, and saves it to disk.
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
+ bool AddCryptedMalleableKey(const CMalleableKeyView& keyView, const std::vector<unsigned char> &vchCryptedSecretH);
// Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
bool AddCScript(const CScript& redeemScript);
bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
+ bool ExtractAddress(const CScript& scriptPubKey, std::string& addressRet);
+
bool SetDefaultKey(const CPubKey &vchPubKey);
// signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
}
else if (strType == "malpair")
{
- string strKey, strKeyView;
-
- CMalleableKey mKey;
- CMalleableKeyView keyView;
+ string strKeyView;
+ CSecret vchSecret;
ssKey >> strKeyView;
- ssValue >> strKey;
-
- keyView.SetString(strKeyView);
- mKey.SetString(strKey);
+ ssValue >> vchSecret;
- if (mKey.IsNull())
- {
- strErr = "Error reading wallet database: CMalleableKey is corrupt";
- return false;
- }
- if (mKey.GetID() != keyView.GetID())
+ CMalleableKeyView keyView(strKeyView);
+ if (!pwallet->LoadMalleableKey(keyView, vchSecret))
{
- strErr = "Error reading wallet database: CMalleableKey view inconsistency";
+ strErr = "Error reading wallet database: LoadMalleableKey failed";
return false;
}
+ }
+ else if (strType == "malcpair")
+ {
+ string strKeyView;
- if (!pwallet->LoadMalleableKey(mKey))
+ std::vector<unsigned char> vchCryptedSecret;
+ ssKey >> strKeyView;
+ ssValue >> vchCryptedSecret;
+
+ CMalleableKeyView keyView(strKeyView);
+ if (!pwallet->LoadCryptedMalleableKey(keyView, vchCryptedSecret))
{
- strErr = "Error reading wallet database: LoadMalleableKey failed";
+ strErr = "Error reading wallet database: LoadCryptedMalleableKey failed";
return false;
}
}
static bool IsKeyType(string strType)
{
return (strType== "key" || strType == "wkey" ||
- strType == "mkey" || strType == "ckey" || strType == "malpair");
+ strType == "mkey" || strType == "ckey" || strType == "malpair" || strType == "malcpair");
}
DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
return true;
}
- bool WriteMalleableKey(const CMalleableKeyView& keyView, const CMalleableKey& malleableKey, const CKeyMetadata &keyMeta)
+ bool WriteMalleableKey(const CMalleableKeyView& keyView, const CSecret& vchSecretH, const CKeyMetadata &keyMeta)
{
nWalletDBUpdated++;
if(!Write(std::make_pair(std::string("malmeta"), keyView.ToString()), keyMeta))
return false;
- if(!Write(std::make_pair(std::string("malpair"), keyView.ToString()), malleableKey.ToString(), false))
+ if(!Write(std::make_pair(std::string("malpair"), keyView.ToString()), vchSecretH, false))
return false;
return true;
}
+ bool WriteCryptedMalleableKey(const CMalleableKeyView& keyView, const std::vector<unsigned char>& vchCryptedSecretH, const CKeyMetadata &keyMeta)
+ {
+ nWalletDBUpdated++;
+ if(!Write(std::make_pair(std::string("malmeta"), keyView.ToString()), keyMeta))
+ return false;
+
+ if(!Write(std::make_pair(std::string("malcpair"), keyView.ToString()), vchCryptedSecretH, false))
+ return false;
+
+ Erase(std::make_pair(std::string("malpair"), keyView.ToString()));
+
+ return true;
+ }
+
bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta)
{
return Erase(std::make_pair(std::string("ckey"), vchPubKey.Raw()));
}
+ bool EraseCryptedMalleableKey(const CMalleableKeyView& keyView)
+ {
+ return Erase(std::make_pair(std::string("malcpair"), keyView.ToString()));
+ }
+
bool WriteCScript(const uint160& hash, const CScript& redeemScript)
{
nWalletDBUpdated++;