Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cw v1 refactor output structure #955

Merged
merged 2 commits into from
Jul 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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