Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Limited caller AuthZone access and AuthZone stack #297

Closed
wants to merge 9 commits into from
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,7 @@ flamegraph.svg

# Emacs
*~

# Rusty Tags
rusty-tags.vi
rusty-tags.emacs
12 changes: 10 additions & 2 deletions radix-engine/src/engine/component_objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,11 @@ impl ComponentObjects {
lazy_maps.insert(lazy_map_id, lazy_map);
}

Ok(ComponentObjects { vaults, lazy_maps, borrowed_vault: None })
Ok(ComponentObjects {
vaults,
lazy_maps,
borrowed_vault: None,
})
}

pub fn insert_objects_into_map(
Expand Down Expand Up @@ -229,7 +233,11 @@ impl ComponentObjects {
pub fn return_borrowed_vault_mut(&mut self, vault: Vault) {
if let Some((vault_id, maybe_ancestor)) = self.borrowed_vault.take() {
if let Some(ancestor_id) = maybe_ancestor {
self.lazy_maps.get_mut(&ancestor_id).unwrap().descendent_vaults.insert(vault_id, vault);
self.lazy_maps
.get_mut(&ancestor_id)
.unwrap()
.descendent_vaults
.insert(vault_id, vault);
} else {
self.vaults.insert(vault_id, vault);
}
Expand Down
252 changes: 177 additions & 75 deletions radix-engine/src/engine/process.rs

Large diffs are not rendered by default.

14 changes: 10 additions & 4 deletions radix-engine/src/engine/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,11 @@ impl<'s, S: SubstateStore> Track<'s, S> {
resource_address
}

pub fn borrow_vault_mut(&mut self, component_address: &ComponentAddress, vid: &VaultId) -> Vault {
pub fn borrow_vault_mut(
&mut self,
component_address: &ComponentAddress,
vid: &VaultId,
) -> Vault {
let canonical_id = (component_address.clone(), vid.clone());
if self.borrowed_vaults.contains_key(&canonical_id) {
panic!("Invalid vault reentrancy");
Expand All @@ -519,9 +523,11 @@ impl<'s, S: SubstateStore> Track<'s, S> {
return value;
}

if let Some((vault, phys_id)) = self.substate_store.get_decoded_child_substate(component_address, vid) {
self.borrowed_vaults
.insert(canonical_id, Some(phys_id));
if let Some((vault, phys_id)) = self
.substate_store
.get_decoded_child_substate(component_address, vid)
{
self.borrowed_vaults.insert(canonical_id, Some(phys_id));
return vault;
}

Expand Down
1 change: 0 additions & 1 deletion radix-engine/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@ pub enum RuntimeError {

/// Can't move restricted proof.
CantMoveRestrictedProof(ProofId),

}

impl fmt::Display for RuntimeError {
Expand Down
2 changes: 1 addition & 1 deletion radix-engine/src/ledger/traits.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use sbor::*;
use scrypto::rule;
use scrypto::buffer::*;
use scrypto::constants::*;
use scrypto::crypto::*;
use scrypto::engine::types::*;
use scrypto::prelude::LOCKED;
use scrypto::resource::ResourceMethod::Withdraw;
use scrypto::rule;
use scrypto::rust::borrow::ToOwned;
use scrypto::rust::collections::*;
use scrypto::rust::vec;
Expand Down
2 changes: 1 addition & 1 deletion radix-engine/src/model/auth_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::model::MethodAuthorization;
use sbor::any::Value;
use sbor::*;
use scrypto::engine::types::*;
use scrypto::prelude::{AccessRuleNode, AccessRule, SoftResource};
use scrypto::prelude::{AccessRule, AccessRuleNode, SoftResource};
use scrypto::resource::{
NonFungibleAddress, ProofRule, SoftCount, SoftDecimal, SoftResourceOrNonFungible,
SoftResourceOrNonFungibleList,
Expand Down
113 changes: 77 additions & 36 deletions radix-engine/src/model/auth_zone.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::engine::SystemApi;
use sbor::DecodeError;
use scrypto::engine::types::*;
use scrypto::prelude::scrypto_decode;
use scrypto::rust::collections::BTreeSet;
use scrypto::rust::vec::Vec;
use scrypto::rust::string::String;
use scrypto::rust::string::ToString;
use scrypto::rust::vec::Vec;
use scrypto::values::ScryptoValue;
use crate::engine::SystemApi;

use crate::model::{Proof, ProofError, ResourceManager};

Expand All @@ -29,15 +29,11 @@ pub struct AuthZone {

impl AuthZone {
pub fn new_with_proofs(proofs: Vec<Proof>) -> Self {
Self {
proofs
}
Self { proofs }
}

pub fn new() -> Self {
Self {
proofs: Vec::new()
}
Self { proofs: Vec::new() }
}

pub fn pop(&mut self) -> Result<Proof, AuthZoneError> {
Expand All @@ -52,7 +48,7 @@ impl AuthZone {
self.proofs.push(proof);
}

fn clear(&mut self) {
pub fn clear(&mut self) {
loop {
if let Some(proof) = self.proofs.pop() {
proof.drop();
Expand All @@ -62,18 +58,31 @@ impl AuthZone {
}
}

fn create_proof(&self, resource_address: ResourceAddress, resource_type: ResourceType) -> Result<Proof, AuthZoneError> {
fn create_proof(
&self,
resource_address: ResourceAddress,
resource_type: ResourceType,
) -> Result<Proof, AuthZoneError> {
Proof::compose(&self.proofs, resource_address, resource_type)
.map_err(AuthZoneError::ProofError)
}

fn create_proof_by_amount(&self, amount:Decimal, resource_address: ResourceAddress, resource_type: ResourceType) -> Result<Proof, AuthZoneError> {
fn create_proof_by_amount(
&self,
amount: Decimal,
resource_address: ResourceAddress,
resource_type: ResourceType,
) -> Result<Proof, AuthZoneError> {
Proof::compose_by_amount(&self.proofs, amount, resource_address, resource_type)
.map_err(AuthZoneError::ProofError)
}


fn create_proof_by_ids(&self, ids: &BTreeSet<NonFungibleId>, resource_address: ResourceAddress, resource_type: ResourceType) -> Result<Proof, AuthZoneError> {
fn create_proof_by_ids(
&self,
ids: &BTreeSet<NonFungibleId>,
resource_address: ResourceAddress,
resource_type: ResourceType,
) -> Result<Proof, AuthZoneError> {
Proof::compose_by_ids(&self.proofs, ids, resource_address, resource_type)
.map_err(AuthZoneError::ProofError)
}
Expand All @@ -91,13 +100,19 @@ impl AuthZone {
}
"pop" => {
let proof = self.pop()?;
let proof_id = system_api.create_proof(proof).map_err(|_| AuthZoneError::CouldNotCreateProof)?;
Ok(ScryptoValue::from_value(&scrypto::resource::Proof(proof_id)))
let proof_id = system_api
.create_proof(proof)
.map_err(|_| AuthZoneError::CouldNotCreateProof)?;
Ok(ScryptoValue::from_value(&scrypto::resource::Proof(
proof_id,
)))
}
"push" => {
let proof_id: scrypto::resource::Proof =
scrypto_decode(&args[0].raw).map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let mut proof = system_api.take_proof(proof_id.0).map_err(|_| AuthZoneError::CouldNotGetProof)?;
let proof_id: scrypto::resource::Proof = scrypto_decode(&args[0].raw)
.map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let mut proof = system_api
.take_proof(proof_id.0)
.map_err(|_| AuthZoneError::CouldNotGetProof)?;
// FIXME: this is a hack for now until we can get snode_state into process
// FIXME: and be able to determine which snode the proof is going into
proof.change_to_unrestricted();
Expand All @@ -106,35 +121,61 @@ impl AuthZone {
Ok(ScryptoValue::from_value(&()))
}
"create_proof" => {
let resource_address = scrypto_decode(&args[0].raw).map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_manager: ResourceManager = system_api.borrow_global_mut_resource_manager(resource_address).map_err(|_| AuthZoneError::CouldNotGetResource)?;
let resource_address = scrypto_decode(&args[0].raw)
.map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_manager: ResourceManager = system_api
.borrow_global_mut_resource_manager(resource_address)
.map_err(|_| AuthZoneError::CouldNotGetResource)?;
let resource_type = resource_manager.resource_type();
system_api.return_borrowed_global_resource_manager(resource_address, resource_manager);
system_api
.return_borrowed_global_resource_manager(resource_address, resource_manager);
let proof = self.create_proof(resource_address, resource_type)?;
let proof_id = system_api.create_proof(proof).map_err(|_| AuthZoneError::CouldNotCreateProof)?;
Ok(ScryptoValue::from_value(&scrypto::resource::Proof(proof_id)))
let proof_id = system_api
.create_proof(proof)
.map_err(|_| AuthZoneError::CouldNotCreateProof)?;
Ok(ScryptoValue::from_value(&scrypto::resource::Proof(
proof_id,
)))
}
"create_proof_by_amount" => {
let amount = scrypto_decode(&args[0].raw).map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_address = scrypto_decode(&args[1].raw).map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_manager: ResourceManager = system_api.borrow_global_mut_resource_manager(resource_address).map_err(|_| AuthZoneError::CouldNotGetResource)?;
let amount = scrypto_decode(&args[0].raw)
.map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_address = scrypto_decode(&args[1].raw)
.map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_manager: ResourceManager = system_api
.borrow_global_mut_resource_manager(resource_address)
.map_err(|_| AuthZoneError::CouldNotGetResource)?;
let resource_type = resource_manager.resource_type();
system_api.return_borrowed_global_resource_manager(resource_address, resource_manager);
system_api
.return_borrowed_global_resource_manager(resource_address, resource_manager);
let proof = self.create_proof_by_amount(amount, resource_address, resource_type)?;
let proof_id = system_api.create_proof(proof).map_err(|_| AuthZoneError::CouldNotCreateProof)?;
Ok(ScryptoValue::from_value(&scrypto::resource::Proof(proof_id)))
let proof_id = system_api
.create_proof(proof)
.map_err(|_| AuthZoneError::CouldNotCreateProof)?;
Ok(ScryptoValue::from_value(&scrypto::resource::Proof(
proof_id,
)))
}
"create_proof_by_ids" => {
let ids = scrypto_decode(&args[0].raw).map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_address = scrypto_decode(&args[1].raw).map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_manager: ResourceManager = system_api.borrow_global_mut_resource_manager(resource_address).map_err(|_| AuthZoneError::CouldNotGetResource)?;
let ids = scrypto_decode(&args[0].raw)
.map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_address = scrypto_decode(&args[1].raw)
.map_err(|e| AuthZoneError::InvalidRequestData(e))?;
let resource_manager: ResourceManager = system_api
.borrow_global_mut_resource_manager(resource_address)
.map_err(|_| AuthZoneError::CouldNotGetResource)?;
let resource_type = resource_manager.resource_type();
system_api.return_borrowed_global_resource_manager(resource_address, resource_manager);
system_api
.return_borrowed_global_resource_manager(resource_address, resource_manager);
let proof = self.create_proof_by_ids(&ids, resource_address, resource_type)?;
let proof_id = system_api.create_proof(proof).map_err(|_| AuthZoneError::CouldNotCreateProof)?;
Ok(ScryptoValue::from_value(&scrypto::resource::Proof(proof_id)))
let proof_id = system_api
.create_proof(proof)
.map_err(|_| AuthZoneError::CouldNotCreateProof)?;
Ok(ScryptoValue::from_value(&scrypto::resource::Proof(
proof_id,
)))
}
_ => Err(AuthZoneError::MethodNotFound(function.to_string())),
}
}
}
}
Loading