mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 22:11:02 +00:00
* Assets balances * Update docs * AssetsApi with MultiLocation as preparation for multi pallet_assets instances (#2187) * AssetsApi with MultiLocation for Westmint + assets-common * AssetsApi with MultiLocation for Statemine/t * typo * typo for check-docs job * WIP: AssetsApi return MultiAsset instead of (MultiLocation, Balance) * WIP: assets_api + conversion refactor * WIP: assets_api + conversion refactor * Finished asset runtimes * Refactor AssetsApi to FungiblesApi * Refactor * Fix check-rust-docs * Removed todo * Fix check-rust-doc * Update parachains/runtimes/assets/common/Cargo.toml Co-authored-by: Bastian Köcher <git@kchr.de> * update lockfile for {"substrate", "polkadot"} --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: parity-processbot <> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -47,6 +47,7 @@ sp-version = { git = "https://github.com/paritytech/substrate", default-features
|
||||
|
||||
# Polkadot
|
||||
pallet-xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
pallet-xcm-benchmarks = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false, optional = true }
|
||||
polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
@@ -68,7 +69,7 @@ cumulus-primitives-utility = { path = "../../../../primitives/utility", default-
|
||||
pallet-collator-selection = { path = "../../../../pallets/collator-selection", default-features = false }
|
||||
parachain-info = { path = "../../../pallets/parachain-info", default-features = false }
|
||||
parachains-common = { path = "../../../common", default-features = false }
|
||||
pallet-xcm-benchmarks = { git = "https://github.com/paritytech/polkadot", branch = "master", default-features = false, optional = true }
|
||||
assets-common = { path = "../common", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.3.4"
|
||||
@@ -176,4 +177,5 @@ std = [
|
||||
"pallet-collator-selection/std",
|
||||
"parachain-info/std",
|
||||
"parachains-common/std",
|
||||
"assets-common/std",
|
||||
]
|
||||
|
||||
@@ -93,7 +93,9 @@ use parachains_common::{
|
||||
Signature, StatemintAuraId as AuraId, AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT,
|
||||
NORMAL_DISPATCH_RATIO, SLOT_DURATION,
|
||||
};
|
||||
use xcm_config::{DotLocation, XcmConfig, XcmOriginToTransactDispatchOrigin};
|
||||
use xcm_config::{
|
||||
DotLocation, TrustBackedAssetsConvertedConcreteId, XcmConfig, XcmOriginToTransactDispatchOrigin,
|
||||
};
|
||||
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub use sp_runtime::BuildStorage;
|
||||
@@ -828,6 +830,34 @@ impl_runtime_apis! {
|
||||
}
|
||||
}
|
||||
|
||||
impl assets_common::runtime_api::FungiblesApi<
|
||||
Block,
|
||||
AccountId,
|
||||
> for Runtime
|
||||
{
|
||||
fn query_account_balances(account: AccountId) -> Result<Vec<xcm::latest::MultiAsset>, assets_common::runtime_api::FungiblesAccessError> {
|
||||
use assets_common::fungible_conversion::{convert, convert_balance};
|
||||
Ok([
|
||||
// collect pallet_balance
|
||||
{
|
||||
let balance = Balances::free_balance(account.clone());
|
||||
if balance > 0 {
|
||||
vec![convert_balance::<DotLocation, Balance>(balance)?]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
},
|
||||
// collect pallet_assets (TrustBackedAssets)
|
||||
convert::<_, _, _, _, TrustBackedAssetsConvertedConcreteId>(
|
||||
Assets::account_balances(account)
|
||||
.iter()
|
||||
.filter(|(_, balance)| balance > &0)
|
||||
)?,
|
||||
// collect ... e.g. pallet_assets ForeignAssets
|
||||
].concat())
|
||||
}
|
||||
}
|
||||
|
||||
impl cumulus_primitives_core::CollectCollationInfo<Block> for Runtime {
|
||||
fn collect_collation_info(header: &<Block as BlockT>::Header) -> cumulus_primitives_core::CollationInfo {
|
||||
ParachainSystem::collect_collation_info(header)
|
||||
|
||||
@@ -14,9 +14,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
use super::{
|
||||
AccountId, AllPalletsWithSystem, AssetIdForTrustBackedAssets, Assets, Authorship, Balance,
|
||||
Balances, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent,
|
||||
RuntimeOrigin, TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
|
||||
AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ParachainInfo,
|
||||
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
|
||||
TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
|
||||
};
|
||||
use frame_support::{
|
||||
match_types, parameter_types,
|
||||
@@ -34,17 +34,13 @@ use sp_runtime::traits::ConvertInto;
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_builder::{
|
||||
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
|
||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex,
|
||||
ConvertedConcreteId, CurrencyAdapter, EnsureXcmOrigin, FungiblesAdapter, IsConcrete, LocalMint,
|
||||
NativeAsset, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
|
||||
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
|
||||
SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds,
|
||||
WithComputedOrigin,
|
||||
};
|
||||
use xcm_executor::{
|
||||
traits::{JustTry, WithOriginFilter},
|
||||
XcmExecutor,
|
||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin,
|
||||
FungiblesAdapter, IsConcrete, LocalMint, NativeAsset, ParentAsSuperuser, ParentIsPreset,
|
||||
RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
|
||||
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
|
||||
UsingComponents, WeightInfoBounds, WithComputedOrigin,
|
||||
};
|
||||
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};
|
||||
|
||||
parameter_types! {
|
||||
pub const DotLocation: MultiLocation = MultiLocation::parent();
|
||||
@@ -84,21 +80,16 @@ pub type CurrencyTransactor = CurrencyAdapter<
|
||||
(),
|
||||
>;
|
||||
|
||||
/// `AssetId/Balancer` converter for `TrustBackedAssets``
|
||||
pub type TrustBackedAssetsConvertedConcreteId =
|
||||
assets_common::TrustBackedAssetsConvertedConcreteId<TrustBackedAssetsPalletLocation, Balance>;
|
||||
|
||||
/// Means for transacting assets besides the native currency on this chain.
|
||||
pub type FungiblesTransactor = FungiblesAdapter<
|
||||
// Use this fungibles implementation:
|
||||
Assets,
|
||||
// Use this currency when it is a fungible asset matching the given location or name:
|
||||
ConvertedConcreteId<
|
||||
AssetIdForTrustBackedAssets,
|
||||
Balance,
|
||||
AsPrefixedGeneralIndex<
|
||||
TrustBackedAssetsPalletLocation,
|
||||
AssetIdForTrustBackedAssets,
|
||||
JustTry,
|
||||
>,
|
||||
JustTry,
|
||||
>,
|
||||
TrustBackedAssetsConvertedConcreteId,
|
||||
// Convert an XCM MultiLocation into a local account id:
|
||||
LocationToAccountId,
|
||||
// Our chain's account ID type (we can't get away without mentioning it explicitly):
|
||||
@@ -302,16 +293,7 @@ impl xcm_executor::Config for XcmConfig {
|
||||
cumulus_primitives_utility::TakeFirstAssetTrader<
|
||||
AccountId,
|
||||
AssetFeeAsExistentialDepositMultiplierFeeCharger,
|
||||
ConvertedConcreteId<
|
||||
AssetIdForTrustBackedAssets,
|
||||
Balance,
|
||||
AsPrefixedGeneralIndex<
|
||||
TrustBackedAssetsPalletLocation,
|
||||
AssetIdForTrustBackedAssets,
|
||||
JustTry,
|
||||
>,
|
||||
JustTry,
|
||||
>,
|
||||
TrustBackedAssetsConvertedConcreteId,
|
||||
Assets,
|
||||
cumulus_primitives_utility::XcmFeesTo32ByteAccount<
|
||||
FungiblesTransactor,
|
||||
|
||||
@@ -3,20 +3,27 @@ use codec::Encode;
|
||||
use cumulus_primitives_utility::ChargeWeightInFungibles;
|
||||
use frame_support::{
|
||||
assert_noop, assert_ok, sp_io,
|
||||
traits::PalletInfo,
|
||||
weights::{Weight, WeightToFee as WeightToFeeT},
|
||||
};
|
||||
use parachains_common::{AccountId, StatemintAuraId as AuraId};
|
||||
use statemint_runtime::xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger;
|
||||
use parachains_common::{AccountId, Balance, StatemintAuraId as AuraId};
|
||||
use statemint_runtime::xcm_config::{
|
||||
AssetFeeAsExistentialDepositMultiplierFeeCharger, DotLocation, TrustBackedAssetsPalletLocation,
|
||||
};
|
||||
pub use statemint_runtime::{
|
||||
constants::fee::WeightToFee, xcm_config::XcmConfig, Assets, Balances, ExistentialDeposit,
|
||||
ReservedDmpWeight, Runtime, SessionKeys, System,
|
||||
};
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_executor::{traits::WeightTrader, XcmExecutor};
|
||||
use xcm_executor::{
|
||||
traits::{Convert, WeightTrader},
|
||||
XcmExecutor,
|
||||
};
|
||||
|
||||
pub const ALICE: [u8; 32] = [1u8; 32];
|
||||
|
||||
type AssetIdForTrustBackedAssetsConvert =
|
||||
assets_common::AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>;
|
||||
|
||||
#[test]
|
||||
fn test_asset_xcm_trader() {
|
||||
ExtBuilder::<Runtime>::default()
|
||||
@@ -48,16 +55,8 @@ fn test_asset_xcm_trader() {
|
||||
));
|
||||
|
||||
// get asset id as multilocation
|
||||
let asset_multilocation = MultiLocation::new(
|
||||
0,
|
||||
X2(
|
||||
PalletInstance(
|
||||
<Runtime as frame_system::Config>::PalletInfo::index::<Assets>().unwrap()
|
||||
as u8,
|
||||
),
|
||||
GeneralIndex(local_asset_id.into()),
|
||||
),
|
||||
);
|
||||
let asset_multilocation =
|
||||
AssetIdForTrustBackedAssetsConvert::reverse_ref(local_asset_id).unwrap();
|
||||
|
||||
// Set Alice as block author, who will receive fees
|
||||
RuntimeHelper::<Runtime>::run_to_block(2, Some(AccountId::from(ALICE)));
|
||||
@@ -98,12 +97,15 @@ fn test_asset_xcm_trader() {
|
||||
|
||||
// Make sure author(Alice) has received the amount
|
||||
assert_eq!(
|
||||
Assets::balance(1, AccountId::from(ALICE)),
|
||||
Assets::balance(local_asset_id, AccountId::from(ALICE)),
|
||||
minimum_asset_balance + asset_amount_needed
|
||||
);
|
||||
|
||||
// We also need to ensure the total supply increased
|
||||
assert_eq!(Assets::total_supply(1), minimum_asset_balance + asset_amount_needed);
|
||||
assert_eq!(
|
||||
Assets::total_supply(local_asset_id),
|
||||
minimum_asset_balance + asset_amount_needed
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -147,16 +149,7 @@ fn test_asset_xcm_trader_with_refund() {
|
||||
// bit more of weight
|
||||
let bought = Weight::from_ref_time(400_000_000_000u64);
|
||||
|
||||
let asset_multilocation = MultiLocation::new(
|
||||
0,
|
||||
X2(
|
||||
PalletInstance(
|
||||
<Runtime as frame_system::Config>::PalletInfo::index::<Assets>().unwrap()
|
||||
as u8,
|
||||
),
|
||||
GeneralIndex(1),
|
||||
),
|
||||
);
|
||||
let asset_multilocation = AssetIdForTrustBackedAssetsConvert::reverse_ref(1).unwrap();
|
||||
|
||||
// lets calculate amount needed
|
||||
let amount_bought = WeightToFee::weight_to_fee(&bought);
|
||||
@@ -228,16 +221,7 @@ fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() {
|
||||
// bit more of weight
|
||||
let bought = Weight::from_ref_time(50_000_000_000u64);
|
||||
|
||||
let asset_multilocation = MultiLocation::new(
|
||||
0,
|
||||
X2(
|
||||
PalletInstance(
|
||||
<Runtime as frame_system::Config>::PalletInfo::index::<Assets>().unwrap()
|
||||
as u8,
|
||||
),
|
||||
GeneralIndex(1),
|
||||
),
|
||||
);
|
||||
let asset_multilocation = AssetIdForTrustBackedAssetsConvert::reverse_ref(1).unwrap();
|
||||
|
||||
let amount_bought = WeightToFee::weight_to_fee(&bought);
|
||||
|
||||
@@ -288,16 +272,7 @@ fn test_that_buying_ed_refund_does_not_refund() {
|
||||
// We are gonna buy ED
|
||||
let bought = Weight::from_ref_time(ExistentialDeposit::get().try_into().unwrap());
|
||||
|
||||
let asset_multilocation = MultiLocation::new(
|
||||
0,
|
||||
X2(
|
||||
PalletInstance(
|
||||
<Runtime as frame_system::Config>::PalletInfo::index::<Assets>().unwrap()
|
||||
as u8,
|
||||
),
|
||||
GeneralIndex(1),
|
||||
),
|
||||
);
|
||||
let asset_multilocation = AssetIdForTrustBackedAssetsConvert::reverse_ref(1).unwrap();
|
||||
|
||||
let amount_bought = WeightToFee::weight_to_fee(&bought);
|
||||
|
||||
@@ -375,16 +350,7 @@ fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() {
|
||||
// lets calculate amount needed
|
||||
let asset_amount_needed = WeightToFee::weight_to_fee(&bought);
|
||||
|
||||
let asset_multilocation = MultiLocation::new(
|
||||
0,
|
||||
X2(
|
||||
PalletInstance(
|
||||
<Runtime as frame_system::Config>::PalletInfo::index::<Assets>().unwrap()
|
||||
as u8,
|
||||
),
|
||||
GeneralIndex(1),
|
||||
),
|
||||
);
|
||||
let asset_multilocation = AssetIdForTrustBackedAssetsConvert::reverse_ref(1).unwrap();
|
||||
|
||||
let asset: MultiAsset = (asset_multilocation, asset_amount_needed).into();
|
||||
|
||||
@@ -402,6 +368,75 @@ fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_assets_balances_api_works() {
|
||||
use assets_common::runtime_api::runtime_decl_for_FungiblesApi::FungiblesApi;
|
||||
|
||||
ExtBuilder::<Runtime>::default()
|
||||
.with_collators(vec![AccountId::from(ALICE)])
|
||||
.with_session_keys(vec![(
|
||||
AccountId::from(ALICE),
|
||||
AccountId::from(ALICE),
|
||||
SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) },
|
||||
)])
|
||||
.build()
|
||||
.execute_with(|| {
|
||||
let local_asset_id = 1;
|
||||
|
||||
// check before
|
||||
assert_eq!(Assets::balance(local_asset_id, AccountId::from(ALICE)), 0);
|
||||
assert_eq!(Balances::free_balance(AccountId::from(ALICE)), 0);
|
||||
assert!(Runtime::query_account_balances(AccountId::from(ALICE)).unwrap().is_empty());
|
||||
|
||||
// Drip some balance
|
||||
use frame_support::traits::fungible::Mutate;
|
||||
let some_currency = ExistentialDeposit::get();
|
||||
Balances::mint_into(&AccountId::from(ALICE), some_currency).unwrap();
|
||||
|
||||
// We need root origin to create a sufficient asset
|
||||
let minimum_asset_balance = 3333333_u128;
|
||||
assert_ok!(Assets::force_create(
|
||||
RuntimeHelper::<Runtime>::root_origin(),
|
||||
local_asset_id.into(),
|
||||
AccountId::from(ALICE).into(),
|
||||
true,
|
||||
minimum_asset_balance
|
||||
));
|
||||
|
||||
// We first mint enough asset for the account to exist for assets
|
||||
assert_ok!(Assets::mint(
|
||||
RuntimeHelper::<Runtime>::origin_of(AccountId::from(ALICE)),
|
||||
local_asset_id.into(),
|
||||
AccountId::from(ALICE).into(),
|
||||
minimum_asset_balance
|
||||
));
|
||||
|
||||
// check after
|
||||
assert_eq!(
|
||||
Assets::balance(local_asset_id, AccountId::from(ALICE)),
|
||||
minimum_asset_balance
|
||||
);
|
||||
assert_eq!(Balances::free_balance(AccountId::from(ALICE)), some_currency);
|
||||
|
||||
let result = Runtime::query_account_balances(AccountId::from(ALICE)).unwrap();
|
||||
assert_eq!(result.len(), 2);
|
||||
|
||||
// check currency
|
||||
assert!(result.iter().any(|asset| asset.eq(
|
||||
&assets_common::fungible_conversion::convert_balance::<DotLocation, Balance>(
|
||||
some_currency
|
||||
)
|
||||
.unwrap()
|
||||
)));
|
||||
// check trusted asset
|
||||
assert!(result.iter().any(|asset| asset.eq(&(
|
||||
AssetIdForTrustBackedAssetsConvert::reverse_ref(local_asset_id).unwrap(),
|
||||
minimum_asset_balance
|
||||
)
|
||||
.into())));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn receive_teleported_asset_works() {
|
||||
ExtBuilder::<Runtime>::default()
|
||||
|
||||
Reference in New Issue
Block a user