Files
pezkuwi-subxt/cumulus/parachains/integration-tests/emulated/common/src/lib.rs
T
Muharem cb944dc548 Treasury spends various asset kinds (#1333)
### Summary 

This PR introduces new dispatchables to the treasury pallet, allowing
spends of various asset types. The enhanced features of the treasury
pallet, in conjunction with the asset-rate pallet, are set up and
enabled for Westend and Rococo.

### Westend and Rococo runtimes.

Polkadot/Kusams/Rococo Treasury can accept proposals for `spends` of
various asset kinds by specifying the asset's location and ID.

#### Treasury Instance New Dispatchables:
- `spend(AssetKind, AssetBalance, Beneficiary, Option<ValidFrom>)` -
propose and approve a spend;
- `payout(SpendIndex)` - payout an approved spend or retry a failed
payout
- `check_payment(SpendIndex)` - check the status of a payout;
- `void_spend(SpendIndex)` - void previously approved spend;
> existing spend dispatchable renamed to spend_local

in this context, the `AssetKind` parameter contains the asset's location
and it's corresponding `asset_id`, for example:
`USDT` on `AssetHub`,
``` rust
location = MultiLocation(0, X1(Parachain(1000)))
asset_id = MultiLocation(0, X2(PalletInstance(50), GeneralIndex(1984)))
```

the `Beneficiary` parameter is a `MultiLocation` in the context of the
asset's location, for example
``` rust
// the Fellowship salary pallet's location / account
FellowshipSalaryPallet = MultiLocation(1, X2(Parachain(1001), PalletInstance(64)))
// or custom `AccountId`
Alice = MultiLocation(0, AccountId32(network: None, id: [1,...]))
```

the `AssetBalance` represents the amount of the `AssetKind` to be
transferred to the `Beneficiary`. For permission checks, the asset
amount is converted to the native amount and compared against the
maximum spendable amount determined by the commanding spend origin.

the `spend` dispatchable allows for batching spends with different
`ValidFrom` arguments, enabling milestone-based spending. If the
expectations tied to an approved spend are not met, it is possible to
void the spend later using the `void_spend` dispatchable.

Asset Rate Pallet provides the conversion rate from the `AssetKind` to
the native balance.

#### Asset Rate Instance Dispatchables:
- `create(AssetKind, Rate)` - initialize a conversion rate to the native
balance for the given asset
- `update(AssetKind, Rate)` - update the conversion rate to the native
balance for the given asset
- `remove(AssetKind)` - remove an existing conversion rate to the native
balance for the given asset

the pallet's dispatchables can be executed by the Root or Treasurer
origins.

### Treasury Pallet

Treasury Pallet can accept proposals for `spends` of various asset kinds
and pay them out through the implementation of the `Pay` trait.

New Dispatchables:
- `spend(Config::AssetKind, AssetBalance, Config::Beneficiary,
Option<ValidFrom>)` - propose and approve a spend;
- `payout(SpendIndex)` - payout an approved spend or retry a failed
payout;
- `check_payment(SpendIndex)` - check the status of a payout;
- `void_spend(SpendIndex)` - void previously approved spend;
> existing spend dispatchable renamed to spend_local

The parameters' types of the `spend` dispatchable exposed via the
pallet's `Config` and allows to propose and accept a spend of a certain
amount.

An approved spend can be claimed via the `payout` within the
`Config::SpendPeriod`. Clients provide an implementation of the `Pay`
trait which can pay an asset of the `AssetKind` to the `Beneficiary` in
`AssetBalance` units.

The implementation of the Pay trait might not have an immediate final
payment status, for example if implemented over `XCM` and the actual
transfer happens on a remote chain.

The `check_status` dispatchable can be executed to update the spend's
payment state and retry the `payout` if the payment has failed.

---------

Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
Co-authored-by: command-bot <>
2023-10-07 19:32:35 +02:00

306 lines
9.2 KiB
Rust

// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
pub mod constants;
pub mod impls;
pub mod xcm_helpers;
use constants::{
accounts::{ALICE, BOB},
asset_hub_rococo, asset_hub_westend, bridge_hub_rococo, penpal, rococo, westend,
};
use impls::{RococoWococoMessageHandler, WococoRococoMessageHandler};
// Substrate
use frame_support::traits::OnInitialize;
// Cumulus
use xcm_emulator::{
decl_test_bridges, decl_test_networks, decl_test_parachains, decl_test_relay_chains,
decl_test_sender_receiver_accounts_parameter_types, DefaultMessageProcessor,
};
decl_test_relay_chains! {
#[api_version(7)]
pub struct Westend {
genesis = westend::genesis(),
on_init = (),
runtime = westend_runtime,
core = {
MessageProcessor: DefaultMessageProcessor<Westend>,
SovereignAccountOf: westend_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
},
pallets = {
XcmPallet: westend_runtime::XcmPallet,
Sudo: westend_runtime::Sudo,
Balances: westend_runtime::Balances,
Treasury: westend_runtime::Treasury,
AssetRate: westend_runtime::AssetRate,
}
},
#[api_version(7)]
pub struct Rococo {
genesis = rococo::genesis(),
on_init = (),
runtime = rococo_runtime,
core = {
MessageProcessor: DefaultMessageProcessor<Rococo>,
SovereignAccountOf: rococo_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
},
pallets = {
XcmPallet: rococo_runtime::XcmPallet,
Sudo: rococo_runtime::Sudo,
Balances: rococo_runtime::Balances,
}
},
#[api_version(7)]
pub struct Wococo {
genesis = rococo::genesis(),
on_init = (),
runtime = rococo_runtime,
core = {
MessageProcessor: DefaultMessageProcessor<Wococo>,
SovereignAccountOf: rococo_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
},
pallets = {
XcmPallet: rococo_runtime::XcmPallet,
Sudo: rococo_runtime::Sudo,
Balances: rococo_runtime::Balances,
}
}
}
decl_test_parachains! {
// Westend Parachains
pub struct AssetHubWestend {
genesis = asset_hub_westend::genesis(),
on_init = {
asset_hub_westend_runtime::AuraExt::on_initialize(1);
},
runtime = asset_hub_westend_runtime,
core = {
XcmpMessageHandler: asset_hub_westend_runtime::XcmpQueue,
DmpMessageHandler: asset_hub_westend_runtime::DmpQueue,
LocationToAccountId: asset_hub_westend_runtime::xcm_config::LocationToAccountId,
ParachainInfo: asset_hub_westend_runtime::ParachainInfo,
},
pallets = {
PolkadotXcm: asset_hub_westend_runtime::PolkadotXcm,
Balances: asset_hub_westend_runtime::Balances,
Assets: asset_hub_westend_runtime::Assets,
ForeignAssets: asset_hub_westend_runtime::ForeignAssets,
PoolAssets: asset_hub_westend_runtime::PoolAssets,
AssetConversion: asset_hub_westend_runtime::AssetConversion,
}
},
pub struct PenpalWestendA {
genesis = penpal::genesis(penpal::PARA_ID_A),
on_init = {
penpal_runtime::AuraExt::on_initialize(1);
},
runtime = penpal_runtime,
core = {
XcmpMessageHandler: penpal_runtime::XcmpQueue,
DmpMessageHandler: penpal_runtime::DmpQueue,
LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId,
ParachainInfo: penpal_runtime::ParachainInfo,
},
pallets = {
PolkadotXcm: penpal_runtime::PolkadotXcm,
Assets: penpal_runtime::Assets,
}
},
// Rococo Parachains
pub struct BridgeHubRococo {
genesis = bridge_hub_rococo::genesis(),
on_init = {
bridge_hub_rococo_runtime::AuraExt::on_initialize(1);
},
runtime = bridge_hub_rococo_runtime,
core = {
XcmpMessageHandler: bridge_hub_rococo_runtime::XcmpQueue,
DmpMessageHandler: bridge_hub_rococo_runtime::DmpQueue,
LocationToAccountId: bridge_hub_rococo_runtime::xcm_config::LocationToAccountId,
ParachainInfo: bridge_hub_rococo_runtime::ParachainInfo,
},
pallets = {
PolkadotXcm: bridge_hub_rococo_runtime::PolkadotXcm,
Balances: bridge_hub_rococo_runtime::Balances,
}
},
// AssetHubRococo (aka Rockmine/Rockmine2) mirrors AssetHubKusama
pub struct AssetHubRococo {
genesis = asset_hub_rococo::genesis(),
on_init = {
asset_hub_polkadot_runtime::AuraExt::on_initialize(1);
},
runtime = asset_hub_kusama_runtime,
core = {
XcmpMessageHandler: asset_hub_kusama_runtime::XcmpQueue,
DmpMessageHandler: asset_hub_kusama_runtime::DmpQueue,
LocationToAccountId: asset_hub_kusama_runtime::xcm_config::LocationToAccountId,
ParachainInfo: asset_hub_kusama_runtime::ParachainInfo,
},
pallets = {
PolkadotXcm: asset_hub_kusama_runtime::PolkadotXcm,
Assets: asset_hub_kusama_runtime::Assets,
}
},
// Wococo Parachains
pub struct BridgeHubWococo {
genesis = bridge_hub_rococo::genesis(),
on_init = {
bridge_hub_rococo_runtime::AuraExt::on_initialize(1);
},
runtime = bridge_hub_rococo_runtime,
core = {
XcmpMessageHandler: bridge_hub_rococo_runtime::XcmpQueue,
DmpMessageHandler: bridge_hub_rococo_runtime::DmpQueue,
LocationToAccountId: bridge_hub_rococo_runtime::xcm_config::LocationToAccountId,
ParachainInfo: bridge_hub_rococo_runtime::ParachainInfo,
},
pallets = {
PolkadotXcm: bridge_hub_rococo_runtime::PolkadotXcm,
}
},
pub struct AssetHubWococo {
genesis = asset_hub_westend::genesis(),
on_init = {
asset_hub_polkadot_runtime::AuraExt::on_initialize(1);
},
runtime = asset_hub_polkadot_runtime,
core = {
XcmpMessageHandler: asset_hub_polkadot_runtime::XcmpQueue,
DmpMessageHandler: asset_hub_polkadot_runtime::DmpQueue,
LocationToAccountId: asset_hub_polkadot_runtime::xcm_config::LocationToAccountId,
ParachainInfo: asset_hub_polkadot_runtime::ParachainInfo,
},
pallets = {
PolkadotXcm: asset_hub_polkadot_runtime::PolkadotXcm,
Assets: asset_hub_polkadot_runtime::Assets,
}
},
pub struct PenpalRococoA {
genesis = penpal::genesis(penpal::PARA_ID_A),
on_init = {
penpal_runtime::AuraExt::on_initialize(1);
},
runtime = penpal_runtime,
core = {
XcmpMessageHandler: penpal_runtime::XcmpQueue,
DmpMessageHandler: penpal_runtime::DmpQueue,
LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId,
ParachainInfo: penpal_runtime::ParachainInfo,
},
pallets = {
PolkadotXcm: penpal_runtime::PolkadotXcm,
Assets: penpal_runtime::Assets,
}
}
}
decl_test_networks! {
pub struct WestendMockNet {
relay_chain = Westend,
parachains = vec![
AssetHubWestend,
PenpalWestendA,
],
bridge = ()
},
pub struct RococoMockNet {
relay_chain = Rococo,
parachains = vec![
AssetHubRococo,
BridgeHubRococo,
PenpalRococoA,
],
bridge = RococoWococoMockBridge
},
pub struct WococoMockNet {
relay_chain = Wococo,
parachains = vec![
AssetHubWococo,
BridgeHubWococo,
],
bridge = WococoRococoMockBridge
}
}
decl_test_bridges! {
pub struct RococoWococoMockBridge {
source = BridgeHubRococo,
target = BridgeHubWococo,
handler = RococoWococoMessageHandler
},
pub struct WococoRococoMockBridge {
source = BridgeHubWococo,
target = BridgeHubRococo,
handler = WococoRococoMessageHandler
}
// TODO: uncomment when https://github.com/paritytech/polkadot-sdk/pull/1352 is merged
// pub struct PolkadotKusamaMockBridge {
// source = BridgeHubPolkadot,
// target = BridgeHubKusama,
// handler = PolkadotKusamaMessageHandler
// },
// pub struct KusamaPolkadotMockBridge {
// source = BridgeHubKusama,
// target = BridgeHubPolkadot,
// handler = KusamaPolkadotMessageHandler
// }
}
// Westend implementation
impl_accounts_helpers_for_relay_chain!(Westend);
impl_assert_events_helpers_for_relay_chain!(Westend);
// Rococo implementation
impl_accounts_helpers_for_relay_chain!(Rococo);
impl_assert_events_helpers_for_relay_chain!(Rococo);
// Wococo implementation
impl_accounts_helpers_for_relay_chain!(Wococo);
impl_assert_events_helpers_for_relay_chain!(Wococo);
// AssetHubWestend implementation
impl_accounts_helpers_for_parachain!(AssetHubWestend);
impl_assets_helpers_for_parachain!(AssetHubWestend, Westend);
impl_assert_events_helpers_for_parachain!(AssetHubWestend);
// PenpalWestendA implementation
impl_assert_events_helpers_for_parachain!(PenpalWestendA);
// BridgeHubRococo implementation
impl_accounts_helpers_for_parachain!(BridgeHubRococo);
impl_assert_events_helpers_for_parachain!(BridgeHubRococo);
decl_test_sender_receiver_accounts_parameter_types! {
// Relays
Westend { sender: ALICE, receiver: BOB },
Rococo { sender: ALICE, receiver: BOB },
Wococo { sender: ALICE, receiver: BOB },
// Asset Hubs
AssetHubWestend { sender: ALICE, receiver: BOB },
AssetHubRococo { sender: ALICE, receiver: BOB },
AssetHubWococo { sender: ALICE, receiver: BOB },
// Bridged Hubs
BridgeHubRococo { sender: ALICE, receiver: BOB },
BridgeHubWococo { sender: ALICE, receiver: BOB },
// Penpals
PenpalWestendA { sender: ALICE, receiver: BOB },
PenpalRococoA { sender: ALICE, receiver: BOB }
}