model.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. # This file is part of DarkFi (https://dark.fi)
  2. #
  3. # Copyright (C) 2020-2023 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. def add_node(self, node):
  24. channel_lookup = {}
  25. name = list(node.keys())[0]
  26. values = list(node.values())[0]
  27. info = values["result"]
  28. channels = info["channels"]
  29. self.nodes[name] = {}
  30. self.nodes[name]['outbound'] = {}
  31. self.nodes[name]['inbound'] = {}
  32. self.nodes[name]['manual'] = {}
  33. self.nodes[name]['event'] = {}
  34. self.nodes[name]['seed'] = {}
  35. self.nodes[name]['msgs'] = dd(list)
  36. for channel in channels:
  37. id = channel["id"]
  38. channel_lookup[id] = channel
  39. for channel in channels:
  40. if channel["session"] != "inbound":
  41. continue
  42. id = channel["id"]
  43. url = channel_lookup[id]["url"]
  44. self.nodes[name]['inbound'][f"{id}"] = url
  45. for i, id in enumerate(info["outbound_slots"]):
  46. if id == 0:
  47. outbounds = self.nodes[name]['outbound'][f"{i}"] = "none"
  48. continue
  49. assert id in channel_lookup
  50. url = channel_lookup[id]["url"]
  51. outbounds = self.nodes[name]['outbound'][f"{i}"] = url
  52. for channel in channels:
  53. if channel["session"] != "seed":
  54. continue
  55. id = channel["id"]
  56. url = channel["url"]
  57. self.nodes[name]['seed'][f"{id}"] = url
  58. for channel in channels:
  59. if channel["session"] != "manual":
  60. continue
  61. id = channel["id"]
  62. url = channel["url"]
  63. self.nodes[name]['manual'][f"{id}"] = url
  64. def add_event(self, event):
  65. name = list(event.keys())[0]
  66. values = list(event.values())[0]
  67. params = values.get("params")
  68. event = params[0].get("event")
  69. info = params[0].get("info")
  70. t = time.localtime()
  71. current_time = time.strftime("%H:%M:%S", t)
  72. match event:
  73. case "send":
  74. nano = info.get("time")
  75. cmd = info.get("cmd")
  76. chan = info.get("chan")
  77. addr = chan.get("addr")
  78. t = (dt.datetime
  79. .fromtimestamp(int(nano)/1000000000)
  80. .strftime('%H:%M:%S'))
  81. msgs = self.nodes[name]['msgs']
  82. msgs[addr].append((t, event, cmd))
  83. case "recv":
  84. nano = info.get("time")
  85. cmd = info.get("cmd")
  86. chan = info.get("chan")
  87. addr = chan.get("addr")
  88. t = (dt.datetime
  89. .fromtimestamp(int(nano)/1000000000)
  90. .strftime('%H:%M:%S'))
  91. msgs = self.nodes[name]['msgs']
  92. msgs[addr].append((t, event, cmd))
  93. case "inbound_connected":
  94. addr = info["addr"]
  95. id = info.get("channel_id")
  96. self.nodes[name]['inbound'][f"{id}"] = addr
  97. logging.debug(f"{current_time} inbound (connect): {addr}")
  98. case "inbound_disconnected":
  99. addr = info["addr"]
  100. id = info.get("channel_id")
  101. inbound = self.nodes[name]['inbound']
  102. del inbound[f"{id}"]
  103. logging.debug(f"{current_time} inbound (disconnect): {addr}")
  104. case "outbound_slot_sleeping":
  105. slot = info["slot"]
  106. logging.debug(f"{current_time} slot {slot}: sleeping")
  107. self.nodes[name]['event'][(f"{name}", f"{slot}")] = "sleeping"
  108. case "outbound_slot_connecting":
  109. slot = info["slot"]
  110. addr = info["addr"]
  111. event = self.nodes[name]['event']
  112. event[(f"{name}", f"{slot}")] = f"connecting: addr={addr}"
  113. logging.debug(f"{current_time} slot {slot}: connecting addr={addr}")
  114. case "outbound_slot_connected":
  115. slot = info["slot"]
  116. addr = info["addr"]
  117. channel_id = info["channel_id"]
  118. event = self.nodes[name]['event']
  119. event[(f"{name}", f"{slot}")] = f"connected: addr={addr}"
  120. logging.debug(f"{current_time} slot {slot}: connected addr={addr}")
  121. case "outbound_slot_disconnected":
  122. slot = info["slot"]
  123. err = info["err"]
  124. event = self.nodes[name]['event']
  125. event[(f"{name}", f"{slot}")] = f"disconnected: {err}"
  126. logging.debug(f"{current_time} slot {slot}: disconnected err='{err}'")
  127. case "outbound_peer_discovery":
  128. attempt = info["attempt"]
  129. state = info["state"]
  130. event = self.nodes[name]['event']
  131. key = (f"{name}", "outbound")
  132. event[key] = f"peer discovery: {state} (attempt {attempt})"
  133. logging.debug(f"{current_time} peer_discovery: {state} (attempt {attempt})")
  134. def __repr__(self):
  135. return f"{self.nodes}"