1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
extern crate serde_json;
use context::Context;
use holochain_core_types::{
entry::Entry, entry_type::EntryType, error::HolochainError, validation::ValidationData,
};
use holochain_dna::wasm::DnaWasm;
use holochain_wasm_utils::api_serialization::validation::EntryValidationArgs;
use nucleus::{
ribosome::{
self,
callback::{get_dna, get_wasm, CallbackResult},
},
ZomeFnCall,
};
use std::sync::Arc;
pub fn validate_entry(
entry: Entry,
entry_type: EntryType,
validation_data: ValidationData,
context: Arc<Context>,
) -> Result<CallbackResult, HolochainError> {
match entry_type {
EntryType::App(app_entry_type) => Ok(validate_app_entry(
entry,
app_entry_type,
validation_data,
context,
)?),
EntryType::Dna => Ok(CallbackResult::Pass),
_ => Ok(CallbackResult::NotImplemented),
}
}
fn validate_app_entry(
entry: Entry,
app_entry_type: String,
validation_data: ValidationData,
context: Arc<Context>,
) -> Result<CallbackResult, HolochainError> {
let dna = get_dna(&context).expect("Callback called without DNA set!");
let zome_name = dna.get_zome_name_for_entry_type(&app_entry_type);
if zome_name.is_none() {
return Ok(CallbackResult::NotImplemented);
}
let zome_name = zome_name.unwrap();
match get_wasm(&context, &zome_name) {
Some(wasm) => {
let validation_call =
build_validation_call(entry, app_entry_type, zome_name, validation_data)?;
Ok(run_validation_callback(
context.clone(),
validation_call,
&wasm,
dna.name.clone(),
))
}
None => Ok(CallbackResult::NotImplemented),
}
}
fn build_validation_call(
entry: Entry,
entry_type: String,
zome_name: String,
validation_data: ValidationData,
) -> Result<ZomeFnCall, HolochainError> {
let params = serde_json::to_string(&EntryValidationArgs {
entry_type,
entry: entry.to_string(),
validation_data,
}).expect("EntryValidationArgs could not be turned into JSON?!");
Ok(ZomeFnCall::new(
&zome_name,
"no capability, since this is an entry validation call",
"__hdk_validate_app_entry",
¶ms,
))
}
fn run_validation_callback(
context: Arc<Context>,
fc: ZomeFnCall,
wasm: &DnaWasm,
dna_name: String,
) -> CallbackResult {
match ribosome::run_dna(
&dna_name,
context,
wasm.code.clone(),
&fc,
Some(fc.clone().parameters.into_bytes()),
) {
Ok(call_result) => match call_result.is_empty() {
true => CallbackResult::Pass,
false => CallbackResult::Fail(call_result),
},
Err(HolochainError::RibosomeFailed(error_string)) => {
if error_string == "Argument deserialization failed" {
CallbackResult::Fail(String::from("JSON object does not match entry schema"))
} else {
CallbackResult::Fail(error_string)
}
}
Err(error) => CallbackResult::Fail(error.to_string()),
}
}