Skip to content

Commit 3562641

Browse files
committed
pytest: test xpay notifications.
The custom_notifications handler produces really ugly results, and I was lazy, but it works! Signed-off-by: Rusty Russell <[email protected]>
1 parent 2c96968 commit 3562641

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

tests/plugins/custom_notifications.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ def on_pay_success(origin, payload, **kwargs):
3434
)
3535

3636

37+
@plugin.subscribe("xpay_attempt_start")
38+
def on_xpay_attempt_start(origin, payload, **kwargs):
39+
plugin.log("Got xpay_attempt_start: {}".format(payload))
40+
41+
42+
@plugin.subscribe("xpay_attempt_end")
43+
def on_xpay_attempt_end(origin, payload, **kwargs):
44+
plugin.log("Got xpay_attempt_end: {}".format(payload))
45+
46+
3747
@plugin.subscribe("ididntannouncethis")
3848
def on_faulty_emit(origin, payload, **kwargs):
3949
"""We should never receive this as it gets dropped.

tests/test_xpay.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,3 +831,53 @@ def test_xpay_twohop_bug(node_factory, bitcoind):
831831
# This doesn't!
832832
l1.rpc.xpay(inv)
833833
l1.daemon.wait_for_log(f'Adding HTLC 1 amount=15002msat cltv={110 + 1 + 100 + 200 + 400}')
834+
835+
836+
def test_attempt_notifications(node_factory):
837+
plugin_path = os.path.join(os.getcwd(), 'tests/plugins/custom_notifications.py')
838+
l1, l2, l3 = node_factory.line_graph(3, wait_for_announce=True,
839+
opts=[{"plugin": plugin_path}, {}, {}])
840+
841+
scid12 = only_one(l1.rpc.listpeerchannels(l2.info['id'])['channels'])['short_channel_id']
842+
scid12_dir = only_one(l1.rpc.listpeerchannels(l2.info['id'])['channels'])['direction']
843+
scid23 = only_one(l2.rpc.listpeerchannels(l3.info['id'])['channels'])['short_channel_id']
844+
scid23_dir = only_one(l2.rpc.listpeerchannels(l3.info['id'])['channels'])['direction']
845+
inv1 = l3.rpc.invoice(5000000, 'test_attempt_notifications1', 'test_attempt_notifications1')
846+
l1.rpc.xpay(inv1['bolt11'])
847+
848+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_start: ")
849+
regex = r".*Got xpay_attempt_start: \{'payment_hash': '" + inv1['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1, 'total_payment_msat': 5000000, 'attempt_msat': 5000000, 'hops': \[\{'next_node': '" + l2.info['id'] + r"', 'short_channel_id': '" + scid12 + r"', 'direction': " + str(scid12_dir) + r", 'channel_in_msat': 5000051, 'channel_out_msat': 5000051\}, \{'next_node': '" + l3.info['id'] + r"', 'short_channel_id': '" + scid23 + r"', 'direction': " + str(scid23_dir) + r", 'channel_in_msat': 5000051, 'channel_out_msat': 5000000\}\]\}"
850+
assert re.match(regex, line)
851+
852+
# Note, duration always has 9 decimals, EXCEPT that the python code interprets it, so if the last digit is a 0 it will only print 8.
853+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_end: ")
854+
regex = r".*Got xpay_attempt_end: \{'status': 'success', 'duration': [0-9]*\.[0-9]*, 'payment_hash': '" + inv1['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1\}"
855+
assert re.match(regex, line)
856+
857+
inv2 = l3.rpc.invoice(10000000, 'test_attempt_notifications2', 'test_attempt_notifications2')
858+
l3.rpc.delinvoice('test_attempt_notifications2', "unpaid")
859+
860+
# Final node failure
861+
with pytest.raises(RpcError, match=r"Destination said it doesn't know invoice: incorrect_or_unknown_payment_details"):
862+
l1.rpc.xpay(inv2['bolt11'])
863+
864+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_start: ")
865+
regex = r".*Got xpay_attempt_start: \{'payment_hash': '" + inv2['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1, 'total_payment_msat': 10000000, 'attempt_msat': 10000000, 'hops': \[\{'next_node': '" + l2.info['id'] + r"', 'short_channel_id': '" + scid12 + r"', 'direction': " + str(scid12_dir) + r", 'channel_in_msat': 10000101, 'channel_out_msat': 10000101\}, \{'next_node': '" + l3.info['id'] + r"', 'short_channel_id': '" + scid23 + r"', 'direction': " + str(scid23_dir) + r", 'channel_in_msat': 10000101, 'channel_out_msat': 10000000\}\]\}"
866+
assert re.match(regex, line)
867+
868+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_end: ")
869+
regex = r".*Got xpay_attempt_end: \{'status': 'failure', 'payment_hash': '" + inv2['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1, 'failed_msg': '400f00000000009896800000006c', 'duration': [0-9]*\.[0-9]*, 'failed_node_id': '" + l3.info['id'] + r"', 'error_code': 16399, 'error_message': 'incorrect_or_unknown_payment_details'\}"
870+
assert re.match(regex, line)
871+
872+
# Intermediary node failure
873+
l3.stop()
874+
with pytest.raises(RpcError, match=r"Failed after 1 attempts"):
875+
l1.rpc.xpay(inv2['bolt11'])
876+
877+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_start: ")
878+
regex = r".*Got xpay_attempt_start: \{'payment_hash': '" + inv2['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1, 'total_payment_msat': 10000000, 'attempt_msat': 10000000, 'hops': \[\{'next_node': '" + l2.info['id'] + r"', 'short_channel_id': '" + scid12 + r"', 'direction': " + str(scid12_dir) + r", 'channel_in_msat': 10000101, 'channel_out_msat': 10000101\}, \{'next_node': '" + l3.info['id'] + r"', 'short_channel_id': '" + scid23 + r"', 'direction': " + str(scid23_dir) + r", 'channel_in_msat': 10000101, 'channel_out_msat': 10000000\}\]\}"
879+
assert re.match(regex, line)
880+
881+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_end: ")
882+
regex = r".*Got xpay_attempt_end: \{'status': 'failure', 'payment_hash': '" + inv2['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1, 'failed_msg': '1007[a-f0-9]*', 'duration': [0-9]*\.[0-9]{9}, 'failed_node_id': '" + l2.info['id'] + r"', 'failed_short_channel_id': '" + scid23 + r"', 'failed_direction': " + str(scid23_dir) + r", 'error_code': 4103, 'error_message': 'temporary_channel_failure'\}"
883+
assert re.match(regex, line)

0 commit comments

Comments
 (0)