sui_sdk_types/effects/
v2.rs

1use crate::digest::EffectsAuxiliaryDataDigest;
2use crate::execution_status::ExecutionStatus;
3use crate::object::Owner;
4use crate::object::Version;
5use crate::EpochId;
6use crate::GasCostSummary;
7use crate::ObjectDigest;
8use crate::ObjectId;
9use crate::TransactionDigest;
10use crate::TransactionEventsDigest;
11
12/// Version 2 of TransactionEffects
13///
14/// # BCS
15///
16/// The BCS serialized form for this type is defined by the following ABNF:
17///
18/// ```text
19/// effects-v2 = execution-status
20///              u64                                ; epoch
21///              gas-cost-summary
22///              digest                             ; transaction digest
23///              (option u32)                       ; gas object index
24///              (option digest)                    ; events digest
25///              (vector digest)                    ; list of transaction dependencies
26///              u64                                ; lamport version
27///              (vector changed-object)
28///              (vector unchanged-shared-object)
29///              (option digest)                    ; auxiliary data digest
30/// ```
31#[derive(Eq, PartialEq, Clone, Debug)]
32#[cfg_attr(
33    feature = "serde",
34    derive(serde_derive::Serialize, serde_derive::Deserialize)
35)]
36#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
37pub struct TransactionEffectsV2 {
38    /// The status of the execution
39    pub status: ExecutionStatus,
40
41    /// The epoch when this transaction was executed.
42    pub epoch: EpochId,
43
44    /// The gas used by this transaction
45    pub gas_used: GasCostSummary,
46
47    /// The transaction digest
48    pub transaction_digest: TransactionDigest,
49
50    /// The updated gas object reference, as an index into the `changed_objects` vector.
51    /// Having a dedicated field for convenient access.
52    /// System transaction that don't require gas will leave this as None.
53    pub gas_object_index: Option<u32>,
54
55    /// The digest of the events emitted during execution,
56    /// can be None if the transaction does not emit any event.
57    pub events_digest: Option<TransactionEventsDigest>,
58
59    /// The set of transaction digests this transaction depends on.
60    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=5).lift()))]
61    pub dependencies: Vec<TransactionDigest>,
62
63    /// The version number of all the written Move objects by this transaction.
64    pub lamport_version: Version,
65
66    /// Objects whose state are changed in the object store.
67    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
68    pub changed_objects: Vec<ChangedObject>,
69
70    /// Shared objects that are not mutated in this transaction. Unlike owned objects,
71    /// read-only shared objects' version are not committed in the transaction,
72    /// and in order for a node to catch up and execute it without consensus sequencing,
73    /// the version needs to be committed in the effects.
74    #[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
75    pub unchanged_shared_objects: Vec<UnchangedSharedObject>,
76
77    /// Auxiliary data that are not protocol-critical, generated as part of the effects but are stored separately.
78    /// Storing it separately allows us to avoid bloating the effects with data that are not critical.
79    /// It also provides more flexibility on the format and type of the data.
80    pub auxiliary_data_digest: Option<EffectsAuxiliaryDataDigest>,
81}
82
83/// Input/output state of an object that was changed during execution
84///
85/// # BCS
86///
87/// The BCS serialized form for this type is defined by the following ABNF:
88///
89/// ```text
90/// changed-object = object-id object-in object-out id-operation
91/// ```
92#[derive(Eq, PartialEq, Clone, Debug)]
93#[cfg_attr(
94    feature = "serde",
95    derive(serde_derive::Serialize, serde_derive::Deserialize)
96)]
97#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
98pub struct ChangedObject {
99    /// Id of the object
100    pub object_id: ObjectId,
101
102    /// State of the object in the store prior to this transaction.
103    pub input_state: ObjectIn,
104
105    /// State of the object in the store after this transaction.
106    pub output_state: ObjectOut,
107
108    /// Whether this object ID is created or deleted in this transaction.
109    /// This information isn't required by the protocol but is useful for providing more detailed
110    /// semantics on object changes.
111    pub id_operation: IdOperation,
112}
113
114/// A shared object that wasn't changed during execution
115///
116/// # BCS
117///
118/// The BCS serialized form for this type is defined by the following ABNF:
119///
120/// ```text
121/// unchanged-shared-object = object-id unchanged-shared-object-kind
122/// ```
123#[derive(Eq, PartialEq, Clone, Debug)]
124#[cfg_attr(
125    feature = "serde",
126    derive(serde_derive::Serialize, serde_derive::Deserialize)
127)]
128#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
129pub struct UnchangedSharedObject {
130    pub object_id: ObjectId,
131    pub kind: UnchangedSharedKind,
132}
133
134/// Type of unchanged shared object
135///
136/// # BCS
137///
138/// The BCS serialized form for this type is defined by the following ABNF:
139///
140/// ```text
141/// unchanged-shared-object-kind =  read-only-root
142///                              =/ mutate-deleted
143///                              =/ read-deleted
144///                              =/ canceled
145///                              =/ per-epoch-config
146///
147/// read-only-root                           = %x00 u64 digest
148/// mutate-deleted                           = %x01 u64
149/// read-deleted                             = %x02 u64
150/// canceled                                 = %x03 u64
151/// per-epoch-config                         = %x04
152/// per-epoch-config-with-sequence-number    = %x05 u64
153/// ```
154#[derive(Eq, PartialEq, Clone, Debug)]
155#[cfg_attr(
156    feature = "serde",
157    derive(serde_derive::Serialize, serde_derive::Deserialize)
158)]
159#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
160pub enum UnchangedSharedKind {
161    /// Read-only shared objects from the input. We don't really need ObjectDigest
162    /// for protocol correctness, but it will make it easier to verify untrusted read.
163    ReadOnlyRoot {
164        version: Version,
165        digest: ObjectDigest,
166    },
167
168    /// Deleted shared objects that appear mutably/owned in the input.
169    MutateDeleted { version: Version },
170
171    /// Deleted shared objects that appear as read-only in the input.
172    ReadDeleted { version: Version },
173
174    /// Shared objects in canceled transaction. The sequence number embed cancellation reason.
175    Canceled { version: Version },
176
177    /// Read of a per-epoch config object that should remain the same during an epoch.
178    /// NOTE: Will be deprecated in the near future in favor of `PerEpochConfigWithSequenceNumber`.
179    PerEpochConfig,
180
181    /// Read of a per-epoch config and it's starting sequence number in the epoch.
182    PerEpochConfigWithSequenceNumber { version: Version },
183}
184
185/// State of an object prior to execution
186///
187/// If an object exists (at root-level) in the store prior to this transaction,
188/// it should be Exist, otherwise it's NonExist, e.g. wrapped objects should be
189/// NonExist.
190///
191/// # BCS
192///
193/// The BCS serialized form for this type is defined by the following ABNF:
194///
195/// ```text
196/// object-in = object-in-not-exist / object-in-exist
197///
198/// object-in-not-exist = %x00
199/// object-in-exist     = %x01 u64 digest owner
200/// ```
201#[derive(Eq, PartialEq, Clone, Debug)]
202#[cfg_attr(
203    feature = "serde",
204    derive(serde_derive::Serialize, serde_derive::Deserialize)
205)]
206#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
207pub enum ObjectIn {
208    NotExist,
209
210    /// The old version, digest and owner.
211    Exist {
212        version: Version,
213        digest: ObjectDigest,
214        owner: Owner,
215    },
216}
217
218/// State of an object after execution
219///
220/// # BCS
221///
222/// The BCS serialized form for this type is defined by the following ABNF:
223///
224/// ```text
225/// object-out  =  object-out-not-exist
226///             =/ object-out-object-write
227///             =/ object-out-package-write
228///
229///
230/// object-out-not-exist        = %x00
231/// object-out-object-write     = %x01 digest owner
232/// object-out-package-write    = %x02 version digest
233/// ```
234#[derive(Eq, PartialEq, Clone, Debug)]
235#[cfg_attr(
236    feature = "serde",
237    derive(serde_derive::Serialize, serde_derive::Deserialize)
238)]
239#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
240pub enum ObjectOut {
241    /// Same definition as in ObjectIn.
242    NotExist,
243
244    /// Any written object, including all of mutated, created, unwrapped today.
245    ObjectWrite { digest: ObjectDigest, owner: Owner },
246
247    /// Packages writes need to be tracked separately with version because
248    /// we don't use lamport version for package publish and upgrades.
249    PackageWrite {
250        version: Version,
251        digest: ObjectDigest,
252    },
253}
254
255/// Defines what happened to an ObjectId during execution
256///
257/// # BCS
258///
259/// The BCS serialized form for this type is defined by the following ABNF:
260///
261/// ```text
262/// id-operation =  id-operation-none
263///              =/ id-operation-created
264///              =/ id-operation-deleted
265///
266/// id-operation-none       = %x00
267/// id-operation-created    = %x01
268/// id-operation-deleted    = %x02
269/// ```
270#[derive(Eq, PartialEq, Copy, Clone, Debug)]
271#[cfg_attr(
272    feature = "serde",
273    derive(serde_derive::Serialize, serde_derive::Deserialize)
274)]
275#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
276pub enum IdOperation {
277    None,
278    Created,
279    Deleted,
280}
281
282impl TransactionEffectsV2 {
283    /// The status of the execution
284    pub fn status(&self) -> &ExecutionStatus {
285        &self.status
286    }
287
288    /// The epoch when this transaction was executed.
289    pub fn epoch(&self) -> EpochId {
290        self.epoch
291    }
292
293    /// The gas used in this transaction.
294    pub fn gas_summary(&self) -> &GasCostSummary {
295        &self.gas_used
296    }
297}