work on torgossip

This commit is contained in:
Kevin Froman 2021-02-11 21:03:41 +00:00
parent 257bef6ca0
commit 4bf1acf446
6 changed files with 78 additions and 45 deletions

View File

@ -24,7 +24,7 @@ except InvalidID:
"Invalid block ID for " + "Invalid block ID for " +
b85encode(block_hash).decode('utf-8')) b85encode(block_hash).decode('utf-8'))
except ValueError as e: 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) stderr.write(e.message)
except BlockExpired: except BlockExpired:
stderr.write( stderr.write(

View File

@ -7,6 +7,7 @@ Create streams to random peers
import sys import sys
from base64 import b32encode from base64 import b32encode
from os import path from os import path
from time import sleep
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from random import SystemRandom from random import SystemRandom
@ -14,6 +15,7 @@ import socks as socket
from netcontroller.torcontrol.onionserviceonline import service_online_recently from netcontroller.torcontrol.onionserviceonline import service_online_recently
from netcontroller.torcontrol import torcontroller from netcontroller.torcontrol import torcontroller
import logger
if TYPE_CHECKING: if TYPE_CHECKING:
from .peerdb import TorGossipPeers from .peerdb import TorGossipPeers
@ -21,6 +23,8 @@ if TYPE_CHECKING:
sys.path.insert(0, path.dirname(path.realpath(__file__))) sys.path.insert(0, path.dirname(path.realpath(__file__)))
from commands import GossipCommands from commands import GossipCommands
from clientfuncs import download_blocks
""" """
This program is free software: you can redistribute it and/or modify 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 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 You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
""" """
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'): 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" bootstap_peers = path.dirname(path.realpath(__file__)) + "/bootstrap.txt"
with open(bootstap_peers, 'r') as bs_peers: with open(bootstap_peers, 'r') as bs_peers:
peers = bs_peers.split(',') peers = bs_peers.read().split(',')
for peer in peers: for peer in peers:
try: try:
peer_db.get(peer) peer_db.db.get(peer)
except KeyError: except KeyError:
pass pass
else: else:
continue continue
if peer and service_online_recently(controller, peer): if peer:
peer_db.add_peer(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): def start_client(shared_state):
# add boot strap peers to db if we need peers # add boot strap peers to db if we need peers
_add_bootstrap_peers(shared_state.get_by_string('TorGossipPeers')) _add_bootstrap_peers(shared_state.get_by_string('TorGossipPeers'))
# create and fill pool of sockets to peers (over tor socks) # create and fill pool of sockets to peers (over tor socks)
socket_pool = {} socket_pool = {}
_client_pool(shared_state, socket_pool) client_funcs(shared_state, socket_pool)
client_loop(shared_state, socket_pool)

View File

@ -25,5 +25,6 @@ def download_blocks(sock: 'socket', offset: int, block_type: str):
int(GossipCommands.GET_BLOCK).to_bytes( int(GossipCommands.GET_BLOCK).to_bytes(
1, 'little') + hash) 1, 'little') + hash)
bl_content = sock.recv(10**6) bl_content = sock.recv(10**6)
print(bl_content)

View File

@ -35,6 +35,7 @@ import logger # noqa
try: try:
from server import start_server from server import start_server
from client import start_client
from peerdb import TorGossipPeers from peerdb import TorGossipPeers
from runtest import torgossip_runtest from runtest import torgossip_runtest
except Exception as _: # noqa except Exception as _: # noqa
@ -48,7 +49,7 @@ def on_init(api, data=None):
shared_state.get(TorGossipPeers) shared_state.get(TorGossipPeers)
hs = "" hs = b""
try: try:
with open(HOSTNAME_FILE, "rb") as f: with open(HOSTNAME_FILE, "rb") as f:
@ -68,7 +69,9 @@ def on_init(api, data=None):
with open(HOSTNAME_FILE, "wb") as hf: with open(HOSTNAME_FILE, "wb") as hf:
hf.write(hs) 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_server, daemon=True, args=[shared_state]).start()
Thread(target=start_client, daemon=True, args=[shared_state]).start()

View File

@ -60,9 +60,9 @@ class TorGossipPeers: # name it this way to avoid collisions in SharedState
if peer == b'enc': if peer == b'enc':
peer = self.db.db_conn.nextkey(peer) peer = self.db.db_conn.nextkey(peer)
assert len(peer) == 34
if not peer: if not peer:
return [] return []
assert len(peer) == 34
top = [(peer, self.db.get(peer))] top = [(peer, self.db.get(peer))]

View File

@ -10,11 +10,16 @@ import selectors
import socket import socket
from time import sleep 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__))) sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
from commands import GossipCommands # noqa from commands import GossipCommands # noqa
import commandhandlers import commandhandlers
from constants import SERVER_SOCKET from constants import SERVER_SOCKET
from blockio import subprocgenerate, store_block
""" """
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -33,6 +38,10 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
def start_server(shared_state): 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() sel = selectors.DefaultSelector()
def accept(sock, mask): def accept(sock, mask):