Skip to content

Commit

Permalink
Add ISMP into the RegionX runtime (#56)
Browse files Browse the repository at this point in the history
* Add ISMP into the RegionX runtime

* compiles

* implement proxy module

* runtime apis

* fix node

* inherent

* fix

* fix message
  • Loading branch information
Szegoo authored Mar 26, 2024
1 parent f1bbf37 commit 57a96cb
Show file tree
Hide file tree
Showing 9 changed files with 1,423 additions and 1,165 deletions.
2,049 changes: 1,006 additions & 1,043 deletions Cargo.lock

Large diffs are not rendered by default.

206 changes: 105 additions & 101 deletions Cargo.toml

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ serde_json = { wokrspace = true }
regionx-runtime = { workspace = true }
regionx-primitives = { workspace = true }

# Polytope Labs
ismp-parachain-inherent = { workspace = true }

# Substrate
frame-benchmarking = { workspace = true }
frame-benchmarking-cli = { workspace = true }
Expand Down Expand Up @@ -66,6 +69,7 @@ cumulus-client-consensus-aura = { workspace = true }
cumulus-client-consensus-common = { workspace = true }
cumulus-client-consensus-proposer = { workspace = true }
cumulus-client-service = { workspace = true }
cumulus-client-parachain-inherent = { workspace = true }
cumulus-primitives-core = { workspace = true }
cumulus-primitives-parachain-inherent = { workspace = true }
cumulus-relay-chain-interface = { workspace = true }
Expand Down
60 changes: 58 additions & 2 deletions node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use cumulus_client_service::{
BuildNetworkParams, CollatorSybilResistance, DARecoveryProfile, StartRelayChainTasksParams,
};
use cumulus_primitives_core::{relay_chain::CollatorPair, ParaId};
use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface};
use cumulus_relay_chain_interface::{OccupiedCoreAssumption, OverseerHandle, RelayChainInterface};

// Substrate Imports
use frame_benchmarking_cli::SUBSTRATE_REFERENCE_HARDWARE;
Expand Down Expand Up @@ -394,8 +394,64 @@ fn start_consensus(
client.clone(),
);

let client_clone = client.clone();
let relay_chain_interface_clone = relay_chain_interface.clone();
let params = BasicAuraParams {
create_inherent_data_providers: move |_, ()| async move { Ok(()) },
create_inherent_data_providers: move |parent, ()| {
let relay_chain_interface = relay_chain_interface_clone.clone();
let client = client_clone.clone();

let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
*timestamp,
slot_duration,
);

async move {
// TODO: Double check if this is correct
let maybe_validation_data = relay_chain_interface
.persisted_validation_data(parent, para_id, OccupiedCoreAssumption::Included)
.await?;

let validation_data = match maybe_validation_data {
Some(v) => v,
None =>
return Err(format!(
"Couldn't get persisted validation data at: {:?}",
parent
)
.into()),
};

let para_inherent_data =
cumulus_client_parachain_inherent::ParachainInherentDataProvider::create_at(
parent,
&relay_chain_interface.clone(),
&validation_data,
para_id,
)
.await;

let para_inherent_data = match para_inherent_data {
Some(p) => p,
None =>
return Err(
format!("Could not create para inherent data at {:?}", parent).into()
),
};

let consensus_inherent =
ismp_parachain_inherent::ConsensusInherentProvider::create(
client.clone(),
parent,
&relay_chain_interface,
validation_data,
)
.await?;

Ok((slot, timestamp, para_inherent_data, consensus_inherent))
}
},
block_import,
para_client: client,
relay_client: relay_chain_interface,
Expand Down
14 changes: 13 additions & 1 deletion runtime/regionx/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ smallvec = { workspace = true }

# Local
regionx-primitives = { workspace = true }
pallet-parachain-template = { workspace = true }
pallet-parachain-template = { workspace = true, default-features = false }

# Polytope Labs
ismp = { workspace = true, optional = true, default-features = false }
pallet-ismp = { workspace = true, optional = true, default-features = false }
ismp-parachain = { workspace = true, optional = true, default-features = false }
ismp-runtime-api = { workspace = true, optional = true, default-features = false }
ismp-parachain-runtime-api = { workspace = true, optional = true, default-features = false }

# Substrate
frame-benchmarking = { workspace = true, optional = true }
Expand Down Expand Up @@ -87,6 +94,11 @@ std = [
"cumulus-pallet-xcmp-queue/std",
"cumulus-primitives-core/std",
"cumulus-primitives-utility/std",
"ismp/std",
"pallet-ismp/std",
"ismp-runtime-api/std",
"ismp-parachain/std",
"ismp-parachain-runtime-api/std",
"frame-benchmarking?/std",
"frame-executive/std",
"frame-support/std",
Expand Down
100 changes: 100 additions & 0 deletions runtime/regionx/src/ismp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use crate::{AccountId, Ismp, IsmpParachain, ParachainInfo, Runtime, RuntimeEvent, Timestamp};
use frame_support::pallet_prelude::Get;
use frame_system::EnsureRoot;
use ismp::{
error::Error,
host::StateMachine,
module::IsmpModule,
prelude::Vec,
router::{IsmpRouter, Post, Request, Response, Timeout},
};
use ismp_parachain::ParachainConsensusClient;
use pallet_ismp::{dispatcher::FeeMetadata, primitives::ModuleId};
use scale_info::prelude::boxed::Box;

pub struct HostStateMachine;
impl Get<StateMachine> for HostStateMachine {
fn get() -> StateMachine {
StateMachine::Kusama(ParachainInfo::get().into())
}
}

pub struct Coprocessor;

impl Get<Option<StateMachine>> for Coprocessor {
fn get() -> Option<StateMachine> {
Some(HostStateMachine::get())
}
}

impl ismp_parachain::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
}

impl pallet_ismp::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
const INDEXING_PREFIX: &'static [u8] = b"ISMP";
type AdminOrigin = EnsureRoot<AccountId>;
type HostStateMachine = HostStateMachine;
type Coprocessor = Coprocessor;
type TimeProvider = Timestamp;
type Router = Router;
type ConsensusClients = (ParachainConsensusClient<Runtime, IsmpParachain>,);
type WeightInfo = ();
type WeightProvider = ();
}

#[derive(Default)]
pub struct ProxyModule;

impl IsmpModule for ProxyModule {
fn on_accept(&self, _request: Post) -> Result<(), Error> {
// we don't support any incoming post requests.
Err(Error::CannotHandleMessage)
}

fn on_response(&self, response: Response) -> Result<(), Error> {
if response.dest_chain() != HostStateMachine::get() {
let meta = FeeMetadata { origin: [0u8; 32].into(), fee: Default::default() };
return Ismp::dispatch_response(response, meta);
}

let request = &response.request();
let from = match &request {
Request::Post(post) => &post.from,
Request::Get(get) => &get.from,
};

let pallet_id = ModuleId::from_bytes(from)
.map_err(|err| Error::ImplementationSpecific(err.to_string()))?;
match pallet_id {
// TODO: route to regions pallet
_ => Err(Error::ImplementationSpecific("Destination module not found".to_string())),
}
}

fn on_timeout(&self, timeout: Timeout) -> Result<(), Error> {
let from = match &timeout {
Timeout::Request(Request::Post(post)) => &post.from,
Timeout::Request(Request::Get(get)) => &get.from,
Timeout::Response(res) => &res.post.to,
};

let pallet_id = ModuleId::from_bytes(from)
.map_err(|err| Error::ImplementationSpecific(err.to_string()))?;
match pallet_id {
// TODO: route to regions pallet
// instead of returning an error, do nothing. The timeout is for a connected chain.
_ => Ok(()),
}
}
}

#[derive(Default)]
pub struct Router;

impl IsmpRouter for Router {
fn module_for_id(&self, _bytes: Vec<u8>) -> Result<Box<dyn IsmpModule>, Error> {
Ok(Box::new(ProxyModule::default()))
}
}
Loading

0 comments on commit 57a96cb

Please sign in to comment.