Skip to content

Commit d2a9afd

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 7b08aff commit d2a9afd

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-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: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,3 +831,52 @@ 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", 'amount_with_fees_msat': 5000051, 'amount_reaching_next_node_msat': 5000051\}, \{'next_node': '" + l3.info['id'] + r"', 'short_channel_id': '" + scid23 + r"', 'direction': " + str(scid23_dir) + r", 'amount_with_fees_msat': 5000051, 'amount_reaching_next_node_msat': 5000000\}\]\}"
850+
assert re.match(regex, line)
851+
852+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_end: ")
853+
regex = r".*Got xpay_attempt_end: \{'status': 'success', 'duration': [0-9]*\.[0-9]{9}, 'payment_hash': '" + inv1['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1\}"
854+
assert re.match(regex, line)
855+
856+
inv2 = l3.rpc.invoice(10000000, 'test_attempt_notifications2', 'test_attempt_notifications2')
857+
l3.rpc.delinvoice('test_attempt_notifications2', "unpaid")
858+
859+
# Final node failure
860+
with pytest.raises(RpcError, match=r"Destination said it doesn't know invoice: incorrect_or_unknown_payment_details"):
861+
l1.rpc.xpay(inv2['bolt11'])
862+
863+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_start: ")
864+
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", 'amount_with_fees_msat': 10000101, 'amount_reaching_next_node_msat': 10000101\}, \{'next_node': '" + l3.info['id'] + r"', 'short_channel_id': '" + scid23 + r"', 'direction': " + str(scid23_dir) + r", 'amount_with_fees_msat': 10000101, 'amount_reaching_next_node_msat': 10000000\}\]\}"
865+
assert re.match(regex, line)
866+
867+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_end: ")
868+
regex = r".*Got xpay_attempt_end: \{'status': 'failure', 'payment_hash': '" + inv2['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1, 'duration': [0-9]*\.[0-9]{9}, 'failed_node_id': '" + l3.info['id'] + r"', 'error_code': 16399, 'error_message': 'incorrect_or_unknown_payment_details'\}"
869+
assert re.match(regex, line)
870+
871+
# Intermediary node failure
872+
l3.stop()
873+
with pytest.raises(RpcError, match=r"Failed after 1 attempts"):
874+
l1.rpc.xpay(inv2['bolt11'])
875+
876+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_start: ")
877+
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", 'amount_with_fees_msat': 10000101, 'amount_reaching_next_node_msat': 10000101\}, \{'next_node': '" + l3.info['id'] + r"', 'short_channel_id': '" + scid23 + r"', 'direction': " + str(scid23_dir) + r", 'amount_with_fees_msat': 10000101, 'amount_reaching_next_node_msat': 10000000\}\]\}"
878+
assert re.match(regex, line)
879+
880+
line = l1.daemon.wait_for_log("plugin-custom_notifications.py: Got xpay_attempt_end: ")
881+
regex = r".*Got xpay_attempt_end: \{'status': 'failure', 'payment_hash': '" + inv2['payment_hash'] + r"', 'groupid': [0-9]*, 'partid': 1, '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'\}"
882+
assert re.match(regex, line)

0 commit comments

Comments
 (0)