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