38 #include <boost/algorithm/string/replace.hpp> 39 #include <boost/thread.hpp> 86 bool operator()(
const std::pair<CInputCoin, CAmount>& t1,
87 const std::pair<CInputCoin, CAmount>& t2)
const 89 return t1.second < t2.second;
95 return strprintf(
"COutput(%s, %d, %d) [%s]", tx->GetHash().ToString(), i, nDepth,
FormatMoney(tx->tx->vout[i].nValue));
108 std::vector<CTxDestination> vDest;
112 boost::apply_visitor(*
this, dest);
118 vKeys.push_back(keyId);
133 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(hash);
134 if (it == mapWallet.end())
136 return &(it->second);
147 int64_t nCreationTime =
GetTime();
152 DeriveNewChildKey(walletdb, metadata, secret, (CanSupportFeature(
FEATURE_HD_SPLIT) ?
internal :
false));
165 mapKeyMetadata[pubkey.
GetID()] = metadata;
166 UpdateTimeFirstKey(nCreationTime);
168 if (!AddKeyPubKeyWithDB(walletdb, secret, pubkey)) {
169 throw std::runtime_error(std::string(__func__) +
": AddKey failed");
184 if (!GetKey(hdChain.seed_id, seed))
185 throw std::runtime_error(std::string(__func__) +
": seed not found");
204 metadata.
hdKeypath =
"m/0'/1'/" + std::to_string(hdChain.nInternalChainCounter) +
"'";
205 hdChain.nInternalChainCounter++;
209 metadata.
hdKeypath =
"m/0'/0'/" + std::to_string(hdChain.nExternalChainCounter) +
"'";
210 hdChain.nExternalChainCounter++;
213 secret = childKey.
key;
217 throw std::runtime_error(std::string(__func__) +
": Writing HD chain model failed");
227 bool needsDB = !pwalletdbEncryption;
229 pwalletdbEncryption = &walletdb;
232 if (needsDB) pwalletdbEncryption =
nullptr;
235 if (needsDB) pwalletdbEncryption =
nullptr;
240 if (HaveWatchOnly(script)) {
241 RemoveWatchOnly(script);
244 if (HaveWatchOnly(script)) {
245 RemoveWatchOnly(script);
251 mapKeyMetadata[pubkey.
GetID()]);
263 const std::vector<unsigned char> &vchCryptedSecret)
269 if (pwalletdbEncryption)
270 return pwalletdbEncryption->WriteCryptedKey(vchPubKey,
272 mapKeyMetadata[vchPubKey.
GetID()]);
276 mapKeyMetadata[vchPubKey.
GetID()]);
284 mapKeyMetadata[keyID] = meta;
300 if (nCreateTime <= 1) {
304 }
else if (!nTimeFirstKey || nCreateTime < nTimeFirstKey) {
305 nTimeFirstKey = nCreateTime;
321 if (redeemScript.
size() > MAX_SCRIPT_ELEMENT_SIZE)
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);
338 NotifyWatchonlyChanged(
true);
344 mapKeyMetadata[
CScriptID(dest)].nCreateTime = nCreateTime;
345 return AddWatchOnly(dest);
353 if (!HaveWatchOnly())
354 NotifyWatchonlyChanged(
false);
373 for (
const MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
375 if(!crypter.
SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
377 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
388 bool fWasLocked = IsLocked();
396 for (MasterKeyMap::value_type& pMasterKey : mapMasterKeys)
398 if(!crypter.
SetKeyFromPassphrase(strOldWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
400 if (!crypter.
Decrypt(pMasterKey.second.vchCryptedKey, _vMasterKey))
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))));
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;
412 if (pMasterKey.second.nDeriveIterations < 25000)
413 pMasterKey.second.nDeriveIterations = 25000;
415 LogPrintf(
"Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
417 if (!crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
419 if (!crypter.
Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
441 if (nWalletVersion >= nVersion)
445 if (fExplicit && nVersion > nWalletMaxVersion)
448 nWalletVersion = nVersion;
450 if (nVersion > nWalletMaxVersion)
451 nWalletMaxVersion = nVersion;
455 if (nWalletVersion > 40000)
468 if (nWalletVersion > nVersion)
471 nWalletMaxVersion = nVersion;
478 std::set<uint256> result;
481 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(txid);
482 if (it == mapWallet.end())
486 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
488 for (
const CTxIn& txin : wtx.
tx->vin)
490 if (mapTxSpends.count(txin.
prevout) <= 1)
492 range = mapTxSpends.equal_range(txin.
prevout);
493 for (TxSpends::const_iterator _it = range.first; _it != range.second; ++_it)
494 result.insert(_it->second);
502 auto iter = mapTxSpends.lower_bound(
COutPoint(txid, 0));
503 return (iter != mapTxSpends.end() && iter->first.hash == txid);
508 dbw->Flush(shutdown);
517 int nMinOrderPos = std::numeric_limits<int>::max();
519 for (TxSpends::iterator it = range.first; it != range.second; ++it)
521 const uint256& hash = it->second;
522 int n = mapWallet[hash].nOrderPos;
523 if (n < nMinOrderPos)
526 copyFrom = &mapWallet[hash];
530 for (TxSpends::iterator it = range.first; it != range.second; ++it)
532 const uint256& hash = it->second;
534 if (copyFrom == copyTo)
continue;
535 assert(copyFrom &&
"Oldest wallet transaction in range assumed to have been found.");
556 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
557 range = mapTxSpends.equal_range(outpoint);
559 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
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()))
574 mapTxSpends.insert(std::make_pair(outpoint, wtxid));
576 std::pair<TxSpends::iterator, TxSpends::iterator> range;
577 range = mapTxSpends.equal_range(outpoint);
584 auto it = mapWallet.find(wtxid);
585 assert(it != mapWallet.end());
587 if (thisTx.IsCoinBase())
590 for (
const CTxIn& txin : thisTx.tx->vin)
591 AddToSpends(txin.
prevout, wtxid);
630 mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
631 assert(!pwalletdbEncryption);
632 pwalletdbEncryption =
new CWalletDB(*dbw);
633 if (!pwalletdbEncryption->TxnBegin()) {
634 delete pwalletdbEncryption;
635 pwalletdbEncryption =
nullptr;
638 pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
640 if (!EncryptKeys(_vMasterKey))
642 pwalletdbEncryption->TxnAbort();
643 delete pwalletdbEncryption;
652 if (!pwalletdbEncryption->TxnCommit()) {
653 delete pwalletdbEncryption;
659 delete pwalletdbEncryption;
660 pwalletdbEncryption =
nullptr;
663 Unlock(strWalletPassphrase);
667 if (!SetHDSeed(GenerateNewSeed())) {
680 NotifyStatusChanged(
this);
694 typedef std::pair<CWalletTx*, CAccountingEntry*>
TxPair;
695 typedef std::multimap<int64_t, TxPair >
TxItems;
698 for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
701 txByTime.insert(std::make_pair(wtx->
nTimeReceived, TxPair(wtx,
nullptr)));
703 std::list<CAccountingEntry> acentries;
707 txByTime.insert(std::make_pair(entry.nTime, TxPair(
nullptr, &entry)));
711 std::vector<int64_t> nOrderPosOffsets;
712 for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it)
714 CWalletTx *
const pwtx = (*it).second.first;
720 nOrderPos = nOrderPosNext++;
721 nOrderPosOffsets.push_back(nOrderPos);
734 int64_t nOrderPosOff = 0;
735 for (
const int64_t& nOffsetStart : nOrderPosOffsets)
737 if (nOrderPos >= nOffsetStart)
740 nOrderPos += nOrderPosOff;
741 nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
765 int64_t nRet = nOrderPosNext++;
784 debit.
nOrderPos = IncOrderPosNext(&walletdb);
790 AddAccountingEntry(debit, &walletdb);
794 credit.
nOrderPos = IncOrderPosNext(&walletdb);
800 AddAccountingEntry(credit, &walletdb);
821 for (std::map<uint256, CWalletTx>::iterator it = mapWallet.begin();
824 for (
const CTxOut& txout : (*it).second.tx->vout)
834 if (!GetKeyFromPool(account.
vchPubKey,
false))
850 for (std::pair<const uint256, CWalletTx>& item : mapWallet)
851 item.second.MarkDirty();
859 auto mi = mapWallet.find(originalHash);
862 assert(mi != mapWallet.end());
867 assert(wtx.mapValue.count(
"replaced_by_txid") == 0);
875 LogPrintf(
"%s: Updating walletdb tx %s failed", __func__, wtx.GetHash().ToString());
879 NotifyTransactionChanged(
this, originalHash,
CT_UPDATED);
888 CWalletDB walletdb(*dbw,
"r+", fFlushOnClose);
893 std::pair<std::map<uint256, CWalletTx>::iterator,
bool> ret = mapWallet.insert(std::make_pair(hash, wtxIn));
896 bool fInsertedNew = ret.second;
900 wtx.
nOrderPos = IncOrderPosNext(&walletdb);
901 wtxOrdered.insert(std::make_pair(wtx.
nOrderPos,
TxPair(&wtx,
nullptr)));
906 bool fUpdated =
false;
936 if (wtxIn.
tx->HasWitness() && !wtx.
tx->HasWitness()) {
943 LogPrintf(
"AddToWallet %s %s%s\n", wtxIn.
GetHash().
ToString(), (fInsertedNew ?
"new" :
""), (fUpdated ?
"update" :
""));
946 if (fInsertedNew || fUpdated)
957 std::string strCmd =
gArgs.
GetArg(
"-walletnotify",
"");
972 mapWallet[hash] = wtxIn;
975 wtxOrdered.insert(std::make_pair(wtx.
nOrderPos,
TxPair(&wtx,
nullptr)));
977 for (
const CTxIn& txin : wtx.
tx->vin) {
979 if (it != mapWallet.end()) {
1009 if (pIndex !=
nullptr) {
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);
1022 bool fExisted = mapWallet.count(tx.
GetHash()) != 0;
1023 if (fExisted && !fUpdate)
return false;
1024 if (fExisted ||
IsMine(tx) || IsFromMe(tx))
1035 std::vector<CKeyID> vAffected;
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);
1043 if (!TopUpKeyPool()) {
1044 LogPrintf(
"%s: Topping up keypool failed (locked wallet)\n", __func__);
1053 if (pIndex !=
nullptr)
1056 return AddToWallet(wtx,
false);
1065 const CWalletTx* wtx = GetWalletTx(hashTx);
1075 std::set<uint256> todo;
1076 std::set<uint256> done;
1079 auto it = mapWallet.find(hashTx);
1080 assert(it != mapWallet.end());
1082 if (origtx.GetDepthInMainChain() > 0 || origtx.InMempool()) {
1086 todo.insert(hashTx);
1088 while (!todo.empty()) {
1092 auto it = mapWallet.find(now);
1093 assert(it != mapWallet.end());
1097 assert(currentconfirm <= 0);
1099 if (currentconfirm == 0 && !wtx.isAbandoned()) {
1101 assert(!wtx.InMempool());
1106 NotifyTransactionChanged(
this, wtx.GetHash(),
CT_UPDATED);
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);
1117 for (
const CTxIn& txin : wtx.tx->vin)
1120 if (it != mapWallet.end()) {
1121 it->second.MarkDirty();
1134 int conflictconfirms = 0;
1145 if (conflictconfirms >= 0)
1151 std::set<uint256> todo;
1152 std::set<uint256> done;
1154 todo.insert(hashTx);
1156 while (!todo.empty()) {
1160 auto it = mapWallet.find(now);
1161 assert(it != mapWallet.end());
1164 if (conflictconfirms < currentconfirm) {
1168 wtx.hashBlock = hashBlock;
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);
1181 for (
const CTxIn& txin : wtx.tx->vin) {
1183 if (it != mapWallet.end()) {
1184 it->second.MarkDirty();
1194 if (!AddToWalletIfInvolvingMe(ptx, pindex, posInBlock,
true))
1202 if (it != mapWallet.end()) {
1203 it->second.MarkDirty();
1210 SyncTransaction(ptx);
1224 SyncTransaction(ptx);
1226 for (
size_t i = 0; i < pblock->vtx.size(); i++) {
1227 SyncTransaction(pblock->vtx[i], pindex, i);
1235 SyncTransaction(ptx);
1245 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.
prevout.
hash);
1246 if (mi != mapWallet.end())
1258 return GetDebit(txin, filter, assetData);
1267 std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(txin.
prevout.
hash);
1268 if (mi != mapWallet.end())
1274 if (prev.
tx->vout[txin.
prevout.
n].scriptPubKey.IsAssetScript())
1292 throw std::runtime_error(std::string(__func__) +
": value out of range");
1312 if (!mapAddressBook.count(address))
1321 throw std::runtime_error(std::string(__func__) +
": value out of range");
1322 return (IsChange(txout) ? txout.
nValue : 0);
1343 nDebit += GetDebit(txin, filter);
1345 throw std::runtime_error(std::string(__func__) +
": value out of range");
1357 if (mi == mapWallet.end())
1376 nCredit += GetCredit(txout, filter);
1378 throw std::runtime_error(std::string(__func__) +
": value out of range");
1388 nChange += GetChange(txout);
1390 throw std::runtime_error(std::string(__func__) +
": value out of range");
1399 return DeriveNewSeed(key);
1404 int64_t nCreationTime =
GetTime();
1419 mapKeyMetadata[seed.
GetID()] = metadata;
1422 if (!AddKeyPubKey(key, seed))
1423 throw std::runtime_error(std::string(__func__) +
": AddKeyPubKey failed");
1438 SetHDChain(newHdChain,
false);
1447 throw std::runtime_error(std::string(__func__) +
": writing chain failed");
1455 return !hdChain.seed_id.IsNull();
1460 int64_t n = nTimeSmart;
1461 return n ? n : nTimeReceived;
1469 LOCK(pwallet->cs_wallet);
1475 std::map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(hashBlock);
1476 if (mi != pwallet->mapRequestCount.end())
1477 nRequests = (*mi).second;
1483 std::map<uint256, int>::const_iterator mi = pwallet->mapRequestCount.find(GetHash());
1484 if (mi != pwallet->mapRequestCount.end())
1486 nRequests = (*mi).second;
1489 if (nRequests == 0 && !hashUnset())
1491 std::map<uint256, int>::const_iterator _mi = pwallet->mapRequestCount.find(hashBlock);
1492 if (_mi != pwallet->mapRequestCount.end())
1493 nRequests = (*_mi).second;
1504 std::list<COutputEntry>& listSent,
CAmount& nFee, std::string& strSentAccount,
const isminefilter& filter)
const {
1506 std::list<CAssetOutputEntry> assetsReceived;
1507 std::list<CAssetOutputEntry> assetsSent;
1508 GetAmounts(listReceived, listSent, nFee, strSentAccount, filter, assetsReceived, assetsSent);
1512 std::list<COutputEntry>& listSent,
CAmount& nFee, std::string& strSentAccount,
const isminefilter& filter, std::list<CAssetOutputEntry>& assetsReceived, std::list<CAssetOutputEntry>& assetsSent)
const 1515 listReceived.clear();
1517 strSentAccount = strFromAccount;
1520 CAmount nDebit = GetDebit(filter);
1523 CAmount nValueOut = tx->GetValueOut();
1524 nFee = nDebit - nValueOut;
1528 for (
unsigned int i = 0; i < tx->vout.size(); ++i)
1530 const CTxOut& txout = tx->vout[i];
1538 if (pwallet->IsChange(txout))
1541 else if (!(fIsMine & filter))
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());
1560 listSent.push_back(output);
1563 if (fIsMine & filter)
1564 listReceived.push_back(output);
1571 assetoutput.
vout = i;
1576 assetsSent.emplace_back(assetoutput);
1578 if (fIsMine & filter)
1579 assetsReceived.emplace_back(assetoutput);
1607 const CBlockIndex*
const failedBlock = ScanForWalletTransactions(startBlock,
nullptr, update);
1640 fAbortRescan =
false;
1641 fScanningWallet =
true;
1643 ShowProgress(
_(
"Rescanning..."), 0);
1646 while (pindex && !fAbortRescan)
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))));
1657 for (
size_t posInBlock = 0; posInBlock < block.
vtx.size(); ++posInBlock) {
1658 AddToWalletIfInvolvingMe(block.
vtx[posInBlock], pindex, posInBlock, fUpdate);
1663 if (pindex == pindexStop) {
1668 if (pindex && fAbortRescan) {
1671 ShowProgress(
_(
"Rescanning..."), 100);
1673 fScanningWallet =
false;
1681 if (!fBroadcastTransactions)
1684 std::map<int64_t, CWalletTx*> mapSorted;
1687 for (std::pair<const uint256, CWalletTx>& item : mapWallet)
1689 const uint256& wtxid = item.first;
1691 assert(wtx.
GetHash() == wtxid);
1696 mapSorted.insert(std::make_pair(wtx.
nOrderPos, &wtx));
1701 for (std::pair<const int64_t, CWalletTx*>& item : mapSorted)
1713 assert(pwallet->GetBroadcastTransactions());
1714 if (!IsCoinBase() && !isAbandoned() && GetDepthInMainChain() == 0)
1719 LogPrintf(
"Relaying wtx %s\n", GetHash().ToString());
1735 std::set<uint256> result;
1736 if (pwallet !=
nullptr)
1739 result = pwallet->GetConflicts(myHash);
1740 result.erase(myHash);
1747 if (tx->vin.empty())
1754 debit += nDebitCached;
1757 nDebitCached = pwallet->GetDebit(*
this, ISMINE_SPENDABLE);
1758 fDebitCached =
true;
1759 debit += nDebitCached;
1764 if(fWatchDebitCached)
1765 debit += nWatchDebitCached;
1768 nWatchDebitCached = pwallet->GetDebit(*
this, ISMINE_WATCH_ONLY);
1769 fWatchDebitCached =
true;
1770 debit += nWatchDebitCached;
1779 if (IsCoinBase() && GetBlocksToMaturity() > 0)
1787 credit += nCreditCached;
1790 nCreditCached = pwallet->GetCredit(*
this, ISMINE_SPENDABLE);
1791 fCreditCached =
true;
1792 credit += nCreditCached;
1797 if (fWatchCreditCached)
1798 credit += nWatchCreditCached;
1801 nWatchCreditCached = pwallet->GetCredit(*
this, ISMINE_WATCH_ONLY);
1802 fWatchCreditCached =
true;
1803 credit += nWatchCreditCached;
1811 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
1813 if (fUseCache && fImmatureCreditCached)
1814 return nImmatureCreditCached;
1816 fImmatureCreditCached =
true;
1817 return nImmatureCreditCached;
1825 if (pwallet ==
nullptr)
1829 if (IsCoinBase() && GetBlocksToMaturity() > 0)
1832 if (fUseCache && fAvailableCreditCached)
1833 return nAvailableCreditCached;
1837 for (
unsigned int i = 0; i < tx->vout.size(); i++)
1839 if (!pwallet->IsSpent(hashTx, i))
1841 const CTxOut &txout = tx->vout[i];
1844 throw std::runtime_error(std::string(__func__) +
" : value out of range");
1848 nAvailableCreditCached = nCredit;
1849 fAvailableCreditCached =
true;
1855 if (IsCoinBase() && GetBlocksToMaturity() > 0 && IsInMainChain())
1857 if (fUseCache && fImmatureWatchCreditCached)
1858 return nImmatureWatchCreditCached;
1860 fImmatureWatchCreditCached =
true;
1861 return nImmatureWatchCreditCached;
1869 if (pwallet ==
nullptr)
1873 if (IsCoinBase() && GetBlocksToMaturity() > 0)
1876 if (fUseCache && fAvailableWatchCreditCached)
1877 return nAvailableWatchCreditCached;
1880 for (
unsigned int i = 0; i < tx->vout.size(); i++)
1882 if (!pwallet->IsSpent(GetHash(), i))
1884 const CTxOut &txout = tx->vout[i];
1887 throw std::runtime_error(std::string(__func__) +
": value out of range");
1891 nAvailableWatchCreditCached = nCredit;
1892 fAvailableWatchCreditCached =
true;
1899 return nChangeCached;
1900 nChangeCached = pwallet->GetChange(*
this);
1901 fChangeCached =
true;
1902 return nChangeCached;
1916 int nDepth = GetDepthInMainChain();
1929 for (
const CTxIn& txin : tx->vin)
1933 if (parent ==
nullptr)
1946 for (
auto& txin : tx1.
vin) txin.scriptSig =
CScript();
1947 for (
auto& txin : tx2.
vin) txin.scriptSig =
CScript();
1953 std::vector<uint256> result;
1958 std::multimap<unsigned int, CWalletTx*> mapSorted;
1959 for (std::pair<const uint256, CWalletTx>& item : mapWallet)
1967 for (std::pair<const unsigned int, CWalletTx*>& item : mapSorted)
1971 result.push_back(wtx.
GetHash());
1980 if (
GetTime() < nNextResend || !fBroadcastTransactions)
1982 bool fFirst = (nNextResend == 0);
1988 if (nBestBlockTime < nLastResend)
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());
2015 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2031 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2046 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2060 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2076 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2091 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it)
2111 for (
const auto& entry : mapWallet) {
2121 const bool outgoing = debit > 0;
2122 for (
const CTxOut& out : wtx.
tx->vout) {
2123 if (outgoing && IsChange(out)) {
2125 }
else if (
IsMine(out) & filter && depth >= minDepth && (!account || *account == GetAccountName(out.
scriptPubKey))) {
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;
2161 std::map<std::string, std::vector<COutput> > mapAssetCoins;
2162 AvailableCoinsAll(vCoins, mapAssetCoins,
true,
false, fOnlySafe, coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2168 const uint64_t &nMaximumCount,
const int &nMinDepth,
const int &nMaxDepth)
const 2173 std::vector<COutput> vCoins;
2175 AvailableCoinsAll(vCoins, mapAssetCoins,
false,
true, fOnlySafe, coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
2181 const uint64_t &nMaximumCount,
const int &nMinDepth,
const int &nMaxDepth)
const 2183 AvailableCoinsAll(vCoins, mapAssetCoins,
true,
AreAssetsDeployed(), fOnlySafe, coinControl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount, nMinDepth, nMaxDepth);
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 {
2195 bool fRVNLimitHit =
false;
2197 std::set<uint256> usedMempoolHashes;
2199 std::map<std::string, CAmount> mapAssetTotals;
2200 std::map<uint256, COutPoint> mapOutPoints;
2201 std::set<std::string> setAssetMaxFound;
2203 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) {
2204 const uint256 &wtxid = it->first;
2239 if (nDepth == 0 && pcoin->
mapValue.count(
"replaces_txid")) {
2251 if (nDepth == 0 && pcoin->
mapValue.count(
"replaced_by_txid")) {
2255 if (fOnlySafe && !safeTx) {
2259 if (nDepth < nMinDepth || nDepth > nMaxDepth)
2262 for (
unsigned int i = 0; i < pcoin->
tx->vout.size(); i++) {
2266 bool isAssetScript = pcoin->
tx->vout[i].scriptPubKey.IsAssetScript(nType, fIsOwner);
2273 if (IsLockedCoin((*it).first, i))
2276 if (IsSpent(wtxid, i))
2290 std::string address;
2302 if (setAssetMaxFound.count(output_data.
assetName))
2312 if (!mapAssetCoins.count(output_data.
assetName)) {
2313 std::vector<COutput> vOutput;
2314 mapAssetCoins.insert(std::make_pair(output_data.
assetName, vOutput));
2318 mapAssetCoins.at(output_data.
assetName).push_back(
2319 COutput(pcoin, i, nDepth, fSpendableIn, fSolvableIn, safeTx));
2322 if (!mapAssetTotals.count(output_data.
assetName))
2323 mapAssetTotals[output_data.
assetName] = 0;
2329 if (nMinimumSumAmount != MAX_MONEY) {
2330 if (mapAssetTotals[output_data.
assetName] >= nMinimumSumAmount)
2331 setAssetMaxFound.insert(output_data.
assetName);
2335 if (nMaximumCount > 0 && mapAssetCoins[output_data.
assetName].size() >= nMaximumCount) {
2336 setAssetMaxFound.insert(output_data.
assetName);
2348 vCoins.push_back(
COutput(pcoin, i, nDepth, fSpendableIn, fSolvableIn, safeTx));
2351 if (nMinimumSumAmount != MAX_MONEY) {
2352 nTotal += pcoin->
tx->vout[i].nValue;
2354 if (nTotal >= nMinimumSumAmount) {
2355 fRVNLimitHit =
true;
2360 if (nMaximumCount > 0 && vCoins.size() >= nMaximumCount) {
2361 fRVNLimitHit =
true;
2385 std::map<CTxDestination, std::vector<COutput>> result;
2387 std::map<std::string, std::vector<COutput> > mapAssets;
2388 AvailableAssets(mapAssets);
2391 for (
auto asset : mapAssets) {
2392 for (
auto &coin : asset.second) {
2394 if (coin.fSpendable &&
2395 ExtractDestination(FindNonChangeParentOutput(*coin.tx->tx, coin.i).scriptPubKey, address)) {
2396 result[address].emplace_back(std::move(coin));
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())
2408 int depth = it->second.GetDepthInMainChain();
2409 if (depth >= 0 && output.n < it->second.tx->vout.size() &&
2412 if (
ExtractDestination(FindNonChangeParentOutput(*it->second.tx, output.n).scriptPubKey, address)) {
2413 result[address].emplace_back(
2414 &it->second, output.n, depth,
true ,
true ,
false );
2437 std::map<CTxDestination, std::vector<COutput>> result;
2439 std::vector<COutput> availableCoins;
2440 AvailableCoins(availableCoins);
2443 for (
auto& coin : availableCoins) {
2445 if (coin.fSpendable &&
2446 ExtractDestination(FindNonChangeParentOutput(*coin.tx->tx, coin.i).scriptPubKey, address)) {
2447 result[address].emplace_back(std::move(coin));
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() &&
2460 if (
ExtractDestination(FindNonChangeParentOutput(*it->second.tx, output.n).scriptPubKey, address)) {
2461 result[address].emplace_back(
2462 &it->second, output.n, depth,
true ,
true ,
false );
2475 while (IsChange(ptx->
vout[n]) && ptx->
vin.size() > 0) {
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])) {
2482 ptx = it->second.tx.get();
2485 return ptx->
vout[n];
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)
2491 std::vector<char> vfIncluded;
2493 vfBest.assign(vValue.size(),
true);
2494 nBest = nTotalLower;
2498 for (
int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
2500 vfIncluded.assign(vValue.size(),
false);
2502 bool fReachedTarget =
false;
2503 for (
int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
2505 for (
unsigned int i = 0; i < vValue.size(); i++)
2513 if (nPass == 0 ? insecure_rand.
randbool() : !vfIncluded[i])
2515 nTotal += vValue[i].txout.nValue;
2516 vfIncluded[i] =
true;
2517 if (nTotal >= nTargetValue)
2519 fReachedTarget =
true;
2523 vfBest = vfIncluded;
2525 nTotal -= vValue[i].txout.nValue;
2526 vfIncluded[i] =
false;
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)
2537 std::vector<char> vfIncluded;
2539 vfBest.assign(vValue.size(),
true);
2540 nBest = nTotalLower;
2544 for (
int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
2546 vfIncluded.assign(vValue.size(),
false);
2548 bool fReachedTarget =
false;
2549 for (
int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
2551 for (
unsigned int i = 0; i < vValue.size(); i++)
2559 if (nPass == 0 ? insecure_rand.
randbool() : !vfIncluded[i])
2561 nTotal += vValue[i].second;
2562 vfIncluded[i] =
true;
2563 if (nTotal >= nTargetValue)
2565 fReachedTarget =
true;
2569 vfBest = vfIncluded;
2571 nTotal -= vValue[i].second;
2572 vfIncluded[i] =
false;
2581 std::set<CInputCoin>& setCoinsRet,
CAmount& nValueRet)
const 2583 setCoinsRet.clear();
2587 boost::optional<CInputCoin> coinLowestLarger;
2588 std::vector<CInputCoin> vValue;
2591 random_shuffle(vCoins.begin(), vCoins.end(),
GetRandInt);
2593 for (
const COutput &output : vCoins)
2595 if (!output.fSpendable)
2612 setCoinsRet.insert(coin);
2616 else if (coin.
txout.
nValue < nTargetValue + MIN_CHANGE)
2618 vValue.push_back(coin);
2621 else if (!coinLowestLarger || coin.
txout.
nValue < coinLowestLarger->txout.nValue)
2623 coinLowestLarger = coin;
2627 if (nTotalLower == nTargetValue)
2629 for (
const auto& input : vValue)
2631 setCoinsRet.insert(input);
2637 if (nTotalLower < nTargetValue)
2639 if (!coinLowestLarger)
2641 setCoinsRet.insert(coinLowestLarger.get());
2642 nValueRet += coinLowestLarger->txout.nValue;
2648 std::reverse(vValue.begin(), vValue.end());
2649 std::vector<char> vfBest;
2652 ApproximateBestSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest);
2653 if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE)
2654 ApproximateBestSubset(vValue, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest);
2658 if (coinLowestLarger &&
2659 ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || coinLowestLarger->txout.nValue <= nBest))
2661 setCoinsRet.insert(coinLowestLarger.get());
2662 nValueRet += coinLowestLarger->txout.nValue;
2665 for (
unsigned int i = 0; i < vValue.size(); i++)
2668 setCoinsRet.insert(vValue[i]);
2669 nValueRet += vValue[i].txout.nValue;
2674 for (
unsigned int i = 0; i < vValue.size(); i++) {
2688 std::vector<COutput> vCoins(vAvailableCoins);
2693 for (
const COutput& out : vCoins)
2695 if (!out.fSpendable)
2697 nValueRet += out.tx->tx->vout[out.i].nValue;
2698 setCoinsRet.insert(
CInputCoin(out.tx, out.i));
2700 return (nValueRet >= nTargetValue);
2704 std::set<CInputCoin> setPresetCoins;
2705 CAmount nValueFromPresetInputs = 0;
2707 std::vector<COutPoint> vPresetInputs;
2710 for (
const COutPoint& outpoint : vPresetInputs)
2712 std::map<uint256, CWalletTx>::const_iterator it = mapWallet.find(outpoint.hash);
2713 if (it != mapWallet.end())
2717 if (pcoin->
tx->vout.size() <= outpoint.n)
2719 nValueFromPresetInputs += pcoin->
tx->vout[outpoint.n].nValue;
2720 setPresetCoins.insert(
CInputCoin(pcoin, outpoint.n));
2726 for (std::vector<COutput>::iterator it = vCoins.begin(); it != vCoins.end() && coinControl && coinControl->
HasSelected();)
2728 if (setPresetCoins.count(
CInputCoin(it->tx, it->i)))
2729 it = vCoins.erase(it);
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);
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));
2747 setCoinsRet.insert(setPresetCoins.begin(), setPresetCoins.end());
2750 nValueRet += nValueFromPresetInputs;
2773 strFailReason =
_(
"Keypool ran out, please call keypoolrefill first");
2777 keyID = vchPubKey.
GetID();
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 2784 setCoinsRet.clear();
2788 boost::optional<CInputCoin> coinLowestLarger;
2789 boost::optional<CAmount> coinLowestLargerAmount;
2790 std::vector<std::pair<CInputCoin, CAmount> > vValue;
2791 std::map<COutPoint, CAmount> mapValueAmount;
2794 random_shuffle(vCoins.begin(), vCoins.end(),
GetRandInt);
2796 for (
const COutput &output : vCoins)
2798 if (!output.fSpendable)
2816 bool fIsOwner =
false;
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;
2826 std::string address;
2829 nTempAmount = assetTemp.
nAmount;
2832 std::string address;
2835 nTempAmount = transferTemp.
nAmount;
2837 std::string ownerName;
2838 std::string address;
2844 std::string address;
2847 nTempAmount = reissueTemp.
nAmount;
2852 if (nTempAmount == nTargetValue)
2854 setCoinsRet.insert(coin);
2855 nValueRet += nTempAmount;
2858 else if (nTempAmount < nTargetValue + MIN_CHANGE)
2860 vValue.push_back(std::make_pair(coin, nTempAmount));
2861 nTotalLower += nTempAmount;
2863 else if (!coinLowestLarger || !coinLowestLargerAmount || nTempAmount < coinLowestLargerAmount)
2865 coinLowestLarger = coin;
2866 coinLowestLargerAmount = nTempAmount;
2870 if (nTotalLower == nTargetValue)
2872 for (
const auto& pair : vValue)
2874 setCoinsRet.insert(pair.first);
2875 nValueRet += pair.second;
2880 if (nTotalLower < nTargetValue)
2882 if (!coinLowestLarger || !coinLowestLargerAmount)
2884 setCoinsRet.insert(coinLowestLarger.get());
2885 nValueRet += coinLowestLargerAmount.get();
2891 std::reverse(vValue.begin(), vValue.end());
2892 std::vector<char> vfBest;
2895 ApproximateBestAssetSubset(vValue, nTotalLower, nTargetValue, vfBest, nBest);
2896 if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE)
2897 ApproximateBestAssetSubset(vValue, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest);
2901 if (coinLowestLarger && coinLowestLargerAmount &&
2902 ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || coinLowestLargerAmount <= nBest))
2904 setCoinsRet.insert(coinLowestLarger.get());
2905 nValueRet += coinLowestLargerAmount.get();
2908 for (
unsigned int i = 0; i < vValue.size(); i++)
2911 setCoinsRet.insert(vValue[i].first);
2912 nValueRet += vValue[i].second;
2917 for (
unsigned int i = 0; i < vValue.size(); i++) {
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 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);
2938 for (
auto assetVector : mapAvailableAssets) {
2940 std::vector<COutput> vAssets(assetVector.second);
2942 std::set<CInputCoin> tempCoinsRet;
2945 std::string strAssetName = assetVector.first;
2947 CAmount nValueFromPresetInputs = 0;
2950 if (!mapAssetTargetValue.count(strAssetName))
2954 if (mapAssetTargetValue.at(strAssetName) <= 0)
2958 if (!mapValueRet.count(strAssetName))
2959 mapValueRet.insert(std::make_pair(strAssetName, 0));
2962 nTempAmountRet = mapValueRet.at(strAssetName);
2963 nTempTargetValue = mapAssetTargetValue.at(strAssetName);
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));
2975 setCoinsRet.insert(tempCoinsRet.begin(), tempCoinsRet.end());
2976 mapValueRet.at(strAssetName) = nTempAmountRet + nValueFromPresetInputs;
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()) {
2999 const CScript& scriptPubKey = mi->second.tx->vout[input.prevout.n].scriptPubKey;
3000 const CAmount& amount = mi->second.tx->vout[input.prevout.n].nValue;
3013 std::vector<CRecipient> vecSend;
3016 for (
size_t idx = 0; idx < tx.
vout.size(); idx++)
3020 vecSend.push_back(recipient);
3030 if (!CreateTransaction(vecSend, wtx, reservekey, nFeeRet, nChangePosInOut, strFailReason, coinControl,
false)) {
3034 if (nChangePosInOut != -1) {
3035 tx.
vout.insert(tx.
vout.begin() + nChangePosInOut, wtx.
tx->vout[nChangePosInOut]);
3042 for (
unsigned int idx = 0; idx < tx.
vout.size(); idx++)
3043 tx.
vout[idx].nValue = wtx.
tx->vout[idx].nValue;
3046 for (
const CTxIn& txin : wtx.
tx->vin)
3050 tx.
vin.push_back(txin);
3068 return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control,
true, assets, destination,
false,
false, reissueAsset, type, sign);
3072 std::string& strFailReason,
const CCoinControl& coin_control,
bool sign)
3078 return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control,
false, asset, destination,
true,
false, reissueAsset, assetType, sign);
3086 return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control,
false, asset, destination,
false,
true, reissueAsset, assetType, sign);
3090 std::string& strFailReason,
const CCoinControl& coin_control,
bool sign)
3097 return CreateTransactionAll(vecSend, wtxNew, reservekey, nFeeRet, nChangePosInOut, strFailReason, coin_control,
false, asset, destination,
false,
false, reissueAsset, assetType, sign);
3101 CAmount& nFeeRet,
int& nChangePosInOut, std::string& strFailReason,
3103 const CTxDestination destination,
bool fTransferAsset,
bool fReissueAsset,
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,
3114 CAmount& nFeeRet,
int& nChangePosInOut, std::string& strFailReason,
3116 const std::vector<CNewAsset> assets,
const CTxDestination destination,
3117 bool fTransferAsset,
bool fReissueAsset,
const CReissueAsset& reissueAsset,
3125 return error(
"%s : Tried creating a new asset transaction and the asset was null or the destination was invalid", __func__);
3127 if ((fNewAsset && fTransferAsset) || (fReissueAsset && fTransferAsset) || (fReissueAsset && fNewAsset))
3128 return error(
"%s : Only one type of asset transaction allowed per transaction");
3131 return error(
"%s : Tried reissuing an asset and the reissue data was null or the destination was invalid", __func__);
3135 std::map<std::string, CAmount> mapAssetValue;
3136 int nChangePosRequest = nChangePosInOut;
3137 unsigned int nSubtractFeeFromAmount = 0;
3138 for (
const auto& recipient : vecSend)
3143 std::string address;
3145 if (!mapAssetValue.count(assetTransfer.
strName))
3146 mapAssetValue[assetTransfer.
strName] = 0;
3148 if (assetTransfer.
nAmount <= 0) {
3149 strFailReason =
_(
"Asset Transfer amounts must be greater than 0");
3158 if (nValue < 0 || recipient.nAmount < 0)
3160 strFailReason =
_(
"Transaction amounts must not be negative");
3163 nValue += recipient.nAmount;
3165 if (recipient.fSubtractFeeFromAmount)
3166 nSubtractFeeFromAmount++;
3168 if (vecSend.empty())
3170 strFailReason =
_(
"Transaction must have at least one recipient");
3208 assert(txNew.
nLockTime < LOCKTIME_THRESHOLD);
3211 unsigned int nBytes;
3213 std::set<CInputCoin> setCoins;
3215 std::set<CInputCoin> setAssets;
3219 std::vector<COutput> vAvailableCoins;
3220 std::map<std::string, std::vector<COutput> > mapAssetCoins;
3222 AvailableCoinsWithAssets(vAvailableCoins, mapAssetCoins,
true, &coin_control);
3224 AvailableCoins(vAvailableCoins,
true, &coin_control);
3232 if (!boost::get<CNoDestination>(&coin_control.
destChange)) {
3238 if (!CreateNewChangeAddress(reservekey, keyID, strFailReason))
3244 CTxOut change_prototype_txout(0, scriptChange);
3249 bool pick_new_inputs =
true;
3255 std::map<std::string, CAmount> mapAssetsIn;
3256 nChangePosInOut = nChangePosRequest;
3262 CAmount nValueToSelect = nValue;
3264 if (nSubtractFeeFromAmount == 0)
3265 nValueToSelect += nFeeRet;
3268 for (
const auto& recipient : vecSend)
3270 CTxOut txout(recipient.nAmount, recipient.scriptPubKey);
3274 if (recipient.scriptPubKey.IsNullAssetTxDataScript()) {
3275 assert(txout.
nValue == 0);
3276 txNew.
vout.push_back(txout);
3281 if (recipient.fSubtractFeeFromAmount)
3283 assert(nSubtractFeeFromAmount != 0);
3284 txout.
nValue -= nFeeRet / nSubtractFeeFromAmount;
3289 txout.
nValue -= nFeeRet % nSubtractFeeFromAmount;
3295 if (recipient.fSubtractFeeFromAmount && nFeeRet > 0)
3298 strFailReason =
_(
"The transaction amount is too small to pay the fee");
3300 strFailReason =
_(
"The transaction amount is too small to send after the fee has been deducted");
3303 strFailReason =
_(
"Transaction amount too small");
3308 txNew.
vout.push_back(txout);
3312 if (pick_new_inputs) {
3315 if (!SelectCoins(vAvailableCoins, nValueToSelect, setCoins, nValueIn, &coin_control))
3317 strFailReason =
_(
"Insufficient funds");
3324 mapAssetsIn.clear();
3325 if (!SelectAssets(mapAssetCoins, mapAssetValue, setAssets, mapAssetsIn)) {
3326 strFailReason =
_(
"Insufficient asset funds");
3333 const CAmount nChange = nValueIn - nValueToSelect;
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)));
3345 for (
auto assetChange : mapAssetChange) {
3346 if (assetChange.second > 0) {
3352 strFailReason =
_(
"Verifier String for asset trasnfer, not found");
3359 strFailReason =
_(
"Failed to extract destination from change script");
3364 bool fFoundValueChangeAddress =
false;
3368 for (
auto asset: setAssets) {
3369 if (asset.txout.scriptPubKey.IsAssetScript()) {
3371 if (!
GetAssetData(asset.txout.scriptPubKey, outputData)) {
3372 strFailReason =
_(
"Failed to get asset data from script");
3377 if (outputData.
assetName != assetChange.first)
3383 fFoundValueChangeAddress =
true;
3386 CAssetTransfer assetTransfer(assetChange.first, assetChange.second);
3389 CTxOut newAssetTxOut(0, scriptAssetChange);
3391 txNew.
vout.emplace_back(newAssetTxOut);
3397 fFoundValueChangeAddress =
true;
3398 CScript scriptAssetChange = scriptChange;
3399 CAssetTransfer assetTransfer(assetChange.first, assetChange.second);
3402 CTxOut newAssetTxOut(0, scriptAssetChange);
3404 txNew.
vout.emplace_back(newAssetTxOut);
3406 if (!fFoundValueChangeAddress) {
3407 strFailReason =
_(
"Failed to find restricted asset change address from inputs");
3411 CScript scriptAssetChange = scriptChange;
3412 CAssetTransfer assetTransfer(assetChange.first, assetChange.second);
3415 CTxOut newAssetTxOut(0, scriptAssetChange);
3417 txNew.
vout.emplace_back(newAssetTxOut);
3427 CTxOut newTxOut(nChange, scriptChange);
3431 if (
IsDust(newTxOut, discard_rate))
3433 nChangePosInOut = -1;
3438 if (nChangePosInOut == -1)
3443 else if ((
unsigned int)nChangePosInOut > txNew.
vout.size())
3445 strFailReason =
_(
"Change index out of range");
3449 std::vector<CTxOut>::iterator position = txNew.
vout.begin()+nChangePosInOut;
3450 txNew.
vout.insert(position, newTxOut);
3453 nChangePosInOut = -1;
3459 for (
auto asset : assets) {
3463 asset.ConstructOwnerTransaction(ownerScript);
3464 CTxOut ownerTxOut(0, ownerScript);
3465 txNew.
vout.push_back(ownerTxOut);
3470 asset.ConstructTransaction(scriptPubKey);
3471 CTxOut newTxOut(0, scriptPubKey);
3472 txNew.
vout.push_back(newTxOut);
3474 }
else if (fReissueAsset) {
3481 CTxOut reissueTxOut(0, reissueScript);
3482 txNew.
vout.push_back(reissueTxOut);
3499 for (
const auto& coin : setCoins)
3505 for (
const auto &asset : setAssets)
3512 std::set<CInputCoin> tempSet = setCoins;
3513 tempSet.insert(setAssets.begin(), setAssets.end());
3516 DummySignTx(txNew, tempSet);
3521 for (
auto& vin : txNew.
vin) {
3523 vin.scriptWitness.SetNull();
3532 strFailReason =
_(
"Transaction too large for fee policy");
3536 if (nFeeRet >= nFeeNeeded) {
3547 if (nChangePosInOut == -1 && nSubtractFeeFromAmount == 0 && pick_new_inputs) {
3548 unsigned int tx_size_with_change = nBytes + change_prototype_size + 2;
3551 if (nFeeRet >= fee_needed_with_change + minimum_value_for_change) {
3552 pick_new_inputs =
false;
3553 nFeeRet = fee_needed_with_change;
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;
3567 else if (!pick_new_inputs) {
3572 strFailReason =
_(
"Transaction fee and change calculation failed");
3577 if (nChangePosInOut != -1 && nSubtractFeeFromAmount == 0) {
3578 CAmount additionalFeeNeeded = nFeeNeeded - nFeeRet;
3579 std::vector<CTxOut>::iterator change_position = txNew.
vout.begin()+nChangePosInOut;
3581 if (change_position->nValue >= MIN_FINAL_CHANGE + additionalFeeNeeded) {
3582 change_position->nValue -= additionalFeeNeeded;
3583 nFeeRet += additionalFeeNeeded;
3590 if (nSubtractFeeFromAmount > 0) {
3591 pick_new_inputs =
false;
3595 nFeeRet = nFeeNeeded;
3600 if (nChangePosInOut == -1) reservekey.
ReturnKey();
3606 for (
const auto& coin : setCoins)
3608 const CScript& scriptPubKey = coin.txout.scriptPubKey;
3613 strFailReason =
_(
"Signing transaction failed");
3623 for (
const auto &asset : setAssets) {
3624 const CScript &scriptPubKey = asset.txout.scriptPubKey;
3629 scriptPubKey, sigdata)) {
3630 strFailReason =
_(
"Signing asset transaction failed");
3643 wtxNew.
SetTx(MakeTransactionRef(std::move(txNew)));
3646 if (GetTransactionWeight(wtxNew) >= MAX_STANDARD_TX_WEIGHT)
3648 strFailReason =
_(
"Transaction too large");
3653 if (
gArgs.
GetBoolArg(
"-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) {
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;
3664 strFailReason =
_(
"Transaction has too long of a mempool chain");
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",
3687 LogPrintf(
"CommitTransaction:\n%s", wtxNew.
tx->ToString());
3694 AddToWallet(wtxNew);
3697 for (
const CTxIn& txin : wtxNew.
tx->vin)
3706 mapRequestCount[wtxNew.
GetHash()] = 0;
3708 if (fBroadcastTransactions)
3714 AbandonTransaction(wtxNew.
tx->GetHash());
3733 return AddAccountingEntry(acentry, &walletdb);
3742 laccentries.push_back(acentry);
3744 wtxOrdered.insert(std::make_pair(entry.
nOrderPos,
TxPair(
nullptr, &entry)));
3753 fFirstRunRet =
false;
3757 if (dbw->Rewrite(
"\x04pool"))
3759 setInternalKeyPool.clear();
3760 setExternalKeyPool.clear();
3761 m_pool_key_to_index.clear();
3769 fFirstRunRet = mapKeys.empty() && mapCryptedKeys.empty() && mapWatchKeys.empty() && setWatchOnly.empty() && mapScripts.empty();
3772 return nLoadWalletRet;
3784 mapWallet.erase(hash);
3788 if (dbw->Rewrite(
"\x04pool"))
3790 setInternalKeyPool.clear();
3791 setExternalKeyPool.clear();
3792 m_pool_key_to_index.clear();
3800 return nZapSelectTxRet;
3813 if (dbw->Rewrite(
"\x04pool"))
3816 setInternalKeyPool.clear();
3817 setExternalKeyPool.clear();
3818 m_pool_key_to_index.clear();
3826 return nZapWalletTxRet;
3834 bool fUpdated =
false;
3837 std::map<CTxDestination, CAddressBookData>::iterator mi = mapAddressBook.find(address);
3838 fUpdated = mi != mapAddressBook.end();
3839 mapAddressBook[address].name = strName;
3840 if (!strPurpose.empty())
3841 mapAddressBook[address].purpose = strPurpose;
3843 NotifyAddressBookChanged(
this, address, strName, ::
IsMine(*
this, address) !=
ISMINE_NO,
3857 for (
const std::pair<std::string, std::string> &item : mapAddressBook[address].destdata)
3861 mapAddressBook.erase(address);
3874 auto mi = mapAddressBook.find(address);
3875 if (mi != mapAddressBook.end()) {
3876 return mi->second.name;
3881 const static std::string DEFAULT_ACCOUNT_NAME;
3882 return DEFAULT_ACCOUNT_NAME;
3895 for (int64_t nIndex : setInternalKeyPool) {
3898 setInternalKeyPool.clear();
3900 for (int64_t nIndex : setExternalKeyPool) {
3903 setExternalKeyPool.clear();
3905 m_pool_key_to_index.clear();
3907 if (!TopUpKeyPool()) {
3910 LogPrintf(
"CWallet::NewKeyPool rewrote keypool\n");
3918 return setExternalKeyPool.size();
3925 setInternalKeyPool.insert(nIndex);
3927 setExternalKeyPool.insert(nIndex);
3929 m_max_keypool_index = std::max(m_max_keypool_index, nIndex);
3936 if (mapKeyMetadata.count(keyid) == 0)
3949 unsigned int nTargetSize;
3951 nTargetSize = kpSize;
3953 nTargetSize = std::max(
gArgs.
GetArg(
"-keypool", DEFAULT_KEYPOOL_SIZE), (int64_t) 0);
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);
3963 missingInternal = 0;
3965 bool internal =
false;
3967 for (int64_t i = missingInternal + missingExternal; i--;)
3969 if (i < missingInternal) {
3973 assert(m_max_keypool_index < std::numeric_limits<int64_t>::max());
3974 int64_t index = ++m_max_keypool_index;
3976 CPubKey pubkey(GenerateNewKey(walletdb,
internal));
3978 throw std::runtime_error(std::string(__func__) +
": writing generated key failed");
3982 setInternalKeyPool.insert(index);
3984 setExternalKeyPool.insert(index);
3986 m_pool_key_to_index[pubkey.
GetID()] = index;
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());
4005 bool fReturningInternal = IsHDEnabled() && CanSupportFeature(
FEATURE_HD_SPLIT) && fRequestedInternal;
4006 std::set<int64_t>& setKeyPool = fReturningInternal ? setInternalKeyPool : setExternalKeyPool;
4009 if(setKeyPool.empty())
4014 auto it = setKeyPool.begin();
4016 setKeyPool.erase(it);
4017 if (!walletdb.
ReadPool(nIndex, keypool)) {
4018 throw std::runtime_error(std::string(__func__) +
": read failed");
4021 throw std::runtime_error(std::string(__func__) +
": unknown key in key pool");
4023 if (keypool.
fInternal != fReturningInternal) {
4024 throw std::runtime_error(std::string(__func__) +
": keypool entry misclassified");
4029 LogPrintf(
"keypool reserve %d\n", nIndex);
4047 setInternalKeyPool.insert(nIndex);
4049 setExternalKeyPool.insert(nIndex);
4051 m_pool_key_to_index[pubkey.
GetID()] = nIndex;
4053 LogPrintf(
"keypool return %d\n", nIndex);
4062 ReserveKeyFromKeyPool(nIndex, keypool,
internal);
4065 if (IsLocked())
return false;
4067 result = GenerateNewKey(walletdb,
internal);
4076 static int64_t GetOldestKeyTimeInPool(
const std::set<int64_t>& setKeyPool,
CWalletDB& walletdb) {
4077 if (setKeyPool.empty()) {
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");
4087 return keypool.
nTime;
4097 int64_t oldestKey = GetOldestKeyTimeInPool(setExternalKeyPool, walletdb);
4099 oldestKey = std::max(GetOldestKeyTimeInPool(setInternalKeyPool, walletdb), oldestKey);
4107 std::map<CTxDestination, CAmount> balances;
4111 for (
const auto& walletEntry : mapWallet)
4113 const CWalletTx *pcoin = &walletEntry.second;
4125 for (
unsigned int i = 0; i < pcoin->
tx->vout.size(); i++)
4133 CAmount n = IsSpent(walletEntry.first, i) ? 0 : pcoin->
tx->vout[i].nValue;
4135 if (!balances.count(addr))
4137 balances[addr] += n;
4148 std::set< std::set<CTxDestination> > groupings;
4149 std::set<CTxDestination> grouping;
4151 for (
const auto& walletEntry : mapWallet)
4153 const CWalletTx *pcoin = &walletEntry.second;
4155 if (pcoin->
tx->vin.size() > 0)
4157 bool any_mine =
false;
4159 for (
CTxIn txin : pcoin->
tx->vin)
4166 grouping.insert(address);
4173 for (
CTxOut txout : pcoin->
tx->vout)
4174 if (IsChange(txout))
4179 grouping.insert(txoutAddr);
4182 if (grouping.size() > 0)
4184 groupings.insert(grouping);
4190 for (
const auto& txout : pcoin->
tx->vout)
4196 grouping.insert(address);
4197 groupings.insert(grouping);
4202 std::set< std::set<CTxDestination>* > uniqueGroupings;
4203 std::map< CTxDestination, std::set<CTxDestination>* > setmap;
4204 for (std::set<CTxDestination> _grouping : groupings)
4207 std::set< std::set<CTxDestination>* > hits;
4208 std::map< CTxDestination, std::set<CTxDestination>* >::iterator it;
4210 if ((it = setmap.find(address)) != setmap.end())
4211 hits.insert((*it).second);
4214 std::set<CTxDestination>* merged =
new std::set<CTxDestination>(_grouping);
4215 for (std::set<CTxDestination>* hit : hits)
4217 merged->insert(hit->begin(), hit->end());
4218 uniqueGroupings.erase(hit);
4221 uniqueGroupings.insert(merged);
4225 setmap[element] = merged;
4228 std::set< std::set<CTxDestination> > ret;
4229 for (std::set<CTxDestination>* uniqueGrouping : uniqueGroupings)
4231 ret.insert(*uniqueGrouping);
4232 delete uniqueGrouping;
4241 std::set<CTxDestination> result;
4242 for (
const std::pair<CTxDestination, CAddressBookData>& item : mapAddressBook)
4245 const std::string& strName = item.second.name;
4246 if (strName == strAccount)
4247 result.insert(address);
4257 pwallet->ReserveKeyFromKeyPool(nIndex, keypool,
internal);
4265 assert(vchPubKey.IsValid());
4273 pwallet->KeepKey(nIndex);
4281 pwallet->ReturnKey(nIndex, fInternal, vchPubKey);
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();
4296 while (it != std::end(*setKeyPool)) {
4297 const int64_t& index = *(it);
4298 if (index > keypool_id)
break;
4301 if (walletdb.
ReadPool(index, keypool)) {
4305 LogPrintf(
"keypool index %d removed\n", index);
4306 it = setKeyPool->erase(it);
4312 std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(
this);
4314 if (!rKey->GetReservedKey(pubkey))
4326 setLockedCoins.insert(output);
4332 setLockedCoins.erase(output);
4338 setLockedCoins.clear();
4346 return (setLockedCoins.count(outpt) > 0);
4352 for (std::set<COutPoint>::iterator it = setLockedCoins.begin();
4353 it != setLockedCoins.end(); it++) {
4355 vOutpts.push_back(outpt);
4363 mapKeyBirth.clear();
4366 for (
const auto& entry : mapKeyMetadata) {
4367 if (entry.second.nCreateTime) {
4368 mapKeyBirth[entry.first] = entry.second.nCreateTime;
4374 std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
4375 for (
const CKeyID &keyid : GetKeys()) {
4376 if (mapKeyBirth.count(keyid) == 0)
4377 mapKeyFirstBlock[keyid] = pindexMax;
4381 if (mapKeyFirstBlock.empty())
4385 std::vector<CKeyID> vAffected;
4386 for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) {
4392 int nHeight = blit->second->nHeight;
4393 for (
const CTxOut &txout : wtx.
tx->vout) {
4396 for (
const CKeyID &keyid : vAffected) {
4398 std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
4399 if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
4400 rit->second = blit->second;
4408 for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
4409 mapKeyBirth[it->first] = it->second->GetBlockTime() - TIMESTAMP_WINDOW;
4439 int64_t latestEntry = 0;
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;
4457 nSmartTime = pacentry->
nTime;
4459 if (nSmartTime <= latestTolerated) {
4460 latestEntry = nSmartTime;
4461 if (nSmartTime > latestNow) {
4462 latestNow = nSmartTime;
4469 nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
4479 if (boost::get<CNoDestination>(&dest))
4482 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
4488 if (!mapAddressBook[dest].destdata.erase(key))
4495 mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
4501 std::map<CTxDestination, CAddressBookData>::const_iterator i = mapAddressBook.find(dest);
4502 if(i != mapAddressBook.end())
4504 CAddressBookData::StringMap::const_iterator j = i->second.destdata.find(key);
4505 if(j != i->second.destdata.end())
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);
4532 std::vector<CWalletTx> vWtx;
4538 std::unique_ptr<CWallet> tempWallet(
new CWallet(std::move(dbw)));
4539 DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
4549 bool fFirstRun =
true;
4562 " or address book entries might be missing or incorrect."),
4582 int nMaxVersion =
gArgs.
GetArg(
"-upgradewallet", 0);
4583 if (nMaxVersion == 0)
4586 nMaxVersion = CLIENT_VERSION;
4590 LogPrintf(
"Allowing wallet upgrade up to %i\n", nMaxVersion);
4591 if (nMaxVersion < walletInstance->GetVersion())
4603 InitError(
strprintf(
_(
"Error creating %s: You can't create non-HD wallets with this version."), walletFile));
4611 throw std::runtime_error(std::string(__func__) +
": Storing HD seed failed");
4615 InitError(
_(
"Unable to generate initial keys") +=
"\n");
4624 InitError(
strprintf(
_(
"Error loading %s: You can't disable HD on an already existing HD wallet"), walletFile));
4628 InitError(
strprintf(
_(
"Error loading %s: You can't enable HD on an already existing non-HD wallet"), walletFile));
4657 block = block->
pprev;
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)"));
4678 walletInstance->
dbw->IncrementUpdateCounter();
4687 uint256 hash = wtxOld.GetHash();
4688 std::map<uint256, CWalletTx>::iterator mi = walletInstance->
mapWallet.find(hash);
4689 if (mi != walletInstance->
mapWallet.end())
4714 return walletInstance;
4723 ReacceptWalletTransactions();
4726 if (!CWallet::fFlushScheduled.exchange(
true)) {
4733 return dbw->Backup(strDest);
4745 vchPubKey = vchPubKeyIn;
4746 fInternal = internalIn;
4751 nTimeCreated = (nExpires ?
GetTime() : 0);
4752 nTimeExpires = nExpires;
4761 nIndex = posInBlock;
4787 return std::max(0, (COINBASE_MATURITY+1) - GetDepthInMainChain());
4794 nullptr ,
false , nAbsurdFee);
bool IsEquivalentTo(const CWalletTx &tx) const
void postInitProcess(CScheduler &scheduler)
Wallet post-init setup Gives the wallet a chance to register repetitive tasks and complete post-init ...
int64_t GetVirtualTransactionSize(int64_t nWeight, int64_t nSigOpCost)
Compute the virtual transaction size (weight reinterpreted as bytes).
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...
bool WriteMinVersion(int nVersion)
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector< unsigned char > &chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
void DeriveNewChildKey(CWalletDB &walletdb, CKeyMetadata &metadata, CKey &secret, bool internal=false)
std::set< std::set< CTxDestination > > GetAddressGroupings()
const char * DEFAULT_WALLET_DAT
void UpdateTransaction(CMutableTransaction &tx, unsigned int nIn, const SignatureData &data)
#define OWNER_ASSET_AMOUNT
void SetTx(CTransactionRef arg)
static const uint256 ABANDON_HASH
Constant used in hashBlock to indicate tx has been abandoned.
bool SignTransaction(CMutableTransaction &tx)
RVN END.
bool IsArgSet(const std::string &strArg) const
Return true if the given argument has been manually set.
int64_t nOrderPos
position in ordered transaction list
CFeeRate GetDiscardRate(const CBlockPolicyEstimator &estimator)
Return the maximum feerate for discarding change.
CPrivKey GetPrivKey() const
Convert the private key to a CPrivKey (serialized OpenSSL private key data).
bool AddKeyPubKeyWithDB(CWalletDB &walletdb, const CKey &key, const CPubKey &pubkey)
void SetMerkleBranch(const CBlockIndex *pIndex, int posInBlock)
void BindWallet(CWallet *pwalletIn)
unsigned int nDerivationMethod
0 = EVP_sha512() 1 = scrypt()
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
bool fPruneMode
True if we're running in -prune mode.
std::vector< CWalletRef > vpwallets
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.
const CWalletTx * GetWalletTx(const uint256 &hash) const
CAmount GetImmatureBalance() const
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Parse a standard scriptPubKey for the destination address.
int64_t GetOldestKeyPoolTime()
bool fAllowWatchOnly
Includes watch only addresses which match the ISMINE_WATCH_SOLVABLE criteria.
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...
bool WriteAccount(const std::string &strAccount, const CAccount &account)
void Process(const CScript &script)
int64_t GetBlockTime() const
void GetKeyBirthTimes(std::map< CTxDestination, int64_t > &mapKeyBirth) const
bool AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment="")
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
const unsigned int WALLET_CRYPTO_KEY_SIZE
CBlockIndex * pprev
pointer to the index of the predecessor of this block
bool Encrypt(const CKeyingMaterial &vchPlaintext, std::vector< unsigned char > &vchCiphertext) const
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
CAmount GetAvailableBalance(const CCoinControl *coinControl=nullptr) const
char fFromMe
From me flag is set to 1 for transactions that were created by the wallet on this raven node...
bool WriteTx(const CWalletTx &wtx)
bool Derive(CExtKey &out, unsigned int nChild) const
bool TxnBegin()
Begin a new transaction.
std::map< CTxDestination, CAddressBookData > mapAddressBook
std::vector< std::string > GetDestValues(const std::string &prefix) const
Get all destination values matching a prefix.
std::set< uint256 > GetConflicts() const
CCriticalSection cs_wallet
std::unique_ptr< CWalletDBWrapper > dbw
Encryption/decryption context with key information.
const uint256 & GetHash() const
bool IsFromMe(const isminefilter &filter) const
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
CAmount maxTxFee
Absolute maximum transaction fee (in satoshis) used by wallet and mempool (rejects high fee in sendra...
CPubKey GetPubKey() const
Compute the public key from a private key.
bool IsFromMe(const CTransaction &tx) const
should probably be renamed to IsRelevantToMe
std::vector< unsigned char > vchCryptedKey
bool bSpendZeroConfChange
std::string strFromAccount
WalletFeature
(client) version numbers for particular wallet features
size_t GetSerializeSize(const T &t, int nType, int nVersion=0)
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
bool TxnCommit()
Commit current transaction.
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
static const uint32_t SEQUENCE_FINAL
Only serialized through CTransaction.
int64_t IncOrderPosNext(CWalletDB *pwalletdb=nullptr)
Increment the next transaction order id.
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Adds a key to the store, and saves it to disk.
CAmount GetDebit(const isminefilter &filter) const
filter decides which addresses will count towards the debit
bool AssetFromScript(const CScript &scriptPubKey, CNewAsset &assetNew, std::string &strAddress)
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key...
void ListSelected(std::vector< COutPoint > &vOutpoints) const
void ReacceptWalletTransactions()
bool MoneyRange(const CAmount &nValue)
bool TransferAssetFromScript(const CScript &scriptPubKey, CAssetTransfer &assetTransfer, std::string &strAddress)
Get specific asset type metadata from the given scripts.
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();.
int Height() const
Return the maximal height in the chain.
const std::string & GetAccountName(const CScript &scriptPubKey) const
CCriticalSection cs_main
Global state.
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
void ConstructTransaction(CScript &script) const
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
CScript GetScriptForRawPubKey(const CPubKey &pubKey)
Generate a P2PK script for the given pubkey.
int64_t nOrderPos
position in ordered transaction list
std::vector< unsigned char, secure_allocator< unsigned char > > CKeyingMaterial
A signature creator for transactions.
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/raven/bips/blob/master/bip-0013.mediawiki.
std::string StringForFeeReason(FeeReason reason)
void GetStrongRandBytes(unsigned char *out, int num)
Function to gather random data from multiple sources, failing whenever any of those source fail to pr...
void AddToSpends(const COutPoint &outpoint, const uint256 &wtxid)
CBlockIndex * ScanForWalletTransactions(CBlockIndex *pindexStart, CBlockIndex *pindexStop, bool fUpdate=false)
Scan the block chain (starting in pindexStart) for transactions from or to us.
bool SetMaxVersion(int nVersion)
change which version we're allowed to upgrade to (note that this does not immediately imply upgrading...
isminetype IsMine(const CKeyStore &keystore, const CScript &scriptPubKey, SigVersion sigversion)
std::set< txiter, CompareIteratorByHash > setEntries
uint8_t isminefilter
used for bitflags of isminetype
void ConstructTransaction(CScript &script) const
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
void scheduleEvery(Function f, int64_t deltaMilliSeconds)
boost::signals2::signal< void(CWallet *wallet)> LoadWallet
A wallet has been loaded.
void ListAccountCreditDebit(const std::string &strAccount, std::list< CAccountingEntry > &acentries)
std::map< CTxDestination, std::vector< COutput > > ListAssets() const
Return list of available assets and locked assets grouped by non-change output address.
void MarkDirty()
make sure balances are recalculated
CChainParams defines various tweakable parameters of a given instance of the Raven system...
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...
unsigned int GetKeyPoolSize()
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
bool Decrypt(const std::vector< unsigned char > &vchCiphertext, CKeyingMaterial &vchPlaintext) const
CWalletKey(int64_t nExpires=0)
todo: add something to note what created it (user, getnewaddress, change) maybe should have a map<str...
uint160 Hash160(const T1 pbegin, const T1 pend)
Compute the 160-bit hash an object.
bool ErasePurpose(const std::string &strAddress)
bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry &acentry)
This writes directly to the database, and will not update the CWallet's cached accounting entries! Us...
virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
const unsigned char * begin() const
bool MarkReplaced(const uint256 &originalHash, const uint256 &newHash)
Mark a transaction as replaced by another transaction (e.g., BIP 125).
DBErrors
Error statuses for the wallet database.
bool ReissueAssetFromScript(const CScript &scriptPubKey, CReissueAsset &reissue, std::string &strAddress)
CAmount GetUnconfirmedWatchOnlyBalance() const
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
bool EncryptWallet(const SecureString &strWalletPassphrase)
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.
std::shared_ptr< const CTransaction > CTransactionRef
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...
bool ProduceSignature(const BaseSignatureCreator &creator, const CScript &fromPubKey, SignatureData &sigdata)
Produce a script signature using a generic signature creator.
std::set< uint256 > GetConflicts(const uint256 &txid) const
Get wallet transactions that conflict with given transaction (spend same outputs) ...
void ReserveKeyFromKeyPool(int64_t &nIndex, CKeyPool &keypool, bool fRequestedInternal)
CAmount GetImmatureWatchOnlyCredit(const bool &fUseCache=true) const
bool IsSpent(const uint256 &hash, unsigned int n) const
Outpoint is spent if any non-conflicted transaction spends it:
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
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
CAmount GetImmatureCredit(bool fUseCache=true) const
bool operator()(const CInputCoin &t1, const CInputCoin &t2) const
void PushInventory(const CInv &inv)
void SyncTransaction(const CTransactionRef &tx, const CBlockIndex *pindex=nullptr, int posInBlock=0)
bool AddWatchOnly(const CScript &dest) override
Private version of AddWatchOnly method which does not accept a timestamp, and which will reset the wa...
CAmount GetBalance() const
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) ...
const std::vector< CTxIn > vin
std::map< CTxDestination, CAmount > GetAddressBalances()
std::string ToString() const
bool WriteOrderPosNext(int64_t nOrderPosNext)
void BlockDisconnected(const std::shared_ptr< const CBlock > &pblock) override
Notifies listeners of a block being disconnected.
bool IsUnspendable() const
Returns whether the script is guaranteed to fail at execution, regardless of the initial stack...
mapValue_t mapValue
Key/value map with information about the transaction.
bool GetAssetData(const CScript &script, CAssetOutputEntry &data)
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
bool ExtractDestinations(const CScript &scriptPubKey, txnouttype &typeRet, std::vector< CTxDestination > &addressRet, int &nRequiredRet)
Parse a standard scriptPubKey with one or more destination addresses.
void operator()(const CNoDestination &none)
void KeepKey(int64_t nIndex)
int64_t CAmount
Amount in corbies (Can be negative)
bool IsAssetSelected(const COutPoint &output) const
std::multimap< int64_t, TxPair > TxItems
bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) override
Add a key to the store.
void MarkReserveKeysAsUsed(int64_t keypool_id)
Marks all keys in the keypool up to and including reserve_key as used.
uint256 GetBlockHash() const
#define AssertLockHeld(cs)
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)
void SetBroadcastTransactions(bool broadcast)
Set whether this wallet broadcasts transactions.
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
CBlockPolicyEstimator feeEstimator
void MarkConflicted(const uint256 &hashBlock, const uint256 &hashTx)
bool AreMessagingDeployed()
DBErrors ReorderTransactions()
size_t KeypoolCountExternalKeys()
bool DelAddressBook(const CTxDestination &address)
unsigned int nTxConfirmTarget
An instance of this class represents one database.
static CFeeRate m_discard_rate
bool CheckFinalTx(const CTransaction &tx, int flags)
Transaction validation functions.
unsigned int ComputeTimeSmart(const CWalletTx &wtx) const
Compute smart timestamp for a transaction being added to the wallet.
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)
int GetDepthInMainChain() const
bool AbandonTransaction(const uint256 &hashTx)
DBErrors LoadWallet(bool &fFirstRunRet)
void UnlockCoin(const COutPoint &output)
bool AreAssetsDeployed()
RVN START.
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
bool WritePool(int64_t nPool, const CKeyPool &keypool)
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...
CPubKey GenerateNewKey(CWalletDB &walletdb, bool internal=false)
keystore implementation Generate a new key
void TransactionAddedToMempool(const CTransactionRef &tx) override
Notifies listeners of a transaction having been added to mempool.
CFeeRate minRelayTxFee
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
bool NewKeyPool()
Mark old keypool keys as used, and generate all new keys.
isminetype
IsMine() return codes.
An input of a transaction.
bool AddCScript(const CScript &redeemScript) override
Support for BIP 0013 : see https://github.com/raven/bips/blob/master/bip-0013.mediawiki.
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
bool WriteName(const std::string &strAddress, const std::string &strName)
DBErrors LoadWallet(CWallet *pwallet)
const uint256 & GetHash() const
void SetBestChain(const CBlockLocator &loc) override
Notifies listeners of the new active block chain on-disk.
void operator()(const CScriptID &scriptId)
CTxDestination destChange
const uint32_t BIP32_HARDENED_KEY_LIMIT
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
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...
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)
uint256 uint256S(const char *str)
CBlockIndex * FindEarliestAtLeast(int64_t nTime) const
Find the earliest block with timestamp equal or greater than the given.
An encapsulated public key.
bool fAllowOtherInputs
If false, allows unselected inputs, but requires all selected inputs be used.
bool Unlock(const CKeyingMaterial &vMasterKeyIn)
bool TransactionCanBeAbandoned(const uint256 &hashTx) const
Return whether transaction can be abandoned.
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...
bool IsLockedCoin(uint256 hash, unsigned int n) const
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.
std::string GetRejectReason() const
void MakeNewKey(bool fCompressed)
Generate a new private key using a cryptographic PRNG.
const std::vector< CTxOut > vout
bool CreateNewChangeAddress(CReserveKey &reservekey, CKeyID &keyID, std::string &strFailReason)
RVN START.
CAmount GetUnconfirmedBalance() const
int64_t GetBlockTimeMax() const
int GetBlocksToMaturity() const
CAmount GetImmatureWatchOnlyBalance() const
CAmount GetLegacyBalance(const isminefilter &filter, int minDepth, const std::string *account) const
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
void Flush(bool shutdown=false)
Flush wallet (bitdb flush)
bool EraseDestData(const CTxDestination &dest, const std::string &key)
Erases a destination data tuple in the store and on disk.
void UpdateTimeFirstKey(int64_t nCreateTime)
Update wallet first key creation time.
void MaybeCompactWalletDB()
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
void ResendWalletTransactions(int64_t nBestBlockTime, CConnman *connman) override
Tells listeners to broadcast their data.
bool GetReservedKey(CPubKey &pubkey, bool internal=false)
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.
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
bool exists(uint256 hash) const
unsigned int size() const
Simple read-only vector-like interface.
bool OwnerAssetFromScript(const CScript &scriptPubKey, std::string &assetName, std::string &strAddress)
An output of a transaction.
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
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.
std::string ToString() const
bool AddToWalletIfInvolvingMe(const CTransactionRef &tx, const CBlockIndex *pIndex, int posInBlock, bool fUpdate)
Add a transaction to the wallet, or update it.
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Raven scriptPubKey for the given CTxDestination.
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
bool LoadToWallet(const CWalletTx &wtxIn)
An outpoint - a combination of a transaction hash and an index n into its vout.
std::vector< CTxOut > vout
bool ErasePool(int64_t nPool)
bool EraseWatchOnly(const CScript &script)
unsigned int fTimeReceivedIsTxTime
static CWallet * CreateWalletFromFile(const std::string walletFile)
bool IsAllFromMe(const CTransaction &tx, const isminefilter &filter) const
Returns whether all of the inputs match the filter.
std::string FormatMoney(const CAmount &n)
Money parsing/formatting utilities.
CAmount GetDustThreshold(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
void ForEachNode(Callable &&func)
bool RemoveWatchOnly(const CScript &dest) override
void SetSeed(const unsigned char *seed, unsigned int nSeedLen)
void LockCoin(const COutPoint &output)
bool AddToWallet(const CWalletTx &wtxIn, bool fFlushOnClose=true)
const CTxOut & FindNonChangeParentOutput(const CTransaction &tx, int output) const
Find non-change parent output.
Access to the wallet database.
A transaction with a bunch of additional info that only the owner cares about.
DBErrors ZapWalletTx(std::vector< CWalletTx > &vWtx)
CFeeRate minRelayTxFeeV2
A fee rate smaller than this is considered zero fee (for relaying, mining and transaction creation) ...
void RegisterValidationInterface(CValidationInterface *pwalletIn)
Register a wallet to receive updates from core.
bool ReadBestBlock(CBlockLocator &locator)
CAmount GetWatchOnlyBalance() const
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...
int64_t RescanFromTime(int64_t startTime, bool update)
Scan active chain for relevant transactions after importing keys.
bool IsScriptTransferAsset(const CScript &scriptPubKey)
Check script and see if it matches the transfer asset template.
#define LogPrint(category,...)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
CPubKey DeriveNewSeed(const CKey &key)
CAmount GetAvailableCredit(bool fUseCache=true) const
bool HasAssetSelected() const
std::vector< uint256 > ResendWalletTransactionsBefore(int64_t nTime, CConnman *connman)
bool WriteBestBlock(const CBlockLocator &locator)
std::set< CTxDestination > GetAccountAddresses(const std::string &strAccount) const
const unsigned int WALLET_CRYPTO_SALT_SIZE
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.
CAssetsCache * passets
Global variable that point to the active assets (protected by cs_main)
bool SetHDSeed(const CPubKey &key)
void GetScriptForMining(std::shared_ptr< CReserveScript > &script)
static std::atomic< bool > fFlushScheduled
std::vector< CTransactionRef > vtx
const ChainTxData & TxData() const
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.
bool randbool()
Generate a random boolean.
std::string EncodeDestination(const CTxDestination &dest)
DBErrors ZapWalletTx(std::vector< CWalletTx > &vWtx)
static CFeeRate fallbackFee
If fee estimation does not have enough data to provide estimates, use this fee instead.
CAmount GetDebit(const CTxIn &txin, const isminefilter &filter) const
Returns amount of debit if the input matches the filter, otherwise returns 0.
bool ChangeWalletPassphrase(const SecureString &strOldWalletPassphrase, const SecureString &strNewWalletPassphrase)
CAmount GetCredit(const isminefilter &filter) const
int64_t GetTxTime() const
A key allocated from the key pool.
bool LoadKeyMetadata(const CTxDestination &pubKey, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
void SyncMetaData(std::pair< TxSpends::iterator, TxSpends::iterator >)
The block chain is a tree shaped structure starting with the genesis block at the root...
const CChainParams & Params()
Return the currently selected parameters.
bool ReadPool(int64_t nPool, CKeyPool &keypool)
Serialized script, used inside transaction inputs and outputs.
CAmount GetAccountCreditDebit(const std::string &strAccount)
bool IsSelected(const COutPoint &output) const
bool TopUpKeyPool(unsigned int kpSize=0)
bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret) override
Adds an encrypted key to the store, and saves it to disk.
unsigned int nTimeSmart
Stable timestamp that never changes, and reflects the order a transaction was added to the wallet...
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.
void ListAccountCreditDebit(const std::string &strAccount, std::list< CAccountingEntry > &entries)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
A virtual base class for key stores.
bool RelayWalletTransaction(CConnman *connman)
std::string verifier_string
CBlockIndex * FindForkInGlobalIndex(const CChain &chain, const CBlockLocator &locator)
Find the last common block between the parameter chain and a locator.
int64_t GetAdjustedTime()
void runCommand(const std::string &strCommand)
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...
A reference to a CKey: the Hash160 of its serialized public key.
bool ContextualCheckVerifierString(CAssetsCache *cache, const std::string &verifier, const std::string &check_address, std::string &strError, bool fWithTags)
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
std::string GetHex() const
bool GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew=false)
static CFeeRate minTxFee
Fees smaller than this (in satoshi) are considered zero fee (for transaction creation) Override with ...
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
void operator()(const CKeyID &keyId)
Fee rate in satoshis per kilobyte: CAmount / kB.
bool SetHDChain(const CHDChain &chain, bool memonly)
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip). ...
bool LoadCScript(const CScript &redeemScript)
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE)
Transaction fee set by the user.
std::vector< unsigned char > vchSalt
bool error(const char *fmt, const Args &... args)
std::map< uint256, CWalletTx > mapWallet
static const int VERSION_HD_CHAIN_SPLIT
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)
A reference to a CScript: the Hash160 of its serialization (see script.h)
bool GetKeyFromPool(CPubKey &key, bool internal=false)
std::vector< CKeyID > & vKeys
bool IsDust(const CTxOut &txout, const CFeeRate &dustRelayFeeIn)
A mutable version of CTransaction.
Indicates that we know how to create a scriptSig that would solve this if we were given the appropria...
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...
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
bool CheckForAddressRestriction(const std::string &restricted_name, const std::string &address, bool fSkipTempCache=false)
Return true if the address is marked as frozen.
unsigned int nTimeReceived
time received by this node
void InitWarning(const std::string &str)
Show warning message.
An encapsulated private key.
bool EraseName(const std::string &strAddress)
CClientUIInterface uiInterface
The basic transaction that is broadcasted on the network and contained in blocks. ...
int nHeight
height of the entry in the chain. The genesis block has height 0
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.
Information about a peer.
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
void ListLockedCoins(std::vector< COutPoint > &vOutpts) const
CAmount GetAvailableWatchOnlyCredit(const bool &fUseCache=true) const
CAmount GetCredit(const CTxOut &txout, const isminefilter &filter) const
unsigned int nDeriveIterations
full block available in blk*.dat
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
isminetype IsMine(const CTxIn &txin) const
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
CTxDestination destination
std::pair< CWalletTx *, CAccountingEntry * > TxPair
CKeyID seed_id
seed hash160
bool BackupWallet(const std::string &strDest)
bool AddAccountingEntry(const CAccountingEntry &)
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
std::string strOtherAccount
void ReturnKey(int64_t nIndex, bool fInternal, const CPubKey &pubkey)
bool AcceptToMemoryPool(const CAmount &nAbsurdFee, CValidationState &state)
Pass this transaction to the mempool.
int GetDepthInMainChain(const CBlockIndex *&pindexRet) const
Return depth of transaction in blockchain: <0 : conflicts with a transaction this deep in the blockch...
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
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.
bool ReadAccount(const std::string &strAccount, CAccount &account)
unsigned int nTx
Number of transactions in this block.
bool operator()(const std::pair< CInputCoin, CAmount > &t1, const std::pair< CInputCoin, CAmount > &t2) const
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
static const int VERSION_HD_BASE
CAmount GetChange(const CTxOut &txout) const
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
boost::signals2::signal< void(const std::string &message)> InitMessage
Progress message during initialization.
CAmount GetChange() const
bool RemoveWatchOnly(const CScript &dest) override
virtual bool GetCScript(const CScriptID &hash, CScript &redeemScriptOut) const =0
CPubKey GenerateNewSeed()
uint64_t GetRand(uint64_t nMax)
CAffectedKeysVisitor(const CKeyStore &keystoreIn, std::vector< CKeyID > &vKeysIn)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
bool Unlock(const SecureString &strWalletPassphrase)
int GetRequestCount() const
bool IsAssetNameAnRestricted(const std::string &name)
Check if an asset is a restricted asset.
bool AddWatchOnly(const CScript &dest) override
Support for Watch-only addresses.
std::vector< unsigned char > ToByteVector(const T &in)
const CKeyStore & keystore
std::vector< std::pair< std::string, std::string > > vOrderForm
bool HasWalletSpend(const uint256 &txid) const
Check if a given transaction has any of its outputs spent by another transaction in the wallet...
bool IsAssetScript(int &nType, bool &fIsOwner, int &nStartingIndex) const
CAmount GetFee(size_t nBytes) const
Return the fee in satoshis for the given size in bytes.
bool CommitTransaction(CWalletTx &wtxNew, CReserveKey &reservekey, CConnman *connman, CValidationState &state)
RVN END.
void GetAmounts(std::list< COutputEntry > &listReceived, std::list< COutputEntry > &listSent, CAmount &nFee, std::string &strSentAccount, const isminefilter &filter) const