Skip to content
Closed

XCMP #263

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
34e0311
mucho todo
4meta5 Feb 22, 2021
fe297be
hard coded method ids for relevant evm calldata
4meta5 Feb 24, 2021
850b095
use pallet evm directly instead of pallet ethereum
4meta5 Feb 24, 2021
38a925c
better error propagation by using events to return exit reason from e…
4meta5 Feb 24, 2021
922ea61
init token dealer update
4meta5 Feb 25, 2021
c159fda
impl TransactAsset
4meta5 Feb 25, 2021
14f7880
failed to get runtime to compile because dependencies must be updated
4meta5 Feb 26, 2021
fe53acc
compiles
4meta5 Feb 26, 2021
51b31cd
resolve conflict
4meta5 Feb 26, 2021
1ac6d18
checkpoint
4meta5 Feb 26, 2021
e246cf9
add token factory to runtime
4meta5 Feb 26, 2021
d5bc62e
xcm runtime config
4meta5 Feb 28, 2021
533cb0d
use SignedAccountId20AsNative instead of SignedAccountId32AsNative
4meta5 Feb 28, 2021
7508a9e
use parachain info from cumulus directly instead of local copy and se…
4meta5 Mar 1, 2021
0f5213a
configure token dealer in runtime
4meta5 Mar 1, 2021
56421bd
rm old token dealer
4meta5 Mar 1, 2021
261579e
contract deployment fails with Revert Reverted in unit tests
4meta5 Mar 2, 2021
f8c2026
gradual progress ty alberto
4meta5 Mar 2, 2021
fcf44a0
token factory works
4meta5 Mar 2, 2021
6e0f6ce
add transactional annotation on fallible dispatchibles and bump spec …
4meta5 Mar 3, 2021
56c232f
add polkadotjs types
4meta5 Mar 3, 2021
df750c0
Merge branch 'master' into amar-xc
4meta5 Mar 3, 2021
6dde5ea
fmt
4meta5 Mar 3, 2021
c899115
Merge branch 'amar-xc' of https://github.com/PureStake/moonbeam into …
4meta5 Mar 3, 2021
fc0833d
add docs to token dealer support
4meta5 Mar 3, 2021
8c655cc
add token dealer docs and simplify solidity contract for our specific…
4meta5 Mar 4, 2021
c356d9b
fmt
4meta5 Mar 4, 2021
c9156cb
add tokens to token factory genesis and move Ticker and CurrencyId ty…
4meta5 Mar 4, 2021
786e0fe
Update runtime/src/lib.rs
4meta5 Mar 4, 2021
6d3353f
inc nonce even for failed evm calls and check balance before burning …
4meta5 Mar 5, 2021
7f1247a
burn entire balance if amount is greater than balance of who
4meta5 Mar 5, 2021
4b33576
update bytecode to minimal solidity contract
4meta5 Mar 5, 2021
9716613
fix doc, impl destroy all and write min test
4meta5 Mar 5, 2021
c934bcd
log errors with calling parameters for all fallible calls in MultiCur…
4meta5 Mar 5, 2021
b333276
fix genesis config
4meta5 Mar 8, 2021
86bef44
fix
4meta5 Mar 9, 2021
e94e71e
support sending to parachains that use AccountKey20 and print Currenc…
4meta5 Mar 11, 2021
a4e68aa
fix runtime
4meta5 Mar 11, 2021
b87f6bc
tightly couple with xcm handler and add dispatchables for channel ope…
4meta5 Mar 13, 2021
d69b655
master.into
4meta5 Mar 16, 2021
62e48dc
fix
4meta5 Mar 16, 2021
eca75a6
save
4meta5 Mar 17, 2021
b9ccfc4
decouple xtransfer from xcm handler
4meta5 Mar 18, 2021
7779c88
downward message handler impl for xtransfer channel management
4meta5 Mar 19, 2021
b10fe86
rm token factory pallet ethereum dep
4meta5 Mar 19, 2021
5d2883b
fix sender origin and clean local channel handling views
4meta5 Mar 23, 2021
eca5882
Merge branch 'master' into amar-xc
4meta5 Mar 23, 2021
98c378d
fix merge conflict
4meta5 Mar 23, 2021
5a86c6e
make channels into own pallet and tightly couple to xtransfer
4meta5 Mar 24, 2021
abd7567
remove duplicate header
4meta5 Mar 24, 2021
1139091
Amar xc fix types (#301)
joelamouche Mar 24, 2021
e370d29
Ama xc fix 2 (#303)
joelamouche Mar 24, 2021
430f7f2
incomplete moonbeam-xcmp tests
4meta5 Mar 25, 2021
47d3bce
clean moonbeam xcmp tests
4meta5 Mar 25, 2021
353ed63
line length
4meta5 Mar 25, 2021
5c87db5
progress (#304)
joelamouche Mar 25, 2021
3e36e75
save
4meta5 Mar 27, 2021
e31e83c
cprightheader
4meta5 Mar 27, 2021
e8a7acf
build failed fml
4meta5 Mar 28, 2021
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
478 changes: 272 additions & 206 deletions Cargo.lock

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions moonbeam-types-bundle/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,20 @@ export const moonbeamDefinitions = {
nominators: "Vec<Bond>",
total: "Balance",
},
TokenId: {
_enum: ["DOT", "KSM", "ACA", "AUSD"],
},
EvmCall: {
_enum: ["Register", "Mint", "Burn", "TotalIssuance", "BalanceOf"],
},
AccountId32: "[u8; 32]",
ChainId: {
_enum: ["RelayChain", { Para: "u32" }],
},
XCurrencyId: {
chain_id: "ChainId",
currency_id: "Vec<u8>",
},
SystemInherentData: {
validation_data: "PersistedValidationData",
relay_chain_state: "StorageProof",
Expand Down
2 changes: 1 addition & 1 deletion node/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ pub fn get_chain_spec(para_id: ParaId) -> ChainSpec {
)
}

pub fn moonbeam_inflation_config() -> InflationInfo<Balance> {
fn moonbeam_inflation_config() -> InflationInfo<Balance> {
InflationInfo {
expect: Range {
min: 100_000 * GLMR,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
[package]
authors = ["Parity Technologies <[email protected]>"]
authors = ["PureStake"]
edition = "2018"
name = "parachain-info"
version = "0.6.0"
name = "hrmp-channels"
version = "0.1.0"
description = "manage HRMP channels between other parachains"

[dependencies]
parity-scale-codec = { version = "2.0.0", default-features = false, features = ["derive"] }
serde = { version = "1.0.101", optional = true, features = ["derive"] }

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" }

sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "rococo-v1", default-features = false }
sp-std = { git = "https://github.com/paritytech/substrate", branch = "rococo-v1", default-features = false }
xcm = { git = "https://github.com/paritytech/polkadot", branch = "rococo-v1" }
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", default-features = false, branch = "rococo-v1" }

[features]
default = ["std"]
std = [
"parity-scale-codec/std",
"serde",
"cumulus-primitives-core/std",
"frame-support/std",
"frame-system/std",
"cumulus-primitives-core/std",
"sp-runtime/std",
"sp-std/std",
"xcm/std",
]
317 changes: 317 additions & 0 deletions pallets/hrmp-channels/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,317 @@
// Copyright 2019-2021 PureStake Inc.
// This file is part of Moonbeam.

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

// Moonbeam 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 Moonbeam. If not, see <http://www.gnu.org/licenses/>.

//! Pallet for tracking HRMP channel events and dispatching HRMP channel actions.
//! - maximum one channel per relation is constraint placed by relay `hrmp` pallet by using
//! HrmpChannelId { sender: Id, recipient: Id } as unique key

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

use frame_support::pallet;
mod set;
pub use pallet::*;

#[pallet]
pub mod pallet {
use crate::set::OrderedSet;
use cumulus_primitives_core::{DownwardMessageHandler, InboundDownwardMessage, ParaId};
use frame_support::{pallet_prelude::*, traits::Get};
use frame_system::pallet_prelude::*;
use sp_std::{convert::TryFrom, prelude::*};
use xcm::{
v0::{Junction, MultiLocation, OriginKind, SendXcm, Xcm},
VersionedXcm,
};

/// Pallet for tracking and managing HRMP channels between other parachains
#[pallet::pallet]
pub struct Pallet<T>(PhantomData<T>);

/// Configuration trait of this pallet.
#[pallet::config]
pub trait Config: frame_system::Config {
/// Overarching event type
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
/// Moonbeam parachain identifier
type ParaId: Get<ParaId>;
/// XCM Sender for sending outgoing messages
type XcmSender: SendXcm;
}

#[pallet::event]
#[pallet::generate_deposit(fn deposit_event)]
pub enum Event<T: Config> {
/// Sent channel open request to parachain \[recipient_para_id\]
SenderChannelRequested(ParaId),
/// Sender channel request accepted by parachain \[recipient_para_id\]
SenderChannelAccepted(ParaId),
/// Error with received sender channel accepted because one already exists locally
SenderChannelAlreadyExists(ParaId),
/// Error with recipient channel requested because request already exists locally
RecipientChannelAlreadyExists(ParaId),
/// Error closing sender channel because channel DNE
CloseSenderChannelDNE(ParaId),
/// Error closing recipient channel because channel DNE
CloseRecipientChannelDNE(ParaId),
/// Received new channel request with self as recipient
ReceivedRecipientChannelRequest(ParaId),
/// Accepted channel open request from parachain
AcceptedChannelRequest(ParaId),
/// Requested to close the channel with self as sender \[recipient_para_id\]
RequestedCloseSenderChannel(ParaId),
/// Requested to close the channel with self as recipient \[sender_para_id\]
RequestedCloseRecipientChannel(ParaId),
/// Closed channel with parachain as recipient and self as sender
ClosedSenderChannel(ParaId),
/// Closed channel with parachain as sender and self as recipient
ClosedRecipientChannel(ParaId),
}

#[pallet::error]
pub enum Error<T> {
/// Cannot send message from parachain to self
CannotSendToSelf,
/// Call to SendXcm failed
FailedToSendXcm,
/// Maximum one channel per relation ~ (sender,receiver) and direction matters
MaxOneChannelPerRelation,
/// Cannot accept a recipient channel request not in local storage
RecipientRequestDNE,
/// Requires existing open channel with self as sender
NoSenderChannelOpen,
/// Requires existing open channel with self as recipient
NoRecipientChannelOpen,
}

#[pallet::storage]
#[pallet::getter(fn recipient_channel_requests)]
/// Open channel requests on the relay chain to self (recipient) from these parachains (sender)
pub type RecipientChannelRequests<T: Config> = StorageValue<_, OrderedSet<ParaId>, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn sender_channels)]
/// Stores all para IDs with which this parachain has opened a channel with self as sender
pub type SenderChannels<T: Config> = StorageValue<_, OrderedSet<ParaId>, ValueQuery>;

#[pallet::storage]
#[pallet::getter(fn recipient_channels)]
/// Stores all para IDs with which this parachain has accepted a channel with self as recipient
pub type RecipientChannels<T: Config> = StorageValue<_, OrderedSet<ParaId>, ValueQuery>;

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}

#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::weight(0)]
/// Request to open HRMP channel with another parachain
pub fn open_channel(
origin: OriginFor<T>,
recipient: ParaId,
// temporary until proper Xcm message variant is added with handler logic
call: Vec<u8>,
) -> DispatchResultWithPostInfo {
frame_system::ensure_root(origin)?;
let sender = T::ParaId::get();
ensure!(sender != recipient, Error::<T>::CannotSendToSelf);
// TODO: could check if sender has already made the request; SenderChannelRequests vec
let channels = <SenderChannels<T>>::get();
ensure!(
!channels.contains(&recipient),
Error::<T>::MaxOneChannelPerRelation
);
// call `hrmp_init_open_channel` on relay chain
let message = Xcm::Transact {
origin_type: OriginKind::Native,
call,
};
// send message to relay chain
T::XcmSender::send_xcm(
MultiLocation::X1(Junction::Parachain { id: sender.into() }),
message,
)
.map_err(|_| Error::<T>::FailedToSendXcm)?;
// emit event
Self::deposit_event(Event::SenderChannelRequested(recipient));
Ok(().into())
}
#[pallet::weight(0)]
/// Accept a request to open HRMP channel
pub fn accept_channel(
origin: OriginFor<T>,
sender: ParaId,
// temporary until proper Xcm message variant is added with handler logic
call: Vec<u8>,
) -> DispatchResultWithPostInfo {
frame_system::ensure_root(origin)?;
let self_id = T::ParaId::get();
ensure!(sender != self_id, Error::<T>::CannotSendToSelf);
// first check if the request even exists (all requests are stored locally)
let mut requests = <RecipientChannelRequests<T>>::get();
ensure!(requests.remove(&sender), Error::<T>::RecipientRequestDNE);
let mut channels = <RecipientChannels<T>>::get();
ensure!(
channels.insert(sender),
Error::<T>::MaxOneChannelPerRelation
);
// call `hrmp_accept_open_channel` on relay chain
let message = Xcm::Transact {
origin_type: OriginKind::Native,
call,
};
// send message to relay chain
T::XcmSender::send_xcm(
MultiLocation::X1(Junction::Parachain { id: self_id.into() }),
message,
)
.map_err(|_| Error::<T>::FailedToSendXcm)?;
// update recipient channel requests
<RecipientChannelRequests<T>>::put(requests);
// update recipient channels storage item
<RecipientChannels<T>>::put(channels);
// emit event
Self::deposit_event(Event::AcceptedChannelRequest(sender));
Ok(().into())
}
#[pallet::weight(0)]
/// Close an open HRMP channel with self as sender
pub fn close_sender_channel(
origin: OriginFor<T>,
recipient: ParaId,
// temporary until hrmp variants added to Xcm
call: Vec<u8>,
) -> DispatchResultWithPostInfo {
frame_system::ensure_root(origin)?;
let self_id = T::ParaId::get();
ensure!(recipient != self_id, Error::<T>::CannotSendToSelf);
let channels = <SenderChannels<T>>::get();
ensure!(
channels.contains(&recipient),
Error::<T>::NoSenderChannelOpen
);
// call `hrmp_close_channel` on relay chain
let message = Xcm::Transact {
origin_type: OriginKind::Native,
call,
};
// send message to relay chain
T::XcmSender::send_xcm(
MultiLocation::X1(Junction::Parachain { id: self_id.into() }),
message,
)
.map_err(|_| Error::<T>::FailedToSendXcm)?;
Self::deposit_event(Event::RequestedCloseSenderChannel(recipient));
Ok(().into())
}
#[pallet::weight(0)]
/// Close an open HRMP channel with self as recipient
pub fn close_recipient_channel(
origin: OriginFor<T>,
sender: ParaId,
// temporary until hrmp variants added to Xcm
call: Vec<u8>,
) -> DispatchResultWithPostInfo {
frame_system::ensure_root(origin)?;
let self_id = T::ParaId::get();
ensure!(sender != self_id, Error::<T>::CannotSendToSelf);
let channels = <RecipientChannels<T>>::get();
ensure!(
channels.contains(&sender),
Error::<T>::NoRecipientChannelOpen
);
// call is to `hrmp_close_channel` on relay chain
let message = Xcm::Transact {
origin_type: OriginKind::Native,
call,
};
// send message to accept the channel request
T::XcmSender::send_xcm(
MultiLocation::X1(Junction::Parachain { id: self_id.into() }),
message,
)
.map_err(|_| Error::<T>::FailedToSendXcm)?;
Self::deposit_event(Event::RequestedCloseRecipientChannel(sender));
Ok(().into())
}
}

impl<T: Config> DownwardMessageHandler for Pallet<T> {
fn handle_downward_message(msg: InboundDownwardMessage) {
match VersionedXcm::decode(&mut &msg.msg[..]).map(Xcm::try_from) {
Ok(Ok(xcm)) => {
match xcm {
Xcm::HrmpNewChannelOpenRequest { sender, .. } => {
let mut channels = <RecipientChannelRequests<T>>::get();
let sender: ParaId = sender.into();
// if request from id already exists, not added to requests
if channels.insert(sender) {
<RecipientChannelRequests<T>>::put(channels);
Self::deposit_event(Event::ReceivedRecipientChannelRequest(sender));
} else {
// event error
Self::deposit_event(Event::RecipientChannelAlreadyExists(sender));
}
}
Xcm::HrmpChannelAccepted { recipient } => {
let mut channels = <SenderChannels<T>>::get();
let recipient: ParaId = recipient.into();
// if channel with id already exists, not added to channels
if channels.insert(recipient) {
<SenderChannels<T>>::put(channels);
Self::deposit_event(Event::SenderChannelAccepted(recipient));
} else {
// event error
Self::deposit_event(Event::SenderChannelAlreadyExists(recipient));
}
}
Xcm::HrmpChannelClosing {
sender, recipient, ..
} => {
let self_id = T::ParaId::get();
let sender: ParaId = sender.into();
let recipient: ParaId = recipient.into();
if sender == self_id {
let mut channels = <SenderChannels<T>>::get();
// update storage
if channels.remove(&recipient) {
<SenderChannels<T>>::put(channels);
Self::deposit_event(Event::ClosedSenderChannel(recipient));
} else {
// event error
Self::deposit_event(Event::CloseSenderChannelDNE(recipient));
}
}
if recipient == self_id {
let mut channels = <RecipientChannels<T>>::get();
// update storage
if channels.remove(&sender) {
<RecipientChannels<T>>::put(channels);
Self::deposit_event(Event::ClosedRecipientChannel(sender));
} else {
// event error
Self::deposit_event(Event::CloseRecipientChannelDNE(sender));
}
}
}
_ => (),
}
}
Ok(Err(..)) => (),
Err(..) => (),
}
}
}
}
Loading