radix_engine/blueprints/resource/auth_zone/
blueprint.rs1use crate::blueprints::resource::ComposedProof;
2use crate::errors::*;
3use crate::internal_prelude::*;
4use crate::kernel::kernel_api::{KernelNodeApi, KernelSubstateApi};
5use crate::system::node_init::type_info_partition;
6use crate::system::system_callback::SystemBasedKernelInternalApi;
7use crate::system::system_callback::SystemLockData;
8use crate::system::system_modules::auth::{Authorization, AuthorizationCheckResult};
9use crate::system::type_info::TypeInfoSubstate;
10use radix_engine_interface::api::{LockFlags, SystemApi, ACTOR_REF_SELF, ACTOR_STATE_SELF};
11use radix_engine_interface::blueprints::package::BlueprintVersion;
12use radix_engine_interface::blueprints::resource::*;
13use radix_native_sdk::resource::NativeProof;
14
15use super::{compose_proof_by_amount, compose_proof_by_ids, AuthZone, ComposeProofError};
16
17#[derive(Debug, Clone, PartialEq, Eq, ScryptoSbor)]
18pub enum AuthZoneError {
19 ComposeProofError(ComposeProofError),
20}
21
22pub struct AuthZoneBlueprint;
23
24impl AuthZoneBlueprint {
25 pub fn pop<Y: SystemApi<RuntimeError>>(api: &mut Y) -> Result<Option<Proof>, RuntimeError> {
26 let auth_zone_handle = api.actor_open_field(
27 ACTOR_STATE_SELF,
28 AuthZoneField::AuthZone.into(),
29 LockFlags::MUTABLE,
30 )?;
31
32 let mut auth_zone: AuthZone = api.field_read_typed(auth_zone_handle)?;
33 let maybe_proof = auth_zone.pop();
34 api.field_write_typed(auth_zone_handle, &auth_zone)?;
35
36 Ok(maybe_proof)
37 }
38
39 pub fn push<Y: SystemApi<RuntimeError>>(proof: Proof, api: &mut Y) -> Result<(), RuntimeError> {
40 let auth_zone_handle = api.actor_open_field(
41 ACTOR_STATE_SELF,
42 AuthZoneField::AuthZone.into(),
43 LockFlags::MUTABLE,
44 )?;
45
46 let mut auth_zone: AuthZone = api.field_read_typed(auth_zone_handle)?;
47 auth_zone.push(proof);
48
49 api.field_write_typed(auth_zone_handle, &auth_zone)?;
50 api.field_close(auth_zone_handle)?;
51
52 Ok(())
53 }
54
55 pub fn create_proof_of_amount<
56 Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<SystemLockData>,
57 >(
58 resource_address: ResourceAddress,
59 amount: Decimal,
60 api: &mut Y,
61 ) -> Result<Proof, RuntimeError> {
62 let auth_zone_handle = api.actor_open_field(
63 ACTOR_STATE_SELF,
64 AuthZoneField::AuthZone.into(),
65 LockFlags::read_only(),
66 )?;
67
68 let composed_proof = {
69 let auth_zone: AuthZone = api.field_read_typed(auth_zone_handle)?;
70 let proofs: Vec<Proof> = auth_zone.proofs.iter().map(|p| Proof(p.0)).collect();
71 compose_proof_by_amount(&proofs, resource_address, Some(amount), api)?
72 };
73
74 let node_id = api.kernel_allocate_node_id(EntityType::InternalGenericComponent)?;
75 match composed_proof {
76 ComposedProof::Fungible(..) => {
77 api.kernel_create_node(
78 node_id,
79 btreemap!(
80 MAIN_BASE_PARTITION => composed_proof.into(),
81 TYPE_INFO_FIELD_PARTITION => type_info_partition(TypeInfoSubstate::Object(ObjectInfo {
82 blueprint_info: BlueprintInfo {
83 blueprint_id: BlueprintId::new(&RESOURCE_PACKAGE, FUNGIBLE_PROOF_BLUEPRINT),
84 blueprint_version: BlueprintVersion::default(),
85 outer_obj_info: OuterObjectInfo::Some {
86 outer_object: resource_address.into(),
87 },
88 features: indexset!(),
89 generic_substitutions: vec![],
90 },
91 object_type: ObjectType::Owned,
92 })),
93 ),
94 )?;
95 api.kernel_pin_node(node_id)?;
96 }
97 ComposedProof::NonFungible(..) => {
98 api.kernel_create_node(
99 node_id,
100 btreemap!(
101 MAIN_BASE_PARTITION => composed_proof.into(),
102 TYPE_INFO_FIELD_PARTITION => type_info_partition(TypeInfoSubstate::Object(ObjectInfo {
103 blueprint_info: BlueprintInfo {
104 blueprint_id: BlueprintId::new(&RESOURCE_PACKAGE, NON_FUNGIBLE_PROOF_BLUEPRINT),
105 blueprint_version: BlueprintVersion::default(),
106 outer_obj_info: OuterObjectInfo::Some {
107 outer_object: resource_address.into(),
108 },
109 features: indexset!(),
110 generic_substitutions: vec![],
111 },
112 object_type: ObjectType::Owned,
113 }))),
114 )?;
115 api.kernel_pin_node(node_id)?;
116 }
117 }
118
119 Ok(Proof(Own(node_id)))
120 }
121
122 pub fn create_proof_of_non_fungibles<
123 Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<SystemLockData>,
124 >(
125 resource_address: ResourceAddress,
126 ids: IndexSet<NonFungibleLocalId>,
127 api: &mut Y,
128 ) -> Result<Proof, RuntimeError> {
129 let auth_zone_handle = api.actor_open_field(
130 ACTOR_STATE_SELF,
131 AuthZoneField::AuthZone.into(),
132 LockFlags::MUTABLE,
133 )?;
134
135 let composed_proof = {
136 let auth_zone: AuthZone = api.field_read_typed(auth_zone_handle)?;
137 let proofs: Vec<Proof> = auth_zone.proofs.iter().map(|p| Proof(p.0)).collect();
138 compose_proof_by_ids(&proofs, resource_address, Some(ids), api)?
139 };
140
141 let node_id = api.kernel_allocate_node_id(EntityType::InternalGenericComponent)?;
142 api.kernel_create_node(
143 node_id,
144 btreemap!(
145 MAIN_BASE_PARTITION => composed_proof.into(),
146 TYPE_INFO_FIELD_PARTITION => type_info_partition(TypeInfoSubstate::Object(ObjectInfo {
147 blueprint_info: BlueprintInfo {
148 blueprint_id: BlueprintId::new(&RESOURCE_PACKAGE, NON_FUNGIBLE_PROOF_BLUEPRINT),
149 blueprint_version: BlueprintVersion::default(),
150 outer_obj_info: OuterObjectInfo::Some {
151 outer_object: resource_address.into(),
152 },
153 features: indexset!(),
154 generic_substitutions: vec![],
155 },
156 object_type: ObjectType::Owned,
157 }))
158 ),
159 )?;
160 api.kernel_pin_node(node_id)?;
161
162 Ok(Proof(Own(node_id)))
163 }
164
165 pub fn create_proof_of_all<
166 Y: SystemApi<RuntimeError> + KernelNodeApi + KernelSubstateApi<SystemLockData>,
167 >(
168 resource_address: ResourceAddress,
169 api: &mut Y,
170 ) -> Result<Proof, RuntimeError> {
171 let auth_zone_handle = api.actor_open_field(
172 ACTOR_STATE_SELF,
173 AuthZoneField::AuthZone.into(),
174 LockFlags::MUTABLE,
175 )?;
176
177 let auth_zone: AuthZone = api.field_read_typed(auth_zone_handle)?;
178 let proofs: Vec<Proof> = auth_zone.proofs.iter().map(|p| Proof(p.0)).collect();
179 let composed_proof = compose_proof_by_amount(&proofs, resource_address, None, api)?;
180
181 let blueprint_name = match &composed_proof {
182 ComposedProof::Fungible(..) => FUNGIBLE_PROOF_BLUEPRINT,
183 ComposedProof::NonFungible(..) => NON_FUNGIBLE_PROOF_BLUEPRINT,
184 };
185 api.field_write_typed(auth_zone_handle, &auth_zone)?;
186
187 let node_id = api.kernel_allocate_node_id(EntityType::InternalGenericComponent)?;
188 api.kernel_create_node(
189 node_id,
190 btreemap!(
191 MAIN_BASE_PARTITION => composed_proof.into(),
192 TYPE_INFO_FIELD_PARTITION => type_info_partition(TypeInfoSubstate::Object(ObjectInfo {
193 blueprint_info: BlueprintInfo {
194 blueprint_id: BlueprintId::new(&RESOURCE_PACKAGE, blueprint_name),
195 blueprint_version: BlueprintVersion::default(),
196 outer_obj_info: OuterObjectInfo::Some {
197 outer_object: resource_address.into(),
198 },
199 features: indexset!(),
200 generic_substitutions: vec![],
201 },
202 object_type: ObjectType::Owned,
203 }))
204 ),
205 )?;
206 api.kernel_pin_node(node_id)?;
207
208 Ok(Proof(Own(node_id)))
209 }
210
211 pub fn drop_proofs<Y: SystemApi<RuntimeError>>(api: &mut Y) -> Result<(), RuntimeError> {
212 Self::drop_signature_proofs(api)?;
213 Self::drop_regular_proofs(api)?;
214 Ok(())
215 }
216
217 pub fn drop_signature_proofs<Y: SystemApi<RuntimeError>>(
218 api: &mut Y,
219 ) -> Result<(), RuntimeError> {
220 let handle = api.actor_open_field(
221 ACTOR_STATE_SELF,
222 AuthZoneField::AuthZone.into(),
223 LockFlags::MUTABLE,
224 )?;
225 let mut auth_zone: AuthZone = api.field_read_typed(handle)?;
226 auth_zone.remove_signature_proofs();
227 api.field_write_typed(handle, &auth_zone)?;
228 api.field_close(handle)?;
229
230 Ok(())
231 }
232
233 pub fn drop_regular_proofs<Y: SystemApi<RuntimeError>>(
234 api: &mut Y,
235 ) -> Result<(), RuntimeError> {
236 let handle = api.actor_open_field(
237 ACTOR_STATE_SELF,
238 AuthZoneField::AuthZone.into(),
239 LockFlags::MUTABLE,
240 )?;
241 let mut auth_zone: AuthZone = api.field_read_typed(handle)?;
242 let proofs = auth_zone.remove_regular_proofs();
243 api.field_write_typed(handle, &auth_zone)?;
244 api.field_close(handle)?;
245
246 for proof in proofs {
247 proof.drop(api)?;
248 }
249
250 Ok(())
251 }
252
253 pub fn drain<Y: SystemApi<RuntimeError>>(api: &mut Y) -> Result<Vec<Proof>, RuntimeError> {
254 let auth_zone_handle = api.actor_open_field(
255 ACTOR_STATE_SELF,
256 AuthZoneField::AuthZone.into(),
257 LockFlags::MUTABLE,
258 )?;
259
260 let mut auth_zone: AuthZone = api.field_read_typed(auth_zone_handle)?;
261 let proofs = auth_zone.remove_regular_proofs();
262 api.field_write_typed(auth_zone_handle, &auth_zone)?;
263
264 Ok(proofs)
265 }
266
267 pub fn assert_access_rule<
268 Y: SystemApi<RuntimeError> + KernelSubstateApi<L> + SystemBasedKernelInternalApi,
269 L: Default,
270 >(
271 access_rule: AccessRule,
272 api: &mut Y,
273 ) -> Result<(), RuntimeError> {
274 let node_id = api.actor_get_node_id(ACTOR_REF_SELF)?;
275
276 let system = api.kernel_get_system();
277 if system
278 .versioned_system_logic
279 .assert_access_rule_is_noop_when_auth_module_disabled()
280 && !system.modules.is_auth_enabled()
281 {
282 return Ok(());
283 }
284
285 let auth_result =
286 Authorization::check_authorization_against_access_rule(api, &node_id, &access_rule)?;
287
288 match auth_result {
289 AuthorizationCheckResult::Authorized => Ok(()),
290 AuthorizationCheckResult::Failed(..) => Err(RuntimeError::SystemError(
291 SystemError::AssertAccessRuleFailed,
292 )),
293 }
294 }
295}