use crate::common::{ExecutableActorData, Program};
use gear_core::{
code::InstrumentedCode,
gas::{GasAllowanceCounter, GasCounter},
ids::ProgramId,
message::IncomingDispatch,
pages::WasmPagesAmount,
program::MemoryInfix,
reservation::GasReserver,
};
#[derive(Debug)]
pub struct ContextChargedForProgram {
pub(crate) dispatch: IncomingDispatch,
pub(crate) destination_id: ProgramId,
pub(crate) gas_counter: GasCounter,
pub(crate) gas_allowance_counter: GasAllowanceCounter,
}
impl ContextChargedForProgram {
#[cfg(feature = "gtest")]
pub fn into_inner(self) -> (IncomingDispatch, ProgramId, GasCounter) {
(self.dispatch, self.destination_id, self.gas_counter)
}
}
pub struct ContextChargedForAllocations(pub(crate) ContextChargedForProgram);
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,
}
impl From<ContextChargedForCodeLength> for ContextChargedForCode {
fn from(context: ContextChargedForCodeLength) -> Self {
Self { data: context.data }
}
}
pub struct ContextChargedForInstrumentation {
pub(crate) data: ContextData,
}
impl From<ContextChargedForCode> for ContextChargedForInstrumentation {
fn from(context: ContextChargedForCode) -> Self {
Self { data: context.data }
}
}
pub struct ContextChargedForMemory {
pub(crate) data: ContextData,
pub(crate) max_reservations: u64,
pub(crate) memory_size: WasmPagesAmount,
}
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: WasmPagesAmount,
}
impl ProcessExecutionContext {
pub fn program_id(&self) -> ProgramId {
self.program.id
}
pub fn memory_infix(&self) -> MemoryInfix {
self.program.memory_infix
}
}
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 {
id: destination_id,
memory_infix: actor_data.memory_infix,
code,
allocations: actor_data.allocations,
};
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,
}
}
}
#[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()
}
}