]> Git Repo - VerusCoin.git/blame - src/wallet.h
Merge pull request #2336 from petertodd/invalid-opcode-coverage
[VerusCoin.git] / src / wallet.h
CommitLineData
b2120e22 1// Copyright (c) 2009-2010 Satoshi Nakamoto
88216419 2// Copyright (c) 2009-2012 The Bitcoin developers
e8ef3da7 3// Distributed under the MIT/X11 software license, see the accompanying
3a25a2b9 4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
e8ef3da7
WL
5#ifndef BITCOIN_WALLET_H
6#define BITCOIN_WALLET_H
7
9c7722b7
LD
8#include <string>
9#include <vector>
10
11#include <stdlib.h>
12
ed6d0b5f 13#include "main.h"
e8ef3da7 14#include "key.h"
2a45a494 15#include "keystore.h"
e8ef3da7 16#include "script.h"
ab1b288f 17#include "ui_interface.h"
9c7722b7 18#include "util.h"
eed1785f 19#include "walletdb.h"
e8ef3da7 20
c3f95ef1 21class CAccountingEntry;
e8ef3da7
WL
22class CWalletTx;
23class CReserveKey;
9b0369c7 24class COutput;
e8ef3da7 25
6b8de05d 26/** (client) version numbers for particular wallet features */
439e1497
PW
27enum WalletFeature
28{
29 FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output)
30
31 FEATURE_WALLETCRYPT = 40000, // wallet encryption
32 FEATURE_COMPRPUBKEY = 60000, // compressed public keys
33
34 FEATURE_LATEST = 60000
35};
36
ed6d0b5f
PW
37
38/** A key pool entry */
39class CKeyPool
40{
41public:
42 int64 nTime;
fd61d6f5 43 CPubKey vchPubKey;
ed6d0b5f
PW
44
45 CKeyPool()
46 {
47 nTime = GetTime();
48 }
49
fd61d6f5 50 CKeyPool(const CPubKey& vchPubKeyIn)
ed6d0b5f
PW
51 {
52 nTime = GetTime();
53 vchPubKey = vchPubKeyIn;
54 }
55
56 IMPLEMENT_SERIALIZE
57 (
58 if (!(nType & SER_GETHASH))
59 READWRITE(nVersion);
60 READWRITE(nTime);
61 READWRITE(vchPubKey);
62 )
63};
64
6b8de05d
PW
65/** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
66 * and provides the ability to create new transactions.
67 */
acd65016 68class CWallet : public CCryptoKeyStore
e8ef3da7
WL
69{
70private:
bde280b9 71 bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
e8ef3da7 72
96f34cd5 73 CWalletDB *pwalletdbEncryption;
e8ef3da7 74
439e1497 75 // the current wallet version: clients below this version are not able to load the wallet
0b807a41
PW
76 int nWalletVersion;
77
e7494052 78 // the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
439e1497
PW
79 int nWalletMaxVersion;
80
e8ef3da7 81public:
6cc4a62c
GA
82 mutable CCriticalSection cs_wallet;
83
e8ef3da7
WL
84 bool fFileBacked;
85 std::string strWalletFile;
86
bde280b9 87 std::set<int64> setKeyPool;
e8ef3da7 88
0b807a41 89
4e87d341
MC
90 typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
91 MasterKeyMap mapMasterKeys;
92 unsigned int nMasterKeyMaxID;
93
e8ef3da7
WL
94 CWallet()
95 {
439e1497
PW
96 nWalletVersion = FEATURE_BASE;
97 nWalletMaxVersion = FEATURE_BASE;
e8ef3da7 98 fFileBacked = false;
4e87d341 99 nMasterKeyMaxID = 0;
96f34cd5 100 pwalletdbEncryption = NULL;
da7b8c12 101 nOrderPosNext = 0;
e8ef3da7
WL
102 }
103 CWallet(std::string strWalletFileIn)
104 {
439e1497
PW
105 nWalletVersion = FEATURE_BASE;
106 nWalletMaxVersion = FEATURE_BASE;
e8ef3da7
WL
107 strWalletFile = strWalletFileIn;
108 fFileBacked = true;
4e87d341 109 nMasterKeyMaxID = 0;
96f34cd5 110 pwalletdbEncryption = NULL;
da7b8c12 111 nOrderPosNext = 0;
e8ef3da7
WL
112 }
113
e8ef3da7 114 std::map<uint256, CWalletTx> mapWallet;
9c7722b7 115 int64 nOrderPosNext;
e8ef3da7 116 std::map<uint256, int> mapRequestCount;
e8ef3da7 117
10254401 118 std::map<CTxDestination, std::string> mapAddressBook;
e8ef3da7 119
fd61d6f5 120 CPubKey vchDefaultKey;
e8ef3da7 121
fdbb537d
JG
122 std::set<COutPoint> setLockedCoins;
123
439e1497
PW
124 // check whether we are allowed to upgrade (or already support) to the named feature
125 bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
126
a2709fad 127 void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true) const;
9b0369c7 128 bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
fdbb537d
JG
129 bool IsLockedCoin(uint256 hash, unsigned int n) const;
130 void LockCoin(COutPoint& output);
131 void UnlockCoin(COutPoint& output);
132 void UnlockAllCoins();
133 void ListLockedCoins(std::vector<COutPoint>& vOutpts);
9b0369c7 134
acd65016 135 // keystore implementation
9976cf07 136 // Generate a new key
fd61d6f5 137 CPubKey GenerateNewKey();
d825e6a3 138 // Adds a key to the store, and saves it to disk.
e8ef3da7 139 bool AddKey(const CKey& key);
d825e6a3 140 // Adds a key to the store, without saving it to disk (used by LoadWallet)
acd65016 141 bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); }
d825e6a3 142
439e1497 143 bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
0b807a41 144
d825e6a3 145 // Adds an encrypted key to the store, and saves it to disk.
fd61d6f5 146 bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
d825e6a3 147 // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
fd61d6f5 148 bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
922e8e29
GA
149 bool AddCScript(const CScript& redeemScript);
150 bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
4e87d341 151
94f778bd
DN
152 bool Unlock(const SecureString& strWalletPassphrase);
153 bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
154 bool EncryptWallet(const SecureString& strWalletPassphrase);
acd65016 155
da7b8c12
LD
156 /** Increment the next transaction order id
157 @return next transaction order id
158 */
4291e8fe 159 int64 IncOrderPosNext(CWalletDB *pwalletdb = NULL);
da7b8c12 160
c3f95ef1
LD
161 typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
162 typedef std::multimap<int64, TxPair > TxItems;
ddb709e9
LD
163
164 /** Get the wallet's activity log
165 @return multimap of ordered transactions and accounting entries
166 @warning Returned pointers are *only* valid within the scope of passed acentries
167 */
168 TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = "");
c3f95ef1 169
95d888a6 170 void MarkDirty();
e8ef3da7 171 bool AddToWallet(const CWalletTx& wtxIn);
64dd46fd 172 bool AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false);
e8ef3da7
WL
173 bool EraseFromWallet(uint256 hash);
174 void WalletUpdateSpent(const CTransaction& prevout);
175 int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
176 void ReacceptWalletTransactions();
177 void ResendWalletTransactions();
bde280b9
WL
178 int64 GetBalance() const;
179 int64 GetUnconfirmedBalance() const;
8fdb7e10 180 int64 GetImmatureBalance() const;
bde280b9
WL
181 bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
182 bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
e8ef3da7 183 bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
bde280b9 184 std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
10254401 185 std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
e8ef3da7 186
37971fcc 187 bool NewKeyPool();
4e87d341 188 bool TopUpKeyPool();
bde280b9
WL
189 int64 AddReserveKey(const CKeyPool& keypool);
190 void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
191 void KeepKey(int64 nIndex);
192 void ReturnKey(int64 nIndex);
fd61d6f5 193 bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true);
bde280b9 194 int64 GetOldestKeyPoolTime();
10254401 195 void GetAllReserveKeys(std::set<CKeyID>& setAddress);
e8ef3da7 196
b1093efa
GM
197 std::set< std::set<CTxDestination> > GetAddressGroupings();
198 std::map<CTxDestination, int64> GetAddressBalances();
22dfd735 199
e8ef3da7 200 bool IsMine(const CTxIn& txin) const;
bde280b9 201 int64 GetDebit(const CTxIn& txin) const;
e8ef3da7
WL
202 bool IsMine(const CTxOut& txout) const
203 {
204 return ::IsMine(*this, txout.scriptPubKey);
205 }
bde280b9 206 int64 GetCredit(const CTxOut& txout) const
e8ef3da7
WL
207 {
208 if (!MoneyRange(txout.nValue))
209 throw std::runtime_error("CWallet::GetCredit() : value out of range");
210 return (IsMine(txout) ? txout.nValue : 0);
211 }
e679ec96 212 bool IsChange(const CTxOut& txout) const;
bde280b9 213 int64 GetChange(const CTxOut& txout) const
e8ef3da7
WL
214 {
215 if (!MoneyRange(txout.nValue))
216 throw std::runtime_error("CWallet::GetChange() : value out of range");
217 return (IsChange(txout) ? txout.nValue : 0);
218 }
219 bool IsMine(const CTransaction& tx) const
220 {
221 BOOST_FOREACH(const CTxOut& txout, tx.vout)
222 if (IsMine(txout))
223 return true;
224 return false;
225 }
226 bool IsFromMe(const CTransaction& tx) const
227 {
228 return (GetDebit(tx) > 0);
229 }
bde280b9 230 int64 GetDebit(const CTransaction& tx) const
e8ef3da7 231 {
bde280b9 232 int64 nDebit = 0;
e8ef3da7
WL
233 BOOST_FOREACH(const CTxIn& txin, tx.vin)
234 {
235 nDebit += GetDebit(txin);
236 if (!MoneyRange(nDebit))
237 throw std::runtime_error("CWallet::GetDebit() : value out of range");
238 }
239 return nDebit;
240 }
bde280b9 241 int64 GetCredit(const CTransaction& tx) const
e8ef3da7 242 {
bde280b9 243 int64 nCredit = 0;
e8ef3da7
WL
244 BOOST_FOREACH(const CTxOut& txout, tx.vout)
245 {
246 nCredit += GetCredit(txout);
247 if (!MoneyRange(nCredit))
248 throw std::runtime_error("CWallet::GetCredit() : value out of range");
249 }
250 return nCredit;
251 }
bde280b9 252 int64 GetChange(const CTransaction& tx) const
e8ef3da7 253 {
bde280b9 254 int64 nChange = 0;
e8ef3da7
WL
255 BOOST_FOREACH(const CTxOut& txout, tx.vout)
256 {
257 nChange += GetChange(txout);
258 if (!MoneyRange(nChange))
259 throw std::runtime_error("CWallet::GetChange() : value out of range");
260 }
261 return nChange;
262 }
ed6d0b5f 263 void SetBestChain(const CBlockLocator& loc);
e8ef3da7 264
eed1785f 265 DBErrors LoadWallet(bool& fFirstRunRet);
ae3d0aba 266
10254401 267 bool SetAddressBookName(const CTxDestination& address, const std::string& strName);
ae3d0aba 268
10254401 269 bool DelAddressBookName(const CTxDestination& address);
e8ef3da7 270
fe4a6550 271 void UpdatedTransaction(const uint256 &hashTx);
e8ef3da7
WL
272
273 void PrintWallet(const CBlock& block);
274
275 void Inventory(const uint256 &hash)
276 {
e8ef3da7 277 {
f8dcd5ca 278 LOCK(cs_wallet);
e8ef3da7
WL
279 std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
280 if (mi != mapRequestCount.end())
281 (*mi).second++;
282 }
283 }
284
4e87d341
MC
285 int GetKeyPoolSize()
286 {
287 return setKeyPool.size();
288 }
289
e8ef3da7
WL
290 bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
291
fd61d6f5 292 bool SetDefaultKey(const CPubKey &vchPubKey);
0b807a41 293
439e1497
PW
294 // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
295 bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
296
297 // change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
298 bool SetMaxVersion(int nVersion);
299
300 // get the current wallet format (the oldest client version guaranteed to understand this wallet)
301 int GetVersion() { return nWalletVersion; }
ab1b288f
WL
302
303 /** Address book entry changed.
304 * @note called with lock cs_wallet held.
305 */
10254401 306 boost::signals2::signal<void (CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
ab1b288f
WL
307
308 /** Wallet transaction added, removed or updated.
309 * @note called with lock cs_wallet held.
310 */
311 boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged;
e8ef3da7
WL
312};
313
6b8de05d 314/** A key allocated from the key pool. */
e8ef3da7
WL
315class CReserveKey
316{
317protected:
318 CWallet* pwallet;
bde280b9 319 int64 nIndex;
fd61d6f5 320 CPubKey vchPubKey;
e8ef3da7
WL
321public:
322 CReserveKey(CWallet* pwalletIn)
323 {
324 nIndex = -1;
325 pwallet = pwalletIn;
326 }
327
328 ~CReserveKey()
329 {
330 if (!fShutdown)
331 ReturnKey();
332 }
333
334 void ReturnKey();
fd61d6f5 335 CPubKey GetReservedKey();
e8ef3da7
WL
336 void KeepKey();
337};
338
339
9c7722b7
LD
340typedef std::map<std::string, std::string> mapValue_t;
341
342
bdab0cf5 343static void ReadOrderPos(int64& nOrderPos, mapValue_t& mapValue)
9c7722b7
LD
344{
345 if (!mapValue.count("n"))
346 {
347 nOrderPos = -1; // TODO: calculate elsewhere
348 return;
349 }
350 nOrderPos = atoi64(mapValue["n"].c_str());
351}
352
353
bdab0cf5 354static void WriteOrderPos(const int64& nOrderPos, mapValue_t& mapValue)
9c7722b7
LD
355{
356 if (nOrderPos == -1)
357 return;
358 mapValue["n"] = i64tostr(nOrderPos);
359}
360
361
ea0796bd 362/** A transaction with a bunch of additional info that only the owner cares about.
6b8de05d
PW
363 * It includes any unrecorded transactions needed to link it back to the block chain.
364 */
e8ef3da7
WL
365class CWalletTx : public CMerkleTx
366{
4c6e2295 367private:
e8ef3da7
WL
368 const CWallet* pwallet;
369
4c6e2295 370public:
e8ef3da7 371 std::vector<CMerkleTx> vtxPrev;
9c7722b7 372 mapValue_t mapValue;
e8ef3da7
WL
373 std::vector<std::pair<std::string, std::string> > vOrderForm;
374 unsigned int fTimeReceivedIsTxTime;
375 unsigned int nTimeReceived; // time received by this node
c3f95ef1 376 unsigned int nTimeSmart;
e8ef3da7
WL
377 char fFromMe;
378 std::string strFromAccount;
d825e6a3 379 std::vector<char> vfSpent; // which outputs are already spent
9c7722b7 380 int64 nOrderPos; // position in ordered transaction list
e8ef3da7
WL
381
382 // memory only
cdcc319c
WL
383 mutable bool fDebitCached;
384 mutable bool fCreditCached;
966a0e8c 385 mutable bool fImmatureCreditCached;
cdcc319c
WL
386 mutable bool fAvailableCreditCached;
387 mutable bool fChangeCached;
bde280b9
WL
388 mutable int64 nDebitCached;
389 mutable int64 nCreditCached;
966a0e8c 390 mutable int64 nImmatureCreditCached;
bde280b9
WL
391 mutable int64 nAvailableCreditCached;
392 mutable int64 nChangeCached;
e8ef3da7 393
e8ef3da7
WL
394 CWalletTx()
395 {
396 Init(NULL);
397 }
398
399 CWalletTx(const CWallet* pwalletIn)
400 {
401 Init(pwalletIn);
402 }
403
404 CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
405 {
406 Init(pwalletIn);
407 }
408
409 CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
410 {
411 Init(pwalletIn);
412 }
413
414 void Init(const CWallet* pwalletIn)
415 {
416 pwallet = pwalletIn;
417 vtxPrev.clear();
418 mapValue.clear();
419 vOrderForm.clear();
420 fTimeReceivedIsTxTime = false;
421 nTimeReceived = 0;
c3f95ef1 422 nTimeSmart = 0;
e8ef3da7
WL
423 fFromMe = false;
424 strFromAccount.clear();
425 vfSpent.clear();
426 fDebitCached = false;
427 fCreditCached = false;
966a0e8c 428 fImmatureCreditCached = false;
e8ef3da7
WL
429 fAvailableCreditCached = false;
430 fChangeCached = false;
431 nDebitCached = 0;
432 nCreditCached = 0;
966a0e8c 433 nImmatureCreditCached = 0;
e8ef3da7
WL
434 nAvailableCreditCached = 0;
435 nChangeCached = 0;
9c7722b7 436 nOrderPos = -1;
e8ef3da7
WL
437 }
438
439 IMPLEMENT_SERIALIZE
440 (
441 CWalletTx* pthis = const_cast<CWalletTx*>(this);
442 if (fRead)
443 pthis->Init(NULL);
444 char fSpent = false;
445
446 if (!fRead)
447 {
448 pthis->mapValue["fromaccount"] = pthis->strFromAccount;
449
450 std::string str;
451 BOOST_FOREACH(char f, vfSpent)
452 {
453 str += (f ? '1' : '0');
454 if (f)
455 fSpent = true;
456 }
457 pthis->mapValue["spent"] = str;
9c7722b7
LD
458
459 WriteOrderPos(pthis->nOrderPos, pthis->mapValue);
c3f95ef1
LD
460
461 if (nTimeSmart)
462 pthis->mapValue["timesmart"] = strprintf("%u", nTimeSmart);
e8ef3da7
WL
463 }
464
465 nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
466 READWRITE(vtxPrev);
467 READWRITE(mapValue);
468 READWRITE(vOrderForm);
469 READWRITE(fTimeReceivedIsTxTime);
470 READWRITE(nTimeReceived);
471 READWRITE(fFromMe);
472 READWRITE(fSpent);
473
474 if (fRead)
475 {
476 pthis->strFromAccount = pthis->mapValue["fromaccount"];
477
478 if (mapValue.count("spent"))
479 BOOST_FOREACH(char c, pthis->mapValue["spent"])
480 pthis->vfSpent.push_back(c != '0');
481 else
482 pthis->vfSpent.assign(vout.size(), fSpent);
e8ef3da7 483
9c7722b7
LD
484 ReadOrderPos(pthis->nOrderPos, pthis->mapValue);
485
c3f95ef1
LD
486 pthis->nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(pthis->mapValue["timesmart"]) : 0;
487 }
488
e8ef3da7
WL
489 pthis->mapValue.erase("fromaccount");
490 pthis->mapValue.erase("version");
491 pthis->mapValue.erase("spent");
9c7722b7 492 pthis->mapValue.erase("n");
c3f95ef1 493 pthis->mapValue.erase("timesmart");
e8ef3da7
WL
494 )
495
496 // marks certain txout's as spent
497 // returns true if any update took place
498 bool UpdateSpent(const std::vector<char>& vfNewSpent)
499 {
500 bool fReturn = false;
c376ac35 501 for (unsigned int i = 0; i < vfNewSpent.size(); i++)
e8ef3da7
WL
502 {
503 if (i == vfSpent.size())
504 break;
505
506 if (vfNewSpent[i] && !vfSpent[i])
507 {
508 vfSpent[i] = true;
509 fReturn = true;
510 fAvailableCreditCached = false;
511 }
512 }
513 return fReturn;
514 }
515
d825e6a3 516 // make sure balances are recalculated
e8ef3da7
WL
517 void MarkDirty()
518 {
519 fCreditCached = false;
520 fAvailableCreditCached = false;
521 fDebitCached = false;
522 fChangeCached = false;
523 }
524
4c6e2295
PW
525 void BindWallet(CWallet *pwalletIn)
526 {
527 pwallet = pwalletIn;
528 MarkDirty();
529 }
530
e8ef3da7
WL
531 void MarkSpent(unsigned int nOut)
532 {
533 if (nOut >= vout.size())
534 throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range");
535 vfSpent.resize(vout.size());
536 if (!vfSpent[nOut])
537 {
538 vfSpent[nOut] = true;
539 fAvailableCreditCached = false;
540 }
541 }
542
543 bool IsSpent(unsigned int nOut) const
544 {
545 if (nOut >= vout.size())
546 throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
547 if (nOut >= vfSpent.size())
548 return false;
549 return (!!vfSpent[nOut]);
550 }
551
bde280b9 552 int64 GetDebit() const
e8ef3da7
WL
553 {
554 if (vin.empty())
555 return 0;
556 if (fDebitCached)
557 return nDebitCached;
558 nDebitCached = pwallet->GetDebit(*this);
559 fDebitCached = true;
560 return nDebitCached;
561 }
562
bde280b9 563 int64 GetCredit(bool fUseCache=true) const
e8ef3da7
WL
564 {
565 // Must wait until coinbase is safely deep enough in the chain before valuing it
566 if (IsCoinBase() && GetBlocksToMaturity() > 0)
567 return 0;
568
569 // GetBalance can assume transactions in mapWallet won't change
570 if (fUseCache && fCreditCached)
571 return nCreditCached;
572 nCreditCached = pwallet->GetCredit(*this);
573 fCreditCached = true;
574 return nCreditCached;
575 }
576
966a0e8c
PK
577 int64 GetImmatureCredit(bool fUseCache=true) const
578 {
579 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
580 {
581 if (fUseCache && fImmatureCreditCached)
582 return nImmatureCreditCached;
583 nImmatureCreditCached = pwallet->GetCredit(*this);
584 fImmatureCreditCached = true;
585 return nImmatureCreditCached;
586 }
587
588 return 0;
589 }
590
bde280b9 591 int64 GetAvailableCredit(bool fUseCache=true) const
e8ef3da7
WL
592 {
593 // Must wait until coinbase is safely deep enough in the chain before valuing it
594 if (IsCoinBase() && GetBlocksToMaturity() > 0)
595 return 0;
596
597 if (fUseCache && fAvailableCreditCached)
598 return nAvailableCreditCached;
599
bde280b9 600 int64 nCredit = 0;
c376ac35 601 for (unsigned int i = 0; i < vout.size(); i++)
e8ef3da7
WL
602 {
603 if (!IsSpent(i))
604 {
605 const CTxOut &txout = vout[i];
606 nCredit += pwallet->GetCredit(txout);
607 if (!MoneyRange(nCredit))
608 throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
609 }
610 }
611
612 nAvailableCreditCached = nCredit;
613 fAvailableCreditCached = true;
614 return nCredit;
615 }
616
617
bde280b9 618 int64 GetChange() const
e8ef3da7
WL
619 {
620 if (fChangeCached)
621 return nChangeCached;
622 nChangeCached = pwallet->GetChange(*this);
623 fChangeCached = true;
624 return nChangeCached;
625 }
626
e07c8e91 627 void GetAmounts(std::list<std::pair<CTxDestination, int64> >& listReceived,
10254401 628 std::list<std::pair<CTxDestination, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
e8ef3da7 629
e07c8e91 630 void GetAccountAmounts(const std::string& strAccount, int64& nReceived,
bde280b9 631 int64& nSent, int64& nFee) const;
e8ef3da7
WL
632
633 bool IsFromMe() const
634 {
635 return (GetDebit() > 0);
636 }
637
638 bool IsConfirmed() const
639 {
640 // Quick answer in most cases
641 if (!IsFinal())
642 return false;
643 if (GetDepthInMainChain() >= 1)
644 return true;
645 if (!IsFromMe()) // using wtx's cached debit
646 return false;
647
648 // If no confirmations but it's from us, we can still
649 // consider it confirmed if all dependencies are confirmed
650 std::map<uint256, const CMerkleTx*> mapPrev;
651 std::vector<const CMerkleTx*> vWorkQueue;
652 vWorkQueue.reserve(vtxPrev.size()+1);
653 vWorkQueue.push_back(this);
c376ac35 654 for (unsigned int i = 0; i < vWorkQueue.size(); i++)
e8ef3da7
WL
655 {
656 const CMerkleTx* ptx = vWorkQueue[i];
657
658 if (!ptx->IsFinal())
659 return false;
660 if (ptx->GetDepthInMainChain() >= 1)
661 continue;
662 if (!pwallet->IsFromMe(*ptx))
663 return false;
664
665 if (mapPrev.empty())
da7bbd9d 666 {
e8ef3da7
WL
667 BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
668 mapPrev[tx.GetHash()] = &tx;
da7bbd9d 669 }
e8ef3da7
WL
670
671 BOOST_FOREACH(const CTxIn& txin, ptx->vin)
672 {
673 if (!mapPrev.count(txin.prevout.hash))
674 return false;
675 vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
676 }
677 }
678 return true;
679 }
680
681 bool WriteToDisk();
682
bde280b9 683 int64 GetTxTime() const;
e8ef3da7
WL
684 int GetRequestCount() const;
685
450cbb09 686 void AddSupportingTransactions();
ae8bfd12 687 bool AcceptWalletTransaction(bool fCheckInputs=true);
e8ef3da7
WL
688 void RelayWalletTransaction();
689};
690
691
9b0369c7
CM
692
693
694class COutput
695{
696public:
697 const CWalletTx *tx;
698 int i;
699 int nDepth;
700
701 COutput(const CWalletTx *txIn, int iIn, int nDepthIn)
702 {
703 tx = txIn; i = iIn; nDepth = nDepthIn;
704 }
705
706 std::string ToString() const
707 {
708 return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString().substr(0,10).c_str(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str());
709 }
710
711 void print() const
712 {
713 printf("%s\n", ToString().c_str());
714 }
715};
716
717
718
719
6b8de05d 720/** Private key that includes an expiration date in case it never gets used. */
e8ef3da7
WL
721class CWalletKey
722{
723public:
724 CPrivKey vchPrivKey;
bde280b9
WL
725 int64 nTimeCreated;
726 int64 nTimeExpires;
e8ef3da7
WL
727 std::string strComment;
728 //// todo: add something to note what created it (user, getnewaddress, change)
729 //// maybe should have a map<string, string> property map
730
bde280b9 731 CWalletKey(int64 nExpires=0)
e8ef3da7
WL
732 {
733 nTimeCreated = (nExpires ? GetTime() : 0);
734 nTimeExpires = nExpires;
735 }
736
737 IMPLEMENT_SERIALIZE
738 (
739 if (!(nType & SER_GETHASH))
740 READWRITE(nVersion);
741 READWRITE(vchPrivKey);
742 READWRITE(nTimeCreated);
743 READWRITE(nTimeExpires);
744 READWRITE(strComment);
745 )
746};
747
748
749
750
751
752
6b8de05d
PW
753/** Account information.
754 * Stored in wallet with key "acc"+string account name.
755 */
e8ef3da7
WL
756class CAccount
757{
758public:
fd61d6f5 759 CPubKey vchPubKey;
e8ef3da7
WL
760
761 CAccount()
762 {
763 SetNull();
764 }
765
766 void SetNull()
767 {
fd61d6f5 768 vchPubKey = CPubKey();
e8ef3da7
WL
769 }
770
771 IMPLEMENT_SERIALIZE
772 (
773 if (!(nType & SER_GETHASH))
774 READWRITE(nVersion);
775 READWRITE(vchPubKey);
776 )
777};
778
779
780
6b8de05d
PW
781/** Internal transfers.
782 * Database key is acentry<account><counter>.
783 */
e8ef3da7
WL
784class CAccountingEntry
785{
786public:
787 std::string strAccount;
bde280b9
WL
788 int64 nCreditDebit;
789 int64 nTime;
e8ef3da7
WL
790 std::string strOtherAccount;
791 std::string strComment;
9c7722b7
LD
792 mapValue_t mapValue;
793 int64 nOrderPos; // position in ordered transaction list
794 uint64 nEntryNo;
e8ef3da7
WL
795
796 CAccountingEntry()
797 {
798 SetNull();
799 }
800
801 void SetNull()
802 {
803 nCreditDebit = 0;
804 nTime = 0;
805 strAccount.clear();
806 strOtherAccount.clear();
807 strComment.clear();
9c7722b7 808 nOrderPos = -1;
e8ef3da7
WL
809 }
810
811 IMPLEMENT_SERIALIZE
812 (
9c7722b7 813 CAccountingEntry& me = *const_cast<CAccountingEntry*>(this);
e8ef3da7
WL
814 if (!(nType & SER_GETHASH))
815 READWRITE(nVersion);
816 // Note: strAccount is serialized as part of the key, not here.
817 READWRITE(nCreditDebit);
818 READWRITE(nTime);
819 READWRITE(strOtherAccount);
9c7722b7
LD
820
821 if (!fRead)
822 {
823 WriteOrderPos(nOrderPos, me.mapValue);
824
825 if (!(mapValue.empty() && _ssExtra.empty()))
826 {
827 CDataStream ss(nType, nVersion);
828 ss.insert(ss.begin(), '\0');
829 ss << mapValue;
830 ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
831 me.strComment.append(ss.str());
832 }
833 }
834
e8ef3da7 835 READWRITE(strComment);
9c7722b7
LD
836
837 size_t nSepPos = strComment.find("\0", 0, 1);
838 if (fRead)
839 {
840 me.mapValue.clear();
841 if (std::string::npos != nSepPos)
842 {
843 CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion);
844 ss >> me.mapValue;
845 me._ssExtra = std::vector<char>(ss.begin(), ss.end());
846 }
847 ReadOrderPos(me.nOrderPos, me.mapValue);
848 }
849 if (std::string::npos != nSepPos)
850 me.strComment.erase(nSepPos);
851
852 me.mapValue.erase("n");
e8ef3da7 853 )
9c7722b7
LD
854
855private:
856 std::vector<char> _ssExtra;
e8ef3da7
WL
857};
858
859bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
860
861#endif
This page took 0.25258 seconds and 4 git commands to generate.