Skip to content

Commit

Permalink
Polish
Browse files Browse the repository at this point in the history
  • Loading branch information
Sajjon committed Jan 23, 2025
1 parent be35bc4 commit 121b413
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 152 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ where
unsecured_entity_control,
)),
EntitySecurityState::Securified { .. } => {

Check warning on line 59 in crates/profile/models/supporting-types/src/unsecurified_entity.rs

View check run for this annotation

Codecov / codecov/patch

crates/profile/models/supporting-types/src/unsecurified_entity.rs#L59

Added line #L59 was not covered by tests
Err(CommonError::AESDecryptionFailed)
Err(CommonError::SecurityStateSecurifiedButExpectedUnsecurified)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,9 @@ impl OsApplySecurityShieldInteraction for SargonOS {
.unsecurified_erased()
.iter()
.map(|e| {

let provisional = e.entity.get_provisional().expect("Entity should have a provisional config set since we applied shield above");
let derived = provisional.as_factor_instances_derived().expect("Should have derived factors");

let input = TransactionManifestApplySecurityShieldUnsecurifiedInput::new(derived.clone());

let input = TransactionManifestApplySecurityShieldUnsecurifiedInput::new(derived.clone());
TransactionManifest::apply_security_shield_for_unsecurified_entity(
e,
input,

Check warning on line 36 in crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs

View check run for this annotation

Codecov / codecov/patch

crates/system/os/factors/src/apply_security_shield/sargon_os_apply_security_shield_interaction.rs#L30-L36

Added lines #L30 - L36 were not covered by tests
Expand Down
2 changes: 2 additions & 0 deletions crates/transaction/manifests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod delete_account;
mod high_level;
mod manifest_account_locker;
mod manifest_assets_transfers;
mod manifest_builder_from_manifest;
mod manifests;
mod manifests_create_tokens;
mod manifests_security_shield;
Expand All @@ -18,6 +19,7 @@ pub mod prelude {
pub use crate::high_level::*;
pub use crate::manifest_account_locker::*;
pub use crate::manifest_assets_transfers::*;
pub use crate::manifest_builder_from_manifest::*;
pub use crate::manifests::*;
pub use crate::manifests_create_tokens::*;
pub use crate::manifests_security_shield::*;
Expand Down
26 changes: 26 additions & 0 deletions crates/transaction/manifests/src/manifest_builder_from_manifest.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use radix_transactions::prelude::ManifestBuilder;

use crate::prelude::*;

pub trait BuilderFromManifest {
fn with_instructions(
instructions: impl IntoIterator<Item = ScryptoInstruction>,
) -> ManifestBuilder;

fn with_manifest(manifest: TransactionManifest) -> ManifestBuilder {
Self::with_instructions(manifest.instructions().clone())
}
}

impl BuilderFromManifest for ManifestBuilder {
fn with_instructions(
instructions: impl IntoIterator<Item = ScryptoInstruction>,
) -> ManifestBuilder {
instructions.into_iter().fold(
ManifestBuilder::new(),
|builder, instruction| {
builder.add_instruction_advanced(instruction).0
},
)
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
use profile_supporting_types::AnyUnsecurifiedEntity;
use radix_common::prelude::{
ManifestGlobalAddress,
ACCESS_CONTROLLER_PACKAGE as SCRYPTO_ACCESS_CONTROLLER_PACKAGE,
};
use radix_common::prelude::ACCESS_CONTROLLER_PACKAGE as SCRYPTO_ACCESS_CONTROLLER_PACKAGE;
use radix_engine_interface::blueprints::{
access_controller::{
AccessControllerContributeRecoveryFeeManifestInput,
AccessControllerCreateManifestInput as ScryptoAccessControllerCreateManifestInput,
ACCESS_CONTROLLER_BLUEPRINT as SCRYPTO_ACCESS_CONTROLLER_BLUEPRINT,
ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT as SCRYPTO_ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT,
ACCESS_CONTROLLER_CREATE_IDENT as SCRYPTO_ACCESS_CONTROLLER_CREATE_IDENT,
ACCESS_CONTROLLER_CREATE_PROOF_IDENT,
},
account::AccountSecurifyManifestInput as ScryptoAccountSecurifyManifestInput,
};
Expand All @@ -35,159 +29,19 @@ impl TransactionManifestApplySecurityShieldUnsecurifiedInput {
}
}

pub trait BuilderFromManifest {
fn with_instructions(
instructions: impl IntoIterator<Item = ScryptoInstruction>,
) -> ManifestBuilder;

fn with_manifest(manifest: TransactionManifest) -> ManifestBuilder {
Self::with_instructions(manifest.instructions().clone())
}
}

impl BuilderFromManifest for ManifestBuilder {
fn with_instructions(
instructions: impl IntoIterator<Item = ScryptoInstruction>,
) -> ManifestBuilder {
instructions.into_iter().fold(
ManifestBuilder::new(),
|builder, instruction| {
builder.add_instruction_advanced(instruction).0
},
)
}
}

pub trait TransactionManifestSecurifyEntity: Sized {
fn apply_security_shield_for_unsecurified_entity(
unsecurified_entity: AnyUnsecurifiedEntity,
input: TransactionManifestApplySecurityShieldUnsecurifiedInput,
) -> Result<Self>;

/// A method modifying manifests which applies security shield. We
/// The `manifest` which applies the security shield could not include
/// the instructions which we append in this method since the host did
/// not know the `payer` at the time of creating that manifest. The host
/// will call this method when the `payer` is known, which appends instructions
/// at the end of `manifest` for topping the XRD vault of the access controller
/// with `top_up_amount` many XRD.
///
/// N.B. We will call this method for both when `entity_applying_shield` is
/// securified or unsecurified. In the case of unsecurified entity we will use
/// the address reservation of `apply_security_shield_for_unsecurified_entity`
/// (`ACCESS_CONTROLLER_ADDRESS_RESERVATION_NAME`) which we cannot access by id
/// since Radix Engine discard those ids and uses internal ones, instead we need
/// to use `ManifestGlobalAddress::Named(ScryptoManifestNamedAddress(0))`.
/// If `entity_applying_shield` is securified we will use the address of the
/// already existing access controller.
///
/// If `payer` is securified we will also add a `create_proof` instruction for
/// authenticating the withdrawal of XRD from the payer.
///
/// If `top_up_amount` is `None` the `XRD_TO_AC_VAULT_FIRST_TOP_UP` will be used.
/// We allow to pass amount so that we can top of with more or less based on
/// token balance of `payer` and current balance of the access controller (when
/// we use this method for securified entities.)
fn modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account(
payer: Account,
// TODO: remove `entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity.
entity_applying_shield: Account,
manifest: TransactionManifest,
top_up_amount: impl Into<Option<Decimal192>>,
) -> TransactionManifest {
let address_of_paying_account = payer.address();
let mut builder = ManifestBuilder::with_manifest(manifest);

let address_of_access_controller_to_top_up =
match entity_applying_shield.security_state() {
EntitySecurityState::Securified { value: sec } => {
ManifestGlobalAddress::Static(
sec.access_controller_address.scrypto(),
)
}
EntitySecurityState::Unsecured { .. } => {
// We are securifying an unsecurified account => use the
// address reservation at index 0,
// which `apply_security_shield_for_unsecurified_entity`
// is using to create the access controller address
ManifestGlobalAddress::Named(ScryptoManifestNamedAddress(0))
}
};

let address_of_access_controller_of_payer = {
match payer.security_state() {
EntitySecurityState::Securified { value: sec } => {
Some(ManifestGlobalAddress::Static(
sec.access_controller_address.scrypto(),
))
}
EntitySecurityState::Unsecured { .. } => {
// No access controller to create proof for
None
}
}
};

// Add `create_proof` instruction for the access controller
if let Some(address_of_access_controller_of_payer) =
address_of_access_controller_of_payer
{
builder = builder.call_method(
address_of_access_controller_of_payer,
ACCESS_CONTROLLER_CREATE_PROOF_IDENT,
(),
);
}

let top_up_amount = top_up_amount
.into()
.map(ScryptoDecimal192::from)
.unwrap_or(XRD_TO_AC_VAULT_FIRST_TOP_UP);

// Add withdraw XRD instruction
builder = builder.withdraw_from_account(
address_of_paying_account.scrypto(),
XRD,
top_up_amount,
);

// Deposit XRD into the access controllers XRD vault
// ... by first taking the XRD from the work top
let xrd_to_top_up_ac_vault_bucket_name =
"xrd_to_top_up_ac_vault_bucket";
builder = builder.take_from_worktop(
XRD,
top_up_amount,
xrd_to_top_up_ac_vault_bucket_name,
);
let xrd_to_top_up_ac_vault_bucket =
builder.bucket(xrd_to_top_up_ac_vault_bucket_name);

// ... then deposit to XRD vault of access controller
builder = builder.call_method(
address_of_access_controller_to_top_up,
SCRYPTO_ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT,
AccessControllerContributeRecoveryFeeManifestInput {
bucket: xrd_to_top_up_ac_vault_bucket,
},
);

TransactionManifest::sargon_built(
builder,
address_of_paying_account.network_id(),
)
}

fn set_rola_key(
builder: ManifestBuilder,
authentication_signing_factor_instance: &HierarchicalDeterministicFactorInstance,
entity_address: &AddressOfAccountOrPersona,
) -> ManifestBuilder;
}

const XRD_TO_AC_VAULT_FIRST_TOP_UP: ScryptoDecimal192 =
ScryptoDecimal192::ONE_HUNDRED;

impl TransactionManifestSecurifyEntity for TransactionManifest {
fn set_rola_key(
builder: ManifestBuilder,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#[allow(clippy::module_inception)]
mod manifests_security_shield;
mod top_up_access_controller_xrd_vault;

pub use manifests_security_shield::*;
pub use top_up_access_controller_xrd_vault::*;
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use radix_common::prelude::ManifestGlobalAddress;
use radix_engine_interface::blueprints::access_controller::{
AccessControllerContributeRecoveryFeeManifestInput,
ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT as SCRYPTO_ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT,
ACCESS_CONTROLLER_CREATE_PROOF_IDENT as SCRYPTO_ACCESS_CONTROLLER_CREATE_PROOF_IDENT,
};
use radix_transactions::prelude::ManifestBuilder;

use crate::prelude::*;

const XRD_TO_AC_VAULT_FIRST_TOP_UP: ScryptoDecimal192 =
ScryptoDecimal192::ONE_HUNDRED;

pub trait TransactionManifestAccessControllerXrdVaultToppingUp {
/// A method modifying manifests which applies security shield. We
/// The `manifest` which applies the security shield could not include
/// the instructions which we append in this method since the host did
/// not know the `payer` at the time of creating that manifest. The host
/// will call this method when the `payer` is known, which appends instructions
/// at the end of `manifest` for topping the XRD vault of the access controller
/// with `top_up_amount` many XRD.
///
/// N.B. We will call this method for both when `entity_applying_shield` is
/// securified or unsecurified. In the case of unsecurified entity we will use
/// the address reservation of `apply_security_shield_for_unsecurified_entity`
/// (`ACCESS_CONTROLLER_ADDRESS_RESERVATION_NAME`) which we cannot access by id
/// since Radix Engine discard those ids and uses internal ones, instead we need
/// to use `ManifestGlobalAddress::Named(ScryptoManifestNamedAddress(0))`.
/// If `entity_applying_shield` is securified we will use the address of the
/// already existing access controller.
///
/// If `payer` is securified we will also add a `create_proof` instruction for
/// authenticating the withdrawal of XRD from the payer.
///
/// If `top_up_amount` is `None` the `XRD_TO_AC_VAULT_FIRST_TOP_UP` will be used.
/// We allow to pass amount so that we can top of with more or less based on
/// token balance of `payer` and current balance of the access controller (when
/// we use this method for securified entities.)
fn modify_manifest_add_withdraw_of_xrd_for_access_controller_xrd_vault_top_up_paid_by_account(
payer: Account,
// TODO: remove `entity_applying_shield`, this should be read out from the manifest in a throwing function, `manifest.get_address_of_entity_applying_shield()` or similar which Omar need to provide us with, oh well we need the account here, so elsewhere, in SargonOS where we have access to Profile we would call `manifest.get_address_of_entity_applying_shield` and then lookup the entity.
entity_applying_shield: Account,
manifest: TransactionManifest,
top_up_amount: impl Into<Option<Decimal192>>,
) -> TransactionManifest {
let address_of_paying_account = payer.address();
let mut builder = ManifestBuilder::with_manifest(manifest);

let address_of_access_controller_to_top_up =
match entity_applying_shield.security_state() {
EntitySecurityState::Securified { value: sec } => {

Check warning on line 51 in crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs

View check run for this annotation

Codecov / codecov/patch

crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs#L51

Added line #L51 was not covered by tests
ManifestGlobalAddress::Static(
sec.access_controller_address.scrypto(),

Check warning on line 53 in crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs

View check run for this annotation

Codecov / codecov/patch

crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs#L53

Added line #L53 was not covered by tests
)
}
EntitySecurityState::Unsecured { .. } => {

Check warning on line 56 in crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs

View check run for this annotation

Codecov / codecov/patch

crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs#L56

Added line #L56 was not covered by tests
// We are securifying an unsecurified account => use the
// address reservation at index 0,
// which `apply_security_shield_for_unsecurified_entity`
// is using to create the access controller address
ManifestGlobalAddress::Named(ScryptoManifestNamedAddress(0))
}
};

let address_of_access_controller_of_payer = {
match payer.security_state() {
EntitySecurityState::Securified { value: sec } => {
Some(ManifestGlobalAddress::Static(
sec.access_controller_address.scrypto(),
))
}
EntitySecurityState::Unsecured { .. } => {

Check warning on line 72 in crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs

View check run for this annotation

Codecov / codecov/patch

crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs#L72

Added line #L72 was not covered by tests
// No access controller to create proof for
None
}
}
};

// Add `create_proof` instruction for the access controller
if let Some(address_of_access_controller_of_payer) =
address_of_access_controller_of_payer
{
builder = builder.call_method(
address_of_access_controller_of_payer,
SCRYPTO_ACCESS_CONTROLLER_CREATE_PROOF_IDENT,

Check warning on line 85 in crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs

View check run for this annotation

Codecov / codecov/patch

crates/transaction/manifests/src/manifests_security_shield/top_up_access_controller_xrd_vault.rs#L83-L85

Added lines #L83 - L85 were not covered by tests
(),
);
}

let top_up_amount = top_up_amount
.into()
.map(ScryptoDecimal192::from)
.unwrap_or(XRD_TO_AC_VAULT_FIRST_TOP_UP);

// Add withdraw XRD instruction
builder = builder.withdraw_from_account(
address_of_paying_account.scrypto(),
XRD,
top_up_amount,
);

// Deposit XRD into the access controllers XRD vault
// ... by first taking the XRD from the work top
let xrd_to_top_up_ac_vault_bucket_name =
"xrd_to_top_up_ac_vault_bucket";
builder = builder.take_from_worktop(
XRD,
top_up_amount,
xrd_to_top_up_ac_vault_bucket_name,
);
let xrd_to_top_up_ac_vault_bucket =
builder.bucket(xrd_to_top_up_ac_vault_bucket_name);

// ... then deposit to XRD vault of access controller
builder = builder.call_method(
address_of_access_controller_to_top_up,
SCRYPTO_ACCESS_CONTROLLER_CONTRIBUTE_RECOVERY_FEE_IDENT,
AccessControllerContributeRecoveryFeeManifestInput {
bucket: xrd_to_top_up_ac_vault_bucket,
},
);

TransactionManifest::sargon_built(
builder,
address_of_paying_account.network_id(),
)
}
}

impl TransactionManifestAccessControllerXrdVaultToppingUp
for TransactionManifest
{
}

0 comments on commit 121b413

Please sign in to comment.