1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
use core::fmt;
// ADVICE EXTRACTORS
// ================================================================================================
/// Defines a set of actions which can be initiated from the VM to extract data from the advice
/// provider. These actions can only modify the advice stack.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum AdviceExtractor {
    /// Pops an element from the advice stack and returns it.
    ///
    /// # Errors
    /// Returns an error if the advice stack is empty.
    ///
    /// Inputs:
    ///  Operand stack: [...]
    ///  Advice stack: [value, ...]
    ///  Advice map: {...}
    ///  Merkle store: {...}
    ///
    /// Outputs:
    ///  Operand stack: [...]
    ///  Advice stack: [...]
    ///  Advice map: {...}
    ///  Merkle store: {...}
    ///  Return: [value]
    PopStack,
    /// Pops a word (4 elements) from the advice stack and returns it.
    ///
    /// Note: a word is popped off the stack element-by-element. For example, a `[d, c, b, a, ...]`
    /// stack (i.e., `d` is at the top of the stack) will yield `[d, c, b, a]`.
    ///
    /// # Errors
    /// Returns an error if the advice stack does not contain a full word.
    ///
    /// Inputs:
    ///  Operand stack: [...]
    ///  Advice stack: [d, c, b, a, ...]
    ///  Advice map: {...}
    ///  Merkle store: {...}
    ///
    /// Outputs:
    ///  Operand stack: [...]
    ///  Advice stack: [...]
    ///  Advice map: {...}
    ///  Merkle store: {...}
    ///  Return: [a, b, c, d]
    PopStackWord,
    /// Pops a double word (8 elements) from the advice stack and returns them.
    ///
    /// Note: words are popped off the stack element-by-element. For example, a
    /// `[h, g, f, e, d, c, b, a, ...]` stack (i.e., `h` is at the top of the stack) will yield
    /// two words: `[h, g, f,e ], [d, c, b, a]`.
    ///
    /// # Errors
    /// Returns an error if the advice stack does not contain two words.
    ///
    /// Inputs:
    ///  Operand stack: [...]
    ///  Advice stack: [h, g, f, e, d, c, b, a, ...]
    ///  Advice map: {...}
    ///  Merkle store: {...}
    ///
    /// Outputs:
    ///  Operand stack: [...]
    ///  Advice stack: [...]
    ///  Advice map: {...}
    ///  Merkle store: {...}
    ///  Return: [a, b, c, d, e, f, g, h]
    PopStackDWord,
    /// Extracts a Merkle path for the node specified by the values at the top of the operand stack
    /// and returns it to the caller.
    ///
    /// # Errors
    /// Returns an error if the Merkle store does not contain the specified Merkle path.
    ///
    /// Inputs:
    ///  Operand stack: [WORD, depth, index, ROOT, ...]
    ///  Advice stack: [...]
    ///  Advice map: {...}
    ///  Merkle store: {path, ...}
    ///
    /// Outputs:
    ///  Operand stack: [WORD, depth, index, ROOT, ...]
    ///  Advice stack: [...]
    ///  Advice map: {...}
    ///  Merkle store: {path, ...}
    ///  Return: [path]
    GetMerklePath,
}
impl fmt::Display for AdviceExtractor {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::PopStack => write!(f, "pop_stack"),
            Self::PopStackWord => write!(f, "pop_stack_word"),
            Self::PopStackDWord => write!(f, "pop_stack_dword"),
            Self::GetMerklePath => {
                write!(f, "get_merkle_path")
            }
        }
    }
}