1use crate::api::CollectionIndex;
2use crate::internal_prelude::*;
3use crate::object_modules::metadata::METADATA_BLUEPRINT;
4use crate::object_modules::role_assignment::ROLE_ASSIGNMENT_BLUEPRINT;
5use crate::types::*;
6#[cfg(feature = "fuzzing")]
7use arbitrary::Arbitrary;
8use radix_common::constants::{
9 METADATA_MODULE_PACKAGE, ROLE_ASSIGNMENT_MODULE_PACKAGE, ROYALTY_MODULE_PACKAGE,
10};
11use radix_common::prelude::{scrypto_encode, ScryptoEncode, VersionedScryptoSchema};
12use radix_common::types::*;
13use radix_common::{ManifestSbor, ScryptoSbor};
14use radix_engine_interface::api::FieldIndex;
15use radix_engine_interface::object_modules::royalty::COMPONENT_ROYALTY_BLUEPRINT;
16use sbor::rust::collections::*;
17use sbor::rust::prelude::*;
18use sbor::rust::vec::Vec;
19
20#[repr(u8)]
21#[cfg_attr(
22 feature = "fuzzing",
23 derive(Arbitrary, serde::Serialize, serde::Deserialize)
24)]
25#[derive(
26 Debug,
27 Clone,
28 Copy,
29 PartialEq,
30 Eq,
31 Hash,
32 PartialOrd,
33 Ord,
34 FromRepr,
35 EnumIter,
36 ManifestSbor,
37 ScryptoCategorize,
38 ScryptoEncode,
39 ScryptoDecode,
40)]
41pub enum ModuleId {
42 Main,
43 Metadata,
44 Royalty,
45 RoleAssignment,
46}
47
48pub type ObjectModuleId = ModuleId;
50
51impl Describe<ScryptoCustomTypeKind> for ModuleId {
52 const TYPE_ID: RustTypeId =
53 RustTypeId::WellKnown(well_known_scrypto_custom_types::MODULE_ID_TYPE);
54
55 fn type_data() -> ScryptoTypeData<RustTypeId> {
56 well_known_scrypto_custom_types::module_id_type_data()
57 }
58}
59
60impl From<Option<AttachedModuleId>> for ModuleId {
61 fn from(value: Option<AttachedModuleId>) -> Self {
62 match value {
63 None => ModuleId::Main,
64 Some(AttachedModuleId::Metadata) => ModuleId::Metadata,
65 Some(AttachedModuleId::Royalty) => ModuleId::Royalty,
66 Some(AttachedModuleId::RoleAssignment) => ModuleId::RoleAssignment,
67 }
68 }
69}
70
71impl Into<Option<AttachedModuleId>> for ModuleId {
72 fn into(self) -> Option<AttachedModuleId> {
73 match self {
74 ModuleId::Main => None,
75 ModuleId::Metadata => Some(AttachedModuleId::Metadata),
76 ModuleId::Royalty => Some(AttachedModuleId::Royalty),
77 ModuleId::RoleAssignment => Some(AttachedModuleId::RoleAssignment),
78 }
79 }
80}
81
82impl ModuleId {
83 pub fn base_partition_num(&self) -> PartitionNumber {
84 match self {
85 ModuleId::Metadata => METADATA_BASE_PARTITION,
86 ModuleId::Royalty => ROYALTY_BASE_PARTITION,
87 ModuleId::RoleAssignment => ROLE_ASSIGNMENT_BASE_PARTITION,
88 ModuleId::Main => MAIN_BASE_PARTITION,
89 }
90 }
91
92 pub fn static_blueprint(&self) -> Option<BlueprintId> {
93 match self {
94 ModuleId::Metadata => Some(BlueprintId::new(
95 &METADATA_MODULE_PACKAGE,
96 METADATA_BLUEPRINT,
97 )),
98 ModuleId::Royalty => Some(BlueprintId::new(
99 &ROYALTY_MODULE_PACKAGE,
100 COMPONENT_ROYALTY_BLUEPRINT,
101 )),
102 ModuleId::RoleAssignment => Some(BlueprintId::new(
103 &ROLE_ASSIGNMENT_MODULE_PACKAGE,
104 ROLE_ASSIGNMENT_BLUEPRINT,
105 )),
106 ModuleId::Main => None,
107 }
108 }
109}
110
111#[repr(u8)]
112#[cfg_attr(
113 feature = "fuzzing",
114 derive(Arbitrary, serde::Serialize, serde::Deserialize)
115)]
116#[derive(
117 Debug,
118 Clone,
119 Copy,
120 PartialEq,
121 Eq,
122 Hash,
123 PartialOrd,
124 Ord,
125 FromRepr,
126 EnumIter,
127 ManifestSbor,
128 ScryptoCategorize,
129 ScryptoEncode,
130 ScryptoDecode,
131)]
132#[sbor(use_repr_discriminators)]
133pub enum AttachedModuleId {
134 Metadata = 1,
135 Royalty = 2,
136 RoleAssignment = 3,
137}
138
139impl Describe<ScryptoCustomTypeKind> for AttachedModuleId {
140 const TYPE_ID: RustTypeId =
141 RustTypeId::WellKnown(well_known_scrypto_custom_types::ATTACHED_MODULE_ID_TYPE);
142
143 fn type_data() -> ScryptoTypeData<RustTypeId> {
144 well_known_scrypto_custom_types::attached_module_id_type_data()
145 }
146}
147
148impl AttachedModuleId {
149 pub fn static_blueprint(&self) -> BlueprintId {
150 match self {
151 AttachedModuleId::Metadata => {
152 BlueprintId::new(&METADATA_MODULE_PACKAGE, METADATA_BLUEPRINT)
153 }
154 AttachedModuleId::Royalty => {
155 BlueprintId::new(&ROYALTY_MODULE_PACKAGE, COMPONENT_ROYALTY_BLUEPRINT)
156 }
157 AttachedModuleId::RoleAssignment => {
158 BlueprintId::new(&ROLE_ASSIGNMENT_MODULE_PACKAGE, ROLE_ASSIGNMENT_BLUEPRINT)
159 }
160 }
161 }
162}
163
164impl Into<ModuleId> for AttachedModuleId {
165 fn into(self) -> ModuleId {
166 match self {
167 AttachedModuleId::Metadata => ModuleId::Metadata,
168 AttachedModuleId::Royalty => ModuleId::Royalty,
169 AttachedModuleId::RoleAssignment => ModuleId::RoleAssignment,
170 }
171 }
172}
173
174#[cfg_attr(feature = "fuzzing", derive(Arbitrary))]
175#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, ScryptoSbor)]
176pub struct FieldValue {
177 pub value: Vec<u8>,
178 pub locked: bool,
179}
180
181impl FieldValue {
182 pub fn new<E: ScryptoEncode>(value: E) -> Self {
183 Self {
184 value: scrypto_encode(&value).unwrap(),
185 locked: false,
186 }
187 }
188
189 pub fn immutable<E: ScryptoEncode>(value: E) -> Self {
190 Self {
191 value: scrypto_encode(&value).unwrap(),
192 locked: true,
193 }
194 }
195}
196
197#[derive(Default, Debug, Clone, PartialEq, Eq, ScryptoSbor)]
198pub struct GenericArgs {
199 pub additional_schema: Option<VersionedScryptoSchema>,
200 pub generic_substitutions: Vec<GenericSubstitution>,
201}
202
203pub struct KVEntry {
204 pub value: Option<Vec<u8>>,
205 pub locked: bool,
206}
207
208pub trait SystemObjectApi<E> {
210 fn new_simple_object(
212 &mut self,
213 blueprint_ident: &str,
214 fields: IndexMap<FieldIndex, FieldValue>,
215 ) -> Result<NodeId, E> {
216 self.new_object(
217 blueprint_ident,
218 vec![],
219 GenericArgs::default(),
220 fields,
221 indexmap![],
222 )
223 }
224
225 fn new_object(
227 &mut self,
228 blueprint_ident: &str,
229 features: Vec<&str>,
230 generic_args: GenericArgs,
231 fields: IndexMap<FieldIndex, FieldValue>,
232 kv_entries: IndexMap<CollectionIndex, IndexMap<Vec<u8>, KVEntry>>,
233 ) -> Result<NodeId, E>;
234
235 fn drop_object(&mut self, node_id: &NodeId) -> Result<Vec<Vec<u8>>, E>;
237
238 fn get_blueprint_id(&mut self, node_id: &NodeId) -> Result<BlueprintId, E>;
240
241 fn get_outer_object(&mut self, node_id: &NodeId) -> Result<GlobalAddress, E>;
243
244 fn allocate_global_address(
246 &mut self,
247 blueprint_id: BlueprintId,
248 ) -> Result<(GlobalAddressReservation, GlobalAddress), E>;
249
250 fn allocate_virtual_global_address(
252 &mut self,
253 blueprint_id: BlueprintId,
254 global_address: GlobalAddress,
255 ) -> Result<GlobalAddressReservation, E>;
256
257 fn get_reservation_address(&mut self, node_id: &NodeId) -> Result<GlobalAddress, E>;
259
260 fn globalize(
263 &mut self,
264 node_id: NodeId,
265 modules: IndexMap<AttachedModuleId, NodeId>,
266 address_reservation: Option<GlobalAddressReservation>,
267 ) -> Result<GlobalAddress, E>;
268
269 fn globalize_with_address_and_create_inner_object_and_emit_event(
271 &mut self,
272 node_id: NodeId,
273 modules: IndexMap<AttachedModuleId, NodeId>,
274 address_reservation: GlobalAddressReservation,
275 inner_object_blueprint: &str,
276 inner_object_fields: IndexMap<u8, FieldValue>,
277 event_name: &str,
278 event_data: Vec<u8>,
279 ) -> Result<(GlobalAddress, NodeId), E>;
280
281 fn call_method(
283 &mut self,
284 receiver: &NodeId,
285 method_name: &str,
286 args: Vec<u8>,
287 ) -> Result<Vec<u8>, E>;
288
289 fn call_direct_access_method(
291 &mut self,
292 receiver: &NodeId,
293 method_name: &str,
294 args: Vec<u8>,
295 ) -> Result<Vec<u8>, E>;
296
297 fn call_module_method(
299 &mut self,
300 receiver: &NodeId,
301 module_id: AttachedModuleId,
302 method_name: &str,
303 args: Vec<u8>,
304 ) -> Result<Vec<u8>, E>;
305}