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