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

Send messages from Polkadot to Ethereum contracts #57

Draft
wants to merge 5 commits into
base: snowbridge
Choose a base branch
from
Draft
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 change: 1 addition & 0 deletions Cargo.lock

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

38 changes: 36 additions & 2 deletions parachain-template/pallets/template/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ mod benchmarking;

#[frame_support::pallet]
pub mod pallet {
use frame_support::{dispatch::DispatchResultWithPostInfo, pallet_prelude::*};
pub const LOG_TARGET: &str = "parachain-template";

use frame_support::{dispatch::DispatchResultWithPostInfo, log, pallet_prelude::*};
use frame_system::pallet_prelude::*;
use sp_std::boxed::Box;
use xcm::{v3::prelude::*, VersionedMultiLocation, VersionedXcm};
Expand All @@ -26,7 +28,8 @@ pub mod pallet {
pub trait Config: frame_system::Config + pallet_xcm::Config {
/// Because this pallet emits events, it depends on the runtime's definition of an event.
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
type BridgeXcmSender: SendXcm;
}

#[pallet::pallet]
pub struct Pallet<T>(_);
Expand All @@ -49,6 +52,8 @@ pub mod pallet {
SomethingStored(u32, T::AccountId),
/// XCM message sent. \[to, message\]
Sent { from: T::AccountId, to: MultiLocation, message: Xcm<()> },
/// ExportMessage message was sent
SentExportMessage {forwarded_message_id: XcmHash, sender_cost: MultiAssets, message: Xcm<()> },
}

// Errors inform users that something went wrong.
Expand All @@ -67,6 +72,8 @@ pub mod pallet {
/// The version of the `Versioned` value used is not able to be
/// interpreted.
BadVersion,
/// The bridge call failed.
BridgeCallError,
}

#[pallet::hooks]
Expand Down Expand Up @@ -137,5 +144,32 @@ pub mod pallet {
Self::deposit_event(Event::Sent { from: who, to: dest, message });
Ok(())
}

#[pallet::call_index(3)]
#[pallet::weight(Weight::from_parts(100_000_000, 0))]
pub fn send_export_message_xcm(
origin: OriginFor<T>,
dest: Box<VersionedMultiLocation>,
message: Box<VersionedXcm<()>>,
) -> DispatchResult {
let _who = ensure_signed(origin)?;

let dest = MultiLocation::try_from(*dest).map_err(|()| Error::<T>::BadVersion)?;
let message: Xcm<()> = (*message).try_into().map_err(|()| Error::<T>::BadVersion)?;

let (forwarded_message_id, sender_cost) = send_xcm::<T::BridgeXcmSender>(dest, message.clone())
.map_err(|e| {
log::error!(
target: LOG_TARGET,
"[T::BridgeXcmSender] SendError occurred, error: {:?}",
e
);
Error::<T>::BridgeCallError
})?;


Self::deposit_event(Event::SentExportMessage {forwarded_message_id, sender_cost, message: message });
Ok(())
}
}
}
3 changes: 3 additions & 0 deletions parachain-template/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ cumulus-primitives-utility = { path = "../../primitives/utility", default-featur
pallet-collator-selection = { path = "../../pallets/collator-selection", default-features = false }
parachain-info = { path = "../../parachains/pallets/parachain-info", default-features = false }

pallet-bridge-transfer-primitives = { path = "../../parachains/pallets/bridge-transfer/primitives", default-features = false }

[features]
default = [
"std",
Expand Down Expand Up @@ -122,6 +124,7 @@ std = [
"xcm-executor/std",
"xcm/std",
"substrate-wasm-builder",
"pallet-bridge-transfer-primitives/std",
]

runtime-benchmarks = [
Expand Down
2 changes: 2 additions & 0 deletions parachain-template/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ use xcm_executor::XcmExecutor;

/// Import the template pallet.
pub use pallet_parachain_template;
use crate::xcm_config::bridging;

/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
pub type Signature = MultiSignature;
Expand Down Expand Up @@ -460,6 +461,7 @@ impl pallet_collator_selection::Config for Runtime {
/// Configure the pallet template in pallets/template.
impl pallet_parachain_template::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type BridgeXcmSender = bridging::BridgeXcmSender;
}

// Create the runtime by composing the FRAME pallets that were previously configured.
Expand Down
50 changes: 46 additions & 4 deletions parachain-template/runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ use xcm_builder::{
CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin,
FixedWeightBounds, IsConcrete, NativeAsset, ParentIsPreset, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId,
UsingComponents, WithComputedOrigin, WithUniqueTopic,
SignedToAccountId32, SovereignPaidRemoteExporter, SovereignSignedViaLocation, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic,
};
use xcm_executor::XcmExecutor;

parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
pub const RelayNetwork: Option<NetworkId> = None;
pub const RelayNetwork: Option<NetworkId> = Some(NetworkId::Kusama);
pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into();
pub UniversalLocation: InteriorMultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();
pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into()));
}

/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
Expand Down Expand Up @@ -191,3 +191,45 @@ impl cumulus_pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type XcmExecutor = XcmExecutor<XcmConfig>;
}

/// All configuration related to bridging
pub mod bridging {
use pallet_bridge_transfer_primitives::{
BridgeConfig, BridgesConfig, BridgesConfigAdapter, BridgesConfigBuilder, MaybePaidLocation,
};

use crate::xcm_config::{
Junction::{GlobalConsensus, Parachain},
Junctions::X1,
MultiLocation, SovereignPaidRemoteExporter, UniversalLocation, XcmRouter,
};
use frame_support::parameter_types;
use xcm::v3::NetworkId;

parameter_types! {
pub BridgeHubKusamaParaId: u32 = 1013;
pub BridgeHubKusama: MultiLocation = MultiLocation::new(1, X1(Parachain(BridgeHubKusamaParaId::get())));
// Network and location for the local Ethereum testnet.
pub EthereumNetwork: NetworkId = NetworkId::Ethereum { chain_id: 15 };
pub EthereumLocation: MultiLocation = MultiLocation::new(2, X1(GlobalConsensus(EthereumNetwork::get())));
pub Bridges: BridgesConfig = BridgesConfigBuilder::default()
.add_or_panic(
EthereumNetwork::get(),
BridgeConfig::new(
MaybePaidLocation {
location: BridgeHubKusama::get(),
maybe_fee: None,
}
).add_target_location(
MaybePaidLocation {
location: EthereumLocation::get(),
maybe_fee: None, // No fees supported for ethereum
},
None,
))
.build();
}

pub type BridgeXcmSender =
SovereignPaidRemoteExporter<BridgesConfigAdapter<Bridges>, XcmRouter, UniversalLocation>;
}