Skip to content

Commit

Permalink
Introducing add_account trusted call (#3155)
Browse files Browse the repository at this point in the history
  • Loading branch information
silva-fj authored Nov 4, 2024
1 parent 0bcb1c0 commit 4905e01
Show file tree
Hide file tree
Showing 36 changed files with 964 additions and 478 deletions.
4 changes: 3 additions & 1 deletion tee-worker/Cargo.lock

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

2 changes: 2 additions & 0 deletions tee-worker/bitacross/enclave-runtime/Cargo.lock

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

3 changes: 2 additions & 1 deletion tee-worker/bitacross/enclave-runtime/Enclave.edl
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ enclave {
sgx_status_t ocall_send_to_parentchain(
[in, size = extrinsics_size] uint8_t * extrinsics, uint32_t extrinsics_size,
[in, size=parentchain_id_size] uint8_t* parentchain_id, uint32_t parentchain_id_size,
int await_each_inclusion
[in, size=watch_until_size] uint8_t* watch_until, uint32_t watch_until_size,
[out, size = resp_size] uint8_t * response, uint32_t resp_size
);
};
};
5 changes: 4 additions & 1 deletion tee-worker/bitacross/enclave-runtime/src/ocall/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,10 @@ extern "C" {
extrinsics_size: u32,
parentchain_id: *const u8,
parentchain_id_size: u32,
await_each_inclusion: c_int,
watch_until: *const u8,
watch_until_size: u32,
response: *mut u8,
response_size: u32,
) -> sgx_status_t;

pub fn ocall_read_ipfs(
Expand Down
55 changes: 46 additions & 9 deletions tee-worker/bitacross/enclave-runtime/src/ocall/on_chain_ocall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,42 @@
*/

use crate::ocall::{ffi, OcallApi};
use codec::{Decode, Encode};
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::ensure;
use itp_node_api::api_client::{ExtrinsicReport, XtStatus};
use itp_ocall_api::{EnclaveOnChainOCallApi, Error, Result};
use itp_storage::{verify_storage_entries, Error as StorageError};
use itp_types::{
parentchain::ParentchainId, storage::StorageEntryVerified, WorkerRequest, WorkerResponse, H256,
parentchain::{AccountId, Index as ParentchainIndex, ParentchainId},
storage::StorageEntryVerified,
WorkerRequest, WorkerResponse, H256,
};
use log::*;
use sgx_types::*;
use sp_runtime::{traits::Header, OpaqueExtrinsic};
use std::vec::Vec;
use std::{mem::size_of, vec::Vec};

impl EnclaveOnChainOCallApi for OcallApi {
fn send_to_parentchain(
&self,
extrinsics: Vec<OpaqueExtrinsic>,
parentchain_id: &ParentchainId,
await_each_inclusion: bool,
) -> SgxResult<()> {
watch_until: Option<XtStatus>,
) -> SgxResult<Vec<ExtrinsicReport<H256>>> {
let mut rt: sgx_status_t = sgx_status_t::SGX_ERROR_UNEXPECTED;
let extrinsics_encoded = extrinsics.encode();
let parentchain_id_encoded = parentchain_id.encode();
let watch_until_encoded = watch_until.encode();
let response_size = match watch_until {
Some(_) => extrinsics
.len()
.checked_mul(ExtrinsicReport::<H256>::max_encoded_len())
.ok_or(sgx_status_t::SGX_ERROR_UNEXPECTED)?
.checked_add(size_of::<Vec<u8>>())
.ok_or(sgx_status_t::SGX_ERROR_UNEXPECTED)?,
None => size_of::<Vec<u8>>(),
};
let mut response: Vec<u8> = vec![0; response_size];

let res = unsafe {
ffi::ocall_send_to_parentchain(
Expand All @@ -47,14 +61,23 @@ impl EnclaveOnChainOCallApi for OcallApi {
extrinsics_encoded.len() as u32,
parentchain_id_encoded.as_ptr(),
parentchain_id_encoded.len() as u32,
await_each_inclusion.into(),
watch_until_encoded.as_ptr(),
watch_until_encoded.len() as u32,
response.as_mut_ptr(),
response_size as u32,
)
};

ensure!(rt == sgx_status_t::SGX_SUCCESS, rt);
ensure!(res == sgx_status_t::SGX_SUCCESS, res);

Ok(())
let decoded_response: Vec<ExtrinsicReport<H256>> = Decode::decode(&mut response.as_slice())
.map_err(|e| {
error!("Failed to decode ExtrinsicReport: {}", e);
sgx_status_t::SGX_ERROR_UNEXPECTED
})?;

Ok(decoded_response)
}

fn worker_request<V: Encode + Decode>(
Expand Down Expand Up @@ -172,10 +195,10 @@ impl EnclaveOnChainOCallApi for OcallApi {
Ok(first_response.clone())
}

fn get_header<H: Header<Hash = H256>>(&self, parentchain_id: &ParentchainId) -> Result<H> {
fn get_header<H: Header<Hash = H256>>(&self) -> Result<H> {
let request = vec![WorkerRequest::ChainHeader(None)];
let responses: Vec<H> = self
.worker_request::<Vec<u8>>(request, parentchain_id)?
.worker_request::<Vec<u8>>(request, &ParentchainId::Litentry)?
.iter()
.filter_map(|r| match r {
WorkerResponse::ChainHeader(Some(h)) =>
Expand All @@ -186,4 +209,18 @@ impl EnclaveOnChainOCallApi for OcallApi {

responses.first().cloned().ok_or(Error::ChainCallFailed)
}

fn get_account_nonce(&self, account_id: AccountId) -> Result<ParentchainIndex> {
let request = vec![WorkerRequest::ChainAccountNonce(account_id.encode())];
let responses: Vec<ParentchainIndex> = self
.worker_request::<Vec<ParentchainIndex>>(request, &ParentchainId::Litentry)?
.iter()
.filter_map(|r| match r {
WorkerResponse::ChainAccountNonce(Some(index)) => Some(*index),
_ => None,
})
.collect();

responses.first().cloned().ok_or(Error::ChainCallFailed)
}
}
4 changes: 2 additions & 2 deletions tee-worker/bitacross/service/src/ocall_bridge/bridge_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,8 @@ pub trait WorkerOnChainBridge {
&self,
extrinsics_encoded: Vec<u8>,
parentchain_id: Vec<u8>,
await_each_inclusion: bool,
) -> OCallBridgeResult<()>;
watch_until: Vec<u8>,
) -> OCallBridgeResult<Vec<u8>>;
}

/// Trait for updating metrics from inside the enclave.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

use crate::ocall_bridge::bridge_api::{Bridge, WorkerOnChainBridge};
use itp_utils::write_slice_and_whitespace_pad;
use log::*;
use sgx_types::{c_int, sgx_status_t};
use std::{slice, sync::Arc, vec::Vec};
Expand All @@ -30,35 +31,53 @@ pub unsafe extern "C" fn ocall_send_to_parentchain(
extrinsics_encoded_size: u32,
parentchain_id: *const u8,
parentchain_id_size: u32,
await_each_inclusion: c_int,
watch_until: *const u8,
watch_until_size: u32,
response: *mut u8,
resp_size: u32,
) -> sgx_status_t {
send_to_parentchain(
extrinsics_encoded,
extrinsics_encoded_size,
parentchain_id,
parentchain_id_size,
await_each_inclusion == 1,
watch_until,
watch_until_size,
response,
resp_size,
Bridge::get_oc_api(),
)
}

#[allow(clippy::too_many_arguments)]
fn send_to_parentchain(
extrinsics_encoded: *const u8,
extrinsics_encoded_size: u32,
parentchain_id: *const u8,
parentchain_id_size: u32,
await_each_inclusion: bool,
watch_until: *const u8,
watch_until_size: u32,
response: *mut u8,
resp_size: u32,
oc_api: Arc<dyn WorkerOnChainBridge>,
) -> sgx_status_t {
let extrinsics_encoded_vec: Vec<u8> = unsafe {
Vec::from(slice::from_raw_parts(extrinsics_encoded, extrinsics_encoded_size as usize))
};

let parentchain_id: Vec<u8> =
unsafe { Vec::from(slice::from_raw_parts(parentchain_id, parentchain_id_size as usize)) };
let watch_until: Vec<u8> =
unsafe { Vec::from(slice::from_raw_parts(watch_until, watch_until_size as usize)) };

match oc_api.send_to_parentchain(extrinsics_encoded_vec, parentchain_id, await_each_inclusion) {
Ok(_) => sgx_status_t::SGX_SUCCESS,
match oc_api.send_to_parentchain(extrinsics_encoded_vec, parentchain_id, watch_until) {
Ok(r) => {
let resp_slice = unsafe { slice::from_raw_parts_mut(response, resp_size as usize) };
if let Err(e) = write_slice_and_whitespace_pad(resp_slice, r) {
error!("Failed to transfer send_to_parentchain response to o-call buffer: {:?}", e);
return sgx_status_t::SGX_ERROR_UNEXPECTED
}
sgx_status_t::SGX_SUCCESS
},
Err(e) => {
error!("send extrinsics_encoded failed: {:?}", e);
sgx_status_t::SGX_ERROR_UNEXPECTED
Expand Down
Loading

0 comments on commit 4905e01

Please sign in to comment.