diff --git a/examples/constructor/src/scheme/mod.rs b/examples/constructor/src/scheme/mod.rs index 280c5682875..fc140c94fe7 100644 --- a/examples/constructor/src/scheme/mod.rs +++ b/examples/constructor/src/scheme/mod.rs @@ -52,6 +52,15 @@ impl Scheme { ) } + pub fn with_handle(handle: Calls) -> Self { + Self::Predefined( + Default::default(), + handle.calls(), + Default::default(), + Default::default(), + ) + } + pub fn init(&self) -> &Vec { match self { Self::Direct(init) => init, diff --git a/pallets/gear/src/runtime_api.rs b/pallets/gear/src/runtime_api.rs index 60fcc9c4c18..72c8f34158b 100644 --- a/pallets/gear/src/runtime_api.rs +++ b/pallets/gear/src/runtime_api.rs @@ -247,11 +247,11 @@ where // 'wait_for' and 'wait_up_to' should not consume all available gas // because of the limited durations. If a duration is a big enough then it // won't matter how to calculate the limit: it will be the same. - JournalNote::WaitDispatch { ref dispatch, .. } - if from_main_chain(dispatch.id())? => - { - min_limit = initial_gas - } + JournalNote::WaitDispatch { + ref dispatch, + waited_type: MessageWaitedType::Wait, + .. + } if from_main_chain(dispatch.id())? => min_limit = initial_gas, _ => (), }, } diff --git a/pallets/gear/src/tests.rs b/pallets/gear/src/tests.rs index f4a13e4db98..05b1b0f5eb5 100644 --- a/pallets/gear/src/tests.rs +++ b/pallets/gear/src/tests.rs @@ -67,6 +67,45 @@ use utils::*; type Gas = <::GasProvider as common::GasProvider>::GasTree; +#[test] +fn calculate_gas_results_in_finite_wait() { + use demo_constructor::{Calls, Scheme}; + + // Imagine that this is async `send_for_reply` to some user + // with wait up to 20 that is not rare case. + let receiver_scheme = Scheme::with_handle(Calls::builder().wait_for(20)); + + let sender_scheme = |receiver_id: ProgramId| { + Scheme::with_handle(Calls::builder().send_wgas( + <[u8; 32]>::from(receiver_id), + [], + 40_000_000_000u64, + )) + }; + + init_logger(); + new_test_ext().execute_with(|| { + let (_init_mid, receiver) = init_constructor(receiver_scheme); + let (_init_mid, sender) = + submit_constructor_with_args(USER_1, "salty salt", sender_scheme(receiver), 0); + + run_to_next_block(None); + + let GasInfo { min_limit, .. } = Gear::calculate_gas_info( + USER_1.into_origin(), + HandleKind::Handle(sender), + EMPTY_PAYLOAD.to_vec(), + 0, + true, + true, + ) + .expect("calculate_gas_info failed"); + + // Original issue: this case used to return block gas limit as minimal. + assert!(BlockGasLimitOf::::get() / 2 > min_limit); + }); +} + #[test] fn state_rpc_calls_trigger_reinstrumentation() { use demo_new_meta::{MessageInitIn, META_WASM_V1, WASM_BINARY};