Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
6 changes: 5 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions modules/transaction-pause/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ pub mod module {
pallet_name_bytes: Vec<u8>,
function_name_bytes: Vec<u8>,
},
XcmPaused,
XcmUnPaused,
}

/// The paused transaction map
Expand All @@ -81,6 +83,10 @@ pub mod module {
#[pallet::getter(fn paused_transactions)]
pub type PausedTransactions<T: Config> = StorageMap<_, Twox64Concat, (Vec<u8>, Vec<u8>), (), OptionQuery>;

#[pallet::storage]
#[pallet::getter(fn xcm_paused)]
pub type XcmPaused<T: Config> = StorageValue<_, bool, ValueQuery>;

#[pallet::pallet]
pub struct Pallet<T>(_);

Expand Down Expand Up @@ -129,6 +135,22 @@ pub mod module {
};
Ok(())
}

#[pallet::weight(T::WeightInfo::pause_transaction())]
pub fn pause_xcm(origin: OriginFor<T>) -> DispatchResult {
T::UpdateOrigin::ensure_origin(origin)?;
XcmPaused::<T>::set(true);
Self::deposit_event(Event::XcmPaused);
Ok(())
}

#[pallet::weight(T::WeightInfo::pause_transaction())]
pub fn unpause_xcm(origin: OriginFor<T>) -> DispatchResult {
Comment thread
zqhxuyuan marked this conversation as resolved.
Outdated
T::UpdateOrigin::ensure_origin(origin)?;
XcmPaused::<T>::set(false);
Self::deposit_event(Event::XcmUnPaused);
Ok(())
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions runtime/acala/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1366,10 +1366,10 @@ impl cumulus_pallet_parachain_system::Config for Runtime {
type Event = Event;
type OnValidationData = ();
type SelfParaId = ParachainInfo;
type DmpMessageHandler = DmpQueue;
type DmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, DmpQueue>;
type ReservedDmpWeight = ReservedDmpWeight;
type OutboundXcmpMessageSource = XcmpQueue;
type XcmpMessageHandler = XcmpQueue;
type XcmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, XcmpQueue>;
type ReservedXcmpWeight = ReservedXcmpWeight;
}

Expand Down
6 changes: 6 additions & 0 deletions runtime/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false }
sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.13", default-features = false }

polkadot-core-primitives = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.13", default-features = false }
cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.13", default-features = false }
cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.13", default-features = false }

orml-oracle = { path = "../../orml/oracle", default-features = false }
Expand All @@ -35,6 +37,7 @@ primitives = { package = "acala-primitives", path = "../../primitives", default-

module-prices = { path = "../../modules/prices", default-features = false }
module-transaction-payment = { path = "../../modules/transaction-payment", default-features = false }
module-transaction-pause = { path = "../../modules/transaction-pause", default-features = false }
module-nft = { path = "../../modules/nft", default-features = false }
module-dex = { path = "../../modules/dex", default-features = false }

Expand Down Expand Up @@ -77,6 +80,8 @@ std = [
"sp-runtime/std",
"sp-std/std",

"polkadot-core-primitives/std",
"cumulus-primitives-core/std",
"cumulus-pallet-parachain-system/std",

"orml-oracle/std",
Expand All @@ -89,6 +94,7 @@ std = [
"primitives/std",
"module-prices/std",
"module-transaction-payment/std",
"module-transaction-pause/std",
"module-nft/std",
"module-dex/std",

Expand Down
45 changes: 45 additions & 0 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ pub use xcm::latest::prelude::*;
pub use xcm_builder::TakeRevenue;
pub use xcm_executor::{traits::DropAssets, Assets};

use cumulus_primitives_core::relay_chain::v1::Id;
use cumulus_primitives_core::{DmpMessageHandler, XcmpMessageHandler};
/// Block number type used by the relay chain.
pub use polkadot_core_primitives::BlockNumber as RelayChainBlockNumber;

pub type TimeStampedPrice = orml_oracle::TimestampedValue<Price, primitives::Moment>;

// Priority of unsigned transactions
Expand Down Expand Up @@ -420,6 +425,46 @@ where
}
}

/// XcmMessageHandler of `DmpMessageHandler` and `XcmpMessageHandler` implementations.
/// if xcm is paused, the `max_weight` of each handle method is set to `0`.
///
/// Parameters type:
/// - `A`: `DmpMessageHandler` or `XcmpMessageHandler`
pub struct XcmMessageHandlerOrPaused<Runtime, A>(PhantomData<(Runtime, A)>);
Comment thread
zqhxuyuan marked this conversation as resolved.
Outdated

impl<Runtime, A> DmpMessageHandler for XcmMessageHandlerOrPaused<Runtime, A>
where
Runtime: module_transaction_pause::Config,
A: DmpMessageHandler,
{
fn handle_dmp_messages(iter: impl Iterator<Item = (RelayChainBlockNumber, Vec<u8>)>, max_weight: Weight) -> Weight {
let xcm_paused: bool = module_transaction_pause::Pallet::<Runtime>::xcm_paused();
if xcm_paused {
A::handle_dmp_messages(iter, 0)
} else {
A::handle_dmp_messages(iter, max_weight)
}
Comment thread
zqhxuyuan marked this conversation as resolved.
Outdated
}
}

impl<Runtime, A> XcmpMessageHandler for XcmMessageHandlerOrPaused<Runtime, A>
where
Runtime: module_transaction_pause::Config,
A: XcmpMessageHandler,
{
fn handle_xcmp_messages<'a, I: Iterator<Item = (Id, BlockNumber, &'a [u8])>>(
iter: I,
max_weight: Weight,
) -> Weight {
let xcm_paused: bool = module_transaction_pause::Pallet::<Runtime>::xcm_paused();
if xcm_paused {
A::handle_xcmp_messages(iter, 0)
} else {
A::handle_xcmp_messages(iter, max_weight)
}
Comment thread
shaunxw marked this conversation as resolved.
Outdated
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
5 changes: 3 additions & 2 deletions runtime/integration-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ orml-unknown-tokens = { path = "../../orml/unknown-tokens" }
orml-xcm = { path = "../../orml/xcm" }

module-transaction-payment = { path = "../../modules/transaction-payment" }
module-transaction-pause = { path = "../../modules/transaction-pause" }
module-asset-registry = { path = "../../modules/asset-registry" }
module-auction-manager = { path = "../../modules/auction-manager" }
module-cdp-engine = { path = "../../modules/cdp-engine" }
Expand Down Expand Up @@ -131,12 +132,12 @@ polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch =
polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.13" }
kusama-runtime = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.13" }

xcm-emulator = { git = "https://github.com/shaunxw/xcm-simulator", rev = "4d3bb9dd4fa2cd554a9970ffff816d9346269eaa" }
xcm-emulator = { git = "https://github.com/zqhxuyuan/xcm-simulator", branch = "handler" }
Comment thread
zqhxuyuan marked this conversation as resolved.
Outdated

acala-service = { path = "../../node/service", features = ["with-all-runtime"] }

[features]
default = ["std"]
default = ["std", "with-karura-runtime"]
no_std = []
with-mandala-runtime = [
"acala-service/with-mandala-runtime",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -768,3 +768,112 @@ fn sibling_trap_assets_works() {
);
});
}

#[test]
fn dmp_queue_pause_resume_works() {
Karura::execute_with(|| {
assert_ok!(module_transaction_pause::Pallet::<Runtime>::pause_xcm(Origin::root()));
assert!(module_transaction_pause::Pallet::<Runtime>::xcm_paused());
});

let fee: u128 = 128_000_000;

KusamaNet::execute_with(|| {
assert_ok!(kusama_runtime::XcmPallet::reserve_transfer_assets(
kusama_runtime::Origin::signed(ALICE.into()),
Box::new(Parachain(2000).into().into()),
Box::new(
Junction::AccountId32 {
id: BOB,
network: NetworkId::Any
}
.into()
.into()
),
Box::new((Here, dollar(KSM)).into()),
0
));
});

Karura::execute_with(|| {
// the first message is not processed but remain in dmq-queue
assert!(module_transaction_pause::Pallet::<Runtime>::xcm_paused());
// Bob balance is 0 as the xcm message not executed
assert_eq!(Tokens::free_balance(KSM, &AccountId::from(BOB)), 0);

// resume the dmp-queue working
assert_ok!(module_transaction_pause::Pallet::<Runtime>::unpause_xcm(Origin::root()));
assert!(!module_transaction_pause::Pallet::<Runtime>::xcm_paused());
});

// the empty body implementation here is used to trigger send downward message to parachain,
// the previous message in the queue storage will be [first executed](https://github.com/paritytech/cumulus/blob/polkadot-v0.9.13/pallets/dmp-queue/src/lib.rs#L270).
// then the second message executed which is also get from storage by runtime.dmq_contents().
KusamaNet::execute_with(|| {});

Karura::execute_with(|| {
assert!(!module_transaction_pause::Pallet::<Runtime>::xcm_paused());
assert_eq!(
Tokens::free_balance(KSM, &AccountId::from(BOB)),
2 * dollar(KSM) - fee * 2
);
});
}

#[test]
fn xcmp_queue_pause_resume_works() {
fn karura_reserve_account() -> AccountId {
use sp_runtime::traits::AccountIdConversion;
polkadot_parachain::primitives::Sibling::from(2000).into_account()
}
Karura::execute_with(|| {
assert_ok!(Tokens::deposit(BNC, &AccountId::from(ALICE), 100 * dollar(BNC)));
});

Sibling::execute_with(|| {
assert_ok!(Tokens::deposit(BNC, &karura_reserve_account(), 100 * dollar(BNC)));
assert_ok!(module_transaction_pause::Pallet::<Runtime>::pause_xcm(Origin::root()));
assert!(module_transaction_pause::Pallet::<Runtime>::xcm_paused());
});

Karura::execute_with(|| {
assert_ok!(XTokens::transfer(
Origin::signed(ALICE.into()),
BNC,
10 * dollar(BNC),
Box::new(
MultiLocation::new(
1,
X2(
Parachain(2001),
Junction::AccountId32 {
network: NetworkId::Any,
id: BOB.into(),
}
)
)
.into()
),
1_000_000_000,
));

assert_eq!(Tokens::free_balance(BNC, &AccountId::from(ALICE)), 90 * dollar(BNC));
});

Sibling::execute_with(|| {
assert_eq!(Tokens::free_balance(BNC, &karura_reserve_account()), 100 * dollar(BNC));
assert_eq!(Tokens::free_balance(BNC, &AccountId::from(BOB)), 0);

// resume the dmp-queue working
assert_ok!(module_transaction_pause::Pallet::<Runtime>::unpause_xcm(Origin::root()));
assert!(!module_transaction_pause::Pallet::<Runtime>::xcm_paused());

assert_eq!(Tokens::free_balance(BNC, &karura_reserve_account()), 100 * dollar(BNC));
assert_eq!(Tokens::free_balance(BNC, &AccountId::from(BOB)), 0);
});

Sibling::execute_with(|| {
assert_eq!(Tokens::free_balance(BNC, &karura_reserve_account()), 90 * dollar(BNC));
assert_eq!(Tokens::free_balance(BNC, &AccountId::from(BOB)), 9_989_760_000_000);
});
}
4 changes: 4 additions & 0 deletions runtime/integration-tests/src/relaychain/kusama_test_net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ decl_test_parachain! {
pub struct Karura {
Runtime = Runtime,
Origin = Origin,
XcmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, XcmpQueue>,
DmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, DmpQueue>,
new_ext = para_ext(2000),
}
}
Expand All @@ -48,6 +50,8 @@ decl_test_parachain! {
pub struct Sibling {
Runtime = Runtime,
Origin = Origin,
XcmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, XcmpQueue>,
DmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, DmpQueue>,
new_ext = para_ext(2001),
}
}
Expand Down
12 changes: 6 additions & 6 deletions runtime/integration-tests/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ mod karura_imports {
constants::parachains, create_x2_parachain_multilocation, get_all_module_accounts, AcalaOracle, AccountId,
AssetRegistry, AuctionManager, Authority, AuthoritysOriginId, Balance, Balances, BlockNumber, Call, CdpEngine,
CdpTreasury, CreateClassDeposit, CreateTokenDeposit, Currencies, CurrencyId, CurrencyIdConvert,
DataDepositPerByte, DefaultExchangeRate, Dex, EmergencyShutdown, Event, EvmAccounts, ExistentialDeposits,
FeePoolSize, FinancialCouncil, Get, GetNativeCurrencyId, HomaLite, Honzon, IdleScheduler, KarPerSecond,
KaruraFoundationAccounts, KsmPerSecond, KusdPerSecond, Loans, MaxTipsOfPriority, MinimumDebitValue,
MultiLocation, NativeTokenExistentialDeposit, NetworkId, NftPalletId, OneDay, Origin, OriginCaller,
ParachainAccount, ParachainInfo, ParachainSystem, PolkadotXcm, Proxy, ProxyType, Ratio,
DataDepositPerByte, DefaultExchangeRate, Dex, DmpQueue, EmergencyShutdown, Event, EvmAccounts,
ExistentialDeposits, FeePoolSize, FinancialCouncil, Get, GetNativeCurrencyId, HomaLite, Honzon, IdleScheduler,
KarPerSecond, KaruraFoundationAccounts, KsmPerSecond, KusdPerSecond, Loans, MaxTipsOfPriority,
MinimumDebitValue, MultiLocation, NativeTokenExistentialDeposit, NetworkId, NftPalletId, OneDay, Origin,
OriginCaller, ParachainAccount, ParachainInfo, ParachainSystem, PolkadotXcm, Proxy, ProxyType, Ratio,
RelayChainBlockNumberProvider, RelayChainSovereignSubAccount, Runtime, Scheduler, Session, SessionManager,
SevenDays, SwapBalanceThreshold, System, Timestamp, TipPerWeightStep, TokenSymbol, Tokens, TreasuryPalletId,
Utility, Vesting, XTokens, XcmConfig, XcmExecutor, XcmUnbondFee, EVM, NFT,
Utility, Vesting, XTokens, XcmConfig, XcmExecutor, XcmUnbondFee, XcmpQueue, EVM, NFT,
};
pub use primitives::TradingPair;
pub use runtime_common::{calculate_asset_ratio, cent, dollar, millicent, KAR, KSM, KUSD, LKSM};
Expand Down
4 changes: 2 additions & 2 deletions runtime/karura/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1381,10 +1381,10 @@ impl cumulus_pallet_parachain_system::Config for Runtime {
type Event = Event;
type OnValidationData = ();
type SelfParaId = ParachainInfo;
type DmpMessageHandler = DmpQueue;
type DmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, DmpQueue>;
type ReservedDmpWeight = ReservedDmpWeight;
type OutboundXcmpMessageSource = XcmpQueue;
type XcmpMessageHandler = XcmpQueue;
type XcmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, XcmpQueue>;
type ReservedXcmpWeight = ReservedXcmpWeight;
}

Expand Down
4 changes: 2 additions & 2 deletions runtime/mandala/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1598,10 +1598,10 @@ impl cumulus_pallet_parachain_system::Config for Runtime {
type Event = Event;
type OnValidationData = ();
type SelfParaId = ParachainInfo;
type DmpMessageHandler = DmpQueue;
type DmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, DmpQueue>;
type ReservedDmpWeight = ReservedDmpWeight;
type OutboundXcmpMessageSource = XcmpQueue;
type XcmpMessageHandler = XcmpQueue;
type XcmpMessageHandler = runtime_common::XcmMessageHandlerOrPaused<Runtime, XcmpQueue>;
type ReservedXcmpWeight = ReservedXcmpWeight;
}

Expand Down