Skip to main content

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}