implemented peer exchange
This commit is contained in:
parent
b4127c9836
commit
f4182cb996
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
Handle commands for the torgossip server
|
Handle commands for the torgossip server
|
||||||
"""
|
"""
|
||||||
from onionrblocks import generators
|
|
||||||
from onionrblocks.generators import anonvdf
|
|
||||||
import blockio
|
import blockio
|
||||||
|
|
||||||
import onionrblocks
|
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):
|
def peer_exchange(peers: 'Peers', num_of_peers: bytes):
|
||||||
#7
|
"""command 7: exchange a number of our top performing peers"""
|
||||||
num_of_peers = int.from_bytes(num_of_peers, 'little')
|
num_of_peers = int(chr(int.from_bytes(num_of_peers, 'little')))
|
||||||
return peers.get_highest_score_peers(num_of_peers)
|
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):
|
def put_block(safe_db, block):
|
||||||
@ -41,7 +43,7 @@ def put_block(safe_db, block):
|
|||||||
safe_db)
|
safe_db)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
except Exception as e:
|
except Exception as _: # noqa
|
||||||
return b"0"
|
return b"0"
|
||||||
return b"1"
|
return b"1"
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ class TorGossipPeers: # name it this way to avoid collisions in SharedState
|
|||||||
|
|
||||||
PACK_FORMAT = "qQ"
|
PACK_FORMAT = "qQ"
|
||||||
|
|
||||||
def __init__(self, encrypt=True):
|
def __init__(self, encrypt=False):
|
||||||
self.db = safedb.SafeDB(
|
self.db = safedb.SafeDB(
|
||||||
identify_home() + "/torgossip-peers.db", protected=encrypt)
|
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))
|
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
|
assert max >= 1
|
||||||
peer = self.db.db_conn.firstkey()
|
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))]
|
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)
|
peer_data = self.db.get(peer)
|
||||||
overwrite = None
|
overwrite = None
|
||||||
|
|
||||||
if len(top) != max:
|
if len(top) != max:
|
||||||
top.append((peer, peer_data))
|
top.append((peer, peer_data))
|
||||||
|
peer = self.db.db_conn.nextkey(peer)
|
||||||
continue
|
continue
|
||||||
for count, cur_top in enumerate(top):
|
for count, cur_top in enumerate(top):
|
||||||
# if peer score is greater than any set peer, overwrite
|
# 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
|
break # below else won't execute, so it will be overwritten
|
||||||
else:
|
else:
|
||||||
# if not overwriting, go to next peer
|
# if not overwriting, go to next peer
|
||||||
|
peer = self.db.db_conn.nextkey(peer)
|
||||||
continue
|
continue
|
||||||
top[overwrite] = (peer, peer_data)
|
top[overwrite] = (peer, peer_data)
|
||||||
return top
|
return top
|
||||||
|
|
||||||
def add_score(self, peer, new_score):
|
def add_score(self, peer, plus):
|
||||||
shrunk = self._shrink_peer_address(peer)
|
shrunk = self._shrink_peer_address(peer)
|
||||||
score, _ = unpack("qQ", self.db.get(shrunk))
|
score, _ = unpack("qQ", self.db.get(shrunk))
|
||||||
|
|
||||||
self._pack_and_store_info(
|
self._pack_and_store_info(
|
||||||
shrunk, new_score=score + new_score)
|
shrunk, new_score=score + plus)
|
||||||
|
|
||||||
def update_seen(self, peer):
|
def update_seen(self, peer):
|
||||||
peer = self._shrink_peer_address(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):
|
def add_peer(self, peer):
|
||||||
self._pack_and_store_info(peer)
|
self._pack_and_store_info(peer)
|
||||||
|
|
||||||
|
def remove_peer(self, peer):
|
||||||
|
peer = self._shrink_peer_address(peer)
|
||||||
|
del self.db.db_conn[peer]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import socket
|
import socket
|
||||||
import os
|
import os
|
||||||
import secrets
|
import secrets
|
||||||
from base64 import b32encode
|
from base64 import b32decode, b32encode
|
||||||
|
|
||||||
from utils import identifyhome
|
from utils import identifyhome
|
||||||
from onionrblocks import blockcreator
|
from onionrblocks import blockcreator
|
||||||
@ -73,10 +73,15 @@ def torgossip_runtest(test_manager):
|
|||||||
shared_state.get_by_string("SafeDB").get('bl-tbt')) - 64
|
shared_state.get_by_string("SafeDB").get('bl-tbt')) - 64
|
||||||
|
|
||||||
# test peer list
|
# test peer list
|
||||||
#fake_peer = _fake_onion()
|
fake_peer = _fake_onion()
|
||||||
#shared_state.get_by_string('TorGossipPeers').add_peer(fake_peer)
|
shared_state.get_by_string('TorGossipPeers').add_peer(fake_peer)
|
||||||
#s.sendall(b'71')
|
shared_state.get_by_string('TorGossipPeers').add_score(fake_peer, 100000)
|
||||||
#assert s.recv(100) == fake_peer
|
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')
|
s.sendall(b'9')
|
||||||
assert s.recv(64) == b"BYE"
|
assert s.recv(64) == b"BYE"
|
||||||
|
@ -82,6 +82,10 @@ def start_server(shared_state):
|
|||||||
conn.sendall(
|
conn.sendall(
|
||||||
commandhandlers.handle_check_block(
|
commandhandlers.handle_check_block(
|
||||||
shared_state.get_by_string('SafeDB'), data))
|
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:
|
else:
|
||||||
conn.sendall(b'Unknown ' + str(cmd).encode('utf-8'))
|
conn.sendall(b'Unknown ' + str(cmd).encode('utf-8'))
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user