From e08a3ce3cdfb4200475610023c34c146c0eb31df Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Fri, 28 Apr 2023 15:37:21 -0300 Subject: [PATCH] Add multi-send test - WIP currently broken --- tests/ledger/conftest.py | 4 +++ tests/ledger/test_ledger.py | 54 ++++++++++++++++++++++++++++++++++ tests/network_tests/daemons.py | 21 +++++++++++++ 3 files changed, 79 insertions(+) diff --git a/tests/ledger/conftest.py b/tests/ledger/conftest.py index e0db1268f..14540355f 100644 --- a/tests/ledger/conftest.py +++ b/tests/ledger/conftest.py @@ -61,3 +61,7 @@ def mike(net): @pytest.fixture def alice(net): return net.alice + +@pytest.fixture +def bob(net): + return net.bob diff --git a/tests/ledger/test_ledger.py b/tests/ledger/test_ledger.py index bd54c791b..a5680a8c3 100644 --- a/tests/ledger/test_ledger.py +++ b/tests/ledger/test_ledger.py @@ -94,3 +94,57 @@ def test_send(net, mike, alice, hal, ledger): net.mine(9) assert hal.balances(refresh=True) == coins(remaining, remaining) assert alice.balances(refresh=True) == coins(42.5, 42.5) + + +def test_multisend(net, mike, alice, bob, hal, ledger): + mike.multi_transfer([hal] * 15, coins([7] * 15)) + net.mine() + + assert hal.balances(refresh=True) == coins(105, 105) + + fee = None + + def store_fee(_, m): + nonlocal fee + fee = float(m[1][1]) + + print("STARTING HAL MULTI TRANSFER in 3s!") + time.sleep(3) + + run_with_interactions( + ledger, + lambda: hal.multi_transfer((alice, bob, alice, alice, hal), (18, 19, 20, 21, 22)), + ExactScreen(["Processing TX"]), + MatchScreen([r"^Confirm Fee$", r"^(0.01\d{1,7})$"], store_fee, fail_index=1), + Do.right, + ExactScreen(["Accept"]), + Do.right, + ExactScreen(["Reject"]), + Do.left, + Do.both, + ExactScreen(["Confirm Amount", "42.5"], fail_index=1), + Do.right, + MatchMulti("Recipient", alice.address()), + Do.right, + ExactScreen(["Accept"]), + Do.right, + ExactScreen(["Reject"]), + Do.right, # This loops back around to the amount: + ExactScreen(["Confirm Amount", "42.5"]), + Do.left, + Do.left, + ExactScreen(["Accept"]), + Do.both, + ) + + net.mine(1) + remaining = coins(5 - fee + 22) + hal_bal = hal.balances(refresh=True) + assert hal_bal[0] == remaining + assert hal_bal[1] < remaining + assert alice.balances(refresh=True) == coins(18 + 20 + 21, 0) + assert bob.balances(refresh=True) == coins(19, 0) + net.mine(9) + assert hal.balances(refresh=True) == coins([remaining] * 2) + assert alice.balances(refresh=True) == coins([18 + 20 + 21] * 2) + assert bob.balances(refresh=True) == coins(19, 19) diff --git a/tests/network_tests/daemons.py b/tests/network_tests/daemons.py index ab2634b0e..27931ef0b 100644 --- a/tests/network_tests/daemons.py +++ b/tests/network_tests/daemons.py @@ -379,6 +379,27 @@ class Wallet(RPCDaemon): raise TransferFailed(f"Transfer failed: {r['error']['message']}", r) return r["result"] + def multi_transfer(self, recipients, amounts, *, priority=None): + """Attempts a transfer to multiple recipients at once. Throws TransferFailed if it gets + rejected by the daemon, otherwise returns the 'result' key.""" + assert 0 < len(recipients) == len(amounts) + if priority is None: + priority = 1 + r = self.json_rpc( + "transfer_split", + { + "destinations": [ + {"address": r.address(), "amount": a} for r, a in zip(recipients, amounts) + ], + "priority": priority, + }, + ) + + r = r.json() + if "error" in r: + raise TransferFailed(f"Transfer failed: {r['error']['message']}", r) + return r["result"] + def find_transfers(self, txids, in_=True, pool=True, out=True, pending=False, failed=False): transfers = self.json_rpc( "get_transfers",