Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_balance.py
Show First 20 Lines • Show All 118 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
# sending on both nodes is faster than waiting for propagation | # sending on both nodes is faster than waiting for propagation | ||||
self.nodes[0].sendrawtransaction(txs[0]['hex']) | self.nodes[0].sendrawtransaction(txs[0]['hex']) | ||||
self.sync_all() | self.sync_all() | ||||
# First argument of getbalance must be set to "*" | # First argument of getbalance must be set to "*" | ||||
assert_raises_rpc_error(-32, "dummy first argument must be excluded or set to \"*\"", | assert_raises_rpc_error(-32, "dummy first argument must be excluded or set to \"*\"", | ||||
self.nodes[1].getbalance, "") | self.nodes[1].getbalance, "") | ||||
self.log.info( | self.log.info("Test balances with unconfirmed inputs") | ||||
"Test getbalance and getunconfirmedbalance with unconfirmed inputs") | |||||
# Before `test_balance()`, we have had two nodes with a balance of 50 | # Before `test_balance()`, we have had two nodes with a balance of 50 | ||||
# each and then we: | # each and then we: | ||||
# | # | ||||
# 1) Sent 40 from node A to node B with fee 0.01 | # 1) Sent 40 from node A to node B with fee 0.01 | ||||
# 2) Sent 60 from node B to node A with fee 0.01 | # 2) Sent 60 from node B to node A with fee 0.01 | ||||
# | # | ||||
# Then we check the balances: | # Then we check the balances: | ||||
Show All 23 Lines | def run_test(self): | ||||
# 1) Sent 40 from node A to node B with fee 0.01 | # 1) Sent 40 from node A to node B with fee 0.01 | ||||
# 2) Sent 10 from node B to node A with fee 0.01 | # 2) Sent 10 from node B to node A with fee 0.01 | ||||
# | # | ||||
# Then our node would report a confirmed balance of 40 + 50 - 10 = 80 | # Then our node would report a confirmed balance of 40 + 50 - 10 = 80 | ||||
# BTC, which is more than would be available if transaction 1 were | # BTC, which is more than would be available if transaction 1 were | ||||
# replaced. | # replaced. | ||||
def test_balances(*, fee_node_1=0): | def test_balances(*, fee_node_1=0): | ||||
# getbalances | |||||
expected_balances_0 = {'mine': {'immature': Decimal('0E-8'), | |||||
# change from node 0's send | |||||
'trusted': Decimal('9.99'), | |||||
'untrusted_pending': Decimal('60.0')}, | |||||
'watchonly': {'immature': Decimal('5000'), | |||||
'trusted': Decimal('50.0'), | |||||
'untrusted_pending': Decimal('0E-8')}} | |||||
expected_balances_1 = {'mine': {'immature': Decimal('0E-8'), | |||||
# node 1's send had an unsafe input | |||||
'trusted': Decimal('0E-8'), | |||||
# Doesn't include output of node | |||||
# 0's send since it was spent | |||||
'untrusted_pending': Decimal('30.0') - fee_node_1}} | |||||
assert_equal(self.nodes[0].getbalances(), expected_balances_0) | |||||
assert_equal(self.nodes[1].getbalances(), expected_balances_1) | |||||
# getbalance without any arguments includes unconfirmed transactions, but not untrusted transactions | # getbalance without any arguments includes unconfirmed transactions, but not untrusted transactions | ||||
# change from node 0's send | # change from node 0's send | ||||
assert_equal(self.nodes[0].getbalance(), Decimal('9.99')) | assert_equal(self.nodes[0].getbalance(), Decimal('9.99')) | ||||
# node 1's send had an unsafe input | # node 1's send had an unsafe input | ||||
assert_equal(self.nodes[1].getbalance(), Decimal('0')) | assert_equal(self.nodes[1].getbalance(), Decimal('0')) | ||||
# Same with minconf=0 | # Same with minconf=0 | ||||
assert_equal(self.nodes[0].getbalance(minconf=0), Decimal('9.99')) | assert_equal(self.nodes[0].getbalance(minconf=0), Decimal('9.99')) | ||||
assert_equal(self.nodes[1].getbalance(minconf=0), Decimal('0')) | assert_equal(self.nodes[1].getbalance(minconf=0), Decimal('0')) | ||||
# getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago | # getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago | ||||
# TODO: fix getbalance tracking of coin spentness depth | # TODO: fix getbalance tracking of coin spentness depth | ||||
assert_equal(self.nodes[0].getbalance(minconf=1), Decimal('0')) | assert_equal(self.nodes[0].getbalance(minconf=1), Decimal('0')) | ||||
assert_equal(self.nodes[1].getbalance(minconf=1), Decimal('0')) | assert_equal(self.nodes[1].getbalance(minconf=1), Decimal('0')) | ||||
# getunconfirmedbalance | # getunconfirmedbalance | ||||
# output of node 1's spend | # output of node 1's spend | ||||
assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('60')) | assert_equal(self.nodes[0].getunconfirmedbalance(), Decimal('60')) | ||||
assert_equal(self.nodes[0].getbalances()['mine'] | |||||
['untrusted_pending'], Decimal('60')) | |||||
assert_equal(self.nodes[0].getwalletinfo()[ | |||||
"unconfirmed_balance"], Decimal('60')) | |||||
# Doesn't include output of node 0's send since it was spent | # Doesn't include output of node 0's send since it was spent | ||||
assert_equal( | assert_equal( | ||||
self.nodes[1].getunconfirmedbalance(), | self.nodes[1].getunconfirmedbalance(), | ||||
Decimal('30') - fee_node_1) | Decimal('30') - fee_node_1) | ||||
assert_equal( | # getwalletinfo.unconfirmed_balance | ||||
self.nodes[1].getbalances()['mine']['untrusted_pending'], | assert_equal(self.nodes[0].getwalletinfo()[ | ||||
Decimal('30') - fee_node_1) | "unconfirmed_balance"], Decimal('60')) | ||||
assert_equal( | assert_equal( | ||||
self.nodes[1].getwalletinfo()["unconfirmed_balance"], | self.nodes[1].getwalletinfo()["unconfirmed_balance"], | ||||
Decimal('30') - fee_node_1) | Decimal('30') - fee_node_1) | ||||
test_balances(fee_node_1=Decimal('0.01')) | test_balances(fee_node_1=Decimal('0.01')) | ||||
# In the original Core version of this test, Node 1 would've bumped | # In the original Core version of this test, Node 1 would've bumped | ||||
# the fee by 0.01 here to resend, but this is BCH, so it has 0.01 BCH | # the fee by 0.01 here to resend, but this is BCH, so it has 0.01 BCH | ||||
# left to spend on goods and services | # left to spend on goods and services | ||||
self.sync_all() | self.sync_all() | ||||
self.log.info( | self.log.info( | ||||
"Test getbalance and getunconfirmedbalance with conflicted unconfirmed inputs") | "Test getbalance and getbalances.mine.untrusted_pending with conflicted unconfirmed inputs") | ||||
test_balances(fee_node_1=Decimal('0.01')) | test_balances(fee_node_1=Decimal('0.01')) | ||||
self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY) | self.nodes[1].generatetoaddress(1, ADDRESS_WATCHONLY) | ||||
self.sync_all() | self.sync_all() | ||||
# balances are correct after the transactions are confirmed | # balances are correct after the transactions are confirmed | ||||
# node 1's send plus change from node 0's send | # node 1's send plus change from node 0's send | ||||
assert_equal(self.nodes[0].getbalance(), Decimal('69.99')) | balance_node0 = Decimal('69.99') | ||||
assert_equal(self.nodes[1].getbalance(), Decimal( | # change from node 0's send | ||||
'29.99')) # change from node 0's send | balance_node1 = Decimal('29.99') | ||||
assert_equal(self.nodes[0].getbalances()[ | |||||
'mine']['trusted'], balance_node0) | |||||
assert_equal(self.nodes[1].getbalances()[ | |||||
'mine']['trusted'], balance_node1) | |||||
assert_equal(self.nodes[0].getbalance(), balance_node0) | |||||
assert_equal(self.nodes[1].getbalance(), balance_node1) | |||||
# Send total balance away from node 1 | # Send total balance away from node 1 | ||||
txs = create_transactions(self.nodes[1], self.nodes[0].getnewaddress( | txs = create_transactions(self.nodes[1], self.nodes[0].getnewaddress( | ||||
), Decimal('29.97'), [Decimal('0.01')]) | ), Decimal('29.97'), [Decimal('0.01')]) | ||||
self.nodes[1].sendrawtransaction(txs[0]['hex']) | self.nodes[1].sendrawtransaction(txs[0]['hex']) | ||||
self.nodes[1].generatetoaddress(2, ADDRESS_WATCHONLY) | self.nodes[1].generatetoaddress(2, ADDRESS_WATCHONLY) | ||||
self.sync_all() | self.sync_all() | ||||
# getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago | # getbalance with a minconf incorrectly excludes coins that have been spent more recently than the minconf blocks ago | ||||
# TODO: fix getbalance tracking of coin spentness depth | # TODO: fix getbalance tracking of coin spentness depth | ||||
# getbalance with minconf=3 should still show the old balance | # getbalance with minconf=3 should still show the old balance | ||||
assert_equal(self.nodes[1].getbalance(minconf=3), Decimal('0')) | assert_equal(self.nodes[1].getbalance(minconf=3), Decimal('0')) | ||||
# getbalance with minconf=2 will show the new balance. | # getbalance with minconf=2 will show the new balance. | ||||
assert_equal(self.nodes[1].getbalance(minconf=2), Decimal('0.01')) | assert_equal(self.nodes[1].getbalance(minconf=2), Decimal('0.01')) | ||||
# check mempool transactions count for wallet unconfirmed balance after | # check mempool transactions count for wallet unconfirmed balance after | ||||
# dynamically loading the wallet. | # dynamically loading the wallet. | ||||
before = self.nodes[1].getunconfirmedbalance() | before = self.nodes[1].getbalances()['mine']['untrusted_pending'] | ||||
dst = self.nodes[1].getnewaddress() | dst = self.nodes[1].getnewaddress() | ||||
self.nodes[1].unloadwallet('') | self.nodes[1].unloadwallet('') | ||||
self.nodes[0].sendtoaddress(dst, 0.1) | self.nodes[0].sendtoaddress(dst, 0.1) | ||||
self.sync_all() | self.sync_all() | ||||
self.nodes[1].loadwallet('') | self.nodes[1].loadwallet('') | ||||
after = self.nodes[1].getunconfirmedbalance() | after = self.nodes[1].getbalances()['mine']['untrusted_pending'] | ||||
assert_equal(before + Decimal('0.1'), after) | assert_equal(before + Decimal('0.1'), after) | ||||
# Create 3 more wallet txs, where the last is not accepted to the | # Create 3 more wallet txs, where the last is not accepted to the | ||||
# mempool because it is the third descendant of the tx above | # mempool because it is the third descendant of the tx above | ||||
for _ in range(3): | for _ in range(3): | ||||
# Set amount high enough such that all coins are spent by each tx | # Set amount high enough such that all coins are spent by each tx | ||||
txid = self.nodes[0].sendtoaddress( | txid = self.nodes[0].sendtoaddress( | ||||
self.nodes[0].getnewaddress(), 99) | self.nodes[0].getnewaddress(), 99) | ||||
▲ Show 20 Lines • Show All 50 Lines • Show Last 20 Lines |