Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show First 20 Lines • Show All 419 Lines • ▼ Show 20 Lines | for (const std::pair<CTxDestination, CAddressBookData> &item : | ||||
if (strName == strAccount) { | if (strName == strAccount) { | ||||
ret.push_back(EncodeDestination(dest)); | ret.push_back(EncodeDestination(dest)); | ||||
} | } | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
static void SendMoney(CWallet *const pwallet, const CTxDestination &address, | static CTransactionRef SendMoney(CWallet *const pwallet, | ||||
Amount nValue, bool fSubtractFeeFromAmount, | const CTxDestination &address, Amount nValue, | ||||
CWalletTx &wtxNew) { | bool fSubtractFeeFromAmount, | ||||
mapValue_t mapValue, std::string fromAccount) { | |||||
Amount curBalance = pwallet->GetBalance(); | Amount curBalance = pwallet->GetBalance(); | ||||
// Check amount | // Check amount | ||||
if (nValue <= Amount::zero()) { | if (nValue <= Amount::zero()) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); | throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount"); | ||||
} | } | ||||
if (nValue > curBalance) { | if (nValue > curBalance) { | ||||
Show All 14 Lines | static CTransactionRef SendMoney(CWallet *const pwallet, | ||||
Amount nFeeRequired; | Amount nFeeRequired; | ||||
std::string strError; | std::string strError; | ||||
std::vector<CRecipient> vecSend; | std::vector<CRecipient> vecSend; | ||||
int nChangePosRet = -1; | int nChangePosRet = -1; | ||||
CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount}; | CRecipient recipient = {scriptPubKey, nValue, fSubtractFeeFromAmount}; | ||||
vecSend.push_back(recipient); | vecSend.push_back(recipient); | ||||
CCoinControl coinControl; | CCoinControl coinControl; | ||||
if (!pwallet->CreateTransaction(vecSend, wtxNew, reservekey, nFeeRequired, | CTransactionRef tx; | ||||
if (!pwallet->CreateTransaction(vecSend, tx, reservekey, nFeeRequired, | |||||
nChangePosRet, strError, coinControl)) { | nChangePosRet, strError, coinControl)) { | ||||
if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) { | if (!fSubtractFeeFromAmount && nValue + nFeeRequired > curBalance) { | ||||
strError = strprintf("Error: This transaction requires a " | strError = strprintf("Error: This transaction requires a " | ||||
"transaction fee of at least %s", | "transaction fee of at least %s", | ||||
FormatMoney(nFeeRequired)); | FormatMoney(nFeeRequired)); | ||||
} | } | ||||
throw JSONRPCError(RPC_WALLET_ERROR, strError); | throw JSONRPCError(RPC_WALLET_ERROR, strError); | ||||
} | } | ||||
CValidationState state; | CValidationState state; | ||||
if (!pwallet->CommitTransaction(wtxNew, reservekey, g_connman.get(), | if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, | ||||
state)) { | std::move(fromAccount), reservekey, | ||||
g_connman.get(), state)) { | |||||
strError = | strError = | ||||
strprintf("Error: The transaction was rejected! Reason given: %s", | strprintf("Error: The transaction was rejected! Reason given: %s", | ||||
state.GetRejectReason()); | state.GetRejectReason()); | ||||
throw JSONRPCError(RPC_WALLET_ERROR, strError); | throw JSONRPCError(RPC_WALLET_ERROR, strError); | ||||
} | } | ||||
return tx; | |||||
} | } | ||||
static UniValue sendtoaddress(const Config &config, | static UniValue sendtoaddress(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | ||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | static UniValue sendtoaddress(const Config &config, | ||||
// Amount | // Amount | ||||
Amount nAmount = AmountFromValue(request.params[1]); | Amount nAmount = AmountFromValue(request.params[1]); | ||||
if (nAmount <= Amount::zero()) { | if (nAmount <= Amount::zero()) { | ||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | ||||
} | } | ||||
// Wallet comments | // Wallet comments | ||||
CWalletTx wtx; | mapValue_t mapValue; | ||||
if (request.params.size() > 2 && !request.params[2].isNull() && | if (request.params.size() > 2 && !request.params[2].isNull() && | ||||
!request.params[2].get_str().empty()) { | !request.params[2].get_str().empty()) { | ||||
wtx.mapValue["comment"] = request.params[2].get_str(); | mapValue["comment"] = request.params[2].get_str(); | ||||
} | } | ||||
if (request.params.size() > 3 && !request.params[3].isNull() && | if (request.params.size() > 3 && !request.params[3].isNull() && | ||||
!request.params[3].get_str().empty()) { | !request.params[3].get_str().empty()) { | ||||
wtx.mapValue["to"] = request.params[3].get_str(); | mapValue["to"] = request.params[3].get_str(); | ||||
} | } | ||||
bool fSubtractFeeFromAmount = false; | bool fSubtractFeeFromAmount = false; | ||||
if (request.params.size() > 4) { | if (request.params.size() > 4) { | ||||
fSubtractFeeFromAmount = request.params[4].get_bool(); | fSubtractFeeFromAmount = request.params[4].get_bool(); | ||||
} | } | ||||
EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, wtx); | CTransactionRef tx = | ||||
SendMoney(pwallet, dest, nAmount, fSubtractFeeFromAmount, | |||||
return wtx.GetId().GetHex(); | std::move(mapValue), {} /* fromAccount */); | ||||
return tx->GetId().GetHex(); | |||||
} | } | ||||
static UniValue listaddressgroupings(const Config &config, | static UniValue listaddressgroupings(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | ||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 554 Lines • ▼ Show 20 Lines | if (nAmount <= Amount::zero()) { | ||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send"); | ||||
} | } | ||||
int nMinDepth = 1; | int nMinDepth = 1; | ||||
if (request.params.size() > 3) { | if (request.params.size() > 3) { | ||||
nMinDepth = request.params[3].get_int(); | nMinDepth = request.params[3].get_int(); | ||||
} | } | ||||
CWalletTx wtx; | mapValue_t mapValue; | ||||
wtx.strFromAccount = label; | |||||
if (request.params.size() > 4 && !request.params[4].isNull() && | if (request.params.size() > 4 && !request.params[4].isNull() && | ||||
!request.params[4].get_str().empty()) { | !request.params[4].get_str().empty()) { | ||||
wtx.mapValue["comment"] = request.params[4].get_str(); | mapValue["comment"] = request.params[4].get_str(); | ||||
} | } | ||||
if (request.params.size() > 5 && !request.params[5].isNull() && | if (request.params.size() > 5 && !request.params[5].isNull() && | ||||
!request.params[5].get_str().empty()) { | !request.params[5].get_str().empty()) { | ||||
wtx.mapValue["to"] = request.params[5].get_str(); | mapValue["to"] = request.params[5].get_str(); | ||||
} | } | ||||
EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
// Check funds | // Check funds | ||||
Amount nBalance = | Amount nBalance = | ||||
pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &label); | pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &label); | ||||
if (nAmount > nBalance) { | if (nAmount > nBalance) { | ||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, | throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, | ||||
"Account has insufficient funds"); | "Account has insufficient funds"); | ||||
} | } | ||||
SendMoney(pwallet, dest, nAmount, false, wtx); | CTransactionRef tx = SendMoney(pwallet, dest, nAmount, false, | ||||
std::move(mapValue), std::move(label)); | |||||
return wtx.GetId().GetHex(); | return tx->GetId().GetHex(); | ||||
} | } | ||||
static UniValue sendmany(const Config &config, const JSONRPCRequest &request) { | static UniValue sendmany(const Config &config, const JSONRPCRequest &request) { | ||||
CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | ||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | static UniValue sendmany(const Config &config, const JSONRPCRequest &request) { | ||||
std::string strAccount = LabelFromValue(request.params[0]); | std::string strAccount = LabelFromValue(request.params[0]); | ||||
UniValue sendTo = request.params[1].get_obj(); | UniValue sendTo = request.params[1].get_obj(); | ||||
int nMinDepth = 1; | int nMinDepth = 1; | ||||
if (request.params.size() > 2) { | if (request.params.size() > 2) { | ||||
nMinDepth = request.params[2].get_int(); | nMinDepth = request.params[2].get_int(); | ||||
} | } | ||||
CWalletTx wtx; | mapValue_t mapValue; | ||||
wtx.strFromAccount = strAccount; | |||||
if (request.params.size() > 3 && !request.params[3].isNull() && | if (request.params.size() > 3 && !request.params[3].isNull() && | ||||
!request.params[3].get_str().empty()) { | !request.params[3].get_str().empty()) { | ||||
wtx.mapValue["comment"] = request.params[3].get_str(); | mapValue["comment"] = request.params[3].get_str(); | ||||
} | } | ||||
UniValue subtractFeeFromAmount(UniValue::VARR); | UniValue subtractFeeFromAmount(UniValue::VARR); | ||||
if (request.params.size() > 4) { | if (request.params.size() > 4) { | ||||
subtractFeeFromAmount = request.params[4].get_array(); | subtractFeeFromAmount = request.params[4].get_array(); | ||||
} | } | ||||
std::set<CTxDestination> destinations; | std::set<CTxDestination> destinations; | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | if (totalAmount > nBalance) { | ||||
"Account has insufficient funds"); | "Account has insufficient funds"); | ||||
} | } | ||||
// Send | // Send | ||||
CReserveKey keyChange(pwallet); | CReserveKey keyChange(pwallet); | ||||
Amount nFeeRequired = Amount::zero(); | Amount nFeeRequired = Amount::zero(); | ||||
int nChangePosRet = -1; | int nChangePosRet = -1; | ||||
std::string strFailReason; | std::string strFailReason; | ||||
CTransactionRef tx; | |||||
CCoinControl coinControl; | CCoinControl coinControl; | ||||
bool fCreated = | bool fCreated = | ||||
pwallet->CreateTransaction(vecSend, wtx, keyChange, nFeeRequired, | pwallet->CreateTransaction(vecSend, tx, keyChange, nFeeRequired, | ||||
nChangePosRet, strFailReason, coinControl); | nChangePosRet, strFailReason, coinControl); | ||||
if (!fCreated) { | if (!fCreated) { | ||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); | throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, strFailReason); | ||||
} | } | ||||
CValidationState state; | CValidationState state; | ||||
if (!pwallet->CommitTransaction(wtx, keyChange, g_connman.get(), state)) { | if (!pwallet->CommitTransaction(tx, std::move(mapValue), {} /* orderForm */, | ||||
std::move(strAccount), keyChange, | |||||
g_connman.get(), state)) { | |||||
strFailReason = strprintf("Transaction commit failed:: %s", | strFailReason = strprintf("Transaction commit failed:: %s", | ||||
state.GetRejectReason()); | state.GetRejectReason()); | ||||
throw JSONRPCError(RPC_WALLET_ERROR, strFailReason); | throw JSONRPCError(RPC_WALLET_ERROR, strFailReason); | ||||
} | } | ||||
return wtx.GetId().GetHex(); | return tx->GetId().GetHex(); | ||||
} | } | ||||
static UniValue addmultisigaddress(const Config &config, | static UniValue addmultisigaddress(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | CWallet *const pwallet = GetWalletForJSONRPCRequest(request); | ||||
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 2,541 Lines • Show Last 20 Lines |