LCOV - code coverage report
Current view: top level - src/wallet - wallet.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 959 1315 72.9 %
Date: 2015-10-12 22:39:14 Functions: 92 124 74.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #include "wallet/wallet.h"
       7             : 
       8             : #include "base58.h"
       9             : #include "checkpoints.h"
      10             : #include "chain.h"
      11             : #include "coincontrol.h"
      12             : #include "consensus/consensus.h"
      13             : #include "consensus/validation.h"
      14             : #include "key.h"
      15             : #include "keystore.h"
      16             : #include "main.h"
      17             : #include "net.h"
      18             : #include "policy/policy.h"
      19             : #include "primitives/block.h"
      20             : #include "primitives/transaction.h"
      21             : #include "script/script.h"
      22             : #include "script/sign.h"
      23             : #include "timedata.h"
      24             : #include "txmempool.h"
      25             : #include "util.h"
      26             : #include "utilmoneystr.h"
      27             : 
      28             : #include <assert.h>
      29             : 
      30             : #include <boost/algorithm/string/replace.hpp>
      31             : #include <boost/filesystem.hpp>
      32             : #include <boost/thread.hpp>
      33             : 
      34             : using namespace std;
      35             : 
      36             : /**
      37             :  * Settings
      38             :  */
      39             : CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
      40             : CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
      41             : unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
      42             : bool bSpendZeroConfChange = true;
      43             : bool fSendFreeTransactions = false;
      44             : bool fPayAtLeastCustomFee = true;
      45             : 
      46             : /**
      47             :  * Fees smaller than this (in satoshi) are considered zero fee (for transaction creation)
      48             :  * Override with -mintxfee
      49             :  */
      50          96 : CFeeRate CWallet::minTxFee = CFeeRate(1000);
      51             : 
      52             : /** @defgroup mapWallet
      53             :  *
      54             :  * @{
      55             :  */
      56             : 
      57             : struct CompareValueOnly
      58             : {
      59           0 :     bool operator()(const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t1,
      60             :                     const pair<CAmount, pair<const CWalletTx*, unsigned int> >& t2) const
      61             :     {
      62           0 :         return t1.first < t2.first;
      63             :     }
      64             : };
      65             : 
      66           0 : std::string COutput::ToString() const
      67             : {
      68           0 :     return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->vout[i].nValue));
      69             : }
      70             : 
      71        2093 : const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
      72             : {
      73        2093 :     LOCK(cs_wallet);
      74        4186 :     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
      75        4186 :     if (it == mapWallet.end())
      76             :         return NULL;
      77        2093 :     return &(it->second);
      78             : }
      79             : 
      80        1056 : CPubKey CWallet::GenerateNewKey()
      81             : {
      82        1056 :     AssertLockHeld(cs_wallet); // mapKeyMetadata
      83        2112 :     bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
      84             : 
      85             :     CKey secret;
      86        1056 :     secret.MakeNewKey(fCompressed);
      87             : 
      88             :     // Compressed public keys were introduced in version 0.6.0
      89        1056 :     if (fCompressed)
      90         949 :         SetMinVersion(FEATURE_COMPRPUBKEY);
      91             : 
      92        1056 :     CPubKey pubkey = secret.GetPubKey();
      93        1056 :     assert(secret.VerifyPubKey(pubkey));
      94             : 
      95             :     // Create new metadata
      96        1056 :     int64_t nCreationTime = GetTime();
      97        1056 :     mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
      98        1056 :     if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
      99          42 :         nTimeFirstKey = nCreationTime;
     100             : 
     101        1056 :     if (!AddKeyPubKey(secret, pubkey))
     102           0 :         throw std::runtime_error("CWallet::GenerateNewKey(): AddKey failed");
     103        1056 :     return pubkey;
     104             : }
     105             : 
     106        1393 : bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
     107             : {
     108        1393 :     AssertLockHeld(cs_wallet); // mapKeyMetadata
     109        1393 :     if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
     110             :         return false;
     111             : 
     112             :     // check if we need to remove from watch-only
     113             :     CScript script;
     114        5572 :     script = GetScriptForDestination(pubkey.GetID());
     115        1393 :     if (HaveWatchOnly(script))
     116           0 :         RemoveWatchOnly(script);
     117        2786 :     script = GetScriptForRawPubKey(pubkey);
     118        1393 :     if (HaveWatchOnly(script))
     119           0 :         RemoveWatchOnly(script);
     120             : 
     121        1393 :     if (!fFileBacked)
     122             :         return true;
     123        1393 :     if (!IsCrypted()) {
     124             :         return CWalletDB(strWalletFile).WriteKey(pubkey,
     125             :                                                  secret.GetPrivKey(),
     126        5396 :                                                  mapKeyMetadata[pubkey.GetID()]);
     127             :     }
     128             :     return true;
     129             : }
     130             : 
     131          65 : bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
     132             :                             const vector<unsigned char> &vchCryptedSecret)
     133             : {
     134          65 :     if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
     135             :         return false;
     136          65 :     if (!fFileBacked)
     137             :         return true;
     138             :     {
     139          65 :         LOCK(cs_wallet);
     140          65 :         if (pwalletdbEncryption)
     141             :             return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
     142             :                                                         vchCryptedSecret,
     143          21 :                                                         mapKeyMetadata[vchPubKey.GetID()]);
     144             :         else
     145             :             return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
     146             :                                                             vchCryptedSecret,
     147         132 :                                                             mapKeyMetadata[vchPubKey.GetID()]);
     148             :     }
     149             :     return false;
     150             : }
     151             : 
     152        2620 : bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
     153             : {
     154        2620 :     AssertLockHeld(cs_wallet); // mapKeyMetadata
     155        2620 :     if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
     156         159 :         nTimeFirstKey = meta.nCreateTime;
     157             : 
     158        2620 :     mapKeyMetadata[pubkey.GetID()] = meta;
     159        2620 :     return true;
     160             : }
     161             : 
     162          22 : bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
     163             : {
     164          22 :     return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
     165             : }
     166             : 
     167           9 : bool CWallet::AddCScript(const CScript& redeemScript)
     168             : {
     169           9 :     if (!CCryptoKeyStore::AddCScript(redeemScript))
     170             :         return false;
     171           9 :     if (!fFileBacked)
     172             :         return true;
     173          36 :     return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
     174             : }
     175             : 
     176           3 : bool CWallet::LoadCScript(const CScript& redeemScript)
     177             : {
     178             :     /* A sanity check was added in pull #3843 to avoid adding redeemScripts
     179             :      * that never can be redeemed. However, old wallets may still contain
     180             :      * these. Do not add them to the wallet and warn. */
     181           6 :     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
     182             :     {
     183           0 :         std::string strAddr = CBitcoinAddress(CScriptID(redeemScript)).ToString();
     184           0 :         LogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
     185           0 :             __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
     186           0 :         return true;
     187             :     }
     188             : 
     189           3 :     return CCryptoKeyStore::AddCScript(redeemScript);
     190             : }
     191             : 
     192           4 : bool CWallet::AddWatchOnly(const CScript &dest)
     193             : {
     194           4 :     if (!CCryptoKeyStore::AddWatchOnly(dest))
     195             :         return false;
     196           4 :     nTimeFirstKey = 1; // No birthday information for watch-only keys.
     197           4 :     NotifyWatchonlyChanged(true);
     198           4 :     if (!fFileBacked)
     199             :         return true;
     200          12 :     return CWalletDB(strWalletFile).WriteWatchOnly(dest);
     201             : }
     202             : 
     203           0 : bool CWallet::RemoveWatchOnly(const CScript &dest)
     204             : {
     205           0 :     AssertLockHeld(cs_wallet);
     206           0 :     if (!CCryptoKeyStore::RemoveWatchOnly(dest))
     207             :         return false;
     208           0 :     if (!HaveWatchOnly())
     209           0 :         NotifyWatchonlyChanged(false);
     210           0 :     if (fFileBacked)
     211           0 :         if (!CWalletDB(strWalletFile).EraseWatchOnly(dest))
     212             :             return false;
     213             : 
     214             :     return true;
     215             : }
     216             : 
     217           2 : bool CWallet::LoadWatchOnly(const CScript &dest)
     218             : {
     219           2 :     return CCryptoKeyStore::AddWatchOnly(dest);
     220             : }
     221             : 
     222           2 : bool CWallet::Unlock(const SecureString& strWalletPassphrase)
     223             : {
     224           2 :     CCrypter crypter;
     225             :     CKeyingMaterial vMasterKey;
     226             : 
     227             :     {
     228           2 :         LOCK(cs_wallet);
     229          18 :         BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
     230             :         {
     231           2 :             if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
     232             :                 return false;
     233           2 :             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
     234             :                 continue; // try another master key
     235           2 :             if (CCryptoKeyStore::Unlock(vMasterKey))
     236             :                 return true;
     237             :         }
     238             :     }
     239           2 :     return false;
     240             : }
     241             : 
     242           0 : bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
     243             : {
     244           0 :     bool fWasLocked = IsLocked();
     245             : 
     246             :     {
     247           0 :         LOCK(cs_wallet);
     248           0 :         Lock();
     249             : 
     250           0 :         CCrypter crypter;
     251             :         CKeyingMaterial vMasterKey;
     252           0 :         BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
     253             :         {
     254           0 :             if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
     255             :                 return false;
     256           0 :             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
     257             :                 return false;
     258           0 :             if (CCryptoKeyStore::Unlock(vMasterKey))
     259             :             {
     260           0 :                 int64_t nStartTime = GetTimeMillis();
     261           0 :                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
     262           0 :                 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
     263             : 
     264           0 :                 nStartTime = GetTimeMillis();
     265           0 :                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
     266           0 :                 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
     267             : 
     268           0 :                 if (pMasterKey.second.nDeriveIterations < 25000)
     269           0 :                     pMasterKey.second.nDeriveIterations = 25000;
     270             : 
     271           0 :                 LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
     272             : 
     273           0 :                 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
     274             :                     return false;
     275           0 :                 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
     276             :                     return false;
     277           0 :                 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
     278           0 :                 if (fWasLocked)
     279           0 :                     Lock();
     280             :                 return true;
     281             :             }
     282             :         }
     283             :     }
     284             : 
     285           0 :     return false;
     286             : }
     287             : 
     288          87 : void CWallet::SetBestChain(const CBlockLocator& loc)
     289             : {
     290          87 :     CWalletDB walletdb(strWalletFile);
     291          87 :     walletdb.WriteBestBlock(loc);
     292          87 : }
     293             : 
     294         987 : bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
     295             : {
     296         987 :     LOCK(cs_wallet); // nWalletVersion
     297         987 :     if (nWalletVersion >= nVersion)
     298             :         return true;
     299             : 
     300             :     // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
     301          37 :     if (fExplicit && nVersion > nWalletMaxVersion)
     302           0 :             nVersion = FEATURE_LATEST;
     303             : 
     304          37 :     nWalletVersion = nVersion;
     305             : 
     306          37 :     if (nVersion > nWalletMaxVersion)
     307          37 :         nWalletMaxVersion = nVersion;
     308             : 
     309          37 :     if (fFileBacked)
     310             :     {
     311          74 :         CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
     312          37 :         if (nWalletVersion > 40000)
     313          37 :             pwalletdb->WriteMinVersion(nWalletVersion);
     314          37 :         if (!pwalletdbIn)
     315          74 :             delete pwalletdb;
     316             :     }
     317             : 
     318             :     return true;
     319             : }
     320             : 
     321          37 : bool CWallet::SetMaxVersion(int nVersion)
     322             : {
     323          37 :     LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
     324             :     // cannot downgrade below current version
     325          37 :     if (nWalletVersion > nVersion)
     326             :         return false;
     327             : 
     328          37 :     nWalletMaxVersion = nVersion;
     329             : 
     330          37 :     return true;
     331             : }
     332             : 
     333         185 : set<uint256> CWallet::GetConflicts(const uint256& txid) const
     334             : {
     335             :     set<uint256> result;
     336         185 :     AssertLockHeld(cs_wallet);
     337             : 
     338         370 :     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
     339         370 :     if (it == mapWallet.end())
     340             :         return result;
     341         185 :     const CWalletTx& wtx = it->second;
     342             : 
     343             :     std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
     344             : 
     345        2323 :     BOOST_FOREACH(const CTxIn& txin, wtx.vin)
     346             :     {
     347         466 :         if (mapTxSpends.count(txin.prevout) <= 1)
     348             :             continue;  // No conflict if zero or one spends
     349           8 :         range = mapTxSpends.equal_range(txin.prevout);
     350          16 :         for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
     351           8 :             result.insert(it->second);
     352             :     }
     353         185 :     return result;
     354             : }
     355             : 
     356         188 : void CWallet::Flush(bool shutdown)
     357             : {
     358         188 :     bitdb.Flush(shutdown);
     359         188 : }
     360             : 
     361          94 : bool CWallet::Verify(const string& walletFile, string& warningString, string& errorString)
     362             : {
     363          94 :     if (!bitdb.Open(GetDataDir()))
     364             :     {
     365             :         // try moving the database env out of the way
     366           0 :         boost::filesystem::path pathDatabase = GetDataDir() / "database";
     367           0 :         boost::filesystem::path pathDatabaseBak = GetDataDir() / strprintf("database.%d.bak", GetTime());
     368             :         try {
     369             :             boost::filesystem::rename(pathDatabase, pathDatabaseBak);
     370           0 :             LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), pathDatabaseBak.string());
     371           0 :         } catch (const boost::filesystem::filesystem_error&) {
     372             :             // failure is ok (well, not really, but it's not worse than what we started with)
     373             :         }
     374             :         
     375             :         // try again
     376           0 :         if (!bitdb.Open(GetDataDir())) {
     377             :             // if it still fails, it probably means we can't even create the database env
     378           0 :             string msg = strprintf(_("Error initializing wallet database environment %s!"), GetDataDir());
     379             :             errorString += msg;
     380           0 :             return true;
     381             :         }
     382             :     }
     383             :     
     384         282 :     if (GetBoolArg("-salvagewallet", false))
     385             :     {
     386             :         // Recover readable keypairs:
     387           0 :         if (!CWalletDB::Recover(bitdb, walletFile, true))
     388             :             return false;
     389             :     }
     390             :     
     391         282 :     if (boost::filesystem::exists(GetDataDir() / walletFile))
     392             :     {
     393          57 :         CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover);
     394          57 :         if (r == CDBEnv::RECOVER_OK)
     395             :         {
     396           0 :             warningString += strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
     397             :                                      " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
     398             :                                      " your balance or transactions are incorrect you should"
     399           0 :                                      " restore from a backup."), GetDataDir());
     400             :         }
     401          57 :         if (r == CDBEnv::RECOVER_FAIL)
     402           0 :             errorString += _("wallet.dat corrupt, salvage failed");
     403             :     }
     404             :     
     405             :     return true;
     406             : }
     407             : 
     408         682 : void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range)
     409             : {
     410             :     // We want all the wallet transactions in range to have the same metadata as
     411             :     // the oldest (smallest nOrderPos).
     412             :     // So: find smallest nOrderPos:
     413             : 
     414         682 :     int nMinOrderPos = std::numeric_limits<int>::max();
     415         682 :     const CWalletTx* copyFrom = NULL;
     416        2052 :     for (TxSpends::iterator it = range.first; it != range.second; ++it)
     417             :     {
     418         688 :         const uint256& hash = it->second;
     419         688 :         int n = mapWallet[hash].nOrderPos;
     420         688 :         if (n < nMinOrderPos)
     421             :         {
     422         682 :             nMinOrderPos = n;
     423         682 :             copyFrom = &mapWallet[hash];
     424             :         }
     425             :     }
     426             :     // Now copy data from copyFrom to rest:
     427        1370 :     for (TxSpends::iterator it = range.first; it != range.second; ++it)
     428             :     {
     429         688 :         const uint256& hash = it->second;
     430         688 :         CWalletTx* copyTo = &mapWallet[hash];
     431         688 :         if (copyFrom == copyTo) continue;
     432           6 :         if (!copyFrom->IsEquivalentTo(*copyTo)) continue;
     433           2 :         copyTo->mapValue = copyFrom->mapValue;
     434           2 :         copyTo->vOrderForm = copyFrom->vOrderForm;
     435             :         // fTimeReceivedIsTxTime not copied on purpose
     436             :         // nTimeReceived not copied on purpose
     437           2 :         copyTo->nTimeSmart = copyFrom->nTimeSmart;
     438           2 :         copyTo->fFromMe = copyFrom->fFromMe;
     439           2 :         copyTo->strFromAccount = copyFrom->strFromAccount;
     440             :         // nOrderPos not copied on purpose
     441             :         // cached members not copied on purpose
     442             :     }
     443         682 : }
     444             : 
     445             : /**
     446             :  * Outpoint is spent if any non-conflicted transaction
     447             :  * spends it:
     448             :  */
     449       16322 : bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
     450             : {
     451             :     const COutPoint outpoint(hash, n);
     452             :     pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
     453       32644 :     range = mapTxSpends.equal_range(outpoint);
     454             : 
     455       32647 :     for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
     456             :     {
     457        7345 :         const uint256& wtxid = it->second;
     458       14690 :         std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
     459       29380 :         if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
     460             :             return true; // Spent
     461             :     }
     462             :     return false;
     463             : }
     464             : 
     465         682 : void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
     466             : {
     467        1364 :     mapTxSpends.insert(make_pair(outpoint, wtxid));
     468             : 
     469             :     pair<TxSpends::iterator, TxSpends::iterator> range;
     470        1364 :     range = mapTxSpends.equal_range(outpoint);
     471         682 :     SyncMetaData(range);
     472         682 : }
     473             : 
     474             : 
     475        4360 : void CWallet::AddToSpends(const uint256& wtxid)
     476             : {
     477        8720 :     assert(mapWallet.count(wtxid));
     478        4360 :     CWalletTx& thisTx = mapWallet[wtxid];
     479        4360 :     if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
     480        4360 :         return;
     481             : 
     482        6522 :     BOOST_FOREACH(const CTxIn& txin, thisTx.vin)
     483         682 :         AddToSpends(txin.prevout, wtxid);
     484             : }
     485             : 
     486           1 : bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
     487             : {
     488           1 :     if (IsCrypted())
     489             :         return false;
     490             : 
     491             :     CKeyingMaterial vMasterKey;
     492           1 :     RandAddSeedPerfmon();
     493             : 
     494           1 :     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
     495           1 :     GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
     496             : 
     497           2 :     CMasterKey kMasterKey;
     498           1 :     RandAddSeedPerfmon();
     499             : 
     500           1 :     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
     501           1 :     GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
     502             : 
     503           2 :     CCrypter crypter;
     504           1 :     int64_t nStartTime = GetTimeMillis();
     505           1 :     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
     506           1 :     kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
     507             : 
     508           1 :     nStartTime = GetTimeMillis();
     509           1 :     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
     510           1 :     kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
     511             : 
     512           1 :     if (kMasterKey.nDeriveIterations < 25000)
     513           0 :         kMasterKey.nDeriveIterations = 25000;
     514             : 
     515           1 :     LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
     516             : 
     517           1 :     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
     518             :         return false;
     519           1 :     if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
     520             :         return false;
     521             : 
     522             :     {
     523           1 :         LOCK(cs_wallet);
     524           1 :         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
     525           1 :         if (fFileBacked)
     526             :         {
     527           1 :             assert(!pwalletdbEncryption);
     528           2 :             pwalletdbEncryption = new CWalletDB(strWalletFile);
     529           1 :             if (!pwalletdbEncryption->TxnBegin()) {
     530           0 :                 delete pwalletdbEncryption;
     531           0 :                 pwalletdbEncryption = NULL;
     532           0 :                 return false;
     533             :             }
     534           1 :             pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
     535             :         }
     536             : 
     537           1 :         if (!EncryptKeys(vMasterKey))
     538             :         {
     539           0 :             if (fFileBacked) {
     540           0 :                 pwalletdbEncryption->TxnAbort();
     541           0 :                 delete pwalletdbEncryption;
     542             :             }
     543             :             // We now probably have half of our keys encrypted in memory, and half not...
     544             :             // die and let the user reload the unencrypted wallet.
     545           0 :             assert(false);
     546             :         }
     547             : 
     548             :         // Encryption was introduced in version 0.4.0
     549           1 :         SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
     550             : 
     551           1 :         if (fFileBacked)
     552             :         {
     553           1 :             if (!pwalletdbEncryption->TxnCommit()) {
     554           0 :                 delete pwalletdbEncryption;
     555             :                 // We now have keys encrypted in memory, but not on disk...
     556             :                 // die to avoid confusion and let the user reload the unencrypted wallet.
     557           0 :                 assert(false);
     558             :             }
     559             : 
     560           2 :             delete pwalletdbEncryption;
     561           1 :             pwalletdbEncryption = NULL;
     562             :         }
     563             : 
     564           1 :         Lock();
     565           1 :         Unlock(strWalletPassphrase);
     566           1 :         NewKeyPool();
     567           1 :         Lock();
     568             : 
     569             :         // Need to completely rewrite the wallet file; if we don't, bdb might keep
     570             :         // bits of the unencrypted private key in slack space in the database file.
     571           1 :         CDB::Rewrite(strWalletFile);
     572             : 
     573             :     }
     574           1 :     NotifyStatusChanged(this);
     575             : 
     576             :     return true;
     577             : }
     578             : 
     579        1623 : int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
     580             : {
     581        1623 :     AssertLockHeld(cs_wallet); // nOrderPosNext
     582        1623 :     int64_t nRet = nOrderPosNext++;
     583        1623 :     if (pwalletdb) {
     584        1622 :         pwalletdb->WriteOrderPosNext(nOrderPosNext);
     585             :     } else {
     586           3 :         CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
     587             :     }
     588        1623 :     return nRet;
     589             : }
     590             : 
     591        1379 : CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
     592             : {
     593        1379 :     AssertLockHeld(cs_wallet); // mapWallet
     594        1379 :     CWalletDB walletdb(strWalletFile);
     595             : 
     596             :     // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
     597             :     TxItems txOrdered;
     598             : 
     599             :     // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
     600             :     // would make this much faster for applications that do this a lot.
     601      174446 :     for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
     602             :     {
     603       84465 :         CWalletTx* wtx = &((*it).second);
     604      168930 :         txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
     605             :     }
     606             :     acentries.clear();
     607        1379 :     walletdb.ListAccountCreditDebit(strAccount, acentries);
     608        8274 :     BOOST_FOREACH(CAccountingEntry& entry, acentries)
     609             :     {
     610           0 :         txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
     611             :     }
     612             : 
     613        1379 :     return txOrdered;
     614             : }
     615             : 
     616           7 : void CWallet::MarkDirty()
     617             : {
     618             :     {
     619           7 :         LOCK(cs_wallet);
     620        1092 :         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
     621         175 :             item.second.MarkDirty();
     622             :     }
     623           7 : }
     624             : 
     625        6856 : bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb)
     626             : {
     627        6856 :     uint256 hash = wtxIn.GetHash();
     628             : 
     629        6856 :     if (fFromLoadWallet)
     630             :     {
     631        2738 :         mapWallet[hash] = wtxIn;
     632        2738 :         mapWallet[hash].BindWallet(this);
     633        2738 :         AddToSpends(hash);
     634             :     }
     635             :     else
     636             :     {
     637        4118 :         LOCK(cs_wallet);
     638             :         // Inserts only if not already there, returns tx inserted or tx found
     639       20590 :         pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
     640        4118 :         CWalletTx& wtx = (*ret.first).second;
     641             :         wtx.BindWallet(this);
     642        4118 :         bool fInsertedNew = ret.second;
     643        4118 :         if (fInsertedNew)
     644             :         {
     645        1622 :             wtx.nTimeReceived = GetAdjustedTime();
     646        1622 :             wtx.nOrderPos = IncOrderPosNext(pwalletdb);
     647             : 
     648        1622 :             wtx.nTimeSmart = wtx.nTimeReceived;
     649        3244 :             if (!wtxIn.hashBlock.IsNull())
     650             :             {
     651        2718 :                 if (mapBlockIndex.count(wtxIn.hashBlock))
     652             :                 {
     653        1359 :                     int64_t latestNow = wtx.nTimeReceived;
     654        1359 :                     int64_t latestEntry = 0;
     655             :                     {
     656             :                         // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
     657        1359 :                         int64_t latestTolerated = latestNow + 300;
     658             :                         std::list<CAccountingEntry> acentries;
     659        4077 :                         TxItems txOrdered = OrderedTxItems(acentries);
     660        2718 :                         for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
     661             :                         {
     662        2692 :                             CWalletTx *const pwtx = (*it).second.first;
     663        2692 :                             if (pwtx == &wtx)
     664             :                                 continue;
     665        1333 :                             CAccountingEntry *const pacentry = (*it).second.second;
     666             :                             int64_t nSmartTime;
     667        1333 :                             if (pwtx)
     668             :                             {
     669        1333 :                                 nSmartTime = pwtx->nTimeSmart;
     670        1333 :                                 if (!nSmartTime)
     671           0 :                                     nSmartTime = pwtx->nTimeReceived;
     672             :                             }
     673             :                             else
     674           0 :                                 nSmartTime = pacentry->nTime;
     675        1333 :                             if (nSmartTime <= latestTolerated)
     676             :                             {
     677        1333 :                                 latestEntry = nSmartTime;
     678        1333 :                                 if (nSmartTime > latestNow)
     679           0 :                                     latestNow = nSmartTime;
     680             :                                 break;
     681             :                             }
     682             :                         }
     683             :                     }
     684             : 
     685        4077 :                     int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
     686        2718 :                     wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
     687             :                 }
     688             :                 else
     689           0 :                     LogPrintf("AddToWallet(): found %s in block %s not in index\n",
     690             :                              wtxIn.GetHash().ToString(),
     691           0 :                              wtxIn.hashBlock.ToString());
     692             :             }
     693        1622 :             AddToSpends(hash);
     694             :         }
     695             : 
     696        4118 :         bool fUpdated = false;
     697        4118 :         if (!fInsertedNew)
     698             :         {
     699             :             // Merge
     700        4810 :             if (!wtxIn.hashBlock.IsNull() && wtxIn.hashBlock != wtx.hashBlock)
     701             :             {
     702         258 :                 wtx.hashBlock = wtxIn.hashBlock;
     703         258 :                 fUpdated = true;
     704             :             }
     705        2496 :             if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex))
     706             :             {
     707         254 :                 wtx.nIndex = wtxIn.nIndex;
     708         254 :                 fUpdated = true;
     709             :             }
     710        2496 :             if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
     711             :             {
     712           0 :                 wtx.fFromMe = wtxIn.fFromMe;
     713           0 :                 fUpdated = true;
     714             :             }
     715             :         }
     716             : 
     717             :         //// debug print
     718        8236 :         LogPrintf("AddToWallet %s  %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
     719             : 
     720             :         // Write to disk
     721        4118 :         if (fInsertedNew || fUpdated)
     722        1880 :             if (!wtx.WriteToDisk(pwalletdb))
     723           0 :                 return false;
     724             : 
     725             :         // Break debit/credit balance caches:
     726             :         wtx.MarkDirty();
     727             : 
     728             :         // Notify UI of new or updated transaction
     729        4118 :         NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
     730             : 
     731             :         // notify an external script when a wallet transaction comes in or is updated
     732       20590 :         std::string strCmd = GetArg("-walletnotify", "");
     733             : 
     734        4118 :         if ( !strCmd.empty())
     735             :         {
     736           0 :             boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
     737           0 :             boost::thread t(runCommand, strCmd); // thread runs free
     738             :         }
     739             : 
     740             :     }
     741             :     return true;
     742             : }
     743             : 
     744             : /**
     745             :  * Add a transaction to the wallet, or update it.
     746             :  * pblock is optional, but should be provided if the transaction is known to be in a block.
     747             :  * If fUpdate is true, existing transactions will be updated.
     748             :  */
     749       15139 : bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
     750             : {
     751             :     {
     752       15139 :         AssertLockHeld(cs_wallet);
     753       30278 :         bool fExisted = mapWallet.count(tx.GetHash()) != 0;
     754       15139 :         if (fExisted && !fUpdate) return false;
     755       26296 :         if (fExisted || IsMine(tx) || IsFromMe(tx))
     756             :         {
     757        3991 :             CWalletTx wtx(this,tx);
     758             : 
     759             :             // Get merkle branch if transaction was found in a block
     760        3991 :             if (pblock)
     761        3673 :                 wtx.SetMerkleBranch(*pblock);
     762             : 
     763             :             // Do not flush the wallet here for performance reasons
     764             :             // this is safe, as in case of a crash, we rescan the necessary blocks on startup through our SetBestChain-mechanism
     765        3991 :             CWalletDB walletdb(strWalletFile, "r+", false);
     766             : 
     767        7982 :             return AddToWallet(wtx, false, &walletdb);
     768             :         }
     769             :     }
     770             :     return false;
     771             : }
     772             : 
     773        6697 : void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
     774             : {
     775        6697 :     LOCK2(cs_main, cs_wallet);
     776        6697 :     if (!AddToWalletIfInvolvingMe(tx, pblock, true))
     777        6697 :         return; // Not one of ours
     778             : 
     779             :     // If a transaction changes 'conflicted' state, that changes the balance
     780             :     // available of the outputs it spends. So force those to be
     781             :     // recomputed, also:
     782       22819 :     BOOST_FOREACH(const CTxIn& txin, tx.vin)
     783             :     {
     784        4518 :         if (mapWallet.count(txin.prevout.hash))
     785         855 :             mapWallet[txin.prevout.hash].MarkDirty();
     786             :     }
     787             : }
     788             : 
     789             : 
     790           0 : isminetype CWallet::IsMine(const CTxIn &txin) const
     791             : {
     792             :     {
     793           0 :         LOCK(cs_wallet);
     794           0 :         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
     795           0 :         if (mi != mapWallet.end())
     796             :         {
     797           0 :             const CWalletTx& prev = (*mi).second;
     798           0 :             if (txin.prevout.n < prev.vout.size())
     799           0 :                 return IsMine(prev.vout[txin.prevout.n]);
     800             :         }
     801             :     }
     802           0 :     return ISMINE_NO;
     803             : }
     804             : 
     805       13912 : CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
     806             : {
     807             :     {
     808       13912 :         LOCK(cs_wallet);
     809       27824 :         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
     810       27824 :         if (mi != mapWallet.end())
     811             :         {
     812        1125 :             const CWalletTx& prev = (*mi).second;
     813        2250 :             if (txin.prevout.n < prev.vout.size())
     814        3375 :                 if (IsMine(prev.vout[txin.prevout.n]) & filter)
     815         960 :                     return prev.vout[txin.prevout.n].nValue;
     816             :         }
     817             :     }
     818       13432 :     return 0;
     819             : }
     820             : 
     821           0 : isminetype CWallet::IsMine(const CTxOut& txout) const
     822             : {
     823       33687 :     return ::IsMine(*this, txout.scriptPubKey);
     824             : }
     825             : 
     826        1505 : CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
     827             : {
     828        3010 :     if (!MoneyRange(txout.nValue))
     829           0 :         throw std::runtime_error("CWallet::GetCredit(): value out of range");
     830        1505 :     return ((IsMine(txout) & filter) ? txout.nValue : 0);
     831             : }
     832             : 
     833         271 : bool CWallet::IsChange(const CTxOut& txout) const
     834             : {
     835             :     // TODO: fix handling of 'change' outputs. The assumption is that any
     836             :     // payment to a script that is ours, but is not in the address book
     837             :     // is change. That assumption is likely to break when we implement multisignature
     838             :     // wallets that return change back into a multi-signature-protected address;
     839             :     // a better way of identifying which outputs are 'the send' and which are
     840             :     // 'the change' will need to be implemented (maybe extend CWalletTx to remember
     841             :     // which output, if any, was change).
     842         271 :     if (::IsMine(*this, txout.scriptPubKey))
     843             :     {
     844             :         CTxDestination address;
     845         195 :         if (!ExtractDestination(txout.scriptPubKey, address))
     846             :             return true;
     847             : 
     848         195 :         LOCK(cs_wallet);
     849         390 :         if (!mapAddressBook.count(address))
     850         112 :             return true;
     851             :     }
     852             :     return false;
     853             : }
     854             : 
     855           0 : CAmount CWallet::GetChange(const CTxOut& txout) const
     856             : {
     857           0 :     if (!MoneyRange(txout.nValue))
     858           0 :         throw std::runtime_error("CWallet::GetChange(): value out of range");
     859           0 :     return (IsChange(txout) ? txout.nValue : 0);
     860             : }
     861             : 
     862       12643 : bool CWallet::IsMine(const CTransaction& tx) const
     863             : {
     864      139769 :     BOOST_FOREACH(const CTxOut& txout, tx.vout)
     865       13502 :         if (IsMine(txout))
     866        1486 :             return true;
     867       11157 :     return false;
     868             : }
     869             : 
     870           0 : bool CWallet::IsFromMe(const CTransaction& tx) const
     871             : {
     872       11157 :     return (GetDebit(tx, ISMINE_ALL) > 0);
     873             : }
     874             : 
     875       12773 : CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
     876             : {
     877       12773 :     CAmount nDebit = 0;
     878      147337 :     BOOST_FOREACH(const CTxIn& txin, tx.vin)
     879             :     {
     880       13912 :         nDebit += GetDebit(txin, filter);
     881       27824 :         if (!MoneyRange(nDebit))
     882           0 :             throw std::runtime_error("CWallet::GetDebit(): value out of range");
     883             :     }
     884       12773 :     return nDebit;
     885             : }
     886             : 
     887          46 : CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
     888             : {
     889          46 :     CAmount nCredit = 0;
     890         668 :     BOOST_FOREACH(const CTxOut& txout, tx.vout)
     891             :     {
     892          73 :         nCredit += GetCredit(txout, filter);
     893         146 :         if (!MoneyRange(nCredit))
     894           0 :             throw std::runtime_error("CWallet::GetCredit(): value out of range");
     895             :     }
     896          46 :     return nCredit;
     897             : }
     898             : 
     899           0 : CAmount CWallet::GetChange(const CTransaction& tx) const
     900             : {
     901           0 :     CAmount nChange = 0;
     902           0 :     BOOST_FOREACH(const CTxOut& txout, tx.vout)
     903             :     {
     904           0 :         nChange += GetChange(txout);
     905           0 :         if (!MoneyRange(nChange))
     906           0 :             throw std::runtime_error("CWallet::GetChange(): value out of range");
     907             :     }
     908           0 :     return nChange;
     909             : }
     910             : 
     911         185 : int64_t CWalletTx::GetTxTime() const
     912             : {
     913         185 :     int64_t n = nTimeSmart;
     914         185 :     return n ? n : nTimeReceived;
     915             : }
     916             : 
     917           0 : int CWalletTx::GetRequestCount() const
     918             : {
     919             :     // Returns -1 if it wasn't being tracked
     920           0 :     int nRequests = -1;
     921             :     {
     922           0 :         LOCK(pwallet->cs_wallet);
     923           0 :         if (IsCoinBase())
     924             :         {
     925             :             // Generated block
     926           0 :             if (!hashBlock.IsNull())
     927             :             {
     928           0 :                 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
     929           0 :                 if (mi != pwallet->mapRequestCount.end())
     930           0 :                     nRequests = (*mi).second;
     931             :             }
     932             :         }
     933             :         else
     934             :         {
     935             :             // Did anyone request this transaction?
     936           0 :             map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
     937           0 :             if (mi != pwallet->mapRequestCount.end())
     938             :             {
     939           0 :                 nRequests = (*mi).second;
     940             : 
     941             :                 // How about the block it's in?
     942           0 :                 if (nRequests == 0 && !hashBlock.IsNull())
     943             :                 {
     944           0 :                     map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
     945           0 :                     if (mi != pwallet->mapRequestCount.end())
     946           0 :                         nRequests = (*mi).second;
     947             :                     else
     948             :                         nRequests = 1; // If it's in someone else's block it must have got out
     949             :                 }
     950             :             }
     951             :         }
     952             :     }
     953           0 :     return nRequests;
     954             : }
     955             : 
     956        1064 : void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
     957             :                            list<COutputEntry>& listSent, CAmount& nFee, string& strSentAccount, const isminefilter& filter) const
     958             : {
     959        1064 :     nFee = 0;
     960             :     listReceived.clear();
     961             :     listSent.clear();
     962        1064 :     strSentAccount = strFromAccount;
     963             : 
     964             :     // Compute fee:
     965        1064 :     CAmount nDebit = GetDebit(filter);
     966        1064 :     if (nDebit > 0) // debit>0 means we signed/sent this transaction
     967             :     {
     968         137 :         CAmount nValueOut = GetValueOut();
     969         137 :         nFee = nDebit - nValueOut;
     970             :     }
     971             : 
     972             :     // Sent/received.
     973        3596 :     for (unsigned int i = 0; i < vout.size(); ++i)
     974             :     {
     975        2532 :         const CTxOut& txout = vout[i];
     976        2532 :         isminetype fIsMine = pwallet->IsMine(txout);
     977             :         // Only need to handle txouts if AT LEAST one of these is true:
     978             :         //   1) they debit from us (sent)
     979             :         //   2) the output is to us (received)
     980        1266 :         if (nDebit > 0)
     981             :         {
     982             :             // Don't report 'change' txouts
     983         271 :             if (pwallet->IsChange(txout))
     984         172 :                 continue;
     985             :         }
     986         995 :         else if (!(fIsMine & filter))
     987             :             continue;
     988             : 
     989             :         // In either case, we need to get the destination address
     990             :         CTxDestination address;
     991        1094 :         if (!ExtractDestination(txout.scriptPubKey, address))
     992             :         {
     993           0 :             LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
     994           0 :                      this->GetHash().ToString());
     995           0 :             address = CNoDestination();
     996             :         }
     997             : 
     998        1094 :         COutputEntry output = {address, txout.nValue, (int)i};
     999             : 
    1000             :         // If we are debited by the transaction, add the output as a "sent" entry
    1001        1094 :         if (nDebit > 0)
    1002             :             listSent.push_back(output);
    1003             : 
    1004             :         // If we are receiving the output, add it as a "received" entry
    1005        1094 :         if (fIsMine & filter)
    1006             :             listReceived.push_back(output);
    1007             :     }
    1008             : 
    1009        1064 : }
    1010             : 
    1011         745 : void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
    1012             :                                   CAmount& nSent, CAmount& nFee, const isminefilter& filter) const
    1013             : {
    1014         745 :     nReceived = nSent = nFee = 0;
    1015             : 
    1016             :     CAmount allFee;
    1017             :     string strSentAccount;
    1018             :     list<COutputEntry> listReceived;
    1019             :     list<COutputEntry> listSent;
    1020         745 :     GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
    1021             : 
    1022         745 :     if (strAccount == strSentAccount)
    1023             :     {
    1024        1953 :         BOOST_FOREACH(const COutputEntry& s, listSent)
    1025          27 :             nSent += s.amount;
    1026         303 :         nFee = allFee;
    1027             :     }
    1028             :     {
    1029         745 :         LOCK(pwallet->cs_wallet);
    1030        8802 :         BOOST_FOREACH(const COutputEntry& r, listReceived)
    1031             :         {
    1032        1444 :             if (pwallet->mapAddressBook.count(r.destination))
    1033             :             {
    1034         172 :                 map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.destination);
    1035         258 :                 if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
    1036          56 :                     nReceived += r.amount;
    1037             :             }
    1038         636 :             else if (strAccount.empty())
    1039             :             {
    1040         251 :                 nReceived += r.amount;
    1041             :             }
    1042             :         }
    1043             :     }
    1044         745 : }
    1045             : 
    1046             : 
    1047           4 : bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb)
    1048             : {
    1049        3768 :     return pwalletdb->WriteTx(GetHash(), *this);
    1050             : }
    1051             : 
    1052             : /**
    1053             :  * Scan the block chain (starting in pindexStart) for transactions
    1054             :  * from or to us. If fUpdate is true, found transactions that already
    1055             :  * exist in the wallet will be updated.
    1056             :  */
    1057          54 : int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
    1058             : {
    1059          54 :     int ret = 0;
    1060          54 :     int64_t nNow = GetTime();
    1061          54 :     const CChainParams& chainParams = Params();
    1062             : 
    1063          54 :     CBlockIndex* pindex = pindexStart;
    1064             :     {
    1065          54 :         LOCK2(cs_main, cs_wallet);
    1066             : 
    1067             :         // no need to read and scan block, if block was created before
    1068             :         // our wallet birthday (as adjusted for block time variability)
    1069        1820 :         while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
    1070         856 :             pindex = chainActive.Next(pindex);
    1071             : 
    1072         108 :         ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
    1073          54 :         double dProgressStart = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false);
    1074          54 :         double dProgressTip = Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), chainActive.Tip(), false);
    1075        8243 :         while (pindex)
    1076             :         {
    1077        8189 :             if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
    1078           0 :                 ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
    1079             : 
    1080        8189 :             CBlock block;
    1081        8189 :             ReadBlockFromDisk(block, pindex);
    1082       99786 :             BOOST_FOREACH(CTransaction& tx, block.vtx)
    1083             :             {
    1084        8442 :                 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
    1085        2138 :                     ret++;
    1086             :             }
    1087        8189 :             pindex = chainActive.Next(pindex);
    1088        8189 :             if (GetTime() >= nNow + 60) {
    1089           0 :                 nNow = GetTime();
    1090           0 :                 LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
    1091             :             }
    1092             :         }
    1093         108 :         ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
    1094             :     }
    1095          54 :     return ret;
    1096             : }
    1097             : 
    1098          95 : void CWallet::ReacceptWalletTransactions()
    1099             : {
    1100             :     // If transactions aren't being broadcasted, don't let them into local mempool either
    1101          95 :     if (!fBroadcastTransactions)
    1102           3 :         return;
    1103          92 :     LOCK2(cs_main, cs_wallet);
    1104             :     std::map<int64_t, CWalletTx*> mapSorted;
    1105             : 
    1106             :     // Sort pending wallet transactions based on their initial wallet insertion order
    1107       15738 :     BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
    1108             :     {
    1109        2531 :         const uint256& wtxid = item.first;
    1110        2531 :         CWalletTx& wtx = item.second;
    1111        5062 :         assert(wtx.GetHash() == wtxid);
    1112             : 
    1113        5062 :         int nDepth = wtx.GetDepthInMainChain();
    1114             : 
    1115        2531 :         if (!wtx.IsCoinBase() && nDepth < 0) {
    1116          28 :             mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
    1117             :         }
    1118             :     }
    1119             : 
    1120             :     // Try to add wallet transactions to memory pool
    1121         622 :     BOOST_FOREACH(PAIRTYPE(const int64_t, CWalletTx*)& item, mapSorted)
    1122             :     {
    1123          14 :         CWalletTx& wtx = *(item.second);
    1124             : 
    1125          14 :         LOCK(mempool.cs);
    1126          14 :         wtx.AcceptToMemoryPool(false);
    1127             :     }
    1128             : }
    1129             : 
    1130        4172 : bool CWalletTx::RelayWalletTransaction()
    1131             : {
    1132        4172 :     assert(pwallet->GetBroadcastTransactions());
    1133        4172 :     if (!IsCoinBase())
    1134             :     {
    1135         264 :         if (GetDepthInMainChain() == 0) {
    1136         248 :             LogPrintf("Relaying wtx %s\n", GetHash().ToString());
    1137         248 :             RelayTransaction((CTransaction)*this);
    1138         124 :             return true;
    1139             :         }
    1140             :     }
    1141             :     return false;
    1142             : }
    1143             : 
    1144         185 : set<uint256> CWalletTx::GetConflicts() const
    1145             : {
    1146             :     set<uint256> result;
    1147         185 :     if (pwallet != NULL)
    1148             :     {
    1149         185 :         uint256 myHash = GetHash();
    1150         370 :         result = pwallet->GetConflicts(myHash);
    1151             :         result.erase(myHash);
    1152             :     }
    1153         185 :     return result;
    1154             : }
    1155             : 
    1156      149700 : CAmount CWalletTx::GetDebit(const isminefilter& filter) const
    1157             : {
    1158      299400 :     if (vin.empty())
    1159             :         return 0;
    1160             : 
    1161        8900 :     CAmount debit = 0;
    1162        8900 :     if(filter & ISMINE_SPENDABLE)
    1163             :     {
    1164        8642 :         if (fDebitCached)
    1165        7778 :             debit += nDebitCached;
    1166             :         else
    1167             :         {
    1168         864 :             nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
    1169         864 :             fDebitCached = true;
    1170         864 :             debit += nDebitCached;
    1171             :         }
    1172             :     }
    1173        8900 :     if(filter & ISMINE_WATCH_ONLY)
    1174             :     {
    1175        7763 :         if(fWatchDebitCached)
    1176        7011 :             debit += nWatchDebitCached;
    1177             :         else
    1178             :         {
    1179         752 :             nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
    1180         752 :             fWatchDebitCached = true;
    1181         752 :             debit += nWatchDebitCached;
    1182             :         }
    1183             :     }
    1184        8900 :     return debit;
    1185             : }
    1186             : 
    1187          44 : CAmount CWalletTx::GetCredit(const isminefilter& filter) const
    1188             : {
    1189             :     // Must wait until coinbase is safely deep enough in the chain before valuing it
    1190          44 :     if (IsCoinBase() && GetBlocksToMaturity() > 0)
    1191             :         return 0;
    1192             : 
    1193          44 :     int64_t credit = 0;
    1194          44 :     if (filter & ISMINE_SPENDABLE)
    1195             :     {
    1196             :         // GetBalance can assume transactions in mapWallet won't change
    1197          44 :         if (fCreditCached)
    1198           0 :             credit += nCreditCached;
    1199             :         else
    1200             :         {
    1201          44 :             nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
    1202          44 :             fCreditCached = true;
    1203          44 :             credit += nCreditCached;
    1204             :         }
    1205             :     }
    1206          44 :     if (filter & ISMINE_WATCH_ONLY)
    1207             :     {
    1208           1 :         if (fWatchCreditCached)
    1209           0 :             credit += nWatchCreditCached;
    1210             :         else
    1211             :         {
    1212           1 :             nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
    1213           1 :             fWatchCreditCached = true;
    1214           1 :             credit += nWatchCreditCached;
    1215             :         }
    1216             :     }
    1217          44 :     return credit;
    1218             : }
    1219             : 
    1220           4 : CAmount CWalletTx::GetImmatureCredit(bool fUseCache) const
    1221             : {
    1222           5 :     if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
    1223             :     {
    1224           1 :         if (fUseCache && fImmatureCreditCached)
    1225           0 :             return nImmatureCreditCached;
    1226           1 :         nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
    1227           1 :         fImmatureCreditCached = true;
    1228           1 :         return nImmatureCreditCached;
    1229             :     }
    1230             : 
    1231             :     return 0;
    1232             : }
    1233             : 
    1234       11684 : CAmount CWalletTx::GetAvailableCredit(bool fUseCache) const
    1235             : {
    1236       11684 :     if (pwallet == 0)
    1237             :         return 0;
    1238             : 
    1239             :     // Must wait until coinbase is safely deep enough in the chain before valuing it
    1240       11684 :     if (IsCoinBase() && GetBlocksToMaturity() > 0)
    1241             :         return 0;
    1242             : 
    1243        4701 :     if (fUseCache && fAvailableCreditCached)
    1244        3234 :         return nAvailableCreditCached;
    1245             : 
    1246        1467 :     CAmount nCredit = 0;
    1247        1467 :     uint256 hashTx = GetHash();
    1248        7186 :     for (unsigned int i = 0; i < vout.size(); i++)
    1249             :     {
    1250        2126 :         if (!pwallet->IsSpent(hashTx, i))
    1251             :         {
    1252        2864 :             const CTxOut &txout = vout[i];
    1253        1432 :             nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
    1254        2864 :             if (!MoneyRange(nCredit))
    1255           0 :                 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
    1256             :         }
    1257             :     }
    1258             : 
    1259        1467 :     nAvailableCreditCached = nCredit;
    1260        1467 :     fAvailableCreditCached = true;
    1261        1467 :     return nCredit;
    1262             : }
    1263             : 
    1264           0 : CAmount CWalletTx::GetImmatureWatchOnlyCredit(const bool& fUseCache) const
    1265             : {
    1266           0 :     if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
    1267             :     {
    1268           0 :         if (fUseCache && fImmatureWatchCreditCached)
    1269           0 :             return nImmatureWatchCreditCached;
    1270           0 :         nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
    1271           0 :         fImmatureWatchCreditCached = true;
    1272           0 :         return nImmatureWatchCreditCached;
    1273             :     }
    1274             : 
    1275             :     return 0;
    1276             : }
    1277             : 
    1278           0 : CAmount CWalletTx::GetAvailableWatchOnlyCredit(const bool& fUseCache) const
    1279             : {
    1280           0 :     if (pwallet == 0)
    1281             :         return 0;
    1282             : 
    1283             :     // Must wait until coinbase is safely deep enough in the chain before valuing it
    1284           0 :     if (IsCoinBase() && GetBlocksToMaturity() > 0)
    1285             :         return 0;
    1286             : 
    1287           0 :     if (fUseCache && fAvailableWatchCreditCached)
    1288           0 :         return nAvailableWatchCreditCached;
    1289             : 
    1290             :     CAmount nCredit = 0;
    1291           0 :     for (unsigned int i = 0; i < vout.size(); i++)
    1292             :     {
    1293           0 :         if (!pwallet->IsSpent(GetHash(), i))
    1294             :         {
    1295           0 :             const CTxOut &txout = vout[i];
    1296           0 :             nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
    1297           0 :             if (!MoneyRange(nCredit))
    1298           0 :                 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
    1299             :         }
    1300             :     }
    1301             : 
    1302           0 :     nAvailableWatchCreditCached = nCredit;
    1303           0 :     fAvailableWatchCreditCached = true;
    1304           0 :     return nCredit;
    1305             : }
    1306             : 
    1307           0 : CAmount CWalletTx::GetChange() const
    1308             : {
    1309           0 :     if (fChangeCached)
    1310           0 :         return nChangeCached;
    1311           0 :     nChangeCached = pwallet->GetChange(*this);
    1312           0 :     fChangeCached = true;
    1313           0 :     return nChangeCached;
    1314             : }
    1315             : 
    1316       34768 : bool CWalletTx::IsTrusted() const
    1317             : {
    1318             :     // Quick answer in most cases
    1319       34768 :     if (!CheckFinalTx(*this))
    1320             :         return false;
    1321       69536 :     int nDepth = GetDepthInMainChain();
    1322       34768 :     if (nDepth >= 1)
    1323             :         return true;
    1324        1507 :     if (nDepth < 0)
    1325             :         return false;
    1326        3006 :     if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
    1327             :         return false;
    1328             : 
    1329             :     // Trusted if all inputs are from us and are in the mempool:
    1330       19913 :     BOOST_FOREACH(const CTxIn& txin, vin)
    1331             :     {
    1332             :         // Transactions not sent by us: not trusted
    1333        2093 :         const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
    1334        2093 :         if (parent == NULL)
    1335           0 :             return false;
    1336        4186 :         const CTxOut& parentOut = parent->vout[txin.prevout.n];
    1337        4186 :         if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
    1338             :             return false;
    1339             :     }
    1340        1471 :     return true;
    1341             : }
    1342             : 
    1343           6 : bool CWalletTx::IsEquivalentTo(const CWalletTx& tx) const
    1344             : {
    1345           6 :         CMutableTransaction tx1 = *this;
    1346           6 :         CMutableTransaction tx2 = tx;
    1347          30 :         for (unsigned int i = 0; i < tx1.vin.size(); i++) tx1.vin[i].scriptSig = CScript();
    1348          46 :         for (unsigned int i = 0; i < tx2.vin.size(); i++) tx2.vin[i].scriptSig = CScript();
    1349          30 :         return CTransaction(tx1) == CTransaction(tx2);
    1350             : }
    1351             : 
    1352         169 : std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime)
    1353             : {
    1354             :     std::vector<uint256> result;
    1355             : 
    1356         169 :     LOCK(cs_wallet);
    1357             :     // Sort them in chronological order
    1358             :     multimap<unsigned int, CWalletTx*> mapSorted;
    1359       25614 :     BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
    1360             :     {
    1361        4100 :         CWalletTx& wtx = item.second;
    1362             :         // Don't rebroadcast if newer than nTime:
    1363        4100 :         if (wtx.nTimeReceived > nTime)
    1364             :             continue;
    1365        8100 :         mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
    1366             :     }
    1367       25314 :     BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
    1368             :     {
    1369        4050 :         CWalletTx& wtx = *item.second;
    1370        4050 :         if (wtx.RelayWalletTransaction())
    1371           4 :             result.push_back(wtx.GetHash());
    1372             :     }
    1373         169 :     return result;
    1374             : }
    1375             : 
    1376       55094 : void CWallet::ResendWalletTransactions(int64_t nBestBlockTime)
    1377             : {
    1378             :     // Do this infrequently and randomly to avoid giving away
    1379             :     // that these are our transactions.
    1380       55094 :     if (GetTime() < nNextResend || !fBroadcastTransactions)
    1381       54926 :         return;
    1382         287 :     bool fFirst = (nNextResend == 0);
    1383         287 :     nNextResend = GetTime() + GetRand(30 * 60);
    1384         287 :     if (fFirst)
    1385             :         return;
    1386             : 
    1387             :     // Only do it if there's been a new block since last time
    1388         221 :     if (nBestBlockTime < nLastResend)
    1389             :         return;
    1390         168 :     nLastResend = GetTime();
    1391             : 
    1392             :     // Rebroadcast unconfirmed txes older than 5 minutes before the last
    1393             :     // block was found:
    1394         168 :     std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60);
    1395         168 :     if (!relayed.empty())
    1396           0 :         LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
    1397             : }
    1398             : 
    1399             : /** @} */ // end of mapWallet
    1400             : 
    1401             : 
    1402             : 
    1403             : 
    1404             : /** @defgroup Actions
    1405             :  *
    1406             :  * @{
    1407             :  */
    1408             : 
    1409             : 
    1410         192 : CAmount CWallet::GetBalance() const
    1411             : {
    1412         192 :     CAmount nTotal = 0;
    1413             :     {
    1414         192 :         LOCK2(cs_main, cs_wallet);
    1415       24162 :         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
    1416             :         {
    1417       11697 :             const CWalletTx* pcoin = &(*it).second;
    1418       11697 :             if (pcoin->IsTrusted())
    1419       11684 :                 nTotal += pcoin->GetAvailableCredit();
    1420             :         }
    1421             :     }
    1422             : 
    1423         192 :     return nTotal;
    1424             : }
    1425             : 
    1426           2 : CAmount CWallet::GetUnconfirmedBalance() const
    1427             : {
    1428           2 :     CAmount nTotal = 0;
    1429             :     {
    1430           2 :         LOCK2(cs_main, cs_wallet);
    1431          16 :         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
    1432             :         {
    1433           4 :             const CWalletTx* pcoin = &(*it).second;
    1434           4 :             if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
    1435           0 :                 nTotal += pcoin->GetAvailableCredit();
    1436             :         }
    1437             :     }
    1438           2 :     return nTotal;
    1439             : }
    1440             : 
    1441           2 : CAmount CWallet::GetImmatureBalance() const
    1442             : {
    1443           2 :     CAmount nTotal = 0;
    1444             :     {
    1445           2 :         LOCK2(cs_main, cs_wallet);
    1446          16 :         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
    1447             :         {
    1448           4 :             const CWalletTx* pcoin = &(*it).second;
    1449           4 :             nTotal += pcoin->GetImmatureCredit();
    1450             :         }
    1451             :     }
    1452           2 :     return nTotal;
    1453             : }
    1454             : 
    1455           0 : CAmount CWallet::GetWatchOnlyBalance() const
    1456             : {
    1457           0 :     CAmount nTotal = 0;
    1458             :     {
    1459           0 :         LOCK2(cs_main, cs_wallet);
    1460           0 :         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
    1461             :         {
    1462           0 :             const CWalletTx* pcoin = &(*it).second;
    1463           0 :             if (pcoin->IsTrusted())
    1464           0 :                 nTotal += pcoin->GetAvailableWatchOnlyCredit();
    1465             :         }
    1466             :     }
    1467             : 
    1468           0 :     return nTotal;
    1469             : }
    1470             : 
    1471           0 : CAmount CWallet::GetUnconfirmedWatchOnlyBalance() const
    1472             : {
    1473           0 :     CAmount nTotal = 0;
    1474             :     {
    1475           0 :         LOCK2(cs_main, cs_wallet);
    1476           0 :         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
    1477             :         {
    1478           0 :             const CWalletTx* pcoin = &(*it).second;
    1479           0 :             if (!CheckFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
    1480           0 :                 nTotal += pcoin->GetAvailableWatchOnlyCredit();
    1481             :         }
    1482             :     }
    1483           0 :     return nTotal;
    1484             : }
    1485             : 
    1486           0 : CAmount CWallet::GetImmatureWatchOnlyBalance() const
    1487             : {
    1488           0 :     CAmount nTotal = 0;
    1489             :     {
    1490           0 :         LOCK2(cs_main, cs_wallet);
    1491           0 :         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
    1492             :         {
    1493           0 :             const CWalletTx* pcoin = &(*it).second;
    1494           0 :             nTotal += pcoin->GetImmatureWatchOnlyCredit();
    1495             :         }
    1496             :     }
    1497           0 :     return nTotal;
    1498             : }
    1499             : 
    1500             : /**
    1501             :  * populate vCoins with vector of available COutputs.
    1502             :  */
    1503         349 : void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl, bool fIncludeZeroValue) const
    1504             : {
    1505             :     vCoins.clear();
    1506             : 
    1507             :     {
    1508         349 :         LOCK2(cs_main, cs_wallet);
    1509       48234 :         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
    1510             :         {
    1511       23419 :             const uint256& wtxid = it->first;
    1512       23419 :             const CWalletTx* pcoin = &(*it).second;
    1513             : 
    1514       23419 :             if (!CheckFinalTx(*pcoin))
    1515             :                 continue;
    1516             : 
    1517       23419 :             if (fOnlyConfirmed && !pcoin->IsTrusted())
    1518             :                 continue;
    1519             : 
    1520       23396 :             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
    1521             :                 continue;
    1522             : 
    1523       18148 :             int nDepth = pcoin->GetDepthInMainChain();
    1524        9074 :             if (nDepth < 0)
    1525             :                 continue;
    1526             : 
    1527       37466 :             for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
    1528       42588 :                 isminetype mine = IsMine(pcoin->vout[i]);
    1529       40799 :                 if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
    1530       28773 :                     !IsLockedCoin((*it).first, i) && (pcoin->vout[i].nValue > 0 || fIncludeZeroValue) &&
    1531         417 :                     (!coinControl || !coinControl->HasSelected() || coinControl->fAllowOtherInputs || coinControl->IsSelected((*it).first, i)))
    1532             :                         vCoins.push_back(COutput(pcoin, i, nDepth,
    1533        4847 :                                                  ((mine & ISMINE_SPENDABLE) != ISMINE_NO) ||
    1534        4852 :                                                   (coinControl && coinControl->fAllowWatchOnly && (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO)));
    1535             :             }
    1536             :         }
    1537             :     }
    1538         349 : }
    1539             : 
    1540        2271 : static void ApproximateBestSubset(vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > >vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
    1541             :                                   vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
    1542             : {
    1543             :     vector<char> vfIncluded;
    1544             : 
    1545        6813 :     vfBest.assign(vValue.size(), true);
    1546        2271 :     nBest = nTotalLower;
    1547             : 
    1548        2271 :     seed_insecure_rand();
    1549             : 
    1550     1268015 :     for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
    1551             :     {
    1552     3804045 :         vfIncluded.assign(vValue.size(), false);
    1553     1268015 :         CAmount nTotal = 0;
    1554     1268015 :         bool fReachedTarget = false;
    1555     3443888 :         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
    1556             :         {
    1557    19416107 :             for (unsigned int i = 0; i < vValue.size(); i++)
    1558             :             {
    1559             :                 //The solver here uses a randomized algorithm,
    1560             :                 //the randomness serves no real security purpose but is just
    1561             :                 //needed to prevent degenerate behavior and it is important
    1562             :                 //that the rng is fast. We do not use a constant random sequence,
    1563             :                 //because there may be some privacy improvement by making
    1564             :                 //the selection random.
    1565    12258828 :                 if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
    1566             :                 {
    1567     9332706 :                     nTotal += vValue[i].first;
    1568     9332706 :                     vfIncluded[i] = true;
    1569     4666353 :                     if (nTotal >= nTargetValue)
    1570             :                     {
    1571     1722655 :                         fReachedTarget = true;
    1572     1722655 :                         if (nTotal < nBest)
    1573             :                         {
    1574        3811 :                             nBest = nTotal;
    1575        3811 :                             vfBest = vfIncluded;
    1576             :                         }
    1577     3445310 :                         nTotal -= vValue[i].first;
    1578     3445310 :                         vfIncluded[i] = false;
    1579             :                     }
    1580             :                 }
    1581             :             }
    1582             :         }
    1583             :     }
    1584        2271 : }
    1585             : 
    1586        5545 : bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
    1587             :                                  set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet) const
    1588             : {
    1589             :     setCoinsRet.clear();
    1590        5545 :     nValueRet = 0;
    1591             : 
    1592             :     // List of values less than target
    1593             :     pair<CAmount, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
    1594        5545 :     coinLowestLarger.first = std::numeric_limits<CAmount>::max();
    1595        5545 :     coinLowestLarger.second.first = NULL;
    1596             :     vector<pair<CAmount, pair<const CWalletTx*,unsigned int> > > vValue;
    1597        5545 :     CAmount nTotalLower = 0;
    1598             : 
    1599        5545 :     random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
    1600             : 
    1601      910395 :     BOOST_FOREACH(const COutput &output, vCoins)
    1602             :     {
    1603      146743 :         if (!output.fSpendable)
    1604        2595 :             continue;
    1605             : 
    1606      146743 :         const CWalletTx *pcoin = output.tx;
    1607             : 
    1608      293486 :         if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
    1609             :             continue;
    1610             : 
    1611      144148 :         int i = output.i;
    1612      288296 :         CAmount n = pcoin->vout[i].nValue;
    1613             : 
    1614             :         pair<CAmount,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
    1615             : 
    1616      144148 :         if (n == nTargetValue)
    1617             :         {
    1618             :             setCoinsRet.insert(coin.second);
    1619        1111 :             nValueRet += coin.first;
    1620        1111 :             return true;
    1621             :         }
    1622      143037 :         else if (n < nTargetValue + CENT)
    1623             :         {
    1624       37861 :             vValue.push_back(coin);
    1625       37861 :             nTotalLower += n;
    1626             :         }
    1627      105176 :         else if (n < coinLowestLarger.first)
    1628             :         {
    1629        3322 :             coinLowestLarger = coin;
    1630             :         }
    1631             :     }
    1632             : 
    1633        4434 :     if (nTotalLower == nTargetValue)
    1634             :     {
    1635        4342 :         for (unsigned int i = 0; i < vValue.size(); ++i)
    1636             :         {
    1637        3840 :             setCoinsRet.insert(vValue[i].second);
    1638        3840 :             nValueRet += vValue[i].first;
    1639             :         }
    1640             :         return true;
    1641             :     }
    1642             : 
    1643        3932 :     if (nTotalLower < nTargetValue)
    1644             :     {
    1645        2290 :         if (coinLowestLarger.second.first == NULL)
    1646             :             return false;
    1647             :         setCoinsRet.insert(coinLowestLarger.second);
    1648        1573 :         nValueRet += coinLowestLarger.first;
    1649        1573 :         return true;
    1650             :     }
    1651             : 
    1652             :     // Solve subset sum by stochastic approximation
    1653        3284 :     sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
    1654             :     vector<char> vfBest;
    1655             :     CAmount nBest;
    1656             : 
    1657        3284 :     ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
    1658        1642 :     if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
    1659        1258 :         ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
    1660             : 
    1661             :     // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
    1662             :     //                                   or the next bigger coin is closer), return the bigger coin
    1663        2558 :     if (coinLowestLarger.second.first &&
    1664        1331 :         ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
    1665             :     {
    1666             :         setCoinsRet.insert(coinLowestLarger.second);
    1667         306 :         nValueRet += coinLowestLarger.first;
    1668             :     }
    1669             :     else {
    1670       54764 :         for (unsigned int i = 0; i < vValue.size(); i++)
    1671       53428 :             if (vfBest[i])
    1672             :             {
    1673       28094 :                 setCoinsRet.insert(vValue[i].second);
    1674       28094 :                 nValueRet += vValue[i].first;
    1675             :             }
    1676             : 
    1677        1336 :         LogPrint("selectcoins", "SelectCoins() best subset: ");
    1678       54764 :         for (unsigned int i = 0; i < vValue.size(); i++)
    1679       53428 :             if (vfBest[i])
    1680       42141 :                 LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first));
    1681        2672 :         LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
    1682             :     }
    1683             : 
    1684        1642 :     return true;
    1685             : }
    1686             : 
    1687         336 : bool CWallet::SelectCoins(const CAmount& nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const
    1688             : {
    1689             :     vector<COutput> vCoins;
    1690         336 :     AvailableCoins(vCoins, true, coinControl);
    1691             : 
    1692             :     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
    1693         384 :     if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
    1694             :     {
    1695           0 :         BOOST_FOREACH(const COutput& out, vCoins)
    1696             :         {
    1697           0 :             if (!out.fSpendable)
    1698             :                  continue;
    1699           0 :             nValueRet += out.tx->vout[out.i].nValue;
    1700           0 :             setCoinsRet.insert(make_pair(out.tx, out.i));
    1701             :         }
    1702           0 :         return (nValueRet >= nTargetValue);
    1703             :     }
    1704             : 
    1705             :     // calculate value from preset inputs and store them
    1706             :     set<pair<const CWalletTx*, uint32_t> > setPresetCoins;
    1707         336 :     CAmount nValueFromPresetInputs = 0;
    1708             : 
    1709             :     std::vector<COutPoint> vPresetInputs;
    1710         336 :     if (coinControl)
    1711             :         coinControl->ListSelected(vPresetInputs);
    1712        2098 :     BOOST_FOREACH(const COutPoint& outpoint, vPresetInputs)
    1713             :     {
    1714          34 :         map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
    1715          34 :         if (it != mapWallet.end())
    1716             :         {
    1717          16 :             const CWalletTx* pcoin = &it->second;
    1718             :             // Clearly invalid input, fail
    1719          32 :             if (pcoin->vout.size() <= outpoint.n)
    1720             :                 return false;
    1721          32 :             nValueFromPresetInputs += pcoin->vout[outpoint.n].nValue;
    1722          32 :             setPresetCoins.insert(make_pair(pcoin, outpoint.n));
    1723             :         } else
    1724             :             return false; // TODO: Allow non-wallet inputs
    1725             :     }
    1726             : 
    1727             :     // remove preset inputs from vCoins
    1728        1551 :     for (vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
    1729             :     {
    1730          88 :         if (setPresetCoins.count(make_pair(it->tx, it->i)))
    1731          16 :             it = vCoins.erase(it);
    1732             :         else
    1733             :             ++it;
    1734             :     }
    1735             : 
    1736         664 :     bool res = nTargetValue <= nValueFromPresetInputs ||
    1737        1071 :         SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, vCoins, setCoinsRet, nValueRet) ||
    1738         864 :         SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, vCoins, setCoinsRet, nValueRet) ||
    1739          82 :         (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, vCoins, setCoinsRet, nValueRet));
    1740             : 
    1741             :     // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
    1742             :     setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
    1743             : 
    1744             :     // add preset inputs to the total value selected
    1745         335 :     nValueRet += nValueFromPresetInputs;
    1746             : 
    1747         335 :     return res;
    1748             : }
    1749             : 
    1750          22 : bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount &nFeeRet, int& nChangePosRet, std::string& strFailReason, bool includeWatching)
    1751             : {
    1752             :     vector<CRecipient> vecSend;
    1753             : 
    1754             :     // Turn the txout set into a CRecipient vector
    1755         287 :     BOOST_FOREACH(const CTxOut& txOut, tx.vout)
    1756             :     {
    1757          62 :         CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, false};
    1758          31 :         vecSend.push_back(recipient);
    1759             :     }
    1760             : 
    1761          22 :     CCoinControl coinControl;
    1762          22 :     coinControl.fAllowOtherInputs = true;
    1763          22 :     coinControl.fAllowWatchOnly = includeWatching;
    1764         180 :     BOOST_FOREACH(const CTxIn& txin, tx.vin)
    1765           8 :         coinControl.Select(txin.prevout);
    1766             : 
    1767          22 :     CReserveKey reservekey(this);
    1768          44 :     CWalletTx wtx;
    1769          22 :     if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosRet, strFailReason, &coinControl, false))
    1770             :         return false;
    1771             : 
    1772          20 :     if (nChangePosRet != -1)
    1773          76 :         tx.vout.insert(tx.vout.begin() + nChangePosRet, wtx.vout[nChangePosRet]);
    1774             : 
    1775             :     // Add new txins (keeping original txin scriptSig/order)
    1776         484 :     BOOST_FOREACH(const CTxIn& txin, wtx.vin)
    1777             :     {
    1778          64 :         bool found = false;
    1779        2740 :         BOOST_FOREACH(const CTxIn& origTxIn, tx.vin)
    1780             :         {
    1781         790 :             if (txin.prevout.hash == origTxIn.prevout.hash && txin.prevout.n == origTxIn.prevout.n)
    1782             :             {
    1783             :                 found = true;
    1784             :                 break;
    1785             :             }
    1786             :         }
    1787          64 :         if (!found)
    1788          57 :             tx.vin.push_back(txin);
    1789             :     }
    1790             : 
    1791          42 :     return true;
    1792             : }
    1793             : 
    1794         146 : bool CWallet::CreateTransaction(const vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet,
    1795             :                                 int& nChangePosRet, std::string& strFailReason, const CCoinControl* coinControl, bool sign)
    1796             : {
    1797         146 :     CAmount nValue = 0;
    1798         146 :     unsigned int nSubtractFeeFromAmount = 0;
    1799        1714 :     BOOST_FOREACH (const CRecipient& recipient, vecSend)
    1800             :     {
    1801         164 :         if (nValue < 0 || recipient.nAmount < 0)
    1802             :         {
    1803           0 :             strFailReason = _("Transaction amounts must be positive");
    1804           0 :             return false;
    1805             :         }
    1806         164 :         nValue += recipient.nAmount;
    1807             : 
    1808         164 :         if (recipient.fSubtractFeeFromAmount)
    1809           4 :             nSubtractFeeFromAmount++;
    1810             :     }
    1811         146 :     if (vecSend.empty() || nValue < 0)
    1812             :     {
    1813           0 :         strFailReason = _("Transaction amounts must be positive");
    1814           0 :         return false;
    1815             :     }
    1816             : 
    1817         146 :     wtxNew.fTimeReceivedIsTxTime = true;
    1818             :     wtxNew.BindWallet(this);
    1819         146 :     CMutableTransaction txNew;
    1820             : 
    1821             :     // Discourage fee sniping.
    1822             :     //
    1823             :     // However because of a off-by-one-error in previous versions we need to
    1824             :     // neuter it by setting nLockTime to at least one less than nBestHeight.
    1825             :     // Secondly currently propagation of transactions created for block heights
    1826             :     // corresponding to blocks that were just mined may be iffy - transactions
    1827             :     // aren't re-accepted into the mempool - we additionally neuter the code by
    1828             :     // going ten blocks back. Doesn't yet do anything for sniping, but does act
    1829             :     // to shake out wallet bugs like not showing nLockTime'd transactions at
    1830             :     // all.
    1831         292 :     txNew.nLockTime = std::max(0, chainActive.Height() - 10);
    1832             : 
    1833             :     // Secondly occasionally randomly pick a nLockTime even further back, so
    1834             :     // that transactions that are delayed after signing for whatever reason,
    1835             :     // e.g. high-latency mix networks and some CoinJoin implementations, have
    1836             :     // better privacy.
    1837         146 :     if (GetRandInt(10) == 0)
    1838          32 :         txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
    1839             : 
    1840         292 :     assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
    1841         146 :     assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
    1842             : 
    1843             :     {
    1844         146 :         LOCK2(cs_main, cs_wallet);
    1845             :         {
    1846         146 :             nFeeRet = 0;
    1847             :             while (true)
    1848             :             {
    1849             :                 txNew.vin.clear();
    1850             :                 txNew.vout.clear();
    1851         336 :                 wtxNew.fFromMe = true;
    1852         336 :                 nChangePosRet = -1;
    1853         336 :                 bool fFirst = true;
    1854             : 
    1855         336 :                 CAmount nValueToSelect = nValue;
    1856         336 :                 if (nSubtractFeeFromAmount == 0)
    1857         328 :                     nValueToSelect += nFeeRet;
    1858         336 :                 double dPriority = 0;
    1859             :                 // vouts to the payees
    1860        3565 :                 BOOST_FOREACH (const CRecipient& recipient, vecSend)
    1861             :                 {
    1862        1131 :                     CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
    1863             : 
    1864         377 :                     if (recipient.fSubtractFeeFromAmount)
    1865             :                     {
    1866           8 :                         txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
    1867             : 
    1868           8 :                         if (fFirst) // first receiver pays the remainder not divisible by output count
    1869             :                         {
    1870           8 :                             fFirst = false;
    1871           8 :                             txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
    1872             :                         }
    1873             :                     }
    1874             : 
    1875         377 :                     if (txout.IsDust(::minRelayTxFee))
    1876             :                     {
    1877           0 :                         if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
    1878             :                         {
    1879           0 :                             if (txout.nValue < 0)
    1880           0 :                                 strFailReason = _("The transaction amount is too small to pay the fee");
    1881             :                             else
    1882           0 :                                 strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
    1883             :                         }
    1884             :                         else
    1885           0 :                             strFailReason = _("Transaction amount too small");
    1886           0 :                         return false;
    1887             :                     }
    1888         377 :                     txNew.vout.push_back(txout);
    1889             :                 }
    1890             : 
    1891             :                 // Choose coins to use
    1892             :                 set<pair<const CWalletTx*,unsigned int> > setCoins;
    1893         336 :                 CAmount nValueIn = 0;
    1894         336 :                 if (!SelectCoins(nValueToSelect, setCoins, nValueIn, coinControl))
    1895             :                 {
    1896           4 :                     strFailReason = _("Insufficient funds");
    1897           2 :                     return false;
    1898             :                 }
    1899        5834 :                 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
    1900             :                 {
    1901        1532 :                     CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
    1902             :                     //The coin age after the next block (depth+1) is used instead of the current,
    1903             :                     //reflecting an assumption the user would accept a bit more delay for
    1904             :                     //a chance at a free transaction.
    1905             :                     //But mempool inputs might still be in the mempool, so their age stays 0
    1906        1532 :                     int age = pcoin.first->GetDepthInMainChain();
    1907         766 :                     if (age != 0)
    1908         729 :                         age += 1;
    1909         766 :                     dPriority += (double)nCredit * age;
    1910             :                 }
    1911             : 
    1912         334 :                 const CAmount nChange = nValueIn - nValueToSelect;
    1913         334 :                 if (nChange > 0)
    1914             :                 {
    1915             :                     // Fill a vout to ourself
    1916             :                     // TODO: pass in scriptChange instead of reservekey so
    1917             :                     // change transaction isn't always pay-to-bitcoin-address
    1918             :                     CScript scriptChange;
    1919             : 
    1920             :                     // coin control: send change to custom address
    1921         352 :                     if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
    1922           0 :                         scriptChange = GetScriptForDestination(coinControl->destChange);
    1923             : 
    1924             :                     // no coin control: send change to newly generated address
    1925             :                     else
    1926             :                     {
    1927             :                         // Note: We use a new key here to keep it from being obvious which side is the change.
    1928             :                         //  The drawback is that by not reusing a previous key, the change may be lost if a
    1929             :                         //  backup is restored, if the backup doesn't have the new private key for the change.
    1930             :                         //  If we reused the old key, it would be possible to add code to look for and
    1931             :                         //  rediscover unknown transactions that were written with keys of ours to recover
    1932             :                         //  post-backup change.
    1933             : 
    1934             :                         // Reserve a new key pair from key pool
    1935             :                         CPubKey vchPubKey;
    1936             :                         bool ret;
    1937         313 :                         ret = reservekey.GetReservedKey(vchPubKey);
    1938         313 :                         assert(ret); // should never fail, as we just unlocked
    1939             : 
    1940        1252 :                         scriptChange = GetScriptForDestination(vchPubKey.GetID());
    1941             :                     }
    1942             : 
    1943         626 :                     CTxOut newTxOut(nChange, scriptChange);
    1944             : 
    1945             :                     // We do not move dust-change to fees, because the sender would end up paying more than requested.
    1946             :                     // This would be against the purpose of the all-inclusive feature.
    1947             :                     // So instead we raise the change and deduct from the recipient.
    1948         315 :                     if (nSubtractFeeFromAmount > 0 && newTxOut.IsDust(::minRelayTxFee))
    1949             :                     {
    1950           0 :                         CAmount nDust = newTxOut.GetDustThreshold(::minRelayTxFee) - newTxOut.nValue;
    1951           0 :                         newTxOut.nValue += nDust; // raise change until no more dust
    1952           0 :                         for (unsigned int i = 0; i < vecSend.size(); i++) // subtract from first recipient
    1953             :                         {
    1954           0 :                             if (vecSend[i].fSubtractFeeFromAmount)
    1955             :                             {
    1956           0 :                                 txNew.vout[i].nValue -= nDust;
    1957           0 :                                 if (txNew.vout[i].IsDust(::minRelayTxFee))
    1958             :                                 {
    1959           0 :                                     strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
    1960           0 :                                     return false;
    1961             :                                 }
    1962             :                                 break;
    1963             :                             }
    1964             :                         }
    1965             :                     }
    1966             : 
    1967             :                     // Never create dust outputs; if we would, just
    1968             :                     // add the dust to the fee.
    1969         313 :                     if (newTxOut.IsDust(::minRelayTxFee))
    1970             :                     {
    1971           1 :                         nFeeRet += nChange;
    1972             :                         reservekey.ReturnKey();
    1973             :                     }
    1974             :                     else
    1975             :                     {
    1976             :                         // Insert change txn at random position:
    1977         624 :                         nChangePosRet = GetRandInt(txNew.vout.size()+1);
    1978         936 :                         vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosRet;
    1979         312 :                         txNew.vout.insert(position, newTxOut);
    1980             :                     }
    1981             :                 }
    1982             :                 else
    1983             :                     reservekey.ReturnKey();
    1984             : 
    1985             :                 // Fill vin
    1986             :                 //
    1987             :                 // Note how the sequence number is set to max()-1 so that the
    1988             :                 // nLockTime set above actually works.
    1989        5834 :                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
    1990         766 :                     txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second,CScript(),
    1991        3830 :                                               std::numeric_limits<unsigned int>::max()-1));
    1992             : 
    1993             :                 // Sign
    1994         334 :                 int nIn = 0;
    1995         334 :                 CTransaction txNewConst(txNew);
    1996        5834 :                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
    1997             :                 {
    1998             :                     bool signSuccess;
    1999        1532 :                     const CScript& scriptPubKey = coin.first->vout[coin.second].scriptPubKey;
    2000        1532 :                     CScript& scriptSigRes = txNew.vin[nIn].scriptSig;
    2001         766 :                     if (sign)
    2002        1192 :                         signSuccess = ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, SIGHASH_ALL), scriptPubKey, scriptSigRes);
    2003             :                     else
    2004         510 :                         signSuccess = ProduceSignature(DummySignatureCreator(this), scriptPubKey, scriptSigRes);
    2005             : 
    2006         766 :                     if (!signSuccess)
    2007             :                     {
    2008           0 :                         strFailReason = _("Signing transaction failed");
    2009             :                         return false;
    2010             :                     }
    2011         766 :                     nIn++;
    2012             :                 }
    2013             : 
    2014         334 :                 unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
    2015             : 
    2016             :                 // Remove scriptSigs if we used dummy signatures for fee calculation
    2017         334 :                 if (!sign) {
    2018        1126 :                     BOOST_FOREACH (CTxIn& vin, txNew.vin)
    2019         340 :                         vin.scriptSig = CScript();
    2020             :                 }
    2021             : 
    2022             :                 // Embed the constructed transaction data in wtxNew.
    2023         668 :                 *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
    2024             : 
    2025             :                 // Limit size
    2026         334 :                 if (nBytes >= MAX_STANDARD_TX_SIZE)
    2027             :                 {
    2028           0 :                     strFailReason = _("Transaction too large");
    2029           0 :                     return false;
    2030             :                 }
    2031             : 
    2032         334 :                 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
    2033             : 
    2034             :                 // Can we complete this as a free transaction?
    2035         334 :                 if (fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE)
    2036             :                 {
    2037             :                     // Not enough fee: enough priority?
    2038           0 :                     double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
    2039             :                     // Not enough mempool history to estimate: use hard-coded AllowFree.
    2040           0 :                     if (dPriorityNeeded <= 0 && AllowFree(dPriority))
    2041             :                         break;
    2042             : 
    2043             :                     // Small enough, and priority high enough, to send for free
    2044           0 :                     if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
    2045             :                         break;
    2046             :                 }
    2047             : 
    2048         334 :                 CAmount nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
    2049             : 
    2050             :                 // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
    2051             :                 // because we must be at the maximum allowed fee.
    2052         334 :                 if (nFeeNeeded < ::minRelayTxFee.GetFee(nBytes))
    2053             :                 {
    2054           0 :                     strFailReason = _("Transaction too large for fee policy");
    2055           0 :                     return false;
    2056             :                 }
    2057             : 
    2058         334 :                 if (nFeeRet >= nFeeNeeded)
    2059             :                     break; // Done, enough fee included.
    2060             : 
    2061             :                 // Include more fee and try again.
    2062         190 :                 nFeeRet = nFeeNeeded;
    2063             :                 continue;
    2064         190 :             }
    2065             :         }
    2066             :     }
    2067             : 
    2068         144 :     return true;
    2069             : }
    2070             : 
    2071             : /**
    2072             :  * Call after CreateTransaction unless you want to abort
    2073             :  */
    2074         124 : bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
    2075             : {
    2076             :     {
    2077         124 :         LOCK2(cs_main, cs_wallet);
    2078         248 :         LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
    2079             :         {
    2080             :             // This is only to keep the database open to defeat the auto-flush for the
    2081             :             // duration of this scope.  This is the only place where this optimization
    2082             :             // maybe makes sense; please don't do it anywhere else.
    2083         248 :             CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r+") : NULL;
    2084             : 
    2085             :             // Take key pair from key pool so it won't be used again
    2086             :             reservekey.KeepKey();
    2087             : 
    2088             :             // Add tx to wallet, because if it has change it's also ours,
    2089             :             // otherwise just for transaction history.
    2090         124 :             AddToWallet(wtxNew, false, pwalletdb);
    2091             : 
    2092             :             // Notify that old coins are spent
    2093             :             set<CWalletTx*> setCoins;
    2094        1880 :             BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
    2095             :             {
    2096         210 :                 CWalletTx &coin = mapWallet[txin.prevout.hash];
    2097             :                 coin.BindWallet(this);
    2098         420 :                 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
    2099             :             }
    2100             : 
    2101         124 :             if (fFileBacked)
    2102         248 :                 delete pwalletdb;
    2103             :         }
    2104             : 
    2105             :         // Track how many getdata requests our transaction gets
    2106         248 :         mapRequestCount[wtxNew.GetHash()] = 0;
    2107             : 
    2108         124 :         if (fBroadcastTransactions)
    2109             :         {
    2110             :             // Broadcast
    2111         122 :             if (!wtxNew.AcceptToMemoryPool(false))
    2112             :             {
    2113             :                 // This must not fail. The transaction has already been signed and recorded.
    2114           0 :                 LogPrintf("CommitTransaction(): Error: Transaction not valid\n");
    2115           0 :                 return false;
    2116             :             }
    2117         122 :             wtxNew.RelayWalletTransaction();
    2118             :         }
    2119             :     }
    2120         124 :     return true;
    2121             : }
    2122             : 
    2123         334 : CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
    2124             : {
    2125             :     // payTxFee is user-set "I want to pay this much"
    2126         334 :     CAmount nFeeNeeded = payTxFee.GetFee(nTxBytes);
    2127             :     // user selected total at least (default=true)
    2128         351 :     if (fPayAtLeastCustomFee && nFeeNeeded > 0 && nFeeNeeded < payTxFee.GetFeePerK())
    2129          14 :         nFeeNeeded = payTxFee.GetFeePerK();
    2130             :     // User didn't set: use -txconfirmtarget to estimate...
    2131         334 :     if (nFeeNeeded == 0)
    2132         317 :         nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
    2133             :     // ... unless we don't have enough mempool data, in which case fall
    2134             :     // back to a hard-coded fee
    2135         334 :     if (nFeeNeeded == 0)
    2136         317 :         nFeeNeeded = minTxFee.GetFee(nTxBytes);
    2137             :     // prevent user from paying a non-sense fee (like 1 satoshi): 0 < fee < minRelayFee
    2138         334 :     if (nFeeNeeded < ::minRelayTxFee.GetFee(nTxBytes))
    2139         317 :         nFeeNeeded = ::minRelayTxFee.GetFee(nTxBytes);
    2140             :     // But always obey the maximum
    2141         334 :     if (nFeeNeeded > maxTxFee)
    2142           0 :         nFeeNeeded = maxTxFee;
    2143         334 :     return nFeeNeeded;
    2144             : }
    2145             : 
    2146             : 
    2147             : 
    2148             : 
    2149         119 : DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
    2150             : {
    2151         119 :     if (!fFileBacked)
    2152             :         return DB_LOAD_OK;
    2153         119 :     fFirstRunRet = false;
    2154         357 :     DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
    2155         119 :     if (nLoadWalletRet == DB_NEED_REWRITE)
    2156             :     {
    2157           0 :         if (CDB::Rewrite(strWalletFile, "\x04pool"))
    2158             :         {
    2159           0 :             LOCK(cs_wallet);
    2160           0 :             setKeyPool.clear();
    2161             :             // Note: can't top-up keypool here, because wallet is locked.
    2162             :             // User will be prompted to unlock wallet the next operation
    2163             :             // that requires a new key.
    2164             :         }
    2165             :     }
    2166             : 
    2167         119 :     if (nLoadWalletRet != DB_LOAD_OK)
    2168             :         return nLoadWalletRet;
    2169         238 :     fFirstRunRet = !vchDefaultKey.IsValid();
    2170             : 
    2171         119 :     uiInterface.LoadWallet(this);
    2172             : 
    2173         119 :     return DB_LOAD_OK;
    2174             : }
    2175             : 
    2176             : 
    2177           1 : DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
    2178             : {
    2179           1 :     if (!fFileBacked)
    2180             :         return DB_LOAD_OK;
    2181           3 :     DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
    2182           1 :     if (nZapWalletTxRet == DB_NEED_REWRITE)
    2183             :     {
    2184           0 :         if (CDB::Rewrite(strWalletFile, "\x04pool"))
    2185             :         {
    2186           0 :             LOCK(cs_wallet);
    2187           0 :             setKeyPool.clear();
    2188             :             // Note: can't top-up keypool here, because wallet is locked.
    2189             :             // User will be prompted to unlock wallet the next operation
    2190             :             // that requires a new key.
    2191             :         }
    2192             :     }
    2193             : 
    2194           1 :     if (nZapWalletTxRet != DB_LOAD_OK)
    2195           0 :         return nZapWalletTxRet;
    2196             : 
    2197             :     return DB_LOAD_OK;
    2198             : }
    2199             : 
    2200             : 
    2201         249 : bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
    2202             : {
    2203         249 :     bool fUpdated = false;
    2204             :     {
    2205         249 :         LOCK(cs_wallet); // mapAddressBook
    2206         498 :         std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
    2207         498 :         fUpdated = mi != mapAddressBook.end();
    2208         249 :         mapAddressBook[address].name = strName;
    2209         249 :         if (!strPurpose.empty()) /* update purpose only if requested */
    2210         249 :             mapAddressBook[address].purpose = strPurpose;
    2211             :     }
    2212         249 :     NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
    2213         498 :                              strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
    2214         249 :     if (!fFileBacked)
    2215             :         return false;
    2216        1494 :     if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
    2217             :         return false;
    2218        1245 :     return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
    2219             : }
    2220             : 
    2221           0 : bool CWallet::DelAddressBook(const CTxDestination& address)
    2222             : {
    2223             :     {
    2224           0 :         LOCK(cs_wallet); // mapAddressBook
    2225             : 
    2226           0 :         if(fFileBacked)
    2227             :         {
    2228             :             // Delete destdata tuples associated with address
    2229           0 :             std::string strAddress = CBitcoinAddress(address).ToString();
    2230           0 :             BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
    2231             :             {
    2232           0 :                 CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
    2233           0 :             }
    2234             :         }
    2235           0 :         mapAddressBook.erase(address);
    2236             :     }
    2237             : 
    2238           0 :     NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
    2239             : 
    2240           0 :     if (!fFileBacked)
    2241             :         return false;
    2242           0 :     CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
    2243           0 :     return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
    2244             : }
    2245             : 
    2246          37 : bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
    2247             : {
    2248          37 :     if (fFileBacked)
    2249             :     {
    2250         111 :         if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
    2251             :             return false;
    2252             :     }
    2253          37 :     vchDefaultKey = vchPubKey;
    2254          37 :     return true;
    2255             : }
    2256             : 
    2257             : /**
    2258             :  * Mark old keypool keys as used,
    2259             :  * and generate all new keys 
    2260             :  */
    2261           1 : bool CWallet::NewKeyPool()
    2262             : {
    2263             :     {
    2264           1 :         LOCK(cs_wallet);
    2265           1 :         CWalletDB walletdb(strWalletFile);
    2266          12 :         BOOST_FOREACH(int64_t nIndex, setKeyPool)
    2267           1 :             walletdb.ErasePool(nIndex);
    2268           1 :         setKeyPool.clear();
    2269             : 
    2270           1 :         if (IsLocked())
    2271           0 :             return false;
    2272             : 
    2273           4 :         int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
    2274           2 :         for (int i = 0; i < nKeys; i++)
    2275             :         {
    2276           1 :             int64_t nIndex = i+1;
    2277           1 :             walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
    2278           1 :             setKeyPool.insert(nIndex);
    2279             :         }
    2280           1 :         LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
    2281             :     }
    2282           1 :     return true;
    2283             : }
    2284             : 
    2285         816 : bool CWallet::TopUpKeyPool(unsigned int kpSize)
    2286             : {
    2287             :     {
    2288         816 :         LOCK(cs_wallet);
    2289             : 
    2290         816 :         if (IsLocked())
    2291           0 :             return false;
    2292             : 
    2293         816 :         CWalletDB walletdb(strWalletFile);
    2294             : 
    2295             :         // Top up key pool
    2296             :         unsigned int nTargetSize;
    2297         816 :         if (kpSize > 0)
    2298             :             nTargetSize = kpSize;
    2299             :         else
    2300        3264 :             nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
    2301             : 
    2302        3738 :         while (setKeyPool.size() < (nTargetSize + 1))
    2303             :         {
    2304        1053 :             int64_t nEnd = 1;
    2305        2106 :             if (!setKeyPool.empty())
    2306        4060 :                 nEnd = *(--setKeyPool.end()) + 1;
    2307        1053 :             if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
    2308           0 :                 throw runtime_error("TopUpKeyPool(): writing generated key failed");
    2309        1053 :             setKeyPool.insert(nEnd);
    2310        2106 :             LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
    2311             :         }
    2312             :     }
    2313         816 :     return true;
    2314             : }
    2315             : 
    2316         637 : void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
    2317             : {
    2318         637 :     nIndex = -1;
    2319         637 :     keypool.vchPubKey = CPubKey();
    2320             :     {
    2321         637 :         LOCK(cs_wallet);
    2322             : 
    2323         637 :         if (!IsLocked())
    2324         636 :             TopUpKeyPool();
    2325             : 
    2326             :         // Get the oldest key
    2327        1274 :         if(setKeyPool.empty())
    2328         637 :             return;
    2329             : 
    2330         637 :         CWalletDB walletdb(strWalletFile);
    2331             : 
    2332        1911 :         nIndex = *(setKeyPool.begin());
    2333        1274 :         setKeyPool.erase(setKeyPool.begin());
    2334         637 :         if (!walletdb.ReadPool(nIndex, keypool))
    2335           0 :             throw runtime_error("ReserveKeyFromKeyPool(): read failed");
    2336         637 :         if (!HaveKey(keypool.vchPubKey.GetID()))
    2337           0 :             throw runtime_error("ReserveKeyFromKeyPool(): unknown key in key pool");
    2338        1274 :         assert(keypool.vchPubKey.IsValid());
    2339         637 :         LogPrintf("keypool reserve %d\n", nIndex);
    2340             :     }
    2341             : }
    2342             : 
    2343         615 : void CWallet::KeepKey(int64_t nIndex)
    2344             : {
    2345             :     // Remove from key pool
    2346         615 :     if (fFileBacked)
    2347             :     {
    2348         615 :         CWalletDB walletdb(strWalletFile);
    2349         615 :         walletdb.ErasePool(nIndex);
    2350             :     }
    2351         615 :     LogPrintf("keypool keep %d\n", nIndex);
    2352         615 : }
    2353             : 
    2354          22 : void CWallet::ReturnKey(int64_t nIndex)
    2355             : {
    2356             :     // Return to key pool
    2357             :     {
    2358          22 :         LOCK(cs_wallet);
    2359          22 :         setKeyPool.insert(nIndex);
    2360             :     }
    2361          22 :     LogPrintf("keypool return %d\n", nIndex);
    2362          22 : }
    2363             : 
    2364         219 : bool CWallet::GetKeyFromPool(CPubKey& result)
    2365             : {
    2366         219 :     int64_t nIndex = 0;
    2367             :     CKeyPool keypool;
    2368             :     {
    2369         219 :         LOCK(cs_wallet);
    2370         219 :         ReserveKeyFromKeyPool(nIndex, keypool);
    2371         219 :         if (nIndex == -1)
    2372             :         {
    2373           0 :             if (IsLocked()) return false;
    2374           0 :             result = GenerateNewKey();
    2375             :             return true;
    2376             :         }
    2377         219 :         KeepKey(nIndex);
    2378         219 :         result = keypool.vchPubKey;
    2379             :     }
    2380         219 :     return true;
    2381             : }
    2382             : 
    2383           2 : int64_t CWallet::GetOldestKeyPoolTime()
    2384             : {
    2385           2 :     int64_t nIndex = 0;
    2386             :     CKeyPool keypool;
    2387           2 :     ReserveKeyFromKeyPool(nIndex, keypool);
    2388           2 :     if (nIndex == -1)
    2389           0 :         return GetTime();
    2390           2 :     ReturnKey(nIndex);
    2391           2 :     return keypool.nTime;
    2392             : }
    2393             : 
    2394           1 : std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
    2395             : {
    2396             :     map<CTxDestination, CAmount> balances;
    2397             : 
    2398             :     {
    2399           1 :         LOCK(cs_wallet);
    2400           6 :         BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
    2401             :         {
    2402           0 :             CWalletTx *pcoin = &walletEntry.second;
    2403             : 
    2404           0 :             if (!CheckFinalTx(*pcoin) || !pcoin->IsTrusted())
    2405             :                 continue;
    2406             : 
    2407           0 :             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
    2408             :                 continue;
    2409             : 
    2410           0 :             int nDepth = pcoin->GetDepthInMainChain();
    2411           0 :             if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
    2412             :                 continue;
    2413             : 
    2414           0 :             for (unsigned int i = 0; i < pcoin->vout.size(); i++)
    2415             :             {
    2416             :                 CTxDestination addr;
    2417           0 :                 if (!IsMine(pcoin->vout[i]))
    2418             :                     continue;
    2419           0 :                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
    2420             :                     continue;
    2421             : 
    2422           0 :                 CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
    2423             : 
    2424           0 :                 if (!balances.count(addr))
    2425           0 :                     balances[addr] = 0;
    2426           0 :                 balances[addr] += n;
    2427             :             }
    2428             :         }
    2429             :     }
    2430             : 
    2431           1 :     return balances;
    2432             : }
    2433             : 
    2434           1 : set< set<CTxDestination> > CWallet::GetAddressGroupings()
    2435             : {
    2436           1 :     AssertLockHeld(cs_wallet); // mapWallet
    2437             :     set< set<CTxDestination> > groupings;
    2438             :     set<CTxDestination> grouping;
    2439             : 
    2440           6 :     BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
    2441             :     {
    2442           0 :         CWalletTx *pcoin = &walletEntry.second;
    2443             : 
    2444           0 :         if (pcoin->vin.size() > 0)
    2445             :         {
    2446           0 :             bool any_mine = false;
    2447             :             // group all input addresses with each other
    2448           0 :             BOOST_FOREACH(CTxIn txin, pcoin->vin)
    2449             :             {
    2450             :                 CTxDestination address;
    2451           0 :                 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
    2452             :                     continue;
    2453           0 :                 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
    2454             :                     continue;
    2455             :                 grouping.insert(address);
    2456           0 :                 any_mine = true;
    2457             :             }
    2458             : 
    2459             :             // group change with input addresses
    2460           0 :             if (any_mine)
    2461             :             {
    2462           0 :                BOOST_FOREACH(CTxOut txout, pcoin->vout)
    2463           0 :                    if (IsChange(txout))
    2464             :                    {
    2465             :                        CTxDestination txoutAddr;
    2466           0 :                        if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
    2467             :                            continue;
    2468             :                        grouping.insert(txoutAddr);
    2469             :                    }
    2470             :             }
    2471           0 :             if (grouping.size() > 0)
    2472             :             {
    2473             :                 groupings.insert(grouping);
    2474             :                 grouping.clear();
    2475             :             }
    2476             :         }
    2477             : 
    2478             :         // group lone addrs by themselves
    2479           0 :         for (unsigned int i = 0; i < pcoin->vout.size(); i++)
    2480           0 :             if (IsMine(pcoin->vout[i]))
    2481             :             {
    2482             :                 CTxDestination address;
    2483           0 :                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
    2484             :                     continue;
    2485             :                 grouping.insert(address);
    2486             :                 groupings.insert(grouping);
    2487             :                 grouping.clear();
    2488             :             }
    2489             :     }
    2490             : 
    2491             :     set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
    2492             :     map< CTxDestination, set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
    2493           6 :     BOOST_FOREACH(set<CTxDestination> grouping, groupings)
    2494             :     {
    2495             :         // make a set of all the groups hit by this new group
    2496             :         set< set<CTxDestination>* > hits;
    2497             :         map< CTxDestination, set<CTxDestination>* >::iterator it;
    2498           0 :         BOOST_FOREACH(CTxDestination address, grouping)
    2499           0 :             if ((it = setmap.find(address)) != setmap.end())
    2500           0 :                 hits.insert((*it).second);
    2501             : 
    2502             :         // merge all hit groups into a new single group and delete old groups
    2503           0 :         set<CTxDestination>* merged = new set<CTxDestination>(grouping);
    2504           0 :         BOOST_FOREACH(set<CTxDestination>* hit, hits)
    2505             :         {
    2506           0 :             merged->insert(hit->begin(), hit->end());
    2507             :             uniqueGroupings.erase(hit);
    2508           0 :             delete hit;
    2509             :         }
    2510             :         uniqueGroupings.insert(merged);
    2511             : 
    2512             :         // update setmap
    2513           0 :         BOOST_FOREACH(CTxDestination element, *merged)
    2514           0 :             setmap[element] = merged;
    2515             :     }
    2516             : 
    2517             :     set< set<CTxDestination> > ret;
    2518           6 :     BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
    2519             :     {
    2520             :         ret.insert(*uniqueGrouping);
    2521           0 :         delete uniqueGrouping;
    2522             :     }
    2523             : 
    2524           1 :     return ret;
    2525             : }
    2526             : 
    2527           0 : std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
    2528             : {
    2529           0 :     LOCK(cs_wallet);
    2530             :     set<CTxDestination> result;
    2531           0 :     BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
    2532             :     {
    2533           0 :         const CTxDestination& address = item.first;
    2534           0 :         const string& strName = item.second.name;
    2535           0 :         if (strName == strAccount)
    2536             :             result.insert(address);
    2537             :     }
    2538           0 :     return result;
    2539             : }
    2540             : 
    2541         588 : bool CReserveKey::GetReservedKey(CPubKey& pubkey)
    2542             : {
    2543         588 :     if (nIndex == -1)
    2544             :     {
    2545             :         CKeyPool keypool;
    2546         416 :         pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
    2547         416 :         if (nIndex != -1)
    2548         416 :             vchPubKey = keypool.vchPubKey;
    2549             :         else {
    2550           0 :             return false;
    2551             :         }
    2552             :     }
    2553        1176 :     assert(vchPubKey.IsValid());
    2554         588 :     pubkey = vchPubKey;
    2555         588 :     return true;
    2556             : }
    2557             : 
    2558        1237 : void CReserveKey::KeepKey()
    2559             : {
    2560        1361 :     if (nIndex != -1)
    2561         396 :         pwallet->KeepKey(nIndex);
    2562        1361 :     nIndex = -1;
    2563        1361 :     vchPubKey = CPubKey();
    2564        1237 : }
    2565             : 
    2566         147 : void CReserveKey::ReturnKey()
    2567             : {
    2568         443 :     if (nIndex != -1)
    2569          20 :         pwallet->ReturnKey(nIndex);
    2570         443 :     nIndex = -1;
    2571         443 :     vchPubKey = CPubKey();
    2572         147 : }
    2573             : 
    2574           3 : void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
    2575             : {
    2576             :     setAddress.clear();
    2577             : 
    2578           3 :     CWalletDB walletdb(strWalletFile);
    2579             : 
    2580           3 :     LOCK2(cs_main, cs_wallet);
    2581        1515 :     BOOST_FOREACH(const int64_t& id, setKeyPool)
    2582             :     {
    2583             :         CKeyPool keypool;
    2584         300 :         if (!walletdb.ReadPool(id, keypool))
    2585           0 :             throw runtime_error("GetAllReserveKeyHashes(): read failed");
    2586         300 :         assert(keypool.vchPubKey.IsValid());
    2587         300 :         CKeyID keyID = keypool.vchPubKey.GetID();
    2588         300 :         if (!HaveKey(keyID))
    2589           0 :             throw runtime_error("GetAllReserveKeyHashes(): unknown key in key pool");
    2590             :         setAddress.insert(keyID);
    2591             :     }
    2592           3 : }
    2593             : 
    2594        5440 : void CWallet::UpdatedTransaction(const uint256 &hashTx)
    2595             : {
    2596             :     {
    2597        5440 :         LOCK(cs_wallet);
    2598             :         // Only notify UI if this transaction is in this wallet
    2599       10880 :         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
    2600       10880 :         if (mi != mapWallet.end())
    2601        1219 :             NotifyTransactionChanged(this, hashTx, CT_UPDATED);
    2602             :     }
    2603        5440 : }
    2604             : 
    2605         274 : void CWallet::GetScriptForMining(boost::shared_ptr<CReserveScript> &script)
    2606             : {
    2607         548 :     boost::shared_ptr<CReserveKey> rKey(new CReserveKey(this));
    2608             :     CPubKey pubkey;
    2609         548 :     if (!rKey->GetReservedKey(pubkey))
    2610         274 :         return;
    2611             : 
    2612         274 :     script = rKey;
    2613        1370 :     script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
    2614             : }
    2615             : 
    2616           0 : void CWallet::LockCoin(COutPoint& output)
    2617             : {
    2618           0 :     AssertLockHeld(cs_wallet); // setLockedCoins
    2619           0 :     setLockedCoins.insert(output);
    2620           0 : }
    2621             : 
    2622           0 : void CWallet::UnlockCoin(COutPoint& output)
    2623             : {
    2624           0 :     AssertLockHeld(cs_wallet); // setLockedCoins
    2625           0 :     setLockedCoins.erase(output);
    2626           0 : }
    2627             : 
    2628           0 : void CWallet::UnlockAllCoins()
    2629             : {
    2630           0 :     AssertLockHeld(cs_wallet); // setLockedCoins
    2631           0 :     setLockedCoins.clear();
    2632           0 : }
    2633             : 
    2634        4859 : bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
    2635             : {
    2636        4859 :     AssertLockHeld(cs_wallet); // setLockedCoins
    2637             :     COutPoint outpt(hash, n);
    2638             : 
    2639        9718 :     return (setLockedCoins.count(outpt) > 0);
    2640             : }
    2641             : 
    2642           1 : void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
    2643             : {
    2644           1 :     AssertLockHeld(cs_wallet); // setLockedCoins
    2645           3 :     for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
    2646           2 :          it != setLockedCoins.end(); it++) {
    2647           0 :         COutPoint outpt = (*it);
    2648           0 :         vOutpts.push_back(outpt);
    2649             :     }
    2650           1 : }
    2651             : 
    2652             : /** @} */ // end of Actions
    2653             : 
    2654           0 : class CAffectedKeysVisitor : public boost::static_visitor<void> {
    2655             : private:
    2656             :     const CKeyStore &keystore;
    2657             :     std::vector<CKeyID> &vKeys;
    2658             : 
    2659             : public:
    2660           0 :     CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
    2661             : 
    2662           0 :     void Process(const CScript &script) {
    2663             :         txnouttype type;
    2664             :         std::vector<CTxDestination> vDest;
    2665             :         int nRequired;
    2666           0 :         if (ExtractDestinations(script, type, vDest, nRequired)) {
    2667           0 :             BOOST_FOREACH(const CTxDestination &dest, vDest)
    2668             :                 boost::apply_visitor(*this, dest);
    2669           0 :         }
    2670           0 :     }
    2671             : 
    2672           0 :     void operator()(const CKeyID &keyId) {
    2673           0 :         if (keystore.HaveKey(keyId))
    2674           0 :             vKeys.push_back(keyId);
    2675           0 :     }
    2676             : 
    2677           0 :     void operator()(const CScriptID &scriptId) {
    2678             :         CScript script;
    2679           0 :         if (keystore.GetCScript(scriptId, script))
    2680           0 :             Process(script);
    2681           0 :     }
    2682             : 
    2683           0 :     void operator()(const CNoDestination &none) {}
    2684             : };
    2685             : 
    2686           3 : void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
    2687           3 :     AssertLockHeld(cs_wallet); // mapKeyMetadata
    2688             :     mapKeyBirth.clear();
    2689             : 
    2690             :     // get birth times for keys with metadata
    2691        1023 :     for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
    2692         337 :         if (it->second.nCreateTime)
    2693         674 :             mapKeyBirth[it->first] = it->second.nCreateTime;
    2694             : 
    2695             :     // map in which we'll infer heights of other keys
    2696           9 :     CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
    2697             :     std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
    2698             :     std::set<CKeyID> setKeys;
    2699           3 :     GetKeys(setKeys);
    2700        2040 :     BOOST_FOREACH(const CKeyID &keyid, setKeys) {
    2701         337 :         if (mapKeyBirth.count(keyid) == 0)
    2702           0 :             mapKeyFirstBlock[keyid] = pindexMax;
    2703             :     }
    2704             :     setKeys.clear();
    2705             : 
    2706             :     // if there are no such keys, we're done
    2707           3 :     if (mapKeyFirstBlock.empty())
    2708           3 :         return;
    2709             : 
    2710             :     // find first block that affects those keys, if there are any left
    2711             :     std::vector<CKeyID> vAffected;
    2712           0 :     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
    2713             :         // iterate over all wallet transactions...
    2714           0 :         const CWalletTx &wtx = (*it).second;
    2715           0 :         BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
    2716           0 :         if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
    2717             :             // ... which are already in a block
    2718           0 :             int nHeight = blit->second->nHeight;
    2719           0 :             BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
    2720             :                 // iterate over all their outputs
    2721           0 :                 CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
    2722           0 :                 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
    2723             :                     // ... and all their affected keys
    2724           0 :                     std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
    2725           0 :                     if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
    2726           0 :                         rit->second = blit->second;
    2727             :                 }
    2728             :                 vAffected.clear();
    2729             :             }
    2730             :         }
    2731             :     }
    2732             : 
    2733             :     // Extract block timestamps for those keys
    2734           0 :     for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
    2735           0 :         mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
    2736             : }
    2737             : 
    2738           0 : bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
    2739             : {
    2740           0 :     if (boost::get<CNoDestination>(&dest))
    2741             :         return false;
    2742             : 
    2743           0 :     mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
    2744           0 :     if (!fFileBacked)
    2745             :         return true;
    2746           0 :     return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
    2747             : }
    2748             : 
    2749           0 : bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
    2750             : {
    2751           0 :     if (!mapAddressBook[dest].destdata.erase(key))
    2752             :         return false;
    2753           0 :     if (!fFileBacked)
    2754             :         return true;
    2755           0 :     return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
    2756             : }
    2757             : 
    2758           0 : bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
    2759             : {
    2760           0 :     mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
    2761           0 :     return true;
    2762             : }
    2763             : 
    2764           0 : bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
    2765             : {
    2766           0 :     std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
    2767           0 :     if(i != mapAddressBook.end())
    2768             :     {
    2769           0 :         CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
    2770           0 :         if(j != i->second.destdata.end())
    2771             :         {
    2772           0 :             if(value)
    2773           0 :                 *value = j->second;
    2774             :             return true;
    2775             :         }
    2776             :     }
    2777             :     return false;
    2778             : }
    2779             : 
    2780        1292 : CKeyPool::CKeyPool()
    2781             : {
    2782        1292 :     nTime = GetTime();
    2783         355 : }
    2784             : 
    2785        1054 : CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn)
    2786             : {
    2787        1054 :     nTime = GetTime();
    2788        1054 :     vchPubKey = vchPubKeyIn;
    2789        1054 : }
    2790             : 
    2791           0 : CWalletKey::CWalletKey(int64_t nExpires)
    2792             : {
    2793           0 :     nTimeCreated = (nExpires ? GetTime() : 0);
    2794           0 :     nTimeExpires = nExpires;
    2795           0 : }
    2796             : 
    2797        3673 : int CMerkleTx::SetMerkleBranch(const CBlock& block)
    2798             : {
    2799        3673 :     AssertLockHeld(cs_main);
    2800        3673 :     CBlock blockTmp;
    2801             : 
    2802             :     // Update the tx's hashBlock
    2803        3673 :     hashBlock = block.GetHash();
    2804             : 
    2805             :     // Locate the transaction
    2806       10636 :     for (nIndex = 0; nIndex < (int)block.vtx.size(); nIndex++)
    2807       15954 :         if (block.vtx[nIndex] == *(CTransaction*)this)
    2808             :             break;
    2809        3673 :     if (nIndex == (int)block.vtx.size())
    2810             :     {
    2811           0 :         nIndex = -1;
    2812           0 :         LogPrintf("ERROR: SetMerkleBranch(): couldn't find tx in block\n");
    2813             :         return 0;
    2814             :     }
    2815             : 
    2816             :     // Is the tx in a block that's in the main chain
    2817        7346 :     BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
    2818        3673 :     if (mi == mapBlockIndex.end())
    2819             :         return 0;
    2820        3673 :     const CBlockIndex* pindex = (*mi).second;
    2821        7346 :     if (!pindex || !chainActive.Contains(pindex))
    2822             :         return 0;
    2823             : 
    2824        3673 :     return chainActive.Height() - pindex->nHeight + 1;
    2825             : }
    2826             : 
    2827       85901 : int CMerkleTx::GetDepthInMainChainINTERNAL(const CBlockIndex* &pindexRet) const
    2828             : {
    2829      171802 :     if (hashBlock.IsNull() || nIndex == -1)
    2830             :         return 0;
    2831       81496 :     AssertLockHeld(cs_main);
    2832             : 
    2833             :     // Find the block it claims to be in
    2834      162992 :     BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
    2835       81496 :     if (mi == mapBlockIndex.end())
    2836             :         return 0;
    2837       81487 :     CBlockIndex* pindex = (*mi).second;
    2838      162974 :     if (!pindex || !chainActive.Contains(pindex))
    2839             :         return 0;
    2840             : 
    2841       81454 :     pindexRet = pindex;
    2842       81454 :     return chainActive.Height() - pindex->nHeight + 1;
    2843             : }
    2844             : 
    2845       85900 : int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
    2846             : {
    2847       85900 :     AssertLockHeld(cs_main);
    2848       85900 :     int nResult = GetDepthInMainChainINTERNAL(pindexRet);
    2849       90347 :     if (nResult == 0 && !mempool.exists(GetHash()))
    2850             :         return -1; // Not in chain, not in mempool
    2851             : 
    2852       85855 :     return nResult;
    2853             : }
    2854             : 
    2855       29741 : int CMerkleTx::GetBlocksToMaturity() const
    2856             : {
    2857       29741 :     if (!IsCoinBase())
    2858             :         return 0;
    2859       59220 :     return max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
    2860             : }
    2861             : 
    2862             : 
    2863         136 : bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
    2864             : {
    2865             :     CValidationState state;
    2866         136 :     return ::AcceptToMemoryPool(mempool, state, *this, fLimitFree, NULL, fRejectAbsurdFee);
    2867         288 : }
    2868             : 

Generated by: LCOV version 1.11