distributed-state-network 0.6.2__tar.gz → 0.6.4__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.
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/PKG-INFO +1 -1
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/pyproject.toml +1 -1
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/handler.py +14 -2
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/tests/test.py +53 -1
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/.github/workflows/publish.yml +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/.gitignore +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/LICENSE +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/README.md +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/coverage.sh +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/ds-node-config.md +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/ds-node-server.md +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/ds-node.md +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/protocol.md +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/usage.md +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/__init__.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/create_key.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/dsnode.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/objects/config.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/objects/data_packet.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/objects/endpoint.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/objects/hello_packet.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/objects/msg_types.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/objects/peers_packet.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/objects/signed_packet.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/objects/state_packet.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/util/__init__.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/util/aes.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/util/byte_helper.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/util/ecdsa.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/util/https.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/src/distributed_state_network/util/key_manager.py +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/technical.md +0 -0
- {distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/tests/connections.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: distributed-state-network
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.4
|
|
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.6.
|
|
7
|
+
version = "0.6.4"
|
|
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"]
|
|
@@ -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.6.
|
|
11
|
+
VERSION = "0.6.4"
|
|
12
12
|
logging.basicConfig(level=logging.INFO)
|
|
13
13
|
|
|
14
14
|
# Silence Flask and Werkzeug logging
|
|
@@ -19,6 +19,7 @@ MSG_HELLO = 1
|
|
|
19
19
|
MSG_PEERS = 2
|
|
20
20
|
MSG_UPDATE = 3
|
|
21
21
|
MSG_PING = 4
|
|
22
|
+
MSG_DATA = 5
|
|
22
23
|
|
|
23
24
|
class DSNodeServer:
|
|
24
25
|
def __init__(
|
|
@@ -60,6 +61,11 @@ class DSNodeServer:
|
|
|
60
61
|
def handle_ping_route():
|
|
61
62
|
return self._handle_request(MSG_PING, request.data, request.remote_addr)
|
|
62
63
|
|
|
64
|
+
@self.app.route('/data', methods=['POST'])
|
|
65
|
+
def handle_data_route():
|
|
66
|
+
return self._handle_request(MSG_DATA, request.data, request.remote_addr)
|
|
67
|
+
|
|
68
|
+
|
|
63
69
|
def _handle_request(self, msg_type: int, data: bytes, remote_addr: str) -> Response:
|
|
64
70
|
if not self.running:
|
|
65
71
|
return Response(status=500)
|
|
@@ -94,6 +100,9 @@ class DSNodeServer:
|
|
|
94
100
|
|
|
95
101
|
elif msg_type == MSG_PING:
|
|
96
102
|
response_data = b''
|
|
103
|
+
|
|
104
|
+
elif msg_type == MSG_DATA:
|
|
105
|
+
response_data = self.node.receive_data(body)
|
|
97
106
|
|
|
98
107
|
# Send response if handler returned data
|
|
99
108
|
if response_data is not None:
|
|
@@ -180,4 +189,7 @@ class DSNodeServer:
|
|
|
180
189
|
self.node.update_cb = cb
|
|
181
190
|
|
|
182
191
|
def set_disconnect_cb(self, cb: Callable):
|
|
183
|
-
self.node.disconnect_cb = cb
|
|
192
|
+
self.node.disconnect_cb = cb
|
|
193
|
+
|
|
194
|
+
def receive_data(self, data: bytes):
|
|
195
|
+
self.node.receive_cb(data)
|
|
@@ -13,6 +13,7 @@ from distributed_state_network import DSNodeServer, Endpoint, DSNodeConfig
|
|
|
13
13
|
|
|
14
14
|
from distributed_state_network.objects.state_packet import StatePacket
|
|
15
15
|
from distributed_state_network.objects.hello_packet import HelloPacket
|
|
16
|
+
from distributed_state_network.objects.data_packet import DataPacket
|
|
16
17
|
|
|
17
18
|
from distributed_state_network.util.aes import generate_aes_key
|
|
18
19
|
|
|
@@ -481,7 +482,7 @@ class TestNode(unittest.TestCase):
|
|
|
481
482
|
n = spawn_node("http-test-node")
|
|
482
483
|
|
|
483
484
|
# Test that all endpoints exist
|
|
484
|
-
endpoints = ['/hello', '/peers', '/update', '/ping']
|
|
485
|
+
endpoints = ['/hello', '/peers', '/update', '/ping', '/data']
|
|
485
486
|
|
|
486
487
|
for endpoint in endpoints:
|
|
487
488
|
# Send a request to each endpoint (will fail due to encryption, but should return 400/500, not 404)
|
|
@@ -497,5 +498,56 @@ class TestNode(unittest.TestCase):
|
|
|
497
498
|
except Exception as e:
|
|
498
499
|
print(f"Endpoint {endpoint} test failed: {e}")
|
|
499
500
|
|
|
501
|
+
def test_send_to_node_success(self):
|
|
502
|
+
bootstrap = spawn_node("bootstrap")
|
|
503
|
+
connector = spawn_node("connector", [bootstrap.node.my_con().to_json()])
|
|
504
|
+
|
|
505
|
+
# Direct DSNode API
|
|
506
|
+
resp = connector.node.send_to_node("bootstrap", b"Hello, world!")
|
|
507
|
+
self.assertEqual(resp, "OK")
|
|
508
|
+
|
|
509
|
+
def test_send_to_node_wrapper(self):
|
|
510
|
+
bootstrap = spawn_node("bootstrap")
|
|
511
|
+
connector = spawn_node("connector", [bootstrap.node.my_con().to_json()])
|
|
512
|
+
|
|
513
|
+
# DSNodeServer wrapper
|
|
514
|
+
resp = connector.send_to_node("bootstrap", b"Hello via wrapper")
|
|
515
|
+
self.assertEqual(resp, "OK")
|
|
516
|
+
|
|
517
|
+
def test_data_route_unknown_sender(self):
|
|
518
|
+
# Start a single node; it should reject data packets from unknown senders
|
|
519
|
+
n = spawn_node("node")
|
|
520
|
+
time.sleep(0.5) # Allow server to start
|
|
521
|
+
|
|
522
|
+
# Craft a DataPacket with a node_id that's not in address book
|
|
523
|
+
pkt = DataPacket("unknown", b"", b"payload")
|
|
524
|
+
encrypted = n.node.encrypt_data(bytes([5]) + pkt.to_bytes()) # MSG_DATA = 5
|
|
525
|
+
|
|
526
|
+
response = requests.post(
|
|
527
|
+
f'http://127.0.0.1:{n.config.port}/data',
|
|
528
|
+
data=encrypted,
|
|
529
|
+
headers={'Content-Type': 'application/octet-stream'},
|
|
530
|
+
timeout=2
|
|
531
|
+
)
|
|
532
|
+
self.assertEqual(response.status_code, 401)
|
|
533
|
+
|
|
534
|
+
def test_data_route_bad_signature(self):
|
|
535
|
+
# Connect two nodes so bootstrap knows connector's public key
|
|
536
|
+
bootstrap = spawn_node("bootstrap")
|
|
537
|
+
connector = spawn_node("connector", [bootstrap.node.my_con().to_json()])
|
|
538
|
+
|
|
539
|
+
# Create a packet claiming to be from connector but without a valid signature
|
|
540
|
+
pkt = DataPacket("connector", b"", b"payload")
|
|
541
|
+
encrypted = bootstrap.node.encrypt_data(bytes([5]) + pkt.to_bytes()) # MSG_DATA = 5
|
|
542
|
+
|
|
543
|
+
response = requests.post(
|
|
544
|
+
f'http://127.0.0.1:{bootstrap.config.port}/data',
|
|
545
|
+
data=encrypted,
|
|
546
|
+
headers={'Content-Type': 'application/octet-stream'},
|
|
547
|
+
timeout=2
|
|
548
|
+
)
|
|
549
|
+
# Should be unauthorized due to bad signature
|
|
550
|
+
self.assertEqual(response.status_code, 401)
|
|
551
|
+
|
|
500
552
|
if __name__ == "__main__":
|
|
501
553
|
unittest.main()
|
{distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/.github/workflows/publish.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/ds-node-config.md
RENAMED
|
File without changes
|
{distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/ds-node-server.md
RENAMED
|
File without changes
|
{distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/ds-node.md
RENAMED
|
File without changes
|
{distributed_state_network-0.6.2 → distributed_state_network-0.6.4}/documentation/protocol.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|