Add -zapwallettxes cli/config option, used for wallet recovery
[novacoin.git] / src / wallet.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 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 "txdb.h"
7 #include "wallet.h"
8 #include "walletdb.h"
9 #include "crypter.h"
10 #include "ui_interface.h"
11 #include "base58.h"
12 #include "kernel.h"
13 #include "coincontrol.h"
14 #include <boost/algorithm/string/replace.hpp>
15
16 #include "main.h"
17
18 using namespace std;
19
20
21 bool fCoinsDataActual;
22
23 //////////////////////////////////////////////////////////////////////////////
24 //
25 // mapWallet
26 //
27
28 struct CompareValueOnly
29 {
30     bool operator()(const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t1,
31                     const pair<int64_t, pair<const CWalletTx*, unsigned int> >& t2) const
32     {
33         return t1.first < t2.first;
34     }
35 };
36
37 CPubKey CWallet::GenerateNewKey()
38 {
39     bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
40
41     RandAddSeedPerfmon();
42     CKey key;
43     key.MakeNewKey(fCompressed);
44
45     // Compressed public keys were introduced in version 0.6.0
46     if (fCompressed)
47         SetMinVersion(FEATURE_COMPRPUBKEY);
48
49     CPubKey pubkey = key.GetPubKey();
50
51     // Create new metadata
52     int64_t nCreationTime = GetTime();
53     mapKeyMetadata[pubkey.GetID()] = CKeyMetadata(nCreationTime);
54     if (!nTimeFirstKey || nCreationTime < nTimeFirstKey)
55         nTimeFirstKey = nCreationTime;
56
57     if (!AddKey(key))
58         throw std::runtime_error("CWallet::GenerateNewKey() : AddKey failed");
59     return key.GetPubKey();
60 }
61
62 bool CWallet::AddKey(const CKey& key)
63 {
64     CPubKey pubkey = key.GetPubKey();
65     if (!CCryptoKeyStore::AddKey(key))
66         return false;
67     if (!fFileBacked)
68         return true;
69     if (!IsCrypted())
70         return CWalletDB(strWalletFile).WriteKey(pubkey, key.GetPrivKey(), mapKeyMetadata[pubkey.GetID()]);
71     return true;
72 }
73
74 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey, const vector<unsigned char> &vchCryptedSecret)
75 {
76     if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
77         return false;
78
79     // check if we need to remove from watch-only
80     CScript script;
81     script.SetDestination(vchPubKey.GetID());
82     if (HaveWatchOnly(script))
83         RemoveWatchOnly(script);
84
85     if (!fFileBacked)
86         return true;
87     {
88         LOCK(cs_wallet);
89         if (pwalletdbEncryption)
90             return pwalletdbEncryption->WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
91         else
92             return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey, vchCryptedSecret, mapKeyMetadata[vchPubKey.GetID()]);
93     }
94     return false;
95 }
96
97 bool CWallet::LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &meta)
98 {
99     if (meta.nCreateTime && (!nTimeFirstKey || meta.nCreateTime < nTimeFirstKey))
100         nTimeFirstKey = meta.nCreateTime;
101
102     mapKeyMetadata[pubkey.GetID()] = meta;
103     return true;
104 }
105
106 bool CWallet::AddCScript(const CScript& redeemScript)
107 {
108     if (!CCryptoKeyStore::AddCScript(redeemScript))
109         return false;
110     if (!fFileBacked)
111         return true;
112     return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
113 }
114
115 bool CWallet::LoadCScript(const CScript& redeemScript)
116 {
117     /* A sanity check was added in commit 5ed0a2b to avoid adding redeemScripts
118      * that never can be redeemed. However, old wallets may still contain
119      * these. Do not add them to the wallet and warn. */
120     if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
121     {
122         std::string strAddr = CBitcoinAddress(redeemScript.GetID()).ToString();
123         printf("LoadCScript() : Warning: This wallet contains a redeemScript of size %" PRIszu " which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n",
124           redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr.c_str());
125           return true;
126     }
127
128     return CCryptoKeyStore::AddCScript(redeemScript);
129 }
130
131
132 bool CWallet::AddWatchOnly(const CScript &dest)
133 {
134     if (!CCryptoKeyStore::AddWatchOnly(dest))
135         return false;
136     nTimeFirstKey = 1; // No birthday information for watch-only keys.
137     NotifyWatchonlyChanged(true);
138     if (!fFileBacked)
139         return true;
140     return CWalletDB(strWalletFile).WriteWatchOnly(dest);
141 }
142
143 bool CWallet::RemoveWatchOnly(const CScript &dest)
144 {
145     LOCK(cs_wallet);
146     if (!CCryptoKeyStore::RemoveWatchOnly(dest))
147         return false;
148     if (!HaveWatchOnly())
149         NotifyWatchonlyChanged(false);
150     if (fFileBacked)
151         if (!CWalletDB(strWalletFile).EraseWatchOnly(dest))
152             return false;
153
154     return true;
155 }
156
157 bool CWallet::LoadWatchOnly(const CScript &dest)
158 {
159     return CCryptoKeyStore::AddWatchOnly(dest);
160 }
161
162 // ppcoin: optional setting to unlock wallet for block minting only;
163 //         serves to disable the trivial sendmoney when OS account compromised
164 bool fWalletUnlockMintOnly = false;
165
166 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
167 {
168     if (!IsLocked())
169         return false;
170
171     CCrypter crypter;
172     CKeyingMaterial vMasterKey;
173
174     {
175         LOCK(cs_wallet);
176         BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
177         {
178             if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
179                 return false;
180             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
181                 return false;
182             if (CCryptoKeyStore::Unlock(vMasterKey))
183                 return true;
184         }
185     }
186     return false;
187 }
188
189 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
190 {
191     bool fWasLocked = IsLocked();
192
193     {
194         LOCK(cs_wallet);
195         Lock();
196
197         CCrypter crypter;
198         CKeyingMaterial vMasterKey;
199         BOOST_FOREACH(MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
200         {
201             if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
202                 return false;
203             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
204                 return false;
205             if (CCryptoKeyStore::Unlock(vMasterKey))
206             {
207                 int64_t nStartTime = GetTimeMillis();
208                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
209                 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime)));
210
211                 nStartTime = GetTimeMillis();
212                 crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
213                 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
214
215                 if (pMasterKey.second.nDeriveIterations < 25000)
216                     pMasterKey.second.nDeriveIterations = 25000;
217
218                 printf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
219
220                 if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
221                     return false;
222                 if (!crypter.Encrypt(vMasterKey, pMasterKey.second.vchCryptedKey))
223                     return false;
224                 CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
225                 if (fWasLocked)
226                     Lock();
227                 return true;
228             }
229         }
230     }
231
232     return false;
233 }
234
235 void CWallet::SetBestChain(const CBlockLocator& loc)
236 {
237     CWalletDB walletdb(strWalletFile);
238     walletdb.WriteBestBlock(loc);
239 }
240
241 // This class implements an addrIncoming entry that causes pre-0.4
242 // clients to crash on startup if reading a private-key-encrypted wallet.
243 class CCorruptAddress
244 {
245 public:
246     IMPLEMENT_SERIALIZE
247     (
248         if (nType & SER_DISK)
249             READWRITE(nVersion);
250     )
251 };
252
253 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
254 {
255     if (nWalletVersion >= nVersion)
256         return true;
257
258     // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
259     if (fExplicit && nVersion > nWalletMaxVersion)
260             nVersion = FEATURE_LATEST;
261
262     nWalletVersion = nVersion;
263
264     if (nVersion > nWalletMaxVersion)
265         nWalletMaxVersion = nVersion;
266
267     if (fFileBacked)
268     {
269         CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
270         if (nWalletVersion > 40000)
271             pwalletdb->WriteMinVersion(nWalletVersion);
272         if (!pwalletdbIn)
273             delete pwalletdb;
274     }
275
276     return true;
277 }
278
279 bool CWallet::SetMaxVersion(int nVersion)
280 {
281     // cannot downgrade below current version
282     if (nWalletVersion > nVersion)
283         return false;
284
285     nWalletMaxVersion = nVersion;
286
287     return true;
288 }
289
290 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
291 {
292     if (IsCrypted())
293         return false;
294
295     CKeyingMaterial vMasterKey;
296     RandAddSeedPerfmon();
297
298     vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
299     RAND_bytes(&vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
300
301     CMasterKey kMasterKey;
302
303     RandAddSeedPerfmon();
304     kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
305     RAND_bytes(&kMasterKey.vchSalt[0], WALLET_CRYPTO_SALT_SIZE);
306
307     CCrypter crypter;
308     int64_t nStartTime = GetTimeMillis();
309     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
310     kMasterKey.nDeriveIterations = 2500000 / ((double)(GetTimeMillis() - nStartTime));
311
312     nStartTime = GetTimeMillis();
313     crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
314     kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime))) / 2;
315
316     if (kMasterKey.nDeriveIterations < 25000)
317         kMasterKey.nDeriveIterations = 25000;
318
319     printf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
320
321     if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
322         return false;
323     if (!crypter.Encrypt(vMasterKey, kMasterKey.vchCryptedKey))
324         return false;
325
326     {
327         LOCK(cs_wallet);
328         mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
329         if (fFileBacked)
330         {
331             pwalletdbEncryption = new CWalletDB(strWalletFile);
332             if (!pwalletdbEncryption->TxnBegin())
333                 return false;
334             pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
335         }
336
337         if (!EncryptKeys(vMasterKey))
338         {
339             if (fFileBacked)
340                 pwalletdbEncryption->TxnAbort();
341             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.
342         }
343
344         // Encryption was introduced in version 0.4.0
345         SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
346
347         if (fFileBacked)
348         {
349             if (!pwalletdbEncryption->TxnCommit())
350                 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.
351
352             delete pwalletdbEncryption;
353             pwalletdbEncryption = NULL;
354         }
355
356         Lock();
357         Unlock(strWalletPassphrase);
358         NewKeyPool();
359         Lock();
360
361         // Need to completely rewrite the wallet file; if we don't, bdb might keep
362         // bits of the unencrypted private key in slack space in the database file.
363         CDB::Rewrite(strWalletFile);
364
365     }
366     NotifyStatusChanged(this);
367
368     return true;
369 }
370
371 bool CWallet::DecryptWallet(const SecureString& strWalletPassphrase)
372 {
373     if (!IsCrypted())
374         return false;
375
376     CCrypter crypter;
377     CKeyingMaterial vMasterKey;
378
379     {
380         LOCK(cs_wallet);
381         BOOST_FOREACH(const MasterKeyMap::value_type& pMasterKey, mapMasterKeys)
382         {
383             if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
384                 return false;
385             if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, vMasterKey))
386                 return false;
387             if (!CCryptoKeyStore::Unlock(vMasterKey))
388                 return false;
389         }
390
391         if (fFileBacked)
392         {
393             pwalletdbDecryption = new CWalletDB(strWalletFile);
394             if (!pwalletdbDecryption->TxnBegin())
395                 return false;
396         }
397
398         if (!DecryptKeys(vMasterKey))
399         {
400             if (fFileBacked)
401                 pwalletdbDecryption->TxnAbort();
402             exit(1); //We now probably have half of our keys decrypted in memory, and half not...die and let the user reload their encrypted wallet.
403         }
404
405         if (fFileBacked)
406         {
407             // Overwrite crypted keys
408             KeyMap::const_iterator mi = mapKeys.begin();
409             while (mi != mapKeys.end())
410             {
411                 CKey key;
412                 key.SetSecret((*mi).second.first, (*mi).second.second);
413                 pwalletdbDecryption->EraseCryptedKey(key.GetPubKey());
414                 pwalletdbDecryption->WriteKey(key.GetPubKey(), key.GetPrivKey(), mapKeyMetadata[(*mi).first]);
415                 mi++;
416             }
417
418             // Erase master keys
419             MasterKeyMap::const_iterator mk = mapMasterKeys.begin();
420             while (mk != mapMasterKeys.end())
421             {
422                 pwalletdbDecryption->EraseMasterKey((*mk).first);
423                 mk++;
424             }
425
426             if (!pwalletdbDecryption->TxnCommit())
427                 exit(1); //We now have keys decrypted in memory, but no on disk...die to avoid confusion and let the user reload their encrypted wallet.
428
429             delete pwalletdbDecryption;
430             pwalletdbDecryption = NULL;
431         }
432
433         // Need to completely rewrite the wallet file; if we don't, bdb might keep
434         // encrypted private keys in the database file which can be a reason of consistency issues.
435         CDB::Rewrite(strWalletFile);
436     }
437     NotifyStatusChanged(this);
438
439     return true;
440 }
441
442 int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
443 {
444     int64_t nRet = nOrderPosNext++;
445     if (pwalletdb) {
446         pwalletdb->WriteOrderPosNext(nOrderPosNext);
447     } else {
448         CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
449     }
450     return nRet;
451 }
452
453 CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
454 {
455     CWalletDB walletdb(strWalletFile);
456
457     // First: get all CWalletTx and CAccountingEntry into a sorted-by-order multimap.
458     TxItems txOrdered;
459
460     // Note: maintaining indices in the database of (account,time) --> txid and (account, time) --> acentry
461     // would make this much faster for applications that do this a lot.
462     for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
463     {
464         CWalletTx* wtx = &((*it).second);
465         txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
466     }
467     acentries.clear();
468     walletdb.ListAccountCreditDebit(strAccount, acentries);
469     BOOST_FOREACH(CAccountingEntry& entry, acentries)
470     {
471         txOrdered.insert(make_pair(entry.nOrderPos, TxPair((CWalletTx*)0, &entry)));
472     }
473
474     return txOrdered;
475 }
476
477 void CWallet::WalletUpdateSpent(const CTransaction &tx, bool fBlock)
478 {
479     // Anytime a signature is successfully verified, it's proof the outpoint is spent.
480     // Update the wallet spent flag if it doesn't know due to wallet.dat being
481     // restored from backup or the user making copies of wallet.dat.
482     {
483         LOCK(cs_wallet);
484         BOOST_FOREACH(const CTxIn& txin, tx.vin)
485         {
486             map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
487             if (mi != mapWallet.end())
488             {
489                 CWalletTx& wtx = (*mi).second;
490                 if (txin.prevout.n >= wtx.vout.size())
491                     printf("WalletUpdateSpent: bad wtx %s\n", wtx.GetHash().ToString().c_str());
492                 else if (!wtx.IsSpent(txin.prevout.n) && IsMine(wtx.vout[txin.prevout.n]))
493                 {
494                     printf("WalletUpdateSpent found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit(MINE_ALL)).c_str(), wtx.GetHash().ToString().c_str());
495                     wtx.MarkSpent(txin.prevout.n);
496                     wtx.WriteToDisk();
497                     NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED);
498                     vMintingWalletUpdated.push_back(txin.prevout.hash);
499                 }
500             }
501         }
502
503         if (fBlock)
504         {
505             uint256 hash = tx.GetHash();
506             map<uint256, CWalletTx>::iterator mi = mapWallet.find(hash);
507             CWalletTx& wtx = (*mi).second;
508
509             BOOST_FOREACH(const CTxOut& txout, tx.vout)
510             {
511                 if (IsMine(txout))
512                 {
513                     wtx.MarkUnspent(&txout - &tx.vout[0]);
514                     wtx.WriteToDisk();
515                     NotifyTransactionChanged(this, hash, CT_UPDATED);
516                     vMintingWalletUpdated.push_back(hash);
517                 }
518             }
519         }
520
521     }
522 }
523
524 void CWallet::MarkDirty()
525 {
526     {
527         LOCK(cs_wallet);
528         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
529             item.second.MarkDirty();
530     }
531 }
532
533 bool CWallet::AddToWallet(const CWalletTx& wtxIn)
534 {
535     uint256 hash = wtxIn.GetHash();
536     {
537         LOCK(cs_wallet);
538         // Inserts only if not already there, returns tx inserted or tx found
539         pair<map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(make_pair(hash, wtxIn));
540         CWalletTx& wtx = (*ret.first).second;
541         wtx.BindWallet(this);
542         bool fInsertedNew = ret.second;
543         if (fInsertedNew)
544         {
545             wtx.nTimeReceived = GetAdjustedTime();
546             wtx.nOrderPos = IncOrderPosNext();
547
548             wtx.nTimeSmart = wtx.nTimeReceived;
549             if (wtxIn.hashBlock != 0)
550             {
551                 if (mapBlockIndex.count(wtxIn.hashBlock))
552                 {
553                     unsigned int latestNow = wtx.nTimeReceived;
554                     unsigned int latestEntry = 0;
555                     {
556                         // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
557                         int64_t latestTolerated = latestNow + 300;
558                         std::list<CAccountingEntry> acentries;
559                         TxItems txOrdered = OrderedTxItems(acentries);
560                         for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
561                         {
562                             CWalletTx *const pwtx = (*it).second.first;
563                             if (pwtx == &wtx)
564                                 continue;
565                             CAccountingEntry *const pacentry = (*it).second.second;
566                             int64_t nSmartTime;
567                             if (pwtx)
568                             {
569                                 nSmartTime = pwtx->nTimeSmart;
570                                 if (!nSmartTime)
571                                     nSmartTime = pwtx->nTimeReceived;
572                             }
573                             else
574                                 nSmartTime = pacentry->nTime;
575                             if (nSmartTime <= latestTolerated)
576                             {
577                                 latestEntry = nSmartTime;
578                                 if (nSmartTime > latestNow)
579                                     latestNow = nSmartTime;
580                                 break;
581                             }
582                         }
583                     }
584
585                     unsigned int& blocktime = mapBlockIndex[wtxIn.hashBlock]->nTime;
586                     wtx.nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
587                 }
588                 else
589                     printf("AddToWallet() : found %s in block %s not in index\n",
590                            wtxIn.GetHash().ToString().substr(0,10).c_str(),
591                            wtxIn.hashBlock.ToString().c_str());
592             }
593         }
594
595         bool fUpdated = false;
596         if (!fInsertedNew)
597         {
598             // Merge
599             if (wtxIn.hashBlock != 0 && wtxIn.hashBlock != wtx.hashBlock)
600             {
601                 wtx.hashBlock = wtxIn.hashBlock;
602                 fUpdated = true;
603             }
604             if (wtxIn.nIndex != -1 && (wtxIn.vMerkleBranch != wtx.vMerkleBranch || wtxIn.nIndex != wtx.nIndex))
605             {
606                 wtx.vMerkleBranch = wtxIn.vMerkleBranch;
607                 wtx.nIndex = wtxIn.nIndex;
608                 fUpdated = true;
609             }
610             if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
611             {
612                 wtx.fFromMe = wtxIn.fFromMe;
613                 fUpdated = true;
614             }
615             fUpdated |= wtx.UpdateSpent(wtxIn.vfSpent);
616         }
617
618         //// debug print
619         printf("AddToWallet %s  %s%s\n", wtxIn.GetHash().ToString().substr(0,10).c_str(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
620
621         // Write to disk
622         if (fInsertedNew || fUpdated)
623             if (!wtx.WriteToDisk())
624                 return false;
625 #ifndef QT_GUI
626         // If default receiving address gets used, replace it with a new one
627         CScript scriptDefaultKey;
628         scriptDefaultKey.SetDestination(vchDefaultKey.GetID());
629         BOOST_FOREACH(const CTxOut& txout, wtx.vout)
630         {
631             if (txout.scriptPubKey == scriptDefaultKey)
632             {
633                 CPubKey newDefaultKey;
634                 if (GetKeyFromPool(newDefaultKey, false))
635                 {
636                     SetDefaultKey(newDefaultKey);
637                     SetAddressBookName(vchDefaultKey.GetID(), "");
638                 }
639             }
640         }
641 #endif
642         // since AddToWallet is called directly for self-originating transactions, check for consumption of own coins
643         WalletUpdateSpent(wtx, (wtxIn.hashBlock != 0));
644
645         // Notify UI of new or updated transaction
646         NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
647         vMintingWalletUpdated.push_back(hash);
648         // notify an external script when a wallet transaction comes in or is updated
649         std::string strCmd = GetArg("-walletnotify", "");
650
651         if ( !strCmd.empty())
652         {
653             boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
654             boost::thread t(runCommand, strCmd); // thread runs free
655         }
656
657     }
658     return true;
659 }
660
661 // Add a transaction to the wallet, or update it.
662 // pblock is optional, but should be provided if the transaction is known to be in a block.
663 // If fUpdate is true, existing transactions will be updated.
664 bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate, bool fFindBlock)
665 {
666     uint256 hash = tx.GetHash();
667     {
668         LOCK(cs_wallet);
669         bool fExisted = mapWallet.count(hash);
670         if (fExisted && !fUpdate) return false;
671         if (fExisted || IsMine(tx) || IsFromMe(tx))
672         {
673             CWalletTx wtx(this,tx);
674             // Get merkle branch if transaction was found in a block
675             if (pblock)
676                 wtx.SetMerkleBranch(pblock);
677             return AddToWallet(wtx);
678         }
679         else
680             WalletUpdateSpent(tx);
681     }
682     return false;
683 }
684
685 bool CWallet::EraseFromWallet(uint256 hash)
686 {
687     if (!fFileBacked)
688         return false;
689     {
690         LOCK(cs_wallet);
691         if (mapWallet.erase(hash))
692             CWalletDB(strWalletFile).EraseTx(hash);
693     }
694     return true;
695 }
696
697
698 isminetype CWallet::IsMine(const CTxIn &txin) const
699 {
700     {
701         LOCK(cs_wallet);
702         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
703         if (mi != mapWallet.end())
704         {
705             const CWalletTx& prev = (*mi).second;
706             if (txin.prevout.n < prev.vout.size())
707                 return IsMine(prev.vout[txin.prevout.n]);
708         }
709     }
710     return MINE_NO;
711 }
712
713 int64_t CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const
714 {
715     {
716         LOCK(cs_wallet);
717         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
718         if (mi != mapWallet.end())
719         {
720             const CWalletTx& prev = (*mi).second;
721             if (txin.prevout.n < prev.vout.size())
722                 if (IsMine(prev.vout[txin.prevout.n]) & filter)
723                     return prev.vout[txin.prevout.n].nValue;
724         }
725     }
726     return 0;
727 }
728
729 bool CWallet::IsChange(const CTxOut& txout) const
730 {
731     // TODO: fix handling of 'change' outputs. The assumption is that any
732     // payment to a script that is ours, but isn't in the address book
733     // is change. That assumption is likely to break when we implement multisignature
734     // wallets that return change back into a multi-signature-protected address;
735     // a better way of identifying which outputs are 'the send' and which are
736     // 'the change' will need to be implemented (maybe extend CWalletTx to remember
737     // which output, if any, was change).
738     if (::IsMine(*this, txout.scriptPubKey))
739     {
740         CTxDestination address;
741         if (!ExtractDestination(txout.scriptPubKey, address))
742             return true;
743
744         LOCK(cs_wallet);
745         if (!mapAddressBook.count(address))
746             return true;
747     }
748     return false;
749 }
750
751 int64_t CWalletTx::GetTxTime() const
752 {
753     return nTime;
754 }
755
756 int CWalletTx::GetRequestCount() const
757 {
758     // Returns -1 if it wasn't being tracked
759     int nRequests = -1;
760     {
761         LOCK(pwallet->cs_wallet);
762         if (IsCoinBase() || IsCoinStake())
763         {
764             // Generated block
765             if (hashBlock != 0)
766             {
767                 map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
768                 if (mi != pwallet->mapRequestCount.end())
769                     nRequests = (*mi).second;
770             }
771         }
772         else
773         {
774             // Did anyone request this transaction?
775             map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
776             if (mi != pwallet->mapRequestCount.end())
777             {
778                 nRequests = (*mi).second;
779
780                 // How about the block it's in?
781                 if (nRequests == 0 && hashBlock != 0)
782                 {
783                     map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
784                     if (mi != pwallet->mapRequestCount.end())
785                         nRequests = (*mi).second;
786                     else
787                         nRequests = 1; // If it's in someone else's block it must have got out
788                 }
789             }
790         }
791     }
792     return nRequests;
793 }
794
795 void CWalletTx::GetAmounts(int64_t& nGeneratedImmature, int64_t& nGeneratedMature, list<pair<CTxDestination, int64_t> >& listReceived,
796                            list<pair<CTxDestination, int64_t> >& listSent, int64_t& nFee, string& strSentAccount, const isminefilter& filter) const
797 {
798     nGeneratedImmature = nGeneratedMature = nFee = 0;
799     listReceived.clear();
800     listSent.clear();
801     strSentAccount = strFromAccount;
802
803     if (IsCoinBase() || IsCoinStake())
804     {
805         if (GetBlocksToMaturity() > 0)
806             nGeneratedImmature = pwallet->GetCredit(*this, filter);
807         else
808             nGeneratedMature = GetCredit(filter);
809         return;
810     }
811
812     // Compute fee:
813     int64_t nDebit = GetDebit(filter);
814     if (nDebit > 0) // debit>0 means we signed/sent this transaction
815     {
816         int64_t nValueOut = GetValueOut();
817         nFee = nDebit - nValueOut;
818     }
819
820     // Sent/received.
821     BOOST_FOREACH(const CTxOut& txout, vout)
822     {
823         isminetype fIsMine = pwallet->IsMine(txout);
824         // Only need to handle txouts if AT LEAST one of these is true:
825         //   1) they debit from us (sent)
826         //   2) the output is to us (received)
827         if (nDebit > 0)
828         {
829             // Don't report 'change' txouts
830             if (pwallet->IsChange(txout))
831                 continue;
832         }
833         else if (!(fIsMine & filter))
834             continue;
835
836         // In either case, we need to get the destination address
837         CTxDestination address;
838         if (!ExtractDestination(txout.scriptPubKey, address))
839         {
840             printf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
841                    this->GetHash().ToString().c_str());
842             address = CNoDestination();
843         }
844
845         // If we are debited by the transaction, add the output as a "sent" entry
846         if (nDebit > 0)
847             listSent.push_back(make_pair(address, txout.nValue));
848
849         // If we are receiving the output, add it as a "received" entry
850         if (fIsMine & filter)
851             listReceived.push_back(make_pair(address, txout.nValue));
852     }
853
854 }
855
856 void CWalletTx::GetAccountAmounts(const string& strAccount, int64_t& nGenerated, int64_t& nReceived,
857                                   int64_t& nSent, int64_t& nFee, const isminefilter& filter) const
858 {
859     nGenerated = nReceived = nSent = nFee = 0;
860
861     int64_t allGeneratedImmature, allGeneratedMature, allFee;
862     allGeneratedImmature = allGeneratedMature = allFee = 0;
863     string strSentAccount;
864     list<pair<CTxDestination, int64_t> > listReceived;
865     list<pair<CTxDestination, int64_t> > listSent;
866     GetAmounts(allGeneratedImmature, allGeneratedMature, listReceived, listSent, allFee, strSentAccount, filter);
867
868     if (strAccount == "")
869         nGenerated = allGeneratedMature;
870     if (strAccount == strSentAccount)
871     {
872         BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& s, listSent)
873             nSent += s.second;
874         nFee = allFee;
875     }
876     {
877         LOCK(pwallet->cs_wallet);
878         BOOST_FOREACH(const PAIRTYPE(CTxDestination,int64_t)& r, listReceived)
879         {
880             if (pwallet->mapAddressBook.count(r.first))
881             {
882                 map<CTxDestination, string>::const_iterator mi = pwallet->mapAddressBook.find(r.first);
883                 if (mi != pwallet->mapAddressBook.end() && (*mi).second == strAccount)
884                     nReceived += r.second;
885             }
886             else if (strAccount.empty())
887             {
888                 nReceived += r.second;
889             }
890         }
891     }
892 }
893
894 void CWalletTx::AddSupportingTransactions(CTxDB& txdb)
895 {
896     vtxPrev.clear();
897
898     const int COPY_DEPTH = 3;
899     if (SetMerkleBranch() < COPY_DEPTH)
900     {
901         vector<uint256> vWorkQueue;
902         BOOST_FOREACH(const CTxIn& txin, vin)
903             vWorkQueue.push_back(txin.prevout.hash);
904
905         // This critsect is OK because txdb is already open
906         {
907             LOCK(pwallet->cs_wallet);
908             map<uint256, const CMerkleTx*> mapWalletPrev;
909             set<uint256> setAlreadyDone;
910             for (unsigned int i = 0; i < vWorkQueue.size(); i++)
911             {
912                 uint256 hash = vWorkQueue[i];
913                 if (setAlreadyDone.count(hash))
914                     continue;
915                 setAlreadyDone.insert(hash);
916
917                 CMerkleTx tx;
918                 map<uint256, CWalletTx>::const_iterator mi = pwallet->mapWallet.find(hash);
919                 if (mi != pwallet->mapWallet.end())
920                 {
921                     tx = (*mi).second;
922                     BOOST_FOREACH(const CMerkleTx& txWalletPrev, (*mi).second.vtxPrev)
923                         mapWalletPrev[txWalletPrev.GetHash()] = &txWalletPrev;
924                 }
925                 else if (mapWalletPrev.count(hash))
926                 {
927                     tx = *mapWalletPrev[hash];
928                 }
929                 else if (!fClient && txdb.ReadDiskTx(hash, tx))
930                 {
931                     ;
932                 }
933                 else
934                 {
935                     printf("ERROR: AddSupportingTransactions() : unsupported transaction\n");
936                     continue;
937                 }
938
939                 int nDepth = tx.SetMerkleBranch();
940                 vtxPrev.push_back(tx);
941
942                 if (nDepth < COPY_DEPTH)
943                 {
944                     BOOST_FOREACH(const CTxIn& txin, tx.vin)
945                         vWorkQueue.push_back(txin.prevout.hash);
946                 }
947             }
948         }
949     }
950
951     reverse(vtxPrev.begin(), vtxPrev.end());
952 }
953
954 bool CWalletTx::WriteToDisk()
955 {
956     return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this);
957 }
958
959 // Scan the block chain (starting in pindexStart) for transactions
960 // from or to us. If fUpdate is true, found transactions that already
961 // exist in the wallet will be updated.
962 int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
963 {
964     int ret = 0;
965
966     CBlockIndex* pindex = pindexStart;
967     {
968         LOCK(cs_wallet);
969         while (pindex)
970         {
971             CBlock block;
972             block.ReadFromDisk(pindex, true);
973             BOOST_FOREACH(CTransaction& tx, block.vtx)
974             {
975                 if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
976                     ret++;
977             }
978             pindex = pindex->pnext;
979         }
980     }
981     return ret;
982 }
983
984 int CWallet::ScanForWalletTransaction(const uint256& hashTx)
985 {
986     CTransaction tx;
987     tx.ReadFromDisk(COutPoint(hashTx, 0));
988     if (AddToWalletIfInvolvingMe(tx, NULL, true, true))
989         return 1;
990     return 0;
991 }
992
993 void CWallet::ReacceptWalletTransactions()
994 {
995     CTxDB txdb("r");
996     bool fRepeat = true;
997     while (fRepeat)
998     {
999         LOCK(cs_wallet);
1000         fRepeat = false;
1001         vector<CDiskTxPos> vMissingTx;
1002         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
1003         {
1004             CWalletTx& wtx = item.second;
1005             if ((wtx.IsCoinBase() && wtx.IsSpent(0)) || (wtx.IsCoinStake() && wtx.IsSpent(1)))
1006                 continue;
1007
1008             CTxIndex txindex;
1009             bool fUpdated = false;
1010             if (txdb.ReadTxIndex(wtx.GetHash(), txindex))
1011             {
1012                 // Update fSpent if a tx got spent somewhere else by a copy of wallet.dat
1013                 if (txindex.vSpent.size() != wtx.vout.size())
1014                 {
1015                     printf("ERROR: ReacceptWalletTransactions() : txindex.vSpent.size() %" PRIszu " != wtx.vout.size() %" PRIszu "\n", txindex.vSpent.size(), wtx.vout.size());
1016                     continue;
1017                 }
1018                 for (unsigned int i = 0; i < txindex.vSpent.size(); i++)
1019                 {
1020                     if (wtx.IsSpent(i))
1021                         continue;
1022                     if (!txindex.vSpent[i].IsNull() && IsMine(wtx.vout[i]))
1023                     {
1024                         wtx.MarkSpent(i);
1025                         fUpdated = true;
1026                         vMissingTx.push_back(txindex.vSpent[i]);
1027                     }
1028                 }
1029                 if (fUpdated)
1030                 {
1031                     printf("ReacceptWalletTransactions found spent coin %snvc %s\n", FormatMoney(wtx.GetCredit(MINE_ALL)).c_str(), wtx.GetHash().ToString().c_str());
1032                     wtx.MarkDirty();
1033                     wtx.WriteToDisk();
1034                 }
1035             }
1036             else
1037             {
1038                 // Re-accept any txes of ours that aren't already in a block
1039                 if (!(wtx.IsCoinBase() || wtx.IsCoinStake()))
1040                     wtx.AcceptWalletTransaction(txdb, false);
1041             }
1042         }
1043         if (!vMissingTx.empty())
1044         {
1045             // TODO: optimize this to scan just part of the block chain?
1046             if (ScanForWalletTransactions(pindexGenesisBlock))
1047                 fRepeat = true;  // Found missing transactions: re-do re-accept.
1048         }
1049     }
1050 }
1051
1052 void CWalletTx::RelayWalletTransaction(CTxDB& txdb)
1053 {
1054     BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
1055     {
1056         if (!(tx.IsCoinBase() || tx.IsCoinStake()))
1057         {
1058             uint256 hash = tx.GetHash();
1059             if (!txdb.ContainsTx(hash))
1060                 RelayTransaction((CTransaction)tx, hash);
1061         }
1062     }
1063     if (!(IsCoinBase() || IsCoinStake()))
1064     {
1065         uint256 hash = GetHash();
1066         if (!txdb.ContainsTx(hash))
1067         {
1068             printf("Relaying wtx %s\n", hash.ToString().substr(0,10).c_str());
1069             RelayTransaction((CTransaction)*this, hash);
1070         }
1071     }
1072 }
1073
1074 void CWalletTx::RelayWalletTransaction()
1075 {
1076    CTxDB txdb("r");
1077    RelayWalletTransaction(txdb);
1078 }
1079
1080 void CWallet::ResendWalletTransactions()
1081 {
1082     // Do this infrequently and randomly to avoid giving away
1083     // that these are our transactions.
1084     static int64_t nNextTime;
1085     if (GetTime() < nNextTime)
1086         return;
1087     bool fFirst = (nNextTime == 0);
1088     nNextTime = GetTime() + GetRand(30 * 60);
1089     if (fFirst)
1090         return;
1091
1092     // Only do it if there's been a new block since last time
1093     static int64_t nLastTime;
1094     if (nTimeBestReceived < nLastTime)
1095         return;
1096     nLastTime = GetTime();
1097
1098     // Rebroadcast any of our txes that aren't in a block yet
1099     printf("ResendWalletTransactions()\n");
1100     CTxDB txdb("r");
1101     {
1102         LOCK(cs_wallet);
1103         // Sort them in chronological order
1104         multimap<unsigned int, CWalletTx*> mapSorted;
1105         BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
1106         {
1107             CWalletTx& wtx = item.second;
1108             // Don't rebroadcast until it's had plenty of time that
1109             // it should have gotten in already by now.
1110             if (nTimeBestReceived - (int64_t)wtx.nTimeReceived > 5 * 60)
1111                 mapSorted.insert(make_pair(wtx.nTimeReceived, &wtx));
1112         }
1113         BOOST_FOREACH(PAIRTYPE(const unsigned int, CWalletTx*)& item, mapSorted)
1114         {
1115             CWalletTx& wtx = *item.second;
1116             if (wtx.CheckTransaction())
1117                 wtx.RelayWalletTransaction(txdb);
1118             else
1119                 printf("ResendWalletTransactions() : CheckTransaction failed for transaction %s\n", wtx.GetHash().ToString().c_str());
1120         }
1121     }
1122 }
1123
1124
1125
1126
1127
1128
1129 //////////////////////////////////////////////////////////////////////////////
1130 //
1131 // Actions
1132 //
1133
1134
1135 int64_t CWallet::GetBalance() const
1136 {
1137     int64_t nTotal = 0;
1138     {
1139         LOCK(cs_wallet);
1140         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1141         {
1142             const CWalletTx* pcoin = &(*it).second;
1143             if (pcoin->IsTrusted())
1144                 nTotal += pcoin->GetAvailableCredit();
1145         }
1146     }
1147
1148     return nTotal;
1149 }
1150
1151 int64_t CWallet::GetWatchOnlyBalance() const
1152 {
1153     int64_t nTotal = 0;
1154     {
1155         LOCK(cs_wallet);
1156         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1157         {
1158             const CWalletTx* pcoin = &(*it).second;
1159             if (pcoin->IsTrusted())
1160                 nTotal += pcoin->GetAvailableWatchCredit();
1161         }
1162     }
1163
1164     return nTotal;
1165 }
1166
1167 int64_t CWallet::GetUnconfirmedBalance() const
1168 {
1169     int64_t nTotal = 0;
1170     {
1171         LOCK(cs_wallet);
1172         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1173         {
1174             const CWalletTx* pcoin = &(*it).second;
1175             if (!pcoin->IsFinal() || !pcoin->IsTrusted())
1176                 nTotal += pcoin->GetAvailableCredit();
1177         }
1178     }
1179     return nTotal;
1180 }
1181
1182 int64_t CWallet::GetUnconfirmedWatchOnlyBalance() const
1183 {
1184     int64_t nTotal = 0;
1185     {
1186         LOCK(cs_wallet);
1187         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1188         {
1189             const CWalletTx* pcoin = &(*it).second;
1190             if (!pcoin->IsFinal() || !pcoin->IsTrusted())
1191                 nTotal += pcoin->GetAvailableWatchCredit();
1192         }
1193     }
1194     return nTotal;
1195 }
1196
1197 int64_t CWallet::GetImmatureBalance() const
1198 {
1199     int64_t nTotal = 0;
1200     {
1201         LOCK(cs_wallet);
1202         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1203         {
1204             const CWalletTx* pcoin = &(*it).second;
1205             nTotal += pcoin->GetImmatureCredit();
1206         }
1207     }
1208     return nTotal;
1209 }
1210
1211 int64_t CWallet::GetImmatureWatchOnlyBalance() const
1212 {
1213     int64_t nTotal = 0;
1214     {
1215         LOCK(cs_wallet);
1216         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1217         {
1218             const CWalletTx* pcoin = &(*it).second;
1219             nTotal += pcoin->GetImmatureWatchOnlyCredit();
1220         }
1221     }
1222     return nTotal;
1223 }
1224
1225 // populate vCoins with vector of spendable COutputs
1226 void CWallet::AvailableCoins(vector<COutput>& vCoins, bool fOnlyConfirmed, const CCoinControl *coinControl) const
1227 {
1228     vCoins.clear();
1229
1230     {
1231         LOCK(cs_wallet);
1232         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1233         {
1234             const CWalletTx* pcoin = &(*it).second;
1235
1236             if (!pcoin->IsFinal())
1237                 continue;
1238
1239             if (fOnlyConfirmed && !pcoin->IsTrusted())
1240                 continue;
1241
1242             if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
1243                 continue;
1244
1245             if(pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0)
1246                 continue;
1247
1248             for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
1249                 isminetype mine = IsMine(pcoin->vout[i]);
1250                 if (!(pcoin->IsSpent(i)) && mine != MINE_NO && 
1251                     pcoin->vout[i].nValue >= nMinimumInputValue &&
1252                     (!coinControl || !coinControl->HasSelected() || coinControl->IsSelected((*it).first, i)))
1253                 {
1254                     vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain(), mine == MINE_SPENDABLE));
1255                 }
1256             }
1257         }
1258     }
1259 }
1260
1261 void CWallet::AvailableCoinsMinConf(vector<COutput>& vCoins, int nConf, int64_t nMinValue, int64_t nMaxValue) const
1262 {
1263     vCoins.clear();
1264
1265     {
1266         LOCK(cs_wallet);
1267         for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1268         {
1269             const CWalletTx* pcoin = &(*it).second;
1270
1271             if (!pcoin->IsFinal())
1272                 continue;
1273
1274             if(pcoin->GetDepthInMainChain() < nConf)
1275                 continue;
1276
1277             for (unsigned int i = 0; i < pcoin->vout.size(); i++) {
1278                 isminetype mine = IsMine(pcoin->vout[i]);
1279
1280                 // ignore coin if it was already spent or we don't own it
1281                 if (pcoin->IsSpent(i) || mine == MINE_NO)
1282                     continue;
1283
1284                 // if coin value is between required limits then add new item to vector
1285                 if (pcoin->vout[i].nValue >= nMinValue && pcoin->vout[i].nValue < nMaxValue)
1286                     vCoins.push_back(COutput(pcoin, i, pcoin->GetDepthInMainChain(), mine == MINE_SPENDABLE));
1287             }
1288         }
1289     }
1290 }
1291
1292 static void ApproximateBestSubset(vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > >vValue, int64_t nTotalLower, int64_t nTargetValue,
1293                                   vector<char>& vfBest, int64_t& nBest, int iterations = 1000)
1294 {
1295     vector<char> vfIncluded;
1296
1297     vfBest.assign(vValue.size(), true);
1298     nBest = nTotalLower;
1299
1300     for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
1301     {
1302         vfIncluded.assign(vValue.size(), false);
1303         int64_t nTotal = 0;
1304         bool fReachedTarget = false;
1305         for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
1306         {
1307             for (unsigned int i = 0; i < vValue.size(); i++)
1308             {
1309                 if (nPass == 0 ? rand() % 2 : !vfIncluded[i])
1310                 {
1311                     nTotal += vValue[i].first;
1312                     vfIncluded[i] = true;
1313                     if (nTotal >= nTargetValue)
1314                     {
1315                         fReachedTarget = true;
1316                         if (nTotal < nBest)
1317                         {
1318                             nBest = nTotal;
1319                             vfBest = vfIncluded;
1320                         }
1321                         nTotal -= vValue[i].first;
1322                         vfIncluded[i] = false;
1323                     }
1324                 }
1325             }
1326         }
1327     }
1328 }
1329
1330 int64_t CWallet::GetStake() const
1331 {
1332     int64_t nTotal = 0;
1333     LOCK(cs_wallet);
1334     for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1335     {
1336         const CWalletTx* pcoin = &(*it).second;
1337         if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
1338             nTotal += CWallet::GetCredit(*pcoin, MINE_ALL);
1339     }
1340     return nTotal;
1341 }
1342
1343 int64_t CWallet::GetWatchOnlyStake() const
1344 {
1345     int64_t nTotal = 0;
1346     LOCK(cs_wallet);
1347     for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1348     {
1349         const CWalletTx* pcoin = &(*it).second;
1350         if (pcoin->IsCoinStake() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
1351             nTotal += CWallet::GetCredit(*pcoin, MINE_WATCH_ONLY);
1352     }
1353     return nTotal;
1354 }
1355
1356 int64_t CWallet::GetNewMint() const
1357 {
1358     int64_t nTotal = 0;
1359     LOCK(cs_wallet);
1360     for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1361     {
1362         const CWalletTx* pcoin = &(*it).second;
1363         if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
1364             nTotal += CWallet::GetCredit(*pcoin, MINE_ALL);
1365     }
1366     return nTotal;
1367 }
1368
1369 int64_t CWallet::GetWatchOnlyNewMint() const
1370 {
1371     int64_t nTotal = 0;
1372     LOCK(cs_wallet);
1373     for (map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
1374     {
1375         const CWalletTx* pcoin = &(*it).second;
1376         if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0 && pcoin->GetDepthInMainChain() > 0)
1377             nTotal += CWallet::GetCredit(*pcoin, MINE_WATCH_ONLY);
1378     }
1379     return nTotal;
1380 }
1381
1382 bool CWallet::SelectCoinsMinConf(int64_t nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, vector<COutput> vCoins, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const
1383 {
1384     setCoinsRet.clear();
1385     nValueRet = 0;
1386
1387     // List of values less than target
1388     pair<int64_t, pair<const CWalletTx*,unsigned int> > coinLowestLarger;
1389     coinLowestLarger.first = std::numeric_limits<int64_t>::max();
1390     coinLowestLarger.second.first = NULL;
1391     vector<pair<int64_t, pair<const CWalletTx*,unsigned int> > > vValue;
1392     int64_t nTotalLower = 0;
1393
1394     random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
1395
1396     BOOST_FOREACH(const COutput &output, vCoins)
1397     {
1398         if (!output.fSpendable)
1399             continue;
1400
1401         const CWalletTx *pcoin = output.tx;
1402
1403         if (output.nDepth < (pcoin->IsFromMe(MINE_ALL) ? nConfMine : nConfTheirs))
1404             continue;
1405
1406         int i = output.i;
1407
1408         // Follow the timestamp rules
1409         if (pcoin->nTime > nSpendTime)
1410             continue;
1411
1412         int64_t n = pcoin->vout[i].nValue;
1413
1414         pair<int64_t,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
1415
1416         if (n == nTargetValue)
1417         {
1418             setCoinsRet.insert(coin.second);
1419             nValueRet += coin.first;
1420             return true;
1421         }
1422         else if (n < nTargetValue + CENT)
1423         {
1424             vValue.push_back(coin);
1425             nTotalLower += n;
1426         }
1427         else if (n < coinLowestLarger.first)
1428         {
1429             coinLowestLarger = coin;
1430         }
1431     }
1432
1433     if (nTotalLower == nTargetValue)
1434     {
1435         for (unsigned int i = 0; i < vValue.size(); ++i)
1436         {
1437             setCoinsRet.insert(vValue[i].second);
1438             nValueRet += vValue[i].first;
1439         }
1440         return true;
1441     }
1442
1443     if (nTotalLower < nTargetValue)
1444     {
1445         if (coinLowestLarger.second.first == NULL)
1446             return false;
1447         setCoinsRet.insert(coinLowestLarger.second);
1448         nValueRet += coinLowestLarger.first;
1449         return true;
1450     }
1451
1452     // Solve subset sum by stochastic approximation
1453     sort(vValue.rbegin(), vValue.rend(), CompareValueOnly());
1454     vector<char> vfBest;
1455     int64_t nBest;
1456
1457     ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
1458     if (nBest != nTargetValue && nTotalLower >= nTargetValue + CENT)
1459         ApproximateBestSubset(vValue, nTotalLower, nTargetValue + CENT, vfBest, nBest, 1000);
1460
1461     // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
1462     //                                   or the next bigger coin is closer), return the bigger coin
1463     if (coinLowestLarger.second.first &&
1464         ((nBest != nTargetValue && nBest < nTargetValue + CENT) || coinLowestLarger.first <= nBest))
1465     {
1466         setCoinsRet.insert(coinLowestLarger.second);
1467         nValueRet += coinLowestLarger.first;
1468     }
1469     else {
1470         for (unsigned int i = 0; i < vValue.size(); i++)
1471             if (vfBest[i])
1472             {
1473                 setCoinsRet.insert(vValue[i].second);
1474                 nValueRet += vValue[i].first;
1475             }
1476
1477         if (fDebug && GetBoolArg("-printpriority"))
1478         {
1479             //// debug print
1480             printf("SelectCoins() best subset: ");
1481             for (unsigned int i = 0; i < vValue.size(); i++)
1482                 if (vfBest[i])
1483                     printf("%s ", FormatMoney(vValue[i].first).c_str());
1484             printf("total %s\n", FormatMoney(nBest).c_str());
1485         }
1486     }
1487
1488     return true;
1489 }
1490
1491 bool CWallet::SelectCoins(int64_t nTargetValue, unsigned int nSpendTime, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl* coinControl) const
1492 {
1493     vector<COutput> vCoins;
1494     AvailableCoins(vCoins, true, coinControl);
1495
1496     // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
1497     if (coinControl && coinControl->HasSelected())
1498     {
1499         BOOST_FOREACH(const COutput& out, vCoins)
1500         {
1501             if(!out.fSpendable)
1502                 continue;
1503             nValueRet += out.tx->vout[out.i].nValue;
1504             setCoinsRet.insert(make_pair(out.tx, out.i));
1505         }
1506         return (nValueRet >= nTargetValue);
1507     }
1508
1509     return (SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 6, vCoins, setCoinsRet, nValueRet) ||
1510             SelectCoinsMinConf(nTargetValue, nSpendTime, 1, 1, vCoins, setCoinsRet, nValueRet) ||
1511             SelectCoinsMinConf(nTargetValue, nSpendTime, 0, 1, vCoins, setCoinsRet, nValueRet));
1512 }
1513
1514 // Select some coins without random shuffle or best subset approximation
1515 bool CWallet::SelectCoinsSimple(int64_t nTargetValue, int64_t nMinValue, int64_t nMaxValue, unsigned int nSpendTime, int nMinConf, set<pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet) const
1516 {
1517     vector<COutput> vCoins;
1518     AvailableCoinsMinConf(vCoins, nMinConf, nMinValue, nMaxValue);
1519
1520     setCoinsRet.clear();
1521     nValueRet = 0;
1522
1523     BOOST_FOREACH(COutput output, vCoins)
1524     {
1525         if(!output.fSpendable)
1526             continue;
1527         const CWalletTx *pcoin = output.tx;
1528         int i = output.i;
1529
1530         // Ignore immature coins
1531         if (pcoin->GetBlocksToMaturity() > 0)
1532             continue;
1533
1534         // Stop if we've chosen enough inputs
1535         if (nValueRet >= nTargetValue)
1536             break;
1537
1538         // Follow the timestamp rules
1539         if (pcoin->nTime > nSpendTime)
1540             continue;
1541
1542         int64_t n = pcoin->vout[i].nValue;
1543
1544         pair<int64_t,pair<const CWalletTx*,unsigned int> > coin = make_pair(n,make_pair(pcoin, i));
1545
1546         if (n >= nTargetValue)
1547         {
1548             // If input value is greater or equal to target then simply insert
1549             //    it into the current subset and exit
1550             setCoinsRet.insert(coin.second);
1551             nValueRet += coin.first;
1552             break;
1553         }
1554         else if (n < nTargetValue + CENT)
1555         {
1556             setCoinsRet.insert(coin.second);
1557             nValueRet += coin.first;
1558         }
1559     }
1560
1561     return true;
1562 }
1563
1564 bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl)
1565 {
1566     int64_t nValue = 0;
1567     BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend)
1568     {
1569         if (nValue < 0)
1570             return false;
1571         nValue += s.second;
1572     }
1573     if (vecSend.empty() || nValue < 0)
1574         return false;
1575
1576     wtxNew.BindWallet(this);
1577
1578     {
1579         LOCK2(cs_main, cs_wallet);
1580         // txdb must be opened before the mapWallet lock
1581         CTxDB txdb("r");
1582         {
1583             nFeeRet = nTransactionFee;
1584             while (true)
1585             {
1586                 wtxNew.vin.clear();
1587                 wtxNew.vout.clear();
1588                 wtxNew.fFromMe = true;
1589
1590                 int64_t nTotalValue = nValue + nFeeRet;
1591                 double dPriority = 0;
1592                 // vouts to the payees
1593                 BOOST_FOREACH (const PAIRTYPE(CScript, int64_t)& s, vecSend)
1594                     wtxNew.vout.push_back(CTxOut(s.second, s.first));
1595
1596                 // Choose coins to use
1597                 set<pair<const CWalletTx*,unsigned int> > setCoins;
1598                 int64_t nValueIn = 0;
1599                 if (!SelectCoins(nTotalValue, wtxNew.nTime, setCoins, nValueIn, coinControl))
1600                     return false;
1601                 BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1602                 {
1603                     int64_t nCredit = pcoin.first->vout[pcoin.second].nValue;
1604                     dPriority += (double)nCredit * pcoin.first->GetDepthInMainChain();
1605                 }
1606
1607                 int64_t nChange = nValueIn - nValue - nFeeRet;
1608                 if (nChange > 0)
1609                 {
1610                     // Fill a vout to ourself
1611                     // TODO: pass in scriptChange instead of reservekey so
1612                     // change transaction isn't always pay-to-bitcoin-address
1613                     CScript scriptChange;
1614
1615                     // coin control: send change to custom address
1616                     if (coinControl && !boost::get<CNoDestination>(&coinControl->destChange))
1617                         scriptChange.SetDestination(coinControl->destChange);
1618
1619                     // no coin control: send change to newly generated address
1620                     else
1621                     {
1622                         // Note: We use a new key here to keep it from being obvious which side is the change.
1623                         //  The drawback is that by not reusing a previous key, the change may be lost if a
1624                         //  backup is restored, if the backup doesn't have the new private key for the change.
1625                         //  If we reused the old key, it would be possible to add code to look for and
1626                         //  rediscover unknown transactions that were written with keys of ours to recover
1627                         //  post-backup change.
1628
1629                         // Reserve a new key pair from key pool
1630                         CPubKey vchPubKey = reservekey.GetReservedKey();
1631
1632                         scriptChange.SetDestination(vchPubKey.GetID());
1633                     }
1634
1635                     // Insert change txn at random position:
1636                     vector<CTxOut>::iterator position = wtxNew.vout.begin()+GetRandInt(wtxNew.vout.size());
1637                     wtxNew.vout.insert(position, CTxOut(nChange, scriptChange));
1638                 }
1639                 else
1640                     reservekey.ReturnKey();
1641
1642                 // Fill vin
1643                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1644                     wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
1645
1646                 // Sign
1647                 int nIn = 0;
1648                 BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
1649                     if (!SignSignature(*this, *coin.first, wtxNew, nIn++))
1650                         return false;
1651
1652                 // Limit size
1653                 unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION);
1654                 if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
1655                     return false;
1656                 dPriority /= nBytes;
1657
1658                 // Check that enough fee is included
1659                 bool fAllowFree = CTransaction::AllowFree(dPriority);
1660                 int64_t nPayFee = nTransactionFee * (1 + (int64_t)nBytes / 1000);
1661                 int64_t nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND, nBytes);
1662
1663                 if (nFeeRet < max(nPayFee, nMinFee))
1664                 {
1665                     nFeeRet = max(nPayFee, nMinFee);
1666                     continue;
1667                 }
1668
1669                 // Fill vtxPrev by copying from previous transactions vtxPrev
1670                 wtxNew.AddSupportingTransactions(txdb);
1671                 wtxNew.fTimeReceivedIsTxTime = true;
1672
1673                 break;
1674             }
1675         }
1676     }
1677     return true;
1678 }
1679
1680 bool CWallet::CreateTransaction(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64_t& nFeeRet, const CCoinControl* coinControl)
1681 {
1682     vector< pair<CScript, int64_t> > vecSend;
1683     vecSend.push_back(make_pair(scriptPubKey, nValue));
1684     return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, coinControl);
1685 }
1686
1687 void CWallet::GetStakeWeightFromValue(const int64_t& nTime, const int64_t& nValue, uint64_t& nWeight)
1688 {
1689     int64_t nTimeWeight = GetWeight(nTime, (int64_t)GetTime());
1690
1691     // If time weight is lower or equal to zero then weight is zero.
1692     if (nTimeWeight <= 0)
1693     {
1694         nWeight = 0;
1695         return;
1696     }
1697
1698     CBigNum bnCoinDayWeight = CBigNum(nValue) * nTimeWeight / COIN / (24 * 60 * 60);
1699     nWeight = bnCoinDayWeight.getuint64();
1700 }
1701
1702
1703 // NovaCoin: get current stake miner statistics
1704 void CWallet::GetStakeStats(float &nKernelsRate, float &nCoinDaysRate)
1705 {
1706     static uint64_t nLastKernels = 0, nLastCoinDays = 0;
1707     static float nLastKernelsRate = 0, nLastCoinDaysRate = 0;
1708     static int64_t nLastTime = GetTime();
1709
1710     if (nKernelsTried < nLastKernels)
1711     {
1712         nLastKernels = 0;
1713         nLastCoinDays = 0;
1714
1715         nLastTime = GetTime();
1716     }
1717
1718     int64_t nInterval = GetTime() - nLastTime;
1719     //if (nKernelsTried > 1000 && nInterval > 5)
1720     if (nInterval > 10)
1721     {
1722         nKernelsRate = nLastKernelsRate = ( nKernelsTried - nLastKernels ) / (float) nInterval;
1723         nCoinDaysRate = nLastCoinDaysRate = ( nCoinDaysTried - nLastCoinDays ) / (float) nInterval;
1724
1725         nLastKernels = nKernelsTried;
1726         nLastCoinDays = nCoinDaysTried;
1727         nLastTime = GetTime();
1728     }
1729     else
1730     {
1731         nKernelsRate = nLastKernelsRate;
1732         nCoinDaysRate = nLastCoinDaysRate;
1733     }
1734 }
1735
1736 bool CWallet::MergeCoins(const int64_t& nAmount, const int64_t& nMinValue, const int64_t& nOutputValue, list<uint256>& listMerged)
1737 {
1738     int64_t nBalance = GetBalance();
1739
1740     if (nAmount > nBalance)
1741         return false;
1742
1743     listMerged.clear();
1744     int64_t nValueIn = 0;
1745     set<pair<const CWalletTx*,unsigned int> > setCoins;
1746
1747     // Simple coins selection - no randomization
1748     if (!SelectCoinsSimple(nAmount, nMinValue, nOutputValue, GetTime(), 1, setCoins, nValueIn))
1749         return false;
1750
1751     if (setCoins.empty())
1752         return false;
1753
1754     CWalletTx wtxNew;
1755     vector<const CWalletTx*> vwtxPrev;
1756
1757     // Reserve a new key pair from key pool
1758     CReserveKey reservekey(this);
1759     CPubKey vchPubKey = reservekey.GetReservedKey();
1760
1761     // Output script
1762     CScript scriptOutput;
1763     scriptOutput.SetDestination(vchPubKey.GetID());
1764
1765     // Insert output
1766     wtxNew.vout.push_back(CTxOut(0, scriptOutput));
1767
1768     double dWeight = 0;
1769     BOOST_FOREACH(PAIRTYPE(const CWalletTx*, unsigned int) pcoin, setCoins)
1770     {
1771         int64_t nCredit = pcoin.first->vout[pcoin.second].nValue;
1772
1773         // Add current coin to inputs list and add its credit to transaction output
1774         wtxNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
1775         wtxNew.vout[0].nValue += nCredit;
1776         vwtxPrev.push_back(pcoin.first);
1777
1778 /*
1779         // Replaced with estimation for performance purposes
1780
1781         for (unsigned int i = 0; i < wtxNew.vin.size(); i++) {
1782             const CWalletTx *txin = vwtxPrev[i];
1783
1784             // Sign scripts to get actual transaction size for fee calculation
1785             if (!SignSignature(*this, *txin, wtxNew, i))
1786                 return false;
1787         }
1788 */
1789
1790         // Assuming that average scriptsig size is 110 bytes
1791         int64_t nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION) + wtxNew.vin.size() * 110;
1792         dWeight += (double)nCredit * pcoin.first->GetDepthInMainChain();
1793
1794         double dFinalPriority = dWeight /= nBytes;
1795         bool fAllowFree = CTransaction::AllowFree(dFinalPriority);
1796
1797         // Get actual transaction fee according to its estimated size and priority
1798         int64_t nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND, nBytes);
1799
1800         // Prepare transaction for commit if sum is enough ot its size is too big
1801         if (nBytes >= MAX_BLOCK_SIZE_GEN/6 || wtxNew.vout[0].nValue >= nOutputValue)
1802         {
1803             wtxNew.vout[0].nValue -= nMinFee; // Set actual fee
1804
1805             for (unsigned int i = 0; i < wtxNew.vin.size(); i++) {
1806                 const CWalletTx *txin = vwtxPrev[i];
1807
1808                 // Sign all scripts
1809                 if (!SignSignature(*this, *txin, wtxNew, i))
1810                     return false;
1811             }
1812
1813             // Try to commit, return false on failure
1814             if (!CommitTransaction(wtxNew, reservekey))
1815                 return false;
1816
1817             listMerged.push_back(wtxNew.GetHash()); // Add to hashes list
1818
1819             dWeight = 0;  // Reset all temporary values
1820             vwtxPrev.clear();
1821             wtxNew.SetNull();
1822             wtxNew.vout.push_back(CTxOut(0, scriptOutput));
1823         }
1824     }
1825
1826     // Create transactions if there are some unhandled coins left
1827     if (wtxNew.vout[0].nValue > 0) {
1828         int64_t nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK, PROTOCOL_VERSION) + wtxNew.vin.size() * 110;
1829
1830         double dFinalPriority = dWeight /= nBytes;
1831         bool fAllowFree = CTransaction::AllowFree(dFinalPriority);
1832
1833         // Get actual transaction fee according to its size and priority
1834         int64_t nMinFee = wtxNew.GetMinFee(1, fAllowFree, GMF_SEND, nBytes);
1835
1836         wtxNew.vout[0].nValue -= nMinFee; // Set actual fee
1837
1838         if (wtxNew.vout[0].nValue <= 0)
1839             return false;
1840
1841         for (unsigned int i = 0; i < wtxNew.vin.size(); i++) {
1842             const CWalletTx *txin = vwtxPrev[i];
1843
1844             // Sign all scripts again
1845             if (!SignSignature(*this, *txin, wtxNew, i))
1846                 return false;
1847         }
1848
1849         // Try to commit, return false on failure
1850         if (!CommitTransaction(wtxNew, reservekey))
1851             return false;
1852
1853         listMerged.push_back(wtxNew.GetHash()); // Add to hashes list
1854     }
1855
1856     return true;
1857 }
1858
1859
1860 bool CWallet::CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, uint32_t nSearchInterval, CTransaction& txNew, CKey& key)
1861 {
1862     // The following combine threshold is important to security
1863     // Should not be adjusted if you don't understand the consequences
1864     int64_t nCombineThreshold = GetProofOfWorkReward(GetLastBlockIndex(pindexBest, false)->nBits) / 3;
1865
1866     CBigNum bnTargetPerCoinDay;
1867     bnTargetPerCoinDay.SetCompact(nBits);
1868
1869     txNew.vin.clear();
1870     txNew.vout.clear();
1871
1872     // Mark coin stake transaction
1873     CScript scriptEmpty;
1874     scriptEmpty.clear();
1875     txNew.vout.push_back(CTxOut(0, scriptEmpty));
1876
1877     // Choose coins to use
1878     int64_t nBalance = GetBalance();
1879     int64_t nReserveBalance = 0;
1880
1881     if (mapArgs.count("-reservebalance") && !ParseMoney(mapArgs["-reservebalance"], nReserveBalance))
1882         return error("CreateCoinStake : invalid reserve balance amount");
1883
1884     if (nBalance <= nReserveBalance)
1885         return false;
1886
1887     vector<const CWalletTx*> vwtxPrev;
1888
1889     CTxDB txdb("r");
1890     {
1891         LOCK2(cs_main, cs_wallet);
1892         // Cache outputs unless best block or wallet transaction set changed
1893         if (!fCoinsDataActual)
1894         {
1895             mapMeta.clear();
1896             int64_t nValueIn = 0;
1897             CoinsSet setCoins;
1898             if (!SelectCoinsSimple(nBalance - nReserveBalance, MIN_TX_FEE, MAX_MONEY, txNew.nTime, nCoinbaseMaturity * 10, setCoins, nValueIn))
1899                 return false;
1900
1901             if (setCoins.empty())
1902                 return false;
1903
1904             {
1905                 CTxIndex txindex;
1906                 CBlock block;
1907                 for(CoinsSet::iterator pcoin = setCoins.begin(); pcoin != setCoins.end(); pcoin++)
1908                 {
1909                     // Load transaction index item
1910                     if (!txdb.ReadTxIndex(pcoin->first->GetHash(), txindex))
1911                         continue;
1912
1913                     // Read block header
1914                     if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
1915                         continue;
1916
1917                     uint64_t nStakeModifier = 0;
1918                     if (!GetKernelStakeModifier(block.GetHash(), nStakeModifier))
1919                         continue;
1920
1921                     // Add meta record
1922                     // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier))
1923                     mapMeta[make_pair(pcoin->first->GetHash(), pcoin->second)] = make_pair(make_pair(txindex, *pcoin), make_pair(block, nStakeModifier));
1924
1925                     if (fDebug)
1926                         printf("Load coin: %s\n", pcoin->first->GetHash().GetHex().c_str());
1927                 }
1928             }
1929
1930             if (fDebug)
1931                 printf("Stake miner: %" PRIszu " meta items loaded for %" PRIszu " coins\n", mapMeta.size(), setCoins.size());
1932
1933             fCoinsDataActual = true;
1934             nKernelsTried = 0;
1935             nCoinDaysTried = 0;
1936         }
1937     }
1938
1939     int64_t nCredit = 0;
1940     CScript scriptPubKeyKernel;
1941
1942     unsigned int nTimeTx, nBlockTime;
1943     COutPoint prevoutStake;
1944     CoinsSet::value_type kernelcoin;
1945
1946     if (ScanForStakeKernelHash(mapMeta, nBits, txNew.nTime, nSearchInterval, kernelcoin, nTimeTx, nBlockTime, nKernelsTried, nCoinDaysTried))
1947     {
1948         // Found a kernel
1949         if (fDebug && GetBoolArg("-printcoinstake"))
1950             printf("CreateCoinStake : kernel found\n");
1951         vector<valtype> vSolutions;
1952         txnouttype whichType;
1953         CScript scriptPubKeyOut;
1954         scriptPubKeyKernel = kernelcoin.first->vout[kernelcoin.second].scriptPubKey;
1955         if (!Solver(scriptPubKeyKernel, whichType, vSolutions))
1956         {
1957             if (fDebug && GetBoolArg("-printcoinstake"))
1958                 printf("CreateCoinStake : failed to parse kernel\n");
1959             return false;
1960         }
1961         if (fDebug && GetBoolArg("-printcoinstake"))
1962             printf("CreateCoinStake : parsed kernel type=%d\n", whichType);
1963         if (whichType != TX_PUBKEY && whichType != TX_PUBKEYHASH)
1964         {
1965             if (fDebug && GetBoolArg("-printcoinstake"))
1966                 printf("CreateCoinStake : no support for kernel type=%d\n", whichType);
1967             return false;  // only support pay to public key and pay to address
1968         }
1969         if (whichType == TX_PUBKEYHASH) // pay to address type
1970         {
1971             // convert to pay to public key type
1972             if (!keystore.GetKey(uint160(vSolutions[0]), key))
1973             {
1974                 if (fDebug && GetBoolArg("-printcoinstake"))
1975                     printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
1976                 return false;  // unable to find corresponding public key
1977             }
1978             scriptPubKeyOut << key.GetPubKey() << OP_CHECKSIG;
1979         }
1980         if (whichType == TX_PUBKEY)
1981         {
1982             valtype& vchPubKey = vSolutions[0];
1983             if (!keystore.GetKey(Hash160(vchPubKey), key))
1984             {
1985                 if (fDebug && GetBoolArg("-printcoinstake"))
1986                     printf("CreateCoinStake : failed to get key for kernel type=%d\n", whichType);
1987                 return false;  // unable to find corresponding public key
1988             }
1989             if (key.GetPubKey() != vchPubKey)
1990             {
1991                 if (fDebug && GetBoolArg("-printcoinstake"))
1992                     printf("CreateCoinStake : invalid key for kernel type=%d\n", whichType);
1993                 return false; // keys mismatch
1994             }
1995
1996             scriptPubKeyOut = scriptPubKeyKernel;
1997         }
1998
1999         txNew.nTime = nTimeTx;
2000         txNew.vin.push_back(CTxIn(kernelcoin.first->GetHash(), kernelcoin.second));
2001         nCredit += kernelcoin.first->vout[kernelcoin.second].nValue;
2002         vwtxPrev.push_back(kernelcoin.first);
2003         txNew.vout.push_back(CTxOut(0, scriptPubKeyOut));
2004
2005         if (GetWeight((int64_t)nBlockTime, (int64_t)txNew.nTime) < nStakeMaxAge)
2006             txNew.vout.push_back(CTxOut(0, scriptPubKeyOut)); //split stake
2007         if (fDebug && GetBoolArg("-printcoinstake"))
2008             printf("CreateCoinStake : added kernel type=%d\n", whichType);
2009     }
2010
2011     if (nCredit == 0 || nCredit > nBalance - nReserveBalance)
2012         return false;
2013
2014     // (txid, vout.n) => ((txindex, (tx, vout.n)), (block, modifier))
2015     for(MetaMap::const_iterator meta_item = mapMeta.begin(); meta_item != mapMeta.end(); meta_item++)
2016     {
2017         // Get coin
2018         CoinsSet::value_type pcoin = meta_item->second.first.second;
2019
2020         // Attempt to add more inputs
2021         // Only add coins of the same key/address as kernel
2022         if (txNew.vout.size() == 2 && ((pcoin.first->vout[pcoin.second].scriptPubKey == scriptPubKeyKernel || pcoin.first->vout[pcoin.second].scriptPubKey == txNew.vout[1].scriptPubKey))
2023             && pcoin.first->GetHash() != txNew.vin[0].prevout.hash)
2024         {
2025             int64_t nTimeWeight = GetWeight((int64_t)pcoin.first->nTime, (int64_t)txNew.nTime);
2026
2027             // Stop adding more inputs if already too many inputs
2028             if (txNew.vin.size() >= 100)
2029                 break;
2030             // Stop adding more inputs if value is already pretty significant
2031             if (nCredit > nCombineThreshold)
2032                 break;
2033             // Stop adding inputs if reached reserve limit
2034             if (nCredit + pcoin.first->vout[pcoin.second].nValue > nBalance - nReserveBalance)
2035                 break;
2036             // Do not add additional significant input
2037             if (pcoin.first->vout[pcoin.second].nValue > nCombineThreshold)
2038                 continue;
2039             // Do not add input that is still too young
2040             if (nTimeWeight < nStakeMaxAge)
2041                 continue;
2042
2043             txNew.vin.push_back(CTxIn(pcoin.first->GetHash(), pcoin.second));
2044             nCredit += pcoin.first->vout[pcoin.second].nValue;
2045             vwtxPrev.push_back(pcoin.first);
2046         }
2047     }
2048
2049     // Calculate coin age reward
2050     {
2051         uint64_t nCoinAge;
2052         CTxDB txdb("r");
2053         if (!txNew.GetCoinAge(txdb, nCoinAge))
2054             return error("CreateCoinStake : failed to calculate coin age");
2055         
2056         int64_t nReward = GetProofOfStakeReward(nCoinAge, nBits, txNew.nTime);
2057         // Refuse to create mint that has zero or negative reward
2058         if(nReward <= 0)
2059             return false;
2060     
2061         nCredit += nReward;
2062     }
2063
2064     int64_t nMinFee = 0;
2065     while (true)
2066     {
2067         // Set output amount
2068         if (txNew.vout.size() == 3)
2069         {
2070             txNew.vout[1].nValue = ((nCredit - nMinFee) / 2 / CENT) * CENT;
2071             txNew.vout[2].nValue = nCredit - nMinFee - txNew.vout[1].nValue;
2072         }
2073         else
2074             txNew.vout[1].nValue = nCredit - nMinFee;
2075
2076         // Sign
2077         int nIn = 0;
2078         BOOST_FOREACH(const CWalletTx* pcoin, vwtxPrev)
2079         {
2080             if (!SignSignature(*this, *pcoin, txNew, nIn++))
2081                 return error("CreateCoinStake : failed to sign coinstake");
2082         }
2083
2084         // Limit size
2085         unsigned int nBytes = ::GetSerializeSize(txNew, SER_NETWORK, PROTOCOL_VERSION);
2086         if (nBytes >= MAX_BLOCK_SIZE_GEN/5)
2087             return error("CreateCoinStake : exceeded coinstake size limit");
2088
2089         // Check enough fee is paid
2090         if (nMinFee < txNew.GetMinFee(1, false, GMF_BLOCK, nBytes) - CENT)
2091         {
2092             nMinFee = txNew.GetMinFee(1, false, GMF_BLOCK, nBytes) - CENT;
2093             continue; // try signing again
2094         }
2095         else
2096         {
2097             if (fDebug && GetBoolArg("-printfee"))
2098                 printf("CreateCoinStake : fee for coinstake %s\n", FormatMoney(nMinFee).c_str());
2099             break;
2100         }
2101     }
2102
2103     // Successfully generated coinstake
2104     return true;
2105 }
2106
2107
2108 // Call after CreateTransaction unless you want to abort
2109 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey)
2110 {
2111     {
2112         printf("CommitTransaction:\n%s", wtxNew.ToString().c_str());
2113
2114         // Track how many getdata requests our transaction gets
2115         mapRequestCount[wtxNew.GetHash()] = 0;
2116
2117         // Try to broadcast before saving
2118         if (!wtxNew.AcceptToMemoryPool())
2119         {
2120             // This must not fail. The transaction has already been signed.
2121             printf("CommitTransaction() : Error: Transaction not valid");
2122             return false;
2123         }
2124
2125         wtxNew.RelayWalletTransaction();
2126
2127         {
2128             LOCK2(cs_main, cs_wallet);
2129
2130             // This is only to keep the database open to defeat the auto-flush for the
2131             // duration of this scope.  This is the only place where this optimization
2132             // maybe makes sense; please don't do it anywhere else.
2133             CWalletDB* pwalletdb = fFileBacked ? new CWalletDB(strWalletFile,"r") : NULL;
2134
2135             // Take key pair from key pool so it won't be used again
2136             reservekey.KeepKey();
2137
2138             // Add tx to wallet, because if it has change it's also ours,
2139             // otherwise just for transaction history.
2140             AddToWallet(wtxNew);
2141
2142             // Mark old coins as spent
2143             set<CWalletTx*> setCoins;
2144             BOOST_FOREACH(const CTxIn& txin, wtxNew.vin)
2145             {
2146                 CWalletTx &coin = mapWallet[txin.prevout.hash];
2147                 coin.BindWallet(this);
2148                 coin.MarkSpent(txin.prevout.n);
2149                 coin.WriteToDisk();
2150                 NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
2151                 vMintingWalletUpdated.push_back(coin.GetHash());
2152             }
2153
2154             if (fFileBacked)
2155                 delete pwalletdb;
2156         }
2157     }
2158     return true;
2159 }
2160
2161
2162
2163
2164 string CWallet::SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, bool fAskFee)
2165 {
2166     CReserveKey reservekey(this);
2167     int64_t nFeeRequired;
2168
2169     if (IsLocked())
2170     {
2171         string strError = _("Error: Wallet locked, unable to create transaction  ");
2172         printf("SendMoney() : %s", strError.c_str());
2173         return strError;
2174     }
2175     if (fWalletUnlockMintOnly)
2176     {
2177         string strError = _("Error: Wallet unlocked for block minting only, unable to create transaction.");
2178         printf("SendMoney() : %s", strError.c_str());
2179         return strError;
2180     }
2181     if (!CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired))
2182     {
2183         string strError;
2184         if (nValue + nFeeRequired > GetBalance())
2185             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).c_str());
2186         else
2187             strError = _("Error: Transaction creation failed  ");
2188         printf("SendMoney() : %s", strError.c_str());
2189         return strError;
2190     }
2191
2192     if (fAskFee && !uiInterface.ThreadSafeAskFee(nFeeRequired, _("Sending...")))
2193         return "ABORTED";
2194
2195     if (!CommitTransaction(wtxNew, reservekey))
2196         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.");
2197
2198     return "";
2199 }
2200
2201
2202
2203 string CWallet::SendMoneyToDestination(const CTxDestination& address, int64_t nValue, CWalletTx& wtxNew, bool fAskFee)
2204 {
2205     // Check amount
2206     if (nValue <= 0)
2207         return _("Invalid amount");
2208     if (nValue + nTransactionFee > GetBalance())
2209         return _("Insufficient funds");
2210
2211     // Parse Bitcoin address
2212     CScript scriptPubKey;
2213     scriptPubKey.SetDestination(address);
2214
2215     return SendMoney(scriptPubKey, nValue, wtxNew, fAskFee);
2216 }
2217
2218
2219
2220
2221 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
2222 {
2223     if (!fFileBacked)
2224         return DB_LOAD_OK;
2225     fFirstRunRet = false;
2226     DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
2227     if (nLoadWalletRet == DB_NEED_REWRITE)
2228     {
2229         if (CDB::Rewrite(strWalletFile, "\x04pool"))
2230         {
2231             setKeyPool.clear();
2232             // Note: can't top-up keypool here, because wallet is locked.
2233             // User will be prompted to unlock wallet the next operation
2234             // the requires a new key.
2235         }
2236     }
2237
2238     if (nLoadWalletRet != DB_LOAD_OK)
2239         return nLoadWalletRet;
2240     fFirstRunRet = !vchDefaultKey.IsValid();
2241
2242     NewThread(ThreadFlushWalletDB, &strWalletFile);
2243     return DB_LOAD_OK;
2244 }
2245
2246 DBErrors CWallet::ZapWalletTx()
2247 {
2248     if (!fFileBacked)
2249         return DB_LOAD_OK;
2250     DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(this);
2251     if (nZapWalletTxRet == DB_NEED_REWRITE)
2252     {
2253         if (CDB::Rewrite(strWalletFile, "\x04pool"))
2254         {
2255             LOCK(cs_wallet);
2256             setKeyPool.clear();
2257             // Note: can't top-up keypool here, because wallet is locked.
2258             // User will be prompted to unlock wallet the next operation
2259             // the requires a new key.
2260         }
2261     }
2262
2263     if (nZapWalletTxRet != DB_LOAD_OK)
2264         return nZapWalletTxRet;
2265
2266     return DB_LOAD_OK;
2267 }
2268
2269 bool CWallet::SetAddressBookName(const CTxDestination& address, const string& strName)
2270 {
2271     std::map<CTxDestination, std::string>::iterator mi = mapAddressBook.find(address);
2272     mapAddressBook[address] = strName;
2273     NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address), (mi == mapAddressBook.end()) ? CT_NEW : CT_UPDATED);
2274     if (!fFileBacked)
2275         return false;
2276     return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
2277 }
2278
2279 bool CWallet::DelAddressBookName(const CTxDestination& address)
2280 {
2281     mapAddressBook.erase(address);
2282     NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address), CT_DELETED);
2283     if (!fFileBacked)
2284         return false;
2285     return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
2286 }
2287
2288
2289 void CWallet::PrintWallet(const CBlock& block)
2290 {
2291     {
2292         LOCK(cs_wallet);
2293         if (block.IsProofOfStake() && mapWallet.count(block.vtx[1].GetHash()))
2294         {
2295             CWalletTx& wtx = mapWallet[block.vtx[1].GetHash()];
2296             printf("    PoS: %d  %d  %" PRId64 "", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit(MINE_ALL));
2297         }
2298         else if (mapWallet.count(block.vtx[0].GetHash()))
2299         {
2300             CWalletTx& wtx = mapWallet[block.vtx[0].GetHash()];
2301             printf("    PoW:  %d  %d  %" PRId64 "", wtx.GetDepthInMainChain(), wtx.GetBlocksToMaturity(), wtx.GetCredit(MINE_ALL));
2302         }
2303     }
2304     printf("\n");
2305 }
2306
2307 bool CWallet::GetTransaction(const uint256 &hashTx, CWalletTx& wtx)
2308 {
2309     {
2310         LOCK(cs_wallet);
2311         map<uint256, CWalletTx>::iterator mi = mapWallet.find(hashTx);
2312         if (mi != mapWallet.end())
2313         {
2314             wtx = (*mi).second;
2315             return true;
2316         }
2317     }
2318     return false;
2319 }
2320
2321 bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
2322 {
2323     if (fFileBacked)
2324     {
2325         if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
2326             return false;
2327     }
2328     vchDefaultKey = vchPubKey;
2329     return true;
2330 }
2331
2332 bool GetWalletFile(CWallet* pwallet, string &strWalletFileOut)
2333 {
2334     if (!pwallet->fFileBacked)
2335         return false;
2336     strWalletFileOut = pwallet->strWalletFile;
2337     return true;
2338 }
2339
2340 //
2341 // Mark old keypool keys as used,
2342 // and generate all new keys
2343 //
2344 bool CWallet::NewKeyPool(unsigned int nSize)
2345 {
2346     {
2347         LOCK(cs_wallet);
2348         CWalletDB walletdb(strWalletFile);
2349         BOOST_FOREACH(int64_t nIndex, setKeyPool)
2350             walletdb.ErasePool(nIndex);
2351         setKeyPool.clear();
2352
2353         if (IsLocked())
2354             return false;
2355
2356         uint64_t nKeys;
2357         if (nSize > 0)
2358             nKeys = nSize;
2359         else
2360             nKeys = max<uint64_t>(GetArg("-keypool", 100), 0);
2361
2362         for (uint64_t i = 0; i < nKeys; i++)
2363         {
2364             uint64_t nIndex = i+1;
2365             walletdb.WritePool(nIndex, CKeyPool(GenerateNewKey()));
2366             setKeyPool.insert(nIndex);
2367         }
2368         printf("CWallet::NewKeyPool wrote %" PRIu64 " new keys\n", nKeys);
2369     }
2370     return true;
2371 }
2372
2373 bool CWallet::TopUpKeyPool(unsigned int nSize)
2374 {
2375     {
2376         LOCK(cs_wallet);
2377
2378         if (IsLocked())
2379             return false;
2380
2381         CWalletDB walletdb(strWalletFile);
2382
2383         // Top up key pool
2384         uint64_t nTargetSize;
2385         if (nSize > 0)
2386             nTargetSize = nSize;
2387         else
2388             nTargetSize = max<uint64_t>(GetArg("-keypool", 100), 0);
2389
2390         while (setKeyPool.size() < (nTargetSize + 1))
2391         {
2392             uint64_t nEnd = 1;
2393             if (!setKeyPool.empty())
2394                 nEnd = *(--setKeyPool.end()) + 1;
2395             if (!walletdb.WritePool(nEnd, CKeyPool(GenerateNewKey())))
2396                 throw runtime_error("TopUpKeyPool() : writing generated key failed");
2397             setKeyPool.insert(nEnd);
2398             printf("keypool added key %" PRIu64 ", size=%" PRIszu "\n", nEnd, setKeyPool.size());
2399         }
2400     }
2401     return true;
2402 }
2403
2404 void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool)
2405 {
2406     nIndex = -1;
2407     keypool.vchPubKey = CPubKey();
2408     {
2409         LOCK(cs_wallet);
2410
2411         if (!IsLocked())
2412             TopUpKeyPool();
2413
2414         // Get the oldest key
2415         if(setKeyPool.empty())
2416             return;
2417
2418         CWalletDB walletdb(strWalletFile);
2419
2420         nIndex = *(setKeyPool.begin());
2421         setKeyPool.erase(setKeyPool.begin());
2422         if (!walletdb.ReadPool(nIndex, keypool))
2423             throw runtime_error("ReserveKeyFromKeyPool() : read failed");
2424         if (!HaveKey(keypool.vchPubKey.GetID()))
2425             throw runtime_error("ReserveKeyFromKeyPool() : unknown key in key pool");
2426         assert(keypool.vchPubKey.IsValid());
2427         if (fDebug && GetBoolArg("-printkeypool"))
2428             printf("keypool reserve %" PRId64 "\n", nIndex);
2429     }
2430 }
2431
2432 int64_t CWallet::AddReserveKey(const CKeyPool& keypool)
2433 {
2434     {
2435         LOCK2(cs_main, cs_wallet);
2436         CWalletDB walletdb(strWalletFile);
2437
2438         int64_t nIndex = 1 + *(--setKeyPool.end());
2439         if (!walletdb.WritePool(nIndex, keypool))
2440             throw runtime_error("AddReserveKey() : writing added key failed");
2441         setKeyPool.insert(nIndex);
2442         return nIndex;
2443     }
2444     return -1;
2445 }
2446
2447 void CWallet::KeepKey(int64_t nIndex)
2448 {
2449     // Remove from key pool
2450     if (fFileBacked)
2451     {
2452         CWalletDB walletdb(strWalletFile);
2453         walletdb.ErasePool(nIndex);
2454     }
2455     if(fDebug)
2456         printf("keypool keep %" PRId64 "\n", nIndex);
2457 }
2458
2459 void CWallet::ReturnKey(int64_t nIndex)
2460 {
2461     // Return to key pool
2462     {
2463         LOCK(cs_wallet);
2464         setKeyPool.insert(nIndex);
2465     }
2466     if(fDebug)
2467         printf("keypool return %" PRId64 "\n", nIndex);
2468 }
2469
2470 bool CWallet::GetKeyFromPool(CPubKey& result, bool fAllowReuse)
2471 {
2472     int64_t nIndex = 0;
2473     CKeyPool keypool;
2474     {
2475         LOCK(cs_wallet);
2476         ReserveKeyFromKeyPool(nIndex, keypool);
2477         if (nIndex == -1)
2478         {
2479             if (fAllowReuse && vchDefaultKey.IsValid())
2480             {
2481                 result = vchDefaultKey;
2482                 return true;
2483             }
2484             if (IsLocked()) return false;
2485             result = GenerateNewKey();
2486             return true;
2487         }
2488         KeepKey(nIndex);
2489         result = keypool.vchPubKey;
2490     }
2491     return true;
2492 }
2493
2494 int64_t CWallet::GetOldestKeyPoolTime()
2495 {
2496     int64_t nIndex = 0;
2497     CKeyPool keypool;
2498     ReserveKeyFromKeyPool(nIndex, keypool);
2499     if (nIndex == -1)
2500         return GetTime();
2501     ReturnKey(nIndex);
2502     return keypool.nTime;
2503 }
2504
2505 std::map<CTxDestination, int64_t> CWallet::GetAddressBalances()
2506 {
2507     map<CTxDestination, int64_t> balances;
2508
2509     {
2510         LOCK(cs_wallet);
2511         BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
2512         {
2513             CWalletTx *pcoin = &walletEntry.second;
2514
2515             if (!pcoin->IsFinal() || !pcoin->IsTrusted())
2516                 continue;
2517
2518             if ((pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetBlocksToMaturity() > 0)
2519                 continue;
2520
2521             int nDepth = pcoin->GetDepthInMainChain();
2522             if (nDepth < (pcoin->IsFromMe(MINE_ALL) ? 0 : 1))
2523                 continue;
2524
2525             for (unsigned int i = 0; i < pcoin->vout.size(); i++)
2526             {
2527                 CTxDestination addr;
2528                 if (!IsMine(pcoin->vout[i]))
2529                     continue;
2530                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, addr))
2531                     continue;
2532
2533                 int64_t n = pcoin->IsSpent(i) ? 0 : pcoin->vout[i].nValue;
2534
2535                 if (!balances.count(addr))
2536                     balances[addr] = 0;
2537                 balances[addr] += n;
2538             }
2539         }
2540     }
2541
2542     return balances;
2543 }
2544
2545 set< set<CTxDestination> > CWallet::GetAddressGroupings()
2546 {
2547     set< set<CTxDestination> > groupings;
2548     set<CTxDestination> grouping;
2549
2550     BOOST_FOREACH(PAIRTYPE(uint256, CWalletTx) walletEntry, mapWallet)
2551     {
2552         CWalletTx *pcoin = &walletEntry.second;
2553
2554         if (pcoin->vin.size() > 0 && IsMine(pcoin->vin[0]))
2555         {
2556             // group all input addresses with each other
2557             BOOST_FOREACH(CTxIn txin, pcoin->vin)
2558             {
2559                 CTxDestination address;
2560                 if(!ExtractDestination(mapWallet[txin.prevout.hash].vout[txin.prevout.n].scriptPubKey, address))
2561                     continue;
2562                 grouping.insert(address);
2563             }
2564
2565             // group change with input addresses
2566             BOOST_FOREACH(CTxOut txout, pcoin->vout)
2567                 if (IsChange(txout))
2568                 {
2569                     CWalletTx tx = mapWallet[pcoin->vin[0].prevout.hash];
2570                     CTxDestination txoutAddr;
2571                     if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
2572                         continue;
2573                     grouping.insert(txoutAddr);
2574                 }
2575             groupings.insert(grouping);
2576             grouping.clear();
2577         }
2578
2579         // group lone addrs by themselves
2580         for (unsigned int i = 0; i < pcoin->vout.size(); i++)
2581             if (IsMine(pcoin->vout[i]))
2582             {
2583                 CTxDestination address;
2584                 if(!ExtractDestination(pcoin->vout[i].scriptPubKey, address))
2585                     continue;
2586                 grouping.insert(address);
2587                 groupings.insert(grouping);
2588                 grouping.clear();
2589             }
2590     }
2591
2592     set< set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
2593     map< CTxDestination, set<CTxDestination>* > setmap;  // map addresses to the unique group containing it
2594     BOOST_FOREACH(set<CTxDestination> grouping, groupings)
2595     {
2596         // make a set of all the groups hit by this new group
2597         set< set<CTxDestination>* > hits;
2598         map< CTxDestination, set<CTxDestination>* >::iterator it;
2599         BOOST_FOREACH(CTxDestination address, grouping)
2600             if ((it = setmap.find(address)) != setmap.end())
2601                 hits.insert((*it).second);
2602
2603         // merge all hit groups into a new single group and delete old groups
2604         set<CTxDestination>* merged = new set<CTxDestination>(grouping);
2605         BOOST_FOREACH(set<CTxDestination>* hit, hits)
2606         {
2607             merged->insert(hit->begin(), hit->end());
2608             uniqueGroupings.erase(hit);
2609             delete hit;
2610         }
2611         uniqueGroupings.insert(merged);
2612
2613         // update setmap
2614         BOOST_FOREACH(CTxDestination element, *merged)
2615             setmap[element] = merged;
2616     }
2617
2618     set< set<CTxDestination> > ret;
2619     BOOST_FOREACH(set<CTxDestination>* uniqueGrouping, uniqueGroupings)
2620     {
2621         ret.insert(*uniqueGrouping);
2622         delete uniqueGrouping;
2623     }
2624
2625     return ret;
2626 }
2627
2628 // ppcoin: check 'spent' consistency between wallet and txindex
2629 // ppcoin: fix wallet spent state according to txindex
2630 void CWallet::FixSpentCoins(int& nMismatchFound, int64_t& nBalanceInQuestion, bool fCheckOnly)
2631 {
2632     nMismatchFound = 0;
2633     nBalanceInQuestion = 0;
2634
2635     LOCK(cs_wallet);
2636     vector<CWalletTx*> vCoins;
2637     vCoins.reserve(mapWallet.size());
2638     for (map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2639         vCoins.push_back(&(*it).second);
2640
2641     CTxDB txdb("r");
2642     BOOST_FOREACH(CWalletTx* pcoin, vCoins)
2643     {
2644         // Find the corresponding transaction index
2645         CTxIndex txindex;
2646         if (!txdb.ReadTxIndex(pcoin->GetHash(), txindex))
2647             continue;
2648         for (unsigned int n=0; n < pcoin->vout.size(); n++)
2649         {
2650             if (IsMine(pcoin->vout[n]) && pcoin->IsSpent(n) && (txindex.vSpent.size() <= n || txindex.vSpent[n].IsNull()))
2651             {
2652                 printf("FixSpentCoins found lost coin %sppc %s[%d], %s\n",
2653                     FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing");
2654                 nMismatchFound++;
2655                 nBalanceInQuestion += pcoin->vout[n].nValue;
2656                 if (!fCheckOnly)
2657                 {
2658                     pcoin->MarkUnspent(n);
2659                     pcoin->WriteToDisk();
2660                 }
2661             }
2662             else if (IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull()))
2663             {
2664                 printf("FixSpentCoins found spent coin %sppc %s[%d], %s\n",
2665                     FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing");
2666                 nMismatchFound++;
2667                 nBalanceInQuestion += pcoin->vout[n].nValue;
2668                 if (!fCheckOnly)
2669                 {
2670                     pcoin->MarkSpent(n);
2671                     pcoin->WriteToDisk();
2672                 }
2673             }
2674
2675         }
2676
2677         if(IsMine((CTransaction)*pcoin) && (pcoin->IsCoinBase() || pcoin->IsCoinStake()) && pcoin->GetDepthInMainChain() == 0)
2678         {
2679             printf("FixSpentCoins %s tx %s\n", fCheckOnly ? "found" : "removed", pcoin->GetHash().ToString().c_str());
2680             if (!fCheckOnly)
2681             {
2682                 EraseFromWallet(pcoin->GetHash());
2683             }
2684         }
2685     }
2686 }
2687
2688 // ppcoin: disable transaction (only for coinstake)
2689 void CWallet::DisableTransaction(const CTransaction &tx)
2690 {
2691     if (!tx.IsCoinStake() || !IsFromMe(tx))
2692         return; // only disconnecting coinstake requires marking input unspent
2693
2694     LOCK(cs_wallet);
2695     BOOST_FOREACH(const CTxIn& txin, tx.vin)
2696     {
2697         map<uint256, CWalletTx>::iterator mi = mapWallet.find(txin.prevout.hash);
2698         if (mi != mapWallet.end())
2699         {
2700             CWalletTx& prev = (*mi).second;
2701             if (txin.prevout.n < prev.vout.size() && IsMine(prev.vout[txin.prevout.n]))
2702             {
2703                 prev.MarkUnspent(txin.prevout.n);
2704                 prev.WriteToDisk();
2705             }
2706         }
2707     }
2708 }
2709
2710 CPubKey CReserveKey::GetReservedKey()
2711 {
2712     if (nIndex == -1)
2713     {
2714         CKeyPool keypool;
2715         pwallet->ReserveKeyFromKeyPool(nIndex, keypool);
2716         if (nIndex != -1)
2717             vchPubKey = keypool.vchPubKey;
2718         else
2719         {
2720             printf("CReserveKey::GetReservedKey(): Warning: Using default key instead of a new key, top up your keypool!");
2721             vchPubKey = pwallet->vchDefaultKey;
2722         }
2723     }
2724     assert(vchPubKey.IsValid());
2725     return vchPubKey;
2726 }
2727
2728 void CReserveKey::KeepKey()
2729 {
2730     if (nIndex != -1)
2731         pwallet->KeepKey(nIndex);
2732     nIndex = -1;
2733     vchPubKey = CPubKey();
2734 }
2735
2736 void CReserveKey::ReturnKey()
2737 {
2738     if (nIndex != -1)
2739         pwallet->ReturnKey(nIndex);
2740     nIndex = -1;
2741     vchPubKey = CPubKey();
2742 }
2743
2744 void CWallet::GetAllReserveKeys(set<CKeyID>& setAddress) const
2745 {
2746     setAddress.clear();
2747
2748     CWalletDB walletdb(strWalletFile);
2749
2750     LOCK2(cs_main, cs_wallet);
2751     BOOST_FOREACH(const int64_t& id, setKeyPool)
2752     {
2753         CKeyPool keypool;
2754         if (!walletdb.ReadPool(id, keypool))
2755             throw runtime_error("GetAllReserveKeyHashes() : read failed");
2756         assert(keypool.vchPubKey.IsValid());
2757         CKeyID keyID = keypool.vchPubKey.GetID();
2758         if (!HaveKey(keyID))
2759             throw runtime_error("GetAllReserveKeyHashes() : unknown key in key pool");
2760         setAddress.insert(keyID);
2761     }
2762 }
2763
2764 void CWallet::UpdatedTransaction(const uint256 &hashTx)
2765 {
2766     {
2767         LOCK(cs_wallet);
2768         // Only notify UI if this transaction is in this wallet
2769         map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
2770         if (mi != mapWallet.end())
2771         {
2772             NotifyTransactionChanged(this, hashTx, CT_UPDATED);
2773             vMintingWalletUpdated.push_back(hashTx);
2774         }
2775     }
2776 }
2777
2778 void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const {
2779     mapKeyBirth.clear();
2780
2781     // get birth times for keys with metadata
2782     for (std::map<CKeyID, CKeyMetadata>::const_iterator it = mapKeyMetadata.begin(); it != mapKeyMetadata.end(); it++)
2783         if (it->second.nCreateTime)
2784             mapKeyBirth[it->first] = it->second.nCreateTime;
2785
2786     // map in which we'll infer heights of other keys
2787     CBlockIndex *pindexMax = FindBlockByHeight(std::max(0, nBestHeight - 144)); // the tip can be reorganised; use a 144-block safety margin
2788     std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
2789     std::set<CKeyID> setKeys;
2790     GetKeys(setKeys);
2791     BOOST_FOREACH(const CKeyID &keyid, setKeys) {
2792         if (mapKeyBirth.count(keyid) == 0)
2793             mapKeyFirstBlock[keyid] = pindexMax;
2794     }
2795     setKeys.clear();
2796
2797     // if there are no such keys, we're done
2798     if (mapKeyFirstBlock.empty())
2799         return;
2800
2801     // find first block that affects those keys, if there are any left
2802     std::vector<CKeyID> vAffected;
2803     for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
2804         // iterate over all wallet transactions...
2805         const CWalletTx &wtx = (*it).second;
2806         std::map<uint256, CBlockIndex*>::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
2807         if (blit != mapBlockIndex.end() && blit->second->IsInMainChain()) {
2808             // ... which are already in a block
2809             int nHeight = blit->second->nHeight;
2810             BOOST_FOREACH(const CTxOut &txout, wtx.vout) {
2811                 // iterate over all their outputs
2812                 ::ExtractAffectedKeys(*this, txout.scriptPubKey, vAffected);
2813                 BOOST_FOREACH(const CKeyID &keyid, vAffected) {
2814                     // ... and all their affected keys
2815                     std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
2816                     if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
2817                         rit->second = blit->second;
2818                 }
2819                 vAffected.clear();
2820             }
2821         }
2822     }
2823
2824     // Extract block timestamps for those keys
2825     for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
2826         mapKeyBirth[it->first] = it->second->nTime - 7200; // block times can be 2h off
2827 }
2828
2829 void CWallet::ClearOrphans()
2830 {
2831     list<uint256> orphans;
2832
2833     LOCK(cs_wallet);
2834     for(map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2835     {
2836         const CWalletTx *wtx = &(*it).second;
2837         if((wtx->IsCoinBase() || wtx->IsCoinStake()) && !wtx->IsInMainChain())
2838         {
2839             orphans.push_back(wtx->GetHash());
2840         }
2841     }
2842
2843     for(list<uint256>::const_iterator it = orphans.begin(); it != orphans.end(); ++it)
2844         EraseFromWallet(*it);
2845 }