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