Skip to content

Commit

Permalink
Merge pull request #39 from holonauts/validation_new
Browse files Browse the repository at this point in the history
Validation
  • Loading branch information
dauphin3 authored Mar 1, 2024
2 parents f68195a + 30303b6 commit f296ff4
Show file tree
Hide file tree
Showing 9 changed files with 162 additions and 34 deletions.
9 changes: 0 additions & 9 deletions dnas/grant_pools/zomes/coordinator/grants/src/evaluation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,3 @@ pub fn get_evaluations_for_application_by_agent(
.filter(|l| l.author == input.agent)
.collect())
}
pub fn get_score_for_evaluation(evaluation: Evaluation) -> u64 {
match evaluation.score {
Score::Single(score) => score,
Score::Weighted(vec) => {
let total: u64 = vec.iter().map(|score| score.value * score.weight).sum();
total
}
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use crate::evaluation::{get_evaluation, get_score_for_evaluation};
use crate::evaluation::get_evaluation;
use alloy_primitives::U256;
use grants_integrity::GrantPoolOutcome;
use grants_integrity::*;
use grants_integrity::{calc_absolute_score, get_score_for_evaluation, GrantPoolOutcome};
use hdk::prelude::*;
use rust_decimal::Decimal;
use std::collections::BTreeMap;
#[hdk_extern]
pub fn create_grant_pool_outcome_for_grant_pool(grant_pool: ActionHash) -> ExternResult<Record> {
Expand Down Expand Up @@ -54,17 +53,18 @@ pub fn create_grant_pool_outcome_for_grant_pool(grant_pool: ActionHash) -> Exter
let score = get_score_for_evaluation(evaluation.clone());
evaluation_scores.push(score);
}
let num_evals = evaluation_scores.clone().len();

let absolute_score = AbsoluteScore {
application: app_action_hash.clone(),
score: Decimal::from(evaluation_scores.iter().sum::<u64>())
/ Decimal::from(links_for_evaluations.len()),
score: calc_absolute_score(evaluation_scores, num_evals),
};

absolute_scores.push(absolute_score);
grant_pool_evaluations.insert(app_action_hash, evaluation_action_hashes);
}
absolute_scores.sort_by(|a, b| b.score.cmp(&a.score));
// TODO: Coupon
let coupon = Vec::new();
let grant_pool_outcome = GrantPoolOutcome {
grant_pool,
Expand Down
23 changes: 21 additions & 2 deletions dnas/grant_pools/zomes/integrity/grants/src/agent_to_evm_wallet.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
use alloy_primitives::Address;
use hdi::prelude::*;

pub fn validate_create_link_agent_to_evm_wallet(
_action: CreateLink,
_base_address: AnyLinkableHash,
_target_address: AnyLinkableHash,
base_address: AnyLinkableHash,
target_address: AnyLinkableHash,
_tag: LinkTag,
) -> ExternResult<ValidateCallbackResult> {
let evm_address = String::from_utf8(target_address.into_inner()).map_err(|e| {
wasm_error!(WasmErrorInner::Guest(format!(
"Error converting target address to string: {:?}",
e
)))
})?;
if !AgentPubKey::try_from(base_address).is_ok() {
return Ok(ValidateCallbackResult::Invalid(
"Can only link wallet from an AgentPubKey".to_string(),
));
}
if !Address::parse_checksummed(&evm_address, None).is_ok() {
return Ok(ValidateCallbackResult::Invalid(
"Can only link to valid evm address".to_string(),
));
}

Ok(ValidateCallbackResult::Valid)
}
pub fn validate_delete_link_agent_to_evm_wallet(
Expand Down
74 changes: 70 additions & 4 deletions dnas/grant_pools/zomes/integrity/grants/src/evaluation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use crate::{EvaluationTemplate, ScoreTemplate};
use hdi::prelude::*;
use rust_decimal::Decimal;
use std::iter::zip;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, SerializedBytes)]
pub struct AttributeScore {
pub label: String,
Expand All @@ -19,21 +22,36 @@ pub struct Evaluation {
pub comments: String,
pub score: Score,
}

pub fn get_score_for_evaluation(evaluation: Evaluation) -> u64 {
match evaluation.score {
Score::Single(score) => score,
Score::Weighted(vec) => {
let total: u64 = vec.iter().map(|score| score.value * score.weight).sum();
total
}
}
}

pub fn calc_absolute_score(raw_scores: Vec<u64>, num_evals: usize) -> Decimal {
Decimal::from(raw_scores.iter().sum::<u64>()) / Decimal::from(num_evals)
}

pub fn validate_create_evaluation(
action: EntryCreationAction,
evaluation: Evaluation,
) -> ExternResult<ValidateCallbackResult> {
let record = must_get_valid_record(evaluation.application.clone())?;
let application: crate::Application = record
let app_record = must_get_valid_record(evaluation.application.clone())?;
let application: crate::Application = app_record
.entry()
.to_app_option()
.map_err(|e| wasm_error!(e))?
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"Dependant action must be accompanied by an entry"
))))?;

let record = must_get_valid_record(application.grant_pool)?;
let grant_pool: crate::GrantPool = record
let pool_record = must_get_valid_record(application.grant_pool)?;
let grant_pool: crate::GrantPool = pool_record
.entry()
.to_app_option()
.map_err(|e| wasm_error!(e))?
Expand All @@ -47,6 +65,54 @@ pub fn validate_create_evaluation(
));
}

let eval_template_record = must_get_valid_record(grant_pool.evaluation_template)?;
let evaluation_template: EvaluationTemplate = eval_template_record
.entry()
.to_app_option()
.map_err(|e| wasm_error!(e))?
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"Dependant action must be accompanied by an entry"
))))?;

match evaluation.score {
Score::Single(_) => {
if evaluation_template.score != ScoreTemplate::Single {
return Ok(ValidateCallbackResult::Invalid(
"Evaluation score must match template".into(),
));
}
}
Score::Weighted(mut scores) => match evaluation_template.score {
ScoreTemplate::Single => {
return Ok(ValidateCallbackResult::Invalid(
"Evaluation score must match template".into(),
));
}
ScoreTemplate::Weighted(mut scores_template) => {
if scores.len() != scores_template.len() {
return Ok(ValidateCallbackResult::Invalid(
"Evaluation score must match template".into(),
));
}
scores.sort_by_key(|s| s.label.clone());
scores_template.sort_by_key(|s| s.label.clone());
let iter = zip(scores, scores_template);
for item in iter {
if item.0.label != item.1.label {
return Ok(ValidateCallbackResult::Invalid(
"Evaluation score must match template".into(),
));
}
if item.0.weight != item.1.weight {
return Ok(ValidateCallbackResult::Invalid(
"Evaluation score must match template".into(),
));
}
}
}
},
}

Ok(ValidateCallbackResult::Valid)
}
pub fn validate_update_evaluation(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use hdi::prelude::*;
use serde_json::Value;
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, SerializedBytes)]
pub struct NumberRange {
min: u32,
max: u32,
pub min: u32,
pub max: u32,
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, SerializedBytes)]
pub struct AttributeScoreTemplate {
label: String,
weight: u32,
pub label: String,
pub weight: u64,
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq, SerializedBytes)]
#[serde(tag = "type", content = "content")]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use hdi::prelude::*;
pub fn validate_create_link_evaluator_to_applications(
_action: CreateLink,
_base_address: AnyLinkableHash,
base_address: AnyLinkableHash,
target_address: AnyLinkableHash,
_tag: LinkTag,
) -> ExternResult<ValidateCallbackResult> {
Expand All @@ -19,6 +19,12 @@ pub fn validate_create_link_evaluator_to_applications(
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"Linked action must reference an entry"
))))?;
if !AgentPubKey::try_from(base_address).is_ok() {
return Ok(ValidateCallbackResult::Invalid(
"Can only evaluator from an AgentPubKey".to_string(),
));
}

Ok(ValidateCallbackResult::Valid)
}
pub fn validate_delete_link_evaluator_to_applications(
Expand All @@ -35,7 +41,7 @@ pub fn validate_delete_link_evaluator_to_applications(
pub fn validate_create_link_application_to_evaluators(
_action: CreateLink,
base_address: AnyLinkableHash,
_target_address: AnyLinkableHash,
target_address: AnyLinkableHash,
_tag: LinkTag,
) -> ExternResult<ValidateCallbackResult> {
// Check the entry type for the given action hash
Expand All @@ -52,7 +58,12 @@ pub fn validate_create_link_application_to_evaluators(
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"Linked action must reference an entry"
))))?;
// TODO: add the appropriate validation rules
if !AgentPubKey::try_from(target_address).is_ok() {
return Ok(ValidateCallbackResult::Invalid(
"Can only link application to valid evaluator AgentPubKey".to_string(),
));
}

Ok(ValidateCallbackResult::Valid)
}
pub fn validate_delete_link_application_to_evaluators(
Expand Down
46 changes: 40 additions & 6 deletions dnas/grant_pools/zomes/integrity/grants/src/grant_pool_outcome.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::Evaluation;
use crate::{calc_absolute_score, get_score_for_evaluation, Evaluation};
use alloy_primitives::U256;
use hdi::prelude::*;
use rust_decimal::Decimal;
use std::collections::BTreeMap;
use std::iter::zip;
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct AbsoluteScore {
pub application: ActionHash,
Expand Down Expand Up @@ -34,21 +35,54 @@ pub fn validate_create_grant_pool_outcome(
"Only grant pool author can create an outcome".to_string(),
));
}
for (application, evaluations) in grant_pool_outcome.evaluations.clone() {
must_get_valid_record(application.clone())?;
for evaluation_action_hash in evaluations {
let record = must_get_valid_record(evaluation_action_hash.clone())?;
let _evaluation: Evaluation = record
let mut ranked_list = grant_pool_outcome.ranked_list.clone();
let mut absolute_scores = Vec::new();
for (app_action_hash, evaluation_action_hashes) in grant_pool_outcome.evaluations.clone() {
must_get_valid_record(app_action_hash.clone())?;
let mut raw_scores = Vec::new();
for eval_action_hash in evaluation_action_hashes.clone() {
let record = must_get_valid_record(eval_action_hash.clone())?;
let evaluation: Evaluation = record
.entry()
.to_app_option()
.map_err(|e| wasm_error!(e))?
.ok_or(wasm_error!(WasmErrorInner::Guest(String::from(
"Dependant action must be accompanied by an entry"
))))?;

let score = get_score_for_evaluation(evaluation.clone());
raw_scores.push(score);
}
let absolute_score = AbsoluteScore {
application: app_action_hash.clone(),
score: calc_absolute_score(raw_scores, evaluation_action_hashes.clone().len()),
};
absolute_scores.push(absolute_score);
}
if grant_pool_outcome.evaluations.len() != ranked_list.len() {
return Ok(ValidateCallbackResult::Invalid(
"Ranked list must be same length as number of applications evaluated".into(),
));
}
absolute_scores.sort_by_key(|s| s.application.clone());
ranked_list.sort_by_key(|s| s.application.clone());
let iter = zip(absolute_scores, ranked_list);
for item in iter {
if item.0.application != item.1.application {
return Ok(ValidateCallbackResult::Invalid(
"Ordered list of applications don't match".into(),
));
}
if item.0.score != item.1.score {
return Ok(ValidateCallbackResult::Invalid(
"Absolute scores don't match".into(),
));
}
}

Ok(ValidateCallbackResult::Valid)
}

pub fn validate_update_grant_pool_outcome(
_action: Update,
_grant_pool_outcome: GrantPoolOutcome,
Expand Down
1 change: 1 addition & 0 deletions dnas/grant_pools/zomes/integrity/grants/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub enum LinkTypes {
EvaluatorToApplications,
ApplicationToEvaluators,
}

#[hdk_extern]
pub fn genesis_self_check(_data: GenesisSelfCheckData) -> ExternResult<ValidateCallbackResult> {
Ok(ValidateCallbackResult::Valid)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
use alloy_primitives::U256;
use hdi::prelude::*;
pub fn validate_create_link_sponsor_to_grant_pool(
_action: CreateLink,
_base_address: AnyLinkableHash,
target_address: AnyLinkableHash,
_tag: LinkTag,
tag: LinkTag,
) -> ExternResult<ValidateCallbackResult> {
if U256::from_le_slice(&tag.into_inner()) == U256::from(0) {
return Ok(ValidateCallbackResult::Invalid(
"amount cannot be zero".to_string(),
));
}
let action_hash =
target_address
.into_action_hash()
Expand Down

0 comments on commit f296ff4

Please sign in to comment.