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