Changeset View
Changeset View
Standalone View
Standalone View
test/functional/wallet_avoidreuse.py
Show All 10 Lines | from test_framework.util import ( | ||||
connect_nodes, | connect_nodes, | ||||
) | ) | ||||
# TODO: Copied from wallet_groups.py -- should perhaps move into util.py | # TODO: Copied from wallet_groups.py -- should perhaps move into util.py | ||||
def assert_approx(v, vexp, vspan=0.00001): | def assert_approx(v, vexp, vspan=0.00001): | ||||
if v < 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))) | |||||
if v > 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): | def reset_balance(node, discardaddr): | ||||
'''Throw away all owned coins by the node so it gets a balance of 0.''' | '''Throw away all owned coins by the node so it gets a balance of 0.''' | ||||
balance = node.getbalance(avoid_reuse=False) | balance = node.getbalance(avoid_reuse=False) | ||||
if balance > 0.5: | if balance > 0.5: | ||||
node.sendtoaddress( | node.sendtoaddress( | ||||
address=discardaddr, | address=discardaddr, | ||||
Show All 39 Lines | def assert_unspent(node, total_count=None, total_sum=None, | ||||
if reused_supported is not None: | if reused_supported is not None: | ||||
assert_equal(stats["reused"]["supported"], reused_supported) | assert_equal(stats["reused"]["supported"], reused_supported) | ||||
if reused_count is not None: | if reused_count is not None: | ||||
assert_equal(stats["reused"]["count"], reused_count) | assert_equal(stats["reused"]["count"], reused_count) | ||||
if reused_sum is not None: | if reused_sum is not None: | ||||
assert_approx(stats["reused"]["sum"], reused_sum, 0.001) | 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): | class AvoidReuseTest(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.setup_clean_chain = False | self.setup_clean_chain = False | ||||
self.num_nodes = 2 | self.num_nodes = 2 | ||||
def skip_test_if_missing_module(self): | def skip_test_if_missing_module(self): | ||||
self.skip_if_no_wallet() | self.skip_if_no_wallet() | ||||
▲ Show 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | def test_fund_send_fund_senddirty(self): | ||||
# listunspent should show 1 single, unused 10 BCH output | # listunspent should show 1 single, unused 10 BCH output | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=10, | total_sum=10, | ||||
reused_supported=True, | reused_supported=True, | ||||
reused_count=0) | 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[1].sendtoaddress(retaddr, 5) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 1 single, unused 5 BCH output | # listunspent should show 1 single, unused 5 BCH output | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=5, | total_sum=5, | ||||
reused_supported=True, | reused_supported=True, | ||||
reused_count=0) | 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].sendtoaddress(fundaddr, 10) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 2 total outputs (5, 10 BCH), one unused (5), | # listunspent should show 2 total outputs (5, 10 BCH), one unused (5), | ||||
# one reused (10) | # one reused (10) | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=2, | total_count=2, | ||||
total_sum=15, | total_sum=15, | ||||
reused_count=1, | reused_count=1, | ||||
reused_sum=10) | 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( | self.nodes[1].sendtoaddress( | ||||
address=retaddr, amount=10, avoid_reuse=False) | address=retaddr, amount=10, avoid_reuse=False) | ||||
# listunspent should show 1 total outputs (5 BCH), unused | # listunspent should show 1 total outputs (5 BCH), unused | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=5, | total_sum=5, | ||||
reused_count=0) | 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) | # node 1 should now have about 5 BCH left (for both cases) | ||||
assert_approx(self.nodes[1].getbalance(), 5, 0.001) | assert_approx(self.nodes[1].getbalance(), 5, 0.001) | ||||
assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 5, 0.001) | assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 5, 0.001) | ||||
def test_fund_send_fund_send(self): | def test_fund_send_fund_send(self): | ||||
''' | ''' | ||||
Test the simple case where [1] generates a new address A, then | Test the simple case where [1] generates a new address A, then | ||||
Show All 13 Lines | def test_fund_send_fund_send(self): | ||||
# listunspent should show 1 single, unused 10 BCH output | # listunspent should show 1 single, unused 10 BCH output | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=10, | total_sum=10, | ||||
reused_supported=True, | reused_supported=True, | ||||
reused_count=0) | 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[1].sendtoaddress(retaddr, 5) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 1 single, unused 5 BCH output | # listunspent should show 1 single, unused 5 BCH output | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=1, | total_count=1, | ||||
total_sum=5, | total_sum=5, | ||||
reused_supported=True, | reused_supported=True, | ||||
reused_count=0) | 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].sendtoaddress(fundaddr, 10) | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
self.sync_all() | self.sync_all() | ||||
# listunspent should show 2 total outputs (5, 10 BCH), one unused (5), | # listunspent should show 2 total outputs (5, 10 BCH), one unused (5), | ||||
# one reused (10) | # one reused (10) | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=2, | total_count=2, | ||||
total_sum=15, | total_sum=15, | ||||
reused_count=1, | reused_count=1, | ||||
reused_sum=10) | 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 | # node 1 should now have a balance of 5 (no dirty) or 15 (including | ||||
# dirty) | # dirty) | ||||
assert_approx(self.nodes[1].getbalance(), 5, 0.001) | assert_approx(self.nodes[1].getbalance(), 5, 0.001) | ||||
assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 15, 0.001) | assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 15, 0.001) | ||||
assert_raises_rpc_error(-6, "Insufficient funds", | assert_raises_rpc_error(-6, "Insufficient funds", | ||||
self.nodes[1].sendtoaddress, retaddr, 10) | self.nodes[1].sendtoaddress, retaddr, 10) | ||||
self.nodes[1].sendtoaddress(retaddr, 4) | self.nodes[1].sendtoaddress(retaddr, 4) | ||||
# listunspent should show 2 total outputs (1, 10 BCH), one unused (1), | # listunspent should show 2 total outputs (1, 10 BCH), one unused (1), | ||||
# one reused (10) | # one reused (10) | ||||
assert_unspent( | assert_unspent( | ||||
self.nodes[1], | self.nodes[1], | ||||
total_count=2, | total_count=2, | ||||
total_sum=11, | total_sum=11, | ||||
reused_count=1, | reused_count=1, | ||||
reused_sum=10) | 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 | # node 1 should now have about 1 BCH left (no dirty) and 11 (including | ||||
# dirty) | # dirty) | ||||
assert_approx(self.nodes[1].getbalance(), 1, 0.001) | assert_approx(self.nodes[1].getbalance(), 1, 0.001) | ||||
assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 11, 0.001) | assert_approx(self.nodes[1].getbalance(avoid_reuse=False), 11, 0.001) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
AvoidReuseTest().main() | AvoidReuseTest().main() |