Skip to content

Added Asset Hub as relay chain token reserve in Filter#1497

Merged
PierreOssun merged 7 commits intomasterfrom
feat/migration-AH
Jul 16, 2025
Merged

Added Asset Hub as relay chain token reserve in Filter#1497
PierreOssun merged 7 commits intomasterfrom
feat/migration-AH

Conversation

@PierreOssun
Copy link
Contributor

@PierreOssun PierreOssun commented Jul 2, 2025

Pull Request Summary

Added Asset Hub as relay chain token reserve in Filter without removing Relay chain as reserve. Both reserved are accepted from DOT/KSM

@PierreOssun PierreOssun added astar Related to Astar shiden related to shiden runtime shibuya related to shibuya and removed shiden related to shiden runtime labels Jul 2, 2025
@PierreOssun PierreOssun added the shiden related to shiden runtime label Jul 2, 2025
@Dinonard Dinonard added the runtime This PR/Issue is related to the topic “runtime”. label Jul 2, 2025
Copy link
Contributor

@Dinonard Dinonard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this looks good.

Before merge we should:

  • understand how it impacts sovereign account on Shiden/Astar
  • test it using chopsticks

We can also ask about this in the recommended element chat.

type AssetTransactor = AssetTransactors;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = ReserveAssetFilter;
type IsReserve = Reserves;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be only for polkadot network

Copy link
Contributor

@ipapandinas ipapandinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to Chopsticks, we should adjust e2e tests and probably fungible_assets from xcm-simulator-tests to test it.

@ermalkaleci
Copy link
Contributor

In addition to Chopsticks, we should adjust e2e tests and probably fungible_assets from xcm-simulator-tests to test it.

e2e-tests will still work until migration happens. What we need is more e2e tests to cover new route (XCM)

@PierreOssun PierreOssun changed the title Added Asset Hub as relay chain token reserve in Filter [Do not merge] Added Asset Hub as relay chain token reserve in Filter Jul 7, 2025
@PierreOssun PierreOssun changed the title [Do not merge] Added Asset Hub as relay chain token reserve in Filter Added Asset Hub as relay chain token reserve in Filter Jul 7, 2025
Copy link
Contributor

@Dinonard Dinonard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made a suggestion how to simplify the test to avoid hacky usage of ParaC.

Comment on lines +1035 to +1060
// On parachain C create an asset which represents a derivative of relay native asset.
// This asset is allowed as an XCM execution fee payment asset.
ParaC::execute_with(|| {
assert_ok!(register_and_setup_xcm_asset::<parachain::Runtime, _>(
parachain::RuntimeOrigin::root(),
relay_asset_id,
source_location.clone(),
parent_account_id(),
Some(true),
Some(1),
Some(1_000_000_000_000)
));
});

// Transfer some relay chain assets to Alice on Parachain C
let from_relay_amount: u128 = 100_000_000_000_000u128;
Relay::execute_with(|| {
assert_ok!(RelayChainPalletXcm::limited_reserve_transfer_assets(
relay_chain::RuntimeOrigin::signed(ALICE),
Box::new(Parachain(1000).into()),
Box::new(alice.into()),
Box::new((Here, from_relay_amount).into()),
0,
Unlimited,
));
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't wrong but it's hacky.
We don't really need to test this - i.e. what happens on AssetHub.

What I'd suggest to do is just send an XCM sequence from ParaC to ParaA and verify it can receive relay asset from it, using ParaC as reserve.


Something like:

ParaC::execute_with( | | {
    ParachainPalletXcm::send(....);
  }
);

No need to assert anything on ParaC side, just on ParaA.

Copy link
Contributor Author

@PierreOssun PierreOssun Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the suggestion, but on Impl details:
How can I send relay asset C -> A if:

  • relay asset is not registered in C
  • Alice has no balance of relay asset in C

This part of the code is the Arrange part of the test, and the C -> A transfer the Act.
Asserting para C sovereign account is ensuring it's using C as reserve and not going back to the relay and sitting in the relay sovereign account, so it's relevant

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now you are constructing a message that uses local execution to execute TransferReserveAsset.
Instead, you can send send an XCM sequence from C to A that will instruct ParaA to mint some new tokens and deposit them to whoever.

You can check how the aforementioned command is handled in polkadot-sdk code:

TransferReserveAsset { mut assets, dest, xcm } => {
Config::TransactionalProcessor::process(|| {
	let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?;
	// Take `assets` from the origin account (on-chain) and place into dest account.
	for asset in assets.inner() {
		Config::AssetTransactor::transfer_asset(
			asset,
			origin,
			&dest,
			&self.context,
		)?;
	}
	let reanchor_context = Config::UniversalLocation::get();
	assets
		.reanchor(&dest, &reanchor_context)
		.map_err(|()| XcmError::LocationFull)?;
	let mut message = vec![ReserveAssetDeposited(assets), ClearOrigin];
	message.extend(xcm.0.into_iter());
	self.send(dest, Xcm(message), FeeReason::TransferReserveAsset)?;
	Ok(())
})
},

Based on this, you can prepare a sequence using ReserveAssetDeposited, ClearOrigin, BuyExecution, DepositAsset and that's it. Use .send(...) to directly send an XCM message.

What you want to verify is that ParaA can accept ParaC as reserve, and that we can return funds back to it.
Everything else is redundant.


For ParaC/Relay sovereign accounts check, it's not wrong but it's redundant.
The only thing we should care about is the status on ParaA (which is Astar/Shiden).
We trust that relay chain & AssetHub handle their side correctly - not something we need to test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyways, I'm not making this as a request for change, just want to emphasize that we need to test how ParaA behaves. Everything else is basically redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried your suggestion:

    let to_para_a_amount = 10_000_000_000_000u128;
    ParaC::execute_with(|| {
        let dest = Location::new(1, [Parachain(1)]);
        let beneficiary = Location::new(0, [alice.into()]);
        
        let assets = Assets::from(Asset {
            id: AssetId(Location::new(1, Here)),
            fun: Fungible(to_para_a_amount),
        });

        let message = Xcm(vec![
            ReserveAssetDeposited(assets.clone()),
            ClearOrigin,
            BuyExecution {
                fees: Asset {
                    id: AssetId(Location::new(1, Here)),
                    fun: Fungible(to_para_a_amount),
                },
                weight_limit: Unlimited,
            },
            DepositAsset {
                assets: Wild(AllCounted(1)),
                beneficiary,
            },
        ]);
        
        assert_ok!(ParachainPalletXcm::send(
            parachain::RuntimeOrigin::signed(ALICE),
            Box::new(dest.into()),
            Box::new(VersionedXcm::from(message)),
        ));
    });

but it's not passing the filter. I got this error:
Incomplete XCMP handling: UntrustedReserveLocation, 1000

When logging in Reserves check:

ReserveAssetFilter::contains origin: Location { parents: 1, interior: X2([Parachain(1000), AccountId32 { network: Some(Kusama), id: [250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250] }]) }, asset: Asset { id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(10000000000000) }
ReserveAssetFilter::contains result: false

DotFromAssetHub::contains origin: Location { parents: 1, interior: X2([Parachain(1000), AccountId32 { network: Some(Kusama), id: [250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250] }]) }, asset: Asset { id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(10000000000000) }
DotFromAssetHub::contains result: false

But with my actual test, using TransferReserveAsset with execute from ParaC, it works at intended:

ReserveAssetFilter::contains origin: Location { parents: 1, interior: X1([Parachain(1000)]) }, asset: Asset { id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(10000000000000) }
ReserveAssetFilter: bool false, 
DotFromAssetHub::contains origin: Location { parents: 1, interior: X1([Parachain(1000)]) }, asset: Asset { id: AssetId(Location { parents: 1, interior: Here }), fun: Fungible(10000000000000) }
DotFromAssetHub: bool true, 

Copy link
Contributor

@Dinonard Dinonard Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to execute the send with root as the origin.

EDIT: What I suggested should work unless the XCM message gets some additional modification in send.
According to your post, there's an additiional Account32 component in the filter, which I assume comes from the fact that somewhere DescendOrigin(account) gets inserted.

It's expected for such message to be rejected by ParaA since we cannot just trust some random account to tell us that they've reserved funds on the ParaC side. E.g. if that was the case, I'd just go to Polkadot, prepare the message as you did now, and tell Astar that I want to deposit 10000000 DOTs into my account.

Copy link
Contributor Author

@PierreOssun PierreOssun Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to execute the send with root as the origin.

Worked !

So I pushed like this and removed redundant checks

@github-actions
Copy link

Code Coverage

Package Line Rate Branch Rate Health
pallets/dapp-staking/rpc/runtime-api/src 0% 0%
chain-extensions/unified-accounts/src 0% 0%
precompiles/dapp-staking/src/test 0% 0%
precompiles/xcm/src 69% 0%
primitives/src/xcm 64% 0%
precompiles/assets-erc20/src 77% 0%
chain-extensions/pallet-assets/src 54% 0%
pallets/xc-asset-config/src 62% 0%
pallets/astar-xcm-benchmarks/src/fungible 100% 0%
pallets/democracy-mbm/src 30% 0%
pallets/dapp-staking/src 80% 0%
precompiles/substrate-ecdsa/src 67% 0%
pallets/dynamic-evm-base-fee/src 85% 0%
pallets/price-aggregator/src 75% 0%
pallets/collective-proxy/src 94% 0%
pallets/unified-accounts/src 80% 0%
pallets/ethereum-checked/src 76% 0%
pallets/dapp-staking/src/test 0% 0%
pallets/inflation/src 84% 0%
chain-extensions/types/assets/src 0% 0%
precompiles/dapp-staking/src 89% 0%
pallets/dapp-staking/src/benchmarking 95% 0%
primitives/src 54% 0%
pallets/vesting-mbm/src 87% 0%
pallets/astar-xcm-benchmarks/src/generic 100% 0%
precompiles/dispatch-lockdrop/src 83% 0%
pallets/static-price-provider/src 91% 0%
pallets/collator-selection/src 87% 0%
chain-extensions/types/unified-accounts/src 0% 0%
precompiles/sr25519/src 56% 0%
pallets/astar-xcm-benchmarks/src 86% 0%
precompiles/unified-accounts/src 100% 0%
Summary 74% (3753 / 5077) 0% (0 / 0)

Minimum allowed line rate is 50%

Copy link
Contributor

@ipapandinas ipapandinas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice simplification in the test scenario - LGTM

@PierreOssun PierreOssun merged commit fa181c4 into master Jul 16, 2025
8 checks passed
@PierreOssun PierreOssun deleted the feat/migration-AH branch July 16, 2025 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

astar Related to Astar runtime This PR/Issue is related to the topic “runtime”. shibuya related to shibuya shiden related to shiden runtime

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants