distributed-state-network 0.5.4__tar.gz → 0.5.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/.gitignore +2 -1
  2. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/PKG-INFO +1 -1
  3. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/pyproject.toml +1 -1
  4. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/dsnode.py +30 -21
  5. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/handler.py +1 -1
  6. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/.github/workflows/publish.yml +0 -0
  7. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/LICENSE +0 -0
  8. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/README.md +0 -0
  9. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/coverage.sh +0 -0
  10. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/documentation/ds-node-config.md +0 -0
  11. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/documentation/ds-node-server.md +0 -0
  12. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/documentation/ds-node.md +0 -0
  13. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/documentation/protocol.md +0 -0
  14. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/documentation/usage.md +0 -0
  15. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/__init__.py +0 -0
  16. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/create_key.py +0 -0
  17. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/objects/config.py +0 -0
  18. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/objects/endpoint.py +0 -0
  19. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/objects/hello_packet.py +0 -0
  20. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/objects/msg_types.py +0 -0
  21. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/objects/peers_packet.py +0 -0
  22. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/objects/signed_packet.py +0 -0
  23. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/objects/state_packet.py +0 -0
  24. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/util/__init__.py +0 -0
  25. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/util/aes.py +0 -0
  26. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/util/byte_helper.py +0 -0
  27. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/util/ecdsa.py +0 -0
  28. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/util/https.py +0 -0
  29. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/src/distributed_state_network/util/key_manager.py +0 -0
  30. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/technical.md +0 -0
  31. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/tests/connections.py +0 -0
  32. {distributed_state_network-0.5.4 → distributed_state_network-0.5.6}/tests/test.py +0 -0
@@ -8,4 +8,5 @@ test.key
8
8
  count.py
9
9
  appended.py
10
10
  py_line_count_history.jsonl
11
- network.key
11
+ network.key
12
+ todo.txt
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: distributed-state-network
3
- Version: 0.5.4
3
+ Version: 0.5.6
4
4
  Summary: A tool to distribute the state of a network device to other devices on the network
5
5
  Project-URL: Homepage, https://github.com/erinclemmer/distributed_state_network
6
6
  Project-URL: Issues, https://github.com/erinclemmer/distributed_state_network/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "distributed-state-network"
7
- version = "0.5.4"
7
+ version = "0.5.6"
8
8
  authors = [{name="Erin Clemmer", email="erin.c.clemmer@gmail.com"}]
9
9
  description = "A tool to distribute the state of a network device to other devices on the network"
10
10
  keywords = ["distributed", "networking"]
@@ -73,8 +73,8 @@ class DSNode:
73
73
  return bytes.fromhex(self.config.aes_key)
74
74
 
75
75
  def write_address_book(self, node_id: str, conn: Endpoint):
76
- if conn.address == "127.0.0.1":
77
- return
76
+ if conn.address == "127.0.0.1" and conn.port == self.config.port:
77
+ raise Exception("Trying to write address book for self")
78
78
  self.logger.info(f"Address set: {node_id} -> {conn.address}:{conn.port}")
79
79
  self.address_book[node_id] = conn
80
80
 
@@ -90,8 +90,10 @@ class DSNode:
90
90
  def remove(node_id: str):
91
91
  if node_id in self.node_states:
92
92
  del self.node_states[node_id]
93
+ if node_id in self.address_book:
93
94
  del self.address_book[node_id]
94
- self.logger.info(f"PING failed for {node_id}, disconnecting...")
95
+ self.logger.info(f"PING failed for {node_id}, disconnecting...")
96
+
95
97
  for node_id in self.node_states.copy().keys():
96
98
  if node_id not in self.node_states or node_id == self.config.node_id:
97
99
  continue
@@ -245,10 +247,13 @@ class DSNode:
245
247
  self.write_address_book(pkt.node_id, con)
246
248
 
247
249
  if pkt.node_id not in self.node_states:
248
- self.node_states[pkt.node_id] = StatePacket(pkt.node_id, 0, b'', { })
250
+ self.init_state(pkt.node_id)
249
251
 
250
252
  return pkt.node_id
251
253
 
254
+ def init_state(self, node_id: str):
255
+ self.node_states[node_id] = StatePacket(node_id, 0, b'', { })
256
+
252
257
  def handle_hello(self, data: bytes, detected_address: str) -> bytes:
253
258
  pkt = HelloPacket.from_bytes(data)
254
259
  self.logger.info(f"Received HELLO from {pkt.node_id}")
@@ -261,7 +266,7 @@ class DSNode:
261
266
  self.write_address_book(pkt.node_id, Endpoint(detected_address, pkt.connection.port))
262
267
 
263
268
  if pkt.node_id not in self.node_states:
264
- self.node_states[pkt.node_id] = StatePacket(pkt.node_id, 0, b'', { })
269
+ self.init_state(pkt.node_id)
265
270
 
266
271
  # Create response with detected address
267
272
  response_pkt = self.my_hello_packet()
@@ -297,22 +302,7 @@ class DSNode:
297
302
  pkt = StatePacket.from_bytes(data)
298
303
  self.logger.info(f"Received UPDATE from {pkt.node_id}")
299
304
 
300
- # ignore if we accidentally sent an update to ourselves
301
- if pkt.node_id == self.config.node_id:
302
- raise Exception(406, "Origin and destination are the same") # Not acceptable
303
-
304
- # don't use packets older than last update
305
- if pkt.node_id in self.node_states and self.node_states[pkt.node_id].last_update > pkt.last_update:
306
- raise Exception(406, "Update is stale") # Not acceptable
307
-
308
- if not pkt.verify_signature(self.cred_manager.read_public(pkt.node_id)):
309
- raise Exception(401, "Could not verify ECDSA signature") # Not authorized
310
-
311
- if pkt.node_id not in self.node_states:
312
- self.node_states[pkt.node_id] = pkt
313
-
314
- if get_dict_hash(self.node_states[pkt.node_id].state_data) != get_dict_hash(pkt.state_data):
315
- self.node_states[pkt.node_id] = pkt
305
+ self.update_state(pkt)
316
306
 
317
307
  if self.update_cb is not None:
318
308
  try:
@@ -325,6 +315,25 @@ class DSNode:
325
315
 
326
316
  def my_state(self):
327
317
  return self.node_states[self.config.node_id]
318
+
319
+ def update_state(self, pkt: StatePacket):
320
+ # ignore if we accidentally sent an update to ourselves
321
+ if pkt.node_id == self.config.node_id:
322
+ raise Exception(406, "Origin and destination are the same") # Not acceptable
323
+
324
+ if pkt.node_id in self.address_book and not pkt.verify_signature(self.cred_manager.read_public(pkt.node_id)):
325
+ raise Exception(401, "Could not verify ECDSA signature") # Not authorized
326
+
327
+ if pkt.node_id in self.node_states:
328
+ current_state = self.node_states[pkt.node_id]
329
+
330
+ if current_state.last_update > pkt.last_update:
331
+ raise Exception(406, "Update is stale")
332
+
333
+ if len(pkt.state_data.keys()) > 0 and get_dict_hash(self.node_states[pkt.node_id].state_data) == get_dict_hash(pkt.state_data):
334
+ raise Exception(406, "Received duplicate packet")
335
+
336
+ self.node_states[pkt.node_id] = pkt
328
337
 
329
338
  def bootstrap(self, con: Endpoint):
330
339
  bootstrap_id = self.send_hello(con)
@@ -8,7 +8,7 @@ from distributed_state_network.objects.config import DSNodeConfig
8
8
  from distributed_state_network.util.aes import generate_aes_key
9
9
  from distributed_state_network.util import stop_thread
10
10
 
11
- VERSION = "0.5.4"
11
+ VERSION = "0.5.6"
12
12
  logging.basicConfig(level=logging.INFO)
13
13
 
14
14
  # Silence Flask and Werkzeug logging