ant_protocol/messages/response.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::{NetworkAddress, error::Result};
10
11use super::ChunkProof;
12use ant_evm::PaymentQuote;
13use bytes::Bytes;
14use core::fmt;
15use libp2p::Multiaddr;
16use serde::{Deserialize, Serialize};
17use std::fmt::Debug;
18
19/// The response to a query, containing the query result.
20#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
21pub enum QueryResponse {
22 // ===== GetStoreQuote =====
23 //
24 /// Response to [`GetStoreQuote`]
25 ///
26 /// [`GetStoreQuote`]: crate::messages::Query::GetStoreQuote
27 GetStoreQuote {
28 /// The store cost quote for storing the next record.
29 quote: Result<PaymentQuote>,
30 /// Node's Peer Address
31 peer_address: NetworkAddress,
32 /// Storage proofs based on requested target address and difficulty
33 storage_proofs: Vec<(NetworkAddress, Result<ChunkProof>)>,
34 },
35 CheckNodeInProblem {
36 /// Address of the peer that queried
37 reporter_address: NetworkAddress,
38 /// Address of the target to be queried
39 target_address: NetworkAddress,
40 /// Status flag indicating whether the target is in trouble
41 is_in_trouble: bool,
42 },
43 // ===== ReplicatedRecord =====
44 //
45 /// Response to [`GetReplicatedRecord`]
46 ///
47 /// [`GetReplicatedRecord`]: crate::messages::Query::GetReplicatedRecord
48 GetReplicatedRecord(Result<(NetworkAddress, Bytes)>),
49 // ===== ChunkExistenceProof =====
50 //
51 /// Response to [`GetChunkExistenceProof`]
52 ///
53 /// [`GetChunkExistenceProof`]: crate::messages::Query::GetChunkExistenceProof
54 GetChunkExistenceProof(Vec<(NetworkAddress, Result<ChunkProof>)>),
55 // ===== GetClosestPeers =====
56 //
57 /// Response to [`GetClosestPeers`]
58 ///
59 /// [`GetClosestPeers`]: crate::messages::Query::GetClosestPeers
60 GetClosestPeers {
61 // The target address that the original request is about.
62 target: NetworkAddress,
63 // `Multiaddr` is required to allow the requester to dial the peer
64 // Note: the list doesn't contain the node that being queried.
65 peers: Vec<(NetworkAddress, Vec<Multiaddr>)>,
66 // Signature of signing the above (if requested), for future economic model usage.
67 signature: Option<Vec<u8>>,
68 },
69 /// *** From now on, the order of variants shall be retained to be backward compatible
70 // ===== GetVersion =====
71 //
72 /// Response to [`GetVersion`]
73 ///
74 /// [`GetVersion`]: crate::messages::Query::GetVersion
75 GetVersion {
76 peer: NetworkAddress,
77 version: String,
78 },
79 /// Response to [`PutRecord`]
80 ///
81 /// [`PutRecord`]: crate::messages::Query::PutRecord
82 PutRecord {
83 /// Result of record upload.
84 result: Result<()>,
85 /// Node's Peer Address
86 peer_address: NetworkAddress,
87 /// Correspondent Record Address
88 record_addr: NetworkAddress,
89 },
90 /// Response to [`GetMerkleCandidateQuote`]
91 ///
92 /// Node's signed commitment containing:
93 /// - pub_key (can derive PeerId)
94 /// - quoting_metrics (current node state)
95 /// - reward_address (where to send payment)
96 /// - merkle_payment_timestamp (binds signature to time)
97 /// - signature (proves pub_key owns reward_address)
98 ///
99 /// [`GetMerkleCandidateQuote`]: crate::messages::Query::GetMerkleCandidateQuote
100 GetMerkleCandidateQuote(Result<ant_evm::merkle_payments::MerklePaymentCandidateNode>),
101 // ===== DevGetClosestPeersFromNetwork =====
102 //
103 /// Response to [`DevGetClosestPeersFromNetwork`]
104 /// Returns closest peers from a network query (not just local routing table).
105 /// Only available when the `developer` feature is enabled.
106 ///
107 /// [`DevGetClosestPeersFromNetwork`]: crate::messages::Query::DevGetClosestPeersFromNetwork
108 #[cfg(feature = "developer")]
109 DevGetClosestPeersFromNetwork {
110 /// The target address that the original request is about.
111 target: NetworkAddress,
112 /// The node that performed the query (the queried node's peer address)
113 queried_node: NetworkAddress,
114 /// Closest peers from the network query, with their multiaddresses.
115 peers: Vec<(NetworkAddress, Vec<Multiaddr>)>,
116 },
117}
118
119// Debug implementation for QueryResponse, to avoid printing Vec<u8>
120impl Debug for QueryResponse {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 match self {
123 QueryResponse::GetStoreQuote {
124 quote,
125 peer_address,
126 storage_proofs,
127 } => {
128 let payment_address = quote.as_ref().map(|q| q.rewards_address).ok();
129 write!(
130 f,
131 "GetStoreQuote(quote: {quote:?}, from {peer_address:?} w/ payment_address: {payment_address:?}, and {} storage proofs)",
132 storage_proofs.len()
133 )
134 }
135 QueryResponse::CheckNodeInProblem {
136 reporter_address,
137 target_address,
138 is_in_trouble,
139 } => {
140 write!(
141 f,
142 "CheckNodeInProblem({reporter_address:?} report target {target_address:?} as {is_in_trouble:?} in problem"
143 )
144 }
145 QueryResponse::GetReplicatedRecord(result) => match result {
146 Ok((holder, data)) => {
147 write!(
148 f,
149 "GetReplicatedRecord(Ok((holder: {:?}, datalen: {:?})))",
150 holder,
151 data.len()
152 )
153 }
154 Err(err) => {
155 write!(f, "GetReplicatedRecord(Err({err:?}))")
156 }
157 },
158 QueryResponse::GetChunkExistenceProof(proofs) => {
159 let addresses: Vec<_> = proofs.iter().map(|(addr, _)| addr.clone()).collect();
160 write!(f, "GetChunkExistenceProof(checked chunks: {addresses:?})")
161 }
162 QueryResponse::GetClosestPeers { target, peers, .. } => {
163 let addresses: Vec<_> = peers.iter().map(|(addr, _)| addr.clone()).collect();
164 write!(
165 f,
166 "GetClosestPeers target {target:?} close peers {addresses:?}"
167 )
168 }
169 QueryResponse::GetVersion { peer, version } => {
170 write!(f, "GetVersion peer {peer:?} has version of {version:?}")
171 }
172 QueryResponse::PutRecord {
173 result,
174 peer_address,
175 record_addr,
176 } => {
177 write!(
178 f,
179 "PutRecord(Record {record_addr:?} uploaded to {peer_address:?} with result {result:?})",
180 )
181 }
182 QueryResponse::GetMerkleCandidateQuote(result) => match result {
183 Ok(candidate) => {
184 write!(
185 f,
186 "GetMerkleCandidateQuote(Ok(reward_address: {:?}, timestamp: {}))",
187 candidate.reward_address, candidate.merkle_payment_timestamp
188 )
189 }
190 Err(err) => {
191 write!(f, "GetMerkleCandidateQuote(Err({err:?}))")
192 }
193 },
194 #[cfg(feature = "developer")]
195 QueryResponse::DevGetClosestPeersFromNetwork {
196 target,
197 queried_node,
198 peers,
199 } => {
200 let addresses: Vec<_> = peers.iter().map(|(addr, _)| addr.clone()).collect();
201 write!(
202 f,
203 "DevGetClosestPeersFromNetwork target {target:?} from {queried_node:?} found {} close peers {addresses:?}",
204 peers.len()
205 )
206 }
207 }
208 }
209}
210
211/// The response to a Cmd, containing the query result.
212#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
213pub enum CmdResponse {
214 //
215 // ===== Replication =====
216 //
217 /// Response to replication cmd
218 Replicate(Result<()>),
219 /// Response to fresh replication cmd
220 FreshReplicate(Result<()>),
221 //
222 // ===== PeerConsideredAsBad =====
223 //
224 /// Response to the considered as bad notification
225 PeerConsideredAsBad(Result<()>),
226}