1use core::fmt;
15use std::collections::HashSet;
16use std::{
17    any::{Any, TypeId},
18    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
19};
20
21use serde::{Deserialize, Serialize};
22use web_time::SystemTime;
23
24use ng_repo::errors::*;
25use ng_repo::log::*;
26use ng_repo::store::Store;
27use ng_repo::types::*;
28use ng_repo::utils::{sign, verify};
29
30use crate::app_protocol::*;
31use crate::utils::{
32    get_domain_without_port_443, is_ipv4_private, is_ipv6_private, is_private_ip, is_public_ip,
33    is_public_ipv4, is_public_ipv6,
34};
35use crate::WS_PORT_ALTERNATE;
36use crate::{actor::EActor, actors::admin::*, actors::*};
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct Credentials {
41    pub user_key: PrivKey,
42    pub read_cap: ReadCap,
43    pub private_store: RepoId,
44    pub protected_store: RepoId,
45    pub public_store: RepoId,
46    pub user_master_key: SymKey,
47    pub peer_priv_key: PrivKey,
48}
49
50impl Credentials {
51    pub fn new_partial(user_priv_key: &PrivKey) -> Self {
52        Credentials {
53            user_key: user_priv_key.clone(),
54            read_cap: ReadCap::nil(),
55            private_store: RepoId::nil(),
56            protected_store: RepoId::nil(),
57            public_store: RepoId::nil(),
58            user_master_key: SymKey::random(),
59            peer_priv_key: PrivKey::random_ed(),
60        }
61    }
62}
63
64#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
69pub enum InterfaceType {
70    Loopback,
71    Private,
72    Public,
73    Invalid,
74}
75
76impl InterfaceType {
77    pub fn is_ip_valid_for_type(&self, ip: &IP) -> bool {
78        self.is_ipaddr_valid_for_type(&ip.into())
79    }
80    pub fn is_ipaddr_valid_for_type(&self, ip: &IpAddr) -> bool {
81        match ip {
82            IpAddr::V4(v4) => self.is_ipv4_valid_for_type(v4),
83            IpAddr::V6(v6) => self.is_ipv6_valid_for_type(v6),
84        }
85    }
86
87    pub fn is_ipv4_valid_for_type(&self, ip: &Ipv4Addr) -> bool {
88        match self {
89            InterfaceType::Loopback => ip.is_loopback(),
90            InterfaceType::Public => is_public_ipv4(ip),
91            InterfaceType::Private => is_ipv4_private(ip),
93            _ => false,
94        }
95    }
96    pub fn is_ipv6_valid_for_type(&self, ip: &Ipv6Addr) -> bool {
97        match self {
98            InterfaceType::Loopback => ip.is_loopback(),
99            InterfaceType::Public => is_public_ipv6(ip),
100            InterfaceType::Private => is_ipv6_private(ip),
102            _ => false,
103        }
104    }
105}
106
107#[cfg(not(target_arch = "wasm32"))]
108#[derive(Clone, Debug)]
109pub struct Interface {
110    pub if_type: InterfaceType,
111    pub name: String,
112    pub mac_addr: Option<netdev::mac::MacAddr>,
113    pub ipv4: Vec<netdev::ip::Ipv4Net>,
115    pub ipv6: Vec<netdev::ip::Ipv6Net>,
117}
118
119#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
121pub struct BindAddress {
122    pub port: u16,
123    pub ip: IP,
124}
125
126impl BindAddress {
127    pub fn to_ws_url(&self) -> String {
128        format!(
129            "ws://{}:{}",
130            self.ip,
131            if self.port == 0 { 80 } else { self.port }
132        )
133    }
134    pub fn new_localhost_with_port(port: u16) -> Self {
135        BindAddress {
136            ip: LOOPBACK_IPV4.clone(),
137            port,
138        }
139    }
140}
141
142impl From<&SocketAddr> for BindAddress {
143    #[inline]
144    fn from(addr: &SocketAddr) -> BindAddress {
145        let ip_addr = addr.ip();
146        let ip = IP::try_from(&ip_addr).unwrap();
147        let port = addr.port();
148        BindAddress { ip, port }
149    }
150}
151
152#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
158pub struct BrokerCoreV0 {
159    pub peer_id: PubKey,
161
162    pub addrs: Vec<BindAddress>,
164}
165
166#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Hash)]
168pub enum BrokerCore {
169    V0(BrokerCoreV0),
170}
171
172#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
174pub enum BrokerServerTypeV0 {
175    Localhost(u16), BoxPrivate(Vec<BindAddress>),
177    Public(Vec<BindAddress>),
178    BoxPublicDyn(Vec<BindAddress>), Domain(String),                 }
182
183#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
185pub struct BrokerServerV0 {
186    pub server_type: BrokerServerTypeV0,
188
189    pub can_verify: bool,
191
192    pub can_forward: bool,
194
195    pub peer_id: PubKey,
197}
198
199#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
200pub struct BrokerServerContentV0 {
201    pub servers: Vec<BrokerServerTypeV0>,
202
203    pub version: u32,
204}
205
206#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
207pub struct BrokerServer {
208    pub content: BrokerServerContentV0,
209
210    pub peer_id: PubKey,
212
213    pub sig: Option<Sig>,
215}
216
217pub type LocatorV0 = Vec<BrokerServer>;
218
219#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
220pub enum Locator {
221    V0(LocatorV0),
222}
223
224impl fmt::Display for Locator {
225    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226        let ser = serde_bare::to_vec(&self).unwrap();
227        write!(f, "{}", base64_url::encode(&ser))
228    }
229}
230
231impl Locator {
232    pub fn empty() -> Self {
233        Self::V0(vec![])
234    }
235    pub fn first_broker_server(&self) -> Result<BrokerServerV0, NgError> {
236        match self {
237            Self::V0(v0) => {
238                let bs = v0.get(0).ok_or(NgError::BrokerNotFound)?;
239                Ok(BrokerServerV0 {
240                    server_type: bs
241                        .content
242                        .servers
243                        .get(0)
244                        .ok_or(NgError::BrokerNotFound)?
245                        .clone(),
246                    can_verify: false,
247                    can_forward: false,
248                    peer_id: bs.peer_id,
249                })
250            }
251        }
252    }
253    pub fn add(&mut self, bs: BrokerServerV0) {
254        match self {
255            Self::V0(v0) => {
256                for b in v0.iter_mut() {
257                    if b.peer_id == bs.peer_id {
258                        b.content.servers.push(bs.server_type);
259                        return;
260                    }
261                }
262                v0.push(BrokerServer {
263                    peer_id: bs.peer_id,
264                    sig: None,
265                    content: BrokerServerContentV0 {
266                        version: 0,
267                        servers: vec![bs.server_type],
268                    },
269                });
270            }
271        }
272    }
273}
274
275impl TryFrom<&str> for Locator {
276    type Error = NgError;
277    fn try_from(string: &str) -> Result<Self, NgError> {
278        let vec = base64_url::decode(string).map_err(|_| NgError::InvalidKey)?;
279        Ok(serde_bare::from_slice(&vec).map_err(|_| NgError::InvalidKey)?)
280    }
281}
282
283impl From<BrokerServerV0> for Locator {
284    fn from(bs: BrokerServerV0) -> Self {
285        Locator::V0(vec![BrokerServer {
286            peer_id: bs.peer_id,
287            content: BrokerServerContentV0 {
288                version: 0,
289                servers: vec![bs.server_type],
290            },
291            sig: None,
292        }])
293    }
294}
295
296#[doc(hidden)]
297pub const APP_ACCOUNT_REGISTERED_SUFFIX: &str = "/#/user/registered";
298
299#[doc(hidden)]
300pub const NG_NET_URL: &str = "https://nextgraph.net";
301
302#[doc(hidden)]
303pub const NG_APP_URL: &str = "https://nextgraph.app";
304
305#[doc(hidden)]
306pub const APP_NG_WS_URL: &str = "wss://nextgraph.app";
307
308#[allow(dead_code)]
309fn api_dyn_peer_url(peer_id: &PubKey) -> String {
310    format!("https://nextgraph.net/api/v1/dynpeer/{}", peer_id)
311}
312
313#[doc(hidden)]
314pub const LOCAL_HOSTS: [&str; 3] = ["localhost", "127.0.0.1", "[::1]"];
315
316fn local_ws_url(port: &u16) -> String {
317    format!("ws://localhost:{}", if *port == 0 { 80 } else { *port })
318}
319#[doc(hidden)]
320pub(crate) fn local_http_url(port: &u16) -> String {
321    format!("http://localhost:{}", if *port == 0 { 80 } else { *port })
322}
323
324#[doc(hidden)]
325pub const LOCAL_URLS: [&str; 3] = ["http://localhost", "http://127.0.0.1", "http://[::1]"];
326use url::{Host, Url};
327
328impl BrokerServerTypeV0 {
329    pub fn find_first_ipv4(&self) -> Option<&BindAddress> {
330        match self {
331            Self::BoxPrivate(addrs) => {
332                for addr in addrs {
333                    if addr.ip.is_v4() {
334                        return Some(addr);
335                    }
336                }
337                return None;
338            }
339            _ => None,
340        }
341    }
342    pub fn find_first_ipv6(&self) -> Option<&BindAddress> {
343        match self {
344            Self::BoxPrivate(addrs) => {
345                for addr in addrs {
346                    if addr.ip.is_v6() {
347                        return Some(addr);
348                    }
349                }
350                return None;
351            }
352            _ => None,
353        }
354    }
355}
356
357impl BrokerServerV0 {
358    pub fn new_localhost(peer_id: PubKey) -> Self {
359        BrokerServerV0 {
360            server_type: BrokerServerTypeV0::Localhost(WS_PORT_ALTERNATE[0]),
361            can_verify: false,
362            can_forward: true,
363            peer_id,
364        }
365    }
366
367    fn first_ipv4(&self) -> Option<(String, Vec<BindAddress>)> {
368        self.server_type.find_first_ipv4().map_or(None, |bindaddr| {
369            Some((format!("ws://{}:{}", bindaddr.ip, bindaddr.port), vec![]))
370        })
371    }
372
373    fn first_ipv6(&self) -> Option<(String, Vec<BindAddress>)> {
374        self.server_type.find_first_ipv6().map_or(None, |bindaddr| {
375            Some((format!("ws://{}:{}", bindaddr.ip, bindaddr.port), vec![]))
376        })
377    }
378
379    pub fn first_ipv4_http(&self) -> Option<String> {
380        self.server_type.find_first_ipv4().map_or(None, |bindaddr| {
381            Some(format!("http://{}:{}", bindaddr.ip, bindaddr.port))
382        })
383    }
384
385    pub fn first_ipv6_http(&self) -> Option<String> {
386        self.server_type.find_first_ipv6().map_or(None, |bindaddr| {
387            Some(format!("http://{}:{}", bindaddr.ip, bindaddr.port))
388        })
389    }
390
391    fn first_ipv6_or_ipv4(
392        ipv4: bool,
393        ipv6: bool,
394        addrs: &Vec<BindAddress>,
395    ) -> Option<&BindAddress> {
396        if ipv6 {
397            for addr in addrs {
398                if addr.ip.is_v6() {
399                    return Some(addr);
400                }
401            }
402        }
403        if ipv4 {
404            for addr in addrs {
405                if addr.ip.is_v4() {
406                    return Some(addr);
407                }
408            }
409        }
410        return None;
411    }
412
413    fn ng_app_bootstrap_url(addr: &BindAddress, key: PubKey) -> Option<String> {
414        let payload = (addr, key);
415        let payload_ser = serde_bare::to_vec(&payload).ok();
416        if payload_ser.is_none() {
417            return None;
418        }
419        Some(format!(
420            "{}?b={}",
421            NG_APP_URL,
422            base64_url::encode(&payload_ser.unwrap())
423        ))
424    }
425
426    fn ng_app_bootstrap_url_with_first_ipv6_or_ipv4(
427        ipv4: bool,
428        ipv6: bool,
429        addrs: &Vec<BindAddress>,
430        key: PubKey,
431    ) -> Option<String> {
432        if let Some(addr) = Self::first_ipv6_or_ipv4(ipv4, ipv6, addrs) {
433            return Self::ng_app_bootstrap_url(addr, key);
434        }
435        None
436    }
437
438    pub async fn get_url_for_ngnet(&self, ipv4: bool, ipv6: bool) -> Option<String> {
440        match &self.server_type {
441            BrokerServerTypeV0::Public(addrs) => {
442                Self::ng_app_bootstrap_url_with_first_ipv6_or_ipv4(
443                    ipv4,
444                    ipv6,
445                    addrs,
446                    self.peer_id,
447                )
448            }
449            BrokerServerTypeV0::BoxPublicDyn(addrs) => {
450                if addrs.len() > 0 {
463                    Self::ng_app_bootstrap_url_with_first_ipv6_or_ipv4(
464                        ipv4,
465                        ipv6,
466                        &addrs,
467                        self.peer_id,
468                    )
469                } else {
470                    None
471                }
472            }
473            BrokerServerTypeV0::Domain(domain) => Some(format!("https://{}", domain)),
474            BrokerServerTypeV0::Localhost(port) => Some(local_http_url(&port)),
475            BrokerServerTypeV0::BoxPrivate(_) => {
476                if ipv6 {
477                    let v6 = self.server_type.find_first_ipv6().map_or(None, |bindaddr| {
478                        Some(format!("http://{}:{}", bindaddr.ip, bindaddr.port))
479                    });
480                    if v6.is_some() {
481                        return v6;
482                    }
483                }
484                if ipv4 {
485                    self.server_type.find_first_ipv4().map_or(None, |bindaddr| {
486                        Some(format!("http://{}:{}", bindaddr.ip, bindaddr.port))
487                    })
488                } else {
489                    None
490                }
491            }
492        }
493    }
494
495    pub fn is_public_server(&self) -> bool {
496        match &self.server_type {
497            BrokerServerTypeV0::Localhost(_) => false,
498            BrokerServerTypeV0::BoxPrivate(_) => false,
499            BrokerServerTypeV0::Public(_) => true,
500            BrokerServerTypeV0::BoxPublicDyn(_) => true,
501            BrokerServerTypeV0::Domain(_) => true,
502        }
503    }
504
505    pub fn get_domain(&self) -> Option<String> {
506        if let BrokerServerTypeV0::Domain(domain) = &self.server_type {
507            Some(domain.clone())
508        } else {
509            None
510        }
511    }
512
513    pub async fn get_ws_url(
518        &self,
519        location: &Option<String>,
520    ) -> Option<(String, Vec<BindAddress>)> {
521        if location.is_some() {
522            let location = location.as_ref().unwrap();
523            if location.starts_with(NG_APP_URL) {
524                match &self.server_type {
525                    BrokerServerTypeV0::Public(addrs) => {
526                        Some((APP_NG_WS_URL.to_string(), addrs.clone()))
527                    }
528                    BrokerServerTypeV0::BoxPublicDyn(addrs) => {
529                        if addrs.len() > 0 {
537                            Some((APP_NG_WS_URL.to_string(), addrs.clone()))
538                        } else {
539                            None
540                        }
541                    }
542                    _ => None,
543                }
544            } else if let BrokerServerTypeV0::Domain(domain) = &self.server_type {
545                let url = format!("https://{}", domain);
546                if location.starts_with(&url) {
547                    let wss_url = format!("wss://{}", domain);
548                    Some((wss_url, vec![]))
549                } else {
550                    None
551                }
552            } else {
553                if location.starts_with(LOCAL_URLS[0])
555                    || location.starts_with(LOCAL_URLS[1])
556                    || location.starts_with(LOCAL_URLS[2])
557                {
558                    if let BrokerServerTypeV0::Localhost(port) = self.server_type {
559                        Some((local_ws_url(&port), vec![]))
560                    } else {
561                        None
562                    }
563                }
564                else if location.starts_with("http://") {
566                    let url = Url::parse(&location).unwrap();
567                    match url.host() {
568                        Some(Host::Ipv4(ip)) => {
569                            if is_ipv4_private(&ip) {
570                                self.first_ipv4()
571                            } else {
572                                None
573                            }
574                        }
575                        Some(Host::Ipv6(ip)) => {
576                            if is_ipv6_private(&ip) {
577                                self.first_ipv6()
578                            } else {
579                                None
580                            }
581                        }
582                        _ => None,
583                    }
584                } else {
585                    None
586                }
587            }
588        } else {
589            match &self.server_type {
591                BrokerServerTypeV0::Localhost(port) => Some((local_ws_url(port), vec![])),
593                BrokerServerTypeV0::BoxPrivate(addrs) => Some((String::new(), addrs.clone())),
594                BrokerServerTypeV0::Public(addrs) => Some((String::new(), addrs.clone())),
595                BrokerServerTypeV0::BoxPublicDyn(addrs) => {
596                    if addrs.len() > 0 {
604                        Some((String::new(), addrs.clone()))
605                    } else {
606                        None
607                    }
608                }
609                BrokerServerTypeV0::Domain(domain) => Some((format!("wss://{}", domain), vec![])),
610            }
611        }
612    }
613
614    pub fn to_iframe_msg(&self) -> BootstrapIframeMsg {
615
616        match &self.server_type {
617            BrokerServerTypeV0::Domain(domain) => BootstrapIframeMsg::domain(domain.clone()),
618            BrokerServerTypeV0::Localhost(port) => BootstrapIframeMsg::local(*port, self.peer_id),
619            BrokerServerTypeV0::BoxPrivate(addrs) => BootstrapIframeMsg::private(addrs.to_vec(), self.peer_id),
620            BrokerServerTypeV0::Public(_) | BrokerServerTypeV0::BoxPublicDyn(_) => BootstrapIframeMsg::ngbox(),
621        }
622    }
623}
624
625#[derive(Clone, Debug, Serialize, Deserialize)]
626pub struct BootstrapIframeMsg {
627
628    pub peer_id: Option<String>,
629
630    pub private: Option<Vec<BindAddress>>,
631
632    pub ngbox: Option<bool>,
633
634    pub domain: Option<String>,
635
636    pub localhost: Option<u16>,
637
638}
639
640impl BootstrapIframeMsg {
641    fn new() -> Self {
642        Self {
643            peer_id:None,
644            private:None,
645            ngbox:None,
646            domain:None,
647            localhost:None
648        }
649    }
650
651    fn domain(domain: String) -> Self {
652        let mut s = Self::new();
653        s.domain = Some(domain);
654        s
655    }
656
657    fn ngbox() -> Self {
658        let mut s = Self::new();
659        s.ngbox = Some(true);
660        s
661    }
662
663    fn private(addrs: Vec<BindAddress>, peer_id: PubKey) -> Self {
664        let mut s = Self::new();
665        s.peer_id = Some(peer_id.to_string());
666        s.private = Some(addrs);
667        s
668    }
669
670    fn local(port: u16, peer_id: PubKey) -> Self {
671        let mut s = Self::new();
672        s.peer_id = Some(peer_id.to_string());
673        s.localhost = Some(port);
674        s
675    }
676}
677
678#[derive(Clone, Debug, Serialize, Deserialize)]
680pub struct BootstrapContentV0 {
681    pub servers: Vec<BrokerServerV0>,
683}
684
685impl BootstrapContentV0 {
686    pub fn new_localhost(peer_id: PubKey) -> Self {
687        BootstrapContentV0 {
688            servers: vec![BrokerServerV0::new_localhost(peer_id)],
689        }
690    }
691    pub fn new_empty() -> Self {
692        BootstrapContentV0 { servers: vec![] }
693    }
694    pub fn merge(&mut self, with: &BootstrapContentV0) {
695        'outer: for server2 in &with.servers {
696            for server1 in &self.servers {
697                if *server1 == *server2 {
698                    continue 'outer;
699                }
700            }
701            self.servers.push(server2.clone());
702        }
703    }
704    pub fn get_first_peer_id(&self) -> Option<PubKey> {
705        self.servers.first().map(|s| s.peer_id)
706    }
707
708    pub fn get_domain(&self) -> Option<String> {
709        for server in self.servers.iter() {
710            if let BrokerServerTypeV0::Domain(name) = &server.server_type {
711                return Some(name.clone());
712            }
713        }
714        None
715    }
716
717    pub fn to_iframe_msgs(&self) -> Vec<BootstrapIframeMsg> {
718        self.servers.iter().map(|server| server.to_iframe_msg()).collect()
719    }
720}
721
722#[derive(Clone, Debug, Serialize, Deserialize)]
723pub enum BootstrapContent {
724    V0(BootstrapContentV0),
725}
726
727impl BootstrapContent {
728    pub fn servers(&self) -> &Vec<BrokerServerV0> {
729        match self {
730            Self::V0(v0) => &v0.servers,
731        }
732    }
733}
734
735#[derive(Clone, Debug, Serialize, Deserialize)]
737pub struct LocalBootstrapInfoV0 {
738    pub bootstrap: BootstrapContentV0,
740
741    pub registration_url: Option<String>,
743}
744
745#[derive(Clone, Debug, Serialize, Deserialize)]
746pub enum LocalBootstrapInfo {
747    V0(LocalBootstrapInfoV0),
748}
749
750impl LocalBootstrapInfo {
751    pub fn servers(&self) -> &Vec<BrokerServerV0> {
752        match self {
753            Self::V0(v0) => &v0.bootstrap.servers,
754        }
755    }
756}
757
758impl From<LocalBootstrapInfo> for Invitation {
759    fn from(value: LocalBootstrapInfo) -> Self {
760        let LocalBootstrapInfo::V0(info) = value;
761        let name = info.bootstrap.get_domain();
762        let url = info.registration_url.clone();
763        Invitation::V0(InvitationV0 {
764            bootstrap: info.bootstrap,
765            code: None,
766            name,
767            url,
768        })
769    }
770}
771
772#[derive(Clone, Debug, Serialize, Deserialize)]
773pub enum InvitationCode {
774    Unique(SymKey),
775    Admin(SymKey),
776    Multi(SymKey),
777    Setup(SymKey),
778}
779
780impl InvitationCode {
781    pub fn get_symkey(&self) -> SymKey {
782        match self {
783            Self::Unique(s) | Self::Admin(s) | Self::Multi(s) | Self::Setup(s) => s.clone(),
784        }
785    }
786}
787
788impl fmt::Display for InvitationCode {
789    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
790        match self {
791            Self::Unique(k) => write!(f, "unique {}", k),
792            Self::Admin(k) => write!(f, "admin {}", k),
793            Self::Multi(k) => write!(f, "multi {}", k),
794            Self::Setup(k) => write!(f, "setup {}", k),
795        }
796    }
797}
798
799#[derive(Clone, Debug, Serialize, Deserialize)]
801pub struct InvitationV0 {
802    pub bootstrap: BootstrapContentV0,
804
805    pub code: Option<SymKey>,
806
807    pub name: Option<String>,
809
810    pub url: Option<String>,
812}
813
814impl InvitationV0 {
815    pub fn set_bootstrap(&mut self, content: BootstrapContent) {
816        match content {
817            BootstrapContent::V0(v0) => self.bootstrap = v0,
818        }
819    }
820    pub fn empty(name: Option<String>) -> Self {
821        InvitationV0 {
822            bootstrap: BootstrapContentV0::new_empty(),
823            code: None,
824            name,
825            url: None,
826        }
827    }
828    pub fn new(
829        bootstrap_content: BootstrapContent,
830        code: Option<SymKey>,
831        name: Option<String>,
832        url: Option<String>,
833    ) -> Self {
834        match bootstrap_content {
835            BootstrapContent::V0(v0) => InvitationV0 {
836                bootstrap: v0,
837                code,
838                name,
839                url,
840            },
841        }
842    }
843    pub fn append_bootstraps(&mut self, add: &mut Option<BootstrapContentV0>) {
844        if add.is_some() {
845            let add = add.as_mut().unwrap();
846            self.bootstrap.servers.append(&mut add.servers);
847        }
848    }
849}
850
851impl Invitation {
852    pub fn new_v0(
853        bootstrap: BootstrapContentV0,
854        name: Option<String>,
855        url: Option<String>,
856    ) -> Self {
857        Invitation::V0(InvitationV0 {
858            bootstrap,
859            code: Some(SymKey::random()),
860            name,
861            url,
862        })
863    }
864
865    pub fn new_v0_free(
866        bootstrap: BootstrapContentV0,
867        name: Option<String>,
868        url: Option<String>,
869    ) -> Self {
870        Invitation::V0(InvitationV0 {
871            bootstrap,
872            code: None,
873            name,
874            url,
875        })
876    }
877
878    pub fn intersects(&self, invite2: Invitation) -> Invitation {
879        let Invitation::V0(v0) = self;
880        let mut new_invite = InvitationV0 {
881            bootstrap: BootstrapContentV0::new_empty(),
882            code: v0.code.clone(),
883            name: v0.name.clone(),
884            url: v0.url.clone(),
885        };
886        for server2 in invite2.get_servers() {
887            for server1 in &v0.bootstrap.servers {
888                if *server1 == *server2 {
889                    new_invite.bootstrap.servers.push(server2.clone());
890                    break;
891                }
892            }
893        }
894        Invitation::V0(new_invite)
895    }
896
897    pub fn get_servers(&self) -> &Vec<BrokerServerV0> {
898        match self {
899            Invitation::V0(v0) => &v0.bootstrap.servers,
900        }
901    }
902    pub fn get_domain(&self) -> Option<String> {
903        for bootstrap in self.get_servers() {
904            let res = bootstrap.get_domain();
905            if res.is_some() {
906                return res;
907            }
908        }
909        None
910    }
911
912    pub fn set_name(&mut self, name: Option<String>) {
913        if name.is_some() {
914            match self {
915                Invitation::V0(v0) => v0.name = Some(name.unwrap()),
916            }
917        }
918    }
919
920    pub fn set_url(&mut self, url: Option<&String>) {
921        if url.is_some() {
922            match self {
923                Invitation::V0(v0) => v0.url = Some(url.unwrap().clone()),
924            }
925        }
926    }
927
928    pub fn get_urls(&self) -> Vec<String> {
930        match self {
931            Invitation::V0(v0) => {
932                let mut res = vec![];
933                let ser = serde_bare::to_vec(&self).unwrap();
934                let url_param = base64_url::encode(&ser);
935                res.push(format!("{}/#/i/{}", NG_NET_URL, url_param));
936                for server in &v0.bootstrap.servers {
937                    match &server.server_type {
938                        BrokerServerTypeV0::Domain(domain) => {
939                            res.push(format!("https://{}/#/i/{}", domain, url_param));
940                        }
941                        BrokerServerTypeV0::BoxPrivate(addrs) => {
942                            for bindaddr in addrs {
943                                res.push(format!(
944                                    "http://{}:{}/#/i/{}",
945                                    bindaddr.ip, bindaddr.port, url_param
946                                ));
947                            }
948                        }
949                        BrokerServerTypeV0::Localhost(port) => {
950                            res.push(format!("{}/#/i/{}", local_http_url(&port), url_param));
951                        }
952                        _ => {}
953                    }
954                }
955                res
956            }
957        }
958    }
959}
960
961impl fmt::Display for Invitation {
962    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
963        let ser = serde_bare::to_vec(&self).unwrap();
964        let string = base64_url::encode(&ser);
965        write!(f, "{}", string)
966    }
967}
968
969impl TryFrom<String> for Invitation {
970    type Error = NgError;
971    fn try_from(value: String) -> Result<Self, NgError> {
972        let ser = base64_url::decode(&value).map_err(|_| NgError::InvalidInvitation)?;
973        let invite: Invitation =
974            serde_bare::from_slice(&ser).map_err(|_| NgError::InvalidInvitation)?;
975        Ok(invite)
976    }
977}
978
979#[derive(Clone, Debug, Serialize, Deserialize)]
981pub enum Invitation {
982    V0(InvitationV0),
983}
984
985#[derive(Clone, Debug, Serialize, Deserialize)]
1000pub enum CreateAccountBSP {
1001    V0(CreateAccountBSPV0),
1002}
1003
1004impl TryFrom<String> for CreateAccountBSP {
1005    type Error = NgError;
1006    fn try_from(value: String) -> Result<Self, NgError> {
1007        let ser = base64_url::decode(&value).map_err(|_| NgError::InvalidCreateAccount)?;
1008        let invite: CreateAccountBSP =
1009            serde_bare::from_slice(&ser).map_err(|_| NgError::InvalidCreateAccount)?;
1010        Ok(invite)
1011    }
1012}
1013
1014impl CreateAccountBSP {
1015    pub fn encode(&self) -> Option<String> {
1016        let payload_ser = serde_bare::to_vec(self).ok();
1017        if payload_ser.is_none() {
1018            return None;
1019        }
1020        Some(base64_url::encode(&payload_ser.unwrap()))
1021    }
1022    pub fn redirect_url(&self) -> &Option<String> {
1028        match self {
1029            Self::V0(v0) => &v0.redirect_url,
1030        }
1031    }
1032    }
1043
1044#[derive(Clone, Debug, Serialize, Deserialize)]
1046pub struct CreateAccountBSPV0 {
1047    pub redirect_url: Option<String>,
1058}
1059
1060#[cfg(not(target_arch = "wasm32"))]
1062#[derive(Clone, Debug, Serialize, Deserialize)]
1063pub struct ListenerInfo {
1064    pub config: ListenerV0,
1065
1066    pub addrs: Vec<BindAddress>,
1068}
1069
1070#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
1076pub enum AcceptForwardForV0 {
1077    No,
1079
1080    PrivateDomain((String, String)),
1082
1083    PublicDomain((String, String)),
1086
1087    PublicDomainPeer((String, PrivKey, String)),
1092
1093    PublicDyn((u16, u32, String)),
1096
1097    PublicStatic((BindAddress, Option<BindAddress>, String)),
1101}
1102
1103impl AcceptForwardForV0 {
1104    pub fn get_public_bind_addresses(&self) -> Vec<BindAddress> {
1105        match self {
1106            AcceptForwardForV0::PublicStatic((ipv4, ipv6, _)) => {
1107                let mut res = vec![ipv4.clone()];
1108                if ipv6.is_some() {
1109                    res.push(ipv6.unwrap().clone())
1110                }
1111                res
1112            }
1113            AcceptForwardForV0::PublicDyn(_) => {
1114                todo!();
1115            }
1116            _ => panic!("cannot call get_public_bind_addresses"),
1117        }
1118    }
1119
1120    pub fn get_public_bind_ipv6_address(&self) -> Option<IP> {
1121        match self {
1122            AcceptForwardForV0::PublicStatic((_ipv4, ipv6, _)) => {
1123                if ipv6.is_some() {
1125                    return Some(ipv6.unwrap().ip.clone());
1126                } else {
1127                    return None;
1128                }
1129            }
1130            AcceptForwardForV0::PublicDyn(_) => {
1131                todo!();
1132            }
1133            _ => None,
1134        }
1135    }
1136
1137    pub fn is_public_domain(&self) -> bool {
1138        match self {
1139            AcceptForwardForV0::PublicDomainPeer(_) => true,
1140            AcceptForwardForV0::PublicDomain(_) => true,
1141            _ => false,
1142        }
1143    }
1144    pub fn is_public_static(&self) -> bool {
1145        match self {
1146            AcceptForwardForV0::PublicStatic(_) => true,
1147            _ => false,
1148        }
1149    }
1150    pub fn is_no(&self) -> bool {
1151        match self {
1152            AcceptForwardForV0::No => true,
1153            _ => false,
1154        }
1155    }
1156    pub fn is_public_dyn(&self) -> bool {
1157        match self {
1158            AcceptForwardForV0::PublicDyn(_) => true,
1159            _ => false,
1160        }
1161    }
1162    pub fn is_private_domain(&self) -> bool {
1163        match self {
1164            AcceptForwardForV0::PrivateDomain(_) => true,
1165            _ => false,
1166        }
1167    }
1168    pub fn domain_with_common_peer_id(&self) -> Option<PubKey> {
1169        match self {
1170            AcceptForwardForV0::PublicDomainPeer((_, privkey, _)) => Some(privkey.to_pub()),
1171            _ => None,
1172        }
1173    }
1174    pub fn get_domain(&self) -> &str {
1175        let domain = get_domain_without_port_443(match self {
1176            AcceptForwardForV0::PrivateDomain((d, _)) => d,
1177            AcceptForwardForV0::PublicDomain((d, _)) => d,
1178            AcceptForwardForV0::PublicDomainPeer((d, _, _)) => d,
1179            _ => panic!("cannot call get_domain if AcceptForwardForV0 is not a domain"),
1180        });
1181        domain
1184    }
1185}
1186
1187#[cfg(not(target_arch = "wasm32"))]
1188#[derive(Clone, Debug, Serialize, Deserialize)]
1190pub struct ListenerV0 {
1191    pub interface_name: String,
1194
1195    pub if_type: InterfaceType,
1196
1197    pub interface_refresh: u32,
1200
1201    pub ipv6: bool,
1203
1204    pub port: u16,
1206
1207    pub private_core: bool,
1209
1210    pub serve_app: bool,
1212
1213    pub bind_public_ipv6: bool,
1215
1216    pub refuse_clients: bool,
1219
1220    pub discoverable: bool,
1222
1223    pub accept_direct: bool,
1226
1227    pub accept_forward_for: AcceptForwardForV0,
1229    }
1234
1235#[cfg(not(target_arch = "wasm32"))]
1236impl ListenerV0 {
1237    pub fn should_bind_public_ipv6_to_private_interface(&self, ip: Ipv6Addr) -> bool {
1238        let public_ip = self.accept_forward_for.get_public_bind_ipv6_address();
1239        if public_ip.is_none() {
1240            return false;
1241        }
1242        let public_ipv6addr: IpAddr = public_ip.as_ref().unwrap().into();
1243        return if let IpAddr::V6(v6) = public_ipv6addr {
1244            self.bind_public_ipv6 && self.if_type == InterfaceType::Private && ip == v6
1245        } else {
1246            false
1247        };
1248    }
1249
1250    pub fn new_direct(interface: Interface, ipv6: bool, port: u16) -> Self {
1251        Self {
1252            interface_name: interface.name,
1253            if_type: interface.if_type,
1254            interface_refresh: 0,
1255            ipv6,
1256            port,
1257            private_core: false,
1258            discoverable: false,
1259            accept_direct: true,
1260            refuse_clients: false,
1261            serve_app: true,
1262            bind_public_ipv6: false,
1263            accept_forward_for: AcceptForwardForV0::No,
1264        }
1265    }
1266
1267    pub fn is_core(&self) -> bool {
1268        match self.accept_forward_for {
1269            AcceptForwardForV0::PublicStatic(_) => true,
1270            AcceptForwardForV0::PublicDyn(_) => true,
1271            AcceptForwardForV0::PublicDomain(_) | AcceptForwardForV0::PublicDomainPeer(_) => false,
1272            AcceptForwardForV0::PrivateDomain(_) => false,
1273            AcceptForwardForV0::No => {
1274                self.if_type == InterfaceType::Public
1275                    || (self.private_core && self.if_type != InterfaceType::Invalid)
1276            }
1277        }
1278    }
1279
1280    pub fn accepts_client(&self) -> bool {
1281        match self.accept_forward_for {
1282            AcceptForwardForV0::PublicStatic(_)
1283            | AcceptForwardForV0::PublicDyn(_)
1284            | AcceptForwardForV0::PublicDomain(_)
1285            | AcceptForwardForV0::PublicDomainPeer(_) => self.accept_direct || !self.refuse_clients,
1286            AcceptForwardForV0::PrivateDomain(_) => true,
1287            AcceptForwardForV0::No => {
1288                self.if_type == InterfaceType::Public && !self.refuse_clients
1289                    || self.if_type != InterfaceType::Public
1290            }
1291        }
1292    }
1293
1294    pub fn get_bootstraps(&self, addrs: Vec<BindAddress>) -> Vec<BrokerServerTypeV0> {
1295        let mut res: Vec<BrokerServerTypeV0> = vec![];
1296        match self.accept_forward_for {
1297            AcceptForwardForV0::PublicStatic(_) => {
1298                let pub_addrs = self.accept_forward_for.get_public_bind_addresses();
1299                if !self.refuse_clients {
1301                    res.push(BrokerServerTypeV0::Public(pub_addrs));
1302                }
1303                if self.accept_direct {
1304                    res.push(BrokerServerTypeV0::BoxPrivate(addrs));
1305                }
1306            }
1307            AcceptForwardForV0::PublicDyn(_) => {
1308                let pub_addrs = self.accept_forward_for.get_public_bind_addresses();
1309                if !self.refuse_clients {
1311                    res.push(BrokerServerTypeV0::BoxPublicDyn(pub_addrs));
1312                }
1313                if self.accept_direct {
1314                    res.push(BrokerServerTypeV0::BoxPrivate(addrs));
1315                }
1316            }
1317            AcceptForwardForV0::PublicDomain(_) | AcceptForwardForV0::PublicDomainPeer(_) => {
1318                if !self.refuse_clients {
1319                    res.push(BrokerServerTypeV0::Domain(
1320                        self.accept_forward_for.get_domain().to_string(),
1321                    ));
1322                }
1323                }
1332            AcceptForwardForV0::PrivateDomain(_) => {
1333                res.push(BrokerServerTypeV0::Domain(
1334                    self.accept_forward_for.get_domain().to_string(),
1335                ));
1336            }
1337            AcceptForwardForV0::No => {
1338                if self.if_type == InterfaceType::Loopback {
1339                    res.push(BrokerServerTypeV0::Localhost(addrs[0].port));
1340                } else if self.if_type == InterfaceType::Public {
1341                    if !self.refuse_clients {
1343                        res.push(BrokerServerTypeV0::Public(addrs));
1344                    }
1345                } else if self.if_type == InterfaceType::Private {
1346                    res.push(BrokerServerTypeV0::BoxPrivate(addrs));
1347                }
1348            }
1349        }
1350        res
1351    }
1352}
1353#[cfg(not(target_arch = "wasm32"))]
1354impl fmt::Display for ListenerV0 {
1355    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1356        let mut id = self.interface_name.clone();
1357        id.push('@');
1358        id.push_str(&self.port.to_string());
1359        write!(f, "{}", id)
1360    }
1361}
1362
1363#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
1365pub enum BrokerOverlayPermission {
1366    Nobody,
1367    Anybody,
1368    AllRegisteredUser,
1369    UsersList(Vec<UserId>),
1370}
1371
1372#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
1374pub struct BrokerOverlayConfigV0 {
1375    pub overlays: Vec<OverlayId>,
1377    pub core: BrokerOverlayPermission,
1379    pub server: BrokerOverlayPermission,
1381    pub allow_read: bool,
1385
1386    pub forward: Vec<BrokerServerV0>,
1390}
1391
1392impl BrokerOverlayConfigV0 {
1393    pub fn new() -> Self {
1394        BrokerOverlayConfigV0 {
1395            overlays: vec![],
1396            core: BrokerOverlayPermission::Nobody,
1397            server: BrokerOverlayPermission::Nobody,
1398            allow_read: false,
1399            forward: vec![],
1400        }
1401    }
1402}
1403
1404#[derive(Clone, Debug, Serialize, Deserialize)]
1406pub enum RegistrationConfig {
1407    Closed,
1408    Invitation,
1409    Open,
1410}
1411
1412#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1416pub enum OverlayAccess {
1417    ReadOnly(OverlayId),
1421    ReadWrite((OverlayId, OverlayId)),
1425    WriteOnly(OverlayId),
1429}
1430
1431impl OverlayAccess {
1432    pub fn is_read_only(&self) -> bool {
1433        match self {
1434            Self::ReadOnly(_) => true,
1435            _ => false,
1436        }
1437    }
1438    pub fn new_write_access_from_store(store: &Store) -> OverlayAccess {
1439        match store.get_store_repo() {
1440            StoreRepo::V0(StoreRepoV0::PrivateStore(_)) | StoreRepo::V0(StoreRepoV0::Dialog(_)) => {
1441                OverlayAccess::WriteOnly(store.inner_overlay())
1442            }
1443            StoreRepo::V0(StoreRepoV0::ProtectedStore(_))
1444            | StoreRepo::V0(StoreRepoV0::Group(_))
1445            | StoreRepo::V0(StoreRepoV0::PublicStore(_)) => {
1446                OverlayAccess::ReadWrite((store.inner_overlay(), store.outer_overlay()))
1447            }
1448        }
1449    }
1450
1451    pub fn new_read_access_from_store(store: &Store) -> OverlayAccess {
1452        match store.get_store_repo() {
1453            StoreRepo::V0(StoreRepoV0::PrivateStore(_)) | StoreRepo::V0(StoreRepoV0::Dialog(_)) => {
1454                panic!("cannot get read access to a private or dialog store");
1455            }
1456            StoreRepo::V0(StoreRepoV0::ProtectedStore(_))
1457            | StoreRepo::V0(StoreRepoV0::Group(_))
1458            | StoreRepo::V0(StoreRepoV0::PublicStore(_)) => {
1459                OverlayAccess::ReadOnly(store.outer_overlay())
1460            }
1461        }
1462    }
1463
1464    pub fn new_ro(outer_overlay: OverlayId) -> Result<Self, NgError> {
1465        if let OverlayId::Outer(_digest) = outer_overlay {
1466            Ok(OverlayAccess::ReadOnly(outer_overlay))
1467        } else {
1468            Err(NgError::InvalidArgument)
1469        }
1470    }
1471    pub fn new_rw(inner_overlay: OverlayId, outer_overlay: OverlayId) -> Result<Self, NgError> {
1472        if let OverlayId::Inner(_digest) = inner_overlay {
1473            if let OverlayId::Outer(_digest) = outer_overlay {
1474                Ok(OverlayAccess::ReadWrite((inner_overlay, outer_overlay)))
1475            } else {
1476                Err(NgError::InvalidArgument)
1477            }
1478        } else {
1479            Err(NgError::InvalidArgument)
1480        }
1481    }
1482    pub fn new_wo(inner_overlay: OverlayId) -> Result<Self, NgError> {
1483        if let OverlayId::Inner(_digest) = inner_overlay {
1484            Ok(OverlayAccess::WriteOnly(inner_overlay))
1485        } else {
1486            Err(NgError::InvalidArgument)
1487        }
1488    }
1489    pub fn overlay_id_for_client_protocol_purpose(&self) -> &OverlayId {
1490        match self {
1491            Self::ReadOnly(ro) => ro,
1492            Self::ReadWrite((inner, _outer)) => inner,
1493            Self::WriteOnly(wo) => wo,
1494        }
1495    }
1496}
1497
1498#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1502pub struct InnerOverlayLink {
1503    pub id: StoreOverlay,
1505
1506    pub store_overlay_readcap: ReadCap,
1512}
1513
1514#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1518pub enum OverlayLink {
1519    Outer(Digest),
1520    InnerLink(InnerOverlayLink),
1521    Inner(Digest),
1522    Inherit,
1523    Public(PubKey),
1524    Global,
1525}
1526
1527impl OverlayLink {
1528    pub fn is_outer(&self) -> bool {
1529        match self {
1530            Self::Outer(_) => true,
1531            _ => false,
1532        }
1533    }
1534    pub fn outer(&self) -> &Digest {
1535        match self {
1536            Self::Outer(o) => o,
1537            _ => panic!("not an outer overlay ID"),
1538        }
1539    }
1540}
1541
1542impl TryFrom<OverlayLink> for OverlayId {
1543    type Error = NgError;
1544    fn try_from(link: OverlayLink) -> Result<Self, Self::Error> {
1545        Ok(match link {
1546            OverlayLink::Inner(Digest::Blake3Digest32(i)) => OverlayId::Inner(i),
1547            OverlayLink::Outer(Digest::Blake3Digest32(i)) => OverlayId::Outer(i),
1548            OverlayLink::Global => OverlayId::Global,
1549            _ => return Err(NgError::InvalidArgument),
1550        })
1551    }
1552}
1553
1554impl From<OverlayId> for OverlayLink {
1555    fn from(id: OverlayId) -> Self {
1556        match id {
1557            OverlayId::Inner(i) => OverlayLink::Inner(Digest::from_slice(i)),
1558            OverlayId::Outer(o) => OverlayLink::Outer(Digest::from_slice(o)),
1559            OverlayId::Global => OverlayLink::Global,
1560        }
1561    }
1562}
1563
1564pub type SessionId = PubKey;
1569
1570pub type ClientId = PubKey;
1572
1573pub type IPv4 = [u8; 4];
1575
1576const LOOPBACK_IPV4: IP = IP::IPv4([127, 0, 0, 1]);
1577
1578pub type IPv6 = [u8; 16];
1580
1581#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1583pub enum IP {
1584    IPv4(IPv4),
1585    IPv6(IPv6),
1586}
1587
1588impl IP {
1589    pub fn is_public(&self) -> bool {
1590        is_public_ip(&self.into())
1591    }
1592    pub fn is_private(&self) -> bool {
1593        is_private_ip(&self.into())
1594    }
1595    pub fn is_loopback(&self) -> bool {
1596        let t: &IpAddr = &self.into();
1597        t.is_loopback()
1598    }
1599    pub fn is_v6(&self) -> bool {
1600        if let Self::IPv6(_) = self {
1601            true
1602        } else {
1603            false
1604        }
1605    }
1606    pub fn is_v4(&self) -> bool {
1607        if let Self::IPv4(_) = self {
1608            true
1609        } else {
1610            false
1611        }
1612    }
1613}
1614
1615impl fmt::Display for IP {
1616    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1617        let t: IpAddr = self.try_into().unwrap();
1618        match self {
1619            IP::IPv4(_) => write!(f, "{}", t),
1620            IP::IPv6(_) => write!(f, "[{}]", t),
1621        }
1622    }
1623}
1624
1625impl From<&IpAddr> for IP {
1626    #[inline]
1627    fn from(ip: &IpAddr) -> IP {
1628        match ip {
1629            IpAddr::V4(v4) => IP::IPv4(v4.octets()),
1630            IpAddr::V6(v6) => IP::IPv6(v6.octets()),
1631        }
1632    }
1633}
1634
1635impl From<&IP> for IpAddr {
1636    #[inline]
1637    fn from(ip: &IP) -> IpAddr {
1638        match ip {
1639            IP::IPv4(v4) => IpAddr::from(*v4),
1640            IP::IPv6(v6) => IpAddr::from(*v6),
1641        }
1642    }
1643}
1644
1645#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
1647pub enum TransportProtocol {
1648    WS,
1649    QUIC,
1650    Local,
1651}
1652
1653#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
1655pub struct IPTransportAddr {
1656    pub ip: IP,
1657    pub port: u16,
1658    pub protocol: TransportProtocol,
1659}
1660
1661#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)]
1663pub enum NetAddr {
1664    IPTransport(IPTransportAddr),
1665}
1666
1667#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1681pub enum ClientType {
1682    Web,
1683    NativeIos,
1684    NativeAndroid,
1685    NativeMacOS,
1686    NativeLinux,
1687    NativeWin,
1688    NativeService,
1689    NodeService,
1690    Verifier,
1691    VerifierLocal,
1692    Box,   Stick, WalletMaster,
1695    ClientBroker,
1696    Cli,
1697}
1698
1699#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1700pub struct ClientInfoV0 {
1701    pub client_type: ClientType,
1702    pub details: String,
1703    pub version: String,
1704    pub timestamp_install: u64,
1705    pub timestamp_updated: u64,
1706}
1707
1708#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)]
1710pub enum ClientInfo {
1711    V0(ClientInfoV0),
1712}
1713
1714impl ClientInfo {
1715    pub fn new(client_type: ClientType, details: String, version: String) -> ClientInfo {
1716        let timestamp_install = SystemTime::now()
1717            .duration_since(SystemTime::UNIX_EPOCH)
1718            .unwrap()
1719            .as_secs();
1720        ClientInfo::V0(ClientInfoV0 {
1721            details,
1722            version,
1723            client_type,
1724            timestamp_install,
1725            timestamp_updated: timestamp_install,
1726        })
1727    }
1728}
1729
1730#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1739pub enum OverlayLeave {
1740    V0(),
1741}
1742
1743#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1747pub struct PublisherAdvertContentV0 {
1748    pub topic: TopicId,
1750
1751    pub peer: DirectPeerId,
1753}
1754
1755#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1760pub struct PublisherAdvertV0 {
1761    pub content: PublisherAdvertContentV0,
1762
1763    pub sig: Sig,
1765}
1766
1767#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1769pub enum PublisherAdvert {
1770    V0(PublisherAdvertV0),
1771}
1772
1773impl PublisherAdvert {
1774    pub fn new(
1775        topic_id: TopicId,
1776        topic_key: BranchWriteCapSecret,
1777        broker_peer: DirectPeerId,
1778    ) -> PublisherAdvert {
1779        let content = PublisherAdvertContentV0 {
1780            peer: broker_peer,
1781            topic: topic_id,
1782        };
1783        let content_ser = serde_bare::to_vec(&content).unwrap();
1784        let sig = sign(&topic_key, &topic_id, &content_ser).unwrap();
1785        PublisherAdvert::V0(PublisherAdvertV0 { content, sig })
1786    }
1787    pub fn topic_id(&self) -> &TopicId {
1788        match self {
1789            Self::V0(v0) => &v0.content.topic,
1790        }
1791    }
1792
1793    pub fn verify(&self) -> Result<(), NgError> {
1794        match self {
1795            Self::V0(v0) => verify(
1796                &serde_bare::to_vec(&v0.content).unwrap(),
1797                v0.sig,
1798                v0.content.topic,
1799            ),
1800        }
1801    }
1802
1803    pub fn verify_for_broker(&self, peer_id: &DirectPeerId) -> Result<(), ProtocolError> {
1804        match self {
1805            Self::V0(v0) => {
1806                if v0.content.peer != *peer_id {
1807                    return Err(ProtocolError::InvalidPublisherAdvert);
1808                }
1809            }
1810        }
1811        Ok(self.verify()?)
1812    }
1813}
1814
1815#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1821pub struct SubReqV0 {
1822    pub topic: TopicId,
1824
1825    pub publisher: Option<DirectPeerId>,
1830}
1831
1832#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1834pub enum SubReq {
1835    V0(SubReqV0),
1836}
1837
1838#[derive(Clone, Debug, Serialize, Deserialize)]
1842pub struct SubMarkerV0 {
1843    pub publisher: DirectPeerId,
1846
1847    pub topic: TopicId,
1849
1850    pub subscriber: DirectPeerId,
1852
1853    pub known_heads: Vec<ObjectId>,
1855}
1856
1857#[derive(Clone, Debug, Serialize, Deserialize)]
1859pub enum SubMarker {
1860    V0(SubMarkerV0),
1861}
1862
1863#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1868pub struct UnsubReqV0 {
1869    pub topic: TopicId,
1871}
1872
1873#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
1875pub enum UnsubReq {
1876    V0(UnsubReqV0),
1877}
1878
1879#[derive(Clone, Debug, Serialize, Deserialize)]
1887pub struct BlockSearchTopicV0 {
1888    pub topic: TopicId,
1890
1891    pub search_in_subs: bool,
1893
1894    pub ids: Vec<ObjectId>,
1896
1897    pub include_children: bool,
1899
1900    pub path: Vec<PeerId>,
1902}
1903
1904#[derive(Clone, Debug, Serialize, Deserialize)]
1906pub enum BlockSearchTopic {
1907    V0(BlockSearchTopicV0),
1908}
1909
1910#[derive(Clone, Debug, Serialize, Deserialize)]
1916pub struct BlockSearchRandomV0 {
1917    pub ids: Vec<BlockId>,
1919
1920    pub include_children: bool,
1922
1923    pub path: Vec<DirectPeerId>,
1929}
1930
1931#[derive(Clone, Debug, Serialize, Deserialize)]
1933pub enum BlockSearchRandom {
1934    V0(BlockSearchRandomV0),
1935}
1936
1937#[derive(Clone, Debug, Serialize, Deserialize)]
1941pub struct BlockResultV0 {
1942    pub payload: Vec<Block>,
1944}
1945
1946#[derive(Clone, Debug, Serialize, Deserialize)]
1950pub enum BlockResult {
1951    V0(BlockResultV0),
1952}
1953
1954#[derive(Clone, Debug, Serialize, Deserialize)]
1958pub struct TopicSyncReqV0 {
1959    pub topic: TopicId,
1961
1962    pub known_heads: Vec<ObjectId>,
1964
1965    pub target_heads: Vec<ObjectId>,
1968
1969    pub known_commits: Option<BloomFilter>,
1971
1972    #[serde(skip)]
1973    pub overlay: Option<OverlayId>,
1974}
1975
1976#[derive(Clone, Debug, Serialize, Deserialize)]
1978pub enum TopicSyncReq {
1979    V0(TopicSyncReqV0),
1980}
1981
1982impl TopicSyncReq {
1983    pub fn overlay(&self) -> &OverlayId {
1984        match self {
1985            Self::V0(v0) => v0.overlay.as_ref().unwrap(),
1986        }
1987    }
1988    pub fn set_overlay(&mut self, overlay: OverlayId) {
1989        match self {
1990            Self::V0(v0) => v0.overlay = Some(overlay),
1991        }
1992    }
1993    pub fn topic(&self) -> &TopicId {
1994        match self {
1995            TopicSyncReq::V0(o) => &o.topic,
1996        }
1997    }
1998    pub fn known_heads(&self) -> &Vec<ObjectId> {
1999        match self {
2000            TopicSyncReq::V0(o) => &o.known_heads,
2001        }
2002    }
2003    pub fn target_heads(&self) -> &Vec<ObjectId> {
2004        match self {
2005            TopicSyncReq::V0(o) => &o.target_heads,
2006        }
2007    }
2008    pub fn known_commits(&self) -> &Option<BloomFilter> {
2009        match self {
2010            TopicSyncReq::V0(o) => &o.known_commits,
2011        }
2012    }
2013}
2014
2015#[derive(Clone, Debug, Serialize, Deserialize)]
2017pub enum PeerStatus {
2018    Connected,
2019    Disconnected,
2020}
2021
2022#[derive(Clone, Debug, Serialize, Deserialize)]
2026pub struct ForwardedPeerAdvertV0 {
2027    pub peer_advert: PeerAdvertV0,
2030
2031    pub user_hash: Digest,
2035
2036    pub status: PeerStatus,
2038}
2039
2040#[derive(Clone, Debug, Serialize, Deserialize)]
2042pub enum ForwardedPeerAdvert {
2043    V0(ForwardedPeerAdvertV0),
2044}
2045
2046#[derive(Clone, Debug, Serialize, Deserialize)]
2055pub struct ForwardedPeerConflictV0 {
2056    pub advert_1: ForwardedPeerAdvertV0,
2058    pub advert_2: ForwardedPeerAdvertV0,
2060
2061    pub error_code: u16,
2062}
2063
2064#[derive(Clone, Debug, Serialize, Deserialize)]
2066pub enum ForwardedPeerConflict {
2067    V0(ForwardedPeerConflictV0),
2068}
2069
2070#[derive(Clone, Debug, Serialize, Deserialize)]
2072pub struct PeerAdvertContentV0 {
2073    pub peer: PeerId,
2075
2076    pub forwarded_by: Option<DirectPeerId>,
2078
2079    pub address: Vec<NetAddr>,
2084
2085    pub version: u32,
2087
2088    #[serde(with = "serde_bytes")]
2090    pub metadata: Vec<u8>,
2091}
2092
2093#[derive(Clone, Debug, Serialize, Deserialize)]
2100pub struct PeerAdvertV0 {
2101    pub content: PeerAdvertContentV0,
2103
2104    pub sig: Sig,
2106}
2107
2108#[derive(Clone, Debug, Serialize, Deserialize)]
2110pub enum PeerAdvert {
2111    V0(PeerAdvertV0),
2112}
2113
2114impl PeerAdvert {
2115    pub fn version(&self) -> u32 {
2116        match self {
2117            PeerAdvert::V0(o) => o.content.version,
2118        }
2119    }
2120    pub fn peer(&self) -> &PeerId {
2121        match self {
2122            PeerAdvert::V0(o) => &o.content.peer,
2123        }
2124    }
2125}
2126
2127#[derive(Clone, Debug, Serialize, Deserialize)]
2129pub enum InnerOverlayMessageContentV0 {
2130    OverlayLeave(OverlayLeave),
2131    ForwardedPeerAdvert(ForwardedPeerAdvert),
2132    ForwardedPeerConflict(ForwardedPeerConflict),
2133    PublisherJoined(PublisherAdvert),
2134    PublisherLeft(PublisherAdvert),
2135    SubReq(SubReq),
2136    SubMarker(SubMarker),
2137    UnsubReq(UnsubReq),
2138    Event(Event),
2139    }
2142
2143#[derive(Clone, Debug, Serialize, Deserialize)]
2145pub struct InnerOverlayMessagePayloadV0 {
2146    pub seq: u64,
2149
2150    pub content: InnerOverlayMessageContentV0,
2151}
2152
2153#[derive(Clone, Debug, Serialize, Deserialize)]
2155pub struct InnerOverlayMessageV0 {
2156    pub session: SessionId,
2158
2159    pub payload: InnerOverlayMessagePayloadV0,
2160
2161    pub sig: Sig,
2163
2164    #[serde(with = "serde_bytes")]
2166    pub padding: Vec<u8>,
2167}
2168
2169#[derive(Clone, Debug, Serialize, Deserialize)]
2171pub enum InnerOverlayMessage {
2172    V0(InnerOverlayMessageV0),
2173}
2174
2175#[derive(Clone, Debug, Serialize, Deserialize)]
2177pub struct OverlayAdvertPayloadV0 {
2178    pub overlay: OverlayId,
2180
2181    pub session: SessionId,
2184
2185    pub seq: u64,
2187
2188    pub publishers: Vec<PublisherAdvert>,
2193
2194    pub previous_session: Option<SessionId>,
2200
2201    pub peer: DirectPeerId,
2203}
2204
2205#[derive(Clone, Debug, Serialize, Deserialize)]
2207pub struct OverlayAdvertV0 {
2208    pub payload: OverlayAdvertPayloadV0,
2209
2210    pub sig: Sig,
2212}
2213
2214#[derive(Clone, Debug, Serialize, Deserialize)]
2216pub enum OverlayAdvert {
2217    V0(OverlayAdvertV0),
2218}
2219
2220#[derive(Clone, Debug, Serialize, Deserialize)]
2226pub struct CoreBrokerJoinedAdvertV0 {
2227    pub overlays: Vec<OverlayAdvertV0>,
2230}
2231
2232#[derive(Clone, Debug, Serialize, Deserialize)]
2237pub struct CoreBrokerLeftAdvertV0 {
2238    pub disconnected: DirectPeerId,
2240}
2241
2242#[derive(Clone, Debug, Serialize, Deserialize)]
2244pub struct CoreOverlayJoinedAdvertV0 {
2245    pub overlay: OverlayAdvertV0,
2248}
2249
2250#[derive(Clone, Debug, Serialize, Deserialize)]
2251pub enum CoreBrokerJoinedAdvert {
2252    V0(CoreBrokerJoinedAdvertV0),
2253}
2254
2255#[derive(Clone, Debug, Serialize, Deserialize)]
2256pub enum CoreBrokerLeftAdvert {
2257    V0(CoreBrokerLeftAdvertV0),
2258}
2259
2260#[derive(Clone, Debug, Serialize, Deserialize)]
2261pub enum CoreOverlayJoinedAdvert {
2262    V0(CoreOverlayJoinedAdvertV0),
2263}
2264
2265#[derive(Clone, Debug, Serialize, Deserialize)]
2267pub enum CoreAdvertContentV0 {
2268    BrokerJoined(CoreBrokerJoinedAdvert),
2269    BrokerLeft(CoreBrokerLeftAdvert),
2270    OverlayJoined(CoreOverlayJoinedAdvert),
2271}
2272
2273#[derive(Clone, Debug, Serialize, Deserialize)]
2275pub struct CoreAdvertV0 {
2276    pub content: CoreAdvertContentV0,
2277
2278    pub path: Vec<DirectPeerId>,
2281
2282    pub sig: Sig,
2284
2285    #[serde(with = "serde_bytes")]
2287    pub padding: Vec<u8>,
2288}
2289
2290#[derive(Clone, Debug, Serialize, Deserialize)]
2297pub struct OverlayAdvertMarkerV0 {
2298    pub marker: OverlayAdvertV0,
2299
2300    pub in_reply_to: SessionId,
2302
2303    pub path: Vec<DirectPeerId>,
2305
2306    pub reply_nonce: u64,
2308}
2309
2310#[derive(Clone, Debug, Serialize, Deserialize)]
2312pub struct CoreBlocksGetV0 {
2313    pub ids: Vec<BlockId>,
2315
2316    pub include_children: bool,
2318
2319    pub req_nonce: u64,
2323}
2324
2325#[derive(Clone, Debug, Serialize, Deserialize)]
2329pub struct CoreBlockResultV0 {
2330    pub payload: Vec<Block>,
2332
2333    pub req_nonce: u64,
2335}
2336
2337#[derive(Clone, Debug, Serialize, Deserialize)]
2339pub struct ReturnPathTimingAdvertV0 {
2340    pub sig: Sig,
2342
2343    pub nonce: u64,
2345}
2346
2347#[derive(Clone, Debug, Serialize, Deserialize)]
2348pub enum OverlayAdvertMarker {
2349    V0(OverlayAdvertMarkerV0),
2350}
2351
2352#[derive(Clone, Debug, Serialize, Deserialize)]
2353pub enum ReturnPathTimingAdvert {
2354    V0(ReturnPathTimingAdvertV0),
2355}
2356
2357#[derive(Clone, Debug, Serialize, Deserialize)]
2358pub enum CoreBlocksGet {
2359    V0(CoreBlocksGetV0),
2360}
2361
2362#[derive(Clone, Debug, Serialize, Deserialize)]
2363pub enum CoreBlockResult {
2364    V0(CoreBlockResultV0),
2365}
2366
2367#[derive(Clone, Debug, Serialize, Deserialize)]
2369pub enum CoreDirectMessageContentV0 {
2370    OverlayAdvertMarker(OverlayAdvertMarker),
2371    ReturnPathTimingAdvert(ReturnPathTimingAdvert),
2372    BlocksGet(CoreBlocksGet),
2373    BlockResult(CoreBlockResult),
2374    }
2378
2379#[derive(Clone, Debug, Serialize, Deserialize)]
2381pub struct CoreDirectMessageV0 {
2382    pub content: CoreDirectMessageContentV0,
2383
2384    pub reverse_path: Vec<DirectPeerId>,
2389
2390    pub from: DirectPeerId,
2392
2393    pub sig: Sig,
2395
2396    #[serde(with = "serde_bytes")]
2398    pub padding: Vec<u8>,
2399}
2400
2401#[derive(Clone, Debug, Serialize, Deserialize)]
2405pub struct CoreBrokerConnectV0 {
2406    pub inner_overlays: Vec<OverlayAdvertV0>,
2407    pub outer_overlays: Vec<Digest>,
2408}
2409
2410#[derive(Clone, Debug, Serialize, Deserialize)]
2412pub enum CoreBrokerConnect {
2413    V0(CoreBrokerConnectV0),
2414}
2415
2416#[derive(Clone, Debug, Serialize, Deserialize)]
2418pub enum CoreBrokerConnectResponse {
2419    V0(CoreBrokerConnectResponseV0),
2420}
2421
2422impl CoreBrokerConnect {
2423    pub fn core_message(&self, id: i64) -> CoreMessage {
2424        match self {
2425            CoreBrokerConnect::V0(v0) => {
2426                CoreMessage::V0(CoreMessageV0::Request(CoreRequest::V0(CoreRequestV0 {
2427                    padding: vec![],
2428                    id,
2429                    content: CoreRequestContentV0::BrokerConnect(CoreBrokerConnect::V0(v0.clone())),
2430                })))
2431            }
2432        }
2433    }
2434}
2435
2436pub type CoreBrokerDisconnectV0 = ();
2438
2439#[derive(Clone, Debug, Serialize, Deserialize)]
2443pub enum CoreOverlayJoinV0 {
2444    Inner(OverlayAdvert),
2445    Outer(Digest),
2446}
2447
2448#[derive(Clone, Debug, Serialize, Deserialize)]
2450pub enum OuterOverlayResponseContentV0 {
2451    EmptyResponse(()),
2452    Block(Block),
2453    TopicSyncRes(TopicSyncRes),
2454    }
2456
2457#[derive(Clone, Debug, Serialize, Deserialize)]
2459pub enum OuterOverlayRequestContentV0 {
2460    TopicSyncReq(TopicSyncReq),
2461    OverlayLeave(OverlayLeave),
2462    TopicSub(PubKey),
2463    TopicUnsub(PubKey),
2464    BlocksGet(BlocksGet),
2465    }
2467
2468#[derive(Clone, Debug, Serialize, Deserialize)]
2472pub struct OuterOverlayRequestV0 {
2473    pub overlay: Digest,
2474    pub content: OuterOverlayRequestContentV0,
2475}
2476
2477#[derive(Clone, Debug, Serialize, Deserialize)]
2481pub struct OuterOverlayResponseV0 {
2482    pub overlay: Digest,
2483    pub content: OuterOverlayResponseContentV0,
2484}
2485
2486#[derive(Clone, Debug, Serialize, Deserialize)]
2497pub struct CoreTopicSyncReqV0 {
2498    pub topic: TopicId,
2500
2501    pub search_in_subs: bool,
2503
2504    pub known_heads: Vec<ObjectId>,
2506
2507    pub target_heads: Vec<ObjectId>,
2510}
2511
2512#[derive(Clone, Debug, Serialize, Deserialize)]
2514pub enum CoreTopicSyncReq {
2515    V0(CoreTopicSyncReqV0),
2516}
2517
2518#[derive(Clone, Debug, Serialize, Deserialize)]
2520pub enum TopicSyncResV0 {
2521    Event(Event),
2522    Block(Block),
2523}
2524
2525#[derive(Clone, Debug, Serialize, Deserialize)]
2529pub enum TopicSyncRes {
2530    V0(TopicSyncResV0),
2531}
2532
2533impl TopicSyncRes {
2534    pub fn event(&self) -> &Event {
2535        match self {
2536            Self::V0(TopicSyncResV0::Event(e)) => e,
2537            _ => panic!("this TopicSyncResV0 is not an event"),
2538        }
2539    }
2540}
2541
2542impl fmt::Display for TopicSyncRes {
2543    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2544        match self {
2545            Self::V0(v0) => match v0 {
2546                TopicSyncResV0::Event(e) => writeln!(f, "====== Event ====== {e}"),
2547                TopicSyncResV0::Block(b) => writeln!(f, "====== Block ID ====== {}", b.id()),
2548            },
2549        }
2550    }
2551}
2552
2553#[derive(Clone, Debug, Serialize, Deserialize)]
2554pub enum CoreBrokerDisconnect {
2555    V0(CoreBrokerDisconnectV0),
2556}
2557
2558#[derive(Clone, Debug, Serialize, Deserialize)]
2559pub enum CoreOverlayJoin {
2560    V0(CoreOverlayJoinV0),
2561}
2562
2563#[derive(Clone, Debug, Serialize, Deserialize)]
2564pub enum OuterOverlayRequest {
2565    V0(OuterOverlayRequestV0),
2566}
2567
2568#[derive(Clone, Debug, Serialize, Deserialize)]
2570pub enum CoreRequestContentV0 {
2571    BrokerConnect(CoreBrokerConnect),
2572    BrokerDisconnect(CoreBrokerDisconnect),
2573    OverlayJoin(CoreOverlayJoin),
2574    BlockSearchTopic(BlockSearchTopic),
2575    BlockSearchRandom(BlockSearchRandom),
2576    TopicSyncReq(CoreTopicSyncReq),
2577    OuterOverlayRequest(OuterOverlayRequest),
2578}
2579
2580#[derive(Clone, Debug, Serialize, Deserialize)]
2584pub struct CoreRequestV0 {
2585    pub id: i64,
2587    pub content: CoreRequestContentV0,
2588
2589    #[serde(with = "serde_bytes")]
2591    pub padding: Vec<u8>,
2592}
2593
2594#[derive(Clone, Debug, Serialize, Deserialize)]
2596pub enum CoreRequest {
2597    V0(CoreRequestV0),
2598}
2599
2600#[derive(Clone, Debug, Serialize, Deserialize)]
2604pub struct CoreBrokerConnectResponseV0 {
2605    pub successes: Vec<OverlayId>,
2606    pub errors: Vec<OverlayId>,
2607}
2608
2609#[derive(Clone, Debug, Serialize, Deserialize)]
2610pub enum OuterOverlayResponse {
2611    V0(OuterOverlayResponseV0),
2612}
2613
2614#[derive(Clone, Debug, Serialize, Deserialize)]
2616pub enum CoreResponseContentV0 {
2617    BrokerConnectResponse(CoreBrokerConnectResponse),
2618    BlockResult(BlockResult),
2619    TopicSyncRes(TopicSyncRes),
2620    OuterOverlayResponse(OuterOverlayResponse),
2621    EmptyResponse(()),
2622}
2623
2624#[derive(Clone, Debug, Serialize, Deserialize)]
2628pub struct CoreResponseV0 {
2629    pub id: i64,
2631
2632    pub result: u16,
2634    pub content: CoreResponseContentV0,
2635
2636    #[serde(with = "serde_bytes")]
2638    pub padding: Vec<u8>,
2639}
2640
2641#[derive(Clone, Debug, Serialize, Deserialize)]
2643pub enum CoreResponse {
2644    V0(CoreResponseV0),
2645}
2646
2647#[derive(Clone, Debug, Serialize, Deserialize)]
2648pub enum OuterOverlayMessageContentV0 {
2649    Event(Event),
2650}
2651
2652#[derive(Clone, Debug, Serialize, Deserialize)]
2654pub struct OuterOverlayMessageV0 {
2655    pub overlay: Digest,
2656
2657    pub content: OuterOverlayMessageContentV0,
2658
2659    #[serde(with = "serde_bytes")]
2661    pub padding: Vec<u8>,
2662}
2663
2664#[derive(Clone, Debug, Serialize, Deserialize)]
2665pub enum CoreAdvert {
2666    V0(CoreAdvertV0),
2667}
2668
2669#[derive(Clone, Debug, Serialize, Deserialize)]
2670pub enum CoreDirectMessage {
2671    V0(CoreDirectMessageV0),
2672}
2673
2674#[derive(Clone, Debug, Serialize, Deserialize)]
2675pub enum OuterOverlayMessage {
2676    V0(OuterOverlayMessageV0),
2677}
2678
2679#[derive(Clone, Debug, Serialize, Deserialize)]
2681pub enum CoreMessageV0 {
2682    Request(CoreRequest),
2683    Response(CoreResponse),
2684    Advert(CoreAdvert),
2685    Direct(CoreDirectMessage),
2686    InnerOverlay(InnerOverlayMessage),
2687    OuterOverlay(OuterOverlayMessage),
2688}
2689
2690#[derive(Clone, Debug, Serialize, Deserialize)]
2692pub enum CoreMessage {
2693    V0(CoreMessageV0),
2694}
2695
2696#[derive(Clone, Debug, Serialize, Deserialize)]
2698pub enum AppMessageContentV0 {
2699    Request(AppRequest),
2700    Response(AppResponse),
2701    SessionStop(AppSessionStop),
2702    SessionStart(AppSessionStart),
2703    EmptyResponse,
2704}
2705
2706#[derive(Clone, Debug, Serialize, Deserialize)]
2708pub struct AppMessageV0 {
2709    pub content: AppMessageContentV0,
2710
2711    pub id: i64,
2712
2713    pub result: u16,
2714}
2715
2716#[derive(Clone, Debug, Serialize, Deserialize)]
2718pub enum AppMessage {
2719    V0(AppMessageV0),
2720}
2721
2722impl IStreamable for AppMessage {
2723    fn result(&self) -> u16 {
2724        match self {
2725            AppMessage::V0(v0) => v0.result,
2726        }
2727    }
2728    fn set_result(&mut self, result: u16) {
2729        match self {
2730            AppMessage::V0(v0) => v0.result = result,
2731        }
2732    }
2733}
2734
2735impl AppMessage {
2736    pub fn get_actor(&self) -> Box<dyn EActor> {
2737        match self {
2738            AppMessage::V0(AppMessageV0 { content: o, id, .. }) => match o {
2739                AppMessageContentV0::Request(req) => req.get_actor(*id),
2740                AppMessageContentV0::SessionStop(req) => req.get_actor(*id),
2741                AppMessageContentV0::SessionStart(req) => req.get_actor(*id),
2742                AppMessageContentV0::Response(_) | AppMessageContentV0::EmptyResponse => {
2743                    panic!("it is not a request");
2744                }
2745            },
2746        }
2747    }
2748    pub fn id(&self) -> Option<i64> {
2749        match self {
2750            AppMessage::V0(v0) => Some(v0.id),
2751        }
2752    }
2753    pub fn set_id(&mut self, id: i64) {
2754        match self {
2755            AppMessage::V0(r) => r.id = id,
2756        }
2757    }
2758}
2759
2760impl From<AppMessage> for ProtocolMessage {
2761    fn from(msg: AppMessage) -> ProtocolMessage {
2762        ProtocolMessage::AppMessage(msg)
2763    }
2764}
2765
2766#[derive(Clone, Debug, Serialize, Deserialize)]
2772pub enum AdminRequestContentV0 {
2773    AddUser(AddUser),
2774    DelUser(DelUser),
2775    ListUsers(ListUsers),
2776    ListInvitations(ListInvitations),
2777    AddInvitation(AddInvitation),
2778    #[doc(hidden)]
2779    CreateUser(CreateUser),
2780}
2781impl AdminRequestContentV0 {
2782    pub fn type_id(&self) -> TypeId {
2783        match self {
2784            Self::AddUser(a) => a.type_id(),
2785            Self::DelUser(a) => a.type_id(),
2786            Self::ListUsers(a) => a.type_id(),
2787            Self::ListInvitations(a) => a.type_id(),
2788            Self::AddInvitation(a) => a.type_id(),
2789            Self::CreateUser(a) => a.type_id(),
2790        }
2791    }
2792    pub fn get_actor(&self) -> Box<dyn EActor> {
2793        match self {
2794            Self::AddUser(a) => a.get_actor(),
2795            Self::DelUser(a) => a.get_actor(),
2796            Self::ListUsers(a) => a.get_actor(),
2797            Self::ListInvitations(a) => a.get_actor(),
2798            Self::AddInvitation(a) => a.get_actor(),
2799            Self::CreateUser(a) => a.get_actor(),
2800        }
2801    }
2802}
2803
2804#[derive(Clone, Debug, Serialize, Deserialize)]
2806pub struct AdminRequestV0 {
2807    pub id: i64,
2809
2810    pub content: AdminRequestContentV0,
2812
2813    pub sig: Sig,
2815
2816    pub admin_user: PubKey,
2818
2819    #[serde(with = "serde_bytes")]
2821    pub padding: Vec<u8>,
2822}
2823
2824impl AdminRequestV0 {
2825    pub fn get_actor(&self) -> Box<dyn EActor> {
2826        self.content.get_actor()
2827    }
2828}
2829
2830#[derive(Clone, Debug, Serialize, Deserialize)]
2832pub enum AdminRequest {
2833    V0(AdminRequestV0),
2834}
2835
2836impl AdminRequest {
2837    pub fn id(&self) -> i64 {
2838        match self {
2839            Self::V0(o) => o.id,
2840        }
2841    }
2842    pub fn set_id(&mut self, id: i64) {
2843        match self {
2844            Self::V0(v0) => {
2845                v0.id = id;
2846            }
2847        }
2848    }
2849    pub fn type_id(&self) -> TypeId {
2850        match self {
2851            Self::V0(o) => o.content.type_id(),
2852        }
2853    }
2854    pub fn sig(&self) -> Sig {
2855        match self {
2856            Self::V0(o) => o.sig,
2857        }
2858    }
2859    pub fn admin_user(&self) -> PubKey {
2860        match self {
2861            Self::V0(o) => o.admin_user,
2862        }
2863    }
2864    pub fn get_actor(&self) -> Box<dyn EActor> {
2865        match self {
2866            Self::V0(a) => a.get_actor(),
2867        }
2868    }
2869}
2870
2871impl From<AdminRequest> for ProtocolMessage {
2872    fn from(msg: AdminRequest) -> ProtocolMessage {
2873        ProtocolMessage::Start(StartProtocol::Admin(msg))
2874    }
2875}
2876
2877#[derive(Clone, Debug, Serialize, Deserialize)]
2879pub enum AdminResponseContentV0 {
2880    EmptyResponse,
2881    Users(Vec<PubKey>),
2882    Invitations(Vec<(InvitationCode, u32, Option<String>)>),
2883    Invitation(Invitation),
2884    UserId(UserId),
2885}
2886
2887#[derive(Clone, Debug, Serialize, Deserialize)]
2889pub struct AdminResponseV0 {
2890    pub id: i64,
2892
2893    pub result: u16,
2895
2896    pub content: AdminResponseContentV0,
2897
2898    #[serde(with = "serde_bytes")]
2900    pub padding: Vec<u8>,
2901}
2902
2903#[derive(Clone, Debug, Serialize, Deserialize)]
2905pub enum AdminResponse {
2906    V0(AdminResponseV0),
2907}
2908
2909impl From<Result<(), ProtocolError>> for AdminResponseV0 {
2910    fn from(res: Result<(), ProtocolError>) -> AdminResponseV0 {
2911        AdminResponseV0 {
2912            id: 0,
2913            result: res.map(|_| 0).unwrap_or_else(|e| e.into()),
2914            content: AdminResponseContentV0::EmptyResponse,
2915            padding: vec![],
2916        }
2917    }
2918}
2919
2920impl From<Result<PubKey, ProtocolError>> for AdminResponseV0 {
2921    fn from(res: Result<PubKey, ProtocolError>) -> AdminResponseV0 {
2922        match res {
2923            Err(e) => AdminResponseV0 {
2924                id: 0,
2925                result: e.into(),
2926                content: AdminResponseContentV0::EmptyResponse,
2927                padding: vec![],
2928            },
2929            Ok(id) => AdminResponseV0 {
2930                id: 0,
2931                result: 0,
2932                content: AdminResponseContentV0::UserId(id),
2933                padding: vec![],
2934            },
2935        }
2936    }
2937}
2938
2939impl From<Result<Vec<PubKey>, ProtocolError>> for AdminResponseV0 {
2940    fn from(res: Result<Vec<PubKey>, ProtocolError>) -> AdminResponseV0 {
2941        match res {
2942            Err(e) => AdminResponseV0 {
2943                id: 0,
2944                result: e.into(),
2945                content: AdminResponseContentV0::EmptyResponse,
2946                padding: vec![],
2947            },
2948            Ok(vec) => AdminResponseV0 {
2949                id: 0,
2950                result: 0,
2951                content: AdminResponseContentV0::Users(vec),
2952                padding: vec![],
2953            },
2954        }
2955    }
2956}
2957
2958impl From<AdminResponseV0> for ProtocolMessage {
2959    fn from(msg: AdminResponseV0) -> ProtocolMessage {
2960        ProtocolMessage::AdminResponse(AdminResponse::V0(msg))
2961    }
2962}
2963
2964impl From<AdminResponse> for ProtocolMessage {
2965    fn from(msg: AdminResponse) -> ProtocolMessage {
2966        ProtocolMessage::AdminResponse(msg)
2967    }
2968}
2969
2970impl TryFrom<ProtocolMessage> for AdminResponse {
2971    type Error = ProtocolError;
2972    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
2973        if let ProtocolMessage::AdminResponse(res) = msg {
2974            Ok(res)
2975        } else {
2976            Err(ProtocolError::InvalidValue)
2977        }
2978    }
2979}
2980
2981impl AdminResponse {
2982    pub fn id(&self) -> i64 {
2983        match self {
2984            Self::V0(o) => o.id,
2985        }
2986    }
2987    pub fn set_id(&mut self, id: i64) {
2988        match self {
2989            Self::V0(v0) => {
2990                v0.id = id;
2991            }
2992        }
2993    }
2994    pub fn result(&self) -> u16 {
2995        match self {
2996            Self::V0(o) => o.result,
2997        }
2998    }
2999    pub fn content_v0(&self) -> AdminResponseContentV0 {
3000        match self {
3001            Self::V0(o) => o.content.clone(),
3002        }
3003    }
3004}
3005
3006#[derive(Clone, Debug, Serialize, Deserialize)]
3016pub struct OpenRepoV0 {
3017    pub hash: RepoHash,
3019
3020    pub overlay: OverlayAccess,
3022
3023    pub peers: Vec<PeerAdvert>,
3028
3029    pub max_peer_count: u16,
3037
3038    pub ro_topics: Vec<TopicId>,
3040
3041    pub rw_topics: Vec<PublisherAdvert>,
3045}
3046
3047#[derive(Clone, Debug, Serialize, Deserialize)]
3049pub enum OpenRepo {
3050    V0(OpenRepoV0),
3051}
3052
3053impl OpenRepo {
3054    pub fn peers(&self) -> &Vec<PeerAdvert> {
3055        match self {
3056            OpenRepo::V0(o) => &o.peers,
3057        }
3058    }
3059}
3060
3061#[derive(Clone, Debug, Serialize, Deserialize)]
3066pub struct PinRepoV0 {
3067    pub hash: RepoHash,
3069
3070    pub overlay: OverlayAccess,
3072
3073    pub overlay_root_topic: Option<TopicId>,
3075
3076    pub expose_outer: bool,
3078
3079    pub peers: Vec<PeerAdvert>,
3083
3084    pub max_peer_count: u16,
3086
3087    pub ro_topics: Vec<TopicId>,
3096
3097    pub rw_topics: Vec<PublisherAdvert>,
3101    }
3104
3105#[derive(Clone, Debug, Serialize, Deserialize)]
3107pub enum PinRepo {
3108    V0(PinRepoV0),
3109}
3110
3111impl PinRepo {
3112    pub fn peers(&self) -> &Vec<PeerAdvert> {
3113        match self {
3114            PinRepo::V0(o) => &o.peers,
3115        }
3116    }
3117    pub fn hash(&self) -> &RepoHash {
3118        match self {
3119            PinRepo::V0(o) => &o.hash,
3120        }
3121    }
3122    pub fn ro_topics(&self) -> &Vec<TopicId> {
3123        match self {
3124            PinRepo::V0(o) => &o.ro_topics,
3125        }
3126    }
3127    pub fn rw_topics(&self) -> &Vec<PublisherAdvert> {
3128        match self {
3129            PinRepo::V0(o) => &o.rw_topics,
3130        }
3131    }
3132    pub fn overlay(&self) -> &OverlayId {
3133        match self {
3134            PinRepo::V0(o) => &o.overlay.overlay_id_for_client_protocol_purpose(),
3135        }
3136    }
3137    pub fn overlay_access(&self) -> &OverlayAccess {
3138        match self {
3139            PinRepo::V0(o) => &o.overlay,
3140        }
3141    }
3142
3143    pub fn overlay_root_topic(&self) -> &Option<TopicId> {
3144        match self {
3145            PinRepo::V0(o) => &o.overlay_root_topic,
3146        }
3147    }
3148
3149    pub fn expose_outer(&self) -> bool {
3150        match self {
3151            PinRepo::V0(o) => o.expose_outer,
3152        }
3153    }
3154}
3155
3156#[derive(Clone, Debug, Serialize, Deserialize)]
3161pub struct RefreshPinRepoV0 {
3162    pub pin: PinRepo,
3164
3165    pub ban_member: Option<Digest>,
3167
3168    pub flush_topics: Vec<(TopicId, Sig)>,
3178}
3179
3180#[derive(Clone, Debug, Serialize, Deserialize)]
3182pub enum RefreshPinRepo {
3183    V0(RefreshPinRepoV0),
3184}
3185
3186#[derive(Clone, Debug, Serialize, Deserialize)]
3192pub struct UnpinRepoV0 {
3193    pub hash: RepoHash,
3195}
3196
3197#[derive(Clone, Debug, Serialize, Deserialize)]
3199pub enum UnpinRepo {
3200    V0(UnpinRepoV0),
3201}
3202
3203impl UnpinRepo {
3204    pub fn hash(&self) -> &RepoHash {
3205        match self {
3206            UnpinRepo::V0(o) => &o.hash,
3207        }
3208    }
3209}
3210
3211#[derive(Clone, Debug, Serialize, Deserialize)]
3217pub struct RepoPinStatusReqV0 {
3218    pub hash: RepoHash,
3220
3221    #[serde(skip)]
3222    pub overlay: Option<OverlayId>,
3223}
3224
3225#[derive(Clone, Debug, Serialize, Deserialize)]
3227pub enum RepoPinStatusReq {
3228    V0(RepoPinStatusReqV0),
3229}
3230
3231impl RepoPinStatusReq {
3232    pub fn hash(&self) -> &RepoHash {
3233        match self {
3234            RepoPinStatusReq::V0(o) => &o.hash,
3235        }
3236    }
3237    pub fn set_overlay(&mut self, overlay: OverlayId) {
3238        match self {
3239            Self::V0(v0) => v0.overlay = Some(overlay),
3240        }
3241    }
3242
3243    pub fn overlay(&self) -> &OverlayId {
3244        match self {
3245            Self::V0(v0) => v0.overlay.as_ref().unwrap(),
3246        }
3247    }
3248}
3249
3250#[derive(Clone, Debug, Serialize, Deserialize)]
3252pub struct RepoPinStatusV0 {
3253    pub hash: RepoHash,
3255
3256    pub expose_outer: bool,
3258
3259    pub topics: Vec<TopicSubRes>,
3261    }
3265
3266#[derive(Clone, Debug, Serialize, Deserialize)]
3268pub enum RepoPinStatus {
3269    V0(RepoPinStatusV0),
3270}
3271
3272impl RepoPinStatus {
3273    pub fn hash(&self) -> &RepoHash {
3274        match self {
3275            RepoPinStatus::V0(o) => &o.hash,
3276        }
3277    }
3278    pub fn is_topic_subscribed_as_publisher(&self, topic: &TopicId) -> bool {
3279        match self {
3280            Self::V0(v0) => {
3281                for sub in &v0.topics {
3282                    if sub.topic_id() == topic {
3283                        return sub.is_publisher();
3284                    }
3285                }
3286                false
3287            }
3288        }
3289    }
3290    pub fn topics(&self) -> &Vec<TopicSubRes> {
3291        match self {
3292            Self::V0(v0) => &v0.topics,
3293        }
3294    }
3295}
3296
3297#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3301pub struct TopicSubV0 {
3302    pub topic: TopicId,
3304
3305    pub repo_hash: RepoHash,
3307
3308    pub publisher: Option<PublisherAdvert>,
3310
3311    #[serde(skip)]
3312    pub overlay: Option<OverlayId>,
3313}
3314
3315#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3317pub enum TopicSub {
3318    V0(TopicSubV0),
3319}
3320
3321impl TopicSub {
3322    pub fn hash(&self) -> &RepoHash {
3323        match self {
3324            Self::V0(o) => &o.repo_hash,
3325        }
3326    }
3327    pub fn topic(&self) -> &TopicId {
3328        match self {
3329            Self::V0(o) => &o.topic,
3330        }
3331    }
3332    pub fn publisher(&self) -> Option<&PublisherAdvert> {
3333        match self {
3334            Self::V0(o) => o.publisher.as_ref(),
3335        }
3336    }
3337    pub fn set_overlay(&mut self, overlay: OverlayId) {
3338        match self {
3339            Self::V0(v0) => v0.overlay = Some(overlay),
3340        }
3341    }
3342    pub fn overlay(&self) -> &OverlayId {
3343        match self {
3344            Self::V0(v0) => v0.overlay.as_ref().unwrap(),
3345        }
3346    }
3347}
3348
3349#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3351pub struct TopicUnsubV0 {
3352    pub topic: PubKey,
3354
3355    pub repo_hash: RepoHash,
3357}
3358
3359#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3361pub enum TopicUnsub {
3362    V0(TopicUnsubV0),
3363}
3364
3365#[derive(Clone, Debug, Serialize, Deserialize)]
3369pub struct BlocksGetV0 {
3370    pub ids: Vec<BlockId>,
3372
3373    pub include_children: bool,
3375
3376    pub topic: Option<TopicId>,
3379
3380    #[serde(skip)]
3381    pub overlay: Option<OverlayId>,
3382}
3383
3384#[derive(Clone, Debug, Serialize, Deserialize)]
3386pub enum BlocksGet {
3387    V0(BlocksGetV0),
3388}
3389
3390impl BlocksGet {
3391    pub fn ids(&self) -> &Vec<BlockId> {
3392        match self {
3393            BlocksGet::V0(o) => &o.ids,
3394        }
3395    }
3396    pub fn include_children(&self) -> bool {
3397        match self {
3398            BlocksGet::V0(o) => o.include_children,
3399        }
3400    }
3401    pub fn topic(&self) -> Option<PubKey> {
3402        match self {
3403            BlocksGet::V0(o) => o.topic,
3404        }
3405    }
3406}
3407
3408#[derive(Clone, Debug, Serialize, Deserialize)]
3416pub struct CommitGetV0 {
3417    pub id: ObjectId,
3419
3420    pub topic: Option<TopicId>,
3423
3424    #[serde(skip)]
3425    pub overlay: Option<OverlayId>,
3426}
3427
3428#[derive(Clone, Debug, Serialize, Deserialize)]
3430pub enum CommitGet {
3431    V0(CommitGetV0),
3432}
3433impl CommitGet {
3434    pub fn id(&self) -> &ObjectId {
3435        match self {
3436            CommitGet::V0(o) => &o.id,
3437        }
3438    }
3439}
3440
3441#[derive(Clone, Debug, Serialize, Deserialize)]
3443pub struct WalletPutExportV0 {
3444    pub wallet: ExportedWallet,
3445    pub rendezvous_id: SymKey,
3446    pub is_rendezvous: bool,
3447}
3448
3449#[derive(Clone, Debug, Serialize, Deserialize)]
3451pub enum WalletPutExport {
3452    V0(WalletPutExportV0),
3453}
3454
3455#[derive(Clone, Debug, Serialize, Deserialize)]
3457pub struct BlocksPutV0 {
3458    pub blocks: Vec<Block>,
3460
3461    #[serde(skip)]
3462    pub overlay: Option<OverlayId>,
3463}
3464
3465#[derive(Clone, Debug, Serialize, Deserialize)]
3467pub enum BlocksPut {
3468    V0(BlocksPutV0),
3469}
3470
3471impl BlocksPut {
3472    pub fn blocks(&self) -> &Vec<Block> {
3473        match self {
3474            BlocksPut::V0(o) => &o.blocks,
3475        }
3476    }
3477    pub fn overlay(&self) -> &OverlayId {
3478        match self {
3479            Self::V0(v0) => v0.overlay.as_ref().unwrap(),
3480        }
3481    }
3482    pub fn set_overlay(&mut self, overlay: OverlayId) {
3483        match self {
3484            Self::V0(v0) => v0.overlay = Some(overlay),
3485        }
3486    }
3487}
3488
3489#[derive(Clone, Debug, Serialize, Deserialize)]
3493pub struct BlocksExistV0 {
3494    pub blocks: Vec<BlockId>,
3496
3497    #[serde(skip)]
3498    pub overlay: Option<OverlayId>,
3499}
3500
3501#[derive(Clone, Debug, Serialize, Deserialize)]
3503pub enum BlocksExist {
3504    V0(BlocksExistV0),
3505}
3506
3507impl BlocksExist {
3508    pub fn blocks(&self) -> &Vec<BlockId> {
3509        match self {
3510            BlocksExist::V0(o) => &o.blocks,
3511        }
3512    }
3513    pub fn overlay(&self) -> &OverlayId {
3514        match self {
3515            Self::V0(v0) => v0.overlay.as_ref().unwrap(),
3516        }
3517    }
3518    pub fn set_overlay(&mut self, overlay: OverlayId) {
3519        match self {
3520            Self::V0(v0) => v0.overlay = Some(overlay),
3521        }
3522    }
3523}
3524
3525#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3531pub struct ObjectPinV0 {
3532    pub id: ObjectId,
3533}
3534
3535#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3537pub enum ObjectPin {
3538    V0(ObjectPinV0),
3539}
3540
3541impl ObjectPin {
3542    pub fn id(&self) -> ObjectId {
3543        match self {
3544            ObjectPin::V0(o) => o.id,
3545        }
3546    }
3547}
3548
3549#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3551pub struct ObjectUnpinV0 {
3552    pub id: ObjectId,
3553}
3554
3555#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3557pub enum ObjectUnpin {
3558    V0(ObjectUnpinV0),
3559}
3560
3561impl ObjectUnpin {
3562    pub fn id(&self) -> ObjectId {
3563        match self {
3564            ObjectUnpin::V0(o) => o.id,
3565        }
3566    }
3567}
3568
3569#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3573pub struct ObjectDelV0 {
3574    pub id: ObjectId,
3575}
3576
3577#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
3579pub enum ObjectDel {
3580    V0(ObjectDelV0),
3581}
3582
3583impl ObjectDel {
3584    pub fn id(&self) -> ObjectId {
3585        match self {
3586            ObjectDel::V0(o) => o.id,
3587        }
3588    }
3589}
3590
3591#[derive(Clone, Debug, Serialize, Deserialize)]
3593pub struct PublishEvent(pub Event, #[serde(skip)] pub Option<OverlayId>);
3594
3595#[derive(Clone, Debug, Serialize, Deserialize)]
3597pub enum ClientRequestContentV0 {
3598    OpenRepo(OpenRepo),
3599    PinRepo(PinRepo),
3600    UnpinRepo(UnpinRepo),
3601    RepoPinStatusReq(RepoPinStatusReq),
3602
3603    TopicSub(TopicSub),
3605    TopicUnsub(TopicUnsub),
3606
3607    BlocksExist(BlocksExist),
3608    BlocksGet(BlocksGet),
3609    CommitGet(CommitGet),
3610    TopicSyncReq(TopicSyncReq),
3611
3612    ObjectPin(ObjectPin),
3614    ObjectUnpin(ObjectUnpin),
3615    ObjectDel(ObjectDel),
3616
3617    BlocksPut(BlocksPut),
3619    PublishEvent(PublishEvent),
3620
3621    WalletPutExport(WalletPutExport),
3622}
3623
3624impl ClientRequestContentV0 {
3625    pub fn set_overlay(&mut self, overlay: OverlayId) {
3626        match self {
3627            ClientRequestContentV0::RepoPinStatusReq(a) => a.set_overlay(overlay),
3628            ClientRequestContentV0::TopicSub(a) => a.set_overlay(overlay),
3629            ClientRequestContentV0::PinRepo(_a) => {}
3630            ClientRequestContentV0::PublishEvent(a) => a.set_overlay(overlay),
3631            ClientRequestContentV0::CommitGet(a) => a.set_overlay(overlay),
3632            ClientRequestContentV0::TopicSyncReq(a) => a.set_overlay(overlay),
3633            ClientRequestContentV0::BlocksPut(a) => a.set_overlay(overlay),
3634            ClientRequestContentV0::BlocksExist(a) => a.set_overlay(overlay),
3635            ClientRequestContentV0::BlocksGet(a) => a.set_overlay(overlay),
3636            ClientRequestContentV0::WalletPutExport(_a) => {}
3637            _ => unimplemented!(),
3638        }
3639    }
3640}
3641
3642#[derive(Clone, Debug, Serialize, Deserialize)]
3644pub struct ClientRequestV0 {
3645    pub id: i64,
3647
3648    pub content: ClientRequestContentV0,
3650}
3651
3652#[derive(Clone, Debug, Serialize, Deserialize)]
3654pub enum ClientRequest {
3655    V0(ClientRequestV0),
3656}
3657
3658impl ClientRequest {
3659    pub fn id(&self) -> i64 {
3660        match self {
3661            ClientRequest::V0(o) => o.id,
3662        }
3663    }
3664    pub fn set_id(&mut self, id: i64) {
3665        match self {
3666            ClientRequest::V0(v0) => {
3667                v0.id = id;
3668            }
3669        }
3670    }
3671    pub fn content_v0(&self) -> &ClientRequestContentV0 {
3672        match self {
3673            ClientRequest::V0(o) => &o.content,
3674        }
3675    }
3676    pub fn get_actor(&self) -> Box<dyn EActor> {
3677        match self {
3678            Self::V0(ClientRequestV0 { content, .. }) => match content {
3679                ClientRequestContentV0::RepoPinStatusReq(r) => r.get_actor(self.id()),
3680                ClientRequestContentV0::PinRepo(r) => r.get_actor(self.id()),
3681                ClientRequestContentV0::TopicSub(r) => r.get_actor(self.id()),
3682                ClientRequestContentV0::PublishEvent(r) => r.get_actor(self.id()),
3683                ClientRequestContentV0::CommitGet(r) => r.get_actor(self.id()),
3684                ClientRequestContentV0::TopicSyncReq(r) => r.get_actor(self.id()),
3685                ClientRequestContentV0::BlocksPut(r) => r.get_actor(self.id()),
3686                ClientRequestContentV0::BlocksExist(r) => r.get_actor(self.id()),
3687                ClientRequestContentV0::BlocksGet(r) => r.get_actor(self.id()),
3688                ClientRequestContentV0::WalletPutExport(r) => r.get_actor(self.id()),
3689                _ => unimplemented!(),
3690            },
3691        }
3692    }
3693}
3694
3695impl TryFrom<ProtocolMessage> for ClientRequestContentV0 {
3696    type Error = ProtocolError;
3697    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
3698        if let ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
3699            overlay,
3700            content:
3701                ClientMessageContentV0::ClientRequest(ClientRequest::V0(ClientRequestV0 {
3702                    mut content,
3703                    ..
3704                })),
3705            ..
3706        })) = msg
3707        {
3708            content.set_overlay(overlay);
3709            Ok(content)
3710        } else {
3711            log_debug!("INVALID {:?}", msg);
3712            Err(ProtocolError::InvalidValue)
3713        }
3714    }
3715}
3716
3717#[derive(Clone, Debug, Serialize, Deserialize)]
3719pub struct BlocksFoundV0 {
3720    pub found: Vec<BlockId>,
3722
3723    pub missing: Vec<BlockId>,
3725}
3726
3727#[derive(Clone, Debug, Serialize, Deserialize)]
3729pub enum BlocksFound {
3730    V0(BlocksFoundV0),
3731}
3732
3733impl BlocksFound {
3734    pub fn found(&self) -> &Vec<BlockId> {
3735        match self {
3736            BlocksFound::V0(o) => &o.found,
3737        }
3738    }
3739    pub fn missing(&self) -> &Vec<BlockId> {
3740        match self {
3741            BlocksFound::V0(o) => &o.missing,
3742        }
3743    }
3744}
3745
3746#[derive(Clone, Debug, Serialize, Deserialize)]
3748pub struct TopicSubResV0 {
3749    pub topic: TopicId,
3751    pub known_heads: Vec<ObjectId>,
3752    pub publisher: bool,
3753    pub commits_nbr: u64,
3754}
3755
3756#[derive(Clone, Debug, Serialize, Deserialize)]
3760pub enum TopicSubRes {
3761    V0(TopicSubResV0),
3762}
3763
3764impl TopicSubRes {
3765    pub fn topic_id(&self) -> &TopicId {
3766        match self {
3767            Self::V0(v0) => &v0.topic,
3768        }
3769    }
3770    pub fn is_publisher(&self) -> bool {
3771        match self {
3772            Self::V0(v0) => v0.publisher,
3773        }
3774    }
3775    pub fn new_from_heads(
3776        topics: HashSet<ObjectId>,
3777        publisher: bool,
3778        topic: TopicId,
3779        commits_nbr: u64,
3780    ) -> Self {
3781        TopicSubRes::V0(TopicSubResV0 {
3782            topic,
3783            known_heads: topics.into_iter().collect(),
3784            publisher,
3785            commits_nbr,
3786        })
3787    }
3788    pub fn known_heads(&self) -> &Vec<ObjectId> {
3789        match self {
3790            Self::V0(v0) => &v0.known_heads,
3791        }
3792    }
3793    pub fn commits_nbr(&self) -> u64 {
3794        match self {
3795            Self::V0(v0) => v0.commits_nbr,
3796        }
3797    }
3798}
3799
3800impl From<TopicId> for TopicSubRes {
3801    fn from(topic: TopicId) -> Self {
3802        TopicSubRes::V0(TopicSubResV0 {
3803            topic,
3804            known_heads: vec![],
3805            publisher: false,
3806            commits_nbr: 0,
3807        })
3808    }
3809}
3810
3811impl From<PublisherAdvert> for TopicSubRes {
3812    fn from(topic: PublisherAdvert) -> Self {
3813        TopicSubRes::V0(TopicSubResV0 {
3814            topic: topic.topic_id().clone(),
3815            known_heads: vec![],
3816            publisher: true,
3817            commits_nbr: 0,
3818        })
3819    }
3820}
3821
3822pub type RepoOpened = Vec<TopicSubRes>;
3823
3824#[derive(Clone, Debug, Serialize, Deserialize)]
3826pub enum ClientResponseContentV0 {
3827    EmptyResponse,
3828    Block(Block),
3829    RepoOpened(RepoOpened),
3830    TopicSubRes(TopicSubRes),
3831    TopicSyncRes(TopicSyncRes),
3832    BlocksFound(BlocksFound),
3833    RepoPinStatus(RepoPinStatus),
3834}
3835
3836#[derive(Clone, Debug, Serialize, Deserialize)]
3838pub struct ClientResponseV0 {
3839    pub id: i64,
3841
3842    pub result: u16,
3844
3845    pub content: ClientResponseContentV0,
3847}
3848
3849impl ClientResponse {
3850    pub fn set_result(&mut self, res: u16) {
3851        match self {
3852            Self::V0(v0) => v0.result = res,
3853        }
3854    }
3855}
3856
3857#[derive(Clone, Debug, Serialize, Deserialize)]
3859pub enum ClientResponse {
3860    V0(ClientResponseV0),
3861}
3862
3863impl From<ServerError> for ClientResponse {
3864    fn from(err: ServerError) -> ClientResponse {
3865        ClientResponse::V0(ClientResponseV0 {
3866            id: 0,
3867            result: err.into(),
3868            content: ClientResponseContentV0::EmptyResponse,
3869        })
3870    }
3871}
3872
3873#[derive(Debug)]
3874pub struct EmptyAppResponse(pub ());
3875
3876impl From<ServerError> for AppMessage {
3877    fn from(err: ServerError) -> AppMessage {
3878        AppMessage::V0(AppMessageV0 {
3879            id: 0,
3880            result: err.into(),
3881            content: AppMessageContentV0::EmptyResponse,
3882        })
3883    }
3884}
3885
3886impl<A> From<Result<A, ServerError>> for ProtocolMessage
3887where
3888    A: Into<ProtocolMessage> + std::fmt::Debug,
3889{
3890    fn from(res: Result<A, ServerError>) -> ProtocolMessage {
3891        match res {
3892            Ok(a) => a.into(),
3893            Err(e) => ProtocolMessage::from_client_response_err(e),
3894        }
3895    }
3896}
3897
3898impl From<()> for ProtocolMessage {
3899    fn from(_msg: ()) -> ProtocolMessage {
3900        let cm: ClientResponse = ServerError::Ok.into();
3901        cm.into()
3902    }
3903}
3904
3905impl ClientResponse {
3906    pub fn id(&self) -> i64 {
3907        match self {
3908            ClientResponse::V0(o) => o.id,
3909        }
3910    }
3911    pub fn set_id(&mut self, id: i64) {
3912        match self {
3913            ClientResponse::V0(v0) => {
3914                v0.id = id;
3915            }
3916        }
3917    }
3918    pub fn result(&self) -> u16 {
3919        match self {
3920            ClientResponse::V0(o) => o.result,
3921        }
3922    }
3923    pub fn block(&self) -> Option<&Block> {
3924        match self {
3925            ClientResponse::V0(o) => match &o.content {
3926                ClientResponseContentV0::Block(b) => Some(b),
3927                _ => panic!("this not a block response"),
3928            },
3929        }
3930    }
3931}
3932
3933impl TryFrom<ProtocolMessage> for ClientResponseContentV0 {
3934    type Error = ProtocolError;
3935    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
3936        if let ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
3937            content:
3938                ClientMessageContentV0::ClientResponse(ClientResponse::V0(ClientResponseV0 {
3939                    content,
3940                    result: res,
3941                    ..
3942                })),
3943            ..
3944        })) = msg
3945        {
3946            let err = ServerError::try_from(res).unwrap();
3947            if !err.is_err() {
3948                Ok(content)
3949            } else {
3950                Err(ProtocolError::ServerError)
3951            }
3952        } else {
3953            log_debug!("INVALID {:?}", msg);
3954            Err(ProtocolError::InvalidValue)
3955        }
3956    }
3957}
3958
3959#[derive(Clone, Debug, Serialize, Deserialize)]
3961pub enum ClientMessageContentV0 {
3962    ClientRequest(ClientRequest),
3963    ClientResponse(ClientResponse),
3964    ForwardedEvent(Event),
3965    ForwardedBlock(Block),
3966}
3967impl ClientMessageContentV0 {
3968    pub fn is_block(&self) -> bool {
3969        match self {
3970            Self::ClientRequest(ClientRequest::V0(ClientRequestV0 {
3971                content: ClientRequestContentV0::BlocksPut(_),
3972                ..
3973            })) => true,
3974            Self::ClientResponse(ClientResponse::V0(ClientResponseV0 {
3975                content: ClientResponseContentV0::Block(_),
3976                ..
3977            })) => true,
3978            _ => false,
3979        }
3980    }
3981}
3982
3983#[derive(Clone, Debug, Serialize, Deserialize)]
3985pub struct ClientMessageV0 {
3986    pub overlay: OverlayId,
3987    pub content: ClientMessageContentV0,
3988    #[serde(with = "serde_bytes")]
3990    pub padding: Vec<u8>,
3991}
3992
3993pub trait IStreamable {
3994    fn result(&self) -> u16;
3995    fn set_result(&mut self, result: u16);
3996}
3997
3998#[derive(Clone, Debug, Serialize, Deserialize)]
4000pub enum ClientMessage {
4001    V0(ClientMessageV0),
4002}
4003
4004impl IStreamable for ClientMessage {
4005    fn result(&self) -> u16 {
4006        match self {
4007            ClientMessage::V0(o) => match &o.content {
4008                ClientMessageContentV0::ClientResponse(r) => r.result(),
4009                ClientMessageContentV0::ClientRequest(_)
4010                | ClientMessageContentV0::ForwardedEvent(_)
4011                | ClientMessageContentV0::ForwardedBlock(_) => {
4012                    panic!("it is not a response");
4013                }
4014            },
4015        }
4016    }
4017    fn set_result(&mut self, result: u16) {
4018        match self {
4019            ClientMessage::V0(o) => match &mut o.content {
4020                ClientMessageContentV0::ClientResponse(r) => r.set_result(result),
4021                ClientMessageContentV0::ClientRequest(_)
4022                | ClientMessageContentV0::ForwardedEvent(_)
4023                | ClientMessageContentV0::ForwardedBlock(_) => {
4024                    panic!("it is not a response");
4025                }
4026            },
4027        }
4028    }
4029}
4030
4031impl ClientMessage {
4032    pub fn content_v0(&self) -> &ClientMessageContentV0 {
4033        match self {
4034            ClientMessage::V0(o) => &o.content,
4035        }
4036    }
4037    pub fn overlay_request(&self) -> &ClientRequest {
4038        match self {
4039            ClientMessage::V0(o) => match &o.content {
4040                ClientMessageContentV0::ClientRequest(r) => &r,
4041                _ => panic!("not an overlay request"),
4042            },
4043        }
4044    }
4045
4046    pub fn forwarded_event(self) -> Option<(Event, OverlayId)> {
4047        let overlay = self.overlay_id();
4048        match self {
4049            ClientMessage::V0(o) => match o.content {
4050                ClientMessageContentV0::ForwardedEvent(e) => Some((e, overlay)),
4051                _ => None,
4052            },
4053        }
4054    }
4055    pub fn overlay_id(&self) -> OverlayId {
4056        match self {
4057            ClientMessage::V0(o) => o.overlay,
4058        }
4059    }
4060    pub fn is_request(&self) -> bool {
4061        match self {
4062            ClientMessage::V0(o) => {
4063                matches!(o.content, ClientMessageContentV0::ClientRequest { .. })
4064            }
4065        }
4066    }
4067    pub fn is_response(&self) -> bool {
4068        match self {
4069            ClientMessage::V0(o) => {
4070                matches!(o.content, ClientMessageContentV0::ClientResponse { .. })
4071            }
4072        }
4073    }
4074    pub fn id(&self) -> Option<i64> {
4075        match self {
4076            ClientMessage::V0(o) => match &o.content {
4077                ClientMessageContentV0::ClientResponse(r) => Some(r.id()),
4078                ClientMessageContentV0::ClientRequest(r) => Some(r.id()),
4079                ClientMessageContentV0::ForwardedEvent(_)
4080                | ClientMessageContentV0::ForwardedBlock(_) => None,
4081            },
4082        }
4083    }
4084    pub fn set_id(&mut self, id: i64) {
4085        match self {
4086            ClientMessage::V0(o) => match &mut o.content {
4087                ClientMessageContentV0::ClientResponse(ref mut r) => r.set_id(id),
4088                ClientMessageContentV0::ClientRequest(ref mut r) => r.set_id(id),
4089                ClientMessageContentV0::ForwardedEvent(_)
4090                | ClientMessageContentV0::ForwardedBlock(_) => {
4091                    panic!("it is an event")
4092                }
4093            },
4094        }
4095    }
4096
4097    pub fn block<'a>(&self) -> Option<&Block> {
4098        match self {
4099            ClientMessage::V0(o) => match &o.content {
4100                ClientMessageContentV0::ClientResponse(r) => r.block(),
4101                ClientMessageContentV0::ClientRequest(_)
4102                | ClientMessageContentV0::ForwardedEvent(_)
4103                | ClientMessageContentV0::ForwardedBlock(_) => {
4104                    panic!("it is not a response");
4105                }
4106            },
4107        }
4108    }
4109
4110    pub fn get_actor(&self) -> Box<dyn EActor> {
4111        match self {
4112            ClientMessage::V0(o) => match &o.content {
4113                ClientMessageContentV0::ClientRequest(req) => req.get_actor(),
4114                ClientMessageContentV0::ClientResponse(_)
4115                | ClientMessageContentV0::ForwardedEvent(_)
4116                | ClientMessageContentV0::ForwardedBlock(_) => {
4117                    panic!("it is not a request");
4118                }
4119            },
4120        }
4121    }
4122}
4123
4124#[derive(Clone, Debug, Serialize, Deserialize)]
4133pub struct ExtObjectGetV0 {
4134    pub overlay: OverlayId,
4136
4137    pub ids: Vec<ObjectId>,
4139
4140    pub include_files: bool,
4142}
4143
4144#[derive(Clone, Debug, Serialize, Deserialize)]
4146pub enum ExtObjectGet {
4147    V0(ExtObjectGetV0),
4148}
4149
4150#[derive(Clone, Debug, Serialize, Deserialize)]
4151pub struct ExtWalletGetExportV0 {
4152    pub id: SymKey,
4153    pub is_rendezvous: bool,
4154}
4155
4156pub type ExtTopicSyncReq = TopicSyncReq;
4158
4159#[derive(Clone, Debug, Serialize, Deserialize)]
4161pub enum ExtRequestContentV0 {
4162    WalletGetExport(ExtWalletGetExportV0),
4163    ExtObjectGet(ExtObjectGetV0),
4164    ExtTopicSyncReq(ExtTopicSyncReq),
4165    }
4168
4169impl ExtRequestContentV0 {
4170    pub fn get_actor(&self) -> Box<dyn EActor> {
4171        match self {
4172            Self::WalletGetExport(a) => a.get_actor(),
4173            Self::ExtObjectGet(a) => a.get_actor(),
4174            _ => unimplemented!(), }
4176    }
4177}
4178
4179#[derive(Clone, Debug, Serialize, Deserialize)]
4181pub struct ExtRequestV0 {
4182    pub id: i64,
4184
4185    pub content: ExtRequestContentV0,
4187}
4188
4189#[derive(Clone, Debug, Serialize, Deserialize)]
4194pub enum ExtRequest {
4195    V0(ExtRequestV0),
4196}
4197
4198impl ExtRequest {
4199    pub fn id(&self) -> i64 {
4200        match self {
4201            ExtRequest::V0(v0) => v0.id,
4202        }
4203    }
4204    pub fn set_id(&mut self, id: i64) {
4205        match self {
4206            ExtRequest::V0(v0) => {
4207                v0.id = id;
4208            }
4209        }
4210    }
4211    pub fn get_actor(&self) -> Box<dyn EActor> {
4212        match self {
4213            Self::V0(a) => a.content.get_actor(),
4214        }
4215    }
4216}
4217
4218#[derive(Clone, Debug, Serialize, Deserialize)]
4219pub struct ExportedWallet(pub serde_bytes::ByteBuf);
4220
4221#[derive(Clone, Debug, Serialize, Deserialize)]
4223pub enum ExtResponseContentV0 {
4224    EmptyResponse,
4225    Block(Block),
4226    Blocks(Vec<Block>),
4227    Wallet(ExportedWallet),
4228    }
4231
4232impl TryFrom<ProtocolMessage> for ExtResponseContentV0 {
4233    type Error = ProtocolError;
4234    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
4235        if let ProtocolMessage::ExtResponse(ExtResponse::V0(ExtResponseV0 {
4236            content,
4237            result,
4238            ..
4239        })) = msg
4240        {
4241            let err = ServerError::try_from(result).unwrap();
4242            if !err.is_err() {
4243                Ok(content)
4244            } else {
4245                Err(ProtocolError::ServerError)
4246            }
4247        } else {
4248            log_debug!("INVALID {:?}", msg);
4249            Err(ProtocolError::InvalidValue)
4250        }
4251    }
4252}
4253
4254#[derive(Clone, Debug, Serialize, Deserialize)]
4256pub struct ExtResponseV0 {
4257    pub id: i64,
4259
4260    pub result: u16,
4262
4263    pub content: ExtResponseContentV0,
4265}
4266
4267#[derive(Clone, Debug, Serialize, Deserialize)]
4269pub enum ExtResponse {
4270    V0(ExtResponseV0),
4271}
4272
4273impl ExtResponse {
4274    pub fn id(&self) -> i64 {
4275        match self {
4276            ExtResponse::V0(v0) => v0.id,
4277        }
4278    }
4279    pub fn set_id(&mut self, id: i64) {
4280        match self {
4281            ExtResponse::V0(v0) => {
4282                v0.id = id;
4283            }
4284        }
4285    }
4286    pub fn result(&self) -> u16 {
4287        match self {
4288            Self::V0(o) => o.result,
4289        }
4290    }
4291    pub fn content_v0(&self) -> ExtResponseContentV0 {
4292        match self {
4293            Self::V0(o) => o.content.clone(),
4294        }
4295    }
4296}
4297
4298impl TryFrom<ProtocolMessage> for ExtResponse {
4299    type Error = ProtocolError;
4300    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
4301        if let ProtocolMessage::ExtResponse(ext_res) = msg {
4302            Ok(ext_res)
4303        } else {
4304            Err(ProtocolError::InvalidValue)
4305        }
4306    }
4307}
4308
4309impl From<Result<ExtResponseContentV0, ServerError>> for ExtResponseV0 {
4310    fn from(res: Result<ExtResponseContentV0, ServerError>) -> ExtResponseV0 {
4311        match res {
4312            Err(e) => ExtResponseV0 {
4313                id: 0,
4314                result: e.into(),
4315                content: ExtResponseContentV0::EmptyResponse,
4316            },
4317            Ok(content) => ExtResponseV0 {
4318                id: 0,
4319                result: 0,
4320                content,
4321            },
4322        }
4323    }
4324}
4325
4326impl From<ExtResponseV0> for ProtocolMessage {
4327    fn from(msg: ExtResponseV0) -> ProtocolMessage {
4328        ProtocolMessage::ExtResponse(ExtResponse::V0(msg))
4329    }
4330}
4331
4332#[doc(hidden)]
4336pub static MAGIC_NG_REQUEST: [u8; 2] = [78u8, 71u8];
4337#[doc(hidden)]
4338pub static MAGIC_NG_RESPONSE: [u8; 4] = [89u8, 88u8, 78u8, 75u8];
4339
4340#[derive(Clone, Debug)]
4341pub enum Authorization {
4342    Discover,
4343    ExtMessage,
4344    Core,
4345    Client((PubKey, Option<Option<[u8; 32]>>)),
4346    OverlayJoin(PubKey),
4347    Admin(PubKey),
4348}
4349
4350#[derive(Clone, Debug, Serialize, Deserialize)]
4352pub struct ProbeResponse {
4353    #[serde(with = "serde_bytes")]
4355    pub magic: Vec<u8>,
4356
4357    pub peer_id: Option<PubKey>,
4360}
4361
4362#[derive(Clone, Debug, Serialize, Deserialize)]
4364pub struct RelayRequest {
4365    pub address: BindAddress,
4367}
4368
4369#[derive(Clone, Debug, Serialize, Deserialize)]
4371pub struct RelayResponse {
4372    #[serde(with = "serde_bytes")]
4374    pub magic: Vec<u8>,
4375
4376    pub result: u16,
4378}
4379
4380#[derive(Clone, Debug, Serialize, Deserialize)]
4382pub struct TunnelRequest {
4383    #[serde(with = "serde_bytes")]
4385    pub magic: Vec<u8>,
4386
4387    pub remote_addr: BindAddress,
4389}
4390
4391#[derive(Clone, Debug, Serialize, Deserialize)]
4393pub struct TunnelResponse {
4394    #[serde(with = "serde_bytes")]
4396    pub magic: Vec<u8>,
4397
4398    pub result: u16,
4400}
4401
4402#[derive(Clone, Debug, Serialize, Deserialize)]
4403pub enum ProtocolMessage {
4404    Probe([u8; 2]),
4405    ProbeResponse(ProbeResponse),
4406    Relay(RelayRequest),
4407    RelayResponse(RelayResponse),
4408    Tunnel(TunnelRequest),
4409    TunnelResponse(TunnelResponse),
4410    Noise(Noise),
4411    Start(StartProtocol),
4412    ServerHello(ServerHello),
4413    ClientAuth(ClientAuth),
4414    AuthResult(AuthResult),
4415    ExtRequest(ExtRequest),
4416    ExtResponse(ExtResponse),
4417    AdminResponse(AdminResponse),
4419    ClientMessage(ClientMessage),
4420    AppMessage(AppMessage),
4421    CoreMessage(CoreMessage),
4422}
4423
4424impl TryFrom<&ProtocolMessage> for ServerError {
4425    type Error = NgError;
4426    fn try_from(msg: &ProtocolMessage) -> Result<Self, NgError> {
4427        if let ProtocolMessage::ClientMessage(ref bm) = msg {
4428            let res = bm.result();
4429            if res != 0 {
4430                return Ok(ServerError::try_from(res).unwrap());
4431            }
4432        }
4433        if let ProtocolMessage::ExtResponse(ref bm) = msg {
4434            let res = bm.result();
4435            if res != 0 {
4436                return Ok(ServerError::try_from(res).unwrap());
4437            }
4438        }
4439        if let ProtocolMessage::AppMessage(ref bm) = msg {
4440            let res = bm.result();
4441            if res != 0 {
4442                return Ok(ServerError::try_from(res).unwrap());
4443            }
4444        }
4445        Err(NgError::NotAServerError)
4446    }
4447}
4448
4449impl ProtocolMessage {
4450    pub fn id(&self) -> Option<i64> {
4451        match self {
4452            ProtocolMessage::ExtRequest(ext_req) => Some(ext_req.id()),
4453            ProtocolMessage::ExtResponse(ext_res) => Some(ext_res.id()),
4454            ProtocolMessage::ClientMessage(client_msg) => client_msg.id(),
4455            ProtocolMessage::AppMessage(app_msg) => app_msg.id(),
4456            _ => None,
4457        }
4458    }
4459    pub fn set_id(&mut self, id: i64) {
4460        match self {
4461            ProtocolMessage::ExtRequest(ext_req) => ext_req.set_id(id),
4462            ProtocolMessage::ExtResponse(ext_res) => ext_res.set_id(id),
4463            ProtocolMessage::ClientMessage(client_msg) => client_msg.set_id(id),
4464            ProtocolMessage::AppMessage(app_msg) => app_msg.set_id(id),
4465            _ => panic!("cannot set ID"),
4466        }
4467    }
4468    pub fn type_id(&self) -> TypeId {
4469        match self {
4470            ProtocolMessage::Noise(a) => a.type_id(),
4471            ProtocolMessage::Start(a) => a.type_id(),
4472            ProtocolMessage::ServerHello(a) => a.type_id(),
4473            ProtocolMessage::ClientAuth(a) => a.type_id(),
4474            ProtocolMessage::AuthResult(a) => a.type_id(),
4475            ProtocolMessage::ExtRequest(a) => a.type_id(),
4476            ProtocolMessage::ExtResponse(a) => a.type_id(),
4477            ProtocolMessage::ClientMessage(a) => a.type_id(),
4478            ProtocolMessage::CoreMessage(a) => a.type_id(),
4479            ProtocolMessage::AppMessage(a) => a.type_id(),
4480            ProtocolMessage::AdminResponse(a) => a.type_id(),
4482            ProtocolMessage::Probe(a) => a.type_id(),
4483            ProtocolMessage::ProbeResponse(a) => a.type_id(),
4484            ProtocolMessage::Relay(a) => a.type_id(),
4485            ProtocolMessage::RelayResponse(a) => a.type_id(),
4486            ProtocolMessage::Tunnel(a) => a.type_id(),
4487            ProtocolMessage::TunnelResponse(a) => a.type_id(),
4488        }
4489    }
4490
4491    pub(crate) fn is_streamable(&self) -> Option<&dyn IStreamable> {
4492        match self {
4493            ProtocolMessage::ClientMessage(s) => Some(s as &dyn IStreamable),
4494            ProtocolMessage::AppMessage(s) => Some(s as &dyn IStreamable),
4495            _ => None,
4496        }
4497    }
4498
4499    pub fn get_actor(&self) -> Box<dyn EActor> {
4500        match self {
4501            ProtocolMessage::Start(a) => a.get_actor(),
4503            ProtocolMessage::ClientMessage(a) => a.get_actor(),
4504            ProtocolMessage::AppMessage(a) => a.get_actor(),
4505            _ => unimplemented!(),
4512        }
4513    }
4514
4515    pub fn from_client_response_err(err: ServerError) -> ProtocolMessage {
4516        let res: ClientResponse = err.into();
4517        res.into()
4518    }
4519
4520    pub fn from_client_request_v0(
4521        req: ClientRequestContentV0,
4522        overlay: OverlayId,
4523    ) -> ProtocolMessage {
4524        ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
4525            overlay,
4526            content: ClientMessageContentV0::ClientRequest(ClientRequest::V0(ClientRequestV0 {
4527                id: 0,
4528                content: req,
4529            })),
4530            padding: vec![],
4531        }))
4532    }
4533
4534    pub fn is_block(&self) -> bool {
4535        match self {
4536            ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
4537                content: c,
4538                ..
4539            })) => c.is_block(),
4540            _ => false,
4541        }
4542    }
4543}
4544
4545impl From<ClientResponseContentV0> for ClientResponse {
4546    fn from(msg: ClientResponseContentV0) -> ClientResponse {
4547        ClientResponse::V0(ClientResponseV0 {
4548            id: 0,
4549            result: 0,
4550            content: msg,
4551        })
4552    }
4553}
4554
4555impl From<ClientResponseContentV0> for ProtocolMessage {
4556    fn from(msg: ClientResponseContentV0) -> ProtocolMessage {
4557        let client_res = ClientResponse::V0(ClientResponseV0 {
4558            id: 0,
4559            result: 0,
4560            content: msg,
4561        });
4562        client_res.into()
4563    }
4564}
4565
4566impl From<ClientResponse> for ProtocolMessage {
4567    fn from(msg: ClientResponse) -> ProtocolMessage {
4568        ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
4569            overlay: OverlayId::nil(),
4570            content: ClientMessageContentV0::ClientResponse(msg),
4571            padding: vec![],
4572        }))
4573    }
4574}
4575
4576#[derive(Clone, Debug, Serialize, Deserialize)]
4582pub struct ClientAuthContentV0 {
4583    pub user: PubKey,
4585
4586    pub client: PubKey,
4588
4589    pub info: ClientInfoV0,
4590
4591    pub registration: Option<Option<[u8; 32]>>,
4592
4593    #[serde(with = "serde_bytes")]
4595    pub nonce: Vec<u8>,
4596}
4597
4598#[derive(Clone, Debug, Serialize, Deserialize)]
4600pub struct ClientAuthV0 {
4601    pub content: ClientAuthContentV0,
4603
4604    pub sig: Sig,
4606
4607    pub client_sig: Sig,
4609}
4610
4611#[derive(Clone, Debug, Serialize, Deserialize)]
4613pub enum ClientAuth {
4614    V0(ClientAuthV0),
4615}
4616
4617impl ClientAuth {
4618    pub fn content_v0(&self) -> ClientAuthContentV0 {
4619        match self {
4620            ClientAuth::V0(o) => o.content.clone(),
4621        }
4622    }
4623    pub fn sig(&self) -> Sig {
4624        match self {
4625            ClientAuth::V0(o) => o.sig,
4626        }
4627    }
4628    pub fn user(&self) -> PubKey {
4629        match self {
4630            ClientAuth::V0(o) => o.content.user,
4631        }
4632    }
4633    pub fn client(&self) -> PubKey {
4634        match self {
4635            ClientAuth::V0(o) => o.content.client,
4636        }
4637    }
4638    pub fn nonce(&self) -> &Vec<u8> {
4639        match self {
4640            ClientAuth::V0(o) => &o.content.nonce,
4641        }
4642    }
4643    pub fn registration(&self) -> Option<Option<[u8; 32]>> {
4644        match self {
4645            ClientAuth::V0(o) => o.content.registration,
4646        }
4647    }
4648}
4649
4650impl From<ClientAuth> for ProtocolMessage {
4651    fn from(msg: ClientAuth) -> ProtocolMessage {
4652        ProtocolMessage::ClientAuth(msg)
4653    }
4654}
4655
4656#[derive(Clone, Debug, Serialize, Deserialize)]
4658pub struct AuthResultV0 {
4659    pub result: u16,
4660    #[serde(with = "serde_bytes")]
4661    pub metadata: Vec<u8>,
4662}
4663
4664#[derive(Clone, Debug, Serialize, Deserialize)]
4666pub enum AuthResult {
4667    V0(AuthResultV0),
4668}
4669
4670impl AuthResult {
4671    pub fn result(&self) -> u16 {
4672        match self {
4673            AuthResult::V0(o) => o.result,
4674        }
4675    }
4676    pub fn metadata(&self) -> &Vec<u8> {
4677        match self {
4678            AuthResult::V0(o) => &o.metadata,
4679        }
4680    }
4681}
4682
4683impl From<AuthResult> for ProtocolMessage {
4684    fn from(msg: AuthResult) -> ProtocolMessage {
4685        ProtocolMessage::AuthResult(msg)
4686    }
4687}
4688
4689#[derive(Clone, Debug, Serialize, Deserialize)]
4703pub struct RepoLinkV0 {
4704    pub id: RepoId,
4706
4707    pub read_cap: ReadCap,
4710
4711    pub overlay: OverlayLink,
4716
4717    pub peers: Vec<PeerAdvert>,
4719}
4720
4721#[derive(Clone, Debug, Serialize, Deserialize)]
4723pub enum RepoLink {
4724    V0(RepoLinkV0),
4725}
4726
4727impl RepoLink {
4728    pub fn id(&self) -> &RepoId {
4729        match self {
4730            RepoLink::V0(o) => &o.id,
4731        }
4732    }
4733    pub fn peers(&self) -> &Vec<PeerAdvert> {
4734        match self {
4735            RepoLink::V0(o) => &o.peers,
4736        }
4737    }
4738}
4739
4740#[derive(Clone, Debug, Serialize, Deserialize)]
4746pub struct PublicRepoLinkV0 {
4747    pub repo: RepoId,
4749
4750    pub branch: Option<BranchId>,
4753
4754    pub heads: Vec<ObjectRef>,
4757
4758    pub snapshot: Option<ObjectRef>,
4760
4761    pub public_store: PubKey,
4763
4764    pub peers: Vec<PeerAdvert>,
4766}
4767
4768#[derive(Clone, Debug, Serialize, Deserialize)]
4770pub enum PublicRepoLink {
4771    V0(PublicRepoLinkV0),
4772}
4773
4774#[derive(Clone, Debug, Serialize, Deserialize)]
4783pub struct ReadBranchLinkV0 {
4784    pub repo: RepoId,
4786
4787    pub branch: BranchId, pub topic: TopicId,
4790
4791    pub heads: Vec<ObjectRef>,
4794
4795    pub read_cap: ReadCap,
4798
4799    pub overlay: OverlayLink,
4801
4802    pub peers: Vec<PeerAdvert>,
4804}
4805
4806#[derive(Clone, Debug, Serialize, Deserialize)]
4808pub enum ReadBranchLink {
4809    V0(ReadBranchLinkV0),
4810}
4811
4812#[derive(Clone, Debug, Serialize, Deserialize)]
4817pub struct ObjectLinkV0 {
4818    pub repo: Option<RepoId>,
4822
4823    pub topic: Option<TopicId>,
4829
4830    pub objects: Vec<ObjectRef>,
4831
4832    pub overlay: OverlayLink,
4834
4835    pub peers: Vec<PeerAdvert>,
4837}
4838
4839#[derive(Clone, Debug, Serialize, Deserialize)]
4841pub enum ObjectLink {
4842    V0(ObjectLinkV0),
4843}
4844
4845#[derive(Clone, Debug, Serialize, Deserialize)]
4847pub enum NgLinkV0 {
4848    Repo(RepoLink),
4849    PublicRepo(PublicRepoLink),
4850    Branch(ReadBranchLink),
4851    Object(ObjectLink),
4852}
4853
4854#[derive(Clone, Debug, Serialize, Deserialize)]
4856pub enum NgLink {
4857    V0(NgLinkV0),
4858}
4859
4860#[cfg(test)]
4863mod test {
4864
4865    use crate::types::{BootstrapContentV0, BrokerServerTypeV0, BrokerServerV0, Invitation};
4866    use ng_repo::types::PubKey;
4867
4868    #[test]
4869    pub fn invitation() {
4870        let inv = Invitation::new_v0(
4871            BootstrapContentV0 {
4872                servers: vec![BrokerServerV0 {
4873                    server_type: BrokerServerTypeV0::Localhost(14400),
4874                    can_verify: false,
4875                    can_forward: false,
4876                    peer_id: PubKey::Ed25519PubKey([
4877                        95, 73, 225, 250, 3, 147, 24, 164, 177, 211, 34, 244, 45, 130, 111, 136,
4878                        229, 145, 53, 167, 50, 168, 140, 227, 65, 111, 203, 41, 210, 186, 162, 149,
4879                    ]),
4880                }],
4881            },
4882            Some("test invitation".to_string()),
4883            None,
4884        );
4885
4886        println!("{:?}", inv.get_urls());
4887    }
4888}