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}