casper_execution_engine/engine_state/
mod.rs

1//!  This module contains all the execution related code.
2pub mod engine_config;
3mod error;
4pub(crate) mod execution_kind;
5mod wasm_v1;
6
7use std::{cell::RefCell, collections::BTreeSet, rc::Rc};
8
9use casper_types::{
10    account::AccountHash, Gas, InitiatorAddr, Key, Phase, RuntimeArgs, StoredValue, TransactionHash,
11};
12
13use casper_storage::{
14    global_state::{
15        error::Error as GlobalStateError,
16        state::{StateProvider, StateReader},
17    },
18    tracking_copy::{TrackingCopyEntityExt, TrackingCopyError},
19    TrackingCopy,
20};
21
22use crate::{execution::Executor, runtime::RuntimeStack};
23pub use engine_config::{
24    EngineConfig, EngineConfigBuilder, DEFAULT_MAX_QUERY_DEPTH,
25    DEFAULT_MAX_RUNTIME_CALL_STACK_HEIGHT,
26};
27pub use error::Error;
28use execution_kind::ExecutionKind;
29pub use wasm_v1::{
30    BlockInfo, ExecutableItem, InvalidRequest, SessionDataDeploy, SessionDataV1, SessionInputData,
31    WasmV1Request, WasmV1Result,
32};
33
34/// Gas/motes conversion rate of wasmless transfer cost is always 1 regardless of what user wants to
35/// pay.
36pub const WASMLESS_TRANSFER_FIXED_GAS_PRICE: u8 = 1;
37
38/// The public api of the v1 execution engine, as of protocol version 2.0.0
39#[derive(Debug, Clone, Default)]
40pub struct ExecutionEngineV1 {
41    config: EngineConfig,
42}
43
44impl ExecutionEngineV1 {
45    /// Creates new execution engine.
46    pub fn new(config: EngineConfig) -> ExecutionEngineV1 {
47        ExecutionEngineV1 { config }
48    }
49
50    /// Returns engine config.
51    pub fn config(&self) -> &EngineConfig {
52        &self.config
53    }
54
55    /// Executes wasm, and that's all. Does not commit or handle payment or anything else.
56    pub fn execute(
57        &self,
58        state_provider: &impl StateProvider,
59        wasm_v1_request: WasmV1Request,
60    ) -> WasmV1Result {
61        let WasmV1Request {
62            block_info,
63            transaction_hash,
64            gas_limit,
65            initiator_addr,
66            executable_item,
67            entry_point,
68            args,
69            authorization_keys,
70            phase,
71        } = wasm_v1_request;
72        // NOTE to core engineers: it is intended for the EE to ONLY execute wasm targeting the
73        // casper v1 virtual machine. it should not handle native behavior, database / global state
74        // interaction, payment processing, or anything other than its single function.
75        // A good deal of effort has been put into removing all such behaviors; please do not
76        // come along and start adding it back.
77
78        let account_hash = initiator_addr.account_hash();
79        let protocol_version = self.config.protocol_version();
80        let state_hash = block_info.state_hash;
81        let tc = match state_provider.tracking_copy(state_hash) {
82            Ok(Some(tracking_copy)) => Rc::new(RefCell::new(tracking_copy)),
83            Ok(None) => return WasmV1Result::root_not_found(gas_limit, state_hash),
84            Err(gse) => {
85                return WasmV1Result::precondition_failure(
86                    gas_limit,
87                    Error::TrackingCopy(TrackingCopyError::Storage(gse)),
88                )
89            }
90        };
91        let (runtime_footprint, entity_addr) = {
92            match tc.borrow_mut().authorized_runtime_footprint_by_account(
93                protocol_version,
94                account_hash,
95                &authorization_keys,
96                &self.config().administrative_accounts,
97            ) {
98                Ok((runtime_footprint, entity_hash)) => (runtime_footprint, entity_hash),
99                Err(tce) => {
100                    return WasmV1Result::precondition_failure(gas_limit, Error::TrackingCopy(tce))
101                }
102            }
103        };
104        let mut named_keys = runtime_footprint.named_keys().clone();
105        let execution_kind = match ExecutionKind::new(
106            &mut *tc.borrow_mut(),
107            &named_keys,
108            &executable_item,
109            entry_point,
110        ) {
111            Ok(execution_kind) => execution_kind,
112            Err(ese) => return WasmV1Result::precondition_failure(gas_limit, ese),
113        };
114        let access_rights = runtime_footprint.extract_access_rights(entity_addr.value());
115        Executor::new(self.config().clone()).exec(
116            execution_kind,
117            args,
118            entity_addr,
119            Rc::new(RefCell::new(runtime_footprint)),
120            &mut named_keys,
121            access_rights,
122            authorization_keys,
123            account_hash,
124            block_info,
125            transaction_hash,
126            gas_limit,
127            Rc::clone(&tc),
128            phase,
129            RuntimeStack::from_account_hash(
130                account_hash,
131                self.config.max_runtime_call_stack_height() as usize,
132            ),
133        )
134    }
135
136    /// Executes wasm, and that's all. Does not commit or handle payment or anything else.
137    #[allow(clippy::too_many_arguments)]
138    pub fn execute_with_tracking_copy<R>(
139        &self,
140        tracking_copy: TrackingCopy<R>,
141        block_info: BlockInfo,
142        transaction_hash: TransactionHash,
143        gas_limit: Gas,
144        initiator_addr: InitiatorAddr,
145        executable_item: ExecutableItem,
146        entry_point: String,
147        args: RuntimeArgs,
148        authorization_keys: BTreeSet<AccountHash>,
149        phase: Phase,
150    ) -> WasmV1Result
151    where
152        R: StateReader<Key, StoredValue, Error = GlobalStateError>,
153    {
154        // NOTE to core engineers: it is intended for the EE to ONLY execute wasm targeting the
155        // casper v1 virtual machine. it should not handle native behavior, database / global state
156        // interaction, payment processing, or anything other than its single function.
157        // A good deal of effort has been put into removing all such behaviors; please do not
158        // come along and start adding it back.
159
160        let account_hash = initiator_addr.account_hash();
161        let protocol_version = self.config.protocol_version();
162        let tc = Rc::new(RefCell::new(tracking_copy));
163        let (runtime_footprint, entity_addr) = {
164            match tc.borrow_mut().authorized_runtime_footprint_by_account(
165                protocol_version,
166                account_hash,
167                &authorization_keys,
168                &self.config().administrative_accounts,
169            ) {
170                Ok((addressable_entity, entity_hash)) => (addressable_entity, entity_hash),
171                Err(tce) => {
172                    return WasmV1Result::precondition_failure(gas_limit, Error::TrackingCopy(tce))
173                }
174            }
175        };
176        let mut named_keys = runtime_footprint.named_keys().clone();
177        let execution_kind = match ExecutionKind::new(
178            &mut *tc.borrow_mut(),
179            &named_keys,
180            &executable_item,
181            entry_point,
182        ) {
183            Ok(execution_kind) => execution_kind,
184            Err(ese) => return WasmV1Result::precondition_failure(gas_limit, ese),
185        };
186        let access_rights = runtime_footprint.extract_access_rights(entity_addr.value());
187        Executor::new(self.config().clone()).exec(
188            execution_kind,
189            args,
190            entity_addr,
191            Rc::new(RefCell::new(runtime_footprint)),
192            &mut named_keys,
193            access_rights,
194            authorization_keys,
195            account_hash,
196            block_info,
197            transaction_hash,
198            gas_limit,
199            Rc::clone(&tc),
200            phase,
201            RuntimeStack::from_account_hash(
202                account_hash,
203                self.config.max_runtime_call_stack_height() as usize,
204            ),
205        )
206    }
207}