sui_types/
accumulator_metadata.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::{
5    MoveTypeTagTrait, MoveTypeTagTraitGeneric, SUI_ACCUMULATOR_ROOT_OBJECT_ID,
6    SUI_FRAMEWORK_ADDRESS, SUI_FRAMEWORK_PACKAGE_ID,
7    base_types::{SequenceNumber, SuiAddress},
8    collection_types::Bag,
9    dynamic_field::DynamicFieldKey,
10    error::SuiResult,
11    storage::ChildObjectResolver,
12};
13use move_core_types::{
14    ident_str,
15    identifier::IdentStr,
16    language_storage::{StructTag, TypeTag},
17};
18use serde::{Deserialize, Serialize};
19
20pub const ACCUMULATOR_METADATA_MODULE: &IdentStr = ident_str!("accumulator_metadata");
21const ACCUMULATOR_OWNER_KEY_TYPE: &IdentStr = ident_str!("OwnerKey");
22const ACCUMULATOR_OWNER_TYPE: &IdentStr = ident_str!("Owner");
23const ACCUMULATOR_METADATA_KEY_TYPE: &IdentStr = ident_str!("MetadataKey");
24
25#[derive(Serialize, Deserialize)]
26pub struct AccumulatorOwner {
27    balances: Bag,
28    owner: SuiAddress,
29}
30
31#[derive(Serialize, Deserialize, Debug, Default)]
32pub struct MetadataKey(u8);
33
34impl MoveTypeTagTraitGeneric for MetadataKey {
35    fn get_type_tag(type_params: &[TypeTag]) -> TypeTag {
36        TypeTag::Struct(Box::new(StructTag {
37            address: SUI_FRAMEWORK_PACKAGE_ID.into(),
38            module: ACCUMULATOR_METADATA_MODULE.to_owned(),
39            name: ACCUMULATOR_METADATA_KEY_TYPE.to_owned(),
40            type_params: type_params.to_vec(),
41        }))
42    }
43}
44
45#[derive(Serialize, Deserialize)]
46pub struct AccumulatorMetadata {
47    /// Any per-balance fields we wish to add in the future.
48    fields: Bag,
49}
50
51#[derive(Serialize, Deserialize, Debug)]
52pub struct OwnerKey {
53    owner: SuiAddress,
54}
55
56impl MoveTypeTagTrait for OwnerKey {
57    fn get_type_tag() -> TypeTag {
58        TypeTag::Struct(Box::new(StructTag {
59            address: SUI_FRAMEWORK_ADDRESS,
60            module: ACCUMULATOR_METADATA_MODULE.to_owned(),
61            name: ACCUMULATOR_OWNER_KEY_TYPE.to_owned(),
62            type_params: vec![],
63        }))
64    }
65}
66
67impl AccumulatorOwner {
68    pub fn type_() -> StructTag {
69        StructTag {
70            address: SUI_FRAMEWORK_ADDRESS,
71            module: ACCUMULATOR_METADATA_MODULE.to_owned(),
72            name: ACCUMULATOR_OWNER_TYPE.to_owned(),
73            type_params: vec![],
74        }
75    }
76
77    pub fn exists(
78        child_object_resolver: &dyn ChildObjectResolver,
79        version_bound: Option<SequenceNumber>,
80        owner: SuiAddress,
81    ) -> SuiResult<bool> {
82        let key = OwnerKey { owner };
83
84        DynamicFieldKey(
85            SUI_ACCUMULATOR_ROOT_OBJECT_ID,
86            key,
87            OwnerKey::get_type_tag(),
88        )
89        .into_id_with_bound(version_bound.unwrap_or(SequenceNumber::MAX))?
90        .exists(child_object_resolver)
91    }
92
93    pub fn load(
94        child_object_resolver: &dyn ChildObjectResolver,
95        root_version: Option<SequenceNumber>,
96        owner: SuiAddress,
97    ) -> SuiResult<Option<Self>> {
98        let key = OwnerKey { owner };
99        DynamicFieldKey(
100            SUI_ACCUMULATOR_ROOT_OBJECT_ID,
101            key,
102            OwnerKey::get_type_tag(),
103        )
104        .into_id_with_bound(root_version.unwrap_or(SequenceNumber::MAX))?
105        .load_object(child_object_resolver)?
106        .map(|o| o.load_value::<Self>())
107        .transpose()
108    }
109
110    pub fn metadata_exists(
111        &self,
112        child_object_resolver: &dyn ChildObjectResolver,
113        version_bound: Option<SequenceNumber>,
114        type_: &TypeTag,
115    ) -> SuiResult<bool> {
116        let key = MetadataKey::default();
117        DynamicFieldKey(
118            *self.balances.id.object_id(),
119            key,
120            MetadataKey::get_type_tag(std::slice::from_ref(type_)),
121        )
122        .into_id_with_bound(version_bound.unwrap_or(SequenceNumber::MAX))?
123        .exists(child_object_resolver)
124    }
125
126    pub fn load_metadata(
127        &self,
128        child_object_resolver: &dyn ChildObjectResolver,
129        version_bound: Option<SequenceNumber>,
130        type_: &TypeTag,
131    ) -> SuiResult<Option<AccumulatorMetadata>> {
132        let key = MetadataKey::default();
133        DynamicFieldKey(
134            *self.balances.id.object_id(),
135            key,
136            MetadataKey::get_type_tag(std::slice::from_ref(type_)),
137        )
138        .into_id_with_bound(version_bound.unwrap_or(SequenceNumber::MAX))?
139        .load_object(child_object_resolver)?
140        .map(|o| o.load_value::<AccumulatorMetadata>())
141        .transpose()
142    }
143}