use super::{
packet_queues::AddressedPacket,
sphinx::build_cover_packet,
topology::{NetworkStatus, RouteGenerator, RouteKind, Topology, TopologyErr},
util::default_boxed_array,
};
use arrayvec::ArrayVec;
use rand::{CryptoRng, Rng};
#[derive(PartialEq, Eq)]
pub enum CoverKind {
Drop,
Loop,
}
pub fn gen_cover_packet<X>(
rng: &mut (impl Rng + CryptoRng),
topology: &Topology<X>,
ns: &dyn NetworkStatus,
kind: CoverKind,
num_hops: usize,
) -> Result<AddressedPacket, TopologyErr> {
let route_generator = RouteGenerator::new(topology, ns);
let route_kind = match kind {
CoverKind::Drop => RouteKind::ToMixnode(route_generator.choose_destination_index(rng)?),
CoverKind::Loop => RouteKind::Loop,
};
let mut targets = ArrayVec::new();
let mut their_kx_publics = ArrayVec::new();
let first_mixnode_index = route_generator.gen_route(
&mut targets,
&mut their_kx_publics,
rng,
route_kind,
num_hops,
)?;
let peer_id = topology.mixnode_index_to_peer_id(first_mixnode_index)?;
let mut packet = default_boxed_array();
build_cover_packet(&mut packet, rng, &targets, &their_kx_publics, None);
Ok(AddressedPacket { peer_id, packet })
}