p2p/channels/
p2p_channels_effectful_effects.rs

1use openmina_core::bug_condition;
2use redux::ActionMeta;
3
4use crate::webrtc::{Offer, P2pConnectionResponse};
5
6use super::{
7    signaling::{
8        discovery::{P2pChannelsSignalingDiscoveryAction, SignalingDiscoveryChannelMsg},
9        exchange::{P2pChannelsSignalingExchangeAction, SignalingExchangeChannelMsg},
10    },
11    ChannelMsg, MsgId, P2pChannelsEffectfulAction, P2pChannelsService,
12};
13
14impl P2pChannelsEffectfulAction {
15    pub fn effects<Store, S>(self, meta: &ActionMeta, store: &mut Store)
16    where
17        Store: crate::P2pStore<S>,
18        Store::Service: P2pChannelsService,
19    {
20        match self {
21            P2pChannelsEffectfulAction::InitChannel {
22                peer_id,
23                id,
24                on_success,
25            } => {
26                store.service().channel_open(peer_id, id);
27                store.dispatch_callback(on_success, peer_id);
28            }
29            P2pChannelsEffectfulAction::MessageSend {
30                peer_id,
31                msg_id,
32                msg,
33            } => {
34                store.service().channel_send(peer_id, msg_id, msg);
35            }
36            P2pChannelsEffectfulAction::SignalingDiscoveryAnswerDecrypt {
37                peer_id,
38                pub_key,
39                answer,
40            } => {
41                match store
42                    .service()
43                    .decrypt::<P2pConnectionResponse>(&pub_key, &answer)
44                {
45                    Err(_) => {
46                        store.dispatch(P2pChannelsSignalingDiscoveryAction::AnswerDecrypted {
47                            peer_id,
48                            answer: P2pConnectionResponse::SignalDecryptionFailed,
49                        });
50                    }
51                    Ok(answer) => {
52                        store.dispatch(P2pChannelsSignalingDiscoveryAction::AnswerDecrypted {
53                            peer_id,
54                            answer,
55                        });
56                    }
57                }
58            }
59            P2pChannelsEffectfulAction::SignalingDiscoveryOfferEncryptAndSend {
60                peer_id,
61                pub_key,
62                offer,
63            } => match store.service().encrypt(&pub_key, offer.as_ref()) {
64                Err(_) => {
65                    // TODO: handle
66                    openmina_core::error!(
67                        meta.time();
68                        summary = "Failed to encrypt webrtc offer",
69                        peer_id = peer_id.to_string()
70                    );
71                }
72                Ok(offer) => {
73                    let message = SignalingDiscoveryChannelMsg::DiscoveredAccept(offer);
74                    store
75                        .service()
76                        .channel_send(peer_id, super::MsgId::first(), message.into());
77                }
78            },
79            P2pChannelsEffectfulAction::SignalingExchangeOfferDecrypt {
80                peer_id,
81                pub_key,
82                offer,
83            } => {
84                match store.service().decrypt::<Offer>(&pub_key, &offer) {
85                    Err(_) => {
86                        store.dispatch(P2pChannelsSignalingExchangeAction::OfferDecryptError {
87                            peer_id,
88                        });
89                    }
90                    Ok(offer) if offer.identity_pub_key != pub_key => {
91                        // TODO(binier): propagate specific error.
92                        // This is invalid behavior either from relayer or offerer.
93                        store.dispatch(P2pChannelsSignalingExchangeAction::OfferDecryptError {
94                            peer_id,
95                        });
96                    }
97                    Ok(offer) => {
98                        store.dispatch(P2pChannelsSignalingExchangeAction::OfferDecryptSuccess {
99                            peer_id,
100                            offer,
101                        });
102                    }
103                }
104            }
105            P2pChannelsEffectfulAction::SignalingExchangeAnswerEncryptAndSend {
106                peer_id,
107                pub_key,
108                answer,
109            } => {
110                let Some(answer) = answer else {
111                    let message = SignalingExchangeChannelMsg::Answer(None);
112                    store.service().channel_send(
113                        peer_id,
114                        MsgId::first(),
115                        ChannelMsg::SignalingExchange(message),
116                    );
117                    return;
118                };
119
120                match store.service().encrypt(&pub_key, &answer) {
121                    Err(_) => bug_condition!("Failed to encrypt webrtc answer. Shouldn't happen since we managed to decrypt sent offer."),
122                    Ok(answer) => {
123                        let message = SignalingExchangeChannelMsg::Answer(Some(answer));
124                        store.service().channel_send(
125                            peer_id,
126                            MsgId::first(),
127                            ChannelMsg::SignalingExchange(message),
128                        );
129                    }
130                }
131            }
132        }
133    }
134}