@@ -831,3 +831,53 @@ def test_xpay_twohop_bug(node_factory, bitcoind):
831
831
# This doesn't!
832
832
l1 .rpc .xpay (inv )
833
833
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