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))]
157pub enum UnchangedConsensusKind {
158    /// Read-only consensus objects from the input. We don't really need ObjectDigest
159    /// for protocol correctness, but it will make it easier to verify untrusted read.
160    ReadOnlyRoot { version: Version, digest: Digest },
161
162    /// Deleted consensus objects that appear mutably/owned in the input.
163    MutateDeleted { version: Version },
164
165    /// Deleted consensus objects that appear as read-only in the input.
166    ReadDeleted { version: Version },
167
168    /// Consensus objects in canceled transaction. The sequence number embed cancellation reason.
169    Canceled { version: Version },
170
171    /// Read of a per-epoch config object that should remain the same during an epoch.
172    /// NOTE: Will be deprecated in the near future in favor of `PerEpochConfigWithSequenceNumber`.
173    PerEpochConfig,
174
175    /// Read of a per-epoch config and it's starting sequence number in the epoch.
176    PerEpochConfigWithSequenceNumber { version: Version },
177}
178
179/// State of an object prior to execution
180///
181/// If an object exists (at root-level) in the store prior to this transaction,
182/// it should be Exist, otherwise it's NonExist, e.g. wrapped objects should be
183/// NonExist.
184///
185/// # BCS
186///
187/// The BCS serialized form for this type is defined by the following ABNF:
188///
189/// ```text
190/// object-in = object-in-not-exist / object-in-exist
191///
192/// object-in-not-exist = %x00
193/// object-in-exist     = %x01 u64 digest owner
194/// ```
195#[derive(Eq, PartialEq, Clone, Debug)]
196#[cfg_attr(
197    feature = "serde",
198    derive(serde_derive::Serialize, serde_derive::Deserialize)
199)]
200#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
201pub enum ObjectIn {
202    NotExist,
203
204    /// The old version, digest and owner.
205    Exist {
206        version: Version,
207        digest: Digest,
208        owner: Owner,
209    },
210}
211
212/// State of an object after execution
213///
214/// # BCS
215///
216/// The BCS serialized form for this type is defined by the following ABNF:
217///
218/// ```text
219/// object-out  =  object-out-not-exist
220///             =/ object-out-object-write
221///             =/ object-out-package-write
222///
223///
224/// object-out-not-exist        = %x00
225/// object-out-object-write     = %x01 digest owner
226/// object-out-package-write    = %x02 version digest
227/// ```
228#[derive(Eq, PartialEq, Clone, Debug)]
229#[cfg_attr(
230    feature = "serde",
231    derive(serde_derive::Serialize, serde_derive::Deserialize)
232)]
233#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
234pub enum ObjectOut {
235    /// Same definition as in ObjectIn.
236    NotExist,
237
238    /// Any written object, including all of mutated, created, unwrapped today.
239    ObjectWrite { digest: Digest, owner: Owner },
240
241    /// Packages writes need to be tracked separately with version because
242    /// we don't use lamport version for package publish and upgrades.
243    PackageWrite { version: Version, digest: Digest },
244}
245
246/// Defines what happened to an ObjectId during execution
247///
248/// # BCS
249///
250/// The BCS serialized form for this type is defined by the following ABNF:
251///
252/// ```text
253/// id-operation =  id-operation-none
254///              =/ id-operation-created
255///              =/ id-operation-deleted
256///
257/// id-operation-none       = %x00
258/// id-operation-created    = %x01
259/// id-operation-deleted    = %x02
260/// ```
261#[derive(Eq, PartialEq, Copy, Clone, Debug)]
262#[cfg_attr(
263    feature = "serde",
264    derive(serde_derive::Serialize, serde_derive::Deserialize)
265)]
266#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
267pub enum IdOperation {
268    None,
269    Created,
270    Deleted,
271}
272
273impl TransactionEffectsV2 {
274    /// The status of the execution
275    pub fn status(&self) -> &ExecutionStatus {
276        &self.status
277    }
278
279    /// The epoch when this transaction was executed.
280    pub fn epoch(&self) -> EpochId {
281        self.epoch
282    }
283
284    /// The gas used in this transaction.
285    pub fn gas_summary(&self) -> &GasCostSummary {
286        &self.gas_used
287    }
288}