Skip to main content

iota_json_rpc_types/
object_changes.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::fmt::{Display, Formatter, Result};
6
7use iota_sdk_types::{ObjectId, Owner, StructTag};
8use iota_types::base_types::{IotaAddress, ObjectDigest, ObjectRef, SequenceNumber};
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11use serde_with::serde_as;
12
13use crate::{
14    iota_owner::OwnerSchema,
15    iota_primitives::{
16        Base58 as Base58Schema, IotaAddress as IotaAddressSchema, ObjectId as ObjectIdSchema,
17        SequenceNumberString as SequenceNumberStringSchema, StructTag as StructTagSchema,
18    },
19};
20
21/// ObjectChange are derived from the object mutations in the TransactionEffect
22/// to provide richer object information.
23#[serde_as]
24#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, PartialEq, Eq)]
25#[serde(rename_all = "camelCase", tag = "type")]
26pub enum ObjectChange {
27    /// Module published
28    #[serde(rename_all = "camelCase")]
29    Published {
30        #[serde_as(as = "ObjectIdSchema")]
31        #[schemars(with = "ObjectIdSchema")]
32        package_id: ObjectId,
33        #[schemars(with = "SequenceNumberStringSchema")]
34        #[serde_as(as = "SequenceNumberStringSchema")]
35        version: SequenceNumber,
36        #[serde_as(as = "Base58Schema")]
37        #[schemars(with = "Base58Schema")]
38        digest: ObjectDigest,
39        modules: Vec<String>,
40    },
41    /// Transfer objects to new address / wrap in another object
42    #[serde(rename_all = "camelCase")]
43    Transferred {
44        #[serde_as(as = "IotaAddressSchema")]
45        #[schemars(with = "IotaAddressSchema")]
46        sender: IotaAddress,
47        #[schemars(with = "OwnerSchema")]
48        #[serde_as(as = "OwnerSchema")]
49        recipient: Owner,
50        #[schemars(with = "StructTagSchema")]
51        #[serde_as(as = "StructTagSchema")]
52        object_type: StructTag,
53        #[serde_as(as = "ObjectIdSchema")]
54        #[schemars(with = "ObjectIdSchema")]
55        object_id: ObjectId,
56        #[schemars(with = "SequenceNumberStringSchema")]
57        #[serde_as(as = "SequenceNumberStringSchema")]
58        version: SequenceNumber,
59        #[serde_as(as = "Base58Schema")]
60        #[schemars(with = "Base58Schema")]
61        digest: ObjectDigest,
62    },
63    /// Object mutated.
64    #[serde(rename_all = "camelCase")]
65    Mutated {
66        #[serde_as(as = "IotaAddressSchema")]
67        #[schemars(with = "IotaAddressSchema")]
68        sender: IotaAddress,
69        #[schemars(with = "OwnerSchema")]
70        #[serde_as(as = "OwnerSchema")]
71        owner: Owner,
72        #[schemars(with = "StructTagSchema")]
73        #[serde_as(as = "StructTagSchema")]
74        object_type: StructTag,
75        #[serde_as(as = "ObjectIdSchema")]
76        #[schemars(with = "ObjectIdSchema")]
77        object_id: ObjectId,
78        #[schemars(with = "SequenceNumberStringSchema")]
79        #[serde_as(as = "SequenceNumberStringSchema")]
80        version: SequenceNumber,
81        #[schemars(with = "SequenceNumberStringSchema")]
82        #[serde_as(as = "SequenceNumberStringSchema")]
83        previous_version: SequenceNumber,
84        #[serde_as(as = "Base58Schema")]
85        #[schemars(with = "Base58Schema")]
86        digest: ObjectDigest,
87    },
88    /// Delete object
89    #[serde(rename_all = "camelCase")]
90    Deleted {
91        #[serde_as(as = "IotaAddressSchema")]
92        #[schemars(with = "IotaAddressSchema")]
93        sender: IotaAddress,
94        #[schemars(with = "StructTagSchema")]
95        #[serde_as(as = "StructTagSchema")]
96        object_type: StructTag,
97        #[serde_as(as = "ObjectIdSchema")]
98        #[schemars(with = "ObjectIdSchema")]
99        object_id: ObjectId,
100        #[schemars(with = "SequenceNumberStringSchema")]
101        #[serde_as(as = "SequenceNumberStringSchema")]
102        version: SequenceNumber,
103    },
104    /// Wrapped object
105    #[serde(rename_all = "camelCase")]
106    Wrapped {
107        #[serde_as(as = "IotaAddressSchema")]
108        #[schemars(with = "IotaAddressSchema")]
109        sender: IotaAddress,
110        #[schemars(with = "StructTagSchema")]
111        #[serde_as(as = "StructTagSchema")]
112        object_type: StructTag,
113        #[serde_as(as = "ObjectIdSchema")]
114        #[schemars(with = "ObjectIdSchema")]
115        object_id: ObjectId,
116        #[schemars(with = "SequenceNumberStringSchema")]
117        #[serde_as(as = "SequenceNumberStringSchema")]
118        version: SequenceNumber,
119    },
120    /// Unwrapped object
121    #[serde(rename_all = "camelCase")]
122    Unwrapped {
123        #[serde_as(as = "IotaAddressSchema")]
124        #[schemars(with = "IotaAddressSchema")]
125        sender: IotaAddress,
126        #[schemars(with = "OwnerSchema")]
127        #[serde_as(as = "OwnerSchema")]
128        owner: Owner,
129        #[schemars(with = "StructTagSchema")]
130        #[serde_as(as = "StructTagSchema")]
131        object_type: StructTag,
132        #[serde_as(as = "ObjectIdSchema")]
133        #[schemars(with = "ObjectIdSchema")]
134        object_id: ObjectId,
135        #[schemars(with = "SequenceNumberStringSchema")]
136        #[serde_as(as = "SequenceNumberStringSchema")]
137        version: SequenceNumber,
138        #[serde_as(as = "Base58Schema")]
139        #[schemars(with = "Base58Schema")]
140        digest: ObjectDigest,
141    },
142    /// New object creation
143    #[serde(rename_all = "camelCase")]
144    Created {
145        #[serde_as(as = "IotaAddressSchema")]
146        #[schemars(with = "IotaAddressSchema")]
147        sender: IotaAddress,
148        #[schemars(with = "OwnerSchema")]
149        #[serde_as(as = "OwnerSchema")]
150        owner: Owner,
151        #[schemars(with = "StructTagSchema")]
152        #[serde_as(as = "StructTagSchema")]
153        object_type: StructTag,
154        #[serde_as(as = "ObjectIdSchema")]
155        #[schemars(with = "ObjectIdSchema")]
156        object_id: ObjectId,
157        #[schemars(with = "SequenceNumberStringSchema")]
158        #[serde_as(as = "SequenceNumberStringSchema")]
159        version: SequenceNumber,
160        #[serde_as(as = "Base58Schema")]
161        #[schemars(with = "Base58Schema")]
162        digest: ObjectDigest,
163    },
164}
165
166impl ObjectChange {
167    pub fn object_id(&self) -> ObjectId {
168        match self {
169            ObjectChange::Published { package_id, .. } => *package_id,
170            ObjectChange::Transferred { object_id, .. }
171            | ObjectChange::Mutated { object_id, .. }
172            | ObjectChange::Deleted { object_id, .. }
173            | ObjectChange::Wrapped { object_id, .. }
174            | ObjectChange::Unwrapped { object_id, .. }
175            | ObjectChange::Created { object_id, .. } => *object_id,
176        }
177    }
178
179    pub fn object_ref(&self) -> ObjectRef {
180        match self {
181            ObjectChange::Published {
182                package_id,
183                version,
184                digest,
185                ..
186            } => ObjectRef::new(*package_id, *version, *digest),
187            ObjectChange::Transferred {
188                object_id,
189                version,
190                digest,
191                ..
192            }
193            | ObjectChange::Mutated {
194                object_id,
195                version,
196                digest,
197                ..
198            }
199            | ObjectChange::Unwrapped {
200                object_id,
201                version,
202                digest,
203                ..
204            }
205            | ObjectChange::Created {
206                object_id,
207                version,
208                digest,
209                ..
210            } => ObjectRef::new(*object_id, *version, *digest),
211            ObjectChange::Deleted {
212                object_id, version, ..
213            } => ObjectRef::new(*object_id, *version, ObjectDigest::OBJECT_DELETED),
214            ObjectChange::Wrapped {
215                object_id, version, ..
216            } => ObjectRef::new(*object_id, *version, ObjectDigest::OBJECT_WRAPPED),
217        }
218    }
219
220    pub fn mask_for_test(&mut self, new_version: SequenceNumber, new_digest: ObjectDigest) {
221        match self {
222            ObjectChange::Published {
223                version, digest, ..
224            }
225            | ObjectChange::Transferred {
226                version, digest, ..
227            }
228            | ObjectChange::Mutated {
229                version, digest, ..
230            }
231            | ObjectChange::Unwrapped {
232                version, digest, ..
233            }
234            | ObjectChange::Created {
235                version, digest, ..
236            } => {
237                *version = new_version;
238                *digest = new_digest
239            }
240            ObjectChange::Deleted { version, .. } | ObjectChange::Wrapped { version, .. } => {
241                *version = new_version
242            }
243        }
244    }
245}
246
247impl Display for ObjectChange {
248    fn fmt(&self, f: &mut Formatter) -> Result {
249        match self {
250            ObjectChange::Published {
251                package_id,
252                version,
253                digest,
254                modules,
255            } => {
256                write!(
257                    f,
258                    " ┌──\n │ PackageID: {} \n │ Version: {} \n │ Digest: {}\n │ Modules: {}\n └──",
259                    package_id,
260                    version,
261                    digest,
262                    modules.join(", ")
263                )
264            }
265            ObjectChange::Transferred {
266                sender,
267                recipient,
268                object_type,
269                object_id,
270                version,
271                digest,
272            } => {
273                write!(
274                    f,
275                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ Recipient: {recipient}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
276                )
277            }
278            ObjectChange::Mutated {
279                sender,
280                owner,
281                object_type,
282                object_id,
283                version,
284                previous_version: _,
285                digest,
286            } => {
287                write!(
288                    f,
289                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ Owner: {owner}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
290                )
291            }
292            ObjectChange::Deleted {
293                sender,
294                object_type,
295                object_id,
296                version,
297            } => {
298                write!(
299                    f,
300                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ ObjectType: {object_type} \n │ Version: {version}\n └──"
301                )
302            }
303            ObjectChange::Wrapped {
304                sender,
305                object_type,
306                object_id,
307                version,
308            } => {
309                write!(
310                    f,
311                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ ObjectType: {object_type} \n │ Version: {version}\n └──"
312                )
313            }
314            ObjectChange::Unwrapped {
315                sender,
316                owner,
317                object_type,
318                object_id,
319                version,
320                digest,
321            } => {
322                write!(
323                    f,
324                    " ┌──\n │ ObjectId: {}\n │ Sender: {} \n │ Owner: {}\n │ ObjectType: {} \n │ Version: {}\n │ Digest: {}\n └──",
325                    object_id,
326                    sender,
327                    owner,
328                    object_type,
329                    version.as_u64(),
330                    digest
331                )
332            }
333            ObjectChange::Created {
334                sender,
335                owner,
336                object_type,
337                object_id,
338                version,
339                digest,
340            } => {
341                write!(
342                    f,
343                    " ┌──\n │ ObjectId: {object_id}\n │ Sender: {sender} \n │ Owner: {owner}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
344                )
345            }
346        }
347    }
348}