Skip to content
This repository was archived by the owner on May 21, 2024. It is now read-only.
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
4 changes: 4 additions & 0 deletions Cargo.lock

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

5 changes: 5 additions & 0 deletions pallets/withdraw-teleport/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,16 @@ sp-io = { workspace = true }
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
pallet-balances = { workspace = true }
xcm-builder = { workspace = true }
polkadot-parachain = { workspace = true }
polkadot-runtime-parachains = { workspace = true }

[features]
default = ["std"]
std = [
"parity-scale-codec/std",
"frame-benchmarking/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
Expand Down
48 changes: 48 additions & 0 deletions pallets/withdraw-teleport/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//! Benchmarking setup for pallet-template
#![cfg(feature = "runtime-benchmarks")]
use super::*;

#[allow(unused)]
use crate::Pallet as WithdrawTeleport;
use frame_benchmarking::{impl_benchmark_test_suite, v2::*};
use frame_support::traits::Currency;
use frame_system::RawOrigin;
use sp_std::prelude::*;

#[benchmarks]
mod benchmarks {
use super::*;

#[benchmark]
fn withdraw_and_teleport() -> Result<(), BenchmarkError> {
let fee_amount = 1_000;
let asset: MultiAsset = (MultiLocation::new(0, Here), fee_amount.clone()).into();
let recipient = [0u8; 32];
let versioned_dest: VersionedMultiLocation = T::ReachableDest::get()
.ok_or(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?
.into();
let versioned_beneficiary: VersionedMultiLocation =
AccountId32 { network: None, id: recipient.into() }.into();
let versioned_assets: VersionedMultiAssets = asset.into();
let amount: u32 = 1_000;
let caller = whitelisted_caller();
T::Currency::make_free_balance_be(&caller, 100_000_000u32.into());
let initial_balance = T::Currency::free_balance(&caller);

#[extrinsic_call]
withdraw_and_teleport(
RawOrigin::Signed(caller.clone()),
Box::new(versioned_dest),
Box::new(versioned_beneficiary),
amount.into(),
Box::new(versioned_assets),
);

let remaining_balance = initial_balance - amount.into() - (fee_amount as u32).into();
// Send or execution error would derive on balances amounts not being deducted from caller.
assert_eq!(T::Currency::free_balance(&caller), remaining_balance);
Ok(())
}

impl_benchmark_test_suite!(WithdrawTeleport, crate::mock::new_test_ext(), crate::mock::Test);
}
51 changes: 41 additions & 10 deletions pallets/withdraw-teleport/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@
type BaseXcm<T> = pallet_xcm::Pallet<T>;
use frame_support::{
dispatch::DispatchResult,
ensure,
ensure, log,
traits::{Contains, EnsureOrigin, Get},
};
use frame_system::pallet_prelude::OriginFor;
pub use pallet::*;
use pallet_xcm::WeightInfo as XcmWeightInfo;
use parity_scale_codec::Encode;
use sp_std::{boxed::Box, vec};
pub use xcm::{
Expand All @@ -37,16 +38,16 @@ pub use xcm::{
};
use xcm_executor::traits::WeightBounds;

// #[cfg(test)]
// mod mock;
#[cfg(test)]
mod mock;

// #[cfg(test)]
// mod tests;

// #[cfg(feature = "runtime-benchmarks")]
// mod benchmarking;
// pub mod weights;
// pub use weights::*;
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
pub mod weights;
pub use weights::*;

#[frame_support::pallet]
pub mod pallet {
Expand All @@ -58,14 +59,15 @@ pub mod pallet {
#[pallet::config]
pub trait Config: frame_system::Config + pallet_xcm::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
type WeightInfo: WeightInfo;
}

#[pallet::error]
pub enum Error<T> {
/// An error ocured during send
SendError,
/// Failed to execute
FailedToExecute,
FailedToExecuteXcm,
}

#[pallet::event]
Expand Down Expand Up @@ -101,7 +103,29 @@ pub mod pallet {
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(<pallet_xcm::TestWeightInfo as pallet_xcm::WeightInfo>::teleport_assets())]
#[pallet::weight({
let native_asset = MultiAsset {
id: AssetId::Concrete(MultiLocation::here()),
fun: Fungibility::Fungible(*native_asset_amount),
};
let native_assets = MultiAssets::from(vec![native_asset.clone()]);
let maybe_assets: Result<MultiAssets, ()> = (*fee_asset.clone()).try_into();
let send_weight = <T as pallet_xcm::Config>::WeightInfo::send();
match maybe_assets {
Ok(assets) => {
use sp_std::vec;
let mut message = Xcm(vec![
WithdrawAsset(native_assets.clone()),
SetFeesMode { jit_withdraw: true },
BurnAsset(native_assets),
WithdrawAsset(assets.clone()),
BurnAsset(assets),
]);
T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| <T as pallet::Config>::WeightInfo::withdraw_and_teleport().saturating_add(w).saturating_add(send_weight))
}
_ => Weight::MAX,
}
})]
pub fn withdraw_and_teleport(
origin: OriginFor<T>,
dest: Box<VersionedMultiLocation>,
Expand Down Expand Up @@ -138,6 +162,10 @@ impl<T: Config> Pallet<T> {
let fee_asset: MultiAssets =
(*fee_asset).try_into().map_err(|()| pallet_xcm::Error::<T>::BadVersion)?;

// Limit the number of fee assets to 1.
ensure!(fee_asset.len() > 0, pallet_xcm::Error::<T>::Empty);
ensure!(fee_asset.len() < 2, pallet_xcm::Error::<T>::TooManyAssets);

//Create assets

// Native from local perspective
Expand Down Expand Up @@ -215,7 +243,10 @@ impl<T: Config> Pallet<T> {
let hash = message.using_encoded(sp_io::hashing::blake2_256);
let outcome =
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, hash, weight, weight);
outcome.clone().ensure_complete().map_err(|_| Error::<T>::FailedToExecute)?;
outcome.clone().ensure_complete().map_err(|e| {
log::debug!("{e:?}");
Error::<T>::FailedToExecuteXcm
})?;
Self::deposit_event(Event::Attempted { outcome });

// Use pallet-xcm send for sending message.
Expand Down
Loading