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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use agent::actions::commit::*;
use futures::{executor::block_on, FutureExt};
use holochain_core_types::{
cas::content::Address,
entry::Entry,
entry_type::EntryType,
error::HolochainError,
hash::HashString,
validation::{EntryAction, EntryLifecycle, ValidationData},
};
use holochain_wasm_utils::api_serialization::commit::{CommitEntryArgs, CommitEntryResult};
use nucleus::{
actions::{build_validation_package::*, validate::*},
ribosome::Runtime,
};
use serde_json;
use std::str::FromStr;
use wasmi::{RuntimeArgs, RuntimeValue, Trap};
pub fn invoke_commit_app_entry(
runtime: &mut Runtime,
args: &RuntimeArgs,
) -> Result<Option<RuntimeValue>, Trap> {
let args_str = runtime.load_utf8_from_args(&args);
let input: CommitEntryArgs = match serde_json::from_str(&args_str) {
Ok(entry_input) => entry_input,
Err(_) => return ribosome_error_code!(ArgumentDeserializationFailed),
};
let entry_type =
EntryType::from_str(&input.entry_type_name).expect("could not create EntryType from str");
let entry = Entry::new(&entry_type, &input.entry_value);
let task_result: Result<Address, HolochainError> = block_on(
build_validation_package(&entry, &runtime.context)
.and_then(|validation_package| {
Ok(ValidationData {
package: validation_package,
sources: vec![HashString::from("<insert your agent key here>")],
lifecycle: EntryLifecycle::Chain,
action: EntryAction::Commit,
})
})
.and_then(|validation_data| {
validate_entry(
entry_type.clone(),
entry.clone(),
validation_data,
&runtime.context)
})
.and_then(|_| commit_entry(entry.clone(), &runtime.context.action_channel, &runtime.context)),
);
let maybe_json = match task_result {
Ok(address) => serde_json::to_string(&CommitEntryResult::success(address)),
Err(HolochainError::ValidationFailed(fail_string)) => {
serde_json::to_string(&CommitEntryResult::failure(fail_string))
}
Err(error_string) => {
let error_report = ribosome_error_report!(format!(
"Call to `hc_commit_entry()` failed: {}",
error_string
));
serde_json::to_string(&error_report.to_string())
}
};
match maybe_json {
Ok(json) => runtime.store_utf8(&json),
Err(_) => ribosome_error_code!(ResponseSerializationFailed),
}
}
#[cfg(test)]
pub mod tests {
extern crate test_utils;
extern crate wabt;
use holochain_core_types::{
cas::content::AddressableContent, entry::test_entry, entry_type::test_entry_type,
};
use nucleus::ribosome::{
api::{commit::CommitEntryArgs, tests::test_zome_api_function, ZomeApiFunction},
Defn,
};
use serde_json;
pub fn test_commit_args_bytes() -> Vec<u8> {
let entry_type = test_entry_type();
let entry = test_entry();
let args = CommitEntryArgs {
entry_type_name: entry_type.to_string(),
entry_value: entry.value().to_owned(),
};
serde_json::to_string(&args)
.expect("args should serialize")
.into_bytes()
}
#[test]
fn test_commit_round_trip() {
let (call_result, _) = test_zome_api_function(
ZomeApiFunction::CommitAppEntry.as_str(),
test_commit_args_bytes(),
);
assert_eq!(
call_result,
format!(
r#"{{"address":"{}","validation_failure":""}}"#,
test_entry().address()
) + "\u{0}",
);
}
}