2022-03-02 13:29:59 +00:00
|
|
|
from typing import TYPE_CHECKING
|
2022-04-24 20:19:39 +00:00
|
|
|
from typing import List
|
2022-03-11 17:15:18 +00:00
|
|
|
import secrets
|
2022-03-02 13:29:59 +00:00
|
|
|
from asyncio import wait_for
|
|
|
|
|
2022-03-05 00:05:12 +00:00
|
|
|
from onionrblocks import Block
|
|
|
|
|
2022-04-24 20:19:39 +00:00
|
|
|
from ..dandelion import StemAcceptResult
|
2022-03-02 13:29:59 +00:00
|
|
|
from ..constants import BLOCK_ID_SIZE, BLOCK_MAX_SIZE
|
2022-03-05 00:05:12 +00:00
|
|
|
from ..constants import MAX_INBOUND_DANDELION_EDGE, MAX_STEM_BLOCKS_PER_STREAM
|
2022-03-21 06:03:53 +00:00
|
|
|
from ..blockqueues import gossip_block_queues
|
2022-03-02 13:29:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
block_size_digits = len(str(BLOCK_MAX_SIZE))
|
2022-05-01 05:45:26 +00:00
|
|
|
base_wait_timeout = 120
|
2022-03-02 13:29:59 +00:00
|
|
|
|
|
|
|
if TYPE_CHECKING:
|
|
|
|
from asyncio import StreamWriter, StreamReader
|
|
|
|
|
|
|
|
|
|
|
|
async def accept_stem_blocks(
|
|
|
|
reader: 'StreamReader',
|
2022-03-05 00:05:12 +00:00
|
|
|
writer: 'StreamWriter',
|
|
|
|
inbound_edge_count: List[int]):
|
|
|
|
|
|
|
|
if inbound_edge_count[0] >= MAX_INBOUND_DANDELION_EDGE:
|
|
|
|
writer.write(StemAcceptResult.DENY)
|
|
|
|
return
|
|
|
|
writer.write(StemAcceptResult.ALLOW)
|
|
|
|
inbound_edge_count[0] += 1
|
2022-03-02 13:29:59 +00:00
|
|
|
|
|
|
|
# Start getting the first block
|
2022-03-26 23:24:40 +00:00
|
|
|
read_routine = reader.readexactly(BLOCK_ID_SIZE)
|
2022-03-02 13:29:59 +00:00
|
|
|
|
2022-03-21 06:03:53 +00:00
|
|
|
block_queue_to_use = secrets.choice(gossip_block_queues)
|
2022-03-13 01:28:18 +00:00
|
|
|
|
2022-03-05 00:05:12 +00:00
|
|
|
for _ in range(MAX_STEM_BLOCKS_PER_STREAM):
|
|
|
|
block_id = (
|
|
|
|
await wait_for(read_routine, base_wait_timeout)).decode('utf-8')
|
2022-03-26 23:24:40 +00:00
|
|
|
if not block_id:
|
|
|
|
break
|
|
|
|
|
2022-03-05 00:05:12 +00:00
|
|
|
block_size = (await wait_for(
|
2022-03-26 23:24:40 +00:00
|
|
|
reader.readexactly(block_size_digits),
|
2022-03-05 00:05:12 +00:00
|
|
|
base_wait_timeout)).decode('utf-8')
|
2022-03-20 23:05:44 +00:00
|
|
|
if not block_size:
|
|
|
|
break
|
|
|
|
|
2022-03-02 13:29:59 +00:00
|
|
|
if not all(c in "0123456789" for c in block_size):
|
|
|
|
raise ValueError("Invalid block size data (non 0-9 char)")
|
2022-03-05 00:05:12 +00:00
|
|
|
block_size = int(block_size)
|
2022-03-02 13:29:59 +00:00
|
|
|
if block_size > BLOCK_MAX_SIZE:
|
|
|
|
raise ValueError("Max block size")
|
|
|
|
|
2022-03-05 00:05:12 +00:00
|
|
|
raw_block: bytes = await wait_for(
|
2022-03-26 23:24:40 +00:00
|
|
|
reader.readexactly(block_size), base_wait_timeout * 6)
|
2022-03-20 23:05:44 +00:00
|
|
|
if not raw_block:
|
|
|
|
break
|
|
|
|
|
2022-03-13 01:28:18 +00:00
|
|
|
block_queue_to_use.put(
|
2022-03-05 00:05:12 +00:00
|
|
|
Block(block_id, raw_block, auto_verify=True)
|
|
|
|
)
|
2022-04-24 20:19:39 +00:00
|
|
|
|
2022-03-05 00:05:12 +00:00
|
|
|
# Regardless of stem phase, we add to queue
|
|
|
|
# Client will decide if they are to be stemmed
|
2022-03-02 13:29:59 +00:00
|
|
|
|
2022-03-26 23:24:40 +00:00
|
|
|
read_routine = reader.readexactly(BLOCK_ID_SIZE)
|
2022-03-02 13:29:59 +00:00
|
|
|
|