Skip to content

Commit

Permalink
refactor(pallet-gear): Allow calculate_gas_info on terminated program.
Browse files Browse the repository at this point in the history
  • Loading branch information
mqxf committed Sep 15, 2023
1 parent 4e263f0 commit d44a160
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 6 deletions.
27 changes: 21 additions & 6 deletions pallets/gear/src/runtime_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use super::*;
use crate::queue::QueueStep;
use crate::queue::{ActorResult, QueueStep};
use common::ActiveProgram;
use core::convert::TryFrom;
use core_processor::common::PrechargedDispatch;
use gear_core::{code::TryNewCodeConfig, pages::WasmPage};
use gear_wasm_instrument::syscalls::SysCallName;

Expand Down Expand Up @@ -126,11 +127,25 @@ where
break;
};

//let actor = ext_manager
// .get_actor(actor_id)
// .ok_or_else(|| b"Program not found in the storage".to_vec())?;

let actor_id = queued_dispatch.destination();
let dispatch_id = queued_dispatch.id();
let dispatch_reply = queued_dispatch.reply_details().is_some();

let balance = CurrencyOf::<T>::free_balance(&<T::AccountId as Origin>::from_origin(
actor_id.into_origin(),
));

let actor = ext_manager
.get_actor(actor_id)
.ok_or_else(|| b"Program not found in the storage".to_vec())?;
let get_actor_data = |precharged_dispatch: PrechargedDispatch| {
// At this point gas counters should be changed accordingly so fetch the program data.
match Self::get_active_actor_data(actor_id, dispatch_id, dispatch_reply) {
ActorResult::Data(data) => Ok((precharged_dispatch, data)),
ActorResult::Continue => Err(precharged_dispatch),
}
};

let dispatch_id = queued_dispatch.id();
let success_reply = queued_dispatch
Expand All @@ -148,8 +163,8 @@ where
ext_manager: &mut ext_manager,
gas_limit,
dispatch: queued_dispatch,
balance: actor.balance,
get_actor_data: |dispatch| Ok((dispatch, actor.executable_data)),
balance: balance.unique_saturated_into(),
get_actor_data,
};
let journal = step.execute().unwrap_or_else(|e| unreachable!("{e:?}"));

Expand Down
39 changes: 39 additions & 0 deletions pallets/gear/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15251,3 +15251,42 @@ mod utils {
<Test as pallet_gear_bank::Config>::GasMultiplier::get().gas_to_value(gas)
}
}

#[test]
fn test_gas_info_of_terminated_program() {
use demo_constructor::{Calls, Scheme};

init_logger();
new_test_ext().execute_with(|| {
// Dies in init
let init_dead = Calls::builder().panic("Die in init");
let handle_dead = Calls::builder().panic("Called after being terminated!");
let (_, pid_dead) = utils::submit_constructor_with_args(
USER_1,
b"salt1".to_vec(),
Scheme::predefined(init_dead, handle_dead, Calls::default()),
0,
);

// Sends in handle message do dead program
let handle_proxy = Calls::builder().send(pid_dead.into_bytes(), []);
let (_, proxy_pid) = utils::submit_constructor_with_args(
USER_1,
b"salt2".to_vec(),
Scheme::predefined(Calls::default(), handle_proxy, Calls::default()),
0,
);

run_to_next_block(None);

let _gas_info = Gear::calculate_gas_info(
USER_1.into_origin(),
HandleKind::Handle(proxy_pid),
EMPTY_PAYLOAD.to_vec(),
0,
true,
true,
)
.expect("failed getting gas info"); // panics here as `pid_dead` is terminated and rpc call wasn't able to get code.
})
}

0 comments on commit d44a160

Please sign in to comment.