34 lines
1.2 KiB
Python
34 lines
1.2 KiB
Python
|
from __future__ import annotations
|
||
|
|
||
|
from typing import List, Tuple
|
||
|
|
||
|
from pysphinx.sphinx import SphinxPacket
|
||
|
|
||
|
from protocol.config import GlobalConfig, NodeInfo
|
||
|
|
||
|
|
||
|
class SphinxPacketBuilder:
|
||
|
@staticmethod
|
||
|
def build(
|
||
|
message: bytes, global_config: GlobalConfig, path_len: int
|
||
|
) -> Tuple[SphinxPacket, List[NodeInfo]]:
|
||
|
if path_len <= 0:
|
||
|
raise ValueError("path_len must be greater than 0")
|
||
|
if len(message) > global_config.max_message_size:
|
||
|
raise ValueError("message is too long")
|
||
|
|
||
|
route = global_config.membership.generate_route(path_len)
|
||
|
# We don't need the destination (defined in the Loopix Sphinx spec)
|
||
|
# because the last mix will broadcast the fully unwrapped message.
|
||
|
# Later, we will optimize the Sphinx according to our requirements.
|
||
|
dummy_destination = route[-1]
|
||
|
|
||
|
packet = SphinxPacket.build(
|
||
|
message,
|
||
|
route=[mixnode.sphinx_node() for mixnode in route],
|
||
|
destination=dummy_destination.sphinx_node(),
|
||
|
max_route_length=global_config.max_mix_path_length,
|
||
|
max_plain_payload_size=global_config.max_message_size,
|
||
|
)
|
||
|
return (packet, route)
|