Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
Withdraw-teleport-benchmark (#296)
Browse files Browse the repository at this point in the history
  • Loading branch information
metricaez authored Oct 2, 2023
1 parent 9b15c1b commit 8aa876d
Show file tree
Hide file tree
Showing 12 changed files with 646 additions and 37 deletions.
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

0 comments on commit 8aa876d

Please sign in to comment.