model.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. # This file is part of DarkFi (https://dark.fi)
  2. #
  3. # Copyright (C) 2020-2024 Dyne.org foundation
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. import logging, time
  18. import datetime as dt
  19. from collections import defaultdict as dd
  20. class Model:
  21. def __init__(self):
  22. self.nodes = {}
  23. self.liliths = {}
  24. def add_node(self, node):
  25. channel_lookup = {}
  26. name = list(node.keys())[0]
  27. values = list(node.values())[0]
  28. info = values['result']
  29. channels = info['channels']
  30. self.nodes[name] = {}
  31. self.nodes[name]['outbound'] = {}
  32. self.nodes[name]['inbound'] = {}
  33. self.nodes[name]['manual'] = {}
  34. self.nodes[name]['event'] = {}
  35. self.nodes[name]['seed'] = {}
  36. self.nodes[name]['msgs'] = dd(list)
  37. for channel in channels:
  38. id = channel['id']
  39. channel_lookup[id] = channel
  40. for channel in channels:
  41. if channel['session'] != 'inbound':
  42. continue
  43. id = channel['id']
  44. url = channel_lookup[id]['url']
  45. self.nodes[name]['inbound'][f'{id}'] = url
  46. for i, id in enumerate(info['outbound_slots']):
  47. if id == 0:
  48. outbounds = self.nodes[name]['outbound'][f'{i}'] = ['none', 0]
  49. continue
  50. assert id in channel_lookup
  51. url = channel_lookup[id]['url']
  52. outbounds = self.nodes[name]['outbound'][f'{i}'] = [url, id]
  53. for channel in channels:
  54. if channel['session'] != 'seed':
  55. continue
  56. id = channel['id']
  57. url = channel['url']
  58. self.nodes[name]['seed'][f'{id}'] = url
  59. for channel in channels:
  60. if channel['session'] != 'manual':
  61. continue
  62. id = channel['id']
  63. url = channel['url']
  64. self.nodes[name]['manual'][f'{id}'] = url
  65. def add_offline(self, node, is_lilith: bool):
  66. name = list(node.keys())[0]
  67. values = list(node.values())[0]
  68. if is_lilith:
  69. self.liliths[name] = values
  70. else:
  71. self.nodes[name] = values
  72. def add_event(self, event):
  73. name = list(event.keys())[0]
  74. values = list(event.values())[0]
  75. params = values.get('params')
  76. event = params[0].get('event')
  77. info = params[0].get('info')
  78. t = time.localtime()
  79. current_time = time.strftime('%H:%M:%S', t)
  80. match event:
  81. case 'send':
  82. nano = info.get('time')
  83. cmd = info.get('cmd')
  84. chan = info.get('chan')
  85. addr = chan.get('addr')
  86. t = (dt.datetime
  87. .fromtimestamp(int(nano)/1000000000)
  88. .strftime('%H:%M:%S'))
  89. msgs = self.nodes[name]['msgs']
  90. msgs[addr].append((t, event, cmd))
  91. case 'recv':
  92. nano = info.get('time')
  93. cmd = info.get('cmd')
  94. chan = info.get('chan')
  95. addr = chan.get('addr')
  96. t = (dt.datetime
  97. .fromtimestamp(int(nano)/1000000000)
  98. .strftime('%H:%M:%S'))
  99. msgs = self.nodes[name]['msgs']
  100. msgs[addr].append((t, event, cmd))
  101. case 'inbound_connected':
  102. addr = info['addr']
  103. id = info.get('channel_id')
  104. self.nodes[name]['inbound'][f'{id}'] = addr
  105. logging.debug(f'{current_time} inbound (connect): {addr}')
  106. case 'inbound_disconnected':
  107. addr = info['addr']
  108. id = info.get('channel_id')
  109. self.nodes[name]['inbound'][f'{id}'] = {}
  110. logging.debug(f'{current_time} inbound (disconnect): {addr}')
  111. case 'outbound_slot_sleeping':
  112. slot = info['slot']
  113. event = self.nodes[name]['event']
  114. event[(f'{name}', f'{slot}')] = ['sleeping', 0]
  115. logging.debug(f'{current_time} slot {slot}: sleeping')
  116. case 'outbound_slot_connecting':
  117. slot = info['slot']
  118. addr = info['addr']
  119. event = self.nodes[name]['event']
  120. event[(f'{name}', f'{slot}')] = [f'connecting: addr={addr}', 0]
  121. logging.debug(f'{current_time} slot {slot}: connecting addr={addr}')
  122. case 'outbound_slot_connected':
  123. slot = info['slot']
  124. addr = info['addr']
  125. event = self.nodes[name]['event']
  126. event[(f'{name}', f'{slot}')] = [f'connected: addr={addr}', 0]
  127. id = info['channel_id']
  128. self.nodes[name]['outbound'][f'{slot}'] = [addr, id]
  129. logging.debug(f'{current_time} slot {slot}: connected addr={addr}')
  130. case 'outbound_slot_disconnected':
  131. slot = info['slot']
  132. err = info['err']
  133. event = self.nodes[name]['event']
  134. event[(f'{name}', f'{slot}')] = [f'disconnected: {err}', 0]
  135. logging.debug(f'{current_time} slot {slot}: disconnected err={err}')
  136. case 'outbound_peer_discovery':
  137. attempt = info['attempt']
  138. state = info['state']
  139. event = self.nodes[name]['event']
  140. key = (f'{name}', 'outbound')
  141. event[key] = f'peer discovery: {state} (attempt {attempt})'
  142. logging.debug(f'{current_time} peer_discovery: {state} (attempt {attempt})')
  143. def add_lilith(self, lilith):
  144. key = list(lilith.keys())[0]
  145. values = list(lilith.values())[0]
  146. info = values['result']
  147. spawns = info['spawns']
  148. self.liliths[key] = {}
  149. self.liliths[key]['spawns'] = {}
  150. for (i, spawn) in enumerate(spawns):
  151. name = spawn['name']
  152. urls = spawn['urls']
  153. whitelist = spawn['whitelist']
  154. greylist = spawn['greylist']
  155. goldlist = spawn['goldlist']
  156. spawn = self.liliths[key]['spawns'][name] = {}
  157. spawn['urls'] = urls
  158. spawn['whitelist'] = whitelist
  159. spawn['greylist'] = greylist
  160. spawn['goldlist'] = goldlist
  161. #logging.debug(f'added lilith {self.liliths}')
  162. def __repr__(self):
  163. return f'{self.nodes}'
  164. return f'{self.liliths}'