Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
| Show First 20 Lines • Show All 905 Lines • ▼ Show 20 Lines | static UniValue getbalance(const Config &config, | ||||
| } | } | ||||
| LOCK2(cs_main, pwallet->cs_wallet); | LOCK2(cs_main, pwallet->cs_wallet); | ||||
| if (request.params.size() == 0) { | if (request.params.size() == 0) { | ||||
| return ValueFromAmount(pwallet->GetBalance()); | return ValueFromAmount(pwallet->GetBalance()); | ||||
| } | } | ||||
| const std::string *account = request.params[0].get_str() != "*" | |||||
| ? &request.params[0].get_str() | |||||
| : nullptr; | |||||
| int nMinDepth = 1; | int nMinDepth = 1; | ||||
| if (request.params.size() > 1) { | if (request.params.size() > 1) { | ||||
| nMinDepth = request.params[1].get_int(); | nMinDepth = request.params[1].get_int(); | ||||
| } | } | ||||
| isminefilter filter = ISMINE_SPENDABLE; | isminefilter filter = ISMINE_SPENDABLE; | ||||
| if (request.params.size() > 2 && request.params[2].get_bool()) { | if (request.params.size() > 2 && request.params[2].get_bool()) { | ||||
| filter = filter | ISMINE_WATCH_ONLY; | filter = filter | ISMINE_WATCH_ONLY; | ||||
| } | } | ||||
| if (request.params[0].get_str() == "*") { | return ValueFromAmount( | ||||
| // Calculate total balance in a very different way from GetBalance(). | pwallet->GetLegacyBalance(filter, nMinDepth, account)); | ||||
| // The biggest difference is that GetBalance() sums up all unspent | |||||
| // TxOuts paying to the wallet, while this sums up both spent and | |||||
| // unspent TxOuts paying to the wallet, and then subtracts the values of | |||||
| // TxIns spending from the wallet. This also has fewer restrictions on | |||||
| // which unconfirmed transactions are considered trusted. | |||||
| Amount nBalance(0); | |||||
| for (const std::pair<uint256, CWalletTx> &pairWtx : | |||||
| pwallet->mapWallet) { | |||||
| const CWalletTx &wtx = pairWtx.second; | |||||
| CValidationState state; | |||||
| if (!ContextualCheckTransactionForCurrentBlock(config, wtx, | |||||
| state) || | |||||
| wtx.GetBlocksToMaturity() > 0 || | |||||
| wtx.GetDepthInMainChain() < 0) { | |||||
| continue; | |||||
| } | |||||
| Amount allFee; | |||||
| std::string strSentAccount; | |||||
| std::list<COutputEntry> listReceived; | |||||
| std::list<COutputEntry> listSent; | |||||
| wtx.GetAmounts(listReceived, listSent, allFee, strSentAccount, | |||||
| filter); | |||||
| if (wtx.GetDepthInMainChain() >= nMinDepth) { | |||||
| for (const COutputEntry &r : listReceived) { | |||||
| nBalance += r.amount; | |||||
| } | |||||
| } | |||||
| for (const COutputEntry &s : listSent) { | |||||
| nBalance -= s.amount; | |||||
| } | |||||
| nBalance -= allFee; | |||||
| } | |||||
| return ValueFromAmount(nBalance); | |||||
| } | |||||
| std::string strAccount = AccountFromValue(request.params[0]); | |||||
| Amount nBalance = pwallet->GetAccountBalance(strAccount, nMinDepth, filter); | |||||
| return ValueFromAmount(nBalance); | |||||
| } | } | ||||
| static UniValue getunconfirmedbalance(const Config &config, | static UniValue getunconfirmedbalance(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 167 Lines • ▼ Show 20 Lines | 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(); | wtx.mapValue["to"] = request.params[5].get_str(); | ||||
| } | } | ||||
| EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
| // Check funds | // Check funds | ||||
| Amount nBalance = | Amount nBalance = | ||||
| pwallet->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); | pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount); | ||||
| 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); | SendMoney(pwallet, dest, nAmount, false, wtx); | ||||
| return wtx.GetId().GetHex(); | return wtx.GetId().GetHex(); | ||||
| ▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | for (const std::string &name_ : keys) { | ||||
| CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount}; | CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount}; | ||||
| vecSend.push_back(recipient); | vecSend.push_back(recipient); | ||||
| } | } | ||||
| EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
| // Check funds | // Check funds | ||||
| Amount nBalance = | Amount nBalance = | ||||
| pwallet->GetAccountBalance(strAccount, nMinDepth, ISMINE_SPENDABLE); | pwallet->GetLegacyBalance(ISMINE_SPENDABLE, nMinDepth, &strAccount); | ||||
| if (totalAmount > nBalance) { | if (totalAmount > nBalance) { | ||||
| throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, | throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, | ||||
| "Account has insufficient funds"); | "Account has insufficient funds"); | ||||
| } | } | ||||
| // Send | // Send | ||||
| CReserveKey keyChange(pwallet); | CReserveKey keyChange(pwallet); | ||||
| Amount nFeeRequired(0); | Amount nFeeRequired(0); | ||||
| ▲ Show 20 Lines • Show All 2,242 Lines • Show Last 20 Lines | |||||