Refactor ProcessState validation logic
This commit is contained in:
parent
491f260374
commit
afc40b4395
@ -132,28 +132,48 @@ impl ProcessState {
|
||||
));
|
||||
}
|
||||
|
||||
if self.validation_tokens.get(0).unwrap().get_message() == OBLITERATION_MSG {
|
||||
// We're dealing with a destruction update
|
||||
return self.handle_obliteration(members_list);
|
||||
}
|
||||
|
||||
// Compute modified fields
|
||||
let modified_fields = self.list_modified_fields(previous_state);
|
||||
|
||||
if modified_fields.is_empty() {
|
||||
return Err(anyhow::anyhow!("State is identical to the previous state"));
|
||||
// We first handle obliteration
|
||||
if self.state_id == [0u8; 32] {
|
||||
if let Some(prev_state) = previous_state {
|
||||
if let Some(apophis) = prev_state.roles.get(APOPHIS) {
|
||||
return self.handle_obliteration(apophis, members_list);
|
||||
}
|
||||
}
|
||||
return Err(anyhow::anyhow!("Can't find apophis"));
|
||||
// then pairing
|
||||
} 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
|
||||
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
|
||||
let applicable_roles: Vec<RoleDefinition> = self.roles
|
||||
.iter()
|
||||
.filter_map(|(role_name, role_def)| {
|
||||
// We allow for a special case with a role that works only for initial state
|
||||
// That's optional though
|
||||
if previous_state.is_some() && *role_name == crate::SpecialRoles::DEMIURGE.to_string() { return None; }
|
||||
if *role_name == crate::SpecialRoles::APOPHIS.to_string() { return None; } // We handle destructions separately
|
||||
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; }
|
||||
// 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 =
|
||||
|
Loading…
x
Reference in New Issue
Block a user