From 7fe65c4d1baa7751a158a3902631686567b8a6d4 Mon Sep 17 00:00:00 2001 From: Belousov Maksim Date: Mon, 28 Mar 2022 15:57:44 +0300 Subject: [PATCH 1/4] Move some tests from sp-mvm to runtime. --- Cargo.lock | 2 + runtime/Cargo.toml | 2 + runtime/tests/assets/build_assets.sh | 42 ++ runtime/tests/assets/root/.gitignore | 2 + runtime/tests/assets/root/Dove.toml | 14 + runtime/tests/assets/root/Move.toml | 17 + runtime/tests/assets/root/doc.toml | 11 + .../tests/assets/root/sources/EventProxy.move | 14 + runtime/tests/assets/root/sources/Store.move | 29 ++ runtime/tests/assets/user/.gitignore | 2 + runtime/tests/assets/user/Dove.toml | 14 + runtime/tests/assets/user/Move.toml | 19 + runtime/tests/assets/user/doc.toml | 11 + runtime/tests/assets/user/scripts/AsRoot.move | 8 + .../assets/user/scripts/DepositBank.move | 12 + .../tests/assets/user/scripts/EmitEvent.move | 7 + .../tests/assets/user/scripts/InfLoop.move | 11 + .../assets/user/scripts/MultisigTest.move | 8 + .../assets/user/scripts/NativeBalance.move | 11 + .../tests/assets/user/scripts/Signers.move | 5 + .../assets/user/scripts/StoreScript.move | 7 + .../tests/assets/user/scripts/SysBlock.move | 8 + .../assets/user/scripts/SysTimestamp.move | 8 + .../assets/user/scripts/TokenBalance.move | 11 + .../tests/assets/user/scripts/Transfer.move | 13 + runtime/tests/assets/user/sources/Bank.move | 22 ++ .../tests/assets/user/sources/EventProxy.move | 16 + runtime/tests/assets/user/sources/Store.move | 29 ++ runtime/tests/common/addr.rs | 68 ++++ runtime/tests/common/assets.rs | 110 ++++++ runtime/tests/common/mocks.rs | 363 ++++++++++++++++++ runtime/tests/common/mod.rs | 5 + runtime/tests/common/utils.rs | 150 ++++++++ runtime/tests/common/vm_config.rs | 20 + runtime/tests/scripts.rs | 76 ++++ 35 files changed, 1147 insertions(+) create mode 100755 runtime/tests/assets/build_assets.sh create mode 100644 runtime/tests/assets/root/.gitignore create mode 100644 runtime/tests/assets/root/Dove.toml create mode 100644 runtime/tests/assets/root/Move.toml create mode 100644 runtime/tests/assets/root/doc.toml create mode 100644 runtime/tests/assets/root/sources/EventProxy.move create mode 100644 runtime/tests/assets/root/sources/Store.move create mode 100644 runtime/tests/assets/user/.gitignore create mode 100644 runtime/tests/assets/user/Dove.toml create mode 100644 runtime/tests/assets/user/Move.toml create mode 100644 runtime/tests/assets/user/doc.toml create mode 100644 runtime/tests/assets/user/scripts/AsRoot.move create mode 100644 runtime/tests/assets/user/scripts/DepositBank.move create mode 100644 runtime/tests/assets/user/scripts/EmitEvent.move create mode 100644 runtime/tests/assets/user/scripts/InfLoop.move create mode 100644 runtime/tests/assets/user/scripts/MultisigTest.move create mode 100644 runtime/tests/assets/user/scripts/NativeBalance.move create mode 100644 runtime/tests/assets/user/scripts/Signers.move create mode 100644 runtime/tests/assets/user/scripts/StoreScript.move create mode 100644 runtime/tests/assets/user/scripts/SysBlock.move create mode 100644 runtime/tests/assets/user/scripts/SysTimestamp.move create mode 100644 runtime/tests/assets/user/scripts/TokenBalance.move create mode 100644 runtime/tests/assets/user/scripts/Transfer.move create mode 100644 runtime/tests/assets/user/sources/Bank.move create mode 100644 runtime/tests/assets/user/sources/EventProxy.move create mode 100644 runtime/tests/assets/user/sources/Store.move create mode 100644 runtime/tests/common/addr.rs create mode 100644 runtime/tests/common/assets.rs create mode 100644 runtime/tests/common/mocks.rs create mode 100644 runtime/tests/common/mod.rs create mode 100644 runtime/tests/common/utils.rs create mode 100644 runtime/tests/common/vm_config.rs create mode 100644 runtime/tests/scripts.rs diff --git a/Cargo.lock b/Cargo.lock index fc1438cf..74b164d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8045,6 +8045,7 @@ name = "pontem-runtime" version = "3.0.0" dependencies = [ "assets", + "bcs 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "constants", "cumulus-pallet-dmp-queue", "cumulus-pallet-parachain-system", @@ -8064,6 +8065,7 @@ dependencies = [ "hex-literal", "kusama-runtime", "module-currencies", + "move-core-types", "mvm", "nimbus-primitives", "orml-tokens", diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 0fc82e8f..19eaa360 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -104,6 +104,8 @@ sp-io = { default-features = false, git = 'https://github.com/paritytech/substra assets = { path = '../assets', default-features = false } env_logger = "0.9.0" test-log = "0.2.8" +move-core-types = { git = "https://github.com/pontem-network/sp-move-vm.git", rev = "c8ac6f91c7ec95e62afa3ee9ef9884eec113511c", default-features = false } +bcs = { package = "bcs", version = "0.1" } [dependencies.move-vm] package = "mvm" diff --git a/runtime/tests/assets/build_assets.sh b/runtime/tests/assets/build_assets.sh new file mode 100755 index 00000000..2816b010 --- /dev/null +++ b/runtime/tests/assets/build_assets.sh @@ -0,0 +1,42 @@ +# Clone move-stdlib +rm -rf ./move-stdlib +git clone https://github.com/pontem-network/move-stdlib ./move-stdlib +pushd ./move-stdlib +git checkout release-v1.0.0 +dove build -b +popd + +# Clone pont-stdlib +rm -rf ./pont-stdlib +git clone https://github.com/pontem-network/pont-stdlib.git ./pont-stdlib +pushd ./pont-stdlib +git checkout release-v1.0.0 +dove build -b +popd + +pushd ./user +dove clean +dove build +dove build -b +dove tx "store_u64(42)" +dove tx "emit_event(42)" +dove tx "store_system_block()" +dove tx "store_system_timestamp()" +dove tx "inf_loop()" +dove tx "store_native_balance()" +dove tx "store_token_balance()" +dove tx "as_root(dr)" +dove tx "transfer<0x1::NOX::NOX>(Alice, 2000)" -o=transfer.mvt +dove tx "transfer<0x1::KSM::KSM>(Alice, 2000)" -o=transfer_token.mvt +dove tx "multisig_test()" +dove tx "deposit_bank<0x1::NOX::NOX>(2000)" -o=deposit_bank_pont.mvt +dove tx "deposit_bank<0x1::KSM::KSM>(2000)" -o=deposit_bank_ksm.mvt +dove tx "signer_one()" -o=signer_user.mvt +dove tx "signer_one(root)" -o=signer_root.mvt +popd + +pushd ./root +dove clean +dove build +dove build -b +pushd diff --git a/runtime/tests/assets/root/.gitignore b/runtime/tests/assets/root/.gitignore new file mode 100644 index 00000000..6eeec870 --- /dev/null +++ b/runtime/tests/assets/root/.gitignore @@ -0,0 +1,2 @@ +build +target diff --git a/runtime/tests/assets/root/Dove.toml b/runtime/tests/assets/root/Dove.toml new file mode 100644 index 00000000..b2fde8a4 --- /dev/null +++ b/runtime/tests/assets/root/Dove.toml @@ -0,0 +1,14 @@ +[package] +name = "assets" +dialect = "pont" +dove_version = ">=1.5.5" + +# account_address = "0x0" # dev/null +account_address = "0x1" # std +# account_address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" # Alice +# account_address = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" # Bob +# account_address = "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48" # Bob + +dependencies = [ + { git = "https://github.com/pontem-network/pont-stdlib.git", rev = "e9bd26720c06705d2e222833a496fda7c67c8e32" }, +] diff --git a/runtime/tests/assets/root/Move.toml b/runtime/tests/assets/root/Move.toml new file mode 100644 index 00000000..e23b3443 --- /dev/null +++ b/runtime/tests/assets/root/Move.toml @@ -0,0 +1,17 @@ +[package] +name = "assets" +version = "0.0.1" +authors = [] +dialect = "Pont" +dove_version = ">=1.5.5" + +[addresses] +RootTests = "0x1" + +[dependencies.PontStdlib] +git = "https://github.com/pontem-network/pont-stdlib.git" +rev = "release-v1.0.0" + +[dependencies.MoveStdlib] +git = "https://github.com/pontem-network/move-stdlib.git" +rev = "release-v1.0.0" diff --git a/runtime/tests/assets/root/doc.toml b/runtime/tests/assets/root/doc.toml new file mode 100644 index 00000000..b5336de3 --- /dev/null +++ b/runtime/tests/assets/root/doc.toml @@ -0,0 +1,11 @@ +enabled = true +section_level_start = 1 +include_private_fun = true +include_specs = true +specs_inlined = true +include_impl = true +toc_depth = 3 +collapsed_sections = true +root_doc_templates = [] +include_dep_diagrams = false +include_call_diagrams = false diff --git a/runtime/tests/assets/root/sources/EventProxy.move b/runtime/tests/assets/root/sources/EventProxy.move new file mode 100644 index 00000000..c60a2f54 --- /dev/null +++ b/runtime/tests/assets/root/sources/EventProxy.move @@ -0,0 +1,14 @@ +module RootTests::EventProxy { + use Std::Event; + + struct U64 has store, drop, copy { val: u64 } + + public fun emit_event(acc: signer, val: u64) { + let event_handle = Event::new_event_handle(&acc); + Event::emit_event( + &mut event_handle, + U64 { val } + ); + Event::destroy_handle(event_handle); + } +} diff --git a/runtime/tests/assets/root/sources/Store.move b/runtime/tests/assets/root/sources/Store.move new file mode 100644 index 00000000..27801068 --- /dev/null +++ b/runtime/tests/assets/root/sources/Store.move @@ -0,0 +1,29 @@ +module RootTests::Store { + struct U64 has key { val: u64 } + + struct U128 has key { val: u128 } + + struct Address has key { val: address } + + struct VectorU8 has key { val: vector } + + public fun store_u64(account: &signer, val: u64) { + let foo = U64 { val: val }; + move_to(account, foo); + } + + public fun store_u128(account: &signer, val: u128) { + let foo = U128 { val: val }; + move_to(account, foo); + } + + public fun store_address(account: &signer, val: address) { + let addr = Address { val: val }; + move_to
(account, addr); + } + + public fun store_vector_u8(account: &signer, val: vector) { + let vec = VectorU8 { val: val }; + move_to(account, vec); + } +} diff --git a/runtime/tests/assets/user/.gitignore b/runtime/tests/assets/user/.gitignore new file mode 100644 index 00000000..6eeec870 --- /dev/null +++ b/runtime/tests/assets/user/.gitignore @@ -0,0 +1,2 @@ +build +target diff --git a/runtime/tests/assets/user/Dove.toml b/runtime/tests/assets/user/Dove.toml new file mode 100644 index 00000000..46cca600 --- /dev/null +++ b/runtime/tests/assets/user/Dove.toml @@ -0,0 +1,14 @@ +[package] +name = "assets" +dialect = "pont" +dove_version = ">=1.5.5" + +# account_address = "0x0" # dev/null +# account_address = "0x1" # std +# account_address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" # Alice +account_address = "gkNW9pAcCHxZrnoVkhLkEQtsLsW5NWTC75cdAdxAMs9LNYCYg" # Bob +# account_address = "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48" # Bob + +dependencies = [ + { git = "https://github.com/pontem-network/pont-stdlib.git", rev = "e9bd26720c06705d2e222833a496fda7c67c8e32" } +] diff --git a/runtime/tests/assets/user/Move.toml b/runtime/tests/assets/user/Move.toml new file mode 100644 index 00000000..61802b00 --- /dev/null +++ b/runtime/tests/assets/user/Move.toml @@ -0,0 +1,19 @@ +[package] +name = "assets" +version = "0.0.1" +authors = [] +dialect = "Pont" +dove_version = ">=1.5.5" + +[addresses] +UserTests = "gkNW9pAcCHxZrnoVkhLkEQtsLsW5NWTC75cdAdxAMs9LNYCYg" +Alice = "gkQ5K6EnLRgZkwozG8GiBAEnJyM6FxzbSaSmVhKJ2w8FcK7ih" +Bob = "gkNW9pAcCHxZrnoVkhLkEQtsLsW5NWTC75cdAdxAMs9LNYCYg" + +[dependencies.PontStdlib] +git = "https://github.com/pontem-network/pont-stdlib.git" +rev = "release-v1.0.0" + +[dependencies.MoveStdlib] +git = "https://github.com/pontem-network/move-stdlib.git" +rev = "release-v1.0.0" diff --git a/runtime/tests/assets/user/doc.toml b/runtime/tests/assets/user/doc.toml new file mode 100644 index 00000000..b5336de3 --- /dev/null +++ b/runtime/tests/assets/user/doc.toml @@ -0,0 +1,11 @@ +enabled = true +section_level_start = 1 +include_private_fun = true +include_specs = true +specs_inlined = true +include_impl = true +toc_depth = 3 +collapsed_sections = true +root_doc_templates = [] +include_dep_diagrams = false +include_call_diagrams = false diff --git a/runtime/tests/assets/user/scripts/AsRoot.move b/runtime/tests/assets/user/scripts/AsRoot.move new file mode 100644 index 00000000..f0b0a75e --- /dev/null +++ b/runtime/tests/assets/user/scripts/AsRoot.move @@ -0,0 +1,8 @@ +script { + use Std::Signer; + + fun as_root(root: signer) { + assert!(Signer::address_of(&root) == @Root, 1); + } +} + \ No newline at end of file diff --git a/runtime/tests/assets/user/scripts/DepositBank.move b/runtime/tests/assets/user/scripts/DepositBank.move new file mode 100644 index 00000000..2c214cac --- /dev/null +++ b/runtime/tests/assets/user/scripts/DepositBank.move @@ -0,0 +1,12 @@ +script { + use PontemFramework::PontAccount; + use UserTests::Bank; + + fun deposit_bank(sender: signer, amount: u64) { + // Withdraw TokenType tokens from sender account. + let tokens = PontAccount::withdraw(&sender, amount); + + Bank::deposit(&sender, tokens); + } +} + \ No newline at end of file diff --git a/runtime/tests/assets/user/scripts/EmitEvent.move b/runtime/tests/assets/user/scripts/EmitEvent.move new file mode 100644 index 00000000..5d7447ca --- /dev/null +++ b/runtime/tests/assets/user/scripts/EmitEvent.move @@ -0,0 +1,7 @@ +script { + use UserTests::EventProxy; + + fun emit_event(acc: signer, val: u64) { + EventProxy::emit_event(&acc, val); + } +} diff --git a/runtime/tests/assets/user/scripts/InfLoop.move b/runtime/tests/assets/user/scripts/InfLoop.move new file mode 100644 index 00000000..fc50344d --- /dev/null +++ b/runtime/tests/assets/user/scripts/InfLoop.move @@ -0,0 +1,11 @@ +script { + fun inf_loop() { + let i = 0; + + loop { + if (i > 1000) { + break + } + } + } +} diff --git a/runtime/tests/assets/user/scripts/MultisigTest.move b/runtime/tests/assets/user/scripts/MultisigTest.move new file mode 100644 index 00000000..82454080 --- /dev/null +++ b/runtime/tests/assets/user/scripts/MultisigTest.move @@ -0,0 +1,8 @@ +script { + use Std::Signer; + + fun multisig_test(account1: signer, account2: signer) { + assert!(Signer::address_of(&account1) == @Alice, 1); // Alice + assert!(Signer::address_of(&account2) == @Bob, 1); // Bob + } +} diff --git a/runtime/tests/assets/user/scripts/NativeBalance.move b/runtime/tests/assets/user/scripts/NativeBalance.move new file mode 100644 index 00000000..191438f3 --- /dev/null +++ b/runtime/tests/assets/user/scripts/NativeBalance.move @@ -0,0 +1,11 @@ +script { + use PontemFramework::PontAccount; + use PontemFramework::NOX::NOX; + use Std::Signer; + use UserTests::Store; + + fun store_native_balance(account: signer) { + let balance = PontAccount::balance(Signer::address_of(&account)); + Store::store_u64(&account, balance); + } +} diff --git a/runtime/tests/assets/user/scripts/Signers.move b/runtime/tests/assets/user/scripts/Signers.move new file mode 100644 index 00000000..6a8c8cb4 --- /dev/null +++ b/runtime/tests/assets/user/scripts/Signers.move @@ -0,0 +1,5 @@ +script { + // Just one signer required + fun signer_one(_s: signer) { + } +} diff --git a/runtime/tests/assets/user/scripts/StoreScript.move b/runtime/tests/assets/user/scripts/StoreScript.move new file mode 100644 index 00000000..49c13421 --- /dev/null +++ b/runtime/tests/assets/user/scripts/StoreScript.move @@ -0,0 +1,7 @@ +script { + use UserTests::Store; + + fun store_u64(account: signer, val: u64) { + Store::store_u64(&account, val); + } +} diff --git a/runtime/tests/assets/user/scripts/SysBlock.move b/runtime/tests/assets/user/scripts/SysBlock.move new file mode 100644 index 00000000..10f36818 --- /dev/null +++ b/runtime/tests/assets/user/scripts/SysBlock.move @@ -0,0 +1,8 @@ +script { + use PontemFramework::PontBlock; + use UserTests::Store; + + fun store_system_block(account: signer) { + Store::store_u64(&account, PontBlock::get_current_block_height()); + } +} diff --git a/runtime/tests/assets/user/scripts/SysTimestamp.move b/runtime/tests/assets/user/scripts/SysTimestamp.move new file mode 100644 index 00000000..03614a0d --- /dev/null +++ b/runtime/tests/assets/user/scripts/SysTimestamp.move @@ -0,0 +1,8 @@ +script { + use PontemFramework::PontTimestamp; + use UserTests::Store; + + fun store_system_timestamp(account: signer) { + Store::store_u64(&account, PontTimestamp::now_microseconds()); + } +} diff --git a/runtime/tests/assets/user/scripts/TokenBalance.move b/runtime/tests/assets/user/scripts/TokenBalance.move new file mode 100644 index 00000000..6112863b --- /dev/null +++ b/runtime/tests/assets/user/scripts/TokenBalance.move @@ -0,0 +1,11 @@ +script { + use PontemFramework::PontAccount; + use PontemFramework::KSM::KSM; + use Std::Signer; + use UserTests::Store; + + fun store_token_balance(account: signer) { + let balance = PontAccount::balance(Signer::address_of(&account)); + Store::store_u64(&account, balance); + } +} diff --git a/runtime/tests/assets/user/scripts/Transfer.move b/runtime/tests/assets/user/scripts/Transfer.move new file mode 100644 index 00000000..5f8c4e94 --- /dev/null +++ b/runtime/tests/assets/user/scripts/Transfer.move @@ -0,0 +1,13 @@ +script { + use PontemFramework::PontAccount; + use Std::Signer; + use UserTests::Store; + + // Transfer from Bob to Alice. + fun transfer(bob: signer, alice: address, to_move: u64) { + PontAccount::pay_from(&bob, alice, to_move); + + let balance = PontAccount::balance(Signer::address_of(&bob)); + Store::store_u64(&bob, balance); + } +} diff --git a/runtime/tests/assets/user/sources/Bank.move b/runtime/tests/assets/user/sources/Bank.move new file mode 100644 index 00000000..760b6d52 --- /dev/null +++ b/runtime/tests/assets/user/sources/Bank.move @@ -0,0 +1,22 @@ +/// Bank module (stores tokens inside module). +module UserTests::Bank { + use Std::Signer; + use PontemFramework::Token::{Self, Token}; + + struct Storage has key, store { + balance: Token, + } + + public fun deposit(account: &signer, deposit: Token) acquires Storage { + let addr = Signer::address_of(account); + + if (!exists>(addr)) { + move_to(account, Storage { + balance: deposit + }); + } else { + let storage = borrow_global_mut>(addr); + Token::deposit(&mut storage.balance, deposit); + } + } +} diff --git a/runtime/tests/assets/user/sources/EventProxy.move b/runtime/tests/assets/user/sources/EventProxy.move new file mode 100644 index 00000000..c9412b07 --- /dev/null +++ b/runtime/tests/assets/user/sources/EventProxy.move @@ -0,0 +1,16 @@ +module UserTests::EventProxy { + use Std::Event; + + struct U64 has store, drop, copy { val: u64 } + + public fun emit_event(acc: &signer, val: u64) { + let event_handle = Event::new_event_handle(acc); + + Event::emit_event( + &mut event_handle, + U64 { val } + ); + + Event::destroy_handle(event_handle); + } +} diff --git a/runtime/tests/assets/user/sources/Store.move b/runtime/tests/assets/user/sources/Store.move new file mode 100644 index 00000000..951d7a53 --- /dev/null +++ b/runtime/tests/assets/user/sources/Store.move @@ -0,0 +1,29 @@ +module UserTests::Store { + struct U64 has key { val: u64 } + + struct U128 has key { val: u128 } + + struct Address has key { val: address } + + struct VectorU8 has key { val: vector } + + public fun store_u64(account: &signer, val: u64) { + let foo = U64 { val: val }; + move_to(account, foo); + } + + public fun store_u128(account: &signer, val: u128) { + let foo = U128 { val: val }; + move_to(account, foo); + } + + public fun store_address(account: &signer, val: address) { + let addr = Address { val: val }; + move_to
(account, addr); + } + + public fun store_vector_u8(account: &signer, val: vector) { + let vec = VectorU8 { val: val }; + move_to(account, vec); + } +} diff --git a/runtime/tests/common/addr.rs b/runtime/tests/common/addr.rs new file mode 100644 index 00000000..585bb4a5 --- /dev/null +++ b/runtime/tests/common/addr.rs @@ -0,0 +1,68 @@ +#![allow(dead_code)] +/// Mock addresses. +use codec::Encode; +use sp_core::sr25519::Public; +use sp_core::crypto::Ss58Codec; +use move_core_types::account_address::AccountAddress; +pub use move_core_types::language_storage::CORE_CODE_ADDRESS as ROOT_ADDR; +use sp_mvm::addr::account_to_account_address; + +pub const BOB_SS58: &str = "gkNW9pAcCHxZrnoVkhLkEQtsLsW5NWTC75cdAdxAMs9LNYCYg"; +pub const ALICE_SS58: &str = "gkQ5K6EnLRgZkwozG8GiBAEnJyM6FxzbSaSmVhKJ2w8FcK7ih"; + +/// Public key of Bob account. +pub fn bob_public_key() -> Public { + Public::from_ss58check_with_version(BOB_SS58).unwrap().0 +} + +/// Public key of alice account. +pub fn alice_public_key() -> Public { + Public::from_ss58check_with_version(ALICE_SS58).unwrap().0 +} + +/// Returns `AccountAddress` for Bob. +pub fn origin_move_addr() -> AccountAddress { + let pk = bob_public_key(); + let vec = pk.encode(); + let mut arr = [0; AccountAddress::LENGTH]; + arr.copy_from_slice(&vec); + AccountAddress::new(arr) +} + +/// Returns `AccountAddress` for Alice. +pub fn alice_move_addr() -> AccountAddress { + let pk = alice_public_key(); + let vec = pk.encode(); + let mut arr = [0; AccountAddress::LENGTH]; + arr.copy_from_slice(&vec); + AccountAddress::new(arr) +} + +/// Returns `AccountAddress` for provided public key. +pub fn to_move_addr(pk: Public) -> AccountAddress { + account_to_account_address(&pk) +} + +#[cfg(test)] +mod tests { + #[test] + fn origin_move_addr() { + let expected = super::AccountAddress::from_hex_literal( + "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", + ) + .unwrap(); + assert_eq!(expected, super::origin_move_addr()); + } + + #[test] + fn origin_to_move_addr() { + use super::*; + + let expected = AccountAddress::from_hex_literal( + "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", + ) + .unwrap(); + let addr = to_move_addr(bob_public_key()); + assert_eq!(expected, addr); + } +} diff --git a/runtime/tests/common/assets.rs b/runtime/tests/common/assets.rs new file mode 100644 index 00000000..438015ef --- /dev/null +++ b/runtime/tests/common/assets.rs @@ -0,0 +1,110 @@ +#![allow(dead_code)] +/// Assets (Move modules/scripts/packages). +pub use assets::*; + +/// Package built using root account. +pub static ROOT_PACKAGE: Package = Package::new( + &["EventProxy", "Store"], + Asset::new("", "tests/assets/root/build/assets/bundles/assets.pac"), +); +/// Package built using user account. +pub static USER_PACKAGE: Package = Package::new( + &["Bank", "EventProxy", "Store"], + Asset::new("", "tests/assets/user/build/assets/bundles/assets.pac"), +); + +/// Modules assets (root/user). +pub mod modules { + pub mod root { + use super::super::Asset; + pub static STORE: Asset = Asset::new( + "Store", + "tests/assets/root/build/assets/bytecode_modules/Store.mv", + ); + pub static EVENT_PROXY: Asset = Asset::new( + "EventProxy", + "tests/assets/root/build/assets/bytecode_modules/EventProxy.mv", + ); + } + + pub mod user { + use super::super::Asset; + pub static STORE: Asset = Asset::new( + "Store", + "tests/assets/user/build/assets//bytecode_modules/Store.mv", + ); + pub static EVENT_PROXY: Asset = Asset::new( + "EventProxy", + "tests/assets/user/build/assets//bytecode_modules/EventProxy.mv", + ); + pub static BANK: Asset = Asset::new( + "Bank", + "tests/assets/user/build/assets/bytecode_modules/Bank.mv", + ); + } +} + +/// Transaction (scripts) assets. +pub mod transactions { + use super::Asset; + pub static STORE_U64: Asset = Asset::new( + "store_u64", + "tests/assets/user/build/assets/transaction/store_u64.mvt", + ); + pub static EMIT_EVENT: Asset = Asset::new( + "emit_event", + "tests/assets/user/build/assets/transaction/emit_event.mvt", + ); + pub static STORE_SYSTEM_BLOCK: Asset = Asset::new( + "store_system_block", + "tests/assets/user/build/assets/transaction/store_system_block.mvt", + ); + pub static STORE_SYSTEM_TIMESTAMP: Asset = Asset::new( + "store_system_timestamp", + "tests/assets/user/build/assets/transaction/store_system_timestamp.mvt", + ); + pub static INF_LOOP: Asset = Asset::new( + "inf_loop", + "tests/assets/user/build/assets/transaction/inf_loop.mvt", + ); + pub static STORE_NATIVE_BALANCE: Asset = Asset::new( + "store_native_balance", + "tests/assets/user/build/assets/transaction/store_native_balance.mvt", + ); + pub static STORE_TOKEN_BALANCE: Asset = Asset::new( + "store_token_balance", + "tests/assets/user/build/assets/transaction/store_token_balance.mvt", + ); + pub static TRANSFER: Asset = Asset::new( + "transfer", + "tests/assets/user/build/assets/transaction/transfer.mvt", + ); + pub static TRANSFER_TOKEN: Asset = Asset::new( + "transfer_token", + "tests/assets/user/build/assets/transaction/transfer_token.mvt", + ); + pub static MULTISIG_TEST: Asset = Asset::new( + "multisig_test", + "tests/assets/user/build/assets/transaction/multisig_test.mvt", + ); + pub static DEPOSIT_BANK_PONT: Asset = Asset::new( + "deposit_bank_pont", + "tests/assets/user/build/assets/transaction/deposit_bank_pont.mvt", + ); + pub static DEPOSIT_BANK_KSM: Asset = Asset::new( + "deposit_bank_ksm", + "tests/assets/user/build/assets/transaction/deposit_bank_ksm.mvt", + ); + pub static AS_ROOT: Asset = Asset::new( + "as_root", + "tests/assets/user/build/assets/transaction/as_root.mvt", + ); + pub static ONE_SIGNER_USER: Asset = Asset::new( + "signer_user", + "tests/assets/user/build/assets/transaction/signer_user.mvt", + ); + pub static ONE_SIGNER_ROOT: Asset = Asset::new( + "signer_root", + "tests/assets/user/build/assets/transaction/signer_root.mvt", + ); +} diff --git a/runtime/tests/common/mocks.rs b/runtime/tests/common/mocks.rs new file mode 100644 index 00000000..d7c91aa7 --- /dev/null +++ b/runtime/tests/common/mocks.rs @@ -0,0 +1,363 @@ +#![allow(dead_code)] +/// Mock runtime. +use groupsign::weights::PontemWeights; +use sp_mvm::gas; +use sp_core::{H256, sr25519}; +use sp_std::{convert::TryFrom, fmt::Debug}; +use frame_system as system; +use codec::{Decode, Encode}; +use system::EnsureRoot; +use frame_support::{ + PalletId, parameter_types, + traits::{Everything, ConstU32}, + weights::{Weight, constants::WEIGHT_PER_SECOND}, +}; +use sp_std::vec; +use std::include_bytes; +use frame_support::traits::{OnInitialize, OnFinalize}; +use sp_runtime::traits::{Verify, Lazy, BlakeTwo256, IdentityLookup, ConvertInto}; +use sp_runtime::{testing::Header}; +use orml_traits::parameter_type_with_key; +use constants::SS58_PREFIX; +use scale_info::TypeInfo; + +pub use primitives::currency::CurrencyId; +use module_currencies::BasicCurrencyAdapter; + +use super::vm_config::build as build_vm_config; + +type UncheckedExtrinsic = system::mocking::MockUncheckedExtrinsic; +type Block = system::mocking::MockBlock; + +/// Initial balance for all existent test accounts +pub const INITIAL_BALANCE: ::Balance = 42000; + +// Unit = the base number of indivisible units for balances +pub const UNIT: Balance = 1_000_000_000_000; +pub const MILLIUNIT: Balance = 1_000_000_000; +pub const MICROUNIT: Balance = 1_000_000; + +// Implement signature just for test. +#[derive(Eq, PartialEq, Clone, Encode, Decode, TypeInfo, Debug)] +pub struct AnySignature(sr25519::Signature); + +impl Verify for AnySignature { + type Signer = sr25519::Public; + fn verify>(&self, mut msg: L, signer: &sr25519::Public) -> bool { + let msg = msg.get(); + self.0.verify(msg, signer) + } +} + +impl From for AnySignature { + fn from(s: sr25519::Signature) -> Self { + Self(s) + } +} + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: system::{Pallet, Call, Config, Storage, Event}, + Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + Vesting: pallet_vesting::{Pallet, Call, Storage, Config, Event}, + Tokens: orml_tokens::{Pallet, Storage, Event}, + Currencies: module_currencies::{Pallet, Call, Storage, Event}, + Mvm: sp_mvm::{Pallet, Call, Config, Storage, Event}, + Groupsign: groupsign::{Pallet, Call, Origin, Event}, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = SS58_PREFIX; +} + +pub type AccountId = sp_core::sr25519::Public; +pub type Amount = i64; +pub type BlockNumber = u64; +pub type Balance = u64; + +impl system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = BlockNumber; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + // type AccountData = (); + type AccountData = pallet_balances::AccountData<::Balance>; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = ConstU32<12>; +} + +// --- gas --- // +/// By inheritance from Moonbeam and from Dfinance (based on validators statistic), we believe max 4125000 gas is currently enough for block. +/// In the same time we use same 500ms Weight as Max Block Weight, from which 75% only are used for transactions. +/// So our max gas is GAS_PER_SECOND * 0.500 * 0.65 => 4125000. +pub const GAS_PER_SECOND: u64 = 11_000_000; + +/// Approximate ratio of the amount of Weight per Gas. +/// u64 works for approximations because Weight is a very small unit compared to gas. +pub const WEIGHT_PER_GAS: u64 = WEIGHT_PER_SECOND / GAS_PER_SECOND; + +pub struct MoveVMGasWeightMapping; + +// Just use provided gas. +impl gas::GasWeightMapping for MoveVMGasWeightMapping { + fn gas_to_weight(gas: u64) -> Weight { + gas.saturating_mul(WEIGHT_PER_GAS) + } + + fn weight_to_gas(weight: Weight) -> u64 { + u64::try_from(weight.wrapping_div(WEIGHT_PER_GAS)).unwrap_or(u32::MAX as u64) + } +} +// ----------------- // + +// --- timestamp --- // + +parameter_types! { + pub const MinimumPeriod: u64 = 5; +} +impl pallet_timestamp::Config for Test { + /// A timestamp: milliseconds since the unix epoch. + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +// --- balances --- // + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; + pub const TransferFee: u64 = 1 * MILLIUNIT; + pub const CreationFee: u64 = 1 * MILLIUNIT; + pub const TransactionByteFee: u64 = 1 * MILLIUNIT; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Test { + type MaxLocks = MaxLocks; + /// The type for recording an account's balance. + type Balance = Balance; + /// The ubiquitous event type. + type Event = Event; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = Sys; + type WeightInfo = pallet_balances::weights::SubstrateWeight; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; +} + +parameter_types! { + pub const MinVestedTransfer: Balance = 1; +} + +impl pallet_vesting::Config for Test { + type Event = Event; + type Currency = Balances; + type BlockNumberToBalance = ConvertInto; + type MinVestedTransfer = MinVestedTransfer; + type WeightInfo = (); + const MAX_VESTING_SCHEDULES: u32 = 1; +} + +parameter_type_with_key! { + pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { + 100 + }; +} + +impl orml_tokens::Config for Test { + type Event = Event; + type Balance = Balance; + type Amount = primitives::Amount; + type CurrencyId = CurrencyId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type OnDust = (); + type MaxLocks = MaxLocks; + type DustRemovalWhitelist = Everything; +} + +parameter_types! { + pub const GetNativeCurrencyId: CurrencyId = CurrencyId::NATIVE; +} +impl module_currencies::Config for Test { + type Event = Event; + type CurrencyId = CurrencyId; + type MultiCurrency = Tokens; + type NativeCurrency = BasicCurrencyAdapter; + type GetNativeCurrencyId = GetNativeCurrencyId; + type WeightInfo = (); + type SweepOrigin = EnsureRoot; + type OnDust = (); +} + +// -------- move vm pallet --------- // +parameter_types! { + pub const MVMPalletId: PalletId = PalletId(*b"_nox/mvm"); +} +impl sp_mvm::Config for Test { + type Event = Event; + type GasWeightMapping = MoveVMGasWeightMapping; + type UpdateOrigin = EnsureRoot; + type PalletId = MVMPalletId; + type CurrencyId = CurrencyId; + type Currencies = Currencies; + type WeightInfo = (); +} + +parameter_types! { + pub const DepositBase: u64 = 0; + pub const DepositFactor: u64 = 0; + pub const MaxSignatories: u16 = 16; +} + +impl groupsign::Config for Test { + type Event = Event; + type Call = Call; + type Public = AccountId; + type Signature = AnySignature; + type MyOrigin = Origin; + type WeightInfo = PontemWeights; +} + +pub type Sys = system::Pallet; +pub type Time = pallet_timestamp::Pallet; +pub type MoveEvent = sp_mvm::Event; + +/// Runtime builder. +pub struct RuntimeBuilder { + balances: Vec<(AccountId, CurrencyId, Balance)>, + vesting: Vec<(AccountId, BlockNumber, u32, Balance)>, +} + +impl RuntimeBuilder { + /// Create new Runtime builder instance. + pub fn new() -> Self { + Self { + balances: vec![], + vesting: vec![], + } + } + + /// Set balances. + pub fn set_balances(mut self, balances: Vec<(AccountId, CurrencyId, Balance)>) -> Self { + self.balances = balances; + self + } + + /// Set vesting. + pub fn set_vesting(mut self, vesting: Vec<(AccountId, BlockNumber, u32, Balance)>) -> Self { + self.vesting = vesting; + self + } + + /// Build genesis storage according to the mock runtime. + pub fn build(self) -> sp_io::TestExternalities { + let mut sys = system::GenesisConfig::default() + .build_storage::() + .expect("Frame system builds valid default genesis config"); + + let native_currency_id = GetNativeCurrencyId::get(); + + pallet_balances::GenesisConfig:: { + balances: self + .balances + .clone() + .into_iter() + .filter(|(_, currency_id, _)| *currency_id == native_currency_id) + .map(|(account_id, _, initial_balance)| (account_id, initial_balance)) + .collect::>(), + } + .assimilate_storage(&mut sys) + .expect("Pallet balances storage can't be assimilated"); + + let vm_config = build_vm_config(); + + let move_stdlib = + include_bytes!("../../../pallets/sp-mvm/tests/assets/move-stdlib/build/MoveStdlib/bundles/MoveStdlib.pac") + .to_vec(); + let pont_framework = + include_bytes!("../../../pallets/sp-mvm/tests/assets/pont-stdlib/build/PontStdlib/bundles/PontStdlib.pac") + .to_vec(); + + sp_mvm::GenesisConfig:: { + move_stdlib, + pont_framework, + init_module: vm_config.0.clone(), + init_func: vm_config.1.clone(), + init_args: vm_config.2.clone(), + ..Default::default() + } + .assimilate_storage(&mut sys) + .expect("Pallet mvm storage can't be assimilated"); + + sys.into() + } +} + +/// Timestamp multiplier. +pub const TIME_BLOCK_MULTIPLIER: u64 = 100; + +/// Roll next block. +pub fn roll_next_block() { + Balances::on_finalize(Sys::block_number()); + Mvm::on_finalize(Sys::block_number()); + Sys::on_finalize(Sys::block_number()); + Sys::set_block_number(Sys::block_number() + 1); + Sys::on_initialize(Sys::block_number()); + Mvm::on_initialize(Sys::block_number()); + Balances::on_initialize(Sys::block_number()); + + // set time with multiplier `*MULTIPLIER` by block: + Time::set_timestamp(Sys::block_number() * TIME_BLOCK_MULTIPLIER); + + println!("now block: {}, time: {}", Sys::block_number(), Time::get()); +} + +/// Roll to block N. +pub fn roll_block_to(n: u64) { + while Sys::block_number() < n { + roll_next_block() + } +} + +/// Get last event. +pub fn last_event() -> Event { + { + let events = Sys::events(); + println!("events: {:?}", events); + } + Sys::events().pop().expect("Event expected").event +} + +/// If no events recently. +pub fn have_no_events() -> bool { + Sys::events().is_empty() +} diff --git a/runtime/tests/common/mod.rs b/runtime/tests/common/mod.rs new file mode 100644 index 00000000..5f7c02c4 --- /dev/null +++ b/runtime/tests/common/mod.rs @@ -0,0 +1,5 @@ +pub mod addr; +pub mod assets; +pub mod mocks; +pub mod utils; +pub mod vm_config; diff --git a/runtime/tests/common/utils.rs b/runtime/tests/common/utils.rs new file mode 100644 index 00000000..49998efa --- /dev/null +++ b/runtime/tests/common/utils.rs @@ -0,0 +1,150 @@ +#![allow(dead_code)] +/// Utils functions to work with Move VM. +use std::convert::TryFrom; +use frame_support::dispatch::DispatchResultWithPostInfo as PsResult; +use move_core_types::account_address::AccountAddress; +use move_core_types::identifier::Identifier; +use move_core_types::language_storage::ModuleId; +use move_core_types::language_storage::StructTag; +use move_vm::io::state::State; +use move_vm::types::ModulePackage; +use move_core_types::language_storage::CORE_CODE_ADDRESS; +use move_core_types::resolver::ModuleResolver; +use move_core_types::resolver::ResourceResolver; + +use sp_mvm::storage::MoveVmStorage; + +use super::assets::*; +use super::mocks::*; +use super::addr::*; + +pub type AccountId = ::AccountId; + +/// Default gas limit. +pub const DEFAULT_GAS_LIMIT: u64 = 1_000_000; + +/// Publish module with storage check. +pub fn publish_module(signer: AccountId, module: &Asset, gas_limit: Option) -> PsResult { + let result = Mvm::publish_module( + Origin::signed(signer), + module.bytes().to_vec(), + gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), + )?; + check_storage_module(to_move_addr(signer), module.bytes().to_vec(), module.name()); + Ok(result) +} + +/// Publish module as root with storage check. +pub fn publish_module_as_root(module: &Asset, gas_limit: Option) -> PsResult { + let result = Mvm::publish_module( + Origin::root(), + module.bytes().to_vec(), + gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), + )?; + check_storage_module(CORE_CODE_ADDRESS, module.bytes().to_vec(), module.name()); + Ok(result) +} + +/// Publish package with storage check. +pub fn publish_package(signer: AccountId, package: &Package, gas_limit: Option) -> PsResult { + let result = Mvm::publish_package( + Origin::signed(signer), + package.bytes().to_vec(), + gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), + )?; + check_storage_package( + to_move_addr(signer), + package.bytes().to_vec(), + package.modules(), + ); + Ok(result) +} + +/// Publish package as root with storage check. +pub fn publish_package_as_root(package: &Package, gas_limit: Option) -> PsResult { + let result = Mvm::publish_package( + Origin::root(), + package.bytes().to_vec(), + gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), + )?; + check_storage_package( + CORE_CODE_ADDRESS, + package.bytes().to_vec(), + package.modules(), + ); + Ok(result) +} + +/// Execute transaction script. +pub fn execute_tx(origin: AccountId, tx: &Asset, gas_limit: Option) -> PsResult { + let gas_limit = gas_limit.unwrap_or(DEFAULT_GAS_LIMIT); + // get bytecode: + let bc = tx.bytes().to_vec(); + // execute VM tx: + let result = Mvm::execute(Origin::signed(origin), bc, gas_limit); + eprintln!("execute tx result: {:?}", result); + result +} + +/// Execute transaction script by Root. +pub fn execute_tx_by_root(tx: &Asset, gas_limit: Option) -> PsResult { + let gas_limit = gas_limit.unwrap_or(DEFAULT_GAS_LIMIT); + // get bytecode: + let bc = tx.bytes().to_vec(); + // execute VM tx: + let result = Mvm::execute(Origin::root(), bc, gas_limit); + eprintln!("execute tx result: {:?}", result); + result +} + +/// Check storage contains module. +pub fn check_storage_module>( + account_address: AccountAddress, + bc: Bc, + name: &str, +) { + let module_id = ModuleId::new(account_address, Identifier::new(name).unwrap()); + let storage = Mvm::move_vm_storage(); + let state = State::new(storage); + let stored = state + .get_module(&module_id) + .expect("VM state read storage") + .expect(&format!("Module '{}' should exist", module_id)); + assert_eq!(bc.as_ref(), &stored); +} + +/// Check storage contains package. +pub fn check_storage_package>( + account_address: AccountAddress, + bytecode: Bc, + names: &[&str], +) { + let (modules, _) = ModulePackage::try_from(bytecode.as_ref()) + .unwrap() + .into_tx(ROOT_ADDR) + .into_inner(); + + for (i, bytecode) in modules.iter().enumerate() { + check_storage_module(account_address, bytecode, names[i]); + } +} + +/// Check resource value inside storage. +pub fn check_storage_res(owner: AccountAddress, ty: StructTag, expected: T) +where + T: for<'de> serde::Deserialize<'de>, + T: std::cmp::PartialEq + std::fmt::Debug, +{ + let storage = Mvm::move_vm_storage(); + let state = State::new(storage); + let blob = state + .get_resource(&owner, &ty) + .expect("VM state read storage (resource)") + .expect(&format!("Resource '{}' should exist", ty)); + + let tt_str = format!("{}", ty); + println!("checking stored resource '{}'", tt_str); + let stored: T = + bcs::from_bytes(&blob).expect(&format!("Resource '{}' should exists", tt_str)); + assert_eq!(expected, stored); +} diff --git a/runtime/tests/common/vm_config.rs b/runtime/tests/common/vm_config.rs new file mode 100644 index 00000000..585de706 --- /dev/null +++ b/runtime/tests/common/vm_config.rs @@ -0,0 +1,20 @@ +/// VM configuration for tests. +use move_vm::genesis::GenesisConfig; + +/// Module to call to initialize genesis. +const MODULE_NAME: &[u8] = "Genesis".as_bytes(); + +/// Function to call to initialize genesis. +const FUNC_NAME: &[u8] = "initialize".as_bytes(); + +/// Build configuration to call initialize functions on Standard Library. +pub fn build() -> (Vec, Vec, Vec>) { + // We use standard arguments. + let genesis: GenesisConfig = Default::default(); + + ( + MODULE_NAME.to_vec(), + FUNC_NAME.to_vec(), + genesis.init_func_config.unwrap().args, + ) +} diff --git a/runtime/tests/scripts.rs b/runtime/tests/scripts.rs new file mode 100644 index 00000000..4ef7ae01 --- /dev/null +++ b/runtime/tests/scripts.rs @@ -0,0 +1,76 @@ +mod common; +use serde::Deserialize; +use move_core_types::{identifier::Identifier, language_storage::StructTag}; +use common::mocks::{AccountId, Mvm, roll_next_block, RuntimeBuilder, Origin, TIME_BLOCK_MULTIPLIER}; +use common::addr::{bob_public_key, to_move_addr, origin_move_addr}; +use common::assets::{Asset, modules, transactions}; +use common::utils::{self, check_storage_module, DEFAULT_GAS_LIMIT}; +use frame_support::dispatch::DispatchResultWithPostInfo; + +/// Check stored value (u64) inside storage. +fn check_stored_value(expected: u64) { + #[derive(Deserialize, Debug, PartialEq)] + struct StoreU64 { + pub val: u64, + } + + let expected = StoreU64 { val: expected }; + + let tag = StructTag { + address: origin_move_addr(), + module: Identifier::new(modules::user::STORE.name()).unwrap(), + name: Identifier::new("U64").unwrap(), + type_params: vec![], + }; + + utils::check_storage_res(origin_move_addr(), tag, expected); +} + +/// Publish module with storage check. +pub fn publish_module( + signer: AccountId, + module: &Asset, + gas_limit: Option, +) -> DispatchResultWithPostInfo { + let result = Mvm::publish_module( + Origin::signed(signer), + module.bytes().to_vec(), + gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), + )?; + check_storage_module(to_move_addr(signer), module.bytes().to_vec(), module.name()); + Ok(result) +} + +#[test] +/// Execute storing of block height inside module by calling script. +fn execute_store_block() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + + utils::publish_module(origin, &modules::user::STORE, None).unwrap(); + + const EXPECTED: u64 = 3; + for _ in 0..EXPECTED { + roll_next_block(); + } + utils::execute_tx(origin, &transactions::STORE_SYSTEM_BLOCK, None).unwrap(); + check_stored_value(EXPECTED); + }); +} + +#[test] +/// Execute storing of timestamp inside module by calling script. +fn execute_store_time() { + RuntimeBuilder::new().build().execute_with(|| { + let origin = bob_public_key(); + + utils::publish_module(origin, &modules::user::STORE, None).unwrap(); + + const EXPECTED: u64 = 3; + for _ in 0..EXPECTED { + roll_next_block(); + } + utils::execute_tx(origin, &transactions::STORE_SYSTEM_TIMESTAMP, None).unwrap(); + check_stored_value(EXPECTED * TIME_BLOCK_MULTIPLIER); + }); +} From 143fcccd9790014206428c008f9c1cb4a96c9e9a Mon Sep 17 00:00:00 2001 From: Belousov Maksim Date: Thu, 7 Apr 2022 00:05:16 +0300 Subject: [PATCH 2/4] Move runtime tests to runtime/src/tests/ --- runtime/src/tests/assets/build_assets.sh | 2 + .../tests/assets/user/scripts/SysBlock.move | 9 ++ .../assets/user/scripts/SysTimestamp.move | 8 ++ .../src/tests/assets/user/sources/Store.move | 29 +++++ runtime/src/tests/mock.rs | 38 ++++-- runtime/src/tests/mod.rs | 3 + runtime/src/tests/scripts.rs | 113 ++++++++++++++++++ rust-toolchain.toml | 2 +- 8 files changed, 191 insertions(+), 13 deletions(-) create mode 100644 runtime/src/tests/assets/user/scripts/SysBlock.move create mode 100644 runtime/src/tests/assets/user/scripts/SysTimestamp.move create mode 100644 runtime/src/tests/assets/user/sources/Store.move create mode 100644 runtime/src/tests/scripts.rs diff --git a/runtime/src/tests/assets/build_assets.sh b/runtime/src/tests/assets/build_assets.sh index c357e844..03c3961c 100755 --- a/runtime/src/tests/assets/build_assets.sh +++ b/runtime/src/tests/assets/build_assets.sh @@ -17,6 +17,8 @@ popd pushd ./user dove clean dove build -b +dove tx "store_system_block()" +dove tx "store_system_timestamp()" dove tx "transfer<0x1::NOX::NOX>(Alice, 500000000000)" -o=transfer_pont.mvt dove tx "transfer<0x1::KSM::KSM>(Alice, 500000000000)" -o=transfer_ksm.mvt dove tx "deposit_bank<0x1::NOX::NOX>(500000000000)" -o=deposit_bank_pont.mvt diff --git a/runtime/src/tests/assets/user/scripts/SysBlock.move b/runtime/src/tests/assets/user/scripts/SysBlock.move new file mode 100644 index 00000000..4eadb4a0 --- /dev/null +++ b/runtime/src/tests/assets/user/scripts/SysBlock.move @@ -0,0 +1,9 @@ +script { + use PontemFramework::PontBlock; + use RuntimeTests::Store; + + fun store_system_block(account: signer) { + Store::store_u64(&account, PontBlock::get_current_block_height()); + } +} + diff --git a/runtime/src/tests/assets/user/scripts/SysTimestamp.move b/runtime/src/tests/assets/user/scripts/SysTimestamp.move new file mode 100644 index 00000000..efc22094 --- /dev/null +++ b/runtime/src/tests/assets/user/scripts/SysTimestamp.move @@ -0,0 +1,8 @@ +script { + use PontemFramework::PontTimestamp; + use RuntimeTests::Store; + + fun store_system_timestamp(account: signer) { + Store::store_u64(&account, PontTimestamp::now_microseconds()); + } +} diff --git a/runtime/src/tests/assets/user/sources/Store.move b/runtime/src/tests/assets/user/sources/Store.move new file mode 100644 index 00000000..fc4326f2 --- /dev/null +++ b/runtime/src/tests/assets/user/sources/Store.move @@ -0,0 +1,29 @@ +module RuntimeTests::Store { + struct U64 has key { val: u64 } + + struct U128 has key { val: u128 } + + struct Address has key { val: address } + + struct VectorU8 has key { val: vector } + + public fun store_u64(account: &signer, val: u64) { + let foo = U64 { val: val }; + move_to(account, foo); + } + + public fun store_u128(account: &signer, val: u128) { + let foo = U128 { val: val }; + move_to(account, foo); + } + + public fun store_address(account: &signer, val: address) { + let addr = Address { val: val }; + move_to
(account, addr); + } + + public fun store_vector_u8(account: &signer, val: vector) { + let vec = VectorU8 { val: val }; + move_to(account, vec); + } +} diff --git a/runtime/src/tests/mock.rs b/runtime/src/tests/mock.rs index c0bc9203..43e36bf3 100644 --- a/runtime/src/tests/mock.rs +++ b/runtime/src/tests/mock.rs @@ -1,8 +1,10 @@ pub use crate::*; use frame_support::sp_io::TestExternalities; use frame_support::traits::GenesisBuild; -use sp_core::crypto::Ss58Codec; +use move_core_types::account_address::AccountAddress; +use sp_core::{Encode, crypto::Ss58Codec}; use frame_support::traits::Hooks; +use sp_core::sr25519::Public; use std::include_bytes; use move_vm::genesis::GenesisConfig; @@ -21,6 +23,9 @@ pub fn build_vm_config() -> (ModuleName, FunctionName, FunctionArgs) { ) } +/// Timestamp multiplier. +pub const TIME_BLOCK_MULTIPLIER: u64 = 12000; + /// User accounts. pub enum Accounts { ALICE, @@ -28,19 +33,28 @@ pub enum Accounts { } impl Accounts { - /// Convert account to AccountId. - pub fn account(&self) -> AccountId { + fn ss58(&self) -> &'static str { match self { - Accounts::ALICE => { - AccountId::from_ss58check("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY") - .unwrap() - } - Accounts::BOB => { - AccountId::from_ss58check("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty") - .unwrap() - } + Accounts::ALICE => "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + Accounts::BOB => "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", } } + + /// Convert account to AccountId. + pub fn account(&self) -> AccountId { + AccountId::from_ss58check(self.ss58()).unwrap() + } + + pub fn public_key(&self) -> Public { + Public::from_ss58check_with_version(self.ss58()).unwrap().0 + } + + pub fn addr(&self) -> AccountAddress { + let key = self.public_key().encode(); + let mut arr = [0; AccountAddress::LENGTH]; + arr.copy_from_slice(&key); + AccountAddress::new(arr) + } } impl Into<[u8; 32]> for Accounts { @@ -61,7 +75,7 @@ pub fn run_to_block(till: u32) { Scheduler::on_finalize(System::block_number()); Balances::on_finalize(System::block_number()); System::set_block_number(System::block_number() + 1); - Timestamp::set_timestamp(System::block_number() as u64 * 12000); + Timestamp::set_timestamp(System::block_number() as u64 * TIME_BLOCK_MULTIPLIER); Scheduler::on_initialize(System::block_number()); ParachainStaking::on_initialize(System::block_number()); TransactionPause::on_initialize(System::block_number()); diff --git a/runtime/src/tests/mod.rs b/runtime/src/tests/mod.rs index e354a452..26746c44 100644 --- a/runtime/src/tests/mod.rs +++ b/runtime/src/tests/mod.rs @@ -7,3 +7,6 @@ pub mod vesting; // Parachain tests. pub mod parachain; + +// MVM scripts tests +pub mod scripts; diff --git a/runtime/src/tests/scripts.rs b/runtime/src/tests/scripts.rs new file mode 100644 index 00000000..aeb3ea1e --- /dev/null +++ b/runtime/src/tests/scripts.rs @@ -0,0 +1,113 @@ +use crate::tests::mock::{RuntimeBuilder, Accounts, Mvm, Origin, run_to_block, TIME_BLOCK_MULTIPLIER}; +use frame_support::assert_ok; +use move_core_types::{ + language_storage::StructTag, identifier::Identifier, account_address::AccountAddress, + resolver::ResourceResolver, +}; +use sp_mvm::storage::MoveVmStorage; +use move_vm::io::state::State; + +pub mod modules { + use assets::Asset; + pub static STORE: Asset = Asset::new( + "Store", + "src/tests/assets/user/build/assets/bytecode_modules/Store.mv", + ); +} + +pub mod transactions { + use assets::Asset; + pub static STORE_SYSTEM_BLOCK: Asset = Asset::new( + "store_system_block", + "src/tests/assets/user/build/assets/transaction/store_system_block.mvt", + ); + pub static STORE_SYSTEM_TIMESTAMP: Asset = Asset::new( + "store_system_timestamp", + "src/tests/assets/user/build/assets/transaction/store_system_timestamp.mvt", + ); +} + +const GAS_LIMIT: u64 = 1_000_000; + +/// Check stored value (u64) inside storage. +fn check_stored_value(expected: u64) { + #[derive(serde::Deserialize, Debug, PartialEq)] + struct StoreU64 { + pub val: u64, + } + + let expected = StoreU64 { val: expected }; + + let tag = StructTag { + address: Accounts::BOB.addr(), + module: Identifier::new(modules::STORE.name()).unwrap(), + name: Identifier::new("U64").unwrap(), + type_params: vec![], + }; + + check_storage_res(Accounts::BOB.addr(), tag, expected); +} + +/// Check resource value inside storage. +pub fn check_storage_res(owner: AccountAddress, ty: StructTag, expected: T) +where + T: for<'de> serde::Deserialize<'de>, + T: std::cmp::PartialEq + std::fmt::Debug, +{ + let storage = Mvm::move_vm_storage(); + let state = State::new(storage); + let blob = state + .get_resource(&owner, &ty) + .expect("VM state read storage (resource)") + .expect(&format!("Resource '{}' should exist", ty)); + + let tt_str = format!("{}", ty); + println!("checking stored resource '{}'", tt_str); + let stored: T = + bcs::from_bytes(&blob).expect(&format!("Resource '{}' should exists", tt_str)); + assert_eq!(expected, stored); +} + +#[test] +/// Execute storing of block height inside module by calling script. +fn execute_store_block() { + RuntimeBuilder::new().build().execute_with(|| { + // Publish STORE module. + assert_ok!(Mvm::publish_module( + Origin::signed(Accounts::BOB.account()), + modules::STORE.bytes().to_vec(), + GAS_LIMIT + )); + + const EXPECTED: u32 = 3; + run_to_block(EXPECTED); + assert_ok!(Mvm::execute( + Origin::signed(Accounts::BOB.account()), + transactions::STORE_SYSTEM_BLOCK.bytes().to_vec(), + GAS_LIMIT + )); + check_stored_value(EXPECTED.into()); + }); +} + +#[test] +/// Execute storing of timestamp inside module by calling script. +fn execute_store_time() { + RuntimeBuilder::new().build().execute_with(|| { + // Publish STORE module. + assert_ok!(Mvm::publish_module( + Origin::signed(Accounts::BOB.account()), + modules::STORE.bytes().to_vec(), + GAS_LIMIT + )); + + const EXPECTED: u32 = 3; + run_to_block(EXPECTED); + assert_ok!(Mvm::execute( + Origin::signed(Accounts::BOB.account()), + transactions::STORE_SYSTEM_TIMESTAMP.bytes().to_vec(), + GAS_LIMIT + )); + check_stored_value(EXPECTED as u64 * TIME_BLOCK_MULTIPLIER); + }); +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index f96fe958..85d09db2 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,4 +1,4 @@ [toolchain] channel = "nightly-2021-11-07" -profile = "complete" +profile = "default" targets = [ "wasm32-unknown-unknown"] From 1732ac59be851a81f4107f3af811066f3213383a Mon Sep 17 00:00:00 2001 From: Belousov Maksim Date: Thu, 7 Apr 2022 00:07:19 +0300 Subject: [PATCH 3/4] Remove runtime/tests --- runtime/tests/assets/build_assets.sh | 42 -- runtime/tests/assets/root/.gitignore | 2 - runtime/tests/assets/root/Dove.toml | 14 - runtime/tests/assets/root/Move.toml | 17 - runtime/tests/assets/root/doc.toml | 11 - .../tests/assets/root/sources/EventProxy.move | 14 - runtime/tests/assets/root/sources/Store.move | 29 -- runtime/tests/assets/user/.gitignore | 2 - runtime/tests/assets/user/Dove.toml | 14 - runtime/tests/assets/user/Move.toml | 19 - runtime/tests/assets/user/doc.toml | 11 - runtime/tests/assets/user/scripts/AsRoot.move | 8 - .../assets/user/scripts/DepositBank.move | 12 - .../tests/assets/user/scripts/EmitEvent.move | 7 - .../tests/assets/user/scripts/InfLoop.move | 11 - .../assets/user/scripts/MultisigTest.move | 8 - .../assets/user/scripts/NativeBalance.move | 11 - .../tests/assets/user/scripts/Signers.move | 5 - .../assets/user/scripts/StoreScript.move | 7 - .../tests/assets/user/scripts/SysBlock.move | 8 - .../assets/user/scripts/SysTimestamp.move | 8 - .../assets/user/scripts/TokenBalance.move | 11 - .../tests/assets/user/scripts/Transfer.move | 13 - runtime/tests/assets/user/sources/Bank.move | 22 -- .../tests/assets/user/sources/EventProxy.move | 16 - runtime/tests/assets/user/sources/Store.move | 29 -- runtime/tests/common/addr.rs | 68 ---- runtime/tests/common/assets.rs | 110 ------ runtime/tests/common/mocks.rs | 363 ------------------ runtime/tests/common/mod.rs | 5 - runtime/tests/common/utils.rs | 150 -------- runtime/tests/common/vm_config.rs | 20 - runtime/tests/scripts.rs | 76 ---- 33 files changed, 1143 deletions(-) delete mode 100755 runtime/tests/assets/build_assets.sh delete mode 100644 runtime/tests/assets/root/.gitignore delete mode 100644 runtime/tests/assets/root/Dove.toml delete mode 100644 runtime/tests/assets/root/Move.toml delete mode 100644 runtime/tests/assets/root/doc.toml delete mode 100644 runtime/tests/assets/root/sources/EventProxy.move delete mode 100644 runtime/tests/assets/root/sources/Store.move delete mode 100644 runtime/tests/assets/user/.gitignore delete mode 100644 runtime/tests/assets/user/Dove.toml delete mode 100644 runtime/tests/assets/user/Move.toml delete mode 100644 runtime/tests/assets/user/doc.toml delete mode 100644 runtime/tests/assets/user/scripts/AsRoot.move delete mode 100644 runtime/tests/assets/user/scripts/DepositBank.move delete mode 100644 runtime/tests/assets/user/scripts/EmitEvent.move delete mode 100644 runtime/tests/assets/user/scripts/InfLoop.move delete mode 100644 runtime/tests/assets/user/scripts/MultisigTest.move delete mode 100644 runtime/tests/assets/user/scripts/NativeBalance.move delete mode 100644 runtime/tests/assets/user/scripts/Signers.move delete mode 100644 runtime/tests/assets/user/scripts/StoreScript.move delete mode 100644 runtime/tests/assets/user/scripts/SysBlock.move delete mode 100644 runtime/tests/assets/user/scripts/SysTimestamp.move delete mode 100644 runtime/tests/assets/user/scripts/TokenBalance.move delete mode 100644 runtime/tests/assets/user/scripts/Transfer.move delete mode 100644 runtime/tests/assets/user/sources/Bank.move delete mode 100644 runtime/tests/assets/user/sources/EventProxy.move delete mode 100644 runtime/tests/assets/user/sources/Store.move delete mode 100644 runtime/tests/common/addr.rs delete mode 100644 runtime/tests/common/assets.rs delete mode 100644 runtime/tests/common/mocks.rs delete mode 100644 runtime/tests/common/mod.rs delete mode 100644 runtime/tests/common/utils.rs delete mode 100644 runtime/tests/common/vm_config.rs delete mode 100644 runtime/tests/scripts.rs diff --git a/runtime/tests/assets/build_assets.sh b/runtime/tests/assets/build_assets.sh deleted file mode 100755 index 2816b010..00000000 --- a/runtime/tests/assets/build_assets.sh +++ /dev/null @@ -1,42 +0,0 @@ -# Clone move-stdlib -rm -rf ./move-stdlib -git clone https://github.com/pontem-network/move-stdlib ./move-stdlib -pushd ./move-stdlib -git checkout release-v1.0.0 -dove build -b -popd - -# Clone pont-stdlib -rm -rf ./pont-stdlib -git clone https://github.com/pontem-network/pont-stdlib.git ./pont-stdlib -pushd ./pont-stdlib -git checkout release-v1.0.0 -dove build -b -popd - -pushd ./user -dove clean -dove build -dove build -b -dove tx "store_u64(42)" -dove tx "emit_event(42)" -dove tx "store_system_block()" -dove tx "store_system_timestamp()" -dove tx "inf_loop()" -dove tx "store_native_balance()" -dove tx "store_token_balance()" -dove tx "as_root(dr)" -dove tx "transfer<0x1::NOX::NOX>(Alice, 2000)" -o=transfer.mvt -dove tx "transfer<0x1::KSM::KSM>(Alice, 2000)" -o=transfer_token.mvt -dove tx "multisig_test()" -dove tx "deposit_bank<0x1::NOX::NOX>(2000)" -o=deposit_bank_pont.mvt -dove tx "deposit_bank<0x1::KSM::KSM>(2000)" -o=deposit_bank_ksm.mvt -dove tx "signer_one()" -o=signer_user.mvt -dove tx "signer_one(root)" -o=signer_root.mvt -popd - -pushd ./root -dove clean -dove build -dove build -b -pushd diff --git a/runtime/tests/assets/root/.gitignore b/runtime/tests/assets/root/.gitignore deleted file mode 100644 index 6eeec870..00000000 --- a/runtime/tests/assets/root/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -target diff --git a/runtime/tests/assets/root/Dove.toml b/runtime/tests/assets/root/Dove.toml deleted file mode 100644 index b2fde8a4..00000000 --- a/runtime/tests/assets/root/Dove.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "assets" -dialect = "pont" -dove_version = ">=1.5.5" - -# account_address = "0x0" # dev/null -account_address = "0x1" # std -# account_address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" # Alice -# account_address = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty" # Bob -# account_address = "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48" # Bob - -dependencies = [ - { git = "https://github.com/pontem-network/pont-stdlib.git", rev = "e9bd26720c06705d2e222833a496fda7c67c8e32" }, -] diff --git a/runtime/tests/assets/root/Move.toml b/runtime/tests/assets/root/Move.toml deleted file mode 100644 index e23b3443..00000000 --- a/runtime/tests/assets/root/Move.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "assets" -version = "0.0.1" -authors = [] -dialect = "Pont" -dove_version = ">=1.5.5" - -[addresses] -RootTests = "0x1" - -[dependencies.PontStdlib] -git = "https://github.com/pontem-network/pont-stdlib.git" -rev = "release-v1.0.0" - -[dependencies.MoveStdlib] -git = "https://github.com/pontem-network/move-stdlib.git" -rev = "release-v1.0.0" diff --git a/runtime/tests/assets/root/doc.toml b/runtime/tests/assets/root/doc.toml deleted file mode 100644 index b5336de3..00000000 --- a/runtime/tests/assets/root/doc.toml +++ /dev/null @@ -1,11 +0,0 @@ -enabled = true -section_level_start = 1 -include_private_fun = true -include_specs = true -specs_inlined = true -include_impl = true -toc_depth = 3 -collapsed_sections = true -root_doc_templates = [] -include_dep_diagrams = false -include_call_diagrams = false diff --git a/runtime/tests/assets/root/sources/EventProxy.move b/runtime/tests/assets/root/sources/EventProxy.move deleted file mode 100644 index c60a2f54..00000000 --- a/runtime/tests/assets/root/sources/EventProxy.move +++ /dev/null @@ -1,14 +0,0 @@ -module RootTests::EventProxy { - use Std::Event; - - struct U64 has store, drop, copy { val: u64 } - - public fun emit_event(acc: signer, val: u64) { - let event_handle = Event::new_event_handle(&acc); - Event::emit_event( - &mut event_handle, - U64 { val } - ); - Event::destroy_handle(event_handle); - } -} diff --git a/runtime/tests/assets/root/sources/Store.move b/runtime/tests/assets/root/sources/Store.move deleted file mode 100644 index 27801068..00000000 --- a/runtime/tests/assets/root/sources/Store.move +++ /dev/null @@ -1,29 +0,0 @@ -module RootTests::Store { - struct U64 has key { val: u64 } - - struct U128 has key { val: u128 } - - struct Address has key { val: address } - - struct VectorU8 has key { val: vector } - - public fun store_u64(account: &signer, val: u64) { - let foo = U64 { val: val }; - move_to(account, foo); - } - - public fun store_u128(account: &signer, val: u128) { - let foo = U128 { val: val }; - move_to(account, foo); - } - - public fun store_address(account: &signer, val: address) { - let addr = Address { val: val }; - move_to
(account, addr); - } - - public fun store_vector_u8(account: &signer, val: vector) { - let vec = VectorU8 { val: val }; - move_to(account, vec); - } -} diff --git a/runtime/tests/assets/user/.gitignore b/runtime/tests/assets/user/.gitignore deleted file mode 100644 index 6eeec870..00000000 --- a/runtime/tests/assets/user/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -target diff --git a/runtime/tests/assets/user/Dove.toml b/runtime/tests/assets/user/Dove.toml deleted file mode 100644 index 46cca600..00000000 --- a/runtime/tests/assets/user/Dove.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "assets" -dialect = "pont" -dove_version = ">=1.5.5" - -# account_address = "0x0" # dev/null -# account_address = "0x1" # std -# account_address = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" # Alice -account_address = "gkNW9pAcCHxZrnoVkhLkEQtsLsW5NWTC75cdAdxAMs9LNYCYg" # Bob -# account_address = "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48" # Bob - -dependencies = [ - { git = "https://github.com/pontem-network/pont-stdlib.git", rev = "e9bd26720c06705d2e222833a496fda7c67c8e32" } -] diff --git a/runtime/tests/assets/user/Move.toml b/runtime/tests/assets/user/Move.toml deleted file mode 100644 index 61802b00..00000000 --- a/runtime/tests/assets/user/Move.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "assets" -version = "0.0.1" -authors = [] -dialect = "Pont" -dove_version = ">=1.5.5" - -[addresses] -UserTests = "gkNW9pAcCHxZrnoVkhLkEQtsLsW5NWTC75cdAdxAMs9LNYCYg" -Alice = "gkQ5K6EnLRgZkwozG8GiBAEnJyM6FxzbSaSmVhKJ2w8FcK7ih" -Bob = "gkNW9pAcCHxZrnoVkhLkEQtsLsW5NWTC75cdAdxAMs9LNYCYg" - -[dependencies.PontStdlib] -git = "https://github.com/pontem-network/pont-stdlib.git" -rev = "release-v1.0.0" - -[dependencies.MoveStdlib] -git = "https://github.com/pontem-network/move-stdlib.git" -rev = "release-v1.0.0" diff --git a/runtime/tests/assets/user/doc.toml b/runtime/tests/assets/user/doc.toml deleted file mode 100644 index b5336de3..00000000 --- a/runtime/tests/assets/user/doc.toml +++ /dev/null @@ -1,11 +0,0 @@ -enabled = true -section_level_start = 1 -include_private_fun = true -include_specs = true -specs_inlined = true -include_impl = true -toc_depth = 3 -collapsed_sections = true -root_doc_templates = [] -include_dep_diagrams = false -include_call_diagrams = false diff --git a/runtime/tests/assets/user/scripts/AsRoot.move b/runtime/tests/assets/user/scripts/AsRoot.move deleted file mode 100644 index f0b0a75e..00000000 --- a/runtime/tests/assets/user/scripts/AsRoot.move +++ /dev/null @@ -1,8 +0,0 @@ -script { - use Std::Signer; - - fun as_root(root: signer) { - assert!(Signer::address_of(&root) == @Root, 1); - } -} - \ No newline at end of file diff --git a/runtime/tests/assets/user/scripts/DepositBank.move b/runtime/tests/assets/user/scripts/DepositBank.move deleted file mode 100644 index 2c214cac..00000000 --- a/runtime/tests/assets/user/scripts/DepositBank.move +++ /dev/null @@ -1,12 +0,0 @@ -script { - use PontemFramework::PontAccount; - use UserTests::Bank; - - fun deposit_bank(sender: signer, amount: u64) { - // Withdraw TokenType tokens from sender account. - let tokens = PontAccount::withdraw(&sender, amount); - - Bank::deposit(&sender, tokens); - } -} - \ No newline at end of file diff --git a/runtime/tests/assets/user/scripts/EmitEvent.move b/runtime/tests/assets/user/scripts/EmitEvent.move deleted file mode 100644 index 5d7447ca..00000000 --- a/runtime/tests/assets/user/scripts/EmitEvent.move +++ /dev/null @@ -1,7 +0,0 @@ -script { - use UserTests::EventProxy; - - fun emit_event(acc: signer, val: u64) { - EventProxy::emit_event(&acc, val); - } -} diff --git a/runtime/tests/assets/user/scripts/InfLoop.move b/runtime/tests/assets/user/scripts/InfLoop.move deleted file mode 100644 index fc50344d..00000000 --- a/runtime/tests/assets/user/scripts/InfLoop.move +++ /dev/null @@ -1,11 +0,0 @@ -script { - fun inf_loop() { - let i = 0; - - loop { - if (i > 1000) { - break - } - } - } -} diff --git a/runtime/tests/assets/user/scripts/MultisigTest.move b/runtime/tests/assets/user/scripts/MultisigTest.move deleted file mode 100644 index 82454080..00000000 --- a/runtime/tests/assets/user/scripts/MultisigTest.move +++ /dev/null @@ -1,8 +0,0 @@ -script { - use Std::Signer; - - fun multisig_test(account1: signer, account2: signer) { - assert!(Signer::address_of(&account1) == @Alice, 1); // Alice - assert!(Signer::address_of(&account2) == @Bob, 1); // Bob - } -} diff --git a/runtime/tests/assets/user/scripts/NativeBalance.move b/runtime/tests/assets/user/scripts/NativeBalance.move deleted file mode 100644 index 191438f3..00000000 --- a/runtime/tests/assets/user/scripts/NativeBalance.move +++ /dev/null @@ -1,11 +0,0 @@ -script { - use PontemFramework::PontAccount; - use PontemFramework::NOX::NOX; - use Std::Signer; - use UserTests::Store; - - fun store_native_balance(account: signer) { - let balance = PontAccount::balance(Signer::address_of(&account)); - Store::store_u64(&account, balance); - } -} diff --git a/runtime/tests/assets/user/scripts/Signers.move b/runtime/tests/assets/user/scripts/Signers.move deleted file mode 100644 index 6a8c8cb4..00000000 --- a/runtime/tests/assets/user/scripts/Signers.move +++ /dev/null @@ -1,5 +0,0 @@ -script { - // Just one signer required - fun signer_one(_s: signer) { - } -} diff --git a/runtime/tests/assets/user/scripts/StoreScript.move b/runtime/tests/assets/user/scripts/StoreScript.move deleted file mode 100644 index 49c13421..00000000 --- a/runtime/tests/assets/user/scripts/StoreScript.move +++ /dev/null @@ -1,7 +0,0 @@ -script { - use UserTests::Store; - - fun store_u64(account: signer, val: u64) { - Store::store_u64(&account, val); - } -} diff --git a/runtime/tests/assets/user/scripts/SysBlock.move b/runtime/tests/assets/user/scripts/SysBlock.move deleted file mode 100644 index 10f36818..00000000 --- a/runtime/tests/assets/user/scripts/SysBlock.move +++ /dev/null @@ -1,8 +0,0 @@ -script { - use PontemFramework::PontBlock; - use UserTests::Store; - - fun store_system_block(account: signer) { - Store::store_u64(&account, PontBlock::get_current_block_height()); - } -} diff --git a/runtime/tests/assets/user/scripts/SysTimestamp.move b/runtime/tests/assets/user/scripts/SysTimestamp.move deleted file mode 100644 index 03614a0d..00000000 --- a/runtime/tests/assets/user/scripts/SysTimestamp.move +++ /dev/null @@ -1,8 +0,0 @@ -script { - use PontemFramework::PontTimestamp; - use UserTests::Store; - - fun store_system_timestamp(account: signer) { - Store::store_u64(&account, PontTimestamp::now_microseconds()); - } -} diff --git a/runtime/tests/assets/user/scripts/TokenBalance.move b/runtime/tests/assets/user/scripts/TokenBalance.move deleted file mode 100644 index 6112863b..00000000 --- a/runtime/tests/assets/user/scripts/TokenBalance.move +++ /dev/null @@ -1,11 +0,0 @@ -script { - use PontemFramework::PontAccount; - use PontemFramework::KSM::KSM; - use Std::Signer; - use UserTests::Store; - - fun store_token_balance(account: signer) { - let balance = PontAccount::balance(Signer::address_of(&account)); - Store::store_u64(&account, balance); - } -} diff --git a/runtime/tests/assets/user/scripts/Transfer.move b/runtime/tests/assets/user/scripts/Transfer.move deleted file mode 100644 index 5f8c4e94..00000000 --- a/runtime/tests/assets/user/scripts/Transfer.move +++ /dev/null @@ -1,13 +0,0 @@ -script { - use PontemFramework::PontAccount; - use Std::Signer; - use UserTests::Store; - - // Transfer from Bob to Alice. - fun transfer(bob: signer, alice: address, to_move: u64) { - PontAccount::pay_from(&bob, alice, to_move); - - let balance = PontAccount::balance(Signer::address_of(&bob)); - Store::store_u64(&bob, balance); - } -} diff --git a/runtime/tests/assets/user/sources/Bank.move b/runtime/tests/assets/user/sources/Bank.move deleted file mode 100644 index 760b6d52..00000000 --- a/runtime/tests/assets/user/sources/Bank.move +++ /dev/null @@ -1,22 +0,0 @@ -/// Bank module (stores tokens inside module). -module UserTests::Bank { - use Std::Signer; - use PontemFramework::Token::{Self, Token}; - - struct Storage has key, store { - balance: Token, - } - - public fun deposit(account: &signer, deposit: Token) acquires Storage { - let addr = Signer::address_of(account); - - if (!exists>(addr)) { - move_to(account, Storage { - balance: deposit - }); - } else { - let storage = borrow_global_mut>(addr); - Token::deposit(&mut storage.balance, deposit); - } - } -} diff --git a/runtime/tests/assets/user/sources/EventProxy.move b/runtime/tests/assets/user/sources/EventProxy.move deleted file mode 100644 index c9412b07..00000000 --- a/runtime/tests/assets/user/sources/EventProxy.move +++ /dev/null @@ -1,16 +0,0 @@ -module UserTests::EventProxy { - use Std::Event; - - struct U64 has store, drop, copy { val: u64 } - - public fun emit_event(acc: &signer, val: u64) { - let event_handle = Event::new_event_handle(acc); - - Event::emit_event( - &mut event_handle, - U64 { val } - ); - - Event::destroy_handle(event_handle); - } -} diff --git a/runtime/tests/assets/user/sources/Store.move b/runtime/tests/assets/user/sources/Store.move deleted file mode 100644 index 951d7a53..00000000 --- a/runtime/tests/assets/user/sources/Store.move +++ /dev/null @@ -1,29 +0,0 @@ -module UserTests::Store { - struct U64 has key { val: u64 } - - struct U128 has key { val: u128 } - - struct Address has key { val: address } - - struct VectorU8 has key { val: vector } - - public fun store_u64(account: &signer, val: u64) { - let foo = U64 { val: val }; - move_to(account, foo); - } - - public fun store_u128(account: &signer, val: u128) { - let foo = U128 { val: val }; - move_to(account, foo); - } - - public fun store_address(account: &signer, val: address) { - let addr = Address { val: val }; - move_to
(account, addr); - } - - public fun store_vector_u8(account: &signer, val: vector) { - let vec = VectorU8 { val: val }; - move_to(account, vec); - } -} diff --git a/runtime/tests/common/addr.rs b/runtime/tests/common/addr.rs deleted file mode 100644 index 585bb4a5..00000000 --- a/runtime/tests/common/addr.rs +++ /dev/null @@ -1,68 +0,0 @@ -#![allow(dead_code)] -/// Mock addresses. -use codec::Encode; -use sp_core::sr25519::Public; -use sp_core::crypto::Ss58Codec; -use move_core_types::account_address::AccountAddress; -pub use move_core_types::language_storage::CORE_CODE_ADDRESS as ROOT_ADDR; -use sp_mvm::addr::account_to_account_address; - -pub const BOB_SS58: &str = "gkNW9pAcCHxZrnoVkhLkEQtsLsW5NWTC75cdAdxAMs9LNYCYg"; -pub const ALICE_SS58: &str = "gkQ5K6EnLRgZkwozG8GiBAEnJyM6FxzbSaSmVhKJ2w8FcK7ih"; - -/// Public key of Bob account. -pub fn bob_public_key() -> Public { - Public::from_ss58check_with_version(BOB_SS58).unwrap().0 -} - -/// Public key of alice account. -pub fn alice_public_key() -> Public { - Public::from_ss58check_with_version(ALICE_SS58).unwrap().0 -} - -/// Returns `AccountAddress` for Bob. -pub fn origin_move_addr() -> AccountAddress { - let pk = bob_public_key(); - let vec = pk.encode(); - let mut arr = [0; AccountAddress::LENGTH]; - arr.copy_from_slice(&vec); - AccountAddress::new(arr) -} - -/// Returns `AccountAddress` for Alice. -pub fn alice_move_addr() -> AccountAddress { - let pk = alice_public_key(); - let vec = pk.encode(); - let mut arr = [0; AccountAddress::LENGTH]; - arr.copy_from_slice(&vec); - AccountAddress::new(arr) -} - -/// Returns `AccountAddress` for provided public key. -pub fn to_move_addr(pk: Public) -> AccountAddress { - account_to_account_address(&pk) -} - -#[cfg(test)] -mod tests { - #[test] - fn origin_move_addr() { - let expected = super::AccountAddress::from_hex_literal( - "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - ) - .unwrap(); - assert_eq!(expected, super::origin_move_addr()); - } - - #[test] - fn origin_to_move_addr() { - use super::*; - - let expected = AccountAddress::from_hex_literal( - "0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48", - ) - .unwrap(); - let addr = to_move_addr(bob_public_key()); - assert_eq!(expected, addr); - } -} diff --git a/runtime/tests/common/assets.rs b/runtime/tests/common/assets.rs deleted file mode 100644 index 438015ef..00000000 --- a/runtime/tests/common/assets.rs +++ /dev/null @@ -1,110 +0,0 @@ -#![allow(dead_code)] -/// Assets (Move modules/scripts/packages). -pub use assets::*; - -/// Package built using root account. -pub static ROOT_PACKAGE: Package = Package::new( - &["EventProxy", "Store"], - Asset::new("", "tests/assets/root/build/assets/bundles/assets.pac"), -); -/// Package built using user account. -pub static USER_PACKAGE: Package = Package::new( - &["Bank", "EventProxy", "Store"], - Asset::new("", "tests/assets/user/build/assets/bundles/assets.pac"), -); - -/// Modules assets (root/user). -pub mod modules { - pub mod root { - use super::super::Asset; - pub static STORE: Asset = Asset::new( - "Store", - "tests/assets/root/build/assets/bytecode_modules/Store.mv", - ); - pub static EVENT_PROXY: Asset = Asset::new( - "EventProxy", - "tests/assets/root/build/assets/bytecode_modules/EventProxy.mv", - ); - } - - pub mod user { - use super::super::Asset; - pub static STORE: Asset = Asset::new( - "Store", - "tests/assets/user/build/assets//bytecode_modules/Store.mv", - ); - pub static EVENT_PROXY: Asset = Asset::new( - "EventProxy", - "tests/assets/user/build/assets//bytecode_modules/EventProxy.mv", - ); - pub static BANK: Asset = Asset::new( - "Bank", - "tests/assets/user/build/assets/bytecode_modules/Bank.mv", - ); - } -} - -/// Transaction (scripts) assets. -pub mod transactions { - use super::Asset; - pub static STORE_U64: Asset = Asset::new( - "store_u64", - "tests/assets/user/build/assets/transaction/store_u64.mvt", - ); - pub static EMIT_EVENT: Asset = Asset::new( - "emit_event", - "tests/assets/user/build/assets/transaction/emit_event.mvt", - ); - pub static STORE_SYSTEM_BLOCK: Asset = Asset::new( - "store_system_block", - "tests/assets/user/build/assets/transaction/store_system_block.mvt", - ); - pub static STORE_SYSTEM_TIMESTAMP: Asset = Asset::new( - "store_system_timestamp", - "tests/assets/user/build/assets/transaction/store_system_timestamp.mvt", - ); - pub static INF_LOOP: Asset = Asset::new( - "inf_loop", - "tests/assets/user/build/assets/transaction/inf_loop.mvt", - ); - pub static STORE_NATIVE_BALANCE: Asset = Asset::new( - "store_native_balance", - "tests/assets/user/build/assets/transaction/store_native_balance.mvt", - ); - pub static STORE_TOKEN_BALANCE: Asset = Asset::new( - "store_token_balance", - "tests/assets/user/build/assets/transaction/store_token_balance.mvt", - ); - pub static TRANSFER: Asset = Asset::new( - "transfer", - "tests/assets/user/build/assets/transaction/transfer.mvt", - ); - pub static TRANSFER_TOKEN: Asset = Asset::new( - "transfer_token", - "tests/assets/user/build/assets/transaction/transfer_token.mvt", - ); - pub static MULTISIG_TEST: Asset = Asset::new( - "multisig_test", - "tests/assets/user/build/assets/transaction/multisig_test.mvt", - ); - pub static DEPOSIT_BANK_PONT: Asset = Asset::new( - "deposit_bank_pont", - "tests/assets/user/build/assets/transaction/deposit_bank_pont.mvt", - ); - pub static DEPOSIT_BANK_KSM: Asset = Asset::new( - "deposit_bank_ksm", - "tests/assets/user/build/assets/transaction/deposit_bank_ksm.mvt", - ); - pub static AS_ROOT: Asset = Asset::new( - "as_root", - "tests/assets/user/build/assets/transaction/as_root.mvt", - ); - pub static ONE_SIGNER_USER: Asset = Asset::new( - "signer_user", - "tests/assets/user/build/assets/transaction/signer_user.mvt", - ); - pub static ONE_SIGNER_ROOT: Asset = Asset::new( - "signer_root", - "tests/assets/user/build/assets/transaction/signer_root.mvt", - ); -} diff --git a/runtime/tests/common/mocks.rs b/runtime/tests/common/mocks.rs deleted file mode 100644 index d7c91aa7..00000000 --- a/runtime/tests/common/mocks.rs +++ /dev/null @@ -1,363 +0,0 @@ -#![allow(dead_code)] -/// Mock runtime. -use groupsign::weights::PontemWeights; -use sp_mvm::gas; -use sp_core::{H256, sr25519}; -use sp_std::{convert::TryFrom, fmt::Debug}; -use frame_system as system; -use codec::{Decode, Encode}; -use system::EnsureRoot; -use frame_support::{ - PalletId, parameter_types, - traits::{Everything, ConstU32}, - weights::{Weight, constants::WEIGHT_PER_SECOND}, -}; -use sp_std::vec; -use std::include_bytes; -use frame_support::traits::{OnInitialize, OnFinalize}; -use sp_runtime::traits::{Verify, Lazy, BlakeTwo256, IdentityLookup, ConvertInto}; -use sp_runtime::{testing::Header}; -use orml_traits::parameter_type_with_key; -use constants::SS58_PREFIX; -use scale_info::TypeInfo; - -pub use primitives::currency::CurrencyId; -use module_currencies::BasicCurrencyAdapter; - -use super::vm_config::build as build_vm_config; - -type UncheckedExtrinsic = system::mocking::MockUncheckedExtrinsic; -type Block = system::mocking::MockBlock; - -/// Initial balance for all existent test accounts -pub const INITIAL_BALANCE: ::Balance = 42000; - -// Unit = the base number of indivisible units for balances -pub const UNIT: Balance = 1_000_000_000_000; -pub const MILLIUNIT: Balance = 1_000_000_000; -pub const MICROUNIT: Balance = 1_000_000; - -// Implement signature just for test. -#[derive(Eq, PartialEq, Clone, Encode, Decode, TypeInfo, Debug)] -pub struct AnySignature(sr25519::Signature); - -impl Verify for AnySignature { - type Signer = sr25519::Public; - fn verify>(&self, mut msg: L, signer: &sr25519::Public) -> bool { - let msg = msg.get(); - self.0.verify(msg, signer) - } -} - -impl From for AnySignature { - fn from(s: sr25519::Signature) -> Self { - Self(s) - } -} - -// Configure a mock runtime to test the pallet. -frame_support::construct_runtime!( - pub enum Test where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: system::{Pallet, Call, Config, Storage, Event}, - Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - Vesting: pallet_vesting::{Pallet, Call, Storage, Config, Event}, - Tokens: orml_tokens::{Pallet, Storage, Event}, - Currencies: module_currencies::{Pallet, Call, Storage, Event}, - Mvm: sp_mvm::{Pallet, Call, Config, Storage, Event}, - Groupsign: groupsign::{Pallet, Call, Origin, Event}, - } -); - -parameter_types! { - pub const BlockHashCount: u64 = 250; - pub const SS58Prefix: u8 = SS58_PREFIX; -} - -pub type AccountId = sp_core::sr25519::Public; -pub type Amount = i64; -pub type BlockNumber = u64; -pub type Balance = u64; - -impl system::Config for Test { - type BaseCallFilter = frame_support::traits::Everything; - type BlockWeights = (); - type BlockLength = (); - type DbWeight = (); - type Origin = Origin; - type Call = Call; - type Index = u64; - type BlockNumber = BlockNumber; - type Hash = H256; - type Hashing = BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Header = Header; - type Event = Event; - type BlockHashCount = BlockHashCount; - type Version = (); - type PalletInfo = PalletInfo; - // type AccountData = (); - type AccountData = pallet_balances::AccountData<::Balance>; - type OnNewAccount = (); - type OnKilledAccount = (); - type SystemWeightInfo = (); - type SS58Prefix = SS58Prefix; - type OnSetCode = (); - type MaxConsumers = ConstU32<12>; -} - -// --- gas --- // -/// By inheritance from Moonbeam and from Dfinance (based on validators statistic), we believe max 4125000 gas is currently enough for block. -/// In the same time we use same 500ms Weight as Max Block Weight, from which 75% only are used for transactions. -/// So our max gas is GAS_PER_SECOND * 0.500 * 0.65 => 4125000. -pub const GAS_PER_SECOND: u64 = 11_000_000; - -/// Approximate ratio of the amount of Weight per Gas. -/// u64 works for approximations because Weight is a very small unit compared to gas. -pub const WEIGHT_PER_GAS: u64 = WEIGHT_PER_SECOND / GAS_PER_SECOND; - -pub struct MoveVMGasWeightMapping; - -// Just use provided gas. -impl gas::GasWeightMapping for MoveVMGasWeightMapping { - fn gas_to_weight(gas: u64) -> Weight { - gas.saturating_mul(WEIGHT_PER_GAS) - } - - fn weight_to_gas(weight: Weight) -> u64 { - u64::try_from(weight.wrapping_div(WEIGHT_PER_GAS)).unwrap_or(u32::MAX as u64) - } -} -// ----------------- // - -// --- timestamp --- // - -parameter_types! { - pub const MinimumPeriod: u64 = 5; -} -impl pallet_timestamp::Config for Test { - /// A timestamp: milliseconds since the unix epoch. - type Moment = u64; - type OnTimestampSet = (); - type MinimumPeriod = MinimumPeriod; - type WeightInfo = (); -} - -// --- balances --- // - -parameter_types! { - pub const ExistentialDeposit: u64 = 1; - pub const TransferFee: u64 = 1 * MILLIUNIT; - pub const CreationFee: u64 = 1 * MILLIUNIT; - pub const TransactionByteFee: u64 = 1 * MILLIUNIT; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; -} - -impl pallet_balances::Config for Test { - type MaxLocks = MaxLocks; - /// The type for recording an account's balance. - type Balance = Balance; - /// The ubiquitous event type. - type Event = Event; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = Sys; - type WeightInfo = pallet_balances::weights::SubstrateWeight; - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; -} - -parameter_types! { - pub const MinVestedTransfer: Balance = 1; -} - -impl pallet_vesting::Config for Test { - type Event = Event; - type Currency = Balances; - type BlockNumberToBalance = ConvertInto; - type MinVestedTransfer = MinVestedTransfer; - type WeightInfo = (); - const MAX_VESTING_SCHEDULES: u32 = 1; -} - -parameter_type_with_key! { - pub ExistentialDeposits: |_currency_id: CurrencyId| -> Balance { - 100 - }; -} - -impl orml_tokens::Config for Test { - type Event = Event; - type Balance = Balance; - type Amount = primitives::Amount; - type CurrencyId = CurrencyId; - type WeightInfo = (); - type ExistentialDeposits = ExistentialDeposits; - type OnDust = (); - type MaxLocks = MaxLocks; - type DustRemovalWhitelist = Everything; -} - -parameter_types! { - pub const GetNativeCurrencyId: CurrencyId = CurrencyId::NATIVE; -} -impl module_currencies::Config for Test { - type Event = Event; - type CurrencyId = CurrencyId; - type MultiCurrency = Tokens; - type NativeCurrency = BasicCurrencyAdapter; - type GetNativeCurrencyId = GetNativeCurrencyId; - type WeightInfo = (); - type SweepOrigin = EnsureRoot; - type OnDust = (); -} - -// -------- move vm pallet --------- // -parameter_types! { - pub const MVMPalletId: PalletId = PalletId(*b"_nox/mvm"); -} -impl sp_mvm::Config for Test { - type Event = Event; - type GasWeightMapping = MoveVMGasWeightMapping; - type UpdateOrigin = EnsureRoot; - type PalletId = MVMPalletId; - type CurrencyId = CurrencyId; - type Currencies = Currencies; - type WeightInfo = (); -} - -parameter_types! { - pub const DepositBase: u64 = 0; - pub const DepositFactor: u64 = 0; - pub const MaxSignatories: u16 = 16; -} - -impl groupsign::Config for Test { - type Event = Event; - type Call = Call; - type Public = AccountId; - type Signature = AnySignature; - type MyOrigin = Origin; - type WeightInfo = PontemWeights; -} - -pub type Sys = system::Pallet; -pub type Time = pallet_timestamp::Pallet; -pub type MoveEvent = sp_mvm::Event; - -/// Runtime builder. -pub struct RuntimeBuilder { - balances: Vec<(AccountId, CurrencyId, Balance)>, - vesting: Vec<(AccountId, BlockNumber, u32, Balance)>, -} - -impl RuntimeBuilder { - /// Create new Runtime builder instance. - pub fn new() -> Self { - Self { - balances: vec![], - vesting: vec![], - } - } - - /// Set balances. - pub fn set_balances(mut self, balances: Vec<(AccountId, CurrencyId, Balance)>) -> Self { - self.balances = balances; - self - } - - /// Set vesting. - pub fn set_vesting(mut self, vesting: Vec<(AccountId, BlockNumber, u32, Balance)>) -> Self { - self.vesting = vesting; - self - } - - /// Build genesis storage according to the mock runtime. - pub fn build(self) -> sp_io::TestExternalities { - let mut sys = system::GenesisConfig::default() - .build_storage::() - .expect("Frame system builds valid default genesis config"); - - let native_currency_id = GetNativeCurrencyId::get(); - - pallet_balances::GenesisConfig:: { - balances: self - .balances - .clone() - .into_iter() - .filter(|(_, currency_id, _)| *currency_id == native_currency_id) - .map(|(account_id, _, initial_balance)| (account_id, initial_balance)) - .collect::>(), - } - .assimilate_storage(&mut sys) - .expect("Pallet balances storage can't be assimilated"); - - let vm_config = build_vm_config(); - - let move_stdlib = - include_bytes!("../../../pallets/sp-mvm/tests/assets/move-stdlib/build/MoveStdlib/bundles/MoveStdlib.pac") - .to_vec(); - let pont_framework = - include_bytes!("../../../pallets/sp-mvm/tests/assets/pont-stdlib/build/PontStdlib/bundles/PontStdlib.pac") - .to_vec(); - - sp_mvm::GenesisConfig:: { - move_stdlib, - pont_framework, - init_module: vm_config.0.clone(), - init_func: vm_config.1.clone(), - init_args: vm_config.2.clone(), - ..Default::default() - } - .assimilate_storage(&mut sys) - .expect("Pallet mvm storage can't be assimilated"); - - sys.into() - } -} - -/// Timestamp multiplier. -pub const TIME_BLOCK_MULTIPLIER: u64 = 100; - -/// Roll next block. -pub fn roll_next_block() { - Balances::on_finalize(Sys::block_number()); - Mvm::on_finalize(Sys::block_number()); - Sys::on_finalize(Sys::block_number()); - Sys::set_block_number(Sys::block_number() + 1); - Sys::on_initialize(Sys::block_number()); - Mvm::on_initialize(Sys::block_number()); - Balances::on_initialize(Sys::block_number()); - - // set time with multiplier `*MULTIPLIER` by block: - Time::set_timestamp(Sys::block_number() * TIME_BLOCK_MULTIPLIER); - - println!("now block: {}, time: {}", Sys::block_number(), Time::get()); -} - -/// Roll to block N. -pub fn roll_block_to(n: u64) { - while Sys::block_number() < n { - roll_next_block() - } -} - -/// Get last event. -pub fn last_event() -> Event { - { - let events = Sys::events(); - println!("events: {:?}", events); - } - Sys::events().pop().expect("Event expected").event -} - -/// If no events recently. -pub fn have_no_events() -> bool { - Sys::events().is_empty() -} diff --git a/runtime/tests/common/mod.rs b/runtime/tests/common/mod.rs deleted file mode 100644 index 5f7c02c4..00000000 --- a/runtime/tests/common/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod addr; -pub mod assets; -pub mod mocks; -pub mod utils; -pub mod vm_config; diff --git a/runtime/tests/common/utils.rs b/runtime/tests/common/utils.rs deleted file mode 100644 index 49998efa..00000000 --- a/runtime/tests/common/utils.rs +++ /dev/null @@ -1,150 +0,0 @@ -#![allow(dead_code)] -/// Utils functions to work with Move VM. -use std::convert::TryFrom; -use frame_support::dispatch::DispatchResultWithPostInfo as PsResult; -use move_core_types::account_address::AccountAddress; -use move_core_types::identifier::Identifier; -use move_core_types::language_storage::ModuleId; -use move_core_types::language_storage::StructTag; -use move_vm::io::state::State; -use move_vm::types::ModulePackage; -use move_core_types::language_storage::CORE_CODE_ADDRESS; -use move_core_types::resolver::ModuleResolver; -use move_core_types::resolver::ResourceResolver; - -use sp_mvm::storage::MoveVmStorage; - -use super::assets::*; -use super::mocks::*; -use super::addr::*; - -pub type AccountId = ::AccountId; - -/// Default gas limit. -pub const DEFAULT_GAS_LIMIT: u64 = 1_000_000; - -/// Publish module with storage check. -pub fn publish_module(signer: AccountId, module: &Asset, gas_limit: Option) -> PsResult { - let result = Mvm::publish_module( - Origin::signed(signer), - module.bytes().to_vec(), - gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), - )?; - check_storage_module(to_move_addr(signer), module.bytes().to_vec(), module.name()); - Ok(result) -} - -/// Publish module as root with storage check. -pub fn publish_module_as_root(module: &Asset, gas_limit: Option) -> PsResult { - let result = Mvm::publish_module( - Origin::root(), - module.bytes().to_vec(), - gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), - )?; - check_storage_module(CORE_CODE_ADDRESS, module.bytes().to_vec(), module.name()); - Ok(result) -} - -/// Publish package with storage check. -pub fn publish_package(signer: AccountId, package: &Package, gas_limit: Option) -> PsResult { - let result = Mvm::publish_package( - Origin::signed(signer), - package.bytes().to_vec(), - gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), - )?; - check_storage_package( - to_move_addr(signer), - package.bytes().to_vec(), - package.modules(), - ); - Ok(result) -} - -/// Publish package as root with storage check. -pub fn publish_package_as_root(package: &Package, gas_limit: Option) -> PsResult { - let result = Mvm::publish_package( - Origin::root(), - package.bytes().to_vec(), - gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), - )?; - check_storage_package( - CORE_CODE_ADDRESS, - package.bytes().to_vec(), - package.modules(), - ); - Ok(result) -} - -/// Execute transaction script. -pub fn execute_tx(origin: AccountId, tx: &Asset, gas_limit: Option) -> PsResult { - let gas_limit = gas_limit.unwrap_or(DEFAULT_GAS_LIMIT); - // get bytecode: - let bc = tx.bytes().to_vec(); - // execute VM tx: - let result = Mvm::execute(Origin::signed(origin), bc, gas_limit); - eprintln!("execute tx result: {:?}", result); - result -} - -/// Execute transaction script by Root. -pub fn execute_tx_by_root(tx: &Asset, gas_limit: Option) -> PsResult { - let gas_limit = gas_limit.unwrap_or(DEFAULT_GAS_LIMIT); - // get bytecode: - let bc = tx.bytes().to_vec(); - // execute VM tx: - let result = Mvm::execute(Origin::root(), bc, gas_limit); - eprintln!("execute tx result: {:?}", result); - result -} - -/// Check storage contains module. -pub fn check_storage_module>( - account_address: AccountAddress, - bc: Bc, - name: &str, -) { - let module_id = ModuleId::new(account_address, Identifier::new(name).unwrap()); - let storage = Mvm::move_vm_storage(); - let state = State::new(storage); - let stored = state - .get_module(&module_id) - .expect("VM state read storage") - .expect(&format!("Module '{}' should exist", module_id)); - assert_eq!(bc.as_ref(), &stored); -} - -/// Check storage contains package. -pub fn check_storage_package>( - account_address: AccountAddress, - bytecode: Bc, - names: &[&str], -) { - let (modules, _) = ModulePackage::try_from(bytecode.as_ref()) - .unwrap() - .into_tx(ROOT_ADDR) - .into_inner(); - - for (i, bytecode) in modules.iter().enumerate() { - check_storage_module(account_address, bytecode, names[i]); - } -} - -/// Check resource value inside storage. -pub fn check_storage_res(owner: AccountAddress, ty: StructTag, expected: T) -where - T: for<'de> serde::Deserialize<'de>, - T: std::cmp::PartialEq + std::fmt::Debug, -{ - let storage = Mvm::move_vm_storage(); - let state = State::new(storage); - let blob = state - .get_resource(&owner, &ty) - .expect("VM state read storage (resource)") - .expect(&format!("Resource '{}' should exist", ty)); - - let tt_str = format!("{}", ty); - println!("checking stored resource '{}'", tt_str); - let stored: T = - bcs::from_bytes(&blob).expect(&format!("Resource '{}' should exists", tt_str)); - assert_eq!(expected, stored); -} diff --git a/runtime/tests/common/vm_config.rs b/runtime/tests/common/vm_config.rs deleted file mode 100644 index 585de706..00000000 --- a/runtime/tests/common/vm_config.rs +++ /dev/null @@ -1,20 +0,0 @@ -/// VM configuration for tests. -use move_vm::genesis::GenesisConfig; - -/// Module to call to initialize genesis. -const MODULE_NAME: &[u8] = "Genesis".as_bytes(); - -/// Function to call to initialize genesis. -const FUNC_NAME: &[u8] = "initialize".as_bytes(); - -/// Build configuration to call initialize functions on Standard Library. -pub fn build() -> (Vec, Vec, Vec>) { - // We use standard arguments. - let genesis: GenesisConfig = Default::default(); - - ( - MODULE_NAME.to_vec(), - FUNC_NAME.to_vec(), - genesis.init_func_config.unwrap().args, - ) -} diff --git a/runtime/tests/scripts.rs b/runtime/tests/scripts.rs deleted file mode 100644 index 4ef7ae01..00000000 --- a/runtime/tests/scripts.rs +++ /dev/null @@ -1,76 +0,0 @@ -mod common; -use serde::Deserialize; -use move_core_types::{identifier::Identifier, language_storage::StructTag}; -use common::mocks::{AccountId, Mvm, roll_next_block, RuntimeBuilder, Origin, TIME_BLOCK_MULTIPLIER}; -use common::addr::{bob_public_key, to_move_addr, origin_move_addr}; -use common::assets::{Asset, modules, transactions}; -use common::utils::{self, check_storage_module, DEFAULT_GAS_LIMIT}; -use frame_support::dispatch::DispatchResultWithPostInfo; - -/// Check stored value (u64) inside storage. -fn check_stored_value(expected: u64) { - #[derive(Deserialize, Debug, PartialEq)] - struct StoreU64 { - pub val: u64, - } - - let expected = StoreU64 { val: expected }; - - let tag = StructTag { - address: origin_move_addr(), - module: Identifier::new(modules::user::STORE.name()).unwrap(), - name: Identifier::new("U64").unwrap(), - type_params: vec![], - }; - - utils::check_storage_res(origin_move_addr(), tag, expected); -} - -/// Publish module with storage check. -pub fn publish_module( - signer: AccountId, - module: &Asset, - gas_limit: Option, -) -> DispatchResultWithPostInfo { - let result = Mvm::publish_module( - Origin::signed(signer), - module.bytes().to_vec(), - gas_limit.unwrap_or(DEFAULT_GAS_LIMIT), - )?; - check_storage_module(to_move_addr(signer), module.bytes().to_vec(), module.name()); - Ok(result) -} - -#[test] -/// Execute storing of block height inside module by calling script. -fn execute_store_block() { - RuntimeBuilder::new().build().execute_with(|| { - let origin = bob_public_key(); - - utils::publish_module(origin, &modules::user::STORE, None).unwrap(); - - const EXPECTED: u64 = 3; - for _ in 0..EXPECTED { - roll_next_block(); - } - utils::execute_tx(origin, &transactions::STORE_SYSTEM_BLOCK, None).unwrap(); - check_stored_value(EXPECTED); - }); -} - -#[test] -/// Execute storing of timestamp inside module by calling script. -fn execute_store_time() { - RuntimeBuilder::new().build().execute_with(|| { - let origin = bob_public_key(); - - utils::publish_module(origin, &modules::user::STORE, None).unwrap(); - - const EXPECTED: u64 = 3; - for _ in 0..EXPECTED { - roll_next_block(); - } - utils::execute_tx(origin, &transactions::STORE_SYSTEM_TIMESTAMP, None).unwrap(); - check_stored_value(EXPECTED * TIME_BLOCK_MULTIPLIER); - }); -} From 8083179ec0c9c5e306378872a9b626f1c32ca393 Mon Sep 17 00:00:00 2001 From: Belousov Maksim Date: Mon, 11 Apr 2022 17:29:07 +0300 Subject: [PATCH 4/4] Add ensure_root runtime tests. --- runtime/src/tests/ensure_root.rs | 81 ++++++++++++++++++++++++++++++++ runtime/src/tests/mod.rs | 3 ++ 2 files changed, 84 insertions(+) create mode 100644 runtime/src/tests/ensure_root.rs diff --git a/runtime/src/tests/ensure_root.rs b/runtime/src/tests/ensure_root.rs new file mode 100644 index 00000000..77634ab1 --- /dev/null +++ b/runtime/src/tests/ensure_root.rs @@ -0,0 +1,81 @@ +use crate::tests::mock::{ + RuntimeBuilder, Accounts, Origin, TransactionPause, CurrencyId, Currencies, ParachainStaking, + Perbill, +}; +use frame_support::{assert_ok, assert_err, error::BadOrigin}; + +#[test] +fn ensure_root_in_transaction_pause() { + RuntimeBuilder::new().build().execute_with(|| { + assert_ok!(TransactionPause::pause_transaction( + Origin::root(), + b"Balances".to_vec(), + b"transfer".to_vec() + )); + assert_err!( + TransactionPause::pause_transaction( + Origin::signed(Accounts::BOB.account()), + b"Balances".to_vec(), + b"transfer".to_vec() + ), + BadOrigin + ); + }) +} + +#[test] +fn ensure_root_in_update_balance() { + RuntimeBuilder::new().build().execute_with(|| { + assert_err!( + Currencies::update_balance( + Origin::signed(Accounts::ALICE.account()), + Accounts::ALICE.account().into(), + CurrencyId::NATIVE, + 100 + ), + BadOrigin + ); + assert_ok!(Currencies::update_balance( + Origin::root(), + Accounts::ALICE.account().into(), + CurrencyId::NATIVE, + 100 + )); + }); +} + +#[test] +fn ensure_root_in_parachain_staking() { + RuntimeBuilder::new().build().execute_with(|| { + assert_err!( + ParachainStaking::set_blocks_per_round( + Origin::signed(Accounts::ALICE.account()), + 20u32 + ), + BadOrigin + ); + assert_ok!(ParachainStaking::set_blocks_per_round( + Origin::root(), + 42u32 + )); + assert_err!( + ParachainStaking::set_collator_commission( + Origin::signed(Accounts::ALICE.account()), + Perbill::from_percent(5) + ), + BadOrigin + ); + assert_ok!(ParachainStaking::set_collator_commission( + Origin::root(), + Perbill::from_percent(5) + )); + assert_err!( + ParachainStaking::set_total_selected( + Origin::signed(Accounts::ALICE.account()), + 42u32 + ), + BadOrigin + ); + assert_ok!(ParachainStaking::set_total_selected(Origin::root(), 42u32)); + }) +} diff --git a/runtime/src/tests/mod.rs b/runtime/src/tests/mod.rs index 26746c44..71c2ccaa 100644 --- a/runtime/src/tests/mod.rs +++ b/runtime/src/tests/mod.rs @@ -10,3 +10,6 @@ pub mod parachain; // MVM scripts tests pub mod scripts; + +// Root access tests +pub mod ensure_root;