You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

wallet.h 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  1. // Copyright (c) 2009-2011 Satoshi Nakamoto & Bitcoin developers
  2. // Distributed under the MIT/X11 software license, see the accompanying
  3. // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  4. #ifndef BITCOIN_WALLET_H
  5. #define BITCOIN_WALLET_H
  6. #include "bignum.h"
  7. #include "key.h"
  8. #include "script.h"
  9. class CWalletTx;
  10. class CReserveKey;
  11. class CWalletDB;
  12. class CWallet : public CKeyStore
  13. {
  14. private:
  15. bool SelectCoinsMinConf(int64 nTargetValue, int nConfMine, int nConfTheirs, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
  16. bool SelectCoins(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
  17. public:
  18. bool fFileBacked;
  19. std::string strWalletFile;
  20. std::set<int64> setKeyPool;
  21. CCriticalSection cs_setKeyPool;
  22. CWallet()
  23. {
  24. fFileBacked = false;
  25. }
  26. CWallet(std::string strWalletFileIn)
  27. {
  28. strWalletFile = strWalletFileIn;
  29. fFileBacked = true;
  30. }
  31. mutable CCriticalSection cs_mapWallet;
  32. std::map<uint256, CWalletTx> mapWallet;
  33. std::vector<uint256> vWalletUpdated;
  34. std::map<uint256, int> mapRequestCount;
  35. mutable CCriticalSection cs_mapRequestCount;
  36. std::map<std::string, std::string> mapAddressBook;
  37. mutable CCriticalSection cs_mapAddressBook;
  38. std::vector<unsigned char> vchDefaultKey;
  39. bool AddKey(const CKey& key);
  40. bool AddToWallet(const CWalletTx& wtxIn);
  41. bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate = false);
  42. bool EraseFromWallet(uint256 hash);
  43. void WalletUpdateSpent(const CTransaction& prevout);
  44. int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
  45. void ReacceptWalletTransactions();
  46. void ResendWalletTransactions();
  47. int64 GetBalance() const;
  48. int64 GetUnconfirmedBalance() const;
  49. bool CreateTransaction(const std::vector<std::pair<CScript, int64> >& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
  50. bool CreateTransaction(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, CReserveKey& reservekey, int64& nFeeRet);
  51. bool CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey);
  52. bool BroadcastTransaction(CWalletTx& wtxNew);
  53. std::string SendMoney(CScript scriptPubKey, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
  54. std::string SendMoneyToBitcoinAddress(std::string strAddress, int64 nValue, CWalletTx& wtxNew, bool fAskFee=false);
  55. void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
  56. void KeepKey(int64 nIndex);
  57. void ReturnKey(int64 nIndex);
  58. std::vector<unsigned char> GetKeyFromKeyPool();
  59. int64 GetOldestKeyPoolTime();
  60. bool IsMine(const CTxIn& txin) const;
  61. int64 GetDebit(const CTxIn& txin) const;
  62. bool IsMine(const CTxOut& txout) const
  63. {
  64. return ::IsMine(*this, txout.scriptPubKey);
  65. }
  66. int64 GetCredit(const CTxOut& txout) const
  67. {
  68. if (!MoneyRange(txout.nValue))
  69. throw std::runtime_error("CWallet::GetCredit() : value out of range");
  70. return (IsMine(txout) ? txout.nValue : 0);
  71. }
  72. bool IsChange(const CTxOut& txout) const
  73. {
  74. std::vector<unsigned char> vchPubKey;
  75. if (ExtractPubKey(txout.scriptPubKey, this, vchPubKey))
  76. CRITICAL_BLOCK(cs_mapAddressBook)
  77. if (!mapAddressBook.count(PubKeyToAddress(vchPubKey)))
  78. return true;
  79. return false;
  80. }
  81. int64 GetChange(const CTxOut& txout) const
  82. {
  83. if (!MoneyRange(txout.nValue))
  84. throw std::runtime_error("CWallet::GetChange() : value out of range");
  85. return (IsChange(txout) ? txout.nValue : 0);
  86. }
  87. bool IsMine(const CTransaction& tx) const
  88. {
  89. BOOST_FOREACH(const CTxOut& txout, tx.vout)
  90. if (IsMine(txout))
  91. return true;
  92. return false;
  93. }
  94. bool IsFromMe(const CTransaction& tx) const
  95. {
  96. return (GetDebit(tx) > 0);
  97. }
  98. int64 GetDebit(const CTransaction& tx) const
  99. {
  100. int64 nDebit = 0;
  101. BOOST_FOREACH(const CTxIn& txin, tx.vin)
  102. {
  103. nDebit += GetDebit(txin);
  104. if (!MoneyRange(nDebit))
  105. throw std::runtime_error("CWallet::GetDebit() : value out of range");
  106. }
  107. return nDebit;
  108. }
  109. int64 GetCredit(const CTransaction& tx) const
  110. {
  111. int64 nCredit = 0;
  112. BOOST_FOREACH(const CTxOut& txout, tx.vout)
  113. {
  114. nCredit += GetCredit(txout);
  115. if (!MoneyRange(nCredit))
  116. throw std::runtime_error("CWallet::GetCredit() : value out of range");
  117. }
  118. return nCredit;
  119. }
  120. int64 GetChange(const CTransaction& tx) const
  121. {
  122. int64 nChange = 0;
  123. BOOST_FOREACH(const CTxOut& txout, tx.vout)
  124. {
  125. nChange += GetChange(txout);
  126. if (!MoneyRange(nChange))
  127. throw std::runtime_error("CWallet::GetChange() : value out of range");
  128. }
  129. return nChange;
  130. }
  131. void SetBestChain(const CBlockLocator& loc)
  132. {
  133. CWalletDB walletdb(strWalletFile);
  134. walletdb.WriteBestBlock(loc);
  135. }
  136. bool LoadWallet(bool& fFirstRunRet);
  137. // bool BackupWallet(const std::string& strDest);
  138. // requires cs_mapAddressBook lock
  139. bool SetAddressBookName(const std::string& strAddress, const std::string& strName);
  140. // requires cs_mapAddressBook lock
  141. bool DelAddressBookName(const std::string& strAddress);
  142. void UpdatedTransaction(const uint256 &hashTx)
  143. {
  144. CRITICAL_BLOCK(cs_mapWallet)
  145. vWalletUpdated.push_back(hashTx);
  146. }
  147. void PrintWallet(const CBlock& block);
  148. void Inventory(const uint256 &hash)
  149. {
  150. CRITICAL_BLOCK(cs_mapRequestCount)
  151. {
  152. std::map<uint256, int>::iterator mi = mapRequestCount.find(hash);
  153. if (mi != mapRequestCount.end())
  154. (*mi).second++;
  155. }
  156. }
  157. bool GetTransaction(const uint256 &hashTx, CWalletTx& wtx);
  158. bool SetDefaultKey(const std::vector<unsigned char> &vchPubKey);
  159. };
  160. class CReserveKey
  161. {
  162. protected:
  163. CWallet* pwallet;
  164. int64 nIndex;
  165. std::vector<unsigned char> vchPubKey;
  166. public:
  167. CReserveKey(CWallet* pwalletIn)
  168. {
  169. nIndex = -1;
  170. pwallet = pwalletIn;
  171. }
  172. ~CReserveKey()
  173. {
  174. if (!fShutdown)
  175. ReturnKey();
  176. }
  177. void ReturnKey();
  178. std::vector<unsigned char> GetReservedKey();
  179. void KeepKey();
  180. };
  181. //
  182. // A transaction with a bunch of additional info that only the owner cares
  183. // about. It includes any unrecorded transactions needed to link it back
  184. // to the block chain.
  185. //
  186. class CWalletTx : public CMerkleTx
  187. {
  188. public:
  189. const CWallet* pwallet;
  190. std::vector<CMerkleTx> vtxPrev;
  191. std::map<std::string, std::string> mapValue;
  192. std::vector<std::pair<std::string, std::string> > vOrderForm;
  193. unsigned int fTimeReceivedIsTxTime;
  194. unsigned int nTimeReceived; // time received by this node
  195. char fFromMe;
  196. std::string strFromAccount;
  197. std::vector<char> vfSpent;
  198. // memory only
  199. mutable char fDebitCached;
  200. mutable char fCreditCached;
  201. mutable char fAvailableCreditCached;
  202. mutable char fChangeCached;
  203. mutable int64 nDebitCached;
  204. mutable int64 nCreditCached;
  205. mutable int64 nAvailableCreditCached;
  206. mutable int64 nChangeCached;
  207. // memory only UI hints
  208. mutable unsigned int nTimeDisplayed;
  209. mutable int nLinesDisplayed;
  210. mutable char fConfirmedDisplayed;
  211. CWalletTx()
  212. {
  213. Init(NULL);
  214. }
  215. CWalletTx(const CWallet* pwalletIn)
  216. {
  217. Init(pwalletIn);
  218. }
  219. CWalletTx(const CWallet* pwalletIn, const CMerkleTx& txIn) : CMerkleTx(txIn)
  220. {
  221. Init(pwalletIn);
  222. }
  223. CWalletTx(const CWallet* pwalletIn, const CTransaction& txIn) : CMerkleTx(txIn)
  224. {
  225. Init(pwalletIn);
  226. }
  227. void Init(const CWallet* pwalletIn)
  228. {
  229. pwallet = pwalletIn;
  230. vtxPrev.clear();
  231. mapValue.clear();
  232. vOrderForm.clear();
  233. fTimeReceivedIsTxTime = false;
  234. nTimeReceived = 0;
  235. fFromMe = false;
  236. strFromAccount.clear();
  237. vfSpent.clear();
  238. fDebitCached = false;
  239. fCreditCached = false;
  240. fAvailableCreditCached = false;
  241. fChangeCached = false;
  242. nDebitCached = 0;
  243. nCreditCached = 0;
  244. nAvailableCreditCached = 0;
  245. nChangeCached = 0;
  246. nTimeDisplayed = 0;
  247. nLinesDisplayed = 0;
  248. fConfirmedDisplayed = false;
  249. }
  250. IMPLEMENT_SERIALIZE
  251. (
  252. CWalletTx* pthis = const_cast<CWalletTx*>(this);
  253. if (fRead)
  254. pthis->Init(NULL);
  255. char fSpent = false;
  256. if (!fRead)
  257. {
  258. pthis->mapValue["fromaccount"] = pthis->strFromAccount;
  259. std::string str;
  260. BOOST_FOREACH(char f, vfSpent)
  261. {
  262. str += (f ? '1' : '0');
  263. if (f)
  264. fSpent = true;
  265. }
  266. pthis->mapValue["spent"] = str;
  267. }
  268. nSerSize += SerReadWrite(s, *(CMerkleTx*)this, nType, nVersion,ser_action);
  269. READWRITE(vtxPrev);
  270. READWRITE(mapValue);
  271. READWRITE(vOrderForm);
  272. READWRITE(fTimeReceivedIsTxTime);
  273. READWRITE(nTimeReceived);
  274. READWRITE(fFromMe);
  275. READWRITE(fSpent);
  276. if (fRead)
  277. {
  278. pthis->strFromAccount = pthis->mapValue["fromaccount"];
  279. if (mapValue.count("spent"))
  280. BOOST_FOREACH(char c, pthis->mapValue["spent"])
  281. pthis->vfSpent.push_back(c != '0');
  282. else
  283. pthis->vfSpent.assign(vout.size(), fSpent);
  284. }
  285. pthis->mapValue.erase("fromaccount");
  286. pthis->mapValue.erase("version");
  287. pthis->mapValue.erase("spent");
  288. )
  289. // marks certain txout's as spent
  290. // returns true if any update took place
  291. bool UpdateSpent(const std::vector<char>& vfNewSpent)
  292. {
  293. bool fReturn = false;
  294. for (int i=0; i < vfNewSpent.size(); i++)
  295. {
  296. if (i == vfSpent.size())
  297. break;
  298. if (vfNewSpent[i] && !vfSpent[i])
  299. {
  300. vfSpent[i] = true;
  301. fReturn = true;
  302. fAvailableCreditCached = false;
  303. }
  304. }
  305. return fReturn;
  306. }
  307. void MarkDirty()
  308. {
  309. fCreditCached = false;
  310. fAvailableCreditCached = false;
  311. fDebitCached = false;
  312. fChangeCached = false;
  313. }
  314. void MarkSpent(unsigned int nOut)
  315. {
  316. if (nOut >= vout.size())
  317. throw std::runtime_error("CWalletTx::MarkSpent() : nOut out of range");
  318. vfSpent.resize(vout.size());
  319. if (!vfSpent[nOut])
  320. {
  321. vfSpent[nOut] = true;
  322. fAvailableCreditCached = false;
  323. }
  324. }
  325. bool IsSpent(unsigned int nOut) const
  326. {
  327. if (nOut >= vout.size())
  328. throw std::runtime_error("CWalletTx::IsSpent() : nOut out of range");
  329. if (nOut >= vfSpent.size())
  330. return false;
  331. return (!!vfSpent[nOut]);
  332. }
  333. int64 GetDebit() const
  334. {
  335. if (vin.empty())
  336. return 0;
  337. if (fDebitCached)
  338. return nDebitCached;
  339. nDebitCached = pwallet->GetDebit(*this);
  340. fDebitCached = true;
  341. return nDebitCached;
  342. }
  343. int64 GetCredit(bool fUseCache=true) const
  344. {
  345. // Must wait until coinbase is safely deep enough in the chain before valuing it
  346. if (IsCoinBase() && GetBlocksToMaturity() > 0)
  347. return 0;
  348. // GetBalance can assume transactions in mapWallet won't change
  349. if (fUseCache && fCreditCached)
  350. return nCreditCached;
  351. nCreditCached = pwallet->GetCredit(*this);
  352. fCreditCached = true;
  353. return nCreditCached;
  354. }
  355. int64 GetAvailableCredit(bool fUseCache=true) const
  356. {
  357. // Must wait until coinbase is safely deep enough in the chain before valuing it
  358. if (IsCoinBase() && GetBlocksToMaturity() > 0)
  359. return 0;
  360. if (fUseCache && fAvailableCreditCached)
  361. return nAvailableCreditCached;
  362. int64 nCredit = 0;
  363. for (int i = 0; i < vout.size(); i++)
  364. {
  365. if (!IsSpent(i))
  366. {
  367. const CTxOut &txout = vout[i];
  368. nCredit += pwallet->GetCredit(txout);
  369. if (!MoneyRange(nCredit))
  370. throw std::runtime_error("CWalletTx::GetAvailableCredit() : value out of range");
  371. }
  372. }
  373. nAvailableCreditCached = nCredit;
  374. fAvailableCreditCached = true;
  375. return nCredit;
  376. }
  377. int64 GetChange() const
  378. {
  379. if (fChangeCached)
  380. return nChangeCached;
  381. nChangeCached = pwallet->GetChange(*this);
  382. fChangeCached = true;
  383. return nChangeCached;
  384. }
  385. void GetAmounts(int64& nGeneratedImmature, int64& nGeneratedMature, std::list<std::pair<std::string /* address */, int64> >& listReceived,
  386. std::list<std::pair<std::string /* address */, int64> >& listSent, int64& nFee, std::string& strSentAccount) const;
  387. void GetAccountAmounts(const std::string& strAccount, int64& nGenerated, int64& nReceived,
  388. int64& nSent, int64& nFee) const;
  389. bool IsFromMe() const
  390. {
  391. return (GetDebit() > 0);
  392. }
  393. bool IsConfirmed() const
  394. {
  395. // Quick answer in most cases
  396. if (!IsFinal())
  397. return false;
  398. if (GetDepthInMainChain() >= 1)
  399. return true;
  400. if (!IsFromMe()) // using wtx's cached debit
  401. return false;
  402. // If no confirmations but it's from us, we can still
  403. // consider it confirmed if all dependencies are confirmed
  404. std::map<uint256, const CMerkleTx*> mapPrev;
  405. std::vector<const CMerkleTx*> vWorkQueue;
  406. vWorkQueue.reserve(vtxPrev.size()+1);
  407. vWorkQueue.push_back(this);
  408. for (int i = 0; i < vWorkQueue.size(); i++)
  409. {
  410. const CMerkleTx* ptx = vWorkQueue[i];
  411. if (!ptx->IsFinal())
  412. return false;
  413. if (ptx->GetDepthInMainChain() >= 1)
  414. continue;
  415. if (!pwallet->IsFromMe(*ptx))
  416. return false;
  417. if (mapPrev.empty())
  418. BOOST_FOREACH(const CMerkleTx& tx, vtxPrev)
  419. mapPrev[tx.GetHash()] = &tx;
  420. BOOST_FOREACH(const CTxIn& txin, ptx->vin)
  421. {
  422. if (!mapPrev.count(txin.prevout.hash))
  423. return false;
  424. vWorkQueue.push_back(mapPrev[txin.prevout.hash]);
  425. }
  426. }
  427. return true;
  428. }
  429. bool WriteToDisk();
  430. int64 GetTxTime() const;
  431. int GetRequestCount() const;
  432. void AddSupportingTransactions(CTxDB& txdb);
  433. bool AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs=true);
  434. bool AcceptWalletTransaction();
  435. void RelayWalletTransaction(CTxDB& txdb);
  436. void RelayWalletTransaction();
  437. };
  438. //
  439. // Private key that includes an expiration date in case it never gets used.
  440. //
  441. class CWalletKey
  442. {
  443. public:
  444. CPrivKey vchPrivKey;
  445. int64 nTimeCreated;
  446. int64 nTimeExpires;
  447. std::string strComment;
  448. //// todo: add something to note what created it (user, getnewaddress, change)
  449. //// maybe should have a map<string, string> property map
  450. CWalletKey(int64 nExpires=0)
  451. {
  452. nTimeCreated = (nExpires ? GetTime() : 0);
  453. nTimeExpires = nExpires;
  454. }
  455. IMPLEMENT_SERIALIZE
  456. (
  457. if (!(nType & SER_GETHASH))
  458. READWRITE(nVersion);
  459. READWRITE(vchPrivKey);
  460. READWRITE(nTimeCreated);
  461. READWRITE(nTimeExpires);
  462. READWRITE(strComment);
  463. )
  464. };
  465. //
  466. // Account information.
  467. // Stored in wallet with key "acc"+string account name
  468. //
  469. class CAccount
  470. {
  471. public:
  472. std::vector<unsigned char> vchPubKey;
  473. CAccount()
  474. {
  475. SetNull();
  476. }
  477. void SetNull()
  478. {
  479. vchPubKey.clear();
  480. }
  481. IMPLEMENT_SERIALIZE
  482. (
  483. if (!(nType & SER_GETHASH))
  484. READWRITE(nVersion);
  485. READWRITE(vchPubKey);
  486. )
  487. };
  488. //
  489. // Internal transfers.
  490. // Database key is acentry<account><counter>
  491. //
  492. class CAccountingEntry
  493. {
  494. public:
  495. std::string strAccount;
  496. int64 nCreditDebit;
  497. int64 nTime;
  498. std::string strOtherAccount;
  499. std::string strComment;
  500. CAccountingEntry()
  501. {
  502. SetNull();
  503. }
  504. void SetNull()
  505. {
  506. nCreditDebit = 0;
  507. nTime = 0;
  508. strAccount.clear();
  509. strOtherAccount.clear();
  510. strComment.clear();
  511. }
  512. IMPLEMENT_SERIALIZE
  513. (
  514. if (!(nType & SER_GETHASH))
  515. READWRITE(nVersion);
  516. // Note: strAccount is serialized as part of the key, not here.
  517. READWRITE(nCreditDebit);
  518. READWRITE(nTime);
  519. READWRITE(strOtherAccount);
  520. READWRITE(strComment);
  521. )
  522. };
  523. bool GetWalletFile(CWallet* pwallet, std::string &strWalletFileOut);
  524. #endif