mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Merge #15930: rpc: Add balances RPC
facfb4111d14a3b06c46690a2cca7ca91cea8a96 rpc: Deprecate getunconfirmedbalance and getwalletinfo balances (MarcoFalke) 999931cf8f167c7547f1015cdf05437a460c27f0 rpc: Add getbalances RPC (MarcoFalke) fad13e925e197163a942f3f0d1ba2c95a2b65a56 rpcwallet: Make helper methods const on CWallet (MarcoFalke) fad40ec9151248c6e8225e14980424f581d23e02 wallet: Use IsValidNumArgs in getwalletinfo rpc (MarcoFalke) Pull request description: This exposes the `CWallet::GetBalance()` struct over RPC. In the future, incorrectly named rpcs such as `getunconfirmedbalance` or rpcs redundant to this such as `getbalance` could be removed. ACKs for commit facfb4: jnewbery: utACK facfb4111d14a3b06c46690a2cca7ca91cea8a96 Tree-SHA512: 1f54fedce55df9a8ea82d2b6265354b39a956072621876ebaee2355aac0e23c7b64340c3279502415598c095858529e18b50789be956250aafda1cd3a8d948a5
This commit is contained in:
parent
ad68327f38
commit
078094b2aa
@ -1,5 +1,5 @@
|
||||
// Copyright (c) 2010 Satoshi Nakamoto
|
||||
// Copyright (c) 2009-2018 The Bitcoin Core developers
|
||||
// Copyright (c) 2009-2019 The Bitcoin Core developers
|
||||
// Copyright (c) 2014-2022 The Dash Core developers
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
@ -20,10 +20,10 @@
|
||||
#include <util/bip32.h>
|
||||
#include <util/fees.h>
|
||||
#include <util/message.h> // For MessageSign()
|
||||
#include <util/system.h>
|
||||
#include <util/moneystr.h>
|
||||
#include <util/ref.h>
|
||||
#include <util/string.h>
|
||||
#include <util/system.h>
|
||||
#include <util/translation.h>
|
||||
#include <util/url.h>
|
||||
#include <util/vector.h>
|
||||
@ -123,7 +123,7 @@ std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& reques
|
||||
"Wallet file not specified (must request wallet RPC through /wallet/<filename> uri-path).");
|
||||
}
|
||||
|
||||
void EnsureWalletIsUnlocked(CWallet * const pwallet)
|
||||
void EnsureWalletIsUnlocked(const CWallet* pwallet)
|
||||
{
|
||||
if (pwallet->IsLocked()) {
|
||||
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
|
||||
@ -801,7 +801,7 @@ static UniValue getbalance(const JSONRPCRequest& request)
|
||||
static UniValue getunconfirmedbalance(const JSONRPCRequest &request)
|
||||
{
|
||||
RPCHelpMan{"getunconfirmedbalance",
|
||||
"Returns the server's total unconfirmed balance\n",
|
||||
"DEPRECATED\nIdentical to getbalances().mine.untrusted_pending\n",
|
||||
{},
|
||||
RPCResult{RPCResult::Type::NUM, "", "The balance"},
|
||||
RPCExamples{""},
|
||||
@ -2381,6 +2381,68 @@ static UniValue setcoinjoinamount(const JSONRPCRequest& request)
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
static UniValue getbalances(const JSONRPCRequest& request)
|
||||
{
|
||||
RPCHelpMan{"getbalances",
|
||||
"Returns an object with all balances in " + CURRENCY_UNIT + ".\n",
|
||||
{},
|
||||
RPCResult{
|
||||
RPCResult::Type::OBJ, "", "",
|
||||
{
|
||||
{RPCResult::Type::OBJ, "mine", "balances from outputs that the wallet can sign",
|
||||
{
|
||||
{RPCResult::Type::STR_AMOUNT, "trusted", " trusted balance (outputs created by the wallet or confirmed outputs)"},
|
||||
{RPCResult::Type::STR_AMOUNT, "untrusted_pending", " untrusted pending balance (outputs created by others that are in the mempool)"},
|
||||
{RPCResult::Type::STR_AMOUNT, "immature", " balance from immature coinbase outputs"},
|
||||
{RPCResult::Type::STR_AMOUNT, "coinjoin", " CoinJoin balance (outputs with enough rounds created by the wallet via mixing)"},
|
||||
}},
|
||||
{RPCResult::Type::OBJ, "watchonly", "watchonly balances (not present if wallet does not watch anything)",
|
||||
{
|
||||
{RPCResult::Type::STR_AMOUNT, "trusted", " trusted balance (outputs created by the wallet or confirmed outputs)"},
|
||||
{RPCResult::Type::STR_AMOUNT, "untrusted_pending", " untrusted pending balance (outputs created by others that are in the mempool)"},
|
||||
{RPCResult::Type::STR_AMOUNT, "immature", " balance from immature coinbase outputs"},
|
||||
}},
|
||||
},
|
||||
},
|
||||
RPCExamples{
|
||||
HelpExampleCli("getbalances", "") +
|
||||
HelpExampleRpc("getbalances", "")
|
||||
},
|
||||
}.Check(request);
|
||||
|
||||
std::shared_ptr<CWallet> const rpc_wallet = GetWalletForJSONRPCRequest(request);
|
||||
if (!rpc_wallet) return NullUniValue;
|
||||
CWallet& wallet = *rpc_wallet;
|
||||
|
||||
// Make sure the results are valid at least up to the most recent block
|
||||
// the user could have gotten from another RPC command prior to now
|
||||
wallet.BlockUntilSyncedToCurrentChain();
|
||||
|
||||
LOCK(wallet.cs_wallet);
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
|
||||
const auto bal = wallet.GetBalance();
|
||||
UniValue balances{UniValue::VOBJ};
|
||||
{
|
||||
UniValue balances_mine{UniValue::VOBJ};
|
||||
balances_mine.pushKV("trusted", ValueFromAmount(bal.m_mine_trusted));
|
||||
balances_mine.pushKV("untrusted_pending", ValueFromAmount(bal.m_mine_untrusted_pending));
|
||||
balances_mine.pushKV("immature", ValueFromAmount(bal.m_mine_immature));
|
||||
balances_mine.pushKV("coinjoin", ValueFromAmount(bal.m_anonymized));
|
||||
balances.pushKV("mine", balances_mine);
|
||||
}
|
||||
auto spk_man = wallet.GetLegacyScriptPubKeyMan();
|
||||
if (spk_man && spk_man->HaveWatchOnly()) {
|
||||
UniValue balances_watchonly{UniValue::VOBJ};
|
||||
balances_watchonly.pushKV("trusted", ValueFromAmount(bal.m_watchonly_trusted));
|
||||
balances_watchonly.pushKV("untrusted_pending", ValueFromAmount(bal.m_watchonly_untrusted_pending));
|
||||
balances_watchonly.pushKV("immature", ValueFromAmount(bal.m_watchonly_immature));
|
||||
balances.pushKV("watchonly", balances_watchonly);
|
||||
}
|
||||
return balances;
|
||||
}
|
||||
|
||||
static UniValue getwalletinfo(const JSONRPCRequest& request)
|
||||
{
|
||||
RPCHelpMan{"getwalletinfo",
|
||||
@ -2391,10 +2453,10 @@ static UniValue getwalletinfo(const JSONRPCRequest& request)
|
||||
{
|
||||
{RPCResult::Type::STR, "walletname", "the wallet name"},
|
||||
{RPCResult::Type::NUM, "walletversion", "the wallet version"},
|
||||
{RPCResult::Type::NUM, "balance", "the total confirmed balance of the wallet in " + CURRENCY_UNIT},
|
||||
{RPCResult::Type::NUM, "coinjoin_balance", "the CoinJoin balance in " + CURRENCY_UNIT},
|
||||
{RPCResult::Type::NUM, "unconfirmed_balance", "the total unconfirmed balance of the wallet in " + CURRENCY_UNIT},
|
||||
{RPCResult::Type::NUM, "immature_balance", "the total immature balance of the wallet in " + CURRENCY_UNIT},
|
||||
{RPCResult::Type::NUM, "balance", "DEPRECATED. Identical to getbalances().mine.trusted"},
|
||||
{RPCResult::Type::NUM, "coinjoin_balance", "DEPRECATED. Identical to getbalances().mine.coinjoin"},
|
||||
{RPCResult::Type::NUM, "unconfirmed_balance", "DEPRECATED. Identical to getbalances().mine.untrusted_pending"},
|
||||
{RPCResult::Type::NUM, "immature_balance", "DEPRECATED. Identical to getbalances().mine.immature"},
|
||||
{RPCResult::Type::NUM, "txcount", "the total number of transactions in the wallet"},
|
||||
{RPCResult::Type::NUM_TIME, "timefirstkey", "the " + UNIX_EPOCH_TIME + " of the oldest known key in the wallet"},
|
||||
{RPCResult::Type::NUM_TIME, "keypoololdest", "the " + UNIX_EPOCH_TIME + " of the oldest pre-generated key in the key pool"},
|
||||
@ -3985,6 +4047,7 @@ static const CRPCCommand commands[] =
|
||||
{ "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf","addlocked"} },
|
||||
{ "wallet", "gettransaction", &gettransaction, {"txid","include_watchonly"} },
|
||||
{ "wallet", "getunconfirmedbalance", &getunconfirmedbalance, {} },
|
||||
{ "wallet", "getbalances", &getbalances, {} },
|
||||
{ "wallet", "getwalletinfo", &getwalletinfo, {} },
|
||||
{ "wallet", "importaddress", &importaddress, {"address","label","rescan","p2sh"} },
|
||||
{ "wallet", "importelectrumwallet", &importelectrumwallet, {"filename", "index"} },
|
||||
|
@ -35,7 +35,7 @@ Span<const CRPCCommand> GetWalletRPCCommands();
|
||||
*/
|
||||
std::shared_ptr<CWallet> GetWalletForJSONRPCRequest(const JSONRPCRequest& request);
|
||||
|
||||
void EnsureWalletIsUnlocked(CWallet *);
|
||||
void EnsureWalletIsUnlocked(const CWallet*);
|
||||
WalletContext& EnsureWalletContext(const util::Ref& context);
|
||||
|
||||
UniValue getaddressinfo(const JSONRPCRequest& request);
|
||||
|
@ -62,14 +62,24 @@ class WalletTest(BitcoinTestFramework):
|
||||
assert_equal(len(self.nodes[0].listunspent()), 0)
|
||||
assert_equal(len(self.nodes[1].listunspent()), 0)
|
||||
|
||||
self.log.info("Mining blocks ...")
|
||||
self.log.info("Check that only node 0 is watching an address")
|
||||
assert 'watchonly' in self.nodes[0].getbalances()
|
||||
assert 'watchonly' not in self.nodes[1].getbalances()
|
||||
|
||||
self.log.info("Mining blocks ...")
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_all()
|
||||
self.nodes[1].generate(1)
|
||||
self.nodes[1].generatetoaddress(101, ADDRESS_WATCHONLY)
|
||||
self.sync_all()
|
||||
|
||||
assert_equal(self.nodes[0].getbalances()['mine']['trusted'], 500)
|
||||
assert_equal(self.nodes[0].getwalletinfo()['balance'], 500)
|
||||
assert_equal(self.nodes[1].getbalances()['mine']['trusted'], 500)
|
||||
|
||||
assert_equal(self.nodes[0].getbalances()['watchonly']['immature'], 50000)
|
||||
assert 'watchonly' not in self.nodes[1].getbalances()
|
||||
|
||||
assert_equal(self.nodes[0].getbalance(), 500)
|
||||
assert_equal(self.nodes[1].getbalance(), 500)
|
||||
|
||||
@ -113,8 +123,11 @@ class WalletTest(BitcoinTestFramework):
|
||||
assert_equal(self.nodes[1].getbalance(minconf=1), Decimal('0'))
|
||||
# getunconfirmedbalance
|
||||
assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('960')) # output of node 1's spend
|
||||
assert_equal(self.nodes[0].getbalances()['mine']['untrusted_pending'], Decimal('960'))
|
||||
assert_equal(self.nodes[0].getwalletinfo()["unconfirmed_balance"], Decimal('960'))
|
||||
|
||||
assert_equal(self.nodes[1].getunconfirmedbalance(), Decimal('0')) # Doesn't include output of node 0's send since it was spent
|
||||
assert_equal(self.nodes[1].getbalances()['mine']['untrusted_pending'], Decimal('0'))
|
||||
assert_equal(self.nodes[1].getwalletinfo()["unconfirmed_balance"], Decimal('0'))
|
||||
|
||||
test_balances(fee_node_1=Decimal('0.01'))
|
||||
|
Loading…
Reference in New Issue
Block a user