casper_execution_engine/engine_state/
mod.rs1pub 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
34pub const WASMLESS_TRANSFER_FIXED_GAS_PRICE: u8 = 1;
37
38#[derive(Debug, Clone, Default)]
40pub struct ExecutionEngineV1 {
41 config: EngineConfig,
42}
43
44impl ExecutionEngineV1 {
45 pub fn new(config: EngineConfig) -> ExecutionEngineV1 {
47 ExecutionEngineV1 { config }
48 }
49
50 pub fn config(&self) -> &EngineConfig {
52 &self.config
53 }
54
55 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 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 #[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 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}