@@ -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