iota_types/effects/
object_change.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use serde::{Deserialize, Serialize};
6
7use super::IDOperation;
8use crate::{
9    base_types::VersionDigest,
10    digests::ObjectDigest,
11    object::{Object, Owner},
12};
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
25    /// providing more detailed 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))
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
60/// If an object exists (at root-level) in the store prior to this transaction,
61/// it should be Exist, otherwise it's NonExist, e.g. wrapped objects should be
62/// NonExist.
63#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
64pub enum ObjectIn {
65    NotExist,
66    /// The old version, digest and owner.
67    Exist((VersionDigest, Owner)),
68}
69
70#[derive(Eq, PartialEq, Clone, Debug, Serialize, Deserialize)]
71pub enum ObjectOut {
72    /// Same definition as in ObjectIn.
73    NotExist,
74    /// Any written object, including all of mutated, created, unwrapped today.
75    ObjectWrite((ObjectDigest, Owner)),
76    /// Packages writes need to be tracked separately with version because
77    /// we don't use lamport version for package publish and upgrades.
78    PackageWrite(VersionDigest),
79}