diff --git a/examples/constructor/src/builder.rs b/examples/constructor/src/builder.rs index bf871191605..a11b94f0640 100644 --- a/examples/constructor/src/builder.rs +++ b/examples/constructor/src/builder.rs @@ -1,5 +1,5 @@ use crate::{Arg, Call}; -use alloc::{boxed::Box, string::ToString, vec, vec::Vec}; +use alloc::{string::ToString, vec, vec::Vec}; use core::{fmt::Debug, ops::Deref}; use parity_scale_codec::{WrapperTypeDecode, WrapperTypeEncode}; @@ -297,20 +297,13 @@ impl Calls { pub fn if_else( self, bool_arg: impl Into>, - mut true_call: Self, - mut false_call: Self, + true_calls: Self, + false_calls: Self, ) -> Self { - if true_call.len() != 1 || false_call.len() != 1 { - unimplemented!() - }; - - let true_call = true_call.0.remove(0); - let false_call = false_call.0.remove(0); - self.add_call(Call::IfElse( bool_arg.into(), - Box::new(true_call), - Box::new(false_call), + true_calls.calls(), + false_calls.calls(), )) } diff --git a/examples/constructor/src/call.rs b/examples/constructor/src/call.rs index 2f14a20030c..2a82d24c5ca 100644 --- a/examples/constructor/src/call.rs +++ b/examples/constructor/src/call.rs @@ -1,5 +1,5 @@ use crate::Arg; -use alloc::{boxed::Box, string::String, vec::Vec}; +use alloc::{string::String, vec::Vec}; use parity_scale_codec::{Decode, Encode}; #[derive(Clone, Debug, Decode, Encode)] @@ -34,7 +34,7 @@ pub enum Call { Exit(Arg<[u8; 32]>), BytesEq(Arg>, Arg>), Noop, - IfElse(Arg, Box, Box), + IfElse(Arg, Vec, Vec), Load, LoadBytes, Wait, @@ -246,18 +246,20 @@ mod wasm { Some((left == right).encode()) } - fn if_else(self, previous: Option) -> Option> { - let Self::IfElse(flag, true_call, false_call) = self else { + fn if_else(self, mut previous: Option) -> Option> { + let Self::IfElse(flag, true_calls, false_calls) = self else { unreachable!() }; let flag = flag.value(); - let call = if flag { true_call } else { false_call }; + let calls = if flag { true_calls } else { false_calls }; - let (_call, value) = call.process(previous); + for call in calls { + previous = Some(call.process(previous)); + } - value + previous.and_then(|res| res.1) } fn value(self) -> Option> { diff --git a/pallets/gear/src/tests.rs b/pallets/gear/src/tests.rs index 5fc4f0f0550..428c78ce8da 100644 --- a/pallets/gear/src/tests.rs +++ b/pallets/gear/src/tests.rs @@ -15086,6 +15086,72 @@ fn test_handle_signal_wait() { }); } +#[test] +fn test_constructor_if_else() { + use demo_constructor::{Arg, Call, Calls, Scheme, WASM_BINARY}; + + init_logger(); + new_test_ext().execute_with(|| { + let init = Calls::builder().bool("switch", false); + let handle = Calls::builder() + .if_else( + Arg::get("switch"), + Calls::builder().add_call(Call::Bool(false)), + Calls::builder().add_call(Call::Bool(true)), + ) + .store("switch") + .if_else( + Arg::get("switch"), + Calls::builder().wait_for(1), + Calls::builder().exit(<[u8; 32]>::from(USER_1.into_origin())), + ); + + let scheme = Scheme::predefined(init, handle, Default::default(), Default::default()); + + assert_ok!(Gear::upload_program( + RuntimeOrigin::signed(USER_1), + WASM_BINARY.to_vec(), + DEFAULT_SALT.to_vec(), + scheme.encode(), + 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(), + 100_000_000_000, + 0, + false, + )); + + let mid = get_last_message_id(); + + run_to_next_block(None); + + let task = ScheduledTask::WakeMessage(pid, mid); + + assert!(WaitlistOf::::contains(&pid, &mid)); + assert!(TaskPoolOf::::contains( + &(Gear::block_number() + 1), + &task + )); + + run_to_next_block(None); + + assert!(!WaitlistOf::::contains(&pid, &mid)); + }); +} + mod utils { #![allow(unused)]