Skip to content

Commit 253d80e

Browse files
committed
spike foreign fungibles v2
1 parent 76128fc commit 253d80e

File tree

5 files changed

+453
-41
lines changed

5 files changed

+453
-41
lines changed

pallets/api/src/fungibles/benchmarking.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,14 @@ mod benchmarks {
108108

109109
#[benchmark]
110110
// Storage: `Assets`
111-
fn total_supply() {
111+
fn total_supply(a: Linear<0, 1>) {
112112
#[block]
113113
{
114-
Pallet::<T>::read(Read::TotalSupply(TokenIdOf::<T>::zero()));
114+
match a {
115+
0 => Pallet::<T>::read(Read::TotalSupply(TokenIdOf::<T>::TrustBacked(0))),
116+
1 =>
117+
Pallet::<T>::read(Read::TotalSupply(TokenIdOf::<T>::Foreign(Location::Parent))),
118+
}
115119
}
116120
}
117121
#[benchmark]

pallets/api/src/fungibles/mod.rs

Lines changed: 218 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22
//! goal is to provide a simplified, consistent API that adheres to standards in the smart contract
33
//! space.
44
5-
use frame_support::traits::fungibles::{metadata::Inspect as MetadataInspect, Inspect};
5+
use codec::{Decode, Encode, MaxEncodedLen};
6+
use frame_support::{
7+
__private::RuntimeDebug,
8+
pallet_prelude::TypeInfo,
9+
traits::fungibles::{metadata::Inspect as MetadataInspect, Inspect},
10+
};
611
pub use pallet::*;
712
use pallet_assets::WeightInfo as AssetsWeightInfoTrait;
813
use weights::WeightInfo;
@@ -13,16 +18,49 @@ mod benchmarking;
1318
mod tests;
1419
pub mod weights;
1520

16-
type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
17-
type TokenIdOf<T> = <AssetsOf<T> as Inspect<<T as frame_system::Config>::AccountId>>::AssetId;
18-
type TokenIdParameterOf<T> = <T as pallet_assets::Config<AssetsInstanceOf<T>>>::AssetIdParameter;
19-
type AssetsOf<T> = pallet_assets::Pallet<T, AssetsInstanceOf<T>>;
20-
type AssetsErrorOf<T> = pallet_assets::Error<T, AssetsInstanceOf<T>>;
21-
type AssetsInstanceOf<T> = <T as Config>::AssetsInstance;
22-
type AssetsWeightInfoOf<T> = <T as pallet_assets::Config<AssetsInstanceOf<T>>>::WeightInfo;
23-
type BalanceOf<T> = <AssetsOf<T> as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
21+
type TrustBackedTokenIdParameterOf<T> =
22+
<T as pallet_assets::Config<TrustBackedAssetsInstanceOf<T>>>::AssetIdParameter;
23+
type ForeignTokenIdParameterOf<T> =
24+
<T as pallet_assets::Config<ForeignAssetsInstanceOf<T>>>::AssetIdParameter;
25+
26+
type TrustBackedAssetsOf<T> = pallet_assets::Pallet<T, TrustBackedAssetsInstanceOf<T>>;
27+
type ForeignAssetsOf<T> = pallet_assets::Pallet<T, ForeignAssetsInstanceOf<T>>;
28+
29+
type TrustBackedAssetsErrorOf<T> = pallet_assets::Error<T, TrustBackedAssetsInstanceOf<T>>;
30+
type ForeignAssetsErrorOf<T> = pallet_assets::Error<T, ForeignAssetsInstanceOf<T>>;
31+
32+
type TrustBackedAssetsInstanceOf<T> = <T as Config>::TrustBackedAssetsInstance;
33+
type ForeignAssetsInstanceOf<T> = <T as Config>::ForeignAssetsInstance;
34+
35+
type TrustBackedAssetsWeightInfoOf<T> =
36+
<T as pallet_assets::Config<TrustBackedAssetsInstanceOf<T>>>::WeightInfo;
37+
type ForeignAssetsWeightInfoOf<T> =
38+
<T as pallet_assets::Config<ForeignAssetsInstanceOf<T>>>::WeightInfo;
2439
type WeightOf<T> = <T as Config>::WeightInfo;
2540

41+
// Our unified asset identifier type. The variant determines which asset instance to call.
42+
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
43+
pub enum MultiAssetId<TrustId, ForeignId> {
44+
TrustBacked(TrustId),
45+
Foreign(ForeignId),
46+
}
47+
48+
/// Renamed to TokenIdOf for minimal changes.
49+
/// It wraps the asset ID from:
50+
/// - the trust‑backed instance (using `TrustBackedAssetsInstanceOf<T>`), and
51+
/// - the foreign instance (using `ForeignAssetsInstanceOf<T>`).
52+
type TokenIdOf<T> = MultiAssetId<
53+
<pallet_assets::Pallet<T, TrustBackedAssetsInstanceOf<T>> as Inspect<
54+
<T as frame_system::Config>::AccountId,
55+
>>::AssetId,
56+
<pallet_assets::Pallet<T, ForeignAssetsInstanceOf<T>> as Inspect<
57+
<T as frame_system::Config>::AccountId,
58+
>>::AssetId,
59+
>;
60+
61+
type AccountIdOf<T> = <T as frame_system::Config>::AccountId;
62+
type BalanceOf<T> = <T as Config>::Balance;
63+
2664
#[frame_support::pallet]
2765
pub mod pallet {
2866
use core::cmp::Ordering::*;
@@ -42,13 +80,44 @@ pub mod pallet {
4280
use super::*;
4381

4482
/// Configure the pallet by specifying the parameters and types on which it depends.
83+
///
84+
/// It now requires two asset instances:
85+
/// - `TrustBackedAssetsInstance`: used for trust‑backed assets (formerly the sole instance),
86+
/// - `ForeignAssetsInstance`: used for foreign assets.
4587
#[pallet::config]
46-
pub trait Config: frame_system::Config + pallet_assets::Config<Self::AssetsInstance> {
88+
pub trait Config:
89+
frame_system::Config
90+
+ pallet_assets::Config<Self::TrustBackedAssetsInstance>
91+
+ pallet_assets::Config<Self::ForeignAssetsInstance>
92+
{
4793
/// Because this pallet emits events, it depends on the runtime's definition of an event.
4894
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
49-
/// The instance of pallet-assets.
50-
type AssetsInstance;
51-
/// Weight information for dispatchables in this pallet.
95+
/// The asset instance for trust‑backed assets (renamed from the old AssetsInstance).
96+
type TrustBackedAssetsInstance;
97+
/// The asset instance for foreign assets.
98+
type ForeignAssetsInstance;
99+
type Balance: Parameter
100+
+ MaybeSerializeDeserialize
101+
+ Default
102+
+ Copy
103+
+ Into<
104+
<pallet_assets::Pallet<Self, Self::TrustBackedAssetsInstance> as Inspect<
105+
<Self as frame_system::Config>::AccountId,
106+
>>::Balance,
107+
> + From<
108+
<pallet_assets::Pallet<Self, Self::TrustBackedAssetsInstance> as Inspect<
109+
<Self as frame_system::Config>::AccountId,
110+
>>::Balance,
111+
> + Into<
112+
<pallet_assets::Pallet<Self, Self::ForeignAssetsInstance> as Inspect<
113+
<Self as frame_system::Config>::AccountId,
114+
>>::Balance,
115+
> + From<
116+
<pallet_assets::Pallet<Self, Self::ForeignAssetsInstance> as Inspect<
117+
<Self as frame_system::Config>::AccountId,
118+
>>::Balance,
119+
>;
120+
/// Weight information for dispatchable functions in this pallet.
52121
type WeightInfo: WeightInfo;
53122
}
54123

@@ -94,6 +163,14 @@ pub mod pallet {
94163
},
95164
}
96165

166+
// A helper function to compute the weight parameter based on the token variant.
167+
fn weight_param<T: Config>(token: &TokenIdOf<T>) -> u32 {
168+
match token {
169+
MultiAssetId::TrustBacked(_) => 0,
170+
MultiAssetId::Foreign(_) => 1,
171+
}
172+
}
173+
97174
#[pallet::call]
98175
impl<T: Config> Pallet<T> {
99176
/// Transfers `value` amount of tokens from the caller's account to account `to`.
@@ -103,20 +180,38 @@ pub mod pallet {
103180
/// - `to` - The recipient account.
104181
/// - `value` - The number of tokens to transfer.
105182
#[pallet::call_index(3)]
106-
#[pallet::weight(AssetsWeightInfoOf::<T>::transfer_keep_alive())]
183+
#[pallet::weight(
184+
if weight_param::<T> (& token) == 0 {
185+
TrustBackedAssetsWeightInfoOf::<T>::transfer_keep_alive()
186+
} else {
187+
ForeignAssetsWeightInfoOf::<T>::transfer_keep_alive()
188+
}
189+
)]
107190
pub fn transfer(
108191
origin: OriginFor<T>,
109192
token: TokenIdOf<T>,
110193
to: AccountIdOf<T>,
111194
value: BalanceOf<T>,
112195
) -> DispatchResult {
113196
let from = ensure_signed(origin.clone())?;
114-
AssetsOf::<T>::transfer_keep_alive(
115-
origin,
116-
token.clone().into(),
117-
T::Lookup::unlookup(to.clone()),
118-
value,
119-
)?;
197+
match token.clone() {
198+
MultiAssetId::TrustBacked(id) => {
199+
TrustBackedAssetsOf::<T>::transfer_keep_alive(
200+
origin,
201+
id.into(),
202+
T::Lookup::unlookup(to.clone()),
203+
value.into(),
204+
)?;
205+
},
206+
MultiAssetId::Foreign(id) => {
207+
ForeignAssetsOf::<T>::transfer_keep_alive(
208+
origin,
209+
id.into(),
210+
T::Lookup::unlookup(to.clone()),
211+
value.into(),
212+
)?;
213+
},
214+
}
120215
Self::deposit_event(Event::Transfer { token, from: Some(from), to: Some(to), value });
121216
Ok(())
122217
}
@@ -499,7 +594,7 @@ pub mod pallet {
499594
fn weight(request: &Self::Read) -> Weight {
500595
use Read::*;
501596
match request {
502-
TotalSupply(_) => <T as Config>::WeightInfo::total_supply(),
597+
TotalSupply(id) => <T as Config>::WeightInfo::total_supply(weight_param(id)),
503598
BalanceOf { .. } => <T as Config>::WeightInfo::balance_of(),
504599
Allowance { .. } => <T as Config>::WeightInfo::allowance(),
505600
TokenName(_) => <T as Config>::WeightInfo::token_name(),
@@ -516,23 +611,110 @@ pub mod pallet {
516611
fn read(request: Self::Read) -> Self::Result {
517612
use Read::*;
518613
match request {
519-
TotalSupply(token) => ReadResult::TotalSupply(AssetsOf::<T>::total_supply(token)),
520-
BalanceOf { token, owner } =>
521-
ReadResult::BalanceOf(AssetsOf::<T>::balance(token, owner)),
522-
Allowance { token, owner, spender } =>
523-
ReadResult::Allowance(AssetsOf::<T>::allowance(token, &owner, &spender)),
524-
TokenName(token) => ReadResult::TokenName(
525-
Some(<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::name(token))
614+
TotalSupply(token) => {
615+
let total = match token {
616+
MultiAssetId::TrustBacked(id) =>
617+
TrustBackedAssetsOf::<T>::total_supply(id).into(),
618+
MultiAssetId::Foreign(id) => ForeignAssetsOf::<T>::total_supply(id).into(),
619+
};
620+
ReadResult::TotalSupply(total)
621+
},
622+
BalanceOf { token, owner } => {
623+
let bal = match token {
624+
MultiAssetId::TrustBacked(id) => pallet_assets::Pallet::<
625+
T,
626+
TrustBackedAssetsInstanceOf<T>,
627+
>::balance(id, &owner)
628+
.into(),
629+
MultiAssetId::Foreign(id) => pallet_assets::Pallet::<
630+
T,
631+
ForeignAssetsInstanceOf<T>,
632+
>::balance(id, &owner)
633+
.into(),
634+
};
635+
ReadResult::BalanceOf(bal)
636+
},
637+
Allowance { token, owner, spender } => {
638+
let allow = match token {
639+
MultiAssetId::TrustBacked(id) => pallet_assets::Pallet::<
640+
T,
641+
TrustBackedAssetsInstanceOf<T>,
642+
>::allowance(id, &owner, &spender)
643+
.into(),
644+
MultiAssetId::Foreign(id) => pallet_assets::Pallet::<
645+
T,
646+
ForeignAssetsInstanceOf<T>,
647+
>::allowance(id, &owner, &spender)
648+
.into(),
649+
};
650+
ReadResult::Allowance(allow)
651+
},
652+
TokenName(token) => {
653+
let name = match token {
654+
MultiAssetId::TrustBacked(id) => Some(<pallet_assets::Pallet<
655+
T,
656+
TrustBackedAssetsInstanceOf<T>,
657+
> as MetadataInspect<AccountIdOf<T>>>::name(
658+
id
659+
))
660+
.filter(|v| !v.is_empty()),
661+
MultiAssetId::Foreign(id) => Some(<pallet_assets::Pallet<
662+
T,
663+
ForeignAssetsInstanceOf<T>,
664+
> as MetadataInspect<AccountIdOf<T>>>::name(
665+
id
666+
))
667+
.filter(|v| !v.is_empty()),
668+
};
669+
ReadResult::TokenName(name)
670+
},
671+
TokenSymbol(token) => {
672+
let symbol = match token {
673+
MultiAssetId::TrustBacked(id) => Some(<pallet_assets::Pallet<
674+
T,
675+
TrustBackedAssetsInstanceOf<T>,
676+
> as MetadataInspect<AccountIdOf<T>>>::symbol(
677+
id
678+
))
526679
.filter(|v| !v.is_empty()),
527-
),
528-
TokenSymbol(token) => ReadResult::TokenSymbol(
529-
Some(<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::symbol(token))
680+
MultiAssetId::Foreign(id) => Some(<pallet_assets::Pallet<
681+
T,
682+
ForeignAssetsInstanceOf<T>,
683+
> as MetadataInspect<AccountIdOf<T>>>::symbol(
684+
id
685+
))
530686
.filter(|v| !v.is_empty()),
531-
),
532-
TokenDecimals(token) => ReadResult::TokenDecimals(
533-
<AssetsOf<T> as MetadataInspect<AccountIdOf<T>>>::decimals(token),
534-
),
535-
TokenExists(token) => ReadResult::TokenExists(AssetsOf::<T>::asset_exists(token)),
687+
};
688+
ReadResult::TokenSymbol(symbol)
689+
},
690+
TokenDecimals(token) => {
691+
let decimals = match token {
692+
MultiAssetId::TrustBacked(id) => <pallet_assets::Pallet<
693+
T,
694+
TrustBackedAssetsInstanceOf<T>,
695+
> as MetadataInspect<AccountIdOf<T>>>::decimals(
696+
id
697+
),
698+
MultiAssetId::Foreign(id) => <pallet_assets::Pallet<
699+
T,
700+
ForeignAssetsInstanceOf<T>,
701+
> as MetadataInspect<AccountIdOf<T>>>::decimals(
702+
id
703+
),
704+
};
705+
ReadResult::TokenDecimals(decimals)
706+
},
707+
TokenExists(token) => {
708+
let exists = match token {
709+
MultiAssetId::TrustBacked(id) => pallet_assets::Pallet::<
710+
T,
711+
TrustBackedAssetsInstanceOf<T>,
712+
>::asset_exists(id),
713+
MultiAssetId::Foreign(id) =>
714+
pallet_assets::Pallet::<T, ForeignAssetsInstanceOf<T>>::asset_exists(id),
715+
};
716+
ReadResult::TokenExists(exists)
717+
},
536718
}
537719
}
538720
}

0 commit comments

Comments
 (0)