4

I am testing transferring ROC between Rococo and a Parachain. The HRMP channels are already open but when I submit try the following XCM Message: enter image description here The transfer returns no errors but the funds do not appear on the account on the parachain but goes to the SovereignAccount.

The current XCM configuration for the runtime is: (link to code: here)

        // Means for transacting assets on this chain.
    pub type LocalAssetTransactor = CurrencyAdapter<
        // Use this currency:
        Balances,
        // Use this currency when it is a fungible asset matching the given location or name:
        IsConcrete<SelfLocation>,
        // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID:
        LocationToAccountId,
        // Our chain's account ID type (we can't get away without mentioning it explicitly):
        AccountId,
        // We don't track any teleports.
        (),
    >;
    
    pub type TrustBackedAssetsConvertedConcreteId =
        assets_common::TrustBackedAssetsConvertedConcreteId<AssetsPalletLocation, Balance>;
    
    /// Means for transacting assets besides the native currency on this chain.
    pub type FungiblesTransactor = FungiblesAdapter<
        // Use this fungibles implementation:
        Assets,
        // Use the asset registry for lookups
        TrustBackedAssetsConvertedConcreteId,
        //ConvertedConcreteAssetId<AssetIdForTrustBackedAssets, Balance, AssetRegistry, JustTry>,
        // 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):
        AccountId,
        // We only want to allow teleports of known assets. We use non-zero issuance as an indication
        // that this asset is known.
        LocalMint<parachains_common::impls::NonZeroIssuance<AccountId, Assets>>,
        // The account to use for tracking teleports.
        CheckingAccount,
    >;
    pub type AssetTransactors = (LocalAssetTransactor, FungiblesTransactor);
    
    pub type Barrier = (
       TakeWeightCredit,
       AllowKnownQueryResponses<PolkadotXcm>,
       AllowTopLevelPaidExecutionFrom<Everything>,
       AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
       AllowSubscriptionsFrom<ParentOrSiblings>,
    );
    
    impl xcm_executor::Config for XcmConfig {
        type Aliasers = Nothing;
        type AssetClaims = PolkadotXcm;
        type AssetExchanger = ();
        type AssetLocker = ();
        type AssetTransactor = AssetTransactors;
        type AssetTrap = PolkadotXcm;
        type Barrier = Barrier;
        type CallDispatcher = RuntimeCall;
        type FeeManager = ();
        type IsReserve = NativeAsset;
        type IsTeleporter = (
            NativeAsset,
            // IsForeignConcreteAsset<FromSiblingParachain<parachain_info::Pallet<Runtime>>>,
        );
        type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
        type MessageExporter = ();
        type OriginConverter = XcmOriginToTransactDispatchOrigin;
        type PalletInstancesInfo = AllPalletsWithSystem;
        type ResponseHandler = PolkadotXcm;
        type RuntimeCall = RuntimeCall;
        type SafeCallFilter = Everything;
        type SubscriptionService = PolkadotXcm;
        type Trader = UsingComponents<WeightToFee, RelayLocation, AccountId, Balances, ()>;
        type UniversalAliases = Nothing;
        type UniversalLocation = UniversalLocation;
        type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
        type XcmSender = XcmRouter;
     }
    
    #[cfg(feature = "runtime-benchmarks")]
        parameter_types! {
        pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
    }
    
    impl pallet_xcm::Config for Runtime {
        type AdminOrigin = EnsureRoot<crate::AccountId>;
        // type AdminOrigin = EnsureRoot<AccountId>;
        type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
        type Currency = Balances;
        type CurrencyMatcher = ();
        // We support local origins dispatching XCM executions in principle...
        type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
        type MaxLockers = ConstU32<8>;
        type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
        // type MaxRemoteLockConsumers = ConstU32<0>;
        #[cfg(feature = "runtime-benchmarks")]
        type ReachableDest = ReachableDest;
        type RemoteLockConsumerIdentifier = ();
        // type RemoteLockConsumerIdentifier = ();
        type RuntimeCall = RuntimeCall;
        type RuntimeEvent = RuntimeEvent;
        type RuntimeOrigin = RuntimeOrigin;
        // We want to disallow users sending (arbitrary) XCMs from this chain.
        type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, ()>;
        type SovereignAccountOf = LocationToAccountId;
        type TrustedLockers = ();
        type UniversalLocation = UniversalLocation;
        type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
        // FIXME: Replace with benchmarked weight info
        type WeightInfo = pallet_xcm::TestWeightInfo;
        // ... but disallow generic XCM execution. As a result only teleports and reserve transfers are allowed.
        type XcmExecuteFilter = Nothing;
        type XcmExecutor = XcmExecutor<XcmConfig>;
        type XcmReserveTransferFilter = Everything;
        type XcmRouter = XcmRouter;
        type XcmTeleportFilter = Everything;
    
        const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
    }

Any guidance on how to resolve that?

2
  • Do you have pallet-assets implemented on your chain? Sep 14 at 15:40
  • Yes the chain supports pallet-assets!
    – chexware
    Sep 14 at 16:49

1 Answer 1

2

The transfer returns no errors but the funds do not appear on the account on the parachain but goes to the SovereignAccount.

It's right. Reserve transfer works like this.

  1. On Rococo: Transfer ROC to your parachain SovereignAccount.
  2. On Rococo: Send ReserveAssetDeposited(ROC) to your parachain.
  3. On your parachain: Execute ReserveAssetDeposited then add ROC to holding register.
  4. On your parachain: Deposit ROC (in holding) to Beneficiary account through Config::AssetTransactor::deposit_asset

Please Note that in step 4. the assetId of ROC is Multilocation(parents:1, Here). And you need to get your Config::AssetTransactor know the mapping from Multiocation(parents:1, Here) to the ID you registered in your parachain. Otherwise it will lead to MatchError::AssetNotHandled

So I think the Matcher in your FungiblesTransactor is wrong. Maybe it should be related to your AssetRegistry.

4
  • Could you explain :) ? Sep 18 at 10:18
  • I am getting the same result as before when specifying the beneficiary network.
    – chexware
    Sep 18 at 12:34
  • Please check the update.
    – Guantong
    Sep 19 at 5:35
  • 1
    @Guantong The Problem seems to be fixed after updating the FungiblesTranscator and AssetRegistry configurations then correctly registering ROC MultiLocation on the parachain.
    – chexware
    Sep 27 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.