gear_core_processor/
context.rs

1// This file is part of Gear.
2
3// Copyright (C) 2021-2023 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::common::ExecutableActorData;
22use gear_core::{
23    code::InstrumentedCode,
24    gas::{GasAllowanceCounter, GasCounter},
25    ids::ProgramId,
26    message::IncomingDispatch,
27    pages::WasmPage,
28    program::Program,
29    reservation::GasReserver,
30};
31
32pub(crate) struct ContextData {
33    pub(crate) gas_counter: GasCounter,
34    pub(crate) gas_allowance_counter: GasAllowanceCounter,
35    pub(crate) dispatch: IncomingDispatch,
36    pub(crate) destination_id: ProgramId,
37    pub(crate) actor_data: ExecutableActorData,
38}
39
40pub struct ContextChargedForCodeLength {
41    pub(crate) data: ContextData,
42}
43
44impl ContextChargedForCodeLength {
45    /// Returns reference to the ExecutableActorData.
46    pub fn actor_data(&self) -> &ExecutableActorData {
47        &self.data.actor_data
48    }
49}
50
51/// The instance returned by `precharge_for_code`.
52/// Existence of the instance means that corresponding counters were
53/// successfully charged for fetching the binary code from storage.
54pub struct ContextChargedForCode {
55    pub(crate) data: ContextData,
56    pub(crate) code_len_bytes: u32,
57}
58
59impl From<(ContextChargedForCodeLength, u32)> for ContextChargedForCode {
60    fn from((context, code_len_bytes): (ContextChargedForCodeLength, u32)) -> Self {
61        Self {
62            data: context.data,
63            code_len_bytes,
64        }
65    }
66}
67
68/// The instance returned by `precharge_for_instrumentation`.
69/// Existence of the instance means that corresponding counters were
70/// successfully charged for reinstrumentation of the code.
71pub struct ContextChargedForInstrumentation {
72    pub(crate) data: ContextData,
73    pub(crate) code_len_bytes: u32,
74}
75
76impl From<ContextChargedForCode> for ContextChargedForInstrumentation {
77    fn from(context: ContextChargedForCode) -> Self {
78        Self {
79            data: context.data,
80            code_len_bytes: context.code_len_bytes,
81        }
82    }
83}
84
85pub struct ContextChargedForMemory {
86    pub(crate) data: ContextData,
87    pub(crate) max_reservations: u64,
88    pub(crate) memory_size: WasmPage,
89}
90
91impl ContextChargedForMemory {
92    /// Returns reference to the ExecutableActorData.
93    pub fn actor_data(&self) -> &ExecutableActorData {
94        &self.data.actor_data
95    }
96
97    /// Returns reference to the GasCounter.
98    pub fn gas_counter(&self) -> &GasCounter {
99        &self.data.gas_counter
100    }
101}
102
103/// Checked parameters for message execution across processing runs.
104pub struct ProcessExecutionContext {
105    pub(crate) gas_counter: GasCounter,
106    pub(crate) gas_allowance_counter: GasAllowanceCounter,
107    pub(crate) gas_reserver: GasReserver,
108    pub(crate) dispatch: IncomingDispatch,
109    pub(crate) balance: u128,
110    pub(crate) program: Program,
111    pub(crate) memory_size: WasmPage,
112}
113
114impl From<(ContextChargedForMemory, InstrumentedCode, u128)> for ProcessExecutionContext {
115    fn from(args: (ContextChargedForMemory, InstrumentedCode, u128)) -> Self {
116        let (context, code, balance) = args;
117
118        let ContextChargedForMemory {
119            data:
120                ContextData {
121                    gas_counter,
122                    gas_allowance_counter,
123                    dispatch,
124                    destination_id,
125                    actor_data,
126                },
127            max_reservations,
128            memory_size,
129        } = context;
130
131        let program = Program::from_parts(
132            destination_id,
133            code,
134            actor_data.allocations,
135            actor_data.initialized,
136        );
137
138        // Must be created once per taken from the queue dispatch by contract.
139        let gas_reserver =
140            GasReserver::new(&dispatch, actor_data.gas_reservation_map, max_reservations);
141
142        Self {
143            gas_counter,
144            gas_allowance_counter,
145            gas_reserver,
146            dispatch,
147            balance,
148            program,
149            memory_size,
150        }
151    }
152}
153
154impl ProcessExecutionContext {
155    /// Returns ref to program.
156    pub fn program(&self) -> &Program {
157        &self.program
158    }
159}