77 sync_blockheight ,
88)
99
10+ import ast
1011import os
1112import pytest
1213import re
@@ -835,6 +836,19 @@ def test_xpay_twohop_bug(node_factory, bitcoind):
835836
836837
837838def test_attempt_notifications (node_factory ):
839+ def zero_fields (obj , fieldnames ):
840+ if isinstance (obj , dict ):
841+ for k , v in obj .items ():
842+ if k in fieldnames :
843+ obj [k ] = 0
844+ else :
845+ zero_fields (v , fieldnames )
846+ elif isinstance (obj , list ):
847+ for item in obj :
848+ zero_fields (item , fieldnames )
849+ # other types are ignored
850+ return obj
851+
838852 plugin_path = os .path .join (os .getcwd (), 'tests/plugins/custom_notifications.py' )
839853 l1 , l2 , l3 = node_factory .line_graph (3 , wait_for_announce = True ,
840854 opts = [{"plugin" : plugin_path }, {}, {}])
@@ -847,13 +861,34 @@ def test_attempt_notifications(node_factory):
847861 l1 .rpc .xpay (inv1 ['bolt11' ])
848862
849863 line = l1 .daemon .wait_for_log ("plugin-custom_notifications.py: Got pay_part_start: " )
850- regex = r".*Got pay_part_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\}\]\}"
851- assert re .match (regex , line )
864+ dict_str = line .split ("Got pay_part_start: " , 1 )[1 ]
865+ data = zero_fields (ast .literal_eval (dict_str ), ['groupid' ])
866+ expected = {'payment_hash' : inv1 ['payment_hash' ],
867+ 'groupid' : 0 ,
868+ 'partid' : 1 ,
869+ 'total_payment_msat' : 5000000 ,
870+ 'attempt_msat' : 5000000 ,
871+ 'hops' : [{'next_node' : l2 .info ['id' ],
872+ 'short_channel_id' : scid12 ,
873+ 'direction' : scid12_dir ,
874+ 'channel_in_msat' : 5000051 ,
875+ 'channel_out_msat' : 5000051 },
876+ {'next_node' : l3 .info ['id' ],
877+ 'short_channel_id' : scid23 ,
878+ 'direction' : scid23_dir ,
879+ 'channel_in_msat' : 5000051 ,
880+ 'channel_out_msat' : 5000000 }]}
881+ assert data == expected
852882
853- # 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.
854883 line = l1 .daemon .wait_for_log ("plugin-custom_notifications.py: Got pay_part_end: " )
855- regex = r".*Got pay_part_end: \{'status': 'success', 'duration': [0-9]*\.[0-9]*, 'payment_hash': '" + inv1 ['payment_hash' ] + r"', 'groupid': [0-9]*, 'partid': 1\}"
856- assert re .match (regex , line )
884+ dict_str = line .split ("Got pay_part_end: " , 1 )[1 ]
885+ data = zero_fields (ast .literal_eval (dict_str ), ('duration' , 'groupid' ))
886+ expected = {'payment_hash' : inv1 ['payment_hash' ],
887+ 'status' : 'success' ,
888+ 'duration' : 0 ,
889+ 'groupid' : 0 ,
890+ 'partid' : 1 }
891+ assert data == expected
857892
858893 inv2 = l3 .rpc .invoice (10000000 , 'test_attempt_notifications2' , 'test_attempt_notifications2' )
859894 l3 .rpc .delinvoice ('test_attempt_notifications2' , "unpaid" )
@@ -863,22 +898,77 @@ def test_attempt_notifications(node_factory):
863898 l1 .rpc .xpay (inv2 ['bolt11' ])
864899
865900 line = l1 .daemon .wait_for_log ("plugin-custom_notifications.py: Got pay_part_start: " )
866- regex = r".*Got pay_part_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\}\]\}"
867- assert re .match (regex , line )
901+ dict_str = line .split ("Got pay_part_start: " , 1 )[1 ]
902+ data = zero_fields (ast .literal_eval (dict_str ), ['groupid' ])
903+ expected = {'payment_hash' : inv2 ['payment_hash' ],
904+ 'groupid' : 0 ,
905+ 'partid' : 1 ,
906+ 'total_payment_msat' : 10000000 ,
907+ 'attempt_msat' : 10000000 ,
908+ 'hops' : [{'next_node' : l2 .info ['id' ],
909+ 'short_channel_id' : scid12 ,
910+ 'direction' : scid12_dir ,
911+ 'channel_in_msat' : 10000101 ,
912+ 'channel_out_msat' : 10000101 },
913+ {'next_node' : l3 .info ['id' ],
914+ 'short_channel_id' : scid23 ,
915+ 'direction' : scid23_dir ,
916+ 'channel_in_msat' : 10000101 ,
917+ 'channel_out_msat' : 10000000 }]}
918+ assert data == expected
868919
869920 line = l1 .daemon .wait_for_log ("plugin-custom_notifications.py: Got pay_part_end: " )
870- regex = r".*Got pay_part_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'\}"
871- assert re .match (regex , line )
921+ dict_str = line .split ("Got pay_part_end: " , 1 )[1 ]
922+ data = zero_fields (ast .literal_eval (dict_str ), ('duration' , 'groupid' ))
923+ expected = {'payment_hash' : inv2 ['payment_hash' ],
924+ 'status' : 'failure' ,
925+ 'duration' : 0 ,
926+ 'groupid' : 0 ,
927+ 'partid' : 1 ,
928+ 'failed_msg' : '400f00000000009896800000006c' ,
929+ 'failed_node_id' : l3 .info ['id' ],
930+ 'error_code' : 16399 ,
931+ 'error_message' : 'incorrect_or_unknown_payment_details' }
932+ assert data == expected
872933
873934 # Intermediary node failure
874935 l3 .stop ()
875936 with pytest .raises (RpcError , match = r"Failed after 1 attempts" ):
876937 l1 .rpc .xpay (inv2 ['bolt11' ])
877938
878939 line = l1 .daemon .wait_for_log ("plugin-custom_notifications.py: Got pay_part_start: " )
879- regex = r".*Got pay_part_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\}\]\}"
880- assert re .match (regex , line )
940+ dict_str = line .split ("Got pay_part_start: " , 1 )[1 ]
941+ data = zero_fields (ast .literal_eval (dict_str ), ['groupid' ])
942+ expected = {'payment_hash' : inv2 ['payment_hash' ],
943+ 'groupid' : 0 ,
944+ 'partid' : 1 ,
945+ 'total_payment_msat' : 10000000 ,
946+ 'attempt_msat' : 10000000 ,
947+ 'hops' : [{'next_node' : l2 .info ['id' ],
948+ 'short_channel_id' : scid12 ,
949+ 'direction' : scid12_dir ,
950+ 'channel_in_msat' : 10000101 ,
951+ 'channel_out_msat' : 10000101 },
952+ {'next_node' : l3 .info ['id' ],
953+ 'short_channel_id' : scid23 ,
954+ 'direction' : scid23_dir ,
955+ 'channel_in_msat' : 10000101 ,
956+ 'channel_out_msat' : 10000000 }]}
957+ assert data == expected
881958
882959 line = l1 .daemon .wait_for_log ("plugin-custom_notifications.py: Got pay_part_end: " )
883- regex = r".*Got pay_part_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]*, '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'\}"
884- assert re .match (regex , line )
960+ dict_str = line .split ("Got pay_part_end: " , 1 )[1 ]
961+ data = zero_fields (ast .literal_eval (dict_str ), ('duration' , 'groupid' , 'failed_msg' ))
962+ expected = {'payment_hash' : inv2 ['payment_hash' ],
963+ 'status' : 'failure' ,
964+ 'duration' : 0 ,
965+ 'groupid' : 0 ,
966+ 'partid' : 1 ,
967+ # This includes the channel update: just zero it out
968+ 'failed_msg' : 0 ,
969+ 'failed_direction' : 0 ,
970+ 'failed_node_id' : l2 .info ['id' ],
971+ 'failed_short_channel_id' : scid23 ,
972+ 'error_code' : 4103 ,
973+ 'error_message' : 'temporary_channel_failure' }
974+ assert data == expected
0 commit comments