Skip to content
This repository was archived by the owner on Jul 28, 2023. It is now read-only.

Commit 7c716a2

Browse files
authored
Move some tests from sp-mvm to runtime (#190)
* Move some tests from sp-mvm to runtime * Add ensure_root runtime tests
1 parent ca7fdd5 commit 7c716a2

File tree

11 files changed

+279
-13
lines changed

11 files changed

+279
-13
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

runtime/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ sp-io = { default-features = false, git = 'https://github.com/paritytech/substra
104104
assets = { path = '../assets', default-features = false }
105105
env_logger = "0.9.0"
106106
test-log = "0.2.8"
107+
move-core-types = { git = "https://github.com/pontem-network/sp-move-vm.git", rev = "c8ac6f91c7ec95e62afa3ee9ef9884eec113511c", default-features = false }
108+
bcs = { package = "bcs", version = "0.1" }
107109

108110
[dependencies.move-vm]
109111
package = "mvm"

runtime/src/tests/assets/build_assets.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ popd
1717
pushd ./user
1818
dove clean
1919
dove build -b
20+
dove tx "store_system_block()"
21+
dove tx "store_system_timestamp()"
2022
dove tx "transfer<0x1::NOX::NOX>(Alice, 500000000000)" -o=transfer_pont.mvt
2123
dove tx "transfer<0x1::KSM::KSM>(Alice, 500000000000)" -o=transfer_ksm.mvt
2224
dove tx "deposit_bank<0x1::NOX::NOX>(500000000000)" -o=deposit_bank_pont.mvt
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
script {
2+
use PontemFramework::PontBlock;
3+
use RuntimeTests::Store;
4+
5+
fun store_system_block(account: signer) {
6+
Store::store_u64(&account, PontBlock::get_current_block_height());
7+
}
8+
}
9+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
script {
2+
use PontemFramework::PontTimestamp;
3+
use RuntimeTests::Store;
4+
5+
fun store_system_timestamp(account: signer) {
6+
Store::store_u64(&account, PontTimestamp::now_microseconds());
7+
}
8+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module RuntimeTests::Store {
2+
struct U64 has key { val: u64 }
3+
4+
struct U128 has key { val: u128 }
5+
6+
struct Address has key { val: address }
7+
8+
struct VectorU8 has key { val: vector<u8> }
9+
10+
public fun store_u64(account: &signer, val: u64) {
11+
let foo = U64 { val: val };
12+
move_to<U64>(account, foo);
13+
}
14+
15+
public fun store_u128(account: &signer, val: u128) {
16+
let foo = U128 { val: val };
17+
move_to<U128>(account, foo);
18+
}
19+
20+
public fun store_address(account: &signer, val: address) {
21+
let addr = Address { val: val };
22+
move_to<Address>(account, addr);
23+
}
24+
25+
public fun store_vector_u8(account: &signer, val: vector<u8>) {
26+
let vec = VectorU8 { val: val };
27+
move_to<VectorU8>(account, vec);
28+
}
29+
}

runtime/src/tests/ensure_root.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
use crate::tests::mock::{
2+
RuntimeBuilder, Accounts, Origin, TransactionPause, CurrencyId, Currencies, ParachainStaking,
3+
Perbill,
4+
};
5+
use frame_support::{assert_ok, assert_err, error::BadOrigin};
6+
7+
#[test]
8+
fn ensure_root_in_transaction_pause() {
9+
RuntimeBuilder::new().build().execute_with(|| {
10+
assert_ok!(TransactionPause::pause_transaction(
11+
Origin::root(),
12+
b"Balances".to_vec(),
13+
b"transfer".to_vec()
14+
));
15+
assert_err!(
16+
TransactionPause::pause_transaction(
17+
Origin::signed(Accounts::BOB.account()),
18+
b"Balances".to_vec(),
19+
b"transfer".to_vec()
20+
),
21+
BadOrigin
22+
);
23+
})
24+
}
25+
26+
#[test]
27+
fn ensure_root_in_update_balance() {
28+
RuntimeBuilder::new().build().execute_with(|| {
29+
assert_err!(
30+
Currencies::update_balance(
31+
Origin::signed(Accounts::ALICE.account()),
32+
Accounts::ALICE.account().into(),
33+
CurrencyId::NATIVE,
34+
100
35+
),
36+
BadOrigin
37+
);
38+
assert_ok!(Currencies::update_balance(
39+
Origin::root(),
40+
Accounts::ALICE.account().into(),
41+
CurrencyId::NATIVE,
42+
100
43+
));
44+
});
45+
}
46+
47+
#[test]
48+
fn ensure_root_in_parachain_staking() {
49+
RuntimeBuilder::new().build().execute_with(|| {
50+
assert_err!(
51+
ParachainStaking::set_blocks_per_round(
52+
Origin::signed(Accounts::ALICE.account()),
53+
20u32
54+
),
55+
BadOrigin
56+
);
57+
assert_ok!(ParachainStaking::set_blocks_per_round(
58+
Origin::root(),
59+
42u32
60+
));
61+
assert_err!(
62+
ParachainStaking::set_collator_commission(
63+
Origin::signed(Accounts::ALICE.account()),
64+
Perbill::from_percent(5)
65+
),
66+
BadOrigin
67+
);
68+
assert_ok!(ParachainStaking::set_collator_commission(
69+
Origin::root(),
70+
Perbill::from_percent(5)
71+
));
72+
assert_err!(
73+
ParachainStaking::set_total_selected(
74+
Origin::signed(Accounts::ALICE.account()),
75+
42u32
76+
),
77+
BadOrigin
78+
);
79+
assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 42u32));
80+
})
81+
}

runtime/src/tests/mock.rs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
pub use crate::*;
22
use frame_support::sp_io::TestExternalities;
33
use frame_support::traits::GenesisBuild;
4-
use sp_core::crypto::Ss58Codec;
4+
use move_core_types::account_address::AccountAddress;
5+
use sp_core::{Encode, crypto::Ss58Codec};
56
use frame_support::traits::Hooks;
7+
use sp_core::sr25519::Public;
68
use std::include_bytes;
79
use move_vm::genesis::GenesisConfig;
810

@@ -21,26 +23,38 @@ pub fn build_vm_config() -> (ModuleName, FunctionName, FunctionArgs) {
2123
)
2224
}
2325

26+
/// Timestamp multiplier.
27+
pub const TIME_BLOCK_MULTIPLIER: u64 = 12000;
28+
2429
/// User accounts.
2530
pub enum Accounts {
2631
ALICE,
2732
BOB,
2833
}
2934

3035
impl Accounts {
31-
/// Convert account to AccountId.
32-
pub fn account(&self) -> AccountId {
36+
fn ss58(&self) -> &'static str {
3337
match self {
34-
Accounts::ALICE => {
35-
AccountId::from_ss58check("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY")
36-
.unwrap()
37-
}
38-
Accounts::BOB => {
39-
AccountId::from_ss58check("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty")
40-
.unwrap()
41-
}
38+
Accounts::ALICE => "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY",
39+
Accounts::BOB => "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
4240
}
4341
}
42+
43+
/// Convert account to AccountId.
44+
pub fn account(&self) -> AccountId {
45+
AccountId::from_ss58check(self.ss58()).unwrap()
46+
}
47+
48+
pub fn public_key(&self) -> Public {
49+
Public::from_ss58check_with_version(self.ss58()).unwrap().0
50+
}
51+
52+
pub fn addr(&self) -> AccountAddress {
53+
let key = self.public_key().encode();
54+
let mut arr = [0; AccountAddress::LENGTH];
55+
arr.copy_from_slice(&key);
56+
AccountAddress::new(arr)
57+
}
4458
}
4559

4660
impl Into<[u8; 32]> for Accounts {
@@ -61,7 +75,7 @@ pub fn run_to_block(till: u32) {
6175
Scheduler::on_finalize(System::block_number());
6276
Balances::on_finalize(System::block_number());
6377
System::set_block_number(System::block_number() + 1);
64-
Timestamp::set_timestamp(System::block_number() as u64 * 12000);
78+
Timestamp::set_timestamp(System::block_number() as u64 * TIME_BLOCK_MULTIPLIER);
6579
Scheduler::on_initialize(System::block_number());
6680
ParachainStaking::on_initialize(System::block_number());
6781
TransactionPause::on_initialize(System::block_number());

runtime/src/tests/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ pub mod vesting;
77

88
// Parachain tests.
99
pub mod parachain;
10+
11+
// MVM scripts tests
12+
pub mod scripts;
13+
14+
// Root access tests
15+
pub mod ensure_root;

runtime/src/tests/scripts.rs

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
use crate::tests::mock::{RuntimeBuilder, Accounts, Mvm, Origin, run_to_block, TIME_BLOCK_MULTIPLIER};
2+
use frame_support::assert_ok;
3+
use move_core_types::{
4+
language_storage::StructTag, identifier::Identifier, account_address::AccountAddress,
5+
resolver::ResourceResolver,
6+
};
7+
use sp_mvm::storage::MoveVmStorage;
8+
use move_vm::io::state::State;
9+
10+
pub mod modules {
11+
use assets::Asset;
12+
pub static STORE: Asset = Asset::new(
13+
"Store",
14+
"src/tests/assets/user/build/assets/bytecode_modules/Store.mv",
15+
);
16+
}
17+
18+
pub mod transactions {
19+
use assets::Asset;
20+
pub static STORE_SYSTEM_BLOCK: Asset = Asset::new(
21+
"store_system_block",
22+
"src/tests/assets/user/build/assets/transaction/store_system_block.mvt",
23+
);
24+
pub static STORE_SYSTEM_TIMESTAMP: Asset = Asset::new(
25+
"store_system_timestamp",
26+
"src/tests/assets/user/build/assets/transaction/store_system_timestamp.mvt",
27+
);
28+
}
29+
30+
const GAS_LIMIT: u64 = 1_000_000;
31+
32+
/// Check stored value (u64) inside storage.
33+
fn check_stored_value(expected: u64) {
34+
#[derive(serde::Deserialize, Debug, PartialEq)]
35+
struct StoreU64 {
36+
pub val: u64,
37+
}
38+
39+
let expected = StoreU64 { val: expected };
40+
41+
let tag = StructTag {
42+
address: Accounts::BOB.addr(),
43+
module: Identifier::new(modules::STORE.name()).unwrap(),
44+
name: Identifier::new("U64").unwrap(),
45+
type_params: vec![],
46+
};
47+
48+
check_storage_res(Accounts::BOB.addr(), tag, expected);
49+
}
50+
51+
/// Check resource value inside storage.
52+
pub fn check_storage_res<T>(owner: AccountAddress, ty: StructTag, expected: T)
53+
where
54+
T: for<'de> serde::Deserialize<'de>,
55+
T: std::cmp::PartialEq + std::fmt::Debug,
56+
{
57+
let storage = Mvm::move_vm_storage();
58+
let state = State::new(storage);
59+
let blob = state
60+
.get_resource(&owner, &ty)
61+
.expect("VM state read storage (resource)")
62+
.expect(&format!("Resource '{}' should exist", ty));
63+
64+
let tt_str = format!("{}", ty);
65+
println!("checking stored resource '{}'", tt_str);
66+
let stored: T =
67+
bcs::from_bytes(&blob).expect(&format!("Resource '{}' should exists", tt_str));
68+
assert_eq!(expected, stored);
69+
}
70+
71+
#[test]
72+
/// Execute storing of block height inside module by calling script.
73+
fn execute_store_block() {
74+
RuntimeBuilder::new().build().execute_with(|| {
75+
// Publish STORE module.
76+
assert_ok!(Mvm::publish_module(
77+
Origin::signed(Accounts::BOB.account()),
78+
modules::STORE.bytes().to_vec(),
79+
GAS_LIMIT
80+
));
81+
82+
const EXPECTED: u32 = 3;
83+
run_to_block(EXPECTED);
84+
assert_ok!(Mvm::execute(
85+
Origin::signed(Accounts::BOB.account()),
86+
transactions::STORE_SYSTEM_BLOCK.bytes().to_vec(),
87+
GAS_LIMIT
88+
));
89+
check_stored_value(EXPECTED.into());
90+
});
91+
}
92+
93+
#[test]
94+
/// Execute storing of timestamp inside module by calling script.
95+
fn execute_store_time() {
96+
RuntimeBuilder::new().build().execute_with(|| {
97+
// Publish STORE module.
98+
assert_ok!(Mvm::publish_module(
99+
Origin::signed(Accounts::BOB.account()),
100+
modules::STORE.bytes().to_vec(),
101+
GAS_LIMIT
102+
));
103+
104+
const EXPECTED: u32 = 3;
105+
run_to_block(EXPECTED);
106+
assert_ok!(Mvm::execute(
107+
Origin::signed(Accounts::BOB.account()),
108+
transactions::STORE_SYSTEM_TIMESTAMP.bytes().to_vec(),
109+
GAS_LIMIT
110+
));
111+
check_stored_value(EXPECTED as u64 * TIME_BLOCK_MULTIPLIER);
112+
});
113+
}

0 commit comments

Comments
 (0)