git.delta.rocks / unique-network / refs/commits / 1c8c05f45308

difftreelog

From Karura transfers

str-mv2022-01-26parent: #ed10be8.patch.diff
in: master

2 files changed

modifiedREADME.mddiffbeforeafterboth
340To get started, you need to open the hrmr channel.340To get started, you need to open the hrmr channel.
341Next, we need to register our asset in Karura.341Next, we need to register our asset in Karura.
342342
343```
343assetRegistry -> registerForeignAsset(location, metadata)344assetRegistry -> registerForeignAsset(location, metadata)
344location:345location:
345 V0(X2(Parent, Parachain(PARA_ID))) 346 V0(X2(Parent, Parachain(PARA_ID)))
348 symbol OPL349 symbol OPL
349 decimals 15350 decimals 15
350minimalBalance 1351minimalBalance 1
352```
351353
352Next, we can send tokens of our chain:354Next, we can send tokens of our chain:
355```
353polkadotXcm -> reserveTransferAssets356polkadotXcm -> reserveTransferAssets
354dest:357dest:
355 V0(X2(Parent, Parachain(KARURA_PARA_ID))) 358 V0(X2(Parent, Parachain(<KARURA_PARA_ID>)))
356beneficiary:359beneficiary:
357 X1(AccountId(Any, ACCOUNT))360 X1(AccountId(Any, <ACCOUNT>))
358assets:361assets:
359 V1(Concrete(0,Here), Fungible(AMOUNT))362 V1(Concrete(0,Here), Fungible(<AMOUNT>))
360feeAssetItem: 363feeAssetItem:
361 0 364 0
362weightLimit:365weightLimit:
363 Limit366 <LIMIT>
364 367```
365368
366The result will be displayed in ChainState 369The result will be displayed in ChainState
367tokens -> accounts 370tokens -> accounts
368371
372
373To send tokens from karura:
374
375```
376xtokens -> transfer
377
378currencyId:
379 ForeingAsset
380 <TOKEN_ID>
381
382amount:
383 <AMOUNT>
384dest:
385 V1
386 (
387 Parents:1,
388 X2(Parachain(<KARURA_PARA_ID>), AccountId(Any, <ACCOUNT>)
389 )
390destWeight:
391 <WEIGHT>
392
393
394```
modifiedruntime/src/lib.rsdiffbeforeafterboth
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -23,7 +23,8 @@
 use sp_runtime::{
 	Permill, Perbill, Percent, create_runtime_str, generic, impl_opaque_keys,
 	traits::{
-		AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify, AccountIdConversion,
+		AccountIdLookup, BlakeTwo256, Block as BlockT, IdentifyAccount, Verify,
+		AccountIdConversion, Zero,
 	},
 	transaction_validity::{TransactionSource, TransactionValidity},
 	ApplyExtrinsicResult, MultiSignature, RuntimeAppPublic,
@@ -45,8 +46,9 @@
 	dispatch::DispatchResult,
 	PalletId, parameter_types, StorageValue, ConsensusEngineId,
 	traits::{
-		Everything, Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem,
-		LockIdentifier, OnUnbalanced, Randomness, FindAuthor,
+		tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Everything,
+		Currency, ExistenceRequirement, Get, IsInVec, KeyOwnerProofSystem, LockIdentifier,
+		OnUnbalanced, Randomness, FindAuthor,
 	},
 	weights::{
 		constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
@@ -69,8 +71,9 @@
 use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall};
 use fp_rpc::TransactionStatus;
 use sp_runtime::{
-	traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf},
+	traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating},
 	transaction_validity::TransactionValidityError,
+	SaturatedConversion,
 };
 
 // pub use pallet_timestamp::Call as TimestampCall;
@@ -82,23 +85,21 @@
 use xcm::v1::{BodyId, Junction::*, MultiLocation, NetworkId, Junctions::*};
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, CurrencyAdapter,
-	EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset,
-	ParentAsSuperuser, ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative,
-	SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
-	SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
+	EnsureXcmOrigin, FixedWeightBounds, LocationInverter, NativeAsset, ParentAsSuperuser,
+	ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
+	SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
 };
-use xcm_executor::{Config, XcmExecutor};
+use xcm_executor::{Config, XcmExecutor, Assets};
+use sp_std::{marker::PhantomData};
 
-use log::{debug};
-use sp_std::{borrow::Borrow, marker::PhantomData};
-
 use xcm::latest::{
-//	Xcm, 	
+	//	Xcm,
 	AssetId::{Concrete},
 	Fungibility::Fungible as XcmFungible,
-	MultiAsset
+	MultiAsset,
+	Error as XcmError,
 };
-use xcm_executor::traits::{ShouldExecute, WeightBounds, MatchesFungible, WeightTrader, Convert};
+use xcm_executor::traits::{MatchesFungible, WeightTrader};
 //use xcm_executor::traits::MatchesFungible;
 use sp_runtime::traits::CheckedConversion;
 
@@ -605,38 +606,7 @@
 	type ReservedXcmpWeight = ReservedXcmpWeight;
 	type XcmpMessageHandler = XcmpQueue;
 }
-
-pub struct SiblingParachainConvertsVia2<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
-impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId: Clone + core::fmt::Debug>
-	Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia2<ParaId, AccountId>
-{
-	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-
 
-
-		match location.borrow() {
-			MultiLocation { parents: 1, interior: X1(Parachain(id)) } => {
-				log::debug!(
-					target: "xcm::converter",
-					"SiblingParachainConvertsVia2 accountId: {:?}",
-					ParaId::from(*id).into_account(),
-				);
-				Ok(ParaId::from(*id).into_account())
-			}
-			_ => Err(()),
-		}
-	}
-
-	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
-		if let Some(id) = ParaId::try_from_account(who.borrow()) {
-			Ok(MultiLocation::new(1, X1(Parachain(id.into()))))
-		} else {
-			Err(())
-		}
-	}
-}
-
-
 impl parachain_info::Config for Runtime {}
 
 impl cumulus_pallet_aura_ext::Config for Runtime {}
@@ -655,18 +625,16 @@
 	// The parent (Relay-chain) origin converts to the default `AccountId`.
 	ParentIsDefault<AccountId>,
 	// Sibling parachain origins convert to AccountId via the `ParaId::into`.
-	SiblingParachainConvertsVia2<Sibling, AccountId>,
+	SiblingParachainConvertsVia<Sibling, AccountId>,
 	// Straight up local `AccountId32` origins just alias directly to `AccountId`.
 	AccountId32Aliases<RelayNetwork, AccountId>,
 );
-
 
 pub struct OnlySelfCurrency;
 impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {
 	fn matches_fungible(a: &MultiAsset) -> Option<B> {
 		match (&a.id, &a.fun) {
-			(Concrete(_), XcmFungible(ref amount)) =>
-				CheckedConversion::checked_from(*amount),
+			(Concrete(_), XcmFungible(ref amount)) => CheckedConversion::checked_from(*amount),
 			_ => None,
 		}
 	}
@@ -733,6 +701,88 @@
 	// ^^^ Parent & its unit plurality gets free execution
 );
 
+pub struct UsingOnlySelfCurrencyComponents<
+	WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+	AssetId: Get<MultiLocation>,
+	AccountId,
+	Currency: CurrencyT<AccountId>,
+	OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+>(
+	Weight,
+	Currency::Balance,
+	PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
+);
+impl<
+		WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+		AssetId: Get<MultiLocation>,
+		AccountId,
+		Currency: CurrencyT<AccountId>,
+		OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+	> WeightTrader
+	for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
+{
+	fn new() -> Self {
+		Self(0, Zero::zero(), PhantomData)
+	}
+
+	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, XcmError> {
+		let amount = WeightToFee::calc(&weight);
+		let u128_amount: u128 = amount.try_into().map_err(|_| XcmError::Overflow)?;
+
+		// location to this parachain through relay chain
+		let option1: xcm::v1::AssetId = Concrete(MultiLocation {
+			parents: 1,
+			interior: X1(Parachain(ParachainInfo::parachain_id().into())),
+		});
+		// direct location
+		let option2: xcm::v1::AssetId = Concrete(MultiLocation {
+			parents: 0,
+			interior: Here,
+		});
+
+		let required = if payment.fungible.contains_key(&option1) {
+			(option1, u128_amount).into()
+		} else if payment.fungible.contains_key(&option2) {
+			(option2, u128_amount).into()
+		} else {
+			(Concrete(MultiLocation::default()), u128_amount).into()
+		};
+
+		let unused = payment
+			.checked_sub(required)
+			.map_err(|_| XcmError::TooExpensive)?;
+		self.0 = self.0.saturating_add(weight);
+		self.1 = self.1.saturating_add(amount);
+		Ok(unused)
+	}
+
+	fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
+		let weight = weight.min(self.0);
+		let amount = WeightToFee::calc(&weight);
+		self.0 -= weight;
+		self.1 = self.1.saturating_sub(amount);
+		let amount: u128 = amount.saturated_into();
+		if amount > 0 {
+			Some((AssetId::get(), amount).into())
+		} else {
+			None
+		}
+	}
+}
+impl<
+		WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+		AssetId: Get<MultiLocation>,
+		AccountId,
+		Currency: CurrencyT<AccountId>,
+		OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+	> Drop
+	for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
+{
+	fn drop(&mut self) {
+		OnUnbalanced::on_unbalanced(Currency::issue(self.1));
+	}
+}
+
 pub struct XcmConfig;
 impl Config for XcmConfig {
 	type Call = Call;
@@ -745,7 +795,13 @@
 	type LocationInverter = LocationInverter<Ancestry>;
 	type Barrier = Barrier;
 	type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
-	type Trader = UsingComponents<IdentityFee<Balance>, RelayLocation, AccountId, Balances, ()>;
+	type Trader = UsingOnlySelfCurrencyComponents<
+		IdentityFee<Balance>,
+		RelayLocation,
+		AccountId,
+		Balances,
+		(),
+	>;
 	type ResponseHandler = (); // Don't handle responses for now.
 	type SubscriptionService = PolkadotXcm;