Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
445ba54
correct rate limiter Cargo.toml
apopiak Jul 12, 2023
cb275b6
Merge branch 'feat/xcm-defer' into feat/xcm-rate-limiter
apopiak Jul 12, 2023
db44625
bump crate versions
apopiak Jul 12, 2023
79a64a1
Revert "remove xcm rate limiter from runtime"
apopiak Jul 24, 2023
144605e
update xcmp queue pallet
apopiak Jul 24, 2023
673f54e
Merge branch 'master' of github.com:galacticcouncil/HydraDX-node into…
apopiak Jul 24, 2023
33828ce
Merge branch 'master' into feat/xcm-rate-limiter
mrq1911 Jul 27, 2023
4d48737
Merge branch 'master' into feat/xcm-rate-limiter
apopiak Jul 28, 2023
353a6c6
Merge branch 'master' into feat/xcm-rate-limiter
mrq1911 Aug 8, 2023
a6ee5de
bump integration tests
dmoka Aug 8, 2023
8797e19
Merge remote-tracking branch 'origin/feat/xcm-rate-limiter' into feat…
dmoka Aug 8, 2023
a931eb0
bump runtime version
dmoka Aug 8, 2023
21f5866
change function order to follow execution orders
dmoka Aug 8, 2023
b743f77
bump patch versions of touched packages
dmoka Aug 8, 2023
c95d0e5
fix xcm rate limiter non deterministic tests as we use different rela…
dmoka Aug 8, 2023
ce57dbb
merge master to feat/xcm-rate-limiter
dmoka Aug 11, 2023
62ecd90
bump versions
dmoka Aug 11, 2023
b33182c
merge master to feat/xcm-rate-limiter
dmoka Aug 14, 2023
04440f3
bump runtime version
dmoka Aug 14, 2023
0671025
bump patch versions for touched packages
dmoka Aug 14, 2023
658b7be
update lock
dmoka Aug 14, 2023
fed4df2
Merge branch 'master' of github.com:galacticcouncil/HydraDX-node into…
apopiak Oct 13, 2023
54744fe
bump versions
apopiak Oct 20, 2023
c90e469
remove duplicate assert macro definitions
apopiak Oct 20, 2023
0a0682a
update xcmp queue pallet to new extended version
apopiak Oct 20, 2023
ff7c102
update integration tests
apopiak Oct 20, 2023
7a1eaed
formatting
apopiak Oct 20, 2023
d958f16
configure defer duration
apopiak Dec 8, 2023
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
Prev Previous commit
Next Next commit
Revert "remove xcm rate limiter from runtime"
This reverts commit 1119b13.
  • Loading branch information
apopiak committed Jul 24, 2023
commit 79a64a179498a1afe970fc32b13117259bd32ad6
1 change: 1 addition & 0 deletions integration-tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ mod otc;
mod polkadot_test_net;
mod transact_call_filter;
mod vesting;
mod xcm_rate_limiter;

#[macro_export]
macro_rules! assert_balance {
Expand Down
243 changes: 243 additions & 0 deletions integration-tests/src/xcm_rate_limiter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
#![cfg(test)]

use crate::polkadot_test_net::*;

use frame_support::{assert_ok, pallet_prelude::Weight};
use orml_traits::currency::MultiCurrency;
use pallet_asset_registry::AssetType;
use polkadot_xcm::prelude::*;
use xcm_emulator::TestExt;

/// Returns the message hash in the `XcmpMessageSent` event at the `n`th last event (1-indexed, so if the second to last
/// event has the hash, pass `2`);
fn get_message_hash_from_event(n: usize) -> Option<[u8; 32]> {
use cumulus_pallet_xcmp_queue::Event;
use hydradx_runtime::RuntimeEvent;
let RuntimeEvent::XcmpQueue(Event::XcmpMessageSent { message_hash }) = &last_hydra_events(n)[0] else {
panic!("expecting to find message sent event");
};
*message_hash
}

#[test]
fn xcm_rate_limiter_should_limit_aca_when_limit_is_exceeded() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would probably also test clearing of the limits in similar fashion after blocks pass

// Arrange
TestNet::reset();

Hydra::execute_with(|| {
assert_ok!(hydradx_runtime::AssetRegistry::set_location(
hydradx_runtime::RuntimeOrigin::root(),
ACA,
hydradx_runtime::AssetLocation(MultiLocation::new(1, X2(Parachain(ACALA_PARA_ID), GeneralIndex(0))))
));

// set an xcm rate limit
assert_ok!(hydradx_runtime::AssetRegistry::update(
hydradx_runtime::RuntimeOrigin::root(),
ACA,
b"ACA".to_vec(),
AssetType::Token,
None,
Some(50 * UNITS),
));

assert_eq!(hydradx_runtime::Tokens::free_balance(ACA, &AccountId::from(BOB)), 0);
});

let amount = 100 * UNITS;
let mut message_hash = None;
Acala::execute_with(|| {
// Act
assert_ok!(hydradx_runtime::XTokens::transfer(
hydradx_runtime::RuntimeOrigin::signed(ALICE.into()),
0,
amount,
Box::new(
MultiLocation::new(
1,
X2(
Junction::Parachain(HYDRA_PARA_ID),
Junction::AccountId32 { id: BOB, network: None }
)
)
.into()
),
WeightLimit::Limited(Weight::from_ref_time(399_600_000_000))
));

message_hash = get_message_hash_from_event(2);

// Assert
assert_eq!(
hydradx_runtime::Balances::free_balance(&AccountId::from(ALICE)),
ALICE_INITIAL_NATIVE_BALANCE - amount
);
});

Hydra::execute_with(|| {
expect_hydra_events(vec![
cumulus_pallet_xcmp_queue::Event::XcmDeferred {
sender: ACALA_PARA_ID.into(),
sent_at: 3,
deferred_to: 604, // received at 4 plus 600 blocks of deferral
message_hash,
}
.into(),
pallet_relaychain_info::Event::CurrentBlockNumbers {
parachain_block_number: 1,
relaychain_block_number: 5,
}
.into(),
]);
assert_eq!(hydradx_runtime::Tokens::free_balance(ACA, &AccountId::from(BOB)), 0);
});
}

#[test]
fn xcm_rate_limiter_should_not_limit_aca_when_limit_is_not_exceeded() {
// Arrange
TestNet::reset();

Hydra::execute_with(|| {
assert_ok!(hydradx_runtime::AssetRegistry::set_location(
hydradx_runtime::RuntimeOrigin::root(),
ACA,
hydradx_runtime::AssetLocation(MultiLocation::new(1, X2(Parachain(ACALA_PARA_ID), GeneralIndex(0))))
));

// set an xcm rate limit
assert_ok!(hydradx_runtime::AssetRegistry::update(
hydradx_runtime::RuntimeOrigin::root(),
ACA,
b"ACA".to_vec(),
AssetType::Token,
None,
Some(101 * UNITS),
));
});

let amount = 100 * UNITS;
Acala::execute_with(|| {
// Act
assert_ok!(hydradx_runtime::XTokens::transfer(
hydradx_runtime::RuntimeOrigin::signed(ALICE.into()),
0,
amount,
Box::new(
MultiLocation::new(
1,
X2(
Junction::Parachain(HYDRA_PARA_ID),
Junction::AccountId32 { id: BOB, network: None }
)
)
.into()
),
WeightLimit::Limited(Weight::from_ref_time(399_600_000_000))
));

// Assert
assert_eq!(
hydradx_runtime::Balances::free_balance(&AccountId::from(ALICE)),
ALICE_INITIAL_NATIVE_BALANCE - amount
);
});

Hydra::execute_with(|| {
let fee = hydradx_runtime::Tokens::free_balance(ACA, &hydradx_runtime::Treasury::account_id());
assert_eq!(
hydradx_runtime::Tokens::free_balance(ACA, &AccountId::from(BOB)),
amount - fee
);
});
}

#[test]
fn deferred_messages_should_be_executable_by_root() {
// Arrange
TestNet::reset();

Hydra::execute_with(|| {
assert_ok!(hydradx_runtime::AssetRegistry::set_location(
hydradx_runtime::RuntimeOrigin::root(),
ACA,
hydradx_runtime::AssetLocation(MultiLocation::new(1, X2(Parachain(ACALA_PARA_ID), GeneralIndex(0))))
));

// set an xcm rate limit
assert_ok!(hydradx_runtime::AssetRegistry::update(
hydradx_runtime::RuntimeOrigin::root(),
ACA,
b"ACA".to_vec(),
AssetType::Token,
None,
Some(50 * UNITS),
));

assert_eq!(hydradx_runtime::Tokens::free_balance(ACA, &AccountId::from(BOB)), 0);
});

let amount = 100 * UNITS;
let mut message_hash = None;
let max_weight = Weight::from_ref_time(399_600_000_000);
Acala::execute_with(|| {
// Act
assert_ok!(hydradx_runtime::XTokens::transfer(
hydradx_runtime::RuntimeOrigin::signed(ALICE.into()),
0,
amount,
Box::new(
MultiLocation::new(
1,
X2(
Junction::Parachain(HYDRA_PARA_ID),
Junction::AccountId32 { id: BOB, network: None }
)
)
.into()
),
WeightLimit::Limited(max_weight),
));

message_hash = get_message_hash_from_event(2);

// Assert
assert_eq!(
hydradx_runtime::Balances::free_balance(&AccountId::from(ALICE)),
ALICE_INITIAL_NATIVE_BALANCE - amount
);
});

Hydra::execute_with(|| {
expect_hydra_events(vec![
cumulus_pallet_xcmp_queue::Event::XcmDeferred {
sender: ACALA_PARA_ID.into(),
sent_at: 3,
deferred_to: 604, // received at 4 plus 600 blocks of deferral
message_hash,
}
.into(),
pallet_relaychain_info::Event::CurrentBlockNumbers {
parachain_block_number: 1,
relaychain_block_number: 5,
}
.into(),
]);
assert_eq!(hydradx_runtime::Tokens::free_balance(ACA, &AccountId::from(BOB)), 0);

set_relaychain_block_number(604);

assert_eq!(hydradx_runtime::Tokens::free_balance(ACA, &AccountId::from(BOB)), 0);
assert_ok!(hydradx_runtime::XcmpQueue::service_deferred(
hydradx_runtime::RuntimeOrigin::root(),
max_weight,
ACALA_PARA_ID.into(),
));

let fee = hydradx_runtime::Tokens::free_balance(ACA, &hydradx_runtime::Treasury::account_id());
assert_eq!(
hydradx_runtime::Tokens::free_balance(ACA, &AccountId::from(BOB)),
amount - fee
);
});
}
1 change: 1 addition & 0 deletions runtime/hydradx/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ construct_runtime!(

Router: pallet_route_executor = 67,
DynamicFees: pallet_dynamic_fees = 68,
XcmRateLimiter: pallet_xcm_rate_limiter = 69,

// ORML related modules
Tokens: orml_tokens = 77,
Expand Down
21 changes: 19 additions & 2 deletions runtime/hydradx/src/xcm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ use frame_system::EnsureRoot;
use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};
use orml_xcm_support::{DepositToAlternative, IsNativeConcrete, MultiNativeAsset};
use pallet_xcm::XcmPassthrough;
use polkadot_parachain::primitives::Sibling;
use polkadot_parachain::primitives::{RelayChainBlockNumber, Sibling};
use polkadot_xcm::v3::{prelude::*, Weight as XcmWeight};
use primitives::Price;
use scale_info::TypeInfo;
use xcm_builder::{
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom,
Expand Down Expand Up @@ -144,7 +145,7 @@ impl cumulus_pallet_xcmp_queue::Config for Runtime {
type ExecuteDeferredOrigin = EnsureRoot<AccountId>;
type MaxDeferredMessages = ConstU32<100>;
type RelayChainBlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
type XcmDeferFilter = ();
type XcmDeferFilter = XcmRateLimiter;
}

impl cumulus_pallet_dmp_queue::Config for Runtime {
Expand Down Expand Up @@ -214,6 +215,22 @@ impl pallet_xcm::Config for Runtime {
#[cfg(feature = "runtime-benchmarks")]
type ReachableDest = ReachableDest;
}

parameter_types! {
pub DeferDuration: RelayChainBlockNumber = 600; // 1 hour
pub MaxDeferDuration: RelayChainBlockNumber = 600 * 24 * 10; // 10 days
}

impl pallet_xcm_rate_limiter::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type AssetId = AssetId;
type DeferDuration = DeferDuration;
type MaxDeferDuration = MaxDeferDuration;
type RelayBlockNumberProvider = RelayChainBlockNumberProvider<Runtime>;
type CurrencyIdConvert = CurrencyIdConvert;
type RateLimitFor = pallet_asset_registry::XcmRateLimitsInRegistry<Runtime>;
}

pub struct CurrencyIdConvert;
use primitives::constants::chain::CORE_ASSET_ID;

Expand Down