Skip to content

Commit

Permalink
feat: add ismp
Browse files Browse the repository at this point in the history
  • Loading branch information
evilrobot-01 committed Mar 24, 2024
1 parent 17dab67 commit 3d2bb3a
Show file tree
Hide file tree
Showing 5 changed files with 354 additions and 16 deletions.
135 changes: 124 additions & 11 deletions Cargo.lock

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

9 changes: 8 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,11 @@ cumulus-client-collator = "0.8.0"
cumulus-client-consensus-aura = "0.8.0"
cumulus-client-consensus-common = "0.8.0"
cumulus-client-consensus-proposer = "0.8.0"
cumulus-client-service = "0.8.0"
cumulus-client-service = "0.8.0"

# ISMP
ismp = { git = "https://github.com/r0gue-io/ismp", branch = "pop", default-features = false }
ismp-parachain = { git = "https://github.com/r0gue-io/ismp", branch = "pop", default-features = false }
ismp-parachain-runtime-api = { git = "https://github.com/r0gue-io/ismp", branch = "pop", default-features = false }
ismp-runtime-api = { git = "https://github.com/r0gue-io/ismp", branch = "pop", default-features = false }
pallet-ismp = { git = "https://github.com/r0gue-io/ismp", branch = "pop", default-features = false }
12 changes: 12 additions & 0 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ pallet-collator-selection = { workspace = true }
parachains-common = { workspace = true }
parachain-info = { workspace = true }

# ISMP
ismp.workspace = true
ismp-parachain.workspace = true
ismp-parachain-runtime-api.workspace = true
ismp-runtime-api.workspace = true
pallet-ismp.workspace = true

[dev-dependencies]
env_logger = "0.11.2"
hex = "0.4.3"
Expand All @@ -107,13 +114,18 @@ std = [
"frame-system-rpc-runtime-api/std",
"frame-system/std",
"frame-try-runtime/std",
"ismp/std",
"ismp-parachain/std",
"ismp-parachain-runtime-api/std",
"ismp-runtime-api/std",
"log/std",
"pallet-aura/std",
"pallet-authorship/std",
"pallet-assets/std",
"pallet-balances/std",
"pallet-collator-selection/std",
"pallet-contracts/std",
"pallet-ismp/std",
"pallet-message-queue/std",
"pallet-nft-fractionalization/std",
"pallet-nfts/std",
Expand Down
104 changes: 104 additions & 0 deletions runtime/src/ismp_config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
use crate::{AccountId, Ismp, IsmpParachain, ParachainInfo, Runtime, RuntimeEvent, Timestamp};
use frame_support::traits::Get;
use frame_system::EnsureRoot;
use ismp::{
error::Error,
host::StateMachine,
module::IsmpModule,
router::{IsmpRouter, Post, Request, Response, Timeout},
};
use ismp_parachain::ParachainConsensusClient;
use pallet_ismp::{dispatcher::FeeMetadata, primitives::ModuleId};
use sp_std::prelude::*;

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 = ();
}

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

pub struct Coprocessor;

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

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

#[derive(Default)]
pub struct ProxyModule;
impl IsmpModule for ProxyModule {
fn on_accept(&self, request: Post) -> Result<(), Error> {
if request.dest != HostStateMachine::get() {
let meta = FeeMetadata { origin: [0u8; 32].into(), fee: Default::default() };
return Ismp::dispatch_request(Request::Post(request), meta);
}

let pallet_id = ModuleId::from_bytes(&request.to)
.map_err(|err| Error::ImplementationSpecific(err.to_string()))?;
match pallet_id {
_ => Err(Error::ImplementationSpecific("Destination module not found".to_string())),
}

Check warning on line 59 in runtime/src/ismp_config.rs

View workflow job for this annotation

GitHub Actions / clippy

this match could be replaced by its body itself

warning: this match could be replaced by its body itself --> runtime/src/ismp_config.rs:57:3 | 57 | / match pallet_id { 58 | | _ => Err(Error::ImplementationSpecific("Destination module not found".to_string())), 59 | | } | |_________^ help: consider using the match body instead: `Err(Error::ImplementationSpecific("Destination module not found".to_string()))` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_single_binding = note: `#[warn(clippy::match_single_binding)]` on by default
}

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 {
_ => Err(Error::ImplementationSpecific("Destination module not found".to_string())),
}

Check warning on line 78 in runtime/src/ismp_config.rs

View workflow job for this annotation

GitHub Actions / clippy

this match could be replaced by its body itself

warning: this match could be replaced by its body itself --> runtime/src/ismp_config.rs:76:3 | 76 | / match pallet_id { 77 | | _ => Err(Error::ImplementationSpecific("Destination module not found".to_string())), 78 | | } | |_________^ help: consider using the match body instead: `Err(Error::ImplementationSpecific("Destination module not found".to_string()))` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_single_binding
}

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 {
// instead of returning an error, do nothing. The timeout is for a connected chain.
_ => Ok(()),
}

Check warning on line 93 in runtime/src/ismp_config.rs

View workflow job for this annotation

GitHub Actions / clippy

this match could be replaced by its body itself

warning: this match could be replaced by its body itself --> runtime/src/ismp_config.rs:90:3 | 90 | / match pallet_id { 91 | | // instead of returning an error, do nothing. The timeout is for a connected chain. 92 | | _ => Ok(()), 93 | | } | |_________^ help: consider using the match body instead: `Ok(())` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_single_binding
}
}

#[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()))

Check warning on line 102 in runtime/src/ismp_config.rs

View workflow job for this annotation

GitHub Actions / clippy

use of `default` to create a unit struct

warning: use of `default` to create a unit struct --> runtime/src/ismp_config.rs:102:26 | 102 | Ok(Box::new(ProxyModule::default())) | ^^^^^^^^^^^ help: remove this call to `default` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#default_constructed_unit_structs = note: `#[warn(clippy::default_constructed_unit_structs)]` on by default

Check warning on line 102 in runtime/src/ismp_config.rs

View workflow job for this annotation

GitHub Actions / clippy

`Box::new(_)` of default value

warning: `Box::new(_)` of default value --> runtime/src/ismp_config.rs:102:6 | 102 | Ok(Box::new(ProxyModule::default())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ProxyModule>::default()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#box_default = note: `#[warn(clippy::box_default)]` on by default
}
}
Loading

0 comments on commit 3d2bb3a

Please sign in to comment.