Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XCM based crosschain transfering on rococov1 branch #139

Merged
merged 8 commits into from
Feb 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,273 changes: 647 additions & 626 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion common/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ serde = { version = "1.0.101", default-features = false, optional = true }
codec = { package = "parity-scale-codec", version = "1.3.4", default-features = false }
sp-core = { version = "2.0.0", default-features = false, git = "https://github.com/paritytech/substrate", branch = "rococo-v1" }

xcm-adapter = {path = "../../pallets/xcm-adapter", default-features = false }
xcm-transactor = {path = "../../pallets/xcm-transactor", default-features = false }
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "rococo-v1" }
cumulus-primitives = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }

Expand Down
2 changes: 1 addition & 1 deletion common/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use serde::{Serialize, Deserialize};

use xcm::v0::{NetworkId};
use cumulus_primitives::{ParaId};
use xcm_adapter::{ PHAXCurrencyId as XCurrencyId };
use xcm_transactor::{ PHAXCurrencyId as XCurrencyId };

#[derive(Encode, Decode)]
pub struct Transfer<AccountId, Balance> {
Expand Down
3 changes: 1 addition & 2 deletions pallets/phala/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ serde_json = { version = "1.0.41", default-features = false, features = ["alloc"
# serde_json_core = {}
blake2-rfc = { version = "0.2.18", default-features = false }

xtoken = {path = "../xtoken", default-features = false }
xcm-adapter = {path = "../xcm-adapter", default-features = false }
xcm-transactor = {path = "../xcm-transactor", default-features = false }

[dependencies.pallet-balances]
default-features = false
Expand Down
23 changes: 10 additions & 13 deletions pallets/phala/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ mod tests;

type BalanceOf<T> = <<T as Config>::TEECurrency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
type NegativeImbalanceOf<T> = <<T as Config>::TEECurrency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
type XBalanceOf<T> = <T as xtoken::Config>::Balance;

const PALLET_ID: ModuleId = ModuleId(*b"Phala!!!");
const RANDOMNESS_SUBJECT: &'static [u8] = b"PhalaPoW";
Expand All @@ -54,7 +53,7 @@ const ROUND_STATS_TO_KEEP: u32 = 2;
pub const PERCENTAGE_BASE: u32 = 100_000;

/// Configure the pallet by specifying the parameters and types on which it depends.
pub trait Config: frame_system::Config + xtoken::Config {
pub trait Config: frame_system::Config {
type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;
type Randomness: Randomness<Self::Hash>;
type TEECurrency: Currency<Self::AccountId>;
Expand Down Expand Up @@ -183,7 +182,7 @@ decl_storage! {
}

decl_event!(
pub enum Event<T> where AccountId = <T as frame_system::Config>::AccountId, Balance = BalanceOf<T>, XBalance = XBalanceOf<T> {
pub enum Event<T> where AccountId = <T as frame_system::Config>::AccountId, Balance = BalanceOf<T> {
// Debug events
LogString(Vec<u8>),
LogI32(i32),
Expand All @@ -193,8 +192,8 @@ decl_event!(
TransferToChain(AccountId, Balance, u64),
TransferTokenToTee(AccountId, Vec<u8>, Balance),
TransferTokenToChain(AccountId, Vec<u8>, Balance, u64),
TransferXTokenToChain(AccountId, Vec<u8>, XBalance, u64),
XcmExecutorFailed(AccountId, Vec<u8>, XBalance, u64),
TransferXTokenToChain(AccountId, Vec<u8>, Balance, u64),
XcmExecutorFailed(AccountId, Vec<u8>, Balance, u64),
WorkerRegistered(AccountId, Vec<u8>, Vec<u8>), // stash, identity_key, machine_id
WorkerUnregistered(AccountId, Vec<u8>), // stash, machine_id
Heartbeat(AccountId, u32),
Expand Down Expand Up @@ -549,7 +548,7 @@ decl_module! {
const CONTRACT_ID: u32 = 3;
ensure_signed(origin.clone())?;

let transfer_data: TransferXTokenData<<T as frame_system::Config>::AccountId, T::Balance>
let transfer_data: TransferXTokenData<<T as frame_system::Config>::AccountId, BalanceOf<T>>
= Decode::decode(&mut &data[..]).map_err(|_| Error::<T>::InvalidInput)?;
// Check sequence
let sequence = IngressSequence::get(CONTRACT_ID);
Expand All @@ -560,13 +559,8 @@ decl_module! {
// Validate TEE signature
Self::verify_signature(&pubkey, &transfer_data)?;

let xcm = <xtoken::Module<T>>::do_transfer_to_parachain(
transfer_data.data.x_currency_id.clone(),
transfer_data.data.para_id,
&transfer_data.data.dest,
transfer_data.data.dest_network,
transfer_data.data.amount
);
// TODO: build crosschain transfer XCM message
Self::do_transfer_to_parachain();

// Announce the successful execution
IngressSequence::insert(CONTRACT_ID, sequence + 1);
Expand Down Expand Up @@ -1069,6 +1063,9 @@ impl<T: Config> Module<T> {
Fire::<T>::mutate(dest, |x| *x += amount);
AccumulatedFire::<T>::mutate(|x| *x += amount);
}

// TODO: build xcm message and execute it
fn do_transfer_to_parachain() {}
}

fn calc_overall_score(features: &Vec<u32>) -> Result<u32, ()> {
Expand Down
32 changes: 32 additions & 0 deletions pallets/xcm-handler/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "xcm-handler"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2018"

[dependencies]
# Other dependencies
codec = { package = "parity-scale-codec", version = "1.3.0", features = [ "derive" ], default-features = false }

# Substrate Dependencies
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-v1" }
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-v1" }
frame-system = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "rococo-v1" }

# Polkadot Dependencies
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "rococo-v1" }
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "rococo-v1" }

# Cumulus Dependencies
cumulus-primitives = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }

[features]
default = [ "std" ]
std = [
"codec/std",
"sp-std/std",
"frame-support/std",
"frame-system/std",
"cumulus-primitives/std",
"xcm/std"
]
243 changes: 243 additions & 0 deletions pallets/xcm-handler/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Cumulus.

// Substrate 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.

// Substrate 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 <http://www.gnu.org/licenses/>.

//! A pallet which implements the message-broker APIs for handling incoming XCM:
//! * `DownwardMessageHandler`
//! * `HrmpMessageHandler`
//!
//! Also provides an implementation of `SendXcm` to handle outgoing XCM.

#![cfg_attr(not(feature = "std"), no_std)]

use codec::{Decode, Encode};
use cumulus_primitives::{
DownwardMessageHandler, HrmpMessageHandler, HrmpMessageSender, InboundDownwardMessage,
InboundHrmpMessage, OutboundHrmpMessage, ParaId, UpwardMessageSender,
};
use frame_support::{decl_error, decl_event, decl_module, sp_runtime::traits::Hash};
use frame_system::ensure_signed;
use sp_std::convert::{TryFrom, TryInto};
use xcm::{
v0::{Error as XcmError, ExecuteXcm, Junction, MultiLocation, SendXcm, Xcm},
VersionedXcm,
};
use xcm_executor::traits::LocationConversion;

pub trait Config: frame_system::Config {
type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;
/// Something to execute an XCM message.
type XcmExecutor: ExecuteXcm;
/// Something to send an upward message.
type UpwardMessageSender: UpwardMessageSender;
/// Something to send an HRMP message.
type HrmpMessageSender: HrmpMessageSender;
/// Convert AccountId to MultiLocation
type AccountIdConverter: LocationConversion<Self::AccountId>;
}

decl_event! {
pub enum Event<T> where Hash = <T as frame_system::Config>::Hash {
/// Some XCM was executed ok.
Success(Hash),
/// Some XCM failed.
Fail(Hash, XcmError),
/// Bad XCM version used.
BadVersion(Hash),
/// Bad XCM format used.
BadFormat(Hash),
/// An upward message was sent to the relay chain.
UpwardMessageSent(Hash),
/// An HRMP message was sent to a sibling parachainchain.
HrmpMessageSent(Hash),
}
}

decl_error! {
pub enum Error for Module<T: Config> {
/// Failed to send XCM message.
FailedToSend,
/// Failed to execute XCM message
FailedToExecute,
}
}

decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::Origin {
fn deposit_event() = default;

#[weight = 1_000]
fn execute_xcm(origin, message: Xcm) {
frame_support::debug::RuntimeLogger::init();

let who = ensure_signed(origin)?;

frame_support::debug::info!("----------- Execute xcm -------------");
let xcm_origin = T::AccountIdConverter::try_into_location(who).map_err(|_| Error::<T>::FailedToExecute)?;
let msg = message.try_into().map_err(|_| Error::<T>::FailedToExecute)?;
T::XcmExecutor::execute_xcm(xcm_origin, msg).map_err(|_| Error::<T>::FailedToExecute)?;
}

#[weight = 1_000]
fn send_plain_xcm(origin, dest: MultiLocation, message: Xcm) {
ensure_signed(origin)?;
Self::send_xcm(dest, message).map_err(|_| Error::<T>::FailedToSend)?;
}

#[weight = 1_000]
fn send_upward_xcm(origin, message: VersionedXcm) {
ensure_signed(origin)?;
let data = message.encode();
T::UpwardMessageSender::send_upward_message(data).map_err(|_| Error::<T>::FailedToSend)?;
}

#[weight = 1_000]
fn send_hrmp_xcm(origin, recipient: ParaId, message: VersionedXcm) {
ensure_signed(origin)?;
let data = message.encode();
let outbound_message = OutboundHrmpMessage {
recipient,
data,
};
T::HrmpMessageSender::send_hrmp_message(outbound_message).map_err(|_| Error::<T>::FailedToSend)?;
}
}
}

impl<T: Config> DownwardMessageHandler for Module<T> {
fn handle_downward_message(msg: InboundDownwardMessage) {

frame_support::debug::RuntimeLogger::init();

frame_support::debug::info!("----------- xcm-handler: handle_downward_message -------------");
frame_support::debug::info!(
">>> inbound downward msg: {:?}",
msg
);
let hash = msg.using_encoded(T::Hashing::hash);
frame_support::debug::info!("Processing Downward XCM: {:?}", &hash);
match VersionedXcm::decode(&mut &msg.msg[..]).map(Xcm::try_from) {
Ok(Ok(xcm)) => {
match T::XcmExecutor::execute_xcm(Junction::Parent.into(), xcm) {
Ok(..) => RawEvent::Success(hash),
Err(e) => RawEvent::Fail(hash, e),
};
}
Ok(Err(..)) => Self::deposit_event(RawEvent::BadVersion(hash)),
Err(..) => Self::deposit_event(RawEvent::BadFormat(hash)),
}
}
}

impl<T: Config> HrmpMessageHandler for Module<T> {
fn handle_hrmp_message(sender: ParaId, msg: InboundHrmpMessage) {

frame_support::debug::RuntimeLogger::init();

frame_support::debug::info!("----------- xcm-handler: handle_hrmp_message -------------");
frame_support::debug::info!(
">>> paraId: {:?}, inbound hrmp msg: {:?}",
sender,
msg
);
let hash = msg.using_encoded(T::Hashing::hash);
frame_support::debug::info!("Processing HRMP XCM: {:?}", &hash);
match VersionedXcm::decode(&mut &msg.data[..]).map(Xcm::try_from) {
Ok(Ok(xcm)) => {
let location = (
Junction::Parent,
Junction::Parachain { id: sender.into() },
);
match T::XcmExecutor::execute_xcm(location.into(), xcm) {
Ok(..) => RawEvent::Success(hash),
Err(e) => RawEvent::Fail(hash, e),
};
}
Ok(Err(..)) => Self::deposit_event(RawEvent::BadVersion(hash)),
Err(..) => Self::deposit_event(RawEvent::BadFormat(hash)),
}
}
}

impl<T: Config> SendXcm for Module<T> {
fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result<(), XcmError> {
let msg: VersionedXcm = msg.into();
frame_support::debug::info!("----------- xcm-handler: send_xcm -------------");
frame_support::debug::info!(
">>> dest: {:?}, dest.first(): {:?} msg: {:?}",
dest,
dest.first(),
msg
);
match dest.first() {
// An upward message for the relay chain.
Some(Junction::Parent) if dest.len() == 1 => {
frame_support::debug::info!("---------------------- Destionation is Parent, send upward message");

let data = msg.encode();
let hash = T::Hashing::hash(&data);

T::UpwardMessageSender::send_upward_message(data)
.map_err(|_| XcmError::Undefined)?;
Self::deposit_event(RawEvent::UpwardMessageSent(hash));

Ok(())
}
// An HRMP message for a sibling parachain.
Some(Junction::Parachain { id }) => {
frame_support::debug::info!("---------------- Destionation is Parachain, send hrmp message ");

let data = msg.encode();
let hash = T::Hashing::hash(&data);
let message = OutboundHrmpMessage {
recipient: (*id).into(),
data,
};
// TODO: Better error here
T::HrmpMessageSender::send_hrmp_message(message)
.map_err(|_| XcmError::Undefined)?;
Self::deposit_event(RawEvent::HrmpMessageSent(hash));
Ok(())
}

_ => {
frame_support::debug::info!("----------------- Unhandled xcm message");
/* TODO: Handle other cases, like downward message */
Err(XcmError::UnhandledXcmMessage)
}
}
}
}

/// Origin for the parachains module.
#[derive(PartialEq, Eq, Clone, Encode, Decode)]
#[cfg_attr(feature = "std", derive(Debug))]
pub enum Origin {
/// It comes from the (parent) relay chain.
Relay,
/// It comes from a (sibling) parachain.
SiblingParachain(ParaId),
}

impl From<ParaId> for Origin {
fn from(id: ParaId) -> Origin {
Origin::SiblingParachain(id)
}
}
impl From<u32> for Origin {
fn from(id: u32) -> Origin {
Origin::SiblingParachain(id.into())
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
[package]
name = "xcm-adapter"
name = "xcm-transactor"
version = "0.1.0"
authors = ["Wenfeng Wang <kalot.wang@gmail.com>"]
edition = "2018"
authors = ['Phala Network']
edition = '2018'
license = "Apache 2.0"
homepage = "https://phala.network/"
repository = "https://github.com/Phala-Network/phala-blockchain"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
Loading