Raven Core  3.0.0
P2P Digital Currency
wallet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Copyright (c) 2017-2019 The Raven Core developers
4 // Distributed under the MIT software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "wallet/wallet.h"
8 
9 #include "base58.h"
10 #include "checkpoints.h"
11 #include "chain.h"
12 #include "wallet/coincontrol.h"
13 #include "consensus/consensus.h"
14 #include "consensus/validation.h"
15 #include "fs.h"
16 #include "init.h"
17 #include "key.h"
18 #include "keystore.h"
19 #include "validation.h"
20 #include "net.h"
21 #include "policy/fees.h"
22 #include "policy/policy.h"
23 #include "policy/rbf.h"
24 #include "primitives/block.h"
25 #include "primitives/transaction.h"
26 #include "script/script.h"
27 #include "script/sign.h"
28 #include "scheduler.h"
29 #include "timedata.h"
30 #include "txmempool.h"
31 #include "util.h"
32 #include "ui_interface.h"
33 #include "utilmoneystr.h"
34 #include "wallet/fees.h"
35 
36 #include <assert.h>
37 
38 #include <boost/algorithm/string/replace.hpp>
39 #include <boost/thread.hpp>
40 #include <tinyformat.h>
41 
42 #include "assets/assets.h"
43 
44 std::vector<CWalletRef> vpwallets;
46 CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE);
47 unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET;
48 bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE;
49 bool fWalletRbf = DEFAULT_WALLET_RBF;
50 
51 const char * DEFAULT_WALLET_DAT = "wallet.dat";
52 const uint32_t BIP32_HARDENED_KEY_LIMIT = 0x80000000;
53 
58 CFeeRate CWallet::minTxFee = CFeeRate(DEFAULT_TRANSACTION_MINFEE);
64 CFeeRate CWallet::fallbackFee = CFeeRate(DEFAULT_FALLBACK_FEE);
65 
66 CFeeRate CWallet::m_discard_rate = CFeeRate(DEFAULT_DISCARD_FEE);
67 
68 const uint256 CMerkleTx::ABANDON_HASH(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
69 
76 {
77  bool operator()(const CInputCoin& t1,
78  const CInputCoin& t2) const
79  {
80  return t1.txout.nValue < t2.txout.nValue;
81  }
82 };
83 
85 {
86  bool operator()(const std::pair<CInputCoin, CAmount>& t1,
87  const std::pair<CInputCoin, CAmount>& t2) const
88  {
89  return t1.second < t2.second;
90  }
91 };
92 
93 std::string COutput::ToString() const
94 {
95  return strprintf("COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth, FormatMoney(tx->tx->vout[i].nValue));
96 }
97 
98 class CAffectedKeysVisitor : public boost::static_visitor<void> {
99 private:
101  std::vector<CKeyID> &vKeys;
102 
103 public:
104  CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector<CKeyID> &vKeysIn) : keystore(keystoreIn), vKeys(vKeysIn) {}
105 
106  void Process(const CScript &script) {
107  txnouttype type;
108  std::vector<CTxDestination> vDest;
109  int nRequired;
110  if (ExtractDestinations(script, type, vDest, nRequired)) {
111  for (const CTxDestination &dest : vDest)
112  boost::apply_visitor(*this, dest);
113  }
114  }
115 
116  void operator()(const CKeyID &keyId) {
117  if (keystore.HaveKey(keyId))
118  vKeys.push_back(keyId);
119  }
120 
121  void operator()(const CScriptID &scriptId) {
122  CScript script;
123  if (keystore.GetCScript(scriptId, script))
124  Process(script);
125  }
126 
127  void operator()(const CNoDestination &none) {}
128 };
129 
130 const CWalletTx* CWallet::GetWalletTx(const uint256& hash) const
131 {
132  LOCK(cs_wallet);
133  std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
134  if (it == mapWallet.end())
135  return nullptr;
136  return &(it->second);
137 }
138 
139 CPubKey CWallet::GenerateNewKey(CWalletDB &walletdb, bool internal)
140 {
141  AssertLockHeld(cs_wallet); // mapKeyMetadata
142  bool fCompressed = CanSupportFeature(FEATURE_COMPRPUBKEY); // default to compressed public keys if we want 0.6.0 wallets
143 
144  CKey secret;
145 
146  // Create new metadata
147  int64_t nCreationTime = GetTime();
148  CKeyMetadata metadata(nCreationTime);
149 
150  // use HD key derivation if HD was enabled during wallet creation
151  if (IsHDEnabled()) {
152  DeriveNewChildKey(walletdb, metadata, secret, (CanSupportFeature(FEATURE_HD_SPLIT) ? internal : false));
153  } else {
154  secret.MakeNewKey(fCompressed);
155  }
156 
157  // Compressed public keys were introduced in version 0.6.0
158  if (fCompressed) {
159  SetMinVersion(FEATURE_COMPRPUBKEY);
160  }
161 
162  CPubKey pubkey = secret.GetPubKey();
163  assert(secret.VerifyPubKey(pubkey));
164 
165  mapKeyMetadata[pubkey.GetID()] = metadata;
166  UpdateTimeFirstKey(nCreationTime);
167 
168  if (!AddKeyPubKeyWithDB(walletdb, secret, pubkey)) {
169  throw std::runtime_error(std::string(__func__) + ": AddKey failed");
170  }
171  return pubkey;
172 }
173 
174 void CWallet::DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata& metadata, CKey& secret, bool internal)
175 {
176  // for now we use a fixed keypath scheme of m/0'/0'/k
177  CKey seed; //seed (256bit)
178  CExtKey masterKey; //hd master key
179  CExtKey accountKey; //key at m/0'
180  CExtKey chainChildKey; //key at m/0'/0' (external) or m/0'/1' (internal)
181  CExtKey childKey; //key at m/0'/0'/<n>'
182 
183  // try to get the seed
184  if (!GetKey(hdChain.seed_id, seed))
185  throw std::runtime_error(std::string(__func__) + ": seed not found");
186 
187  masterKey.SetSeed(seed.begin(), seed.size());
188 
189  // derive m/0'
190  // use hardened derivation (child keys >= 0x80000000 are hardened after bip32)
191  masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT);
192 
193  // derive m/0'/0' (external chain) OR m/0'/1' (internal chain)
194  assert(internal ? CanSupportFeature(FEATURE_HD_SPLIT) : true);
195  accountKey.Derive(chainChildKey, BIP32_HARDENED_KEY_LIMIT+(internal ? 1 : 0));
196 
197  // derive child key at next index, skip keys already known to the wallet
198  do {
199  // always derive hardened keys
200  // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range
201  // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649
202  if (internal) {
203  chainChildKey.Derive(childKey, hdChain.nInternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
204  metadata.hdKeypath = "m/0'/1'/" + std::to_string(hdChain.nInternalChainCounter) + "'";
205  hdChain.nInternalChainCounter++;
206  }
207  else {
208  chainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT);
209  metadata.hdKeypath = "m/0'/0'/" + std::to_string(hdChain.nExternalChainCounter) + "'";
210  hdChain.nExternalChainCounter++;
211  }
212  } while (HaveKey(childKey.key.GetPubKey().GetID()));
213  secret = childKey.key;
214  metadata.hd_seed_id = hdChain.seed_id;
215  // update the chain model in the database
216  if (!walletdb.WriteHDChain(hdChain))
217  throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
218 }
219 
220 bool CWallet::AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey& secret, const CPubKey &pubkey)
221 {
222  AssertLockHeld(cs_wallet); // mapKeyMetadata
223 
224  // CCryptoKeyStore has no concept of wallet databases, but calls AddCryptedKey
225  // which is overridden below. To avoid flushes, the database handle is
226  // tunneled through to it.
227  bool needsDB = !pwalletdbEncryption;
228  if (needsDB) {
229  pwalletdbEncryption = &walletdb;
230  }
231  if (!CCryptoKeyStore::AddKeyPubKey(secret, pubkey)) {
232  if (needsDB) pwalletdbEncryption = nullptr;
233  return false;
234  }
235  if (needsDB) pwalletdbEncryption = nullptr;
236 
237  // check if we need to remove from watch-only
238  CScript script;
239  script = GetScriptForDestination(pubkey.GetID());
240  if (HaveWatchOnly(script)) {
241  RemoveWatchOnly(script);
242  }
243  script = GetScriptForRawPubKey(pubkey);
244  if (HaveWatchOnly(script)) {
245  RemoveWatchOnly(script);
246  }
247 
248  if (!IsCrypted()) {
249  return walletdb.WriteKey(pubkey,
250  secret.GetPrivKey(),
251  mapKeyMetadata[pubkey.GetID()]);
252  }
253  return true;
254 }
255 
256 bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
257 {
258  CWalletDB walletdb(*dbw);
259  return CWallet::AddKeyPubKeyWithDB(walletdb, secret, pubkey);
260 }
261 
262 bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
263  const std::vector<unsigned char> &vchCryptedSecret)
264 {
265  if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
266  return false;
267  {
268  LOCK(cs_wallet);
269  if (pwalletdbEncryption)
270  return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
271  vchCryptedSecret,
272  mapKeyMetadata[vchPubKey.GetID()]);
273  else
274  return CWalletDB(*dbw).WriteCryptedKey(vchPubKey,
275  vchCryptedSecret,
276  mapKeyMetadata[vchPubKey.GetID()]);
277  }
278 }
279 
280 bool CWallet::LoadKeyMetadata(const CTxDestination& keyID, const CKeyMetadata &meta)
281 {
282  AssertLockHeld(cs_wallet); // mapKeyMetadata
283  UpdateTimeFirstKey(meta.nCreateTime);
284  mapKeyMetadata[keyID] = meta;
285  return true;
286 }
287 
288 bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
289 {
290  return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
291 }
292 
297 void CWallet::UpdateTimeFirstKey(int64_t nCreateTime)
298 {
299  AssertLockHeld(cs_wallet);
300  if (nCreateTime <= 1) {
301  // Cannot determine birthday information, so set the wallet birthday to
302  // the beginning of time.
303  nTimeFirstKey = 1;
304  } else if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) {
305  nTimeFirstKey = nCreateTime;
306  }
307 }
308 
309 bool CWallet::AddCScript(const CScript& redeemScript)
310 {
311  if (!CCryptoKeyStore::AddCScript(redeemScript))
312  return false;
313  return CWalletDB(*dbw).WriteCScript(Hash160(redeemScript), redeemScript);
314 }
315 
316 bool CWallet::LoadCScript(const CScript& redeemScript)
317 {
318  /* A sanity check was added in pull #3843 to avoid adding redeemScripts
319  * that never can be redeemed. However, old wallets may still contain
320  * these. Do not add them to the wallet and warn. */
321  if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
322  {
323  std::string strAddr = EncodeDestination(CScriptID(redeemScript));
324  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",
325  __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
326  return true;
327  }
328 
329  return CCryptoKeyStore::AddCScript(redeemScript);
330 }
331 
333 {
335  return false;
336  const CKeyMetadata& meta = mapKeyMetadata[CScriptID(dest)];
337  UpdateTimeFirstKey(meta.nCreateTime);
338  NotifyWatchonlyChanged(true);
339  return CWalletDB(*dbw).WriteWatchOnly(dest, meta);
340 }
341 
342 bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
343 {
344  mapKeyMetadata[CScriptID(dest)].nCreateTime = nCreateTime;
345  return AddWatchOnly(dest);
346 }
347 
349 {
350  AssertLockHeld(cs_wallet);
352  return false;
353  if (!HaveWatchOnly())
354  NotifyWatchonlyChanged(false);
355  if (!CWalletDB(*dbw).EraseWatchOnly(dest))
356  return false;
357 
358  return true;
359 }
360 
362 {
363  return CCryptoKeyStore::AddWatchOnly(dest);
364 }
365 
366 bool CWallet::Unlock(const SecureString& strWalletPassphrase)
367 {
368  CCrypter crypter;
369  CKeyingMaterial _vMasterKey;
370 
371  {
372  LOCK(cs_wallet);
373  for (const MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
374  {
375  if(!crypter.SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
376  return false;
377  if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
378  continue; // try another master key
379  if (CCryptoKeyStore::Unlock(_vMasterKey))
380  return true;
381  }
382  }
383  return false;
384 }
385 
386 bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase, const SecureString& strNewWalletPassphrase)
387 {
388  bool fWasLocked = IsLocked();
389 
390  {
391  LOCK(cs_wallet);
392  Lock();
393 
394  CCrypter crypter;
395  CKeyingMaterial _vMasterKey;
396  for (MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
397  {
398  if(!crypter.SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
399  return false;
400  if (!crypter.Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
401  return false;
402  if (CCryptoKeyStore::Unlock(_vMasterKey))
403  {
404  int64_t nStartTime = GetTimeMillis();
405  crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
406  pMasterKey.second.nDeriveIterations = static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * (100 / ((double)(GetTimeMillis() - nStartTime))));
407 
408  nStartTime = GetTimeMillis();
409  crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
410  pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + static_cast<unsigned int>(pMasterKey.second.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
411 
412  if (pMasterKey.second.nDeriveIterations < 25000)
413  pMasterKey.second.nDeriveIterations = 25000;
414 
415  LogPrintf("Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
416 
417  if (!crypter.SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
418  return false;
419  if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
420  return false;
421  CWalletDB(*dbw).WriteMasterKey(pMasterKey.first, pMasterKey.second);
422  if (fWasLocked)
423  Lock();
424  return true;
425  }
426  }
427  }
428 
429  return false;
430 }
431 
433 {
434  CWalletDB walletdb(*dbw);
435  walletdb.WriteBestBlock(loc);
436 }
437 
438 bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn, bool fExplicit)
439 {
440  LOCK(cs_wallet); // nWalletVersion
441  if (nWalletVersion >= nVersion)
442  return true;
443 
444  // when doing an explicit upgrade, if we pass the max version permitted, upgrade all the way
445  if (fExplicit && nVersion > nWalletMaxVersion)
446  nVersion = FEATURE_LATEST;
447 
448  nWalletVersion = nVersion;
449 
450  if (nVersion > nWalletMaxVersion)
451  nWalletMaxVersion = nVersion;
452 
453  {
454  CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(*dbw);
455  if (nWalletVersion > 40000)
456  pwalletdb->WriteMinVersion(nWalletVersion);
457  if (!pwalletdbIn)
458  delete pwalletdb;
459  }
460 
461  return true;
462 }
463 
464 bool CWallet::SetMaxVersion(int nVersion)
465 {
466  LOCK(cs_wallet); // nWalletVersion, nWalletMaxVersion
467  // cannot downgrade below current version
468  if (nWalletVersion > nVersion)
469  return false;
470 
471  nWalletMaxVersion = nVersion;
472 
473  return true;
474 }
475 
476 std::set<uint256> CWallet::GetConflicts(const uint256& txid) const
477 {
478  std::set<uint256> result;
479  AssertLockHeld(cs_wallet);
480 
481  std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
482  if (it == mapWallet.end())
483  return result;
484  const CWalletTx& wtx = it->second;
485 
486  std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
487 
488  for (const CTxIn& txin : wtx.tx->vin)
489  {
490  if (mapTxSpends.count(txin.prevout) <= 1)
491  continue; // No conflict if zero or one spends
492  range = mapTxSpends.equal_range(txin.prevout);
493  for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
494  result.insert(_it->second);
495  }
496  return result;
497 }
498 
499 bool CWallet::HasWalletSpend(const uint256& txid) const
500 {
501  AssertLockHeld(cs_wallet);
502  auto iter = mapTxSpends.lower_bound(COutPoint(txid, 0));
503  return (iter != mapTxSpends.end() && iter->first.hash == txid);
504 }
505 
506 void CWallet::Flush(bool shutdown)
507 {
508  dbw->Flush(shutdown);
509 }
510 
511 void CWallet::SyncMetaData(std::pair<TxSpends::iterator, TxSpends::iterator> range)
512 {
513  // We want all the wallet transactions in range to have the same metadata as
514  // the oldest (smallest nOrderPos).
515  // So: find smallest nOrderPos:
516 
517  int nMinOrderPos = std::numeric_limits<int>::max();
518  const CWalletTx* copyFrom = nullptr;
519  for (TxSpends::iterator it = range.first; it != range.second; ++it)
520  {
521  const uint256& hash = it->second;
522  int n = mapWallet[hash].nOrderPos;
523  if (n < nMinOrderPos)
524  {
525  nMinOrderPos = n;
526  copyFrom = &mapWallet[hash];
527  }
528  }
529  // Now copy data from copyFrom to rest:
530  for (TxSpends::iterator it = range.first; it != range.second; ++it)
531  {
532  const uint256& hash = it->second;
533  CWalletTx* copyTo = &mapWallet[hash];
534  if (copyFrom == copyTo) continue;
535  assert(copyFrom && "Oldest wallet transaction in range assumed to have been found.");
536  if (!copyFrom->IsEquivalentTo(*copyTo)) continue;
537  copyTo->mapValue = copyFrom->mapValue;
538  copyTo->vOrderForm = copyFrom->vOrderForm;
539  // fTimeReceivedIsTxTime not copied on purpose
540  // nTimeReceived not copied on purpose
541  copyTo->nTimeSmart = copyFrom->nTimeSmart;
542  copyTo->fFromMe = copyFrom->fFromMe;
543  copyTo->strFromAccount = copyFrom->strFromAccount;
544  // nOrderPos not copied on purpose
545  // cached members not copied on purpose
546  }
547 }
548 
553 bool CWallet::IsSpent(const uint256& hash, unsigned int n) const
554 {
555  const COutPoint outpoint(hash, n);
556  std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
557  range = mapTxSpends.equal_range(outpoint);
558 
559  for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
560  {
561  const uint256& wtxid = it->second;
562  std::map<uint256, CWalletTx>::const_iterator mit = mapWallet.find(wtxid);
563  if (mit != mapWallet.end()) {
564  int depth = mit->second.GetDepthInMainChain();
565  if (depth > 0 || (depth == 0 && !mit->second.isAbandoned()))
566  return true; // Spent
567  }
568  }
569  return false;
570 }
571 
572 void CWallet::AddToSpends(const COutPoint& outpoint, const uint256& wtxid)
573 {
574  mapTxSpends.insert(std::make_pair(outpoint, wtxid));
575 
576  std::pair<TxSpends::iterator, TxSpends::iterator> range;
577  range = mapTxSpends.equal_range(outpoint);
578  SyncMetaData(range);
579 }
580 
581 
582 void CWallet::AddToSpends(const uint256& wtxid)
583 {
584  auto it = mapWallet.find(wtxid);
585  assert(it != mapWallet.end());
586  CWalletTx& thisTx = it->second;
587  if (thisTx.IsCoinBase()) // Coinbases don't spend anything!
588  return;
589 
590  for (const CTxIn& txin : thisTx.tx->vin)
591  AddToSpends(txin.prevout, wtxid);
592 }
593 
594 bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
595 {
596  if (IsCrypted())
597  return false;
598 
599  CKeyingMaterial _vMasterKey;
600 
601  _vMasterKey.resize(WALLET_CRYPTO_KEY_SIZE);
602  GetStrongRandBytes(&_vMasterKey[0], WALLET_CRYPTO_KEY_SIZE);
603 
604  CMasterKey kMasterKey;
605 
606  kMasterKey.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE);
608 
609  CCrypter crypter;
610  int64_t nStartTime = GetTimeMillis();
611  crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, 25000, kMasterKey.nDerivationMethod);
612  kMasterKey.nDeriveIterations = static_cast<unsigned int>(2500000 / ((double)(GetTimeMillis() - nStartTime)));
613 
614  nStartTime = GetTimeMillis();
615  crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod);
616  kMasterKey.nDeriveIterations = (kMasterKey.nDeriveIterations + static_cast<unsigned int>(kMasterKey.nDeriveIterations * 100 / ((double)(GetTimeMillis() - nStartTime)))) / 2;
617 
618  if (kMasterKey.nDeriveIterations < 25000)
619  kMasterKey.nDeriveIterations = 25000;
620 
621  LogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", kMasterKey.nDeriveIterations);
622 
623  if (!crypter.SetKeyFromPassphrase(strWalletPassphrase, kMasterKey.vchSalt, kMasterKey.nDeriveIterations, kMasterKey.nDerivationMethod))
624  return false;
625  if (!crypter.Encrypt(_vMasterKey, kMasterKey.vchCryptedKey))
626  return false;
627 
628  {
629  LOCK(cs_wallet);
630  mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
631  assert(!pwalletdbEncryption);
632  pwalletdbEncryption = new CWalletDB(*dbw);
633  if (!pwalletdbEncryption->TxnBegin()) {
634  delete pwalletdbEncryption;
635  pwalletdbEncryption = nullptr;
636  return false;
637  }
638  pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
639 
640  if (!EncryptKeys(_vMasterKey))
641  {
642  pwalletdbEncryption->TxnAbort();
643  delete pwalletdbEncryption;
644  // We now probably have half of our keys encrypted in memory, and half not...
645  // die and let the user reload the unencrypted wallet.
646  assert(false);
647  }
648 
649  // Encryption was introduced in version 0.4.0
650  SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
651 
652  if (!pwalletdbEncryption->TxnCommit()) {
653  delete pwalletdbEncryption;
654  // We now have keys encrypted in memory, but not on disk...
655  // die to avoid confusion and let the user reload the unencrypted wallet.
656  assert(false);
657  }
658 
659  delete pwalletdbEncryption;
660  pwalletdbEncryption = nullptr;
661 
662  Lock();
663  Unlock(strWalletPassphrase);
664 
665  // if we are using HD, replace the HD seed with a new one
666  if (IsHDEnabled()) {
667  if (!SetHDSeed(GenerateNewSeed())) {
668  return false;
669  }
670  }
671 
672  NewKeyPool();
673  Lock();
674 
675  // Need to completely rewrite the wallet file; if we don't, bdb might keep
676  // bits of the unencrypted private key in slack space in the database file.
677  dbw->Rewrite();
678 
679  }
680  NotifyStatusChanged(this);
681 
682  return true;
683 }
684 
686 {
687  LOCK(cs_wallet);
688  CWalletDB walletdb(*dbw);
689 
690  // Old wallets didn't have any defined order for transactions
691  // Probably a bad idea to change the output of this
692 
693  // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap.
694  typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
695  typedef std::multimap<int64_t, TxPair > TxItems;
696  TxItems txByTime;
697 
698  for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
699  {
700  CWalletTx* wtx = &((*it).second);
701  txByTime.insert(std::make_pair(wtx->nTimeReceived, TxPair(wtx, nullptr)));
702  }
703  std::list<CAccountingEntry> acentries;
704  walletdb.ListAccountCreditDebit("", acentries);
705  for (CAccountingEntry& entry : acentries)
706  {
707  txByTime.insert(std::make_pair(entry.nTime, TxPair(nullptr, &entry)));
708  }
709 
710  nOrderPosNext = 0;
711  std::vector<int64_t> nOrderPosOffsets;
712  for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it)
713  {
714  CWalletTx *const pwtx = (*it).second.first;
715  CAccountingEntry *const pacentry = (*it).second.second;
716  int64_t& nOrderPos = (pwtx != nullptr) ? pwtx->nOrderPos : pacentry->nOrderPos;
717 
718  if (nOrderPos == -1)
719  {
720  nOrderPos = nOrderPosNext++;
721  nOrderPosOffsets.push_back(nOrderPos);
722 
723  if (pwtx)
724  {
725  if (!walletdb.WriteTx(*pwtx))
726  return DB_LOAD_FAIL;
727  }
728  else
729  if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
730  return DB_LOAD_FAIL;
731  }
732  else
733  {
734  int64_t nOrderPosOff = 0;
735  for (const int64_t& nOffsetStart : nOrderPosOffsets)
736  {
737  if (nOrderPos >= nOffsetStart)
738  ++nOrderPosOff;
739  }
740  nOrderPos += nOrderPosOff;
741  nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
742 
743  if (!nOrderPosOff)
744  continue;
745 
746  // Since we're changing the order, write it back
747  if (pwtx)
748  {
749  if (!walletdb.WriteTx(*pwtx))
750  return DB_LOAD_FAIL;
751  }
752  else
753  if (!walletdb.WriteAccountingEntry(pacentry->nEntryNo, *pacentry))
754  return DB_LOAD_FAIL;
755  }
756  }
757  walletdb.WriteOrderPosNext(nOrderPosNext);
758 
759  return DB_LOAD_OK;
760 }
761 
763 {
764  AssertLockHeld(cs_wallet); // nOrderPosNext
765  int64_t nRet = nOrderPosNext++;
766  if (pwalletdb) {
767  pwalletdb->WriteOrderPosNext(nOrderPosNext);
768  } else {
769  CWalletDB(*dbw).WriteOrderPosNext(nOrderPosNext);
770  }
771  return nRet;
772 }
773 
774 bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment)
775 {
776  CWalletDB walletdb(*dbw);
777  if (!walletdb.TxnBegin())
778  return false;
779 
780  int64_t nNow = GetAdjustedTime();
781 
782  // Debit
783  CAccountingEntry debit;
784  debit.nOrderPos = IncOrderPosNext(&walletdb);
785  debit.strAccount = strFrom;
786  debit.nCreditDebit = -nAmount;
787  debit.nTime = nNow;
788  debit.strOtherAccount = strTo;
789  debit.strComment = strComment;
790  AddAccountingEntry(debit, &walletdb);
791 
792  // Credit
793  CAccountingEntry credit;
794  credit.nOrderPos = IncOrderPosNext(&walletdb);
795  credit.strAccount = strTo;
796  credit.nCreditDebit = nAmount;
797  credit.nTime = nNow;
798  credit.strOtherAccount = strFrom;
799  credit.strComment = strComment;
800  AddAccountingEntry(credit, &walletdb);
801 
802  if (!walletdb.TxnCommit())
803  return false;
804 
805  return true;
806 }
807 
808 bool CWallet::GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew)
809 {
810  CWalletDB walletdb(*dbw);
811 
812  CAccount account;
813  walletdb.ReadAccount(strAccount, account);
814 
815  if (!bForceNew) {
816  if (!account.vchPubKey.IsValid())
817  bForceNew = true;
818  else {
819  // Check if the current key has been used
820  CScript scriptPubKey = GetScriptForDestination(account.vchPubKey.GetID());
821  for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin();
822  it != mapWallet.end() && account.vchPubKey.IsValid();
823  ++it)
824  for (const CTxOut& txout : (*it).second.tx->vout)
825  if (txout.scriptPubKey == scriptPubKey) {
826  bForceNew = true;
827  break;
828  }
829  }
830  }
831 
832  // Generate a new key
833  if (bForceNew) {
834  if (!GetKeyFromPool(account.vchPubKey, false))
835  return false;
836 
837  SetAddressBook(account.vchPubKey.GetID(), strAccount, "receive");
838  walletdb.WriteAccount(strAccount, account);
839  }
840 
841  pubKey = account.vchPubKey;
842 
843  return true;
844 }
845 
847 {
848  {
849  LOCK(cs_wallet);
850  for (std::pair<const uint256, CWalletTx>& item : mapWallet)
851  item.second.MarkDirty();
852  }
853 }
854 
855 bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
856 {
857  LOCK(cs_wallet);
858 
859  auto mi = mapWallet.find(originalHash);
860 
861  // There is a bug if MarkReplaced is not called on an existing wallet transaction.
862  assert(mi != mapWallet.end());
863 
864  CWalletTx& wtx = (*mi).second;
865 
866  // Ensure for now that we're not overwriting data
867  assert(wtx.mapValue.count("replaced_by_txid") == 0);
868 
869  wtx.mapValue["replaced_by_txid"] = newHash.ToString();
870 
871  CWalletDB walletdb(*dbw, "r+");
872 
873  bool success = true;
874  if (!walletdb.WriteTx(wtx)) {
875  LogPrintf("%s: Updating walletdb tx %s failed", __func__, wtx.GetHash().ToString());
876  success = false;
877  }
878 
879  NotifyTransactionChanged(this, originalHash, CT_UPDATED);
880 
881  return success;
882 }
883 
884 bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
885 {
886  LOCK(cs_wallet);
887 
888  CWalletDB walletdb(*dbw, "r+", fFlushOnClose);
889 
890  uint256 hash = wtxIn.GetHash();
891 
892  // Inserts only if not already there, returns tx inserted or tx found
893  std::pair<std::map<uint256, CWalletTx>::iterator, bool> ret = mapWallet.insert(std::make_pair(hash, wtxIn));
894  CWalletTx& wtx = (*ret.first).second;
895  wtx.BindWallet(this);
896  bool fInsertedNew = ret.second;
897  if (fInsertedNew)
898  {
900  wtx.nOrderPos = IncOrderPosNext(&walletdb);
901  wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr)));
902  wtx.nTimeSmart = ComputeTimeSmart(wtx);
903  AddToSpends(hash);
904  }
905 
906  bool fUpdated = false;
907  if (!fInsertedNew)
908  {
909  // Merge
910  if (!wtxIn.hashUnset() && wtxIn.hashBlock != wtx.hashBlock)
911  {
912  wtx.hashBlock = wtxIn.hashBlock;
913  fUpdated = true;
914  }
915  // If no longer abandoned, update
916  if (wtxIn.hashBlock.IsNull() && wtx.isAbandoned())
917  {
918  wtx.hashBlock = wtxIn.hashBlock;
919  fUpdated = true;
920  }
921  if (wtxIn.nIndex != -1 && (wtxIn.nIndex != wtx.nIndex))
922  {
923  wtx.nIndex = wtxIn.nIndex;
924  fUpdated = true;
925  }
926  if (wtxIn.fFromMe && wtxIn.fFromMe != wtx.fFromMe)
927  {
928  wtx.fFromMe = wtxIn.fFromMe;
929  fUpdated = true;
930  }
931  // If we have a witness-stripped version of this transaction, and we
932  // see a new version with a witness, then we must be upgrading a pre-segwit
933  // wallet. Store the new version of the transaction with the witness,
934  // as the stripped-version must be invalid.
935  // TODO: Store all versions of the transaction, instead of just one.
936  if (wtxIn.tx->HasWitness() && !wtx.tx->HasWitness()) {
937  wtx.SetTx(wtxIn.tx);
938  fUpdated = true;
939  }
940  }
941 
943  LogPrintf("AddToWallet %s %s%s\n", wtxIn.GetHash().ToString(), (fInsertedNew ? "new" : ""), (fUpdated ? "update" : ""));
944 
945  // Write to disk
946  if (fInsertedNew || fUpdated)
947  if (!walletdb.WriteTx(wtx))
948  return false;
949 
950  // Break debit/credit balance caches:
951  wtx.MarkDirty();
952 
953  // Notify UI of new or updated transaction
954  NotifyTransactionChanged(this, hash, fInsertedNew ? CT_NEW : CT_UPDATED);
955 
956  // notify an external script when a wallet transaction comes in or is updated
957  std::string strCmd = gArgs.GetArg("-walletnotify", "");
958 
959  if (!strCmd.empty())
960  {
961  boost::replace_all(strCmd, "%s", wtxIn.GetHash().GetHex());
962  boost::thread t(runCommand, strCmd); // thread runs free
963  }
964 
965  return true;
966 }
967 
969 {
970  uint256 hash = wtxIn.GetHash();
971 
972  mapWallet[hash] = wtxIn;
973  CWalletTx& wtx = mapWallet[hash];
974  wtx.BindWallet(this);
975  wtxOrdered.insert(std::make_pair(wtx.nOrderPos, TxPair(&wtx, nullptr)));
976  AddToSpends(hash);
977  for (const CTxIn& txin : wtx.tx->vin) {
978  auto it = mapWallet.find(txin.prevout.hash);
979  if (it != mapWallet.end()) {
980  CWalletTx& prevtx = it->second;
981  if (prevtx.nIndex == -1 && !prevtx.hashUnset()) {
982  MarkConflicted(prevtx.hashBlock, wtx.GetHash());
983  }
984  }
985  }
986 
987  return true;
988 }
989 
1003 bool CWallet::AddToWalletIfInvolvingMe(const CTransactionRef& ptx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate)
1004 {
1005  const CTransaction& tx = *ptx;
1006  {
1007  AssertLockHeld(cs_wallet);
1008 
1009  if (pIndex != nullptr) {
1010  for (const CTxIn& txin : tx.vin) {
1011  std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range = mapTxSpends.equal_range(txin.prevout);
1012  while (range.first != range.second) {
1013  if (range.first->second != tx.GetHash()) {
1014  LogPrintf("Transaction %s (in block %s) conflicts with wallet transaction %s (both spend %s:%i)\n", tx.GetHash().ToString(), pIndex->GetBlockHash().ToString(), range.first->second.ToString(), range.first->first.hash.ToString(), range.first->first.n);
1015  MarkConflicted(pIndex->GetBlockHash(), range.first->second);
1016  }
1017  range.first++;
1018  }
1019  }
1020  }
1021 
1022  bool fExisted = mapWallet.count(tx.GetHash()) != 0;
1023  if (fExisted && !fUpdate) return false;
1024  if (fExisted || IsMine(tx) || IsFromMe(tx))
1025  {
1026  /* Check if any keys in the wallet keypool that were supposed to be unused
1027  * have appeared in a new transaction. If so, remove those keys from the keypool.
1028  * This can happen when restoring an old wallet backup that does not contain
1029  * the mostly recently created transactions from newer versions of the wallet.
1030  */
1031 
1032  // loop though all outputs
1033  for (const CTxOut& txout: tx.vout) {
1034  // extract addresses and check if they match with an unused keypool key
1035  std::vector<CKeyID> vAffected;
1036  CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
1037  for (const CKeyID &keyid : vAffected) {
1038  std::map<CKeyID, int64_t>::const_iterator mi = m_pool_key_to_index.find(keyid);
1039  if (mi != m_pool_key_to_index.end()) {
1040  LogPrintf("%s: Detected a used keypool key, mark all keypool key up to this key as used\n", __func__);
1041  MarkReserveKeysAsUsed(mi->second);
1042 
1043  if (!TopUpKeyPool()) {
1044  LogPrintf("%s: Topping up keypool failed (locked wallet)\n", __func__);
1045  }
1046  }
1047  }
1048  }
1049 
1050  CWalletTx wtx(this, ptx);
1051 
1052  // Get merkle branch if transaction was found in a block
1053  if (pIndex != nullptr)
1054  wtx.SetMerkleBranch(pIndex, posInBlock);
1055 
1056  return AddToWallet(wtx, false);
1057  }
1058  }
1059  return false;
1060 }
1061 
1063 {
1064  LOCK2(cs_main, cs_wallet);
1065  const CWalletTx* wtx = GetWalletTx(hashTx);
1066  return wtx && !wtx->isAbandoned() && wtx->GetDepthInMainChain() <= 0 && !wtx->InMempool();
1067 }
1068 
1070 {
1071  LOCK2(cs_main, cs_wallet);
1072 
1073  CWalletDB walletdb(*dbw, "r+");
1074 
1075  std::set<uint256> todo;
1076  std::set<uint256> done;
1077 
1078  // Can't mark abandoned if confirmed or in mempool
1079  auto it = mapWallet.find(hashTx);
1080  assert(it != mapWallet.end());
1081  CWalletTx& origtx = it->second;
1082  if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) {
1083  return false;
1084  }
1085 
1086  todo.insert(hashTx);
1087 
1088  while (!todo.empty()) {
1089  uint256 now = *todo.begin();
1090  todo.erase(now);
1091  done.insert(now);
1092  auto it = mapWallet.find(now);
1093  assert(it != mapWallet.end());
1094  CWalletTx& wtx = it->second;
1095  int currentconfirm = wtx.GetDepthInMainChain();
1096  // If the orig tx was not in block, none of its spends can be
1097  assert(currentconfirm <= 0);
1098  // if (currentconfirm < 0) {Tx and spends are already conflicted, no need to abandon}
1099  if (currentconfirm == 0 && !wtx.isAbandoned()) {
1100  // If the orig tx was not in block/mempool, none of its spends can be in mempool
1101  assert(!wtx.InMempool());
1102  wtx.nIndex = -1;
1103  wtx.setAbandoned();
1104  wtx.MarkDirty();
1105  walletdb.WriteTx(wtx);
1106  NotifyTransactionChanged(this, wtx.GetHash(), CT_UPDATED);
1107  // Iterate over all its outputs, and mark transactions in the wallet that spend them abandoned too
1108  TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(hashTx, 0));
1109  while (iter != mapTxSpends.end() && iter->first.hash == now) {
1110  if (!done.count(iter->second)) {
1111  todo.insert(iter->second);
1112  }
1113  iter++;
1114  }
1115  // If a transaction changes 'conflicted' state, that changes the balance
1116  // available of the outputs it spends. So force those to be recomputed
1117  for (const CTxIn& txin : wtx.tx->vin)
1118  {
1119  auto it = mapWallet.find(txin.prevout.hash);
1120  if (it != mapWallet.end()) {
1121  it->second.MarkDirty();
1122  }
1123  }
1124  }
1125  }
1126 
1127  return true;
1128 }
1129 
1130 void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
1131 {
1132  LOCK2(cs_main, cs_wallet);
1133 
1134  int conflictconfirms = 0;
1135  if (mapBlockIndex.count(hashBlock)) {
1136  CBlockIndex* pindex = mapBlockIndex[hashBlock];
1137  if (chainActive.Contains(pindex)) {
1138  conflictconfirms = -(chainActive.Height() - pindex->nHeight + 1);
1139  }
1140  }
1141  // If number of conflict confirms cannot be determined, this means
1142  // that the block is still unknown or not yet part of the main chain,
1143  // for example when loading the wallet during a reindex. Do nothing in that
1144  // case.
1145  if (conflictconfirms >= 0)
1146  return;
1147 
1148  // Do not flush the wallet here for performance reasons
1149  CWalletDB walletdb(*dbw, "r+", false);
1150 
1151  std::set<uint256> todo;
1152  std::set<uint256> done;
1153 
1154  todo.insert(hashTx);
1155 
1156  while (!todo.empty()) {
1157  uint256 now = *todo.begin();
1158  todo.erase(now);
1159  done.insert(now);
1160  auto it = mapWallet.find(now);
1161  assert(it != mapWallet.end());
1162  CWalletTx& wtx = it->second;
1163  int currentconfirm = wtx.GetDepthInMainChain();
1164  if (conflictconfirms < currentconfirm) {
1165  // Block is 'more conflicted' than current confirm; update.
1166  // Mark transaction as conflicted with this block.
1167  wtx.nIndex = -1;
1168  wtx.hashBlock = hashBlock;
1169  wtx.MarkDirty();
1170  walletdb.WriteTx(wtx);
1171  // Iterate over all its outputs, and mark transactions in the wallet that spend them conflicted too
1172  TxSpends::const_iterator iter = mapTxSpends.lower_bound(COutPoint(now, 0));
1173  while (iter != mapTxSpends.end() && iter->first.hash == now) {
1174  if (!done.count(iter->second)) {
1175  todo.insert(iter->second);
1176  }
1177  iter++;
1178  }
1179  // If a transaction changes 'conflicted' state, that changes the balance
1180  // available of the outputs it spends. So force those to be recomputed
1181  for (const CTxIn& txin : wtx.tx->vin) {
1182  auto it = mapWallet.find(txin.prevout.hash);
1183  if (it != mapWallet.end()) {
1184  it->second.MarkDirty();
1185  }
1186  }
1187  }
1188  }
1189 }
1190 
1191 void CWallet::SyncTransaction(const CTransactionRef& ptx, const CBlockIndex *pindex, int posInBlock) {
1192  const CTransaction& tx = *ptx;
1193 
1194  if (!AddToWalletIfInvolvingMe(ptx, pindex, posInBlock, true))
1195  return; // Not one of ours
1196 
1197  // If a transaction changes 'conflicted' state, that changes the balance
1198  // available of the outputs it spends. So force those to be
1199  // recomputed, also:
1200  for (const CTxIn& txin : tx.vin) {
1201  auto it = mapWallet.find(txin.prevout.hash);
1202  if (it != mapWallet.end()) {
1203  it->second.MarkDirty();
1204  }
1205  }
1206 }
1207 
1209  LOCK2(cs_main, cs_wallet);
1210  SyncTransaction(ptx);
1211 }
1212 
1213 void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) {
1214  LOCK2(cs_main, cs_wallet);
1215  // TODO: Temporarily ensure that mempool removals are notified before
1216  // connected transactions. This shouldn't matter, but the abandoned
1217  // state of transactions in our wallet is currently cleared when we
1218  // receive another notification and there is a race condition where
1219  // notification of a connected conflict might cause an outside process
1220  // to abandon a transaction and then have it inadvertently cleared by
1221  // the notification that the conflicted transaction was evicted.
1222 
1223  for (const CTransactionRef& ptx : vtxConflicted) {
1224  SyncTransaction(ptx);
1225  }
1226  for (size_t i = 0; i < pblock->vtx.size(); i++) {
1227  SyncTransaction(pblock->vtx[i], pindex, i);
1228  }
1229 }
1230 
1231 void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) {
1232  LOCK2(cs_main, cs_wallet);
1233 
1234  for (const CTransactionRef& ptx : pblock->vtx) {
1235  SyncTransaction(ptx);
1236  }
1237 }
1238 
1239 
1240 
1242 {
1243  {
1244  LOCK(cs_wallet);
1245  std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1246  if (mi != mapWallet.end())
1247  {
1248  const CWalletTx& prev = (*mi).second;
1249  if (txin.prevout.n < prev.tx->vout.size())
1250  return IsMine(prev.tx->vout[txin.prevout.n]);
1251  }
1252  }
1253  return ISMINE_NO;
1254 }
1255 
1256 CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter) const {
1257  CAssetOutputEntry assetData;
1258  return GetDebit(txin, filter, assetData);
1259 }
1260 
1261 // Note that this function doesn't distinguish between a 0-valued input,
1262 // and a not-"is mine" (according to the filter) input.
1263 CAmount CWallet::GetDebit(const CTxIn &txin, const isminefilter& filter, CAssetOutputEntry& assetData) const
1264 {
1265  {
1266  LOCK(cs_wallet);
1267  std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.prevout.hash);
1268  if (mi != mapWallet.end())
1269  {
1270  const CWalletTx& prev = (*mi).second;
1271  if (txin.prevout.n < prev.tx->vout.size())
1272  if (IsMine(prev.tx->vout[txin.prevout.n]) & filter) {
1273  // if asset get that assets data from the scriptPubKey
1274  if (prev.tx->vout[txin.prevout.n].scriptPubKey.IsAssetScript())
1275  GetAssetData(prev.tx->vout[txin.prevout.n].scriptPubKey, assetData);
1276 
1277  return prev.tx->vout[txin.prevout.n].nValue;
1278  }
1279  }
1280  }
1281  return 0;
1282 }
1283 
1284 isminetype CWallet::IsMine(const CTxOut& txout) const
1285 {
1286  return ::IsMine(*this, txout.scriptPubKey);
1287 }
1288 
1289 CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) const
1290 {
1291  if (!MoneyRange(txout.nValue))
1292  throw std::runtime_error(std::string(__func__) + ": value out of range");
1293  return ((IsMine(txout) & filter) ? txout.nValue : 0);
1294 }
1295 
1296 bool CWallet::IsChange(const CTxOut& txout) const
1297 {
1298  // TODO: fix handling of 'change' outputs. The assumption is that any
1299  // payment to a script that is ours, but is not in the address book
1300  // is change. That assumption is likely to break when we implement multisignature
1301  // wallets that return change back into a multi-signature-protected address;
1302  // a better way of identifying which outputs are 'the send' and which are
1303  // 'the change' will need to be implemented (maybe extend CWalletTx to remember
1304  // which output, if any, was change).
1305  if (::IsMine(*this, txout.scriptPubKey))
1306  {
1307  CTxDestination address;
1308  if (!ExtractDestination(txout.scriptPubKey, address))
1309  return true;
1310 
1311  LOCK(cs_wallet);
1312  if (!mapAddressBook.count(address))
1313  return true;
1314  }
1315  return false;
1316 }
1317 
1318 CAmount CWallet::GetChange(const CTxOut& txout) const
1319 {
1320  if (!MoneyRange(txout.nValue))
1321  throw std::runtime_error(std::string(__func__) + ": value out of range");
1322  return (IsChange(txout) ? txout.nValue : 0);
1323 }
1324 
1325 bool CWallet::IsMine(const CTransaction& tx) const
1326 {
1327  for (const CTxOut& txout : tx.vout)
1328  if (IsMine(txout))
1329  return true;
1330  return false;
1331 }
1332 
1333 bool CWallet::IsFromMe(const CTransaction& tx) const
1334 {
1335  return (GetDebit(tx, ISMINE_ALL) > 0);
1336 }
1337 
1338 CAmount CWallet::GetDebit(const CTransaction& tx, const isminefilter& filter) const
1339 {
1340  CAmount nDebit = 0;
1341  for (const CTxIn& txin : tx.vin)
1342  {
1343  nDebit += GetDebit(txin, filter);
1344  if (!MoneyRange(nDebit))
1345  throw std::runtime_error(std::string(__func__) + ": value out of range");
1346  }
1347  return nDebit;
1348 }
1349 
1350 bool CWallet::IsAllFromMe(const CTransaction& tx, const isminefilter& filter) const
1351 {
1352  LOCK(cs_wallet);
1353 
1354  for (const CTxIn& txin : tx.vin)
1355  {
1356  auto mi = mapWallet.find(txin.prevout.hash);
1357  if (mi == mapWallet.end())
1358  return false; // any unknown inputs can't be from us
1359 
1360  const CWalletTx& prev = (*mi).second;
1361 
1362  if (txin.prevout.n >= prev.tx->vout.size())
1363  return false; // invalid input!
1364 
1365  if (!(IsMine(prev.tx->vout[txin.prevout.n]) & filter))
1366  return false;
1367  }
1368  return true;
1369 }
1370 
1371 CAmount CWallet::GetCredit(const CTransaction& tx, const isminefilter& filter) const
1372 {
1373  CAmount nCredit = 0;
1374  for (const CTxOut& txout : tx.vout)
1375  {
1376  nCredit += GetCredit(txout, filter);
1377  if (!MoneyRange(nCredit))
1378  throw std::runtime_error(std::string(__func__) + ": value out of range");
1379  }
1380  return nCredit;
1381 }
1382 
1384 {
1385  CAmount nChange = 0;
1386  for (const CTxOut& txout : tx.vout)
1387  {
1388  nChange += GetChange(txout);
1389  if (!MoneyRange(nChange))
1390  throw std::runtime_error(std::string(__func__) + ": value out of range");
1391  }
1392  return nChange;
1393 }
1394 
1396 {
1397  CKey key;
1398  key.MakeNewKey(true);
1399  return DeriveNewSeed(key);
1400 }
1401 
1403 {
1404  int64_t nCreationTime = GetTime();
1405  CKeyMetadata metadata(nCreationTime);
1406 
1407  // calculate the seed
1408  CPubKey seed = key.GetPubKey();
1409  assert(key.VerifyPubKey(seed));
1410 
1411  // set the hd keypath to "s" -> Seed, refers the seed to itself
1412  metadata.hdKeypath = "s";
1413  metadata.hd_seed_id = seed.GetID();
1414 
1415  {
1416  LOCK(cs_wallet);
1417 
1418  // mem store the metadata
1419  mapKeyMetadata[seed.GetID()] = metadata;
1420 
1421  // write the key&metadata to the database
1422  if (!AddKeyPubKey(key, seed))
1423  throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
1424  }
1425 
1426  return seed;
1427 }
1428 
1429 bool CWallet::SetHDSeed(const CPubKey& seed)
1430 {
1431  LOCK(cs_wallet);
1432  // store the keyid (hash160) together with
1433  // the child index counter in the database
1434  // as a hdchain object
1435  CHDChain newHdChain;
1437  newHdChain.seed_id = seed.GetID();
1438  SetHDChain(newHdChain, false);
1439 
1440  return true;
1441 }
1442 
1443 bool CWallet::SetHDChain(const CHDChain& chain, bool memonly)
1444 {
1445  LOCK(cs_wallet);
1446  if (!memonly && !CWalletDB(*dbw).WriteHDChain(chain))
1447  throw std::runtime_error(std::string(__func__) + ": writing chain failed");
1448 
1449  hdChain = chain;
1450  return true;
1451 }
1452 
1454 {
1455  return !hdChain.seed_id.IsNull();
1456 }
1457 
1458 int64_t CWalletTx::GetTxTime() const
1459 {
1460  int64_t n = nTimeSmart;
1461  return n ? n : nTimeReceived;
1462 }
1463 
1465 {
1466  // Returns -1 if it wasn't being tracked
1467  int nRequests = -1;
1468  {
1469  LOCK(pwallet->cs_wallet);
1470  if (IsCoinBase())
1471  {
1472  // Generated block
1473  if (!hashUnset())
1474  {
1475  std::map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
1476  if (mi != pwallet->mapRequestCount.end())
1477  nRequests = (*mi).second;
1478  }
1479  }
1480  else
1481  {
1482  // Did anyone request this transaction?
1483  std::map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
1484  if (mi != pwallet->mapRequestCount.end())
1485  {
1486  nRequests = (*mi).second;
1487 
1488  // How about the block it's in?
1489  if (nRequests == 0 && !hashUnset())
1490  {
1491  std::map<uint256, int>::const_iterator _mi = pwallet->mapRequestCount.find(hashBlock);
1492  if (_mi != pwallet->mapRequestCount.end())
1493  nRequests = (*_mi).second;
1494  else
1495  nRequests = 1; // If it's in someone else's block it must have got out
1496  }
1497  }
1498  }
1499  }
1500  return nRequests;
1501 }
1502 
1503 void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived,
1504  std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter) const {
1505 
1506  std::list<CAssetOutputEntry> assetsReceived;
1507  std::list<CAssetOutputEntry> assetsSent;
1508  GetAmounts(listReceived, listSent, nFee, strSentAccount, filter, assetsReceived, assetsSent);
1509 }
1510 
1511 void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived,
1512  std::list<COutputEntry>& listSent, CAmount& nFee, std::string& strSentAccount, const isminefilter& filter, std::list<CAssetOutputEntry>& assetsReceived, std::list<CAssetOutputEntry>& assetsSent) const
1513 {
1514  nFee = 0;
1515  listReceived.clear();
1516  listSent.clear();
1517  strSentAccount = strFromAccount;
1518 
1519  // Compute fee:
1520  CAmount nDebit = GetDebit(filter);
1521  if (nDebit > 0) // debit>0 means we signed/sent this transaction
1522  {
1523  CAmount nValueOut = tx->GetValueOut();
1524  nFee = nDebit - nValueOut;
1525  }
1526 
1527  // Sent/received.
1528  for (unsigned int i = 0; i < tx->vout.size(); ++i)
1529  {
1530  const CTxOut& txout = tx->vout[i];
1531  isminetype fIsMine = pwallet->IsMine(txout);
1532  // Only need to handle txouts if AT LEAST one of these is true:
1533  // 1) they debit from us (sent)
1534  // 2) the output is to us (received)
1535  if (nDebit > 0)
1536  {
1537  // Don't report 'change' txouts
1538  if (pwallet->IsChange(txout))
1539  continue;
1540  }
1541  else if (!(fIsMine & filter))
1542  continue;
1543 
1544  // In either case, we need to get the destination address
1545  CTxDestination address;
1546 
1547  if (!ExtractDestination(txout.scriptPubKey, address) && !txout.scriptPubKey.IsUnspendable())
1548  {
1549  LogPrintf("%s: Failing on the %d tx\n", __func__, i);
1550  LogPrintf("CWalletTx::GetAmounts: Unknown transaction type found, txid %s\n",
1551  this->GetHash().ToString());
1552  address = CNoDestination();
1553  }
1554 
1555  if (!txout.scriptPubKey.IsAssetScript()) {
1556  COutputEntry output = {address, txout.nValue, (int) i};
1557 
1558  // If we are debited by the transaction, add the output as a "sent" entry
1559  if (nDebit > 0)
1560  listSent.push_back(output);
1561 
1562  // If we are receiving the output, add it as a "received" entry
1563  if (fIsMine & filter)
1564  listReceived.push_back(output);
1565  }
1566 
1568  if (AreAssetsDeployed()) {
1569  if (txout.scriptPubKey.IsAssetScript()) {
1570  CAssetOutputEntry assetoutput;
1571  assetoutput.vout = i;
1572  GetAssetData(txout.scriptPubKey, assetoutput);
1573 
1574  // The only asset type we send is transfer_asset. We need to skip all other types for the sent category
1575  if (nDebit > 0 && assetoutput.type == TX_TRANSFER_ASSET)
1576  assetsSent.emplace_back(assetoutput);
1577 
1578  if (fIsMine & filter)
1579  assetsReceived.emplace_back(assetoutput);
1580  }
1581  }
1583  }
1584 
1585 }
1586 
1595 int64_t CWallet::RescanFromTime(int64_t startTime, bool update)
1596 {
1598  AssertLockHeld(cs_wallet);
1599 
1600  // Find starting block. May be null if nCreateTime is greater than the
1601  // highest blockchain timestamp, in which case there is nothing that needs
1602  // to be scanned.
1603  CBlockIndex* const startBlock = chainActive.FindEarliestAtLeast(startTime - TIMESTAMP_WINDOW);
1604  LogPrintf("%s: Rescanning last %i blocks\n", __func__, startBlock ? chainActive.Height() - startBlock->nHeight + 1 : 0);
1605 
1606  if (startBlock) {
1607  const CBlockIndex* const failedBlock = ScanForWalletTransactions(startBlock, nullptr, update);
1608  if (failedBlock) {
1609  return failedBlock->GetBlockTimeMax() + TIMESTAMP_WINDOW + 1;
1610  }
1611  }
1612  return startTime;
1613 }
1614 
1628 {
1629  int64_t nNow = GetTime();
1630  const CChainParams& chainParams = Params();
1631 
1632  if (pindexStop) {
1633  assert(pindexStop->nHeight >= pindexStart->nHeight);
1634  }
1635 
1636  CBlockIndex* pindex = pindexStart;
1637  CBlockIndex* ret = nullptr;
1638  {
1639  LOCK2(cs_main, cs_wallet);
1640  fAbortRescan = false;
1641  fScanningWallet = true;
1642 
1643  ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup
1644  double dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex);
1645  double dProgressTip = GuessVerificationProgress(chainParams.TxData(), chainActive.Tip());
1646  while (pindex && !fAbortRescan)
1647  {
1648  if (pindex->nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
1649  ShowProgress(_("Rescanning..."), std::max(1, std::min(99, (int)((GuessVerificationProgress(chainParams.TxData(), pindex) - dProgressStart) / (dProgressTip - dProgressStart) * 100))));
1650  if (GetTime() >= nNow + 60) {
1651  nNow = GetTime();
1652  LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
1653  }
1654 
1655  CBlock block;
1656  if (ReadBlockFromDisk(block, pindex, Params().GetConsensus())) {
1657  for (size_t posInBlock = 0; posInBlock < block.vtx.size(); ++posInBlock) {
1658  AddToWalletIfInvolvingMe(block.vtx[posInBlock], pindex, posInBlock, fUpdate);
1659  }
1660  } else {
1661  ret = pindex;
1662  }
1663  if (pindex == pindexStop) {
1664  break;
1665  }
1666  pindex = chainActive.Next(pindex);
1667  }
1668  if (pindex && fAbortRescan) {
1669  LogPrintf("Rescan aborted at block %d. Progress=%f\n", pindex->nHeight, GuessVerificationProgress(chainParams.TxData(), pindex));
1670  }
1671  ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
1672 
1673  fScanningWallet = false;
1674  }
1675  return ret;
1676 }
1677 
1679 {
1680  // If transactions aren't being broadcasted, don't let them into local mempool either
1681  if (!fBroadcastTransactions)
1682  return;
1683  LOCK2(cs_main, cs_wallet);
1684  std::map<int64_t, CWalletTx*> mapSorted;
1685 
1686  // Sort pending wallet transactions based on their initial wallet insertion order
1687  for (std::pair<const uint256, CWalletTx>& item : mapWallet)
1688  {
1689  const uint256& wtxid = item.first;
1690  CWalletTx& wtx = item.second;
1691  assert(wtx.GetHash() == wtxid);
1692 
1693  int nDepth = wtx.GetDepthInMainChain();
1694 
1695  if (!wtx.IsCoinBase() && (nDepth == 0 && !wtx.isAbandoned())) {
1696  mapSorted.insert(std::make_pair(wtx.nOrderPos, &wtx));
1697  }
1698  }
1699 
1700  // Try to add wallet transactions to memory pool
1701  for (std::pair<const int64_t, CWalletTx*>& item : mapSorted)
1702  {
1703  CWalletTx& wtx = *(item.second);
1704 
1705  LOCK(mempool.cs);
1706  CValidationState state;
1707  wtx.AcceptToMemoryPool(maxTxFee, state);
1708  }
1709 }
1710 
1712 {
1713  assert(pwallet->GetBroadcastTransactions());
1714  if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain() == 0)
1715  {
1716  /* GetDepthInMainChain already catches known conflicts. */
1717  CValidationState state;
1718  if (InMempool() || AcceptToMemoryPool(maxTxFee, state)) {
1719  LogPrintf("Relaying wtx %s\n", GetHash().ToString());
1720  if (connman) {
1721  CInv inv(MSG_TX, GetHash());
1722  connman->ForEachNode([&inv](CNode* pnode)
1723  {
1724  pnode->PushInventory(inv);
1725  });
1726  return true;
1727  }
1728  }
1729  }
1730  return false;
1731 }
1732 
1733 std::set<uint256> CWalletTx::GetConflicts() const
1734 {
1735  std::set<uint256> result;
1736  if (pwallet != nullptr)
1737  {
1738  uint256 myHash = GetHash();
1739  result = pwallet->GetConflicts(myHash);
1740  result.erase(myHash);
1741  }
1742  return result;
1743 }
1744 
1746 {
1747  if (tx->vin.empty())
1748  return 0;
1749 
1750  CAmount debit = 0;
1751  if(filter & ISMINE_SPENDABLE)
1752  {
1753  if (fDebitCached)
1754  debit += nDebitCached;
1755  else
1756  {
1757  nDebitCached = pwallet->GetDebit(*this, ISMINE_SPENDABLE);
1758  fDebitCached = true;
1759  debit += nDebitCached;
1760  }
1761  }
1762  if(filter & ISMINE_WATCH_ONLY)
1763  {
1764  if(fWatchDebitCached)
1765  debit += nWatchDebitCached;
1766  else
1767  {
1768  nWatchDebitCached = pwallet->GetDebit(*this, ISMINE_WATCH_ONLY);
1769  fWatchDebitCached = true;
1770  debit += nWatchDebitCached;
1771  }
1772  }
1773  return debit;
1774 }
1775 
1777 {
1778  // Must wait until coinbase is safely deep enough in the chain before valuing it
1779  if (IsCoinBase() && GetBlocksToMaturity() > 0)
1780  return 0;
1781 
1782  CAmount credit = 0;
1783  if (filter & ISMINE_SPENDABLE)
1784  {
1785  // GetBalance can assume transactions in mapWallet won't change
1786  if (fCreditCached)
1787  credit += nCreditCached;
1788  else
1789  {
1790  nCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
1791  fCreditCached = true;
1792  credit += nCreditCached;
1793  }
1794  }
1795  if (filter & ISMINE_WATCH_ONLY)
1796  {
1797  if (fWatchCreditCached)
1798  credit += nWatchCreditCached;
1799  else
1800  {
1801  nWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
1802  fWatchCreditCached = true;
1803  credit += nWatchCreditCached;
1804  }
1805  }
1806  return credit;
1807 }
1808 
1810 {
1811  if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
1812  {
1813  if (fUseCache && fImmatureCreditCached)
1814  return nImmatureCreditCached;
1815  nImmatureCreditCached = pwallet->GetCredit(*this, ISMINE_SPENDABLE);
1816  fImmatureCreditCached = true;
1817  return nImmatureCreditCached;
1818  }
1819 
1820  return 0;
1821 }
1822 
1824 {
1825  if (pwallet == nullptr)
1826  return 0;
1827 
1828  // Must wait until coinbase is safely deep enough in the chain before valuing it
1829  if (IsCoinBase() && GetBlocksToMaturity() > 0)
1830  return 0;
1831 
1832  if (fUseCache && fAvailableCreditCached)
1833  return nAvailableCreditCached;
1834 
1835  CAmount nCredit = 0;
1836  uint256 hashTx = GetHash();
1837  for (unsigned int i = 0; i < tx->vout.size(); i++)
1838  {
1839  if (!pwallet->IsSpent(hashTx, i))
1840  {
1841  const CTxOut &txout = tx->vout[i];
1842  nCredit += pwallet->GetCredit(txout, ISMINE_SPENDABLE);
1843  if (!MoneyRange(nCredit))
1844  throw std::runtime_error(std::string(__func__) + " : value out of range");
1845  }
1846  }
1847 
1848  nAvailableCreditCached = nCredit;
1849  fAvailableCreditCached = true;
1850  return nCredit;
1851 }
1852 
1854 {
1855  if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
1856  {
1857  if (fUseCache && fImmatureWatchCreditCached)
1858  return nImmatureWatchCreditCached;
1859  nImmatureWatchCreditCached = pwallet->GetCredit(*this, ISMINE_WATCH_ONLY);
1860  fImmatureWatchCreditCached = true;
1861  return nImmatureWatchCreditCached;
1862  }
1863 
1864  return 0;
1865 }
1866 
1868 {
1869  if (pwallet == nullptr)
1870  return 0;
1871 
1872  // Must wait until coinbase is safely deep enough in the chain before valuing it
1873  if (IsCoinBase() && GetBlocksToMaturity() > 0)
1874  return 0;
1875 
1876  if (fUseCache && fAvailableWatchCreditCached)
1877  return nAvailableWatchCreditCached;
1878 
1879  CAmount nCredit = 0;
1880  for (unsigned int i = 0; i < tx->vout.size(); i++)
1881  {
1882  if (!pwallet->IsSpent(GetHash(), i))
1883  {
1884  const CTxOut &txout = tx->vout[i];
1885  nCredit += pwallet->GetCredit(txout, ISMINE_WATCH_ONLY);
1886  if (!MoneyRange(nCredit))
1887  throw std::runtime_error(std::string(__func__) + ": value out of range");
1888  }
1889  }
1890 
1891  nAvailableWatchCreditCached = nCredit;
1892  fAvailableWatchCreditCached = true;
1893  return nCredit;
1894 }
1895 
1897 {
1898  if (fChangeCached)
1899  return nChangeCached;
1900  nChangeCached = pwallet->GetChange(*this);
1901  fChangeCached = true;
1902  return nChangeCached;
1903 }
1904 
1906 {
1907  LOCK(mempool.cs);
1908  return mempool.exists(GetHash());
1909 }
1910 
1912 {
1913  // Quick answer in most cases
1914  if (!CheckFinalTx(*this))
1915  return false;
1916  int nDepth = GetDepthInMainChain();
1917  if (nDepth >= 1)
1918  return true;
1919  if (nDepth < 0)
1920  return false;
1921  if (!bSpendZeroConfChange || !IsFromMe(ISMINE_ALL)) // using wtx's cached debit
1922  return false;
1923 
1924  // Don't trust unconfirmed transactions from us unless they are in the mempool.
1925  if (!InMempool())
1926  return false;
1927 
1928  // Trusted if all inputs are from us and are in the mempool:
1929  for (const CTxIn& txin : tx->vin)
1930  {
1931  // Transactions not sent by us: not trusted
1932  const CWalletTx* parent = pwallet->GetWalletTx(txin.prevout.hash);
1933  if (parent == nullptr)
1934  return false;
1935  const CTxOut& parentOut = parent->tx->vout[txin.prevout.n];
1936  if (pwallet->IsMine(parentOut) != ISMINE_SPENDABLE)
1937  return false;
1938  }
1939  return true;
1940 }
1941 
1942 bool CWalletTx::IsEquivalentTo(const CWalletTx& _tx) const
1943 {
1944  CMutableTransaction tx1 = *this->tx;
1945  CMutableTransaction tx2 = *_tx.tx;
1946  for (auto& txin : tx1.vin) txin.scriptSig = CScript();
1947  for (auto& txin : tx2.vin) txin.scriptSig = CScript();
1948  return CTransaction(tx1) == CTransaction(tx2);
1949 }
1950 
1951 std::vector<uint256> CWallet::ResendWalletTransactionsBefore(int64_t nTime, CConnman* connman)
1952 {
1953  std::vector<uint256> result;
1954 
1955  LOCK(cs_wallet);
1956 
1957  // Sort them in chronological order
1958  std::multimap<unsigned int, CWalletTx*> mapSorted;
1959  for (std::pair<const uint256, CWalletTx>& item : mapWallet)
1960  {
1961  CWalletTx& wtx = item.second;
1962  // Don't rebroadcast if newer than nTime:
1963  if (wtx.nTimeReceived > nTime)
1964  continue;
1965  mapSorted.insert(std::make_pair(wtx.nTimeReceived, &wtx));
1966  }
1967  for (std::pair<const unsigned int, CWalletTx*>& item : mapSorted)
1968  {
1969  CWalletTx& wtx = *item.second;
1970  if (wtx.RelayWalletTransaction(connman))
1971  result.push_back(wtx.GetHash());
1972  }
1973  return result;
1974 }
1975 
1976 void CWallet::ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman)
1977 {
1978  // Do this infrequently and randomly to avoid giving away
1979  // that these are our transactions.
1980  if (GetTime() < nNextResend || !fBroadcastTransactions)
1981  return;
1982  bool fFirst = (nNextResend == 0);
1983  nNextResend = GetTime() + GetRand(30 * 60);
1984  if (fFirst)
1985  return;
1986 
1987  // Only do it if there's been a new block since last time
1988  if (nBestBlockTime < nLastResend)
1989  return;
1990  nLastResend = GetTime();
1991 
1992  // Rebroadcast unconfirmed txes older than 5 minutes before the last
1993  // block was found:
1994  std::vector<uint256> relayed = ResendWalletTransactionsBefore(nBestBlockTime-5*60, connman);
1995  if (!relayed.empty())
1996  LogPrintf("%s: rebroadcast %u unconfirmed transactions\n", __func__, relayed.size());
1997 }
1998  // end of mapWallet
2000 
2001 
2002 
2003 
2011 {
2012  CAmount nTotal = 0;
2013  {
2014  LOCK2(cs_main, cs_wallet);
2015  for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2016  {
2017  const CWalletTx* pcoin = &(*it).second;
2018  if (pcoin->IsTrusted())
2019  nTotal += pcoin->GetAvailableCredit();
2020  }
2021  }
2022 
2023  return nTotal;
2024 }
2025 
2027 {
2028  CAmount nTotal = 0;
2029  {
2030  LOCK2(cs_main, cs_wallet);
2031  for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2032  {
2033  const CWalletTx* pcoin = &(*it).second;
2034  if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 && pcoin->InMempool())
2035  nTotal += pcoin->GetAvailableCredit();
2036  }
2037  }
2038  return nTotal;
2039 }
2040 
2042 {
2043  CAmount nTotal = 0;
2044  {
2045  LOCK2(cs_main, cs_wallet);
2046  for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2047  {
2048  const CWalletTx* pcoin = &(*it).second;
2049  nTotal += pcoin->GetImmatureCredit();
2050  }
2051  }
2052  return nTotal;
2053 }
2054 
2056 {
2057  CAmount nTotal = 0;
2058  {
2059  LOCK2(cs_main, cs_wallet);
2060  for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2061  {
2062  const CWalletTx* pcoin = &(*it).second;
2063  if (pcoin->IsTrusted())
2064  nTotal += pcoin->GetAvailableWatchOnlyCredit();
2065  }
2066  }
2067 
2068  return nTotal;
2069 }
2070 
2072 {
2073  CAmount nTotal = 0;
2074  {
2075  LOCK2(cs_main, cs_wallet);
2076  for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2077  {
2078  const CWalletTx* pcoin = &(*it).second;
2079  if (!pcoin->IsTrusted() && pcoin->GetDepthInMainChain() == 0 && pcoin->InMempool())
2080  nTotal += pcoin->GetAvailableWatchOnlyCredit();
2081  }
2082  }
2083  return nTotal;
2084 }
2085 
2087 {
2088  CAmount nTotal = 0;
2089  {
2090  LOCK2(cs_main, cs_wallet);
2091  for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2092  {
2093  const CWalletTx* pcoin = &(*it).second;
2094  nTotal += pcoin->GetImmatureWatchOnlyCredit();
2095  }
2096  }
2097  return nTotal;
2098 }
2099 
2100 // Calculate total balance in a different way from GetBalance. The biggest
2101 // difference is that GetBalance sums up all unspent TxOuts paying to the
2102 // wallet, while this sums up both spent and unspent TxOuts paying to the
2103 // wallet, and then subtracts the values of TxIns spending from the wallet. This
2104 // also has fewer restrictions on which unconfirmed transactions are considered
2105 // trusted.
2106 CAmount CWallet::GetLegacyBalance(const isminefilter& filter, int minDepth, const std::string* account) const
2107 {
2108  LOCK2(cs_main, cs_wallet);
2109 
2110  CAmount balance = 0;
2111  for (const auto& entry : mapWallet) {
2112  const CWalletTx& wtx = entry.second;
2113  const int depth = wtx.GetDepthInMainChain();
2114  if (depth < 0 || !CheckFinalTx(*wtx.tx) || wtx.GetBlocksToMaturity() > 0) {
2115  continue;
2116  }
2117 
2118  // Loop through tx outputs and add incoming payments. For outgoing txs,
2119  // treat change outputs specially, as part of the amount debited.
2120  CAmount debit = wtx.GetDebit(filter);
2121  const bool outgoing = debit > 0;
2122  for (const CTxOut& out : wtx.tx->vout) {
2123  if (outgoing && IsChange(out)) {
2124  debit -= out.nValue;
2125  } else if (IsMine(out) & filter && depth >= minDepth && (!account || *account == GetAccountName(out.scriptPubKey))) {
2126  balance += out.nValue;
2127  }
2128  }
2129 
2130  // For outgoing txs, subtract amount debited.
2131  if (outgoing && (!account || *account == wtx.strFromAccount)) {
2132  balance -= debit;
2133  }
2134  }
2135 
2136  if (account) {
2137  balance += CWalletDB(*dbw).GetAccountCreditDebit(*account);
2138  }
2139 
2140  return balance;
2141 }
2142 
2144 {
2145  LOCK2(cs_main, cs_wallet);
2146 
2147  CAmount balance = 0;
2148  std::vector<COutput> vCoins;
2149  AvailableCoins(vCoins, true, coinControl);
2150  for (const COutput& out : vCoins) {
2151  if (out.fSpendable) {
2152  balance += out.tx->tx->vout[out.i].nValue;
2153  }
2154  }
2155  return balance;
2156 }
2157 
2158 
2159 void CWallet::AvailableCoins(std::vector<COutput> &vCoins, bool fOnlySafe, const CCoinControl *coinControl, const CAmount &nMinimumAmount, const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount, const uint64_t &nMaximumCount, const int &nMinDepth, const int &nMaxDepth) const
2160 {
2161  std::map<std::string, std::vector<COutput> > mapAssetCoins;
2162  AvailableCoinsAll(vCoins, mapAssetCoins, true, false, fOnlySafe, coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2163 }
2164 
2165 void CWallet::AvailableAssets(std::map<std::string, std::vector<COutput> > &mapAssetCoins, bool fOnlySafe,
2166  const CCoinControl *coinControl, const CAmount &nMinimumAmount,
2167  const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount,
2168  const uint64_t &nMaximumCount, const int &nMinDepth, const int &nMaxDepth) const
2169 {
2170  if (!AreAssetsDeployed())
2171  return;
2172 
2173  std::vector<COutput> vCoins;
2174 
2175  AvailableCoinsAll(vCoins, mapAssetCoins, false, true, fOnlySafe, coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2176 }
2177 
2178 void CWallet::AvailableCoinsWithAssets(std::vector<COutput> &vCoins, std::map<std::string, std::vector<COutput> > &mapAssetCoins,
2179  bool fOnlySafe, const CCoinControl *coinControl, const CAmount &nMinimumAmount,
2180  const CAmount &nMaximumAmount, const CAmount &nMinimumSumAmount,
2181  const uint64_t &nMaximumCount, const int &nMinDepth, const int &nMaxDepth) const
2182 {
2183  AvailableCoinsAll(vCoins, mapAssetCoins, true, AreAssetsDeployed(), fOnlySafe, coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2184 }
2185 
2186 void CWallet::AvailableCoinsAll(std::vector<COutput>& vCoins, std::map<std::string, std::vector<COutput> >& mapAssetCoins, bool fGetRVN, bool fGetAssets, bool fOnlySafe, const CCoinControl *coinControl, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t& nMaximumCount, const int& nMinDepth, const int& nMaxDepth) const {
2187  vCoins.clear();
2188 
2189  {
2190  LOCK2(cs_main, cs_wallet);
2191 
2192  CAmount nTotal = 0;
2193 
2195  bool fRVNLimitHit = false;
2196  // A set of the hashes that have already been used
2197  std::set<uint256> usedMempoolHashes;
2198 
2199  std::map<std::string, CAmount> mapAssetTotals;
2200  std::map<uint256, COutPoint> mapOutPoints;
2201  std::set<std::string> setAssetMaxFound;
2202  // Turn the OutPoints into a map that is easily interatable.
2203  for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) {
2204  const uint256 &wtxid = it->first;
2205  const CWalletTx *pcoin = &(*it).second;
2206 
2207  if (!CheckFinalTx(*pcoin))
2208  continue;
2209 
2210  if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
2211  continue;
2212 
2213  int nDepth = pcoin->GetDepthInMainChain();
2214  if (nDepth < 0)
2215  continue;
2216 
2217  // We should not consider coins which aren't at least in our mempool
2218  // It's possible for these to be conflicted via ancestors which we may never be able to detect
2219  if (nDepth == 0 && !pcoin->InMempool())
2220  continue;
2221 
2222  bool safeTx = pcoin->IsTrusted();
2223 
2224  // We should not consider coins from transactions that are replacing
2225  // other transactions.
2226  //
2227  // Example: There is a transaction A which is replaced by bumpfee
2228  // transaction B. In this case, we want to prevent creation of
2229  // a transaction B' which spends an output of B.
2230  //
2231  // Reason: If transaction A were initially confirmed, transactions B
2232  // and B' would no longer be valid, so the user would have to create
2233  // a new transaction C to replace B'. However, in the case of a
2234  // one-block reorg, transactions B' and C might BOTH be accepted,
2235  // when the user only wanted one of them. Specifically, there could
2236  // be a 1-block reorg away from the chain where transactions A and C
2237  // were accepted to another chain where B, B', and C were all
2238  // accepted.
2239  if (nDepth == 0 && pcoin->mapValue.count("replaces_txid")) {
2240  safeTx = false;
2241  }
2242 
2243  // Similarly, we should not consider coins from transactions that
2244  // have been replaced. In the example above, we would want to prevent
2245  // creation of a transaction A' spending an output of A, because if
2246  // transaction B were initially confirmed, conflicting with A and
2247  // A', we wouldn't want to the user to create a transaction D
2248  // intending to replace A', but potentially resulting in a scenario
2249  // where A, A', and D could all be accepted (instead of just B and
2250  // D, or just A and A' like the user would want).
2251  if (nDepth == 0 && pcoin->mapValue.count("replaced_by_txid")) {
2252  safeTx = false;
2253  }
2254 
2255  if (fOnlySafe && !safeTx) {
2256  continue;
2257  }
2258 
2259  if (nDepth < nMinDepth || nDepth > nMaxDepth)
2260  continue;
2261 
2262  for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++) {
2263 
2264  int nType;
2265  bool fIsOwner;
2266  bool isAssetScript = pcoin->tx->vout[i].scriptPubKey.IsAssetScript(nType, fIsOwner);
2267  if (coinControl && !isAssetScript && coinControl->HasSelected() && !coinControl->fAllowOtherInputs && !coinControl->IsSelected(COutPoint((*it).first, i)))
2268  continue;
2269 
2270  if (coinControl && isAssetScript && coinControl->HasAssetSelected() && !coinControl->fAllowOtherInputs && !coinControl->IsAssetSelected(COutPoint((*it).first, i)))
2271  continue;
2272 
2273  if (IsLockedCoin((*it).first, i))
2274  continue;
2275 
2276  if (IsSpent(wtxid, i))
2277  continue;
2278 
2279  isminetype mine = IsMine(pcoin->tx->vout[i]);
2280 
2281  if (mine == ISMINE_NO) {
2282  continue;
2283  }
2284 
2285  bool fSpendableIn = ((mine & ISMINE_SPENDABLE) != ISMINE_NO) ||
2286  (coinControl && coinControl->fAllowWatchOnly &&
2287  (mine & ISMINE_WATCH_SOLVABLE) != ISMINE_NO);
2288  bool fSolvableIn = (mine & (ISMINE_SPENDABLE | ISMINE_WATCH_SOLVABLE)) != ISMINE_NO;
2289 
2290  std::string address;
2291 
2292  // Looking for Asset Tx OutPoints Only
2293  if (fGetAssets && AreAssetsDeployed() && isAssetScript) {
2294 
2295  CAssetOutputEntry output_data;
2296  if (!GetAssetData(pcoin->tx->vout[i].scriptPubKey, output_data))
2297  continue;
2298 
2299  address = EncodeDestination(output_data.destination);
2300 
2301  // If we already have the maximum amount or size for this asset, skip it
2302  if (setAssetMaxFound.count(output_data.assetName))
2303  continue;
2304 
2305  if (IsAssetNameAnRestricted(output_data.assetName)) {
2306  if (passets->CheckForAddressRestriction(output_data.assetName, address, true)) {
2307  continue;
2308  }
2309  }
2310 
2311  // Initialize the map vector is it doesn't exist yet
2312  if (!mapAssetCoins.count(output_data.assetName)) {
2313  std::vector<COutput> vOutput;
2314  mapAssetCoins.insert(std::make_pair(output_data.assetName, vOutput));
2315  }
2316 
2317  // Add the COutput to the map of available Asset Coins
2318  mapAssetCoins.at(output_data.assetName).push_back(
2319  COutput(pcoin, i, nDepth, fSpendableIn, fSolvableIn, safeTx));
2320 
2321  // Initialize the map of current asset totals
2322  if (!mapAssetTotals.count(output_data.assetName))
2323  mapAssetTotals[output_data.assetName] = 0;
2324 
2325  // Update the map of totals depending the which type of asset tx we are looking at
2326  mapAssetTotals[output_data.assetName] += output_data.nAmount;
2327 
2328  // Checks the sum amount of all UTXO's, and adds to the set of assets that we found the max for
2329  if (nMinimumSumAmount != MAX_MONEY) {
2330  if (mapAssetTotals[output_data.assetName] >= nMinimumSumAmount)
2331  setAssetMaxFound.insert(output_data.assetName);
2332  }
2333 
2334  // Checks the maximum number of UTXO's, and addes to set of of asset that we found the max for
2335  if (nMaximumCount > 0 && mapAssetCoins[output_data.assetName].size() >= nMaximumCount) {
2336  setAssetMaxFound.insert(output_data.assetName);
2337  }
2338  }
2339 
2340  if (fGetRVN) { // Looking for RVN Tx OutPoints Only
2341  if (fRVNLimitHit) // We hit our limit
2342  continue;
2343 
2344  // We only want RVN OutPoints. Don't include Asset OutPoints
2345  if (isAssetScript)
2346  continue;
2347 
2348  vCoins.push_back(COutput(pcoin, i, nDepth, fSpendableIn, fSolvableIn, safeTx));
2349 
2350  // Checks the sum amount of all UTXO's.
2351  if (nMinimumSumAmount != MAX_MONEY) {
2352  nTotal += pcoin->tx->vout[i].nValue;
2353 
2354  if (nTotal >= nMinimumSumAmount) {
2355  fRVNLimitHit = true;
2356  }
2357  }
2358 
2359  // Checks the maximum number of UTXO's.
2360  if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) {
2361  fRVNLimitHit = true;
2362  }
2363  continue;
2364  }
2365  }
2366  }
2368  }
2369 }
2370 
2373 std::map<CTxDestination, std::vector<COutput>> CWallet::ListAssets() const
2374 {
2375  // TODO: Add AssertLockHeld(cs_wallet) here.
2376  //
2377  // Because the return value from this function contains pointers to
2378  // CWalletTx objects, callers to this function really should acquire the
2379  // cs_wallet lock before calling it. However, the current caller doesn't
2380  // acquire this lock yet. There was an attempt to add the missing lock in
2381  // https://github.com/RavenProject/Ravencoin/pull/10340, but that change has been
2382  // postponed until after https://github.com/RavenProject/Ravencoin/pull/10244 to
2383  // avoid adding some extra complexity to the Qt code.
2384 
2385  std::map<CTxDestination, std::vector<COutput>> result;
2386 
2387  std::map<std::string, std::vector<COutput> > mapAssets;
2388  AvailableAssets(mapAssets);
2389 
2390  LOCK2(cs_main, cs_wallet);
2391  for (auto asset : mapAssets) {
2392  for (auto &coin : asset.second) {
2393  CTxDestination address;
2394  if (coin.fSpendable &&
2395  ExtractDestination(FindNonChangeParentOutput(*coin.tx->tx, coin.i).scriptPubKey, address)) {
2396  result[address].emplace_back(std::move(coin));
2397  }
2398  }
2399  }
2400 
2401  std::vector<COutPoint> lockedCoins;
2402  ListLockedCoins(lockedCoins);
2403  for (const auto& output : lockedCoins) {
2404  auto it = mapWallet.find(output.hash);
2405  if (it != mapWallet.end()) {
2406  if (!it->second.tx->vout[output.n].scriptPubKey.IsAssetScript()) // If not an asset script skip it
2407  continue;
2408  int depth = it->second.GetDepthInMainChain();
2409  if (depth >= 0 && output.n < it->second.tx->vout.size() &&
2410  IsMine(it->second.tx->vout[output.n]) == ISMINE_SPENDABLE) {
2411  CTxDestination address;
2412  if (ExtractDestination(FindNonChangeParentOutput(*it->second.tx, output.n).scriptPubKey, address)) {
2413  result[address].emplace_back(
2414  &it->second, output.n, depth, true /* spendable */, true /* solvable */, false /* safe */);
2415  }
2416  }
2417  }
2418  }
2419 
2420  return result;
2421 }
2422 
2425 std::map<CTxDestination, std::vector<COutput>> CWallet::ListCoins() const
2426 {
2427  // TODO: Add AssertLockHeld(cs_wallet) here.
2428  //
2429  // Because the return value from this function contains pointers to
2430  // CWalletTx objects, callers to this function really should acquire the
2431  // cs_wallet lock before calling it. However, the current caller doesn't
2432  // acquire this lock yet. There was an attempt to add the missing lock in
2433  // https://github.com/RavenProject/Ravencoin/pull/10340, but that change has been
2434  // postponed until after https://github.com/RavenProject/Ravencoin/pull/10244 to
2435  // avoid adding some extra complexity to the Qt code.
2436 
2437  std::map<CTxDestination, std::vector<COutput>> result;
2438 
2439  std::vector<COutput> availableCoins;
2440  AvailableCoins(availableCoins);
2441 
2442  LOCK2(cs_main, cs_wallet);
2443  for (auto& coin : availableCoins) {
2444  CTxDestination address;
2445  if (coin.fSpendable &&
2446  ExtractDestination(FindNonChangeParentOutput(*coin.tx->tx, coin.i).scriptPubKey, address)) {
2447  result[address].emplace_back(std::move(coin));
2448  }
2449  }
2450 
2451  std::vector<COutPoint> lockedCoins;
2452  ListLockedCoins(lockedCoins);
2453  for (const auto& output : lockedCoins) {
2454  auto it = mapWallet.find(output.hash);
2455  if (it != mapWallet.end()) {
2456  int depth = it->second.GetDepthInMainChain();
2457  if (depth >= 0 && output.n < it->second.tx->vout.size() &&
2458  IsMine(it->second.tx->vout[output.n]) == ISMINE_SPENDABLE) {
2459  CTxDestination address;
2460  if (ExtractDestination(FindNonChangeParentOutput(*it->second.tx, output.n).scriptPubKey, address)) {
2461  result[address].emplace_back(
2462  &it->second, output.n, depth, true /* spendable */, true /* solvable */, false /* safe */);
2463  }
2464  }
2465  }
2466  }
2467 
2468  return result;
2469 }
2470 
2471 const CTxOut& CWallet::FindNonChangeParentOutput(const CTransaction& tx, int output) const
2472 {
2473  const CTransaction* ptx = &tx;
2474  int n = output;
2475  while (IsChange(ptx->vout[n]) && ptx->vin.size() > 0) {
2476  const COutPoint& prevout = ptx->vin[0].prevout;
2477  auto it = mapWallet.find(prevout.hash);
2478  if (it == mapWallet.end() || it->second.tx->vout.size() <= prevout.n ||
2479  !IsMine(it->second.tx->vout[prevout.n])) {
2480  break;
2481  }
2482  ptx = it->second.tx.get();
2483  n = prevout.n;
2484  }
2485  return ptx->vout[n];
2486 }
2487 
2488 static void ApproximateBestSubset(const std::vector<CInputCoin>& vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
2489  std::vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
2490 {
2491  std::vector<char> vfIncluded;
2492 
2493  vfBest.assign(vValue.size(), true);
2494  nBest = nTotalLower;
2495 
2496  FastRandomContext insecure_rand;
2497 
2498  for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
2499  {
2500  vfIncluded.assign(vValue.size(), false);
2501  CAmount nTotal = 0;
2502  bool fReachedTarget = false;
2503  for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
2504  {
2505  for (unsigned int i = 0; i < vValue.size(); i++)
2506  {
2507  //The solver here uses a randomized algorithm,
2508  //the randomness serves no real security purpose but is just
2509  //needed to prevent degenerate behavior and it is important
2510  //that the rng is fast. We do not use a constant random sequence,
2511  //because there may be some privacy improvement by making
2512  //the selection random.
2513  if (nPass == 0 ? insecure_rand.randbool() : !vfIncluded[i])
2514  {
2515  nTotal += vValue[i].txout.nValue;
2516  vfIncluded[i] = true;
2517  if (nTotal >= nTargetValue)
2518  {
2519  fReachedTarget = true;
2520  if (nTotal < nBest)
2521  {
2522  nBest = nTotal;
2523  vfBest = vfIncluded;
2524  }
2525  nTotal -= vValue[i].txout.nValue;
2526  vfIncluded[i] = false;
2527  }
2528  }
2529  }
2530  }
2531  }
2532 }
2533 
2534 static void ApproximateBestAssetSubset(const std::vector<std::pair<CInputCoin, CAmount> >& vValue, const CAmount& nTotalLower, const CAmount& nTargetValue,
2535  std::vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
2536 {
2537  std::vector<char> vfIncluded;
2538 
2539  vfBest.assign(vValue.size(), true);
2540  nBest = nTotalLower;
2541 
2542  FastRandomContext insecure_rand;
2543 
2544  for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
2545  {
2546  vfIncluded.assign(vValue.size(), false);
2547  CAmount nTotal = 0;
2548  bool fReachedTarget = false;
2549  for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
2550  {
2551  for (unsigned int i = 0; i < vValue.size(); i++)
2552  {
2553  //The solver here uses a randomized algorithm,
2554  //the randomness serves no real security purpose but is just
2555  //needed to prevent degenerate behavior and it is important
2556  //that the rng is fast. We do not use a constant random sequence,
2557  //because there may be some privacy improvement by making
2558  //the selection random.
2559  if (nPass == 0 ? insecure_rand.randbool() : !vfIncluded[i])
2560  {
2561  nTotal += vValue[i].second;
2562  vfIncluded[i] = true;
2563  if (nTotal >= nTargetValue)
2564  {
2565  fReachedTarget = true;
2566  if (nTotal < nBest)
2567  {
2568  nBest = nTotal;
2569  vfBest = vfIncluded;
2570  }
2571  nTotal -= vValue[i].second;
2572  vfIncluded[i] = false;
2573  }
2574  }
2575  }
2576  }
2577  }
2578 }
2579 
2580 bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const int nConfMine, const int nConfTheirs, const uint64_t nMaxAncestors, std::vector<COutput> vCoins,
2581  std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet) const
2582 {
2583  setCoinsRet.clear();
2584  nValueRet = 0;
2585 
2586  // List of values less than target
2587  boost::optional<CInputCoin> coinLowestLarger;
2588  std::vector<CInputCoin> vValue;
2589  CAmount nTotalLower = 0;
2590 
2591  random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
2592 
2593  for (const COutput &output : vCoins)
2594  {
2595  if (!output.fSpendable)
2596  continue;
2597 
2598  const CWalletTx *pcoin = output.tx;
2599 
2600  if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
2601  continue;
2602 
2603  if (!mempool.TransactionWithinChainLimit(pcoin->GetHash(), nMaxAncestors))
2604  continue;
2605 
2606  int i = output.i;
2607 
2608  CInputCoin coin = CInputCoin(pcoin, i);
2609 
2610  if (coin.txout.nValue == nTargetValue)
2611  {
2612  setCoinsRet.insert(coin);
2613  nValueRet += coin.txout.nValue;
2614  return true;
2615  }
2616  else if (coin.txout.nValue < nTargetValue + MIN_CHANGE)
2617  {
2618  vValue.push_back(coin);
2619  nTotalLower += coin.txout.nValue;
2620  }
2621  else if (!coinLowestLarger || coin.txout.nValue < coinLowestLarger->txout.nValue)
2622  {
2623  coinLowestLarger = coin;
2624  }
2625  }
2626 
2627  if (nTotalLower == nTargetValue)
2628  {
2629  for (const auto& input : vValue)
2630  {
2631  setCoinsRet.insert(input);
2632  nValueRet += input.txout.nValue;
2633  }
2634  return true;
2635  }
2636 
2637  if (nTotalLower < nTargetValue)
2638  {
2639  if (!coinLowestLarger)
2640  return false;
2641  setCoinsRet.insert(coinLowestLarger.get());
2642  nValueRet += coinLowestLarger->txout.nValue;
2643  return true;
2644  }
2645 
2646  // Solve subset sum by stochastic approximation
2647  std::sort(vValue.begin(), vValue.end(), CompareValueOnly());
2648  std::reverse(vValue.begin(), vValue.end());
2649  std::vector<char> vfBest;
2650  CAmount nBest;
2651 
2652  ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest);
2653  if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE)
2654  ApproximateBestSubset(vValue, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest);
2655 
2656  // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
2657  // or the next bigger coin is closer), return the bigger coin
2658  if (coinLowestLarger &&
2659  ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || coinLowestLarger->txout.nValue <= nBest))
2660  {
2661  setCoinsRet.insert(coinLowestLarger.get());
2662  nValueRet += coinLowestLarger->txout.nValue;
2663  }
2664  else {
2665  for (unsigned int i = 0; i < vValue.size(); i++)
2666  if (vfBest[i])
2667  {
2668  setCoinsRet.insert(vValue[i]);
2669  nValueRet += vValue[i].txout.nValue;
2670  }
2671 
2672  if (LogAcceptCategory(BCLog::SELECTCOINS)) {
2673  LogPrint(BCLog::SELECTCOINS, "SelectCoins() best subset: ");
2674  for (unsigned int i = 0; i < vValue.size(); i++) {
2675  if (vfBest[i]) {
2676  LogPrint(BCLog::SELECTCOINS, "%s ", FormatMoney(vValue[i].txout.nValue));
2677  }
2678  }
2679  LogPrint(BCLog::SELECTCOINS, "total %s\n", FormatMoney(nBest));
2680  }
2681  }
2682 
2683  return true;
2684 }
2685 
2686 bool CWallet::SelectCoins(const std::vector<COutput>& vAvailableCoins, const CAmount& nTargetValue, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet, const CCoinControl* coinControl) const
2687 {
2688  std::vector<COutput> vCoins(vAvailableCoins);
2689 
2690  // coin control -> return all selected outputs (we want all selected to go into the transaction for sure)
2691  if (coinControl && coinControl->HasSelected() && !coinControl->fAllowOtherInputs)
2692  {
2693  for (const COutput& out : vCoins)
2694  {
2695  if (!out.fSpendable)
2696  continue;
2697  nValueRet += out.tx->tx->vout[out.i].nValue;
2698  setCoinsRet.insert(CInputCoin(out.tx, out.i));
2699  }
2700  return (nValueRet >= nTargetValue);
2701  }
2702 
2703  // calculate value from preset inputs and store them
2704  std::set<CInputCoin> setPresetCoins;
2705  CAmount nValueFromPresetInputs = 0;
2706 
2707  std::vector<COutPoint> vPresetInputs;
2708  if (coinControl)
2709  coinControl->ListSelected(vPresetInputs);
2710  for (const COutPoint& outpoint : vPresetInputs)
2711  {
2712  std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
2713  if (it != mapWallet.end())
2714  {
2715  const CWalletTx* pcoin = &it->second;
2716  // Clearly invalid input, fail
2717  if (pcoin->tx->vout.size() <= outpoint.n)
2718  return false;
2719  nValueFromPresetInputs += pcoin->tx->vout[outpoint.n].nValue;
2720  setPresetCoins.insert(CInputCoin(pcoin, outpoint.n));
2721  }
2722  // Allow non-wallet inputs
2723  }
2724 
2725  // remove preset inputs from vCoins
2726  for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->HasSelected();)
2727  {
2728  if (setPresetCoins.count(CInputCoin(it->tx, it->i)))
2729  it = vCoins.erase(it);
2730  else
2731  ++it;
2732  }
2733 
2734  size_t nMaxChainLength = std::min(gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT), gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT));
2735  bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS);
2736 
2737  bool res = nTargetValue <= nValueFromPresetInputs ||
2738  SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 6, 0, vCoins, setCoinsRet, nValueRet) ||
2739  SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 1, 1, 0, vCoins, setCoinsRet, nValueRet) ||
2740  (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, 2, vCoins, setCoinsRet, nValueRet)) ||
2741  (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, std::min((size_t)4, nMaxChainLength/3), vCoins, setCoinsRet, nValueRet)) ||
2742  (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength/2, vCoins, setCoinsRet, nValueRet)) ||
2743  (bSpendZeroConfChange && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength, vCoins, setCoinsRet, nValueRet)) ||
2744  (bSpendZeroConfChange && !fRejectLongChains && SelectCoinsMinConf(nTargetValue - nValueFromPresetInputs, 0, 1, std::numeric_limits<uint64_t>::max(), vCoins, setCoinsRet, nValueRet));
2745 
2746  // because SelectCoinsMinConf clears the setCoinsRet, we now add the possible inputs to the coinset
2747  setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
2748 
2749  // add preset inputs to the total value selected
2750  nValueRet += nValueFromPresetInputs;
2751 
2752  return res;
2753 }
2754 
2756 bool CWallet::CreateNewChangeAddress(CReserveKey& reservekey, CKeyID& keyID, std::string& strFailReason)
2757 {
2758  // Called with coin control doesn't have a change_address
2759  // no coin control: send change to newly generated address
2760  // Note: We use a new key here to keep it from being obvious which side is the change.
2761  // The drawback is that by not reusing a previous key, the change may be lost if a
2762  // backup is restored, if the backup doesn't have the new private key for the change.
2763  // If we reused the old key, it would be possible to add code to look for and
2764  // rediscover unknown transactions that were written with keys of ours to recover
2765  // post-backup change.
2766 
2767  // Reserve a new key pair from key pool
2768  CPubKey vchPubKey;
2769  bool ret;
2770  ret = reservekey.GetReservedKey(vchPubKey, true);
2771  if (!ret)
2772  {
2773  strFailReason = _("Keypool ran out, please call keypoolrefill first");
2774  return false;
2775  }
2776 
2777  keyID = vchPubKey.GetID();
2778  return true;
2779 }
2780 
2781 bool CWallet::SelectAssetsMinConf(const CAmount& nTargetValue, const int nConfMine, const int nConfTheirs, const uint64_t nMaxAncestors, const std::string& strAssetName, std::vector<COutput> vCoins,
2782  std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet) const
2783 {
2784  setCoinsRet.clear();
2785  nValueRet = 0;
2786 
2787  // List of values less than target
2788  boost::optional<CInputCoin> coinLowestLarger;
2789  boost::optional<CAmount> coinLowestLargerAmount;
2790  std::vector<std::pair<CInputCoin, CAmount> > vValue;
2791  std::map<COutPoint, CAmount> mapValueAmount;
2792  CAmount nTotalLower = 0;
2793 
2794  random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt);
2795 
2796  for (const COutput &output : vCoins)
2797  {
2798  if (!output.fSpendable)
2799  continue;
2800 
2801  const CWalletTx *pcoin = output.tx;
2802 
2803  if (output.nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? nConfMine : nConfTheirs))
2804  continue;
2805 
2806  if (!mempool.TransactionWithinChainLimit(pcoin->GetHash(), nMaxAncestors))
2807  continue;
2808 
2809  int i = output.i;
2810 
2811  CInputCoin coin = CInputCoin(pcoin, i);
2812 
2813  //-------------------------------
2814 
2815  int nType = -1;
2816  bool fIsOwner = false;
2817  if (!coin.txout.scriptPubKey.IsAssetScript(nType, fIsOwner)) {
2818  // TODO - Remove std::cout this before mainnet release
2819  std::cout << "This shouldn't be occuring: Non Asset Script pub key made it to the SelectAssetsMinConf function call. Look into this!" << std::endl;
2820  continue;
2821  }
2822 
2823  CAmount nTempAmount = 0;
2824  if (nType == TX_NEW_ASSET && !fIsOwner) { // Root/Sub Asset
2825  CNewAsset assetTemp;
2826  std::string address;
2827  if (!AssetFromScript(coin.txout.scriptPubKey, assetTemp, address))
2828  continue;
2829  nTempAmount = assetTemp.nAmount;
2830  } else if (nType == TX_TRANSFER_ASSET) { // Transfer Asset
2831  CAssetTransfer transferTemp;
2832  std::string address;
2833  if (!TransferAssetFromScript(coin.txout.scriptPubKey, transferTemp, address))
2834  continue;
2835  nTempAmount = transferTemp.nAmount;
2836  } else if (nType == TX_NEW_ASSET && fIsOwner) { // Owner Asset
2837  std::string ownerName;
2838  std::string address;
2839  if (!OwnerAssetFromScript(coin.txout.scriptPubKey, ownerName, address))
2840  continue;
2841  nTempAmount = OWNER_ASSET_AMOUNT;
2842  } else if (nType == TX_REISSUE_ASSET) { // Reissue Asset
2843  CReissueAsset reissueTemp;
2844  std::string address;
2845  if (!ReissueAssetFromScript(coin.txout.scriptPubKey, reissueTemp, address))
2846  continue;
2847  nTempAmount = reissueTemp.nAmount;
2848  } else {
2849  continue;
2850  }
2851 
2852  if (nTempAmount == nTargetValue)
2853  {
2854  setCoinsRet.insert(coin);
2855  nValueRet += nTempAmount;
2856  return true;
2857  }
2858  else if (nTempAmount < nTargetValue + MIN_CHANGE)
2859  {
2860  vValue.push_back(std::make_pair(coin, nTempAmount));
2861  nTotalLower += nTempAmount;
2862  }
2863  else if (!coinLowestLarger || !coinLowestLargerAmount || nTempAmount < coinLowestLargerAmount)
2864  {
2865  coinLowestLarger = coin;
2866  coinLowestLargerAmount = nTempAmount;
2867  }
2868  }
2869 
2870  if (nTotalLower == nTargetValue)
2871  {
2872  for (const auto& pair : vValue)
2873  {
2874  setCoinsRet.insert(pair.first);
2875  nValueRet += pair.second;
2876  }
2877  return true;
2878  }
2879 
2880  if (nTotalLower < nTargetValue)
2881  {
2882  if (!coinLowestLarger || !coinLowestLargerAmount)
2883  return false;
2884  setCoinsRet.insert(coinLowestLarger.get());
2885  nValueRet += coinLowestLargerAmount.get();
2886  return true;
2887  }
2888 
2889  // Solve subset sum by stochastic approximation
2890  std::sort(vValue.begin(), vValue.end(), CompareAssetValueOnly());
2891  std::reverse(vValue.begin(), vValue.end());
2892  std::vector<char> vfBest;
2893  CAmount nBest;
2894 
2895  ApproximateBestAssetSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest);
2896  if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE)
2897  ApproximateBestAssetSubset(vValue, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest);
2898 
2899  // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
2900  // or the next bigger coin is closer), return the bigger coin
2901  if (coinLowestLarger && coinLowestLargerAmount &&
2902  ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || coinLowestLargerAmount <= nBest))
2903  {
2904  setCoinsRet.insert(coinLowestLarger.get());
2905  nValueRet += coinLowestLargerAmount.get();
2906  }
2907  else {
2908  for (unsigned int i = 0; i < vValue.size(); i++)
2909  if (vfBest[i])
2910  {
2911  setCoinsRet.insert(vValue[i].first);
2912  nValueRet += vValue[i].second;
2913  }
2914 
2915  if (LogAcceptCategory(BCLog::SELECTCOINS)) {
2916  LogPrint(BCLog::SELECTCOINS, "SelectAssets() best subset: ");
2917  for (unsigned int i = 0; i < vValue.size(); i++) {
2918  if (vfBest[i]) {
2919  LogPrint(BCLog::SELECTCOINS, "%s : %s", strAssetName, FormatMoney(vValue[i].second));
2920  }
2921  }
2922  LogPrint(BCLog::SELECTCOINS, "total %s : %s\n", strAssetName, FormatMoney(nBest));
2923  }
2924  }
2925 
2926  return true;
2927 }
2928 
2929 
2930 bool CWallet::SelectAssets(const std::map<std::string, std::vector<COutput> >& mapAvailableAssets, const std::map<std::string, CAmount>& mapAssetTargetValue, std::set<CInputCoin>& setCoinsRet, std::map<std::string, CAmount>& mapValueRet) const
2931 {
2932  if (!AreAssetsDeployed())
2933  return false;
2934 
2935  size_t nMaxChainLength = std::min(gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT), gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT));
2936  bool fRejectLongChains = gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS);
2937 
2938  for (auto assetVector : mapAvailableAssets) {
2939  // Setup temporay variables
2940  std::vector<COutput> vAssets(assetVector.second);
2941 
2942  std::set<CInputCoin> tempCoinsRet;
2943  CAmount nTempAmountRet;
2944  CAmount nTempTargetValue;
2945  std::string strAssetName = assetVector.first;
2946 
2947  CAmount nValueFromPresetInputs = 0; // This is used with coincontrol, which assets doesn't support yet
2948 
2949  // If we dont have a target value for this asset, don't select coins for it
2950  if (!mapAssetTargetValue.count(strAssetName))
2951  continue;
2952 
2953  // If we dont have a target value greater than zero, don't select coins for it
2954  if (mapAssetTargetValue.at(strAssetName) <= 0)
2955  continue;
2956 
2957  // Add the starting value into the mapValueRet
2958  if (!mapValueRet.count(strAssetName))
2959  mapValueRet.insert(std::make_pair(strAssetName, 0));
2960 
2961  // assign our temporary variable
2962  nTempAmountRet = mapValueRet.at(strAssetName);
2963  nTempTargetValue = mapAssetTargetValue.at(strAssetName);
2964 
2965  bool res = nTempTargetValue <= nValueFromPresetInputs ||
2966  SelectAssetsMinConf(nTempTargetValue - nValueFromPresetInputs, 1, 6, 0, strAssetName, vAssets, tempCoinsRet, nTempAmountRet) ||
2967  SelectAssetsMinConf(nTempTargetValue - nValueFromPresetInputs, 1, 1, 0, strAssetName, vAssets, tempCoinsRet, nTempAmountRet) ||
2968  (bSpendZeroConfChange && SelectAssetsMinConf(nTempTargetValue - nValueFromPresetInputs, 0, 1, 2, strAssetName, vAssets, tempCoinsRet, nTempAmountRet)) ||
2969  (bSpendZeroConfChange && SelectAssetsMinConf(nTempTargetValue - nValueFromPresetInputs, 0, 1, std::min((size_t)4, nMaxChainLength/3), strAssetName, vAssets, tempCoinsRet, nTempAmountRet)) ||
2970  (bSpendZeroConfChange && SelectAssetsMinConf(nTempTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength/2, strAssetName, vAssets, tempCoinsRet, nTempAmountRet)) ||
2971  (bSpendZeroConfChange && SelectAssetsMinConf(nTempTargetValue - nValueFromPresetInputs, 0, 1, nMaxChainLength, strAssetName, vAssets, tempCoinsRet, nTempAmountRet)) ||
2972  (bSpendZeroConfChange && !fRejectLongChains && SelectAssetsMinConf(nTempTargetValue - nValueFromPresetInputs, 0, 1, std::numeric_limits<uint64_t>::max(), strAssetName, vAssets, tempCoinsRet, nTempAmountRet));
2973 
2974  if (res) {
2975  setCoinsRet.insert(tempCoinsRet.begin(), tempCoinsRet.end());
2976  mapValueRet.at(strAssetName) = nTempAmountRet + nValueFromPresetInputs;
2977  } else {
2978  return false;
2979  }
2980  }
2981 
2982  return true;
2983 }
2984 
2988 {
2989  AssertLockHeld(cs_wallet); // mapWallet
2990 
2991  // sign the new tx
2992  CTransaction txNewConst(tx);
2993  int nIn = 0;
2994  for (const auto& input : tx.vin) {
2995  std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(input.prevout.hash);
2996  if(mi == mapWallet.end() || input.prevout.n >= mi->second.tx->vout.size()) {
2997  return false;
2998  }
2999  const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
3000  const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
3001  SignatureData sigdata;
3002  if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, amount, SIGHASH_ALL), scriptPubKey, sigdata)) {
3003  return false;
3004  }
3005  UpdateTransaction(tx, nIn, sigdata);
3006  nIn++;
3007  }
3008  return true;
3009 }
3010 
3011 bool CWallet::FundTransaction(CMutableTransaction& tx, CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason, bool lockUnspents, const std::set<int>& setSubtractFeeFromOutputs, CCoinControl coinControl)
3012 {
3013  std::vector<CRecipient> vecSend;
3014 
3015  // Turn the txout set into a CRecipient vector
3016  for (size_t idx = 0; idx < tx.vout.size(); idx++)
3017  {
3018  const CTxOut& txOut = tx.vout[idx];
3019  CRecipient recipient = {txOut.scriptPubKey, txOut.nValue, setSubtractFeeFromOutputs.count(idx) == 1};
3020  vecSend.push_back(recipient);
3021  }
3022 
3023  coinControl.fAllowOtherInputs = true;
3024 
3025  for (const CTxIn& txin : tx.vin)
3026  coinControl.Select(txin.prevout);
3027 
3028  CReserveKey reservekey(this);
3029  CWalletTx wtx;
3030  if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl, false)) {
3031  return false;
3032  }
3033 
3034  if (nChangePosInOut != -1) {
3035  tx.vout.insert(tx.vout.begin() + nChangePosInOut, wtx.tx->vout[nChangePosInOut]);
3036  // we don't have the normal Create/Commit cycle, and don't want to risk reusing change,
3037  // so just remove the key from the keypool here.
3038  reservekey.KeepKey();
3039  }
3040 
3041  // Copy output sizes from new transaction; they may have had the fee subtracted from them
3042  for (unsigned int idx = 0; idx < tx.vout.size(); idx++)
3043  tx.vout[idx].nValue = wtx.tx->vout[idx].nValue;
3044 
3045  // Add new txins (keeping original txin scriptSig/order)
3046  for (const CTxIn& txin : wtx.tx->vin)
3047  {
3048  if (!coinControl.IsSelected(txin.prevout))
3049  {
3050  tx.vin.push_back(txin);
3051 
3052  if (lockUnspents)
3053  {
3054  LOCK2(cs_main, cs_wallet);
3055  LockCoin(txin.prevout);
3056  }
3057  }
3058  }
3059 
3060 
3061  return true;
3062 }
3063 
3064 bool CWallet::CreateTransactionWithAssets(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
3065  std::string& strFailReason, const CCoinControl& coin_control, const std::vector<CNewAsset> assets, const CTxDestination destination, const AssetType& type, bool sign)
3066 {
3067  CReissueAsset reissueAsset;
3068  return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control, true, assets, destination, false, false, reissueAsset, type, sign);
3069 }
3070 
3071 bool CWallet::CreateTransactionWithTransferAsset(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
3072  std::string& strFailReason, const CCoinControl& coin_control, bool sign)
3073 {
3074  CNewAsset asset;
3075  CReissueAsset reissueAsset;
3076  CTxDestination destination;
3077  AssetType assetType = AssetType::INVALID;
3078  return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control, false, asset, destination, true, false, reissueAsset, assetType, sign);
3079 }
3080 
3081 bool CWallet::CreateTransactionWithReissueAsset(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
3082  std::string& strFailReason, const CCoinControl& coin_control, const CReissueAsset& reissueAsset, const CTxDestination destination, bool sign)
3083 {
3084  CNewAsset asset;
3085  AssetType assetType = AssetType::REISSUE;
3086  return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control, false, asset, destination, false, true, reissueAsset, assetType, sign);
3087 }
3088 
3089 bool CWallet::CreateTransaction(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey, CAmount& nFeeRet, int& nChangePosInOut,
3090  std::string& strFailReason, const CCoinControl& coin_control, bool sign)
3091 {
3092 
3093  CNewAsset asset;
3094  CReissueAsset reissueAsset;
3095  CTxDestination destination;
3096  AssetType assetType = AssetType::INVALID;
3097  return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control, false, asset, destination, false, false, reissueAsset, assetType, sign);
3098 }
3099 
3100 bool CWallet::CreateTransactionAll(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey,
3101  CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason,
3102  const CCoinControl& coin_control, bool fNewAsset, const CNewAsset& asset,
3103  const CTxDestination destination, bool fTransferAsset, bool fReissueAsset,
3104  const CReissueAsset& reissueAsset, const AssetType& assetType, bool sign)
3105 {
3106  std::vector<CNewAsset> assets;
3107  assets.push_back(asset);
3108  return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control,
3109  fNewAsset, assets, destination, fTransferAsset, fReissueAsset, reissueAsset, assetType,
3110  sign);
3111 }
3112 
3113 bool CWallet::CreateTransactionAll(const std::vector<CRecipient>& vecSend, CWalletTx& wtxNew, CReserveKey& reservekey,
3114  CAmount& nFeeRet, int& nChangePosInOut, std::string& strFailReason,
3115  const CCoinControl& coin_control, bool fNewAsset,
3116  const std::vector<CNewAsset> assets, const CTxDestination destination,
3117  bool fTransferAsset, bool fReissueAsset, const CReissueAsset& reissueAsset,
3118  const AssetType& assetType, bool sign)
3119 {
3121  if (!AreAssetsDeployed() && (fTransferAsset || fNewAsset || fReissueAsset))
3122  return false;
3123 
3124  if (fNewAsset && (assets.size() < 1 || !IsValidDestination(destination)))
3125  return error("%s : Tried creating a new asset transaction and the asset was null or the destination was invalid", __func__);
3126 
3127  if ((fNewAsset && fTransferAsset) || (fReissueAsset && fTransferAsset) || (fReissueAsset && fNewAsset))
3128  return error("%s : Only one type of asset transaction allowed per transaction");
3129 
3130  if (fReissueAsset && (reissueAsset.IsNull() || !IsValidDestination(destination)))
3131  return error("%s : Tried reissuing an asset and the reissue data was null or the destination was invalid", __func__);
3134  CAmount nValue = 0;
3135  std::map<std::string, CAmount> mapAssetValue;
3136  int nChangePosRequest = nChangePosInOut;
3137  unsigned int nSubtractFeeFromAmount = 0;
3138  for (const auto& recipient : vecSend)
3139  {
3141  if (fTransferAsset || fReissueAsset || assetType == AssetType::SUB || assetType == AssetType::UNIQUE || assetType == AssetType::MSGCHANNEL || assetType == AssetType::SUB_QUALIFIER || assetType == AssetType::RESTRICTED) {
3142  CAssetTransfer assetTransfer;
3143  std::string address;
3144  if (TransferAssetFromScript(recipient.scriptPubKey, assetTransfer, address)) {
3145  if (!mapAssetValue.count(assetTransfer.strName))
3146  mapAssetValue[assetTransfer.strName] = 0;
3147 
3148  if (assetTransfer.nAmount <= 0) {
3149  strFailReason = _("Asset Transfer amounts must be greater than 0");
3150  return false;
3151  }
3152 
3153  mapAssetValue[assetTransfer.strName] += assetTransfer.nAmount;
3154  }
3155  }
3158  if (nValue < 0 || recipient.nAmount < 0)
3159  {
3160  strFailReason = _("Transaction amounts must not be negative");
3161  return false;
3162  }
3163  nValue += recipient.nAmount;
3164 
3165  if (recipient.fSubtractFeeFromAmount)
3166  nSubtractFeeFromAmount++;
3167  }
3168  if (vecSend.empty())
3169  {
3170  strFailReason = _("Transaction must have at least one recipient");
3171  return false;
3172  }
3173 
3174  wtxNew.fTimeReceivedIsTxTime = true;
3175  wtxNew.BindWallet(this);
3176  CMutableTransaction txNew;
3177 
3178  // Discourage fee sniping.
3179  //
3180  // For a large miner the value of the transactions in the best block and
3181  // the mempool can exceed the cost of deliberately attempting to mine two
3182  // blocks to orphan the current best block. By setting nLockTime such that
3183  // only the next block can include the transaction, we discourage this
3184  // practice as the height restricted and limited blocksize gives miners
3185  // considering fee sniping fewer options for pulling off this attack.
3186  //
3187  // A simple way to think about this is from the wallet's point of view we
3188  // always want the blockchain to move forward. By setting nLockTime this
3189  // way we're basically making the statement that we only want this
3190  // transaction to appear in the next block; we don't want to potentially
3191  // encourage reorgs by allowing transactions to appear at lower heights
3192  // than the next block in forks of the best chain.
3193  //
3194  // Of course, the subsidy is high enough, and transaction volume low
3195  // enough, that fee sniping isn't a problem yet, but by implementing a fix
3196  // now we ensure code won't be written that makes assumptions about
3197  // nLockTime that preclude a fix later.
3198  txNew.nLockTime = chainActive.Height();
3199 
3200  // Secondly occasionally randomly pick a nLockTime even further back, so
3201  // that transactions that are delayed after signing for whatever reason,
3202  // e.g. high-latency mix networks and some CoinJoin implementations, have
3203  // better privacy.
3204  if (GetRandInt(10) == 0)
3205  txNew.nLockTime = std::max(0, (int)txNew.nLockTime - GetRandInt(100));
3206 
3207  assert(txNew.nLockTime <= (unsigned int)chainActive.Height());
3208  assert(txNew.nLockTime < LOCKTIME_THRESHOLD);
3209  FeeCalculation feeCalc;
3210  CAmount nFeeNeeded;
3211  unsigned int nBytes;
3212  {
3213  std::set<CInputCoin> setCoins;
3214 
3215  std::set<CInputCoin> setAssets;
3216  LOCK2(cs_main, cs_wallet);
3217  {
3219  std::vector<COutput> vAvailableCoins;
3220  std::map<std::string, std::vector<COutput> > mapAssetCoins;
3221  if (fTransferAsset || fReissueAsset || assetType == AssetType::SUB || assetType == AssetType::UNIQUE || assetType == AssetType::MSGCHANNEL || assetType == AssetType::SUB_QUALIFIER || assetType == AssetType::RESTRICTED)
3222  AvailableCoinsWithAssets(vAvailableCoins, mapAssetCoins, true, &coin_control);
3223  else
3224  AvailableCoins(vAvailableCoins, true, &coin_control);
3226  // Create change script that will be used if we need change
3227  // TODO: pass in scriptChange instead of reservekey so
3228  // change transaction isn't always pay-to-raven-address
3229  CScript scriptChange;
3230 
3231  // coin control: send change to custom address
3232  if (!boost::get<CNoDestination>(&coin_control.destChange)) {
3233  scriptChange = GetScriptForDestination(coin_control.destChange);
3234  } else {
3235 
3236  // no coin control: send change to newly generated address
3237  CKeyID keyID;
3238  if (!CreateNewChangeAddress(reservekey, keyID, strFailReason))
3239  return false;
3240 
3241  scriptChange = GetScriptForDestination(keyID);
3242  }
3243 
3244  CTxOut change_prototype_txout(0, scriptChange);
3245  size_t change_prototype_size = GetSerializeSize(change_prototype_txout, SER_DISK, 0);
3246 
3247  CFeeRate discard_rate = GetDiscardRate(::feeEstimator);
3248  nFeeRet = 0;
3249  bool pick_new_inputs = true;
3250  CAmount nValueIn = 0;
3251 
3252  // Start with no fee and loop until there is enough fee
3253  while (true)
3254  {
3255  std::map<std::string, CAmount> mapAssetsIn;
3256  nChangePosInOut = nChangePosRequest;
3257  txNew.vin.clear();
3258  txNew.vout.clear();
3259  wtxNew.fFromMe = true;
3260  bool fFirst = true;
3261 
3262  CAmount nValueToSelect = nValue;
3263 
3264  if (nSubtractFeeFromAmount == 0)
3265  nValueToSelect += nFeeRet;
3266 
3267  // vouts to the payees
3268  for (const auto& recipient : vecSend)
3269  {
3270  CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
3271 
3273  // Check to see if you need to make an asset data outpoint OP_RVN_ASSET data
3274  if (recipient.scriptPubKey.IsNullAssetTxDataScript()) {
3275  assert(txout.nValue == 0);
3276  txNew.vout.push_back(txout);
3277  continue;
3278  }
3281  if (recipient.fSubtractFeeFromAmount)
3282  {
3283  assert(nSubtractFeeFromAmount != 0);
3284  txout.nValue -= nFeeRet / nSubtractFeeFromAmount; // Subtract fee equally from each selected recipient
3285 
3286  if (fFirst) // first receiver pays the remainder not divisible by output count
3287  {
3288  fFirst = false;
3289  txout.nValue -= nFeeRet % nSubtractFeeFromAmount;
3290  }
3291  }
3292 
3293  if (IsDust(txout, ::dustRelayFee) && !IsScriptTransferAsset(recipient.scriptPubKey))
3294  {
3295  if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
3296  {
3297  if (txout.nValue < 0)
3298  strFailReason = _("The transaction amount is too small to pay the fee");
3299  else
3300  strFailReason = _("The transaction amount is too small to send after the fee has been deducted");
3301  }
3302  else {
3303  strFailReason = _("Transaction amount too small");
3304  }
3305  return false;
3306  }
3307 
3308  txNew.vout.push_back(txout);
3309  }
3310 
3311  // Choose coins to use
3312  if (pick_new_inputs) {
3313  nValueIn = 0;
3314  setCoins.clear();
3315  if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, &coin_control))
3316  {
3317  strFailReason = _("Insufficient funds");
3318  return false;
3319  }
3320 
3322  if (AreAssetsDeployed()) {
3323  setAssets.clear();
3324  mapAssetsIn.clear();
3325  if (!SelectAssets(mapAssetCoins, mapAssetValue, setAssets, mapAssetsIn)) {
3326  strFailReason = _("Insufficient asset funds");
3327  return false;
3328  }
3329  }
3331  }
3332 
3333  const CAmount nChange = nValueIn - nValueToSelect;
3334 
3336  if (AreAssetsDeployed()) {
3337  // Add the change for the assets
3338  std::map<std::string, CAmount> mapAssetChange;
3339  for (auto asset : mapAssetValue) {
3340  if (mapAssetsIn.count(asset.first))
3341  mapAssetChange.insert(
3342  std::make_pair(asset.first, (mapAssetsIn.at(asset.first) - asset.second)));
3343  }
3344 
3345  for (auto assetChange : mapAssetChange) {
3346  if (assetChange.second > 0) {
3347  if (IsAssetNameAnRestricted(assetChange.first))
3348  {
3349  // Get the verifier string for the restricted asset
3350  CNullAssetTxVerifierString verifier;
3351  if (!passets->GetAssetVerifierStringIfExists(assetChange.first, verifier)) {
3352  strFailReason = _("Verifier String for asset trasnfer, not found");
3353  return false;
3354  }
3355 
3356  // Get the change address
3357  CTxDestination dest;
3358  if (!ExtractDestination(scriptChange, dest)) {
3359  strFailReason = _("Failed to extract destination from change script");
3360  return false;
3361  }
3362 
3363  std::string change_address = EncodeDestination(dest);
3364  bool fFoundValueChangeAddress = false;
3365  // Check the verifier string against the change address, if it fails, we will try to send the change back to the same input that created this transaction
3366  if (!ContextualCheckVerifierString(passets, verifier.verifier_string, change_address, strFailReason)) {
3367  // Loop through all assets that are inputs into the transaction
3368  for (auto asset: setAssets) {
3369  if (asset.txout.scriptPubKey.IsAssetScript()) {
3370  CAssetOutputEntry outputData;
3371  if (!GetAssetData(asset.txout.scriptPubKey, outputData)) {
3372  strFailReason = _("Failed to get asset data from script");
3373  return false;
3374  }
3375 
3376  // If the asset names don't match, continue through the set of assets
3377  if (outputData.assetName != assetChange.first)
3378  continue;
3379 
3380  std::string check_address = EncodeDestination(outputData.destination);
3381 
3382  if (ContextualCheckVerifierString(passets, verifier.verifier_string, check_address, strFailReason)) {
3383  fFoundValueChangeAddress = true;
3384 
3385  CScript scriptAssetChange = GetScriptForDestination(outputData.destination);
3386  CAssetTransfer assetTransfer(assetChange.first, assetChange.second);
3387 
3388  assetTransfer.ConstructTransaction(scriptAssetChange);
3389  CTxOut newAssetTxOut(0, scriptAssetChange);
3390 
3391  txNew.vout.emplace_back(newAssetTxOut);
3392  break;
3393  }
3394  }
3395  }
3396  } else {
3397  fFoundValueChangeAddress = true;
3398  CScript scriptAssetChange = scriptChange;
3399  CAssetTransfer assetTransfer(assetChange.first, assetChange.second);
3400 
3401  assetTransfer.ConstructTransaction(scriptAssetChange);
3402  CTxOut newAssetTxOut(0, scriptAssetChange);
3403 
3404  txNew.vout.emplace_back(newAssetTxOut);
3405  }
3406  if (!fFoundValueChangeAddress) {
3407  strFailReason = _("Failed to find restricted asset change address from inputs");
3408  return false;
3409  }
3410  } else {
3411  CScript scriptAssetChange = scriptChange;
3412  CAssetTransfer assetTransfer(assetChange.first, assetChange.second);
3413 
3414  assetTransfer.ConstructTransaction(scriptAssetChange);
3415  CTxOut newAssetTxOut(0, scriptAssetChange);
3416 
3417  txNew.vout.emplace_back(newAssetTxOut);
3418  }
3419  }
3420  }
3421  }
3424  if (nChange > 0)
3425  {
3426  // Fill a vout to ourself
3427  CTxOut newTxOut(nChange, scriptChange);
3428 
3429  // Never create dust outputs; if we would, just
3430  // add the dust to the fee.
3431  if (IsDust(newTxOut, discard_rate))
3432  {
3433  nChangePosInOut = -1;
3434  nFeeRet += nChange;
3435  }
3436  else
3437  {
3438  if (nChangePosInOut == -1)
3439  {
3440  // Insert change txn at random position:
3441  nChangePosInOut = GetRandInt(txNew.vout.size()+1);
3442  }
3443  else if ((unsigned int)nChangePosInOut > txNew.vout.size())
3444  {
3445  strFailReason = _("Change index out of range");
3446  return false;
3447  }
3448 
3449  std::vector<CTxOut>::iterator position = txNew.vout.begin()+nChangePosInOut;
3450  txNew.vout.insert(position, newTxOut);
3451  }
3452  } else {
3453  nChangePosInOut = -1;
3454  }
3455 
3457  if (AreAssetsDeployed()) {
3458  if (fNewAsset) {
3459  for (auto asset : assets) {
3460  // Create the owner token output for non-unique assets
3461  if (assetType != AssetType::UNIQUE && assetType != AssetType::MSGCHANNEL && assetType != AssetType::QUALIFIER && assetType != AssetType::SUB_QUALIFIER && assetType != AssetType::RESTRICTED) {
3462  CScript ownerScript = GetScriptForDestination(destination);
3463  asset.ConstructOwnerTransaction(ownerScript);
3464  CTxOut ownerTxOut(0, ownerScript);
3465  txNew.vout.push_back(ownerTxOut);
3466  }
3467 
3468  // Create the asset transaction and push it back so it is the last CTxOut in the transaction
3469  CScript scriptPubKey = GetScriptForDestination(destination);
3470  asset.ConstructTransaction(scriptPubKey);
3471  CTxOut newTxOut(0, scriptPubKey);
3472  txNew.vout.push_back(newTxOut);
3473  }
3474  } else if (fReissueAsset) {
3475  // Create the asset transaction and push it back so it is the last CTxOut in the transaction
3476  CScript reissueScript = GetScriptForDestination(destination);
3477 
3478  // Create the scriptPubKeys for the reissue data, and that owner asset
3479  reissueAsset.ConstructTransaction(reissueScript);
3480 
3481  CTxOut reissueTxOut(0, reissueScript);
3482  txNew.vout.push_back(reissueTxOut);
3483  }
3484  }
3487  // Fill vin
3488  //
3489  // Note how the sequence number is set to non-maxint so that
3490  // the nLockTime set above actually works.
3491  //
3492  // BIP125 defines opt-in RBF as any nSequence < maxint-1, so
3493  // we use the highest possible value in that range (maxint-2)
3494  // to avoid conflicting with other possible uses of nSequence,
3495  // and in the spirit of "smallest possible change from prior
3496  // behavior."
3497 // const uint32_t nSequence = coin_control.signalRbf ? MAX_BIP125_RBF_SEQUENCE : (CTxIn::SEQUENCE_FINAL - 1);
3498  const uint32_t nSequence = CTxIn::SEQUENCE_FINAL - 1;
3499  for (const auto& coin : setCoins)
3500  txNew.vin.push_back(CTxIn(coin.outpoint,CScript(),
3501  nSequence));
3502 
3504  if (AreAssetsDeployed()) {
3505  for (const auto &asset : setAssets)
3506  txNew.vin.push_back(CTxIn(asset.outpoint, CScript(),
3507  nSequence));
3508  }
3511  // Add the new asset inputs into the tempSet so the dummysigntx will add the correct amount of sigsß
3512  std::set<CInputCoin> tempSet = setCoins;
3513  tempSet.insert(setAssets.begin(), setAssets.end());
3514 
3515  // Fill in dummy signatures for fee calculation.
3516  DummySignTx(txNew, tempSet);
3517 
3518  nBytes = GetVirtualTransactionSize(txNew);
3519 
3520  // Remove scriptSigs to eliminate the fee calculation dummy signatures
3521  for (auto& vin : txNew.vin) {
3522  vin.scriptSig = CScript();
3523  vin.scriptWitness.SetNull();
3524  }
3525 
3526  nFeeNeeded = GetMinimumFee(nBytes, coin_control, ::mempool, ::feeEstimator, &feeCalc);
3527 
3528  // If we made it here and we aren't even able to meet the relay fee on the next pass, give up
3529  // because we must be at the maximum allowed fee.
3530  if (nFeeNeeded < (AreMessagingDeployed() ? ::minRelayTxFeeV2.GetFee(nBytes) : ::minRelayTxFee.GetFee(nBytes)))
3531  {
3532  strFailReason = _("Transaction too large for fee policy");
3533  return false;
3534  }
3535 
3536  if (nFeeRet >= nFeeNeeded) {
3537  // Reduce fee to only the needed amount if possible. This
3538  // prevents potential overpayment in fees if the coins
3539  // selected to meet nFeeNeeded result in a transaction that
3540  // requires less fee than the prior iteration.
3541 
3542  // If we have no change and a big enough excess fee, then
3543  // try to construct transaction again only without picking
3544  // new inputs. We now know we only need the smaller fee
3545  // (because of reduced tx size) and so we should add a
3546  // change output. Only try this once.
3547  if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
3548  unsigned int tx_size_with_change = nBytes + change_prototype_size + 2; // Add 2 as a buffer in case increasing # of outputs changes compact size
3549  CAmount fee_needed_with_change = GetMinimumFee(tx_size_with_change, coin_control, ::mempool, ::feeEstimator, nullptr);
3550  CAmount minimum_value_for_change = GetDustThreshold(change_prototype_txout, discard_rate);
3551  if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) {
3552  pick_new_inputs = false;
3553  nFeeRet = fee_needed_with_change;
3554  continue;
3555  }
3556  }
3557 
3558  // If we have change output already, just increase it
3559  if (nFeeRet > nFeeNeeded && nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3560  CAmount extraFeePaid = nFeeRet - nFeeNeeded;
3561  std::vector<CTxOut>::iterator change_position = txNew.vout.begin()+nChangePosInOut;
3562  change_position->nValue += extraFeePaid;
3563  nFeeRet -= extraFeePaid;
3564  }
3565  break; // Done, enough fee included.
3566  }
3567  else if (!pick_new_inputs) {
3568  // This shouldn't happen, we should have had enough excess
3569  // fee to pay for the new output and still meet nFeeNeeded
3570  // Or we should have just subtracted fee from recipients and
3571  // nFeeNeeded should not have changed
3572  strFailReason = _("Transaction fee and change calculation failed");
3573  return false;
3574  }
3575 
3576  // Try to reduce change to include necessary fee
3577  if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3578  CAmount additionalFeeNeeded = nFeeNeeded - nFeeRet;
3579  std::vector<CTxOut>::iterator change_position = txNew.vout.begin()+nChangePosInOut;
3580  // Only reduce change if remaining amount is still a large enough output.
3581  if (change_position->nValue >= MIN_FINAL_CHANGE + additionalFeeNeeded) {
3582  change_position->nValue -= additionalFeeNeeded;
3583  nFeeRet += additionalFeeNeeded;
3584  break; // Done, able to increase fee from change
3585  }
3586  }
3587 
3588  // If subtracting fee from recipients, we now know what fee we
3589  // need to subtract, we have no reason to reselect inputs
3590  if (nSubtractFeeFromAmount > 0) {
3591  pick_new_inputs = false;
3592  }
3593 
3594  // Include more fee and try again.
3595  nFeeRet = nFeeNeeded;
3596  continue;
3597  }
3598  }
3599 
3600  if (nChangePosInOut == -1) reservekey.ReturnKey(); // Return any reserved key if we don't have change
3601 
3602  if (sign)
3603  {
3604  CTransaction txNewConst(txNew);
3605  int nIn = 0;
3606  for (const auto& coin : setCoins)
3607  {
3608  const CScript& scriptPubKey = coin.txout.scriptPubKey;
3609  SignatureData sigdata;
3610 
3611  if (!ProduceSignature(TransactionSignatureCreator(this, &txNewConst, nIn, coin.txout.nValue, SIGHASH_ALL), scriptPubKey, sigdata))
3612  {
3613  strFailReason = _("Signing transaction failed");
3614  return false;
3615  } else {
3616  UpdateTransaction(txNew, nIn, sigdata);
3617  }
3618 
3619  nIn++;
3620  }
3622  if (AreAssetsDeployed()) {
3623  for (const auto &asset : setAssets) {
3624  const CScript &scriptPubKey = asset.txout.scriptPubKey;
3625  SignatureData sigdata;
3626 
3627  if (!ProduceSignature(
3628  TransactionSignatureCreator(this, &txNewConst, nIn, asset.txout.nValue, SIGHASH_ALL),
3629  scriptPubKey, sigdata)) {
3630  strFailReason = _("Signing asset transaction failed");
3631  return false;
3632  } else {
3633  UpdateTransaction(txNew, nIn, sigdata);
3634  }
3635 
3636  nIn++;
3637  }
3638  }
3640  }
3641 
3642  // Embed the constructed transaction data in wtxNew.
3643  wtxNew.SetTx(MakeTransactionRef(std::move(txNew)));
3644 
3645  // Limit size
3646  if (GetTransactionWeight(wtxNew) >= MAX_STANDARD_TX_WEIGHT)
3647  {
3648  strFailReason = _("Transaction too large");
3649  return false;
3650  }
3651  }
3652 
3653  if (gArgs.GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
3654  // Lastly, ensure this tx will pass the mempool's chain limits
3655  LockPoints lp;
3656  CTxMemPoolEntry entry(wtxNew.tx, 0, 0, 0, false, 0, lp);
3657  CTxMemPool::setEntries setAncestors;
3658  size_t nLimitAncestors = gArgs.GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
3659  size_t nLimitAncestorSize = gArgs.GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000;
3660  size_t nLimitDescendants = gArgs.GetArg("-limitdescendantcount", DEFAULT_DESCENDANT_LIMIT);
3661  size_t nLimitDescendantSize = gArgs.GetArg("-limitdescendantsize", DEFAULT_DESCENDANT_SIZE_LIMIT)*1000;
3662  std::string errString;
3663  if (!mempool.CalculateMemPoolAncestors(entry, setAncestors, nLimitAncestors, nLimitAncestorSize, nLimitDescendants, nLimitDescendantSize, errString)) {
3664  strFailReason = _("Transaction has too long of a mempool chain");
3665  return false;
3666  }
3667  }
3668 
3669  LogPrintf("Fee Calculation: Fee:%d Bytes:%u Needed:%d Tgt:%d (requested %d) Reason:\"%s\" Decay %.5f: Estimation: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out) Fail: (%g - %g) %.2f%% %.1f/(%.1f %d mem %.1f out)\n",
3670  nFeeRet, nBytes, nFeeNeeded, feeCalc.returnedTarget, feeCalc.desiredTarget, StringForFeeReason(feeCalc.reason), feeCalc.est.decay,
3671  feeCalc.est.pass.start, feeCalc.est.pass.end,
3672  100 * feeCalc.est.pass.withinTarget / (feeCalc.est.pass.totalConfirmed + feeCalc.est.pass.inMempool + feeCalc.est.pass.leftMempool),
3673  feeCalc.est.pass.withinTarget, feeCalc.est.pass.totalConfirmed, feeCalc.est.pass.inMempool, feeCalc.est.pass.leftMempool,
3674  feeCalc.est.fail.start, feeCalc.est.fail.end,
3675  100 * feeCalc.est.fail.withinTarget / (feeCalc.est.fail.totalConfirmed + feeCalc.est.fail.inMempool + feeCalc.est.fail.leftMempool),
3676  feeCalc.est.fail.withinTarget, feeCalc.est.fail.totalConfirmed, feeCalc.est.fail.inMempool, feeCalc.est.fail.leftMempool);
3677  return true;
3678 }
3679 
3683 bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CConnman* connman, CValidationState& state)
3684 {
3685  {
3686  LOCK2(cs_main, cs_wallet);
3687  LogPrintf("CommitTransaction:\n%s", wtxNew.tx->ToString());
3688  {
3689  // Take key pair from key pool so it won't be used again
3690  reservekey.KeepKey();
3691 
3692  // Add tx to wallet, because if it has change it's also ours,
3693  // otherwise just for transaction history.
3694  AddToWallet(wtxNew);
3695 
3696  // Notify that old coins are spent
3697  for (const CTxIn& txin : wtxNew.tx->vin)
3698  {
3699  CWalletTx &coin = mapWallet[txin.prevout.hash];
3700  coin.BindWallet(this);
3701  NotifyTransactionChanged(this, coin.GetHash(), CT_UPDATED);
3702  }
3703  }
3704 
3705  // Track how many getdata requests our transaction gets
3706  mapRequestCount[wtxNew.GetHash()] = 0;
3707 
3708  if (fBroadcastTransactions)
3709  {
3710  // Broadcast
3711  if (!wtxNew.AcceptToMemoryPool(maxTxFee, state)) {
3712  LogPrintf("CommitTransaction(): Transaction cannot be broadcast immediately, %s\n", state.GetRejectReason());
3713  // TODO: if we expect the failure to be long term or permanent, instead delete wtx from the wallet and return failure.
3714  AbandonTransaction(wtxNew.tx->GetHash());
3715  return false;
3716  } else {
3717  wtxNew.RelayWalletTransaction(connman);
3718  }
3719  }
3720  }
3721  return true;
3722 }
3723 
3724 void CWallet::ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries) {
3725  CWalletDB walletdb(*dbw);
3726  return walletdb.ListAccountCreditDebit(strAccount, entries);
3727 }
3728 
3730 {
3731  CWalletDB walletdb(*dbw);
3732 
3733  return AddAccountingEntry(acentry, &walletdb);
3734 }
3735 
3737 {
3738  if (!pwalletdb->WriteAccountingEntry(++nAccountingEntryNumber, acentry)) {
3739  return false;
3740  }
3741 
3742  laccentries.push_back(acentry);
3743  CAccountingEntry & entry = laccentries.back();
3744  wtxOrdered.insert(std::make_pair(entry.nOrderPos, TxPair(nullptr, &entry)));
3745 
3746  return true;
3747 }
3748 
3749 DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
3750 {
3751  LOCK2(cs_main, cs_wallet);
3752 
3753  fFirstRunRet = false;
3754  DBErrors nLoadWalletRet = CWalletDB(*dbw,"cr+").LoadWallet(this);
3755  if (nLoadWalletRet == DB_NEED_REWRITE)
3756  {
3757  if (dbw->Rewrite("\x04pool"))
3758  {
3759  setInternalKeyPool.clear();
3760  setExternalKeyPool.clear();
3761  m_pool_key_to_index.clear();
3762  // Note: can't top-up keypool here, because wallet is locked.
3763  // User will be prompted to unlock wallet the next operation
3764  // that requires a new key.
3765  }
3766  }
3767 
3768  // This wallet is in its first run if all of these are empty
3769  fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && mapWatchKeys.empty() && setWatchOnly.empty() && mapScripts.empty();
3770 
3771  if (nLoadWalletRet != DB_LOAD_OK)
3772  return nLoadWalletRet;
3773 
3774  uiInterface.LoadWallet(this);
3775 
3776  return DB_LOAD_OK;
3777 }
3778 
3779 DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
3780 {
3781  AssertLockHeld(cs_wallet); // mapWallet
3782  DBErrors nZapSelectTxRet = CWalletDB(*dbw,"cr+").ZapSelectTx(vHashIn, vHashOut);
3783  for (uint256 hash : vHashOut)
3784  mapWallet.erase(hash);
3785 
3786  if (nZapSelectTxRet == DB_NEED_REWRITE)
3787  {
3788  if (dbw->Rewrite("\x04pool"))
3789  {
3790  setInternalKeyPool.clear();
3791  setExternalKeyPool.clear();
3792  m_pool_key_to_index.clear();
3793  // Note: can't top-up keypool here, because wallet is locked.
3794  // User will be prompted to unlock wallet the next operation
3795  // that requires a new key.
3796  }
3797  }
3798 
3799  if (nZapSelectTxRet != DB_LOAD_OK)
3800  return nZapSelectTxRet;
3801 
3802  MarkDirty();
3803 
3804  return DB_LOAD_OK;
3805 
3806 }
3807 
3808 DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
3809 {
3810  DBErrors nZapWalletTxRet = CWalletDB(*dbw,"cr+").ZapWalletTx(vWtx);
3811  if (nZapWalletTxRet == DB_NEED_REWRITE)
3812  {
3813  if (dbw->Rewrite("\x04pool"))
3814  {
3815  LOCK(cs_wallet);
3816  setInternalKeyPool.clear();
3817  setExternalKeyPool.clear();
3818  m_pool_key_to_index.clear();
3819  // Note: can't top-up keypool here, because wallet is locked.
3820  // User will be prompted to unlock wallet the next operation
3821  // that requires a new key.
3822  }
3823  }
3824 
3825  if (nZapWalletTxRet != DB_LOAD_OK)
3826  return nZapWalletTxRet;
3827 
3828  return DB_LOAD_OK;
3829 }
3830 
3831 
3832 bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& strName, const std::string& strPurpose)
3833 {
3834  bool fUpdated = false;
3835  {
3836  LOCK(cs_wallet); // mapAddressBook
3837  std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
3838  fUpdated = mi != mapAddressBook.end();
3839  mapAddressBook[address].name = strName;
3840  if (!strPurpose.empty()) /* update purpose only if requested */
3841  mapAddressBook[address].purpose = strPurpose;
3842  }
3843  NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
3844  strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
3845  if (!strPurpose.empty() && !CWalletDB(*dbw).WritePurpose(EncodeDestination(address), strPurpose))
3846  return false;
3847  return CWalletDB(*dbw).WriteName(EncodeDestination(address), strName);
3848 }
3849 
3851 {
3852  {
3853  LOCK(cs_wallet); // mapAddressBook
3854 
3855  // Delete destdata tuples associated with address
3856  std::string strAddress = EncodeDestination(address);
3857  for (const std::pair<std::string, std::string> &item : mapAddressBook[address].destdata)
3858  {
3859  CWalletDB(*dbw).EraseDestData(strAddress, item.first);
3860  }
3861  mapAddressBook.erase(address);
3862  }
3863 
3864  NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
3865 
3866  CWalletDB(*dbw).ErasePurpose(EncodeDestination(address));
3867  return CWalletDB(*dbw).EraseName(EncodeDestination(address));
3868 }
3869 
3870 const std::string& CWallet::GetAccountName(const CScript& scriptPubKey) const
3871 {
3872  CTxDestination address;
3873  if (ExtractDestination(scriptPubKey, address) && !scriptPubKey.IsUnspendable()) {
3874  auto mi = mapAddressBook.find(address);
3875  if (mi != mapAddressBook.end()) {
3876  return mi->second.name;
3877  }
3878  }
3879  // A scriptPubKey that doesn't have an entry in the address book is
3880  // associated with the default account ("").
3881  const static std::string DEFAULT_ACCOUNT_NAME;
3882  return DEFAULT_ACCOUNT_NAME;
3883 }
3884 
3890 {
3891  {
3892  LOCK(cs_wallet);
3893  CWalletDB walletdb(*dbw);
3894 
3895  for (int64_t nIndex : setInternalKeyPool) {
3896  walletdb.ErasePool(nIndex);
3897  }
3898  setInternalKeyPool.clear();
3899 
3900  for (int64_t nIndex : setExternalKeyPool) {
3901  walletdb.ErasePool(nIndex);
3902  }
3903  setExternalKeyPool.clear();
3904 
3905  m_pool_key_to_index.clear();
3906 
3907  if (!TopUpKeyPool()) {
3908  return false;
3909  }
3910  LogPrintf("CWallet::NewKeyPool rewrote keypool\n");
3911  }
3912  return true;
3913 }
3914 
3916 {
3917  AssertLockHeld(cs_wallet); // setExternalKeyPool
3918  return setExternalKeyPool.size();
3919 }
3920 
3921 void CWallet::LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
3922 {
3923  AssertLockHeld(cs_wallet);
3924  if (keypool.fInternal) {
3925  setInternalKeyPool.insert(nIndex);
3926  } else {
3927  setExternalKeyPool.insert(nIndex);
3928  }
3929  m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
3930  m_pool_key_to_index[keypool.vchPubKey.GetID()] = nIndex;
3931 
3932  // If no metadata exists yet, create a default with the pool key's
3933  // creation time. Note that this may be overwritten by actually
3934  // stored metadata for that key later, which is fine.
3935  CKeyID keyid = keypool.vchPubKey.GetID();
3936  if (mapKeyMetadata.count(keyid) == 0)
3937  mapKeyMetadata[keyid] = CKeyMetadata(keypool.nTime);
3938 }
3939 
3940 bool CWallet::TopUpKeyPool(unsigned int kpSize)
3941 {
3942  {
3943  LOCK(cs_wallet);
3944 
3945  if (IsLocked())
3946  return false;
3947 
3948  // Top up key pool
3949  unsigned int nTargetSize;
3950  if (kpSize > 0)
3951  nTargetSize = kpSize;
3952  else
3953  nTargetSize = std::max(gArgs.GetArg("-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0);
3954 
3955  // count amount of available keys (internal, external)
3956  // make sure the keypool of external and internal keys fits the user selected target (-keypool)
3957  int64_t missingExternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setExternalKeyPool.size(), (int64_t) 0);
3958  int64_t missingInternal = std::max(std::max((int64_t) nTargetSize, (int64_t) 1) - (int64_t)setInternalKeyPool.size(), (int64_t) 0);
3959 
3960  if (!IsHDEnabled() || !CanSupportFeature(FEATURE_HD_SPLIT))
3961  {
3962  // don't create extra internal keys
3963  missingInternal = 0;
3964  }
3965  bool internal = false;
3966  CWalletDB walletdb(*dbw);
3967  for (int64_t i = missingInternal + missingExternal; i--;)
3968  {
3969  if (i < missingInternal) {
3970  internal = true;
3971  }
3972 
3973  assert(m_max_keypool_index < std::numeric_limits<int64_t>::max()); // How in the hell did you use so many keys?
3974  int64_t index = ++m_max_keypool_index;
3975 
3976  CPubKey pubkey(GenerateNewKey(walletdb, internal));
3977  if (!walletdb.WritePool(index, CKeyPool(pubkey, internal))) {
3978  throw std::runtime_error(std::string(__func__) + ": writing generated key failed");
3979  }
3980 
3981  if (internal) {
3982  setInternalKeyPool.insert(index);
3983  } else {
3984  setExternalKeyPool.insert(index);
3985  }
3986  m_pool_key_to_index[pubkey.GetID()] = index;
3987  }
3988  if (missingInternal + missingExternal > 0) {
3989  LogPrintf("keypool added %d keys (%d internal), size=%u (%u internal)\n", missingInternal + missingExternal, missingInternal, setInternalKeyPool.size() + setExternalKeyPool.size(), setInternalKeyPool.size());
3990  }
3991  }
3992  return true;
3993 }
3994 
3995 void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool fRequestedInternal)
3996 {
3997  nIndex = -1;
3998  keypool.vchPubKey = CPubKey();
3999  {
4000  LOCK(cs_wallet);
4001 
4002  if (!IsLocked())
4003  TopUpKeyPool();
4004 
4005  bool fReturningInternal = IsHDEnabled() && CanSupportFeature(FEATURE_HD_SPLIT) && fRequestedInternal;
4006  std::set<int64_t>& setKeyPool = fReturningInternal ? setInternalKeyPool : setExternalKeyPool;
4007 
4008  // Get the oldest key
4009  if(setKeyPool.empty())
4010  return;
4011 
4012  CWalletDB walletdb(*dbw);
4013 
4014  auto it = setKeyPool.begin();
4015  nIndex = *it;
4016  setKeyPool.erase(it);
4017  if (!walletdb.ReadPool(nIndex, keypool)) {
4018  throw std::runtime_error(std::string(__func__) + ": read failed");
4019  }
4020  if (!HaveKey(keypool.vchPubKey.GetID())) {
4021  throw std::runtime_error(std::string(__func__) + ": unknown key in key pool");
4022  }
4023  if (keypool.fInternal != fReturningInternal) {
4024  throw std::runtime_error(std::string(__func__) + ": keypool entry misclassified");
4025  }
4026 
4027  assert(keypool.vchPubKey.IsValid());
4028  m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
4029  LogPrintf("keypool reserve %d\n", nIndex);
4030  }
4031 }
4032 
4033 void CWallet::KeepKey(int64_t nIndex)
4034 {
4035  // Remove from key pool
4036  CWalletDB walletdb(*dbw);
4037  walletdb.ErasePool(nIndex);
4038  LogPrintf("keypool keep %d\n", nIndex);
4039 }
4040 
4041 void CWallet::ReturnKey(int64_t nIndex, bool fInternal, const CPubKey& pubkey)
4042 {
4043  // Return to key pool
4044  {
4045  LOCK(cs_wallet);
4046  if (fInternal) {
4047  setInternalKeyPool.insert(nIndex);
4048  } else {
4049  setExternalKeyPool.insert(nIndex);
4050  }
4051  m_pool_key_to_index[pubkey.GetID()] = nIndex;
4052  }
4053  LogPrintf("keypool return %d\n", nIndex);
4054 }
4055 
4056 bool CWallet::GetKeyFromPool(CPubKey& result, bool internal)
4057 {
4058  CKeyPool keypool;
4059  {
4060  LOCK(cs_wallet);
4061  int64_t nIndex = 0;
4062  ReserveKeyFromKeyPool(nIndex, keypool, internal);
4063  if (nIndex == -1)
4064  {
4065  if (IsLocked()) return false;
4066  CWalletDB walletdb(*dbw);
4067  result = GenerateNewKey(walletdb, internal);
4068  return true;
4069  }
4070  KeepKey(nIndex);
4071  result = keypool.vchPubKey;
4072  }
4073  return true;
4074 }
4075 
4076 static int64_t GetOldestKeyTimeInPool(const std::set<int64_t>& setKeyPool, CWalletDB& walletdb) {
4077  if (setKeyPool.empty()) {
4078  return GetTime();
4079  }
4080 
4081  CKeyPool keypool;
4082  int64_t nIndex = *(setKeyPool.begin());
4083  if (!walletdb.ReadPool(nIndex, keypool)) {
4084  throw std::runtime_error(std::string(__func__) + ": read oldest key in keypool failed");
4085  }
4086  assert(keypool.vchPubKey.IsValid());
4087  return keypool.nTime;
4088 }
4089 
4091 {
4092  LOCK(cs_wallet);
4093 
4094  CWalletDB walletdb(*dbw);
4095 
4096  // load oldest key from keypool, get time and return
4097  int64_t oldestKey = GetOldestKeyTimeInPool(setExternalKeyPool, walletdb);
4098  if (IsHDEnabled() && CanSupportFeature(FEATURE_HD_SPLIT)) {
4099  oldestKey = std::max(GetOldestKeyTimeInPool(setInternalKeyPool, walletdb), oldestKey);
4100  }
4101 
4102  return oldestKey;
4103 }
4104 
4105 std::map<CTxDestination, CAmount> CWallet::GetAddressBalances()
4106 {
4107  std::map<CTxDestination, CAmount> balances;
4108 
4109  {
4110  LOCK(cs_wallet);
4111  for (const auto& walletEntry : mapWallet)
4112  {
4113  const CWalletTx *pcoin = &walletEntry.second;
4114 
4115  if (!pcoin->IsTrusted())
4116  continue;
4117 
4118  if (pcoin->IsCoinBase() && pcoin->GetBlocksToMaturity() > 0)
4119  continue;
4120 
4121  int nDepth = pcoin->GetDepthInMainChain();
4122  if (nDepth < (pcoin->IsFromMe(ISMINE_ALL) ? 0 : 1))
4123  continue;
4124 
4125  for (unsigned int i = 0; i < pcoin->tx->vout.size(); i++)
4126  {
4127  CTxDestination addr;
4128  if (!IsMine(pcoin->tx->vout[i]))
4129  continue;
4130  if(!ExtractDestination(pcoin->tx->vout[i].scriptPubKey, addr))
4131  continue;
4132 
4133  CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->tx->vout[i].nValue;
4134 
4135  if (!balances.count(addr))
4136  balances[addr] = 0;
4137  balances[addr] += n;
4138  }
4139  }
4140  }
4141 
4142  return balances;
4143 }
4144 
4145 std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
4146 {
4147  AssertLockHeld(cs_wallet); // mapWallet
4148  std::set< std::set<CTxDestination> > groupings;
4149  std::set<CTxDestination> grouping;
4150 
4151  for (const auto& walletEntry : mapWallet)
4152  {
4153  const CWalletTx *pcoin = &walletEntry.second;
4154 
4155  if (pcoin->tx->vin.size() > 0)
4156  {
4157  bool any_mine = false;
4158  // group all input addresses with each other
4159  for (CTxIn txin : pcoin->tx->vin)
4160  {
4161  CTxDestination address;
4162  if(!IsMine(txin)) /* If this input isn't mine, ignore it */
4163  continue;
4164  if(!ExtractDestination(mapWallet[txin.prevout.hash].tx->vout[txin.prevout.n].scriptPubKey, address))
4165  continue;
4166  grouping.insert(address);
4167  any_mine = true;
4168  }
4169 
4170  // group change with input addresses
4171  if (any_mine)
4172  {
4173  for (CTxOut txout : pcoin->tx->vout)
4174  if (IsChange(txout))
4175  {
4176  CTxDestination txoutAddr;
4177  if(!ExtractDestination(txout.scriptPubKey, txoutAddr))
4178  continue;
4179  grouping.insert(txoutAddr);
4180  }
4181  }
4182  if (grouping.size() > 0)
4183  {
4184  groupings.insert(grouping);
4185  grouping.clear();
4186  }
4187  }
4188 
4189  // group lone addrs by themselves
4190  for (const auto& txout : pcoin->tx->vout)
4191  if (IsMine(txout))
4192  {
4193  CTxDestination address;
4194  if(!ExtractDestination(txout.scriptPubKey, address))
4195  continue;
4196  grouping.insert(address);
4197  groupings.insert(grouping);
4198  grouping.clear();
4199  }
4200  }
4201 
4202  std::set< std::set<CTxDestination>* > uniqueGroupings; // a set of pointers to groups of addresses
4203  std::map< CTxDestination, std::set<CTxDestination>* > setmap; // map addresses to the unique group containing it
4204  for (std::set<CTxDestination> _grouping : groupings)
4205  {
4206  // make a set of all the groups hit by this new group
4207  std::set< std::set<CTxDestination>* > hits;
4208  std::map< CTxDestination, std::set<CTxDestination>* >::iterator it;
4209  for (CTxDestination address : _grouping)
4210  if ((it = setmap.find(address)) != setmap.end())
4211  hits.insert((*it).second);
4212 
4213  // merge all hit groups into a new single group and delete old groups
4214  std::set<CTxDestination>* merged = new std::set<CTxDestination>(_grouping);
4215  for (std::set<CTxDestination>* hit : hits)
4216  {
4217  merged->insert(hit->begin(), hit->end());
4218  uniqueGroupings.erase(hit);
4219  delete hit;
4220  }
4221  uniqueGroupings.insert(merged);
4222 
4223  // update setmap
4224  for (CTxDestination element : *merged)
4225  setmap[element] = merged;
4226  }
4227 
4228  std::set< std::set<CTxDestination> > ret;
4229  for (std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)
4230  {
4231  ret.insert(*uniqueGrouping);
4232  delete uniqueGrouping;
4233  }
4234 
4235  return ret;
4236 }
4237 
4238 std::set<CTxDestination> CWallet::GetAccountAddresses(const std::string& strAccount) const
4239 {
4240  LOCK(cs_wallet);
4241  std::set<CTxDestination> result;
4242  for (const std::pair<CTxDestination, CAddressBookData>& item : mapAddressBook)
4243  {
4244  const CTxDestination& address = item.first;
4245  const std::string& strName = item.second.name;
4246  if (strName == strAccount)
4247  result.insert(address);
4248  }
4249  return result;
4250 }
4251 
4252 bool CReserveKey::GetReservedKey(CPubKey& pubkey, bool internal)
4253 {
4254  if (nIndex == -1)
4255  {
4256  CKeyPool keypool;
4257  pwallet->ReserveKeyFromKeyPool(nIndex, keypool, internal);
4258  if (nIndex != -1)
4259  vchPubKey = keypool.vchPubKey;
4260  else {
4261  return false;
4262  }
4263  fInternal = keypool.fInternal;
4264  }
4265  assert(vchPubKey.IsValid());
4266  pubkey = vchPubKey;
4267  return true;
4268 }
4269 
4271 {
4272  if (nIndex != -1)
4273  pwallet->KeepKey(nIndex);
4274  nIndex = -1;
4275  vchPubKey = CPubKey();
4276 }
4277 
4279 {
4280  if (nIndex != -1) {
4281  pwallet->ReturnKey(nIndex, fInternal, vchPubKey);
4282  }
4283  nIndex = -1;
4284  vchPubKey = CPubKey();
4285 }
4286 
4287 void CWallet::MarkReserveKeysAsUsed(int64_t keypool_id)
4288 {
4289  AssertLockHeld(cs_wallet);
4290  bool internal = setInternalKeyPool.count(keypool_id);
4291  if (!internal) assert(setExternalKeyPool.count(keypool_id));
4292  std::set<int64_t> *setKeyPool = internal ? &setInternalKeyPool : &setExternalKeyPool;
4293  auto it = setKeyPool->begin();
4294 
4295  CWalletDB walletdb(*dbw);
4296  while (it != std::end(*setKeyPool)) {
4297  const int64_t& index = *(it);
4298  if (index > keypool_id) break; // set*KeyPool is ordered
4299 
4300  CKeyPool keypool;
4301  if (walletdb.ReadPool(index, keypool)) { //TODO: This should be unnecessary
4302  m_pool_key_to_index.erase(keypool.vchPubKey.GetID());
4303  }
4304  walletdb.ErasePool(index);
4305  LogPrintf("keypool index %d removed\n", index);
4306  it = setKeyPool->erase(it);
4307  }
4308 }
4309 
4310 void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script)
4311 {
4312  std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(this);
4313  CPubKey pubkey;
4314  if (!rKey->GetReservedKey(pubkey))
4315  {
4316  return;
4317  }
4318 
4319  script = rKey;
4320  script->reserveScript = CScript() << ToByteVector(pubkey) << OP_CHECKSIG;
4321 }
4322 
4323 void CWallet::LockCoin(const COutPoint& output)
4324 {
4325  AssertLockHeld(cs_wallet); // setLockedCoins
4326  setLockedCoins.insert(output);
4327 }
4328 
4329 void CWallet::UnlockCoin(const COutPoint& output)
4330 {
4331  AssertLockHeld(cs_wallet); // setLockedCoins
4332  setLockedCoins.erase(output);
4333 }
4334 
4336 {
4337  AssertLockHeld(cs_wallet); // setLockedCoins
4338  setLockedCoins.clear();
4339 }
4340 
4341 bool CWallet::IsLockedCoin(uint256 hash, unsigned int n) const
4342 {
4343  AssertLockHeld(cs_wallet); // setLockedCoins
4344  COutPoint outpt(hash, n);
4345 
4346  return (setLockedCoins.count(outpt) > 0);
4347 }
4348 
4349 void CWallet::ListLockedCoins(std::vector<COutPoint>& vOutpts) const
4350 {
4351  AssertLockHeld(cs_wallet); // setLockedCoins
4352  for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
4353  it != setLockedCoins.end(); it++) {
4354  COutPoint outpt = (*it);
4355  vOutpts.push_back(outpt);
4356  }
4357 }
4358  // end of Actions
4360 
4361 void CWallet::GetKeyBirthTimes(std::map<CTxDestination, int64_t> &mapKeyBirth) const {
4362  AssertLockHeld(cs_wallet); // mapKeyMetadata
4363  mapKeyBirth.clear();
4364 
4365  // get birth times for keys with metadata
4366  for (const auto& entry : mapKeyMetadata) {
4367  if (entry.second.nCreateTime) {
4368  mapKeyBirth[entry.first] = entry.second.nCreateTime;
4369  }
4370  }
4371 
4372  // map in which we'll infer heights of other keys
4373  CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganized; use a 144-block safety margin
4374  std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
4375  for (const CKeyID &keyid : GetKeys()) {
4376  if (mapKeyBirth.count(keyid) == 0)
4377  mapKeyFirstBlock[keyid] = pindexMax;
4378  }
4379 
4380  // if there are no such keys, we're done
4381  if (mapKeyFirstBlock.empty())
4382  return;
4383 
4384  // find first block that affects those keys, if there are any left
4385  std::vector<CKeyID> vAffected;
4386  for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
4387  // iterate over all wallet transactions...
4388  const CWalletTx &wtx = (*it).second;
4389  BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock);
4390  if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) {
4391  // ... which are already in a block
4392  int nHeight = blit->second->nHeight;
4393  for (const CTxOut &txout : wtx.tx->vout) {
4394  // iterate over all their outputs
4395  CAffectedKeysVisitor(*this, vAffected).Process(txout.scriptPubKey);
4396  for (const CKeyID &keyid : vAffected) {
4397  // ... and all their affected keys
4398  std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
4399  if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
4400  rit->second = blit->second;
4401  }
4402  vAffected.clear();
4403  }
4404  }
4405  }
4406 
4407  // Extract block timestamps for those keys
4408  for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
4409  mapKeyBirth[it->first] = it->second->GetBlockTime() - TIMESTAMP_WINDOW; // block times can be 2h off
4410 }
4411 
4433 unsigned int CWallet::ComputeTimeSmart(const CWalletTx& wtx) const
4434 {
4435  unsigned int nTimeSmart = wtx.nTimeReceived;
4436  if (!wtx.hashUnset()) {
4437  if (mapBlockIndex.count(wtx.hashBlock)) {
4438  int64_t latestNow = wtx.nTimeReceived;
4439  int64_t latestEntry = 0;
4440 
4441  // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
4442  int64_t latestTolerated = latestNow + 300;
4443  const TxItems& txOrdered = wtxOrdered;
4444  for (auto it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
4445  CWalletTx* const pwtx = it->second.first;
4446  if (pwtx == &wtx) {
4447  continue;
4448  }
4449  CAccountingEntry* const pacentry = it->second.second;
4450  int64_t nSmartTime;
4451  if (pwtx) {
4452  nSmartTime = pwtx->nTimeSmart;
4453  if (!nSmartTime) {
4454  nSmartTime = pwtx->nTimeReceived;
4455  }
4456  } else {
4457  nSmartTime = pacentry->nTime;
4458  }
4459  if (nSmartTime <= latestTolerated) {
4460  latestEntry = nSmartTime;
4461  if (nSmartTime > latestNow) {
4462  latestNow = nSmartTime;
4463  }
4464  break;
4465  }
4466  }
4467 
4468  int64_t blocktime = mapBlockIndex[wtx.hashBlock]->GetBlockTime();
4469  nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
4470  } else {
4471  LogPrintf("%s: found %s in block %s not in index\n", __func__, wtx.GetHash().ToString(), wtx.hashBlock.ToString());
4472  }
4473  }
4474  return nTimeSmart;
4475 }
4476 
4477 bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
4478 {
4479  if (boost::get<CNoDestination>(&dest))
4480  return false;
4481 
4482  mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
4483  return CWalletDB(*dbw).WriteDestData(EncodeDestination(dest), key, value);
4484 }
4485 
4486 bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
4487 {
4488  if (!mapAddressBook[dest].destdata.erase(key))
4489  return false;
4490  return CWalletDB(*dbw).EraseDestData(EncodeDestination(dest), key);
4491 }
4492 
4493 bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
4494 {
4495  mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
4496  return true;
4497 }
4498 
4499 bool CWallet::GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
4500 {
4501  std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
4502  if(i != mapAddressBook.end())
4503  {
4504  CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
4505  if(j != i->second.destdata.end())
4506  {
4507  if(value)
4508  *value = j->second;
4509  return true;
4510  }
4511  }
4512  return false;
4513 }
4514 
4515 std::vector<std::string> CWallet::GetDestValues(const std::string& prefix) const
4516 {
4517  LOCK(cs_wallet);
4518  std::vector<std::string> values;
4519  for (const auto& address : mapAddressBook) {
4520  for (const auto& data : address.second.destdata) {
4521  if (!data.first.compare(0, prefix.size(), prefix)) {
4522  values.emplace_back(data.second);
4523  }
4524  }
4525  }
4526  return values;
4527 }
4528 
4529 CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
4530 {
4531  // needed to restore wallet transaction meta data after -zapwallettxes
4532  std::vector<CWalletTx> vWtx;
4533 
4534  if (gArgs.GetBoolArg("-zapwallettxes", false)) {
4535  uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
4536 
4537  std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile));
4538  std::unique_ptr<CWallet> tempWallet(new CWallet(std::move(dbw)));
4539  DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
4540  if (nZapWalletRet != DB_LOAD_OK) {
4541  InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
4542  return nullptr;
4543  }
4544  }
4545 
4546  uiInterface.InitMessage(_("Loading wallet..."));
4547 
4548  int64_t nStart = GetTimeMillis();
4549  bool fFirstRun = true;
4550  std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile));
4551  CWallet *walletInstance = new CWallet(std::move(dbw));
4552  DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
4553  if (nLoadWalletRet != DB_LOAD_OK)
4554  {
4555  if (nLoadWalletRet == DB_CORRUPT) {
4556  InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
4557  return nullptr;
4558  }
4559  else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
4560  {
4561  InitWarning(strprintf(_("Error reading %s! All keys read correctly, but transaction data"
4562  " or address book entries might be missing or incorrect."),
4563  walletFile));
4564  }
4565  else if (nLoadWalletRet == DB_TOO_NEW) {
4566  InitError(strprintf(_("Error loading %s: Wallet requires newer version of %s"), walletFile, _(PACKAGE_NAME)));
4567  return nullptr;
4568  }
4569  else if (nLoadWalletRet == DB_NEED_REWRITE)
4570  {
4571  InitError(strprintf(_("Wallet needed to be rewritten: restart %s to complete"), _(PACKAGE_NAME)));
4572  return nullptr;
4573  }
4574  else {
4575  InitError(strprintf(_("Error loading %s"), walletFile));
4576  return nullptr;
4577  }
4578  }
4579 
4580  if (gArgs.GetBoolArg("-upgradewallet", fFirstRun))
4581  {
4582  int nMaxVersion = gArgs.GetArg("-upgradewallet", 0);
4583  if (nMaxVersion == 0) // the -upgradewallet without argument case
4584  {
4585  LogPrintf("Performing wallet upgrade to %i\n", FEATURE_LATEST);
4586  nMaxVersion = CLIENT_VERSION;
4587  walletInstance->SetMinVersion(FEATURE_LATEST); // permanently upgrade the wallet immediately
4588  }
4589  else
4590  LogPrintf("Allowing wallet upgrade up to %i\n", nMaxVersion);
4591  if (nMaxVersion < walletInstance->GetVersion())
4592  {
4593  InitError(_("Cannot downgrade wallet"));
4594  return nullptr;
4595  }
4596  walletInstance->SetMaxVersion(nMaxVersion);
4597  }
4598 
4599  if (fFirstRun)
4600  {
4601  // ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
4602  if (!gArgs.GetBoolArg("-usehd", true)) {
4603  InitError(strprintf(_("Error creating %s: You can't create non-HD wallets with this version."), walletFile));
4604  return nullptr;
4605  }
4606  walletInstance->SetMinVersion(FEATURE_NO_DEFAULT_KEY);
4607 
4608  // generate a new seed
4609  CPubKey seed = walletInstance->GenerateNewSeed();
4610  if (!walletInstance->SetHDSeed(seed))
4611  throw std::runtime_error(std::string(__func__) + ": Storing HD seed failed");
4612 
4613  // Top up the keypool
4614  if (!walletInstance->TopUpKeyPool()) {
4615  InitError(_("Unable to generate initial keys") += "\n");
4616  return nullptr;
4617  }
4618 
4619  walletInstance->SetBestChain(chainActive.GetLocator());
4620  }
4621  else if (gArgs.IsArgSet("-usehd")) {
4622  bool useHD = gArgs.GetBoolArg("-usehd", true);
4623  if (walletInstance->IsHDEnabled() && !useHD) {
4624  InitError(strprintf(_("Error loading %s: You can't disable HD on an already existing HD wallet"), walletFile));
4625  return nullptr;
4626  }
4627  if (!walletInstance->IsHDEnabled() && useHD) {
4628  InitError(strprintf(_("Error loading %s: You can't enable HD on an already existing non-HD wallet"), walletFile));
4629  return nullptr;
4630  }
4631  }
4632 
4633  LogPrintf(" wallet %15dms\n", GetTimeMillis() - nStart);
4634 
4635  RegisterValidationInterface(walletInstance);
4636 
4637  // Try to top up keypool. No-op if the wallet is locked.
4638  walletInstance->TopUpKeyPool();
4639 
4640  CBlockIndex *pindexRescan = chainActive.Genesis();
4641  if (!gArgs.GetBoolArg("-rescan", false))
4642  {
4643  CWalletDB walletdb(*walletInstance->dbw);
4644  CBlockLocator locator;
4645  if (walletdb.ReadBestBlock(locator))
4646  pindexRescan = FindForkInGlobalIndex(chainActive, locator);
4647  }
4648  if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
4649  {
4650  //We can't rescan beyond non-pruned blocks, stop and throw an error
4651  //this might happen if a user uses an old wallet within a pruned node
4652  // or if he ran -disablewallet for a longer time, then decided to re-enable
4653  if (fPruneMode)
4654  {
4655  CBlockIndex *block = chainActive.Tip();
4656  while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block)
4657  block = block->pprev;
4658 
4659  if (pindexRescan != block) {
4660  InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
4661  return nullptr;
4662  }
4663  }
4664 
4665  uiInterface.InitMessage(_("Rescanning..."));
4666  LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);
4667 
4668  // No need to read and scan block if block was created before
4669  // our wallet birthday (as adjusted for block time variability)
4670  while (pindexRescan && walletInstance->nTimeFirstKey && (pindexRescan->GetBlockTime() < (walletInstance->nTimeFirstKey - TIMESTAMP_WINDOW))) {
4671  pindexRescan = chainActive.Next(pindexRescan);
4672  }
4673 
4674  nStart = GetTimeMillis();
4675  walletInstance->ScanForWalletTransactions(pindexRescan, nullptr, true);
4676  LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart);
4677  walletInstance->SetBestChain(chainActive.GetLocator());
4678  walletInstance->dbw->IncrementUpdateCounter();
4679 
4680  // Restore wallet transaction metadata after -zapwallettxes=1
4681  if (gArgs.GetBoolArg("-zapwallettxes", false) && gArgs.GetArg("-zapwallettxes", "1") != "2")
4682  {
4683  CWalletDB walletdb(*walletInstance->dbw);
4684 
4685  for (const CWalletTx& wtxOld : vWtx)
4686  {
4687  uint256 hash = wtxOld.GetHash();
4688  std::map<uint256, CWalletTx>::iterator mi = walletInstance->mapWallet.find(hash);
4689  if (mi != walletInstance->mapWallet.end())
4690  {
4691  const CWalletTx* copyFrom = &wtxOld;
4692  CWalletTx* copyTo = &mi->second;
4693  copyTo->mapValue = copyFrom->mapValue;
4694  copyTo->vOrderForm = copyFrom->vOrderForm;
4695  copyTo->nTimeReceived = copyFrom->nTimeReceived;
4696  copyTo->nTimeSmart = copyFrom->nTimeSmart;
4697  copyTo->fFromMe = copyFrom->fFromMe;
4698  copyTo->strFromAccount = copyFrom->strFromAccount;
4699  copyTo->nOrderPos = copyFrom->nOrderPos;
4700  walletdb.WriteTx(*copyTo);
4701  }
4702  }
4703  }
4704  }
4705  walletInstance->SetBroadcastTransactions(gArgs.GetBoolArg("-walletbroadcast", DEFAULT_WALLETBROADCAST));
4706 
4707  {
4708  LOCK(walletInstance->cs_wallet);
4709  LogPrintf("setKeyPool.size() = %u\n", walletInstance->GetKeyPoolSize());
4710  LogPrintf("mapWallet.size() = %u\n", walletInstance->mapWallet.size());
4711  LogPrintf("mapAddressBook.size() = %u\n", walletInstance->mapAddressBook.size());
4712  }
4713 
4714  return walletInstance;
4715 }
4716 
4717 std::atomic<bool> CWallet::fFlushScheduled(false);
4718 
4720 {
4721  // Add wallet transactions that aren't already in a block to mempool
4722  // Do this here as mempool requires genesis block to be loaded
4723  ReacceptWalletTransactions();
4724 
4725  // Run a thread to flush wallet periodically
4726  if (!CWallet::fFlushScheduled.exchange(true)) {
4727  scheduler.scheduleEvery(MaybeCompactWalletDB, 500);
4728  }
4729 }
4730 
4731 bool CWallet::BackupWallet(const std::string& strDest)
4732 {
4733  return dbw->Backup(strDest);
4734 }
4735 
4737 {
4738  nTime = GetTime();
4739  fInternal = false;
4740 }
4741 
4742 CKeyPool::CKeyPool(const CPubKey& vchPubKeyIn, bool internalIn)
4743 {
4744  nTime = GetTime();
4745  vchPubKey = vchPubKeyIn;
4746  fInternal = internalIn;
4747 }
4748 
4749 CWalletKey::CWalletKey(int64_t nExpires)
4750 {
4751  nTimeCreated = (nExpires ? GetTime() : 0);
4752  nTimeExpires = nExpires;
4753 }
4754 
4755 void CMerkleTx::SetMerkleBranch(const CBlockIndex* pindex, int posInBlock)
4756 {
4757  // Update the tx's hashBlock
4758  hashBlock = pindex->GetBlockHash();
4759 
4760  // set the position of the transaction in the block
4761  nIndex = posInBlock;
4762 }
4763 
4764 int CMerkleTx::GetDepthInMainChain(const CBlockIndex* &pindexRet) const
4765 {
4766  if (hashUnset())
4767  return 0;
4768 
4770 
4771  // Find the block it claims to be in
4772  BlockMap::iterator mi = mapBlockIndex.find(hashBlock);
4773  if (mi == mapBlockIndex.end())
4774  return 0;
4775  CBlockIndex* pindex = (*mi).second;
4776  if (!pindex || !chainActive.Contains(pindex))
4777  return 0;
4778 
4779  pindexRet = pindex;
4780  return ((nIndex == -1) ? (-1) : 1) * (chainActive.Height() - pindex->nHeight + 1);
4781 }
4782 
4784 {
4785  if (!IsCoinBase())
4786  return 0;
4787  return std::max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
4788 }
4789 
4790 
4792 {
4793  return ::AcceptToMemoryPool(mempool, state, tx, nullptr /* pfMissingInputs */,
4794  nullptr /* plTxnReplaced */, false /* bypass_limits */, nAbsurdFee);
4795 }
bool IsEquivalentTo(const CWalletTx &tx) const
Definition: wallet.cpp:1942
CAmount nValue
Definition: transaction.h:140
void postInitProcess(CScheduler &scheduler)
Wallet post-init setup Gives the wallet a chance to register repetitive tasks and complete post-init ...
Definition: wallet.cpp:4719
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
Compute the virtual transaction size (weight reinterpreted as bytes).
Definition: policy.cpp:266
void AvailableCoinsAll(std::vector< COutput > &vCoins, std::map< std::string, std::vector< COutput > > &mapAssetCoins, bool fGetRVN=true, bool fOnlyAssets=false, bool fOnlySafe=true, const CCoinControl *coinControl=nullptr, const CAmount &nMinimumAmount=1, const CAmount &nMaximumAmount=MAX_MONEY, const CAmount &nMinimumSumAmount=MAX_MONEY, const uint64_t &nMaximumCount=0, const int &nMinDepth=0, const int &nMaxDepth=9999999) const
populate vCoins with vector of available COutputs, and populates vAssetCoins in fWithAssets is set to...
Definition: wallet.cpp:2186
bool WriteMinVersion(int nVersion)
Definition: walletdb.cpp:149
CTxMemPool mempool
EstimatorBucket pass
Definition: fees.h:120
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector< unsigned char > &chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
Definition: crypter.cpp:43
void DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata &metadata, CKey &secret, bool internal=false)
Definition: wallet.cpp:174
std::set< std::set< CTxDestination > > GetAddressGroupings()
Definition: wallet.cpp:4145
const char * DEFAULT_WALLET_DAT
Definition: wallet.cpp:51
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
Definition: sign.cpp:236
#define OWNER_ASSET_AMOUNT
Definition: assets.h:35
void SetTx(CTransactionRef arg)
Definition: wallet.h:243
static const uint256 ABANDON_HASH
Constant used in hashBlock to indicate tx has been abandoned.
Definition: wallet.h:208
bool SignTransaction(CMutableTransaction &tx)
RVN END.
Definition: wallet.cpp:2987
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
Definition: util.cpp:448
Account information.
Definition: wallet.h:1228
int64_t nOrderPos
position in ordered transaction list
Definition: wallet.h:599
CFeeRate GetDiscardRate(const CBlockPolicyEstimator &estimator)
Return the maximum feerate for discarding change.
Definition: fees.cpp:81
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
Definition: key.cpp:135
std::string hdKeypath
Definition: walletdb.h:102
bool AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey &key, const CPubKey &pubkey)
Definition: wallet.cpp:220
void SetMerkleBranch(const CBlockIndex *pIndex, int posInBlock)
Definition: wallet.cpp:4755
void UnlockAllCoins()
Definition: wallet.cpp:4335
void BindWallet(CWallet *pwalletIn)
Definition: wallet.h:457
unsigned int nDerivationMethod
0 = EVP_sha512() 1 = scrypt()
Definition: crypter.h:42
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:89
bool IsNull() const
Definition: assets.cpp:1596
bool fPruneMode
True if we&#39;re running in -prune mode.
Definition: validation.cpp:89
std::vector< CWalletRef > vpwallets
Definition: wallet.cpp:44
bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
Adds a destination data tuple to the store, without saving it to disk.
Definition: wallet.cpp:4493
const CWalletTx * GetWalletTx(const uint256 &hash) const
Definition: wallet.cpp:130
CAmount GetImmatureBalance() const
Definition: wallet.cpp:2041
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
Definition: standard.cpp:210
int64_t GetOldestKeyPoolTime()
Definition: wallet.cpp:4090
bool fAllowWatchOnly
Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria.
Definition: coincontrol.h:24
EstimationResult est
Definition: fees.h:128
bool SelectCoinsMinConf(const CAmount &nTargetValue, int nConfMine, int nConfTheirs, uint64_t nMaxAncestors, std::vector< COutput > vCoins, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet) const
Shuffle and select coins until nTargetValue is reached while avoiding small change; This method is st...
Definition: wallet.cpp:2580
bool WriteAccount(const std::string &strAccount, const CAccount &account)
Definition: walletdb.cpp:160
void Process(const CScript &script)
Definition: wallet.cpp:106
int64_t GetBlockTime() const
Definition: chain.h:299
void GetKeyBirthTimes(std::map< CTxDestination, int64_t > &mapKeyBirth) const
Definition: wallet.cpp:4361
bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment="")
Definition: wallet.cpp:774
int returnedTarget
Definition: fees.h:131
Describes a place in the block chain to another node such that if the other node doesn&#39;t have the sam...
Definition: block.h:132
CScript scriptPubKey
Definition: transaction.h:141
const unsigned int WALLET_CRYPTO_KEY_SIZE
Definition: crypter.h:15
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:179
bool Encrypt(const CKeyingMaterial &vchPlaintext, std::vector< unsigned char > &vchCiphertext) const
Definition: crypter.cpp:75
int GetRandInt(int nMax)
Definition: random.cpp:368
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
Definition: chain.h:209
CKey key
Definition: key.h:141
CAmount GetAvailableBalance(const CCoinControl *coinControl=nullptr) const
Definition: wallet.cpp:2143
char fFromMe
From me flag is set to 1 for transactions that were created by the wallet on this raven node...
Definition: wallet.h:335
bool WriteTx(const CWalletTx &wtx)
Definition: walletdb.cpp:50
bool Derive(CExtKey &out, unsigned int nChild) const
Definition: key.cpp:237
bool TxnBegin()
Begin a new transaction.
Definition: walletdb.cpp:851
Definition: block.h:73
std::map< CTxDestination, CAddressBookData > mapAddressBook
Definition: wallet.h:829
std::vector< std::string > GetDestValues(const std::string &prefix) const
Get all destination values matching a prefix.
Definition: wallet.cpp:4515
std::set< uint256 > GetConflicts() const
Definition: wallet.cpp:1733
CCriticalSection cs_wallet
Definition: wallet.h:751
#define strprintf
Definition: tinyformat.h:1054
std::unique_ptr< CWalletDBWrapper > dbw
Definition: wallet.h:744
Encryption/decryption context with key information.
Definition: crypter.h:77
const uint256 & GetHash() const
Definition: wallet.h:277
bool IsFromMe(const isminefilter &filter) const
Definition: wallet.h:478
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
Definition: key.cpp:176
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
Definition: validation.cpp:105
CPubKey GetPubKey() const
Compute the public key from a private key.
Definition: key.cpp:148
double start
Definition: fees.h:109
bool IsFromMe(const CTransaction &tx) const
should probably be renamed to IsRelevantToMe
Definition: wallet.cpp:1333
int nIndex
Definition: wallet.h:219
std::vector< unsigned char > vchCryptedKey
Definition: crypter.h:38
inv message data
Definition: protocol.h:397
std::vector< CTxIn > vin
Definition: transaction.h:391
bool bSpendZeroConfChange
Definition: wallet.cpp:48
std::string strFromAccount
Definition: wallet.h:336
WalletFeature
(client) version numbers for particular wallet features
Definition: wallet.h:89
size_t GetSerializeSize(const T &t, int nType, int nVersion=0)
Definition: serialize.h:967
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
Definition: walletdb.cpp:91
bool TxnCommit()
Commit current transaction.
Definition: walletdb.cpp:856
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:75
static const uint32_t SEQUENCE_FINAL
Only serialized through CTransaction.
Definition: transaction.h:77
int64_t IncOrderPosNext(CWalletDB *pwalletdb=nullptr)
Increment the next transaction order id.
Definition: wallet.cpp:762
const char * prefix
Definition: rest.cpp:568
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
Definition: wallet.cpp:256
CAmount GetDebit(const isminefilter &filter) const
filter decides which addresses will count towards the debit
Definition: wallet.cpp:1745
Definition: key.h:136
bool AssetFromScript(const CScript &scriptPubKey, CNewAsset &assetNew, std::string &strAddress)
Definition: assets.cpp:664
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key...
Definition: crypter.h:35
txnouttype type
Definition: wallet.h:193
void ListSelected(std::vector< COutPoint > &vOutpoints) const
Definition: coincontrol.h:113
void ReacceptWalletTransactions()
Definition: wallet.cpp:1678
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:28
bool TransferAssetFromScript(const CScript &scriptPubKey, CAssetTransfer &assetTransfer, std::string &strAddress)
Get specific asset type metadata from the given scripts.
Definition: assets.cpp:638
bool FundTransaction(CMutableTransaction &tx, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, bool lockUnspents, const std::set< int > &setSubtractFeeFromOutputs, CCoinControl)
Insert additional inputs into the transaction by calling CreateTransaction();.
Definition: wallet.cpp:3011
int Height() const
Return the maximal height in the chain.
Definition: chain.h:479
uint256 hashBlock
Definition: wallet.h:212
FeeReason reason
Definition: fees.h:129
const std::string & GetAccountName(const CScript &scriptPubKey) const
Definition: wallet.cpp:3870
CCriticalSection cs_main
Global state.
Definition: validation.cpp:72
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:402
void ConstructTransaction(CScript &script) const
Definition: assets.cpp:1555
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition: secure.h:57
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
Definition: standard.cpp:363
int64_t nOrderPos
position in ordered transaction list
Definition: wallet.h:337
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
Definition: keystore.h:107
A signature creator for transactions.
Definition: sign.h:35
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/raven/bips/blob/master/bip-0013.mediawiki.
Definition: keystore.cpp:40
std::string StringForFeeReason(FeeReason reason)
Definition: fees.cpp:33
bool HasSelected() const
Definition: coincontrol.h:61
void GetStrongRandBytes(unsigned char *out, int num)
Function to gather random data from multiple sources, failing whenever any of those source fail to pr...
Definition: random.cpp:318
void AddToSpends(const COutPoint &outpoint, const uint256 &wtxid)
Definition: wallet.cpp:572
CBlockIndex * ScanForWalletTransactions(CBlockIndex *pindexStart, CBlockIndex *pindexStop, bool fUpdate=false)
Scan the block chain (starting in pindexStart) for transactions from or to us.
Definition: wallet.cpp:1627
bool SetMaxVersion(int nVersion)
change which version we&#39;re allowed to upgrade to (note that this does not immediately imply upgrading...
Definition: wallet.cpp:464
isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey, SigVersion sigversion)
Definition: ismine.cpp:32
std::set< txiter, CompareIteratorByHash > setEntries
Definition: txmempool.h:499
uint8_t isminefilter
used for bitflags of isminetype
Definition: ismine.h:30
void ConstructTransaction(CScript &script) const
Definition: assets.cpp:1581
int64_t nTimeFirstKey
Definition: wallet.h:731
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
Definition: chain.h:443
void scheduleEvery(Function f, int64_t deltaMilliSeconds)
Definition: scheduler.cpp:127
boost::signals2::signal< void(CWallet *wallet)> LoadWallet
A wallet has been loaded.
Definition: ui_interface.h:96
void ListAccountCreditDebit(const std::string &strAccount, std::list< CAccountingEntry > &acentries)
Definition: walletdb.cpp:182
std::map< CTxDestination, std::vector< COutput > > ListAssets() const
Return list of available assets and locked assets grouped by non-change output address.
Definition: wallet.cpp:2373
void MarkDirty()
make sure balances are recalculated
Definition: wallet.h:444
CChainParams defines various tweakable parameters of a given instance of the Raven system...
Definition: chainparams.h:48
bool SetMinVersion(enum WalletFeature, CWalletDB *pwalletdbIn=nullptr, bool fExplicit=false)
signify that a particular wallet feature is now used. this may change nWalletVersion and nWalletMaxVe...
Definition: wallet.cpp:438
unsigned int GetKeyPoolSize()
Definition: wallet.h:1101
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:470
bool Decrypt(const std::vector< unsigned char > &vchCiphertext, CKeyingMaterial &vchPlaintext) const
Definition: crypter.cpp:93
CWalletKey(int64_t nExpires=0)
todo: add something to note what created it (user, getnewaddress, change) maybe should have a map<str...
Definition: wallet.cpp:4749
uint160 Hash160(const T1 pbegin, const T1 pend)
Compute the 160-bit hash an object.
Definition: hash.h:208
bool ErasePurpose(const std::string &strAddress)
Definition: walletdb.cpp:45
bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry &acentry)
This writes directly to the database, and will not update the CWallet&#39;s cached accounting entries! Us...
Definition: walletdb.cpp:165
std::string strName
Definition: assettypes.h:190
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Definition: crypter.cpp:230
#define PACKAGE_NAME
Definition: raven-config.h:350
const unsigned char * begin() const
Definition: key.h:84
bool MarkReplaced(const uint256 &originalHash, const uint256 &newHash)
Mark a transaction as replaced by another transaction (e.g., BIP 125).
Definition: wallet.cpp:855
DBErrors
Error statuses for the wallet database.
Definition: walletdb.h:50
bool ReissueAssetFromScript(const CScript &scriptPubKey, CReissueAsset &reissue, std::string &strAddress)
Definition: assets.cpp:789
CAmount GetUnconfirmedWatchOnlyBalance() const
Definition: wallet.cpp:2071
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Definition: wallet.cpp:3921
bool EncryptWallet(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:594
bool GetDestData(const CTxDestination &dest, const std::string &key, std::string *value) const
Look up a destination data tuple in the store, return true if found false otherwise.
Definition: wallet.cpp:4499
unsigned char * begin()
Definition: uint256.h:57
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:436
bool CreateTransactionAll(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, const CCoinControl &coin_control, bool fNewAsset, const CNewAsset &asset, const CTxDestination dest, bool fTransferAsset, bool fReissueAsset, const CReissueAsset &reissueAsset, const AssetType &assetType, bool sign=true)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
Definition: wallet.cpp:3100
double withinTarget
Definition: fees.h:111
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
Definition: sign.cpp:179
std::set< uint256 > GetConflicts(const uint256 &txid) const
Get wallet transactions that conflict with given transaction (spend same outputs) ...
Definition: wallet.cpp:476
void ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
Definition: wallet.cpp:3995
CAmount GetImmatureWatchOnlyCredit(const bool &fUseCache=true) const
Definition: wallet.cpp:1853
bool IsSpent(const uint256 &hash, unsigned int n) const
Outpoint is spent if any non-conflicted transaction spends it:
Definition: wallet.cpp:553
double GuessVerificationProgress(const ChainTxData &data, CBlockIndex *pindex)
Guess how far we are in the verification process at the given block index.
bool IsChange(const CTxOut &txout) const
Definition: wallet.cpp:1296
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:143
bool IsNull() const
Definition: uint256.h:33
CAmount GetImmatureCredit(bool fUseCache=true) const
Definition: wallet.cpp:1809
bool operator()(const CInputCoin &t1, const CInputCoin &t2) const
Definition: wallet.cpp:77
void PushInventory(const CInv &inv)
Definition: net.h:820
void SyncTransaction(const CTransactionRef &tx, const CBlockIndex *pindex=nullptr, int posInBlock=0)
Definition: wallet.cpp:1191
bool AddWatchOnly(const CScript &dest) override
Private version of AddWatchOnly method which does not accept a timestamp, and which will reset the wa...
Definition: wallet.cpp:332
Coin Control Features.
Definition: coincontrol.h:17
CAmount GetBalance() const
Definition: wallet.cpp:2010
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet) ...
Definition: wallet.cpp:288
const std::vector< CTxIn > vin
Definition: transaction.h:287
std::map< CTxDestination, CAmount > GetAddressBalances()
Definition: wallet.cpp:4105
std::string ToString() const
Definition: wallet.cpp:93
bool WriteOrderPosNext(int64_t nOrderPosNext)
Definition: walletdb.cpp:129
void BlockDisconnected(const std::shared_ptr< const CBlock > &pblock) override
Notifies listeners of a block being disconnected.
Definition: wallet.cpp:1231
int desiredTarget
Definition: fees.h:130
RVN START.
Definition: wallet.h:191
bool IsUnspendable() const
Returns whether the script is guaranteed to fail at execution, regardless of the initial stack...
Definition: script.cpp:449
mapValue_t mapValue
Key/value map with information about the transaction.
Definition: wallet.h:316
bool GetAssetData(const CScript &script, CAssetOutputEntry &data)
Definition: assets.cpp:3440
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: txmempool.h:68
bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< CTxDestination > &addressRet, int &nRequiredRet)
Parse a standard scriptPubKey with one or more destination addresses.
Definition: standard.cpp:251
void operator()(const CNoDestination &none)
Definition: wallet.cpp:127
CDBEnv bitdb
Definition: db.cpp:62
void KeepKey(int64_t nIndex)
Definition: wallet.cpp:4033
int64_t CAmount
Amount in corbies (Can be negative)
Definition: amount.h:13
bool IsAssetSelected(const COutPoint &output) const
Definition: coincontrol.h:76
std::multimap< int64_t, TxPair > TxItems
Definition: wallet.h:822
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Add a key to the store.
Definition: crypter.cpp:208
void MarkReserveKeysAsUsed(int64_t keypool_id)
Marks all keys in the keypool up to and including reserve_key as used.
Definition: wallet.cpp:4287
uint256 GetBlockHash() const
Definition: chain.h:294
#define AssertLockHeld(cs)
Definition: sync.h:86
bool CreateTransaction(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, const CCoinControl &coin_control, bool sign=true)
Definition: wallet.cpp:3089
void SetBroadcastTransactions(bool broadcast)
Set whether this wallet broadcasts transactions.
Definition: wallet.h:1150
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:3832
CBlockPolicyEstimator feeEstimator
Definition: validation.cpp:109
void MarkConflicted(const uint256 &hashBlock, const uint256 &hashTx)
Definition: wallet.cpp:1130
bool AreMessagingDeployed()
void MarkDirty()
Definition: wallet.cpp:846
std::string strComment
Definition: wallet.h:597
DBErrors ReorderTransactions()
Definition: wallet.cpp:685
#define LOCK2(cs1, cs2)
Definition: sync.h:177
size_t KeypoolCountExternalKeys()
Definition: wallet.cpp:3915
bool DelAddressBook(const CTxDestination &address)
Definition: wallet.cpp:3850
unsigned int nTxConfirmTarget
Definition: wallet.cpp:47
An instance of this class represents one database.
Definition: db.h:94
int64_t nTime
Definition: wallet.h:110
#define LogPrintf(...)
Definition: util.h:149
static CFeeRate m_discard_rate
Definition: wallet.h:1037
bool CheckFinalTx(const CTransaction &tx, int flags)
Transaction validation functions.
Definition: validation.cpp:255
unsigned int ComputeTimeSmart(const CWalletTx &wtx) const
Compute smart timestamp for a transaction being added to the wallet.
Definition: wallet.cpp:4433
bool CreateTransactionWithReissueAsset(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, const CCoinControl &coin_control, const CReissueAsset &reissueAsset, const CTxDestination destination, bool sign=true)
Definition: wallet.cpp:3081
int GetDepthInMainChain() const
Definition: wallet.h:268
bool AbandonTransaction(const uint256 &hashTx)
Definition: wallet.cpp:1069
DBErrors LoadWallet(bool &fFirstRunRet)
Definition: wallet.cpp:3749
void UnlockCoin(const COutPoint &output)
Definition: wallet.cpp:4329
bool AreAssetsDeployed()
RVN START.
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
Definition: walletdb.cpp:840
bool WritePool(int64_t nPool, const CKeyPool &keypool)
Definition: walletdb.cpp:139
bool AcceptToMemoryPool(CTxMemPool &pool, CValidationState &state, const CTransactionRef &tx, bool *pfMissingInputs, std::list< CTransactionRef > *plTxnReplaced, bool bypass_limits, const CAmount nAbsurdFee)
(try to) add transaction to memory pool plTxnReplaced will be appended to with all transactions repla...
uint64_t nEntryNo
Definition: wallet.h:600
CPubKey GenerateNewKey(CWalletDB &walletdb, bool internal=false)
keystore implementation Generate a new key
Definition: wallet.cpp:139
void TransactionAddedToMempool(const CTransactionRef &tx) override
Notifies listeners of a transaction having been added to mempool.
Definition: wallet.cpp:1208
double end
Definition: fees.h:110
CTransactionRef tx
Definition: wallet.h:211
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
Definition: validation.cpp:104
EstimatorBucket fail
Definition: fees.h:121
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
Definition: wallet.cpp:3889
isminetype
IsMine() return codes.
Definition: ismine.h:18
An input of a transaction.
Definition: transaction.h:67
bool fWalletRbf
Definition: wallet.cpp:49
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/raven/bips/blob/master/bip-0013.mediawiki.
Definition: wallet.cpp:309
bool SelectAssets(const std::map< std::string, std::vector< COutput > > &mapAvailableAssets, const std::map< std::string, CAmount > &mapAssetTargetValue, std::set< CInputCoin > &setCoinsRet, std::map< std::string, CAmount > &nValueRet) const
Definition: wallet.cpp:2930
bool IsHDEnabled() const
Definition: wallet.cpp:1453
#define LOCK(cs)
Definition: sync.h:176
bool InMempool() const
Definition: wallet.cpp:1905
bool WriteName(const std::string &strAddress, const std::string &strName)
Definition: walletdb.cpp:28
DBErrors LoadWallet(CWallet *pwallet)
Definition: walletdb.cpp:532
const uint256 & GetHash() const
Definition: transaction.h:320
CKeyPool()
Definition: wallet.cpp:4736
void SetBestChain(const CBlockLocator &loc) override
Notifies listeners of the new active block chain on-disk.
Definition: wallet.cpp:432
std::string assetName
Definition: wallet.h:194
void operator()(const CScriptID &scriptId)
Definition: wallet.cpp:121
CTxDestination destChange
Definition: coincontrol.h:20
const uint32_t BIP32_HARDENED_KEY_LIMIT
Definition: wallet.cpp:52
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:466
bool SelectCoins(const std::vector< COutput > &vAvailableCoins, const CAmount &nTargetValue, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet, const CCoinControl *coinControl=nullptr) const
Select a set of coins such that nValueRet >= nTargetValue and at least all coins from coinControl are...
Definition: wallet.cpp:2686
bool IsValid() const
Definition: pubkey.h:159
Fast randomness source.
Definition: random.h:45
virtual bool HaveKey(const CKeyID &address) const =0
Check whether a key corresponding to a given address is present in the store.
void Select(const COutPoint &output)
Definition: coincontrol.h:81
uint256 uint256S(const char *str)
Definition: uint256.h:150
CBlockIndex * FindEarliestAtLeast(int64_t nTime) const
Find the earliest block with timestamp equal or greater than the given.
Definition: chain.cpp:63
An encapsulated public key.
Definition: pubkey.h:40
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
Definition: coincontrol.h:22
bool Unlock(const CKeyingMaterial &vMasterKeyIn)
Definition: crypter.cpp:170
bool TransactionCanBeAbandoned(const uint256 &hashTx) const
Return whether transaction can be abandoned.
Definition: wallet.cpp:1062
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
Definition: chain.h:471
bool IsLockedCoin(uint256 hash, unsigned int n) const
Definition: wallet.cpp:4341
void AvailableCoins(std::vector< COutput > &vCoins, bool fOnlySafe=true, const CCoinControl *coinControl=nullptr, const CAmount &nMinimumAmount=1, const CAmount &nMaximumAmount=MAX_MONEY, const CAmount &nMinimumSumAmount=MAX_MONEY, const uint64_t &nMaximumCount=0, const int &nMinDepth=0, const int &nMaxDepth=9999999) const
populate vCoins with vector of available COutputs.
Definition: wallet.cpp:2159
std::string GetRejectReason() const
Definition: validation.h:92
uint32_t n
Definition: transaction.h:26
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
Definition: key.cpp:127
const std::vector< CTxOut > vout
Definition: transaction.h:288
bool IsCoinBase() const
Definition: wallet.h:278
bool CreateNewChangeAddress(CReserveKey &reservekey, CKeyID &keyID, std::string &strFailReason)
RVN START.
Definition: wallet.cpp:2756
CAmount GetUnconfirmedBalance() const
Definition: wallet.cpp:2026
double inMempool
Definition: fees.h:113
int64_t GetBlockTimeMax() const
Definition: chain.h:304
int GetBlocksToMaturity() const
Definition: wallet.cpp:4783
CAmount GetImmatureWatchOnlyBalance() const
Definition: wallet.cpp:2086
CAmount GetLegacyBalance(const isminefilter &filter, int minDepth, const std::string *account) const
Definition: wallet.cpp:2106
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
Definition: walletdb.cpp:835
void Flush(bool shutdown=false)
Flush wallet (bitdb flush)
Definition: wallet.cpp:506
bool EraseDestData(const CTxDestination &dest, const std::string &key)
Erases a destination data tuple in the store and on disk.
Definition: wallet.cpp:4486
void UpdateTimeFirstKey(int64_t nCreateTime)
Update wallet first key creation time.
Definition: wallet.cpp:297
bool IsTrusted() const
Definition: wallet.cpp:1911
void MaybeCompactWalletDB()
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
Definition: walletdb.cpp:757
void ResendWalletTransactions(int64_t nBestBlockTime, CConnman *connman) override
Tells listeners to broadcast their data.
Definition: wallet.cpp:1976
bool GetReservedKey(CPubKey &pubkey, bool internal=false)
Definition: wallet.cpp:4252
bool CreateTransactionWithAssets(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, const CCoinControl &coin_control, const std::vector< CNewAsset > assets, const CTxDestination destination, const AssetType &assetType, bool sign=true)
RVN START.
Definition: wallet.cpp:3064
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
Definition: wallet.cpp:3779
bool exists(uint256 hash) const
Definition: txmempool.h:660
unsigned int size() const
Simple read-only vector-like interface.
Definition: key.h:83
Definition: net.h:120
bool OwnerAssetFromScript(const CScript &scriptPubKey, std::string &assetName, std::string &strAddress)
Definition: assets.cpp:764
An output of a transaction.
Definition: transaction.h:137
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:75
bool CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents=true) const
Try to calculate all in-mempool ancestors of entry.
Definition: txmempool.cpp:154
std::string ToString() const
Definition: uint256.cpp:63
bool AddToWalletIfInvolvingMe(const CTransactionRef &tx, const CBlockIndex *pIndex, int posInBlock, bool fUpdate)
Add a transaction to the wallet, or update it.
Definition: wallet.cpp:1003
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Raven scriptPubKey for the given CTxDestination.
Definition: standard.cpp:347
bool SelectAssetsMinConf(const CAmount &nTargetValue, const int nConfMine, const int nConfTheirs, const uint64_t nMaxAncestors, const std::string &strAssetName, std::vector< COutput > vCoins, std::set< CInputCoin > &setCoinsRet, CAmount &nValueRet) const
Definition: wallet.cpp:2781
bool LoadToWallet(const CWalletTx &wtxIn)
Definition: wallet.cpp:968
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:22
int64_t nCreateTime
Definition: walletdb.h:101
std::vector< CTxOut > vout
Definition: transaction.h:392
bool ErasePool(int64_t nPool)
Definition: walletdb.cpp:144
bool EraseWatchOnly(const CScript &script)
Definition: walletdb.cpp:109
unsigned int fTimeReceivedIsTxTime
Definition: wallet.h:318
static CWallet * CreateWalletFromFile(const std::string walletFile)
Definition: wallet.cpp:4529
bool IsAllFromMe(const CTransaction &tx, const isminefilter &filter) const
Returns whether all of the inputs match the filter.
Definition: wallet.cpp:1350
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
CAmount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
Definition: policy.cpp:19
void ForEachNode(Callable &&func)
Definition: net.h:185
bool RemoveWatchOnly(const CScript &dest) override
Definition: keystore.cpp:94
void SetSeed(const unsigned char *seed, unsigned int nSeedLen)
Definition: key.cpp:245
void LockCoin(const COutPoint &output)
Definition: wallet.cpp:4323
bool AddToWallet(const CWalletTx &wtxIn, bool fFlushOnClose=true)
Definition: wallet.cpp:884
const CTxOut & FindNonChangeParentOutput(const CTransaction &tx, int output) const
Find non-change parent output.
Definition: wallet.cpp:2471
CCriticalSection cs
Definition: txmempool.h:468
Access to the wallet database.
Definition: walletdb.h:142
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:285
DBErrors ZapWalletTx(std::vector< CWalletTx > &vWtx)
Definition: walletdb.cpp:740
CFeeRate minRelayTxFeeV2
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
Definition: validation.cpp:107
void RegisterValidationInterface(CValidationInterface *pwalletIn)
Register a wallet to receive updates from core.
bool ReadBestBlock(CBlockLocator &locator)
Definition: walletdb.cpp:123
CAmount GetWatchOnlyBalance() const
Definition: wallet.cpp:2055
AssetType
Definition: assettypes.h:21
bool TransactionWithinChainLimit(const uint256 &txid, size_t chainLimit) const
Returns false if the transaction is in the mempool and not within the chain limit specified...
Definition: txmempool.cpp:1432
int64_t RescanFromTime(int64_t startTime, bool update)
Scan active chain for relevant transactions after importing keys.
Definition: wallet.cpp:1595
CPubKey vchPubKey
Definition: wallet.h:1231
void KeepKey()
Definition: wallet.cpp:4270
bool IsScriptTransferAsset(const CScript &scriptPubKey)
Check script and see if it matches the transfer asset template.
Definition: assets.cpp:3202
CAmount nAmount
Definition: assettypes.h:240
#define LogPrint(category,...)
Definition: util.h:160
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
Definition: walletdb.cpp:846
CPubKey DeriveNewSeed(const CKey &key)
Definition: wallet.cpp:1402
CAmount GetAvailableCredit(bool fUseCache=true) const
Definition: wallet.cpp:1823
bool HasAssetSelected() const
Definition: coincontrol.h:66
txnouttype
Definition: standard.h:57
RVN END.
Definition: validation.h:30
std::vector< uint256 > ResendWalletTransactionsBefore(int64_t nTime, CConnman *connman)
Definition: wallet.cpp:1951
bool WriteBestBlock(const CBlockLocator &locator)
Definition: walletdb.cpp:117
256-bit opaque blob.
Definition: uint256.h:123
CPubKey vchPubKey
Definition: wallet.h:111
std::set< CTxDestination > GetAccountAddresses(const std::string &strAccount) const
Definition: wallet.cpp:4238
const unsigned int WALLET_CRYPTO_SALT_SIZE
Definition: crypter.h:16
void AvailableAssets(std::map< std::string, std::vector< COutput > > &mapAssetCoins, bool fOnlySafe=true, const CCoinControl *coinControl=nullptr, const CAmount &nMinimumAmount=1, const CAmount &nMaximumAmount=MAX_MONEY, const CAmount &nMinimumSumAmount=MAX_MONEY, const uint64_t &nMaximumCount=0, const int &nMinDepth=0, const int &nMaxDepth=9999999) const
Helper function that calls AvailableCoinsAll, used for transfering assets.
Definition: wallet.cpp:2165
CAssetsCache * passets
Global variable that point to the active assets (protected by cs_main)
Definition: validation.cpp:227
bool SetHDSeed(const CPubKey &key)
Definition: wallet.cpp:1429
ArgsManager gArgs
Definition: util.cpp:94
CAmount nAmount
Definition: assettypes.h:101
void GetScriptForMining(std::shared_ptr< CReserveScript > &script)
Definition: wallet.cpp:4310
static std::atomic< bool > fFlushScheduled
Definition: wallet.h:676
int vout
Definition: wallet.h:199
std::vector< CTransactionRef > vtx
Definition: block.h:77
const ChainTxData & TxData() const
Definition: chainparams.h:80
bool InitError(const std::string &str)
Show error message.
std::map< CTxDestination, std::vector< COutput > > ListCoins() const
Return list of available coins and locked coins grouped by non-change output address.
Definition: wallet.cpp:2425
bool randbool()
Generate a random boolean.
Definition: random.h:124
std::string EncodeDestination(const CTxDestination &dest)
Definition: base58.cpp:326
DBErrors ZapWalletTx(std::vector< CWalletTx > &vWtx)
Definition: wallet.cpp:3808
static CFeeRate fallbackFee
If fee estimation does not have enough data to provide estimates, use this fee instead.
Definition: wallet.h:1036
CAmount GetDebit(const CTxIn &txin, const isminefilter &filter) const
Returns amount of debit if the input matches the filter, otherwise returns 0.
Definition: wallet.cpp:1256
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
Definition: wallet.cpp:386
CAmount GetCredit(const isminefilter &filter) const
Definition: wallet.cpp:1776
int64_t GetTxTime() const
Definition: wallet.cpp:1458
A key allocated from the key pool.
Definition: wallet.h:1193
bool LoadKeyMetadata(const CTxDestination &pubKey, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
Definition: wallet.cpp:280
void SyncMetaData(std::pair< TxSpends::iterator, TxSpends::iterator >)
Definition: wallet.cpp:511
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:172
const CChainParams & Params()
Return the currently selected parameters.
bool ReadPool(int64_t nPool, CKeyPool &keypool)
Definition: walletdb.cpp:134
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:396
CAmount GetAccountCreditDebit(const std::string &strAccount)
Definition: walletdb.cpp:170
bool IsSelected(const COutPoint &output) const
Definition: coincontrol.h:71
bool TopUpKeyPool(unsigned int kpSize=0)
Definition: wallet.cpp:3940
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret) override
Adds an encrypted key to the store, and saves it to disk.
Definition: wallet.cpp:262
int64_t GetTimeMillis()
Definition: utiltime.cpp:40
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet...
Definition: wallet.h:329
void BlockConnected(const std::shared_ptr< const CBlock > &pblock, const CBlockIndex *pindex, const std::vector< CTransactionRef > &vtxConflicted) override
Notifies listeners of a block being connected.
Definition: wallet.cpp:1213
void ListAccountCreditDebit(const std::string &strAccount, std::list< CAccountingEntry > &entries)
Definition: wallet.cpp:3724
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: util.cpp:454
A virtual base class for key stores.
Definition: keystore.h:19
bool RelayWalletTransaction(CConnman *connman)
Definition: wallet.cpp:1711
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
Definition: validation.cpp:204
int64_t GetAdjustedTime()
Definition: timedata.cpp:36
void runCommand(const std::string &strCommand)
Definition: util.cpp:841
void AvailableCoinsWithAssets(std::vector< COutput > &vCoins, std::map< std::string, std::vector< COutput > > &mapAssetCoins, bool fOnlySafe=true, const CCoinControl *coinControl=nullptr, const CAmount &nMinimumAmount=1, const CAmount &nMaximumAmount=MAX_MONEY, const CAmount &nMinimumSumAmount=MAX_MONEY, const uint64_t &nMaximumCount=0, const int &nMinDepth=0, const int &nMaxDepth=9999999) const
Helper function that calls AvailableCoinsAll, used to receive all coins, Assets and RVN...
Definition: wallet.cpp:2178
double leftMempool
Definition: fees.h:114
RVN START.
Definition: standard.h:69
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:30
Internal transfers.
Definition: wallet.h:590
bool ContextualCheckVerifierString(CAssetsCache *cache, const std::string &verifier, const std::string &check_address, std::string &strError, bool fWithTags)
Definition: assets.cpp:4979
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:448
std::string GetHex() const
Definition: uint256.cpp:22
bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew=false)
Definition: wallet.cpp:808
static CFeeRate minTxFee
Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) Override with ...
Definition: wallet.h:1035
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:673
void operator()(const CKeyID &keyId)
Definition: wallet.cpp:116
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:20
bool SetHDChain(const CHDChain &chain, bool memonly)
Definition: wallet.cpp:1443
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
Definition: chain.cpp:24
bool LoadCScript(const CScript &redeemScript)
Definition: wallet.cpp:316
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE)
Transaction fee set by the user.
std::vector< unsigned char > vchSalt
Definition: crypter.h:39
bool error(const char *fmt, const Args &... args)
Definition: util.h:168
Definition: wallet.h:183
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:818
static const int VERSION_HD_CHAIN_SPLIT
Definition: walletdb.h:69
bool CreateTransactionWithTransferAsset(const std::vector< CRecipient > &vecSend, CWalletTx &wtxNew, CReserveKey &reservekey, CAmount &nFeeRet, int &nChangePosInOut, std::string &strFailReason, const CCoinControl &coin_control, bool sign=true)
Definition: wallet.cpp:3071
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:23
bool GetKeyFromPool(CPubKey &key, bool internal=false)
Definition: wallet.cpp:4056
std::vector< CKeyID > & vKeys
Definition: wallet.cpp:101
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
Definition: policy.cpp:53
A mutable version of CTransaction.
Definition: transaction.h:389
size_type size() const
Definition: prevector.h:283
double totalConfirmed
Definition: fees.h:112
Indicates that we know how to create a scriptSig that would solve this if we were given the appropria...
Definition: ismine.h:24
void ReturnKey()
Definition: wallet.cpp:4278
bool GetAssetVerifierStringIfExists(const std::string &name, CNullAssetTxVerifierString &verifier, bool fSkipTempCache=false)
Returns true if the Asset Verifier String was found for an asset_name, if fSkipTempCache is true...
Definition: assets.cpp:4445
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
Definition: utiltime.cpp:20
bool CheckForAddressRestriction(const std::string &restricted_name, const std::string &address, bool fSkipTempCache=false)
Return true if the address is marked as frozen.
Definition: assets.cpp:4593
unsigned int nTimeReceived
time received by this node
Definition: wallet.h:319
void InitWarning(const std::string &str)
Show warning message.
An encapsulated private key.
Definition: key.h:36
bool EraseName(const std::string &strAddress)
Definition: walletdb.cpp:33
CClientUIInterface uiInterface
Definition: ui_interface.cpp:9
CAmount nAmount
Definition: wallet.h:196
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:270
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:185
bool AddDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
Adds a destination data tuple to the store, and saves it to disk.
Definition: wallet.cpp:4477
Information about a peer.
Definition: net.h:596
CKeyID hd_seed_id
Definition: walletdb.h:103
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const
Definition: wallet.cpp:4349
CAmount GetAvailableWatchOnlyCredit(const bool &fUseCache=true) const
Definition: wallet.cpp:1867
CAmount GetCredit(const CTxOut &txout, const isminefilter &filter) const
Definition: wallet.cpp:1289
unsigned int nDeriveIterations
Definition: crypter.h:43
full block available in blk*.dat
Definition: chain.h:156
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
Definition: walletdb.cpp:96
isminetype IsMine(const CTxIn &txin) const
Definition: wallet.cpp:1241
bool hashUnset() const
Definition: wallet.h:273
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
Definition: walletdb.cpp:40
CTxDestination destination
Definition: wallet.h:195
std::pair< CWalletTx *, CAccountingEntry * > TxPair
Definition: wallet.h:821
CKeyID seed_id
seed hash160
Definition: walletdb.h:66
bool BackupWallet(const std::string &strDest)
Definition: wallet.cpp:4731
bool AddAccountingEntry(const CAccountingEntry &)
Definition: wallet.cpp:3729
COutPoint prevout
Definition: transaction.h:70
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
Definition: walletdb.cpp:702
std::string strOtherAccount
Definition: wallet.h:596
void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey &pubkey)
Definition: wallet.cpp:4041
bool AcceptToMemoryPool(const CAmount &nAbsurdFee, CValidationState &state)
Pass this transaction to the mempool.
Definition: wallet.cpp:4791
int nVersion
Definition: walletdb.h:71
int GetDepthInMainChain(const CBlockIndex *&pindexRet) const
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
Definition: wallet.cpp:4764
BlockMap mapBlockIndex
Definition: validation.cpp:74
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
Definition: walletdb.cpp:101
CAmount GetMinimumFee(unsigned int nTxBytes, const CCoinControl &coin_control, const CTxMemPool &pool, const CBlockPolicyEstimator &estimator, FeeCalculation *feeCalc)
Estimate the minimum fee considering user set parameters and the required fee.
Definition: fees.cpp:23
CAmount nAmount
Definition: assettypes.h:191
bool ReadAccount(const std::string &strAccount, CAccount &account)
Definition: walletdb.cpp:154
bool fInternal
Definition: wallet.h:112
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:201
bool operator()(const std::pair< CInputCoin, CAmount > &t1, const std::pair< CInputCoin, CAmount > &t2) const
Definition: wallet.cpp:86
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
Definition: wallet.cpp:361
static const int VERSION_HD_BASE
Definition: walletdb.h:68
CAmount nCreditDebit
Definition: wallet.h:594
int64_t nTime
Definition: wallet.h:595
CAmount GetChange(const CTxOut &txout) const
Definition: wallet.cpp:1318
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Definition: util.h:66
CTxOut txout
Definition: wallet.h:513
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
Definition: ui_interface.h:82
CAmount GetChange() const
Definition: wallet.cpp:1896
bool RemoveWatchOnly(const CScript &dest) override
Definition: wallet.cpp:348
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const =0
CPubKey GenerateNewSeed()
Definition: wallet.cpp:1395
uint64_t GetRand(uint64_t nMax)
Definition: random.cpp:353
CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector< CKeyID > &vKeysIn)
Definition: wallet.cpp:104
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:60
bool Unlock(const SecureString &strWalletPassphrase)
Definition: wallet.cpp:366
int GetRequestCount() const
Definition: wallet.cpp:1464
bool IsAssetNameAnRestricted(const std::string &name)
Check if an asset is a restricted asset.
Definition: assets.cpp:301
bool AddWatchOnly(const CScript &dest) override
Support for Watch-only addresses.
Definition: keystore.cpp:84
A key pool entry.
Definition: wallet.h:107
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:45
const CKeyStore & keystore
Definition: wallet.cpp:100
std::vector< std::pair< std::string, std::string > > vOrderForm
Definition: wallet.h:317
bool HasWalletSpend(const uint256 &txid) const
Check if a given transaction has any of its outputs spent by another transaction in the wallet...
Definition: wallet.cpp:499
bool IsAssetScript(int &nType, bool &fIsOwner, int &nStartingIndex) const
Definition: script.cpp:245
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
Definition: feerate.cpp:24
bool isAbandoned() const
Definition: wallet.h:274
uint256 hash
Definition: transaction.h:25
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, CConnman *connman, CValidationState &state)
RVN END.
Definition: wallet.cpp:3683
void GetAmounts(std::list< COutputEntry > &listReceived, std::list< COutputEntry > &listSent, CAmount &nFee, std::string &strSentAccount, const isminefilter &filter) const
Definition: wallet.cpp:1503
CFeeRate dustRelayFee
Definition: policy.cpp:263
double decay
Definition: fees.h:122
std::string strAccount
Definition: wallet.h:593