Skip to content

Commit

Permalink
[backport#16239] wallet/rpc/getbalances: add entry for 'mine.used' ba…
Browse files Browse the repository at this point in the history
…lance in results

Summary:
bitcoin/bitcoin@53c3c1e

---

Partial backport of Core [[bitcoin/bitcoin#16239 | PR16239]]

Test Plan:
  ninja
  ./src/bitcoind -regtest -daemon
  ./src/bitcoin-cli -regtest getbalances help

check that it looks right

  test_runner.py wallet_avoidreuse

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D6482
  • Loading branch information
kallewoof authored and majcosta committed Jun 10, 2020
1 parent 6f41fa1 commit e6bbd99
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 2 deletions.
14 changes: 14 additions & 0 deletions src/wallet/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2931,6 +2931,9 @@ static UniValue getbalances(const Config &config,
"mempool)\n"
" \"immature\": xxx (numeric) balance from "
"immature coinbase outputs\n"
" \"used\": xxx (numeric) (only present if "
"avoid_reuse is set) balance from coins sent to addresses that "
"were previously spent from (potentially privacy violating)\n"
" },\n"
" \"watchonly\": { (object) watchonly "
"balances (not present if wallet does not watch anything)\n"
Expand Down Expand Up @@ -2968,6 +2971,17 @@ static UniValue getbalances(const Config &config,
balances_mine.pushKV("untrusted_pending",
ValueFromAmount(bal.m_mine_untrusted_pending));
balances_mine.pushKV("immature", ValueFromAmount(bal.m_mine_immature));
if (wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) {
// If the AVOID_REUSE flag is set, bal has been set to just the
// un-reused address balance. Get the total balance, and then
// subtract bal to get the reused address balance.
const auto full_bal = wallet.GetBalance(0, false);
balances_mine.pushKV(
"used", ValueFromAmount(full_bal.m_mine_trusted +
full_bal.m_mine_untrusted_pending -
bal.m_mine_trusted -
bal.m_mine_untrusted_pending));
}
balances.pushKV("mine", balances_mine);
}
if (wallet.HaveWatchOnly()) {
Expand Down
32 changes: 30 additions & 2 deletions test/functional/wallet_avoidreuse.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

def assert_approx(v, vexp, vspan=0.00001):
if v < vexp - vspan:
raise AssertionError("{} < [{}..{}]".format(str(v), str(vexp - vspan), str(vexp + vspan)))
raise AssertionError("{} < [{}..{}]".format(
str(v), str(vexp - vspan), str(vexp + vspan)))
if v > vexp + vspan:
raise AssertionError("{} > [{}..{}]".format(str(v), str(vexp - vspan), str(vexp + vspan)))
raise AssertionError("{} > [{}..{}]".format(
str(v), str(vexp - vspan), str(vexp + vspan)))


def reset_balance(node, discardaddr):
Expand Down Expand Up @@ -74,6 +76,13 @@ def assert_unspent(node, total_count=None, total_sum=None,
assert_approx(stats["reused"]["sum"], reused_sum, 0.001)


def assert_balances(node, mine):
'''Make assertions about a node's getbalances output'''
got = node.getbalances()["mine"]
for k, v in mine.items():
assert_approx(got[k], v, 0.001)


class AvoidReuseTest(BitcoinTestFramework):

def set_test_params(self):
Expand Down Expand Up @@ -171,6 +180,11 @@ def test_fund_send_fund_senddirty(self):
total_sum=10,
reused_supported=True,
reused_count=0)
# getbalances should show no used, 10 BCH trusted
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10})
# node 0 should not show a used entry, as it does not enable
# avoid_reuse
assert("used" not in self.nodes[0].getbalances()["mine"])

self.nodes[1].sendtoaddress(retaddr, 5)
self.nodes[0].generate(1)
Expand All @@ -183,6 +197,8 @@ def test_fund_send_fund_senddirty(self):
total_sum=5,
reused_supported=True,
reused_count=0)
# getbalances should show no used, 5 BCH trusted
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5})

self.nodes[0].sendtoaddress(fundaddr, 10)
self.nodes[0].generate(1)
Expand All @@ -196,6 +212,8 @@ def test_fund_send_fund_senddirty(self):
total_sum=15,
reused_count=1,
reused_sum=10)
# getbalances should show 10 used, 5 BCH trusted
assert_balances(self.nodes[1], mine={"used": 10, "trusted": 5})

self.nodes[1].sendtoaddress(
address=retaddr, amount=10, avoid_reuse=False)
Expand All @@ -206,6 +224,8 @@ def test_fund_send_fund_senddirty(self):
total_count=1,
total_sum=5,
reused_count=0)
# getbalances should show no used, 5 BCH trusted
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5})

# node 1 should now have about 5 BCH left (for both cases)
assert_approx(self.nodes[1].getbalance(), 5, 0.001)
Expand Down Expand Up @@ -235,6 +255,8 @@ def test_fund_send_fund_send(self):
total_sum=10,
reused_supported=True,
reused_count=0)
# getbalances should show no used, 10 BCH trusted
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 10})

self.nodes[1].sendtoaddress(retaddr, 5)
self.nodes[0].generate(1)
Expand All @@ -247,6 +269,8 @@ def test_fund_send_fund_send(self):
total_sum=5,
reused_supported=True,
reused_count=0)
# getbalances should show no used, 5 BCH trusted
assert_balances(self.nodes[1], mine={"used": 0, "trusted": 5})

self.nodes[0].sendtoaddress(fundaddr, 10)
self.nodes[0].generate(1)
Expand All @@ -260,6 +284,8 @@ def test_fund_send_fund_send(self):
total_sum=15,
reused_count=1,
reused_sum=10)
# getbalances should show 10 used, 5 BCH trusted
assert_balances(self.nodes[1], mine={"used": 10, "trusted": 5})

# node 1 should now have a balance of 5 (no dirty) or 15 (including
# dirty)
Expand All @@ -279,6 +305,8 @@ def test_fund_send_fund_send(self):
total_sum=11,
reused_count=1,
reused_sum=10)
# getbalances should show 10 used, 1 BCH trusted
assert_balances(self.nodes[1], mine={"used": 10, "trusted": 1})

# node 1 should now have about 1 BCH left (no dirty) and 11 (including
# dirty)
Expand Down

0 comments on commit e6bbd99

Please sign in to comment.