core_processor/
context.rs

1// This file is part of Gear.
2
3// Copyright (C) 2021-2025 Gear Technologies Inc.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Module contains context-structures for processing.
20
21use crate::{
22    common::Program,
23    precharge::{ContextCharged, ForModuleInstantiation},
24};
25use gear_core::{
26    code::InstrumentedCodeAndMetadata,
27    gas::{GasAllowanceCounter, GasCounter},
28    ids::ActorId,
29    message::IncomingDispatch,
30    pages::WasmPagesAmount,
31    program::MemoryInfix,
32    reservation::GasReserver,
33};
34
35/// Checked parameters for message execution across processing runs.
36pub struct ProcessExecutionContext {
37    pub(crate) gas_counter: GasCounter,
38    pub(crate) gas_allowance_counter: GasAllowanceCounter,
39    pub(crate) gas_reserver: GasReserver,
40    pub(crate) dispatch: IncomingDispatch,
41    pub(crate) balance: u128,
42    pub(crate) program: Program,
43    pub(crate) memory_size: WasmPagesAmount,
44}
45
46impl ProcessExecutionContext {
47    /// Creates a new instance of the process execution context.
48    pub fn new(
49        context: ContextCharged<ForModuleInstantiation>,
50        instrumented_code_and_metadata: InstrumentedCodeAndMetadata,
51        balance: u128,
52    ) -> Self {
53        let (
54            destination_id,
55            dispatch,
56            gas_counter,
57            gas_allowance_counter,
58            actor_data,
59            allocations_data,
60        ) = context.into_final_parts();
61
62        let program = Program {
63            id: destination_id,
64            memory_infix: actor_data.memory_infix,
65            instrumented_code: instrumented_code_and_metadata.instrumented_code,
66            code_metadata: instrumented_code_and_metadata.metadata,
67            allocations: actor_data.allocations,
68        };
69
70        // Must be created once per taken from the queue dispatch by program.
71        let gas_reserver = GasReserver::new(
72            &dispatch,
73            actor_data.gas_reservation_map,
74            allocations_data.max_reservations,
75        );
76
77        Self {
78            gas_counter,
79            gas_allowance_counter,
80            gas_reserver,
81            dispatch,
82            balance,
83            program,
84            memory_size: allocations_data.memory_size,
85        }
86    }
87
88    /// Returns program id.
89    pub fn program_id(&self) -> ActorId {
90        self.program.id
91    }
92
93    /// Returns memory infix.
94    pub fn memory_infix(&self) -> MemoryInfix {
95        self.program.memory_infix
96    }
97}
98
99/// System reservation context.
100#[derive(Debug, Default)]
101pub struct SystemReservationContext {
102    /// Reservation created in current execution.
103    pub current_reservation: Option<u64>,
104    /// Reservation from `ContextStore`.
105    pub previous_reservation: Option<u64>,
106}
107
108impl SystemReservationContext {
109    /// Extracts reservation context from dispatch.
110    pub fn from_dispatch(dispatch: &IncomingDispatch) -> Self {
111        Self {
112            current_reservation: None,
113            previous_reservation: dispatch
114                .context()
115                .as_ref()
116                .and_then(|ctx| ctx.system_reservation()),
117        }
118    }
119
120    /// Checks if there are any reservations.
121    pub fn has_any(&self) -> bool {
122        self.current_reservation.is_some() || self.previous_reservation.is_some()
123    }
124}