mirror of https://github.com/oxen-io/oxen-core.git
Split ledger tests into multiple test files/groups
This commit is contained in:
parent
9cd7756d51
commit
67e1e6b364
|
@ -15,6 +15,13 @@ def pytest_addoption(parser):
|
|||
parser.addoption("--ledger-api", default="http://127.0.0.1:5000", action="store")
|
||||
|
||||
|
||||
def pytest_collection_modifyitems(session, config, items):
|
||||
"""Reorders the tests more logically than the default alphabetical order"""
|
||||
pos = {"test_basic.py": 1, "test_transfers.py": 2, "test_sn.py": 3, "test_ons.py": 4, "": 5}
|
||||
|
||||
items.sort(key=lambda i: pos.get(i.parent.name, pos[""]))
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def binary_dir(request):
|
||||
binpath = request.config.getoption("--binary-dir")
|
||||
|
@ -36,7 +43,6 @@ def ledger(request):
|
|||
|
||||
@pytest.fixture
|
||||
def net(pytestconfig, tmp_path, binary_dir):
|
||||
import vprint
|
||||
return service_node_network.basic_net(pytestconfig, tmp_path, binary_dir)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
from expected import *
|
||||
|
||||
|
||||
def test_init(net, mike, hal, ledger):
|
||||
"""
|
||||
Tests that the node fakenet got initialized properly, and that the wallet starts up and shows
|
||||
the right address.
|
||||
"""
|
||||
|
||||
# All nodes should be at the same height:
|
||||
heights = [x.rpc("/get_height").json()["height"] for x in net.all_nodes]
|
||||
height = max(heights)
|
||||
assert heights == [height] * len(net.all_nodes)
|
||||
|
||||
assert mike.height(refresh=True) == height
|
||||
assert mike.balances() > (0, 0)
|
||||
assert hal.height(refresh=True) == height
|
||||
assert hal.balances() == (0, 0)
|
||||
|
||||
address = hal.address()
|
||||
|
||||
def check_addr(_, m):
|
||||
assert address.startswith(m[1][1]) and address.endswith(m[1][2])
|
||||
|
||||
check_interactions(
|
||||
ledger,
|
||||
MatchScreen([r"^OXEN wallet$", r"^(\w+)\.\.(\w+)$"], check_addr),
|
||||
Do.both, # Hitting both on the main screen shows us the full address details
|
||||
ExactScreen(["Regular address", "(fakenet)"]),
|
||||
Do.right,
|
||||
MatchMulti("Address", address),
|
||||
Do.right,
|
||||
ExactScreen(["Back"]),
|
||||
Do.both,
|
||||
MatchScreen([r"^OXEN wallet$", r"^(\w+)\.\.(\w+)$"], check_addr),
|
||||
)
|
|
@ -0,0 +1,159 @@
|
|||
import pytest
|
||||
from functools import partial
|
||||
|
||||
from utils import *
|
||||
from expected import *
|
||||
|
||||
|
||||
def check_sn_rewards(net, hal, sn, starting_bal, reward):
|
||||
net.mine(5) # 5 blocks until it starts earning rewards (testnet/fakenet)
|
||||
|
||||
hal_bal = hal.balances(refresh=True)
|
||||
|
||||
batch_offset = None
|
||||
assert hal_bal == coins(starting_bal, 0)
|
||||
# We don't know where our batch payment occurs yet, but let's look for it:
|
||||
for i in range(20):
|
||||
net.mine(1)
|
||||
if hal.balances(refresh=True)[0] > coins(starting_bal):
|
||||
batch_offset = sn.height() % 20
|
||||
break
|
||||
|
||||
assert batch_offset is not None
|
||||
|
||||
hal_bal = hal.balances()
|
||||
|
||||
net.mine(19)
|
||||
assert hal.balances(refresh=True)[0] == hal_bal[0]
|
||||
net.mine(1) # Should be our batch height
|
||||
assert hal.balances(refresh=True)[0] == hal_bal[0] + coins(20 * reward)
|
||||
|
||||
|
||||
def test_sn_register(net, mike, hal, ledger, sn):
|
||||
mike.transfer(hal, coins(101))
|
||||
net.mine()
|
||||
|
||||
assert hal.balances(refresh=True) == coins(101, 101)
|
||||
|
||||
store_fee = StoreFee()
|
||||
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.register_sn, sn),
|
||||
ExactScreen(["Processing Stake"]),
|
||||
MatchScreen([r"^Confirm Fee$", r"^(0\.01\d{1,7})$"], store_fee, fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.both,
|
||||
ExactScreen(["Confirm Stake", "100.0"], fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.left,
|
||||
Do.both,
|
||||
ExactScreen(["Processing Stake"]),
|
||||
)
|
||||
|
||||
# We are half the SN network, so get half of the block reward per block:
|
||||
reward = 0.5 * 16.5
|
||||
check_sn_rewards(net, hal, sn, 101 - store_fee.fee, reward)
|
||||
|
||||
|
||||
def test_sn_stake(net, mike, alice, hal, ledger, sn):
|
||||
mike.multi_transfer([hal, alice], coins(13.02, 87.02))
|
||||
net.mine()
|
||||
|
||||
assert hal.balances(refresh=True) == coins(13.02, 13.02)
|
||||
assert alice.balances(refresh=True) == coins(87.02, 87.02)
|
||||
|
||||
alice.register_sn(sn, stake=coins(87))
|
||||
net.mine(1)
|
||||
|
||||
store_fee = StoreFee()
|
||||
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.stake_sn, sn, coins(13)),
|
||||
ExactScreen(["Processing Stake"]),
|
||||
MatchScreen([r"^Confirm Fee$", r"^(0\.01\d{1,7})$"], store_fee, fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.both,
|
||||
ExactScreen(["Confirm Stake", "13.0"], fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.left,
|
||||
Do.both,
|
||||
ExactScreen(["Processing Stake"]),
|
||||
)
|
||||
|
||||
# Our SN is 1 or 2 registered, so we get 50% of the 16.5 reward, 10% is removed for operator
|
||||
# fee, then hal gets 13/100 of the rest:
|
||||
reward = 0.5 * 16.5 * 0.9 * 0.13
|
||||
|
||||
check_sn_rewards(net, hal, sn, 13 - store_fee.fee, reward)
|
||||
|
||||
|
||||
def test_sn_reject(net, mike, hal, ledger, sn):
|
||||
mike.transfer(hal, coins(101))
|
||||
net.mine()
|
||||
|
||||
assert hal.balances(refresh=True) == coins(101, 101)
|
||||
|
||||
store_fee = StoreFee()
|
||||
|
||||
with pytest.raises(RuntimeError, match=r"Fee denied on device\.$"):
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.register_sn, sn),
|
||||
ExactScreen(["Processing Stake"]),
|
||||
MatchScreen([r"^Confirm Fee$", r"^(0\.01\d{1,7})$"], store_fee, fail_index=1),
|
||||
Do.right,
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.both,
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError, match=r"Transaction denied on device\.$"):
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.register_sn, sn),
|
||||
ExactScreen(["Processing Stake"]),
|
||||
MatchScreen([r"^Confirm Fee$", r"^(0\.01\d{1,7})$"], store_fee, fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.both,
|
||||
ExactScreen(["Confirm Stake", "100.0"], fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.both,
|
||||
)
|
||||
|
||||
|
||||
def test_sn_unstake(net, mike, hal, ledger, sn):
|
||||
# Do the full registration:
|
||||
test_sn_register(net, mike, hal, ledger, sn)
|
||||
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.unstake_sn, sn),
|
||||
ExactScreen(["Confirm Service", "Node Unlock"]),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.left,
|
||||
Do.both,
|
||||
)
|
||||
# A fakechain unlock takes 30 blocks, plus add another 20 just so we are sure we've received the
|
||||
# last batch reward:
|
||||
net.mine(30 + 20)
|
||||
|
||||
hal_bal = hal.balances(refresh=True)
|
||||
net.mine(20)
|
||||
assert hal.balances(refresh=True) == hal_bal
|
|
@ -1,54 +1,11 @@
|
|||
import pytest
|
||||
import time
|
||||
import re
|
||||
from functools import partial
|
||||
|
||||
from service_node_network import coins, vprint
|
||||
from ledgerapi import LedgerAPI
|
||||
from utils import *
|
||||
from expected import *
|
||||
import daemons
|
||||
|
||||
|
||||
def balance(c):
|
||||
"""Shortcut for coins(c,c), particularly useful when c is complex"""
|
||||
return coins(c, c)
|
||||
|
||||
|
||||
def test_init(net, mike, hal, ledger):
|
||||
"""
|
||||
Tests that the node fakenet got initialized properly, and that the wallet starts up and shows
|
||||
the right address.
|
||||
"""
|
||||
|
||||
# All nodes should be at the same height:
|
||||
heights = [x.rpc("/get_height").json()["height"] for x in net.all_nodes]
|
||||
height = max(heights)
|
||||
assert heights == [height] * len(net.all_nodes)
|
||||
|
||||
assert mike.height(refresh=True) == height
|
||||
assert mike.balances() > (0, 0)
|
||||
assert hal.height(refresh=True) == height
|
||||
assert hal.balances() == (0, 0)
|
||||
|
||||
address = hal.address()
|
||||
|
||||
def check_addr(_, m):
|
||||
assert address.startswith(m[1][1]) and address.endswith(m[1][2])
|
||||
|
||||
check_interactions(
|
||||
ledger,
|
||||
MatchScreen([r"^OXEN wallet$", r"^(\w+)\.\.(\w+)$"], check_addr),
|
||||
Do.both, # Hitting both on the main screen shows us the full address details
|
||||
ExactScreen(["Regular address", "(fakenet)"]),
|
||||
Do.right,
|
||||
MatchMulti("Address", address),
|
||||
Do.right,
|
||||
ExactScreen(["Back"]),
|
||||
Do.both,
|
||||
MatchScreen([r"^OXEN wallet$", r"^(\w+)\.\.(\w+)$"], check_addr),
|
||||
)
|
||||
|
||||
|
||||
def test_receive(net, mike, hal):
|
||||
mike.transfer(hal, coins(100))
|
||||
net.mine(blocks=2)
|
||||
|
@ -59,14 +16,6 @@ def test_receive(net, mike, hal):
|
|||
assert hal.balances(refresh=True) == coins(100, 100)
|
||||
|
||||
|
||||
class StoreFee:
|
||||
def __init__(self):
|
||||
self.fee = None
|
||||
|
||||
def __call__(self, _, m):
|
||||
self.fee = float(m[1][1])
|
||||
|
||||
|
||||
def test_send(net, mike, alice, hal, ledger):
|
||||
mike.transfer(hal, coins(100))
|
||||
net.mine()
|
||||
|
@ -386,157 +335,3 @@ def test_subaddr_send(net, mike, alice, bob, hal, ledger):
|
|||
assert alice.balances(refresh=True) == coins(6, 6)
|
||||
assert bob.balances(refresh=True) == coins(15, 15)
|
||||
assert hal.balances(refresh=True) == balance(100 - sum(amounts) - store_fee.fee)
|
||||
|
||||
|
||||
def check_sn_rewards(net, hal, sn, starting_bal, reward):
|
||||
net.mine(5) # 5 blocks until it starts earning rewards (testnet/fakenet)
|
||||
|
||||
hal_bal = hal.balances(refresh=True)
|
||||
|
||||
batch_offset = None
|
||||
assert hal_bal == coins(starting_bal, 0)
|
||||
# We don't know where our batch payment occurs yet, but let's look for it:
|
||||
for i in range(20):
|
||||
net.mine(1)
|
||||
if hal.balances(refresh=True)[0] > coins(starting_bal):
|
||||
batch_offset = sn.height() % 20
|
||||
break
|
||||
|
||||
assert batch_offset is not None
|
||||
|
||||
hal_bal = hal.balances()
|
||||
|
||||
net.mine(19)
|
||||
assert hal.balances(refresh=True)[0] == hal_bal[0]
|
||||
net.mine(1) # Should be our batch height
|
||||
assert hal.balances(refresh=True)[0] == hal_bal[0] + coins(20 * reward)
|
||||
|
||||
|
||||
def test_sn_register(net, mike, hal, ledger, sn):
|
||||
mike.transfer(hal, coins(101))
|
||||
net.mine()
|
||||
|
||||
assert hal.balances(refresh=True) == coins(101, 101)
|
||||
|
||||
store_fee = StoreFee()
|
||||
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.register_sn, sn),
|
||||
ExactScreen(["Processing Stake"]),
|
||||
MatchScreen([r"^Confirm Fee$", r"^(0\.01\d{1,7})$"], store_fee, fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.both,
|
||||
ExactScreen(["Confirm Stake", "100.0"], fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.left,
|
||||
Do.both,
|
||||
ExactScreen(["Processing Stake"]),
|
||||
)
|
||||
|
||||
# We are half the SN network, so get half of the block reward per block:
|
||||
reward = 0.5 * 16.5
|
||||
check_sn_rewards(net, hal, sn, 101 - store_fee.fee, reward)
|
||||
|
||||
|
||||
def test_sn_stake(net, mike, alice, hal, ledger, sn):
|
||||
mike.multi_transfer([hal, alice], coins(13.02, 87.02))
|
||||
net.mine()
|
||||
|
||||
assert hal.balances(refresh=True) == coins(13.02, 13.02)
|
||||
assert alice.balances(refresh=True) == coins(87.02, 87.02)
|
||||
|
||||
alice.register_sn(sn, stake=coins(87))
|
||||
net.mine(1)
|
||||
|
||||
store_fee = StoreFee()
|
||||
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.stake_sn, sn, coins(13)),
|
||||
ExactScreen(["Processing Stake"]),
|
||||
MatchScreen([r"^Confirm Fee$", r"^(0\.01\d{1,7})$"], store_fee, fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.both,
|
||||
ExactScreen(["Confirm Stake", "13.0"], fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.left,
|
||||
Do.both,
|
||||
ExactScreen(["Processing Stake"]),
|
||||
)
|
||||
|
||||
# Our SN is 1 or 2 registered, so we get 50% of the 16.5 reward, 10% is removed for operator
|
||||
# fee, then hal gets 13/100 of the rest:
|
||||
reward = 0.5 * 16.5 * 0.9 * 0.13
|
||||
|
||||
check_sn_rewards(net, hal, sn, 13 - store_fee.fee, reward)
|
||||
|
||||
|
||||
def test_sn_reject(net, mike, hal, ledger, sn):
|
||||
mike.transfer(hal, coins(101))
|
||||
net.mine()
|
||||
|
||||
assert hal.balances(refresh=True) == coins(101, 101)
|
||||
|
||||
store_fee = StoreFee()
|
||||
|
||||
with pytest.raises(RuntimeError, match=r"Fee denied on device\.$"):
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.register_sn, sn),
|
||||
ExactScreen(["Processing Stake"]),
|
||||
MatchScreen([r"^Confirm Fee$", r"^(0\.01\d{1,7})$"], store_fee, fail_index=1),
|
||||
Do.right,
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.both,
|
||||
)
|
||||
|
||||
with pytest.raises(RuntimeError, match=r"Transaction denied on device\.$"):
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.register_sn, sn),
|
||||
ExactScreen(["Processing Stake"]),
|
||||
MatchScreen([r"^Confirm Fee$", r"^(0\.01\d{1,7})$"], store_fee, fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.both,
|
||||
ExactScreen(["Confirm Stake", "100.0"], fail_index=1),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.both,
|
||||
)
|
||||
|
||||
|
||||
def test_sn_unstake(net, mike, hal, ledger, sn):
|
||||
# Do the full registration:
|
||||
test_sn_register(net, mike, hal, ledger, sn)
|
||||
|
||||
run_with_interactions(
|
||||
ledger,
|
||||
partial(hal.unstake_sn, sn),
|
||||
ExactScreen(["Confirm Service", "Node Unlock"]),
|
||||
Do.right,
|
||||
ExactScreen(["Accept"]),
|
||||
Do.right,
|
||||
ExactScreen(["Reject"]),
|
||||
Do.left,
|
||||
Do.both,
|
||||
)
|
||||
# A fakechain unlock takes 30 blocks, plus add another 20 just so we are sure we've received the
|
||||
# last batch reward:
|
||||
net.mine(30 + 20)
|
||||
|
||||
hal_bal = hal.balances(refresh=True)
|
||||
net.mine(20)
|
||||
assert hal.balances(refresh=True) == hal_bal
|
|
@ -0,0 +1,14 @@
|
|||
from service_node_network import coins, vprint
|
||||
|
||||
|
||||
def balance(c):
|
||||
"""Shortcut for coins(c,c), particularly useful when c is complex"""
|
||||
return coins(c, c)
|
||||
|
||||
|
||||
class StoreFee:
|
||||
def __init__(self):
|
||||
self.fee = None
|
||||
|
||||
def __call__(self, _, m):
|
||||
self.fee = float(m[1][1])
|
Loading…
Reference in New Issue