diff --git a/Cargo.lock b/Cargo.lock index b981cad3a04..1dccf560b3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2450,6 +2450,14 @@ dependencies = [ "parity-scale-codec", ] +[[package]] +name = "demo-signal-wait" +version = "0.1.0" +dependencies = [ + "gear-wasm-builder", + "gstd", +] + [[package]] name = "demo-stack-allocations" version = "0.1.0" @@ -7619,6 +7627,7 @@ dependencies = [ "demo-rwlock", "demo-send-from-reservation", "demo-signal-entry", + "demo-signal-wait", "demo-state-rollback", "demo-sync-duplicate", "demo-wait", diff --git a/Cargo.toml b/Cargo.toml index 3dd644893ef..a2b8fad3ce2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,6 +58,7 @@ members = [ "examples/rwlock", "examples/send-from-reservation", "examples/signal-entry", + "examples/signal-wait", "examples/state-rollback", "examples/sync-duplicate", "examples/sys-calls", @@ -416,6 +417,7 @@ demo-reserve-gas = { path = "examples/reserve-gas", default-features = false } demo-rwlock = { path = "examples/rwlock" } demo-send-from-reservation = { path = "examples/send-from-reservation" } demo-signal-entry = { path = "examples/signal-entry" } +demo-signal-wait = { path = "examples/signal-wait" } demo-state-rollback = { path = "examples/state-rollback" } demo-sync-duplicate = { path = "examples/sync-duplicate" } demo-vec = { path = "examples/vec" } diff --git a/examples/signal-wait/Cargo.toml b/examples/signal-wait/Cargo.toml new file mode 100644 index 00000000000..a69c63c4d01 --- /dev/null +++ b/examples/signal-wait/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "demo-signal-wait" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true + +[dependencies] +gstd.workspace = true + +[build-dependencies] +gear-wasm-builder.workspace = true + +[features] +debug = ["gstd/debug"] +default = ["std"] +std = [] diff --git a/examples/signal-wait/build.rs b/examples/signal-wait/build.rs new file mode 100644 index 00000000000..4c502a3ddee --- /dev/null +++ b/examples/signal-wait/build.rs @@ -0,0 +1,21 @@ +// This file is part of Gear. + +// Copyright (C) 2021-2023 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 . + +fn main() { + gear_wasm_builder::build(); +} diff --git a/examples/signal-wait/src/lib.rs b/examples/signal-wait/src/lib.rs new file mode 100644 index 00000000000..43f5e17c84a --- /dev/null +++ b/examples/signal-wait/src/lib.rs @@ -0,0 +1,30 @@ +// This file is part of Gear. + +// Copyright (C) 2022-2023 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 . + +#![no_std] + +#[cfg(feature = "std")] +mod code { + include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +} + +#[cfg(feature = "std")] +pub use code::WASM_BINARY_OPT as WASM_BINARY; + +#[cfg(not(feature = "std"))] +mod wasm; diff --git a/examples/signal-wait/src/wasm.rs b/examples/signal-wait/src/wasm.rs new file mode 100644 index 00000000000..d00fb71420a --- /dev/null +++ b/examples/signal-wait/src/wasm.rs @@ -0,0 +1,39 @@ +// This file is part of Gear. + +// Copyright (C) 2023 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 . + +use gstd::{exec, prelude::*}; + +static mut FIRST_EXEC: bool = true; + +#[no_mangle] +extern "C" fn handle() { + if unsafe { FIRST_EXEC } { + unsafe { + FIRST_EXEC = false; + } + exec::system_reserve_gas(1_000_000_000).unwrap(); + exec::wait_for(1); + } else { + panic!(); + } +} + +#[no_mangle] +extern "C" fn handle_signal() { + exec::wait(); +} diff --git a/pallets/gear/Cargo.toml b/pallets/gear/Cargo.toml index 74f38e368cf..a70eaf7fe1c 100644 --- a/pallets/gear/Cargo.toml +++ b/pallets/gear/Cargo.toml @@ -106,6 +106,7 @@ demo-rwlock.workspace = true demo-reservation-manager.workspace = true demo-send-from-reservation.workspace = true demo-signal-entry.workspace = true +demo-signal-wait.workspace = true demo-state-rollback.workspace = true demo-async-signal-entry.workspace = true demo-async-custom-entry.workspace = true diff --git a/pallets/gear/src/tests.rs b/pallets/gear/src/tests.rs index d959bd76375..5fc4f0f0550 100644 --- a/pallets/gear/src/tests.rs +++ b/pallets/gear/src/tests.rs @@ -15028,6 +15028,64 @@ fn test_gas_info_of_terminated_program() { }) } +#[test] +fn test_handle_signal_wait() { + use demo_signal_wait::WASM_BINARY; + + init_logger(); + new_test_ext().execute_with(|| { + assert_ok!(Gear::upload_program( + RuntimeOrigin::signed(USER_1), + WASM_BINARY.to_vec(), + DEFAULT_SALT.to_vec(), + EMPTY_PAYLOAD.to_vec(), + 100_000_000_000, + 0, + false, + )); + + let pid = get_last_program_id(); + + run_to_next_block(None); + + assert!(Gear::is_active(pid)); + assert!(Gear::is_initialized(pid)); + + assert_ok!(Gear::send_message( + RuntimeOrigin::signed(USER_1), + pid, + EMPTY_PAYLOAD.to_vec(), + 50_000_000_000, + 0, + false, + )); + + let mid = get_last_message_id(); + + run_to_next_block(None); + + assert_ok!(GasHandlerOf::::get_system_reserve(mid)); + assert!(WaitlistOf::::contains(&pid, &mid)); + + run_to_next_block(None); + + let signal_mid = MessageId::generate_signal(mid); + assert!(WaitlistOf::::contains(&pid, &signal_mid)); + + let (mid, block) = get_last_message_waited(); + + assert_eq!(mid, signal_mid); + + System::set_block_number(block - 1); + Gear::set_block_number(block - 1); + run_to_next_block(None); + + assert!(!WaitlistOf::::contains(&pid, &signal_mid)); + + assert_total_dequeued(4); + }); +} + mod utils { #![allow(unused)]