fuel_vm/
context.rs

1//! VM runtime context definitions
2
3use crate::predicate::RuntimePredicate;
4
5use fuel_asm::Word;
6use fuel_types::BlockHeight;
7
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10/// Runtime context description.
11pub enum Context {
12    /// Current context is a predicate estimation.
13    PredicateEstimation {
14        /// Predicate program to be executed
15        program: RuntimePredicate,
16    },
17    /// Current context is a predicate verification.
18    PredicateVerification {
19        /// Predicate program to be executed
20        program: RuntimePredicate,
21    },
22    /// Current context is a script execution.
23    Script {
24        /// Block height of the context
25        block_height: BlockHeight,
26    },
27    /// Current context is under a `CALL` scope
28    Call {
29        /// Block height of the context
30        block_height: BlockHeight,
31    },
32    /// No transaction initialized/invalid context.
33    NotInitialized,
34}
35
36impl Default for Context {
37    fn default() -> Self {
38        Self::NotInitialized
39    }
40}
41
42impl Context {
43    /// Check if the context is predicate
44    pub const fn is_predicate(&self) -> bool {
45        matches!(
46            self,
47            Self::PredicateEstimation { .. } | Self::PredicateVerification { .. }
48        )
49    }
50
51    /// Return `true` if the context is external; `false` otherwise.
52    pub const fn is_external(&self) -> bool {
53        matches!(
54            self,
55            Self::PredicateEstimation { .. }
56                | Self::PredicateVerification { .. }
57                | Self::Script { .. }
58        )
59    }
60
61    /// Return `true` if the context is internal; `false` otherwise.
62    pub const fn is_internal(&self) -> bool {
63        !self.is_external()
64    }
65
66    /// Return the program to be executed, if its a predicate
67    pub const fn predicate(&self) -> Option<&RuntimePredicate> {
68        match self {
69            Context::PredicateEstimation { program } => Some(program),
70            Context::PredicateVerification { program } => Some(program),
71            _ => None,
72        }
73    }
74
75    /// Return the block height from the context, if either script or call
76    pub const fn block_height(&self) -> Option<BlockHeight> {
77        match self {
78            Context::Script { block_height } | Context::Call { block_height } => {
79                Some(*block_height)
80            }
81            _ => None,
82        }
83    }
84
85    /// Update the context according to the provided frame pointer
86    pub fn update_from_frame_pointer(&mut self, fp: Word) {
87        match self {
88            Context::Script { block_height } if fp != 0 => {
89                *self = Self::Call {
90                    block_height: *block_height,
91                }
92            }
93
94            Context::Call { block_height } if fp == 0 => {
95                *self = Self::Script {
96                    block_height: *block_height,
97                }
98            }
99            _ => (),
100        }
101    }
102}