@@ -445,6 +445,8 @@ def make_completion_dict(contacts, pending={}, to=None, channels=None):
445445 "upload_contact" : None ,
446446 "path" : None ,
447447 "disc_path" : None ,
448+ "trace" : None ,
449+ "dtrace" : None ,
448450 "reset_path" : None ,
449451 "change_path" : None ,
450452 "change_flags" : None ,
@@ -810,6 +812,15 @@ def _(event):
810812 await process_cmds (mc , ["cmd" , contact ["adv_name" ], newline ])
811813 except IndexError :
812814 print ("Wrong number of parameters" )
815+
816+ # trace called on a contact
817+ elif contact ["type" ] > 0 and (
818+ line == "trace" or line == "tr" ) :
819+ await print_trace_to (mc , contact )
820+
821+ elif contact ["type" ] > 0 and (
822+ line == "dtrace" or line == "dt" ) :
823+ await print_disc_trace_to (mc , contact )
813824
814825 # same but for commands with a parameter
815826 elif contact ["type" ] > 0 and (line .startswith ("cmd " ) or \
@@ -1064,6 +1075,70 @@ async def get_channels (mc, anim=False) :
10641075 print (" Done" )
10651076 return mc .channels
10661077
1078+ async def print_trace_to (mc , contact ):
1079+ path = contact ["out_path" ]
1080+ path_len = contact ["out_path_len" ]
1081+ trace = ""
1082+
1083+ if path_len == - 1 :
1084+ print ("No path to destination" )
1085+ return
1086+
1087+ if contact ["type" ] == 2 or contact ["type" ] == 3 :
1088+ # repeater or room, can trace to the contact itself
1089+ trace = contact ["public_key" ][0 :2 ]
1090+
1091+ for i in range (0 , path_len ):
1092+ elem = path [2 * (path_len - i - 1 ):2 * (path_len - i )]
1093+ trace = elem if trace == "" else f"{ elem } ,{ trace } ,{ elem } "
1094+
1095+ await next_cmd (mc , ["trace" , trace ])
1096+
1097+ async def discover_path (mc , contact ):
1098+ await mc .ensure_contacts ()
1099+ res = await mc .commands .send_path_discovery (contact )
1100+ if res .type == EventType .ERROR :
1101+ return None
1102+ else :
1103+ timeout = res .payload ["suggested_timeout" ]/ 600 if not "timeout" in contact or contact ['timeout' ]== 0 else contact ["timeout" ]
1104+ res = await mc .wait_for_event (EventType .PATH_RESPONSE , timeout = timeout )
1105+ if res is None :
1106+ return {"error" : "timeout" }
1107+ else :
1108+ return res .payload
1109+
1110+ async def print_disc_trace_to (mc , contact ):
1111+ p = await discover_path (mc , contact )
1112+ if p is None :
1113+ print ("Error discovering path" )
1114+ return
1115+
1116+ if "error" in p :
1117+ print ("Timeout discovering path" )
1118+ return
1119+
1120+ inp = p ["in_path" ]
1121+ outp = p ["out_path" ]
1122+ inp_l = int (len (inp )/ 2 )
1123+ outp_l = int (len (outp )/ 2 )
1124+
1125+ trace = ""
1126+
1127+ for i in range (0 , outp_l ):
1128+ elem = outp [2 * i :2 * (i + 1 )]
1129+ trace = elem if trace == "" else f"{ trace } ,{ elem } "
1130+
1131+ if contact ["type" ] == 2 or contact ["type" ] == 3 :
1132+ # repeater or room, can trace to the contact itself
1133+ elem = contact ["public_key" ][0 :2 ]
1134+ trace = elem if trace == "" else f"{ trace } ,{ elem } "
1135+
1136+ for i in range (0 , inp_l ):
1137+ elem = inp [2 * i :2 * (i + 1 )]
1138+ trace = elem if trace == "" else f"{ trace } ,{ elem } "
1139+
1140+ await next_cmd (mc , ["trace" , trace ])
1141+
10671142async def next_cmd (mc , cmds , json_output = False ):
10681143 """ process next command """
10691144 try :
@@ -1703,7 +1778,7 @@ async def next_cmd(mc, cmds, json_output=False):
17031778 print (res .payload )
17041779 print (json .dumps (res .payload , indent = 4 ))
17051780
1706- case "trace" :
1781+ case "trace" | "tr" :
17071782 argnum = 1
17081783 res = await mc .commands .send_trace (path = cmds [1 ])
17091784 if res and res .type != EventType .ERROR :
@@ -1716,7 +1791,7 @@ async def next_cmd(mc, cmds, json_output=False):
17161791 if json_output :
17171792 print (json .dumps ({"error" : "timeout waiting trace" }))
17181793 else :
1719- print ("Timeout waiting trace" )
1794+ print (f "Timeout waiting trace for path { cmds [ 1 ] } " )
17201795 elif ev .type == EventType .ERROR :
17211796 if json_output :
17221797 print (json .dumps (ev .payload ))
@@ -1840,26 +1915,19 @@ async def next_cmd(mc, cmds, json_output=False):
18401915 argnum = 1
18411916 await mc .ensure_contacts ()
18421917 contact = mc .get_contact_by_name (cmds [1 ])
1843- res = await mc .commands .send_path_discovery (contact )
1844- logger .debug (res )
1845- if res .type == EventType .ERROR :
1918+ res = await discover_path (mc , contact )
1919+ if res is None :
18461920 print (f"Error while discovering path" )
18471921 else :
1848- timeout = res .payload ["suggested_timeout" ]/ 800 if not "timeout" in contact or contact ['timeout' ]== 0 else contact ["timeout" ]
1849- res = await mc .wait_for_event (EventType .PATH_RESPONSE , timeout = timeout )
1850- logger .debug (res )
1851- if res is None :
1852- if json_output :
1853- print (json .dumps ({"error" : "Timeout discovering path" }))
1854- else :
1855- print ("Timeout discovering path" )
1856- else :
1857- if json_output :
1858- print (json .dumps (res .payload , indent = 4 ))
1922+ if json_output :
1923+ print (json .dumps (res , indent = 4 ))
1924+ else :
1925+ if "error" in res :
1926+ print ("Timeout while discovering path" )
18591927 else :
1860- outp = res . payload ['out_path' ]
1928+ outp = res ['out_path' ]
18611929 outp = outp if outp != "" else "direct"
1862- inp = res . payload ['in_path' ]
1930+ inp = res ['in_path' ]
18631931 inp = inp if inp != "" else "direct"
18641932 print (f"Path for { contact ['adv_name' ]} : out { outp } , in { inp } " )
18651933
@@ -2054,12 +2122,16 @@ async def next_cmd(mc, cmds, json_output=False):
20542122 else :
20552123 print (f"Unknown contact { cmds [1 ]} " )
20562124 else :
2057- res = await mc .commands .change_contact_path (contact , cmds [2 ])
2058- logger .debug (res )
2059- if res .type == EventType .ERROR :
2060- print (f"Error setting path: { res } " )
2061- elif json_output :
2062- print (json .dumps (res .payload , indent = 4 ))
2125+ path = cmds [2 ].replace ("," ,"" ) # we'll accept path with ,
2126+ try :
2127+ res = await mc .commands .change_contact_path (contact , path )
2128+ logger .debug (res )
2129+ if res .type == EventType .ERROR :
2130+ print (f"Error setting path: { res } " )
2131+ elif json_output :
2132+ print (json .dumps (res .payload , indent = 4 ))
2133+ except ValueError :
2134+ print (f"Bad path format { cmds [2 ]} " )
20632135
20642136 case "change_flags" | "cf" :
20652137 argnum = 2
0 commit comments