p2p/connection/outgoing_effectful/
p2p_connection_outgoing_effectful_effects.rs

1use openmina_core::bug_condition;
2use redux::ActionMeta;
3
4use crate::{
5    connection::{
6        outgoing::{P2pConnectionOutgoingAction, P2pConnectionOutgoingError},
7        P2pConnectionService,
8    },
9    webrtc,
10};
11
12use super::P2pConnectionOutgoingEffectfulAction;
13
14impl P2pConnectionOutgoingEffectfulAction {
15    pub fn effects<Store, S>(self, _meta: &ActionMeta, store: &mut Store)
16    where
17        Store: crate::P2pStore<S>,
18        Store::Service: P2pConnectionService,
19    {
20        match self {
21            P2pConnectionOutgoingEffectfulAction::RandomInit { peers } => {
22                let picked_peer = store.service().random_pick(&peers);
23                if let Some(picked_peer) = picked_peer {
24                    store.dispatch(P2pConnectionOutgoingAction::Reconnect {
25                        opts: picked_peer,
26                        rpc_id: None,
27                    });
28                } else {
29                    bug_condition!("Picked peer is None");
30                }
31            }
32            P2pConnectionOutgoingEffectfulAction::Init { opts, .. } => {
33                let peer_id = *opts.peer_id();
34                store.service().outgoing_init(opts);
35                store.dispatch(P2pConnectionOutgoingAction::OfferSdpCreatePending { peer_id });
36            }
37            P2pConnectionOutgoingEffectfulAction::OfferSend {
38                peer_id,
39                offer,
40                signaling_method,
41            } => {
42                match signaling_method {
43                    webrtc::SignalingMethod::Http(_)
44                    | webrtc::SignalingMethod::Https(_)
45                    | webrtc::SignalingMethod::HttpsProxy(_, _) => {
46                        let Some(url) = signaling_method.http_url() else {
47                            return;
48                        };
49                        store.service().http_signaling_request(url, *offer);
50                    }
51                    webrtc::SignalingMethod::P2p { .. } => {
52                        bug_condition!("`P2pConnectionOutgoingEffectfulAction::OfferSend` shouldn't be called for `webrtc::SignalingMethod::P2p`");
53                        return;
54                    }
55                }
56                store.dispatch(P2pConnectionOutgoingAction::OfferSendSuccess { peer_id });
57            }
58            P2pConnectionOutgoingEffectfulAction::AnswerSet { peer_id, answer } => {
59                store.service().set_answer(peer_id, *answer);
60                store.dispatch(P2pConnectionOutgoingAction::FinalizePending { peer_id });
61            }
62            P2pConnectionOutgoingEffectfulAction::ConnectionAuthorizationEncryptAndSend {
63                peer_id,
64                other_pub_key,
65                auth,
66            } => {
67                store
68                    .service()
69                    .auth_encrypt_and_send(peer_id, &other_pub_key, auth);
70            }
71            P2pConnectionOutgoingEffectfulAction::ConnectionAuthorizationDecryptAndCheck {
72                peer_id,
73                other_pub_key,
74                expected_auth,
75                auth,
76            } => {
77                if store
78                    .service()
79                    .auth_decrypt(&other_pub_key, auth)
80                    .is_some_and(|remote_auth| remote_auth == expected_auth)
81                {
82                    store.dispatch(P2pConnectionOutgoingAction::Success { peer_id });
83                } else {
84                    store.dispatch(P2pConnectionOutgoingAction::Error {
85                        peer_id,
86                        error: P2pConnectionOutgoingError::ConnectionAuthError,
87                    });
88                }
89            }
90        }
91    }
92}