From 4bf1acf446a1d834aa8d2c2a473f2e1e50bfc76b Mon Sep 17 00:00:00 2001 From: Kevin Froman Date: Thu, 11 Feb 2021 21:03:41 +0000 Subject: [PATCH] work on torgossip --- src/anonvdf-block-validator.py | 2 +- .../default-plugins/torgossip/client.py | 102 +++++++++++------- .../torgossip/clientfuncs/__init__.py | 1 + static-data/default-plugins/torgossip/main.py | 7 +- .../default-plugins/torgossip/peerdb.py | 2 +- .../default-plugins/torgossip/server.py | 9 ++ 6 files changed, 78 insertions(+), 45 deletions(-) diff --git a/src/anonvdf-block-validator.py b/src/anonvdf-block-validator.py index c0609661..8f47b889 100755 --- a/src/anonvdf-block-validator.py +++ b/src/anonvdf-block-validator.py @@ -24,7 +24,7 @@ except InvalidID: "Invalid block ID for " + b85encode(block_hash).decode('utf-8')) except ValueError as e: - # Supposed to be if rounds are not specifid in the block + # Supposed to be if rounds are not specified in the block stderr.write(e.message) except BlockExpired: stderr.write( diff --git a/static-data/default-plugins/torgossip/client.py b/static-data/default-plugins/torgossip/client.py index bcda9324..329bbf69 100644 --- a/static-data/default-plugins/torgossip/client.py +++ b/static-data/default-plugins/torgossip/client.py @@ -7,6 +7,7 @@ Create streams to random peers import sys from base64 import b32encode from os import path +from time import sleep from typing import TYPE_CHECKING from random import SystemRandom @@ -14,6 +15,7 @@ import socks as socket from netcontroller.torcontrol.onionserviceonline import service_online_recently from netcontroller.torcontrol import torcontroller +import logger if TYPE_CHECKING: from .peerdb import TorGossipPeers @@ -21,6 +23,8 @@ if TYPE_CHECKING: sys.path.insert(0, path.dirname(path.realpath(__file__))) from commands import GossipCommands + +from clientfuncs import download_blocks """ 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 @@ -35,63 +39,79 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ -controller = torcontroller.get_controller() + + +def client_funcs(shared_state, socket_pool): + controller = torcontroller.get_controller() + + def _client_pool(shared_state, socket_pool: dict): + peer_db: 'TorGossipPeers' = shared_state.get_by_string('TorGossipPeers') + socks_port = shared_state.get_by_string('NetController').socksPort + + peers = peer_db.get_highest_score_peers(20) + SystemRandom().shuffle(peers) + + for peer in peers: + if peer in socket_pool: + continue + if not service_online_recently(controller, peer): + continue + s = socket.socksocket() + s.set_proxy( + socket.SOCKS5, '127.0.0.1', socks_port, rdns=True) + try: + socket_pool[peer] = s.connect( + (b32encode(peer).decode().lower() + ".onion", 2021)) + + except socket.GeneralProxyError: + s.close() + + + def client_loop(shared_state, socket_pool): + sleep_t = 60 + block_db = shared_state.get_by_string('SafeDB') + peer_db = shared_state.get_by_string('TorGossipPeers') + + while True: + if not socket_pool: + _client_pool(shared_state, socket_pool) + peers = list(socket_pool) + SystemRandom().shuffle(peers) + try: + peer = peers[0] + except IndexError: + logger.error( + "There are no known TorGossip peers." + + f"Sleeping for {sleep_t}s", + terminal=True) + sleep(sleep_t) + continue + download_blocks(socket_pool[peer], 0, 'txt') + + _client_pool(shared_state, socket_pool) + client_loop(shared_state, socket_pool) def _add_bootstrap_peers(peer_db: 'TorGossipPeers'): + if len(peer_db.db.db_conn.keys()): + return bootstap_peers = path.dirname(path.realpath(__file__)) + "/bootstrap.txt" with open(bootstap_peers, 'r') as bs_peers: - peers = bs_peers.split(',') + peers = bs_peers.read().split(',') for peer in peers: try: - peer_db.get(peer) + peer_db.db.get(peer) except KeyError: pass else: continue - if peer and service_online_recently(controller, peer): + if peer: peer_db.add_peer(peer) -def _client_pool(shared_state, socket_pool: dict): - peer_db: 'TorGossipPeers' = shared_state.get_by_string('TorGossipPeers') - socks_port = shared_state.get_by_string('NetController').socksPort - - peers = peer_db.get_highest_score_peers(20) - SystemRandom().shuffle(peers) - - for peer in peers: - if peer in socket_pool: - continue - if not service_online_recently(controller, peer): - continue - s = socket.socksocket() - s.set_proxy( - socket.SOCKS5, '127.0.0.1', socks_port, rdns=True) - try: - socket_pool[peer] = s.connect( - (b32encode(peer).decode().lower() + ".onion", 2021)) - - except socket.GeneralProxyError: - s.close() - - -def client_loop(shared_state, socket_pool): - block_db = shared_state.get_by_string('SafeDB') - peer_db = shared_state.get_by_string('TorGossipPeers') - - while True: - if not socket_pool: - _client_pool(shared_state, socket_pool) - sync_ - - - - def start_client(shared_state): # add boot strap peers to db if we need peers _add_bootstrap_peers(shared_state.get_by_string('TorGossipPeers')) # create and fill pool of sockets to peers (over tor socks) socket_pool = {} - _client_pool(shared_state, socket_pool) - client_loop(shared_state, socket_pool) + client_funcs(shared_state, socket_pool) diff --git a/static-data/default-plugins/torgossip/clientfuncs/__init__.py b/static-data/default-plugins/torgossip/clientfuncs/__init__.py index 99ad20d9..f156a040 100644 --- a/static-data/default-plugins/torgossip/clientfuncs/__init__.py +++ b/static-data/default-plugins/torgossip/clientfuncs/__init__.py @@ -25,5 +25,6 @@ def download_blocks(sock: 'socket', offset: int, block_type: str): int(GossipCommands.GET_BLOCK).to_bytes( 1, 'little') + hash) bl_content = sock.recv(10**6) + print(bl_content) diff --git a/static-data/default-plugins/torgossip/main.py b/static-data/default-plugins/torgossip/main.py index 5d76d51b..fd7a9995 100755 --- a/static-data/default-plugins/torgossip/main.py +++ b/static-data/default-plugins/torgossip/main.py @@ -35,6 +35,7 @@ import logger # noqa try: from server import start_server + from client import start_client from peerdb import TorGossipPeers from runtest import torgossip_runtest except Exception as _: # noqa @@ -48,7 +49,7 @@ def on_init(api, data=None): shared_state.get(TorGossipPeers) - hs = "" + hs = b"" try: with open(HOSTNAME_FILE, "rb") as f: @@ -68,7 +69,9 @@ def on_init(api, data=None): with open(HOSTNAME_FILE, "wb") as hf: hf.write(hs) - + logger.info("TorGossip server on " + b32encode(hs).lower().decode('utf-8'), terminal=True) + Thread(target=start_server, daemon=True, args=[shared_state]).start() + Thread(target=start_client, daemon=True, args=[shared_state]).start() diff --git a/static-data/default-plugins/torgossip/peerdb.py b/static-data/default-plugins/torgossip/peerdb.py index 2f59a0c1..ab154325 100644 --- a/static-data/default-plugins/torgossip/peerdb.py +++ b/static-data/default-plugins/torgossip/peerdb.py @@ -60,9 +60,9 @@ class TorGossipPeers: # name it this way to avoid collisions in SharedState if peer == b'enc': peer = self.db.db_conn.nextkey(peer) - assert len(peer) == 34 if not peer: return [] + assert len(peer) == 34 top = [(peer, self.db.get(peer))] diff --git a/static-data/default-plugins/torgossip/server.py b/static-data/default-plugins/torgossip/server.py index 96673526..d10a40d1 100644 --- a/static-data/default-plugins/torgossip/server.py +++ b/static-data/default-plugins/torgossip/server.py @@ -10,11 +10,16 @@ import selectors import socket from time import sleep +from kasten.main import Kasten +from onionrblocks.generators.anonvdf import AnonVDFGenerator +from blockio import store + sys.path.insert(0, os.path.dirname(os.path.realpath(__file__))) from commands import GossipCommands # noqa import commandhandlers from constants import SERVER_SOCKET +from blockio import subprocgenerate, store_block """ 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 @@ -33,6 +38,10 @@ along with this program. If not, see . def start_server(shared_state): + bl = subprocgenerate.vdf_block(b"yep", "txt", 120) + store_block(Kasten(bl.id, bl.get_packed(), generator=AnonVDFGenerator), shared_state.get_by_string('SafeDB')) + print(bl.id) + sel = selectors.DefaultSelector() def accept(sock, mask):