cfx_executor/internal_contract/components/
executable.rs

1use 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}