Added peer exchange test (passing)

This commit is contained in:
Kevin F 2022-04-20 00:28:29 -05:00
parent 6a6460ef31
commit 237cdde4e5
10 changed files with 30 additions and 18 deletions

View File

@ -76,6 +76,8 @@ def gossip_client():
dandelion_phase = DandelionPhase(DANDELION_EPOCH_LENGTH) dandelion_phase = DandelionPhase(DANDELION_EPOCH_LENGTH)
while True: while True:
sleep(5)
continue
while not len(gossip_peer_set): while not len(gossip_peer_set):
sleep(0.2) sleep(0.2)
if dandelion_phase.remaining_time() <= 10: if dandelion_phase.remaining_time() <= 10:
@ -84,7 +86,7 @@ def gossip_client():
logger.debug("Entering stem phase", terminal=True) logger.debug("Entering stem phase", terminal=True)
try: try:
# Stem out blocks for (roughly) remaining epoch time # Stem out blocks for (roughly) remaining epoch time
asyncio.run(stem_out()) asyncio.run(stem_out(dandelion_phase))
except TimeoutError: except TimeoutError:
continue continue
except Exception: except Exception:

View File

@ -16,7 +16,7 @@ def do_announce():
"Announce with N peers of each identified transport" "Announce with N peers of each identified transport"
def _announce(announce_peer: 'Peer', our_transport_address: str): def _announce(announce_peer: 'Peer', our_transport_address: str):
try: try:
our_transport_address = our_transport_address.encode('utf-8') our_transport_address = our_transport_address.encode('utf-8') + b"\n"
except AttributeError: except AttributeError:
pass pass
sock = announce_peer.get_socket(12) sock = announce_peer.get_socket(12)

View File

@ -20,7 +20,11 @@ def _ask_peer(peer):
s.sendall(command_to_byte(GossipCommands.PEER_EXCHANGE)) s.sendall(command_to_byte(GossipCommands.PEER_EXCHANGE))
# Get 10 max peers # Get 10 max peers
for _ in range(MAX_PEERS): for _ in range(MAX_PEERS):
peer = s.recv(TRANSPORT_SIZE_BYTES) peer = b''
c = b''
while c != b'\n':
c = s.recv(1)
peer += c
if not peer: if not peer:
break break
connect_data = { connect_data = {
@ -54,7 +58,7 @@ def get_new_peers():
# Start threads to ask the peers for more peers # Start threads to ask the peers for more peers
threads = [] threads = []
for peer in peers_we_ask: for peer in peers_we_ask:
t = Thread(target=_ask_peer, args=[peer, gossip_peer_set], daemon=True) t = Thread(target=_ask_peer, args=[peer], daemon=True)
t.start() t.start()
threads.append(t) threads.append(t)
peers_we_ask.clear() peers_we_ask.clear()

View File

@ -59,6 +59,7 @@ def stream_from_peers():
need_socket_lock = Semaphore(MAX_STREAMS) need_socket_lock = Semaphore(MAX_STREAMS)
offset = 0 offset = 0
def _stream_from_peer(peer: Peer): def _stream_from_peer(peer: Peer):
try: try:
@ -83,11 +84,11 @@ def stream_from_peers():
"reported block size out of range") "reported block size out of range")
break break
block_data = sock.recv(block_size) block_data = sock.recv(block_size)
try: try:
blockdb.add_block_to_db( blockdb.add_block_to_db(
onionrblocks.Block( onionrblocks.Block(
block_id, block_data, auto_verify=True) block_id, block_data, auto_verify=True))
)
except Exception: except Exception:
# They gave us a bad block, kill the stream # They gave us a bad block, kill the stream
# Could be corruption or malice # Could be corruption or malice

View File

@ -8,7 +8,7 @@ def connect_peer(peer):
if peer in gossip_peer_set: if peer in gossip_peer_set:
return return
try: try:
s = peer.get_socket(12) s = peer.get_socket(15)
except Exception: except Exception:
logger.warn(f"Could not connect to {peer.transport_address}") logger.warn(f"Could not connect to {peer.transport_address}")
else: else:

View File

@ -1,4 +1,5 @@
import asyncio import asyncio
from audioop import add
import traceback import traceback
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Set, Tuple from typing import Set, Tuple
@ -63,8 +64,8 @@ def gossip_server():
pass pass
case GossipCommands.ANNOUNCE: case GossipCommands.ANNOUNCE:
async def _read_announce(): async def _read_announce():
address = await reader.readexactly( address = await reader.readuntil(b'\n')
constants.TRANSPORT_SIZE_BYTES)
if address: if address:
onionrevents.event( onionrevents.event(
'announce_rec', 'announce_rec',
@ -74,10 +75,10 @@ def gossip_server():
writer.write(int(1).to_bytes(1, 'big')) writer.write(int(1).to_bytes(1, 'big'))
await asyncio.wait_for(_read_announce(), 10) await asyncio.wait_for(_read_announce(), 10)
case GossipCommands.PEER_EXCHANGE: case GossipCommands.PEER_EXCHANGE:
for peer in gossip_peer_set: for peer in gossip_peer_set:
writer.write( writer.write(peer.transport_address.encode('utf-8') + b'\n')
peer.transport_address.encode( await writer.drain()
'utf-8').removesuffix(b'.onion'))
case GossipCommands.STREAM_BLOCKS: case GossipCommands.STREAM_BLOCKS:
try: try:
await diffuse_blocks(reader, writer) await diffuse_blocks(reader, writer)

View File

@ -70,6 +70,7 @@ async def diffuse_blocks(reader: 'StreamReader', writer: 'StreamWriter'):
return return
await writer.drain() await writer.drain()
# write block size
writer.write( writer.write(
str(len(block.raw)).zfill(BLOCK_MAX_SIZE_LEN).encode('utf-8')) str(len(block.raw)).zfill(BLOCK_MAX_SIZE_LEN).encode('utf-8'))
await writer.drain() await writer.drain()

View File

@ -3,7 +3,6 @@ import logger
from getsocks import get_socks from getsocks import get_socks
from torpeer import TorPeer from torpeer import TorPeer
from gossip.peerset import gossip_peer_set
def on_announce_rec(api, data=None): def on_announce_rec(api, data=None):
@ -16,11 +15,11 @@ def on_announce_rec(api, data=None):
pass pass
if announced == config.get('tor.transport_address'): if announced == config.get('tor.transport_address'):
logger.warn("Recieved announcement for our own node, which shouldnt happen") logger.warn(
"Received announcement for our own node, which shouldn't happen")
return return
announced = announced.strip()
announced += '.onion' announced += '.onion'
data['callback']( data['callback'](TorPeer(socks_address, socks_port, announced))
gossip_peer_set,
TorPeer(socks_address, socks_port, announced))

View File

@ -92,7 +92,7 @@ def on_gossip_start(api, data: Set[Peer] = None):
try: try:
add_onion_resp = controller.create_ephemeral_hidden_service( add_onion_resp = controller.create_ephemeral_hidden_service(
{'80': f'unix:{gossip_server_socket_file}'}, {'80': f'unix:{gossip_server_socket_file}'},
key_content=key, key_type='ED25519-V3', detached=True) key_content=key, key_type='ED25519-V3', detached=True, await_publication=True)
except stem.ProtocolError: except stem.ProtocolError:
logger.error( logger.error(
"Could not start Tor transport. Try restarting Onionr", "Could not start Tor transport. Try restarting Onionr",

View File

@ -6,11 +6,15 @@ class TorPeer:
def __init__(self, socks_host, socks_port, onion_address): def __init__(self, socks_host, socks_port, onion_address):
if not onion_address or onion_address == '.onion': if not onion_address or onion_address == '.onion':
raise ValueError("Invalid transport address") raise ValueError("Invalid transport address")
if not onion_address.endswith('.onion'):
self.onion_address = onion_address.strip() + '.onion'
self.transport_address = self.onion_address = onion_address self.transport_address = self.onion_address = onion_address
self.socks_host = socks_host self.socks_host = socks_host
self.socks_port = socks_port self.socks_port = socks_port
def get_socket(self, connect_timeout) -> socks.socksocket: def get_socket(self, connect_timeout) -> socks.socksocket:
s = socks.socksocket() s = socks.socksocket()
s.set_proxy(socks.SOCKS4, self.socks_host, self.socks_port, rdns=True) s.set_proxy(socks.SOCKS4, self.socks_host, self.socks_port, rdns=True)
s.settimeout(connect_timeout) s.settimeout(connect_timeout)