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

feat(demo-constructor): Support multiple calls in if_else #3487

Merged
merged 13 commits into from
Dec 3, 2023
17 changes: 5 additions & 12 deletions examples/constructor/src/builder.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -297,20 +297,13 @@ impl Calls {
pub fn if_else(
mqxf marked this conversation as resolved.
Show resolved Hide resolved
self,
bool_arg: impl Into<Arg<bool>>,
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(),
))
}

Expand Down
16 changes: 9 additions & 7 deletions examples/constructor/src/call.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand Down Expand Up @@ -34,7 +34,7 @@ pub enum Call {
Exit(Arg<[u8; 32]>),
BytesEq(Arg<Vec<u8>>, Arg<Vec<u8>>),
Noop,
IfElse(Arg<bool>, Box<Self>, Box<Self>),
IfElse(Arg<bool>, Vec<Self>, Vec<Self>),
Load,
LoadBytes,
Wait,
Expand Down Expand Up @@ -246,18 +246,20 @@ mod wasm {
Some((left == right).encode())
}

fn if_else(self, previous: Option<CallResult>) -> Option<Vec<u8>> {
let Self::IfElse(flag, true_call, false_call) = self else {
fn if_else(self, mut previous: Option<CallResult>) -> Option<Vec<u8>> {
mqxf marked this conversation as resolved.
Show resolved Hide resolved
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));
mqxf marked this conversation as resolved.
Show resolved Hide resolved
}

value
previous.and_then(|res| res.1)
techraed marked this conversation as resolved.
Show resolved Hide resolved
}

fn value(self) -> Option<Vec<u8>> {
Expand Down
74 changes: 74 additions & 0 deletions pallets/gear/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15086,6 +15086,80 @@ 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)),
mqxf marked this conversation as resolved.
Show resolved Hide resolved
Calls::builder().add_call(Call::Bool(true)),
)
.store("switch")
.if_else(
Arg::get("switch"),
Calls::builder().wait_for(1),
mqxf marked this conversation as resolved.
Show resolved Hide resolved
Calls::builder().wait(),
);

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::<Test>::contains(&pid, &mid));
assert!(TaskPoolOf::<Test>::contains(
&(Gear::block_number() + 1),
&task
));

run_to_next_block(None);

assert!(WaitlistOf::<Test>::contains(&pid, &mid));
assert!(!TaskPoolOf::<Test>::contains(
&(Gear::block_number()),
&task
));
assert!(!TaskPoolOf::<Test>::contains(
&(Gear::block_number() + 1),
&task
));
});
}

mod utils {
#![allow(unused)]

Expand Down