From 09c2fef4a409d70f4be150e8b4c8900d5c1c5d88 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 1 Oct 2021 06:49:37 +0930 Subject: [PATCH] onion_message: dev options to ignore obsolete/modern onions. This lets us test that both work, as expected. Signed-off-by: Rusty Russell --- lightningd/lightningd.c | 2 ++ lightningd/lightningd.h | 3 +++ lightningd/onion_message.c | 10 +++++++++ lightningd/options.c | 6 ++++++ tests/test_pay.py | 43 +++++++++++++++++++++++++++++++++++--- 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index b849b8a23..1bc644c78 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -127,6 +127,8 @@ static struct lightningd *new_lightningd(const tal_t *ctx) ld->dev_no_htlc_timeout = false; ld->dev_no_version_checks = false; ld->dev_max_funding_unconfirmed = 2016; + ld->dev_ignore_modern_onion = false; + ld->dev_ignore_obsolete_onion = false; #endif /*~ These are CCAN lists: an embedded double-linked list. It's not diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index 699f7e330..d04b45964 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -242,6 +242,9 @@ struct lightningd { /* Number of blocks we wait for a channel to get funded * if we are the fundee. */ u32 dev_max_funding_unconfirmed; + + /* Special switches to test onion compatibility */ + bool dev_ignore_modern_onion, dev_ignore_obsolete_onion; #endif /* DEVELOPER */ /* tor support */ diff --git a/lightningd/onion_message.c b/lightningd/onion_message.c index 1161d1c0d..476232f09 100644 --- a/lightningd/onion_message.c +++ b/lightningd/onion_message.c @@ -142,6 +142,11 @@ void handle_obs_onionmsg_to_us(struct lightningd *ld, const u8 *msg) size_t submsglen; const u8 *subptr; +#if DEVELOPER + if (ld->dev_ignore_obsolete_onion) + return; +#endif + payload = tal(ld, struct onion_message_hook_payload); payload->obsolete = true; payload->reply_first_node = NULL; @@ -228,6 +233,11 @@ void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg) size_t submsglen; const u8 *subptr; +#if DEVELOPER + if (ld->dev_ignore_modern_onion) + return; +#endif + payload = tal(ld, struct onion_message_hook_payload); payload->obsolete = false; payload->om = tlv_onionmsg_payload_new(payload); diff --git a/lightningd/options.c b/lightningd/options.c index 969f5ef85..5a163e59e 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -648,6 +648,12 @@ static void dev_register_opts(struct lightningd *ld) opt_register_arg("--dev-timeout-secs", opt_set_u32, opt_show_u32, &ld->config.connection_timeout_secs, "Seconds to timeout if we don't receive INIT from peer"); + opt_register_noarg("--dev-no-modern-onion", opt_set_bool, + &ld->dev_ignore_modern_onion, + "Ignore modern onion messages"); + opt_register_noarg("--dev-no-obsolete-onion", opt_set_bool, + &ld->dev_ignore_obsolete_onion, + "Ignore obsolete onion messages"); } #endif /* DEVELOPER */ diff --git a/tests/test_pay.py b/tests/test_pay.py index 244314dea..d07ab9175 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -4117,15 +4117,34 @@ def test_offer(node_factory, bitcoind): assert 'recurrence: every 600 seconds paywindow -10 to +600 (pay proportional)\n' in output +@pytest.mark.developer("dev-no-modern-onion is DEVELOPER-only") def test_fetchinvoice_3hop(node_factory, bitcoind): l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True, - opts={'experimental-offers': None}) + opts={'experimental-offers': None, + 'may_reconnect': True}) offer1 = l4.rpc.call('offer', {'amount': '2msat', 'description': 'simple test'}) assert offer1['created'] is True l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']}) + # Test with obsolete onion. + l4.stop() + l4.daemon.opts['dev-no-modern-onion'] = None + l4.start() + l4.rpc.connect(l3.info['id'], 'localhost', l3.port) + + l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']}) + + # Test with modern onion. + l4.stop() + del l4.daemon.opts['dev-no-modern-onion'] + l4.daemon.opts['dev-no-obsolete-onion'] = None + l4.start() + l4.rpc.connect(l3.info['id'], 'localhost', l3.port) + + l1.rpc.call('fetchinvoice', {'offer': offer1['bolt12']}) + def test_fetchinvoice(node_factory, bitcoind): # We remove the conversion plugin on l3, causing it to get upset. @@ -4426,9 +4445,13 @@ def test_dev_rawrequest(node_factory): assert 'invoice' in ret -def test_sendinvoice(node_factory, bitcoind): +def do_test_sendinvoice(node_factory, bitcoind, disable): + l2opts = {'experimental-offers': None} + if disable: + l2opts[disable] = None l1, l2 = node_factory.line_graph(2, wait_for_announce=True, - opts={'experimental-offers': None}) + opts=[{'experimental-offers': None}, + l2opts]) # Simple offer to send money (balances channel a little) offer = l1.rpc.call('offerout', {'amount': '100000sat', @@ -4507,6 +4530,20 @@ def test_sendinvoice(node_factory, bitcoind): assert out['amount_received_msat'] == Millisatoshi(10000000) +def test_sendinvoice(node_factory, bitcoind): + do_test_sendinvoice(node_factory, bitcoind, None) + + +@pytest.mark.developer("needs to --dev-no-obsolete-onion") +def test_sendinvoice_modern(node_factory, bitcoind): + do_test_sendinvoice(node_factory, bitcoind, 'dev-no-obsolete-onion') + + +@pytest.mark.developer("needs to --dev-no-modern-onion") +def test_sendinvoice_obsolete(node_factory, bitcoind): + do_test_sendinvoice(node_factory, bitcoind, 'dev-no-modern-onion') + + def test_self_pay(node_factory): """Repro test for issue 4345: pay ourselves via the pay plugin.