sui_json_rpc/
object_changes.rs1use std::collections::BTreeMap;
5
6use sui_json_rpc_types::ObjectChange;
7use sui_types::base_types::{ObjectID, ObjectRef, SequenceNumber, SuiAddress};
8use sui_types::effects::ObjectRemoveKind;
9use sui_types::effects::{TransactionEffects, TransactionEffectsAPI};
10use sui_types::object::Owner;
11use sui_types::storage::WriteKind;
12use tracing::instrument;
13
14use crate::ObjectProvider;
15
16#[instrument(skip_all, fields(transaction_digest = %effects.transaction_digest()))]
17pub async fn get_object_changes<P: ObjectProvider<Error = E>, E>(
18 object_provider: &P,
19 effects: &TransactionEffects,
20 sender: SuiAddress,
21 modified_at_versions: Vec<(ObjectID, SequenceNumber)>,
22 all_changed_objects: Vec<(ObjectRef, Owner, WriteKind)>,
23 all_removed_objects: Vec<(ObjectRef, ObjectRemoveKind)>,
24) -> Result<Vec<ObjectChange>, E> {
25 let mut object_changes = vec![];
26
27 let modify_at_version = modified_at_versions.into_iter().collect::<BTreeMap<_, _>>();
28
29 for ((object_id, version, digest), owner, kind) in all_changed_objects {
30 let o = object_provider.get_object(&object_id, &version).await?;
31 if let Some(type_) = o.type_() {
32 let object_type = type_.clone().into();
33
34 match kind {
35 WriteKind::Mutate => object_changes.push(ObjectChange::Mutated {
36 sender,
37 owner,
38 object_type,
39 object_id,
40 version,
41 previous_version: modify_at_version
43 .get(&object_id)
44 .cloned()
45 .unwrap_or_default(),
46 digest,
47 }),
48 WriteKind::Create => object_changes.push(ObjectChange::Created {
49 sender,
50 owner,
51 object_type,
52 object_id,
53 version,
54 digest,
55 }),
56 _ => {}
57 }
58 } else if let Some(p) = o.data.try_as_package()
59 && kind == WriteKind::Create
60 {
61 object_changes.push(ObjectChange::Published {
62 package_id: p.id(),
63 version: p.version(),
64 digest,
65 modules: p.serialized_module_map().keys().cloned().collect(),
66 })
67 };
68 }
69
70 for ((id, version, _), kind) in all_removed_objects {
71 let o = object_provider
72 .find_object_lt_or_eq_version(&id, &version)
73 .await?;
74 if let Some(o) = o
75 && let Some(type_) = o.type_()
76 {
77 let object_type = type_.clone().into();
78 match kind {
79 ObjectRemoveKind::Delete => object_changes.push(ObjectChange::Deleted {
80 sender,
81 object_type,
82 object_id: id,
83 version,
84 }),
85 ObjectRemoveKind::Wrap => object_changes.push(ObjectChange::Wrapped {
86 sender,
87 object_type,
88 object_id: id,
89 version,
90 }),
91 }
92 };
93 }
94
95 Ok(object_changes)
96}