redgold_executor/
extism_wrapper.rs1use extism::{Context, Plugin};
2
3use redgold_schema::helpers::easy_json::EasyJson;
4use redgold_schema::observability::errors::EnhanceErrorInfo;
5use redgold_schema::proto_serde::ProtoSerde;
6use redgold_schema::structs::{ExecutionInput, ExecutionResult, TestContractInternalState, TestContractRequest, TestContractUpdate2};
7use redgold_schema::{bytes_data, error_info, ErrorInfoContext, RgResult};
8
9pub async fn invoke_wasm(
10 wasm_bytes: &[u8],
11 function_name: impl Into<String>,
12 args: ExecutionInput
13) -> RgResult<ExecutionResult> {
14 let context = Context::new();
15 let mut plugin = Plugin::new(
16 &context,
17 wasm_bytes,
18 vec![],
19 false
20 ).map_err(|e|
21 error_info(
22 format!("Unable to build plugin while invoking wasm {}", e.to_string())))?;
23
24 let fname = function_name.into();
25 let has = plugin.has_function(fname.clone());
26 if !has {
27 return Err(error_info(format!("Function not found {}", fname.clone())))?
28 }
29 let data = plugin.call(fname.clone(), args.proto_serialize())
30 .map_err(|e|
31 error_info(
32 format!("Error calling function {}", e.to_string())))
33 .add(fname.clone())?;
34 ExecutionResult::proto_deserialize(data.to_vec())
35}
36
37pub async fn invoke_extism_wasm(
38 wasm_bytes: &[u8],
39 args: ExecutionInput
40) -> RgResult<ExecutionResult> {
41 invoke_wasm(wasm_bytes, "extism_entrypoint", args).await
42}
43
44pub async fn invoke_extism_wasm_direct(
46 wasm_bytes: impl AsRef<[u8]>,
47 input: &Vec<u8>,
48 state: &Vec<u8>
49) -> RgResult<ExecutionResult> {
50 let mut args = ExecutionInput::default();
51 args.input = bytes_data(input.clone());
52 args.state = bytes_data(state.clone());
53 invoke_wasm(wasm_bytes.as_ref(), "extism_entrypoint", args).await
54}
55
56
57#[ignore]
58#[tokio::test]
59async fn extism_direct_test() {
60 let wasm = std::fs::read("../sdk/test_contract_guest.wasm").expect("");
62
63 let res_g = invoke_wasm(
64 &*wasm, "extism_entrypoint", ExecutionInput::default()
65 ).await.unwrap();
66 let gen_state = res_g.data.expect("d").state;
67 let gen_state_deser = TestContractInternalState::proto_deserialize
68 (gen_state.clone().expect("s").value).expect("");
69 let res = gen_state_deser.json_or();
70 println!("initial result genesis: {}", res);
71
72 let mut input = ExecutionInput::default();
73 let mut req = TestContractRequest::default();
74 let mut update2 = TestContractUpdate2::default();
75 update2.value = "UPDATED".to_string();
76 req.test_contract_update2 = Some(update2);
77 input.input = bytes_data(req.proto_serialize());
78 input.state = gen_state.clone();
79
80 let res = invoke_wasm(&*wasm, "extism_entrypoint", input).await.unwrap();
81 println!("Exec result: {}", res.json_or());
82
83 let done_state = res.data.clone().expect("d").state;
84 let done_state_deser = TestContractInternalState::proto_deserialize
85 (done_state.clone().expect("s").value).expect("");
86 let resr = done_state_deser.json_or();
87 println!("final result after: {}", resr);
88
89 assert!(res.valid);
91}
92
93
94#[ignore]
95#[tokio::test]
96async fn proto_test() {
97 let wasm = std::fs::read("../sdk/test_contract_guest.wasm").expect("");
99 let input = ExecutionInput::default();
100 let res = invoke_wasm(&*wasm, "extism_entrypoint", input).await.unwrap();
101 println!("Exec result: {}", res.json_or());
102 assert!(res.valid);
104}
105
106#[ignore]
107#[test]
108fn debug_test() {
109
110 let context = Context::new();
111 let wasm = std::fs::read("../../sdk/test_contract_guest.wasm").expect("");
113 let mut plugin = Plugin::new(&context, wasm, vec![], false).unwrap();
119 let has = plugin.has_function("count_vowels");
120 println!("has: {:?}", has);
121 let data = plugin.call("count_vowels", "this is a test");
122 println!("data: {:?}", data);
123 }