From eb1a5a36325d63374b58ad1fca61ca3c9c3bd5ec Mon Sep 17 00:00:00 2001 From: Ryan Tan Date: Mon, 18 Nov 2024 10:33:18 +0000 Subject: [PATCH] fix: remove tag from receipt result container fix: try with receipt error fix: add tag to operation content --- crates/jstz_cli/src/deploy.rs | 8 +- crates/jstz_cli/src/run.rs | 10 +- crates/jstz_node/openapi.json | 232 ++++++++++-------- crates/jstz_proto/src/executor/deposit.rs | 10 +- crates/jstz_proto/src/executor/fa_deposit.rs | 13 +- crates/jstz_proto/src/executor/fa_withdraw.rs | 1 + crates/jstz_proto/src/operation.rs | 4 + crates/jstz_proto/src/receipt.rs | 57 +++-- 8 files changed, 186 insertions(+), 149 deletions(-) diff --git a/crates/jstz_cli/src/deploy.rs b/crates/jstz_cli/src/deploy.rs index c0ddb74af..ab6ea4954 100644 --- a/crates/jstz_cli/src/deploy.rs +++ b/crates/jstz_cli/src/deploy.rs @@ -2,7 +2,7 @@ use boa_engine::JsError; use jstz_proto::{ context::account::ParsedCode, operation::{Content, DeployFunction, Operation, SignedOperation}, - receipt::ReceiptContent, + receipt::{ReceiptContent, ReceiptResult}, }; use log::{debug, info}; @@ -96,11 +96,11 @@ pub async fn exec( debug!("Receipt: {:?}", receipt); let address = match receipt.inner { - Ok(ReceiptContent::DeployFunction(deploy)) => deploy.address, - Ok(_) => { + ReceiptResult::Success(ReceiptContent::DeployFunction(deploy)) => deploy.address, + ReceiptResult::Success(_) => { bail!("Expected a `DeployFunction` receipt, but got something else.") } - Err(err) => { + ReceiptResult::Failed { source: err } => { bail_user_error!("Failed to deploy smart function with error {err:?}.") } }; diff --git a/crates/jstz_cli/src/run.rs b/crates/jstz_cli/src/run.rs index a1a259c40..54b6465f1 100644 --- a/crates/jstz_cli/src/run.rs +++ b/crates/jstz_cli/src/run.rs @@ -6,7 +6,7 @@ use jstz_proto::context::account::Address; use jstz_proto::executor::JSTZ_HOST; use jstz_proto::{ operation::{Content as OperationContent, Operation, RunFunction, SignedOperation}, - receipt::ReceiptContent, + receipt::{ReceiptContent, ReceiptResult}, }; use log::{debug, info}; use spinners::{Spinner, Spinners}; @@ -165,14 +165,16 @@ pub async fn exec( debug!("Receipt: {:?}", receipt); let (status_code, headers, body) = match receipt.inner { - Ok(ReceiptContent::RunFunction(run_function)) => ( + ReceiptResult::Success(ReceiptContent::RunFunction(run_function)) => ( run_function.status_code, run_function.headers, run_function.body, ), - Ok(_) => bail!("Expected a `RunFunction` receipt, but got something else."), + ReceiptResult::Success(_) => { + bail!("Expected a `RunFunction` receipt, but got something else.") + } - Err(err) => bail_user_error!("{err}"), + ReceiptResult::Failed { source: err } => bail_user_error!("{err}"), }; if let Some(spinner) = spinner.as_mut() { diff --git a/crates/jstz_node/openapi.json b/crates/jstz_node/openapi.json index 0a3fb24e4..e355e73f2 100644 --- a/crates/jstz_node/openapi.json +++ b/crates/jstz_node/openapi.json @@ -440,7 +440,8 @@ } } } - ] + ], + "title": "DeployFunction" }, { "allOf": [ @@ -461,7 +462,8 @@ } } } - ] + ], + "title": "RunFunction" } ] }, @@ -667,122 +669,130 @@ "type": "string" }, "inner": { - "$ref": "#/components/schemas/ReceiptResult_ReceiptContent" + "$ref": "#/components/schemas/ReceiptResult" } } }, - "ReceiptResult_ReceiptContent": { + "ReceiptContent": { "oneOf": [ { "allOf": [ { - "oneOf": [ - { - "allOf": [ - { - "$ref": "#/components/schemas/DeployFunctionReceipt" - }, - { - "type": "object", - "required": [ - "_type" - ], - "properties": { - "_type": { - "type": "string", - "enum": [ - "DeployFunction" - ] - } - } - } + "$ref": "#/components/schemas/DeployFunctionReceipt" + }, + { + "type": "object", + "required": [ + "_type" + ], + "properties": { + "_type": { + "type": "string", + "enum": [ + "DeployFunction" ] - }, - { - "allOf": [ - { - "$ref": "#/components/schemas/RunFunctionReceipt" - }, - { - "type": "object", - "required": [ - "_type" - ], - "properties": { - "_type": { - "type": "string", - "enum": [ - "RunFunction" - ] - } - } - } + } + } + } + ], + "title": "DeployFunction" + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/RunFunctionReceipt" + }, + { + "type": "object", + "required": [ + "_type" + ], + "properties": { + "_type": { + "type": "string", + "enum": [ + "RunFunction" ] - }, - { - "allOf": [ - { - "$ref": "#/components/schemas/DepositReceipt" - }, - { - "type": "object", - "required": [ - "_type" - ], - "properties": { - "_type": { - "type": "string", - "enum": [ - "Deposit" - ] - } - } - } + } + } + } + ], + "title": "RunFunction" + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/DepositReceipt" + }, + { + "type": "object", + "required": [ + "_type" + ], + "properties": { + "_type": { + "type": "string", + "enum": [ + "Deposit" ] - }, - { - "allOf": [ - { - "$ref": "#/components/schemas/FaDepositReceipt" - }, - { - "type": "object", - "required": [ - "_type" - ], - "properties": { - "_type": { - "type": "string", - "enum": [ - "FaDeposit" - ] - } - } - } + } + } + } + ], + "title": "Deposit" + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/FaDepositReceipt" + }, + { + "type": "object", + "required": [ + "_type" + ], + "properties": { + "_type": { + "type": "string", + "enum": [ + "FaDeposit" ] - }, - { - "allOf": [ - { - "$ref": "#/components/schemas/FaWithdrawReceipt" - }, - { - "type": "object", - "required": [ - "_type" - ], - "properties": { - "_type": { - "type": "string", - "enum": [ - "FaWithdraw" - ] - } - } - } + } + } + } + ], + "title": "FaDeposit" + }, + { + "allOf": [ + { + "$ref": "#/components/schemas/FaWithdrawReceipt" + }, + { + "type": "object", + "required": [ + "_type" + ], + "properties": { + "_type": { + "type": "string", + "enum": [ + "FaWithdraw" ] } - ] + } + } + ], + "title": "FaWithdraw" + } + ] + }, + "ReceiptResult": { + "oneOf": [ + { + "allOf": [ + { + "$ref": "#/components/schemas/ReceiptContent" }, { "type": "object", @@ -793,24 +803,30 @@ "_type": { "type": "string", "enum": [ - "Ok" + "Success" ] } } } - ] + ], + "title": "Success" }, { "type": "object", + "title": "Failure", "required": [ + "source", "_type" ], "properties": { "_type": { "type": "string", "enum": [ - "Err" + "Failed" ] + }, + "source": { + "type": "string" } } } diff --git a/crates/jstz_proto/src/executor/deposit.rs b/crates/jstz_proto/src/executor/deposit.rs index b9a7a78a0..6bb1bbad9 100644 --- a/crates/jstz_proto/src/executor/deposit.rs +++ b/crates/jstz_proto/src/executor/deposit.rs @@ -36,7 +36,7 @@ mod test { use crate::{ operation::external::Deposit, - receipt::{DepositReceipt, ReceiptContent}, + receipt::{DepositReceipt, ReceiptContent, ReceiptResult}, }; use super::execute; @@ -54,11 +54,13 @@ mod test { tx.begin(); let receipt = execute(&mut host, &mut tx, deposit); assert!(matches!( - receipt.inner, - Ok(ReceiptContent::Deposit(DepositReceipt { + receipt.clone().inner, + ReceiptResult::Success(ReceiptContent::Deposit(DepositReceipt { account, updated_balance, })) if account == receiver && updated_balance == 20 - )) + )); + let raw_json_payload = r#"{"hash":[39,12,7,148,87,7,176,168,111,219,214,147,14,123,179,202,232,151,138,59,207,182,101,158,128,98,239,57,236,88,195,42],"inner":{"_type":"Success","inner":{"_type":"DepositReceipt","account":"tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx","updated_balance":20}}}"#; + assert_eq!(raw_json_payload, serde_json::to_string(&receipt).unwrap()); } } diff --git a/crates/jstz_proto/src/executor/fa_deposit.rs b/crates/jstz_proto/src/executor/fa_deposit.rs index fcf94ff5e..1c93a140c 100644 --- a/crates/jstz_proto/src/executor/fa_deposit.rs +++ b/crates/jstz_proto/src/executor/fa_deposit.rs @@ -23,6 +23,7 @@ const NULL_ADDRESS: &str = "tz1KqTpEZ7Yob7QbPE4Hy4Wo8fHG8LhKxZSx"; const DEPOSIT_URI: &str = "/-/deposit"; #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[serde(tag = "_type")] pub struct FaDepositReceipt { pub receiver: PublicKeyHash, pub ticket_balance: Amount, @@ -173,7 +174,7 @@ mod test { use crate::{ context::{account::ParsedCode, ticket_table::TicketTable}, executor::fa_deposit::{FaDeposit, FaDepositReceipt}, - receipt::{Receipt, ReceiptContent}, + receipt::{Receipt, ReceiptContent, ReceiptResult}, }; fn mock_fa_deposit(proxy: Option) -> FaDeposit { @@ -201,7 +202,7 @@ mod test { assert_eq!(expected_hash, *receipt.hash()); match receipt.inner { - Ok(ReceiptContent::FaDeposit(FaDepositReceipt { + ReceiptResult::Success(ReceiptContent::FaDeposit(FaDepositReceipt { receiver, ticket_balance, run_function, @@ -240,7 +241,7 @@ mod test { assert_eq!(expected_hash, *receipt.hash()); match receipt.inner { - Ok(ReceiptContent::FaDeposit(FaDepositReceipt { + ReceiptResult::Success(ReceiptContent::FaDeposit(FaDepositReceipt { receiver, ticket_balance, run_function, @@ -292,7 +293,7 @@ mod test { let Receipt { inner, .. } = super::execute(&mut host, &mut tx, fa_deposit); match inner { - Ok(ReceiptContent::FaDeposit(FaDepositReceipt { + ReceiptResult::Success(ReceiptContent::FaDeposit(FaDepositReceipt { receiver, ticket_balance, run_function, @@ -344,7 +345,7 @@ mod test { let Receipt { inner, .. } = super::execute(&mut host, &mut tx, fa_deposit2); match inner { - Ok(ReceiptContent::FaDeposit(FaDepositReceipt { + ReceiptResult::Success(ReceiptContent::FaDeposit(FaDepositReceipt { receiver, ticket_balance, run_function, @@ -391,7 +392,7 @@ mod test { let Receipt { inner, .. } = super::execute(&mut host, &mut tx, fa_deposit); match inner { - Ok(ReceiptContent::FaDeposit(FaDepositReceipt { + ReceiptResult::Success(ReceiptContent::FaDeposit(FaDepositReceipt { receiver, ticket_balance, run_function, diff --git a/crates/jstz_proto/src/executor/fa_withdraw.rs b/crates/jstz_proto/src/executor/fa_withdraw.rs index c4c23086e..70f65d99e 100644 --- a/crates/jstz_proto/src/executor/fa_withdraw.rs +++ b/crates/jstz_proto/src/executor/fa_withdraw.rs @@ -83,6 +83,7 @@ impl TryFrom for Ticket { type OutboxMessageId = String; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, ToSchema)] +#[serde(tag = "_type")] pub struct FaWithdrawReceipt { pub source: PublicKeyHash, pub outbox_message_id: OutboxMessageId, diff --git a/crates/jstz_proto/src/operation.rs b/crates/jstz_proto/src/operation.rs index 20301e3c1..6f96994e6 100644 --- a/crates/jstz_proto/src/operation.rs +++ b/crates/jstz_proto/src/operation.rs @@ -80,6 +80,7 @@ impl Operation { } #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, ToSchema)] +#[serde(tag = "_type")] pub struct DeployFunction { /// Smart function code pub function_code: ParsedCode, @@ -91,6 +92,7 @@ pub struct DeployFunction { #[schema(description = "Request used to run a smart function. \ The target smart function is given by the host part of the uri. \ The rest of the attributes will be handled by the smart function itself.")] +#[serde(tag = "_type")] pub struct RunFunction { /// Smart function URI in the form tezos://{smart_function_address}/rest/of/path #[serde(with = "http_serde::uri")] @@ -123,7 +125,9 @@ pub struct RunFunction { #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, ToSchema)] #[serde(tag = "_type")] pub enum Content { + #[schema(title = "DeployFunction")] DeployFunction(DeployFunction), + #[schema(title = "RunFunction")] RunFunction(RunFunction), } diff --git a/crates/jstz_proto/src/receipt.rs b/crates/jstz_proto/src/receipt.rs index dc6dfd0c5..3870407f0 100644 --- a/crates/jstz_proto/src/receipt.rs +++ b/crates/jstz_proto/src/receipt.rs @@ -1,29 +1,48 @@ -use http::{HeaderMap, StatusCode}; -use jstz_api::http::body::HttpBody; -use serde::{Deserialize, Serialize}; -use utoipa::ToSchema; - use crate::{ context::account::Address, executor::{fa_deposit::FaDepositReceipt, fa_withdraw::FaWithdrawReceipt}, operation::OperationHash, Result, }; +use http::{HeaderMap, StatusCode}; +use jstz_api::http::body::HttpBody; +use serde::{Deserialize, Serialize}; +use utoipa::ToSchema; -pub type ReceiptResult = std::result::Result; +// pub type ReceiptResult = std::result::Result; +#[derive(Debug, Clone, ToSchema, Serialize, Deserialize)] +#[serde(tag = "_type")] +pub enum ReceiptResult { + #[schema(title = "Success")] + Success(ReceiptContent), + #[schema(title = "Failure")] + Failed { source: String }, +} + +impl From> for ReceiptResult { + fn from(value: Result) -> Self { + match value { + Ok(ok) => ReceiptResult::Success(ok), + Err(err) => ReceiptResult::Failed { + source: err.to_string(), + }, + } + } +} #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] pub struct Receipt { #[schema(value_type = String)] hash: OperationHash, - #[schema(value_type = openapi::ReceiptResult)] - pub inner: ReceiptResult, + pub inner: ReceiptResult, } impl Receipt { pub fn new(hash: OperationHash, inner: Result) -> Self { - let inner = inner.map_err(|e| e.to_string()); - Self { hash, inner } + Self { + hash, + inner: inner.into(), + } } pub fn hash(&self) -> &OperationHash { @@ -59,22 +78,14 @@ pub struct DepositReceipt { #[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] #[serde(tag = "_type")] pub enum ReceiptContent { + #[schema(title = "DeployFunction")] DeployFunction(DeployFunctionReceipt), + #[schema(title = "RunFunction")] RunFunction(RunFunctionReceipt), + #[schema(title = "Deposit")] Deposit(DepositReceipt), + #[schema(title = "FaDeposit")] FaDeposit(FaDepositReceipt), + #[schema(title = "FaWithdraw")] FaWithdraw(FaWithdrawReceipt), } - -mod openapi { - use serde::{Deserialize, Serialize}; - use utoipa::ToSchema; - - #[allow(dead_code)] - #[derive(ToSchema, Serialize, Deserialize)] - #[serde(tag = "_type")] - pub enum ReceiptResult { - Ok(T), - Err(String), - } -}