cannon_io/oracle/
key.rs

1#[derive(Debug, Default, Clone, Copy)]
2/// Types of preimage oracle keys. See https://github.com/ethereum-optimism/optimism/blob/develop/specs/fault-proof.md#pre-image-key-types
3pub enum KeyType {
4    /// Local key types are local and context dependent.
5    /// E.g. they might be different depending on the details of what is running the program and why
6    Local = 1,
7    /// keccak256 keys are global and refer to the data by its hash
8    #[default]
9    Keccak256 = 2,
10    /// Generic are also global and can implement different hash functions or other methods of referring to data
11    Generic = 3,
12    /// Sha256 preimages are useful for retrieving beacon chain SSZ encoded data. Note this is non-standard as is defined by us
13    Sha256 = 129,
14}
15
16#[derive(Debug, Default, Clone, Copy)]
17pub struct PreimageKey {
18    pub key_type: KeyType,
19    pub x: [u8; 31],
20}
21
22impl PreimageKey {
23    pub fn new(key_type: KeyType, x: [u8; 31]) -> Self {
24        Self { key_type, x }
25    }
26
27    /// This will panic if using a slice greater than 31 bytes
28    pub fn new_local(x: &[u8]) -> Self {
29        let mut key_bytes = [0_u8; 31];
30        // slice is inserted at the end
31        key_bytes[31 - x.len()..31].clone_from_slice(x);
32        Self::new(KeyType::Local, key_bytes)
33    }
34
35    /// produce a key from 32 byte of a Keccak hash.
36    /// The first byte is discarded and replaced by the type byte
37    pub fn new_keccak(hash: [u8; 32]) -> Self {
38        let mut x = [0; 31];
39        x.clone_from_slice(&hash[1..]);
40        Self::new(KeyType::Keccak256, x)
41    }
42
43    /// produce a key from 32 byte of a Sha256 hash.
44    /// The first byte is discarded and replaced by the type byte
45    pub fn new_sha256(hash: [u8; 32]) -> Self {
46        let mut x = [0; 31];
47        x.clone_from_slice(&hash[1..]);
48        Self::new(KeyType::Sha256, x)
49    }
50}
51
52impl From<PreimageKey> for [u8; 32] {
53    fn from(key: PreimageKey) -> Self {
54        let mut result = [0; 32];
55        result[0] = key.key_type as u8;
56        result[1..].copy_from_slice(&key.x);
57        result
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64
65    #[test]
66    fn test_local() {
67        let key = PreimageKey::new_local(&[0xff]);
68        assert_eq!(
69            <[u8; 32]>::from(key),
70            [
71                0x1_u8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72                0, 0, 0, 0, 0, 0xff
73            ]
74        )
75    }
76}