sui_types/effects/
object_change.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    base_types::{SuiAddress, VersionDigest},
6    digests::{Digest, ObjectDigest},
7    object::{Object, Owner},
8};
9use move_core_types::language_storage::TypeTag;
10use serde::{Deserialize, Serialize};
11
12use super::IDOperation;
13
14#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
15pub struct EffectsObjectChange {
16    // input_state and output_state are the core fields that's required by
17    // the protocol as it tells how an object changes on-chain.
18    /// State of the object in the store prior to this transaction.
19    pub(crate) input_state: ObjectIn,
20    /// State of the object in the store after this transaction.
21    pub(crate) output_state: ObjectOut,
22
23    /// Whether this object ID is created or deleted in this transaction.
24    /// This information isn't required by the protocol but is useful for providing more detailed
25    /// semantics on object changes.
26    pub(crate) id_operation: IDOperation,
27}
28
29impl EffectsObjectChange {
30    pub fn new(
31        modified_at: Option<(VersionDigest, Owner)>,
32        written: Option<&Object>,
33        id_created: bool,
34        id_deleted: bool,
35    ) -> Self {
36        debug_assert!(
37            !id_created || !id_deleted,
38            "Object ID can't be created and deleted at the same time."
39        );
40        Self {
41            input_state: modified_at.map_or(ObjectIn::NotExist, ObjectIn::Exist),
42            output_state: written.map_or(ObjectOut::NotExist, |o| {
43                if o.is_package() {
44                    ObjectOut::PackageWrite((o.version(), o.digest()))
45                } else {
46                    ObjectOut::ObjectWrite((o.digest(), o.owner.clone()))
47                }
48            }),
49            id_operation: if id_created {
50                IDOperation::Created
51            } else if id_deleted {
52                IDOperation::Deleted
53            } else {
54                IDOperation::None
55            },
56        }
57    }
58
59    pub fn new_from_accumulator_write(write: AccumulatorWriteV1) -> Self {
60        Self {
61            input_state: ObjectIn::NotExist,
62            output_state: ObjectOut::AccumulatorWriteV1(write),
63            id_operation: IDOperation::None,
64        }
65    }
66}
67
68/// If an object exists (at root-level) in the store prior to this transaction,
69/// it should be Exist, otherwise it's NonExist, e.g. wrapped objects should be
70/// NotExist.
71#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
72pub enum ObjectIn {
73    NotExist,
74    /// The old version, digest and owner.
75    Exist((VersionDigest, Owner)),
76}
77
78#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
79pub enum AccumulatorOperation {
80    /// Merge the value into the accumulator.
81    Merge,
82    /// Split the value from the accumulator.
83    Split,
84}
85
86#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
87pub enum AccumulatorValue {
88    Integer(u64),
89    IntegerTuple(u64, u64),
90    EventDigest(u64 /* event index in the transaction */, Digest),
91}
92
93/// Accumulator objects are named by an address (can be an account address or a UID)
94/// and a type tag.
95#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
96pub struct AccumulatorAddress {
97    pub address: SuiAddress,
98    pub ty: TypeTag,
99}
100
101impl AccumulatorAddress {
102    pub fn new(address: SuiAddress, ty: TypeTag) -> Self {
103        Self { address, ty }
104    }
105}
106
107#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
108pub struct AccumulatorWriteV1 {
109    pub address: AccumulatorAddress,
110    /// The operation to be applied to the accumulator.
111    pub operation: AccumulatorOperation,
112    /// The value to be merged into or split from the accumulator.
113    pub value: AccumulatorValue,
114}
115
116#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
117pub enum ObjectOut {
118    /// Same definition as in ObjectIn.
119    NotExist,
120    /// Any written object, including all of mutated, created, unwrapped today.
121    ObjectWrite((ObjectDigest, Owner)),
122    /// Packages writes need to be tracked separately with version because
123    /// we don't use lamport version for package publish and upgrades.
124    PackageWrite(VersionDigest),
125    /// This isn't an object write, but a special write to an accumulator.
126    AccumulatorWriteV1(AccumulatorWriteV1),
127}