98 lines
2.8 KiB
Python
Raw Normal View History

2024-07-05 16:56:36 -05:00
import sys
from hashlib import sha256
from random import randbytes
from typing import Self
import multiaddr
import trio
from constants import HASH_LENGTH, PROTOCOL_ID
2024-07-05 16:56:36 -05:00
from libp2p import host, new_host
from libp2p.network.stream.net_stream_interface import INetStream
from libp2p.peer.peerinfo import info_from_p2p_addr
class Executor:
"""
A class for simulating a simple executor.
Runs on hardcoded port.
Creates random data and disperses it.
One packet represents a subnet, and each packet is sent
to one DANode.
2024-07-05 16:56:36 -05:00
"""
listen_addr: multiaddr.Multiaddr
host: host
port: int
2024-07-10 18:41:50 -05:00
num_subnets: int
2024-07-09 19:11:29 -05:00
node_list: {}
# size of a packet
data_size: int
# holds random data for dispersal
2024-07-05 16:56:36 -05:00
data: []
# stores hashes of the data for later verification
2024-07-05 16:56:36 -05:00
data_hashes: []
@classmethod
2024-07-10 18:41:50 -05:00
def new(cls, port, node_list, num_subnets, data_size) -> Self:
2024-07-05 16:56:36 -05:00
self = cls()
self.listen_addr = multiaddr.Multiaddr(f"/ip4/0.0.0.0/tcp/{port}")
self.host = new_host()
self.port = port
2024-07-10 18:41:50 -05:00
self.num_subnets = num_subnets
self.data_size = data_size
# one packet per subnet
2024-07-10 18:41:50 -05:00
self.data = [[] * data_size] * num_subnets
# one hash per packet. **assumes 256 hash length**
self.data_hashes = [[] * HASH_LENGTH] * num_subnets
2024-07-05 16:56:36 -05:00
self.node_list = node_list
# create random simulated data right from the beginning
2024-07-05 16:56:36 -05:00
self.__create_data()
return self
def get_id(self):
return self.host.get_id()
def net_iface(self):
return self.host
def get_port(self):
return self.port
def get_hash(self, index: int):
return self.data_hashes[index]
2024-07-05 16:56:36 -05:00
def __create_data(self):
"""
Create random data for dispersal
One packet of self.data_size length per subnet
"""
2024-07-10 18:41:50 -05:00
for i in range(self.num_subnets):
self.data[i] = randbytes(self.data_size)
2024-07-05 16:56:36 -05:00
self.data_hashes[i] = sha256(self.data[i]).hexdigest()
async def disperse(self, nursery):
"""
Disperse the data to the DA network.
Sends one packet of data per network node
"""
2024-07-05 16:56:36 -05:00
async with self.host.run(listen_addrs=[self.listen_addr]):
2024-07-09 19:11:29 -05:00
for subnet, nodes in self.node_list.items():
# get first node of each subnet
2024-07-09 19:11:29 -05:00
n = nodes[0]
# connect to it...
2024-07-05 16:56:36 -05:00
await self.host.connect(n)
# ...and send (async)
2024-07-05 16:56:36 -05:00
stream = await self.host.new_stream(n.peer_id, [PROTOCOL_ID])
2024-07-09 19:11:29 -05:00
nursery.start_soon(self.write_data, stream, subnet)
2024-07-05 16:56:36 -05:00
async def write_data(self, stream: INetStream, index: int) -> None:
"""
Send data to peer (async)
The index is the subnet number
"""
2024-07-05 16:56:36 -05:00
await stream.write(self.data[index])