1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! KitsuneP2p Wire Protocol Encoding Decoding

use crate::actor::BroadcastTo;
use crate::agent_store::AgentInfoSigned;
use crate::types::*;
use derive_more::*;
use kitsune_p2p_types::dht_arc::DhtLocation;
use std::sync::Arc;

/// Type used for content data of wire messages.
#[derive(
    Debug, Clone, PartialEq, Eq, Deref, AsRef, From, Into, serde::Serialize, serde::Deserialize,
)]
pub struct WireData(#[serde(with = "serde_bytes")] pub Vec<u8>);

/// Enum containing the individual metric exchange messages used by clients
#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum MetricExchangeMsg {
    /// To start off, let's use a naive single message sending
    /// everything we care about.
    V1UniBlast {
        /// The extrapolated coverage calculated by this node
        /// note this is NOT the aggregate the node has collected,
        /// just the direct extrapolation based on known peer infos.
        extrap_cov_f32_le: WireData,
    },

    /// Future proof by having an unknown message catch-all variant
    /// that we can ignore for any future variants that are added
    #[serde(other)]
    UnknownMessage,
}

kitsune_p2p_types::write_codec_enum! {
    /// KitsuneP2p Wire Protocol Top-Level Enum.
    codec Wire {
        /// Failure
        Failure(0x00) {
            reason.0: String,
        },

        /// "Call" to the remote.
        Call(0x010) {
            space.0: Arc<KitsuneSpace>,
            to_agent.1: Arc<KitsuneAgent>,
            data.2: WireData,
        },

        /// "Call" response from the remote.
        CallResp(0x11) {
            data.0: WireData,
        },

        /// "DelegateBroadcast" to the remote.
        /// Remote should in turn connect to nodes in neighborhood,
        /// and call "Notify" per broadcast algorithm.
        /// uses low-level notify, not request
        DelegateBroadcast(0x22) {
            space.0: Arc<KitsuneSpace>,
            basis.1: Arc<KitsuneBasis>,
            to_agent.2: Arc<KitsuneAgent>,

            /// If `tgt_agent.get_loc() % mod_cnt == mod_idx`,
            /// we are responsible for broadcasting to tgt_agent.
            mod_idx.3: u32,

            /// see mod_idx description
            mod_cnt.4: u32,

            destination.5: BroadcastTo,

            data.6: WireData,
        },

        /// Fire-and-forget broadcast message.
        /// uses low-level notify, not request
        Broadcast(0x23) {
            space.0: Arc<KitsuneSpace>,
            to_agent.1: Arc<KitsuneAgent>,
            destination.2: BroadcastTo,
            data.3: WireData,
        },

        /// Gossip op with opaque data section,
        /// to be forwarded to gossip module.
        /// uses low-level notify, not request
        Gossip(0x42) {
            space.0: Arc<KitsuneSpace>,
            data.1: WireData,
            module.2: gossip::GossipModuleType,
        },

        /// Ask a remote node if they know about a specific agent
        PeerGet(0x50) {
            space.0: Arc<KitsuneSpace>,
            agent.1: Arc<KitsuneAgent>,
        },

        /// Response to a peer get
        PeerGetResp(0x51) {
            agent_info_signed.0: AgentInfoSigned,
        },

        /// Query a remote node for peers holding
        /// or nearest to holding a u32 location.
        PeerQuery(0x52) {
            space.0: Arc<KitsuneSpace>,
            basis_loc.1: DhtLocation,
        },

        /// Response to a peer query
        PeerQueryResp(0x53) {
            peer_list.0: Vec<AgentInfoSigned>,
        },

        /// MetricsExchangeMessage
        MetricExchange(0xa0) {
            space.0: Arc<KitsuneSpace>,
            msgs.1: Vec<MetricExchangeMsg>,
        },
    }
}