rings_node/onion/circuit/
protocol.rs1use super::codec::decode_event;
2use super::codec::OnionCircuitEvent;
3use super::reducer::OnionCircuitEffect;
4use super::reducer::OnionCircuitReducer;
5use super::reducer::OnionCircuitState;
6use super::ONION_CIRCUIT_NAMESPACE;
7use crate::extension::ext::Ctx;
8use crate::extension::ext::Protocol;
9use crate::extension::ext::Reject;
10use crate::extension::ext::Transition;
11use crate::extension::ext::Wire;
12
13#[derive(Clone, Copy, Debug, Eq, PartialEq)]
15pub enum OnionCircuitCapabilities {
16 Client,
18 Relay,
20 Exit,
22 RelayAndExit,
24}
25
26impl OnionCircuitCapabilities {
27 pub const fn from_registration(relay: bool, exit: bool) -> Self {
29 match (relay, exit) {
30 (false, false) => Self::Client,
31 (true, false) => Self::Relay,
32 (false, true) => Self::Exit,
33 (true, true) => Self::RelayAndExit,
34 }
35 }
36
37 pub const fn client() -> Self {
39 Self::Client
40 }
41
42 pub const fn relay() -> Self {
44 Self::Relay
45 }
46
47 pub const fn exit() -> Self {
49 Self::Exit
50 }
51
52 pub(super) const fn accepts_forward_layers(self) -> bool {
53 matches!(self, Self::Relay | Self::Exit | Self::RelayAndExit)
54 }
55
56 pub(super) const fn permits_relay_layer(self) -> bool {
57 matches!(self, Self::Relay | Self::RelayAndExit)
58 }
59
60 pub(super) const fn permits_exit_layer(self) -> bool {
61 matches!(self, Self::Exit | Self::RelayAndExit)
62 }
63}
64
65#[derive(Clone, Debug)]
67pub struct OnionCircuitProtocol {
68 reducer: OnionCircuitReducer,
69}
70
71impl OnionCircuitProtocol {
72 pub fn new(capabilities: OnionCircuitCapabilities) -> Self {
74 Self {
75 reducer: OnionCircuitReducer::new(capabilities),
76 }
77 }
78}
79
80impl Protocol for OnionCircuitProtocol {
81 type State = OnionCircuitState;
82 type Event = OnionCircuitEvent;
83 type Effect = OnionCircuitEffect;
84
85 fn namespace(&self) -> &str {
86 ONION_CIRCUIT_NAMESPACE
87 }
88
89 fn init(&self) -> Self::State {
90 OnionCircuitState::default()
91 }
92
93 fn decode(&self, wire: Wire<'_>) -> std::result::Result<Self::Event, Reject> {
94 decode_event(wire)
95 }
96
97 fn step(
98 &self,
99 ctx: Ctx<'_, Self::State>,
100 event: Self::Event,
101 ) -> Transition<Self::State, Self::Effect> {
102 self.reducer.apply(ctx.state, event.input)
103 }
104}