Skip to content

Commit

Permalink
[block-import] add ImportType to distinguish sync and block-product…
Browse files Browse the repository at this point in the history
…ion import type.
  • Loading branch information
clangenb committed Jun 16, 2023
1 parent 8c13871 commit c3c46fd
Show file tree
Hide file tree
Showing 10 changed files with 143 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

use crate::{error::Result, DispatchBlockImport};
use itc_parentchain_block_importer::ImportParentchainBlocks;
use itc_parentchain_block_importer::{ImportParentchainBlocks, ImportType};
use log::*;
use std::{boxed::Box, vec::Vec};

Expand Down Expand Up @@ -47,9 +47,14 @@ impl<BlockImporter, SignedBlockType> DispatchBlockImport<SignedBlockType>
where
BlockImporter: ImportParentchainBlocks<SignedBlockType = SignedBlockType>,
{
fn dispatch_import(&self, blocks: Vec<SignedBlockType>, events: Vec<Vec<u8>>) -> Result<()> {
fn dispatch_import(
&self,
blocks: Vec<SignedBlockType>,
events: Vec<Vec<u8>>,
import_type: &ImportType,
) -> Result<()> {
debug!("Importing {} parentchain blocks", blocks.len());
self.block_importer.import_parentchain_blocks(blocks, events)?;
self.block_importer.import_parentchain_blocks(blocks, events, import_type)?;
debug!("Notifying {} observers of import", self.import_event_observers.len());
self.import_event_observers.iter().for_each(|callback| callback());
Ok(())
Expand Down Expand Up @@ -93,7 +98,9 @@ mod tests {
counter_clone.increment();
});

dispatcher.dispatch_import(vec![1u32, 2u32], vec![]).unwrap();
dispatcher
.dispatch_import(vec![1u32, 2u32], vec![], &ImportType::BlockProduction)
.unwrap();

assert_eq!(1, notification_counter.get_counter());
}
Expand Down
20 changes: 16 additions & 4 deletions core/parentchain/block-import-dispatcher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,19 @@ use crate::triggered_dispatcher::TriggerParentchainBlockImport;
use error::{Error, Result};
use std::{sync::Arc, vec::Vec};

pub use itc_parentchain_block_importer::ImportType;

/// Trait to dispatch blocks for import into the local light-client.
pub trait DispatchBlockImport<SignedBlockType> {
/// Dispatch blocks to be imported.
///
/// The blocks may be imported immediately, get queued, delayed or grouped.
fn dispatch_import(&self, blocks: Vec<SignedBlockType>, events: Vec<Vec<u8>>) -> Result<()>;
fn dispatch_import(
&self,
blocks: Vec<SignedBlockType>,
events: Vec<Vec<u8>>,
import_type: &ImportType,
) -> Result<()>;
}

/// Wrapper for the actual dispatchers. Allows to define one global type for
Expand Down Expand Up @@ -99,15 +106,20 @@ where
TriggeredDispatcher: DispatchBlockImport<SignedBlockType>,
ImmediateDispatcher: DispatchBlockImport<SignedBlockType>,
{
fn dispatch_import(&self, blocks: Vec<SignedBlockType>, events: Vec<Vec<u8>>) -> Result<()> {
fn dispatch_import(
&self,
blocks: Vec<SignedBlockType>,
events: Vec<Vec<u8>>,
import_type: &ImportType,
) -> Result<()> {
match self {
BlockImportDispatcher::TriggeredDispatcher(dispatcher) => {
log::info!("TRIGGERED DISPATCHER MATCH");
dispatcher.dispatch_import(blocks, events)
dispatcher.dispatch_import(blocks, events, import_type)
},
BlockImportDispatcher::ImmediateDispatcher(dispatcher) => {
log::info!("IMMEDIATE DISPATCHER MATCH");
dispatcher.dispatch_import(blocks, events)
dispatcher.dispatch_import(blocks, events, import_type)
},
BlockImportDispatcher::EmptyDispatcher => {
log::info!("EMPTY DISPATCHER DISPATCHER MATCH");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#[cfg(feature = "sgx")]
use std::sync::SgxRwLock as RwLock;

use itc_parentchain_block_importer::ImportType;
#[cfg(feature = "std")]
use std::sync::RwLock;

Expand Down Expand Up @@ -60,20 +61,21 @@ where
{
type SignedBlockType = SignedBlockType;

fn import_all(&self) -> Result<Option<SignedBlockType>> {
fn import_all(&self, _import_type: &ImportType) -> Result<Option<SignedBlockType>> {
let mut import_flag = self.import_has_been_called.write().unwrap();
*import_flag = true;
Ok(self.latest_imported.clone())
}

fn import_all_but_latest(&self) -> Result<()> {
fn import_all_but_latest(&self, _import_type: &ImportType) -> Result<()> {
let mut import_flag = self.import_has_been_called.write().unwrap();
*import_flag = true;
Ok(())
}

fn import_until(
&self,
_import_type: &ImportType,
_predicate: impl Fn(&SignedBlockType) -> bool,
) -> Result<Option<SignedBlockType>> {
let mut import_flag = self.import_has_been_called.write().unwrap();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
error::{Error, Result},
DispatchBlockImport,
};
use itc_parentchain_block_importer::ImportParentchainBlocks;
use itc_parentchain_block_importer::{ImportParentchainBlocks, ImportType};
use itp_import_queue::{PeekQueue, PopFromQueue, PushToQueue};
use log::trace;
use std::vec::Vec;
Expand All @@ -34,17 +34,18 @@ pub trait TriggerParentchainBlockImport {
/// Trigger the import of all queued block, **including** the latest one.
///
/// Returns the latest imported block (if any).
fn import_all(&self) -> Result<Option<Self::SignedBlockType>>;
fn import_all(&self, import_type: &ImportType) -> Result<Option<Self::SignedBlockType>>;

/// Trigger import of all queued blocks, **except** the latest one.
fn import_all_but_latest(&self) -> Result<()>;
fn import_all_but_latest(&self, import_type: &ImportType) -> Result<()>;

/// Trigger import of all blocks up to **and including** a specific block.
///
/// If no block in the queue matches, then no blocks will be imported.
/// Returns the latest imported block (if any).
fn import_until(
&self,
import_type: &ImportType,
predicate: impl Fn(&Self::SignedBlockType) -> bool,
) -> Result<Option<Self::SignedBlockType>>;

Expand Down Expand Up @@ -100,6 +101,7 @@ where
&self,
blocks: Vec<SignedBlockType>,
events: Vec<RawEventsPerBlock>,
_import_type: &ImportType,
) -> Result<()> {
trace!(
"Pushing parentchain block(s) and event(s) ({}) ({}) to import queue",
Expand All @@ -125,7 +127,10 @@ where
{
type SignedBlockType = BlockImporter::SignedBlockType;

fn import_all(&self) -> Result<Option<BlockImporter::SignedBlockType>> {
fn import_all(
&self,
import_type: &ImportType,
) -> Result<Option<BlockImporter::SignedBlockType>> {
let blocks_to_import = self.import_queue.pop_all().map_err(Error::ImportQueue)?;
let events_to_import = self.events_queue.pop_all().map_err(Error::ImportQueue)?;

Expand All @@ -138,13 +143,13 @@ where
);

self.block_importer
.import_parentchain_blocks(blocks_to_import, events_to_import)
.import_parentchain_blocks(blocks_to_import, events_to_import, import_type)
.map_err(Error::BlockImport)?;

Ok(latest_imported_block)
}

fn import_all_but_latest(&self) -> Result<()> {
fn import_all_but_latest(&self, import_type: &ImportType) -> Result<()> {
let blocks_to_import = self.import_queue.pop_all_but_last().map_err(Error::ImportQueue)?;
let events_to_import = self.events_queue.pop_all_but_last().map_err(Error::ImportQueue)?;

Expand All @@ -155,12 +160,13 @@ where
);

self.block_importer
.import_parentchain_blocks(blocks_to_import, events_to_import)
.import_parentchain_blocks(blocks_to_import, events_to_import, import_type)
.map_err(Error::BlockImport)
}

fn import_until(
&self,
import_type: &ImportType,
predicate: impl Fn(&BlockImporter::SignedBlockType) -> bool,
) -> Result<Option<BlockImporter::SignedBlockType>> {
let blocks_to_import =
Expand All @@ -180,7 +186,7 @@ where
);

self.block_importer
.import_parentchain_blocks(blocks_to_import, events_to_import)
.import_parentchain_blocks(blocks_to_import, events_to_import, import_type)
.map_err(Error::BlockImport)?;

Ok(latest_imported_block)
Expand Down
52 changes: 29 additions & 23 deletions core/parentchain/block-importer/src/block_importer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

//! Imports parentchain blocks and executes any indirect calls found in the extrinsics.
use crate::{error::Result, ImportParentchainBlocks};
use crate::{error::Result, ImportParentchainBlocks, ImportType};
use ita_stf::ParentchainHeader;
use itc_parentchain_indirect_calls_executor::ExecuteIndirectCalls;
use itc_parentchain_light_client::{
Expand Down Expand Up @@ -119,6 +119,7 @@ impl<
&self,
blocks_to_import: Vec<Self::SignedBlockType>,
events_to_import: Vec<Vec<u8>>,
import_type: &ImportType,
) -> Result<()> {
let mut calls = Vec::<OpaqueCall>::new();

Expand All @@ -138,23 +139,26 @@ impl<
}

let block = signed_block.block;
// Perform state updates.
if let Err(e) = self.stf_executor.update_states(block.header()) {
error!("Error performing state updates upon block import");
return Err(e.into())
}

// Execute indirect calls that were found in the extrinsics of the block,
// incl. shielding and unshielding.
match self
.indirect_calls_executor
.execute_indirect_calls_in_extrinsics(&block, &raw_events)
{
Ok(executed_shielding_calls) => {
calls.push(executed_shielding_calls);
},
Err(_) => error!("Error executing relevant extrinsics"),
};
if import_type == &ImportType::BlockProduction {
// Perform state updates.
if let Err(e) = self.stf_executor.update_states(block.header()) {
error!("Error performing state updates upon block import");
return Err(e.into())
}

// Execute indirect calls that were found in the extrinsics of the block,
// incl. shielding and unshielding.
match self
.indirect_calls_executor
.execute_indirect_calls_in_extrinsics(&block, &raw_events)
{
Ok(executed_shielding_calls) => {
calls.push(executed_shielding_calls);
},
Err(_) => error!("Error executing relevant extrinsics"),
};
}

info!(
"Successfully imported parentchain block (number: {}, hash: {})",
Expand All @@ -163,13 +167,15 @@ impl<
);
}

// Create extrinsics for all `unshielding` and `block processed` calls we've gathered.
let parentchain_extrinsics =
self.extrinsics_factory.create_extrinsics(calls.as_slice(), None)?;
if import_type == &ImportType::BlockProduction {
// Create extrinsics for all `unshielding` and `block processed` calls we've gathered.
let parentchain_extrinsics =
self.extrinsics_factory.create_extrinsics(calls.as_slice(), None)?;

// Sending the extrinsic requires mut access because the validator caches the sent extrinsics internally.
self.validator_accessor
.execute_mut_on_validator(|v| v.send_extrinsics(parentchain_extrinsics))?;
// Sending the extrinsic requires mut access because the validator caches the sent extrinsics internally.
self.validator_accessor
.execute_mut_on_validator(|v| v.send_extrinsics(parentchain_extrinsics))?;
}

Ok(())
}
Expand Down
10 changes: 10 additions & 0 deletions core/parentchain/block-importer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ pub use block_importer::*;
use error::Result;
use std::vec::Vec;

#[derive(Debug, PartialEq, Copy, Clone)]
pub enum ImportType {
/// Importing in sync mode and ommiting STF actions.
Sync,
/// Importing as a pre-step to sidechain block production
/// and we perform STF actions.
BlockProduction,
}

/// Block import from the parentchain.
pub trait ImportParentchainBlocks {
type SignedBlockType: Clone;
Expand All @@ -54,5 +63,6 @@ pub trait ImportParentchainBlocks {
&self,
blocks_to_import: Vec<Self::SignedBlockType>,
events_to_import: Vec<Vec<u8>>,
import_type: &ImportType,
) -> Result<()>;
}
12 changes: 8 additions & 4 deletions enclave-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ use crate::{
},
};
use codec::Decode;
use itc_parentchain::block_import_dispatcher::{
triggered_dispatcher::TriggerParentchainBlockImport, DispatchBlockImport,
use itc_parentchain::{
block_import_dispatcher::{
triggered_dispatcher::TriggerParentchainBlockImport, DispatchBlockImport,
},
block_importer::ImportType,
};
use itp_component_container::ComponentGetter;
use itp_import_queue::PushToQueue;
Expand Down Expand Up @@ -455,7 +458,8 @@ fn dispatch_parentchain_blocks_for_import<WorkerModeProvider: ProvideWorkerMode>
return Err(Error::NoParentchainAssigned)
};

import_dispatcher.dispatch_import(blocks_to_sync, events_to_sync)?;
// We use the triggered dispatched, hence the import type does not matter here.
import_dispatcher.dispatch_import(blocks_to_sync, events_to_sync, &ImportType::Sync)?;
Ok(())
}

Expand Down Expand Up @@ -514,7 +518,7 @@ pub unsafe extern "C" fn trigger_parentchain_block_import() -> sgx_status_t {

fn internal_trigger_parentchain_block_import() -> Result<()> {
let triggered_import_dispatcher = get_triggered_dispatcher_from_solo_or_parachain()?;
triggered_import_dispatcher.import_all()?;
triggered_import_dispatcher.import_all(&ImportType::Sync)?;
Ok(())
}

Expand Down
Loading

0 comments on commit c3c46fd

Please sign in to comment.