96 lines
3.1 KiB
Python
Raw Normal View History

2024-06-25 17:45:10 -05:00
import sys
2024-07-05 16:56:36 -05:00
from hashlib import sha256
2024-06-25 17:45:10 -05:00
from random import randint
2024-07-05 16:56:36 -05:00
import multiaddr
import trio
from blspy import BasicSchemeMPL, G1Element, PrivateKey
from constants import *
2024-07-05 16:56:36 -05:00
from libp2p import host, new_host
from libp2p.network.stream.exceptions import StreamReset
2024-07-05 16:56:36 -05:00
from libp2p.network.stream.net_stream_interface import INetStream
from libp2p.peer.peerinfo import info_from_p2p_addr
2024-06-25 17:45:10 -05:00
class DANode:
"""
A class handling Data Availability (DA)
"""
listen_addr: multiaddr.Multiaddr
2024-07-09 19:11:29 -05:00
libp2phost: host
2024-06-25 17:45:10 -05:00
port: int
node_list: []
hashes: set()
2024-06-25 17:45:10 -05:00
@classmethod
async def new(cls, port, node_list, nursery, shutdown):
2024-06-25 17:45:10 -05:00
self = cls()
self.listen_addr = multiaddr.Multiaddr(f"/ip4/0.0.0.0/tcp/{port}")
2024-07-09 19:11:29 -05:00
self.libp2phost = new_host()
2024-06-25 17:45:10 -05:00
self.port = port
self.node_list = node_list
self.hashes = set()
nursery.start_soon(self.__run, nursery, shutdown)
2024-06-25 17:45:10 -05:00
print("DA node at port {} initialized".format(port))
def get_id(self):
2024-07-09 19:11:29 -05:00
return self.libp2phost.get_id()
2024-06-25 17:45:10 -05:00
def net_iface(self):
2024-07-09 19:11:29 -05:00
return self.libp2phost
2024-06-25 17:45:10 -05:00
def get_port(self):
return self.port
async def __run(self, nursery, shutdown):
2024-07-05 16:56:36 -05:00
""" """
2024-07-09 19:11:29 -05:00
async with self.libp2phost.run(listen_addrs=[self.listen_addr]):
2024-06-25 17:45:10 -05:00
print("starting node at {}...".format(self.listen_addr))
2024-07-05 16:56:36 -05:00
async def stream_handler(stream: INetStream) -> None:
nursery.start_soon(self.read_data, stream, nursery, shutdown)
2024-06-25 17:45:10 -05:00
2024-07-09 19:11:29 -05:00
self.libp2phost.set_stream_handler(PROTOCOL_ID, stream_handler)
2024-06-25 17:45:10 -05:00
self.node_list.append(self)
await shutdown.wait()
2024-06-25 17:45:10 -05:00
async def read_data(self, stream: INetStream, nursery, shutdown) -> None:
first_event = None
async def select_event(async_fn, cancel_scope):
nonlocal first_event
first_event = await async_fn()
cancel_scope.cancel()
async def read_stream():
while True:
read_bytes = await stream.read(MAX_READ_LEN)
if read_bytes is not None:
hashstr = sha256(read_bytes).hexdigest()
2024-07-09 19:11:29 -05:00
if hashstr not in self.hashes:
self.hashes.add(hashstr)
nursery.start_soon(self.disperse, read_bytes)
if DEBUG:
print(
"{} stored {}".format(
self.libp2phost.get_id().pretty(), hashstr
)
)
else:
print("read_bytes is None, unexpected!")
2024-06-25 17:45:10 -05:00
nursery.start_soon(select_event, read_stream, nursery.cancel_scope)
nursery.start_soon(select_event, shutdown.wait, nursery.cancel_scope)
2024-07-09 19:11:29 -05:00
async def disperse(self, packet) -> None:
for p_id in self.libp2phost.get_peerstore().peer_ids():
if p_id == self.libp2phost.get_id():
continue
stream = await self.libp2phost.new_stream(p_id, [PROTOCOL_ID])
await stream.write(packet)
2024-06-25 17:45:10 -05:00
async def has_hash(self, hashstr: str):
return hashstr in self.hashes