wallet.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. // ECOin - Copyright (c) - 2014/2022 - GPLv3 - epsylon@riseup.net (https://03c8.net)
  2. #ifndef ECOIN_WALLET_H
  3. #define ECOIN_WALLET_H
  4. #include <string>
  5. #include <vector>
  6. #include <stdlib.h>
  7. #include "main.h"
  8. #include "key.h"
  9. #include "keystore.h"
  10. #include "script.h"
  11. #include "ui_interface.h"
  12. #include "util.h"
  13. #include "walletdb.h"
  14. extern bool fWalletUnlockStakingOnly;
  15. extern bool fConfChange;
  16. class CAccountingEntry;
  17. class CWalletTx;
  18. class CReserveKey;
  19. class COutput;
  20. class CCoinControl;
  21. /** (client) version numbers for particular wallet features */
  22. enum WalletFeature
  23. {
  24. FEATURE_BASE = 10500, // the earliest version new wallets supports (only useful for getinfo's clientversion output)
  25. FEATURE_WALLETCRYPT = 40000, // wallet encryption
  26. FEATURE_COMPRPUBKEY = 60000, // compressed public keys
  27. FEATURE_LATEST = 60000
  28. };
  29. /** A key pool entry */
  30. class CKeyPool
  31. {
  32. public:
  33. int64 nTime;
  34. CPubKey vchPubKey;
  35. CKeyPool()
  36. {
  37. nTime = GetTime();
  38. }
  39. CKeyPool(const CPubKey& vchPubKeyIn)
  40. {
  41. nTime = GetTime();
  42. vchPubKey = vchPubKeyIn;
  43. }
  44. IMPLEMENT_SERIALIZE
  45. (
  46. if (!(nType & SER_GETHASH))
  47. READWRITE(nVersion);
  48. READWRITE(nTime);
  49. READWRITE(vchPubKey);
  50. )
  51. };
  52. /** A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,
  53. * and provides the ability to create new transactions.
  54. */
  55. class CWallet : public CCryptoKeyStore
  56. {
  57. private:
  58. bool SelectCoinsSimple(int64 nTargetValue, unsigned int nSpendTime, int nMinConf, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
  59. bool SelectCoins(int64 nTargetValue, unsigned int nSpendTime, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet, const CCoinControl *coinControl=NULL) const;
  60. CWalletDB *pwalletdbEncryption;
  61. // the current wallet version: clients below this version are not able to load the wallet
  62. int nWalletVersion;
  63. // the maximum wallet format version: memory-only variable that specifies to what version this wallet may be upgraded
  64. int nWalletMaxVersion;
  65. public:
  66. mutable CCriticalSection cs_wallet;
  67. bool fFileBacked;
  68. std::string strWalletFile;
  69. std::set<int64> setKeyPool;
  70. std::map<CKeyID, CKeyMetadata> mapKeyMetadata;
  71. typedef std::map<unsigned int, CMasterKey> MasterKeyMap;
  72. MasterKeyMap mapMasterKeys;
  73. unsigned int nMasterKeyMaxID;
  74. CWallet()
  75. {
  76. nWalletVersion = FEATURE_BASE;
  77. nWalletMaxVersion = FEATURE_BASE;
  78. fFileBacked = false;
  79. nMasterKeyMaxID = 0;
  80. pwalletdbEncryption = NULL;
  81. nOrderPosNext = 0;
  82. }
  83. CWallet(std::string strWalletFileIn)
  84. {
  85. nWalletVersion = FEATURE_BASE;
  86. nWalletMaxVersion = FEATURE_BASE;
  87. strWalletFile = strWalletFileIn;
  88. fFileBacked = true;
  89. nMasterKeyMaxID = 0;
  90. pwalletdbEncryption = NULL;
  91. nOrderPosNext = 0;
  92. }
  93. std::map<uint256, CWalletTx> mapWallet;
  94. int64 nOrderPosNext;
  95. std::map<uint256, int> mapRequestCount;
  96. std::map<CTxDestination, std::string> mapAddressBook;
  97. CPubKey vchDefaultKey;
  98. int64 nTimeFirstKey;
  99. // check whether we are allowed to upgrade (or already support) to the named feature
  100. bool CanSupportFeature(enum WalletFeature wf) { return nWalletMaxVersion >= wf; }
  101. void AvailableCoinsMinConf(std::vector<COutput>& vCoins, int nConf) const;
  102. void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlyConfirmed=true, const CCoinControl *coinControl=NULL) const;
  103. bool SelectCoinsMinConf(int64 nTargetValue, unsigned int nSpendTime, int nConfMine, int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
  104. // keystore implementation
  105. // Generate a new key
  106. CPubKey GenerateNewKey();
  107. // Adds a key to the store, and saves it to disk.
  108. bool AddKey(const CKey& key);
  109. // Adds a key to the store, without saving it to disk (used by LoadWallet)
  110. bool LoadKey(const CKey& key) { return CCryptoKeyStore::AddKey(key); }
  111. // Load metadata (used by LoadWallet)
  112. bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata);
  113. bool LoadMinVersion(int nVersion) { nWalletVersion = nVersion; nWalletMaxVersion = std::max(nWalletMaxVersion, nVersion); return true; }
  114. // Adds an encrypted key to the store, and saves it to disk.
  115. bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
  116. // Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
  117. //bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret) { SetMinVersion(FEATURE_WALLETCRYPT); return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); }
  118. bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
  119. bool AddCScript(const CScript& redeemScript);
  120. bool LoadCScript(const CScript& redeemScript) { return CCryptoKeyStore::AddCScript(redeemScript); }
  121. bool Unlock(const SecureString& strWalletPassphrase);
  122. bool ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase);
  123. bool EncryptWallet(const SecureString& strWalletPassphrase);
  124. void GetKeyBirthTimes(std::map<CKeyID, int64> &mapKeyBirth) const;
  125. int64 IncOrderPosNext(CWalletDB *pwalletdb = NULL);
  126. typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
  127. typedef std::multimap<int64, TxPair > TxItems;
  128. TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = "");
  129. void MarkDirty();
  130. bool AddToWallet(const CWalletTx& wtxIn);
  131. bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false, bool fFindBlock = false);
  132. bool EraseFromWallet(uint256 hash);
  133. void WalletUpdateSpent(const CTransaction& prevout, bool fBlock = false);
  134. int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
  135. int ScanForWalletTransaction(const uint256& hashTx);
  136. void ReacceptWalletTransactions();
  137. void ResendWalletTransactions(bool fForce = false);
  138. int64 GetBalance() const;
  139. int64 GetUnconfirmedBalance() const;
  140. int64 GetImmatureBalance() const;
  141. int64 GetStake() const;
  142. int64 GetNewMint() const;
  143. bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL);
  144. bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet, const CCoinControl *coinControl=NULL);
  145. bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
  146. bool GetStakeWeight(const CKeyStore& keystore, uint64_t& nMinWeight, uint64_t& nMaxWeight, uint64_t& nWeight);
  147. bool CreateCoinStake(const CKeyStore& keystore, unsigned int nBits, int64 nSearchInterval, CTransaction& txNew, CKey& key);
  148. std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
  149. std::string SendMoneyToDestination(const CTxDestination &address, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
  150. bool NewKeyPool();
  151. bool TopUpKeyPool(unsigned int nSize = 0);
  152. int64 AddReserveKey(const CKeyPool& keypool);
  153. void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
  154. void KeepKey(int64 nIndex);
  155. void ReturnKey(int64 nIndex);
  156. bool GetKeyFromPool(CPubKey &key, bool fAllowReuse=true);
  157. int64 GetOldestKeyPoolTime();
  158. void GetAllReserveKeys(std::set<CKeyID>& setAddress) const;
  159. std::set< std::set<CTxDestination> > GetAddressGroupings();
  160. std::map<CTxDestination, int64> GetAddressBalances();
  161. bool IsMine(const CTxIn& txin) const;
  162. int64 GetDebit(const CTxIn& txin) const;
  163. bool IsMine(const CTxOut& txout) const
  164. {
  165. return ::IsMine(*this, txout.scriptPubKey);
  166. }
  167. int64 GetCredit(const CTxOut& txout) const
  168. {
  169. if (!MoneyRange(txout.nValue))
  170. throw std::runtime_error("CWallet::GetCredit() : value out of range");
  171. return (IsMine(txout) ? txout.nValue : 0);
  172. }
  173. bool IsChange(const CTxOut& txout) const;
  174. int64 GetChange(const CTxOut& txout) const
  175. {
  176. if (!MoneyRange(txout.nValue))
  177. throw std::runtime_error("CWallet::GetChange() : value out of range");
  178. return (IsChange(txout) ? txout.nValue : 0);
  179. }
  180. bool IsMine(const CTransaction& tx) const
  181. {
  182. BOOST_FOREACH(const CTxOut& txout, tx.vout)
  183. if (IsMine(txout) && txout.nValue >= nMinimumInputValue)
  184. return true;
  185. return false;
  186. }
  187. bool IsFromMe(const CTransaction& tx) const
  188. {
  189. return (GetDebit(tx) > 0);
  190. }
  191. int64 GetDebit(const CTransaction& tx) const
  192. {
  193. int64 nDebit = 0;
  194. BOOST_FOREACH(const CTxIn& txin, tx.vin)
  195. {
  196. nDebit += GetDebit(txin);
  197. if (!MoneyRange(nDebit))
  198. throw std::runtime_error("CWallet::GetDebit() : value out of range");
  199. }
  200. return nDebit;
  201. }
  202. int64 GetCredit(const CTransaction& tx) const
  203. {
  204. int64 nCredit = 0;
  205. BOOST_FOREACH(const CTxOut& txout, tx.vout)
  206. {
  207. nCredit += GetCredit(txout);
  208. if (!MoneyRange(nCredit))
  209. throw std::runtime_error("CWallet::GetCredit() : value out of range");
  210. }
  211. return nCredit;
  212. }
  213. int64 GetChange(const CTransaction& tx) const
  214. {
  215. int64 nChange = 0;
  216. BOOST_FOREACH(const CTxOut& txout, tx.vout)
  217. {
  218. nChange += GetChange(txout);
  219. if (!MoneyRange(nChange))
  220. throw std::runtime_error("CWallet::GetChange() : value out of range");
  221. }
  222. return nChange;
  223. }
  224. void SetBestChain(const CBlockLocator& loc);
  225. DBErrors LoadWallet(bool& fFirstRunRet);
  226. bool SetAddressBookName(const CTxDestination& address, const std::string& strName);
  227. bool DelAddressBookName(const CTxDestination& address);
  228. void UpdatedTransaction(const uint256 &hashTx);
  229. void PrintWallet(const CBlock& block);
  230. void Inventory(const uint256 &hash)
  231. {
  232. {
  233. LOCK(cs_wallet);
  234. std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
  235. if (mi != mapRequestCount.end())
  236. (*mi).second++;
  237. }
  238. }
  239. unsigned int GetKeyPoolSize()
  240. {
  241. return setKeyPool.size();
  242. }
  243. bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
  244. bool SetDefaultKey(const CPubKey &vchPubKey);
  245. // signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVersion if those are lower
  246. bool SetMinVersion(enum WalletFeature, CWalletDB* pwalletdbIn = NULL, bool fExplicit = false);
  247. // change which version we're allowed to upgrade to (note that this does not immediately imply upgrading to that format)
  248. bool SetMaxVersion(int nVersion);
  249. // get the current wallet format (the oldest client version guaranteed to understand this wallet)
  250. int GetVersion() { return nWalletVersion; }
  251. void FixSpentCoins(int& nMismatchSpent, int64& nBalanceInQuestion, bool fCheckOnly = false);
  252. void DisableTransaction(const CTransaction &tx);
  253. boost::signals2::signal<void (CWallet *wallet, const CTxDestination &address, const std::string &label, bool isMine, ChangeType status)> NotifyAddressBookChanged;
  254. boost::signals2::signal<void (CWallet *wallet, const uint256 &hashTx, ChangeType status)> NotifyTransactionChanged;
  255. };
  256. /** A key allocated from the key pool. */
  257. class CReserveKey
  258. {
  259. protected:
  260. CWallet* pwallet;
  261. int64 nIndex;
  262. CPubKey vchPubKey;
  263. public:
  264. CReserveKey(CWallet* pwalletIn)
  265. {
  266. nIndex = -1;
  267. pwallet = pwalletIn;
  268. }
  269. ~CReserveKey()
  270. {
  271. if (!fShutdown)
  272. ReturnKey();
  273. }
  274. void ReturnKey();
  275. CPubKey GetReservedKey();
  276. void KeepKey();
  277. };
  278. typedef std::map<std::string, std::string> mapValue_t;
  279. static void ReadOrderPos(int64& nOrderPos, mapValue_t& mapValue)
  280. {
  281. if (!mapValue.count("n"))
  282. {
  283. nOrderPos = -1; // TODO: calculate elsewhere
  284. return;
  285. }
  286. nOrderPos = atoi64(mapValue["n"].c_str());
  287. }
  288. static void WriteOrderPos(const int64& nOrderPos, mapValue_t& mapValue)
  289. {
  290. if (nOrderPos == -1)
  291. return;
  292. mapValue["n"] = i64tostr(nOrderPos);
  293. }
  294. class CWalletTx : public CMerkleTx
  295. {
  296. private:
  297. const CWallet* pwallet;
  298. public:
  299. std::vector<CMerkleTx> vtxPrev;
  300. mapValue_t mapValue;
  301. std::vector<std::pair<std::string, std::string> > vOrderForm;
  302. unsigned int fTimeReceivedIsTxTime;
  303. unsigned int nTimeReceived; // time received by this node
  304. unsigned int nTimeSmart;
  305. char fFromMe;
  306. std::string strFromAccount;
  307. std::vector<char> vfSpent; // which outputs are already spent
  308. int64 nOrderPos; // position in ordered transaction list
  309. // memory only
  310. mutable bool fDebitCached;
  311. mutable bool fCreditCached;
  312. mutable bool fAvailableCreditCached;
  313. mutable bool fChangeCached;
  314. mutable int64 nDebitCached;
  315. mutable int64 nCreditCached;
  316. mutable int64 nAvailableCreditCached;
  317. mutable int64 nChangeCached;
  318. CWalletTx()
  319. {
  320. Init(NULL);
  321. }
  322. CWalletTx(const CWallet* pwalletIn)
  323. {
  324. Init(pwalletIn);
  325. }
  326. CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
  327. {
  328. Init(pwalletIn);
  329. }
  330. CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
  331. {
  332. Init(pwalletIn);
  333. }
  334. void Init(const CWallet* pwalletIn)
  335. {
  336. pwallet = pwalletIn;
  337. vtxPrev.clear();
  338. mapValue.clear();
  339. vOrderForm.clear();
  340. fTimeReceivedIsTxTime = false;
  341. nTimeReceived = 0;
  342. nTimeSmart = 0;
  343. fFromMe = false;
  344. strFromAccount.clear();
  345. vfSpent.clear();
  346. fDebitCached = false;
  347. fCreditCached = false;
  348. fAvailableCreditCached = false;
  349. fChangeCached = false;
  350. nDebitCached = 0;
  351. nCreditCached = 0;
  352. nAvailableCreditCached = 0;
  353. nChangeCached = 0;
  354. nOrderPos = -1;
  355. }
  356. IMPLEMENT_SERIALIZE
  357. (
  358. CWalletTx* pthis = const_cast<CWalletTx*>(this);
  359. if (fRead)
  360. pthis->Init(NULL);
  361. char fSpent = false;
  362. if (!fRead)
  363. {
  364. pthis->mapValue["fromaccount"] = pthis->strFromAccount;
  365. std::string str;
  366. BOOST_FOREACH(char f, vfSpent)
  367. {
  368. str += (f ? '1' : '0');
  369. if (f)
  370. fSpent = true;
  371. }
  372. pthis->mapValue["spent"] = str;
  373. WriteOrderPos(pthis->nOrderPos, pthis->mapValue);
  374. if (nTimeSmart)
  375. pthis->mapValue["timesmart"] = strprintf("%u", nTimeSmart);
  376. }
  377. nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
  378. READWRITE(vtxPrev);
  379. READWRITE(mapValue);
  380. READWRITE(vOrderForm);
  381. READWRITE(fTimeReceivedIsTxTime);
  382. READWRITE(nTimeReceived);
  383. READWRITE(fFromMe);
  384. READWRITE(fSpent);
  385. if (fRead)
  386. {
  387. pthis->strFromAccount = pthis->mapValue["fromaccount"];
  388. if (mapValue.count("spent"))
  389. BOOST_FOREACH(char c, pthis->mapValue["spent"])
  390. pthis->vfSpent.push_back(c != '0');
  391. else
  392. pthis->vfSpent.assign(vout.size(), fSpent);
  393. ReadOrderPos(pthis->nOrderPos, pthis->mapValue);
  394. pthis->nTimeSmart = mapValue.count("timesmart") ? (unsigned int)atoi64(pthis->mapValue["timesmart"]) : 0;
  395. }
  396. pthis->mapValue.erase("fromaccount");
  397. pthis->mapValue.erase("version");
  398. pthis->mapValue.erase("spent");
  399. pthis->mapValue.erase("n");
  400. pthis->mapValue.erase("timesmart");
  401. )
  402. // marks certain txout's as spent
  403. // returns true if any update took place
  404. bool UpdateSpent(const std::vector<char>& vfNewSpent)
  405. {
  406. bool fReturn = false;
  407. for (unsigned int i = 0; i < vfNewSpent.size(); i++)
  408. {
  409. if (i == vfSpent.size())
  410. break;
  411. if (vfNewSpent[i] && !vfSpent[i])
  412. {
  413. vfSpent[i] = true;
  414. fReturn = true;
  415. fAvailableCreditCached = false;
  416. }
  417. }
  418. return fReturn;
  419. }
  420. // make sure balances are recalculated
  421. void MarkDirty()
  422. {
  423. fCreditCached = false;
  424. fAvailableCreditCached = false;
  425. fDebitCached = false;
  426. fChangeCached = false;
  427. }
  428. void BindWallet(CWallet *pwalletIn)
  429. {
  430. pwallet = pwalletIn;
  431. MarkDirty();
  432. }
  433. void MarkSpent(unsigned int nOut)
  434. {
  435. if (nOut >= vout.size())
  436. throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range");
  437. vfSpent.resize(vout.size());
  438. if (!vfSpent[nOut])
  439. {
  440. vfSpent[nOut] = true;
  441. fAvailableCreditCached = false;
  442. }
  443. }
  444. void MarkUnspent(unsigned int nOut)
  445. {
  446. if (nOut >= vout.size())
  447. throw std::runtime_error("CWalletTx::MarkUnspent() : nOut out of range");
  448. vfSpent.resize(vout.size());
  449. if (vfSpent[nOut])
  450. {
  451. vfSpent[nOut] = false;
  452. fAvailableCreditCached = false;
  453. }
  454. }
  455. bool IsSpent(unsigned int nOut) const
  456. {
  457. if (nOut >= vout.size())
  458. throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
  459. if (nOut >= vfSpent.size())
  460. return false;
  461. return (!!vfSpent[nOut]);
  462. }
  463. int64 GetDebit() const
  464. {
  465. if (vin.empty())
  466. return 0;
  467. if (fDebitCached)
  468. return nDebitCached;
  469. nDebitCached = pwallet->GetDebit(*this);
  470. fDebitCached = true;
  471. return nDebitCached;
  472. }
  473. int64 GetCredit(bool fUseCache=true) const
  474. {
  475. // Must wait until coinbase is safely deep enough in the chain before valuing it
  476. if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0)
  477. return 0;
  478. // GetBalance can assume transactions in mapWallet won't change
  479. if (fUseCache && fCreditCached)
  480. return nCreditCached;
  481. nCreditCached = pwallet->GetCredit(*this);
  482. fCreditCached = true;
  483. return nCreditCached;
  484. }
  485. int64 GetAvailableCredit(bool fUseCache=true) const
  486. {
  487. // Must wait until coinbase is safely deep enough in the chain before valuing it
  488. if ((IsCoinBase() || IsCoinStake()) && GetBlocksToMaturity() > 0)
  489. return 0;
  490. if (fUseCache && fAvailableCreditCached)
  491. return nAvailableCreditCached;
  492. int64 nCredit = 0;
  493. for (unsigned int i = 0; i < vout.size(); i++)
  494. {
  495. if (!IsSpent(i))
  496. {
  497. const CTxOut &txout = vout[i];
  498. nCredit += pwallet->GetCredit(txout);
  499. if (!MoneyRange(nCredit))
  500. throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
  501. }
  502. }
  503. nAvailableCreditCached = nCredit;
  504. fAvailableCreditCached = true;
  505. return nCredit;
  506. }
  507. int64 GetChange() const
  508. {
  509. if (fChangeCached)
  510. return nChangeCached;
  511. nChangeCached = pwallet->GetChange(*this);
  512. fChangeCached = true;
  513. return nChangeCached;
  514. }
  515. void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<CTxDestination, int64> >& listReceived,
  516. std::list<std::pair<CTxDestination, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
  517. void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived,
  518. int64& nSent, int64& nFee) const;
  519. bool IsFromMe() const
  520. {
  521. return (GetDebit() > 0);
  522. }
  523. bool IsTrusted() const
  524. {
  525. // Quick answer in most cases
  526. if (!IsFinal())
  527. return false;
  528. if (GetDepthInMainChain() >= 1)
  529. return true;
  530. if (fConfChange || !IsFromMe()) // using wtx's cached debit
  531. return false;
  532. // If no confirmations but it's from us, we can still
  533. // consider it confirmed if all dependencies are confirmed
  534. std::map<uint256, const CMerkleTx*> mapPrev;
  535. std::vector<const CMerkleTx*> vWorkQueue;
  536. vWorkQueue.reserve(vtxPrev.size()+1);
  537. vWorkQueue.push_back(this);
  538. for (unsigned int i = 0; i < vWorkQueue.size(); i++)
  539. {
  540. const CMerkleTx* ptx = vWorkQueue[i];
  541. if (!ptx->IsFinal())
  542. return false;
  543. if (ptx->GetDepthInMainChain() >= 1)
  544. continue;
  545. if (!pwallet->IsFromMe(*ptx))
  546. return false;
  547. if (mapPrev.empty())
  548. {
  549. BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
  550. mapPrev[tx.GetHash()] = &tx;
  551. }
  552. BOOST_FOREACH(const CTxIn& txin, ptx->vin)
  553. {
  554. if (!mapPrev.count(txin.prevout.hash))
  555. return false;
  556. vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
  557. }
  558. }
  559. return true;
  560. }
  561. bool WriteToDisk();
  562. int64 GetTxTime() const;
  563. int GetRequestCount() const;
  564. void AddSupportingTransactions(CTxDB& txdb);
  565. bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
  566. bool AcceptWalletTransaction();
  567. void RelayWalletTransaction(CTxDB& txdb);
  568. void RelayWalletTransaction();
  569. };
  570. class COutput
  571. {
  572. public:
  573. const CWalletTx *tx;
  574. int i;
  575. int nDepth;
  576. COutput(const CWalletTx *txIn, int iIn, int nDepthIn)
  577. {
  578. tx = txIn; i = iIn; nDepth = nDepthIn;
  579. }
  580. std::string ToString() const
  581. {
  582. return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString().substr(0,10).c_str(), i, nDepth, FormatMoney(tx->vout[i].nValue).c_str());
  583. }
  584. void print() const
  585. {
  586. printf("%s\n", ToString().c_str());
  587. }
  588. };
  589. /** Private key that includes an expiration date in case it never gets used. */
  590. class CWalletKey
  591. {
  592. public:
  593. CPrivKey vchPrivKey;
  594. int64 nTimeCreated;
  595. int64 nTimeExpires;
  596. std::string strComment;
  597. CWalletKey(int64 nExpires=0)
  598. {
  599. nTimeCreated = (nExpires ? GetTime() : 0);
  600. nTimeExpires = nExpires;
  601. }
  602. IMPLEMENT_SERIALIZE
  603. (
  604. if (!(nType & SER_GETHASH))
  605. READWRITE(nVersion);
  606. READWRITE(vchPrivKey);
  607. READWRITE(nTimeCreated);
  608. READWRITE(nTimeExpires);
  609. READWRITE(strComment);
  610. )
  611. };
  612. /** Account information.
  613. * Stored in wallet with key "acc"+string account name.
  614. */
  615. class CAccount
  616. {
  617. public:
  618. CPubKey vchPubKey;
  619. CAccount()
  620. {
  621. SetNull();
  622. }
  623. void SetNull()
  624. {
  625. vchPubKey = CPubKey();
  626. }
  627. IMPLEMENT_SERIALIZE
  628. (
  629. if (!(nType & SER_GETHASH))
  630. READWRITE(nVersion);
  631. READWRITE(vchPubKey);
  632. )
  633. };
  634. /** Internal transfers.
  635. * Database key is acentry<account><counter>.
  636. */
  637. class CAccountingEntry
  638. {
  639. public:
  640. std::string strAccount;
  641. int64 nCreditDebit;
  642. int64 nTime;
  643. std::string strOtherAccount;
  644. std::string strComment;
  645. mapValue_t mapValue;
  646. int64 nOrderPos; // position in ordered transaction list
  647. uint64 nEntryNo;
  648. CAccountingEntry()
  649. {
  650. SetNull();
  651. }
  652. void SetNull()
  653. {
  654. nCreditDebit = 0;
  655. nTime = 0;
  656. strAccount.clear();
  657. strOtherAccount.clear();
  658. strComment.clear();
  659. nOrderPos = -1;
  660. }
  661. IMPLEMENT_SERIALIZE
  662. (
  663. CAccountingEntry& me = *const_cast<CAccountingEntry*>(this);
  664. if (!(nType & SER_GETHASH))
  665. READWRITE(nVersion);
  666. // Note: strAccount is serialized as part of the key, not here.
  667. READWRITE(nCreditDebit);
  668. READWRITE(nTime);
  669. READWRITE(strOtherAccount);
  670. if (!fRead)
  671. {
  672. WriteOrderPos(nOrderPos, me.mapValue);
  673. if (!(mapValue.empty() && _ssExtra.empty()))
  674. {
  675. CDataStream ss(nType, nVersion);
  676. ss.insert(ss.begin(), '\0');
  677. ss << mapValue;
  678. ss.insert(ss.end(), _ssExtra.begin(), _ssExtra.end());
  679. me.strComment.append(ss.str());
  680. }
  681. }
  682. READWRITE(strComment);
  683. size_t nSepPos = strComment.find("\0", 0, 1);
  684. if (fRead)
  685. {
  686. me.mapValue.clear();
  687. if (std::string::npos != nSepPos)
  688. {
  689. CDataStream ss(std::vector<char>(strComment.begin() + nSepPos + 1, strComment.end()), nType, nVersion);
  690. ss >> me.mapValue;
  691. me._ssExtra = std::vector<char>(ss.begin(), ss.end());
  692. }
  693. ReadOrderPos(me.nOrderPos, me.mapValue);
  694. }
  695. if (std::string::npos != nSepPos)
  696. me.strComment.erase(nSepPos);
  697. me.mapValue.erase("n");
  698. )
  699. private:
  700. std::vector<char> _ssExtra;
  701. };
  702. bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
  703. #endif