Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 313 Lines • ▼ Show 20 Lines | if (encrypted_batch) { | ||||
return encrypted_batch->WriteCryptedKey( | return encrypted_batch->WriteCryptedKey( | ||||
vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); | vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); | ||||
} | } | ||||
return WalletBatch(*database).WriteCryptedKey( | return WalletBatch(*database).WriteCryptedKey( | ||||
vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); | vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]); | ||||
} | } | ||||
bool CWallet::LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &meta) { | void CWallet::LoadKeyMetadata(const CKeyID &keyID, const CKeyMetadata &meta) { | ||||
// mapKeyMetadata | // mapKeyMetadata | ||||
AssertLockHeld(cs_wallet); | AssertLockHeld(cs_wallet); | ||||
UpdateTimeFirstKey(meta.nCreateTime); | UpdateTimeFirstKey(meta.nCreateTime); | ||||
mapKeyMetadata[keyID] = meta; | mapKeyMetadata[keyID] = meta; | ||||
return true; | |||||
} | } | ||||
bool CWallet::LoadScriptMetadata(const CScriptID &script_id, | void CWallet::LoadScriptMetadata(const CScriptID &script_id, | ||||
const CKeyMetadata &meta) { | const CKeyMetadata &meta) { | ||||
// m_script_metadata | // m_script_metadata | ||||
AssertLockHeld(cs_wallet); | AssertLockHeld(cs_wallet); | ||||
UpdateTimeFirstKey(meta.nCreateTime); | UpdateTimeFirstKey(meta.nCreateTime); | ||||
m_script_metadata[script_id] = meta; | m_script_metadata[script_id] = meta; | ||||
return true; | |||||
} | } | ||||
bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, | bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, | ||||
const std::vector<uint8_t> &vchCryptedSecret) { | const std::vector<uint8_t> &vchCryptedSecret) { | ||||
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); | return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); | ||||
} | } | ||||
/** | /** | ||||
▲ Show 20 Lines • Show All 176 Lines • ▼ Show 20 Lines | bool CWallet::ChangeWalletPassphrase( | ||||
return false; | return false; | ||||
} | } | ||||
void CWallet::ChainStateFlushed(const CBlockLocator &loc) { | void CWallet::ChainStateFlushed(const CBlockLocator &loc) { | ||||
WalletBatch batch(*database); | WalletBatch batch(*database); | ||||
batch.WriteBestBlock(loc); | batch.WriteBestBlock(loc); | ||||
} | } | ||||
bool CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch *batch_in, | void CWallet::SetMinVersion(enum WalletFeature nVersion, WalletBatch *batch_in, | ||||
bool fExplicit) { | bool fExplicit) { | ||||
// nWalletVersion | // nWalletVersion | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
if (nWalletVersion >= nVersion) { | if (nWalletVersion >= nVersion) { | ||||
return true; | return; | ||||
} | } | ||||
// When doing an explicit upgrade, if we pass the max version permitted, | // When doing an explicit upgrade, if we pass the max version permitted, | ||||
// upgrade all the way. | // upgrade all the way. | ||||
if (fExplicit && nVersion > nWalletMaxVersion) { | if (fExplicit && nVersion > nWalletMaxVersion) { | ||||
nVersion = FEATURE_LATEST; | nVersion = FEATURE_LATEST; | ||||
} | } | ||||
nWalletVersion = nVersion; | nWalletVersion = nVersion; | ||||
if (nVersion > nWalletMaxVersion) { | if (nVersion > nWalletMaxVersion) { | ||||
nWalletMaxVersion = nVersion; | nWalletMaxVersion = nVersion; | ||||
} | } | ||||
WalletBatch *batch = batch_in ? batch_in : new WalletBatch(*database); | WalletBatch *batch = batch_in ? batch_in : new WalletBatch(*database); | ||||
if (nWalletVersion > 40000) { | if (nWalletVersion > 40000) { | ||||
batch->WriteMinVersion(nWalletVersion); | batch->WriteMinVersion(nWalletVersion); | ||||
} | } | ||||
if (!batch_in) { | if (!batch_in) { | ||||
delete batch; | delete batch; | ||||
} | } | ||||
return true; | |||||
} | } | ||||
bool CWallet::SetMaxVersion(int nVersion) { | bool CWallet::SetMaxVersion(int nVersion) { | ||||
// nWalletVersion, nWalletMaxVersion | // nWalletVersion, nWalletMaxVersion | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
// Cannot downgrade below current version | // Cannot downgrade below current version | ||||
if (nWalletVersion > nVersion) { | if (nWalletVersion > nVersion) { | ||||
▲ Show 20 Lines • Show All 214 Lines • ▼ Show 20 Lines | if (!crypter.Encrypt(_vMasterKey, kMasterKey.vchCryptedKey)) { | ||||
delete encrypted_batch; | delete encrypted_batch; | ||||
encrypted_batch = nullptr; | encrypted_batch = nullptr; | ||||
Lock(); | Lock(); | ||||
Unlock(strWalletPassphrase); | Unlock(strWalletPassphrase); | ||||
// If we are using HD, replace the HD master key (seed) with a new one. | // If we are using HD, replace the HD master key (seed) with a new one. | ||||
if (IsHDEnabled()) { | if (IsHDEnabled()) { | ||||
if (!SetHDMasterKey(GenerateNewHDMasterKey())) { | SetHDMasterKey(GenerateNewHDMasterKey()); | ||||
return false; | |||||
} | |||||
} | } | ||||
NewKeyPool(); | NewKeyPool(); | ||||
Lock(); | Lock(); | ||||
// Need to completely rewrite the wallet file; if we don't, bdb might | // Need to completely rewrite the wallet file; if we don't, bdb might | ||||
// keep bits of the unencrypted private key in slack space in the | // keep bits of the unencrypted private key in slack space in the | ||||
// database file. | // database file. | ||||
▲ Show 20 Lines • Show All 245 Lines • ▼ Show 20 Lines | if (!strCmd.empty()) { | ||||
std::thread t(runCommand, strCmd); | std::thread t(runCommand, strCmd); | ||||
// Thread runs free. | // Thread runs free. | ||||
t.detach(); | t.detach(); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CWallet::LoadToWallet(const CWalletTx &wtxIn) { | void CWallet::LoadToWallet(const CWalletTx &wtxIn) { | ||||
const TxId &txid = wtxIn.GetId(); | const TxId &txid = wtxIn.GetId(); | ||||
CWalletTx &wtx = mapWallet.emplace(txid, wtxIn).first->second; | CWalletTx &wtx = mapWallet.emplace(txid, wtxIn).first->second; | ||||
wtx.BindWallet(this); | wtx.BindWallet(this); | ||||
wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr))); | wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr))); | ||||
AddToSpends(txid); | AddToSpends(txid); | ||||
for (const CTxIn &txin : wtx.tx->vin) { | for (const CTxIn &txin : wtx.tx->vin) { | ||||
auto it = mapWallet.find(txin.prevout.GetTxId()); | auto it = mapWallet.find(txin.prevout.GetTxId()); | ||||
if (it != mapWallet.end()) { | if (it != mapWallet.end()) { | ||||
CWalletTx &prevtx = it->second; | CWalletTx &prevtx = it->second; | ||||
if (prevtx.nIndex == -1 && !prevtx.hashUnset()) { | if (prevtx.nIndex == -1 && !prevtx.hashUnset()) { | ||||
MarkConflicted(prevtx.hashBlock, wtx.GetId()); | MarkConflicted(prevtx.hashBlock, wtx.GetId()); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return true; | |||||
} | } | ||||
/** | /** | ||||
* Add a transaction to the wallet, or update it. pIndex and posInBlock should | * Add a transaction to the wallet, or update it. pIndex and posInBlock should | ||||
* be set when the transaction was known to be included in a block. When pIndex | * be set when the transaction was known to be included in a block. When pIndex | ||||
* == nullptr, then wallet state is not updated in AddToWallet, but | * == nullptr, then wallet state is not updated in AddToWallet, but | ||||
* notifications happen and cached balances are marked dirty. | * notifications happen and cached balances are marked dirty. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 494 Lines • ▼ Show 20 Lines | CPubKey CWallet::GenerateNewHDMasterKey() { | ||||
if (!AddKeyPubKey(key, pubkey)) { | if (!AddKeyPubKey(key, pubkey)) { | ||||
throw std::runtime_error(std::string(__func__) + | throw std::runtime_error(std::string(__func__) + | ||||
": AddKeyPubKey failed"); | ": AddKeyPubKey failed"); | ||||
} | } | ||||
return pubkey; | return pubkey; | ||||
} | } | ||||
bool CWallet::SetHDMasterKey(const CPubKey &pubkey) { | void CWallet::SetHDMasterKey(const CPubKey &pubkey) { | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
// Store the keyid (hash160) together with the child index counter in the | // Store the keyid (hash160) together with the child index counter in the | ||||
// database as a hdchain object. | // database as a hdchain object. | ||||
CHDChain newHdChain; | CHDChain newHdChain; | ||||
newHdChain.nVersion = CanSupportFeature(FEATURE_HD_SPLIT) | newHdChain.nVersion = CanSupportFeature(FEATURE_HD_SPLIT) | ||||
? CHDChain::VERSION_HD_CHAIN_SPLIT | ? CHDChain::VERSION_HD_CHAIN_SPLIT | ||||
: CHDChain::VERSION_HD_BASE; | : CHDChain::VERSION_HD_BASE; | ||||
newHdChain.masterKeyID = pubkey.GetID(); | newHdChain.masterKeyID = pubkey.GetID(); | ||||
SetHDChain(newHdChain, false); | SetHDChain(newHdChain, false); | ||||
return true; | |||||
} | } | ||||
bool CWallet::SetHDChain(const CHDChain &chain, bool memonly) { | void CWallet::SetHDChain(const CHDChain &chain, bool memonly) { | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
if (!memonly && !WalletBatch(*database).WriteHDChain(chain)) { | if (!memonly && !WalletBatch(*database).WriteHDChain(chain)) { | ||||
throw std::runtime_error(std::string(__func__) + | throw std::runtime_error(std::string(__func__) + | ||||
": writing chain failed"); | ": writing chain failed"); | ||||
} | } | ||||
hdChain = chain; | hdChain = chain; | ||||
return true; | |||||
} | } | ||||
bool CWallet::IsHDEnabled() const { | bool CWallet::IsHDEnabled() const { | ||||
return !hdChain.masterKeyID.IsNull(); | return !hdChain.masterKeyID.IsNull(); | ||||
} | } | ||||
int64_t CWalletTx::GetTxTime() const { | int64_t CWalletTx::GetTxTime() const { | ||||
int64_t n = nTimeSmart; | int64_t n = nTimeSmart; | ||||
▲ Show 20 Lines • Show All 2,587 Lines • ▼ Show 20 Lines | bool CWallet::EraseDestData(const CTxDestination &dest, | ||||
const std::string &key) { | const std::string &key) { | ||||
if (!mapAddressBook[dest].destdata.erase(key)) { | if (!mapAddressBook[dest].destdata.erase(key)) { | ||||
return false; | return false; | ||||
} | } | ||||
return WalletBatch(*database).EraseDestData(dest, key); | return WalletBatch(*database).EraseDestData(dest, key); | ||||
} | } | ||||
bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, | void CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, | ||||
const std::string &value) { | const std::string &value) { | ||||
mapAddressBook[dest].destdata.insert(std::make_pair(key, value)); | mapAddressBook[dest].destdata.insert(std::make_pair(key, value)); | ||||
return true; | |||||
} | } | ||||
bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, | bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, | ||||
std::string *value) const { | std::string *value) const { | ||||
std::map<CTxDestination, CAddressBookData>::const_iterator i = | std::map<CTxDestination, CAddressBookData>::const_iterator i = | ||||
mapAddressBook.find(dest); | mapAddressBook.find(dest); | ||||
if (i != mapAddressBook.end()) { | if (i != mapAddressBook.end()) { | ||||
CAddressBookData::StringMap::const_iterator j = | CAddressBookData::StringMap::const_iterator j = | ||||
▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | if (fFirstRun) { | ||||
"wallets with this version."), | "wallets with this version."), | ||||
walletFile)); | walletFile)); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
walletInstance->SetMinVersion(FEATURE_NO_DEFAULT_KEY); | walletInstance->SetMinVersion(FEATURE_NO_DEFAULT_KEY); | ||||
// Generate a new master key. | // Generate a new master key. | ||||
CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); | CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); | ||||
if (!walletInstance->SetHDMasterKey(masterPubKey)) { | walletInstance->SetHDMasterKey(masterPubKey); | ||||
throw std::runtime_error(std::string(__func__) + | |||||
": Storing master key failed"); | |||||
} | |||||
// Top up the keypool | // Top up the keypool | ||||
if (!walletInstance->TopUpKeyPool()) { | if (!walletInstance->TopUpKeyPool()) { | ||||
InitError(_("Unable to generate initial keys") += "\n"); | InitError(_("Unable to generate initial keys") += "\n"); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
walletInstance->ChainStateFlushed(chainActive.GetLocator()); | walletInstance->ChainStateFlushed(chainActive.GetLocator()); | ||||
▲ Show 20 Lines • Show All 361 Lines • Show Last 20 Lines |