Refactor ProcessState validation logic

This commit is contained in:
NicolasCantu 2025-03-26 12:37:12 +01:00
parent 491f260374
commit afc40b4395

View File

@ -132,28 +132,48 @@ impl ProcessState {
)); ));
} }
if self.validation_tokens.get(0).unwrap().get_message() == OBLITERATION_MSG { // We first handle obliteration
// We're dealing with a destruction update if self.state_id == [0u8; 32] {
return self.handle_obliteration(members_list); if let Some(prev_state) = previous_state {
} if let Some(apophis) = prev_state.roles.get(APOPHIS) {
return self.handle_obliteration(apophis, members_list);
// Compute modified fields }
let modified_fields = self.list_modified_fields(previous_state); }
return Err(anyhow::anyhow!("Can't find apophis"));
if modified_fields.is_empty() { // then pairing
return Err(anyhow::anyhow!("State is identical to the previous state")); } else if let Some(pairing_role) = self.roles.get(PAIRING) {
if self.pcd_commitment.contains_key(PAIREDADDRESSES) {
if let Some(prev_state) = previous_state {
let prev_paired_addresses = prev_state.public_data.get(PAIREDADDRESSES).ok_or(anyhow::Error::msg("Missing pairedAddresses"))?;
let paired_addresses = extract_paired_addresses(prev_paired_addresses)?;
return self.handle_pairing(pairing_role.clone(), paired_addresses);
} else {
// We are in a creation
return self.handle_pairing(pairing_role.clone(), vec![]);
}
}
// If we don't update pairedAddresses, we don't need to bother about pairing
} }
// 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 = modified_fields.iter().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<RoleDefinition> = self.roles let applicable_roles: Vec<RoleDefinition> = self.roles
.iter() .iter()
.filter_map(|(role_name, role_def)| { .filter_map(|(role_name, role_def)| {
// We allow for a special case with a role that works only for initial state if let Ok(special_role) = SpecialRoles::from_str(&role_name) {
// That's optional though match special_role {
if previous_state.is_some() && *role_name == crate::SpecialRoles::DEMIURGE.to_string() { return None; } // We allow for a special case with a role that works only for initial state
if *role_name == crate::SpecialRoles::APOPHIS.to_string() { return None; } // We handle destructions separately // That's optional though
SpecialRoles::Demiurge => {
// If we're not in initial state just ignore it
if previous_state.is_some() { 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 mut filtered_role_def = role_def.clone();
let rules = filtered_role_def.get_applicable_rules(field); let rules = filtered_role_def.get_applicable_rules(field);
filtered_role_def.validation_rules = filtered_role_def.validation_rules =