diff --git a/Cargo.lock b/Cargo.lock
index bf4bfa28517..51c70c0b785 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -449,10 +449,13 @@ dependencies = [
"memory-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"polkadot-parachain 0.6.0 (git+https://github.com/paritytech/polkadot?branch=bkchr-cumulus-branch)",
+ "polkadot-primitives 0.6.0 (git+https://github.com/paritytech/polkadot?branch=bkchr-cumulus-branch)",
"sr-io 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
"sr-primitives 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
"sr-std 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
"srml-executive 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
+ "srml-support 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
+ "srml-system 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
"substrate-consensus-common 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
"substrate-executor 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
"substrate-keyring 2.0.0 (git+https://github.com/paritytech/substrate?branch=bkchr-cumulus-branch)",
diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml
index 433c8fee635..c23105cae06 100644
--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -17,10 +17,13 @@ rstd = { package = "sr-std", git = "https://github.com/paritytech/substrate", de
runtime-primitives = { package = "sr-primitives", git = "https://github.com/paritytech/substrate", default-features = false, branch = "bkchr-cumulus-branch" }
primitives = { package = "substrate-primitives", git = "https://github.com/paritytech/substrate", default-features = false, branch = "bkchr-cumulus-branch" }
rio = { package = "sr-io", git = "https://github.com/paritytech/substrate", default-features = false, branch = "bkchr-cumulus-branch" }
+support = { package = "srml-support", git = "https://github.com/paritytech/substrate", default-features = false, branch = "bkchr-cumulus-branch" }
+system = { package = "srml-system", git = "https://github.com/paritytech/substrate", default-features = false, branch = "bkchr-cumulus-branch" }
executive = { package = "srml-executive", git = "https://github.com/paritytech/substrate", default-features = false, branch = "bkchr-cumulus-branch" }
substrate-trie = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "bkchr-cumulus-branch" }
# Polkadot dependencies
+polkadot-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "bkchr-cumulus-branch" }
parachain = { package = "polkadot-parachain", git = "https://github.com/paritytech/polkadot", branch = "bkchr-cumulus-branch", default-features = false, features = [ "wasm-api" ] }
[dev-dependencies]
@@ -42,5 +45,6 @@ std = [
"hash-db/std",
"trie-db/std",
"substrate-trie/std",
+ "polkadot-primitives/std",
"parachain/std",
]
diff --git a/runtime/src/icmp.rs b/runtime/src/icmp.rs
new file mode 100644
index 00000000000..1d1cfc6dca1
--- /dev/null
+++ b/runtime/src/icmp.rs
@@ -0,0 +1,186 @@
+// Copyright 2019 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Cumulus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Cumulus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus. If not, see .
+
+//! The main entry point for messaging I/O of the runtime.
+//!
+//! This module includes:
+//! - logic for creating inherent extrinsics on the client-side from a set of incoming messages;
+//! - API to allow runtimes to configure the how messages are handled;
+//! - API to allow runtimes to deposit outgoing messages.
+
+use rstd::prelude::*;
+use codec::Codec;
+use support::{decl_module, decl_storage, decl_event};
+use system::ensure_none;
+use runtime_primitives::traits::Dispatchable;
+use polkadot_primitives::parachain::{Chain, Id as ParaId};
+
+/// Means of handling a bunch of "messages" (opaque blobs of data) coming in from other chains.
+pub trait HandleMessages {
+ /// Messages have arrived: do something with them. The default implementation just forwards
+ /// each message to be handled by `handle_message`.
+ fn handle_messages(messages: &[(Chain, Vec)]) {
+ for (from, ref data) in messages.iter() {
+ Self::handle_message(*from, data)
+ }
+ }
+
+ /// Handle an individual message of `_data` from endpoint `_from`. The default implementation
+ /// simply drops the message.
+ fn handle_message(_from: Chain, _data: &[u8]) {}
+}
+
+/// Empty tuple drops all messages.
+impl HandleMessages for () {}
+
+/// An origin for this module.
+#[derive(PartialEq, Eq, Clone)]
+#[cfg_attr(feature = "std", derive(Debug))]
+pub enum Origin {
+ /// It comes from a parachain.
+ Parachain(ParaId),
+
+ /// It comes from the Relay chain.
+ Relay,
+}
+
+/// A message handler which treats each message as a `Call` and dispatches them as per `Call`s
+/// with a corresponding `Origin`.
+pub struct DispatchCall(::rstd::marker::PhantomData<(Origin, Call)>);
+
+impl<
+ Call: Codec + Dispatchable
+> HandleMessages for DispatchCall where Call::Origin: From {
+ fn handle_message(from: Chain, mut data: &[u8]) {
+ if let Ok(call) = Call::decode(&mut data) {
+ let origin: Call::Origin = match from {
+ Chain::Parachain(id) => Origin::Parachain(id),
+ Chain::Relay => Origin::Relay,
+ }.into();
+ // we disregard the result for now, much like transactions. If we eventually get some
+ // economic disincentive to spam the chain, then we could place events down here.
+ let _ = call.dispatch(origin);
+ }
+ }
+}
+
+/// The module's configuration trait.
+pub trait Trait: system::Trait {
+ /// The type which is used to handle incoming messages.
+ type OnIncoming: HandleMessages;
+
+ /// The outer origin type.
+ type Origin: From + From>;
+
+ /// The overarching event type.
+ type Event: From + Into<::Event>;
+}
+
+// This module's storage items.
+decl_storage! {
+ trait Store for Module as TemplateModule {
+ }
+}
+
+// The module's dispatchable functions.
+decl_module! {
+ /// The module declaration.
+ pub struct Module for enum Call where origin: ::Origin {
+ fn deposit_event() = default;
+
+ /// Provide any incoming messages from external ICMP chains (i.e. parachains or the relay
+ /// chain) for this block to execute.
+ fn note_incoming(origin, messages: Vec<(Chain, Vec)>) {
+ ensure_none(origin)?;
+
+ T::OnIncoming::handle_messages(&messages);
+ }
+ }
+}
+
+decl_event!(
+ pub enum Event {
+ // Just a dummy event.
+ Dummy,
+ }
+);
+
+/// tests for this module
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ use primitives::H256;
+ use support::{impl_outer_origin, assert_ok, parameter_types};
+ use sr_primitives::{
+ traits::{BlakeTwo256, IdentityLookup}, testing::Header, weights::Weight, Perbill,
+ };
+
+ impl_outer_origin! {
+ pub enum Origin for Test {}
+ }
+
+ // For testing the module, we construct most of a mock runtime. This means
+ // first constructing a configuration type (`Test`) which `impl`s each of the
+ // configuration traits of modules we want to use.
+ #[derive(Clone, Eq, PartialEq)]
+ pub struct Test;
+ parameter_types! {
+ pub const BlockHashCount: u64 = 250;
+ pub const MaximumBlockWeight: Weight = 1024;
+ pub const MaximumBlockLength: u32 = 2 * 1024;
+ pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
+ }
+ impl system::Trait for Test {
+ type Origin = Origin;
+ type Call = ();
+ type Index = u64;
+ type BlockNumber = u64;
+ type Hash = H256;
+ type Hashing = BlakeTwo256;
+ type AccountId = u64;
+ type Lookup = IdentityLookup;
+ type Header = Header;
+ type WeightMultiplierUpdate = ();
+ type Event = ();
+ type BlockHashCount = BlockHashCount;
+ type MaximumBlockWeight = MaximumBlockWeight;
+ type MaximumBlockLength = MaximumBlockLength;
+ type AvailableBlockRatio = AvailableBlockRatio;
+ type Version = ();
+ }
+ impl Trait for Test {
+ type Event = ();
+ }
+ type TemplateModule = Module;
+
+ // This function basically just builds a genesis storage key/value store according to
+ // our desired mockup.
+ fn new_test_ext() -> runtime_io::TestExternalities {
+ system::GenesisConfig::default().build_storage::().unwrap().into()
+ }
+
+ #[test]
+ fn it_works_for_default_value() {
+ new_test_ext().execute_with(|| {
+ // Just a dummy test for the dummy funtion `do_something`
+ // calling the `do_something` function with a value 42
+ assert_ok!(TemplateModule::do_something(Origin::signed(1), 42));
+ // asserting that the stored value is equal to what we stored
+ assert_eq!(TemplateModule::something(), Some(42));
+ });
+ }
+}
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index 1bd76353116..5ffd2c124f1 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -29,6 +29,8 @@ pub use rstd::slice;
#[macro_use]
pub mod validate_block;
+pub mod icmp;
+
/// The witness data type.
type WitnessData = Vec>;