Skip to content

Commit

Permalink
Merge pull request #955 from scrtlabs/cw-v1-refactor-output-structure
Browse files Browse the repository at this point in the history
  • Loading branch information
liorbond authored Jul 10, 2022
2 parents 3688f34 + 862ba0f commit 39f353d
Show file tree
Hide file tree
Showing 98 changed files with 354 additions and 16,290 deletions.
755 changes: 3 additions & 752 deletions cosmwasm/Cargo.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ pub fn init(
})?;
env_v010.contract_code_hash = hex::encode(contract_code.hash());

trace!("init env_v010: {:?}", env_v010);

let canonical_contract_address = CanonicalAddr::from_human(&env_v010.contract.address).map_err(|err| {
warn!(
"init got an error while trying to deserialize env_v010.contract.address from bech32 string to bytes {:?}: {}",
Expand All @@ -77,6 +75,8 @@ pub fn init(
EnclaveError::FailedToDeserialize
})?;

trace!("init env_v010: {:?}", env_v010);

let canonical_sender_address = CanonicalAddr::from_human(&env_v010.message.sender).map_err(|err| {
warn!(
"init got an error while trying to deserialize env_v010.message.sender from bech32 string to bytes {:?}: {}",
Expand Down Expand Up @@ -148,6 +148,7 @@ pub fn init(
&env_v010.contract_code_hash,
reply_params,
&canonical_sender_address,
false,
)?;

Ok(output)
Expand Down Expand Up @@ -661,6 +662,7 @@ pub fn handle(
&env_v010.contract_code_hash,
reply_params,
&canonical_sender_address,
false,
)?;
Ok(output)
})
Expand Down Expand Up @@ -753,6 +755,7 @@ pub fn query(
&"".to_string(), // Not used for queries (can't call a sub-message from a query),
None, // Not used for queries (Query response is not replied to the caller),
&CanonicalAddr(Binary(Vec::new())), // Not used for queries (used only for replies)
true,
)?;
Ok(output)
})
Expand Down
138 changes: 116 additions & 22 deletions cosmwasm/enclaves/shared/contract-engine/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,13 @@ use sha2::Digest;
/// b. Authenticate the reply.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(untagged)]
enum WasmOutput {
ErrV010 {
enum RawWasmOutput {
Err {
#[serde(rename = "Err")]
err: Value,
internal_msg_id: Option<Binary>,
internal_reply_enclave_sig: Option<Binary>,
},
ErrV1 {
#[serde(rename = "error")]
err: Value,
internal_msg_id: Option<Binary>,
internal_reply_enclave_sig: Option<Binary>,
},
QueryOkV010 {
#[serde(rename = "Ok")]
ok: String,
Expand All @@ -52,13 +46,46 @@ enum WasmOutput {
internal_msg_id: Option<Binary>,
},
OkV1 {
#[serde(rename = "ok")]
#[serde(rename = "Ok")]
ok: enclave_cosmwasm_v1_types::results::Response,
internal_reply_enclave_sig: Option<Binary>,
internal_msg_id: Option<Binary>,
},
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
struct V010WasmOutput {
#[serde(rename = "Ok")]
pub ok: Option<cosmwasm_v010_types::types::ContractResult>,
#[serde(rename = "Err")]
pub err: Option<Value>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
struct V1WasmOutput {
#[serde(rename = "Ok")]
pub ok: Option<enclave_cosmwasm_v1_types::results::Response>,
#[serde(rename = "Err")]
pub err: Option<Value>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
struct QueryOutput {
#[serde(rename = "Ok")]
pub ok: Option<String>,
#[serde(rename = "Err")]
pub err: Option<Value>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
struct WasmOutput {
pub v010: Option<V010WasmOutput>,
pub v1: Option<V1WasmOutput>,
pub query: Option<QueryOutput>,
pub internal_reply_enclave_sig: Option<Binary>,
pub internal_msg_id: Option<Binary>,
}

pub fn calc_encryption_key(nonce: &IoNonce, user_public_key: &Ed25519PublicKey) -> AESKey {
let enclave_io_key = KEY_MANAGER.get_consensus_io_exchange_keypair().unwrap();

Expand Down Expand Up @@ -131,6 +158,7 @@ pub fn encrypt_output(
contract_hash: &String,
reply_params: Option<(Vec<u8>, u64)>,
sender_addr: &CanonicalAddr,
is_query_output: bool,
) -> Result<Vec<u8>, EnclaveError> {
// When encrypting an output we might encrypt an output that is a reply to a caller contract (Via "Reply" endpoint).
// Therefore if reply_recipient_contract_hash is not "None" we append it to any encrypted data besided submessages that are irrelevant for replies.
Expand All @@ -141,19 +169,14 @@ pub fn encrypt_output(
String::from_utf8_lossy(&output)
);

let mut output: WasmOutput = serde_json::from_slice(&output).map_err(|err| {
let mut output: RawWasmOutput = serde_json::from_slice(&output).map_err(|err| {
warn!("got an error while trying to deserialize output bytes into json");
trace!("output: {:?} error: {:?}", output, err);
EnclaveError::FailedToDeserialize
})?;

match &mut output {
WasmOutput::ErrV010 {
err,
internal_reply_enclave_sig,
internal_msg_id,
}
| WasmOutput::ErrV1 {
RawWasmOutput::Err {
err,
internal_reply_enclave_sig,
internal_msg_id,
Expand Down Expand Up @@ -205,12 +228,12 @@ pub fn encrypt_output(
}
}

WasmOutput::QueryOkV010 { ok } | WasmOutput::QueryOkV1 { ok } => {
RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => {
*ok = encrypt_serializable(&encryption_key, ok, &reply_params)?;
}

// Encrypt all Wasm messages (keeps Bank, Staking, etc.. as is)
WasmOutput::OkV010 {
RawWasmOutput::OkV010 {
ok,
internal_reply_enclave_sig,
internal_msg_id,
Expand Down Expand Up @@ -284,7 +307,7 @@ pub fn encrypt_output(
None => None, // Not a reply, we don't need enclave sig
}
}
WasmOutput::OkV1 {
RawWasmOutput::OkV1 {
ok,
internal_reply_enclave_sig,
internal_msg_id,
Expand Down Expand Up @@ -380,12 +403,82 @@ pub fn encrypt_output(
}
};

trace!("WasmOutput: {:?}", output);
let final_output: WasmOutput = match output {
RawWasmOutput::Err {
err,
internal_msg_id,
internal_reply_enclave_sig,
} => {
if is_query_output {
WasmOutput {
v010: None,
v1: None,
query: Some(QueryOutput {
ok: None,
err: Some(err),
}),
internal_reply_enclave_sig: None,
internal_msg_id: None,
}
} else {
WasmOutput {
v010: Some(V010WasmOutput {
err: Some(err),
ok: None,
}),
v1: None,
query: None,
internal_reply_enclave_sig,
internal_msg_id,
}
}
}
RawWasmOutput::OkV010 {
ok,
internal_reply_enclave_sig,
internal_msg_id,
} => WasmOutput {
v010: Some(V010WasmOutput {
err: None,
ok: Some(ok),
}),
v1: None,
query: None,
internal_reply_enclave_sig,
internal_msg_id,
},
RawWasmOutput::OkV1 {
ok,
internal_reply_enclave_sig,
internal_msg_id,
} => WasmOutput {
v010: None,
v1: Some(V1WasmOutput {
err: None,
ok: Some(ok),
}),
query: None,
internal_reply_enclave_sig,
internal_msg_id,
},
RawWasmOutput::QueryOkV010 { ok } | RawWasmOutput::QueryOkV1 { ok } => WasmOutput {
v010: None,
v1: None,
query: Some(QueryOutput {
ok: Some(ok),
err: None,
}),
internal_reply_enclave_sig: None,
internal_msg_id: None,
},
};

let encrypted_output = serde_json::to_vec(&output).map_err(|err| {
trace!("WasmOutput: {:?}", final_output);

let encrypted_output = serde_json::to_vec(&final_output).map_err(|err| {
debug!(
"got an error while trying to serialize output json into bytes {:?}: {}",
output, err
final_output, err
);
EnclaveError::FailedToSerialize
})?;
Expand Down Expand Up @@ -480,6 +573,7 @@ fn encrypt_v1_wasm_msg(
)?;

msg_to_pass.encrypt_in_place()?;

*msg = Binary::from(msg_to_pass.to_vec().as_slice());

*callback_sig = Some(create_callback_signature(
Expand Down
29 changes: 5 additions & 24 deletions cosmwasm/enclaves/shared/contract-engine/src/query_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::wasm::CosmWasmApiVersion;

use enclave_cosmwasm_types::{
encoding::Binary,
query::{QueryRequest, WasmQuery, V1SmartQueryAnswer, V1SmartQueryResult},
query::{QueryRequest, V1SmartQueryAnswer, V1SmartQueryResult, WasmQuery},
std_error::{StdError, StdResult},
system_error::{SystemError, SystemResult},
};
Expand Down Expand Up @@ -135,29 +135,10 @@ pub fn encrypt_and_query_chain(
answer
);

let answer_as_vec = match contract_version {
CosmWasmApiVersion::V010 => { serde_json::to_vec(&answer).map_err(|err| {
debug!("encrypt_and_query_chain() got an error while trying to serialize the decrypted answer to bytes: {:?}", err);
WasmEngineError::SerializationError
})?
},
CosmWasmApiVersion::V1 => {
let v1_answer : V1SmartQueryAnswer = match answer {
Ok(o) => {
match o {
Ok(o2) => V1SmartQueryAnswer::Ok(V1SmartQueryResult::Ok(o2)),
Err(e) => V1SmartQueryAnswer::Ok(V1SmartQueryResult::Err(format!("{:?}", e))),
}
},
Err(e) => V1SmartQueryAnswer::Err(e),
};

serde_json::to_vec(&v1_answer).map_err(|err| {
debug!("encrypt_and_query_chain() got an error while trying to serialize the decrypted answer to bytes: {:?}", err);
WasmEngineError::SerializationError
})?
},
};
let answer_as_vec = serde_json::to_vec(&answer).map_err(|err| {
debug!("encrypt_and_query_chain() got an error while trying to serialize the decrypted answer to bytes: {:?}", err);
WasmEngineError::SerializationError
})?;

Ok(answer_as_vec)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ impl WasmiApi for ContractInstance {
)?;

trace!(
"query_chain() got answer from outside with gas {} and result {:?}",
"query_chain() got an answer from outside with gas {} and result {:?}",
gas_used,
String::from_utf8_lossy(&answer)
);
Expand Down
5 changes: 3 additions & 2 deletions cosmwasm/enclaves/shared/cosmwasm-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ sgx_tstd = { rev = "a37ffb9449ba6d5b6e4a9d586bbab864ae732269", git = "https://gi

[dependencies]
enclave-ffi-types = { path = "../../ffi-types" }

log = "0.4.8"
serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = ["derive"] }
serde = { git = "https://github.com/mesalock-linux/serde-sgx", features = [
"derive"
] }
serde_json = { git = "https://github.com/mesalock-linux/serde-json-sgx" }
derive_more = "0.99"
bech32 = "0.7.2"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@ use std::fmt;
/// assert_eq!(to_vec(&result).unwrap(), br#"{"error":"Something went wrong"}"#.to_vec());
/// ```
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum ContractResult<S> {
Ok(S),
/// An error type that every custom error created by contract developers can be converted to.
/// This could potientially have more structure, but String is the easiest.
#[serde(rename = "error")]
Err(String),
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ pub enum WasmMsg {
code_hash: String,
/// msg is the json-encoded ExecuteMsg struct (as raw Binary)
msg: Binary,
#[serde(rename = "send")]
funds: Vec<Coin>,
/// callback_sig is used only inside the enclave to validate messages
/// that are originating from other contracts
Expand All @@ -136,6 +137,7 @@ pub enum WasmMsg {
code_hash: String,
/// msg is the JSON-encoded InstantiateMsg struct (as raw Binary)
msg: Binary,
#[serde(rename = "send")]
funds: Vec<Coin>,
/// A human-readbale label for the contract
label: String,
Expand Down
44 changes: 0 additions & 44 deletions cosmwasm/packages/crypto/Cargo.toml

This file was deleted.

Loading

0 comments on commit 39f353d

Please sign in to comment.