]> Git Repo - VerusCoin.git/blob - src/wallet.cpp
UniValue: compact (!pretty) output should not include extra whitespace
[VerusCoin.git] / src / wallet.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6 #include "wallet.h"
7
8 #include "base58.h"
9 #include "checkpoints.h"
10 #include "coincontrol.h"
11 #include "net.h"
12 #include "timedata.h"
13
14 #include <boost/algorithm/string/replace.hpp>
15
16 using namespace std;
17
18 // Settings
19 CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
20 unsigned int nTxConfirmTarget = 1;
21 bool bSpendZeroConfChange = true;
22
23 /** Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) */
24 CFeeRate CWallet::minTxFee = CFeeRate(10000);  // Override with -mintxfee
25
26 //////////////////////////////////////////////////////////////////////////////
27 //
28 // mapWallet
29 //
30
31 struct CompareValueOnly
32 {
33     bool operator()(const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t1,
34                     const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t2) const
35     {
36         return t1.first < t2.first;
37     }
38 };
39
40 const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
41 {
42     LOCK(cs_wallet);
43     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
44     if (it == mapWallet.end())
45         return NULL;
46     return &(it->second);
47 }
48
49 CPubKey CWallet::GenerateNewKey()
50 {
51     AssertLockHeld(cs_wallet); // mapKeyMetadata
52     bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
53
54     RandAddSeedPerfmon();
55     CKey secret;
56     secret.MakeNewKey(fCompressed);
57
58     // Compressed public keys were introduced in version 0.6.0
59     if (fCompressed)
60         SetMinVersion(FEATURE_COMPRPUBKEY);
61
62     CPubKey pubkey = secret.GetPubKey();
63
64     // Create new metadata
65     int64_t nCreationTime = GetTime();
66     mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
67     if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
68         nTimeFirstKey = nCreationTime;
69
70     if (!AddKeyPubKey(secret, pubkey))
71         throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
72     return pubkey;
73 }
74
75 bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
76 {
77     AssertLockHeld(cs_wallet); // mapKeyMetadata
78     if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey))
79         return false;
80     if (!fFileBacked)
81         return true;
82     if (!IsCrypted()) {
83         return CWalletDB(strWalletFile).WriteKey(pubkey,
84                                                  secret.GetPrivKey(),
85                                                  mapKeyMetadata[pubkey.GetID()]);
86     }
87     return true;
88 }
89
90 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
91                             const vector<unsigned char> &vchCryptedSecret)
92 {
93     if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
94         return false;
95     if (!fFileBacked)
96         return true;
97     {
98         LOCK(cs_wallet);
99         if (pwalletdbEncryption)
100             return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
101                                                         vchCryptedSecret,
102                                                         mapKeyMetadata[vchPubKey.GetID()]);
103         else
104             return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
105                                                             vchCryptedSecret,
106                                                             mapKeyMetadata[vchPubKey.GetID()]);
107     }
108     return false;
109 }
110
111 bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
112 {
113     AssertLockHeld(cs_wallet); // mapKeyMetadata
114     if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
115         nTimeFirstKey = meta.nCreateTime;
116
117     mapKeyMetadata[pubkey.GetID()] = meta;
118     return true;
119 }
120
121 bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
122 {
123     return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
124 }
125
126 bool CWallet::AddCScript(const CScript& redeemScript)
127 {
128     if (!CCryptoKeyStore::AddCScript(redeemScript))
129         return false;
130     if (!fFileBacked)
131         return true;
132     return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
133 }
134
135 bool CWallet::LoadCScript(const CScript& redeemScript)
136 {
137     /* A sanity check was added in pull #3843 to avoid adding redeemScripts
138      * that never can be redeemed. However, old wallets may still contain
139      * these. Do not add them to the wallet and warn. */
140     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
141     {
142         std::string strAddr = CBitcoinAddress(redeemScript.GetID()).ToString();
143         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",
144             __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
145         return true;
146     }
147
148     return CCryptoKeyStore::AddCScript(redeemScript);
149 }
150
151 bool CWallet::AddWatchOnly(const CScript &dest)
152 {
153     if (!CCryptoKeyStore::AddWatchOnly(dest))
154         return false;
155     nTimeFirstKey = 1; // No birthday information for watch-only keys.
156     if (!fFileBacked)
157         return true;
158     return CWalletDB(strWalletFile).WriteWatchOnly(dest);
159 }
160
161 bool CWallet::LoadWatchOnly(const CScript &dest)
162 {
163     return CCryptoKeyStore::AddWatchOnly(dest);
164 }
165
166 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
167 {
168     CCrypter crypter;
169     CKeyingMaterial vMasterKey;
170
171     {
172         LOCK(cs_wallet);
173         BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
174         {
175             if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
176                 return false;
177             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
178                 continue; // try another master key
179             if (CCryptoKeyStore::Unlock(vMasterKey))
180                 return true;
181         }
182     }
183     return false;
184 }
185
186 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
187 {
188     bool fWasLocked = IsLocked();
189
190     {
191         LOCK(cs_wallet);
192         Lock();
193
194         CCrypter crypter;
195         CKeyingMaterial vMasterKey;
196         BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
197         {
198             if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
199                 return false;
200             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
201                 return false;
202             if (CCryptoKeyStore::Unlock(vMasterKey))
203             {
204                 int64_t nStartTime = GetTimeMillis();
205                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
206                 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
207
208                 nStartTime = GetTimeMillis();
209                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
210                 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
211
212                 if (pMasterKey.second.nDeriveIterations < 25000)
213                     pMasterKey.second.nDeriveIterations = 25000;
214
215                 LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
216
217                 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
218                     return false;
219                 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
220                     return false;
221                 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
222                 if (fWasLocked)
223                     Lock();
224                 return true;
225             }
226         }
227     }
228
229     return false;
230 }
231
232 void CWallet::SetBestChain(const CBlockLocator& loc)
233 {
234     CWalletDB walletdb(strWalletFile);
235     walletdb.WriteBestBlock(loc);
236 }
237
238 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
239 {
240     LOCK(cs_wallet); // nWalletVersion
241     if (nWalletVersion >= nVersion)
242         return true;
243
244     // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
245     if (fExplicit && nVersion > nWalletMaxVersion)
246             nVersion = FEATURE_LATEST;
247
248     nWalletVersion = nVersion;
249
250     if (nVersion > nWalletMaxVersion)
251         nWalletMaxVersion = nVersion;
252
253     if (fFileBacked)
254     {
255         CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
256         if (nWalletVersion > 40000)
257             pwalletdb->WriteMinVersion(nWalletVersion);
258         if (!pwalletdbIn)
259             delete pwalletdb;
260     }
261
262     return true;
263 }
264
265 bool CWallet::SetMaxVersion(int nVersion)
266 {
267     LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
268     // cannot downgrade below current version
269     if (nWalletVersion > nVersion)
270         return false;
271
272     nWalletMaxVersion = nVersion;
273
274     return true;
275 }
276
277 set<uint256> CWallet::GetConflicts(const uint256& txid) const
278 {
279     set<uint256> result;
280     AssertLockHeld(cs_wallet);
281
282     std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
283     if (it == mapWallet.end())
284         return result;
285     const CWalletTx& wtx = it->second;
286
287     std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
288
289     BOOST_FOREACH(const CTxIn& txin, wtx.vin)
290     {
291         if (mapTxSpends.count(txin.prevout) <= 1)
292             continue;  // No conflict if zero or one spends
293         range = mapTxSpends.equal_range(txin.prevout);
294         for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
295             result.insert(it->second);
296     }
297     return result;
298 }
299
300 void CWallet::SyncMetaData(pair<TxSpends::iterator, TxSpends::iterator> range)
301 {
302     // We want all the wallet transactions in range to have the same metadata as
303     // the oldest (smallest nOrderPos).
304     // So: find smallest nOrderPos:
305
306     int nMinOrderPos = std::numeric_limits<int>::max();
307     const CWalletTx* copyFrom = NULL;
308     for (TxSpends::iterator it = range.first; it != range.second; ++it)
309     {
310         const uint256& hash = it->second;
311         int n = mapWallet[hash].nOrderPos;
312         if (n < nMinOrderPos)
313         {
314             nMinOrderPos = n;
315             copyFrom = &mapWallet[hash];
316         }
317     }
318     // Now copy data from copyFrom to rest:
319     for (TxSpends::iterator it = range.first; it != range.second; ++it)
320     {
321         const uint256& hash = it->second;
322         CWalletTx* copyTo = &mapWallet[hash];
323         if (copyFrom == copyTo) continue;
324         copyTo->mapValue = copyFrom->mapValue;
325         copyTo->vOrderForm = copyFrom->vOrderForm;
326         // fTimeReceivedIsTxTime not copied on purpose
327         // nTimeReceived not copied on purpose
328         copyTo->nTimeSmart = copyFrom->nTimeSmart;
329         copyTo->fFromMe = copyFrom->fFromMe;
330         copyTo->strFromAccount = copyFrom->strFromAccount;
331         // nOrderPos not copied on purpose
332         // cached members not copied on purpose
333     }
334 }
335
336 // Outpoint is spent if any non-conflicted transaction
337 // spends it:
338 bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
339 {
340     const COutPoint outpoint(hash, n);
341     pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
342     range = mapTxSpends.equal_range(outpoint);
343
344     for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
345     {
346         const uint256& wtxid = it->second;
347         std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
348         if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
349             return true; // Spent
350     }
351     return false;
352 }
353
354 void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
355 {
356     mapTxSpends.insert(make_pair(outpoint, wtxid));
357
358     pair<TxSpends::iterator, TxSpends::iterator> range;
359     range = mapTxSpends.equal_range(outpoint);
360     SyncMetaData(range);
361 }
362
363
364 void CWallet::AddToSpends(const uint256& wtxid)
365 {
366     assert(mapWallet.count(wtxid));
367     CWalletTx& thisTx = mapWallet[wtxid];
368     if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
369         return;
370
371     BOOST_FOREACH(const CTxIn& txin, thisTx.vin)
372         AddToSpends(txin.prevout, wtxid);
373 }
374
375 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
376 {
377     if (IsCrypted())
378         return false;
379
380     CKeyingMaterial vMasterKey;
381     RandAddSeedPerfmon();
382
383     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
384     if (!GetRandBytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE))
385         return false;
386
387     CMasterKey kMasterKey;
388     RandAddSeedPerfmon();
389
390     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
391     if (!GetRandBytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE))
392         return false;
393
394     CCrypter crypter;
395     int64_t nStartTime = GetTimeMillis();
396     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
397     kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
398
399     nStartTime = GetTimeMillis();
400     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
401     kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
402
403     if (kMasterKey.nDeriveIterations < 25000)
404         kMasterKey.nDeriveIterations = 25000;
405
406     LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
407
408     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
409         return false;
410     if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
411         return false;
412
413     {
414         LOCK(cs_wallet);
415         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
416         if (fFileBacked)
417         {
418             pwalletdbEncryption = new CWalletDB(strWalletFile);
419             if (!pwalletdbEncryption->TxnBegin())
420                 return false;
421             pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
422         }
423
424         if (!EncryptKeys(vMasterKey))
425         {
426             if (fFileBacked)
427                 pwalletdbEncryption->TxnAbort();
428             exit(1); //We now probably have half of our keys encrypted in memory, and half not...die and let the user reload their unencrypted wallet.
429         }
430
431         // Encryption was introduced in version 0.4.0
432         SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
433
434         if (fFileBacked)
435         {
436             if (!pwalletdbEncryption->TxnCommit())
437                 exit(1); //We now have keys encrypted in memory, but no on disk...die to avoid confusion and let the user reload their unencrypted wallet.
438
439             delete pwalletdbEncryption;
440             pwalletdbEncryption = NULL;
441         }
442
443         Lock();
444         Unlock(strWalletPassphrase);
445         NewKeyPool();
446         Lock();
447
448         // Need to completely rewrite the wallet file; if we don't, bdb might keep
449         // bits of the unencrypted private key in slack space in the database file.
450         CDB::Rewrite(strWalletFile);
451
452     }
453     NotifyStatusChanged(this);
454
455     return true;
456 }
457
458 int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
459 {
460     AssertLockHeld(cs_wallet); // nOrderPosNext
461     int64_t nRet = nOrderPosNext++;
462     if (pwalletdb) {
463         pwalletdb->WriteOrderPosNext(nOrderPosNext);
464     } else {
465         CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
466     }
467     return nRet;
468 }
469
470 CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
471 {
472     AssertLockHeld(cs_wallet); // mapWallet
473     CWalletDB walletdb(strWalletFile);
474
475     // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
476     TxItems txOrdered;
477
478     // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
479     // would make this much faster for applications that do this a lot.
480     for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
481     {
482         CWalletTx* wtx = &((*it).second);
483         txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
484     }
485     acentries.clear();
486     walletdb.ListAccountCreditDebit(strAccount, acentries);
487     BOOST_FOREACH(CAccountingEntry& entry, acentries)
488     {
489         txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
490     }
491
492     return txOrdered;
493 }
494
495 void CWallet::MarkDirty()
496 {
497     {
498         LOCK(cs_wallet);
499         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
500             item.second.MarkDirty();
501     }
502 }
503
504 bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet)
505 {
506     uint256 hash = wtxIn.GetHash();
507
508     if (fFromLoadWallet)
509     {
510         mapWallet[hash] = wtxIn;
511         mapWallet[hash].BindWallet(this);
512         AddToSpends(hash);
513     }
514     else
515     {
516         LOCK(cs_wallet);
517         // Inserts only if not already there, returns tx inserted or tx found
518         pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
519         CWalletTx& wtx = (*ret.first).second;
520         wtx.BindWallet(this);
521         bool fInsertedNew = ret.second;
522         if (fInsertedNew)
523         {
524             wtx.nTimeReceived = GetAdjustedTime();
525             wtx.nOrderPos = IncOrderPosNext();
526
527             wtx.nTimeSmart = wtx.nTimeReceived;
528             if (wtxIn.hashBlock != 0)
529             {
530                 if (mapBlockIndex.count(wtxIn.hashBlock))
531                 {
532                     int64_t latestNow = wtx.nTimeReceived;
533                     int64_t latestEntry = 0;
534                     {
535                         // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
536                         int64_t latestTolerated = latestNow + 300;
537                         std::list<CAccountingEntry> acentries;
538                         TxItems txOrdered = OrderedTxItems(acentries);
539                         for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
540                         {
541                             CWalletTx *const pwtx = (*it).second.first;
542                             if (pwtx == &wtx)
543                                 continue;
544                             CAccountingEntry *const pacentry = (*it).second.second;
545                             int64_t nSmartTime;
546                             if (pwtx)
547                             {
548                                 nSmartTime = pwtx->nTimeSmart;
549                                 if (!nSmartTime)
550                                     nSmartTime = pwtx->nTimeReceived;
551                             }
552                             else
553                                 nSmartTime = pacentry->nTime;
554                             if (nSmartTime <= latestTolerated)
555                             {
556                                 latestEntry = nSmartTime;
557                                 if (nSmartTime > latestNow)
558                                     latestNow = nSmartTime;
559                                 break;
560                             }
561                         }
562                     }
563
564                     int64_t blocktime = mapBlockIndex[wtxIn.hashBlock]->GetBlockTime();
565                     wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
566                 }
567                 else
568                     LogPrintf("AddToWallet() : found %s in block %s not in index\n",
569                              wtxIn.GetHash().ToString(),
570                              wtxIn.hashBlock.ToString());
571             }
572             AddToSpends(hash);
573         }
574
575         bool fUpdated = false;
576         if (!fInsertedNew)
577         {
578             // Merge
579             if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
580             {
581                 wtx.hashBlock = wtxIn.hashBlock;
582                 fUpdated = true;
583             }
584             if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
585             {
586                 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
587                 wtx.nIndex = wtxIn.nIndex;
588                 fUpdated = true;
589             }
590             if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
591             {
592                 wtx.fFromMe = wtxIn.fFromMe;
593                 fUpdated = true;
594             }
595         }
596
597         //// debug print
598         LogPrintf("AddToWallet %s  %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
599
600         // Write to disk
601         if (fInsertedNew || fUpdated)
602             if (!wtx.WriteToDisk())
603                 return false;
604
605         // Break debit/credit balance caches:
606         wtx.MarkDirty();
607
608         // Notify UI of new or updated transaction
609         NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
610
611         // notify an external script when a wallet transaction comes in or is updated
612         std::string strCmd = GetArg("-walletnotify", "");
613
614         if ( !strCmd.empty())
615         {
616             boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
617             boost::thread t(runCommand, strCmd); // thread runs free
618         }
619
620     }
621     return true;
622 }
623
624 // Add a transaction to the wallet, or update it.
625 // pblock is optional, but should be provided if the transaction is known to be in a block.
626 // If fUpdate is true, existing transactions will be updated.
627 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate)
628 {
629     {
630         AssertLockHeld(cs_wallet);
631         bool fExisted = mapWallet.count(tx.GetHash());
632         if (fExisted && !fUpdate) return false;
633         if (fExisted || IsMine(tx) || IsFromMe(tx))
634         {
635             CWalletTx wtx(this,tx);
636             // Get merkle branch if transaction was found in a block
637             if (pblock)
638                 wtx.SetMerkleBranch(pblock);
639             return AddToWallet(wtx);
640         }
641     }
642     return false;
643 }
644
645 void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock)
646 {
647     LOCK2(cs_main, cs_wallet);
648     if (!AddToWalletIfInvolvingMe(tx, pblock, true))
649         return; // Not one of ours
650
651     // If a transaction changes 'conflicted' state, that changes the balance
652     // available of the outputs it spends. So force those to be
653     // recomputed, also:
654     BOOST_FOREACH(const CTxIn& txin, tx.vin)
655     {
656         if (mapWallet.count(txin.prevout.hash))
657             mapWallet[txin.prevout.hash].MarkDirty();
658     }
659 }
660
661 void CWallet::EraseFromWallet(const uint256 &hash)
662 {
663     if (!fFileBacked)
664         return;
665     {
666         LOCK(cs_wallet);
667         if (mapWallet.erase(hash))
668             CWalletDB(strWalletFile).EraseTx(hash);
669     }
670     return;
671 }
672
673
674 isminetype CWallet::IsMine(const CTxIn &txin) const
675 {
676     {
677         LOCK(cs_wallet);
678         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
679         if (mi != mapWallet.end())
680         {
681             const CWalletTx& prev = (*mi).second;
682             if (txin.prevout.n < prev.vout.size())
683                 return IsMine(prev.vout[txin.prevout.n]);
684         }
685     }
686     return ISMINE_NO;
687 }
688
689 int64_t CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
690 {
691     {
692         LOCK(cs_wallet);
693         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
694         if (mi != mapWallet.end())
695         {
696             const CWalletTx& prev = (*mi).second;
697             if (txin.prevout.n < prev.vout.size())
698                 if (IsMine(prev.vout[txin.prevout.n]) & filter)
699                     return prev.vout[txin.prevout.n].nValue;
700         }
701     }
702     return 0;
703 }
704
705 bool CWallet::IsChange(const CTxOut& txout) const
706 {
707     // TODO: fix handling of 'change' outputs. The assumption is that any
708     // payment to a script that is ours, but is not in the address book
709     // is change. That assumption is likely to break when we implement multisignature
710     // wallets that return change back into a multi-signature-protected address;
711     // a better way of identifying which outputs are 'the send' and which are
712     // 'the change' will need to be implemented (maybe extend CWalletTx to remember
713     // which output, if any, was change).
714     if (::IsMine(*this, txout.scriptPubKey))
715     {
716         CTxDestination address;
717         if (!ExtractDestination(txout.scriptPubKey, address))
718             return true;
719
720         LOCK(cs_wallet);
721         if (!mapAddressBook.count(address))
722             return true;
723     }
724     return false;
725 }
726
727 int64_t CWalletTx::GetTxTime() const
728 {
729     int64_t n = nTimeSmart;
730     return n ? n : nTimeReceived;
731 }
732
733 int CWalletTx::GetRequestCount() const
734 {
735     // Returns -1 if it wasn't being tracked
736     int nRequests = -1;
737     {
738         LOCK(pwallet->cs_wallet);
739         if (IsCoinBase())
740         {
741             // Generated block
742             if (hashBlock != 0)
743             {
744                 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
745                 if (mi != pwallet->mapRequestCount.end())
746                     nRequests = (*mi).second;
747             }
748         }
749         else
750         {
751             // Did anyone request this transaction?
752             map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
753             if (mi != pwallet->mapRequestCount.end())
754             {
755                 nRequests = (*mi).second;
756
757                 // How about the block it's in?
758                 if (nRequests == 0 && hashBlock != 0)
759                 {
760                     map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
761                     if (mi != pwallet->mapRequestCount.end())
762                         nRequests = (*mi).second;
763                     else
764                         nRequests = 1; // If it's in someone else's block it must have got out
765                 }
766             }
767         }
768     }
769     return nRequests;
770 }
771
772 void CWalletTx::GetAmounts(list<COutputEntry>& listReceived,
773                            list<COutputEntry>& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const
774 {
775     nFee = 0;
776     listReceived.clear();
777     listSent.clear();
778     strSentAccount = strFromAccount;
779
780     // Compute fee:
781     int64_t nDebit = GetDebit(filter);
782     if (nDebit > 0) // debit>0 means we signed/sent this transaction
783     {
784         int64_t nValueOut = GetValueOut();
785         nFee = nDebit - nValueOut;
786     }
787
788     // Sent/received.
789     for (unsigned int i = 0; i < vout.size(); ++i)
790     {
791         const CTxOut& txout = vout[i];
792         isminetype fIsMine = pwallet->IsMine(txout);
793         // Only need to handle txouts if AT LEAST one of these is true:
794         //   1) they debit from us (sent)
795         //   2) the output is to us (received)
796         if (nDebit > 0)
797         {
798             // Don't report 'change' txouts
799             if (pwallet->IsChange(txout))
800                 continue;
801         }
802         else if (!(fIsMine & filter))
803             continue;
804
805         // In either case, we need to get the destination address
806         CTxDestination address;
807         if (!ExtractDestination(txout.scriptPubKey, address))
808         {
809             LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
810                      this->GetHash().ToString());
811             address = CNoDestination();
812         }
813
814         COutputEntry output = {address, txout.nValue, (int)i};
815
816         // If we are debited by the transaction, add the output as a "sent" entry
817         if (nDebit > 0)
818             listSent.push_back(output);
819
820         // If we are receiving the output, add it as a "received" entry
821         if (fIsMine & filter)
822             listReceived.push_back(output);
823     }
824
825 }
826
827 void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nReceived,
828                                   int64_t& nSent, int64_t& nFee, const isminefilter& filter) const
829 {
830     nReceived = nSent = nFee = 0;
831
832     int64_t allFee;
833     string strSentAccount;
834     list<COutputEntry> listReceived;
835     list<COutputEntry> listSent;
836     GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
837
838     if (strAccount == strSentAccount)
839     {
840         BOOST_FOREACH(const COutputEntry& s, listSent)
841             nSent += s.amount;
842         nFee = allFee;
843     }
844     {
845         LOCK(pwallet->cs_wallet);
846         BOOST_FOREACH(const COutputEntry& r, listReceived)
847         {
848             if (pwallet->mapAddressBook.count(r.destination))
849             {
850                 map<CTxDestination, CAddressBookData>::const_iterator mi = pwallet->mapAddressBook.find(r.destination);
851                 if (mi != pwallet->mapAddressBook.end() && (*mi).second.name == strAccount)
852                     nReceived += r.amount;
853             }
854             else if (strAccount.empty())
855             {
856                 nReceived += r.amount;
857             }
858         }
859     }
860 }
861
862
863 bool CWalletTx::WriteToDisk()
864 {
865     return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
866 }
867
868 // Scan the block chain (starting in pindexStart) for transactions
869 // from or to us. If fUpdate is true, found transactions that already
870 // exist in the wallet will be updated.
871 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
872 {
873     int ret = 0;
874     int64_t nNow = GetTime();
875
876     CBlockIndex* pindex = pindexStart;
877     {
878         LOCK2(cs_main, cs_wallet);
879
880         // no need to read and scan block, if block was created before
881         // our wallet birthday (as adjusted for block time variability)
882         while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - 7200)))
883             pindex = chainActive.Next(pindex);
884
885         ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
886         double dProgressStart = Checkpoints::GuessVerificationProgress(pindex, false);
887         double dProgressTip = Checkpoints::GuessVerificationProgress(chainActive.Tip(), false);
888         while (pindex)
889         {
890             if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
891                 ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((Checkpoints::GuessVerificationProgress(pindex, false) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
892
893             CBlock block;
894             ReadBlockFromDisk(block, pindex);
895             BOOST_FOREACH(CTransaction& tx, block.vtx)
896             {
897                 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
898                     ret++;
899             }
900             pindex = chainActive.Next(pindex);
901             if (GetTime() >= nNow + 60) {
902                 nNow = GetTime();
903                 LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(pindex));
904             }
905         }
906         ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
907     }
908     return ret;
909 }
910
911 void CWallet::ReacceptWalletTransactions()
912 {
913     LOCK2(cs_main, cs_wallet);
914     BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
915     {
916         const uint256& wtxid = item.first;
917         CWalletTx& wtx = item.second;
918         assert(wtx.GetHash() == wtxid);
919
920         int nDepth = wtx.GetDepthInMainChain();
921
922         if (!wtx.IsCoinBase() && nDepth < 0)
923         {
924             // Try to add to memory pool
925             LOCK(mempool.cs);
926             wtx.AcceptToMemoryPool(false);
927         }
928     }
929 }
930
931 void CWalletTx::RelayWalletTransaction()
932 {
933     if (!IsCoinBase())
934     {
935         if (GetDepthInMainChain() == 0) {
936             LogPrintf("Relaying wtx %s\n", GetHash().ToString());
937             RelayTransaction((CTransaction)*this);
938         }
939     }
940 }
941
942 set<uint256> CWalletTx::GetConflicts() const
943 {
944     set<uint256> result;
945     if (pwallet != NULL)
946     {
947         uint256 myHash = GetHash();
948         result = pwallet->GetConflicts(myHash);
949         result.erase(myHash);
950     }
951     return result;
952 }
953
954 void CWallet::ResendWalletTransactions()
955 {
956     // Do this infrequently and randomly to avoid giving away
957     // that these are our transactions.
958     if (GetTime() < nNextResend)
959         return;
960     bool fFirst = (nNextResend == 0);
961     nNextResend = GetTime() + GetRand(30 * 60);
962     if (fFirst)
963         return;
964
965     // Only do it if there's been a new block since last time
966     if (nTimeBestReceived < nLastResend)
967         return;
968     nLastResend = GetTime();
969
970     // Rebroadcast any of our txes that aren't in a block yet
971     LogPrintf("ResendWalletTransactions()\n");
972     {
973         LOCK(cs_wallet);
974         // Sort them in chronological order
975         multimap<unsigned int, CWalletTx*> mapSorted;
976         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
977         {
978             CWalletTx& wtx = item.second;
979             // Don't rebroadcast until it's had plenty of time that
980             // it should have gotten in already by now.
981             if (nTimeBestReceived - (int64_t)wtx.nTimeReceived > 5 * 60)
982                 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
983         }
984         BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
985         {
986             CWalletTx& wtx = *item.second;
987             wtx.RelayWalletTransaction();
988         }
989     }
990 }
991
992
993
994
995
996
997 //////////////////////////////////////////////////////////////////////////////
998 //
999 // Actions
1000 //
1001
1002
1003 int64_t CWallet::GetBalance() const
1004 {
1005     int64_t nTotal = 0;
1006     {
1007         LOCK2(cs_main, cs_wallet);
1008         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1009         {
1010             const CWalletTx* pcoin = &(*it).second;
1011             if (pcoin->IsTrusted())
1012                 nTotal += pcoin->GetAvailableCredit();
1013         }
1014     }
1015
1016     return nTotal;
1017 }
1018
1019 int64_t CWallet::GetUnconfirmedBalance() const
1020 {
1021     int64_t nTotal = 0;
1022     {
1023         LOCK2(cs_main, cs_wallet);
1024         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1025         {
1026             const CWalletTx* pcoin = &(*it).second;
1027             if (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
1028                 nTotal += pcoin->GetAvailableCredit();
1029         }
1030     }
1031     return nTotal;
1032 }
1033
1034 int64_t CWallet::GetImmatureBalance() const
1035 {
1036     int64_t nTotal = 0;
1037     {
1038         LOCK2(cs_main, cs_wallet);
1039         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1040         {
1041             const CWalletTx* pcoin = &(*it).second;
1042             nTotal += pcoin->GetImmatureCredit();
1043         }
1044     }
1045     return nTotal;
1046 }
1047
1048 int64_t CWallet::GetWatchOnlyBalance() const
1049 {
1050     int64_t nTotal = 0;
1051     {
1052         LOCK2(cs_main, cs_wallet);
1053         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1054         {
1055             const CWalletTx* pcoin = &(*it).second;
1056             if (pcoin->IsTrusted())
1057                 nTotal += pcoin->GetAvailableWatchOnlyCredit();
1058         }
1059     }
1060     
1061     return nTotal;
1062 }
1063
1064 int64_t CWallet::GetUnconfirmedWatchOnlyBalance() const
1065 {
1066     int64_t nTotal = 0;
1067     {
1068         LOCK2(cs_main, cs_wallet);
1069         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1070         {
1071             const CWalletTx* pcoin = &(*it).second;
1072             if (!IsFinalTx(*pcoin) || (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0))
1073                 nTotal += pcoin->GetAvailableWatchOnlyCredit();
1074         }
1075     }
1076     return nTotal;
1077 }
1078
1079 int64_t CWallet::GetImmatureWatchOnlyBalance() const
1080 {
1081     int64_t nTotal = 0;
1082     {
1083         LOCK2(cs_main, cs_wallet);
1084         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1085         {
1086             const CWalletTx* pcoin = &(*it).second;
1087             nTotal += pcoin->GetImmatureWatchOnlyCredit();
1088         }
1089     }
1090     return nTotal;
1091 }
1092
1093 // populate vCoins with vector of available COutputs.
1094 void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const
1095 {
1096     vCoins.clear();
1097
1098     {
1099         LOCK2(cs_main, cs_wallet);
1100         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1101         {
1102             const uint256& wtxid = it->first;
1103             const CWalletTx* pcoin = &(*it).second;
1104
1105             if (!IsFinalTx(*pcoin))
1106                 continue;
1107
1108             if (fOnlyConfirmed && !pcoin->IsTrusted())
1109                 continue;
1110
1111             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1112                 continue;
1113
1114             int nDepth = pcoin->GetDepthInMainChain();
1115             if (nDepth < 0)
1116                 continue;
1117
1118             for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
1119                 isminetype mine = IsMine(pcoin->vout[i]);
1120                 if (!(IsSpent(wtxid, i)) && mine != ISMINE_NO &&
1121                     !IsLockedCoin((*it).first, i) && pcoin->vout[i].nValue > 0 &&
1122                     (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
1123                         vCoins.push_back(COutput(pcoin, i, nDepth, mine & ISMINE_SPENDABLE));
1124             }
1125         }
1126     }
1127 }
1128
1129 static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > >vValue, int64_t nTotalLower, int64_t nTargetValue,
1130                                   vector<char>& vfBest, int64_t& nBest, int iterations = 1000)
1131 {
1132     vector<char> vfIncluded;
1133
1134     vfBest.assign(vValue.size(), true);
1135     nBest = nTotalLower;
1136
1137     seed_insecure_rand();
1138
1139     for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
1140     {
1141         vfIncluded.assign(vValue.size(), false);
1142         int64_t nTotal = 0;
1143         bool fReachedTarget = false;
1144         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
1145         {
1146             for (unsigned int i = 0; i < vValue.size(); i++)
1147             {
1148                 //The solver here uses a randomized algorithm,
1149                 //the randomness serves no real security purpose but is just
1150                 //needed to prevent degenerate behavior and it is important
1151                 //that the rng fast. We do not use a constant random sequence,
1152                 //because there may be some privacy improvement by making
1153                 //the selection random.
1154                 if (nPass == 0 ? insecure_rand()&1 : !vfIncluded[i])
1155                 {
1156                     nTotal += vValue[i].first;
1157                     vfIncluded[i] = true;
1158                     if (nTotal >= nTargetValue)
1159                     {
1160                         fReachedTarget = true;
1161                         if (nTotal < nBest)
1162                         {
1163                             nBest = nTotal;
1164                             vfBest = vfIncluded;
1165                         }
1166                         nTotal -= vValue[i].first;
1167                         vfIncluded[i] = false;
1168                     }
1169                 }
1170             }
1171         }
1172     }
1173 }
1174
1175 bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, int nConfMine, int nConfTheirs, vector<COutput> vCoins,
1176                                  set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const
1177 {
1178     setCoinsRet.clear();
1179     nValueRet = 0;
1180
1181     // List of values less than target
1182     pair<int64_t, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
1183     coinLowestLarger.first = std::numeric_limits<int64_t>::max();
1184     coinLowestLarger.second.first = NULL;
1185     vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > > vValue;
1186     int64_t nTotalLower = 0;
1187
1188     random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
1189
1190     BOOST_FOREACH(const COutput &output, vCoins)
1191     {
1192         if (!output.fSpendable)
1193             continue;
1194
1195         const CWalletTx *pcoin = output.tx;
1196
1197         if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
1198             continue;
1199
1200         int i = output.i;
1201         int64_t n = pcoin->vout[i].nValue;
1202
1203         pair<int64_t,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
1204
1205         if (n == nTargetValue)
1206         {
1207             setCoinsRet.insert(coin.second);
1208             nValueRet += coin.first;
1209             return true;
1210         }
1211         else if (n < nTargetValue + CENT)
1212         {
1213             vValue.push_back(coin);
1214             nTotalLower += n;
1215         }
1216         else if (n < coinLowestLarger.first)
1217         {
1218             coinLowestLarger = coin;
1219         }
1220     }
1221
1222     if (nTotalLower == nTargetValue)
1223     {
1224         for (unsigned int i = 0; i < vValue.size(); ++i)
1225         {
1226             setCoinsRet.insert(vValue[i].second);
1227             nValueRet += vValue[i].first;
1228         }
1229         return true;
1230     }
1231
1232     if (nTotalLower < nTargetValue)
1233     {
1234         if (coinLowestLarger.second.first == NULL)
1235             return false;
1236         setCoinsRet.insert(coinLowestLarger.second);
1237         nValueRet += coinLowestLarger.first;
1238         return true;
1239     }
1240
1241     // Solve subset sum by stochastic approximation
1242     sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
1243     vector<char> vfBest;
1244     int64_t nBest;
1245
1246     ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
1247     if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
1248         ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
1249
1250     // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
1251     //                                   or the next bigger coin is closer), return the bigger coin
1252     if (coinLowestLarger.second.first &&
1253         ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
1254     {
1255         setCoinsRet.insert(coinLowestLarger.second);
1256         nValueRet += coinLowestLarger.first;
1257     }
1258     else {
1259         for (unsigned int i = 0; i < vValue.size(); i++)
1260             if (vfBest[i])
1261             {
1262                 setCoinsRet.insert(vValue[i].second);
1263                 nValueRet += vValue[i].first;
1264             }
1265
1266         LogPrint("selectcoins", "SelectCoins() best subset: ");
1267         for (unsigned int i = 0; i < vValue.size(); i++)
1268             if (vfBest[i])
1269                 LogPrint("selectcoins", "%s ", FormatMoney(vValue[i].first));
1270         LogPrint("selectcoins", "total %s\n", FormatMoney(nBest));
1271     }
1272
1273     return true;
1274 }
1275
1276 bool CWallet::SelectCoins(int64_t nTargetValue, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl* coinControl) const
1277 {
1278     vector<COutput> vCoins;
1279     AvailableCoins(vCoins, true, coinControl);
1280
1281     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
1282     if (coinControl && coinControl->HasSelected())
1283     {
1284         BOOST_FOREACH(const COutput& out, vCoins)
1285         {
1286             if(!out.fSpendable)
1287                 continue;
1288             nValueRet += out.tx->vout[out.i].nValue;
1289             setCoinsRet.insert(make_pair(out.tx, out.i));
1290         }
1291         return (nValueRet >= nTargetValue);
1292     }
1293
1294     return (SelectCoinsMinConf(nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) ||
1295             SelectCoinsMinConf(nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) ||
1296             (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue, 0, 1, vCoins, setCoinsRet, nValueRet)));
1297 }
1298
1299
1300
1301
1302 bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
1303                                 CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
1304 {
1305     int64_t nValue = 0;
1306     BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend)
1307     {
1308         if (nValue < 0)
1309         {
1310             strFailReason = _("Transaction amounts must be positive");
1311             return false;
1312         }
1313         nValue += s.second;
1314     }
1315     if (vecSend.empty() || nValue < 0)
1316     {
1317         strFailReason = _("Transaction amounts must be positive");
1318         return false;
1319     }
1320
1321     wtxNew.fTimeReceivedIsTxTime = true;
1322     wtxNew.BindWallet(this);
1323     CMutableTransaction txNew;
1324
1325     {
1326         LOCK2(cs_main, cs_wallet);
1327         {
1328             nFeeRet = payTxFee.GetFeePerK();
1329             while (true)
1330             {
1331                 txNew.vin.clear();
1332                 txNew.vout.clear();
1333                 wtxNew.fFromMe = true;
1334
1335                 int64_t nTotalValue = nValue + nFeeRet;
1336                 double dPriority = 0;
1337                 // vouts to the payees
1338                 BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend)
1339                 {
1340                     CTxOut txout(s.second, s.first);
1341                     if (txout.IsDust(::minRelayTxFee))
1342                     {
1343                         strFailReason = _("Transaction amount too small");
1344                         return false;
1345                     }
1346                     txNew.vout.push_back(txout);
1347                 }
1348
1349                 // Choose coins to use
1350                 set<pair<const CWalletTx*,unsigned int> > setCoins;
1351                 int64_t nValueIn = 0;
1352                 if (!SelectCoins(nTotalValue, setCoins, nValueIn, coinControl))
1353                 {
1354                     strFailReason = _("Insufficient funds");
1355                     return false;
1356                 }
1357                 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1358                 {
1359                     int64_t nCredit = pcoin.first->vout[pcoin.second].nValue;
1360                     //The priority after the next block (depth+1) is used instead of the current,
1361                     //reflecting an assumption the user would accept a bit more delay for
1362                     //a chance at a free transaction.
1363                     dPriority += (double)nCredit * (pcoin.first->GetDepthInMainChain()+1);
1364                 }
1365
1366                 int64_t nChange = nValueIn - nValue - nFeeRet;
1367
1368                 if (nChange > 0)
1369                 {
1370                     // Fill a vout to ourself
1371                     // TODO: pass in scriptChange instead of reservekey so
1372                     // change transaction isn't always pay-to-bitcoin-address
1373                     CScript scriptChange;
1374
1375                     // coin control: send change to custom address
1376                     if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
1377                         scriptChange.SetDestination(coinControl->destChange);
1378
1379                     // no coin control: send change to newly generated address
1380                     else
1381                     {
1382                         // Note: We use a new key here to keep it from being obvious which side is the change.
1383                         //  The drawback is that by not reusing a previous key, the change may be lost if a
1384                         //  backup is restored, if the backup doesn't have the new private key for the change.
1385                         //  If we reused the old key, it would be possible to add code to look for and
1386                         //  rediscover unknown transactions that were written with keys of ours to recover
1387                         //  post-backup change.
1388
1389                         // Reserve a new key pair from key pool
1390                         CPubKey vchPubKey;
1391                         bool ret;
1392                         ret = reservekey.GetReservedKey(vchPubKey);
1393                         assert(ret); // should never fail, as we just unlocked
1394
1395                         scriptChange.SetDestination(vchPubKey.GetID());
1396                     }
1397
1398                     CTxOut newTxOut(nChange, scriptChange);
1399
1400                     // Never create dust outputs; if we would, just
1401                     // add the dust to the fee.
1402                     if (newTxOut.IsDust(::minRelayTxFee))
1403                     {
1404                         nFeeRet += nChange;
1405                         reservekey.ReturnKey();
1406                     }
1407                     else
1408                     {
1409                         // Insert change txn at random position:
1410                         vector<CTxOut>::iterator position = txNew.vout.begin()+GetRandInt(txNew.vout.size()+1);
1411                         txNew.vout.insert(position, newTxOut);
1412                     }
1413                 }
1414                 else
1415                     reservekey.ReturnKey();
1416
1417                 // Fill vin
1418                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1419                     txNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
1420
1421                 // Sign
1422                 int nIn = 0;
1423                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1424                     if (!SignSignature(*this, *coin.first, txNew, nIn++))
1425                     {
1426                         strFailReason = _("Signing transaction failed");
1427                         return false;
1428                     }
1429
1430                 // Embed the constructed transaction data in wtxNew.
1431                 *static_cast<CTransaction*>(&wtxNew) = CTransaction(txNew);
1432
1433                 // Limit size
1434                 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
1435                 if (nBytes >= MAX_STANDARD_TX_SIZE)
1436                 {
1437                     strFailReason = _("Transaction too large");
1438                     return false;
1439                 }
1440                 dPriority = wtxNew.ComputePriority(dPriority, nBytes);
1441
1442                 int64_t nFeeNeeded = GetMinimumFee(nBytes, nTxConfirmTarget, mempool);
1443
1444                 if (nFeeRet >= nFeeNeeded)
1445                     break; // Done, enough fee included.
1446
1447                 // Too big to send for free? Include more fee and try again:
1448                 if (nBytes > MAX_FREE_TRANSACTION_CREATE_SIZE)
1449                 {
1450                     nFeeRet = nFeeNeeded;
1451                     continue;
1452                 }
1453
1454                 // Not enough fee: enough priority?
1455                 double dPriorityNeeded = mempool.estimatePriority(nTxConfirmTarget);
1456                 // Not enough mempool history to estimate: use hard-coded AllowFree.
1457                 if (dPriorityNeeded <= 0 && AllowFree(dPriority))
1458                     break;
1459
1460                 // Small enough, and priority high enough, to send for free
1461                 if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
1462                     break;
1463
1464                 // Include more fee and try again.
1465                 nFeeRet = nFeeNeeded;
1466                 continue;
1467             }
1468         }
1469     }
1470     return true;
1471 }
1472
1473 bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue,
1474                                 CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, std::string& strFailReason, const CCoinControl* coinControl)
1475 {
1476     vector< pair<CScript, int64_t> > vecSend;
1477     vecSend.push_back(make_pair(scriptPubKey, nValue));
1478     return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl);
1479 }
1480
1481 // Call after CreateTransaction unless you want to abort
1482 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
1483 {
1484     {
1485         LOCK2(cs_main, cs_wallet);
1486         LogPrintf("CommitTransaction:\n%s", wtxNew.ToString());
1487         {
1488             // This is only to keep the database open to defeat the auto-flush for the
1489             // duration of this scope.  This is the only place where this optimization
1490             // maybe makes sense; please don't do it anywhere else.
1491             CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
1492
1493             // Take key pair from key pool so it won't be used again
1494             reservekey.KeepKey();
1495
1496             // Add tx to wallet, because if it has change it's also ours,
1497             // otherwise just for transaction history.
1498             AddToWallet(wtxNew);
1499
1500             // Notify that old coins are spent
1501             set<CWalletTx*> setCoins;
1502             BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
1503             {
1504                 CWalletTx &coin = mapWallet[txin.prevout.hash];
1505                 coin.BindWallet(this);
1506                 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
1507             }
1508
1509             if (fFileBacked)
1510                 delete pwalletdb;
1511         }
1512
1513         // Track how many getdata requests our transaction gets
1514         mapRequestCount[wtxNew.GetHash()] = 0;
1515
1516         // Broadcast
1517         if (!wtxNew.AcceptToMemoryPool(false))
1518         {
1519             // This must not fail. The transaction has already been signed and recorded.
1520             LogPrintf("CommitTransaction() : Error: Transaction not valid");
1521             return false;
1522         }
1523         wtxNew.RelayWalletTransaction();
1524     }
1525     return true;
1526 }
1527
1528
1529
1530
1531 string CWallet::SendMoney(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew)
1532 {
1533     // Check amount
1534     if (nValue <= 0)
1535         return _("Invalid amount");
1536     if (nValue > GetBalance())
1537         return _("Insufficient funds");
1538
1539     string strError;
1540     if (IsLocked())
1541     {
1542         strError = _("Error: Wallet locked, unable to create transaction!");
1543         LogPrintf("SendMoney() : %s", strError);
1544         return strError;
1545     }
1546
1547     // Parse Bitcoin address
1548     CScript scriptPubKey;
1549     scriptPubKey.SetDestination(address);
1550
1551     // Create and send the transaction
1552     CReserveKey reservekey(this);
1553     int64_t nFeeRequired;
1554     if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError))
1555     {
1556         if (nValue + nFeeRequired > GetBalance())
1557             strError = strprintf(_("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!"), FormatMoney(nFeeRequired));
1558         LogPrintf("SendMoney() : %s\n", strError);
1559         return strError;
1560     }
1561     if (!CommitTransaction(wtxNew, reservekey))
1562         return _("Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
1563
1564     return "";
1565 }
1566
1567
1568
1569 int64_t CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarget, const CTxMemPool& pool)
1570 {
1571     // payTxFee is user-set "I want to pay this much"
1572     int64_t nFeeNeeded = payTxFee.GetFee(nTxBytes);
1573     // User didn't set: use -txconfirmtarget to estimate...
1574     if (nFeeNeeded == 0)
1575         nFeeNeeded = pool.estimateFee(nConfirmTarget).GetFee(nTxBytes);
1576     // ... unless we don't have enough mempool data, in which case fall
1577     // back to a hard-coded fee
1578     if (nFeeNeeded == 0)
1579         nFeeNeeded = minTxFee.GetFee(nTxBytes);
1580     return nFeeNeeded;
1581 }
1582
1583
1584
1585
1586 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
1587 {
1588     if (!fFileBacked)
1589         return DB_LOAD_OK;
1590     fFirstRunRet = false;
1591     DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
1592     if (nLoadWalletRet == DB_NEED_REWRITE)
1593     {
1594         if (CDB::Rewrite(strWalletFile, "\x04pool"))
1595         {
1596             LOCK(cs_wallet);
1597             setKeyPool.clear();
1598             // Note: can't top-up keypool here, because wallet is locked.
1599             // User will be prompted to unlock wallet the next operation
1600             // the requires a new key.
1601         }
1602     }
1603
1604     if (nLoadWalletRet != DB_LOAD_OK)
1605         return nLoadWalletRet;
1606     fFirstRunRet = !vchDefaultKey.IsValid();
1607
1608     uiInterface.LoadWallet(this);
1609
1610     return DB_LOAD_OK;
1611 }
1612
1613
1614 DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
1615 {
1616     if (!fFileBacked)
1617         return DB_LOAD_OK;
1618     DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this, vWtx);
1619     if (nZapWalletTxRet == DB_NEED_REWRITE)
1620     {
1621         if (CDB::Rewrite(strWalletFile, "\x04pool"))
1622         {
1623             LOCK(cs_wallet);
1624             setKeyPool.clear();
1625             // Note: can't top-up keypool here, because wallet is locked.
1626             // User will be prompted to unlock wallet the next operation
1627             // the requires a new key.
1628         }
1629     }
1630
1631     if (nZapWalletTxRet != DB_LOAD_OK)
1632         return nZapWalletTxRet;
1633
1634     return DB_LOAD_OK;
1635 }
1636
1637
1638 bool CWallet::SetAddressBook(const CTxDestination& address, const string& strName, const string& strPurpose)
1639 {
1640     bool fUpdated = false;
1641     {
1642         LOCK(cs_wallet); // mapAddressBook
1643         std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
1644         fUpdated = mi != mapAddressBook.end();
1645         mapAddressBook[address].name = strName;
1646         if (!strPurpose.empty()) /* update purpose only if requested */
1647             mapAddressBook[address].purpose = strPurpose;
1648     }
1649     NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address),
1650                              strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
1651     if (!fFileBacked)
1652         return false;
1653     if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
1654         return false;
1655     return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
1656 }
1657
1658 bool CWallet::DelAddressBook(const CTxDestination& address)
1659 {
1660     {
1661         LOCK(cs_wallet); // mapAddressBook
1662
1663         if(fFileBacked)
1664         {
1665             // Delete destdata tuples associated with address
1666             std::string strAddress = CBitcoinAddress(address).ToString();
1667             BOOST_FOREACH(const PAIRTYPE(string, string) &item, mapAddressBook[address].destdata)
1668             {
1669                 CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
1670             }
1671         }
1672         mapAddressBook.erase(address);
1673     }
1674
1675     NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), "", CT_DELETED);
1676
1677     if (!fFileBacked)
1678         return false;
1679     CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
1680     return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
1681 }
1682
1683 bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
1684 {
1685     if (fFileBacked)
1686     {
1687         if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
1688             return false;
1689     }
1690     vchDefaultKey = vchPubKey;
1691     return true;
1692 }
1693
1694 //
1695 // Mark old keypool keys as used,
1696 // and generate all new keys
1697 //
1698 bool CWallet::NewKeyPool()
1699 {
1700     {
1701         LOCK(cs_wallet);
1702         CWalletDB walletdb(strWalletFile);
1703         BOOST_FOREACH(int64_t nIndex, setKeyPool)
1704             walletdb.ErasePool(nIndex);
1705         setKeyPool.clear();
1706
1707         if (IsLocked())
1708             return false;
1709
1710         int64_t nKeys = max(GetArg("-keypool", 100), (int64_t)0);
1711         for (int i = 0; i < nKeys; i++)
1712         {
1713             int64_t nIndex = i+1;
1714             walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
1715             setKeyPool.insert(nIndex);
1716         }
1717         LogPrintf("CWallet::NewKeyPool wrote %d new keys\n", nKeys);
1718     }
1719     return true;
1720 }
1721
1722 bool CWallet::TopUpKeyPool(unsigned int kpSize)
1723 {
1724     {
1725         LOCK(cs_wallet);
1726
1727         if (IsLocked())
1728             return false;
1729
1730         CWalletDB walletdb(strWalletFile);
1731
1732         // Top up key pool
1733         unsigned int nTargetSize;
1734         if (kpSize > 0)
1735             nTargetSize = kpSize;
1736         else
1737             nTargetSize = max(GetArg("-keypool", 100), (int64_t) 0);
1738
1739         while (setKeyPool.size() < (nTargetSize + 1))
1740         {
1741             int64_t nEnd = 1;
1742             if (!setKeyPool.empty())
1743                 nEnd = *(--setKeyPool.end()) + 1;
1744             if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
1745                 throw runtime_error("TopUpKeyPool() : writing generated key failed");
1746             setKeyPool.insert(nEnd);
1747             LogPrintf("keypool added key %d, size=%u\n", nEnd, setKeyPool.size());
1748         }
1749     }
1750     return true;
1751 }
1752
1753 void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
1754 {
1755     nIndex = -1;
1756     keypool.vchPubKey = CPubKey();
1757     {
1758         LOCK(cs_wallet);
1759
1760         if (!IsLocked())
1761             TopUpKeyPool();
1762
1763         // Get the oldest key
1764         if(setKeyPool.empty())
1765             return;
1766
1767         CWalletDB walletdb(strWalletFile);
1768
1769         nIndex = *(setKeyPool.begin());
1770         setKeyPool.erase(setKeyPool.begin());
1771         if (!walletdb.ReadPool(nIndex, keypool))
1772             throw runtime_error("ReserveKeyFromKeyPool() : read failed");
1773         if (!HaveKey(keypool.vchPubKey.GetID()))
1774             throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
1775         assert(keypool.vchPubKey.IsValid());
1776         LogPrintf("keypool reserve %d\n", nIndex);
1777     }
1778 }
1779
1780 void CWallet::KeepKey(int64_t nIndex)
1781 {
1782     // Remove from key pool
1783     if (fFileBacked)
1784     {
1785         CWalletDB walletdb(strWalletFile);
1786         walletdb.ErasePool(nIndex);
1787     }
1788     LogPrintf("keypool keep %d\n", nIndex);
1789 }
1790
1791 void CWallet::ReturnKey(int64_t nIndex)
1792 {
1793     // Return to key pool
1794     {
1795         LOCK(cs_wallet);
1796         setKeyPool.insert(nIndex);
1797     }
1798     LogPrintf("keypool return %d\n", nIndex);
1799 }
1800
1801 bool CWallet::GetKeyFromPool(CPubKey& result)
1802 {
1803     int64_t nIndex = 0;
1804     CKeyPool keypool;
1805     {
1806         LOCK(cs_wallet);
1807         ReserveKeyFromKeyPool(nIndex, keypool);
1808         if (nIndex == -1)
1809         {
1810             if (IsLocked()) return false;
1811             result = GenerateNewKey();
1812             return true;
1813         }
1814         KeepKey(nIndex);
1815         result = keypool.vchPubKey;
1816     }
1817     return true;
1818 }
1819
1820 int64_t CWallet::GetOldestKeyPoolTime()
1821 {
1822     int64_t nIndex = 0;
1823     CKeyPool keypool;
1824     ReserveKeyFromKeyPool(nIndex, keypool);
1825     if (nIndex == -1)
1826         return GetTime();
1827     ReturnKey(nIndex);
1828     return keypool.nTime;
1829 }
1830
1831 std::map<CTxDestination, int64_t> CWallet::GetAddressBalances()
1832 {
1833     map<CTxDestination, int64_t> balances;
1834
1835     {
1836         LOCK(cs_wallet);
1837         BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
1838         {
1839             CWalletTx *pcoin = &walletEntry.second;
1840
1841             if (!IsFinalTx(*pcoin) || !pcoin->IsTrusted())
1842                 continue;
1843
1844             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1845                 continue;
1846
1847             int nDepth = pcoin->GetDepthInMainChain();
1848             if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
1849                 continue;
1850
1851             for (unsigned int i = 0; i < pcoin->vout.size(); i++)
1852             {
1853                 CTxDestination addr;
1854                 if (!IsMine(pcoin->vout[i]))
1855                     continue;
1856                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
1857                     continue;
1858
1859                 int64_t n = IsSpent(walletEntry.first, i) ? 0 : pcoin->vout[i].nValue;
1860
1861                 if (!balances.count(addr))
1862                     balances[addr] = 0;
1863                 balances[addr] += n;
1864             }
1865         }
1866     }
1867
1868     return balances;
1869 }
1870
1871 set< set<CTxDestination> > CWallet::GetAddressGroupings()
1872 {
1873     AssertLockHeld(cs_wallet); // mapWallet
1874     set< set<CTxDestination> > groupings;
1875     set<CTxDestination> grouping;
1876
1877     BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
1878     {
1879         CWalletTx *pcoin = &walletEntry.second;
1880
1881         if (pcoin->vin.size() > 0)
1882         {
1883             bool any_mine = false;
1884             // group all input addresses with each other
1885             BOOST_FOREACH(CTxIn txin, pcoin->vin)
1886             {
1887                 CTxDestination address;
1888                 if(!IsMine(txin)) /* If this input isn't mine, ignore it */
1889                     continue;
1890                 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
1891                     continue;
1892                 grouping.insert(address);
1893                 any_mine = true;
1894             }
1895
1896             // group change with input addresses
1897             if (any_mine)
1898             {
1899                BOOST_FOREACH(CTxOut txout, pcoin->vout)
1900                    if (IsChange(txout))
1901                    {
1902                        CTxDestination txoutAddr;
1903                        if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
1904                            continue;
1905                        grouping.insert(txoutAddr);
1906                    }
1907             }
1908             if (grouping.size() > 0)
1909             {
1910                 groupings.insert(grouping);
1911                 grouping.clear();
1912             }
1913         }
1914
1915         // group lone addrs by themselves
1916         for (unsigned int i = 0; i < pcoin->vout.size(); i++)
1917             if (IsMine(pcoin->vout[i]))
1918             {
1919                 CTxDestination address;
1920                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
1921                     continue;
1922                 grouping.insert(address);
1923                 groupings.insert(grouping);
1924                 grouping.clear();
1925             }
1926     }
1927
1928     set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
1929     map< CTxDestination, set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
1930     BOOST_FOREACH(set<CTxDestination> grouping, groupings)
1931     {
1932         // make a set of all the groups hit by this new group
1933         set< set<CTxDestination>* > hits;
1934         map< CTxDestination, set<CTxDestination>* >::iterator it;
1935         BOOST_FOREACH(CTxDestination address, grouping)
1936             if ((it = setmap.find(address)) != setmap.end())
1937                 hits.insert((*it).second);
1938
1939         // merge all hit groups into a new single group and delete old groups
1940         set<CTxDestination>* merged = new set<CTxDestination>(grouping);
1941         BOOST_FOREACH(set<CTxDestination>* hit, hits)
1942         {
1943             merged->insert(hit->begin(), hit->end());
1944             uniqueGroupings.erase(hit);
1945             delete hit;
1946         }
1947         uniqueGroupings.insert(merged);
1948
1949         // update setmap
1950         BOOST_FOREACH(CTxDestination element, *merged)
1951             setmap[element] = merged;
1952     }
1953
1954     set< set<CTxDestination> > ret;
1955     BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
1956     {
1957         ret.insert(*uniqueGrouping);
1958         delete uniqueGrouping;
1959     }
1960
1961     return ret;
1962 }
1963
1964 set<CTxDestination> CWallet::GetAccountAddresses(string strAccount) const
1965 {
1966     AssertLockHeld(cs_wallet); // mapWallet
1967     set<CTxDestination> result;
1968     BOOST_FOREACH(const PAIRTYPE(CTxDestination, CAddressBookData)& item, mapAddressBook)
1969     {
1970         const CTxDestination& address = item.first;
1971         const string& strName = item.second.name;
1972         if (strName == strAccount)
1973             result.insert(address);
1974     }
1975     return result;
1976 }
1977
1978 bool CReserveKey::GetReservedKey(CPubKey& pubkey)
1979 {
1980     if (nIndex == -1)
1981     {
1982         CKeyPool keypool;
1983         pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
1984         if (nIndex != -1)
1985             vchPubKey = keypool.vchPubKey;
1986         else {
1987             return false;
1988         }
1989     }
1990     assert(vchPubKey.IsValid());
1991     pubkey = vchPubKey;
1992     return true;
1993 }
1994
1995 void CReserveKey::KeepKey()
1996 {
1997     if (nIndex != -1)
1998         pwallet->KeepKey(nIndex);
1999     nIndex = -1;
2000     vchPubKey = CPubKey();
2001 }
2002
2003 void CReserveKey::ReturnKey()
2004 {
2005     if (nIndex != -1)
2006         pwallet->ReturnKey(nIndex);
2007     nIndex = -1;
2008     vchPubKey = CPubKey();
2009 }
2010
2011 void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
2012 {
2013     setAddress.clear();
2014
2015     CWalletDB walletdb(strWalletFile);
2016
2017     LOCK2(cs_main, cs_wallet);
2018     BOOST_FOREACH(const int64_t& id, setKeyPool)
2019     {
2020         CKeyPool keypool;
2021         if (!walletdb.ReadPool(id, keypool))
2022             throw runtime_error("GetAllReserveKeyHashes() : read failed");
2023         assert(keypool.vchPubKey.IsValid());
2024         CKeyID keyID = keypool.vchPubKey.GetID();
2025         if (!HaveKey(keyID))
2026             throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
2027         setAddress.insert(keyID);
2028     }
2029 }
2030
2031 void CWallet::UpdatedTransaction(const uint256 &hashTx)
2032 {
2033     {
2034         LOCK(cs_wallet);
2035         // Only notify UI if this transaction is in this wallet
2036         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
2037         if (mi != mapWallet.end())
2038             NotifyTransactionChanged(this, hashTx, CT_UPDATED);
2039     }
2040 }
2041
2042 void CWallet::LockCoin(COutPoint& output)
2043 {
2044     AssertLockHeld(cs_wallet); // setLockedCoins
2045     setLockedCoins.insert(output);
2046 }
2047
2048 void CWallet::UnlockCoin(COutPoint& output)
2049 {
2050     AssertLockHeld(cs_wallet); // setLockedCoins
2051     setLockedCoins.erase(output);
2052 }
2053
2054 void CWallet::UnlockAllCoins()
2055 {
2056     AssertLockHeld(cs_wallet); // setLockedCoins
2057     setLockedCoins.clear();
2058 }
2059
2060 bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
2061 {
2062     AssertLockHeld(cs_wallet); // setLockedCoins
2063     COutPoint outpt(hash, n);
2064
2065     return (setLockedCoins.count(outpt) > 0);
2066 }
2067
2068 void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts)
2069 {
2070     AssertLockHeld(cs_wallet); // setLockedCoins
2071     for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
2072          it != setLockedCoins.end(); it++) {
2073         COutPoint outpt = (*it);
2074         vOutpts.push_back(outpt);
2075     }
2076 }
2077
2078 void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
2079     AssertLockHeld(cs_wallet); // mapKeyMetadata
2080     mapKeyBirth.clear();
2081
2082     // get birth times for keys with metadata
2083     for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
2084         if (it->second.nCreateTime)
2085             mapKeyBirth[it->first] = it->second.nCreateTime;
2086
2087     // map in which we'll infer heights of other keys
2088     CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganised; use a 144-block safety margin
2089     std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
2090     std::set<CKeyID> setKeys;
2091     GetKeys(setKeys);
2092     BOOST_FOREACH(const CKeyID &keyid, setKeys) {
2093         if (mapKeyBirth.count(keyid) == 0)
2094             mapKeyFirstBlock[keyid] = pindexMax;
2095     }
2096     setKeys.clear();
2097
2098     // if there are no such keys, we're done
2099     if (mapKeyFirstBlock.empty())
2100         return;
2101
2102     // find first block that affects those keys, if there are any left
2103     std::vector<CKeyID> vAffected;
2104     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
2105         // iterate over all wallet transactions...
2106         const CWalletTx &wtx = (*it).second;
2107         std::map<uint256, CBlockIndex*>::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
2108         if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
2109             // ... which are already in a block
2110             int nHeight = blit->second->nHeight;
2111             BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
2112                 // iterate over all their outputs
2113                 ::ExtractAffectedKeys(*this, txout.scriptPubKey, vAffected);
2114                 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
2115                     // ... and all their affected keys
2116                     std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
2117                     if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
2118                         rit->second = blit->second;
2119                 }
2120                 vAffected.clear();
2121             }
2122         }
2123     }
2124
2125     // Extract block timestamps for those keys
2126     for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
2127         mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200; // block times can be 2h off
2128 }
2129
2130 bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
2131 {
2132     if (boost::get<CNoDestination>(&dest))
2133         return false;
2134
2135     mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
2136     if (!fFileBacked)
2137         return true;
2138     return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
2139 }
2140
2141 bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
2142 {
2143     if (!mapAddressBook[dest].destdata.erase(key))
2144         return false;
2145     if (!fFileBacked)
2146         return true;
2147     return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
2148 }
2149
2150 bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
2151 {
2152     mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
2153     return true;
2154 }
2155
2156 bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
2157 {
2158     std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
2159     if(i != mapAddressBook.end())
2160     {
2161         CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
2162         if(j != i->second.destdata.end())
2163         {
2164             if(value)
2165                 *value = j->second;
2166             return true;
2167         }
2168     }
2169     return false;
2170 }
This page took 0.146848 seconds and 4 git commands to generate.