1pub mod buf;
10
11#[non_exhaustive]
12#[derive(Debug, Clone, Copy)]
13pub struct WasmLinearMem {
14 pub start_ptr: *const u8,
15 pub size: u64,
16}
17
18impl WasmLinearMem {
19 pub unsafe fn new(start_ptr: *const u8, size: u64) -> Self {
23 Self { start_ptr, size }
24 }
25}
26
27#[cfg(feature = "contract")]
28pub mod wasm_interface {
29 use crate::prelude::*;
30
31 fn set_logger() -> Result<(), ContractInterfaceResult> {
32 #[cfg(feature = "trace")]
33 {
34 use crate::prelude::*;
35 use tracing_subscriber as tra;
36 if let Err(err) = tra::fmt()
37 .with_env_filter("warn,freenet_stdlib=trace")
38 .try_init()
39 {
40 return Err(ContractInterfaceResult::from(Err::<ValidateResult, _>(
41 ContractError::Other(format!("{}", err)),
42 )));
43 }
44 }
45 Ok(())
46 }
47
48 use std::io::Read;
49
50 fn read_streaming_bytes(ptr: i64) -> Result<Vec<u8>, ContractInterfaceResult> {
52 let mut reader = unsafe { super::buf::StreamingBuffer::from_ptr(ptr) };
53 let mut bytes = Vec::with_capacity(reader.total_remaining());
54 reader.read_to_end(&mut bytes).map_err(|e| {
55 ContractInterfaceResult::from(Err::<ValidateResult, _>(ContractError::Other(format!(
56 "streaming read failed: {e}"
57 ))))
58 })?;
59 Ok(bytes)
60 }
61
62 pub fn inner_validate_state<T: ContractInterface>(
63 parameters: i64,
64 state: i64,
65 related: i64,
66 ) -> i64 {
67 if let Err(e) = set_logger().map_err(|e| e.into_raw()) {
68 return e;
69 }
70 let parameters = match read_streaming_bytes(parameters) {
71 Ok(bytes) => Parameters::from(bytes),
72 Err(e) => return e.into_raw(),
73 };
74 let state = match read_streaming_bytes(state) {
75 Ok(bytes) => State::from(bytes),
76 Err(e) => return e.into_raw(),
77 };
78 let related_bytes = match read_streaming_bytes(related) {
79 Ok(bytes) => bytes,
80 Err(e) => return e.into_raw(),
81 };
82 let related: RelatedContracts<'static> =
83 match bincode::deserialize::<RelatedContracts>(&related_bytes) {
84 Ok(v) => v.into_owned(),
85 Err(err) => {
86 return ContractInterfaceResult::from(Err::<::core::primitive::bool, _>(
87 ContractError::Deser(format!("{}", err)),
88 ))
89 .into_raw()
90 }
91 };
92 let result = <T as ContractInterface>::validate_state(parameters, state, related);
93 ContractInterfaceResult::from(result).into_raw()
94 }
95
96 pub fn inner_update_state<T: ContractInterface>(
97 parameters: i64,
98 state: i64,
99 updates: i64,
100 ) -> i64 {
101 if let Err(e) = set_logger().map_err(|e| e.into_raw()) {
102 return e;
103 }
104 let parameters = match read_streaming_bytes(parameters) {
105 Ok(bytes) => Parameters::from(bytes),
106 Err(e) => return e.into_raw(),
107 };
108 let state = match read_streaming_bytes(state) {
109 Ok(bytes) => State::from(bytes),
110 Err(e) => return e.into_raw(),
111 };
112 let updates_bytes = match read_streaming_bytes(updates) {
113 Ok(bytes) => bytes,
114 Err(e) => return e.into_raw(),
115 };
116 let updates: Vec<UpdateData<'static>> =
117 match bincode::deserialize::<Vec<UpdateData>>(&updates_bytes) {
118 Ok(v) => v.into_iter().map(|u| u.into_owned()).collect(),
119 Err(err) => {
120 return ContractInterfaceResult::from(Err::<ValidateResult, _>(
121 ContractError::Deser(format!("{}", err)),
122 ))
123 .into_raw()
124 }
125 };
126 let result = <T as ContractInterface>::update_state(parameters, state, updates);
127 ContractInterfaceResult::from(result).into_raw()
128 }
129
130 pub fn inner_summarize_state<T: ContractInterface>(parameters: i64, state: i64) -> i64 {
131 if let Err(e) = set_logger().map_err(|e| e.into_raw()) {
132 return e;
133 }
134 let parameters = match read_streaming_bytes(parameters) {
135 Ok(bytes) => Parameters::from(bytes),
136 Err(e) => return e.into_raw(),
137 };
138 let state = match read_streaming_bytes(state) {
139 Ok(bytes) => State::from(bytes),
140 Err(e) => return e.into_raw(),
141 };
142 let summary = <T as ContractInterface>::summarize_state(parameters, state);
143 ContractInterfaceResult::from(summary).into_raw()
144 }
145
146 pub fn inner_get_state_delta<T: ContractInterface>(
147 parameters: i64,
148 state: i64,
149 summary: i64,
150 ) -> i64 {
151 if let Err(e) = set_logger().map_err(|e| e.into_raw()) {
152 return e;
153 }
154 let parameters = match read_streaming_bytes(parameters) {
155 Ok(bytes) => Parameters::from(bytes),
156 Err(e) => return e.into_raw(),
157 };
158 let state = match read_streaming_bytes(state) {
159 Ok(bytes) => State::from(bytes),
160 Err(e) => return e.into_raw(),
161 };
162 let summary = match read_streaming_bytes(summary) {
163 Ok(bytes) => StateSummary::from(bytes),
164 Err(e) => return e.into_raw(),
165 };
166 let new_delta = <T as ContractInterface>::get_state_delta(parameters, state, summary);
167 ContractInterfaceResult::from(new_delta).into_raw()
168 }
169}