implemented peer exchange

This commit is contained in:
Kevin Froman 2021-02-05 02:19:23 +00:00
parent b4127c9836
commit f4182cb996
4 changed files with 44 additions and 16 deletions

View File

@ -2,8 +2,6 @@
Handle commands for the torgossip server
"""
from onionrblocks import generators
from onionrblocks.generators import anonvdf
import blockio
import onionrblocks
@ -26,9 +24,13 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
def peer_exchange(peers: 'Peers', num_of_peers: bytes):
#7
num_of_peers = int.from_bytes(num_of_peers, 'little')
return peers.get_highest_score_peers(num_of_peers)
"""command 7: exchange a number of our top performing peers"""
num_of_peers = int(chr(int.from_bytes(num_of_peers, 'little')))
peers = peers.get_highest_score_peers(num_of_peers)
just_addresses = []
for i in peers:
just_addresses.append(i[0])
return b''.join(just_addresses)
def put_block(safe_db, block):
@ -41,7 +43,7 @@ def put_block(safe_db, block):
safe_db)
except ValueError:
pass
except Exception as e:
except Exception as _: # noqa
return b"0"
return b"1"

View File

@ -29,7 +29,7 @@ class TorGossipPeers: # name it this way to avoid collisions in SharedState
PACK_FORMAT = "qQ"
def __init__(self, encrypt=True):
def __init__(self, encrypt=False):
self.db = safedb.SafeDB(
identify_home() + "/torgossip-peers.db", protected=encrypt)
@ -54,18 +54,30 @@ class TorGossipPeers: # name it this way to avoid collisions in SharedState
self.db.put(peer, pack(self.PACK_FORMAT, score, seen))
def get_highest_score_peers(self, max=5):
def get_highest_score_peers(self, max):
assert max >= 1
peer = self.db.db_conn.firstkey()
if peer == b'enc':
peer = self.db.db_conn.nextkey(peer)
print('p', peer)
assert len(peer) == 34
if not peer:
return []
top = [(peer, self.db.get(peer))]
for peer in self.db.db_conn.nextkey(peer):
while peer:
peer = self.db.db_conn.nextkey(peer)
if not peer:
break
if peer == b"enc":
continue
peer_data = self.db.get(peer)
overwrite = None
if len(top) != max:
top.append((peer, peer_data))
peer = self.db.db_conn.nextkey(peer)
continue
for count, cur_top in enumerate(top):
# if peer score is greater than any set peer, overwrite
@ -75,16 +87,17 @@ class TorGossipPeers: # name it this way to avoid collisions in SharedState
break # below else won't execute, so it will be overwritten
else:
# if not overwriting, go to next peer
peer = self.db.db_conn.nextkey(peer)
continue
top[overwrite] = (peer, peer_data)
return top
def add_score(self, peer, new_score):
def add_score(self, peer, plus):
shrunk = self._shrink_peer_address(peer)
score, _ = unpack("qQ", self.db.get(shrunk))
self._pack_and_store_info(
shrunk, new_score=score + new_score)
shrunk, new_score=score + plus)
def update_seen(self, peer):
peer = self._shrink_peer_address(peer)
@ -92,3 +105,7 @@ class TorGossipPeers: # name it this way to avoid collisions in SharedState
def add_peer(self, peer):
self._pack_and_store_info(peer)
def remove_peer(self, peer):
peer = self._shrink_peer_address(peer)
del self.db.db_conn[peer]

View File

@ -1,7 +1,7 @@
import socket
import os
import secrets
from base64 import b32encode
from base64 import b32decode, b32encode
from utils import identifyhome
from onionrblocks import blockcreator
@ -73,10 +73,15 @@ def torgossip_runtest(test_manager):
shared_state.get_by_string("SafeDB").get('bl-tbt')) - 64
# test peer list
#fake_peer = _fake_onion()
#shared_state.get_by_string('TorGossipPeers').add_peer(fake_peer)
#s.sendall(b'71')
#assert s.recv(100) == fake_peer
fake_peer = _fake_onion()
shared_state.get_by_string('TorGossipPeers').add_peer(fake_peer)
shared_state.get_by_string('TorGossipPeers').add_score(fake_peer, 100000)
s.sendall(b'71')
stored = s.recv(1000)
expected = b32decode(fake_peer.replace('.onion', '')).replace(b'.onion', b'')
print(stored, expected)
assert stored == expected
shared_state.get_by_string('TorGossipPeers').remove_peer(fake_peer)
s.sendall(b'9')
assert s.recv(64) == b"BYE"

View File

@ -82,6 +82,10 @@ def start_server(shared_state):
conn.sendall(
commandhandlers.handle_check_block(
shared_state.get_by_string('SafeDB'), data))
elif cmd == GossipCommands.PEER_EXCHANGE:
conn.sendall(
commandhandlers.peer_exchange(
shared_state.get_by_string('TorGossipPeers'), data))
else:
conn.sendall(b'Unknown ' + str(cmd).encode('utf-8'))
else: