Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Pause program API #691

Merged
merged 67 commits into from Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
2860d32
pause module
gshep Feb 18, 2022
c23aa8f
test pause_program_should_work
gshep Feb 21, 2022
49f3fcd
update test case
gshep Feb 21, 2022
3bab1df
test case pause_program_twice_fails
gshep Feb 21, 2022
7335440
test case pause_terminated_program_fails
gshep Feb 21, 2022
38c1d63
test case pause_uninitialized_program_works
gshep Feb 21, 2022
3cc65fd
initial version of resume_program
gshep Feb 21, 2022
d3d02ad
remove from paused_programs
gshep Feb 21, 2022
e8c4583
test case resume_uninitialized_program_works
gshep Feb 22, 2022
c1ade54
refactor pause_uninitialized_program_works
gshep Feb 22, 2022
d894439
add pages_prefix
gshep Feb 22, 2022
62b3238
calculate memory pages hash in the function
gshep Feb 22, 2022
9883cfb
make paused_program_key private
gshep Feb 22, 2022
5d0dfa7
test case resume_program_twice_fails
gshep Feb 22, 2022
969db44
test case resume_program_wrong_memory_fails
gshep Feb 22, 2022
7627a35
edit test pause_program_works
gshep Feb 22, 2022
104a7db
refactor some pallet tests
gshep Feb 22, 2022
7548f1f
pallet test case paused_program_keeps_id
gshep Feb 22, 2022
3254ccf
pass the test
gshep Feb 22, 2022
69a55fe
Merge remote-tracking branch 'origin/master'
gshep Feb 23, 2022
3ea0dee
fix build after master merged
gshep Feb 23, 2022
0d40496
pallet test case messages_to_paused_program_skipped
gshep Feb 23, 2022
c76f7b6
pass the test
gshep Feb 23, 2022
bf7e582
pallet test case replies_to_paused_program_skipped
gshep Feb 23, 2022
d805b84
pass the test
gshep Feb 23, 2022
f9b115c
pallet test case
gshep Feb 24, 2022
209a95c
pass the test
gshep Feb 24, 2022
af430a4
resume_program extrinsic
gshep Feb 24, 2022
eb7f643
pallet test case resume_program_works
gshep Feb 24, 2022
0fa37e8
add corresponding benchmark
gshep Feb 25, 2022
466a48f
update weights.rs
gshep Feb 25, 2022
84eb5ab
emit event in resume_program
gshep Feb 25, 2022
b4f0ca6
docs
gshep Feb 25, 2022
ba1f51e
Merge remote-tracking branch 'origin/master'
gshep Feb 25, 2022
2049bc2
bump spec version
gshep Feb 25, 2022
a9bf141
pre-commit
gshep Feb 25, 2022
bb3d4c4
Merge remote-tracking branch 'origin/master'
gshep Feb 28, 2022
ca8cd81
fix several remarks after review
gshep Feb 28, 2022
a98d71a
initial pallet/gear-program
gshep Mar 9, 2022
329ee41
move resume_program to the pallet
gshep Mar 10, 2022
2ce03f2
move tests from common to the pallet
gshep Mar 10, 2022
059c357
refactor a bit
gshep Mar 10, 2022
c8d999b
fix build
gshep Mar 10, 2022
e12f12d
fix remark after review
gshep Mar 10, 2022
9e178ff
fix benchmarks build
gshep Mar 10, 2022
da96dfc
Merge remote-tracking branch 'origin/master'
gshep Mar 10, 2022
fbdcacd
bump spec version
gshep Mar 10, 2022
75502ca
pre-commit
gshep Mar 10, 2022
b22229b
update README
gshep Mar 11, 2022
841e3c5
move extrinsic `resume_program`
gshep Mar 14, 2022
ba9af42
adjust pallet/gear
gshep Mar 14, 2022
965b45f
adjust pallet/gear-debug
gshep Mar 14, 2022
55bf9ce
adjust pallets/usage
gshep Mar 14, 2022
2ceda67
move common funcs to common::benchmarking
gshep Mar 14, 2022
dae3209
impl pallets/gear-program/benchmarking
gshep Mar 14, 2022
c0e4eba
perform benchmarks and use generated weights
gshep Mar 14, 2022
882067a
Merge remote-tracking branch 'origin/master'
gshep Mar 14, 2022
538b275
pre-commit
gshep Mar 14, 2022
62e4c47
rename to WeightInfo
gshep Mar 14, 2022
a53261c
fix several remarks after review
gshep Mar 15, 2022
48fa59d
pallets/gear-program: remove redundant deps
gshep Mar 15, 2022
91311fd
fix benchmarks build
gshep Mar 15, 2022
7ae08bb
set lock on value in resume_program
gshep Mar 16, 2022
fbc0cd7
don't store wait_list for PausedProgram
gshep Mar 16, 2022
4505439
pre-commit
gshep Mar 16, 2022
0909acc
fix benchmark build
gshep Mar 16, 2022
4a5d8f1
add TODO comment about lock
gshep Mar 16, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 39 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions common/Cargo.toml
Expand Up @@ -22,7 +22,10 @@ sp-runtime = { version = "5.0.0", git = "https://github.com/gear-tech/substrate.
sp-std = { version = "4.0.0", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false }
sp-arithmetic = { version = "4.0.0-dev", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false }
frame-support = { version = "4.0.0-dev", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false }
frame-system = { version = "4.0.0-dev", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false, optional = true }
frame-benchmarking = { version = "4.0.0-dev", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable", default-features = false, optional = true }
gear-runtime-interface = { path = "../runtime-interface", default-features = false }
parity-wasm = { version = "0.42.2", default-features = false, optional = true }

[features]
default = ["std"]
Expand All @@ -38,3 +41,9 @@ std = [
"primitive-types/std",
"gear-runtime-interface/std",
]
runtime-benchmarks = [
"frame-benchmarking",
"frame-system/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"parity-wasm",
]
147 changes: 147 additions & 0 deletions common/src/benchmarking.rs
@@ -0,0 +1,147 @@
// This file is part of Gear.

// Copyright (C) 2022 Gear Technologies Inc.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use super::*;

use parity_wasm::elements::*;
use sp_io::hashing::blake2_256;
use sp_std::borrow::ToOwned;

pub fn account<AccountId: Origin>(name: &'static str, index: u32, seed: u32) -> AccountId {
let entropy = (name, index, seed).using_encoded(blake2_256);
AccountId::from_origin(H256::from_slice(&entropy[..]))
}

// A wasm module that allocates `$num_pages` of memory in `init` function.
// In text format would look something like
// (module
// (type (func))
// (import "env" "memory" (memory $num_pages))
// (func (type 0))
// (export "init" (func 0)))
pub fn create_module(num_pages: u32) -> parity_wasm::elements::Module {
parity_wasm::elements::Module::new(vec![
Section::Type(TypeSection::with_types(vec![Type::Function(
FunctionType::new(vec![], vec![]),
)])),
Section::Import(ImportSection::with_entries(vec![ImportEntry::new(
"env".into(),
"memory".into(),
External::Memory(MemoryType::new(num_pages, None)),
)])),
Section::Function(FunctionSection::with_entries(vec![Func::new(0)])),
Section::Export(ExportSection::with_entries(vec![ExportEntry::new(
"init".into(),
Internal::Function(0),
)])),
Section::Code(CodeSection::with_bodies(vec![FuncBody::new(
vec![],
Instructions::new(vec![Instruction::End]),
)])),
])
}

pub fn generate_wasm(num_pages: u32) -> Result<Vec<u8>, &'static str> {
let module = create_module(num_pages);
let code = parity_wasm::serialize(module).map_err(|_| "Failed to serialize module")?;

Ok(code)
}

// A wasm module that allocates `$num_pages` in `handle` function:
// (module
// (import "env" "memory" (memory 1))
// (import "env" "alloc" (func $alloc (param i32) (result i32)))
// (export "init" (func $init))
// (export "handle" (func $handle))
// (func $init)
// (func $handle
// (local $result i32)
// (local.set $result (call $alloc (i32.const $num_pages)))
// )
// )
pub fn generate_wasm2(num_pages: i32) -> Result<Vec<u8>, &'static str> {
let module = parity_wasm::elements::Module::new(vec![
Section::Type(TypeSection::with_types(vec![
Type::Function(FunctionType::new(
vec![ValueType::I32],
vec![ValueType::I32],
)),
Type::Function(FunctionType::new(vec![], vec![])),
])),
Section::Import(ImportSection::with_entries(vec![
ImportEntry::new(
"env".into(),
"memory".into(),
External::Memory(MemoryType::new(1_u32, None)),
),
ImportEntry::new("env".into(), "alloc".into(), External::Function(0_u32)),
])),
Section::Function(FunctionSection::with_entries(vec![
Func::new(1_u32),
Func::new(1_u32),
])),
Section::Export(ExportSection::with_entries(vec![
ExportEntry::new("init".into(), Internal::Function(1)),
ExportEntry::new("handle".into(), Internal::Function(2)),
])),
Section::Code(CodeSection::with_bodies(vec![
FuncBody::new(vec![], Instructions::new(vec![Instruction::End])),
FuncBody::new(
vec![Local::new(1, ValueType::I32)],
Instructions::new(vec![
Instruction::I32Const(num_pages),
Instruction::Call(0),
Instruction::SetLocal(0),
Instruction::End,
]),
),
])),
]);
let code = parity_wasm::serialize(module).map_err(|_| "Failed to serialize module")?;

Ok(code)
}

pub fn generate_wasm3(payload: Vec<u8>) -> Result<Vec<u8>, &'static str> {
let mut module = create_module(1);
module
.insert_section(Section::Custom(CustomSection::new(
"zeroed_section".to_owned(),
payload,
)))
.unwrap();
let code = parity_wasm::serialize(module).map_err(|_| "Failed to serialize module")?;

Ok(code)
}

pub fn set_program(program_id: H256, code: Vec<u8>, static_pages: u32, nonce: u64) {
let code_hash = CodeHash::generate(&code).into_origin();
super::set_program(
program_id,
ActiveProgram {
static_pages,
persistent_pages: (0..static_pages).collect(),
code_hash,
nonce,
state: ProgramState::Initialized,
},
(0..static_pages).map(|i| (i, vec![0u8; 65536])).collect(),
);
}
28 changes: 20 additions & 8 deletions common/src/lib.rs
Expand Up @@ -22,6 +22,9 @@ pub mod lazy_pages;
pub mod native;
pub mod storage_queue;

#[cfg(feature = "runtime-benchmarks")]
pub mod benchmarking;

use codec::{Decode, Encode};
use frame_support::{
dispatch::{DispatchError, DispatchResult},
Expand Down Expand Up @@ -492,22 +495,32 @@ fn code_key(code_hash: H256, kind: CodeKeyPrefixKind) -> Vec<u8> {
key
}

fn page_key(id: H256, page: u32) -> Vec<u8> {
pub fn pages_prefix(program_id: H256) -> Vec<u8> {
let mut key = Vec::new();
key.extend(STORAGE_PROGRAM_PAGES_PREFIX);
id.encode_to(&mut key);
program_id.encode_to(&mut key);

key
}

fn page_key(id: H256, page: u32) -> Vec<u8> {
let mut key = pages_prefix(id);
key.extend(b"::");
page.encode_to(&mut key);
key
}

pub fn wait_key(prog_id: H256, msg_id: H256) -> Vec<u8> {
pub fn wait_prefix(prog_id: H256) -> Vec<u8> {
let mut key = Vec::new();
key.extend(STORAGE_WAITLIST_PREFIX);
prog_id.encode_to(&mut key);
key.extend(b"::");
msg_id.encode_to(&mut key);
key
}

pub fn wait_key(prog_id: H256, msg_id: H256) -> Vec<u8> {
let mut key = wait_prefix(prog_id);
msg_id.encode_to(&mut key);
key
}

Expand Down Expand Up @@ -545,9 +558,8 @@ pub fn set_program_terminated_status(id: H256) -> Result<(), ProgramError> {
if program.is_terminated() {
return Err(ProgramError::IsTerminated);
}
let mut pages_prefix = STORAGE_PROGRAM_PAGES_PREFIX.to_vec();
pages_prefix.extend(&program_key(id));
sp_io::storage::clear_prefix(&pages_prefix, None);

sp_io::storage::clear_prefix(&pages_prefix(id), None);
sp_io::storage::set(&program_key(id), &Program::Terminated.encode());

Ok(())
Expand Down Expand Up @@ -699,7 +711,7 @@ pub fn remove_waiting_message(dest_prog_id: H256, msg_id: H256) -> Option<(Queue
msg
}

fn waiting_init_prefix(prog_id: H256) -> Vec<u8> {
pub fn waiting_init_prefix(prog_id: H256) -> Vec<u8> {
let mut key = Vec::new();
key.extend(STORAGE_PROGRAM_STATE_WAIT_PREFIX);
prog_id.encode_to(&mut key);
Expand Down
1 change: 1 addition & 0 deletions pallets/gear-debug/Cargo.toml
Expand Up @@ -43,6 +43,7 @@ gear-backend-sandbox = { path = "../../core-backend/sandbox", default-features =
hex-literal = "0.3.3"
pallet-timestamp = { version = "4.0.0-dev", git = "https://github.com/gear-tech/substrate.git", branch = "gear-stable" }
pallet-gas = { path = "../gas" }
pallet-gear-program = { path = "../gear-program", default-features = false }

[features]
default = ['std']
Expand Down
7 changes: 7 additions & 0 deletions pallets/gear-debug/src/mock.rs
Expand Up @@ -118,6 +118,12 @@ impl common::GasPrice for GasConverter {
type Balance = u128;
}

impl pallet_gear_program::Config for Test {
type Event = Event;
type WeightInfo = ();
type Currency = Balances;
}

impl pallet_gear::Config for Test {
type Event = Event;
type Currency = Balances;
Expand All @@ -143,6 +149,7 @@ construct_runtime!(
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
Authorship: pallet_authorship::{Pallet, Storage},
Timestamp: pallet_timestamp::{Pallet, Storage},
GearProgram: pallet_gear_program::{Pallet, Storage, Event<T>},
Gear: pallet_gear::{Pallet, Call, Storage, Event<T>},
Gas: pallet_gas,
}
Expand Down