use crate::common::ExecutableActorData;
use gear_core::{
code::InstrumentedCode,
gas::{GasAllowanceCounter, GasCounter},
ids::ProgramId,
message::IncomingDispatch,
pages::WasmPage,
program::Program,
reservation::GasReserver,
};
pub(crate) struct ContextData {
pub(crate) gas_counter: GasCounter,
pub(crate) gas_allowance_counter: GasAllowanceCounter,
pub(crate) dispatch: IncomingDispatch,
pub(crate) destination_id: ProgramId,
pub(crate) actor_data: ExecutableActorData,
}
pub struct ContextChargedForCodeLength {
pub(crate) data: ContextData,
}
impl ContextChargedForCodeLength {
pub fn actor_data(&self) -> &ExecutableActorData {
&self.data.actor_data
}
}
pub struct ContextChargedForCode {
pub(crate) data: ContextData,
pub(crate) code_len_bytes: u32,
}
impl From<(ContextChargedForCodeLength, u32)> for ContextChargedForCode {
fn from((context, code_len_bytes): (ContextChargedForCodeLength, u32)) -> Self {
Self {
data: context.data,
code_len_bytes,
}
}
}
pub struct ContextChargedForInstrumentation {
pub(crate) data: ContextData,
pub(crate) code_len_bytes: u32,
}
impl From<ContextChargedForCode> for ContextChargedForInstrumentation {
fn from(context: ContextChargedForCode) -> Self {
Self {
data: context.data,
code_len_bytes: context.code_len_bytes,
}
}
}
pub struct ContextChargedForMemory {
pub(crate) data: ContextData,
pub(crate) max_reservations: u64,
pub(crate) memory_size: WasmPage,
}
impl ContextChargedForMemory {
pub fn actor_data(&self) -> &ExecutableActorData {
&self.data.actor_data
}
pub fn gas_counter(&self) -> &GasCounter {
&self.data.gas_counter
}
}
pub struct ProcessExecutionContext {
pub(crate) gas_counter: GasCounter,
pub(crate) gas_allowance_counter: GasAllowanceCounter,
pub(crate) gas_reserver: GasReserver,
pub(crate) dispatch: IncomingDispatch,
pub(crate) balance: u128,
pub(crate) program: Program,
pub(crate) memory_size: WasmPage,
}
impl From<(ContextChargedForMemory, InstrumentedCode, u128)> for ProcessExecutionContext {
fn from(args: (ContextChargedForMemory, InstrumentedCode, u128)) -> Self {
let (context, code, balance) = args;
let ContextChargedForMemory {
data:
ContextData {
gas_counter,
gas_allowance_counter,
dispatch,
destination_id,
actor_data,
},
max_reservations,
memory_size,
} = context;
let program = Program::from_parts(
destination_id,
actor_data.memory_infix,
code,
actor_data.allocations,
actor_data.initialized,
);
let gas_reserver =
GasReserver::new(&dispatch, actor_data.gas_reservation_map, max_reservations);
Self {
gas_counter,
gas_allowance_counter,
gas_reserver,
dispatch,
balance,
program,
memory_size,
}
}
}
impl ProcessExecutionContext {
pub fn program(&self) -> &Program {
&self.program
}
}
#[derive(Debug, Default)]
pub struct SystemReservationContext {
pub current_reservation: Option<u64>,
pub previous_reservation: Option<u64>,
}
impl SystemReservationContext {
pub fn from_dispatch(dispatch: &IncomingDispatch) -> Self {
Self {
current_reservation: None,
previous_reservation: dispatch
.context()
.as_ref()
.and_then(|ctx| ctx.system_reservation()),
}
}
pub fn has_any(&self) -> bool {
self.current_reservation.is_some() || self.previous_reservation.is_some()
}
}