ant_protocol/messages/
query.rs

1// Copyright 2024 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3.
4// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed
5// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
6// KIND, either express or implied. Please review the Licences for the specific language governing
7// permissions and limitations relating to use of the SAFE Network Software.
8
9use crate::{messages::Nonce, NetworkAddress};
10use libp2p::kad::U256;
11use serde::{Deserialize, Serialize};
12
13/// Data queries - retrieving data and inspecting their structure.
14///
15/// See the [`protocol`] module documentation for more details of the types supported by the Safe
16/// Network, and their semantics.
17///
18/// [`protocol`]: crate
19#[derive(Eq, PartialEq, PartialOrd, Clone, Serialize, Deserialize, Debug)]
20pub enum Query {
21    /// Retrieve the quote to store a record at the given address.
22    /// The storage verification is optional to be undertaken
23    GetStoreQuote {
24        /// The Address of the record to be stored.
25        key: NetworkAddress,
26        /// DataTypes as represented as its `index`
27        data_type: u32,
28        /// Data size of the record
29        data_size: usize,
30        /// The random nonce that nodes use to produce the Proof (i.e., hash(record+nonce))
31        /// Set to None if no need to carry out storage check.
32        nonce: Option<Nonce>,
33        /// Defines the expected number of answers to the challenge.
34        /// Node shall try their best to fulfill the number, based on their capacity.
35        /// Set to 0 to indicate not carry out any verification.
36        difficulty: usize,
37    },
38    /// Retrieve a specific record from a specific peer.
39    ///
40    /// This should eventually lead to a [`GetReplicatedRecord`] response.
41    ///
42    /// [`GetReplicatedRecord`]: super::QueryResponse::GetReplicatedRecord
43    GetReplicatedRecord {
44        /// Sender of the query
45        requester: NetworkAddress,
46        /// Key of the record to be fetched
47        key: NetworkAddress,
48    },
49    /// Get the proof that the chunk with the given NetworkAddress exists with the requested node.
50    GetChunkExistenceProof {
51        /// The Address of the chunk that we are trying to verify.
52        key: NetworkAddress,
53        /// The random nonce that the node uses to produce the Proof (i.e., hash(record+nonce))
54        nonce: Nonce,
55        /// Defines the expected number of answers to the challenge.
56        /// For client publish verification, use 1 for efficiency.
57        /// Node shall try their best to fulfill the number, based on their capacity.
58        difficulty: usize,
59    },
60    /// Queries close_group peers whether the target peer is a bad_node
61    CheckNodeInProblem(NetworkAddress),
62    /// Query the peers in range to the target address, from the receiver's perspective.
63    /// In case none of the parameters provided, returns nothing.
64    /// In case both of the parameters provided, `range` is preferred to be replied.
65    GetClosestPeers {
66        key: NetworkAddress,
67        // Shall be greater than K_VALUE, otherwise can use libp2p function directly
68        num_of_peers: Option<usize>,
69        // Defines the range that replied peers shall be within
70        range: Option<[u8; 32]>,
71        // For future econ usage,
72        sign_result: bool,
73    },
74    /// *** From now on, the order of variants shall be retained to be backward compatible
75    /// Query peer's cargo package version.
76    GetVersion(NetworkAddress),
77}
78
79impl Query {
80    /// Used to send a query to the close group of the address.
81    pub fn dst(&self) -> NetworkAddress {
82        match self {
83            Query::CheckNodeInProblem(address) | Query::GetVersion(address) => address.clone(),
84            // Shall not be called for this, as this is a `one-to-one` message,
85            // and the destination shall be decided by the requester already.
86            Query::GetStoreQuote { key, .. }
87            | Query::GetReplicatedRecord { key, .. }
88            | Query::GetChunkExistenceProof { key, .. }
89            | Query::GetClosestPeers { key, .. } => key.clone(),
90        }
91    }
92}
93
94impl std::fmt::Display for Query {
95    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
96        match self {
97            Query::GetStoreQuote {
98                key,
99                data_type,
100                data_size,
101                nonce,
102                difficulty,
103            } => {
104                write!(
105                    f,
106                    "Query::GetStoreQuote({key:?} {data_type} {data_size} {nonce:?} {difficulty})"
107                )
108            }
109            Query::GetReplicatedRecord { key, requester } => {
110                write!(f, "Query::GetReplicatedRecord({requester:?} {key:?})")
111            }
112            Query::GetChunkExistenceProof {
113                key,
114                nonce,
115                difficulty,
116            } => {
117                write!(
118                    f,
119                    "Query::GetChunkExistenceProof({key:?} {nonce:?} {difficulty})"
120                )
121            }
122            Query::CheckNodeInProblem(address) => {
123                write!(f, "Query::CheckNodeInProblem({address:?})")
124            }
125            Query::GetClosestPeers {
126                key,
127                num_of_peers,
128                range,
129                sign_result,
130            } => {
131                let distance = range.as_ref().map(|value| U256::from_big_endian(value));
132                write!(
133                    f,
134                    "Query::GetClosestPeers({key:?} {num_of_peers:?} {distance:?} {sign_result})"
135                )
136            }
137            Query::GetVersion(address) => {
138                write!(f, "Query::GetVersion({address:?})")
139            }
140        }
141    }
142}