spacejam_service/service/
result.rs1use crate::{Gas, OpaqueHash, ServiceId, Vec, service::RefineLoad};
4
5use serde::{Deserialize, Serialize};
6
7#[cfg(feature = "json")]
8use {crate::String, crate::service::RefineLoadJson, spacejson::Json};
9
10#[cfg(feature = "json")]
11pub use json::WorkExecResultJson;
12
13#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
15#[cfg_attr(feature = "json", derive(Json))]
16pub struct WorkDigest {
17 pub service_id: ServiceId,
19
20 #[cfg_attr(feature = "json", json(hex))]
22 pub code_hash: OpaqueHash,
23
24 #[cfg_attr(feature = "json", json(hex))]
26 pub payload_hash: OpaqueHash,
27
28 pub accumulate_gas: Gas,
30
31 #[cfg_attr(feature = "json", json(nested))]
33 pub result: WorkExecResult,
34
35 #[cfg_attr(feature = "json", json(nested))]
37 pub refine_load: RefineLoad,
38}
39
40#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
42#[repr(C)]
43pub enum WorkExecResult {
44 Ok(Vec<u8>),
46 OutOfGas,
48 Panic,
50 InvalidExports,
52 InvalidDigest,
55 BadCode,
59 CodeOversize,
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
65pub struct Executed {
66 pub data: Vec<u8>,
68
69 pub exec: WorkExecResult,
71
72 pub gas: Gas,
74}
75
76impl Executed {
77 pub fn new(data: Vec<u8>, exec: WorkExecResult, gas: Gas) -> Self {
79 Self { data, exec, gas }
80 }
81
82 pub fn is_ok(&self) -> bool {
84 matches!(self.exec, WorkExecResult::Ok(_))
85 }
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
90pub struct Refined {
91 pub executed: Executed,
93
94 pub segments: Vec<Segment>,
96}
97
98impl Refined {
99 pub fn new(executed: Executed, segments: Vec<[u8; crate::SEGMENT_SIZE]>) -> Self {
101 Self {
102 executed,
103 segments: segments.iter().map(|s| Segment(*s)).collect(),
104 }
105 }
106}
107
108#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
110pub struct Segment(#[serde(with = "codec::bytes")] pub [u8; crate::SEGMENT_SIZE]);
111
112#[cfg(feature = "json")]
113mod json {
114 use super::WorkExecResult;
115 use crate::String;
116 use serde::{Deserialize, Serialize};
117 use spacejson::Json;
118
119 #[derive(Debug, Clone, Serialize, Deserialize, Default)]
121 pub struct WorkExecResultJson {
122 pub ok: Option<String>,
124 #[serde(default = "default_some_unit")]
126 pub out_of_gas: Option<()>,
127 #[serde(default = "default_some_unit")]
129 pub panic: Option<()>,
130 #[serde(default = "default_some_unit")]
132 pub invalid_exports: Option<()>,
133 #[serde(default = "default_some_unit")]
135 pub invalid_digest: Option<()>,
136 #[serde(default = "default_some_unit")]
138 pub bad_code: Option<()>,
139 #[serde(default = "default_some_unit")]
141 pub code_oversize: Option<()>,
142 }
143
144 fn default_some_unit() -> Option<()> {
145 Some(())
146 }
147
148 impl Json<WorkExecResultJson> for WorkExecResult {
149 fn to_json(self) -> WorkExecResultJson {
150 match self {
151 WorkExecResult::Ok(v) => WorkExecResultJson {
152 ok: Some(hex::encode(v)),
153 ..Default::default()
154 },
155 WorkExecResult::OutOfGas => WorkExecResultJson {
156 out_of_gas: Some(()),
157 ..Default::default()
158 },
159 WorkExecResult::Panic => WorkExecResultJson {
160 panic: Some(()),
161 ..Default::default()
162 },
163 WorkExecResult::InvalidExports => WorkExecResultJson {
164 invalid_exports: Some(()),
165 ..Default::default()
166 },
167 WorkExecResult::InvalidDigest => WorkExecResultJson {
168 invalid_digest: Some(()),
169 ..Default::default()
170 },
171 WorkExecResult::CodeOversize => WorkExecResultJson {
172 code_oversize: Some(()),
173 ..Default::default()
174 },
175 WorkExecResult::BadCode => WorkExecResultJson {
176 bad_code: Some(()),
177 ..Default::default()
178 },
179 }
180 }
181
182 fn from_json(json: WorkExecResultJson) -> anyhow::Result<Self> {
183 if let Some(ok) = json.ok {
184 Ok(WorkExecResult::Ok(
185 hex::decode(ok.trim_start_matches("0x"))
186 .map_err(|e| anyhow::anyhow!("{e:?}"))?,
187 ))
188 } else if json.out_of_gas.is_none() {
189 Ok(WorkExecResult::OutOfGas)
190 } else if json.panic.is_none() {
191 Ok(WorkExecResult::Panic)
192 } else if json.bad_code.is_none() {
193 Ok(WorkExecResult::BadCode)
194 } else {
195 Ok(WorkExecResult::CodeOversize)
196 }
197 }
198 }
199}