1use super::{super::*, *};
2use crate::{Data, P2pState, PeerId};
3use openmina_core::ActionEvent;
4use serde::{Deserialize, Serialize};
5
6#[derive(Serialize, Deserialize, Debug, Clone, ActionEvent)]
7#[action_event(fields(display(addr), select_kind = debug(kind), debug(data), fin, debug(token), debug(tokens)))]
8pub enum P2pNetworkSelectAction {
9 Init {
16 addr: ConnectionAddr,
17 kind: SelectKind,
18 incoming: bool,
19 },
20 #[action_event(level = trace)]
21 IncomingDataAuth {
22 addr: ConnectionAddr,
23 data: Data,
24 fin: bool,
25 },
26 #[action_event(level = trace)]
27 IncomingDataMux {
28 addr: ConnectionAddr,
29 peer_id: Option<PeerId>,
30 data: Data,
31 fin: bool,
32 },
33 #[action_event(level = trace)]
34 IncomingData {
35 addr: ConnectionAddr,
36 peer_id: PeerId,
37 stream_id: StreamId,
38 data: Data,
39 fin: bool,
40 },
41 IncomingPayloadAuth {
42 addr: ConnectionAddr,
43 fin: bool,
44 data: Data,
45 },
46 IncomingPayloadMux {
47 addr: ConnectionAddr,
48 peer_id: Option<PeerId>,
49 fin: bool,
50 data: Data,
51 },
52 IncomingPayload {
53 addr: ConnectionAddr,
54 peer_id: PeerId,
55 stream_id: StreamId,
56 fin: bool,
57 data: Data,
58 },
59 IncomingToken {
60 addr: ConnectionAddr,
61 kind: SelectKind,
62 },
63 OutgoingTokens {
64 addr: ConnectionAddr,
65 kind: SelectKind,
66 tokens: Vec<token::Token>,
67 },
68 Timeout {
69 addr: ConnectionAddr,
70 kind: SelectKind,
71 },
72}
73
74#[derive(Default, Serialize, Deserialize, Debug, Clone, Copy)]
75pub enum SelectKind {
76 #[default]
77 Authentication,
78 MultiplexingNoPeerId,
79 Multiplexing(PeerId),
80 Stream(PeerId, StreamId),
81}
82
83impl SelectKind {
84 pub fn stream_id(&self) -> Option<StreamId> {
85 match self {
86 Self::Authentication => None,
87 Self::MultiplexingNoPeerId => None,
88 Self::Multiplexing(_) => None,
89 Self::Stream(_, v) => Some(*v),
90 }
91 }
92
93 pub fn peer_id(&self) -> Option<PeerId> {
94 match self {
95 Self::Authentication => None,
96 Self::MultiplexingNoPeerId => None,
97 Self::Multiplexing(peer_id) => Some(*peer_id),
98 Self::Stream(peer_id, _) => Some(*peer_id),
99 }
100 }
101
102 #[allow(dead_code)]
103 pub(super) fn forward_data(
104 self,
105 addr: ConnectionAddr,
106 data: Data,
107 fin: bool,
108 ) -> P2pNetworkSelectAction {
109 match self {
110 SelectKind::Authentication => {
111 P2pNetworkSelectAction::IncomingPayloadAuth { addr, fin, data }
112 }
113 SelectKind::Multiplexing(peer_id) => P2pNetworkSelectAction::IncomingPayloadMux {
114 addr,
115 peer_id: Some(peer_id),
116 fin,
117 data,
118 },
119 SelectKind::MultiplexingNoPeerId => P2pNetworkSelectAction::IncomingPayloadMux {
120 addr,
121 peer_id: None,
122 fin,
123 data,
124 },
125 SelectKind::Stream(peer_id, stream_id) => P2pNetworkSelectAction::IncomingPayload {
126 addr,
127 peer_id,
128 stream_id,
129 fin,
130 data,
131 },
132 }
133 }
134}
135
136impl P2pNetworkSelectAction {
137 pub fn addr(&self) -> &ConnectionAddr {
138 match self {
139 Self::Init { addr, .. } => addr,
140 Self::IncomingDataAuth { addr, .. } => addr,
141 Self::IncomingDataMux { addr, .. } => addr,
142 Self::IncomingData { addr, .. } => addr,
143 Self::IncomingPayloadAuth { addr, .. } => addr,
144 Self::IncomingPayloadMux { addr, .. } => addr,
145 Self::IncomingPayload { addr, .. } => addr,
146 Self::IncomingToken { addr, .. } => addr,
147 Self::OutgoingTokens { addr, .. } => addr,
148 Self::Timeout { addr, .. } => addr,
149 }
150 }
151
152 pub fn select_kind(&self) -> SelectKind {
153 match self {
154 Self::Init { kind, .. } => *kind,
155 Self::IncomingDataAuth { .. } => SelectKind::Authentication,
156 Self::IncomingDataMux {
157 peer_id: Some(peer_id),
158 ..
159 } => SelectKind::Multiplexing(*peer_id),
160 Self::IncomingDataMux { peer_id: None, .. } => SelectKind::MultiplexingNoPeerId,
161 Self::IncomingData {
162 peer_id, stream_id, ..
163 } => SelectKind::Stream(*peer_id, *stream_id),
164 Self::IncomingPayloadAuth { .. } => SelectKind::Authentication,
165 Self::IncomingPayloadMux {
166 peer_id: Some(peer_id),
167 ..
168 } => SelectKind::Multiplexing(*peer_id),
169 Self::IncomingPayloadMux { peer_id: None, .. } => SelectKind::MultiplexingNoPeerId,
170 Self::IncomingPayload {
171 peer_id, stream_id, ..
172 } => SelectKind::Stream(*peer_id, *stream_id),
173 Self::IncomingToken { kind, .. } => *kind,
174 Self::OutgoingTokens { kind, .. } => *kind,
175 Self::Timeout { kind, .. } => *kind,
176 }
177 }
178}
179
180impl From<P2pNetworkSelectAction> for crate::P2pAction {
181 fn from(a: P2pNetworkSelectAction) -> Self {
182 Self::Network(a.into())
183 }
184}
185impl redux::EnablingCondition<P2pState> for P2pNetworkSelectAction {
186 fn is_enabled(&self, state: &P2pState, _time: redux::Timestamp) -> bool {
187 if state
188 .network
189 .scheduler
190 .connection_state(self.addr())
191 .and_then(|conn| conn.select_state(&self.select_kind()))
192 .is_none()
193 {
194 return false;
195 }
196
197 match self {
198 Self::Init { .. } => true,
199 Self::IncomingDataAuth { .. } => true,
200 Self::IncomingDataMux { .. } => true,
201 Self::IncomingData { .. } => true,
202 Self::IncomingPayloadAuth { .. } => true,
203 Self::IncomingPayloadMux { .. } => true,
204 Self::IncomingPayload { .. } => true,
205 Self::IncomingToken { .. } => true,
206 Self::OutgoingTokens { .. } => true,
207 Self::Timeout { .. } => true,
208 }
209 }
210}