diff options
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r-- | src/wallet/wallet.cpp | 85 |
1 files changed, 43 insertions, 42 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index af07be311e..f54405534a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5,7 +5,6 @@ #include <wallet/wallet.h> -#include <base58.h> #include <checkpoints.h> #include <chain.h> #include <wallet/coincontrol.h> @@ -14,6 +13,7 @@ #include <fs.h> #include <wallet/init.h> #include <key.h> +#include <key_io.h> #include <keystore.h> #include <validation.h> #include <net.h> @@ -43,9 +43,8 @@ bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; bool fWalletRbf = DEFAULT_WALLET_RBF; OutputType g_address_type = OUTPUT_TYPE_NONE; OutputType g_change_type = OUTPUT_TYPE_NONE; -bool g_wallet_allow_fallback_fee = false; //<! will be defined via chainparams +bool g_wallet_allow_fallback_fee = true; //<! will be defined via chainparams -const char * DEFAULT_WALLET_DAT = "wallet.dat"; const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000; /** @@ -532,7 +531,7 @@ void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> ran int nMinOrderPos = std::numeric_limits<int>::max(); const CWalletTx* copyFrom = nullptr; for (TxSpends::iterator it = range.first; it != range.second; ++it) { - const CWalletTx* wtx = &mapWallet[it->second]; + const CWalletTx* wtx = &mapWallet.at(it->second); if (wtx->nOrderPos < nMinOrderPos) { nMinOrderPos = wtx->nOrderPos;; copyFrom = wtx; @@ -545,7 +544,7 @@ void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> ran for (TxSpends::iterator it = range.first; it != range.second; ++it) { const uint256& hash = it->second; - CWalletTx* copyTo = &mapWallet[hash]; + CWalletTx* copyTo = &mapWallet.at(hash); if (copyFrom == copyTo) continue; assert(copyFrom && "Oldest wallet transaction in range assumed to have been found."); if (!copyFrom->IsEquivalentTo(*copyTo)) continue; @@ -1148,11 +1147,9 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx) LOCK2(cs_main, cs_wallet); int conflictconfirms = 0; - if (mapBlockIndex.count(hashBlock)) { - CBlockIndex* pindex = mapBlockIndex[hashBlock]; - if (chainActive.Contains(pindex)) { - conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1); - } + CBlockIndex* pindex = LookupBlockIndex(hashBlock); + if (pindex && chainActive.Contains(pindex)) { + conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1); } // If number of conflict confirms cannot be determined, this means // that the block is still unknown or not yet part of the main chain, @@ -2632,13 +2629,13 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC LOCK2(cs_main, cs_wallet); CReserveKey reservekey(this); - CWalletTx wtx; - if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) { + CTransactionRef tx_new; + if (!CreateTransaction(vecSend, tx_new, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) { return false; } if (nChangePosInOut != -1) { - tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.tx->vout[nChangePosInOut]); + tx.vout.insert(tx.vout.begin() + nChangePosInOut, tx_new->vout[nChangePosInOut]); // We don't have the normal Create/Commit cycle, and don't want to risk // reusing change, so just remove the key from the keypool here. reservekey.KeepKey(); @@ -2647,11 +2644,11 @@ bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nC // Copy output sizes from new transaction; they may have had the fee // subtracted from them. for (unsigned int idx = 0; idx < tx.vout.size(); idx++) { - tx.vout[idx].nValue = wtx.tx->vout[idx].nValue; + tx.vout[idx].nValue = tx_new->vout[idx].nValue; } // Add new txins while keeping original txin scriptSig/order. - for (const CTxIn& txin : wtx.tx->vin) { + for (const CTxIn& txin : tx_new->vin) { if (!coinControl.IsSelected(txin.prevout)) { tx.vin.push_back(txin); @@ -2692,7 +2689,7 @@ OutputType CWallet::TransactionChangeType(OutputType change_type, const std::vec return g_address_type; } -bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, +bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CTransactionRef& tx, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, const CCoinControl& coin_control, bool sign) { CAmount nValue = 0; @@ -2716,8 +2713,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT return false; } - wtxNew.fTimeReceivedIsTxTime = true; - wtxNew.BindWallet(this); CMutableTransaction txNew; // Discourage fee sniping. @@ -2805,7 +2800,6 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT nChangePosInOut = nChangePosRequest; txNew.vin.clear(); txNew.vout.clear(); - wtxNew.fFromMe = true; bool fFirst = true; CAmount nValueToSelect = nValue; @@ -3020,11 +3014,11 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT } } - // Embed the constructed transaction data in wtxNew. - wtxNew.SetTx(MakeTransactionRef(std::move(txNew))); + // Return the constructed transaction data. + tx = MakeTransactionRef(std::move(txNew)); // Limit size - if (GetTransactionWeight(*wtxNew.tx) >= MAX_STANDARD_TX_WEIGHT) + if (GetTransactionWeight(*tx) >= MAX_STANDARD_TX_WEIGHT) { strFailReason = _("Transaction too large"); return false; @@ -3034,7 +3028,7 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) { // Lastly, ensure this tx will pass the mempool's chain limits LockPoints lp; - CTxMemPoolEntry entry(wtxNew.tx, 0, 0, 0, false, 0, lp); + CTxMemPoolEntry entry(tx, 0, 0, 0, false, 0, lp); CTxMemPool::setEntries setAncestors; size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; @@ -3061,10 +3055,18 @@ bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletT /** * Call after CreateTransaction unless you want to abort */ -bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state) +bool CWallet::CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm, std::string fromAccount, CReserveKey& reservekey, CConnman* connman, CValidationState& state) { { LOCK2(cs_main, cs_wallet); + + CWalletTx wtxNew(this, std::move(tx)); + wtxNew.mapValue = std::move(mapValue); + wtxNew.vOrderForm = std::move(orderForm); + wtxNew.strFromAccount = std::move(fromAccount); + wtxNew.fTimeReceivedIsTxTime = true; + wtxNew.fFromMe = true; + LogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString()); { // Take key pair from key pool so it won't be used again @@ -3077,7 +3079,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon // Notify that old coins are spent for (const CTxIn& txin : wtxNew.tx->vin) { - CWalletTx &coin = mapWallet[txin.prevout.hash]; + CWalletTx &coin = mapWallet.at(txin.prevout.hash); coin.BindWallet(this); NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED); } @@ -3088,7 +3090,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon // Get the inserted-CWalletTx from mapWallet so that the // fInMempool flag is cached properly - CWalletTx& wtx = mapWallet[wtxNew.GetHash()]; + CWalletTx& wtx = mapWallet.at(wtxNew.GetHash()); if (fBroadcastTransactions) { @@ -3544,7 +3546,7 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings() CTxDestination address; if(!IsMine(txin)) /* If this input isn't mine, ignore it */ continue; - if(!ExtractDestination(mapWallet[txin.prevout.hash].tx->vout[txin.prevout.n].scriptPubKey, address)) + if(!ExtractDestination(mapWallet.at(txin.prevout.hash).tx->vout[txin.prevout.n].scriptPubKey, address)) continue; grouping.insert(address); any_mine = true; @@ -3768,10 +3770,10 @@ void CWallet::GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) c for (const auto& entry : mapWallet) { // iterate over all wallet transactions... const CWalletTx &wtx = entry.second; - BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); - if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) { + CBlockIndex* pindex = LookupBlockIndex(wtx.hashBlock); + if (pindex && chainActive.Contains(pindex)) { // ... which are already in a block - int nHeight = blit->second->nHeight; + int nHeight = pindex->nHeight; for (const CTxOut &txout : wtx.tx->vout) { // iterate over all their outputs CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey); @@ -3779,7 +3781,7 @@ void CWallet::GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) c // ... and all their affected keys std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid); if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight) - rit->second = blit->second; + rit->second = pindex; } vAffected.clear(); } @@ -3816,7 +3818,7 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const { unsigned int nTimeSmart = wtx.nTimeReceived; if (!wtx.hashUnset()) { - if (mapBlockIndex.count(wtx.hashBlock)) { + if (const CBlockIndex* pindex = LookupBlockIndex(wtx.hashBlock)) { int64_t latestNow = wtx.nTimeReceived; int64_t latestEntry = 0; @@ -3847,7 +3849,7 @@ unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const } } - int64_t blocktime = mapBlockIndex[wtx.hashBlock]->GetBlockTime(); + int64_t blocktime = pindex->GetBlockTime(); nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow)); } else { LogPrintf("%s: found %s in block %s not in index\n", __func__, wtx.GetHash().ToString(), wtx.hashBlock.ToString()); @@ -3908,16 +3910,17 @@ std::vector<std::string> CWallet::GetDestValues(const std::string& prefix) const return values; } -CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) +CWallet* CWallet::CreateWalletFromFile(const std::string& name, const fs::path& path) { + const std::string& walletFile = name; + // needed to restore wallet transaction meta data after -zapwallettxes std::vector<CWalletTx> vWtx; if (gArgs.GetBoolArg("-zapwallettxes", false)) { uiInterface.InitMessage(_("Zapping all transactions from wallet...")); - std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile)); - std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(std::move(dbw)); + std::unique_ptr<CWallet> tempWallet = MakeUnique<CWallet>(name, CWalletDBWrapper::Create(path)); DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx); if (nZapWalletRet != DB_LOAD_OK) { InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile)); @@ -3929,8 +3932,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) int64_t nStart = GetTimeMillis(); bool fFirstRun = true; - std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile)); - CWallet *walletInstance = new CWallet(std::move(dbw)); + CWallet *walletInstance = new CWallet(name, CWalletDBWrapper::Create(path)); DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun); if (nLoadWalletRet != DB_LOAD_OK) { @@ -4017,6 +4019,8 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) // Try to top up keypool. No-op if the wallet is locked. walletInstance->TopUpKeyPool(); + LOCK(cs_main); + CBlockIndex *pindexRescan = chainActive.Genesis(); if (!gArgs.GetBoolArg("-rescan", false)) { @@ -4160,10 +4164,7 @@ int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const AssertLockHeld(cs_main); // Find the block it claims to be in - BlockMap::iterator mi = mapBlockIndex.find(hashBlock); - if (mi == mapBlockIndex.end()) - return 0; - CBlockIndex* pindex = (*mi).second; + CBlockIndex* pindex = LookupBlockIndex(hashBlock); if (!pindex || !chainActive.Contains(pindex)) return 0; |