Skip to content

Commit

Permalink
Add serialization for ExecutionResponse object
Browse files Browse the repository at this point in the history
  • Loading branch information
iamalwaysuncomfortable committed Oct 26, 2023
1 parent 538a9e2 commit f79e499
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 27 deletions.
2 changes: 1 addition & 1 deletion wasm/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ version = "1.8"
[dependencies.reqwest]
version = "0.11.18"


[dependencies.serde_json]
version = "1.0"

Expand All @@ -95,7 +96,8 @@ version = "0.4.37"
version = "0.1.7"

[dependencies.serde]
version = "1.0.183"
version = "1.0.184"
features = [ "derive" ]

[dev-dependencies.snarkvm-parameters]
version = "0.16.6"
Expand Down
2 changes: 1 addition & 1 deletion wasm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@aleohq/wasm",
"version": "0.6.3",
"version": "0.6.5",
"description": "Wasm build for the SDK",
"collaborators": [
"The Aleo Team <[email protected]>"
Expand Down
4 changes: 2 additions & 2 deletions wasm/src/programs/manager/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ impl ProgramManager {
log("Proving execution");
let locator = program_native.id().to_string().add("/").add(function);
let execution = trace.prove_execution::<CurrentAleo, _>(&locator, rng).map_err(|e| e.to_string())?;
ExecutionResponse::new(Some(execution), function, response, process, program)?
ExecutionResponse::new(Some(execution), function, None, process, program)?
} else {
ExecutionResponse::new(None, function, response, process, program)?
ExecutionResponse::new(None, function, Some(response), process, program)?
};

if cache {
Expand Down
85 changes: 63 additions & 22 deletions wasm/src/programs/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,28 @@
// You should have received a copy of the GNU General Public License
// along with the Aleo SDK library. If not, see <https://www.gnu.org/licenses/>.

use crate::types::{
ExecutionNative,
IdentifierNative,
ProcessNative,
ProgramIDNative,
ProgramNative,
ProvingKeyNative,
ResponseNative,
VerifyingKeyNative,
};

use crate::{Execution, KeyPair, Program, ProvingKey, VerifyingKey};
use std::{ops::Deref, str::FromStr};
use crate::{Execution, KeyPair, Program, ProvingKey, VerifyingKey,
types::{CurrentNetwork, ExecutionNative, IdentifierNative, ProcessNative, ProgramIDNative, ProgramNative, ProvingKeyNative, ResponseNative, VerifyingKeyNative}};
use snarkvm_ledger_block::Transition;

use serde::{Deserialize, Serialize};
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};

use core::{fmt::{Debug, Display, Formatter}, str::{FromStr}};

/// Webassembly Representation of an Aleo function execution response
///
/// This object is returned by the execution of an Aleo function off-chain. It provides methods for
/// retrieving the outputs of the function execution.
#[derive(Serialize, Deserialize)]
#[wasm_bindgen]
pub struct ExecutionResponse {
execution: Option<ExecutionNative>,
function_id: IdentifierNative,
response: ResponseNative,
#[serde(skip)]
response: Option<ResponseNative>,
program: ProgramNative,
#[serde(skip)]
proving_key: Option<ProvingKeyNative>,
verifying_key: VerifyingKeyNative,
}
Expand All @@ -48,7 +45,7 @@ impl ExecutionResponse {
pub(crate) fn new(
execution: Option<ExecutionNative>,
function_id: &str,
response: ResponseNative,
response: Option<ResponseNative>,
process: &ProcessNative,
program: &str,
) -> Result<Self, String> {
Expand Down Expand Up @@ -86,9 +83,16 @@ impl ExecutionResponse {
#[wasm_bindgen(js_name = "getOutputs")]
pub fn get_outputs(&self) -> js_sys::Array {
let array = js_sys::Array::new_with_length(0u32);
self.response.outputs().iter().enumerate().for_each(|(i, output)| {
array.set(i as u32, JsValue::from_str(&output.to_string()));
});
if let Some(response) = &self.response {
response.outputs().iter().enumerate().for_each(|(i, output)| {
array.set(i as u32, JsValue::from_str(&output.to_string()));
});
} else if let Some(execution) = &self.execution {
let transition: &Transition<CurrentNetwork> = execution.transitions().last().unwrap();
transition.outputs().iter().enumerate().for_each(|(i, output)| {
array.set(i as u32, JsValue::from_str(&output.to_string()));
});
};
array
}

Expand Down Expand Up @@ -139,12 +143,49 @@ impl ExecutionResponse {
pub fn get_program(&self) -> Program {
Program::from(self.program.clone())
}

/// Creates an execution response object from a string representation
#[wasm_bindgen(js_name = "fromString")]
pub fn from_string(string: &str) -> Result<ExecutionResponse, String> {
ExecutionResponse::from_str(string).map_err(|e| e.to_string())
}

/// Gets a string representation of the execution response
#[wasm_bindgen(js_name = "toString")]
pub fn to_string(&self) -> String {
serde_json::to_string(self).unwrap()
}
}

impl Deref for ExecutionResponse {
type Target = ResponseNative;
impl FromStr for ExecutionResponse {
type Err = String;

fn deref(&self) -> &Self::Target {
&self.response
fn from_str(string: &str) -> Result<Self, Self::Err> {
serde_json::from_str(string).map_err(|e| e.to_string())
}
}

impl Debug for ExecutionResponse {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
Display::fmt(self, f)
}
}

impl Display for ExecutionResponse {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", serde_json::to_string(self).unwrap())
}
}

#[cfg(test)]
mod tests {
use super::*;
use wasm_bindgen_test::*;
const EXECUTION_RESPONSE_STRING: &str = r#"{"execution":{"transitions":[{"id":"au1dfrkzg88p0pcgy56du90y9xugmuclu90kqd7ptgwark9t5qxfcrqw52hv7","program":"hello_hello.aleo","function":"hello","inputs":[{"type":"public","id":"4945992393802635475563268868099292760643816190063237189685350751189981170816field","value":"5u32"},{"type":"private","id":"4164103417332231618737989065641386688266929073430922423679012291923769848499field","value":"ciphertext1qyqwhn4l6n3r3vuxll4nknsjjm85ymf9xfp0xrgvffhw9vyvd6ax7qsgpxvjj"}],"outputs":[{"type":"private","id":"5698382242539043620442411567938920404298421896333837450816037367993133498453field","value":"ciphertext1qyq2seq9t7nwfrsyvwxdat85zgsrumfkfpcy4s9p0ek7fuejvwzj2qc6rfj60"}],"tpk":"1486634957944190724396679076295465074325176108987233340308498709130933996149group","tcm":"7676439751717049208763075205278935619467292973248433417291209210873565684393field"}],"global_state_root":"sr1mt27mfdealt4nfwv4fv56nv53zk42xpk7s2e7emklx8fze60dvqqsmyqyp","proof":"proof1qyqsqqqqqqqqqqqpqqqqqqqqqqqfsrvj33m0zeyzu0xvsmrh9mhpue5nnn5r48auwr3lkdtr56jkmpkjqy56y7uzmtmxsg9l9lqsqmvqq87fyhw6nl3nu470mehj8elnu2k5nkqvdycapmqdx4revnemljv7cy54fedtg8pz06jxmxzqgp7kvqt2gf5n0u3962zchpc3hhmvurlyraxz64qrd05whadfq20atmlf4dvz2mtwxw3dcq4efuztf3wk9gq95fj38e2fghvthexhke0e5sjek3g9a8rlqjk7xk25eywkk6zra0prwtfs7m8zzw0e4ntascva7scp3k846j4vgxl0txs74w8rz584jfm0yvg96f0272kmlws8lgcl0q9ym6ak55l4d7qvf5tqk7kmeyucp9fkq5kk6ya62tecws255nay67vmqaljn6hhcc6wetjxu2pad8zxszy62hlwj8ansfnt3j4wrme5qpadk4karx7fvzzlpx0meadg38eyuj2793tppl749se9fradadf0zprvwltlc2w57ftekyejg9laeq9uug9auxj2mmxugs6zc8sx3lw73a6wgw8kemm6q7yae65lt94sazzj3u249plu89kdedn400l8jwq69r76hh56ffa88m35dc8mlar7v5ftaft836dmxn3xgzzvs97v4gujcmtt5rzcrav53k4eemczkwcqps77tlg2qknlarv54qcra2vkswsqwr0a2qj09uncv48luzkdny9selq52nqyndnfyr82l9crpkgxd7pmvw8axt59ea3ry0n9pghqgzlrcrvgr5mvh4qjmpt99c6psgae857e8xwdlw5vqt7683877md7py5979lyk96e7rc0f0qnn58gghcw8lhxpu9fs48fux7yyyamal5qmjxfqqzulmugwg90mtyvsrgg0mawawkmhtrqn3ft85k97mw7atqrmtduzm6awmkhzlqsywazs05yx00nqga8m3nse6qq6gnvrs998v8y4k92yx4ca3fv9x2p05slt6hkgs5ev78z3cxrshkwcv890t7dwyry3cqgpx5g3fh8vzlprnwy6k0gwmxry2jzdvg75gxtyfaargq9q3p2ay5u7hysehpawe9hdqv0pzj4zeh3zpzskmcd65fnd7senwdq762tea3lxkg5c4wx8uspa3g4a8s050nlf4hsgw0g87af605nccspqvqqqqqqqqqqqa9vd7ws94vxswct8y8yc0hqx8axxq2smawwns3zlt7hn0h9rshd2r2axfzq7q95ccg6z63vegq9syqqn375qy2en9wry7pxs34ycxxt4s9qwulfwl8kygrfkzmaj9rh6fvr3dwxcjd33tggndd4agg5sn5pqy43eu72lcj5e7stnlkw2f8huvctx45csaea7q4gsen7tx002rkq759y86c06rem3hvywm925dulyg9vvzg6hs7xxqkprgmdh84jfw4hu75342xw8aqnr84uq02etkc3sqqqvdhysh"},"function_id":"hello","program":"program hello_hello.aleo;\n\nfunction hello:\n input r0 as u32.public;\n input r1 as u32.private;\n add r0 r1 into r2;\n output r2 as u32.private;\n","verifying_key":"verifier1qygqqqqqqqqqqqrexyqqqqqqqqqxuvgqqqqqqqqqm4usqqqqqqqqpj9wqqqqqqqqqqj5zqqqqqqqqqqvqqqqqqqqqqqdc2dqsuva0q6lxnhp03h2tpdy9ga2kecvk68uc320nhthal2lndrm8qp9463cwa2tu2x928nd7rcq7df7ptdvnzxckqelxmvd2pd6w57auf7ej5tvq3wfn25celv46zy425cphqgj5jyug06fzcemyfhsrdvqptvynulc88zaq8ak3ezszyzvqzj7s4f6ewkqr63kr2y06c7g3napl6un62zfcrjgrumnwmzhs96zr27slulnvxcvtu884dvfffr7sfv3ves2645v6sr79frqt50z90exdpmjnep5q9mncdsx9gg6cq99wjqeavg2xryhsk2m0e8nnevjcz4rv5evx3l88lzjezaqrc3mdm0n5u66kvtlc7y6558gyfy82jqvh690eyxplnulckn3kdmk29x9jgmm5vuk2f90ct6u60hsly0uhwxz27mqzk5t6u5psr0pcnpwlrsqfc5rqx2rghgmaxpxx9fr0a6m4xh3x9hjakgtuqumntnwkf56xfxch5aavnkx0ylgesj976g5g4nqpvjn3rc3sd7mcpzcwgprzmgdt7lfp5lkaydznyu537u6la7khc5f4dfkmqp8uyxl6s3et78mxr5sqxjcdpf7tea6qucvyylu46t84n682zlunhzq9hqs8wfnnqcwwkxkw08926fudhuqvp3c0rt2w8dryqt0anx5w2844skt3xqs6c02gjvr4hcxkxfkpmd68rt94t9y2vauxwlceymvmazwlr0vjeuq7atlwsq33zms3vmz2uplna0jurtw9zfpvl2mtll80r33hc26mcuggcy9fh98t9aap6psgjlmh0mynrfyhgqq9zpmh5uqtsjh8tfgeqfxrzhyvuxum7h3tpu4gleslk8utascqaeqnfkngcd32lpglqh5rqdy6wkszpfk0e6dpx87c3d84zquguf6n3f5mr8hjffq9c5da73dm04r0wf6dsegtk"}"#;

#[wasm_bindgen_test]
fn test_execution_response_string_roundtrip() {
let execution_response = ExecutionResponse::from_string(EXECUTION_RESPONSE_STRING).unwrap();
assert_eq!(execution_response.to_string(), EXECUTION_RESPONSE_STRING);
}
}

0 comments on commit f79e499

Please sign in to comment.