Skip to content

Commit

Permalink
skip indirect invocations for initial sync of integritee parentchain (#…
Browse files Browse the repository at this point in the history
…1517)

* ensure extrinsic success for enclave RA registration and fix #1515

* postpone provisioning to after registering own enclave onchain

* remove request-state argument form run config. no longer necessary to explicitly request this

* introduce shard birth concept and a bit of renaming throughout

* fixing startup panic. fast-sync disabled now

* fast-syncing integritee parentchain now

* cargo fix

* clippy

* fast-sync now also skips event and proof fetching from rpc

* clippy

* OCW now provisions entire state as well

* fix enclave tests

* fetch peer for provisioning based on their activity and avoid fetching from other shards or self

* tiny clone remove

* rename birth > creation

* bump v0.12.2

* rename is_syncing > immediate_import
  • Loading branch information
brenzi authored Dec 8, 2023
1 parent 66223ce commit 8a3ea6e
Show file tree
Hide file tree
Showing 34 changed files with 694 additions and 246 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2704,7 +2704,7 @@ dependencies = [

[[package]]
name = "integritee-cli"
version = "0.12.1"
version = "0.12.2"
dependencies = [
"array-bytes 6.1.0",
"base58",
Expand Down Expand Up @@ -2796,7 +2796,7 @@ dependencies = [

[[package]]
name = "integritee-service"
version = "0.12.1"
version = "0.12.2"
dependencies = [
"anyhow",
"async-trait",
Expand Down
2 changes: 1 addition & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "integritee-cli"
version = "0.12.1"
version = "0.12.2"
authors = ["Integritee AG <[email protected]>"]
edition = "2021"

Expand Down
22 changes: 21 additions & 1 deletion core-primitives/enclave-api/ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,26 @@ extern "C" {
parentchain_id_size: u32,
) -> sgx_status_t;

pub fn init_shard_creation_parentchain_header(
eid: sgx_enclave_id_t,
retval: *mut sgx_status_t,
shard: *const u8,
shard_size: u32,
parentchain_id: *const u8,
parentchain_id_size: u32,
header: *const u8,
header_size: u32,
) -> sgx_status_t;

pub fn get_shard_creation_header(
eid: sgx_enclave_id_t,
retval: *mut sgx_status_t,
shard: *const u8,
shard_size: u32,
creation: *mut u8,
creation_size: u32,
) -> sgx_status_t;

pub fn execute_trusted_calls(eid: sgx_enclave_id_t, retval: *mut sgx_status_t) -> sgx_status_t;

pub fn sync_parentchain(
Expand All @@ -80,7 +100,7 @@ extern "C" {
events_proofs_size: usize,
parentchain_id: *const u8,
parentchain_id_size: u32,
is_syncing: c_int,
immediate_import: c_int,
) -> sgx_status_t;

pub fn set_nonce(
Expand Down
72 changes: 70 additions & 2 deletions core-primitives/enclave-api/src/enclave_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::EnclaveResult;
use codec::Decode;
use core::fmt::Debug;
use itc_parentchain::primitives::{ParentchainId, ParentchainInitParams};
use itp_types::ShardIdentifier;
use itp_types::{parentchain::Header, ShardIdentifier};
use sgx_crypto_helper::rsa3072::Rsa3072PubKey;
use sp_core::ed25519;
use teerex_primitives::EnclaveFingerprint;
Expand Down Expand Up @@ -57,6 +57,19 @@ pub trait EnclaveBase: Send + Sync + 'static {
parentchain_id: &ParentchainId,
) -> EnclaveResult<()>;

/// Initialize parentchain checkpoint after which invocations will be processed
fn init_shard_creation_parentchain_header(
&self,
shard: &ShardIdentifier,
parentchain_id: &ParentchainId,
header: &Header,
) -> EnclaveResult<()>;

fn get_shard_creation_header(
&self,
shard: &ShardIdentifier,
) -> EnclaveResult<(ParentchainId, Header)>;

fn set_nonce(&self, nonce: u32, parentchain_id: ParentchainId) -> EnclaveResult<()>;

fn set_node_metadata(
Expand Down Expand Up @@ -88,7 +101,7 @@ mod impl_ffi {
use itp_settings::worker::{
HEADER_MAX_SIZE, MR_ENCLAVE_SIZE, SHIELDING_KEY_SIZE, SIGNING_KEY_SIZE,
};
use itp_types::ShardIdentifier;
use itp_types::{parentchain::Header, ShardIdentifier};
use log::*;
use sgx_crypto_helper::rsa3072::Rsa3072PubKey;
use sgx_types::*;
Expand Down Expand Up @@ -208,6 +221,61 @@ mod impl_ffi {
Ok(())
}

fn init_shard_creation_parentchain_header(
&self,
shard: &ShardIdentifier,
parentchain_id: &ParentchainId,
header: &Header,
) -> EnclaveResult<()> {
let mut retval = sgx_status_t::SGX_SUCCESS;
let parentchain_id_enc = parentchain_id.encode();
let header_bytes = header.encode();
let shard_bytes = shard.encode();
let result = unsafe {
ffi::init_shard_creation_parentchain_header(
self.eid,
&mut retval,
shard_bytes.as_ptr(),
shard_bytes.len() as u32,
parentchain_id_enc.as_ptr(),
parentchain_id_enc.len() as u32,
header_bytes.as_ptr(),
header_bytes.len() as u32,
)
};

ensure!(result == sgx_status_t::SGX_SUCCESS, Error::Sgx(result));
ensure!(retval == sgx_status_t::SGX_SUCCESS, Error::Sgx(retval));

Ok(())
}

fn get_shard_creation_header(
&self,
shard: &ShardIdentifier,
) -> EnclaveResult<(ParentchainId, Header)> {
let mut retval = sgx_status_t::SGX_SUCCESS;
let mut creation = [0u8; HEADER_MAX_SIZE + std::mem::size_of::<ParentchainId>()];
let shard_bytes = shard.encode();

let result = unsafe {
ffi::get_shard_creation_header(
self.eid,
&mut retval,
shard_bytes.as_ptr(),
shard_bytes.len() as u32,
creation.as_mut_ptr(),
creation.len() as u32,
)
};

ensure!(result == sgx_status_t::SGX_SUCCESS, Error::Sgx(result));
ensure!(retval == sgx_status_t::SGX_SUCCESS, Error::Sgx(retval));
let (creation_parentchain_id, creation_header): (ParentchainId, Header) =
Decode::decode(&mut creation.as_slice())?;
Ok((creation_parentchain_id, creation_header))
}

fn set_nonce(&self, nonce: u32, parentchain_id: ParentchainId) -> EnclaveResult<()> {
let mut retval = sgx_status_t::SGX_SUCCESS;

Expand Down
6 changes: 3 additions & 3 deletions core-primitives/enclave-api/src/sidechain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub trait Sidechain: Send + Sync + 'static {
events: &[Vec<u8>],
events_proofs: &[StorageProof],
parentchain_id: &ParentchainId,
is_syncing: bool,
immediate_import: bool,
) -> EnclaveResult<()>;

fn execute_trusted_calls(&self) -> EnclaveResult<()>;
Expand All @@ -57,7 +57,7 @@ mod impl_ffi {
events: &[Vec<u8>],
events_proofs: &[StorageProof],
parentchain_id: &ParentchainId,
is_syncing: bool,
immediate_import: bool,
) -> EnclaveResult<()> {
let mut retval = sgx_status_t::SGX_SUCCESS;
let blocks_enc = blocks.encode();
Expand All @@ -77,7 +77,7 @@ mod impl_ffi {
events_proofs_enc.len(),
parentchain_id_enc.as_ptr(),
parentchain_id_enc.len() as u32,
is_syncing.into(),
immediate_import.into(),
)
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

use crate::ApiResult;
use itp_api_client_types::{traits::GetStorage, Api, Config, Request};
use itp_types::{AccountId, IpfsHash, MultiEnclave, ShardIdentifier, ShardStatus};
use itp_types::{
AccountId, IpfsHash, MultiEnclave, ShardIdentifier, ShardSignerStatus, ShardStatus,
};
use log::error;

pub const TEEREX: &str = "Teerex";
Expand All @@ -40,6 +42,11 @@ pub trait PalletTeerexApi {
shard: &ShardIdentifier,
at_block: Option<Self::Hash>,
) -> ApiResult<Option<MultiEnclave<Vec<u8>>>>;
fn shard_status(
&self,
shard: &ShardIdentifier,
at_block: Option<Self::Hash>,
) -> ApiResult<Option<Vec<ShardSignerStatus>>>;
fn latest_ipfs_hash(
&self,
shard: &ShardIdentifier,
Expand Down Expand Up @@ -100,6 +107,14 @@ where
)
}

fn shard_status(
&self,
shard: &ShardIdentifier,
at_block: Option<Self::Hash>,
) -> ApiResult<Option<Vec<ShardSignerStatus>>> {
self.get_storage_map(ENCLAVE_BRIDGE, "ShardStatus", shard, at_block)
}

fn latest_ipfs_hash(
&self,
shard: &ShardIdentifier,
Expand Down
1 change: 1 addition & 0 deletions core-primitives/stf-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub mod sudo_pallet;
pub mod system_pallet;

pub const SHARD_VAULT_KEY: &str = "ShardVaultPubKey";
pub const SHARD_CREATION_HEADER_KEY: &str = "ShardCreationHeaderKey";

/// Interface to initialize a new state.
pub trait InitState<State, AccountId> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ where
&self,
blocks: Vec<SignedBlockType>,
events: Vec<Vec<u8>>,
_is_syncing: bool,
_immediate_import: bool,
) -> Result<()> {
// _is_syncing does not matter for the immediate dispatcher, behavoiur is the same. Immediate block import.
// _immediate_import does not matter for the immediate dispatcher, behavoiur is the same. Immediate block import.

debug!("Importing {} parentchain blocks", blocks.len());
self.block_importer.import_parentchain_blocks(blocks, events)?;
Expand Down
8 changes: 4 additions & 4 deletions core/parentchain/block-import-dispatcher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ pub trait DispatchBlockImport<SignedBlockType> {
&self,
blocks: Vec<SignedBlockType>,
events: Vec<Vec<u8>>,
is_syncing: bool,
immediate_import: bool,
) -> Result<()>;
}

Expand Down Expand Up @@ -105,16 +105,16 @@ where
&self,
blocks: Vec<SignedBlockType>,
events: Vec<Vec<u8>>,
is_syncing: bool,
immediate_import: bool,
) -> Result<()> {
match self {
BlockImportDispatcher::TriggeredDispatcher(dispatcher) => {
log::trace!("TRIGGERED DISPATCHER MATCH");
dispatcher.dispatch_import(blocks, events, is_syncing)
dispatcher.dispatch_import(blocks, events, immediate_import)
},
BlockImportDispatcher::ImmediateDispatcher(dispatcher) => {
log::trace!("IMMEDIATE DISPATCHER MATCH");
dispatcher.dispatch_import(blocks, events, is_syncing)
dispatcher.dispatch_import(blocks, events, immediate_import)
},
BlockImportDispatcher::EmptyDispatcher => {
log::trace!("EMPTY DISPATCHER DISPATCHER MATCH");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ where
&self,
blocks: Vec<SignedBlockType>,
events: Vec<RawEventsPerBlock>,
is_syncing: bool,
immediate_import: bool,
) -> Result<()> {
let parentchain_id = self.block_importer.parentchain_id();
trace!(
Expand All @@ -109,7 +109,7 @@ where
blocks.len(),
events.len()
);
if is_syncing {
if immediate_import {
trace!(
"[{:?}] Triggered is in sync mode, immediately importing blocks and events",
parentchain_id
Expand Down
20 changes: 19 additions & 1 deletion core/parentchain/block-importer/src/block_importer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
//! Imports parentchain blocks and executes any indirect calls found in the extrinsics.

use crate::{error::Result, ImportParentchainBlocks};

use ita_stf::ParentchainHeader;
use itc_parentchain_indirect_calls_executor::ExecuteIndirectCalls;
use itc_parentchain_light_client::{
Expand All @@ -26,7 +27,7 @@ use itc_parentchain_light_client::{
use itp_extrinsics_factory::CreateExtrinsics;
use itp_stf_executor::traits::StfUpdateState;
use itp_types::{
parentchain::{IdentifyParentchain, ParentchainId},
parentchain::{Header, IdentifyParentchain, ParentchainId},
OpaqueCall, H256,
};
use log::*;
Expand All @@ -48,6 +49,7 @@ pub struct ParentchainBlockImporter<
stf_executor: Arc<StfExecutor>,
extrinsics_factory: Arc<ExtrinsicsFactory>,
pub indirect_calls_executor: Arc<IndirectCallsExecutor>,
maybe_creation_header: Option<Header>,
_phantom: PhantomData<ParentchainBlock>,
}

Expand All @@ -71,12 +73,14 @@ impl<
stf_executor: Arc<StfExecutor>,
extrinsics_factory: Arc<ExtrinsicsFactory>,
indirect_calls_executor: Arc<IndirectCallsExecutor>,
maybe_creation_header: Option<Header>,
) -> Self {
ParentchainBlockImporter {
validator_accessor,
stf_executor,
extrinsics_factory,
indirect_calls_executor,
maybe_creation_header,
_phantom: Default::default(),
}
}
Expand Down Expand Up @@ -122,9 +126,23 @@ impl<
.execute_mut_on_validator(|v| v.submit_block(&signed_block))
{
error!("[{:?}] Header submission to light client failed: {:?}", id, e);

return Err(e.into())
}

// check if we can fast-sync
if id == ParentchainId::Integritee {
if let Some(ref creation_header) = self.maybe_creation_header {
if signed_block.block.header().number < creation_header.number {
trace!(
"fast-syncing block import, ignoring any invocations before block {:}",
creation_header.number
);
continue
}
}
}

let block = signed_block.block;
// Perform state updates.
if let Err(e) = self
Expand Down
18 changes: 10 additions & 8 deletions core/parentchain/parentchain-crate/src/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ use codec::{Decode, Encode};

use sp_runtime::traits::Block;

use itp_types::ShardIdentifier;
pub use itp_types::{parentchain::ParentchainId, Block as ParachainBlock, Block as SolochainBlock};

pub type HeaderFor<B> = <B as Block>::Header;
pub type SolochainHeader = HeaderFor<SolochainBlock>;
pub type ParachainHeader = HeaderFor<ParachainBlock>;
Expand All @@ -33,8 +35,8 @@ pub type ParachainParams = SimpleParams<ParachainHeader>;
/// Allows to use a single E-call for the initialization of different parentchain types.
#[derive(Encode, Decode, Clone)]
pub enum ParentchainInitParams {
Solochain { id: ParentchainId, params: SolochainParams },
Parachain { id: ParentchainId, params: ParachainParams },
Solochain { id: ParentchainId, shard: ShardIdentifier, params: SolochainParams },
Parachain { id: ParentchainId, shard: ShardIdentifier, params: ParachainParams },
}

impl ParentchainInitParams {
Expand All @@ -46,14 +48,14 @@ impl ParentchainInitParams {
}
}

impl From<(ParentchainId, SolochainParams)> for ParentchainInitParams {
fn from(value: (ParentchainId, SolochainParams)) -> Self {
Self::Solochain { id: value.0, params: value.1 }
impl From<(ParentchainId, ShardIdentifier, SolochainParams)> for ParentchainInitParams {
fn from(value: (ParentchainId, ShardIdentifier, SolochainParams)) -> Self {
Self::Solochain { id: value.0, shard: value.1, params: value.2 }
}
}

impl From<(ParentchainId, ParachainParams)> for ParentchainInitParams {
fn from(value: (ParentchainId, ParachainParams)) -> Self {
Self::Parachain { id: value.0, params: value.1 }
impl From<(ParentchainId, ShardIdentifier, ParachainParams)> for ParentchainInitParams {
fn from(value: (ParentchainId, ShardIdentifier, ParachainParams)) -> Self {
Self::Parachain { id: value.0, shard: value.1, params: value.2 }
}
}
Loading

0 comments on commit 8a3ea6e

Please sign in to comment.