Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
479a7d9
fix(bulletin-westend-runtime): xcm config
franciscoaguirre Jan 22, 2026
e3b1cb4
fix: fmt
franciscoaguirre Jan 22, 2026
e499015
chore: remove useless dispatch origin converter
franciscoaguirre Jan 22, 2026
b658dd6
Add TX_MODE_FINALIZED_BLOCK to authorizeAccount calls
bkontur Jan 22, 2026
f6a71a0
Apply suggestions from code review
bkontur Jan 22, 2026
904fd43
Merge branch 'main' into review-xcm-config
franciscoaguirre Jan 23, 2026
fc43713
changing para id to 2487 as per PR#195 comment (#198)
rosarp Jan 23, 2026
f961316
test: add integration-tests for bulletin XCMs
franciscoaguirre Jan 23, 2026
80f8b91
chore(bulletin-westend-integration-tests): use sender and receiver in…
franciscoaguirre Jan 23, 2026
c138293
chore: remove useless comments
franciscoaguirre Jan 23, 2026
c582fa1
fix: bulletin's para id changed
franciscoaguirre Jan 23, 2026
f13afd9
Merge branch 'main' into review-xcm-config
franciscoaguirre Jan 23, 2026
b745fec
fix: taplo
franciscoaguirre Jan 23, 2026
59e3b59
chore: set MAX_ASSETS to 5
franciscoaguirre Jan 23, 2026
7cc8a6e
fix: correct feature propagation for integration tests
franciscoaguirre Jan 23, 2026
bfde790
chore: remove random picture
franciscoaguirre Jan 24, 2026
19fa43e
fix: zepter
franciscoaguirre Jan 24, 2026
c60ec05
fix: taplo
franciscoaguirre Jan 24, 2026
27a7361
chore: some tweaks
franciscoaguirre Jan 24, 2026
5cffca8
fix: clippy
franciscoaguirre Jan 24, 2026
793a76e
chore: benchmark pallet_xcm_benchmarks::fungible
franciscoaguirre Jan 24, 2026
1e3d040
Add bulletin-westend-integration-tests to the CI
bkontur Jan 25, 2026
33176fb
Removed unused deps
bkontur Jan 25, 2026
563b876
ci: Enable WASM build for XCM integration tests
bkontur Jan 25, 2026
37e139c
fix: add westend-runtime back for proper feature propagation
franciscoaguirre Jan 25, 2026
d62c6ee
Revert back
bkontur Jan 25, 2026
f368b2c
fix unset SKIP_WASM_BUILD?
bkontur Jan 25, 2026
2e2cdf5
Revert of revert
bkontur Jan 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,6 @@ docker exec -it ipfs-node ipfs swarm connect /ip4/172.17.0.1/tcp/12347/ws/p2p/12

#### Example for Simple Authorizing and Store

##### Using Legacy @polkadot/api (PJS)
```
cd examples
npm install

node authorize_and_store.js
```

##### Using Modern PAPI (Polkadot API)
```bash
Expand Down
84 changes: 0 additions & 84 deletions examples/authorize_and_store.js

This file was deleted.

3 changes: 2 additions & 1 deletion examples/authorize_and_store_papi.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import assert from "assert";
import { createClient } from 'polkadot-api';
import { getWsProvider } from 'polkadot-api/ws-provider';
import { cryptoWaitReady } from '@polkadot/util-crypto';
import { authorizeAccount, fetchCid, store} from './api.js';
import { authorizeAccount, fetchCid, store, TX_MODE_FINALIZED_BLOCK } from './api.js';
import { setupKeyringAndSigners } from './common.js';
import { cidFromBytes } from "./cid_dag_metadata.js";
import { bulletin } from './.papi/descriptors/dist/index.mjs';
Expand Down Expand Up @@ -39,6 +39,7 @@ async function main() {
whoAddress,
100,
BigInt(100 * 1024 * 1024), // 100 MiB
TX_MODE_FINALIZED_BLOCK,
);

// Store data.
Expand Down
3 changes: 2 additions & 1 deletion examples/store_big_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import fs from 'fs'
import os from "os";
import path from "path";
import assert from "assert";
import {authorizeAccount, store, } from "./api.js";
import { authorizeAccount, store, TX_MODE_FINALIZED_BLOCK } from "./api.js";
import {cidFromBytes} from "./cid_dag_metadata.js";
import {
setupKeyringAndSigners,
Expand Down Expand Up @@ -166,6 +166,7 @@ async function main() {
signers.map(a => a.address),
100,
BigInt(100 * 1024 * 1024), // 100 MiB
TX_MODE_FINALIZED_BLOCK,
);

// Start 8 workers
Expand Down
51 changes: 36 additions & 15 deletions runtimes/bulletin-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ use sp_version::RuntimeVersion;
use testnet_parachains_constants::westend::{consensus::*, currency::*, fee::WeightToFee, time::*};
use weights::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight};
use xcm::{prelude::*, Version as XcmVersion};
#[cfg(feature = "runtime-benchmarks")]
use xcm_config::AssetHubLocation;
use xcm_config::{
FellowshipLocation, GovernanceLocation, TokenRelayLocation, XcmOriginToTransactDispatchOrigin,
};
Expand Down Expand Up @@ -964,7 +966,12 @@ impl_runtime_apis! {
}

fn teleportable_asset_and_dest() -> Option<(Asset, Location)> {
// Relay/native token can be teleported between AH and Relay.
// Non-system parachains do not support teleports.
None
}

fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
// Non-system parachains use reserve transfers for DOT from Asset Hub.
Some((
Asset {
fun: Fungible(ExistentialDeposit::get()),
Expand All @@ -974,18 +981,32 @@ impl_runtime_apis! {
))
}

fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
None
}

fn set_up_complex_asset_transfer() -> Option<(Assets, u32, Location, alloc::boxed::Box<dyn FnOnce()>)> {
let native_location = Parent.into();
let dest = Parent.into();

pallet_xcm::benchmarking::helpers::native_teleport_as_asset_transfer::<Runtime>(
native_location,
dest,
)
// Bulletin-westend is a non-system parachain that uses reserve transfers for the relay token.
// We set up a reserve transfer of the native token (relay token) to AssetHub.
use frame_support::traits::fungible::{Inspect, Mutate};

let dest = AssetHubLocation::get();
let fee_amount: Balance = ExistentialDeposit::get();
let fee_asset: Asset = (Location::parent(), fee_amount).into();

let who = frame_benchmarking::whitelisted_caller();
// Give some multiple of the existential deposit
let balance: Balance = fee_amount + ExistentialDeposit::get() * 1000;
let _ = <Balances as Mutate<_>>::mint_into(&who, balance);
// verify initial balance
assert_eq!(<Balances as Inspect<_>>::balance(&who), balance);

let assets: Assets = vec![fee_asset.clone()].into();
let fee_index = 0u32;

// verify transferred successfully
let verify = alloc::boxed::Box::new(move || {
// verify balance after transfer, decreased by transferred amount
// (plus transport/remote fees)
assert!(<Balances as Inspect<_>>::balance(&who) <= balance - fee_amount);
});
Some((assets, fee_index, dest, verify))
}

fn get_asset() -> Asset {
Expand Down Expand Up @@ -1038,12 +1059,12 @@ impl_runtime_apis! {
}

parameter_types! {
pub const TrustedTeleporter: Option<(Location, Asset)> = Some((
pub const TrustedTeleporter: Option<(Location, Asset)> = None;
pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
pub const TrustedReserve: Option<(Location, Asset)> = Some((
TokenRelayLocation::get(),
Asset { fun: Fungible(UNITS), id: AssetId(TokenRelayLocation::get()) },
));
pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
pub const TrustedReserve: Option<(Location, Asset)> = None;
}

impl pallet_xcm_benchmarks::fungible::Config for Runtime {
Expand Down
55 changes: 39 additions & 16 deletions runtimes/bulletin-westend/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use pallet_xcm::{AuthorizedAliasers, XcmPassthrough};
use parachains_common::{
xcm_config::{
AliasAccountId32FromSiblingSystemChain, AllSiblingSystemParachains,
ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains,
ParentRelayOrSiblingParachains, RelayOrOtherSystemParachains,
},
TREASURY_PALLET_ID,
};
Expand All @@ -47,8 +47,8 @@ use xcm_builder::{
AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
DenyRecursively, DenyReserveTransferToRelayChain, DenyThenTry, DescribeAllTerminal,
DescribeFamily, EnsureXcmOrigin, FrameTransactionalProcessor, FungibleAdapter,
HashedDescription, IsConcrete, LocationAsSuperuser, ParentAsSuperuser, ParentIsPreset,
RelayChainAsNative, SendXcmFeeToAccount, SiblingParachainAsNative, SiblingParachainConvertsVia,
HashedDescription, IsConcrete, LocationAsSuperuser, ParentIsPreset, RelayChainAsNative,
SendXcmFeeToAccount, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
XcmFeeManagerFromComponents,
Expand Down Expand Up @@ -119,9 +119,6 @@ pub type XcmOriginToTransactDispatchOrigin = (
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
// recognized.
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
// transaction from the Root origin.
ParentAsSuperuser<RuntimeOrigin>,
// Native signed account converter; this just converts an `AccountId32` origin into a normal
// `RuntimeOrigin::Signed` origin of the same 32-byte value.
SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
Expand Down Expand Up @@ -159,14 +156,15 @@ pub type Barrier = TrailingSetTopicAsId<
// If the message is one that immediately attempts to pay for execution, then
// allow it.
AllowTopLevelPaidExecutionFrom<Everything>,
// Parent, its pluralities (i.e. governance bodies), and the Fellows plurality
// get free execution.
// Parent, its pluralities (i.e. governance bodies), Fellows plurality,
// and AssetHub get free execution.
AllowExplicitUnpaidExecutionFrom<(
ParentOrParentsPlurality,
FellowsPlurality,
Equals<GovernanceLocation>,
// Let's allow a People chain for PoP authorizations.
Equals<PeopleLocation>,
Equals<AssetHubLocation>,
)>,
// Subscriptions for version tracking are OK.
AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
Expand All @@ -191,11 +189,36 @@ pub type WaivedLocations = (
Equals<RootLocation>,
RelayOrOtherSystemParachains<AllSiblingSystemParachains, Runtime>,
Equals<RelayTreasuryLocation>,
Equals<AssetHubLocation>,
);

/// Cases where a remote origin is accepted as trusted Teleporter for a given asset:
/// - WND with the parent Relay Chain and sibling parachains.
pub type TrustedTeleporters = ConcreteAssetFromSystem<TokenRelayLocation>;
/// Helper type to match DOT (relay native token) from Asset Hub.
/// Non-system parachains should trust Asset Hub as the reserve location for DOT.
pub struct IsDotFrom<Origin>(core::marker::PhantomData<Origin>);
impl<Origin> frame_support::traits::ContainsPair<Asset, Location> for IsDotFrom<Origin>
where
Origin: frame_support::traits::Get<Location>,
{
fn contains(asset: &Asset, origin: &Location) -> bool {
let loc = Origin::get();
&loc == origin &&
matches!(
asset,
Asset {
id: AssetId(asset_id_location),
fun: Fungible(_),
} if *asset_id_location == TokenRelayLocation::get()
)
}
}

/// Reserve locations for assets.
/// Non-system parachains should trust Asset Hub as the reserve for relay chain native token (DOT).
pub type Reserves = IsDotFrom<AssetHubLocation>;

/// Cases where a remote origin is accepted as trusted Teleporter for a given asset.
/// Non-system parachains should not accept teleports, use reserve transfers instead.
pub type TrustedTeleporters = ();

/// Defines origin aliasing rules for this chain.
///
Expand All @@ -217,10 +240,10 @@ impl xcm_executor::Config for XcmConfig {
type XcmEventEmitter = PolkadotXcm;
type AssetTransactor = AssetTransactors;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
// Bulletin chain does not recognize a reserve location for any asset. Users must teleport ROC
// where allowed (e.g. with the Relay Chain).
type IsReserve = ();
type IsTeleporter = TrustedTeleporters;
// As a non-system parachain, Bulletin accepts DOT reserve transfers from Asset Hub.
// Teleports are not supported.
type IsReserve = Reserves;
type IsTeleporter = ();
type UniversalLocation = UniversalLocation;
type Barrier = Barrier;
type Weigher = WeightInfoBounds<
Expand Down Expand Up @@ -290,7 +313,7 @@ impl pallet_xcm::Config for Runtime {
type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type XcmExecuteFilter = Everything;
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmTeleportFilter = Everything;
type XcmTeleportFilter = Nothing;
type XcmReserveTransferFilter = Everything;
type Weigher = WeightInfoBounds<
crate::weights::xcm::BulletinWestendXcmWeight<RuntimeCall>,
Expand Down
15 changes: 9 additions & 6 deletions runtimes/bulletin-westend/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,13 +454,16 @@ fn governance_authorize_upgrade_works() {
Either::Right(InstructionError { index: 2, error: XcmError::BadOrigin })
);

// ok - relaychain
assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
Runtime,
RuntimeOrigin,
>(GovernanceOrigin::Location(Location::parent())));
// no - relaychain (relay chain does not have superuser access, only AssetHub does)
assert_err!(
parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
Runtime,
RuntimeOrigin,
>(GovernanceOrigin::Location(Location::parent())),
Either::Right(InstructionError { index: 1, error: XcmError::BadOrigin })
);

// ok - governance location
// ok - governance location (which is AssetHub)
assert_ok!(parachains_runtimes_test_utils::test_cases::can_governance_authorize_upgrade::<
Runtime,
RuntimeOrigin,
Expand Down
Loading