model.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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):
  66. name = list(node.keys())[0]
  67. values = list(node.values())[0]
  68. self.nodes[name] = values
  69. def add_event(self, event):
  70. name = list(event.keys())[0]
  71. values = list(event.values())[0]
  72. params = values.get('params')
  73. event = params[0].get('event')
  74. info = params[0].get('info')
  75. t = time.localtime()
  76. current_time = time.strftime('%H:%M:%S', t)
  77. match event:
  78. case 'send':
  79. nano = info.get('time')
  80. cmd = info.get('cmd')
  81. chan = info.get('chan')
  82. addr = chan.get('addr')
  83. t = (dt.datetime
  84. .fromtimestamp(int(nano)/1000000000)
  85. .strftime('%H:%M:%S'))
  86. msgs = self.nodes[name]['msgs']
  87. msgs[addr].append((t, event, cmd))
  88. case 'recv':
  89. nano = info.get('time')
  90. cmd = info.get('cmd')
  91. chan = info.get('chan')
  92. addr = chan.get('addr')
  93. t = (dt.datetime
  94. .fromtimestamp(int(nano)/1000000000)
  95. .strftime('%H:%M:%S'))
  96. msgs = self.nodes[name]['msgs']
  97. msgs[addr].append((t, event, cmd))
  98. case 'inbound_connected':
  99. addr = info['addr']
  100. id = info.get('channel_id')
  101. self.nodes[name]['inbound'][f'{id}'] = addr
  102. logging.debug(f'{current_time} inbound (connect): {addr}')
  103. case 'inbound_disconnected':
  104. addr = info['addr']
  105. id = info.get('channel_id')
  106. self.nodes[name]['inbound'][f'{id}'] = {}
  107. logging.debug(f'{current_time} inbound (disconnect): {addr}')
  108. case 'outbound_slot_sleeping':
  109. slot = info['slot']
  110. event = self.nodes[name]['event']
  111. event[(f'{name}', f'{slot}')] = ['sleeping', 0]
  112. logging.debug(f'{current_time} slot {slot}: sleeping')
  113. case 'outbound_slot_connecting':
  114. slot = info['slot']
  115. addr = info['addr']
  116. event = self.nodes[name]['event']
  117. event[(f'{name}', f'{slot}')] = [f'connecting: addr={addr}', 0]
  118. logging.debug(f'{current_time} slot {slot}: connecting addr={addr}')
  119. case 'outbound_slot_connected':
  120. slot = info['slot']
  121. addr = info['addr']
  122. id = info['channel_id']
  123. self.nodes[name]['outbound'][f'{slot}'] = [addr, id]
  124. logging.debug(f'{current_time} slot {slot}: connected addr={addr}')
  125. case 'outbound_slot_disconnected':
  126. slot = info['slot']
  127. err = info['err']
  128. event = self.nodes[name]['event']
  129. event[(f'{name}', f'{slot}')] = [f'disconnected: {err}', 0]
  130. logging.debug(f'{current_time} slot {slot}: disconnected err={err}')
  131. case 'outbound_peer_discovery':
  132. attempt = info['attempt']
  133. state = info['state']
  134. event = self.nodes[name]['event']
  135. key = (f'{name}', 'outbound')
  136. event[key] = f'peer discovery: {state} (attempt {attempt})'
  137. logging.debug(f'{current_time} peer_discovery: {state} (attempt {attempt})')
  138. def add_lilith(self, lilith):
  139. #logging.debug(f'adding lilith {lilith}')
  140. key = list(lilith.keys())[0]
  141. values = list(lilith.values())[0]
  142. info = values['result']
  143. spawns = info['spawns']
  144. self.liliths[key] = {}
  145. self.liliths[key]['spawns'] = {}
  146. for (i, spawn) in enumerate(spawns):
  147. name = spawn['name']
  148. urls = spawn['urls']
  149. whitelist = spawn['whitelist']
  150. greylist = spawn['greylist']
  151. goldlist = spawn['goldlist']
  152. spawn = self.liliths[key]['spawns'][name] = {}
  153. spawn['urls'] = urls
  154. spawn['whitelist'] = whitelist
  155. spawn['greylist'] = greylist
  156. spawn['goldlist'] = goldlist
  157. #logging.debug(f'added lilith {self.liliths}')
  158. def __repr__(self):
  159. return f'{self.nodes}'
  160. return f'{self.liliths}'