Roles is now part of ProcessState out of the pcd
This commit is contained in:
parent
855cd948ef
commit
17ad1a0319
31
src/pcd.rs
31
src/pcd.rs
@ -1,7 +1,7 @@
|
||||
use anyhow::{Error, Result};
|
||||
use rs_merkle::{algorithms::Sha256, MerkleTree};
|
||||
use serde::ser::SerializeStruct;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::collections::HashSet;
|
||||
use std::hash::{Hash as StdHash, Hasher};
|
||||
use std::fmt;
|
||||
|
||||
@ -336,34 +336,6 @@ pub trait Pcd<'a>: Serialize + Deserialize<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn extract_roles(&self) -> Result<HashMap<String, RoleDefinition>> {
|
||||
let obj = self.to_value_object()?;
|
||||
|
||||
let parse_roles_map = |m: &Map<String, Value>| {
|
||||
let mut res: HashMap<String, RoleDefinition> = HashMap::new();
|
||||
for (name, role_def) in m {
|
||||
res.insert(name.clone(), serde_json::from_value(role_def.clone())?);
|
||||
}
|
||||
<Result<HashMap<String, RoleDefinition>, Error>>::Ok(res)
|
||||
};
|
||||
|
||||
if let Some(roles) = obj.get("roles") {
|
||||
match roles {
|
||||
Value::Object(m) => {
|
||||
parse_roles_map(m)
|
||||
},
|
||||
Value::String(s) => {
|
||||
let m: Map<String, Value> = serde_json::from_str(&s)?;
|
||||
|
||||
parse_roles_map(&m)
|
||||
}
|
||||
_ => Err(Error::msg("\"roles\" is not an object"))
|
||||
}
|
||||
} else {
|
||||
Err(Error::msg("No \"roles\" key in this pcd"))
|
||||
}
|
||||
}
|
||||
|
||||
fn is_hex_string(&self, length: Option<usize>) -> Result<()> {
|
||||
let value = serde_json::to_value(self)?;
|
||||
|
||||
@ -1003,7 +975,6 @@ mod tests {
|
||||
let new_state_merkle_root = Value::Object(new_state_commitments).create_merkle_tree().unwrap().root().unwrap();
|
||||
|
||||
let validation_hash = AnkValidationYesHash::from_merkle_root(new_state_merkle_root);
|
||||
// let validation_hash = AnkValidationNoHash::from_commitment(new_state_hash);
|
||||
|
||||
let alice_spend_key: SecretKey = alice_wallet
|
||||
.get_client()
|
||||
|
@ -1,5 +1,5 @@
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
collections::{BTreeMap, HashMap, HashSet},
|
||||
sync::{Mutex, MutexGuard, OnceLock},
|
||||
};
|
||||
|
||||
@ -28,10 +28,12 @@ pub struct ProcessState {
|
||||
pub validation_tokens: Vec<Proof>, // Signature of the hash of the encrypted pcd tagged with some decision like "yes" or "no"
|
||||
#[tsify(type = "Record<string, string>")]
|
||||
pub descriptions: Map<String, Value>, // long descriptions that can be used for the ihm
|
||||
#[tsify(type = "Record<string, RoleDefinition>")]
|
||||
pub roles: BTreeMap<String, RoleDefinition>,
|
||||
}
|
||||
|
||||
impl ProcessState {
|
||||
pub fn new(commited_in: OutPoint, clear_state: Map<String, Value>, descriptions: Map<String, Value>) -> anyhow::Result<Self> {
|
||||
pub fn new(commited_in: OutPoint, clear_state: Map<String, Value>, descriptions: Map<String, Value>, roles: BTreeMap<String, RoleDefinition>) -> anyhow::Result<Self> {
|
||||
// Check all descriptions matches clear_state
|
||||
for (key, _) in &descriptions {
|
||||
clear_state.get(key).ok_or(anyhow::Error::msg("Missing field in descriptions"))?;
|
||||
@ -59,6 +61,7 @@ impl ProcessState {
|
||||
keys,
|
||||
validation_tokens: vec![],
|
||||
descriptions,
|
||||
roles,
|
||||
};
|
||||
|
||||
Ok(res)
|
||||
@ -160,22 +163,11 @@ impl ProcessState {
|
||||
return Err(anyhow::anyhow!("State is identical to the previous state"));
|
||||
}
|
||||
|
||||
let roles2rules = match self.encrypted_pcd.extract_roles() {
|
||||
Ok(roles) => roles,
|
||||
Err(_) => {
|
||||
let mut fields2plains = Map::new();
|
||||
let fields2commit = self.pcd_commitment.as_object().ok_or(anyhow::Error::msg("pcd_commitment is not an object"))?;
|
||||
self.encrypted_pcd
|
||||
.decrypt_all(self.commited_in, &fields2commit, &self.keys, &mut fields2plains)?;
|
||||
|
||||
Value::Object(fields2plains).extract_roles()?
|
||||
}
|
||||
};
|
||||
|
||||
// Check if each modified field satisfies at least one applicable rule across all roles
|
||||
let all_fields_validated = modified_fields.iter().all(|field| {
|
||||
// Collect applicable rules from all roles for the current field
|
||||
let applicable_roles: Vec<RoleDefinition> = roles2rules
|
||||
let applicable_roles: Vec<RoleDefinition> = self.roles
|
||||
.iter()
|
||||
.filter_map(|(_, role_def)| {
|
||||
let mut filtered_role_def = role_def.clone();
|
||||
@ -222,19 +214,15 @@ impl ProcessState {
|
||||
}
|
||||
|
||||
pub fn get_fields_to_validate_for_member(&self, member: &Member) -> anyhow::Result<Vec<String>> {
|
||||
let decrypted = self.decrypt_pcd()?;
|
||||
|
||||
let roles = Value::Object(decrypted).extract_roles()?;
|
||||
|
||||
let mut res: HashSet<String> = HashSet::new();
|
||||
|
||||
// Are we in that role?
|
||||
for (_, role_def) in roles {
|
||||
for (_, role_def) in &self.roles {
|
||||
if !role_def.members.contains(member) {
|
||||
continue;
|
||||
} else {
|
||||
// what are the fields we can modify?
|
||||
for rule in role_def.validation_rules {
|
||||
for rule in &role_def.validation_rules {
|
||||
if rule.allows_modification() {
|
||||
res.extend(rule.fields.iter().map(|f| f.clone()));
|
||||
}
|
||||
@ -656,7 +644,7 @@ mod tests {
|
||||
let carol = Member::new(vec![carol_address]).unwrap();
|
||||
|
||||
let validation_rule1 =
|
||||
ValidationRule::new(1.0, vec!["field1".to_owned(), "roles".to_owned()], 0.5).unwrap();
|
||||
ValidationRule::new(1.0, vec!["field1".to_owned()], 0.5).unwrap();
|
||||
let validation_rule2 = ValidationRule::new(1.0, vec!["field2".to_owned()], 0.5).unwrap();
|
||||
|
||||
let role_def1 = RoleDefinition {
|
||||
@ -670,18 +658,19 @@ mod tests {
|
||||
storages: vec![]
|
||||
};
|
||||
|
||||
let roles: BTreeMap<String, RoleDefinition> = BTreeMap::from([
|
||||
("role1".to_owned(), role_def1),
|
||||
("role2".to_owned(), role_def2)
|
||||
]);
|
||||
|
||||
let clear_pcd = json!({
|
||||
"field1": "value1",
|
||||
"field2": "value2",
|
||||
"roles": {
|
||||
"role1": role_def1,
|
||||
"role2": role_def2
|
||||
}
|
||||
});
|
||||
|
||||
let outpoint = OutPoint::null();
|
||||
|
||||
ProcessState::new(outpoint, clear_pcd.as_object().unwrap().clone(), Map::new()).unwrap()
|
||||
ProcessState::new(outpoint, clear_pcd.as_object().unwrap().clone(), Map::new(), roles).unwrap()
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
x
Reference in New Issue
Block a user