iota_types/
messages_grpc.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use move_core_types::annotated_value::MoveStructLayout;
6use serde::{Deserialize, Serialize};
7
8use crate::{
9    base_types::{ObjectID, SequenceNumber, TransactionDigest},
10    crypto::{AuthoritySignInfo, AuthorityStrongQuorumSignInfo},
11    effects::{SignedTransactionEffects, TransactionEvents, VerifiedSignedTransactionEffects},
12    messages_consensus::SignedAuthorityCapabilitiesV1,
13    object::Object,
14    transaction::{CertifiedTransaction, SenderSignedData, SignedTransaction},
15};
16
17#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
18pub enum ObjectInfoRequestKind {
19    /// Request the latest object state.
20    LatestObjectInfo,
21    /// Request a specific version of the object.
22    /// This is used only for debugging purpose and will not work as a generic
23    /// solution since we don't keep around all historic object versions.
24    /// No production code should depend on this kind.
25    PastObjectInfoDebug(SequenceNumber),
26}
27
28/// Layout generation options -- you can either generate or not generate the
29/// layout.
30#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
31pub enum LayoutGenerationOption {
32    Generate,
33    None,
34}
35
36/// A request for information about an object and optionally its
37/// parent certificate at a specific version.
38#[derive(Debug, PartialEq, Eq, Hash, Clone, Serialize, Deserialize)]
39pub struct ObjectInfoRequest {
40    /// The id of the object to retrieve, at the latest version.
41    pub object_id: ObjectID,
42    /// if true return the layout of the object.
43    pub generate_layout: LayoutGenerationOption,
44    /// The type of request, either latest object info or the past.
45    pub request_kind: ObjectInfoRequestKind,
46}
47
48impl ObjectInfoRequest {
49    pub fn past_object_info_debug_request(
50        object_id: ObjectID,
51        version: SequenceNumber,
52        generate_layout: LayoutGenerationOption,
53    ) -> Self {
54        ObjectInfoRequest {
55            object_id,
56            generate_layout,
57            request_kind: ObjectInfoRequestKind::PastObjectInfoDebug(version),
58        }
59    }
60
61    pub fn latest_object_info_request(
62        object_id: ObjectID,
63        generate_layout: LayoutGenerationOption,
64    ) -> Self {
65        ObjectInfoRequest {
66            object_id,
67            generate_layout,
68            request_kind: ObjectInfoRequestKind::LatestObjectInfo,
69        }
70    }
71}
72
73/// This message provides information about the latest object and its lock.
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct ObjectInfoResponse {
76    /// Value of the requested object in this authority
77    pub object: Object,
78    /// Schema of the Move value inside this object.
79    /// None if the object is a Move package, or the request did not ask for the
80    /// layout
81    pub layout: Option<MoveStructLayout>,
82    /// Transaction the object is locked on in this authority.
83    /// None if the object is not currently locked by this authority.
84    /// This should be only used for debugging purpose, such as from iota-tool.
85    /// No prod clients should rely on it.
86    pub lock_for_debugging: Option<SignedTransaction>,
87}
88
89/// Verified version of `ObjectInfoResponse`. `layout` and `lock_for_debugging`
90/// are skipped because they are not needed and we don't want to verify them.
91#[derive(Debug, Clone)]
92pub struct VerifiedObjectInfoResponse {
93    /// Value of the requested object in this authority
94    pub object: Object,
95}
96
97#[derive(Clone, Debug, Serialize, Deserialize)]
98pub struct TransactionInfoRequest {
99    pub transaction_digest: TransactionDigest,
100}
101
102#[expect(clippy::large_enum_variant)]
103#[derive(Clone, Debug, Serialize, Deserialize)]
104pub enum TransactionStatus {
105    /// Signature over the transaction.
106    Signed(AuthoritySignInfo),
107    /// For executed transaction, we could return an optional certificate
108    /// signature on the transaction (i.e. the signature part of the
109    /// CertifiedTransaction), as well as the signed effects.
110    /// The certificate signature is optional because for transactions executed
111    /// in previous epochs, we won't keep around the certificate signatures.
112    Executed(
113        Option<AuthorityStrongQuorumSignInfo>,
114        SignedTransactionEffects,
115        TransactionEvents,
116    ),
117}
118
119impl TransactionStatus {
120    pub fn into_signed_for_testing(self) -> AuthoritySignInfo {
121        match self {
122            Self::Signed(s) => s,
123            _ => unreachable!("Incorrect response type"),
124        }
125    }
126
127    pub fn into_effects_for_testing(self) -> SignedTransactionEffects {
128        match self {
129            Self::Executed(_, e, _) => e,
130            _ => unreachable!("Incorrect response type"),
131        }
132    }
133}
134
135impl PartialEq for TransactionStatus {
136    fn eq(&self, other: &Self) -> bool {
137        match self {
138            Self::Signed(s1) => match other {
139                Self::Signed(s2) => s1.epoch == s2.epoch,
140                _ => false,
141            },
142            Self::Executed(c1, e1, ev1) => match other {
143                Self::Executed(c2, e2, ev2) => {
144                    c1.as_ref().map(|a| a.epoch) == c2.as_ref().map(|a| a.epoch)
145                        && e1.epoch() == e2.epoch()
146                        && e1.digest() == e2.digest()
147                        && ev1.digest() == ev2.digest()
148                }
149                _ => false,
150            },
151        }
152    }
153}
154
155#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
156pub struct HandleTransactionResponse {
157    pub status: TransactionStatus,
158}
159
160#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
161pub struct TransactionInfoResponse {
162    pub transaction: SenderSignedData,
163    pub status: TransactionStatus,
164}
165
166#[derive(Clone, Debug, Serialize, Deserialize)]
167pub struct SubmitCertificateResponse {
168    /// If transaction is already executed, return same result as
169    /// handle_certificate
170    pub executed: Option<HandleCertificateResponseV1>,
171}
172
173#[derive(Clone, Debug)]
174pub struct VerifiedHandleCertificateResponse {
175    pub signed_effects: VerifiedSignedTransactionEffects,
176    pub events: TransactionEvents,
177}
178
179#[derive(Serialize, Deserialize, Clone, Debug)]
180pub struct SystemStateRequest {
181    // This is needed to make gRPC happy.
182    pub _unused: bool,
183}
184
185/// Response type for version 1 of the handle certificate validator API.
186///
187/// The corresponding version 1 request type allows for a client to request
188/// events as well as input/output objects from a transaction's execution. Given
189/// Validators operate with very aggressive object pruning, the return of
190/// input/output objects is only done immediately after the transaction has been
191/// executed locally on the validator and will not be returned for requests to
192/// previously executed transactions.
193#[derive(Clone, Debug, Serialize, Deserialize)]
194pub struct HandleCertificateResponseV1 {
195    pub signed_effects: SignedTransactionEffects,
196    pub events: Option<TransactionEvents>,
197
198    /// If requested, will include all initial versions of objects modified in
199    /// this transaction. This includes owned objects included as input into
200    /// the transaction as well as the assigned versions of shared objects.
201    // TODO: In the future we may want to include shared objects or child objects which were read
202    //  but not modified during execution.
203    pub input_objects: Option<Vec<Object>>,
204
205    /// If requested, will include all changed objects, including mutated,
206    /// created and unwrapped objects. In other words, all objects that
207    /// still exist in the object state after this transaction.
208    pub output_objects: Option<Vec<Object>>,
209    pub auxiliary_data: Option<Vec<u8>>,
210}
211
212#[derive(Clone, Debug, Serialize, Deserialize)]
213pub struct HandleCertificateRequestV1 {
214    pub certificate: CertifiedTransaction,
215
216    pub include_events: bool,
217    pub include_input_objects: bool,
218    pub include_output_objects: bool,
219    pub include_auxiliary_data: bool,
220}
221
222impl HandleCertificateRequestV1 {
223    pub fn new(certificate: CertifiedTransaction) -> Self {
224        Self {
225            certificate,
226            include_events: false,
227            include_input_objects: false,
228            include_output_objects: false,
229            include_auxiliary_data: false,
230        }
231    }
232
233    pub fn with_events(mut self) -> Self {
234        self.include_events = true;
235        self
236    }
237
238    pub fn with_input_objects(mut self) -> Self {
239        self.include_input_objects = true;
240        self
241    }
242
243    pub fn with_output_objects(mut self) -> Self {
244        self.include_output_objects = true;
245        self
246    }
247
248    pub fn with_auxiliary_data(mut self) -> Self {
249        self.include_auxiliary_data = true;
250        self
251    }
252}
253
254/// Response type for the handle Soft Bundle certificates validator API.
255/// If `wait_for_effects` is true, it is guaranteed that:
256///  - Number of responses will be equal to the number of input transactions.
257///  - The order of the responses matches the order of the input transactions.
258///
259/// Otherwise, `responses` will be empty.
260#[derive(Clone, Debug, Serialize, Deserialize)]
261pub struct HandleSoftBundleCertificatesResponseV1 {
262    pub responses: Vec<HandleCertificateResponseV1>,
263}
264
265/// Soft Bundle request.  See [SIP-19](https://github.com/sui-foundation/sips/blob/main/sips/sip-19.md).
266#[derive(Clone, Debug, Serialize, Deserialize)]
267pub struct HandleSoftBundleCertificatesRequestV1 {
268    pub certificates: Vec<CertifiedTransaction>,
269
270    pub wait_for_effects: bool,
271    pub include_events: bool,
272    pub include_input_objects: bool,
273    pub include_output_objects: bool,
274    pub include_auxiliary_data: bool,
275}
276
277#[derive(Clone, Debug, Serialize, Deserialize)]
278pub struct HandleCapabilityNotificationRequestV1 {
279    pub message: SignedAuthorityCapabilitiesV1,
280}
281
282#[derive(Clone, Debug, Serialize, Deserialize)]
283pub struct HandleCapabilityNotificationResponseV1 {
284    // This is needed to make gRPC happy.
285    pub _unused: bool,
286}