33 #include <boost/algorithm/string.hpp>
40 #include <boost/algorithm/string/replace.hpp>
41 #include <boost/thread.hpp>
42 #include <boost/date_time/posix_time/posix_time.hpp>
45 #ifdef __linux__ //linux only
69 void ecdhEncode(
unsigned char* unmasked,
unsigned char* amount,
const unsigned char* sharedSec,
int size)
71 uint256 sharedSec1 =
Hash(sharedSec, sharedSec + size);
74 for (
int i = 0; i < 32; i++) {
75 unmasked[i] ^= *(sharedSec1.
begin() + i);
77 unsigned char temp[32];
79 for (
int i = 0; i < 32; i++) {
80 amount[i] = temp[i % 8] ^ *(sharedSec2.
begin() + i);
83 void ecdhDecode(
unsigned char* masked,
unsigned char* amount,
const unsigned char* sharedSec,
int size)
85 uint256 sharedSec1 =
Hash(sharedSec, sharedSec + size);
88 for (
int i = 0; i < 32; i++) {
89 masked[i] ^= *(sharedSec1.
begin() + i);
92 unsigned char temp[32];
95 for (
int i = 0; i < 32; i++) {
96 amount[i] = temp[i % 8] ^ *(sharedSec2.
begin() + i);
100 static std::string ValueFromAmountToString(
const CAmount &amount) {
101 bool sign = amount < 0;
102 int64_t n_abs = (sign ? -amount : amount);
103 int64_t quotient = n_abs / COIN;
104 int64_t remainder = n_abs % COIN;
105 std::string ret(
strprintf(
"%s%d.%08d", sign ?
"-" :
"", quotient, remainder));
112 unsigned char temp[65];
115 throw std::runtime_error(
"Cannot compute EC multiplication: secp256k1_ec_pubkey_tweak_mul");
116 sharedSec.
Set(temp, temp + 33);
128 unsigned char tempAmount[32], tempDecoded[32];
129 memcpy(tempDecoded, encodedMask, 32);
130 decodedMask.
Set(tempDecoded, tempDecoded + 32, 32);
131 memcpy(tempAmount, encodedAmount, 32);
134 memcpy(&decodedAmount, tempAmount, 8);
136 decodedMask.
Set(tempDecoded, tempDecoded + 32,
true);
137 memcpy(&decodedAmount, tempAmount, 8);
156 const std::pair<
CAmount, std::pair<const CWalletTx*, unsigned int> >& t2)
const
158 return t1.first < t2.first;
170 std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.find(hash);
173 return &(it->second);
179 std::vector<CWalletTx> result;
182 result.emplace_back(entry.second);
193 std::string passphrase(pass);
194 for (
int i = 0; i < passphrase.size(); i++) {
195 if (isupper(passphrase[i])) {
198 }
else if (islower(passphrase[i])) {
201 }
else if (isdigit(passphrase[i])) {
204 }
else if (!symbol) {
209 if (upper && lower && digit && symbol)
213 return upper && lower && digit && symbol;
230 int64_t nCreationTime =
GetTime();
236 throw std::runtime_error(
"CWallet::GenerateNewKey() : AddKey failed");
268 throw std::runtime_error(std::string(__func__) +
": WriteHDChain failed");
285 throw std::runtime_error(std::string(__func__) +
": WriteCryptedHDChain failed");
288 throw std::runtime_error(std::string(__func__) +
": WriteCryptedHDChain failed");
312 hdChainRet = hdChainTmp;
322 std::string strMnemonic =
GetArg(
"-mnemonic",
"");
324 std::string strMnemonicPassphrase =
GetArg(
"-mnemonicpassphrase",
"");
327 strMnemonic = *phrase;
328 strMnemonicPassphrase =
"";
331 SecureVector vchMnemonic(strMnemonic.begin(), strMnemonic.end());
332 SecureVector vchMnemonicPassphrase(strMnemonicPassphrase.begin(), strMnemonicPassphrase.end());
334 if (!newHdChain.
SetMnemonic(vchMnemonic, vchMnemonicPassphrase,
true))
335 throw std::runtime_error(std::string(__func__) +
": SetMnemonic failed");
338 throw std::runtime_error(std::string(__func__) +
": SetHDChain failed");
359 if (!hdChainCurrent.
GetMnemonic(mnemonic, mnemonicPass))
362 phrase = std::string(mnemonic.begin(), mnemonic.end()).c_str();
412 const std::vector<unsigned char>& vchCryptedSecret)
459 if (redeemScript.
size() > MAX_SCRIPT_ELEMENT_SIZE) {
461 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",
462 __func__, redeemScript.
size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
510 if (fromHeight == 0) {
513 int scannedHeight = 0;
524 for (std::map<uint256, CWalletTx>::iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
556 bool rescanNeeded =
false;
560 for (
const MasterKeyMap::value_type& pMasterKey :
mapMasterKeys) {
561 if (!crypter.
SetKeyFromPassphrase(strWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
603 bool keyPass =
false;
604 bool keyFail =
false;
607 const CPubKey& vchPubKey = (*mi).second.first;
608 const std::vector<unsigned char>& vchCryptedSecret = (*mi).second.second;
614 if (vchSecret.size() != 32) {
628 if (keyPass && keyFail) {
629 LogPrintf(
"The wallet is probably corrupted: Some keys decrypt but not all.\n");
630 throw std::runtime_error(
"Error unlocking wallet: some keys decrypt but not all. Your wallet file may be corrupt.");
632 if (keyFail || !keyPass)
637 bool chainPass =
false;
659 bool rescanNeeded =
false;
660 SecureString strOldWalletPassphraseFinal = strOldWalletPassphrase;
669 if (!crypter.
SetKeyFromPassphrase(strOldWalletPassphraseFinal, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
675 crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
676 pMasterKey.second.nDeriveIterations = pMasterKey.second.nDeriveIterations * (100 / ((double)(
GetTimeMillis() - nStartTime)));
679 crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod);
680 pMasterKey.second.nDeriveIterations = (pMasterKey.second.nDeriveIterations + pMasterKey.second.nDeriveIterations * 100 / ((double)(
GetTimeMillis() - nStartTime))) / 2;
682 if (pMasterKey.second.nDeriveIterations < 25000)
683 pMasterKey.second.nDeriveIterations = 25000;
685 LogPrintf(
"Wallet passphrase changed to an nDeriveIterations of %i\n", pMasterKey.second.nDeriveIterations);
687 if (!crypter.
SetKeyFromPassphrase(strNewWalletPassphrase, pMasterKey.second.vchSalt, pMasterKey.second.nDeriveIterations, pMasterKey.second.nDerivationMethod))
756 std::set<uint256> result;
759 std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.find(txid);
764 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
771 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
772 result.insert(it->second);
783 int nMinOrderPos = std::numeric_limits<int>::max();
785 for (TxSpends::iterator it = range.first; it != range.second; ++it) {
786 const uint256& hash = it->second;
788 if (n < nMinOrderPos) {
794 for (TxSpends::iterator it = range.first; it != range.second; ++it) {
795 const uint256& hash = it->second;
797 if (copyFrom == copyTo)
continue;
814 if (
mapArgs.count(
"-mintxfee")) {
819 return UIError(AmountErrMsg(
"mintxfee",
mapArgs[
"-mintxfee"]));
821 if (
mapArgs.count(
"-paytxfee")) {
824 return UIError(AmountErrMsg(
"paytxfee",
mapArgs[
"-paytxfee"]));
825 if (nFeePerK > nHighTransactionFeeWarning)
826 UIWarning(
_(
"Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction."));
829 return UIError(
strprintf(
_(
"Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)"),
833 if (
mapArgs.count(
"-maxtxfee")) {
836 return UIError(AmountErrMsg(
"maxtxfee",
mapArgs[
"-maxtxfee"]));
837 if (nMaxFee > nHighTransactionMaxFeeWarning)
838 UIWarning(
_(
"Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction."));
841 return UIError(
strprintf(
_(
"Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)"),
863 std::string keyImageHex;
865 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
867 for (TxSpends::const_iterator it = range.first; it != range.second; ++it) {
868 const uint256& wtxid = it->second;
869 std::map<uint256, CWalletTx>::const_iterator mit =
mapWallet.find(wtxid);
870 if (mit !=
mapWallet.end() &&
int(mit->second.GetDepthInMainChain()) >
int(0)) {
876 std::string outString = outpoint.
hash.
GetHex() + std::to_string(outpoint.
n);
888 std::pair<TxSpends::const_iterator, TxSpends::const_iterator> range;
891 for (TxSpends::const_iterator it = range.first; it != range.second; ++it)
893 const uint256& wtxid = it->second;
894 std::map<uint256, CWalletTx>::const_iterator mit =
mapWallet.find(wtxid);
895 if (mit !=
mapWallet.end() && mit->second.GetDepthInMainChain() >= 0)
896 return mit->second.GetDepthInMainChain();
903 mapTxSpends.insert(std::make_pair(outpoint, wtxid));
904 std::pair<TxSpends::iterator, TxSpends::iterator> range;
914 bool fAllFromMe =
true;
916 bool fAllToMe =
true;
917 for(
size_t i = 0; i < tx.
vin.size(); i++) {
924 if (fAllFromMe)
return "withdrawal";
925 for(
size_t i = 0; i < tx.
vout.size(); i++) {
933 if (fToMe)
return "deposit";
944 for (
const CTxIn& txin : thisTx.
vin) {
956 std::string outpoint = prevout.
hash.
GetHex() + std::to_string(prevout.
n);
964 std::string outpoint = out.
hash.
GetHex() + std::to_string(out.
n);
966 bool ret = (computed == ki);
978 pubScript = out.
tx->
vout[out.
i].scriptPubKey;
991 LogPrintf(
"%s: Address does not refer to a key\n", __func__);
995 if (!
GetKey(keyID, keyRet)) {
996 LogPrintf(
"%s: Private key for address is not known\n", __func__);
1005 LogPrintf(
"%s: Failed to generate key image\n", __func__);
1009 LogPrintf(
"%s: Failed to make Shnorr signature\n", __func__);
1015 LogPrintf(
"%s: Failed to verify Shnorr signature\n", __func__);
1034 std::vector<unsigned char> commitment;
1041 if (amount !=
Params().MNCollateralAmt()) {
1111 if (!hdChainCurrent.
IsNull()) {
1118 assert(hdChainCurrent.
GetID() == hdChainCrypted.
GetID());
1167 item.second.MarkDirty();
1183 for (
size_t i = 0; i < wtxIn.
vout.size(); i++) {
1184 std::string outpoint = hash.
GetHex() + std::to_string(i);
1202 if (fFromLoadWallet) {
1211 std::pair<std::map<uint256, CWalletTx>::iterator,
bool> ret =
mapWallet.insert(std::make_pair(hash, wtxIn));
1214 bool fInsertedNew = ret.second;
1224 bool fUpdated =
false;
1225 if (!fInsertedNew) {
1245 if (fInsertedNew || fUpdated)
1257 std::string strCmd =
GetArg(
"-walletnotify",
"");
1259 if (!strCmd.empty()) {
1277 if (fExisted && !fUpdate)
return false;
1283 }
catch (
const std::exception& e) {
1284 LogPrintf(
"Cannot open data base or wallet is locked\n");
1338 std::map<uint256, CWalletTx>::const_iterator mi =
mapWallet.find(prevout.
hash);
1341 if (prevout.
n < prev.
vout.size())
1353 for (
size_t i = 0; i < txin.
decoys.size(); i++) {
1354 std::string out = txin.
decoys[i].hash.GetHex() + std::to_string(txin.
decoys[i].n);
1379 for (
size_t i = 0; i < txin.
decoys.size(); i++) {
1390 outpoint = txin.
decoys[i];
1391 std::string out = txin.
decoys[i].hash.GetHex() + std::to_string(txin.
decoys[i].n);
1408 std::map<uint256, CWalletTx>::const_iterator mi =
mapWallet.find(prevout.
hash);
1411 if (prevout.
n < prev.
vout.size())
1456 nRequests = (*mi).second;
1462 nRequests = (*mi).second;
1468 nRequests = (*mi).second;
1564 for (
unsigned int i = 0; i <
vout.size(); i++) {
1597 for (
unsigned int i = 0; i <
vout.size(); i++) {
1621 for (
unsigned int i = 0; i <
vout.size(); i++) {
1669 for (
unsigned int i = 0; i <
vout.size(); i++) {
1682 std::list<COutputEntry>& listSent,
1684 std::string& strSentAccount,
1688 listReceived.clear();
1697 for (
unsigned int i = 0; i <
vout.size(); ++i) {
1707 }
else if (!(fIsMine & filter))
1723 listSent.push_back(output);
1726 if (fIsMine & filter)
1727 listReceived.push_back(output);
1733 nReceived = nSent = nFee = 0;
1736 std::string strSentAccount;
1737 std::list<COutputEntry> listReceived;
1738 std::list<COutputEntry> listSent;
1739 GetAmounts(listReceived, listSent, allFee, strSentAccount, filter);
1741 if (strAccount == strSentAccount) {
1750 std::map<CTxDestination, CAddressBookData>::const_iterator mi =
pwallet->
mapAddressBook.find(
r.destination);
1752 nReceived +=
r.amount;
1753 }
else if (strAccount.empty()) {
1754 nReceived +=
r.amount;
1772 std::multimap<COutPoint, uint256>::const_iterator itr =
mapTxSpends.cbegin();
1775 if (itr->second == wtxid)
1797 >>>>>>> 8b6832858a1ed35a91aa239a94722b31d6e659f1
1803 for (std::map<uint256, CWalletTx>::iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it)
1806 maxOrderPos = std::max(maxOrderPos, pwtx->
nOrderPos);
1810 auto key = std::make_pair(wtxHeight, pwtx->
nIndex);
1811 mapSorted.insert(make_pair(
key, pwtx));
1814 auto key = std::make_pair(maxSortNumber, 0);
1815 mapSorted.insert(std::make_pair(
key, pwtx));
1830 >>>>>>> 8b6832858a1ed35a91aa239a94722b31d6e659f1
1834 int64_t previousPosition = 0;
1835 std::map<const uint256, CWalletTx*> mapUpdatedTxs;
1838 for (std::map<std::pair<int,int>,
CWalletTx*>::iterator it = mapSorted.begin(); it != mapSorted.end(); ++it) {
1842 if (pwtx->
nOrderPos <= previousPosition || resetOrder) {
1845 mapUpdatedTxs.insert(std::make_pair(wtxid, pwtx));
1854 for (std::map<const uint256, CWalletTx*>::iterator it = mapUpdatedTxs.begin(); it != mapUpdatedTxs.end(); ++it) {
1871 >>>>>>> 8b6832858a1ed35a91aa239a94722b31d6e659f1
1881 bool removingTransactions =
false;
1882 if (removeTxs.size() > 0) {
1883 removingTransactions =
true;
1888 for (
int i = 0; i < removeTxs.size(); i++) {
1889 bool fRemoveFromSpends = !(
mapWallet.at(removeTxs[i]).IsCoinBase());
1891 if (fRemoveFromSpends) {
1906 return removingTransactions;
1915 bool runCompact =
false;
1916 bool deletedTransactions =
false;
1922 std::list<CAccountingEntry> acentries;
1925 if (acentries.size() > 0) {
1926 LogPrintf(
"deletetx not compatible to account entries\n");
1933 int64_t maxOrderPos = 0;
1934 std::map<std::pair<int,int>,
CWalletTx*> mapSorted;
1936 if (maxOrderPos > int64_t(mapSorted.size())*10) {
1948 int txConflictCount = 0;
1949 int txUnConfirmed = 0;
1951 int txSaveCount = 0;
1952 std::vector<uint256> removeTxs;
1954 for (
auto & item : mapSorted)
1958 bool deleteTx =
true;
1966 if (wtxDepth < nDeleteAfter && wtxDepth >= 0) {
1971 }
else if (wtxDepth == -1) {
1983 for (
unsigned int i = 0; i < pwtx->
vout.size(); i++) {
2001 for (
int i = 0; i < pwtx->
vin.size(); i++) {
2005 if (parent != NULL && parentHash != wtxid) {
2027 if (deleteTx &&
int(removeTxs.size()) < MAX_DELETE_TX_SIZE) {
2028 removeTxs.push_back(wtxid);
2043 LogPrintf(
"DeleteTx - Total Transaction Count %i, Transactions Deleted %i\n", txCount,
int(removeTxs.size()));
2053 return deletedTransactions;
2071 }
else if (height == -1) {
2083 if (pindex->
nHeight % 100 == 0 && dProgressTip - dProgressStart > 0.0)
2102 LogPrintf(
"%s: Deleting Txes 1 start\n", __func__);
2106 LogPrintf(
"%s: Deleting Txes 1 end\n", __func__);
2107 >>>>>>> 8b6832858a1ed35a91aa239a94722b31d6e659f1
2115 LogPrintf(
"Rescan aborted at block %d. Please rescanwallettransactions %f from the Debug Console to continue.\n", pindex->nHeight, pindex->nHeight);
2119 ShowProgress(
_(
"Rescanning... Please do not interrupt this process as it could lead to a corrupt wallet."), 100);
2124 LogPrintf(
"%s: Deleting Txes 2 start\n", __func__);
2126 LogPrintf(
"%s: Deleting Txes 2 end\n", __func__);
2127 >>>>>>> 8b6832858a1ed35a91aa239a94722b31d6e659f1
2135 std::map<int64_t, CWalletTx*> mapSorted;
2139 const uint256& wtxid = item.first;
2141 assert(wtx.
GetHash() == wtxid);
2146 mapSorted.insert(std::make_pair(wtx.
nOrderPos, &wtx));
2190 std::set<uint256> result;
2194 result.erase(myHash);
2216 LogPrintf(
"ResendWalletTransactions()\n");
2220 std::multimap<unsigned int, CWalletTx*> mapSorted;
2248 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2266 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2277 nTotal = nTotal - nLockedBalance;
2289 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2307 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2324 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2338 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2351 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2366 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2380 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2395 if (fOnlyConfirmed && !pcoin->
IsTrusted())
return false;
2400 if (fUseIX && nDepth < 6)
return false;
2404 if (nDepth == 0 && !pcoin->
InMempool())
return false;
2414 if (strTxHash.empty() || strOutputIndex.empty()) {
2415 strError =
"Invalid masternode collateral hash or output index";
2416 return error(
"%s: %s", __func__, strError);
2421 nOutputIndex = std::stoi(strOutputIndex.c_str());
2422 }
catch (
const std::exception& e) {
2423 strError =
"Invalid masternode output index";
2424 return error(
"%s: %s on strOutputIndex", __func__, e.what());
2429 std::map<uint256, CWalletTx>::const_iterator mi =
mapWallet.find(txHash);
2431 strError =
"collateral tx not found in the wallet";
2432 return error(
"%s: %s", __func__, strError);
2438 if (nOutputIndex < 0 || nOutputIndex >= (
int) wtx.
vout.size()) {
2439 strError =
"Invalid masternode output index";
2440 return error(
"%s: output index %d not found in %s", __func__, nOutputIndex, strTxHash);
2447 if (nValue !=
Params().MNCollateralAmt()) {
2448 strError =
"Invalid collateral tx value, must be 5,000 PRCY";
2449 return error(
"%s: tx %s, index %d not a masternode collateral", __func__, strTxHash, nOutputIndex);
2457 strError =
"Not available collateral transaction";
2458 return error(
"%s: tx %s not available", __func__, strTxHash);
2462 if (
IsSpent(txHash, nOutputIndex)) {
2463 strError =
"Error: collateral already spent";
2464 return error(
"%s: tx %s already spent", __func__, strTxHash);
2470 return error(
"%s: %s", __func__, strError);
2476 strError =
"Invalid collateral transaction. Not from this wallet";
2477 return error(
"%s: tx %s not mine", __func__, strTxHash);
2481 COutput(&wtx, nOutputIndex, nDepth,
true),
2491 std::vector<COutput>& vCoins,
2492 bool fOnlyConfirmed,
2494 bool fIncludeZeroValue,
2501 const bool fCoinsSelected = (coinControl !=
nullptr) && coinControl->
HasSelected();
2505 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2506 const uint256& wtxid = it->first;
2514 for (
unsigned int i = 0; i < pcoin->
vout.size(); i++) {
2515 if (pcoin->
vout[i].IsEmpty()) {
2532 if (!found)
continue;
2541 if (value <= 0 && !fIncludeZeroValue)
2547 bool fIsSpendable =
false;
2549 fIsSpendable =
true;
2555 vCoins.emplace_back(
COutput(pcoin, i, nDepth, fIsSpendable));
2564 std::vector<COutput> vCoins;
2567 std::map<CBitcoinAddress, std::vector<COutput> > mapCoins;
2570 if (maxCoinValue > 0 && value > maxCoinValue)
2583 static CAmount ApproximateBestSubset(
int numOut,
int ringSize, std::vector<std::pair<
CAmount, std::pair<const CWalletTx*, unsigned int> > > vValue,
const CAmount& nTotalLower,
const CAmount& nTargetValue, std::vector<char>& vfBest,
CAmount& nBest,
int iterations = 1000)
2585 std::vector<char> vfIncluded;
2587 vfBest.assign(vValue.size(),
true);
2588 nBest = nTotalLower;
2589 int estimateTxSize = 0;
2593 for (
int nRep = 0; nRep < iterations && nBest != nTargetValue + nFeeNeeded; nRep++) {
2594 vfIncluded.assign(vValue.size(),
false);
2596 bool fReachedTarget =
false;
2597 for (
int nPass = 0; nPass < 2 && !fReachedTarget; nPass++) {
2598 int numSelected = 0;
2599 for (
unsigned int i = 0; i < vValue.size(); i++) {
2606 if (nPass == 0 ? insecure_rand.
randbool() : !vfIncluded[i]) {
2607 nTotal += vValue[i].first;
2608 vfIncluded[i] =
true;
2612 if (nTotal >= nTargetValue + nFeeNeeded) {
2613 fReachedTarget =
true;
2614 if (nTotal < nBest) {
2616 vfBest = vfIncluded;
2618 nTotal -= vValue[i].first;
2619 vfIncluded[i] =
false;
2631 std::vector<COutput> vCoins;
2635 for (
const COutput &out : vCoins) {
2638 if (nAmountSelected + value > nTargetAmount)
2642 if (value <
Params().MinimumStakeAmount())
2646 if (value ==
Params().MNCollateralAmt()) {
2647 COutPoint outpoint(out.tx->GetHash(), out.i);
2653 int64_t nTxTime = out.tx->GetTxTime();
2660 if (out.nDepth < (out.tx->IsCoinStake() ?
Params().COINBASE_MATURITY() : 10))
2664 nAmountSelected += value;
2666 std::unique_ptr<CPrcyStake> input(
new CPrcyStake());
2668 listInputs.emplace_back(std::move(input));
2681 return error(
"%s : invalid reserve balance amount", __func__);
2685 std::vector<COutput> vCoins;
2688 for (
const COutput& out : vCoins) {
2689 int64_t nTxTime = out.tx->GetTxTime();
2695 bool isCollateral =
false;
2696 if (nVal ==
Params().MNCollateralAmt()) {
2697 COutPoint outpoint(out.tx->GetHash(), out.i);
2699 isCollateral =
true;
2722 if (nBalance < minStakingAmount) {
2729 std::vector<COutput> vCoins, coinsUnderThreshold, coinsOverThreshold;
2739 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
2740 const uint256& wtxid = it->first;
2754 if (pcoin->
GetTxTime() > nTime)
continue;
2756 for (
unsigned int i = 0; i < pcoin->
vout.size(); i++) {
2757 if (pcoin->
vout[i].IsEmpty()) {
2761 if (value ==
Params().MNCollateralAmt()) {
2787 COutput out(pcoin, i, nDepth,
true);
2788 if (value >= minStakingAmount) {
2789 coinsOverThreshold.push_back(out);
2791 coinsUnderThreshold.push_back(out);
2794 vCoins.emplace_back(out);
2800 int numUTXOs = coinsUnderThreshold.size();
2801 int numConsolidationTxs = numUTXOs > 0? 1:0;
2806 numConsolidationTxs++;
2812 if (coinsUnderThreshold.size() == 0) {
2815 if (nBalance < minStakingAmount + maxFee) {
2821 std::set<std::pair<const CWalletTx*, unsigned int> > setCoinsRet;
2828 if (!selectCoinRet) {
2832 minFee += estimatedFee;
2833 maxFee += estimatedFee;
2861 bool CWallet::SelectCoinsMinConf(
bool needFee,
CAmount& feeNeeded,
int ringSize,
int numOut,
const CAmount& nTargetValue,
int nConfMine,
int nConfTheirs, std::vector<COutput> vCoins, std::set<std::pair<const CWalletTx*, unsigned int> >& setCoinsRet,
CAmount& nValueRet)
2863 setCoinsRet.clear();
2869 std::pair<CAmount, std::pair<const CWalletTx*, unsigned int> > coinLowestLarger;
2870 coinLowestLarger.first = std::numeric_limits<CAmount>::max();
2871 coinLowestLarger.second.first = NULL;
2872 std::vector<std::pair<CAmount, std::pair<const CWalletTx*, unsigned int> > > vValue;
2876 random_shuffle(vCoins.begin(), vCoins.end(),
GetRandInt);
2878 for (
const COutput& output : vCoins) {
2879 if (!output.fSpendable)
2891 if (n == 0)
continue;
2894 std::pair<CAmount, std::pair<const CWalletTx*, unsigned int> > coin = std::make_pair(n, std::make_pair(pcoin, i));
2897 feeNeeded =
ComputeFee(vValue.size() + 1, numOut, ringSize);
2898 feeForOneInput =
ComputeFee(1, numOut, ringSize);
2900 if (n == nTargetValue + feeForOneInput) {
2901 setCoinsRet.clear();
2902 setCoinsRet.insert(coin.second);
2903 nValueRet = coin.first;
2904 feeNeeded = feeForOneInput;
2906 }
else if (n < nTargetValue + feeNeeded) {
2907 vValue.push_back(coin);
2909 }
else if (n < coinLowestLarger.first) {
2910 coinLowestLarger = coin;
2915 if (nTotalLower == nTargetValue + feeNeeded) {
2916 for (
unsigned int i = 0; i < vValue.size(); ++i) {
2917 setCoinsRet.insert(vValue[i].second);
2918 nValueRet += vValue[i].first;
2923 if (nTotalLower < nTargetValue + feeNeeded) {
2924 if (coinLowestLarger.second.first == NULL)
2926 setCoinsRet.insert(coinLowestLarger.second);
2927 nValueRet += coinLowestLarger.first;
2934 for (
unsigned int i = 0; i < vValue.size(); i++) {
2935 setCoinsRet.insert(vValue[i].second);
2936 nValueRet += vValue[i].first;
2947 for (
unsigned int i = 0; i < vValue.size(); i++) {
2948 setCoinsRet.insert(vValue[i].second);
2949 nValueRet += vValue[i].first;
2959 feeNeeded =
ComputeFee(50, numOut, ringSize);
2962 nValueRet += vValue[i].first;
2964 if (nValueRet < nTargetValue + feeNeeded) {
2966 for (
unsigned int i = 0; i < vValue.size(); i++) {
2967 setCoinsRet.insert(vValue[i].second);
2973 std::vector<char> vfBest;
2975 feeNeeded = ApproximateBestSubset(numOut, ringSize, vValue, nTotalLower, nTargetValue, vfBest, nBest, 1000);
2979 if (coinLowestLarger.second.first &&
2980 ((nBest != nTargetValue + feeNeeded && nBest < nTargetValue + feeNeeded) || coinLowestLarger.first <= nBest)) {
2981 setCoinsRet.insert(coinLowestLarger.second);
2982 nValueRet += coinLowestLarger.first;
2985 for (
unsigned int i = 0; i < vValue.size(); i++) {
2987 setCoinsRet.insert(vValue[i].second);
2988 nValueRet += vValue[i].first;
3007 for (std::map<uint256, CTxMemPoolEntry>::const_iterator it =
mempool.
mapTx.begin(); it !=
mempool.
mapTx.end(); ++it) {
3009 for (
size_t i = 0; i < tx.
vin.size(); i++) {
3023 bool CWallet::SelectCoins(
bool needFee,
CAmount& estimatedFee,
int ringSize,
int numOut,
const CAmount& nTargetValue, std::set<std::pair<const CWalletTx*, unsigned int> >& setCoinsRet,
CAmount& nValueRet,
const CCoinControl* coinControl,
AvailableCoinsType coin_type,
bool useIX)
3026 std::vector<COutput> vCoins;
3029 AvailableCoins(vCoins,
true, coinControl,
false, coin_type, useIX);
3033 for (
const COutput& out : vCoins) {
3034 if (!out.fSpendable)
3038 setCoinsRet.insert(std::make_pair(out.tx, out.i));
3040 return (nValueRet >= nTargetValue);
3043 return (
SelectCoinsMinConf(needFee, estimatedFee, ringSize, numOut, nTargetValue, 1, 6, vCoins, setCoinsRet, nValueRet) ||
3044 SelectCoinsMinConf(needFee, estimatedFee, ringSize, numOut, nTargetValue, 1, 1, vCoins, setCoinsRet, nValueRet) ||
3051 if (mne.getTxHash() == outpoint.
hash.
GetHex() && mne.getOutputIndex() == outpoint.
n) {
3082 std::string strFail =
"";
3083 std::vector<std::pair<CScript, CAmount> > vecSend;
3084 vecSend.push_back(std::make_pair(scriptChange, BUDGET_FEE_TX));
3089 LogPrintf(
"GetBudgetSystemCollateralTX: Error - %s\n", strFail);
3104 memset(pBlind, 0, 32);
3115 unsigned char output[33];
3119 std::copy(output, output + 33, std::back_inserter(commitment));
3125 int txinSize = 36 + 4 + 33 + 36 * ringSize;
3126 int txoutSize = 8 + 35 + 33 + 32 + 32 + 32 + 33;
3127 int bpSize = numOut == 1 ? 675 : 738;
3128 int txSize = 4 + numIn * txinSize + numOut * txoutSize + 4 + 1 + 8 + 4 + bpSize + 8 + 32 + (numIn + 1) * (ringSize + 1) * 32 + 33;
3143 if (nFeeNeeded > MAX_FEE) nFeeNeeded = MAX_FEE;
3147 bool CWallet::CreateTransactionBulletProof(
const CKey& txPrivDes,
const CPubKey& recipientViewKey,
CScript scriptPubKey,
const CAmount& nValue,
CWalletTx& wtxNew,
CReserveKey& reservekey,
CAmount& nFeeRet, std::string& strFailReason,
const CCoinControl* coinControl,
AvailableCoinsType coin_type,
bool useIX,
CAmount nFeePay,
int ringSize,
bool sendtoMyself)
3149 std::vector<std::pair<CScript, CAmount> > vecSend;
3150 vecSend.push_back(std::make_pair(scriptPubKey, nValue));
3151 return CreateTransactionBulletProof(txPrivDes, recipientViewKey, vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl, coin_type, useIX, nFeePay, ringSize, sendtoMyself);
3171 bool CWallet::CreateTransactionBulletProof(
const CKey& txPrivDes,
const CPubKey& recipientViewKey,
const std::vector<std::pair<CScript, CAmount> >& vecSend,
CWalletTx& wtxNew,
CReserveKey& reservekey,
CAmount& nFeeRet, std::string& strFailReason,
const CCoinControl* coinControl,
AvailableCoinsType coin_type,
bool useIX,
CAmount nFeePay,
int ringSize,
bool tomyself)
3173 if (useIX && nFeePay < CENT) nFeePay = CENT;
3177 unsigned char rand_seed[16];
3179 secp256k1_rand_seed(rand_seed);
3184 if (vecSend.size() > 1) {
3185 strFailReason =
_(
"Currently the Number of supported recipients must be 1");
3193 strFailReason =
_(
"Transaction amounts must be positive");
3198 if (vecSend.empty() || nValue < 0) {
3199 strFailReason =
_(
"Transaction amounts must be positive");
3214 if (nFeePay > 0) nFeeRet = nFeePay;
3215 unsigned int nBytes = 0;
3217 while (
true && iterations < 10) {
3223 CAmount nTotalValue = nValue + nFeeRet;
3224 double dPriority = 0;
3228 CTxOut txout(s.second, s.first);
3231 std::copy(txPub.
begin(), txPub.
end(), std::back_inserter(txout.
txPub));
3233 strFailReason =
_(
"Transaction amount too small");
3240 txNew.
vout.push_back(txout);
3247 std::set<std::pair<const CWalletTx*, unsigned int> > setCoins;
3250 if (!
SelectCoins(
true, estimateFee, ringSize, 2, nTotalValue, setCoins, nValueIn, coinControl, coin_type, useIX)) {
3252 if (nSpendableBalance < nTotalValue + estimateFee) {
3254 if (estimateFee > 0)
3256 strFailReason =
"Insufficient funds. Transaction requires a fee of " + ValueFromAmountToString(estimateFee);
3259 strFailReason =
"Insufficient reserved funds! Your wallet is staking with a reserve balance of " + ValueFromAmountToString(
nReserveBalance) +
" less than the sending amount " + ValueFromAmountToString(nTotalValue);
3262 strFailReason =
"Insufficient reserved funds! Your wallet is staking with a reserve balance of " + ValueFromAmountToString(
nReserveBalance) +
" less than the sending amount " + ValueFromAmountToString(nTotalValue);
3265 strFailReason =
_(
"You have attempted to send more than 50 UTXOs in a single transaction. To work around this limitation, please either lower the total amount of the transaction or send two separate transactions with 50% of your total desired amount.");
3268 strFailReason =
_(
"Error in CreateTransactionBulletProof. Please try again.");
3276 CAmount nChange = nValueIn - nValue - nFeeRet;
3283 CTxOut newTxOut(nChange, scriptChange);
3286 std::copy(txPubChange.
begin(), txPubChange.
end(), std::back_inserter(newTxOut.
txPub));
3292 LogPrintf(
"%s: nFeeNeeded=%d, rsSize=%d\n", __func__, nFeeNeeded, rsSize);
3293 if (nFeeNeeded >= MAX_FEE) nFeeNeeded = MAX_FEE;
3294 newTxOut.
nValue -= nFeeNeeded;
3295 txNew.
nTxFee = nFeeNeeded;
3296 if (newTxOut.
nValue < 0) {
3297 if (nSpendableBalance > nValueIn) {
3307 txNew.
vout.push_back(newTxOut);
3309 std::vector<CTxOut>::iterator position = txNew.
vout.begin() +
GetRandInt(txNew.
vout.size() + 1);
3310 txNew.
vout.insert(position, newTxOut);
3313 if (nSpendableBalance > nValueIn) {
3322 txNew.
vin.push_back(
CTxIn(coin.first->GetHash(), coin.second));
3328 if (ret && !
makeRingCT(wtxNew, ringSize, strFailReason)) {
3333 strFailReason =
_(
"Failed to generate bulletproof");
3339 for (
size_t i = 0; i < wtxNew.
vout.size(); i++) {
3340 wtxNew.
vout[i].nValue = 0;
3346 strFailReason =
_(
"Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
3355 for (
int i = 0; i < maxTxPrivKeys; i++) {
3356 std::string
key = hash.
GetHex() + std::to_string(i);
3371 std::string& strFailReason,
3377 if (useIX && nFeePay < CENT) nFeePay = CENT;
3383 strFailReason =
_(
"Transaction amounts must be positive");
3388 if (vecSend.empty() || nValue < 0) {
3389 strFailReason =
_(
"Transaction amounts must be positive");
3406 if (nFeePay > 0) nFeeRet = nFeePay;
3412 CAmount nTotalValue = nValue + nFeeRet;
3413 double dPriority = 0;
3418 CTxOut txout(s.second, s.first);
3420 strFailReason =
_(
"Transaction amount too small");
3423 txNew.
vout.push_back(txout);
3435 for (
int i = 0; i < nSplitBlock; i++) {
3436 if (i == nSplitBlock - 1) {
3437 uint64_t nRemainder = s.second % nSplitBlock;
3438 txNew.
vout.push_back(
CTxOut((s.second / nSplitBlock) + nRemainder, s.first));
3440 txNew.
vout.push_back(
CTxOut(s.second / nSplitBlock, s.first));
3446 std::set<std::pair<const CWalletTx*, unsigned int> > setCoins;
3449 if (!
SelectCoins(
true, estimatedFee, 10, 2, nTotalValue, setCoins, nValueIn, coinControl, coin_type, useIX)) {
3451 strFailReason =
_(
"Insufficient funds.");
3453 strFailReason =
_(
"Error in CreateTransaction. Please try again.");
3461 CAmount nCredit = pcoin.first->vout[pcoin.second].nValue;
3466 int age = pcoin.first->GetDepthInMainChain();
3469 dPriority += (double)nCredit * age;
3472 CAmount nChange = nValueIn - nValue - nFeeRet;
3497 CTxOut newTxOut(nChange, scriptChange);
3507 std::vector<CTxOut>::iterator position = txNew.
vout.begin() +
GetRandInt(txNew.
vout.size() + 1);
3508 txNew.
vout.insert(position, newTxOut);
3515 txNew.
vin.push_back(
CTxIn(coin.first->GetHash(), coin.second));
3521 strFailReason =
_(
"Signing transaction failed");
3529 if (nBytes >= MAX_STANDARD_TX_SIZE) {
3530 strFailReason =
_(
"Transaction too large");
3540 if (dPriorityNeeded <= 0 &&
AllowFree(dPriority))
3544 if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded)
3553 strFailReason =
_(
"Transaction too large for fee policy");
3566 unsigned char proof[2000];
3568 const size_t MAX_VOUT = 5;
3569 unsigned char nonce[32];
3571 unsigned char blinds[MAX_VOUT][32];
3572 uint64_t values[MAX_VOUT];
3574 const unsigned char* blind_ptr[MAX_VOUT];
3575 if (tx.
vout.size() > MAX_VOUT)
return false;
3576 memset(blinds, 0, tx.
vout.size() * 32);
3577 for (i = 0; i < tx.
vout.size(); i++) {
3578 memcpy(&blinds[i][0], tx.
vout[i].maskValue.inMemoryRawBind.begin(), 32);
3579 blind_ptr[i] = blinds[i];
3580 values[i] = tx.
vout[i].nValue;
3582 int ret =
secp256k1_bulletproof_rangeproof_prove(
GetContext(),
GetScratch(),
GetGenerator(), proof, &len, values, NULL, blind_ptr, tx.
vout.size(), &
secp256k1_generator_const_h, 64, nonce, NULL, 0);
3583 std::copy(proof, proof + len, std::back_inserter(tx.
bulletproofs));
3589 LogPrintf(
"Making RingCT using ring size=%d\n", ringSize);
3602 throw std::runtime_error(
"Cannot commit commitment");
3603 unsigned char output[33];
3605 throw std::runtime_error(
"Cannot serialize commitment");
3607 std::copy(output, output + 33, std::back_inserter(out.
commitment));
3614 const size_t MAX_VOUT = 5;
3617 strFailReason =
_(
"You have attempted to send a total value that is comprised of more than 50 smaller deposits. This is a rare occurrence, and lowering the total value sent, or sending the same total value in two separate transactions will usually work around this limitation.");
3621 for (
size_t i = 0; i < wtxNew.
vin.size(); i++) {
3622 if (wtxNew.
vin[i].decoys.size() != wtxNew.
vin[0].decoys.size()) {
3623 strFailReason =
_(
"All inputs should have the same number of decoys");
3628 if (wtxNew.
vin[0].decoys.size() > MAX_DECOYS || wtxNew.
vin[0].decoys.size() <
MIN_RING_SIZE) {
3629 strFailReason =
_(
"Too many decoys");
3633 std::vector<secp256k1_pedersen_commitment> myInputCommiments;
3634 int totalCommits = wtxNew.
vin.size() + wtxNew.
vout.size();
3635 int npositive = wtxNew.
vin.size();
3636 unsigned char myBlinds[MAX_VIN + MAX_VIN + MAX_VOUT + 1][32];
3637 memset(myBlinds, 0, (MAX_VIN + MAX_VIN + MAX_VOUT + 1) * 32);
3638 const unsigned char* bptr[MAX_VIN + MAX_VIN + MAX_VOUT + 1];
3640 unsigned char allInPubKeys[MAX_VIN + 1][MAX_DECOYS + 1][33];
3641 unsigned char allKeyImages[MAX_VIN + 1][33];
3642 unsigned char allInCommitments[MAX_VIN][MAX_DECOYS + 1][33];
3643 unsigned char allOutCommitments[MAX_VOUT][33];
3645 int myBlindsIdx = 0;
3647 for (
size_t j = 0; j < wtxNew.
vin.size(); j++) {
3649 if (myIndex == -1) {
3650 myOutpoint = wtxNew.
vin[j].prevout;
3652 myOutpoint = wtxNew.
vin[j].decoys[myIndex];
3657 throw std::runtime_error(
"Cannot find private key corresponding to the input");
3658 memcpy(&myBlinds[myBlindsIdx][0], tmp.
begin(), 32);
3659 bptr[myBlindsIdx] = &myBlinds[myBlindsIdx][0];
3666 if (myIndex == -1) {
3669 myOutpoint = in.
decoys[myIndex];
3674 strFailReason =
_(
"Cannot parse the commitment for inputs");
3678 myInputCommiments.push_back(inCommitment);
3684 std::vector<unsigned char> recomputedCommitment;
3685 if (!
CreateCommitment(&myBlinds[myBlindsIdx][0], tempAmount, recomputedCommitment))
3686 throw std::runtime_error(
"Cannot create pedersen commitment");
3687 if (recomputedCommitment != inTx.
vout[myOutpoint.
n].commitment) {
3688 strFailReason =
_(
"Input commitments are not correct");
3692 bptr[myBlindsIdx] = myBlinds[myBlindsIdx];
3702 bptr[myBlindsIdx] = &myBlinds[myBlindsIdx][0];
3708 memcpy(&myBlinds[myBlindsIdx][0], newBlind.
begin(), 32);
3709 bptr[myBlindsIdx] = &myBlinds[myBlindsIdx][0];
3711 int myRealIndex = 0;
3712 if (myIndex != -1) {
3713 myRealIndex = myIndex + 1;
3716 int PI = myRealIndex;
3717 unsigned char SIJ[MAX_VIN + 1][MAX_DECOYS + 1][32];
3718 unsigned char LIJ[MAX_VIN + 1][MAX_DECOYS + 1][33];
3719 unsigned char RIJ[MAX_VIN + 1][MAX_DECOYS + 1][33];
3720 unsigned char ALPHA[MAX_VIN + 1][32];
3721 unsigned char AllPrivKeys[MAX_VIN + 1][32];
3724 for (
size_t j = 0; j < wtxNew.
vin.size(); j++) {
3726 if (myIndex == -1) {
3727 myOutpoint = wtxNew.
vin[j].prevout;
3729 myOutpoint = wtxNew.
vin[j].decoys[myIndex];
3735 strFailReason =
_(
"Cannot find corresponding private key");
3740 memcpy(allKeyImages[j], wtxNew.
vin[j].keyImage.begin(), 33);
3743 memcpy(allInPubKeys[j][PI], tempPubKey.
begin(), 33);
3745 memcpy(allInCommitments[j][PI], &(inTx.
vout[myOutpoint.
n].commitment[0]), 33);
3756 unsigned char outSum[32];
3758 throw std::runtime_error(
"Cannot compute pedersen blind sum");
3759 memcpy(myBlinds[myBlindsIdx], outSum, 32);
3760 memcpy(AllPrivKeys[wtxNew.
vin.size()], outSum, 32);
3761 CKey additionalPkKey;
3762 additionalPkKey.
Set(myBlinds[myBlindsIdx], myBlinds[myBlindsIdx] + 32,
true);
3764 memcpy(allInPubKeys[wtxNew.
vin.size()][PI], additionalPubKey.
begin(), 33);
3770 CKey alpha_additional;
3774 memcpy(LIJ[wtxNew.
vin.size()][PI], LIJ_PI_additional.
begin(), 33);
3778 for (
int i = 0; i < (int)wtxNew.
vin.size() + 1; i++) {
3779 for (
int j = 0; j < (int)wtxNew.
vin[0].decoys.size() + 1; j++) {
3789 for (
int i = 0; i < (int)wtxNew.
vin.size(); i++) {
3790 std::vector<COutPoint> decoysForIn;
3791 decoysForIn.push_back(wtxNew.
vin[i].prevout);
3792 for (
int j = 0; j < (int)wtxNew.
vin[i].decoys.size(); j++) {
3793 decoysForIn.push_back(wtxNew.
vin[i].decoys[j]);
3795 for (
int j = 0; j < (int)wtxNew.
vin[0].decoys.size() + 1; j++) {
3804 strFailReason =
_(
"Cannot extract public key from script pubkey");
3807 memcpy(allInPubKeys[i][j], extractedPub.
begin(), 33);
3808 memcpy(allInCommitments[i][j], &(txPrev.
vout[decoysForIn[j].n].commitment[0]), 33);
3816 for (
size_t i = 0; i < wtxNew.
vout.size(); i++) {
3817 memcpy(&(allOutCommitments[i][0]), &(wtxNew.
vout[i].commitment[0]), 33);
3819 strFailReason =
_(
"Cannot parse the commitment for inputs");
3825 unsigned char txFeeBlind[32];
3826 memset(txFeeBlind, 0, 32);
3828 strFailReason =
_(
"Cannot parse the commitment for transaction fee");
3835 for (
size_t i = 0; i < wtxNew.
vout.size() + 1; i++) {
3836 outCptr[i] = &allOutCommitmentsPacked[i];
3839 for (
int i = 0; i < (int)wtxNew.
vin.size(); i++) {
3840 for (
int j = 0; j < (int)wtxNew.
vin[0].decoys.size() + 1; j++) {
3845 for (
int j = 0; j < (int)wtxNew.
vin[0].decoys.size() + 1; j++) {
3848 for (
int k = 0; k < (int)wtxNew.
vin.size(); k++) {
3850 strFailReason =
_(
"Cannot parse the commitment for inputs");
3853 inCptr[k] = &allInCommitmentsPacked[k][j];
3855 for (
size_t k = wtxNew.
vin.size(); k < 2 * wtxNew.
vin.size(); k++) {
3856 inCptr[k] = &inPubKeysToCommitments[k - wtxNew.
vin.size()][j];
3862 throw std::runtime_error(
"Cannot compute sum of commitment");
3864 throw std::runtime_error(
"Cannot covert from commitment to public key");
3869 int PI_interator = PI + 1;
3873 unsigned char CI[MAX_DECOYS + 1][32];
3874 unsigned char tempForHash[2 * (MAX_VIN + 1) * 33 + 32];
3875 unsigned char* tempForHashPtr = tempForHash;
3876 for (
size_t i = 0; i < wtxNew.
vin.size() + 1; i++) {
3877 memcpy(tempForHashPtr, &LIJ[i][PI][0], 33);
3878 tempForHashPtr += 33;
3879 memcpy(tempForHashPtr, &RIJ[i][PI][0], 33);
3880 tempForHashPtr += 33;
3885 if (PI_interator == (
int)wtxNew.
vin[0].decoys.size() + 1) PI_interator = 0;
3886 uint256 temppi1 =
Hash(tempForHash, tempForHash + 2 * (wtxNew.
vin.size() + 1) * 33 + 32);
3887 if (PI_interator == 0) {
3893 while (PI_interator != PI) {
3894 for (
int j = 0; j < (int)wtxNew.
vin.size() + 1; j++) {
3896 unsigned char CP[33];
3897 memcpy(CP, allInPubKeys[j][PI_interator], 33);
3899 strFailReason =
_(
"Cannot compute LIJ for ring signature in secp256k1_ec_pubkey_tweak_mul");
3903 strFailReason =
_(
"Cannot compute LIJ for ring signature in secp256k1_ec_pubkey_tweak_add");
3906 memcpy(LIJ[j][PI_interator], CP, 33);
3910 memcpy(RIJ[j][PI_interator], allKeyImages[j], 33);
3912 strFailReason =
_(
"Cannot compute RIJ for ring signature in secp256k1_ec_pubkey_tweak_mul");
3917 unsigned char SHP[33];
3919 tempP.
Set(allInPubKeys[j][PI_interator], allInPubKeys[j][PI_interator] + 33);
3930 twoElements[0] = &SHP_commitment;
3931 twoElements[1] = &cii_commitment;
3935 throw std::runtime_error(
"Cannot compute sum of commitments");
3938 strFailReason =
_(
"Cannot compute two elements and serialize it to pubkey");
3943 if (PI_interator == (
int)wtxNew.
vin[0].decoys.size() + 1) PI_interator = 0;
3946 if (PI_interator == 0) {
3947 prev = wtxNew.
vin[0].decoys.size();
3950 prev = PI_interator - 1;
3951 ciIdx = PI_interator;
3954 tempForHashPtr = tempForHash;
3955 for (
int i = 0; i < (int)wtxNew.
vin.size() + 1; i++) {
3956 memcpy(tempForHashPtr, LIJ[i][prev], 33);
3957 tempForHashPtr += 33;
3958 memcpy(tempForHashPtr, RIJ[i][prev], 33);
3959 tempForHashPtr += 33;
3962 uint256 ciHashTmp =
Hash(tempForHash, tempForHash + 2 * (wtxNew.
vin.size() + 1) * 33 + 32);
3967 for (
size_t j = 0; j < wtxNew.
vin.size() + 1; j++) {
3968 unsigned char cx[32];
3971 throw std::runtime_error(
"Cannot compute EC mul");
3972 const unsigned char* sumArray[2];
3973 sumArray[0] = ALPHA[j];
3976 throw std::runtime_error(
"Cannot compute pedersen blind sum");
3980 for (
int i = 0; i < (int)wtxNew.
vin[0].decoys.size() + 1; i++) {
3981 std::vector<uint256> S_column;
3982 for (
int j = 0; j < (int)wtxNew.
vin.size() + 1; j++) {
3985 S_column.push_back(t);
3987 wtxNew.
S.push_back(S_column);
4019 unsigned char R[33];
4023 unsigned char buff[33 + 32];
4029 unsigned char ex[32];
4033 std::copy(ex, ex + 32, std::back_inserter(txin.
s));
4035 std::copy(
R,
R + 33, std::back_inserter(txin.
R));
4041 LogPrintf(
"Selecting coinbase decoys for transaction\n");
4048 int coinbaseIdx = 0;
4053 if (
b.posBlocksAudited.size() > 0)
continue;
4056 for (
size_t i = 0; i < coinbase.
vout.size(); i++) {
4057 if (!coinbase.
vout[i].IsNull() && !coinbase.
vout[i].commitment.empty() && coinbase.
vout[i].nValue > 0 && !coinbase.
vout[i].IsEmpty()) {
4069 std::map<COutPoint, uint256>::const_iterator it = std::next(
coinbaseDecoysPool.begin(), selected);
4082 for (
size_t i = 0; i < tx.
vin.size(); i++) {
4087 LogPrintf(
"Selected transaction: %s is not in the main chain\n", tx.
vin[i].prevout.hash.GetHex().c_str());
4092 LogPrintf(
"tx.nLockTime != 0, currently disabled\n");
4105 if (ancestor != atTheblock) {
4112 LogPrintf(
"Cannot generate key image\n");
4115 tx.
vin[i].keyImage = ki;
4122 while (numDecoys < ringSize) {
4123 bool duplicated =
false;
4124 bool invalid =
false;
4132 for (
size_t d = 0; d < tx.
vin[i].decoys.size(); d++) {
4133 if (tx.
vin[i].decoys[d] == outpoint) {
4139 if (duplicated || invalid) {
4143 if (duplicated || invalid) {
4146 tx.
vin[i].decoys.push_back(outpoint);
4151 std::map<COutPoint, uint256>::const_iterator it = std::next(
coinbaseDecoysPool.begin(), j);
4161 tx.
vin[i].decoys.push_back(outpoint);
4163 if (numDecoys == ringSize)
break;
4166 LogPrintf(
"Not enough decoys. Please wait approximately 10 minutes and try again.\n");
4172 if ((
int)decoySet.size() >= ringSize * 5) {
4173 while (numDecoys < ringSize) {
4174 bool duplicated =
false;
4175 bool invalid =
false;
4176 std::map<COutPoint, uint256>::const_iterator it = std::next(decoySet.begin(), secp256k1_rand32() % decoySet.size());
4183 for (
size_t d = 0; d < tx.
vin[i].decoys.size(); d++) {
4184 if (tx.
vin[i].decoys[d] == outpoint) {
4190 if (duplicated || invalid) {
4194 if (duplicated || invalid) {
4197 tx.
vin[i].decoys.push_back(outpoint);
4200 }
else if ((
int)decoySet.size() >= ringSize) {
4201 for (
size_t j = 0; j < decoySet.size(); j++) {
4202 std::map<COutPoint, uint256>::const_iterator it = std::next(decoySet.begin(), j);
4212 tx.
vin[i].decoys.push_back(outpoint);
4214 if (numDecoys == ringSize)
break;
4217 LogPrintf(
"Not enough decoys. Please wait approximately 10 minutes and try again.\n");
4222 myIndex = secp256k1_rand32() % (tx.
vin[0].decoys.size() + 1) - 1;
4224 for (
size_t i = 0; i < tx.
vin.size(); i++) {
4231 if (myIndex != -1) {
4232 for (
size_t i = 0; i < tx.
vin.size(); i++) {
4233 if (tx.
vin[i].decoys.size() <= myIndex || tx.
vin[i].decoys.size() != ringSize) {
4234 throw std::runtime_error(
"Failed to annonymize the transaction, please wait about 10 minutes to re-create your transaction");
4237 tx.
vin[i].prevout = tx.
vin[i].decoys[myIndex];
4238 tx.
vin[i].decoys[myIndex] = prevout;
4247 std::vector<std::pair<CScript, CAmount> > vecSend;
4248 vecSend.push_back(std::make_pair(scriptPubKey, nValue));
4249 return CreateTransaction(vecSend, wtxNew, reservekey, nFeeRet, strFailReason, coinControl, coin_type, useIX, nFeePay);
4273 unsigned char aR[33];
4278 throw std::runtime_error(
"Failed to do secp256k1_ec_privkey_tweak_mul");
4284 unsigned char HStemp[32];
4285 unsigned char spendTemp[32];
4288 throw std::runtime_error(
"Failed to do secp256k1_ec_privkey_tweak_add");
4290 privKey.
Set(HStemp, HStemp + 32,
true);
4296 LogPrintf(
"AddComputedPrivateKey: Fail to generate corresponding private key\n");
4305 int64_t nSearchInterval,
4307 unsigned int& nTxNewTime
4313 int static wlIdx = 0;
4319 scriptEmpty.
clear();
4320 txNew.
vout.push_back(
CTxOut(0, scriptEmpty));
4327 return error(
"CreateCoinStake : invalid reserve balance amount");
4333 std::list<std::unique_ptr<CStakeInput> > listInputs;
4335 LogPrintf(
"CreateCoinStake(): selectStakeCoins failed\n");
4339 if (listInputs.empty()) {
4346 if (
Params().IsRegTestNet()) {
4353 bool fKernelFound =
false;
4355 for (std::unique_ptr<CStakeInput>& stakeInput : listInputs) {
4363 if (!pindex || pindex->
nHeight < 1) {
4364 LogPrintf(
"CreateCoinStake(): no pindexfrom\n");
4375 if (
Stake(stakeInput.get(), nBits, block.
GetBlockTime(), nTxNewTime, hashProofOfStake)) {
4378 LogPrintf(
"CreateCoinStake() : kernel found, but it is too far in the past \n");
4383 LogPrintf(
"CreateCoinStake : kernel found\n");
4384 nCredit += stakeInput->GetValue();
4385 std::vector<CTxOut> vout;
4386 if (!stakeInput->CreateTxOuts(
this, vout, nCredit)) {
4387 LogPrintf(
"%s : failed to get scriptPubKey\n", __func__);
4390 txNew.
vout.insert(txNew.
vout.end(), vout.begin(), vout.end());
4395 txNew.
vout[1].nValue = nCredit;
4396 txNew.
vout[2].nValue = nReward;
4400 if (nBytes >= DEFAULT_BLOCK_MAX_SIZE / 5)
4401 return error(
"CreateCoinStake : exceeded coinstake size limit");
4405 LogPrintf(
"%s: Cannot fill block payee\n", __func__);
4411 if (!stakeInput->CreateTxIn(
this, in, hashTxOut)) {
4412 LogPrintf(
"%s : failed to create TxIn\n", __func__);
4417 txNew.
vin.push_back(in);
4419 fKernelFound =
true;
4433 for (
size_t i = 1; i < txNew.
vout.size(); i++) {
4434 sharedSec1.
Set(txNew.
vout[i].txPub.begin(), txNew.
vout[i].txPub.end());
4437 unsigned char zeroBlind[32];
4438 memset(zeroBlind, 0, 32);
4439 txNew.
vout[i].commitment.clear();
4448 return error(
"CreateCoinStake : failed to sign coinstake");
4478 std::set<uint256> updated_hahes;
4479 for (
const CTxIn& txin : wtxNew.
vin) {
4482 if (updated_hahes.find(prevout.
hash) != updated_hahes.end())
continue;
4487 updated_hahes.insert(prevout.
hash);
4501 LogPrintf(
"CommitTransaction() : Error: Transaction not valid\n");
4525 if (nFeeNeeded >= MAX_FEE) nFeeNeeded = MAX_FEE;
4533 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
4544 fFirstRunRet =
false;
4557 return nLoadWalletRet;
4583 return nZapWalletTxRet;
4591 bool fUpdated =
false;
4594 std::map<CTxDestination, CAddressBookData>::iterator mi =
mapAddressBook.find(address);
4597 if (!strPurpose.empty())
4658 int64_t nKeys = std::max(
GetArg(
"-keypool", 1000), (int64_t)0);
4659 for (
int i = 0; i < nKeys; i++) {
4660 int64_t nIndex = i + 1;
4664 LogPrintf(
"CWallet::NewKeyPool wrote %d new keys\n", nKeys);
4678 bool bKeyUsed =
false;
4717 unsigned int nTargetSize;
4719 nTargetSize = kpSize;
4721 nTargetSize = std::max(
GetArg(
"-keypool", 1000), (int64_t)0);
4757 if (!walletdb.
ReadPool(nIndex, keypool))
4758 throw std::runtime_error(
"ReserveKeyFromKeyPool() : read failed");
4760 throw std::runtime_error(
"ReserveKeyFromKeyPool() : unknown key in key pool");
4762 LogPrintf(
"keypool reserve %d\n", nIndex);
4776 std::string viewAccountLabel =
"viewaccount";
4777 std::string spendAccountLabel =
"spendaccount";
4781 walletdb.
ReadAccount(viewAccountLabel, viewAccount);
4783 walletdb.
ReadAccount(viewAccountLabel, viewAccount);
4791 walletdb.
ReadAccount(spendAccountLabel, spendAccount);
4793 walletdb.
ReadAccount(spendAccountLabel, spendAccount);
4826 LogPrintf(
"keypool return %d\n", nIndex);
4855 return keypool.
nTime;
4860 std::map<CTxDestination, CAmount> balances;
4877 for (
unsigned int i = 0; i < pcoin->
vout.size(); i++) {
4886 if (!balances.count(addr))
4888 balances[addr] += n;
4899 std::set<std::set<CTxDestination> > groupings;
4900 std::set<CTxDestination> grouping;
4905 if (pcoin->
vin.size() > 0) {
4906 bool any_mine =
false;
4914 grouping.insert(address);
4925 grouping.insert(txoutAddr);
4928 if (grouping.size() > 0) {
4929 groupings.insert(grouping);
4935 for (
unsigned int i = 0; i < pcoin->
vout.size(); i++)
4940 grouping.insert(address);
4941 groupings.insert(grouping);
4946 std::set<std::set<CTxDestination>*> uniqueGroupings;
4947 std::map<CTxDestination, std::set<CTxDestination>*> setmap;
4948 for (std::set<CTxDestination> grouping : groupings) {
4950 std::set<std::set<CTxDestination>*> hits;
4951 std::map<CTxDestination, std::set<CTxDestination>*>::iterator it;
4953 if ((it = setmap.find(address)) != setmap.end())
4954 hits.insert((*it).second);
4957 std::set<CTxDestination>* merged =
new std::set<CTxDestination>(grouping);
4958 for (std::set<CTxDestination>* hit : hits) {
4959 merged->insert(hit->begin(), hit->end());
4960 uniqueGroupings.erase(hit);
4963 uniqueGroupings.insert(merged);
4967 setmap[element] = merged;
4970 std::set<std::set<CTxDestination> > ret;
4971 for (std::set<CTxDestination>* uniqueGrouping : uniqueGroupings) {
4972 ret.insert(*uniqueGrouping);
4973 delete uniqueGrouping;
4982 std::set<CTxDestination> result;
4985 const std::string& strName = item.second.name;
4986 if (strName == strAccount)
4987 result.insert(address);
5033 if (!walletdb.
ReadPool(
id, keypool))
5034 throw std::runtime_error(
"GetAllReserveKeyHashes() : read failed");
5038 throw std::runtime_error(
"GetAllReserveKeyHashes() : unknown key in key pool");
5039 setAddress.insert(keyID);
5048 std::map<uint256, CWalletTx>::const_iterator mi =
mapWallet.find(hashTx);
5089 vOutpts.push_back(outpt);
5107 std::vector<CTxDestination> vDest;
5111 boost::apply_visitor(*
this, dest);
5118 vKeys.push_back(keyId);
5134 mapKeyBirth.clear();
5138 if (it->second.nCreateTime)
5139 mapKeyBirth[it->first] = it->second.nCreateTime;
5143 std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
5144 std::set<CKeyID> setKeys;
5146 for (
const CKeyID& keyid : setKeys) {
5147 if (mapKeyBirth.count(keyid) == 0)
5148 mapKeyFirstBlock[keyid] = pindexMax;
5153 if (mapKeyFirstBlock.empty())
5157 std::vector<CKeyID> vAffected;
5158 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); it++) {
5164 int nHeight = blit->second->nHeight;
5168 for (
const CKeyID& keyid : vAffected) {
5170 std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
5171 if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
5172 rit->second = blit->second;
5180 for (std::map<CKeyID, CBlockIndex*>::const_iterator it = mapKeyFirstBlock.begin(); it != mapKeyFirstBlock.end(); it++)
5181 mapKeyBirth[it->first] = it->second->GetBlockTime() - 7200;
5190 int64_t latestEntry = 0;
5193 int64_t latestTolerated = latestNow + 300;
5195 for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) {
5196 CWalletTx*
const pwtx = (*it).second.first;
5206 nSmartTime = pacentry->
nTime;
5207 if (nSmartTime <= latestTolerated) {
5208 latestEntry = nSmartTime;
5209 if (nSmartTime > latestNow)
5210 latestNow = nSmartTime;
5217 nTimeSmart = std::max(latestEntry, std::min(blocktime, latestNow));
5219 LogPrintf(
"AddToWallet() : found %s in block %s not in index\n",
5228 if (boost::get<CNoDestination>(&dest))
5254 std::string strFailReason;
5256 strFailReason =
"Wallet is locked! Please unlock it to make transactions.";
5257 LogPrintf(
"%s: %s\n", __func__, strFailReason);
5258 throw std::runtime_error(strFailReason);
5265 strFailReason =
"Not enough balance to pay minimum transaction fee: " + ValueFromAmountToString(nFeeNeeded);
5266 LogPrintf(
"%s: %s\n", __func__, strFailReason);
5267 throw std::runtime_error(strFailReason);
5271 std::vector<COutput> vCoins;
5277 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
5278 const uint256& wtxid = it->first;
5286 for (
size_t i = 0; i < pcoin->
vout.size(); i++) {
5287 if (pcoin->
vout[i].IsEmpty())
continue;
5297 std::vector<unsigned char> commitment;
5298 if (!decodedBlind.
IsValid()) {
5299 unsigned char blind[32];
5304 if (pcoin->
vout[i].commitment != commitment) {
5305 LogPrintf(
"%s: Commitment not match hash = %s, i = %d, commitment = %s, recomputed = %s, revealed mask = %s\n", __func__, pcoin->
GetHash().
GetHex(), i,
HexStr(&pcoin->
vout[i].commitment[0], &pcoin->
vout[i].commitment[0] + 33),
HexStr(&commitment[0], &commitment[0] + 33),
HexStr(decodedBlind.
begin(), decodedBlind.
begin() + 32));
5309 if (
IsSpent(wtxid, i))
continue;
5320 vCoins.push_back(
COutput(pcoin, i, nDepth,
true));
5321 total += decodedAmount;
5328 strFailReason =
"Transaction size too large. Please combine/consolidate UTXOs and try again.";
5330 LogPrintf(
"%s: %s\n", __func__, strFailReason);
5331 throw std::runtime_error(strFailReason);
5340 unsigned char rand_seed[16];
5342 secp256k1_rand_seed(rand_seed);
5347 if (total < nFeeNeeded) {
5348 strFailReason =
"Not enough balance to pay minimum transaction Fee: " + ValueFromAmountToString(nFeeNeeded);
5350 LogPrintf(
"%s: %s\n", __func__, strFailReason);
5351 throw std::runtime_error(strFailReason);
5354 CPubKey pubViewKey, pubSpendKey;
5361 strFailReason =
"Invalid Destination Address!";
5362 LogPrintf(
"%s: %s\n", __func__, strFailReason);
5363 throw std::runtime_error(strFailReason);
5383 CAmount nValue = total - nFeeNeeded;
5397 double dPriority = 0;
5400 CTxOut txout(nValue, scriptPubKey);
5403 std::copy(txPub.
begin(), txPub.
end(), std::back_inserter(txout.
txPub));
5408 txNew.
vout.push_back(txout);
5409 txNew.
nTxFee = nFeeNeeded;
5412 for (
size_t i = 0; i < vCoins.size(); i++) {
5413 txNew.
vin.push_back(
CTxIn(vCoins[i].tx->GetHash(), vCoins[i].i));
5421 if (!
makeRingCT(wtxNew, ringSize, strFailReason)) {
5422 strFailReason =
_(
"Failed to generate RingCT");
5424 LogPrintf(
"%s: %s\n", __func__, strFailReason);
5425 throw std::runtime_error(strFailReason);
5429 strFailReason =
_(
"Failed to generate bulletproof");
5431 LogPrintf(
"%s: %s\n", __func__, strFailReason);
5432 throw std::runtime_error(strFailReason);
5436 for (
size_t i = 0; i < wtxNew.
vout.size(); i++) {
5437 wtxNew.
vout[i].nValue = 0;
5442 strFailReason =
"Internal error! Please try again later!";
5444 LogPrintf(
"%s: %s\n", __func__, strFailReason);
5445 throw std::runtime_error(strFailReason);
5455 for (
int i = 0; i < maxTxPrivKeys; i++) {
5456 std::string
key = hash.
GetHex() + std::to_string(i);
5482 std::vector<COutput> vCoins;
5483 COutput lowestLarger(NULL, 0, 0,
false);
5484 CAmount currentLowestLargerAmount = 0;
5487 bool isReserveUTXOExist =
false;
5492 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
5493 const uint256& wtxid = it->first;
5496 if (pcoin->
GetTxTime() > nTimeBefore)
continue;
5503 for (
size_t i = 0; i < pcoin->
vout.size(); i++) {
5504 if (pcoin->
vout[i].IsEmpty())
continue;
5514 std::vector<unsigned char> commitment;
5515 if (!decodedBlind.
IsValid()) {
5516 unsigned char blind[32];
5521 if (pcoin->
vout[i].commitment != commitment) {
5522 LogPrintf(
"%s: Commitment not match hash = %s, i = %d, commitment = %s, recomputed = %s, revealed mask = %s\n", __func__, pcoin->
GetHash().
GetHex(), i,
HexStr(&pcoin->
vout[i].commitment[0], &pcoin->
vout[i].commitment[0] + 33),
HexStr(&commitment[0], &commitment[0] + 33),
HexStr(decodedBlind.
begin(), decodedBlind.
begin() + 32));
5526 if (
IsSpent(wtxid, i))
continue;
5541 isReserveUTXOExist =
true;
5542 reserveHash = wtxid;
5548 if (nDepth <= 5)
continue;
5549 if (decodedAmount >= threshold) {
5550 if (lowestLarger.
tx == NULL || (lowestLarger.
tx != NULL && currentLowestLargerAmount > decodedAmount)) {
5551 lowestLarger.
tx = pcoin;
5553 lowestLarger.
nDepth = nDepth;
5555 currentLowestLargerAmount = decodedAmount;
5561 vCoins.push_back(
COutput(pcoin, i, nDepth,
true));
5562 total += decodedAmount;
5568 if (!isReserveUTXOExist) {
5571 std::string masterAddr;
5575 }
catch (
const std::exception& err) {
5576 LogPrintf(
"Failed to create reserve UTXO\n");
5580 if (
mapWallet.count(reserveHash) < 1)
return false;
5590 if (vCoins.size() <= 1)
return false;
5596 LogPrintf(
"Attempting to create a sweeping transaction\n");
5598 if (total < target + estimatedFee) {
5599 if (lowestLarger.
tx != NULL && currentLowestLargerAmount >= threshold) {
5600 vCoins.push_back(lowestLarger);
5601 total += currentLowestLargerAmount;
5603 LogPrintf(
"No set of UTXOs to combine into a stakeable coin - autocombine any way if minimum UTXOs satisfied\n");
5608 LogPrintf(
"Generating consolidation transaction, total = %d PRCY\n", total / COIN);
5615 int estimateTxSize =
ComputeTxSize(vCoins.size(), 1, ringSize);
5617 if (total < nFeeNeeded * 2) {
5620 std::string myAddress;
5623 CPubKey pubViewKey, pubSpendKey;
5644 CAmount nValue = total - nFeeNeeded;
5653 unsigned int nBytes = 0;
5659 double dPriority = 0;
5661 CTxOut txout(nValue, scriptPubKey);
5664 std::copy(txPub.
begin(), txPub.
end(), std::back_inserter(txout.
txPub));
5669 txNew.
vout.push_back(txout);
5672 txNew.
nTxFee = nFeeNeeded;
5675 for (
size_t i = 0; i < vCoins.size(); i++) {
5676 txNew.
vin.push_back(
CTxIn(vCoins[i].tx->GetHash(), vCoins[i].i));
5684 std::string strFailReason;
5685 if (!
makeRingCT(wtxNew, ringSize, strFailReason)) {
5690 strFailReason =
_(
"There is an internal error in generating bulletproofs. Please try again later.");
5695 for (
size_t i = 0; i < wtxNew.
vout.size(); i++) {
5696 wtxNew.
vout[i].nValue = 0;
5711 for (
int i = 0; i < maxTxPrivKeys; i++) {
5712 std::string
key = hash.
GetHex() + std::to_string(i);
5746 LogPrintf(
"Attempting to create a consolidation transaction for a larger UTXO for staking\n");
5759 std::vector<COutput> vCoins, underStakingThresholdCoins;
5763 for (std::map<uint256, CWalletTx>::const_iterator it =
mapWallet.begin(); it !=
mapWallet.end(); ++it) {
5764 const uint256& wtxid = it->first;
5772 for(
size_t i = 0; i < pcoin->
vout.size(); i++) {
5773 if (pcoin->
vout[i].IsEmpty())
continue;
5783 std::vector<unsigned char> commitment;
5784 if (!decodedBlind.
IsValid()) {
5785 unsigned char blind[32];
5790 if (pcoin->
vout[i].commitment != commitment) {
5791 LogPrintf(
"%s: Commitment not match hash = %s, i = %d, commitment = %s, recomputed = %s, revealed mask = %s\n", __func__, pcoin->
GetHash().
GetHex(), i,
HexStr(&pcoin->
vout[i].commitment[0], &pcoin->
vout[i].commitment[0] + 33),
HexStr(&commitment[0], &commitment[0] + 33),
HexStr(decodedBlind.
begin(), decodedBlind.
begin() + 32));
5795 if (
IsSpent(wtxid, i))
continue;
5803 vCoins.push_back(
COutput(pcoin, i, nDepth,
true));
5804 total += decodedAmount;
5805 if (decodedAmount < minStakingAmount) underStakingThresholdCoins.push_back(
COutput(pcoin, i, nDepth,
true));
5813 if (total < minStakingAmount)
return false;
5814 size_t numUTXOs = vCoins.size();
5831 LogPrintf(
"Multisend: lastmultisendheight is higher than current best height\n");
5835 std::vector<COutput> vCoins;
5838 bool stakeSent =
false;
5839 bool mnSent =
false;
5840 for (
const COutput& out : vCoins) {
5842 if (out.tx->GetDepthInMainChain() !=
Params().COINBASE_MATURITY() + 1)
5845 COutPoint outpoint(out.tx->GetHash(), out.i);
5847 bool sendMSOnStake =
fMultiSendStake && out.tx->IsCoinStake() && !sendMSonMNReward;
5849 if (!(sendMSOnStake || sendMSonMNReward))
5854 LogPrintf(
"Multisend: failed to extract destination\n");
5862 LogPrintf(
"Multisend: disabled address preventing multisend\n");
5870 COutPoint outpt(out.tx->GetHash(), out.i);
5877 std::vector<std::pair<CScript, CAmount> > vecSend;
5882 for (
unsigned int i = 0; i <
vMultiSend.size(); i++) {
5884 nAmount = ((out.tx->GetCredit(filter) - out.tx->GetDebit(filter)) *
vMultiSend[i].second) / 100;
5888 vecSend.push_back(std::make_pair(scriptPubKey, nAmount));
5895 CAmount nLastSendAmount = vecSend[vecSend.size() - 1].second;
5896 if (nLastSendAmount < nFeeRet + 500) {
5897 LogPrintf(
"%s: fee of %d is too large to insert into last output\n", __func__, nFeeRet + 500);
5900 vecSend[vecSend.size() - 1].second = nLastSendAmount - nFeeRet - 500;
5904 LogPrintf(
"MultiSend createtransaction failed\n");
5909 LogPrintf(
"MultiSend transaction commit failed\n");
5918 LogPrintf(
"Failed to write MultiSend setting to DB\n");
5920 LogPrintf(
"MultiSend successfully sent\n");
5967 LogPrintf(
"ERROR: SetMerkleBranch() : couldn't find tx in block\n");
6042 return (depth > 0 && depth <=
Params().COINBASE_MATURITY());
6062 return (*i).second.CountSignatures();
6075 return GetTime() > (*i).second.nTimeout;
6083 std::stringstream ssDateTime;
6085 ssDateTime << strWalletBackupName;
6208 nCredit +=
GetCredit(tx, txout, filter);
6321 const CTxOut& parentOut = parent->
vout[prevout.
n];
6397 void add1s(std::string& s,
int wantedSize)
6399 int currentLength = s.length();
6400 for (
int i = 0; i < wantedSize - currentLength; i++) {
6408 if (raw.size() != 71 && raw.size() != 79) {
6415 while (i < (
int)raw.size()) {
6416 std::vector<unsigned char> input8;
6417 std::copy(raw.begin() + i, raw.begin() + i + 8, std::back_inserter(input8));
6419 if (out.length() < 11) {
6424 if (i + 8 > (
int)raw.size()) {
6426 std::vector<unsigned char> input7;
6427 std::copy(raw.begin() + i, raw.begin() + i + 7, std::back_inserter(input7));
6439 std::vector<unsigned char> pubAddr;
6440 pubAddr.push_back(
Params().StealthPrefix());
6441 std::copy(pubSpendKey.begin(), pubSpendKey.begin() + 33, std::back_inserter(pubAddr));
6442 std::copy(pubViewKey.begin(), pubViewKey.begin() + 33, std::back_inserter(pubAddr));
6444 unsigned char* begin = h.
begin();
6445 pubAddr.push_back(*(begin));
6446 pubAddr.push_back(*(begin + 1));
6447 pubAddr.push_back(*(begin + 2));
6448 pubAddr.push_back(*(begin + 3));
6453 bool CWallet::EncodeIntegratedAddress(
const std::vector<unsigned char>& pubViewKey,
const std::vector<unsigned char>& pubSpendKey, uint64_t paymentID, std::string& pubAddrb58)
6455 std::vector<unsigned char> pubAddr;
6456 pubAddr.push_back(
Params().IntegratedPrefix());
6457 std::copy(pubSpendKey.begin(), pubSpendKey.begin() + 33, std::back_inserter(pubAddr));
6458 std::copy(pubViewKey.begin(), pubViewKey.begin() + 33, std::back_inserter(pubAddr));
6459 std::copy((
char*)&paymentID, (
char*)&paymentID +
sizeof(paymentID), std::back_inserter(pubAddr));
6461 unsigned char* begin = h.
begin();
6462 pubAddr.push_back(*(begin));
6463 pubAddr.push_back(*(begin + 1));
6464 pubAddr.push_back(*(begin + 2));
6465 pubAddr.push_back(*(begin + 3));
6497 uint64_t paymentID =
GetRand(0xFFFFFFFFFFFFFFFF);
6504 std::string pubAddress;
6505 paymentID =
GetRand(0xFFFFFFFFFFFFFFFF);
6515 std::string pubAddress;
6524 if (stealth.length() != 99 && stealth.length() != 110) {
6527 std::vector<unsigned char> raw;
6529 while (i < stealth.length()) {
6531 std::string sub = stealth.substr(i, npos);
6532 std::vector<unsigned char> decoded;
6534 ((decoded.size() == 8 && i + 11 < stealth.length() - 1) || (decoded.size() == 7 && i + 11 == stealth.length() - 1))) {
6535 std::copy(decoded.begin(), decoded.end(), std::back_inserter(raw));
6536 }
else if (sub[0] ==
'1') {
6539 while (lastPad < sub.length() - 1) {
6540 if (sub[lastPad + 1] !=
'1') {
6546 int padIdx = lastPad;
6547 while (padIdx >= 0 && sub[padIdx] ==
'1') {
6548 std::string str_without_pads = sub.substr(padIdx + 1);
6551 if ((decoded.size() == 8 && i + 11 < stealth.length()) || (decoded.size() == 7 && i + 11 == stealth.length())) {
6552 std::copy(decoded.begin(), decoded.end(), std::back_inserter(raw));
6560 if (decoded.size() == 0) {
6570 if (raw.size() != 71 && raw.size() != 79) {
6573 hasPaymentID =
false;
6574 if (raw.size() == 79) {
6575 hasPaymentID =
true;
6579 uint256 h =
Hash(raw.begin(), raw.begin() + raw.size() - 4);
6580 unsigned char* h_begin = h.
begin();
6581 unsigned char* p_raw = &raw[raw.size() - 4];
6582 if (memcmp(h_begin, p_raw, 4) != 0) {
6586 std::vector<unsigned char> vchSpend, vchView;
6587 std::copy(raw.begin() + 1, raw.begin() + 34, std::back_inserter(vchSpend));
6588 std::copy(raw.begin() + 34, raw.begin() + 67, std::back_inserter(vchView));
6590 memcpy((
char*)&paymentID, &raw[0] + 67,
sizeof(paymentID));
6592 pubSpendKey.
Set(vchSpend.begin(), vchSpend.end());
6593 pubViewKey.
Set(vchView.begin(), vchView.end());
6602 unsigned char rA[65];
6603 unsigned char B[65];
6613 throw std::runtime_error(
"Cannot compute stealth destination");
6614 des.
Set(B, B + pubSpendKey.
size());
6629 LogPrintf(
"%s: Wallet is locked\n", __func__);
6644 std::string strFailReason;
6646 strFailReason =
"Error: Wallet locked, unable to create transaction!";
6647 LogPrintf(
"%s: %s\n", __func__, strFailReason);
6648 throw std::runtime_error(strFailReason);
6651 std::string myAddress;
6653 bool tomyself = (myAddress == stealthAddr);
6655 CPubKey pubViewKey, pubSpendKey;
6659 throw std::runtime_error(
"Stealth address mal-formatted");
6693 control.
txPriv = secretChange;
6696 nFeeRequired, strFailReason, &control,
ALL_COINS, fUseIX, (
CAmount)0, 6, tomyself)) {
6698 strFailReason =
strprintf(
"Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!, nfee=%d, nValue=%d",
FormatMoney(nFeeRequired), nFeeRequired, nValue);
6699 LogPrintf(
"%s: %s\n", __func__, strFailReason);
6700 throw std::runtime_error(strFailReason);
6709 std::vector<CKey> spends, views;
6715 LogPrintf(
"Failed to find private keys\n");
6718 spends.push_back(spend);
6719 views.push_back(view);
6726 for (
size_t i = 0; i < spends.size(); i++) {
6727 CKey& spend = spends[i];
6728 CKey& view = views[i];
6734 unsigned char aR[65];
6741 unsigned char* pHS = HS.
begin();
6742 unsigned char expectedDestination[65];
6747 CPubKey expectedDes(expectedDestination, expectedDestination + 33);
6757 unsigned char HStemp[32];
6758 unsigned char spendTemp[32];
6762 throw std::runtime_error(
"Failed to do secp256k1_ec_privkey_tweak_add");
6764 privKey.
Set(HStemp, HStemp + 32,
true);
6783 std::string labelList;
6785 std::string masterAddr;
6787 addresses.push_back(masterAddr);
6788 accountNames.push_back(
"Master Account");
6792 std::vector<std::string> results;
6793 boost::split(results, labelList, [](
char c) {
return c ==
','; });
6794 std::string masterAddr;
6796 accountNames.push_back(
"Master Account");
6797 results.push_back(masterAddr);
6798 for (
size_t i = 0; i < results.size(); i++) {
6799 std::string& accountName = results[i];
6800 std::string stealthAddr;
6802 addresses.push_back(stealthAddr);
6803 accountNames.push_back(accountName);
6814 std::string labelList;
6818 spends.push_back(spend);
6819 views.push_back(view);
6824 std::vector<std::string> results;
6825 boost::split(results, labelList, [](
char c) {
return c ==
','; });
6826 for (
size_t i = 0; i < results.size(); i++) {
6827 std::string& accountName = results[i];
6830 CKey accSpend, accView;
6833 spends.push_back(accSpend);
6834 views.push_back(accView);
6864 throw std::runtime_error(std::string(__func__) +
": GetHDChain failed");
6868 throw std::runtime_error(std::string(__func__) +
": DecryptHDChainSeed failed");
6871 throw std::runtime_error(std::string(__func__) +
": Wrong HD chain!");
6875 uint32_t nChildIndex = 0;
6881 secretRet = childKey.
key;
6887 int64_t nCreationTime =
GetTime();
6891 throw std::runtime_error(std::string(__func__) +
": AddHDPubKey failed");
6897 std::map<CKeyID, CHDPubKey>::const_iterator mi =
mapHdPubKeys.find(address);
6899 const CHDPubKey& hdPubKey = (*mi).second;
6909 std::map<CKeyID, CHDPubKey>::const_iterator mi =
mapHdPubKeys.find(address);
6912 const CHDPubKey& hdPubKey = (*mi).second;
6915 throw std::runtime_error(std::string(__func__) +
": GetHDChain failed");
6917 throw std::runtime_error(std::string(__func__) +
": DecryptHDChainSeed failed");
6920 throw std::runtime_error(std::string(__func__) +
": Wrong HD chain!");
6924 keyOut = extkey.
key;
6980 std::string viewAccountLabel =
"viewaccount";
6981 std::string spendAccountLabel =
"spendaccount";
7009 LogPrintf(
"%s: Wallet is locked\n", __func__);
7012 std::string spendAccountLabel =
"spendaccount";
7015 if (!pDB.
ReadAccount(spendAccountLabel, spendAccount)) {
7016 LogPrintf(
"Cannot load private Spend key, now creating the master keys\n");
7030 LogPrintf(
"%s: Wallet is locked\n", __func__);
7033 std::string viewAccountLabel =
"viewaccount";
7036 if (!pDB.
ReadAccount(viewAccountLabel, viewAccount)) {
7037 LogPrintf(
"Cannot load private View key, now creating the master keys\n");
7071 std::set<CKeyID> keyIDs;
7074 for (
const CKeyID& keyID : keyIDs) {
7087 std::vector<unsigned char> commitment;
7110 std::set<CKeyID> keyIDs;
7112 for (
const CKeyID& keyID : keyIDs) {
7129 std::set<CKeyID> keyIDs;
7132 unsigned char pubData[65];
7133 for (
const CKeyID& keyID : keyIDs) {
7138 if (script == scriptPubKey) {
7140 pubData[0] = *(pub.
begin());
7142 CPubKey newPubKey(pubData, pubData + 33);
7144 unsigned char ki[65];
7149 pubData[0] = *(newPubKey.
begin());
7151 newPubKey.
Set(pubData, pubData + 33);
7177 uint256 tempAmount((uint64_t)amount);
7179 CPubKey sharedPub(sharedSec, sharedSec + 33);
7183 uint256 tempAmount((uint64_t)amount);
7186 CPubKey sharedPub(sharedSec, sharedSec + 33);