diff --git a/src/gossip/__init__.py b/src/gossip/__init__.py index d17b9dee..e1490fc3 100644 --- a/src/gossip/__init__.py +++ b/src/gossip/__init__.py @@ -11,6 +11,7 @@ if TYPE_CHECKING: from onionrthreads import add_onionr_thread import onionrplugins +from .connectpeer import connect_peer from .client import gossip_client from .server import gossip_server from .commands import GossipCommands @@ -46,5 +47,5 @@ def start_gossip_threads( add_onionr_thread( gossip_client, 1, peer_set, block_queue, seed, initial_sleep=0) onionrplugins.events.event('gossip_start', data=peer_set, threaded=True) - sleep(4) - onionrplugins.events.event('bootstrap', data=peer_set) + onionrplugins.events.event( + 'bootstrap', data={'peer_set': peer_set, 'callback': connect_peer}) diff --git a/src/gossip/client/__init__.py b/src/gossip/client/__init__.py index 6f6e56d0..883dd5c3 100644 --- a/src/gossip/client/__init__.py +++ b/src/gossip/client/__init__.py @@ -20,7 +20,7 @@ from gossip.phase import DandelionPhase from onionrthreads import add_onionr_thread from .announce import do_announce -from .peerexchange import get_new_peers +#from .peerexchange import get_new_peers """ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -54,9 +54,11 @@ def gossip_client( data={'peers': peer_set, 'new_peers': new_peer_set}) add_onionr_thread(do_announce, 3600, peer_set, initial_sleep=10) + """ add_onionr_thread( get_new_peers, 1200, peer_set, _trigger_new_peers_event, initial_sleep=5) + """ dandelion_phase = DandelionPhase(dandelion_seed, 30) diff --git a/src/gossip/connectpeer.py b/src/gossip/connectpeer.py new file mode 100644 index 00000000..22aae214 --- /dev/null +++ b/src/gossip/connectpeer.py @@ -0,0 +1,11 @@ +import logger + + +def connect_peer(peer_set, peer): + try: + peer.get_socket() + except Exception: + logger.warn(f"Could not connect to {peer.transport_address}") + else: + peer_set.add(peer) + logger.info(f"connected to {peer.transport_address}") diff --git a/src/gossip/server.py b/src/gossip/server.py index acf48a6b..387ce58d 100644 --- a/src/gossip/server.py +++ b/src/gossip/server.py @@ -3,6 +3,7 @@ from typing import TYPE_CHECKING from typing import Set from queue import Queue +from .connectpeer import connect_peer from onionrplugins import onionrevents @@ -53,8 +54,10 @@ def gossip_server( address = await reader.read(56) onionrevents.event( 'announce_rec', - data={'peer_set': peer_set, 'address': address}, - threaded=False) + data={'peer_set': peer_set, + 'address': address, + 'callback': connect_peer}, + threaded=True) writer.write(int(1).to_bytes(1, 'big')) await asyncio.wait_for(_read_announce(), 10) diff --git a/static-data/default-plugins/tor/announce.py b/static-data/default-plugins/tor/announce.py new file mode 100644 index 00000000..63b0b980 --- /dev/null +++ b/static-data/default-plugins/tor/announce.py @@ -0,0 +1,25 @@ +import config +import logger + +from getsocks import get_socks +from torpeer import TorPeer + + +def on_announce_rec(api, data=None): + socks_address, socks_port = get_socks()[0] + + announced = data['address'] + try: + announced = announced.decode('utf-8') + except AttributeError: + pass + + if announced == config.get('tor.transport_address'): + logger.warn("Recieved announcement for our own node, which shouldnt happen") + return + + announced += '.onion' + + data['callback']( + data['peer_set'], + TorPeer(socks_address, socks_port, announced)) diff --git a/static-data/default-plugins/tor/bootstrap.py b/static-data/default-plugins/tor/bootstrap.py new file mode 100644 index 00000000..ff7c5839 --- /dev/null +++ b/static-data/default-plugins/tor/bootstrap.py @@ -0,0 +1,44 @@ +from threading import Thread +from time import sleep +import os + +from gossip.peer import Peer +import logger +import config +from getsocks import get_socks + +from torpeer import TorPeer +from torfilepaths import control_socket + +bootstrap_file = f'{os.path.dirname(os.path.realpath(__file__))}/bootstrap.txt' + +def on_bootstrap(api, data): + + try: + with open(bootstrap_file, 'r') as bootstrap_file_obj: + bootstrap_nodes = set(bootstrap_file_obj.read().split(',')) + except FileNotFoundError: + bootstrap_nodes = set() + + while not os.path.exists(control_socket): + sleep(0.1) + + while not config.get('tor.transport_address'): + sleep(1) + config.reload() + + socks_address, socks_port = get_socks()[0] + + for address in bootstrap_nodes: + if address == config.get('tor.transport_address'): + continue + if not address.endswith('.onion'): + address += '.onion' + # Tell the gossip logic that this peer is ready to connect + # it will add it to data['peer_set'] if it responds to ping + Thread( + target=data['callback'], + args=[data['peer_set'], TorPeer(socks_address, socks_port, address)], + daemon=True).start() + + diff --git a/static-data/default-plugins/tor/main.py b/static-data/default-plugins/tor/main.py index 441517be..fe0a365c 100644 --- a/static-data/default-plugins/tor/main.py +++ b/static-data/default-plugins/tor/main.py @@ -28,7 +28,9 @@ sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) import starttor from torpeer import TorPeer from torfilepaths import control_socket -from getsocks import get_socks + +from bootstrap import on_bootstrap +from announce import on_announce_rec """ This program is free software: you can redistribute it and/or modify @@ -50,9 +52,6 @@ plugin_name = 'tor' PLUGIN_VERSION = '0.0.0' -bootstrap_file = f'{os.path.dirname(os.path.realpath(__file__))}/bootstrap.txt' - - class OnionrTor: def __init__(self): return @@ -70,47 +69,6 @@ def on_get_our_transport(api, data=None): callback_func(for_peer, config.get('tor.transport_address')) -def on_announce_rec(api, data=None): - print("got announce rec event") - - -def on_bootstrap(api, data: Set[Peer] = None): - bootstrap_nodes: Set[str] - peers = data - - try: - with open(bootstrap_file, 'r') as bootstrap_file_obj: - bootstrap_nodes = set(bootstrap_file_obj.read().split(',')) - except FileNotFoundError: - bootstrap_nodes = set() - - while not os.path.exists(control_socket): - sleep(0.1) - - socks_address, socks_port = get_socks()[0] - sleep(5) - - for transport_address in bootstrap_nodes: - config.reload() - if config.get('tor.transport_address') == transport_address: - # ignore if its our own - continue - if not transport_address.endswith('.onion'): - transport_address += '.onion' - tor_peer = TorPeer(socks_address, socks_port, transport_address) - try: - tor_peer.get_socket() - except Exception: - logger.warn( - f"Could not connnect to Tor peer {transport_address} " + - "see logs for more info", - terminal=True) - logger.warn(traceback.format_exc()) - continue - peers.add(tor_peer) - logger.info(f"Connected to {len(peers)} Tor peers", terminal=True) - - def on_gossip_start(api, data: Set[Peer] = None): # We don't do gossip logic