Compare commits
No commits in common. "dab1a4dd2cc286ca51e9411eec811734ab581dad" and "922cf2aa53b8f610e4b5f7c895ef851637c679f0" have entirely different histories.
dab1a4dd2c
...
922cf2aa53
@ -654,10 +654,6 @@ impl Roles {
|
|||||||
pub fn iter_mut(&mut self) -> std::collections::btree_map::IterMut<'_, String, RoleDefinition> {
|
pub fn iter_mut(&mut self) -> std::collections::btree_map::IterMut<'_, String, RoleDefinition> {
|
||||||
self.0.iter_mut()
|
self.0.iter_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&mut self, key: String, value: RoleDefinition) -> Option<RoleDefinition> {
|
|
||||||
self.0.insert(key, value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use std::collections::{BTreeMap, HashMap, HashSet};
|
use std::collections::{BTreeMap, HashMap, HashSet};
|
||||||
|
use std::str::FromStr;
|
||||||
use std::sync::{Mutex, MutexGuard, OnceLock};
|
use std::sync::{Mutex, MutexGuard, OnceLock};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -13,7 +14,7 @@ use crate::{
|
|||||||
pcd::{Member, Pcd, PcdCommitments, RoleDefinition, Roles, ValidationRule},
|
pcd::{Member, Pcd, PcdCommitments, RoleDefinition, Roles, ValidationRule},
|
||||||
serialization::{deserialize_hex, hex_array_btree, serialize_hex, OutPointMemberMap},
|
serialization::{deserialize_hex, hex_array_btree, serialize_hex, OutPointMemberMap},
|
||||||
signature::{AnkHash, AnkValidationNoHash, AnkValidationYesHash, Proof},
|
signature::{AnkHash, AnkValidationNoHash, AnkValidationYesHash, Proof},
|
||||||
MutexExt, APOPHIS, PAIREDADDRESSES, PAIRING,
|
MutexExt, SpecialRoles, APOPHIS, PAIREDADDRESSES, PAIRING,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, Tsify)]
|
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize, Tsify)]
|
||||||
@ -235,61 +236,55 @@ impl ProcessState {
|
|||||||
// If we don't update pairedAddresses, we don't need to bother about pairing
|
// If we don't update pairedAddresses, we don't need to bother about pairing
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.pcd_commitment.is_empty() {
|
|
||||||
return Err(anyhow::anyhow!("No fields to validate"));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut roles = self.roles.clone();
|
|
||||||
|
|
||||||
// If we're initial state, we add the demiurge role, otherwise we can just ignore it
|
|
||||||
if previous_state.is_none() {
|
|
||||||
if let Some(demiurge) = roles.get(crate::DEMIURGE) {
|
|
||||||
match self.handle_demiurge(demiurge) {
|
|
||||||
Ok(role) => {
|
|
||||||
log::debug!("Adding demiurge role: {:?}", role);
|
|
||||||
roles.insert(crate::DEMIURGE.to_string(), role);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
log::debug!("{}", e.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log::debug!("No demiurge role for initial state");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log::debug!("Not initial state, ignoring demiurge role");
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut error_msg = String::new();
|
|
||||||
|
|
||||||
log::debug!("Checking fields for roles: {:?}", roles);
|
|
||||||
|
|
||||||
// Check if each modified field satisfies at least one applicable rule across all roles
|
// Check if each modified field satisfies at least one applicable rule across all roles
|
||||||
let all_fields_validated: bool = self.pcd_commitment.keys().all(|field| {
|
let all_fields_validated = !self.pcd_commitment.is_empty()
|
||||||
|
&& self.pcd_commitment.keys().all(|field| {
|
||||||
// Collect applicable rules from all roles for the current field
|
// Collect applicable rules from all roles for the current field
|
||||||
let applicable_roles: Vec<(String, RoleDefinition)> = roles.clone()
|
let applicable_roles: Vec<RoleDefinition> = self
|
||||||
.into_iter()
|
.roles
|
||||||
.filter_map(|(role_name, mut role_def)| {
|
.iter()
|
||||||
let rules = role_def.get_applicable_rules(field);
|
.filter_map(|(role_name, role_def)| {
|
||||||
role_def.validation_rules =
|
if let Ok(special_role) = SpecialRoles::from_str(&role_name) {
|
||||||
|
match special_role {
|
||||||
|
// We allow for a special case with a role that works only for initial state
|
||||||
|
// That's optional though
|
||||||
|
SpecialRoles::Demiurge => {
|
||||||
|
// If we're not in initial state just ignore it
|
||||||
|
if previous_state.is_some() {
|
||||||
|
return None;
|
||||||
|
} else {
|
||||||
|
// We try to validate with demiurge
|
||||||
|
match self.handle_demiurge(role_def) {
|
||||||
|
Ok(role) => return Some(role),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("{}", e.to_string());
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Otherwise we just continue normal validation
|
||||||
|
}
|
||||||
|
// We already handled other special roles
|
||||||
|
_ => return None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut filtered_role_def = role_def.clone();
|
||||||
|
let rules = filtered_role_def.get_applicable_rules(field);
|
||||||
|
filtered_role_def.validation_rules =
|
||||||
rules.into_iter().map(|r| r.clone()).collect();
|
rules.into_iter().map(|r| r.clone()).collect();
|
||||||
if role_def.validation_rules.is_empty() {
|
if filtered_role_def.validation_rules.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some((role_name.clone(), role_def))
|
Some(filtered_role_def)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if applicable_roles.is_empty() {
|
if applicable_roles.is_empty() {
|
||||||
error_msg = format!("No relevant roles for field: {}", field);
|
return false; // No rules apply to this field, consider it invalid
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tested_roles = vec![];
|
applicable_roles.into_iter().any(|role_def| {
|
||||||
|
|
||||||
if let Some((role_name, _valid_role)) = applicable_roles.into_iter().find(|(role_name, role_def)| {
|
|
||||||
tested_roles.push(role_name.clone());
|
|
||||||
role_def.validation_rules.iter().any(|rule| {
|
role_def.validation_rules.iter().any(|rule| {
|
||||||
let members: Vec<&Member> = role_def
|
let members: Vec<&Member> = role_def
|
||||||
.members
|
.members
|
||||||
@ -304,19 +299,13 @@ impl ProcessState {
|
|||||||
)
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
})
|
})
|
||||||
}) {
|
})
|
||||||
log::debug!("Validated field {} with role: {}", field, role_name);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
error_msg = format!("Failed validation for field {} in roles: {:?}", field, tested_roles);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if all_fields_validated {
|
if all_fields_validated {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow::anyhow!("Not enough valid proofs: {}", error_msg))
|
Err(anyhow::anyhow!("Not enough valid proofs"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -971,7 +960,7 @@ mod tests {
|
|||||||
.push(Proof::new(message_hash, signing_key));
|
.push(Proof::new(message_hash, signing_key));
|
||||||
let result = state.is_valid(None, &OutPointMemberMap(get_members_map()));
|
let result = state.is_valid(None, &OutPointMemberMap(get_members_map()));
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs: Failed validation for field field1 in roles: [\"demiurge\", \"role1\"]");
|
assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -986,7 +975,7 @@ mod tests {
|
|||||||
.push(Proof::new(message_hash, carol_key));
|
.push(Proof::new(message_hash, carol_key));
|
||||||
let result = state.is_valid(None, &OutPointMemberMap(get_members_map()));
|
let result = state.is_valid(None, &OutPointMemberMap(get_members_map()));
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs: Failed validation for field field1 in roles: [\"demiurge\", \"role1\"]");
|
assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1336,7 +1325,7 @@ mod tests {
|
|||||||
&OutPointMemberMap(get_members_map()),
|
&OutPointMemberMap(get_members_map()),
|
||||||
);
|
);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs: Failed validation for field field2 in roles: [\"role2\"]");
|
assert_eq!(result.unwrap_err().to_string(), "Not enough valid proofs");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user