sui_sdk_types/effects/
v2.rs

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