Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add statemint as trustable chain for pendulum + integration tests #192

Merged
merged 19 commits into from
Apr 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
73a4799
update pendulum runtime to support XCM reserve transfer for USDT
RustNinja Mar 29, 2023
0761f1a
add pendulum integration tests for XCM (#190)
RustNinja Mar 29, 2023
08a81de
add polkadot runtime to integration tests
RustNinja Mar 29, 2023
2717818
add xcm test configuration
RustNinja Mar 29, 2023
1c9aad6
fix type XcmConfig instead of XCMConfig
RustNinja Mar 29, 2023
cb5346a
add relay chain + parachain base integration tests
RustNinja Mar 29, 2023
8396e3f
add Pendulum parachain to decl_test_network in xcm integration tests
RustNinja Mar 29, 2023
e4b60ce
Configure pendulum runtime for xcm simulator (#193)
RustNinja Mar 31, 2023
82e3409
Add xcm tests for pendulum (#195)
RustNinja Mar 31, 2023
54fa5dd
added test for transfer polkadot_from_pendulum_to_relay_chain
RustNinja Apr 3, 2023
75b0c81
Statemint integration tests to cover USDT bidirectional reserve trans…
RustNinja Apr 4, 2023
c41a382
rename to runtime-integration-tests
RustNinja Apr 4, 2023
741ae7d
Final refactor xcm integration tests (#198)
RustNinja Apr 5, 2023
039bdbd
move comment up function statemint_transfer_incorrect_asset_to_pendulum
RustNinja Apr 6, 2023
79a7c99
renamed to renamed to fn units(amount)
RustNinja Apr 6, 2023
0471cad
wrap AccountId32 to X1 when call reserve_transfer_assets
RustNinja Apr 6, 2023
0f42bd0
Merge remote-tracking branch 'origin/main' into add-statemint-as-trus…
RustNinja Apr 6, 2023
63b8975
make Foucoco xcm config identical to pendulum runtime (#199)
RustNinja Apr 6, 2023
35386bc
remove duplicate of "runtime/development"
RustNinja Apr 6, 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
6 changes: 5 additions & 1 deletion runtime/integration-tests/pendulum/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#![cfg(test)]
#[cfg(test)]
mod polkadot_test_net;

#[cfg(test)]
mod setup;

#[cfg(test)]
mod tests;
8 changes: 4 additions & 4 deletions runtime/integration-tests/pendulum/src/polkadot_test_net.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::setup::{dot, ExtBuilderPendulum, ExtStatemintBuilder, ALICE, BOB};
use crate::setup::{one, ExtBuilderPendulum, ExtStatemintBuilder, ALICE, BOB};
use frame_support::traits::GenesisBuild;
use polkadot_core_primitives::{AccountId, BlockNumber};
use polkadot_parachain::primitives::Id as ParaId;
Expand Down Expand Up @@ -54,9 +54,9 @@ pub fn relay_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap();
pallet_balances::GenesisConfig::<Runtime> {
balances: vec![
(AccountId::from(ALICE), dot(100000)),
(AccountId::from(BOB), dot(100)),
(para_account_id(2094), 10 * dot(100000)),
(AccountId::from(ALICE), one(100000)),
(AccountId::from(BOB), one(100)),
(para_account_id(2094), 10 * one(100000)),
],
}
.assimilate_storage(&mut t)
Expand Down
8 changes: 6 additions & 2 deletions runtime/integration-tests/pendulum/src/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ use frame_support::traits::GenesisBuild;
use pendulum_runtime::{PendulumCurrencyId, Runtime, System};
use polkadot_core_primitives::{AccountId, Balance};

pub fn dot(amount: Balance) -> Balance {
pub fn one(amount: Balance) -> Balance {
amount * 10u128.saturating_pow(9)
}

pub const ALICE: [u8; 32] = [4u8; 32];
pub const BOB: [u8; 32] = [5u8; 32];
pub const INITIAL_BALANCE: u128 = 1_000_000_000;
Expand All @@ -13,6 +14,7 @@ pub struct ExtBuilderPendulum {
balances: Vec<(AccountId, PendulumCurrencyId, Balance)>,
parachain_id: u32,
}

impl Default for ExtBuilderPendulum {
fn default() -> Self {
Self { balances: vec![], parachain_id: 2094 }
Expand All @@ -24,10 +26,12 @@ impl ExtBuilderPendulum {
self.balances = balances;
self
}

pub fn parachain_id(mut self, parachain_id: u32) -> Self {
self.parachain_id = parachain_id;
self
}

pub fn build(self) -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap();
pallet_balances::GenesisConfig::<Runtime> {
Expand All @@ -40,7 +44,7 @@ impl ExtBuilderPendulum {
.unwrap();

orml_tokens::GenesisConfig::<Runtime> {
balances: vec![(AccountId::from(BOB), PendulumCurrencyId::XCM(0), dot(100))],
balances: vec![(AccountId::from(BOB), PendulumCurrencyId::XCM(0), one(100))],
}
.assimilate_storage(&mut t)
.unwrap();
Expand Down
80 changes: 47 additions & 33 deletions runtime/integration-tests/pendulum/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,22 @@ use sp_runtime::{traits::AccountIdConversion, MultiAddress};
use xcm::latest::{Junction, Junction::*, Junctions::*, MultiLocation, NetworkId, WeightLimit};
use xcm_emulator::{Junctions, TestExt};

use pendulum_runtime::{RuntimeEvent, System};
use polkadot_core_primitives::{AccountId, Balance};
use polkadot_parachain::primitives::Sibling;

const DOT_FEE: Balance = 3200000000;
const DOT_FEE_WHEN_TRANSFER_TO_PARACHAIN: Balance = 3200000000; //The fees that relay chain will charge when transfer DOT to parachain. sovereign account of some parachain will receive transfer_amount - DOT_FEE
const ASSET_ID: u32 = 1984; //Real USDT Asset ID from Statemint
const INCORRECT_ASSET_ID: u32 = 0;
const INCORRECT_ASSET_ID: u32 = 0; //Incorrect asset id that pendulum is not supporting pendulum_runtime xcm_config
pub const UNIT: Balance = 1_000_000_000_000;
pub const TEN: Balance = 10_000_000_000_000;
const FEE: u128 = 421434140;
pub const TEN_UNITS: Balance = 10_000_000_000_000;
const DOT_FEE_WHEN_TRANSFER_TO_RELAY: u128 = 421434140; //This fee will taken to transfer assets(Polkadot) from sovereign parachain account to destination user account;

#[test]
fn transfer_polkadot_from_relay_chain_to_pendulum() {
fn transfer_dot_from_relay_chain_to_pendulum() {
MockNet::reset();

let transfer_amount: Balance = dot(20);
let transfer_amount: Balance = one(20);
let mut orml_tokens_before = 0;
PendulumParachain::execute_with(|| {
orml_tokens_before = pendulum_runtime::Tokens::balance(
Expand All @@ -34,16 +35,14 @@ fn transfer_polkadot_from_relay_chain_to_pendulum() {
Relay::execute_with(|| {
assert_ok!(polkadot_runtime::XcmPallet::reserve_transfer_assets(
polkadot_runtime::RuntimeOrigin::signed(ALICE.into()),
Box::new(Parachain(2094).into().into()),
Box::new(X1(Parachain(2094)).into().into()),
Box::new(Junction::AccountId32 { network: NetworkId::Any, id: ALICE }.into().into()),
Box::new((Here, transfer_amount).into()),
0
));
});

PendulumParachain::execute_with(|| {
use pendulum_runtime::{RuntimeEvent, System};

assert!(System::events().iter().any(|r| matches!(
r.event,
RuntimeEvent::Tokens(orml_tokens::Event::Deposited { .. })
Expand All @@ -61,20 +60,21 @@ fn transfer_polkadot_from_relay_chain_to_pendulum() {
pendulum_runtime::PendulumCurrencyId::XCM(0),
&ALICE.into()
),
orml_tokens_before + transfer_amount - DOT_FEE
orml_tokens_before + transfer_amount - DOT_FEE_WHEN_TRANSFER_TO_PARACHAIN
);
});
}

#[test]
fn transfer_polkadot_from_pendulum_to_relay_chain() {
fn transfer_dot_from_pendulum_to_relay_chain() {
MockNet::reset();

let transfer_dot_amount: Balance = dot(10);
let transfer_dot_amount: Balance = one(10);

let expected_base_balance = one(100);
Relay::execute_with(|| {
let after_bob_free_balance = polkadot_runtime::Balances::free_balance(&BOB.into());
assert_eq!(after_bob_free_balance, dot(100));
let before_bob_free_balance = polkadot_runtime::Balances::free_balance(&BOB.into());
assert_eq!(before_bob_free_balance, expected_base_balance);
});

PendulumParachain::execute_with(|| {
Expand All @@ -94,8 +94,6 @@ fn transfer_polkadot_from_pendulum_to_relay_chain() {
});

PendulumParachain::execute_with(|| {
use pendulum_runtime::{RuntimeEvent, System};

assert!(System::events().iter().any(|r| matches!(
r.event,
RuntimeEvent::Tokens(orml_tokens::Event::Withdrawn { .. })
Expand Down Expand Up @@ -128,29 +126,37 @@ fn transfer_polkadot_from_pendulum_to_relay_chain() {

Relay::execute_with(|| {
let after_bob_free_balance = polkadot_runtime::Balances::free_balance(&BOB.into());
assert_eq!(after_bob_free_balance, dot(100) + transfer_dot_amount - FEE);
assert_eq!(
after_bob_free_balance,
expected_base_balance + transfer_dot_amount - DOT_FEE_WHEN_TRANSFER_TO_RELAY
);
});
}

#[test]
fn statemint_transfer_incorrect_asset_to_pendulum_fails() {
fn statemint_transfer_incorrect_asset_to_pendulum_should_fails() {
let para_2094: AccountId = Sibling::from(2094).into_account_truncating();

//pendulum_runtime::PendulumCurrencyId::XCM(1) is the representation of USDT from Statemint on Pendulum chain.
//The asset id for USDT on Statemint is 1984. and pendulum support only this asset id to recive it on chain.
//we are going to execute XCM call to sent incorrect Asset Id and expect to see cumulus_pallet_xcmp_queue::Event::Fail event with an error FailedToTransactAsset.
//we what to be sure that the initial USDT balance for BOB is the same after XCM call from statemint when we tried to send wrong ASSET_ID from system parachain.
let extected_base_usdt_balance = 0;
PendulumParachain::execute_with(|| {
assert_eq!(
pendulum_runtime::Tokens::balance(
pendulum_runtime::PendulumCurrencyId::XCM(1),
&BOB.into()
),
0
extected_base_usdt_balance
);
});

Statemint::execute_with(|| {
use statemint_runtime::*;

let origin = RuntimeOrigin::signed(ALICE.into());
Balances::make_free_balance_be(&ALICE.into(), TEN);
Balances::make_free_balance_be(&ALICE.into(), TEN_UNITS);
Balances::make_free_balance_be(&BOB.into(), UNIT);

// If using non root, create custom asset cost 0.1 Dot
Expand Down Expand Up @@ -178,7 +184,8 @@ fn statemint_transfer_incorrect_asset_to_pendulum_fails() {
Box::new(MultiLocation::new(1, X1(Parachain(2094))).into()),
Box::new(Junction::AccountId32 { id: BOB, network: NetworkId::Any }.into().into()),
Box::new(
(X2(PalletInstance(50), GeneralIndex(INCORRECT_ASSET_ID as u128)), TEN).into()
(X2(PalletInstance(50), GeneralIndex(INCORRECT_ASSET_ID as u128)), TEN_UNITS)
.into()
),
0,
WeightLimit::Unlimited
Expand All @@ -187,7 +194,7 @@ fn statemint_transfer_incorrect_asset_to_pendulum_fails() {
assert_eq!(990 * UNIT, Assets::balance(INCORRECT_ASSET_ID, &AccountId::from(ALICE)));
assert_eq!(0, Assets::balance(INCORRECT_ASSET_ID, &AccountId::from(BOB)));

assert_eq!(TEN, Assets::balance(INCORRECT_ASSET_ID, &para_2094));
assert_eq!(TEN_UNITS, Assets::balance(INCORRECT_ASSET_ID, &para_2094));
// the DOT balance of sibling parachain sovereign account is not changed
assert_eq!(UNIT, Balances::free_balance(&para_2094));
});
Expand All @@ -196,8 +203,6 @@ fn statemint_transfer_incorrect_asset_to_pendulum_fails() {
Statemint::execute_with(|| {});

PendulumParachain::execute_with(|| {
use pendulum_runtime::{RuntimeEvent, System};

assert!(System::events().iter().any(|r| matches!(
r.event,
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::Fail {
Expand All @@ -207,6 +212,16 @@ fn statemint_transfer_incorrect_asset_to_pendulum_fails() {
})
)));
});

PendulumParachain::execute_with(|| {
assert_eq!(
pendulum_runtime::Tokens::balance(
pendulum_runtime::PendulumCurrencyId::XCM(1),
&BOB.into()
),
extected_base_usdt_balance
);
});
}

#[test]
Expand All @@ -227,7 +242,7 @@ fn statemint_transfer_asset_to_pendulum() {
use statemint_runtime::*;

let origin = RuntimeOrigin::signed(ALICE.into());
Balances::make_free_balance_be(&ALICE.into(), TEN);
Balances::make_free_balance_be(&ALICE.into(), TEN_UNITS);
Balances::make_free_balance_be(&BOB.into(), UNIT);

// If using non root, create custom asset cost 0.1 Dot
Expand All @@ -254,15 +269,15 @@ fn statemint_transfer_asset_to_pendulum() {
origin.clone(),
Box::new(MultiLocation::new(1, X1(Parachain(2094))).into()),
Box::new(Junction::AccountId32 { id: BOB, network: NetworkId::Any }.into().into()),
Box::new((X2(PalletInstance(50), GeneralIndex(ASSET_ID as u128)), TEN).into()),
Box::new((X2(PalletInstance(50), GeneralIndex(ASSET_ID as u128)), TEN_UNITS).into()),
0,
WeightLimit::Unlimited
));

assert_eq!(990 * UNIT, Assets::balance(ASSET_ID, &AccountId::from(ALICE)));
assert_eq!(0, Assets::balance(ASSET_ID, &AccountId::from(BOB)));

assert_eq!(TEN, Assets::balance(ASSET_ID, &para_2094));
assert_eq!(TEN_UNITS, Assets::balance(ASSET_ID, &para_2094));
// the DOT balance of sibling parachain sovereign account is not changed
assert_eq!(UNIT, Balances::free_balance(&para_2094));
});
Expand All @@ -271,7 +286,6 @@ fn statemint_transfer_asset_to_pendulum() {
Statemint::execute_with(|| {});

PendulumParachain::execute_with(|| {
use pendulum_runtime::{RuntimeEvent, System};
for i in System::events().iter() {
println!(" Pendulum_runtime {:?}", i);
}
Expand All @@ -295,21 +309,22 @@ fn statemint_transfer_asset_to_pendulum() {
pendulum_runtime::PendulumCurrencyId::XCM(1),
&BOB.into()
),
TEN
TEN_UNITS
);
});
}

#[test]
fn statemint_transfer_asset_to_statemint() {
//first we need to set up USDT balance on pendulum chain before to start transfer it back.
statemint_transfer_asset_to_pendulum();

Statemint::execute_with(|| {});

PendulumParachain::execute_with(|| {
assert_eq!(TEN, Tokens::balance(PendulumCurrencyId::XCM(1), &AccountId::from(BOB)));
assert_eq!(TEN_UNITS, Tokens::balance(PendulumCurrencyId::XCM(1), &AccountId::from(BOB)));
// ensure sender has enough PEN balance to be charged as fee
assert_ok!(Balances::mint_into(&AccountId::from(BOB), TEN));
assert_ok!(Balances::mint_into(&AccountId::from(BOB), TEN_UNITS));

assert_ok!(XTokens::transfer(
RuntimeOrigin::signed(BOB.into()),
Expand All @@ -329,11 +344,10 @@ fn statemint_transfer_asset_to_statemint() {
));

assert_eq!(
TEN - 1 * UNIT, //inital balance - one unit
TEN_UNITS - 1 * UNIT, //inital balance - one unit
Tokens::balance(PendulumCurrencyId::XCM(1), &AccountId::from(BOB))
);

use pendulum_runtime::{RuntimeEvent, System};
assert!(System::events().iter().any(|r| matches!(
r.event,
RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. })
Expand Down