From c9f54e3c39bd227104a7dbae0e59bdc587e2ec43 Mon Sep 17 00:00:00 2001 From: Xavier Lau Date: Thu, 12 Jan 2023 22:06:36 +0800 Subject: [PATCH] Refactor runtime tests (#204) --- Cargo.lock | 3 + node/src/chain_spec/crab.rs | 1 - node/src/chain_spec/darwinia.rs | 1 - node/src/chain_spec/pangolin.rs | 1 - pallet/account-migration/src/lib.rs | 3 +- runtime/common/Cargo.toml | 14 +- runtime/common/src/lib.rs | 3 + runtime/common/src/test.rs | 310 ++++++++++++++++++ runtime/crab/Cargo.toml | 6 + runtime/crab/src/lib.rs | 3 +- runtime/crab/tests/account_migration.rs | 330 -------------------- runtime/crab/tests/mock.rs | 40 +-- runtime/crab/tests/tests.rs | 3 + runtime/darwinia/Cargo.toml | 6 + runtime/darwinia/src/lib.rs | 3 +- runtime/darwinia/tests/account_migration.rs | 330 -------------------- runtime/darwinia/tests/mock.rs | 40 +-- runtime/darwinia/tests/tests.rs | 3 + runtime/pangolin/Cargo.toml | 6 + runtime/pangolin/src/lib.rs | 3 +- runtime/pangolin/tests/account_migration.rs | 330 -------------------- runtime/pangolin/tests/mock.rs | 40 +-- runtime/pangolin/tests/tests.rs | 3 + 23 files changed, 416 insertions(+), 1066 deletions(-) create mode 100644 runtime/common/src/test.rs delete mode 100644 runtime/crab/tests/account_migration.rs create mode 100644 runtime/crab/tests/tests.rs delete mode 100644 runtime/darwinia/tests/account_migration.rs create mode 100644 runtime/darwinia/tests/tests.rs delete mode 100644 runtime/pangolin/tests/account_migration.rs create mode 100644 runtime/pangolin/tests/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 0e1ae127f..e40761dbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1424,6 +1424,7 @@ dependencies = [ "sp-core", "sp-inherents", "sp-io", + "sp-keyring", "sp-offchain", "sp-runtime", "sp-session", @@ -2629,6 +2630,7 @@ dependencies = [ "sp-core", "sp-inherents", "sp-io", + "sp-keyring", "sp-offchain", "sp-runtime", "sp-session", @@ -7571,6 +7573,7 @@ dependencies = [ "sp-core", "sp-inherents", "sp-io", + "sp-keyring", "sp-offchain", "sp-runtime", "sp-session", diff --git a/node/src/chain_spec/crab.rs b/node/src/chain_spec/crab.rs index ae9ebf56a..f04cd8b46 100644 --- a/node/src/chain_spec/crab.rs +++ b/node/src/chain_spec/crab.rs @@ -29,7 +29,6 @@ use cumulus_primitives_core::ParaId; // darwinia use super::*; use crab_runtime::*; -use dc_primitives::*; // frontier use fp_evm::GenesisAccount; // substrate diff --git a/node/src/chain_spec/darwinia.rs b/node/src/chain_spec/darwinia.rs index 1752cecdc..4c7f20b75 100644 --- a/node/src/chain_spec/darwinia.rs +++ b/node/src/chain_spec/darwinia.rs @@ -29,7 +29,6 @@ use cumulus_primitives_core::ParaId; // darwinia use super::*; use darwinia_runtime::*; -use dc_primitives::*; // frontier use fp_evm::GenesisAccount; // substrate diff --git a/node/src/chain_spec/pangolin.rs b/node/src/chain_spec/pangolin.rs index 9e5e54925..c3801eb0f 100644 --- a/node/src/chain_spec/pangolin.rs +++ b/node/src/chain_spec/pangolin.rs @@ -28,7 +28,6 @@ use std::{ use cumulus_primitives_core::ParaId; // darwinia use super::*; -use dc_primitives::*; use pangolin_runtime::*; // frontier use fp_evm::GenesisAccount; diff --git a/pallet/account-migration/src/lib.rs b/pallet/account-migration/src/lib.rs index dccfd7988..95bf67bb1 100644 --- a/pallet/account-migration/src/lib.rs +++ b/pallet/account-migration/src/lib.rs @@ -275,7 +275,8 @@ pub mod pallet { } pub use pallet::*; -fn sr25519_signable_message(spec_name: &[u8], account_id_20: &AccountId20) -> Vec { +/// Build a Darwinia account migration message. +pub fn sr25519_signable_message(spec_name: &[u8], account_id_20: &AccountId20) -> Vec { [ b"I authorize the migration to ", account_id_20.0.as_slice(), diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index f6419615e..6783afc30 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -29,12 +29,12 @@ xcm-builder = { default-features = false, git = "https://github.com/paritytech/ xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.30" } # substrate -frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } -frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } -pallet-collective = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } -sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } -sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } -sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +pallet-collective = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } [features] default = ["std"] @@ -61,3 +61,5 @@ std = [ "sp-runtime/std", "sp-std/std", ] + +test = [] diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 55431448b..155449da8 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -27,6 +27,9 @@ pub use bp_darwinia_core as bp_crab; pub use bp_darwinia_core as bp_darwinia; pub use bp_darwinia_core as bp_pangolin; +// #[cfg(feature = "test")] +pub mod test; + // darwinia use dc_primitives::*; // substrate diff --git a/runtime/common/src/test.rs b/runtime/common/src/test.rs new file mode 100644 index 000000000..d64250990 --- /dev/null +++ b/runtime/common/src/test.rs @@ -0,0 +1,310 @@ +#[macro_export] +macro_rules! impl_account_migration_tests { + () => { + mod account_migration { + // darwinia + use super::mock::*; + use darwinia_deposit::Deposit as DepositS; + use darwinia_staking::Ledger; + // substrate + use frame_support::{ + assert_err, assert_ok, migration, traits::Get, Blake2_128Concat, StorageHasher, + }; + use frame_system::AccountInfo; + use pallet_assets::ExistenceReason; + use pallet_balances::AccountData; + use sp_core::{sr25519::Pair, Encode, Pair as PairT, H160}; + use sp_keyring::sr25519::Keyring; + use sp_runtime::{ + traits::ValidateUnsigned, + transaction_validity::{InvalidTransaction, TransactionValidityError}, + AccountId32, DispatchError, + }; + use sp_version::RuntimeVersion; + + const RING_AMOUNT: u128 = 100; + const KTON_AMOUNT: u128 = 100; + + #[derive(Debug, PartialEq, Eq)] + enum E { + T(TransactionValidityError), + D(DispatchError), + } + use E::*; + impl From for E { + fn from(t: TransactionValidityError) -> Self { + T(t) + } + } + impl From for E { + fn from(d: DispatchError) -> Self { + D(d) + } + } + + // This struct is private in `pallet-assets`. + #[derive(Encode)] + struct AssetAccount { + balance: u128, + is_frozen: bool, + reason: ExistenceReason, + extra: (), + } + + // This struct is private in `pallet-vesting`. + #[derive(Encode)] + struct VestingInfo { + locked: u128, + per_block: u128, + starting_block: u32, + } + + fn alice() -> (Pair, AccountId32) { + let pair = Keyring::Alice.pair(); + let public_key = AccountId32::new(pair.public().0); + + (pair, public_key) + } + + fn invalid_transaction(code: u8) -> E { + T(TransactionValidityError::Invalid(InvalidTransaction::Custom(code))) + } + + fn preset_state_of(who: &Pair) { + let account_id_32 = AccountId32::new(who.public().0); + let asset_account = AssetAccount { + balance: KTON_AMOUNT, + is_frozen: false, + reason: ExistenceReason::::Sufficient, + extra: (), + }; + + assert!(AccountMigration::account_of(&account_id_32).is_none()); + assert!(AccountMigration::kton_account_of(&account_id_32).is_none()); + + >::insert( + &account_id_32, + AccountInfo { + nonce: 100, + consumers: 1, + providers: 1, + sufficients: 1, + data: AccountData { free: RING_AMOUNT, ..Default::default() }, + }, + ); + migration::put_storage_value( + b"AccountMigration", + b"KtonAccounts", + &Blake2_128Concat::hash(account_id_32.as_ref()), + asset_account, + ); + assert!(AccountMigration::account_of(&account_id_32).is_some()); + assert!(AccountMigration::kton_account_of(&account_id_32).is_some()); + } + + fn migrate(from: Pair, to: AccountId) -> Result<(), E> { + let message = darwinia_account_migration::sr25519_signable_message( + <::Version as Get>::get() + .spec_name + .as_bytes(), + &to, + ); + let sig = from.sign(&message); + let from_pk = AccountId32::new(from.public().0); + + AccountMigration::pre_dispatch(&darwinia_account_migration::Call::migrate { + from: from_pk.clone(), + to, + signature: sig.clone(), + })?; + AccountMigration::migrate(RuntimeOrigin::none(), from_pk, to, sig)?; + + Ok(()) + } + + #[test] + fn validate_substrate_account_not_found() { + ExtBuilder::default().build().execute_with(|| { + let (from, _) = alice(); + let to = AccountId::default(); + + // Migration source doesn't exist. + assert_err!(migrate(from, to), invalid_transaction(1)); + }); + } + + #[test] + fn validate_evm_account_already_exist() { + let (from, _) = alice(); + let to = H160::from_low_u64_be(33).into(); + + ExtBuilder::default().with_balances(vec![(to, RING_AMOUNT)]).build().execute_with( + || { + preset_state_of(&from); + + // Migration target has already been migrated. + assert_err!(migrate(from, to), invalid_transaction(0)); + }, + ); + } + + #[test] + fn validate_invalid_sig() { + let (from, from_pk) = alice(); + let to = H160::from_low_u64_be(33).into(); + let message = darwinia_account_migration::sr25519_signable_message(b"?", &to); + let sig = from.sign(&message); + + ExtBuilder::default().build().execute_with(|| { + preset_state_of(&from); + + assert_err!( + AccountMigration::pre_dispatch( + &darwinia_account_migration::Call::migrate { + from: from_pk.clone(), + to, + signature: sig.clone(), + } + ) + .map_err(E::from), + invalid_transaction(2) + ); + }); + } + + #[test] + fn migrate_accounts_should_work() { + let (from, from_pk) = alice(); + let to = H160::from_low_u64_be(255).into(); + + ExtBuilder::default().build().execute_with(|| { + preset_state_of(&from); + + assert_ok!(migrate(from, to)); + assert_eq!(AccountMigration::account_of(from_pk), None); + assert_eq!( + System::account(to), + AccountInfo { + nonce: 100, + consumers: 1, + providers: 1, + sufficients: 1, + data: AccountData { free: RING_AMOUNT, ..Default::default() }, + } + ); + }); + } + + #[test] + fn migrate_kton_accounts_should_work() { + let (from, from_pk) = alice(); + let to = H160::from_low_u64_be(255).into(); + + ExtBuilder::default().build().execute_with(|| { + preset_state_of(&from); + + assert_ok!(migrate(from, to)); + assert_eq!(AccountMigration::kton_account_of(from_pk), None); + assert_eq!( + Assets::maybe_balance(KTON_ID, to).unwrap(), + KTON_AMOUNT + ); + }); + } + + #[test] + fn vesting_should_work() { + let (from, from_pk) = alice(); + let to = H160::from_low_u64_be(255).into(); + + ExtBuilder::default().build().execute_with(|| { + preset_state_of(&from); + + migration::put_storage_value( + b"AccountMigration", + b"Vestings", + &Blake2_128Concat::hash(from_pk.as_ref()), + vec![ + VestingInfo { locked: 100, per_block: 5, starting_block: 0 }, + VestingInfo { locked: 100, per_block: 5, starting_block: 0 }, + ], + ); + assert!(Vesting::vesting(to).is_none()); + assert!(Balances::locks(to).is_empty()); + + assert_ok!(migrate(from, to)); + assert_eq!(Vesting::vesting(to).unwrap().len(), 2); + assert_eq!(Balances::locks(to).len(), 1); + }); + } + + #[test] + fn staking_should_work() { + let (from, from_pk) = alice(); + let init = H160::from_low_u64_be(254).into(); + let to = H160::from_low_u64_be(255).into(); + + ExtBuilder::default() + .with_assets_accounts(vec![(KTON_ID, init, KTON_AMOUNT)]) + .build() + .execute_with(|| { + preset_state_of(&from); + + >::insert( + &from_pk, + vec![ + DepositS { + id: 1, + value: 10, + start_time: 1000, + expired_time: 2000, + in_use: true, + }, + DepositS { + id: 2, + value: 10, + start_time: 1000, + expired_time: 2000, + in_use: true, + }, + ], + ); + >::insert( + &from_pk, + Ledger { + staked_ring: 20, + staked_kton: 20, + staked_deposits: Default::default(), + unstaking_ring: Default::default(), + unstaking_kton: Default::default(), + unstaking_deposits: Default::default(), + }, + ); + + assert_ok!(migrate(from, to)); + assert_eq!(Balances::free_balance(to), 60); + assert_eq!( + Balances::free_balance(&darwinia_deposit::account_id::()), + 20 + ); + assert_eq!( + Balances::free_balance(&darwinia_staking::account_id::()), + 20 + ); + assert_eq!(Deposit::deposit_of(to).unwrap().len(), 2); + assert_eq!(Assets::maybe_balance(KTON_ID, to).unwrap(), 80); + assert_eq!( + Assets::maybe_balance( + KTON_ID, + darwinia_staking::account_id::() + ) + .unwrap(), + 20 + ); + assert_eq!(Staking::ledger_of(to).unwrap().staked_ring, 20); + assert_eq!(Staking::ledger_of(to).unwrap().staked_kton, 20); + }); + } + } + }; +} diff --git a/runtime/crab/Cargo.toml b/runtime/crab/Cargo.toml index b61443dee..5fdef26a1 100644 --- a/runtime/crab/Cargo.toml +++ b/runtime/crab/Cargo.toml @@ -128,6 +128,12 @@ frame-benchmarking = { optional = true, default-features = false, git = " frame-system-benchmarking = { optional = true, default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } frame-try-runtime = { optional = true, default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +[dev-dependencies] +# darwinia +darwinia-common-runtime = { features = ["test"], path = "../common" } +# substrate +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } + [features] default = ["std"] std = [ diff --git a/runtime/crab/src/lib.rs b/runtime/crab/src/lib.rs index 1a9efa5c1..64fb84e1e 100644 --- a/runtime/crab/src/lib.rs +++ b/runtime/crab/src/lib.rs @@ -33,12 +33,11 @@ pub use bridges_message::*; mod weights; pub use darwinia_common_runtime::*; +pub use dc_primitives::*; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; // cumulus use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; -// darwinia -use dc_primitives::*; // polkadot use xcm_executor::XcmExecutor; // substrate diff --git a/runtime/crab/tests/account_migration.rs b/runtime/crab/tests/account_migration.rs deleted file mode 100644 index 3e76afa91..000000000 --- a/runtime/crab/tests/account_migration.rs +++ /dev/null @@ -1,330 +0,0 @@ -// This file is part of Darwinia. -// -// Copyright (C) 2018-2022 Darwinia Network -// SPDX-License-Identifier: GPL-3.0 -// -// Darwinia is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Darwinia is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Darwinia. If not, see . - -#![cfg(test)] - -mod mock; -use mock::*; - -// darwinia -use crab_runtime::*; -use darwinia_deposit::Deposit; -use darwinia_staking::Ledger; -use dc_primitives::AccountId; -// substrate -use frame_support::{ - assert_err, assert_ok, migration, traits::Get, Blake2_128Concat, StorageHasher, -}; -use frame_system::AccountInfo; -use pallet_assets::ExistenceReason; -use pallet_balances::AccountData; -use sp_core::{sr25519::Pair, Encode, Pair as PairT, H160}; -use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::ValidateUnsigned, - transaction_validity::{InvalidTransaction, TransactionValidityError}, - AccountId32, DispatchError, DispatchResult, -}; -use sp_version::RuntimeVersion; - -const RING_AMOUNT: u128 = 100; -const KTON_AMOUNT: u128 = 100; - -fn migrate(pair: Pair, to: AccountId, chain_id: u64, spec_name: &[u8]) -> DispatchResult { - let account_id = AccountId32::new(pair.public().0); - - let message = blake2_256( - &[ - &blake2_256(&[&chain_id.to_le_bytes(), spec_name, b"::account-migration"].concat()), - to.0.as_slice(), - ] - .concat(), - ); - let sig = pair.sign(&message); - - AccountMigration::pre_dispatch(&darwinia_account_migration::Call::migrate { - from: account_id.clone(), - to, - signature: sig.clone(), - }) - .map_err(|e| match e { - TransactionValidityError::Invalid(InvalidTransaction::Custom(e)) => - Box::leak(format!("err code: {}", e).into_boxed_str()), - e => <&'static str>::from(e), - })?; - AccountMigration::migrate(RuntimeOrigin::none(), account_id, to, sig) -} - -fn prepare_accounts(storage: bool) -> Pair { - let pair = Pair::from_seed(b"00000000000000000000000000000001"); - let account_id = AccountId32::new(pair.public().0); - - if storage { - >::insert( - account_id.clone(), - AccountInfo { - nonce: 100, - consumers: 1, - providers: 1, - sufficients: 1, - data: AccountData { free: RING_AMOUNT, ..Default::default() }, - }, - ); - - // The struct in the upstream repo is not accessible due to viable. - #[derive(Clone, Encode)] - pub struct AssetAccount { - pub balance: u128, - pub is_frozen: bool, - pub reason: ExistenceReason, - pub extra: (), - } - let asset_account = AssetAccount { - balance: KTON_AMOUNT, - is_frozen: false, - reason: ExistenceReason::::Sufficient, - extra: (), - }; - migration::put_storage_value( - b"AccountMigration", - b"KtonAccounts", - &Blake2_128Concat::hash(account_id.as_ref()), - asset_account.clone(), - ); - assert!(AccountMigration::account_of(account_id).is_some()); - } - pair -} - -#[test] -fn validate_substrate_account_not_found() { - ExtBuilder::default().build().execute_with(|| { - let to = H160::default(); - let pair = prepare_accounts(false); - - assert_err!( - migrate( - pair, - to.into(), - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 1") // The migration source not exist. - ); - }); -} - -#[test] -fn validate_evm_account_already_exist() { - let to = H160::from_low_u64_be(33).into(); - ExtBuilder::default().with_balances(vec![(to, 100)]).build().execute_with(|| { - let pair = prepare_accounts(true); - - assert_err!( - migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 0") // To account has been used. - ); - }); -} - -#[test] -fn validate_invalid_sig() { - let to = H160::from_low_u64_be(33).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - - assert_err!( - migrate( - pair, - to, - <::ChainId as Get>::get() + 1, - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 2") // Invalid signature - ); - }); -} - -#[test] -fn migrate_accounts() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - assert_eq!(AccountMigration::account_of(account_id), None); - assert_eq!( - System::account(to), - AccountInfo { - nonce: 100, - consumers: 1, - providers: 1, - sufficients: 1, - data: AccountData { free: 100, ..Default::default() }, - } - ); - }); -} - -#[test] -fn migrate_kton_accounts() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - assert_eq!(AccountMigration::kton_account_of(account_id), None); - assert_eq!(Assets::maybe_balance(KTON_ID, to).unwrap(), KTON_AMOUNT); - }); -} - -#[test] -fn vesting() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - // The struct in the upstream repo is not accessible due to viable. - #[derive(Encode)] - pub struct VestingInfo { - locked: u128, - per_block: u128, - starting_block: u32, - } - - migration::put_storage_value( - b"AccountMigration", - b"Vestings", - &Blake2_128Concat::hash(account_id.as_ref()), - vec![ - VestingInfo { locked: 100, per_block: 5, starting_block: 0 }, - VestingInfo { locked: 100, per_block: 5, starting_block: 0 }, - ], - ); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - - assert_eq!(Vesting::vesting(to).unwrap().len(), 2); - assert_eq!(Balances::locks(to).len(), 1); - }); -} - -#[test] -fn staking() { - let init = H160::from_low_u64_be(254).into(); - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default() - .with_assets_accounts(vec![(KTON_ID, init, KTON_AMOUNT)]) - .build() - .execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - >::insert( - account_id.clone(), - vec![ - Deposit { - id: 1, - value: 10, - start_time: 1000, - expired_time: 2000, - in_use: true, - }, - Deposit { - id: 2, - value: 10, - start_time: 1000, - expired_time: 2000, - in_use: true, - }, - ], - ); - - >::insert( - account_id.clone(), - Ledger { - staked_ring: 20, - staked_kton: 20, - staked_deposits: vec![].try_into().unwrap(), - unstaking_ring: vec![].try_into().unwrap(), - unstaking_kton: vec![].try_into().unwrap(), - unstaking_deposits: vec![].try_into().unwrap(), - }, - ); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - - assert_eq!(Balances::free_balance(to), 60); - assert_eq!(Balances::free_balance(&darwinia_deposit::account_id::()), 20); - assert_eq!(Balances::free_balance(&darwinia_staking::account_id::()), 20); - - assert_eq!(crab_runtime::Deposit::deposit_of(to).unwrap().len(), 2); - - assert_eq!(Assets::maybe_balance(KTON_ID, to).unwrap(), 80); - assert_eq!( - Assets::maybe_balance(KTON_ID, darwinia_staking::account_id::()) - .unwrap(), - 20 - ); - - assert_eq!(crab_runtime::Staking::ledger_of(to).unwrap().staked_ring, 20); - assert_eq!(crab_runtime::Staking::ledger_of(to).unwrap().staked_kton, 20); - }); -} diff --git a/runtime/crab/tests/mock.rs b/runtime/crab/tests/mock.rs index b67b64fa4..5419a06e2 100644 --- a/runtime/crab/tests/mock.rs +++ b/runtime/crab/tests/mock.rs @@ -16,50 +16,50 @@ // You should have received a copy of the GNU General Public License // along with Darwinia. If not, see . -// darwinia -use crab_runtime::{Runtime, System}; -use darwinia_common_runtime::gov_origin::ROOT; -use dc_primitives::{AccountId, Balance}; -// parity +pub use crab_runtime::*; + +// substrate use frame_support::traits::GenesisBuild; use sp_io::TestExternalities; -pub(crate) const KTON_ID: u64 = 1026; +pub const KTON_ID: u64 = AssetIds::CKton as _; -#[derive(Default, Clone)] +#[derive(Clone, Default)] pub struct ExtBuilder { balances: Vec<(AccountId, Balance)>, assets_accounts: Vec<(u64, AccountId, Balance)>, } - impl ExtBuilder { + pub fn with_balances(&mut self, balances: Vec<(AccountId, Balance)>) -> &mut Self { + self.balances = balances; + + self + } + + pub fn with_assets_accounts(&mut self, accounts: Vec<(u64, AccountId, Balance)>) -> &mut Self { + self.assets_accounts = accounts; + + self + } + pub fn build(&mut self) -> TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: self.balances.clone() } .assimilate_storage(&mut t) .unwrap(); - pallet_assets::GenesisConfig:: { assets: vec![(KTON_ID, ROOT, true, 1)], - metadata: vec![(KTON_ID, b"Test Commitment Token".to_vec(), b"TKTON".to_vec(), 18)], + metadata: vec![(KTON_ID, b"Crab Commitment Token".to_vec(), b"CKTON".to_vec(), 18)], accounts: self.assets_accounts.clone(), } .assimilate_storage(&mut t) .unwrap(); let mut ext = TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } - pub fn with_balances(&mut self, balances: Vec<(AccountId, Balance)>) -> &mut Self { - self.balances = balances; - self - } + ext.execute_with(|| System::set_block_number(1)); - pub fn with_assets_accounts(&mut self, accounts: Vec<(u64, AccountId, Balance)>) -> &mut Self { - self.assets_accounts = accounts; - self + ext } } diff --git a/runtime/crab/tests/tests.rs b/runtime/crab/tests/tests.rs new file mode 100644 index 000000000..43b5d3724 --- /dev/null +++ b/runtime/crab/tests/tests.rs @@ -0,0 +1,3 @@ +pub mod mock; + +darwinia_common_runtime::impl_account_migration_tests! {} diff --git a/runtime/darwinia/Cargo.toml b/runtime/darwinia/Cargo.toml index 8ede78417..9b687de83 100644 --- a/runtime/darwinia/Cargo.toml +++ b/runtime/darwinia/Cargo.toml @@ -128,6 +128,12 @@ frame-benchmarking = { optional = true, default-features = false, git = " frame-system-benchmarking = { optional = true, default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } frame-try-runtime = { optional = true, default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +[dev-dependencies] +# darwinia +darwinia-common-runtime = { features = ["test"], path = "../common" } +# substrate +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } + [features] default = ["std"] std = [ diff --git a/runtime/darwinia/src/lib.rs b/runtime/darwinia/src/lib.rs index f45610bee..2f8a5d9cb 100644 --- a/runtime/darwinia/src/lib.rs +++ b/runtime/darwinia/src/lib.rs @@ -33,12 +33,11 @@ pub use bridges_message::*; mod weights; pub use darwinia_common_runtime::*; +pub use dc_primitives::*; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; // cumulus use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; -// darwinia -use dc_primitives::*; // polkadot use xcm_executor::XcmExecutor; // substrate diff --git a/runtime/darwinia/tests/account_migration.rs b/runtime/darwinia/tests/account_migration.rs deleted file mode 100644 index 603f5e4d3..000000000 --- a/runtime/darwinia/tests/account_migration.rs +++ /dev/null @@ -1,330 +0,0 @@ -// This file is part of Darwinia. -// -// Copyright (C) 2018-2022 Darwinia Network -// SPDX-License-Identifier: GPL-3.0 -// -// Darwinia is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Darwinia is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Darwinia. If not, see . - -#![cfg(test)] - -mod mock; -use mock::*; - -// darwinia -use darwinia_deposit::Deposit; -use darwinia_runtime::*; -use darwinia_staking::Ledger; -use dc_primitives::AccountId; -// substrate -use frame_support::{ - assert_err, assert_ok, migration, traits::Get, Blake2_128Concat, StorageHasher, -}; -use frame_system::AccountInfo; -use pallet_assets::ExistenceReason; -use pallet_balances::AccountData; -use sp_core::{sr25519::Pair, Encode, Pair as PairT, H160}; -use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::ValidateUnsigned, - transaction_validity::{InvalidTransaction, TransactionValidityError}, - AccountId32, DispatchError, DispatchResult, -}; -use sp_version::RuntimeVersion; - -const RING_AMOUNT: u128 = 100; -const KTON_AMOUNT: u128 = 100; - -fn migrate(pair: Pair, to: AccountId, chain_id: u64, spec_name: &[u8]) -> DispatchResult { - let account_id = AccountId32::new(pair.public().0); - - let message = blake2_256( - &[ - &blake2_256(&[&chain_id.to_le_bytes(), spec_name, b"::account-migration"].concat()), - to.0.as_slice(), - ] - .concat(), - ); - let sig = pair.sign(&message); - - AccountMigration::pre_dispatch(&darwinia_account_migration::Call::migrate { - from: account_id.clone(), - to, - signature: sig.clone(), - }) - .map_err(|e| match e { - TransactionValidityError::Invalid(InvalidTransaction::Custom(e)) => - Box::leak(format!("err code: {}", e).into_boxed_str()), - e => <&'static str>::from(e), - })?; - AccountMigration::migrate(RuntimeOrigin::none(), account_id, to, sig) -} - -fn prepare_accounts(storage: bool) -> Pair { - let pair = Pair::from_seed(b"00000000000000000000000000000001"); - let account_id = AccountId32::new(pair.public().0); - - if storage { - >::insert( - account_id.clone(), - AccountInfo { - nonce: 100, - consumers: 1, - providers: 1, - sufficients: 1, - data: AccountData { free: RING_AMOUNT, ..Default::default() }, - }, - ); - - // The struct in the upstream repo is not accessible due to viable. - #[derive(Clone, Encode)] - pub struct AssetAccount { - pub balance: u128, - pub is_frozen: bool, - pub reason: ExistenceReason, - pub extra: (), - } - let asset_account = AssetAccount { - balance: KTON_AMOUNT, - is_frozen: false, - reason: ExistenceReason::::Sufficient, - extra: (), - }; - migration::put_storage_value( - b"AccountMigration", - b"KtonAccounts", - &Blake2_128Concat::hash(account_id.as_ref()), - asset_account.clone(), - ); - assert!(AccountMigration::account_of(account_id).is_some()); - } - pair -} - -#[test] -fn validate_substrate_account_not_found() { - ExtBuilder::default().build().execute_with(|| { - let to = H160::default(); - let pair = prepare_accounts(false); - - assert_err!( - migrate( - pair, - to.into(), - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 1") // The migration source not exist. - ); - }); -} - -#[test] -fn validate_evm_account_already_exist() { - let to = H160::from_low_u64_be(33).into(); - ExtBuilder::default().with_balances(vec![(to, 100)]).build().execute_with(|| { - let pair = prepare_accounts(true); - - assert_err!( - migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 0") // To account has been used. - ); - }); -} - -#[test] -fn validate_invalid_sig() { - let to = H160::from_low_u64_be(33).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - - assert_err!( - migrate( - pair, - to, - <::ChainId as Get>::get() + 1, - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 2") // Invalid signature - ); - }); -} - -#[test] -fn migrate_accounts() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - assert_eq!(AccountMigration::account_of(account_id), None); - assert_eq!( - System::account(to), - AccountInfo { - nonce: 100, - consumers: 1, - providers: 1, - sufficients: 1, - data: AccountData { free: 100, ..Default::default() }, - } - ); - }); -} - -#[test] -fn migrate_kton_accounts() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - assert_eq!(AccountMigration::kton_account_of(account_id), None); - assert_eq!(Assets::maybe_balance(KTON_ID, to).unwrap(), KTON_AMOUNT); - }); -} - -#[test] -fn vesting() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - // The struct in the upstream repo is not accessible due to viable. - #[derive(Encode)] - pub struct VestingInfo { - locked: u128, - per_block: u128, - starting_block: u32, - } - - migration::put_storage_value( - b"AccountMigration", - b"Vestings", - &Blake2_128Concat::hash(account_id.as_ref()), - vec![ - VestingInfo { locked: 100, per_block: 5, starting_block: 0 }, - VestingInfo { locked: 100, per_block: 5, starting_block: 0 }, - ], - ); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - - assert_eq!(Vesting::vesting(to).unwrap().len(), 2); - assert_eq!(Balances::locks(to).len(), 1); - }); -} - -#[test] -fn staking() { - let init = H160::from_low_u64_be(254).into(); - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default() - .with_assets_accounts(vec![(KTON_ID, init, KTON_AMOUNT)]) - .build() - .execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - >::insert( - account_id.clone(), - vec![ - Deposit { - id: 1, - value: 10, - start_time: 1000, - expired_time: 2000, - in_use: true, - }, - Deposit { - id: 2, - value: 10, - start_time: 1000, - expired_time: 2000, - in_use: true, - }, - ], - ); - - >::insert( - account_id.clone(), - Ledger { - staked_ring: 20, - staked_kton: 20, - staked_deposits: vec![].try_into().unwrap(), - unstaking_ring: vec![].try_into().unwrap(), - unstaking_kton: vec![].try_into().unwrap(), - unstaking_deposits: vec![].try_into().unwrap(), - }, - ); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - - assert_eq!(Balances::free_balance(to), 60); - assert_eq!(Balances::free_balance(&darwinia_deposit::account_id::()), 20); - assert_eq!(Balances::free_balance(&darwinia_staking::account_id::()), 20); - - assert_eq!(darwinia_runtime::Deposit::deposit_of(to).unwrap().len(), 2); - - assert_eq!(Assets::maybe_balance(KTON_ID, to).unwrap(), 80); - assert_eq!( - Assets::maybe_balance(KTON_ID, darwinia_staking::account_id::()) - .unwrap(), - 20 - ); - - assert_eq!(darwinia_runtime::Staking::ledger_of(to).unwrap().staked_ring, 20); - assert_eq!(darwinia_runtime::Staking::ledger_of(to).unwrap().staked_kton, 20); - }); -} diff --git a/runtime/darwinia/tests/mock.rs b/runtime/darwinia/tests/mock.rs index 9b2503ae0..ce94f4be4 100644 --- a/runtime/darwinia/tests/mock.rs +++ b/runtime/darwinia/tests/mock.rs @@ -16,50 +16,50 @@ // You should have received a copy of the GNU General Public License // along with Darwinia. If not, see . -// darwinia -use darwinia_common_runtime::gov_origin::ROOT; -use darwinia_runtime::{Runtime, System}; -use dc_primitives::{AccountId, Balance}; -// parity +pub use darwinia_runtime::*; + +// substrate use frame_support::traits::GenesisBuild; use sp_io::TestExternalities; -pub(crate) const KTON_ID: u64 = 1026; +pub const KTON_ID: u64 = AssetIds::Kton as _; -#[derive(Default, Clone)] +#[derive(Clone, Default)] pub struct ExtBuilder { balances: Vec<(AccountId, Balance)>, assets_accounts: Vec<(u64, AccountId, Balance)>, } - impl ExtBuilder { + pub fn with_balances(&mut self, balances: Vec<(AccountId, Balance)>) -> &mut Self { + self.balances = balances; + + self + } + + pub fn with_assets_accounts(&mut self, accounts: Vec<(u64, AccountId, Balance)>) -> &mut Self { + self.assets_accounts = accounts; + + self + } + pub fn build(&mut self) -> TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: self.balances.clone() } .assimilate_storage(&mut t) .unwrap(); - pallet_assets::GenesisConfig:: { assets: vec![(KTON_ID, ROOT, true, 1)], - metadata: vec![(KTON_ID, b"Test Commitment Token".to_vec(), b"TKTON".to_vec(), 18)], + metadata: vec![(KTON_ID, b"Darwinia Commitment Token".to_vec(), b"KTON".to_vec(), 18)], accounts: self.assets_accounts.clone(), } .assimilate_storage(&mut t) .unwrap(); let mut ext = TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } - pub fn with_balances(&mut self, balances: Vec<(AccountId, Balance)>) -> &mut Self { - self.balances = balances; - self - } + ext.execute_with(|| System::set_block_number(1)); - pub fn with_assets_accounts(&mut self, accounts: Vec<(u64, AccountId, Balance)>) -> &mut Self { - self.assets_accounts = accounts; - self + ext } } diff --git a/runtime/darwinia/tests/tests.rs b/runtime/darwinia/tests/tests.rs new file mode 100644 index 000000000..43b5d3724 --- /dev/null +++ b/runtime/darwinia/tests/tests.rs @@ -0,0 +1,3 @@ +pub mod mock; + +darwinia_common_runtime::impl_account_migration_tests! {} diff --git a/runtime/pangolin/Cargo.toml b/runtime/pangolin/Cargo.toml index d6908fd55..aa619b242 100644 --- a/runtime/pangolin/Cargo.toml +++ b/runtime/pangolin/Cargo.toml @@ -127,6 +127,12 @@ frame-benchmarking = { optional = true, default-features = false, git = " frame-system-benchmarking = { optional = true, default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } frame-try-runtime = { optional = true, default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } +[dev-dependencies] +# darwinia +darwinia-common-runtime = { features = ["test"], path = "../common" } +# substrate +sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.30" } + [features] default = ["std"] std = [ diff --git a/runtime/pangolin/src/lib.rs b/runtime/pangolin/src/lib.rs index a4b055299..0ffadeb46 100644 --- a/runtime/pangolin/src/lib.rs +++ b/runtime/pangolin/src/lib.rs @@ -30,12 +30,11 @@ pub use pallets::*; mod weights; pub use darwinia_common_runtime::*; +pub use dc_primitives::*; pub use sp_consensus_aura::sr25519::AuthorityId as AuraId; // cumulus use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; -// darwinia -use dc_primitives::*; // polkadot use xcm_executor::XcmExecutor; // substrate diff --git a/runtime/pangolin/tests/account_migration.rs b/runtime/pangolin/tests/account_migration.rs deleted file mode 100644 index 5edf31de6..000000000 --- a/runtime/pangolin/tests/account_migration.rs +++ /dev/null @@ -1,330 +0,0 @@ -// This file is part of Darwinia. -// -// Copyright (C) 2018-2022 Darwinia Network -// SPDX-License-Identifier: GPL-3.0 -// -// Darwinia is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Darwinia is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Darwinia. If not, see . - -#![cfg(test)] - -mod mock; -use mock::*; - -// darwinia -use darwinia_deposit::Deposit; -use darwinia_staking::Ledger; -use dc_primitives::AccountId; -use pangolin_runtime::*; -// substrate -use frame_support::{ - assert_err, assert_ok, migration, traits::Get, Blake2_128Concat, StorageHasher, -}; -use frame_system::AccountInfo; -use pallet_assets::ExistenceReason; -use pallet_balances::AccountData; -use sp_core::{sr25519::Pair, Encode, Pair as PairT, H160}; -use sp_io::hashing::blake2_256; -use sp_runtime::{ - traits::ValidateUnsigned, - transaction_validity::{InvalidTransaction, TransactionValidityError}, - AccountId32, DispatchError, DispatchResult, -}; -use sp_version::RuntimeVersion; - -const RING_AMOUNT: u128 = 100; -const KTON_AMOUNT: u128 = 100; - -fn migrate(pair: Pair, to: AccountId, chain_id: u64, spec_name: &[u8]) -> DispatchResult { - let account_id = AccountId32::new(pair.public().0); - - let message = blake2_256( - &[ - &blake2_256(&[&chain_id.to_le_bytes(), spec_name, b"::account-migration"].concat()), - to.0.as_slice(), - ] - .concat(), - ); - let sig = pair.sign(&message); - - AccountMigration::pre_dispatch(&darwinia_account_migration::Call::migrate { - from: account_id.clone(), - to, - signature: sig.clone(), - }) - .map_err(|e| match e { - TransactionValidityError::Invalid(InvalidTransaction::Custom(e)) => - Box::leak(format!("err code: {}", e).into_boxed_str()), - e => <&'static str>::from(e), - })?; - AccountMigration::migrate(RuntimeOrigin::none(), account_id, to, sig) -} - -fn prepare_accounts(storage: bool) -> Pair { - let pair = Pair::from_seed(b"00000000000000000000000000000001"); - let account_id = AccountId32::new(pair.public().0); - - if storage { - >::insert( - account_id.clone(), - AccountInfo { - nonce: 100, - consumers: 1, - providers: 1, - sufficients: 1, - data: AccountData { free: RING_AMOUNT, ..Default::default() }, - }, - ); - - // The struct in the upstream repo is not accessible due to viable. - #[derive(Clone, Encode)] - pub struct AssetAccount { - pub balance: u128, - pub is_frozen: bool, - pub reason: ExistenceReason, - pub extra: (), - } - let asset_account = AssetAccount { - balance: KTON_AMOUNT, - is_frozen: false, - reason: ExistenceReason::::Sufficient, - extra: (), - }; - migration::put_storage_value( - b"AccountMigration", - b"KtonAccounts", - &Blake2_128Concat::hash(account_id.as_ref()), - asset_account.clone(), - ); - assert!(AccountMigration::account_of(account_id).is_some()); - } - pair -} - -#[test] -fn validate_substrate_account_not_found() { - ExtBuilder::default().build().execute_with(|| { - let to = H160::default(); - let pair = prepare_accounts(false); - - assert_err!( - migrate( - pair, - to.into(), - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 1") // The migration source not exist. - ); - }); -} - -#[test] -fn validate_evm_account_already_exist() { - let to = H160::from_low_u64_be(33).into(); - ExtBuilder::default().with_balances(vec![(to, 100)]).build().execute_with(|| { - let pair = prepare_accounts(true); - - assert_err!( - migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 0") // To account has been used. - ); - }); -} - -#[test] -fn validate_invalid_sig() { - let to = H160::from_low_u64_be(33).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - - assert_err!( - migrate( - pair, - to, - <::ChainId as Get>::get() + 1, - <::Version as Get>::get() - .spec_name - .as_bytes() - ), - DispatchError::Other("err code: 2") // Invalid signature - ); - }); -} - -#[test] -fn migrate_accounts() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - assert_eq!(AccountMigration::account_of(account_id), None); - assert_eq!( - System::account(to), - AccountInfo { - nonce: 100, - consumers: 1, - providers: 1, - sufficients: 1, - data: AccountData { free: 100, ..Default::default() }, - } - ); - }); -} - -#[test] -fn migrate_kton_accounts() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - assert_eq!(AccountMigration::kton_account_of(account_id), None); - assert_eq!(Assets::maybe_balance(KTON_ID, to).unwrap(), KTON_AMOUNT); - }); -} - -#[test] -fn vesting() { - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default().build().execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - // The struct in the upstream repo is not accessible due to viable. - #[derive(Encode)] - pub struct VestingInfo { - locked: u128, - per_block: u128, - starting_block: u32, - } - - migration::put_storage_value( - b"AccountMigration", - b"Vestings", - &Blake2_128Concat::hash(account_id.as_ref()), - vec![ - VestingInfo { locked: 100, per_block: 5, starting_block: 0 }, - VestingInfo { locked: 100, per_block: 5, starting_block: 0 }, - ], - ); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - - assert_eq!(Vesting::vesting(to).unwrap().len(), 2); - assert_eq!(Balances::locks(to).len(), 1); - }); -} - -#[test] -fn staking() { - let init = H160::from_low_u64_be(254).into(); - let to = H160::from_low_u64_be(255).into(); - ExtBuilder::default() - .with_assets_accounts(vec![(KTON_ID, init, KTON_AMOUNT)]) - .build() - .execute_with(|| { - let pair = prepare_accounts(true); - let account_id = AccountId32::new(pair.public().0); - - >::insert( - account_id.clone(), - vec![ - Deposit { - id: 1, - value: 10, - start_time: 1000, - expired_time: 2000, - in_use: true, - }, - Deposit { - id: 2, - value: 10, - start_time: 1000, - expired_time: 2000, - in_use: true, - }, - ], - ); - - >::insert( - account_id.clone(), - Ledger { - staked_ring: 20, - staked_kton: 20, - staked_deposits: vec![].try_into().unwrap(), - unstaking_ring: vec![].try_into().unwrap(), - unstaking_kton: vec![].try_into().unwrap(), - unstaking_deposits: vec![].try_into().unwrap(), - }, - ); - - assert_ok!(migrate( - pair, - to, - <::ChainId as Get>::get(), - <::Version as Get>::get() - .spec_name - .as_bytes() - )); - - assert_eq!(Balances::free_balance(to), 60); - assert_eq!(Balances::free_balance(&darwinia_deposit::account_id::()), 20); - assert_eq!(Balances::free_balance(&darwinia_staking::account_id::()), 20); - - assert_eq!(pangolin_runtime::Deposit::deposit_of(to).unwrap().len(), 2); - - assert_eq!(Assets::maybe_balance(KTON_ID, to).unwrap(), 80); - assert_eq!( - Assets::maybe_balance(KTON_ID, darwinia_staking::account_id::()) - .unwrap(), - 20 - ); - - assert_eq!(pangolin_runtime::Staking::ledger_of(to).unwrap().staked_ring, 20); - assert_eq!(pangolin_runtime::Staking::ledger_of(to).unwrap().staked_kton, 20); - }); -} diff --git a/runtime/pangolin/tests/mock.rs b/runtime/pangolin/tests/mock.rs index bf14d351e..6daa27e82 100644 --- a/runtime/pangolin/tests/mock.rs +++ b/runtime/pangolin/tests/mock.rs @@ -16,50 +16,50 @@ // You should have received a copy of the GNU General Public License // along with Darwinia. If not, see . -// darwinia -use darwinia_common_runtime::gov_origin::ROOT; -use dc_primitives::{AccountId, Balance}; -use pangolin_runtime::{Runtime, System}; -// parity +pub use pangolin_runtime::*; + +// substrate use frame_support::traits::GenesisBuild; use sp_io::TestExternalities; -pub(crate) const KTON_ID: u64 = 1026; +pub const KTON_ID: u64 = AssetIds::PKton as _; -#[derive(Default, Clone)] +#[derive(Clone, Default)] pub struct ExtBuilder { balances: Vec<(AccountId, Balance)>, assets_accounts: Vec<(u64, AccountId, Balance)>, } - impl ExtBuilder { + pub fn with_balances(&mut self, balances: Vec<(AccountId, Balance)>) -> &mut Self { + self.balances = balances; + + self + } + + pub fn with_assets_accounts(&mut self, accounts: Vec<(u64, AccountId, Balance)>) -> &mut Self { + self.assets_accounts = accounts; + + self + } + pub fn build(&mut self) -> TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); pallet_balances::GenesisConfig:: { balances: self.balances.clone() } .assimilate_storage(&mut t) .unwrap(); - pallet_assets::GenesisConfig:: { assets: vec![(KTON_ID, ROOT, true, 1)], - metadata: vec![(KTON_ID, b"Test Commitment Token".to_vec(), b"TKTON".to_vec(), 18)], + metadata: vec![(KTON_ID, b"Pangolin Commitment Token".to_vec(), b"PKTON".to_vec(), 18)], accounts: self.assets_accounts.clone(), } .assimilate_storage(&mut t) .unwrap(); let mut ext = TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext - } - pub fn with_balances(&mut self, balances: Vec<(AccountId, Balance)>) -> &mut Self { - self.balances = balances; - self - } + ext.execute_with(|| System::set_block_number(1)); - pub fn with_assets_accounts(&mut self, accounts: Vec<(u64, AccountId, Balance)>) -> &mut Self { - self.assets_accounts = accounts; - self + ext } } diff --git a/runtime/pangolin/tests/tests.rs b/runtime/pangolin/tests/tests.rs new file mode 100644 index 000000000..43b5d3724 --- /dev/null +++ b/runtime/pangolin/tests/tests.rs @@ -0,0 +1,3 @@ +pub mod mock; + +darwinia_common_runtime::impl_account_migration_tests! {}