Work on stemout
This commit is contained in:
parent
19159ffa06
commit
9bf16c5758
@ -18,7 +18,7 @@ def do_announce(peer_set):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
sock = announce_peer.get_socket()
|
sock = announce_peer.get_socket()
|
||||||
sock.send(
|
sock.sendall(
|
||||||
command_to_byte(GossipCommands.ANNOUNCE) + our_transport_address)
|
command_to_byte(GossipCommands.ANNOUNCE) + our_transport_address)
|
||||||
if int.from_bytes(sock.recv(1), 'big') != 1:
|
if int.from_bytes(sock.recv(1), 'big') != 1:
|
||||||
logger.warn(
|
logger.warn(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from queue import Queue
|
from queue import Queue
|
||||||
from threading import Timer
|
from threading import Thread, Timer
|
||||||
from time import sleep
|
from time import sleep
|
||||||
from secrets import choice
|
from secrets import choice
|
||||||
import traceback
|
import traceback
|
||||||
@ -11,20 +11,24 @@ from blockdb import add_block_to_db
|
|||||||
import logger
|
import logger
|
||||||
|
|
||||||
from ..constants import BLACKHOLE_EVADE_TIMER_SECS, MAX_OUTBOUND_DANDELION_EDGE
|
from ..constants import BLACKHOLE_EVADE_TIMER_SECS, MAX_OUTBOUND_DANDELION_EDGE
|
||||||
|
from ..commands import GossipCommands, command_to_byte
|
||||||
|
from .. import dandelion
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from ordered_set import OrderedSet
|
from ordered_set import OrderedSet
|
||||||
from onionrblocks import Block
|
from onionrblocks import Block
|
||||||
from ..peer import Peer
|
from ..peer import Peer
|
||||||
from ..dandelion.phase import DandelionPhase
|
from ..dandelion.phase import DandelionPhase
|
||||||
|
import socket
|
||||||
|
|
||||||
|
|
||||||
class NotEnoughEdges(ValueError): pass # noqa
|
class NotEnoughEdges(ValueError): pass # noqa
|
||||||
|
class StemConnectionDenied(ConnectionRefusedError): pass # noqa
|
||||||
|
|
||||||
|
|
||||||
def _setup_edge(
|
async def _setup_edge(
|
||||||
peer_set: OrderedSet['Peer'], exclude_set: OrderedSet['Peer']):
|
peer_set: OrderedSet['Peer'], exclude_set: OrderedSet['Peer']):
|
||||||
"""Negotiate stem connection with random peer, add to exclude set if fail"""
|
"""Negotiate stem connection with random peer, add to exclu set if fail"""
|
||||||
try:
|
try:
|
||||||
peer: 'Peer' = choice(peer_set - exclude_set)
|
peer: 'Peer' = choice(peer_set - exclude_set)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
@ -35,13 +39,46 @@ def _setup_edge(
|
|||||||
logger.debug(traceback.format_exc())
|
logger.debug(traceback.format_exc())
|
||||||
exclude_set.add(peer)
|
exclude_set.add(peer)
|
||||||
|
|
||||||
|
try:
|
||||||
|
s.sendall(command_to_byte(GossipCommands.PUT_BLOCKS))
|
||||||
|
if s.recv(1) == dandelion.StemAcceptResult.DENY:
|
||||||
|
raise StemConnectionDenied
|
||||||
|
except StemConnectionDenied:
|
||||||
|
logger.debug(
|
||||||
|
"Stem connection denied (peer has too many) " +
|
||||||
|
f"{peer.transport_address}")
|
||||||
|
except Exception:
|
||||||
|
logger.warn(
|
||||||
|
"Error asking peer to establish stem connection" +
|
||||||
|
traceback.format_exc(), terminal=True)
|
||||||
|
else:
|
||||||
|
# Return peer socket if it is in stem reception mode successfully
|
||||||
|
return s
|
||||||
|
finally:
|
||||||
|
# If peer is good or bad, exclude it no matter what
|
||||||
|
exclude_set.add(peer)
|
||||||
|
# If they won't accept stem blocks, close the socket
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
|
||||||
def stem_out(
|
async def _do_stem_stream(
|
||||||
|
peer_socket: 'socket.socket',
|
||||||
|
block_queue: Queue['Block'],
|
||||||
|
d_phase: 'DandelionPhase'):
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
async def stem_out(
|
||||||
block_queues: Tuple[Queue['Block'], Queue['Block']],
|
block_queues: Tuple[Queue['Block'], Queue['Block']],
|
||||||
peer_set: OrderedSet['Peer'],
|
peer_set: OrderedSet['Peer'],
|
||||||
d_phase: 'DandelionPhase'):
|
d_phase: 'DandelionPhase'):
|
||||||
|
|
||||||
|
|
||||||
|
# don't bother if there are no possible outbound edges
|
||||||
|
if not len(peer_set):
|
||||||
|
sleep(1)
|
||||||
|
return
|
||||||
|
|
||||||
# Spawn threads with deep copied block queue to add to db after time
|
# Spawn threads with deep copied block queue to add to db after time
|
||||||
# for black hole attack
|
# for black hole attack
|
||||||
for block_q in block_queues:
|
for block_q in block_queues:
|
||||||
@ -49,14 +86,23 @@ def stem_out(
|
|||||||
lambda q: set(map(add_block_to_db, q)),
|
lambda q: set(map(add_block_to_db, q)),
|
||||||
BLACKHOLE_EVADE_TIMER_SECS, list(block_q.queue))
|
BLACKHOLE_EVADE_TIMER_SECS, list(block_q.queue))
|
||||||
|
|
||||||
# don't bother if there are no possible outbound edges
|
peer_sockets: List['socket.socket'] = []
|
||||||
if not len(peer_set):
|
|
||||||
sleep(1)
|
|
||||||
return
|
|
||||||
|
|
||||||
# Pick edges randomly
|
# Pick edges randomly
|
||||||
# Using orderedset for the tried edges to ensure random pairing with queue
|
# Using orderedset for the tried edges to ensure random pairing with queue
|
||||||
tried_edges: OrderedSet['Peer'] = OrderedSet()
|
tried_edges: OrderedSet['Peer'] = OrderedSet()
|
||||||
|
|
||||||
|
while len(peer_sockets) < MAX_OUTBOUND_DANDELION_EDGE:
|
||||||
|
try:
|
||||||
|
peer_sockets.append(_setup_edge(peer_set, tried_edges))
|
||||||
|
except NotEnoughEdges:
|
||||||
|
logger.debug("Not able to build enough peers for stemout")
|
||||||
|
break
|
||||||
|
finally:
|
||||||
|
if not d_phase.is_stem_phase() or d_phase.remaining_time() < 5:
|
||||||
|
logger.error(
|
||||||
|
"Did not stem out any blocks in time, " +
|
||||||
|
"if this happens regularly you may be under attack",
|
||||||
|
terminal=True)
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ BLOCK_ID_SIZE = 128
|
|||||||
DANDELION_EPOCH_LENGTH = 60
|
DANDELION_EPOCH_LENGTH = 60
|
||||||
|
|
||||||
# Magic number i made up, not really specified in dandelion++ paper
|
# Magic number i made up, not really specified in dandelion++ paper
|
||||||
MAX_INBOUND_DANDELION_EDGE = 50 # Mainly picked to avoid slowlorisstor browser dvm 16
|
MAX_INBOUND_DANDELION_EDGE = 50 # Mainly picked to avoid slowloris
|
||||||
|
|
||||||
# Dandelion subgraph is aprox 4-regular
|
# Dandelion subgraph is aprox 4-regular
|
||||||
MAX_OUTBOUND_DANDELION_EDGE = 2
|
MAX_OUTBOUND_DANDELION_EDGE = 2
|
||||||
|
Loading…
Reference in New Issue
Block a user