sui_types/
accumulator_metadata.rs1use crate::{
5 MoveTypeTagTrait, MoveTypeTagTraitGeneric, SUI_ACCUMULATOR_ROOT_OBJECT_ID,
6 SUI_FRAMEWORK_ADDRESS, SUI_FRAMEWORK_PACKAGE_ID,
7 base_types::{ObjectID, SequenceNumber, SuiAddress},
8 collection_types::Bag,
9 dynamic_field::{DynamicFieldKey, DynamicFieldObject},
10 error::SuiResult,
11 object::Object,
12 storage::ChildObjectResolver,
13};
14use move_core_types::{
15 ident_str,
16 identifier::IdentStr,
17 language_storage::{StructTag, TypeTag},
18};
19use serde::{Deserialize, Serialize};
20
21pub const ACCUMULATOR_METADATA_MODULE: &IdentStr = ident_str!("accumulator_metadata");
22pub const ACCUMULATOR_OWNER_KEY_TYPE: &IdentStr = ident_str!("OwnerKey");
23pub const ACCUMULATOR_OWNER_TYPE: &IdentStr = ident_str!("Owner");
24pub const ACCUMULATOR_METADATA_KEY_TYPE: &IdentStr = ident_str!("MetadataKey");
25pub const ACCUMULATOR_METADATA_TYPE: &IdentStr = ident_str!("Metadata");
26
27#[derive(Serialize, Deserialize)]
28pub struct AccumulatorOwner {
29 pub balances: Bag,
30 pub owner: SuiAddress,
31}
32
33impl MoveTypeTagTrait for AccumulatorOwner {
34 fn get_type_tag() -> TypeTag {
35 TypeTag::Struct(Box::new(StructTag {
36 address: SUI_FRAMEWORK_ADDRESS,
37 module: ACCUMULATOR_METADATA_MODULE.to_owned(),
38 name: ACCUMULATOR_OWNER_TYPE.to_owned(),
39 type_params: vec![],
40 }))
41 }
42}
43
44#[derive(Serialize, Deserialize, Debug, Default)]
45pub struct MetadataKey(u8);
46
47impl MoveTypeTagTraitGeneric for MetadataKey {
48 fn get_type_tag(type_params: &[TypeTag]) -> TypeTag {
49 TypeTag::Struct(Box::new(StructTag {
50 address: SUI_FRAMEWORK_PACKAGE_ID.into(),
51 module: ACCUMULATOR_METADATA_MODULE.to_owned(),
52 name: ACCUMULATOR_METADATA_KEY_TYPE.to_owned(),
53 type_params: type_params.to_vec(),
54 }))
55 }
56}
57
58#[derive(Serialize, Deserialize)]
59pub struct AccumulatorMetadata {
60 fields: Bag,
62}
63
64impl MoveTypeTagTraitGeneric for AccumulatorMetadata {
65 fn get_type_tag(type_params: &[TypeTag]) -> TypeTag {
66 TypeTag::Struct(Box::new(StructTag {
67 address: SUI_FRAMEWORK_ADDRESS,
68 module: ACCUMULATOR_METADATA_MODULE.to_owned(),
69 name: ACCUMULATOR_METADATA_TYPE.to_owned(),
70 type_params: type_params.to_vec(),
71 }))
72 }
73}
74
75#[derive(Serialize, Deserialize, Debug)]
76pub struct OwnerKey {
77 owner: SuiAddress,
78}
79
80impl MoveTypeTagTrait for OwnerKey {
81 fn get_type_tag() -> TypeTag {
82 TypeTag::Struct(Box::new(StructTag {
83 address: SUI_FRAMEWORK_ADDRESS,
84 module: ACCUMULATOR_METADATA_MODULE.to_owned(),
85 name: ACCUMULATOR_OWNER_KEY_TYPE.to_owned(),
86 type_params: vec![],
87 }))
88 }
89}
90
91impl AccumulatorOwner {
92 pub fn type_() -> StructTag {
93 StructTag {
94 address: SUI_FRAMEWORK_ADDRESS,
95 module: ACCUMULATOR_METADATA_MODULE.to_owned(),
96 name: ACCUMULATOR_OWNER_TYPE.to_owned(),
97 type_params: vec![],
98 }
99 }
100
101 pub fn get_object_id(owner: SuiAddress) -> SuiResult<ObjectID> {
102 let key = OwnerKey { owner };
103 DynamicFieldKey(
104 SUI_ACCUMULATOR_ROOT_OBJECT_ID,
105 key,
106 OwnerKey::get_type_tag(),
107 )
108 .object_id()
109 }
110
111 pub fn exists(
112 child_object_resolver: &dyn ChildObjectResolver,
113 version_bound: Option<SequenceNumber>,
114 owner: SuiAddress,
115 ) -> SuiResult<bool> {
116 let key = OwnerKey { owner };
117
118 DynamicFieldKey(
119 SUI_ACCUMULATOR_ROOT_OBJECT_ID,
120 key,
121 OwnerKey::get_type_tag(),
122 )
123 .into_id_with_bound(version_bound.unwrap_or(SequenceNumber::MAX))?
124 .exists(child_object_resolver)
125 }
126
127 pub fn load_object(
128 child_object_resolver: &dyn ChildObjectResolver,
129 root_version: Option<SequenceNumber>,
130 owner: SuiAddress,
131 ) -> SuiResult<Option<Object>> {
132 let key = OwnerKey { owner };
133 Ok(DynamicFieldKey(
134 SUI_ACCUMULATOR_ROOT_OBJECT_ID,
135 key,
136 OwnerKey::get_type_tag(),
137 )
138 .into_id_with_bound(root_version.unwrap_or(SequenceNumber::MAX))?
139 .load_object(child_object_resolver)?
140 .map(|o| o.into_object()))
141 }
142
143 pub fn from_object(object: Object) -> SuiResult<Self> {
144 DynamicFieldObject::<OwnerKey>::new(object).load_value::<Self>()
145 }
146
147 pub fn load(
148 child_object_resolver: &dyn ChildObjectResolver,
149 root_version: Option<SequenceNumber>,
150 owner: SuiAddress,
151 ) -> SuiResult<Option<Self>> {
152 let key = OwnerKey { owner };
153 DynamicFieldKey(
154 SUI_ACCUMULATOR_ROOT_OBJECT_ID,
155 key,
156 OwnerKey::get_type_tag(),
157 )
158 .into_id_with_bound(root_version.unwrap_or(SequenceNumber::MAX))?
159 .load_object(child_object_resolver)?
160 .map(|o| o.load_value::<Self>())
161 .transpose()
162 }
163
164 pub fn metadata_exists(
165 &self,
166 child_object_resolver: &dyn ChildObjectResolver,
167 version_bound: Option<SequenceNumber>,
168 type_: &TypeTag,
169 ) -> SuiResult<bool> {
170 let key = MetadataKey::default();
171 DynamicFieldKey(
172 *self.balances.id.object_id(),
173 key,
174 MetadataKey::get_type_tag(std::slice::from_ref(type_)),
175 )
176 .into_id_with_bound(version_bound.unwrap_or(SequenceNumber::MAX))?
177 .exists(child_object_resolver)
178 }
179
180 pub fn load_metadata(
181 &self,
182 child_object_resolver: &dyn ChildObjectResolver,
183 version_bound: Option<SequenceNumber>,
184 type_: &TypeTag,
185 ) -> SuiResult<Option<AccumulatorMetadata>> {
186 let key = MetadataKey::default();
187 DynamicFieldKey(
188 *self.balances.id.object_id(),
189 key,
190 MetadataKey::get_type_tag(std::slice::from_ref(type_)),
191 )
192 .into_id_with_bound(version_bound.unwrap_or(SequenceNumber::MAX))?
193 .load_object(child_object_resolver)?
194 .map(|o| o.load_value::<AccumulatorMetadata>())
195 .transpose()
196 }
197}