From 84f15fd2f08d516a86a71ee6c0536c4c2bc085c5 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 5 Dec 2024 13:10:56 +1030 Subject: [PATCH] doc: document and test the onionmessage_forward_fail notification. Doing exactly what we expect to do: initiate a connection and then forward the message. Signed-off-by: Rusty Russell --- .../plugin-development/event-notifications.md | 36 +++++++++++++++++++ .../onionmessage_forward_fail_notification.py | 20 +++++++++++ tests/test_connection.py | 20 +++++++++++ 3 files changed, 76 insertions(+) create mode 100755 tests/plugins/onionmessage_forward_fail_notification.py diff --git a/doc/developers-guide/plugin-development/event-notifications.md b/doc/developers-guide/plugin-development/event-notifications.md index 7d3aeba994af..cb26d8a16e82 100644 --- a/doc/developers-guide/plugin-development/event-notifications.md +++ b/doc/developers-guide/plugin-development/event-notifications.md @@ -471,6 +471,42 @@ When opening a channel with a peer using the collaborative transaction protocol } ``` +### `onionmessage_forward_fail` + +When we receive an onion message from a peer (and it's not ratelimited), and we cannot forward it for some reason. There are three reasons why this can be called: + +1. The onion message cannot be parsed. In this case, `outgoing` and `next_node_id`/`next_short_channel_id_dir` fields are missing. +2. The forward was by short_channel_id, but we don't know that id. In this case, `next_node_id` is missing, but `next_short_channel_id_dir` is present. +3. The next peer wasn't connected. In this case, only `next_short_channel_id_dir` is missing. + +Example 1: Failure because next node wasn't connected: + +```json +{ + "onionmessage_forward_fail": { + "source": "0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518", + "incoming": "0002d32df088bbe2723c619b0bb88bd0969843320f961744816cbcf30ad92d8f8db567687640ffdf492971729befd7016443514bed786fbcde7be8935f09b624868c912674abd3764099f082da36c8431a847cb486f19f4888a34ee19850b6977b2b0019b8570f9a194f952a451711a42cc9b7b26b1f0f099a43f94c2946a0e3b6425abff66f002b50ab16939d0239496309198870fbb91cf2c9e67b6092a843e827e01d44898c28d4e31d1278daef2e6d7dd4ffb7d170d102a198451c46974d93a1e86e1a752db64cd067089e42ae90be27a86dbee3462850fca616bf9aac4cfe704bcf82a4d90c9cab2f107f93c9d96a400f09fd3520d55262bd99880f82525560b4d605dfe40b87ea7a606f7a12fc86b6be45bbfb4fe10686a040523f5270a40dc125466ff2f470ee82f07cf0f55f826e669e265bba2ef4649aaeec91d3e82e02b64bd93e8d3eb3f84bc4734fe36649859d6a573a7ce32ee49ecf419892d24aa0cdf778b48bb60476c29c398b2faa2ad095b76f508e69fb1fc3b26c3495c38b5e01741557bd4f22c5e752209fd7f3bbac53bed7d43c97f59294df67ec3489ae28deafbc6a24675d0d33ec59ed698932ab39d132aea90a0c8a1577dc149769c28d1e709d37ce945e1a1a3587df288725075a55cc881a821abd8179e48183482d909371fc6132cb6eb588d1e1f99a4da625da4b1bf54365ec4426e52ea0bcc8da5b7768f0dd5cd3d16116987d24f9e99e0f1c16e7564bec502b29ff3d1dde44f438bda52d716965751e173458318dfef1bb441ae55a77cd8a3a018c21770581d65edcb50146e4c06a4a545c1629fbcbf9985ab0de8c2d7b16ce67ac97ee4475d9b890a96481bf53960350194404c84ad8ddf78c956b3d5538741dc21030f7d4407ec55a5ec41e142b3613d14955f0b19232a7e2c403aa76b5289c714697d61e2ba6ad33f9e1c68fdb0b0d3dba91170eeb2647eca097b6aed5a86a8af41c026768a03f8f0225e7f7e025152a2fd9238c54a53e95ae3c8d867b41f014ab799365f5f12c214b91b7df04ad7055930fc652b24ba4bdaa509002dee61a49b80323e5a8b576beefa50149adc9ea55d00799cdf97efb0c60c9c05e812d203034bd0c3c3405d53e22e15b9c543f7655a327ddb9879ba7959215f1562d974447ecd5ea08fbc8665619f5aee259ebf6f2dd3f851bda06861817d7751126c48beba46b63f87aacba344be60ba437b677fd6ca997848c00a79377425f2c70ea4097e29a06028bdf8d34eeda515682e148832af2ee8efa326997a7f834609363114e1015115c37c8a59b2fd18554e59a6cd049acf95ead7023d2f4654fd938f821324d6cc87161b202dfc5b69803d4b3b0f8dcd5d2eb9058973027966ea48f1b63766074fceb5827d7da4fcd50d554f0a971fdfb7760b65cf413e5653065b1b728c09f1c75aaf635a6f350a04163af02e51031642439486c623f71e78ab9141c09afcc9963808ec063bbc393163e91e21dea1d6543da8c27dcc37bd68d90fb5bff3912caf29f5c9c0398f8a4384a3bc75213cac334e0f078034fbaf0ae541fbe20da77404759c72d036750f30247cd2b9317e71dea7907047457b010acfdc17ae4671c7fcc7800031a4473f924fcc9483deaa912a838c90eae30a96355cc34303f7cd4146fcefb2cc81359adcfa60b5f5a67ee203bb21d1a6a75a7315fe25fd53b729c9e32b17eef2fda0e4e00e357a55bb4c97e82f39cf386e3c40b8a1e6aae62654ad0d050e23030061ea4baf5d3fa3395d146072e30c48ff7f7ad36199774baa8c26f0e17d26c340f294c64cdbd001929a46bd0b58d472d630bba53b848eddcec0a4e3ca098e3350c022011b2ca57719e9ba10a185e2fe0959bb4796f8806642d01700c1a5c617ae68f3ec9447a40b8751bb43b4eb1052fa0f35d", + "path_key": "036fb5acc4ddcd66bebbc00831e856720f92255017ae200bfafaa2f5fb23aa74e2", + "outgoing": "02010221795ac7fd20c3905ced2317c9455adcdb4166be10fd0b10b9408373c8db813c05560002da9320b96766a2b754923854bf99aa9cfe96263e24ead7d0f027b4941702fc6fdf2878caab06852f5f20857699a81c421e784a744d4d0d3706d328a8ff6c61a6d07e4f4496c6ace9b34d860c325cd0676fa7251f9fddf572fb454f0738ee3d16cb88045f325e88ba804936789539a7250584a6611a5b51d3d4c41ad4ca9d1988cdb0c32adae4261c78da204ea6123a0c3afa7c9b6891c7132fedf07f7cedfb0faa685f0fc91be657169983403a0e9d62558e0eb28456ca3f26a272cf447c2c417e34346a3a175abac1af534fa7c1d5427e2ad9343266f7edbb48f9bcb0ee4afca808572606a5a23cda7e54936ea0691e49f065b02cac3dfdb84e248ff7c69b8bd31345b295c1f58b572f72b8453bc434dc1744c8abf22d3bbda741be411fbbb7ec51fb66f229deacd56f180f92c12bd62cad53fc695aa41305b2a5751f449c361061e417a6d00a12d27d9fd0a043a40d60fd6e28f37096cb9f9f5000b088cba346a2d6d6d9db1d8f5144a625b5dd7204392f0ff4c5a2e92e8e787d336a6090c94d7f60668807429dcce5af39b8688d8cc48d1618de9b48219d3ddfa0ad4e5712966267a4bd41d8d1135e594b1d5b4de4050e46b1bc10cde4f0a401e0b14edd74b675b56f0177f713c89ec963cc97896c7aa918339104ae7eec6a16f9c08950f2d6f7f54bb8da2700e88825fead9d463b47bb9f45c11bdfeda92b5afb12942d162392ebc8e403b1c89838c772d4f6e737ff5e0eb03887a996b2f5591fec34da4eb2330e0b09b763f1165f098b204b590250f5013edbdc51fe04cd3ac9c412b0f6f7af9f88ddde58ae17e21466f3a71ab55fd557b7d52e8da8d62800313d13447ff92c557f19b52acaab60223cb7fb36ebc4b5279f097c0710fa86385e8ff4544515feb53fa0a6385f47f57e3b690e198ffc77be73ef25ef00676fdbb8750fecbc2bfdc081a0a3a2340dae8e3810f9fe7f6c365ec1903f2d4f48017b6d591e87ef148da5e41f80c02a1d4747b0e69934abf3ed57af48918b2d2facda94ce8759c2d98663e33ac1a5e293479332389d85b25cd69484d25a1e52d93cde5812bc5b69439e03339b595c4ee0035195c1a73d152a1763b7df77a48f36781c719c8c482fce687792c9fc5b2a9b51f679f82c4327b6478922ee47ee6524cb4aa63121222fa4762fa7bb6798444522030aa2c27b75cbf6f20d802e321d9b648d7f556a0d3be3e61d06a02f800c927fc15027a44d0132cf277083de6118ac163fa47d662b3274a00f0b561248e350313fbd446eb495ab9503b749ca0126b5690755ca43372db968ac7a2c41aa7f019184c3208b40e3ebd2b5d38e33cb0435b3ad2d5eec77101ae26b113c07c3044da335e57378c6cf1b2d3339d49244cb4d0f6982505ec06b85aedc91c241cfc429628fca8756b4c172f4af35e73ee57f650d0e049100d2664d016571e83ce06929ec37dc77bbd3bad59435ff2406084b24165b94704d8df16577b7100a41503a247f60f4f6a58e3fce6e789e19e5b04c64ca30e09207bb8b556db17dda1d00f7c47c391086247b63388275f2018f29d7bfd33dac7f73924f6c2e50e0d26a6f7f3ca19156e092a1f13d9205fec58d33f5e18360ab295c7798475229a95b56af4df9035e676a0bed91faa8df5b2e1131ba7d8b9155b12cb1358ae5d739893503bce95540dac5bb377660ef74bd0da5a2f655db5ecc785143cec2dba84a5208fa711cf680f027259efcfaad64e20daf8cc4ad4396296f9c8fa51e20dd457594d26fbe1f36278e5483401ad158363ea43bdae7595c434a4af3d47f25d61fee9a996bde1a018f544dfe7cb4b986c55f5d5d6783efc9078e423f7855be7415764a8b5a5fe350032f16a3b4f18db2062a5ae6446dffbb346f5429a30d9a13c7736af009ef0b9c64defca7d17bbabac9", + "next_node_id": "035d2b1192dfba134e10e540875d366ebc8bc353d5aa766b80c090b39c3a5d885d" + } +} +``` + +Example 2: failed because we don't know short-channel `1x2x3`: + +```json +{ + "onionmessage_forward_fail": { + "source": "0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518", + "incoming": "0002d32df088bbe2723c619b0bb88bd0969843320f961744816cbcf30ad92d8f8db567687640ffdf492971729befd7016443514bed786fbcde7be8935f09b624868c912674abd3764099f082da36c8431a847cb486f19f4888a34ee19850b6977b2b0019b8570f9a194f952a451711a42cc9b7b26b1f0f099a43f94c2946a0e3b6425abff66f002b50ab16939d0239496309198870fbb91cf2c9e67b6092a843e827e01d44898c28d4e31d1278daef2e6d7dd4ffb7d170d102a198451c46974d93a1e86e1a752db64cd067089e42ae90be27a86dbee3462850fca616bf9aac4cfe704bcf82a4d90c9cab2f107f93c9d96a400f09fd3520d55262bd99880f82525560b4d605dfe40b87ea7a606f7a12fc86b6be45bbfb4fe10686a040523f5270a40dc125466ff2f470ee82f07cf0f55f826e669e265bba2ef4649aaeec91d3e82e02b64bd93e8d3eb3f84bc4734fe36649859d6a573a7ce32ee49ecf419892d24aa0cdf778b48bb60476c29c398b2faa2ad095b76f508e69fb1fc3b26c3495c38b5e01741557bd4f22c5e752209fd7f3bbac53bed7d43c97f59294df67ec3489ae28deafbc6a24675d0d33ec59ed698932ab39d132aea90a0c8a1577dc149769c28d1e709d37ce945e1a1a3587df288725075a55cc881a821abd8179e48183482d909371fc6132cb6eb588d1e1f99a4da625da4b1bf54365ec4426e52ea0bcc8da5b7768f0dd5cd3d16116987d24f9e99e0f1c16e7564bec502b29ff3d1dde44f438bda52d716965751e173458318dfef1bb441ae55a77cd8a3a018c21770581d65edcb50146e4c06a4a545c1629fbcbf9985ab0de8c2d7b16ce67ac97ee4475d9b890a96481bf53960350194404c84ad8ddf78c956b3d5538741dc21030f7d4407ec55a5ec41e142b3613d14955f0b19232a7e2c403aa76b5289c714697d61e2ba6ad33f9e1c68fdb0b0d3dba91170eeb2647eca097b6aed5a86a8af41c026768a03f8f0225e7f7e025152a2fd9238c54a53e95ae3c8d867b41f014ab799365f5f12c214b91b7df04ad7055930fc652b24ba4bdaa509002dee61a49b80323e5a8b576beefa50149adc9ea55d00799cdf97efb0c60c9c05e812d203034bd0c3c3405d53e22e15b9c543f7655a327ddb9879ba7959215f1562d974447ecd5ea08fbc8665619f5aee259ebf6f2dd3f851bda06861817d7751126c48beba46b63f87aacba344be60ba437b677fd6ca997848c00a79377425f2c70ea4097e29a06028bdf8d34eeda515682e148832af2ee8efa326997a7f834609363114e1015115c37c8a59b2fd18554e59a6cd049acf95ead7023d2f4654fd938f821324d6cc87161b202dfc5b69803d4b3b0f8dcd5d2eb9058973027966ea48f1b63766074fceb5827d7da4fcd50d554f0a971fdfb7760b65cf413e5653065b1b728c09f1c75aaf635a6f350a04163af02e51031642439486c623f71e78ab9141c09afcc9963808ec063bbc393163e91e21dea1d6543da8c27dcc37bd68d90fb5bff3912caf29f5c9c0398f8a4384a3bc75213cac334e0f078034fbaf0ae541fbe20da77404759c72d036750f30247cd2b9317e71dea7907047457b010acfdc17ae4671c7fcc7800031a4473f924fcc9483deaa912a838c90eae30a96355cc34303f7cd4146fcefb2cc81359adcfa60b5f5a67ee203bb21d1a6a75a7315fe25fd53b729c9e32b17eef2fda0e4e00e357a55bb4c97e82f39cf386e3c40b8a1e6aae62654ad0d050e23030061ea4baf5d3fa3395d146072e30c48ff7f7ad36199774baa8c26f0e17d26c340f294c64cdbd001929a46bd0b58d472d630bba53b848eddcec0a4e3ca098e3350c022011b2ca57719e9ba10a185e2fe0959bb4796f8806642d01700c1a5c617ae68f3ec9447a40b8751bb43b4eb1052fa0f35d", + "path_key": "036fb5acc4ddcd66bebbc00831e856720f92255017ae200bfafaa2f5fb23aa74e2", + "outgoing": "02010221795ac7fd20c3905ced2317c9455adcdb4166be10fd0b10b9408373c8db813c05560002da9320b96766a2b754923854bf99aa9cfe96263e24ead7d0f027b4941702fc6fdf2878caab06852f5f20857699a81c421e784a744d4d0d3706d328a8ff6c61a6d07e4f4496c6ace9b34d860c325cd0676fa7251f9fddf572fb454f0738ee3d16cb88045f325e88ba804936789539a7250584a6611a5b51d3d4c41ad4ca9d1988cdb0c32adae4261c78da204ea6123a0c3afa7c9b6891c7132fedf07f7cedfb0faa685f0fc91be657169983403a0e9d62558e0eb28456ca3f26a272cf447c2c417e34346a3a175abac1af534fa7c1d5427e2ad9343266f7edbb48f9bcb0ee4afca808572606a5a23cda7e54936ea0691e49f065b02cac3dfdb84e248ff7c69b8bd31345b295c1f58b572f72b8453bc434dc1744c8abf22d3bbda741be411fbbb7ec51fb66f229deacd56f180f92c12bd62cad53fc695aa41305b2a5751f449c361061e417a6d00a12d27d9fd0a043a40d60fd6e28f37096cb9f9f5000b088cba346a2d6d6d9db1d8f5144a625b5dd7204392f0ff4c5a2e92e8e787d336a6090c94d7f60668807429dcce5af39b8688d8cc48d1618de9b48219d3ddfa0ad4e5712966267a4bd41d8d1135e594b1d5b4de4050e46b1bc10cde4f0a401e0b14edd74b675b56f0177f713c89ec963cc97896c7aa918339104ae7eec6a16f9c08950f2d6f7f54bb8da2700e88825fead9d463b47bb9f45c11bdfeda92b5afb12942d162392ebc8e403b1c89838c772d4f6e737ff5e0eb03887a996b2f5591fec34da4eb2330e0b09b763f1165f098b204b590250f5013edbdc51fe04cd3ac9c412b0f6f7af9f88ddde58ae17e21466f3a71ab55fd557b7d52e8da8d62800313d13447ff92c557f19b52acaab60223cb7fb36ebc4b5279f097c0710fa86385e8ff4544515feb53fa0a6385f47f57e3b690e198ffc77be73ef25ef00676fdbb8750fecbc2bfdc081a0a3a2340dae8e3810f9fe7f6c365ec1903f2d4f48017b6d591e87ef148da5e41f80c02a1d4747b0e69934abf3ed57af48918b2d2facda94ce8759c2d98663e33ac1a5e293479332389d85b25cd69484d25a1e52d93cde5812bc5b69439e03339b595c4ee0035195c1a73d152a1763b7df77a48f36781c719c8c482fce687792c9fc5b2a9b51f679f82c4327b6478922ee47ee6524cb4aa63121222fa4762fa7bb6798444522030aa2c27b75cbf6f20d802e321d9b648d7f556a0d3be3e61d06a02f800c927fc15027a44d0132cf277083de6118ac163fa47d662b3274a00f0b561248e350313fbd446eb495ab9503b749ca0126b5690755ca43372db968ac7a2c41aa7f019184c3208b40e3ebd2b5d38e33cb0435b3ad2d5eec77101ae26b113c07c3044da335e57378c6cf1b2d3339d49244cb4d0f6982505ec06b85aedc91c241cfc429628fca8756b4c172f4af35e73ee57f650d0e049100d2664d016571e83ce06929ec37dc77bbd3bad59435ff2406084b24165b94704d8df16577b7100a41503a247f60f4f6a58e3fce6e789e19e5b04c64ca30e09207bb8b556db17dda1d00f7c47c391086247b63388275f2018f29d7bfd33dac7f73924f6c2e50e0d26a6f7f3ca19156e092a1f13d9205fec58d33f5e18360ab295c7798475229a95b56af4df9035e676a0bed91faa8df5b2e1131ba7d8b9155b12cb1358ae5d739893503bce95540dac5bb377660ef74bd0da5a2f655db5ecc785143cec2dba84a5208fa711cf680f027259efcfaad64e20daf8cc4ad4396296f9c8fa51e20dd457594d26fbe1f36278e5483401ad158363ea43bdae7595c434a4af3d47f25d61fee9a996bde1a018f544dfe7cb4b986c55f5d5d6783efc9078e423f7855be7415764a8b5a5fe350032f16a3b4f18db2062a5ae6446dffbb346f5429a30d9a13c7736af009ef0b9c64defca7d17bbabac9", + "next_short_channel_id_dir": "1x2x3/1" + } +} + +``` ### `shutdown` Send in two situations: lightningd is (almost completely) shutdown, or the plugin `stop` command has been called for this plugin. In both cases the plugin has 30 seconds to exit itself, otherwise it's killed. diff --git a/tests/plugins/onionmessage_forward_fail_notification.py b/tests/plugins/onionmessage_forward_fail_notification.py new file mode 100755 index 000000000000..69606e2334e2 --- /dev/null +++ b/tests/plugins/onionmessage_forward_fail_notification.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python3 + +""" We get an onionmessage_forward_fail notification, and open a connection +""" +from pyln.client import Plugin + +plugin = Plugin() + + +@plugin.subscribe("onionmessage_forward_fail") +def on_onionmessage_forward_fail(onionmessage_forward_fail, **kwargs): + plugin.log(f"Received onionmessage_forward_fail {onionmessage_forward_fail}") + + plugin.rpc.connect(onionmessage_forward_fail['next_node_id']) + # injectonionmessage expects to unwrap, so hand it *incoming* + plugin.rpc.injectonionmessage(onionmessage_forward_fail['path_key'], + onionmessage_forward_fail['incoming']) + + +plugin.run() diff --git a/tests/test_connection.py b/tests/test_connection.py index ba224ad3c8f8..9f4d12c4476f 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -4725,3 +4725,23 @@ def test_connect_ratelimit(node_factory, bitcoind): # And now they're all connected wait_for(lambda: [p['connected'] for p in l1.rpc.listpeers()['peers']] == [True] * len(nodes)) + + +def test_onionmessage_forward_fail(node_factory, bitcoind): + # The plugin will try to connect to l3, so it needs an advertized address. + l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True, + opts=[{}, + {'dev-allow-localhost': None, + 'may_reconnect': True, + 'plugin': os.path.join(os.getcwd(), 'tests/plugins/onionmessage_forward_fail_notification.py'), + }, + {'dev-allow-localhost': None, + 'may_reconnect': True}]) + + offer = l3.rpc.offer(300, "test_onionmessage_forward_fail") + l2.rpc.disconnect(l3.info['id'], force=True) + + # The plugin in l2 fixes up the connection, so this works! + l1.rpc.fetchinvoice(offer['bolt12']) + + l2.daemon.is_in_log('plugin-onionmessage_forward_fail_notification.py: Received onionmessage_forward_fail')