Skip to main content

fuel_vm/interpreter/executors/
predicate.rs

1use crate::{
2    error::InterpreterError,
3    interpreter::{
4        EcalHandler,
5        Memory,
6    },
7    prelude::{
8        ExecutableTransaction,
9        Interpreter,
10    },
11    state::{
12        ExecuteState,
13        ProgramState,
14    },
15    storage::predicate::{
16        PredicateStorage,
17        PredicateStorageError,
18    },
19};
20
21use crate::storage::predicate::PredicateStorageRequirements;
22use fuel_asm::PanicReason;
23
24impl<M, Tx, Ecal, S> Interpreter<M, PredicateStorage<S>, Tx, Ecal>
25where
26    M: Memory,
27    Tx: ExecutableTransaction,
28    Ecal: EcalHandler,
29    S: PredicateStorageRequirements,
30{
31    /// Verify a predicate that has been initialized already
32    pub(crate) fn verify_predicate(
33        &mut self,
34    ) -> Result<ProgramState, InterpreterError<PredicateStorageError>> {
35        loop {
36            match self.execute::<true>()? {
37                ExecuteState::Return(r) => {
38                    if r == 1 {
39                        return Ok(ProgramState::Return(r))
40                    } else {
41                        return Err(InterpreterError::Panic(
42                            PanicReason::PredicateReturnedNonOne,
43                        ))
44                    }
45                }
46
47                // A predicate is not expected to return data
48                ExecuteState::ReturnData(_) => {
49                    return Err(InterpreterError::Panic(
50                        PanicReason::ContractInstructionNotAllowed,
51                    ))
52                }
53
54                ExecuteState::Revert(r) => return Ok(ProgramState::Revert(r)),
55
56                ExecuteState::Proceed => (),
57
58                ExecuteState::DebugEvent(d) => {
59                    return Ok(ProgramState::VerifyPredicate(d))
60                }
61            }
62        }
63    }
64}