Skip to content

Commit

Permalink
Handle xcm deposit callback (#3723)
Browse files Browse the repository at this point in the history
  • Loading branch information
RustNinja authored Jun 21, 2023
2 parents d0fa950 + f240668 commit 7a97ee0
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 15 deletions.
2 changes: 2 additions & 0 deletions code/Cargo.lock

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

4 changes: 4 additions & 0 deletions code/parachain/frame/pallet-xcm-ibc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ sp-core = { default-features = false, workspace = true }
sp-io = { default-features = false, workspace = true }
sp-runtime = { default-features = false, workspace = true }
sp-std = { default-features = false, workspace = true }
pallet-ibc = { workspace = true, default-features = false }
ibc-primitives = { workspace = true, default-features = false }

frame-support = { default-features = false, workspace = true }
frame-system = { default-features = false, workspace = true }
Expand Down Expand Up @@ -55,6 +57,8 @@ std = [
"frame-support/std",
"frame-system/std",
"frame-benchmarking/std",
"pallet-ibc/std",
"ibc-primitives/std"
]

runtime-benchmarks = [
Expand Down
68 changes: 63 additions & 5 deletions code/parachain/frame/pallet-xcm-ibc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub use pallet::*;
pub use pallet::Error;

type AccoindIdOf<T> = <T as frame_system::Config>::AccountId;

#[frame_support::pallet]
pub mod pallet {
use super::*;
Expand All @@ -9,7 +11,7 @@ pub mod pallet {
/// ## Configuration
/// The pallet's configuration trait.
#[pallet::config]
pub trait Config: frame_system::Config {
pub trait Config: frame_system::Config + pallet_ibc::Config {
#[allow(missing_docs)]
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
Expand Down Expand Up @@ -39,15 +41,71 @@ pub mod pallet {
impl<T: Config> Pallet<T> {
}

impl<T> MultiCurrencyCallback for Pallet<T> {
use frame_system::{RawOrigin};

// use frame_system::Config;
use xcm::latest::prelude::*;
impl<T : Config
// frame_system::Config + pallet_ibc::Config + Send + Sync,
// T: ,
// T: Send
// `T: Sync`
// `frame_support::sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>`
// `u32: From<<T as frame_system::Config>::BlockNumber>
> MultiCurrencyCallback<T> for Pallet<T>
where
T: Send + Sync,
u32: From<<T as frame_system::Config>::BlockNumber>,
sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
{
fn deposit_asset(asset: &MultiAsset, location: &MultiLocation, context: &XcmContext, deposit_result : Result, asset_id : Option<<T as pallet_ibc::Config>::AssetId>){
let id = match location {
MultiLocation { parents: 0, interior: X4(
PalletInstance(_),
AccountId32{ id, network: None },
GeneralIndex(_),
AccountId32{ id: _, network: None } ) } => Some(id.clone()),
_ => None,
};
let Some(id) = id else{
//does not match the pattern of multihop
return;
};

let Ok(_) = deposit_result else {
//deposit does not executed propertly. nothing todo. assets will stay in the account id address
return;
};

let account_id = pallet_ibc::MultiAddress::<AccoindIdOf<T>>::Raw(id.to_vec());
let transfer_params = pallet_ibc::TransferParams::<AccoindIdOf<T>>{
to : account_id,
source_channel : 1,
timeout : ibc_primitives::Timeout::Offset{ timestamp : Some(1), height : Some(1)}
};

let account = sp_runtime::AccountId32::new(
id
);
let mut to32 : &[u8] = sp_runtime::AccountId32::as_ref(&account);
let account_id = T::AccountId::decode(&mut to32).unwrap();
let signed_account_id = RawOrigin::Signed(account_id);

// let
let Fungibility::Fungible(ref amount) = asset.fun else{
return;
//do not support non fungible.
};

let result = pallet_ibc::Pallet::<T>::transfer(signed_account_id.into(), transfer_params, asset_id.unwrap(), (*amount).into(), None);
}
}
}


use xcm::v3::*;
pub trait MultiCurrencyCallback{
fn deposit_asset(asset: &MultiAsset, location: &MultiLocation, context: &XcmContext, deposit_result : Result){
pub trait MultiCurrencyCallback<T : Config>{
fn deposit_asset(asset: &MultiAsset, location: &MultiLocation, context: &XcmContext, deposit_result : Result, asset_id : Option<<T as pallet_ibc::Config>::AssetId>);
//check result, unwrap memo if exists and execute ibc packet
}

}
28 changes: 18 additions & 10 deletions code/parachain/runtime/composable/src/xcmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ pub type LocationToAccountId = (
// Straight up local `AccountId32` origins just alias directly to `AccountId`.
AccountId32Aliases<RelayNetwork, AccountId>,
//Convert Multilication X4(PalletInstance, AccountId, GeneralIndex, AccountId32) into AccountId
AccountId32BatchTx<AccountId>
AccountId32MultihopTx<AccountId>
);

pub struct AccountId32BatchTx<AccountId>(PhantomData<AccountId>);
pub struct AccountId32MultihopTx<AccountId>(PhantomData<AccountId>);
impl<AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone>
xcm_executor::traits::Convert<MultiLocation, AccountId> for AccountId32BatchTx<AccountId>
xcm_executor::traits::Convert<MultiLocation, AccountId> for AccountId32MultihopTx<AccountId>
{
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
let id = match location {
Expand Down Expand Up @@ -159,7 +159,6 @@ pub type LocalAssetTransactor = MultiCurrencyAdapterWrapper<
IsNativeConcrete<CurrencyId, AssetsIdConverter>,
AccountId,
LocationToAccountId,
CurrencyId,
AssetsIdConverter,
DepositToAlternative<TreasuryAccount, Tokens, CurrencyId, AccountId, Balance>,
PalletXcmIbc
Expand All @@ -171,7 +170,6 @@ UnknownAsset,
Match,
AccountId,
AccountIdConvert,
CurrencyId,
CurrencyIdConvert,
DepositFailureHandler,
MultiCurrencyCallback
Expand All @@ -182,7 +180,6 @@ PhantomData<(
Match,
AccountId,
AccountIdConvert,
CurrencyId,
CurrencyIdConvert,
DepositFailureHandler,
MultiCurrencyCallback
Expand All @@ -195,18 +192,16 @@ impl<
Match: MatchesFungible<MultiCurrency::Balance>,
AccountId: sp_std::fmt::Debug + Clone,
AccountIdConvert: xcm_executor::traits::Convert<MultiLocation, AccountId>,
CurrencyId: FullCodec + Eq + PartialEq + Copy + MaybeSerializeDeserialize + sp_std::fmt::Debug,
CurrencyIdConvert: Convert<MultiAsset, Option<CurrencyId>>,
DepositFailureHandler: orml_xcm_support::OnDepositFail<CurrencyId, AccountId, MultiCurrency::Balance>,
DepositCallback: MultiCurrencyCallback
DepositCallback: MultiCurrencyCallback::<Runtime>
> xcm_executor::traits::TransactAsset
for MultiCurrencyAdapterWrapper<
MultiCurrency,
UnknownAsset,
Match,
AccountId,
AccountIdConvert,
CurrencyId,
CurrencyIdConvert,
DepositFailureHandler,
DepositCallback
Expand All @@ -223,7 +218,20 @@ impl<
CurrencyIdConvert,
DepositFailureHandler,
>::deposit_asset(asset, location, context);
DepositCallback::deposit_asset(asset, location, context, result);
// let currency_id = CurrencyIdConvert::convert(asset.clone());
// let balance = Match::matches_fungible(asset);
match (
AccountIdConvert::convert_ref(location),
CurrencyIdConvert::convert(asset.clone()),
Match::matches_fungible(asset),
) {
// known asset
(Ok(who), Some(currency_id), Some(amount)) => {
DepositCallback::deposit_asset(asset, location, context, result, Some(currency_id));
},
// unknown asset
_ => {},
}
result
}

Expand Down

0 comments on commit 7a97ee0

Please sign in to comment.