tests: not DEVELOPER -> mark.developer

Nicer syntaxtic sugar for marking pytests as 'developer required'
This commit is contained in:
niftynei 2021-04-26 14:58:58 -05:00 committed by Rusty Russell
parent b4e24ac8ba
commit d0bbf07655
9 changed files with 202 additions and 195 deletions

View File

@ -1,5 +1,7 @@
import pytest import pytest
from pyln.testing.utils import DEVELOPER
# This function is based upon the example of how to # This function is based upon the example of how to
# "[make] test result information available in fixtures" at: # "[make] test result information available in fixtures" at:
@ -21,3 +23,14 @@ def pytest_runtest_makereport(item, call):
def pytest_configure(config): def pytest_configure(config):
config.addinivalue_line("markers", config.addinivalue_line("markers",
"slow_test: slow tests aren't run under Valgrind") "slow_test: slow tests aren't run under Valgrind")
config.addinivalue_line("markers",
"developer: only run when developer is flagged on")
def pytest_runtest_setup(item):
for mark in item.iter_markers(name='developer'):
if not DEVELOPER:
if len(mark.args):
pytest.skip('!DEVELOPER: {}'.format(mark.args[0]))
else:
pytest.skip('!DEVELOPER: Requires DEVELOPER=1')

View File

@ -4,7 +4,7 @@ from pyln.client import RpcError, Millisatoshi
from shutil import copyfile from shutil import copyfile
from pyln.testing.utils import SLOW_MACHINE, EXPERIMENTAL_DUAL_FUND from pyln.testing.utils import SLOW_MACHINE, EXPERIMENTAL_DUAL_FUND
from utils import ( from utils import (
only_one, sync_blockheight, wait_for, DEVELOPER, TIMEOUT, only_one, sync_blockheight, wait_for, TIMEOUT,
account_balance, first_channel_id, basic_fee, TEST_NETWORK, account_balance, first_channel_id, basic_fee, TEST_NETWORK,
EXPERIMENTAL_FEATURES, scriptpubkey_addr EXPERIMENTAL_FEATURES, scriptpubkey_addr
) )
@ -18,7 +18,7 @@ import threading
import unittest import unittest
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-bitcoind-poll") @pytest.mark.developer("Too slow without --dev-bitcoind-poll")
def test_closing(node_factory, bitcoind, chainparams): def test_closing(node_factory, bitcoind, chainparams):
l1, l2 = node_factory.line_graph(2) l1, l2 = node_factory.line_graph(2)
chan = l1.get_channel_scid(l2) chan = l1.get_channel_scid(l2)
@ -35,16 +35,12 @@ def test_closing(node_factory, bitcoind, chainparams):
bitcoind.generate_block(5) bitcoind.generate_block(5)
# Only wait for the channels to activate with DEVELOPER=1, wait_for(lambda: len(l1.getactivechannels()) == 2)
# otherwise it's going to take too long because of the missing wait_for(lambda: len(l2.getactivechannels()) == 2)
# --dev-fast-gossip billboard = only_one(l1.rpc.listpeers(l2.info['id'])['peers'][0]['channels'])['status']
if DEVELOPER: # This may either be from a local_update or an announce, so just
wait_for(lambda: len(l1.getactivechannels()) == 2) # check for the substring
wait_for(lambda: len(l2.getactivechannels()) == 2) assert 'CHANNELD_NORMAL:Funding transaction locked.' in billboard[0]
billboard = only_one(l1.rpc.listpeers(l2.info['id'])['peers'][0]['channels'])['status']
# This may either be from a local_update or an announce, so just
# check for the substring
assert 'CHANNELD_NORMAL:Funding transaction locked.' in billboard[0]
l1.rpc.close(chan) l1.rpc.close(chan)
@ -293,7 +289,7 @@ def test_closing_different_fees(node_factory, bitcoind, executor):
l1.daemon.wait_for_logs([' to ONCHAIN'] * num_peers) l1.daemon.wait_for_logs([' to ONCHAIN'] * num_peers)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_closing_negotiation_reconnect(node_factory, bitcoind): def test_closing_negotiation_reconnect(node_factory, bitcoind):
disconnects = ['-WIRE_CLOSING_SIGNED', disconnects = ['-WIRE_CLOSING_SIGNED',
'@WIRE_CLOSING_SIGNED', '@WIRE_CLOSING_SIGNED',
@ -317,7 +313,7 @@ def test_closing_negotiation_reconnect(node_factory, bitcoind):
n.daemon.wait_for_log(r'Resolved FUNDING_TRANSACTION/FUNDING_OUTPUT by MUTUAL_CLOSE') n.daemon.wait_for_log(r'Resolved FUNDING_TRANSACTION/FUNDING_OUTPUT by MUTUAL_CLOSE')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_closing_specified_destination(node_factory, bitcoind, chainparams): def test_closing_specified_destination(node_factory, bitcoind, chainparams):
l1, l2, l3, l4 = node_factory.get_nodes(4) l1, l2, l3, l4 = node_factory.get_nodes(4)
@ -525,7 +521,7 @@ def test_closing_negotiation_step_700sat(node_factory, bitcoind, chainparams):
closing_negotiation_step(node_factory, bitcoind, chainparams, opts) closing_negotiation_step(node_factory, bitcoind, chainparams, opts)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_penalty_inhtlc(node_factory, bitcoind, executor, chainparams): def test_penalty_inhtlc(node_factory, bitcoind, executor, chainparams):
"""Test penalty transaction with an incoming HTLC""" """Test penalty transaction with an incoming HTLC"""
@ -621,7 +617,7 @@ def test_penalty_inhtlc(node_factory, bitcoind, executor, chainparams):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_penalty_outhtlc(node_factory, bitcoind, executor, chainparams): def test_penalty_outhtlc(node_factory, bitcoind, executor, chainparams):
"""Test penalty transaction with an outgoing HTLC""" """Test penalty transaction with an outgoing HTLC"""
@ -722,7 +718,7 @@ def test_penalty_outhtlc(node_factory, bitcoind, executor, chainparams):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db") @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_penalty_htlc_tx_fulfill(node_factory, bitcoind, chainparams): def test_penalty_htlc_tx_fulfill(node_factory, bitcoind, chainparams):
@ -855,7 +851,7 @@ def test_penalty_htlc_tx_fulfill(node_factory, bitcoind, chainparams):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db") @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams): def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams):
@ -1039,7 +1035,7 @@ def test_penalty_htlc_tx_timeout(node_factory, bitcoind, chainparams):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "uses dev_sign_last_tx") @pytest.mark.developer("uses dev_sign_last_tx")
def test_penalty_rbf_normal(node_factory, bitcoind, executor, chainparams): def test_penalty_rbf_normal(node_factory, bitcoind, executor, chainparams):
''' '''
Test that penalty transactions are RBFed. Test that penalty transactions are RBFed.
@ -1144,7 +1140,7 @@ def test_penalty_rbf_normal(node_factory, bitcoind, executor, chainparams):
assert(len(l2.rpc.listfunds()['outputs']) >= 1) assert(len(l2.rpc.listfunds()['outputs']) >= 1)
@unittest.skipIf(not DEVELOPER, "uses dev_sign_last_tx") @pytest.mark.developer("uses dev_sign_last_tx")
def test_penalty_rbf_burn(node_factory, bitcoind, executor, chainparams): def test_penalty_rbf_burn(node_factory, bitcoind, executor, chainparams):
''' '''
Test that penalty transactions are RBFed and we are willing to burn Test that penalty transactions are RBFed and we are willing to burn
@ -1249,7 +1245,7 @@ def test_penalty_rbf_burn(node_factory, bitcoind, executor, chainparams):
assert(len(l2.rpc.listfunds()['outputs']) == 0) assert(len(l2.rpc.listfunds()['outputs']) == 0)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchain_first_commit(node_factory, bitcoind): def test_onchain_first_commit(node_factory, bitcoind):
"""Onchain handling where opener immediately drops to chain""" """Onchain handling where opener immediately drops to chain"""
@ -1291,7 +1287,7 @@ def test_onchain_first_commit(node_factory, bitcoind):
l1.daemon.wait_for_log('onchaind complete, forgetting peer') l1.daemon.wait_for_log('onchaind complete, forgetting peer')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchain_unwatch(node_factory, bitcoind): def test_onchain_unwatch(node_factory, bitcoind):
"""Onchaind should not watch random spends""" """Onchaind should not watch random spends"""
# We track channel balances, to verify that accounting is ok. # We track channel balances, to verify that accounting is ok.
@ -1345,7 +1341,7 @@ def test_onchain_unwatch(node_factory, bitcoind):
# any leaks! # any leaks!
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchaind_replay(node_factory, bitcoind): def test_onchaind_replay(node_factory, bitcoind):
disconnects = ['+WIRE_REVOKE_AND_ACK', 'permfail'] disconnects = ['+WIRE_REVOKE_AND_ACK', 'permfail']
# Feerates identical so we don't get gratuitous commit to update them # Feerates identical so we don't get gratuitous commit to update them
@ -1395,7 +1391,7 @@ def test_onchaind_replay(node_factory, bitcoind):
sync_blockheight(bitcoind, [l1]) sync_blockheight(bitcoind, [l1])
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchain_dust_out(node_factory, bitcoind, executor): def test_onchain_dust_out(node_factory, bitcoind, executor):
"""Onchain handling of outgoing dust htlcs (they should fail)""" """Onchain handling of outgoing dust htlcs (they should fail)"""
# We track channel balances, to verify that accounting is ok. # We track channel balances, to verify that accounting is ok.
@ -1466,7 +1462,7 @@ def test_onchain_dust_out(node_factory, bitcoind, executor):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchain_timeout(node_factory, bitcoind, executor): def test_onchain_timeout(node_factory, bitcoind, executor):
"""Onchain handling of outgoing failed htlcs""" """Onchain handling of outgoing failed htlcs"""
# We track channel balances, to verify that accounting is ok. # We track channel balances, to verify that accounting is ok.
@ -1552,7 +1548,7 @@ def test_onchain_timeout(node_factory, bitcoind, executor):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchain_middleman(node_factory, bitcoind): def test_onchain_middleman(node_factory, bitcoind):
# We track channel balances, to verify that accounting is ok. # We track channel balances, to verify that accounting is ok.
coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py') coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py')
@ -1638,7 +1634,7 @@ def test_onchain_middleman(node_factory, bitcoind):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchain_middleman_their_unilateral_in(node_factory, bitcoind): def test_onchain_middleman_their_unilateral_in(node_factory, bitcoind):
""" This is the same as test_onchain_middleman, except that """ This is the same as test_onchain_middleman, except that
node l1 drops to chain, not l2, reversing the unilateral node l1 drops to chain, not l2, reversing the unilateral
@ -1724,7 +1720,7 @@ def test_onchain_middleman_their_unilateral_in(node_factory, bitcoind):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchain_their_unilateral_out(node_factory, bitcoind): def test_onchain_their_unilateral_out(node_factory, bitcoind):
""" Very similar to the test_onchain_middleman, except there's no """ Very similar to the test_onchain_middleman, except there's no
middleman, we simply want to check that our offered htlc middleman, we simply want to check that our offered htlc
@ -1821,7 +1817,7 @@ Make sure we show the address.
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_onchain_feechange(node_factory, bitcoind, executor): def test_onchain_feechange(node_factory, bitcoind, executor):
"""Onchain handling when we restart with different fees""" """Onchain handling when we restart with different fees"""
# HTLC 1->2, 2 fails just after they're both irrevocably committed # HTLC 1->2, 2 fails just after they're both irrevocably committed
@ -1901,7 +1897,7 @@ def test_onchain_feechange(node_factory, bitcoind, executor):
assert only_one(l2.rpc.listinvoices('onchain_timeout')['invoices'])['status'] == 'unpaid' assert only_one(l2.rpc.listinvoices('onchain_timeout')['invoices'])['status'] == 'unpaid'
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev-set-fees") @pytest.mark.developer("needs DEVELOPER=1 for dev-set-fees")
def test_onchain_all_dust(node_factory, bitcoind, executor): def test_onchain_all_dust(node_factory, bitcoind, executor):
"""Onchain handling when we reduce output to all dust""" """Onchain handling when we reduce output to all dust"""
# We track channel balances, to verify that accounting is ok. # We track channel balances, to verify that accounting is ok.
@ -1967,7 +1963,7 @@ def test_onchain_all_dust(node_factory, bitcoind, executor):
assert account_balance(l2, channel_id) == 0 assert account_balance(l2, channel_id) == 0
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev_fail") @pytest.mark.developer("needs DEVELOPER=1 for dev_fail")
def test_onchain_different_fees(node_factory, bitcoind, executor): def test_onchain_different_fees(node_factory, bitcoind, executor):
"""Onchain handling when we've had a range of fees""" """Onchain handling when we've had a range of fees"""
l1, l2 = node_factory.line_graph(2, fundchannel=True, fundamount=10**7, l1, l2 = node_factory.line_graph(2, fundchannel=True, fundamount=10**7,
@ -2031,7 +2027,7 @@ def test_onchain_different_fees(node_factory, bitcoind, executor):
wait_for(lambda: l2.rpc.listpeers()['peers'] == []) wait_for(lambda: l2.rpc.listpeers()['peers'] == [])
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_permfail_new_commit(node_factory, bitcoind, executor): def test_permfail_new_commit(node_factory, bitcoind, executor):
# Test case where we have two possible commits: it will use new one. # Test case where we have two possible commits: it will use new one.
disconnects = ['-WIRE_REVOKE_AND_ACK', 'permfail'] disconnects = ['-WIRE_REVOKE_AND_ACK', 'permfail']
@ -2141,7 +2137,7 @@ def setup_multihtlc_test(node_factory, bitcoind):
return h, nodes return h, nodes
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev_ignore_htlcs") @pytest.mark.developer("needs DEVELOPER=1 for dev_ignore_htlcs")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_onchain_multihtlc_our_unilateral(node_factory, bitcoind): def test_onchain_multihtlc_our_unilateral(node_factory, bitcoind):
"""Node pushes a channel onchain with multiple HTLCs with same payment_hash """ """Node pushes a channel onchain with multiple HTLCs with same payment_hash """
@ -2233,7 +2229,7 @@ def test_onchain_multihtlc_our_unilateral(node_factory, bitcoind):
assert only_one(nodes[i].rpc.listpeers(nodes[i + 1].info['id'])['peers'])['connected'] assert only_one(nodes[i].rpc.listpeers(nodes[i + 1].info['id'])['peers'])['connected']
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev_ignore_htlcs") @pytest.mark.developer("needs DEVELOPER=1 for dev_ignore_htlcs")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_onchain_multihtlc_their_unilateral(node_factory, bitcoind): def test_onchain_multihtlc_their_unilateral(node_factory, bitcoind):
"""Node pushes a channel onchain with multiple HTLCs with same payment_hash """ """Node pushes a channel onchain with multiple HTLCs with same payment_hash """
@ -2333,7 +2329,7 @@ def test_onchain_multihtlc_their_unilateral(node_factory, bitcoind):
assert only_one(nodes[i].rpc.listpeers(nodes[i + 1].info['id'])['peers'])['connected'] assert only_one(nodes[i].rpc.listpeers(nodes[i + 1].info['id'])['peers'])['connected']
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_permfail_htlc_in(node_factory, bitcoind, executor): def test_permfail_htlc_in(node_factory, bitcoind, executor):
# Test case where we fail with unsettled incoming HTLC. # Test case where we fail with unsettled incoming HTLC.
disconnects = ['-WIRE_UPDATE_FULFILL_HTLC', 'permfail'] disconnects = ['-WIRE_UPDATE_FULFILL_HTLC', 'permfail']
@ -2379,7 +2375,7 @@ def test_permfail_htlc_in(node_factory, bitcoind, executor):
l2.daemon.wait_for_log('onchaind complete, forgetting peer') l2.daemon.wait_for_log('onchaind complete, forgetting peer')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_permfail_htlc_out(node_factory, bitcoind, executor): def test_permfail_htlc_out(node_factory, bitcoind, executor):
# Test case where we fail with unsettled outgoing HTLC. # Test case where we fail with unsettled outgoing HTLC.
disconnects = ['+WIRE_REVOKE_AND_ACK', 'permfail'] disconnects = ['+WIRE_REVOKE_AND_ACK', 'permfail']
@ -2438,7 +2434,7 @@ def test_permfail_htlc_out(node_factory, bitcoind, executor):
wait_for(lambda: l2.rpc.listpeers()['peers'] == []) wait_for(lambda: l2.rpc.listpeers()['peers'] == [])
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_permfail(node_factory, bitcoind): def test_permfail(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2) l1, l2 = node_factory.line_graph(2)
@ -2529,7 +2525,7 @@ def test_permfail(node_factory, bitcoind):
l1.rpc.withdraw(addr, "all") l1.rpc.withdraw(addr, "all")
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_shutdown(node_factory): def test_shutdown(node_factory):
# Fail, in that it will exit before cleanup. # Fail, in that it will exit before cleanup.
l1 = node_factory.get_node(may_fail=True) l1 = node_factory.get_node(may_fail=True)
@ -2542,7 +2538,7 @@ def test_shutdown(node_factory):
@flaky @flaky
@unittest.skipIf(not DEVELOPER, "needs to set upfront_shutdown_script") @pytest.mark.developer("needs to set upfront_shutdown_script")
def test_option_upfront_shutdown_script(node_factory, bitcoind, executor): def test_option_upfront_shutdown_script(node_factory, bitcoind, executor):
# There's a workaround in channeld, that it treats incoming errors # There's a workaround in channeld, that it treats incoming errors
# before both sides are locked in as warnings; this happens in # before both sides are locked in as warnings; this happens in
@ -2607,7 +2603,7 @@ def test_option_upfront_shutdown_script(node_factory, bitcoind, executor):
wait_for(lambda: sorted([c['state'] for c in only_one(l1.rpc.listpeers()['peers'])['channels']]) == ['CLOSINGD_COMPLETE', 'ONCHAIN', 'ONCHAIN']) wait_for(lambda: sorted([c['state'] for c in only_one(l1.rpc.listpeers()['peers'])['channels']]) == ['CLOSINGD_COMPLETE', 'ONCHAIN', 'ONCHAIN'])
@unittest.skipIf(not DEVELOPER, "needs to set upfront_shutdown_script") @pytest.mark.developer("needs to set upfront_shutdown_script")
def test_invalid_upfront_shutdown_script(node_factory, bitcoind, executor): def test_invalid_upfront_shutdown_script(node_factory, bitcoind, executor):
l1, l2 = node_factory.line_graph(2, fundchannel=False) l1, l2 = node_factory.line_graph(2, fundchannel=False)
@ -2622,7 +2618,7 @@ def test_invalid_upfront_shutdown_script(node_factory, bitcoind, executor):
l1.fundchannel(l2, 1000000, False) l1.fundchannel(l2, 1000000, False)
@unittest.skipIf(not DEVELOPER, "needs to set upfront_shutdown_script") @pytest.mark.developer("needs to set upfront_shutdown_script")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_segwit_shutdown_script(node_factory, bitcoind, executor): def test_segwit_shutdown_script(node_factory, bitcoind, executor):
""" """

View File

@ -4,7 +4,7 @@ from fixtures import TEST_NETWORK
from flaky import flaky # noqa: F401 from flaky import flaky # noqa: F401
from pyln.client import RpcError, Millisatoshi from pyln.client import RpcError, Millisatoshi
from utils import ( from utils import (
DEVELOPER, only_one, wait_for, sync_blockheight, TIMEOUT, only_one, wait_for, sync_blockheight, TIMEOUT,
expected_peer_features, expected_node_features, expected_peer_features, expected_node_features,
expected_channel_features, expected_channel_features,
check_coin_moves, first_channel_id, account_balance, basic_fee, check_coin_moves, first_channel_id, account_balance, basic_fee,
@ -167,7 +167,7 @@ def test_bad_opening(node_factory):
l2.daemon.wait_for_log('to_self_delay 100 larger than 99') l2.daemon.wait_for_log('to_self_delay 100 larger than 99')
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
@unittest.skipIf(TEST_NETWORK != 'regtest', "Fee computation and limits are network specific") @unittest.skipIf(TEST_NETWORK != 'regtest', "Fee computation and limits are network specific")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_opening_tiny_channel(node_factory): def test_opening_tiny_channel(node_factory):
@ -237,7 +237,7 @@ def test_second_channel(node_factory):
l1.fundchannel(l3, 10**6) l1.fundchannel(l3, 10**6)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_disconnect(node_factory): def test_disconnect(node_factory):
# These should all make us fail # These should all make us fail
disconnects = ['-WIRE_INIT', disconnects = ['-WIRE_INIT',
@ -263,7 +263,7 @@ def test_disconnect(node_factory):
assert len(l2.rpc.listpeers()) == 1 assert len(l2.rpc.listpeers()) == 1
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_disconnect_opener(node_factory): def test_disconnect_opener(node_factory):
# Now error on opener side during channel open. # Now error on opener side during channel open.
disconnects = ['-WIRE_OPEN_CHANNEL', disconnects = ['-WIRE_OPEN_CHANNEL',
@ -305,7 +305,7 @@ def test_disconnect_opener(node_factory):
assert len(l2.rpc.listpeers()) == 1 assert len(l2.rpc.listpeers()) == 1
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_disconnect_fundee(node_factory): def test_disconnect_fundee(node_factory):
# Now error on fundee side during channel open. # Now error on fundee side during channel open.
disconnects = ['-WIRE_ACCEPT_CHANNEL', disconnects = ['-WIRE_ACCEPT_CHANNEL',
@ -340,7 +340,7 @@ def test_disconnect_fundee(node_factory):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_disconnect_fundee_v2(node_factory): def test_disconnect_fundee_v2(node_factory):
# Now error on fundee side during channel open, with them funding # Now error on fundee side during channel open, with them funding
disconnects = ['-WIRE_ACCEPT_CHANNEL2', disconnects = ['-WIRE_ACCEPT_CHANNEL2',
@ -381,7 +381,7 @@ def test_disconnect_fundee_v2(node_factory):
assert len(l2.rpc.listpeers()) == 1 assert len(l2.rpc.listpeers()) == 1
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_disconnect_half_signed(node_factory): def test_disconnect_half_signed(node_factory):
# Now, these are the corner cases. Fundee sends funding_signed, # Now, these are the corner cases. Fundee sends funding_signed,
# but opener doesn't receive it. # but opener doesn't receive it.
@ -402,7 +402,7 @@ def test_disconnect_half_signed(node_factory):
assert l2.rpc.getpeer(l1.info['id'])['id'] == l1.info['id'] assert l2.rpc.getpeer(l1.info['id'])['id'] == l1.info['id']
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_signed(node_factory): def test_reconnect_signed(node_factory):
# This will fail *after* both sides consider channel opening. # This will fail *after* both sides consider channel opening.
disconnects = ['+WIRE_FUNDING_SIGNED'] disconnects = ['+WIRE_FUNDING_SIGNED']
@ -436,7 +436,7 @@ def test_reconnect_signed(node_factory):
l2.daemon.wait_for_log(' to CHANNELD_NORMAL') l2.daemon.wait_for_log(' to CHANNELD_NORMAL')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_openingd(node_factory): def test_reconnect_openingd(node_factory):
# Openingd thinks we're still opening; opener reconnects.. # Openingd thinks we're still opening; opener reconnects..
disconnects = ['0WIRE_ACCEPT_CHANNEL'] disconnects = ['0WIRE_ACCEPT_CHANNEL']
@ -473,7 +473,7 @@ def test_reconnect_openingd(node_factory):
l2.daemon.wait_for_log(r'channeld-chan#[0-9]: pid [0-9]+, msgfd [0-9]+') l2.daemon.wait_for_log(r'channeld-chan#[0-9]: pid [0-9]+, msgfd [0-9]+')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_gossiping(node_factory): def test_reconnect_gossiping(node_factory):
# connectd thinks we're still gossiping; peer reconnects. # connectd thinks we're still gossiping; peer reconnects.
disconnects = ['0WIRE_PING'] disconnects = ['0WIRE_PING']
@ -492,7 +492,7 @@ def test_reconnect_gossiping(node_factory):
@flaky @flaky
@unittest.skipIf(not DEVELOPER, "needs dev-disconnect") @pytest.mark.developer("needs dev-disconnect")
def test_reconnect_no_update(node_factory, executor, bitcoind): def test_reconnect_no_update(node_factory, executor, bitcoind):
"""Test that funding_locked is retransmitted on reconnect if new channel """Test that funding_locked is retransmitted on reconnect if new channel
@ -577,7 +577,7 @@ def test_connect_stresstest(node_factory, executor):
assert successes > failures assert successes > failures
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_normal(node_factory): def test_reconnect_normal(node_factory):
# Should reconnect fine even if locked message gets lost. # Should reconnect fine even if locked message gets lost.
disconnects = ['-WIRE_FUNDING_LOCKED', disconnects = ['-WIRE_FUNDING_LOCKED',
@ -591,7 +591,7 @@ def test_reconnect_normal(node_factory):
l1.fundchannel(l2, 10**6) l1.fundchannel(l2, 10**6)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_sender_add1(node_factory): def test_reconnect_sender_add1(node_factory):
# Fail after add is OK, will cause payment failure though. # Fail after add is OK, will cause payment failure though.
disconnects = ['-WIRE_UPDATE_ADD_HTLC-nocommit', disconnects = ['-WIRE_UPDATE_ADD_HTLC-nocommit',
@ -625,7 +625,7 @@ def test_reconnect_sender_add1(node_factory):
l1.rpc.sendpay(route, rhash) l1.rpc.sendpay(route, rhash)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_sender_add(node_factory): def test_reconnect_sender_add(node_factory):
disconnects = ['-WIRE_COMMITMENT_SIGNED', disconnects = ['-WIRE_COMMITMENT_SIGNED',
'@WIRE_COMMITMENT_SIGNED', '@WIRE_COMMITMENT_SIGNED',
@ -658,7 +658,7 @@ def test_reconnect_sender_add(node_factory):
l1.daemon.wait_for_log('Already have funding locked in') l1.daemon.wait_for_log('Already have funding locked in')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_receiver_add(node_factory): def test_reconnect_receiver_add(node_factory):
disconnects = ['-WIRE_COMMITMENT_SIGNED', disconnects = ['-WIRE_COMMITMENT_SIGNED',
'@WIRE_COMMITMENT_SIGNED', '@WIRE_COMMITMENT_SIGNED',
@ -689,7 +689,7 @@ def test_reconnect_receiver_add(node_factory):
assert only_one(l2.rpc.listinvoices('testpayment2')['invoices'])['status'] == 'paid' assert only_one(l2.rpc.listinvoices('testpayment2')['invoices'])['status'] == 'paid'
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_receiver_fulfill(node_factory): def test_reconnect_receiver_fulfill(node_factory):
# Ordering matters: after +WIRE_UPDATE_FULFILL_HTLC, channeld # Ordering matters: after +WIRE_UPDATE_FULFILL_HTLC, channeld
# will continue and try to send WIRE_COMMITMENT_SIGNED: if # will continue and try to send WIRE_COMMITMENT_SIGNED: if
@ -722,7 +722,7 @@ def test_reconnect_receiver_fulfill(node_factory):
@flaky @flaky
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_shutdown_reconnect(node_factory): def test_shutdown_reconnect(node_factory):
disconnects = ['-WIRE_SHUTDOWN', disconnects = ['-WIRE_SHUTDOWN',
'@WIRE_SHUTDOWN', '@WIRE_SHUTDOWN',
@ -754,7 +754,7 @@ def test_shutdown_reconnect(node_factory):
@flaky @flaky
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_reconnect_remote_sends_no_sigs(node_factory): def test_reconnect_remote_sends_no_sigs(node_factory):
"""We re-announce, even when remote node doesn't send its announcement_signatures on reconnect. """We re-announce, even when remote node doesn't send its announcement_signatures on reconnect.
""" """
@ -1060,7 +1060,7 @@ def test_funding_by_utxos(node_factory, bitcoind):
l1.rpc.fundchannel(l3.info["id"], int(0.01 * 10**8), utxos=utxos) l1.rpc.fundchannel(l3.info["id"], int(0.01 * 10**8), utxos=utxos)
@unittest.skipIf(not DEVELOPER, "needs dev_forget_channel") @pytest.mark.developer("needs dev_forget_channel")
@unittest.skipIf(EXPERIMENTAL_DUAL_FUND, "Uses fundchannel_start") @unittest.skipIf(EXPERIMENTAL_DUAL_FUND, "Uses fundchannel_start")
def test_funding_external_wallet_corners(node_factory, bitcoind): def test_funding_external_wallet_corners(node_factory, bitcoind):
l1 = node_factory.get_node(may_reconnect=True) l1 = node_factory.get_node(may_reconnect=True)
@ -1541,7 +1541,7 @@ def test_multifunding_one(node_factory, bitcoind):
l1.rpc.pay(inv) l1.rpc.pay(inv)
@unittest.skipIf(not DEVELOPER, "disconnect=... needs DEVELOPER=1") @pytest.mark.developer("needs dev-disconnect")
def test_multifunding_disconnect(node_factory): def test_multifunding_disconnect(node_factory):
''' '''
Test disconnection during multifundchannel Test disconnection during multifundchannel
@ -1621,7 +1621,7 @@ def test_multifunding_wumbo(node_factory):
@unittest.skipIf(TEST_NETWORK == 'liquid-regtest', "Fees on elements are different") @unittest.skipIf(TEST_NETWORK == 'liquid-regtest', "Fees on elements are different")
@unittest.skipIf(not DEVELOPER, "uses dev-fail") @pytest.mark.developer("uses dev-fail")
def test_multifunding_feerates(node_factory, bitcoind): def test_multifunding_feerates(node_factory, bitcoind):
''' '''
Test feerate parameters for multifundchannel Test feerate parameters for multifundchannel
@ -1725,7 +1725,7 @@ def test_multifunding_param_failures(node_factory):
l1.rpc.multifundchannel(destinations) l1.rpc.multifundchannel(destinations)
@unittest.skipIf(not DEVELOPER, "disconnect=... needs DEVELOPER=1") @pytest.mark.developer("disconnect=... needs DEVELOPER=1")
def test_multifunding_best_effort(node_factory, bitcoind): def test_multifunding_best_effort(node_factory, bitcoind):
''' '''
Check that best_effort flag works. Check that best_effort flag works.
@ -1841,7 +1841,7 @@ def test_funding_while_offline(node_factory, bitcoind):
assert len(l1.rpc.listfunds()['outputs']) == 1 assert len(l1.rpc.listfunds()['outputs']) == 1
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_channel_persistence(node_factory, bitcoind, executor): def test_channel_persistence(node_factory, bitcoind, executor):
# Start two nodes and open a channel (to remember). l2 will # Start two nodes and open a channel (to remember). l2 will
# mysteriously die while committing the first HTLC so we can # mysteriously die while committing the first HTLC so we can
@ -1918,7 +1918,7 @@ def test_channel_persistence(node_factory, bitcoind, executor):
l1.daemon.wait_for_log(' to ONCHAIN') l1.daemon.wait_for_log(' to ONCHAIN')
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_private_channel(node_factory): def test_private_channel(node_factory):
l1, l2 = node_factory.line_graph(2, announce_channels=False, wait_for_announce=False) l1, l2 = node_factory.line_graph(2, announce_channels=False, wait_for_announce=False)
l3, l4 = node_factory.line_graph(2, announce_channels=True, wait_for_announce=True) l3, l4 = node_factory.line_graph(2, announce_channels=True, wait_for_announce=True)
@ -1939,7 +1939,7 @@ def test_private_channel(node_factory):
assert not only_one(only_one(l4.rpc.listpeers(l3.info['id'])['peers'])['channels'])['private'] assert not only_one(only_one(l4.rpc.listpeers(l3.info['id'])['peers'])['channels'])['private']
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_channel_reenable(node_factory): def test_channel_reenable(node_factory):
l1, l2 = node_factory.line_graph(2, opts={'may_reconnect': True}, fundchannel=True, wait_for_announce=True) l1, l2 = node_factory.line_graph(2, opts={'may_reconnect': True}, fundchannel=True, wait_for_announce=True)
@ -1959,7 +1959,7 @@ def test_channel_reenable(node_factory):
wait_for(lambda: [c['active'] for c in l2.rpc.listchannels()['channels']] == [True, True]) wait_for(lambda: [c['active'] for c in l2.rpc.listchannels()['channels']] == [True, True])
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_update_fee(node_factory, bitcoind): def test_update_fee(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, fundchannel=True) l1, l2 = node_factory.line_graph(2, fundchannel=True)
chanid = l1.get_channel_scid(l2) chanid = l1.get_channel_scid(l2)
@ -1997,7 +1997,7 @@ def test_update_fee(node_factory, bitcoind):
l2.daemon.wait_for_log('onchaind complete, forgetting peer') l2.daemon.wait_for_log('onchaind complete, forgetting peer')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_fee_limits(node_factory, bitcoind): def test_fee_limits(node_factory, bitcoind):
l1, l2, l3, l4 = node_factory.get_nodes(4, opts=[{'dev-max-fee-multiplier': 5, 'may_reconnect': True, l1, l2, l3, l4 = node_factory.get_nodes(4, opts=[{'dev-max-fee-multiplier': 5, 'may_reconnect': True,
'allow_warning': True}, 'allow_warning': True},
@ -2070,7 +2070,7 @@ def test_fee_limits(node_factory, bitcoind):
l1.rpc.close(chan) l1.rpc.close(chan)
@unittest.skipIf(not DEVELOPER, "needs dev-no-fake-fees") @pytest.mark.developer("needs dev-no-fake-fees")
def test_update_fee_dynamic(node_factory, bitcoind): def test_update_fee_dynamic(node_factory, bitcoind):
# l1 has no fee estimates to start. # l1 has no fee estimates to start.
l1 = node_factory.get_node(options={'log-level': 'io', l1 = node_factory.get_node(options={'log-level': 'io',
@ -2121,7 +2121,7 @@ def test_update_fee_dynamic(node_factory, bitcoind):
l2.daemon.wait_for_log('peer_in.*UPDATE_FEE') l2.daemon.wait_for_log('peer_in.*UPDATE_FEE')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_update_fee_reconnect(node_factory, bitcoind): def test_update_fee_reconnect(node_factory, bitcoind):
# Disconnect after commitsig for fee update. # Disconnect after commitsig for fee update.
disconnects = ['+WIRE_COMMITMENT_SIGNED*3'] disconnects = ['+WIRE_COMMITMENT_SIGNED*3']
@ -2170,7 +2170,7 @@ def test_update_fee_reconnect(node_factory, bitcoind):
l2.daemon.wait_for_log('onchaind complete, forgetting peer') l2.daemon.wait_for_log('onchaind complete, forgetting peer')
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-bitcoind-poll") @pytest.mark.developer("Too slow without --dev-bitcoind-poll")
def test_multiple_channels(node_factory): def test_multiple_channels(node_factory):
l1 = node_factory.get_node() l1 = node_factory.get_node()
l2 = node_factory.get_node() l2 = node_factory.get_node()
@ -2200,7 +2200,7 @@ def test_multiple_channels(node_factory):
assert channels[-1]['state'] == 'CLOSINGD_COMPLETE' assert channels[-1]['state'] == 'CLOSINGD_COMPLETE'
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer
def test_forget_channel(node_factory): def test_forget_channel(node_factory):
l1 = node_factory.get_node() l1 = node_factory.get_node()
l2 = node_factory.get_node() l2 = node_factory.get_node()
@ -2319,7 +2319,7 @@ def test_disconnectpeer(node_factory, bitcoind):
l1.rpc.disconnect(l3.info['id']) l1.rpc.disconnect(l3.info['id'])
@unittest.skipIf(not DEVELOPER, "needs --dev-max-funding-unconfirmed-blocks") @pytest.mark.developer("needs --dev-max-funding-unconfirmed-blocks")
def test_fundee_forget_funding_tx_unconfirmed(node_factory, bitcoind): def test_fundee_forget_funding_tx_unconfirmed(node_factory, bitcoind):
"""Test that fundee will forget the channel if """Test that fundee will forget the channel if
the funding tx has been unconfirmed for too long. the funding tx has been unconfirmed for too long.
@ -2362,7 +2362,7 @@ def test_fundee_forget_funding_tx_unconfirmed(node_factory, bitcoind):
assert len(l2.rpc.listpeers(l1.info['id'])['peers']) == 0 assert len(l2.rpc.listpeers(l1.info['id'])['peers']) == 0
@unittest.skipIf(not DEVELOPER, "needs dev_fail") @pytest.mark.developer("needs dev_fail")
def test_no_fee_estimate(node_factory, bitcoind, executor): def test_no_fee_estimate(node_factory, bitcoind, executor):
l1 = node_factory.get_node(start=False, options={'dev-no-fake-fees': True}) l1 = node_factory.get_node(start=False, options={'dev-no-fake-fees': True})
@ -2454,7 +2454,7 @@ def test_no_fee_estimate(node_factory, bitcoind, executor):
l1.rpc.withdraw(l2.rpc.newaddr()['bech32'], 'all', 'urgent', minconf=0) l1.rpc.withdraw(l2.rpc.newaddr()['bech32'], 'all', 'urgent', minconf=0)
@unittest.skipIf(not DEVELOPER, "needs --dev-disconnect") @pytest.mark.developer("needs --dev-disconnect")
def test_opener_feerate_reconnect(node_factory, bitcoind): def test_opener_feerate_reconnect(node_factory, bitcoind):
# l1 updates fees, then reconnect so l2 retransmits commitment_signed. # l1 updates fees, then reconnect so l2 retransmits commitment_signed.
disconnects = ['-WIRE_COMMITMENT_SIGNED*3'] disconnects = ['-WIRE_COMMITMENT_SIGNED*3']
@ -2498,7 +2498,7 @@ def test_opener_simple_reconnect(node_factory, bitcoind):
@unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "sqlite3-specific DB rollback") @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "sqlite3-specific DB rollback")
@unittest.skipIf(not DEVELOPER, "needs LIGHTNINGD_DEV_LOG_IO") @pytest.mark.developer("needs LIGHTNINGD_DEV_LOG_IO")
def test_dataloss_protection(node_factory, bitcoind): def test_dataloss_protection(node_factory, bitcoind):
l1 = node_factory.get_node(may_reconnect=True, options={'log-level': 'io'}, l1 = node_factory.get_node(may_reconnect=True, options={'log-level': 'io'},
feerates=(7500, 7500, 7500, 7500)) feerates=(7500, 7500, 7500, 7500))
@ -2594,7 +2594,7 @@ def test_dataloss_protection(node_factory, bitcoind):
assert (closetxid, "confirmed") in set([(o['txid'], o['status']) for o in l2.rpc.listfunds()['outputs']]) assert (closetxid, "confirmed") in set([(o['txid'], o['status']) for o in l2.rpc.listfunds()['outputs']])
@unittest.skipIf(not DEVELOPER, "needs dev_disconnect") @pytest.mark.developer("needs dev_disconnect")
def test_restart_multi_htlc_rexmit(node_factory, bitcoind, executor): def test_restart_multi_htlc_rexmit(node_factory, bitcoind, executor):
# l1 disables commit timer once we send first htlc, dies on commit # l1 disables commit timer once we send first htlc, dies on commit
disconnects = ['=WIRE_UPDATE_ADD_HTLC-nocommit', disconnects = ['=WIRE_UPDATE_ADD_HTLC-nocommit',
@ -2621,7 +2621,7 @@ def test_restart_multi_htlc_rexmit(node_factory, bitcoind, executor):
wait_for(lambda: [p['status'] for p in l1.rpc.listsendpays()['payments']] == ['complete', 'complete']) wait_for(lambda: [p['status'] for p in l1.rpc.listsendpays()['payments']] == ['complete', 'complete'])
@unittest.skipIf(not DEVELOPER, "needs dev-disconnect") @pytest.mark.developer("needs dev_disconnect")
def test_fulfill_incoming_first(node_factory, bitcoind): def test_fulfill_incoming_first(node_factory, bitcoind):
"""Test that we handle the case where we completely resolve incoming htlc """Test that we handle the case where we completely resolve incoming htlc
before fulfilled outgoing htlc""" before fulfilled outgoing htlc"""
@ -2664,7 +2664,7 @@ def test_fulfill_incoming_first(node_factory, bitcoind):
l3.daemon.wait_for_log('onchaind complete, forgetting peer') l3.daemon.wait_for_log('onchaind complete, forgetting peer')
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_restart_many_payments(node_factory, bitcoind): def test_restart_many_payments(node_factory, bitcoind):
l1 = node_factory.get_node(may_reconnect=True) l1 = node_factory.get_node(may_reconnect=True)
@ -2757,7 +2757,7 @@ def test_restart_many_payments(node_factory, bitcoind):
wait_for(lambda: 'pending' not in [p['status'] for p in n.rpc.listsendpays()['payments']]) wait_for(lambda: 'pending' not in [p['status'] for p in n.rpc.listsendpays()['payments']])
@unittest.skipIf(not DEVELOPER, "need dev-disconnect") @pytest.mark.developer("need dev-disconnect")
def test_fail_unconfirmed(node_factory, bitcoind, executor): def test_fail_unconfirmed(node_factory, bitcoind, executor):
"""Test that if we crash with an unconfirmed connection to a known """Test that if we crash with an unconfirmed connection to a known
peer, we don't have a dangling peer in db""" peer, we don't have a dangling peer in db"""
@ -2810,7 +2810,7 @@ def test_fail_unconfirmed(node_factory, bitcoind, executor):
l1.fundchannel(l2, 200000, wait_for_active=True) l1.fundchannel(l2, 200000, wait_for_active=True)
@unittest.skipIf(not DEVELOPER, "need dev-disconnect") @pytest.mark.developer("need dev-disconnect")
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
def test_fail_unconfirmed_openchannel2(node_factory, bitcoind, executor): def test_fail_unconfirmed_openchannel2(node_factory, bitcoind, executor):
"""Test that if we crash with an unconfirmed connection to a known """Test that if we crash with an unconfirmed connection to a known
@ -2911,7 +2911,7 @@ def test_feerate_spam(node_factory, chainparams):
l1.daemon.wait_for_log('peer_out WIRE_UPDATE_FEE', timeout=5) l1.daemon.wait_for_log('peer_out WIRE_UPDATE_FEE', timeout=5)
@unittest.skipIf(not DEVELOPER, "need dev-feerate") @pytest.mark.developer("need dev-feerate")
def test_feerate_stress(node_factory, executor): def test_feerate_stress(node_factory, executor):
# Third node makes HTLC traffic less predictable. # Third node makes HTLC traffic less predictable.
l1, l2, l3 = node_factory.line_graph(3, opts={'commit-time': 100, l1, l2, l3 = node_factory.line_graph(3, opts={'commit-time': 100,
@ -2962,7 +2962,7 @@ def test_feerate_stress(node_factory, executor):
assert not l2.daemon.is_in_log('Bad.*signature') assert not l2.daemon.is_in_log('Bad.*signature')
@unittest.skipIf(not DEVELOPER, "need dev_disconnect") @pytest.mark.developer("need dev_disconnect")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_pay_disconnect_stress(node_factory, executor): def test_pay_disconnect_stress(node_factory, executor):
"""Expose race in htlc restoration in channeld: 50% chance of failure""" """Expose race in htlc restoration in channeld: 50% chance of failure"""
@ -3093,7 +3093,7 @@ def test_channel_features(node_factory, bitcoind):
assert only_one(only_one(l2.rpc.listpeers()['peers'])['channels'])['features'] == chan['features'] assert only_one(only_one(l2.rpc.listpeers()['peers'])['channels'])['features'] == chan['features']
@unittest.skipIf(not DEVELOPER, "need dev-force-features") @pytest.mark.developer("need dev-force-features")
def test_nonstatic_channel(node_factory, bitcoind): def test_nonstatic_channel(node_factory, bitcoind):
"""Smoke test for a channel without option_static_remotekey""" """Smoke test for a channel without option_static_remotekey"""
l1, l2 = node_factory.line_graph(2, l1, l2 = node_factory.line_graph(2,
@ -3107,7 +3107,7 @@ def test_nonstatic_channel(node_factory, bitcoind):
l1.rpc.close(l2.info['id']) l1.rpc.close(l2.info['id'])
@unittest.skipIf(not DEVELOPER, "needs --dev-timeout-secs") @pytest.mark.developer("need --dev-timeout-secs")
def test_connection_timeout(node_factory): def test_connection_timeout(node_factory):
# l1 hears nothing back after sending INIT, should time out. # l1 hears nothing back after sending INIT, should time out.
l1, l2 = node_factory.get_nodes(2, l1, l2 = node_factory.get_nodes(2,
@ -3124,7 +3124,7 @@ def test_connection_timeout(node_factory):
l1.daemon.wait_for_log('conn timed out') l1.daemon.wait_for_log('conn timed out')
@unittest.skipIf(not DEVELOPER, "needs --dev-disconnect") @pytest.mark.developer("needs --dev-disconnect")
def test_htlc_retransmit_order(node_factory, executor): def test_htlc_retransmit_order(node_factory, executor):
NUM_HTLCS = 10 NUM_HTLCS = 10
l1, l2 = node_factory.line_graph(2, l1, l2 = node_factory.line_graph(2,

View File

@ -4,7 +4,7 @@ from fixtures import * # noqa: F401,F403
from fixtures import TEST_NETWORK from fixtures import TEST_NETWORK
from pyln.client import RpcError, Millisatoshi from pyln.client import RpcError, Millisatoshi
from utils import ( from utils import (
wait_for, TIMEOUT, only_one, sync_blockheight, expected_node_features, COMPAT DEVELOPER, wait_for, TIMEOUT, only_one, sync_blockheight, expected_node_features, COMPAT
) )
import json import json
@ -22,10 +22,8 @@ import socket
with open('config.vars') as configfile: with open('config.vars') as configfile:
config = dict([(line.rstrip().split('=', 1)) for line in configfile]) config = dict([(line.rstrip().split('=', 1)) for line in configfile])
DEVELOPER = os.getenv("DEVELOPER", config['DEVELOPER']) == "1"
@pytest.mark.developer("needs --dev-fast-gossip-prune")
@unittest.skipIf(not DEVELOPER, "needs --dev-fast-gossip-prune")
def test_gossip_pruning(node_factory, bitcoind): def test_gossip_pruning(node_factory, bitcoind):
""" Create channel and see it being updated in time before pruning """ Create channel and see it being updated in time before pruning
""" """
@ -70,7 +68,7 @@ def test_gossip_pruning(node_factory, bitcoind):
assert l1.info['id'] not in [n['nodeid'] for n in l3.rpc.listnodes()['nodes']] assert l1.info['id'] not in [n['nodeid'] for n in l3.rpc.listnodes()['nodes']]
@unittest.skipIf(not DEVELOPER, "needs --dev-fast-gossip, --dev-no-reconnect") @pytest.mark.developer("needs --dev-fast-gossip, --dev-no-reconnect")
def test_gossip_disable_channels(node_factory, bitcoind): def test_gossip_disable_channels(node_factory, bitcoind):
"""Simple test to check that channels get disabled correctly on disconnect and """Simple test to check that channels get disabled correctly on disconnect and
reenabled upon reconnecting reenabled upon reconnecting
@ -106,7 +104,7 @@ def test_gossip_disable_channels(node_factory, bitcoind):
wait_for(lambda: count_active(l2) == 2) wait_for(lambda: count_active(l2) == 2)
@unittest.skipIf(not DEVELOPER, "needs --dev-allow-localhost") @pytest.mark.developer("needs --dev-allow-localhost")
def test_announce_address(node_factory, bitcoind): def test_announce_address(node_factory, bitcoind):
"""Make sure our announcements are well formed.""" """Make sure our announcements are well formed."""
@ -137,7 +135,7 @@ def test_announce_address(node_factory, bitcoind):
"04e00533f3e8f2aedaa8969b3d0fa03a96e857bbb28064dca5e147e934244b9ba50230032607") "04e00533f3e8f2aedaa8969b3d0fa03a96e857bbb28064dca5e147e934244b9ba50230032607")
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_gossip_timestamp_filter(node_factory, bitcoind): def test_gossip_timestamp_filter(node_factory, bitcoind):
# Updates get backdated 5 seconds with --dev-fast-gossip. # Updates get backdated 5 seconds with --dev-fast-gossip.
backdate = 5 backdate = 5
@ -211,7 +209,7 @@ def test_gossip_timestamp_filter(node_factory, bitcoind):
assert types['0102'] == 2 assert types['0102'] == 2
@unittest.skipIf(not DEVELOPER, "needs --dev-allow-localhost") @pytest.mark.developer("needs --dev-allow-localhost")
def test_connect_by_gossip(node_factory, bitcoind): def test_connect_by_gossip(node_factory, bitcoind):
"""Test connecting to an unknown peer using node gossip """Test connecting to an unknown peer using node gossip
""" """
@ -253,7 +251,7 @@ def test_connect_by_gossip(node_factory, bitcoind):
assert ret['address'] == {'type': 'ipv4', 'address': '127.0.0.1', 'port': l3.port} assert ret['address'] == {'type': 'ipv4', 'address': '127.0.0.1', 'port': l3.port}
@unittest.skipIf(not DEVELOPER, "DEVELOPER=1 needed to speed up gossip propagation, would be too long otherwise") @pytest.mark.developer("DEVELOPER=1 needed to speed up gossip propagation, would be too long otherwise")
def test_gossip_jsonrpc(node_factory): def test_gossip_jsonrpc(node_factory):
l1, l2 = node_factory.line_graph(2, fundchannel=True, wait_for_announce=False) l1, l2 = node_factory.line_graph(2, fundchannel=True, wait_for_announce=False)
@ -326,7 +324,7 @@ def test_gossip_jsonrpc(node_factory):
assert [c['public'] for c in l2.rpc.listchannels()['channels']] == [True, True] assert [c['public'] for c in l2.rpc.listchannels()['channels']] == [True, True]
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip") @pytest.mark.developer("Too slow without --dev-fast-gossip")
def test_gossip_badsig(node_factory): def test_gossip_badsig(node_factory):
"""Make sure node announcement signatures are ok. """Make sure node announcement signatures are ok.
@ -384,7 +382,7 @@ def test_gossip_weirdalias(node_factory, bitcoind):
assert node['alias'] == weird_name assert node['alias'] == weird_name
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for --dev-no-reconnect") @pytest.mark.developer("needs DEVELOPER=1 for --dev-no-reconnect")
def test_gossip_persistence(node_factory, bitcoind): def test_gossip_persistence(node_factory, bitcoind):
"""Gossip for a while, restart and it should remember. """Gossip for a while, restart and it should remember.
@ -459,7 +457,7 @@ def test_gossip_persistence(node_factory, bitcoind):
wait_for(lambda: non_public(l4) == [scid34, scid34]) wait_for(lambda: non_public(l4) == [scid34, scid34])
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_routing_gossip_reconnect(node_factory): def test_routing_gossip_reconnect(node_factory):
# Connect two peers, reconnect and then see if we resume the # Connect two peers, reconnect and then see if we resume the
# gossip. # gossip.
@ -481,7 +479,7 @@ def test_routing_gossip_reconnect(node_factory):
wait_for(lambda: len(n.rpc.listchannels()['channels']) == 4) wait_for(lambda: len(n.rpc.listchannels()['channels']) == 4)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_gossip_no_empty_announcements(node_factory, bitcoind): def test_gossip_no_empty_announcements(node_factory, bitcoind):
# Need full IO logging so we can see gossip # Need full IO logging so we can see gossip
# l3 sends CHANNEL_ANNOUNCEMENT to l2, but not CHANNEL_UDPATE. # l3 sends CHANNEL_ANNOUNCEMENT to l2, but not CHANNEL_UDPATE.
@ -509,7 +507,7 @@ def test_gossip_no_empty_announcements(node_factory, bitcoind):
wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2) wait_for(lambda: len(l1.rpc.listchannels()['channels']) == 2)
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip") @pytest.mark.developer("Too slow without --dev-fast-gossip")
def test_routing_gossip(node_factory, bitcoind): def test_routing_gossip(node_factory, bitcoind):
nodes = node_factory.get_nodes(5) nodes = node_factory.get_nodes(5)
@ -550,7 +548,7 @@ def test_routing_gossip(node_factory, bitcoind):
wait_for(lambda: check_gossip(n)) wait_for(lambda: check_gossip(n))
@unittest.skipIf(not DEVELOPER, "needs dev-set-max-scids-encode-size") @pytest.mark.developer("needs dev-set-max-scids-encode-size")
def test_gossip_query_channel_range(node_factory, bitcoind, chainparams): def test_gossip_query_channel_range(node_factory, bitcoind, chainparams):
l1, l2, l3, l4 = node_factory.line_graph(4, fundchannel=False) l1, l2, l3, l4 = node_factory.line_graph(4, fundchannel=False)
genesis_blockhash = chainparams['chain_hash'] genesis_blockhash = chainparams['chain_hash']
@ -771,7 +769,7 @@ def test_gossip_query_channel_range(node_factory, bitcoind, chainparams):
# Long test involving 4 lightningd instances. # Long test involving 4 lightningd instances.
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_report_routing_failure(node_factory, bitcoind): def test_report_routing_failure(node_factory, bitcoind):
"""Test routing failure and retrying of routing. """Test routing failure and retrying of routing.
""" """
@ -825,7 +823,7 @@ def test_report_routing_failure(node_factory, bitcoind):
l1.rpc.pay(inv) l1.rpc.pay(inv)
@unittest.skipIf(not DEVELOPER, "needs fast gossip") @pytest.mark.developer("needs fast gossip")
def test_query_short_channel_id(node_factory, bitcoind, chainparams): def test_query_short_channel_id(node_factory, bitcoind, chainparams):
l1, l2, l3 = node_factory.get_nodes(3) l1, l2, l3 = node_factory.get_nodes(3)
l1.rpc.connect(l2.info['id'], 'localhost', l2.port) l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
@ -1028,7 +1026,7 @@ def test_gossip_store_load_amount_truncated(node_factory):
l1.rpc.call('dev-compact-gossip-store') l1.rpc.call('dev-compact-gossip-store')
@unittest.skipIf(not DEVELOPER, "Needs fast gossip propagation") @pytest.mark.developer("Needs fast gossip propagation")
def test_node_reannounce(node_factory, bitcoind): def test_node_reannounce(node_factory, bitcoind):
"Test that we reannounce a node when parameters change" "Test that we reannounce a node when parameters change"
l1, l2 = node_factory.line_graph(2, opts={'may_reconnect': True, l1, l2 = node_factory.line_graph(2, opts={'may_reconnect': True,
@ -1188,7 +1186,7 @@ def test_getroute_exclude_duplicate(node_factory):
assert route == route3 assert route == route3
@unittest.skipIf(not DEVELOPER, "gossip propagation is slow without DEVELOPER=1") @pytest.mark.developer("gossip propagation is slow without DEVELOPER=1")
def test_getroute_exclude(node_factory, bitcoind): def test_getroute_exclude(node_factory, bitcoind):
"""Test getroute's exclude argument""" """Test getroute's exclude argument"""
l1, l2, l3, l4, l5 = node_factory.get_nodes(5) l1, l2, l3, l4, l5 = node_factory.get_nodes(5)
@ -1279,7 +1277,7 @@ def test_getroute_exclude(node_factory, bitcoind):
l1.rpc.getroute(l4.info['id'], 1, 1, exclude=[chan_l2l3, l5.info['id'], chan_l2l4]) l1.rpc.getroute(l4.info['id'], 1, 1, exclude=[chan_l2l3, l5.info['id'], chan_l2l4])
@unittest.skipIf(not DEVELOPER, "need dev-compact-gossip-store") @pytest.mark.developer("need dev-compact-gossip-store")
def test_gossip_store_local_channels(node_factory, bitcoind): def test_gossip_store_local_channels(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, wait_for_announce=False) l1, l2 = node_factory.line_graph(2, wait_for_announce=False)
@ -1304,7 +1302,7 @@ def test_gossip_store_local_channels(node_factory, bitcoind):
assert len(chans) == 2 assert len(chans) == 2
@unittest.skipIf(not DEVELOPER, "need dev-compact-gossip-store") @pytest.mark.developer("need dev-compact-gossip-store")
def test_gossip_store_private_channels(node_factory, bitcoind): def test_gossip_store_private_channels(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, announce_channels=False) l1, l2 = node_factory.line_graph(2, announce_channels=False)
@ -1379,7 +1377,7 @@ def setup_gossip_store_test(node_factory, bitcoind):
return l2 return l2
@unittest.skipIf(not DEVELOPER, "need dev-compact-gossip-store") @pytest.mark.developer("need dev-compact-gossip-store")
def test_gossip_store_compact_noappend(node_factory, bitcoind): def test_gossip_store_compact_noappend(node_factory, bitcoind):
l2 = setup_gossip_store_test(node_factory, bitcoind) l2 = setup_gossip_store_test(node_factory, bitcoind)
@ -1393,7 +1391,7 @@ def test_gossip_store_compact_noappend(node_factory, bitcoind):
assert not l2.daemon.is_in_log('gossip_store:.*truncate') assert not l2.daemon.is_in_log('gossip_store:.*truncate')
@unittest.skipIf(not DEVELOPER, "updates are delayed without --dev-fast-gossip") @pytest.mark.developer("updates are delayed without --dev-fast-gossip")
def test_gossip_store_load_complex(node_factory, bitcoind): def test_gossip_store_load_complex(node_factory, bitcoind):
l2 = setup_gossip_store_test(node_factory, bitcoind) l2 = setup_gossip_store_test(node_factory, bitcoind)
@ -1402,7 +1400,7 @@ def test_gossip_store_load_complex(node_factory, bitcoind):
wait_for(lambda: l2.daemon.is_in_log('gossip_store: Read ')) wait_for(lambda: l2.daemon.is_in_log('gossip_store: Read '))
@unittest.skipIf(not DEVELOPER, "need dev-compact-gossip-store") @pytest.mark.developer("need dev-compact-gossip-store")
def test_gossip_store_compact(node_factory, bitcoind): def test_gossip_store_compact(node_factory, bitcoind):
l2 = setup_gossip_store_test(node_factory, bitcoind) l2 = setup_gossip_store_test(node_factory, bitcoind)
@ -1418,7 +1416,7 @@ def test_gossip_store_compact(node_factory, bitcoind):
wait_for(lambda: l2.daemon.is_in_log('gossip_store: Read ')) wait_for(lambda: l2.daemon.is_in_log('gossip_store: Read '))
@unittest.skipIf(not DEVELOPER, "need dev-compact-gossip-store") @pytest.mark.developer("need dev-compact-gossip-store")
def test_gossip_store_compact_restart(node_factory, bitcoind): def test_gossip_store_compact_restart(node_factory, bitcoind):
l2 = setup_gossip_store_test(node_factory, bitcoind) l2 = setup_gossip_store_test(node_factory, bitcoind)
@ -1430,7 +1428,7 @@ def test_gossip_store_compact_restart(node_factory, bitcoind):
l2.rpc.call('dev-compact-gossip-store') l2.rpc.call('dev-compact-gossip-store')
@unittest.skipIf(not DEVELOPER, "need dev-compact-gossip-store") @pytest.mark.developer("need dev-compact-gossip-store")
def test_gossip_store_load_no_channel_update(node_factory): def test_gossip_store_load_no_channel_update(node_factory):
"""Make sure we can read truncated gossip store with a channel_announcement and no channel_update""" """Make sure we can read truncated gossip store with a channel_announcement and no channel_update"""
l1 = node_factory.get_node(start=False, allow_broken_log=True) l1 = node_factory.get_node(start=False, allow_broken_log=True)
@ -1467,7 +1465,7 @@ def test_gossip_store_load_no_channel_update(node_factory):
assert bytearray(f.read()) == bytearray.fromhex("09") assert bytearray(f.read()) == bytearray.fromhex("09")
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_gossip_store_compact_on_load(node_factory, bitcoind): def test_gossip_store_compact_on_load(node_factory, bitcoind):
l2 = setup_gossip_store_test(node_factory, bitcoind) l2 = setup_gossip_store_test(node_factory, bitcoind)
@ -1536,7 +1534,7 @@ def test_gossip_announce_unknown_block(node_factory, bitcoind):
sync_blockheight(bitcoind, [l1]) sync_blockheight(bitcoind, [l1])
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_gossip_no_backtalk(node_factory): def test_gossip_no_backtalk(node_factory):
# l3 connects, gets gossip, but should *not* play it back. # l3 connects, gets gossip, but should *not* play it back.
l1, l2, l3 = node_factory.get_nodes(3, l1, l2, l3 = node_factory.get_nodes(3,
@ -1554,7 +1552,7 @@ def test_gossip_no_backtalk(node_factory):
assert not l3.daemon.is_in_log(r'\[OUT\] 0100') assert not l3.daemon.is_in_log(r'\[OUT\] 0100')
@unittest.skipIf(not DEVELOPER, "Needs --dev-gossip") @pytest.mark.developer("Needs --dev-gossip")
@unittest.skipIf( @unittest.skipIf(
TEST_NETWORK != 'regtest', TEST_NETWORK != 'regtest',
"Channel announcement contains genesis hash, receiving node discards on mismatch" "Channel announcement contains genesis hash, receiving node discards on mismatch"
@ -1662,7 +1660,7 @@ def check_socket(ip_addr, port):
return not result return not result
@unittest.skipIf(not DEVELOPER, "needs a running Tor service instance at port 9151 or 9051") @pytest.mark.developer("needs a running Tor service instance at port 9151 or 9051")
def test_statictor_onions(node_factory): def test_statictor_onions(node_factory):
"""First basic tests ;-) """First basic tests ;-)
@ -1695,7 +1693,7 @@ def test_statictor_onions(node_factory):
assert l2.daemon.is_in_log('x2y4zvh4fn5q3eouuh7nxnc7zeawrqoutljrup2xjtiyxgx3emgkemad.onion:9735,127.0.0.1:{}'.format(l2.port)) assert l2.daemon.is_in_log('x2y4zvh4fn5q3eouuh7nxnc7zeawrqoutljrup2xjtiyxgx3emgkemad.onion:9735,127.0.0.1:{}'.format(l2.port))
@unittest.skipIf(not DEVELOPER, "needs a running Tor service instance at port 9151 or 9051") @pytest.mark.developer("needs a running Tor service instance at port 9151 or 9051")
def test_torport_onions(node_factory): def test_torport_onions(node_factory):
"""First basic tests for torport ;-) """First basic tests for torport ;-)
@ -1794,7 +1792,7 @@ def test_gossip_store_upgrade_v7_v8(node_factory):
'features': '80000000000000000000000000'}] 'features': '80000000000000000000000000'}]
@unittest.skipIf(not DEVELOPER, "devtools are for devs anyway") @pytest.mark.developer("devtools are for devs anyway")
def test_routetool(node_factory): def test_routetool(node_factory):
"""Test that route tool can see unpublished channels""" """Test that route tool can see unpublished channels"""
l1, l2 = node_factory.line_graph(2) l1, l2 = node_factory.line_graph(2)

View File

@ -1,7 +1,7 @@
from fixtures import * # noqa: F401,F403 from fixtures import * # noqa: F401,F403
from fixtures import TEST_NETWORK from fixtures import TEST_NETWORK
from pyln.client import RpcError, Millisatoshi from pyln.client import RpcError, Millisatoshi
from utils import only_one, DEVELOPER, wait_for, wait_channel_quiescent from utils import only_one, wait_for, wait_channel_quiescent
import pytest import pytest
@ -149,7 +149,7 @@ def test_invoice_preimage(node_factory):
l2.rpc.invoice(123456, 'inv2', '?', preimage=invoice_preimage) l2.rpc.invoice(123456, 'inv2', '?', preimage=invoice_preimage)
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
@unittest.skipIf(TEST_NETWORK != 'regtest', "Amounts too low, dominated by fees in elements") @unittest.skipIf(TEST_NETWORK != 'regtest', "Amounts too low, dominated by fees in elements")
def test_invoice_routeboost(node_factory, bitcoind): def test_invoice_routeboost(node_factory, bitcoind):
"""Test routeboost 'r' hint in bolt11 invoice. """Test routeboost 'r' hint in bolt11 invoice.
@ -205,7 +205,7 @@ def test_invoice_routeboost(node_factory, bitcoind):
assert 'warning_offline' not in inv assert 'warning_offline' not in inv
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_invoice_routeboost_private(node_factory, bitcoind): def test_invoice_routeboost_private(node_factory, bitcoind):
"""Test routeboost 'r' hint in bolt11 invoice for private channels """Test routeboost 'r' hint in bolt11 invoice for private channels
""" """
@ -445,7 +445,7 @@ def test_invoice_expiry(node_factory, executor):
assert expiry >= start + 7 * 24 * 3600 and expiry <= end + 7 * 24 * 3600 assert expiry >= start + 7 * 24 * 3600 and expiry <= end + 7 * 24 * 3600
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip") @pytest.mark.developer("Too slow without --dev-fast-gossip")
def test_waitinvoice(node_factory, executor): def test_waitinvoice(node_factory, executor):
"""Test waiting for one invoice will not return if another invoice is paid. """Test waiting for one invoice will not return if another invoice is paid.
""" """
@ -481,7 +481,7 @@ def test_waitinvoice(node_factory, executor):
assert not f3.done() assert not f3.done()
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip") @pytest.mark.developer("Too slow without --dev-fast-gossip")
def test_waitanyinvoice(node_factory, executor): def test_waitanyinvoice(node_factory, executor):
"""Test various variants of waiting for the next invoice to complete. """Test various variants of waiting for the next invoice to complete.
""" """

View File

@ -27,7 +27,7 @@ import time
import unittest import unittest
@unittest.skipIf(not DEVELOPER, "needs --dev-disconnect") @pytest.mark.developer("needs --dev-disconnect")
def test_stop_pending_fundchannel(node_factory, executor): def test_stop_pending_fundchannel(node_factory, executor):
"""Stop the daemon while waiting for an accept_channel """Stop the daemon while waiting for an accept_channel
@ -290,7 +290,7 @@ def test_ping(node_factory):
.format(l2.info['version'])) .format(l2.info['version']))
@unittest.skipIf(not DEVELOPER, "needs --dev-disconnect") @pytest.mark.developer("needs --dev-disconnect")
def test_htlc_sig_persistence(node_factory, bitcoind, executor): def test_htlc_sig_persistence(node_factory, bitcoind, executor):
"""Interrupt a payment between two peers, then fail and recover funds using the HTLC sig. """Interrupt a payment between two peers, then fail and recover funds using the HTLC sig.
""" """
@ -338,7 +338,7 @@ def test_htlc_sig_persistence(node_factory, bitcoind, executor):
assert len(l1.rpc.listfunds()['outputs']) == 3 assert len(l1.rpc.listfunds()['outputs']) == 3
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_htlc_out_timeout(node_factory, bitcoind, executor): def test_htlc_out_timeout(node_factory, bitcoind, executor):
"""Test that we drop onchain if the peer doesn't time out HTLC""" """Test that we drop onchain if the peer doesn't time out HTLC"""
@ -405,7 +405,7 @@ def test_htlc_out_timeout(node_factory, bitcoind, executor):
l2.daemon.wait_for_log('onchaind complete, forgetting peer') l2.daemon.wait_for_log('onchaind complete, forgetting peer')
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_htlc_in_timeout(node_factory, bitcoind, executor): def test_htlc_in_timeout(node_factory, bitcoind, executor):
"""Test that we drop onchain if the peer doesn't accept fulfilled HTLC""" """Test that we drop onchain if the peer doesn't accept fulfilled HTLC"""
@ -465,7 +465,7 @@ def test_htlc_in_timeout(node_factory, bitcoind, executor):
@unittest.skipIf(not TEST_NETWORK == 'regtest', 'must be on bitcoin network') @unittest.skipIf(not TEST_NETWORK == 'regtest', 'must be on bitcoin network')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_bech32_funding(node_factory, chainparams): def test_bech32_funding(node_factory, chainparams):
# Don't get any funds from previous runs. # Don't get any funds from previous runs.
l1, l2 = node_factory.line_graph(2, opts={'random_hsm': True}, fundchannel=False) l1, l2 = node_factory.line_graph(2, opts={'random_hsm': True}, fundchannel=False)
@ -863,7 +863,7 @@ def test_multirpc(node_factory):
sock.close() sock.close()
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_multiplexed_rpc(node_factory): def test_multiplexed_rpc(node_factory):
"""Test that we can do multiple RPCs which exit in different orders""" """Test that we can do multiple RPCs which exit in different orders"""
l1 = node_factory.get_node() l1 = node_factory.get_node()
@ -1105,7 +1105,7 @@ def test_daemon_option(node_factory):
@flaky @flaky
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_blockchaintrack(node_factory, bitcoind): def test_blockchaintrack(node_factory, bitcoind):
"""Check that we track the blockchain correctly across reorgs """Check that we track the blockchain correctly across reorgs
""" """
@ -1150,7 +1150,7 @@ def test_blockchaintrack(node_factory, bitcoind):
assert [o for o in l1.rpc.listfunds()['outputs'] if o['status'] != "unconfirmed"] == [] assert [o for o in l1.rpc.listfunds()['outputs'] if o['status'] != "unconfirmed"] == []
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_funding_reorg_private(node_factory, bitcoind): def test_funding_reorg_private(node_factory, bitcoind):
"""Change funding tx height after lockin, between node restart. """Change funding tx height after lockin, between node restart.
""" """
@ -1191,7 +1191,7 @@ def test_funding_reorg_private(node_factory, bitcoind):
l2.daemon.wait_for_log(r'Deleting channel') l2.daemon.wait_for_log(r'Deleting channel')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_funding_reorg_remote_lags(node_factory, bitcoind): def test_funding_reorg_remote_lags(node_factory, bitcoind):
"""Nodes may disagree about short_channel_id before channel announcement """Nodes may disagree about short_channel_id before channel announcement
""" """
@ -1363,7 +1363,7 @@ def test_reserve_enforcement(node_factory, executor):
assert only_one(l1.rpc.listpeers()['peers'])['connected'] is False assert only_one(l1.rpc.listpeers()['peers'])['connected'] is False
@unittest.skipIf(not DEVELOPER, "needs dev_disconnect") @pytest.mark.developer("needs dev_disconnect")
def test_htlc_send_timeout(node_factory, bitcoind, compat): def test_htlc_send_timeout(node_factory, bitcoind, compat):
"""Test that we don't commit an HTLC to an unreachable node.""" """Test that we don't commit an HTLC to an unreachable node."""
# Feerates identical so we don't get gratuitous commit to update them # Feerates identical so we don't get gratuitous commit to update them
@ -1682,7 +1682,7 @@ def test_check_command(node_factory):
sock.close() sock.close()
@unittest.skipIf(not DEVELOPER, "FIXME: without DEVELOPER=1 we timeout") @pytest.mark.developer("FIXME: without DEVELOPER=1 we timeout")
def test_bad_onion(node_factory, bitcoind): def test_bad_onion(node_factory, bitcoind):
"""Test that we get a reasonable error from sendpay when an onion is bad""" """Test that we get a reasonable error from sendpay when an onion is bad"""
l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True, l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True,
@ -1733,7 +1733,7 @@ def test_bad_onion(node_factory, bitcoind):
assert err.value.error['data']['erring_channel'] == route[1]['channel'] assert err.value.error['data']['erring_channel'] == route[1]['channel']
@unittest.skipIf(not DEVELOPER, "Needs DEVELOPER=1 to force onion fail") @pytest.mark.developer("Needs DEVELOPER=1 to force onion fail")
def test_bad_onion_immediate_peer(node_factory, bitcoind): def test_bad_onion_immediate_peer(node_factory, bitcoind):
"""Test that we handle the malformed msg when we're the origin""" """Test that we handle the malformed msg when we're the origin"""
l1, l2 = node_factory.line_graph(2, opts={'dev-fail-process-onionpacket': None}) l1, l2 = node_factory.line_graph(2, opts={'dev-fail-process-onionpacket': None})
@ -1802,7 +1802,7 @@ def test_bitcoind_fail_first(node_factory, bitcoind, executor):
f.result() f.result()
@unittest.skipIf(not DEVELOPER, "needs --dev-force-bip32-seed") @pytest.mark.developer("needs --dev-force-bip32-seed")
@unittest.skipIf(TEST_NETWORK != 'regtest', "Addresses are network specific") @unittest.skipIf(TEST_NETWORK != 'regtest', "Addresses are network specific")
def test_dev_force_bip32_seed(node_factory): def test_dev_force_bip32_seed(node_factory):
l1 = node_factory.get_node(options={'dev-force-bip32-seed': '0000000000000000000000000000000000000000000000000000000000000001'}) l1 = node_factory.get_node(options={'dev-force-bip32-seed': '0000000000000000000000000000000000000000000000000000000000000001'})
@ -1819,7 +1819,7 @@ def test_dev_force_bip32_seed(node_factory):
assert bech32 == "bcrt1q622lwmdzxxterumd746eu3d3t40pq53p62zhlz" assert bech32 == "bcrt1q622lwmdzxxterumd746eu3d3t40pq53p62zhlz"
@unittest.skipIf(not DEVELOPER, "needs dev command") @pytest.mark.developer("needs dev command")
def test_dev_demux(node_factory): def test_dev_demux(node_factory):
l1 = node_factory.get_node(may_fail=True, allow_broken_log=True) l1 = node_factory.get_node(may_fail=True, allow_broken_log=True)
@ -2221,7 +2221,7 @@ def test_waitblockheight(node_factory, executor, bitcoind):
fut2.result(5) fut2.result(5)
@unittest.skipIf(not DEVELOPER, "Needs dev-sendcustommsg") @pytest.mark.developer("Needs dev-sendcustommsg")
def test_sendcustommsg(node_factory): def test_sendcustommsg(node_factory):
"""Check that we can send custommsgs to peers in various states. """Check that we can send custommsgs to peers in various states.
@ -2366,7 +2366,7 @@ def test_sendonionmessage_reply(node_factory):
assert l1.daemon.wait_for_log('Got onionmsg') assert l1.daemon.wait_for_log('Got onionmsg')
@unittest.skipIf(not DEVELOPER, "needs --dev-force-privkey") @pytest.mark.developer("needs --dev-force-privkey")
def test_getsharedsecret(node_factory): def test_getsharedsecret(node_factory):
""" """
Test getsharedsecret command. Test getsharedsecret command.

View File

@ -2,7 +2,7 @@ from fixtures import * # noqa: F401,F403
from fixtures import TEST_NETWORK from fixtures import TEST_NETWORK
from pyln.client import RpcError from pyln.client import RpcError
from utils import ( from utils import (
only_one, wait_for, sync_blockheight, DEVELOPER, first_channel_id only_one, wait_for, sync_blockheight, first_channel_id
) )
import pytest import pytest
@ -16,7 +16,7 @@ def find_next_feerate(node, peer):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@unittest.skipIf(not DEVELOPER, "uses dev-disconnect") @pytest.mark.developer("uses dev-disconnect")
def test_multifunding_v2_best_effort(node_factory, bitcoind): def test_multifunding_v2_best_effort(node_factory, bitcoind):
''' '''
Check that best_effort flag works. Check that best_effort flag works.
@ -100,7 +100,7 @@ def test_multifunding_v2_best_effort(node_factory, bitcoind):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@unittest.skipIf(not DEVELOPER, "uses dev-disconnect") @pytest.mark.developer("uses dev-disconnect")
def test_v2_open_sigs_restart(node_factory, bitcoind): def test_v2_open_sigs_restart(node_factory, bitcoind):
disconnects_1 = ['-WIRE_TX_SIGNATURES'] disconnects_1 = ['-WIRE_TX_SIGNATURES']
disconnects_2 = ['+WIRE_TX_SIGNATURES'] disconnects_2 = ['+WIRE_TX_SIGNATURES']
@ -146,7 +146,7 @@ def test_v2_open_sigs_restart(node_factory, bitcoind):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@unittest.skipIf(not DEVELOPER, "uses dev-disconnect") @pytest.mark.developer("uses dev-disconnect")
def test_v2_open_sigs_restart_while_dead(node_factory, bitcoind): def test_v2_open_sigs_restart_while_dead(node_factory, bitcoind):
# Same thing as above, except the transaction mines # Same thing as above, except the transaction mines
# while we're asleep # while we're asleep
@ -360,7 +360,7 @@ def test_v2_rbf_multi(node_factory, bitcoind, chainparams):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@unittest.skipIf(not DEVELOPER, "uses dev-disconnect") @pytest.mark.developer("uses dev-disconnect")
def test_rbf_reconnect_init(node_factory, bitcoind, chainparams): def test_rbf_reconnect_init(node_factory, bitcoind, chainparams):
disconnects = ['-WIRE_INIT_RBF', disconnects = ['-WIRE_INIT_RBF',
'@WIRE_INIT_RBF', '@WIRE_INIT_RBF',
@ -412,7 +412,7 @@ def test_rbf_reconnect_init(node_factory, bitcoind, chainparams):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@unittest.skipIf(not DEVELOPER, "uses dev-disconnect") @pytest.mark.developer("uses dev-disconnect")
def test_rbf_reconnect_ack(node_factory, bitcoind, chainparams): def test_rbf_reconnect_ack(node_factory, bitcoind, chainparams):
disconnects = ['-WIRE_ACK_RBF', disconnects = ['-WIRE_ACK_RBF',
'@WIRE_ACK_RBF', '@WIRE_ACK_RBF',
@ -464,7 +464,7 @@ def test_rbf_reconnect_ack(node_factory, bitcoind, chainparams):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@unittest.skipIf(not DEVELOPER, "uses dev-disconnect") @pytest.mark.developer("uses dev-disconnect")
def test_rbf_reconnect_tx_construct(node_factory, bitcoind, chainparams): def test_rbf_reconnect_tx_construct(node_factory, bitcoind, chainparams):
disconnects = ['=WIRE_TX_ADD_INPUT', # Initial funding succeeds disconnects = ['=WIRE_TX_ADD_INPUT', # Initial funding succeeds
'-WIRE_TX_ADD_INPUT', '-WIRE_TX_ADD_INPUT',
@ -532,7 +532,7 @@ def test_rbf_reconnect_tx_construct(node_factory, bitcoind, chainparams):
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need') @unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
@unittest.skipIf(not DEVELOPER, "uses dev-disconnect") @pytest.mark.developer("uses dev-disconnect")
def test_rbf_reconnect_tx_sigs(node_factory, bitcoind, chainparams): def test_rbf_reconnect_tx_sigs(node_factory, bitcoind, chainparams):
disconnects = ['=WIRE_TX_SIGNATURES', # Initial funding succeeds disconnects = ['=WIRE_TX_SIGNATURES', # Initial funding succeeds
'-WIRE_TX_SIGNATURES', # When we send tx-sigs, RBF '-WIRE_TX_SIGNATURES', # When we send tx-sigs, RBF

View File

@ -21,7 +21,7 @@ import time
import unittest import unittest
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_pay(node_factory): def test_pay(node_factory):
l1, l2 = node_factory.line_graph(2) l1, l2 = node_factory.line_graph(2)
@ -70,7 +70,7 @@ def test_pay(node_factory):
assert len(payments) == 1 and payments[0]['payment_preimage'] == preimage assert len(payments) == 1 and payments[0]['payment_preimage'] == preimage
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_pay_amounts(node_factory): def test_pay_amounts(node_factory):
l1, l2 = node_factory.line_graph(2) l1, l2 = node_factory.line_graph(2)
inv = l2.rpc.invoice(Millisatoshi("123sat"), 'test_pay_amounts', 'description')['bolt11'] inv = l2.rpc.invoice(Millisatoshi("123sat"), 'test_pay_amounts', 'description')['bolt11']
@ -87,7 +87,7 @@ def test_pay_amounts(node_factory):
assert invoice['amount_received_msat'] >= Millisatoshi(123000) assert invoice['amount_received_msat'] >= Millisatoshi(123000)
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_pay_limits(node_factory, compat): def test_pay_limits(node_factory, compat):
"""Test that we enforce fee max percentage and max delay""" """Test that we enforce fee max percentage and max delay"""
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True) l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True)
@ -134,7 +134,7 @@ def test_pay_limits(node_factory, compat):
assert status[0]['strategy'] == "Initial attempt" assert status[0]['strategy'] == "Initial attempt"
@unittest.skipIf(not DEVELOPER, "Gossip is too slow without developer") @pytest.mark.developer("Gossip is too slow without developer")
def test_pay_exclude_node(node_factory, bitcoind): def test_pay_exclude_node(node_factory, bitcoind):
"""Test excluding the node if there's the NODE-level error in the failure_code """Test excluding the node if there's the NODE-level error in the failure_code
""" """
@ -231,7 +231,7 @@ def test_pay0(node_factory):
l1.rpc.waitsendpay(rhash) l1.rpc.waitsendpay(rhash)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_pay_disconnect(node_factory, bitcoind): def test_pay_disconnect(node_factory, bitcoind):
"""If the remote node has disconnected, we fail payment, but can try again when it reconnects""" """If the remote node has disconnected, we fail payment, but can try again when it reconnects"""
l1, l2 = node_factory.line_graph(2, opts={'dev-max-fee-multiplier': 5, l1, l2 = node_factory.line_graph(2, opts={'dev-max-fee-multiplier': 5,
@ -281,7 +281,7 @@ def test_pay_disconnect(node_factory, bitcoind):
l1.daemon.wait_for_log('ONCHAIN') l1.daemon.wait_for_log('ONCHAIN')
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev_suppress_gossip") @pytest.mark.developer("needs DEVELOPER=1 for dev_suppress_gossip")
def test_pay_get_error_with_update(node_factory): def test_pay_get_error_with_update(node_factory):
"""We should process an update inside a temporary_channel_failure""" """We should process an update inside a temporary_channel_failure"""
l1, l2, l3 = node_factory.line_graph(3, opts={'log-level': 'io'}, fundchannel=True, wait_for_announce=True) l1, l2, l3 = node_factory.line_graph(3, opts={'log-level': 'io'}, fundchannel=True, wait_for_announce=True)
@ -310,7 +310,7 @@ def test_pay_get_error_with_update(node_factory):
wait_for(lambda: not l1.is_channel_active(chanid2)) wait_for(lambda: not l1.is_channel_active(chanid2))
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_pay_optional_args(node_factory, compat): def test_pay_optional_args(node_factory, compat):
l1, l2 = node_factory.line_graph(2) l1, l2 = node_factory.line_graph(2)
@ -338,7 +338,7 @@ def test_pay_optional_args(node_factory, compat):
assert len(l1.rpc.listsendpays()['payments']) == 3 assert len(l1.rpc.listsendpays()['payments']) == 3
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_payment_success_persistence(node_factory, bitcoind, executor): def test_payment_success_persistence(node_factory, bitcoind, executor):
# Start two nodes and open a channel.. die during payment. # Start two nodes and open a channel.. die during payment.
# Feerates identical so we don't get gratuitous commit to update them # Feerates identical so we don't get gratuitous commit to update them
@ -389,7 +389,7 @@ def test_payment_success_persistence(node_factory, bitcoind, executor):
assert l1.rpc.dev_rhash(preimage)['rhash'] == inv1['payment_hash'] assert l1.rpc.dev_rhash(preimage)['rhash'] == inv1['payment_hash']
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_payment_failed_persistence(node_factory, executor): def test_payment_failed_persistence(node_factory, executor):
# Start two nodes and open a channel.. die during payment. # Start two nodes and open a channel.. die during payment.
# Feerates identical so we don't get gratuitous commit to update them # Feerates identical so we don't get gratuitous commit to update them
@ -440,7 +440,7 @@ def test_payment_failed_persistence(node_factory, executor):
l1.rpc.pay(inv1['bolt11']) l1.rpc.pay(inv1['bolt11'])
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_payment_duplicate_uncommitted(node_factory, executor): def test_payment_duplicate_uncommitted(node_factory, executor):
# We want to test two payments at the same time, before we send commit # We want to test two payments at the same time, before we send commit
l1 = node_factory.get_node(disconnect=['=WIRE_UPDATE_ADD_HTLC-nocommit']) l1 = node_factory.get_node(disconnect=['=WIRE_UPDATE_ADD_HTLC-nocommit'])
@ -474,7 +474,7 @@ def test_payment_duplicate_uncommitted(node_factory, executor):
fut2.result(TIMEOUT) fut2.result(TIMEOUT)
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip") @pytest.mark.developer("Too slow without --dev-fast-gossip")
def test_pay_maxfee_shadow(node_factory): def test_pay_maxfee_shadow(node_factory):
"""Test that we respect maxfeepercent for shadow routing.""" """Test that we respect maxfeepercent for shadow routing."""
l1, l2, l3 = node_factory.line_graph(3, fundchannel=True, l1, l2, l3 = node_factory.line_graph(3, fundchannel=True,
@ -1011,7 +1011,7 @@ def test_decodepay(node_factory):
l1.rpc.decodepay('1111111') l1.rpc.decodepay('1111111')
@unittest.skipIf(not DEVELOPER, "Too slow without --dev-fast-gossip") @pytest.mark.developer("Too slow without --dev-fast-gossip")
def test_forward(node_factory, bitcoind): def test_forward(node_factory, bitcoind):
# Connect 1 -> 2 -> 3. # Connect 1 -> 2 -> 3.
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True) l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True)
@ -1067,7 +1067,7 @@ def test_forward(node_factory, bitcoind):
l1.rpc.waitsendpay(rhash) l1.rpc.waitsendpay(rhash)
@unittest.skipIf(not DEVELOPER, "needs --dev-fast-gossip") @pytest.mark.developer("needs --dev-fast-gossip")
def test_forward_different_fees_and_cltv(node_factory, bitcoind): def test_forward_different_fees_and_cltv(node_factory, bitcoind):
# FIXME: Check BOLT quotes here too # FIXME: Check BOLT quotes here too
# BOLT #7: # BOLT #7:
@ -1203,7 +1203,7 @@ def test_forward_different_fees_and_cltv(node_factory, bitcoind):
assert c[1]['source'] == c[0]['destination'] assert c[1]['source'] == c[0]['destination']
@unittest.skipIf(not DEVELOPER, "too slow without --dev-fast-gossip") @pytest.mark.developer("too slow without --dev-fast-gossip")
def test_forward_pad_fees_and_cltv(node_factory, bitcoind): def test_forward_pad_fees_and_cltv(node_factory, bitcoind):
"""Test that we are allowed extra locktime delta, and fees""" """Test that we are allowed extra locktime delta, and fees"""
@ -1254,7 +1254,7 @@ def test_forward_pad_fees_and_cltv(node_factory, bitcoind):
assert only_one(l3.rpc.listinvoices('test_forward_pad_fees_and_cltv')['invoices'])['status'] == 'paid' assert only_one(l3.rpc.listinvoices('test_forward_pad_fees_and_cltv')['invoices'])['status'] == 'paid'
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 for dev_ignore_htlcs") @pytest.mark.developer("needs DEVELOPER=1 for dev_ignore_htlcs")
def test_forward_stats(node_factory, bitcoind): def test_forward_stats(node_factory, bitcoind):
"""Check that we track forwarded payments correctly. """Check that we track forwarded payments correctly.
@ -1333,7 +1333,7 @@ def test_forward_stats(node_factory, bitcoind):
assert 'received_time' in stats['forwards'][2] and 'resolved_time' not in stats['forwards'][2] assert 'received_time' in stats['forwards'][2] and 'resolved_time' not in stats['forwards'][2]
@unittest.skipIf(not DEVELOPER, "too slow without --dev-fast-gossip") @pytest.mark.developer("too slow without --dev-fast-gossip")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_forward_local_failed_stats(node_factory, bitcoind, executor): def test_forward_local_failed_stats(node_factory, bitcoind, executor):
"""Check that we track forwarded payments correctly. """Check that we track forwarded payments correctly.
@ -1554,7 +1554,7 @@ def test_forward_local_failed_stats(node_factory, bitcoind, executor):
assert 'received_time' in stats['forwards'][3] and 'resolved_time' not in stats['forwards'][4] assert 'received_time' in stats['forwards'][3] and 'resolved_time' not in stats['forwards'][4]
@unittest.skipIf(not DEVELOPER, "too slow without --dev-fast-gossip") @pytest.mark.developer("too slow without --dev-fast-gossip")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_htlcs_cltv_only_difference(node_factory, bitcoind): def test_htlcs_cltv_only_difference(node_factory, bitcoind):
# l1 -> l2 -> l3 -> l4 # l1 -> l2 -> l3 -> l4
@ -1631,7 +1631,7 @@ def test_pay_variants(node_factory):
l1.rpc.pay(b11) l1.rpc.pay(b11)
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_pay_retry(node_factory, bitcoind, executor, chainparams): def test_pay_retry(node_factory, bitcoind, executor, chainparams):
"""Make sure pay command retries properly. """ """Make sure pay command retries properly. """
@ -1715,7 +1715,7 @@ def test_pay_retry(node_factory, bitcoind, executor, chainparams):
l1.rpc.dev_pay(inv, use_shadow=False) l1.rpc.dev_pay(inv, use_shadow=False)
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1 otherwise gossip takes 5 minutes!") @pytest.mark.developer("needs DEVELOPER=1 otherwise gossip takes 5 minutes!")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_pay_routeboost(node_factory, bitcoind, compat): def test_pay_routeboost(node_factory, bitcoind, compat):
"""Make sure we can use routeboost information. """ """Make sure we can use routeboost information. """
@ -1828,7 +1828,7 @@ def test_pay_routeboost(node_factory, bitcoind, compat):
# output # output
@unittest.skipIf(not DEVELOPER, "updates are delayed without --dev-fast-gossip") @pytest.mark.developer("updates are delayed without --dev-fast-gossip")
def test_setchannelfee_usage(node_factory, bitcoind): def test_setchannelfee_usage(node_factory, bitcoind):
# TEST SETUP # TEST SETUP
# #
@ -1970,7 +1970,7 @@ def test_setchannelfee_usage(node_factory, bitcoind):
l1.rpc.setchannelfee(scid, 2**32) l1.rpc.setchannelfee(scid, 2**32)
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_setchannelfee_state(node_factory, bitcoind): def test_setchannelfee_state(node_factory, bitcoind):
# TEST SETUP # TEST SETUP
# #
@ -2027,7 +2027,7 @@ def test_setchannelfee_state(node_factory, bitcoind):
l1.rpc.setchannelfee(l2.info['id'], 10, 1) l1.rpc.setchannelfee(l2.info['id'], 10, 1)
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_setchannelfee_routing(node_factory, bitcoind): def test_setchannelfee_routing(node_factory, bitcoind):
# TEST SETUP # TEST SETUP
# #
@ -2103,7 +2103,7 @@ def test_setchannelfee_routing(node_factory, bitcoind):
assert result['msatoshi_sent'] == 5000049 assert result['msatoshi_sent'] == 5000049
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_setchannelfee_zero(node_factory, bitcoind): def test_setchannelfee_zero(node_factory, bitcoind):
# TEST SETUP # TEST SETUP
# #
@ -2144,7 +2144,7 @@ def test_setchannelfee_zero(node_factory, bitcoind):
assert result['msatoshi_sent'] == 4999999 assert result['msatoshi_sent'] == 4999999
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_setchannelfee_restart(node_factory, bitcoind): def test_setchannelfee_restart(node_factory, bitcoind):
# TEST SETUP # TEST SETUP
# #
@ -2190,7 +2190,7 @@ def test_setchannelfee_restart(node_factory, bitcoind):
assert result['msatoshi_sent'] == 5002020 assert result['msatoshi_sent'] == 5002020
@unittest.skipIf(not DEVELOPER, "updates are delayed without --dev-fast-gossip") @pytest.mark.developer("updates are delayed without --dev-fast-gossip")
def test_setchannelfee_all(node_factory, bitcoind): def test_setchannelfee_all(node_factory, bitcoind):
# TEST SETUP # TEST SETUP
# #
@ -2227,7 +2227,7 @@ def test_setchannelfee_all(node_factory, bitcoind):
assert result['channels'][1]['short_channel_id'] == scid3 assert result['channels'][1]['short_channel_id'] == scid3
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_channel_spendable(node_factory, bitcoind): def test_channel_spendable(node_factory, bitcoind):
"""Test that spendable_msat is accurate""" """Test that spendable_msat is accurate"""
sats = 10**6 sats = 10**6
@ -2280,7 +2280,7 @@ def test_channel_spendable(node_factory, bitcoind):
l2.rpc.waitsendpay(payment_hash, TIMEOUT) l2.rpc.waitsendpay(payment_hash, TIMEOUT)
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_channel_receivable(node_factory, bitcoind): def test_channel_receivable(node_factory, bitcoind):
"""Test that receivable_msat is accurate""" """Test that receivable_msat is accurate"""
sats = 10**6 sats = 10**6
@ -2333,7 +2333,7 @@ def test_channel_receivable(node_factory, bitcoind):
l2.rpc.waitsendpay(payment_hash, TIMEOUT) l2.rpc.waitsendpay(payment_hash, TIMEOUT)
@unittest.skipIf(not DEVELOPER, "gossip without DEVELOPER=1 is slow") @pytest.mark.developer("gossip without DEVELOPER=1 is slow")
def test_channel_spendable_large(node_factory, bitcoind): def test_channel_spendable_large(node_factory, bitcoind):
"""Test that spendable_msat is accurate for large channels""" """Test that spendable_msat is accurate for large channels"""
# This is almost the max allowable spend. # This is almost the max allowable spend.
@ -2425,7 +2425,7 @@ def test_error_returns_blockheight(node_factory, bitcoind):
== '400f{:016x}{:08x}'.format(100, bitcoind.rpc.getblockcount())) == '400f{:016x}{:08x}'.format(100, bitcoind.rpc.getblockcount()))
@unittest.skipIf(not DEVELOPER, 'Needs dev-routes') @pytest.mark.developer('Needs dev-routes')
def test_tlv_or_legacy(node_factory, bitcoind): def test_tlv_or_legacy(node_factory, bitcoind):
l1, l2, l3 = node_factory.line_graph(3, l1, l2, l3 = node_factory.line_graph(3,
opts={'plugin': os.path.join(os.getcwd(), 'tests/plugins/print_htlc_onion.py')}) opts={'plugin': os.path.join(os.getcwd(), 'tests/plugins/print_htlc_onion.py')})
@ -2466,7 +2466,7 @@ def test_tlv_or_legacy(node_factory, bitcoind):
l3.daemon.wait_for_log("Got onion.*'type': 'tlv'") l3.daemon.wait_for_log("Got onion.*'type': 'tlv'")
@unittest.skipIf(not DEVELOPER, 'Needs dev-routes') @pytest.mark.developer('Needs dev-routes')
@unittest.skipIf(TEST_NETWORK != 'regtest', "Invoice is network specific") @unittest.skipIf(TEST_NETWORK != 'regtest', "Invoice is network specific")
def test_pay_no_secret(node_factory, bitcoind): def test_pay_no_secret(node_factory, bitcoind):
l1, l2 = node_factory.line_graph(2, wait_for_announce=True) l1, l2 = node_factory.line_graph(2, wait_for_announce=True)
@ -2548,7 +2548,7 @@ def test_createonion_rpc(node_factory):
assert(res['onion'].endswith('9400f45a48e6dc8ddbaeb3')) assert(res['onion'].endswith('9400f45a48e6dc8ddbaeb3'))
@unittest.skipIf(not DEVELOPER, "gossip propagation is slow without DEVELOPER=1") @pytest.mark.developer("gossip propagation is slow without DEVELOPER=1")
def test_sendonion_rpc(node_factory): def test_sendonion_rpc(node_factory):
l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True) l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True)
amt = 10**3 amt = 10**3
@ -2634,7 +2634,7 @@ def test_sendonion_rpc(node_factory):
assert(e.error['data']['raw_message'] == "400f00000000000003e80000006c") assert(e.error['data']['raw_message'] == "400f00000000000003e80000006c")
@unittest.skipIf(not DEVELOPER, "needs dev-disconnect, dev-no-htlc-timeout") @pytest.mark.developer("needs dev-disconnect, dev-no-htlc-timeout")
def test_partial_payment(node_factory, bitcoind, executor): def test_partial_payment(node_factory, bitcoind, executor):
# We want to test two payments at the same time, before we send commit # We want to test two payments at the same time, before we send commit
l1, l2, l3, l4 = node_factory.get_nodes(4, [{}] + [{'disconnect': ['=WIRE_UPDATE_ADD_HTLC-nocommit'], 'dev-no-htlc-timeout': None}] * 2 + [{'plugin': os.path.join(os.getcwd(), 'tests/plugins/print_htlc_onion.py')}]) l1, l2, l3, l4 = node_factory.get_nodes(4, [{}] + [{'disconnect': ['=WIRE_UPDATE_ADD_HTLC-nocommit'], 'dev-no-htlc-timeout': None}] * 2 + [{'plugin': os.path.join(os.getcwd(), 'tests/plugins/print_htlc_onion.py')}])
@ -2777,7 +2777,7 @@ def test_partial_payment_restart(node_factory, bitcoind):
l1.rpc.waitsendpay(payment_hash=inv['payment_hash'], timeout=TIMEOUT, partid=2) l1.rpc.waitsendpay(payment_hash=inv['payment_hash'], timeout=TIMEOUT, partid=2)
@unittest.skipIf(not DEVELOPER, "needs dev-disconnect") @pytest.mark.developer("needs dev-disconnect")
def test_partial_payment_htlc_loss(node_factory, bitcoind): def test_partial_payment_htlc_loss(node_factory, bitcoind):
"""Test that we discard a set when the HTLC is lost""" """Test that we discard a set when the HTLC is lost"""
# We want l2 to fail once it has completed first htlc. # We want l2 to fail once it has completed first htlc.
@ -2833,7 +2833,7 @@ def test_createonion_limits(node_factory):
l1.rpc.createonion(hops=hops, assocdata="BB" * 32) l1.rpc.createonion(hops=hops, assocdata="BB" * 32)
@unittest.skipIf(not DEVELOPER, "needs use_shadow") @pytest.mark.developer("needs use_shadow")
def test_blockheight_disagreement(node_factory, bitcoind, executor): def test_blockheight_disagreement(node_factory, bitcoind, executor):
""" """
While a payment is in-transit from payer to payee, a block While a payment is in-transit from payer to payee, a block
@ -3084,7 +3084,7 @@ def test_invalid_onion_channel_update(node_factory):
assert l1.rpc.getinfo()['id'] == l1id assert l1.rpc.getinfo()['id'] == l1id
@unittest.skipIf(not DEVELOPER, "Requires use_shadow") @pytest.mark.developer("Requires use_shadow")
def test_pay_exemptfee(node_factory, compat): def test_pay_exemptfee(node_factory, compat):
"""Tiny payment, huge fee """Tiny payment, huge fee
@ -3123,7 +3123,7 @@ def test_pay_exemptfee(node_factory, compat):
l1.rpc.dev_pay(l3.rpc.invoice(int(5001 * 200), "lbl4", "desc")['bolt11'], use_shadow=False) l1.rpc.dev_pay(l3.rpc.invoice(int(5001 * 200), "lbl4", "desc")['bolt11'], use_shadow=False)
@unittest.skipIf(not DEVELOPER, "Requires use_shadow flag") @pytest.mark.developer("Requires use_shadow flag")
def test_pay_peer(node_factory, bitcoind): def test_pay_peer(node_factory, bitcoind):
"""If we have a direct channel to the destination we should use that. """If we have a direct channel to the destination we should use that.
@ -3472,7 +3472,7 @@ def test_listpays_ongoing_attempt(node_factory, bitcoind, executor):
l1.rpc.listpays() l1.rpc.listpays()
@unittest.skipIf(not DEVELOPER, "needs use_shadow") @pytest.mark.developer("needs use_shadow")
def test_mpp_waitblockheight_routehint_conflict(node_factory, bitcoind, executor): def test_mpp_waitblockheight_routehint_conflict(node_factory, bitcoind, executor):
''' '''
We have a bug where a blockheight disagreement between us and We have a bug where a blockheight disagreement between us and
@ -3520,7 +3520,7 @@ def test_mpp_waitblockheight_routehint_conflict(node_factory, bitcoind, executor
fut.result(TIMEOUT) fut.result(TIMEOUT)
@unittest.skipIf(not DEVELOPER, "channel setup very slow (~10 minutes) if not DEVELOPER") @pytest.mark.developer("channel setup very slow (~10 minutes) if not DEVELOPER")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_mpp_interference_2(node_factory, bitcoind, executor): def test_mpp_interference_2(node_factory, bitcoind, executor):
''' '''
@ -3677,7 +3677,7 @@ def test_large_mpp_presplit(node_factory):
assert(inv['msatoshi'] == inv['msatoshi_received']) assert(inv['msatoshi'] == inv['msatoshi_received'])
@unittest.skipIf(not DEVELOPER, "builds large network, which is slow if not DEVELOPER") @pytest.mark.developer("builds large network, which is slow if not DEVELOPER")
@pytest.mark.slow_test @pytest.mark.slow_test
def test_mpp_overload_payee(node_factory, bitcoind): def test_mpp_overload_payee(node_factory, bitcoind):
""" """

View File

@ -965,7 +965,7 @@ def test_channel_state_change_history(node_factory, bitcoind):
assert(history[3]['message'] == "Closing complete") assert(history[3]['message'] == "Closing complete")
@unittest.skipIf(not DEVELOPER, "without DEVELOPER=1, gossip v slow") @pytest.mark.developer("without DEVELOPER=1, gossip v slow")
def test_htlc_accepted_hook_fail(node_factory): def test_htlc_accepted_hook_fail(node_factory):
"""Send payments from l1 to l2, but l2 just declines everything. """Send payments from l1 to l2, but l2 just declines everything.
@ -1008,7 +1008,7 @@ def test_htlc_accepted_hook_fail(node_factory):
assert len(inv) == 1 and inv[0]['status'] == 'unpaid' assert len(inv) == 1 and inv[0]['status'] == 'unpaid'
@unittest.skipIf(not DEVELOPER, "without DEVELOPER=1, gossip v slow") @pytest.mark.developer("without DEVELOPER=1, gossip v slow")
def test_htlc_accepted_hook_resolve(node_factory): def test_htlc_accepted_hook_resolve(node_factory):
"""l3 creates an invoice, l2 knows the preimage and will shortcircuit. """l3 creates an invoice, l2 knows the preimage and will shortcircuit.
""" """
@ -1050,7 +1050,7 @@ def test_htlc_accepted_hook_direct_restart(node_factory, executor):
f1.result() f1.result()
@unittest.skipIf(not DEVELOPER, "without DEVELOPER=1, gossip v slow") @pytest.mark.developer("without DEVELOPER=1, gossip v slow")
def test_htlc_accepted_hook_forward_restart(node_factory, executor): def test_htlc_accepted_hook_forward_restart(node_factory, executor):
"""l2 restarts while it is pondering what to do with an HTLC. """l2 restarts while it is pondering what to do with an HTLC.
""" """
@ -1120,7 +1120,7 @@ def test_warning_notification(node_factory):
l1.daemon.wait_for_log('plugin-pretend_badlog.py: log: Test warning notification\\(for broken event\\)') l1.daemon.wait_for_log('plugin-pretend_badlog.py: log: Test warning notification\\(for broken event\\)')
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_invoice_payment_notification(node_factory): def test_invoice_payment_notification(node_factory):
""" """
Test the 'invoice_payment' notification Test the 'invoice_payment' notification
@ -1139,7 +1139,7 @@ def test_invoice_payment_notification(node_factory):
.format(label, preimage, msats)) .format(label, preimage, msats))
@unittest.skipIf(not DEVELOPER, "needs to deactivate shadow routing") @pytest.mark.developer("needs to deactivate shadow routing")
def test_invoice_creation_notification(node_factory): def test_invoice_creation_notification(node_factory):
""" """
Test the 'invoice_creation' notification Test the 'invoice_creation' notification
@ -1173,7 +1173,7 @@ def test_channel_opened_notification(node_factory):
.format(l1.info["id"], amount)) .format(l1.info["id"], amount))
@unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") @pytest.mark.developer("needs DEVELOPER=1")
def test_forward_event_notification(node_factory, bitcoind, executor): def test_forward_event_notification(node_factory, bitcoind, executor):
""" test 'forward_event' notifications """ test 'forward_event' notifications
""" """
@ -1738,7 +1738,7 @@ def test_replacement_payload(node_factory):
assert l2.daemon.wait_for_log("Attept to pay.*with wrong secret") assert l2.daemon.wait_for_log("Attept to pay.*with wrong secret")
@unittest.skipIf(not DEVELOPER, "Requires dev_sign_last_tx") @pytest.mark.developer("Requires dev_sign_last_tx")
def test_watchtower(node_factory, bitcoind, directory, chainparams): def test_watchtower(node_factory, bitcoind, directory, chainparams):
"""Test watchtower hook. """Test watchtower hook.
@ -1827,7 +1827,7 @@ def test_plugin_fail(node_factory):
l1.daemon.wait_for_log(r': exited during normal operation') l1.daemon.wait_for_log(r': exited during normal operation')
@unittest.skipIf(not DEVELOPER, "without DEVELOPER=1, gossip v slow") @pytest.mark.developer("without DEVELOPER=1, gossip v slow")
def test_coin_movement_notices(node_factory, bitcoind, chainparams): def test_coin_movement_notices(node_factory, bitcoind, chainparams):
"""Verify that coin movements are triggered correctly. """Verify that coin movements are triggered correctly.
""" """
@ -2117,7 +2117,7 @@ def test_important_plugin(node_factory):
assert get_logfile_match(logpath, 'pay: Plugin marked as important, shutting down lightningd') assert get_logfile_match(logpath, 'pay: Plugin marked as important, shutting down lightningd')
@unittest.skipIf(not DEVELOPER, "tests developer-only option.") @pytest.mark.developer("tests developer-only option.")
def test_dev_builtin_plugins_unimportant(node_factory): def test_dev_builtin_plugins_unimportant(node_factory):
n = node_factory.get_node(options={"dev-builtin-plugins-unimportant": None}) n = node_factory.get_node(options={"dev-builtin-plugins-unimportant": None})
n.rpc.plugin_stop(plugin="pay") n.rpc.plugin_stop(plugin="pay")