Update ValidationRule is_satisfied()
This commit is contained in:
parent
e60ef13133
commit
2c92c9340c
60
src/pcd.rs
60
src/pcd.rs
@ -20,7 +20,7 @@ use tsify::Tsify;
|
||||
|
||||
use crate::{
|
||||
crypto::AAD,
|
||||
signature::{AnkValidationNoHash, AnkValidationYesHash, Proof},
|
||||
signature::{AnkHash, AnkValidationNoHash, AnkValidationYesHash, Proof},
|
||||
};
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, Tsify)]
|
||||
@ -317,13 +317,15 @@ impl ValidationRule {
|
||||
pub fn is_satisfied(
|
||||
&self,
|
||||
field: &str,
|
||||
new_state_hash: AnkPcdHash,
|
||||
merkle_root: [u8; 32],
|
||||
proofs: &[Proof],
|
||||
members: &[Member],
|
||||
) -> bool {
|
||||
) -> Result<()> {
|
||||
// Check if this rule applies to the field
|
||||
if !self.fields.contains(&field.to_string()) || members.is_empty() {
|
||||
return false;
|
||||
if !self.fields.contains(&field.to_string()) {
|
||||
return Err(Error::msg("Field isn't part of this rule"));
|
||||
} else if members.is_empty() {
|
||||
return Err(Error::msg("Members list is empty"));
|
||||
}
|
||||
|
||||
let required_members = (members.len() as f32 * self.quorum).ceil() as usize;
|
||||
@ -335,18 +337,18 @@ impl ValidationRule {
|
||||
.filter(|p| member.key_is_part_of_member(&p.get_key()))
|
||||
.collect();
|
||||
|
||||
self.satisfy_min_sig_member(member, new_state_hash, &member_proofs)
|
||||
self.satisfy_min_sig_member(member, merkle_root, &member_proofs)
|
||||
.is_ok()
|
||||
})
|
||||
.count();
|
||||
|
||||
validating_members >= required_members
|
||||
if validating_members >= required_members { Ok(()) } else { Err(Error::msg("Not enough members to validate"))}
|
||||
}
|
||||
|
||||
pub fn satisfy_min_sig_member(
|
||||
&self,
|
||||
member: &Member,
|
||||
new_state_hash: AnkPcdHash,
|
||||
merkle_root: [u8; 32],
|
||||
proofs: &[&Proof],
|
||||
) -> Result<()> {
|
||||
if proofs.len() == 0 {
|
||||
@ -369,9 +371,8 @@ impl ValidationRule {
|
||||
let mut yes_votes: Vec<Proof> = Vec::new();
|
||||
let mut no_votes: Vec<Proof> = Vec::new();
|
||||
|
||||
// Compute both yes and no commitment
|
||||
let yes = AnkValidationYesHash::from_commitment(new_state_hash).to_byte_array();
|
||||
let no = AnkValidationNoHash::from_commitment(new_state_hash).to_byte_array();
|
||||
let yes = AnkHash::ValidationYes(AnkValidationYesHash::from_byte_array(merkle_root));
|
||||
let no = AnkHash::ValidationNo(AnkValidationNoHash::from_byte_array(merkle_root));
|
||||
|
||||
// Validate proofs here
|
||||
for proof in proofs {
|
||||
@ -381,9 +382,9 @@ impl ValidationRule {
|
||||
|
||||
let signed_message = proof.get_message();
|
||||
|
||||
if signed_message == yes {
|
||||
if signed_message == yes.to_byte_array() {
|
||||
yes_votes.push(**proof);
|
||||
} else if signed_message == no {
|
||||
} else if signed_message == no.to_byte_array() {
|
||||
no_votes.push(**proof);
|
||||
} else {
|
||||
return Err(Error::msg("We don't know what this proof signs for"));
|
||||
@ -407,33 +408,20 @@ pub struct RoleDefinition {
|
||||
impl RoleDefinition {
|
||||
pub fn is_satisfied(
|
||||
&self,
|
||||
new_state: &Value,
|
||||
previous_state: &Value,
|
||||
diff: Vec<String>,
|
||||
new_state_merkle_root: [u8; 32],
|
||||
proofs: &[Proof],
|
||||
) -> bool {
|
||||
// compute the modified fields
|
||||
let modified_fields: Vec<String> = new_state
|
||||
.as_object()
|
||||
.unwrap()
|
||||
.iter()
|
||||
.filter_map(|(key, value)| {
|
||||
let previous_value = previous_state.as_object().unwrap().get(key);
|
||||
if previous_value.is_none() || value != previous_value.unwrap() {
|
||||
Some(key.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let new_state_hash = AnkPcdHash::from_value(new_state);
|
||||
|
||||
// check that for each field we can satisfy at least one rule
|
||||
modified_fields.iter().all(|field| {
|
||||
) -> Result<()> {
|
||||
if diff.iter().all(|field| {
|
||||
self.validation_rules
|
||||
.iter()
|
||||
.any(|rule| rule.is_satisfied(field, new_state_hash, proofs, &self.members))
|
||||
.any(|rule| rule.is_satisfied(field, new_state_merkle_root, proofs, &self.members).is_ok())
|
||||
})
|
||||
{
|
||||
Ok(())
|
||||
} else {
|
||||
Err(Error::msg("Failed to validate all rules"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_applicable_rules(&self, field: &str) -> Vec<&ValidationRule> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user