cfx_executor/internal_contract/components/
executable.rs1use super::{InternalContractTrait, InternalTrapResult};
2use cfx_statedb::Result as DbResult;
3use cfx_vm_interpreter::Finalize;
4use cfx_vm_types::{
5 separate_out_db_error, ActionParams, CallType, Error as VmError,
6};
7use InternalTrapResult::*;
8
9use crate::stack::{Context, Executable, ExecutableOutcome};
10
11pub struct InternalContractExec<'a> {
12 pub internal: &'a Box<dyn InternalContractTrait>,
13 pub params: ActionParams,
14}
15
16impl<'a> Executable for InternalContractExec<'a> {
17 fn execute(
18 self: Box<Self>, mut context: Context,
19 ) -> DbResult<ExecutableOutcome> {
20 let result = if self.params.call_type != CallType::Call
21 && self.params.call_type != CallType::StaticCall
22 {
23 ExecutableOutcome::Return(Err(VmError::InternalContract(
24 "Incorrect call type.".into(),
25 )))
26 } else {
27 match self
28 .internal
29 .execute(&self.params, &mut context.internal_ref())
30 {
31 Return(result) => {
32 let result = separate_out_db_error(result)?;
33 let finalized_result = result.finalize(context);
34 debug!("Internal Call Result: {:?}", finalized_result);
35 ExecutableOutcome::Return(finalized_result)
36 }
37 Invoke(p, r) => {
38 debug!("Internal Call Has a sub-call/create");
39 ExecutableOutcome::Invoke(p, r)
40 }
41 }
42 };
43
44 Ok(result)
45 }
46}