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