Skip to content

Commit

Permalink
use hash to identify policies (#39)
Browse files Browse the repository at this point in the history
* use hash to identify policies

* use policy account in hash
  • Loading branch information
Bhargavamacha authored Apr 10, 2024
1 parent 7dfef19 commit a092f80
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 12 deletions.
114 changes: 114 additions & 0 deletions programs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions programs/policy_engine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ default = []
anchor-lang = { git = "https://[email protected]/bridgesplit/anchor" }
anchor-spl = { git = "https://[email protected]/bridgesplit/anchor" }
num_enum = "0.7.2"
sha256 = "1.5.0"
2 changes: 2 additions & 0 deletions programs/policy_engine/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ pub enum PolicyEngineErrors {
IdentityFilterFailed,
#[msg("Unauthorized signer")]
UnauthorizedSigner,
#[msg("Policy already exists")]
PolicyAlreadyExists,
}
3 changes: 2 additions & 1 deletion programs/policy_engine/src/instructions/attach.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ pub fn handler(
identity_filter: IdentityFilter,
policy_type: PolicyType,
) -> Result<()> {
let policy_account_address = ctx.accounts.policy_account.key();
ctx.accounts
.policy_account
.attach(policy_type, identity_filter);
.attach(policy_account_address, policy_type, identity_filter)?;
ctx.accounts.policy_engine.update_max_timeframe(policy_type);
Ok(())
}
2 changes: 2 additions & 0 deletions programs/policy_engine/src/instructions/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ pub fn handler(
identity_filter: IdentityFilter,
policy_type: PolicyType,
) -> Result<()> {
let policy_account_address = ctx.accounts.policy_account.key();
ctx.accounts.policy_account.new(
policy_account_address,
ctx.accounts.policy_engine.key(),
identity_filter,
policy_type,
Expand Down
4 changes: 2 additions & 2 deletions programs/policy_engine/src/instructions/detach.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ pub struct DetachFromPolicyAccount<'info> {
pub system_program: Program<'info, System>,
}

pub fn handler(ctx: Context<DetachFromPolicyAccount>, policy_type: PolicyType) -> Result<()> {
ctx.accounts.policy_account.detach(policy_type);
pub fn handler(ctx: Context<DetachFromPolicyAccount>, hash: String) -> Result<()> {
let policy_type = ctx.accounts.policy_account.detach(hash)?;
// update max timeframe if detached policy was the max timeframe

let mut max_timeframe = match policy_type {
Expand Down
4 changes: 2 additions & 2 deletions programs/policy_engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ pub mod policy_engine {
/// remove policy
pub fn detach_from_policy_account(
ctx: Context<DetachFromPolicyAccount>,
policy_type: PolicyType,
hash: String,
) -> Result<()> {
instructions::detach::handler(ctx, policy_type)
instructions::detach::handler(ctx, hash)
}
}
50 changes: 43 additions & 7 deletions programs/policy_engine/src/state/account.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
pub use anchor_lang::prelude::*;
use num_enum::IntoPrimitive;

#[derive(AnchorDeserialize, AnchorSerialize, Clone, InitSpace, Copy)]
use crate::PolicyEngineErrors;

#[derive(AnchorDeserialize, AnchorSerialize, Clone, InitSpace, Copy, Debug)]
pub struct IdentityFilter {
pub identity_levels: [u8; 10],
pub comparision_type: ComparisionType,
}

#[repr(u8)]
#[derive(IntoPrimitive, AnchorDeserialize, AnchorSerialize, Clone, InitSpace, Copy)]
#[derive(IntoPrimitive, AnchorDeserialize, AnchorSerialize, Clone, InitSpace, Copy, Debug)]
pub enum ComparisionType {
Or,
And,
Expand All @@ -27,11 +29,13 @@ pub struct PolicyAccount {

#[derive(AnchorSerialize, AnchorDeserialize, Clone, InitSpace)]
pub struct Policy {
#[max_len(32)]
pub hash: String,
pub policy_type: PolicyType,
pub identity_filter: IdentityFilter,
}

#[derive(AnchorSerialize, AnchorDeserialize, Clone, InitSpace, PartialEq, Copy)]
#[derive(AnchorSerialize, AnchorDeserialize, Clone, InitSpace, PartialEq, Copy, Debug)]
pub enum PolicyType {
IdentityApproval,
TransactionAmountLimit { limit: u64 },
Expand All @@ -40,28 +44,60 @@ pub enum PolicyType {
}

impl PolicyAccount {
fn hash_policy(
policy_account: Pubkey,
policy_type: PolicyType,
identity_filter: IdentityFilter,
) -> String {
let hash = format!("{:?}{:?}{:?}", policy_account, policy_type, identity_filter);
sha256::digest(hash.as_bytes())
}
/// hash
pub fn new(
&mut self,
policy_account: Pubkey,
policy_engine: Pubkey,
identity_filter: IdentityFilter,
policy_type: PolicyType,
) {
self.version = 1;
self.policy_engine = policy_engine;
self.policies = vec![Policy {
hash: Self::hash_policy(policy_account, policy_type, identity_filter),
policy_type,
identity_filter,
}];
}
pub fn attach(&mut self, policy_type: PolicyType, identity_filter: IdentityFilter) {
pub fn attach(
&mut self,
policy_account: Pubkey,
policy_type: PolicyType,
identity_filter: IdentityFilter,
) -> Result<()> {
let hash = Self::hash_policy(policy_account, policy_type, identity_filter);
if self.policies.iter().any(|policy| policy.hash == hash) {
return Err(PolicyEngineErrors::PolicyAlreadyExists.into());
}
self.policies.push(Policy {
hash,
policy_type,
identity_filter,
});
Ok(())
}

pub fn detach(&mut self, policy_type: PolicyType) {
self.policies
.retain(|policy| policy.policy_type != policy_type);
pub fn detach(&mut self, hash: String) -> Result<PolicyType> {
if self.policies.iter().all(|policy| policy.hash != hash) {
return Err(PolicyEngineErrors::PolicyNotFound.into());
}
// remove and return the policy type
let policy_type = self
.policies
.iter()
.find(|policy| policy.hash == hash)
.unwrap() // safe to unwrap as we checked the policy exists
.policy_type;
self.policies.retain(|policy| policy.hash != hash);
Ok(policy_type)
}
}

0 comments on commit a092f80

Please sign in to comment.