Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
Show First 20 Lines • Show All 805 Lines • ▼ Show 20 Lines | for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) { | ||||
(pwtx != nullptr) ? pwtx->nOrderPos : pacentry->nOrderPos; | (pwtx != nullptr) ? pwtx->nOrderPos : pacentry->nOrderPos; | ||||
if (nOrderPos == -1) { | if (nOrderPos == -1) { | ||||
nOrderPos = nOrderPosNext++; | nOrderPos = nOrderPosNext++; | ||||
nOrderPosOffsets.push_back(nOrderPos); | nOrderPosOffsets.push_back(nOrderPos); | ||||
if (pwtx) { | if (pwtx) { | ||||
if (!walletdb.WriteTx(*pwtx)) { | if (!walletdb.WriteTx(*pwtx)) { | ||||
return DB_LOAD_FAIL; | return DBErrors::LOAD_FAIL; | ||||
} | } | ||||
} else if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, | } else if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, | ||||
*pacentry)) { | *pacentry)) { | ||||
return DB_LOAD_FAIL; | return DBErrors::LOAD_FAIL; | ||||
} | } | ||||
} else { | } else { | ||||
int64_t nOrderPosOff = 0; | int64_t nOrderPosOff = 0; | ||||
for (const int64_t &nOffsetStart : nOrderPosOffsets) { | for (const int64_t &nOffsetStart : nOrderPosOffsets) { | ||||
if (nOrderPos >= nOffsetStart) { | if (nOrderPos >= nOffsetStart) { | ||||
++nOrderPosOff; | ++nOrderPosOff; | ||||
} | } | ||||
} | } | ||||
nOrderPos += nOrderPosOff; | nOrderPos += nOrderPosOff; | ||||
nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1); | nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1); | ||||
if (!nOrderPosOff) { | if (!nOrderPosOff) { | ||||
continue; | continue; | ||||
} | } | ||||
// Since we're changing the order, write it back. | // Since we're changing the order, write it back. | ||||
if (pwtx) { | if (pwtx) { | ||||
if (!walletdb.WriteTx(*pwtx)) { | if (!walletdb.WriteTx(*pwtx)) { | ||||
return DB_LOAD_FAIL; | return DBErrors::LOAD_FAIL; | ||||
} | } | ||||
} else if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, | } else if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, | ||||
*pacentry)) { | *pacentry)) { | ||||
return DB_LOAD_FAIL; | return DBErrors::LOAD_FAIL; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
walletdb.WriteOrderPosNext(nOrderPosNext); | walletdb.WriteOrderPosNext(nOrderPosNext); | ||||
return DB_LOAD_OK; | return DBErrors::LOAD_OK; | ||||
} | } | ||||
int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) { | int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb) { | ||||
// nOrderPosNext | // nOrderPosNext | ||||
AssertLockHeld(cs_wallet); | AssertLockHeld(cs_wallet); | ||||
int64_t nRet = nOrderPosNext++; | int64_t nRet = nOrderPosNext++; | ||||
if (pwalletdb) { | if (pwalletdb) { | ||||
pwalletdb->WriteOrderPosNext(nOrderPosNext); | pwalletdb->WriteOrderPosNext(nOrderPosNext); | ||||
▲ Show 20 Lines • Show All 2,456 Lines • ▼ Show 20 Lines | bool CWallet::AddAccountingEntry(const CAccountingEntry &acentry, | ||||
return true; | return true; | ||||
} | } | ||||
DBErrors CWallet::LoadWallet(bool &fFirstRunRet) { | DBErrors CWallet::LoadWallet(bool &fFirstRunRet) { | ||||
LOCK2(cs_main, cs_wallet); | LOCK2(cs_main, cs_wallet); | ||||
fFirstRunRet = false; | fFirstRunRet = false; | ||||
DBErrors nLoadWalletRet = CWalletDB(*dbw, "cr+").LoadWallet(this); | DBErrors nLoadWalletRet = CWalletDB(*dbw, "cr+").LoadWallet(this); | ||||
if (nLoadWalletRet == DB_NEED_REWRITE) { | if (nLoadWalletRet == DBErrors::NEED_REWRITE) { | ||||
if (dbw->Rewrite("\x04pool")) { | if (dbw->Rewrite("\x04pool")) { | ||||
setInternalKeyPool.clear(); | setInternalKeyPool.clear(); | ||||
setExternalKeyPool.clear(); | setExternalKeyPool.clear(); | ||||
m_pool_key_to_index.clear(); | m_pool_key_to_index.clear(); | ||||
// Note: can't top-up keypool here, because wallet is locked. | // Note: can't top-up keypool here, because wallet is locked. | ||||
// User will be prompted to unlock wallet the next operation | // User will be prompted to unlock wallet the next operation | ||||
// that requires a new key. | // that requires a new key. | ||||
} | } | ||||
} | } | ||||
// This wallet is in its first run if all of these are empty | // This wallet is in its first run if all of these are empty | ||||
fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && | fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && | ||||
mapWatchKeys.empty() && setWatchOnly.empty() && | mapWatchKeys.empty() && setWatchOnly.empty() && | ||||
mapScripts.empty(); | mapScripts.empty(); | ||||
if (nLoadWalletRet != DB_LOAD_OK) { | if (nLoadWalletRet != DBErrors::LOAD_OK) { | ||||
return nLoadWalletRet; | return nLoadWalletRet; | ||||
} | } | ||||
uiInterface.LoadWallet(this); | uiInterface.LoadWallet(this); | ||||
return DB_LOAD_OK; | return DBErrors::LOAD_OK; | ||||
} | } | ||||
DBErrors CWallet::ZapSelectTx(std::vector<TxId> &txIdsIn, | DBErrors CWallet::ZapSelectTx(std::vector<TxId> &txIdsIn, | ||||
std::vector<TxId> &txIdsOut) { | std::vector<TxId> &txIdsOut) { | ||||
AssertLockHeld(cs_wallet); // mapWallet | AssertLockHeld(cs_wallet); // mapWallet | ||||
DBErrors nZapSelectTxRet = | DBErrors nZapSelectTxRet = | ||||
CWalletDB(*dbw, "cr+").ZapSelectTx(txIdsIn, txIdsOut); | CWalletDB(*dbw, "cr+").ZapSelectTx(txIdsIn, txIdsOut); | ||||
for (const TxId &txid : txIdsOut) { | for (const TxId &txid : txIdsOut) { | ||||
mapWallet.erase(txid); | mapWallet.erase(txid); | ||||
} | } | ||||
if (nZapSelectTxRet == DB_NEED_REWRITE) { | if (nZapSelectTxRet == DBErrors::NEED_REWRITE) { | ||||
if (dbw->Rewrite("\x04pool")) { | if (dbw->Rewrite("\x04pool")) { | ||||
setInternalKeyPool.clear(); | setInternalKeyPool.clear(); | ||||
setExternalKeyPool.clear(); | setExternalKeyPool.clear(); | ||||
m_pool_key_to_index.clear(); | m_pool_key_to_index.clear(); | ||||
// Note: can't top-up keypool here, because wallet is locked. | // Note: can't top-up keypool here, because wallet is locked. | ||||
// User will be prompted to unlock wallet the next operation | // User will be prompted to unlock wallet the next operation | ||||
// that requires a new key. | // that requires a new key. | ||||
} | } | ||||
} | } | ||||
if (nZapSelectTxRet != DB_LOAD_OK) { | if (nZapSelectTxRet != DBErrors::LOAD_OK) { | ||||
return nZapSelectTxRet; | return nZapSelectTxRet; | ||||
} | } | ||||
MarkDirty(); | MarkDirty(); | ||||
return DB_LOAD_OK; | return DBErrors::LOAD_OK; | ||||
} | } | ||||
DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx> &vWtx) { | DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx> &vWtx) { | ||||
DBErrors nZapWalletTxRet = CWalletDB(*dbw, "cr+").ZapWalletTx(vWtx); | DBErrors nZapWalletTxRet = CWalletDB(*dbw, "cr+").ZapWalletTx(vWtx); | ||||
if (nZapWalletTxRet == DB_NEED_REWRITE) { | if (nZapWalletTxRet == DBErrors::NEED_REWRITE) { | ||||
if (dbw->Rewrite("\x04pool")) { | if (dbw->Rewrite("\x04pool")) { | ||||
LOCK(cs_wallet); | LOCK(cs_wallet); | ||||
setInternalKeyPool.clear(); | setInternalKeyPool.clear(); | ||||
setExternalKeyPool.clear(); | setExternalKeyPool.clear(); | ||||
m_pool_key_to_index.clear(); | m_pool_key_to_index.clear(); | ||||
// Note: can't top-up keypool here, because wallet is locked. | // Note: can't top-up keypool here, because wallet is locked. | ||||
// User will be prompted to unlock wallet the next operation | // User will be prompted to unlock wallet the next operation | ||||
// that requires a new key. | // that requires a new key. | ||||
} | } | ||||
} | } | ||||
if (nZapWalletTxRet != DB_LOAD_OK) { | if (nZapWalletTxRet != DBErrors::LOAD_OK) { | ||||
return nZapWalletTxRet; | return nZapWalletTxRet; | ||||
} | } | ||||
return DB_LOAD_OK; | return DBErrors::LOAD_OK; | ||||
} | } | ||||
bool CWallet::SetAddressBook(const CTxDestination &address, | bool CWallet::SetAddressBook(const CTxDestination &address, | ||||
const std::string &strName, | const std::string &strName, | ||||
const std::string &strPurpose) { | const std::string &strPurpose) { | ||||
bool fUpdated = false; | bool fUpdated = false; | ||||
{ | { | ||||
// mapAddressBook | // mapAddressBook | ||||
▲ Show 20 Lines • Show All 766 Lines • ▼ Show 20 Lines | CWallet *CWallet::CreateWalletFromFile(const CChainParams &chainParams, | ||||
if (gArgs.GetBoolArg("-zapwallettxes", false)) { | if (gArgs.GetBoolArg("-zapwallettxes", false)) { | ||||
uiInterface.InitMessage(_("Zapping all transactions from wallet...")); | uiInterface.InitMessage(_("Zapping all transactions from wallet...")); | ||||
std::unique_ptr<CWalletDBWrapper> dbw( | std::unique_ptr<CWalletDBWrapper> dbw( | ||||
new CWalletDBWrapper(&bitdb, walletFile)); | new CWalletDBWrapper(&bitdb, walletFile)); | ||||
std::unique_ptr<CWallet> tempWallet = | std::unique_ptr<CWallet> tempWallet = | ||||
MakeUnique<CWallet>(chainParams, std::move(dbw)); | MakeUnique<CWallet>(chainParams, std::move(dbw)); | ||||
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); | DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); | ||||
if (nZapWalletRet != DB_LOAD_OK) { | if (nZapWalletRet != DBErrors::LOAD_OK) { | ||||
InitError( | InitError( | ||||
strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); | strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
} | } | ||||
uiInterface.InitMessage(_("Loading wallet...")); | uiInterface.InitMessage(_("Loading wallet...")); | ||||
int64_t nStart = GetTimeMillis(); | int64_t nStart = GetTimeMillis(); | ||||
bool fFirstRun = true; | bool fFirstRun = true; | ||||
std::unique_ptr<CWalletDBWrapper> dbw( | std::unique_ptr<CWalletDBWrapper> dbw( | ||||
new CWalletDBWrapper(&bitdb, walletFile)); | new CWalletDBWrapper(&bitdb, walletFile)); | ||||
CWallet *walletInstance = new CWallet(chainParams, std::move(dbw)); | CWallet *walletInstance = new CWallet(chainParams, std::move(dbw)); | ||||
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); | DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); | ||||
if (nLoadWalletRet != DB_LOAD_OK) { | if (nLoadWalletRet != DBErrors::LOAD_OK) { | ||||
if (nLoadWalletRet == DB_CORRUPT) { | if (nLoadWalletRet == DBErrors::CORRUPT) { | ||||
InitError( | InitError( | ||||
strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); | strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
if (nLoadWalletRet == DB_NONCRITICAL_ERROR) { | if (nLoadWalletRet == DBErrors::NONCRITICAL_ERROR) { | ||||
InitWarning(strprintf( | InitWarning(strprintf( | ||||
_("Error reading %s! All keys read correctly, but transaction " | _("Error reading %s! All keys read correctly, but transaction " | ||||
"data" | "data" | ||||
" or address book entries might be missing or incorrect."), | " or address book entries might be missing or incorrect."), | ||||
walletFile)); | walletFile)); | ||||
} else if (nLoadWalletRet == DB_TOO_NEW) { | } else if (nLoadWalletRet == DBErrors::TOO_NEW) { | ||||
InitError(strprintf( | InitError(strprintf( | ||||
_("Error loading %s: Wallet requires newer version of %s"), | _("Error loading %s: Wallet requires newer version of %s"), | ||||
walletFile, _(PACKAGE_NAME))); | walletFile, _(PACKAGE_NAME))); | ||||
return nullptr; | return nullptr; | ||||
} else if (nLoadWalletRet == DB_NEED_REWRITE) { | } else if (nLoadWalletRet == DBErrors::NEED_REWRITE) { | ||||
InitError(strprintf( | InitError(strprintf( | ||||
_("Wallet needed to be rewritten: restart %s to complete"), | _("Wallet needed to be rewritten: restart %s to complete"), | ||||
_(PACKAGE_NAME))); | _(PACKAGE_NAME))); | ||||
return nullptr; | return nullptr; | ||||
} else { | } else { | ||||
InitError(strprintf(_("Error loading %s"), walletFile)); | InitError(strprintf(_("Error loading %s"), walletFile)); | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 252 Lines • Show Last 20 Lines |