aurora_engine_precompiles/
random.rs

1use super::{EvmPrecompileResult, Precompile};
2use crate::prelude::types::{make_address, Address, EthGas};
3use crate::prelude::H256;
4use crate::{utils, PrecompileOutput};
5use aurora_evm::{Context, ExitError};
6
7mod costs {
8    use crate::prelude::types::EthGas;
9
10    // TODO(#483): Determine the correct amount of gas
11    pub(super) const RANDOM_BYTES_GAS: EthGas = EthGas::new(0);
12}
13
14pub struct RandomSeed {
15    random_seed: H256,
16}
17
18impl RandomSeed {
19    /// Random bytes precompile address
20    /// This is a per-block entropy source which could then be used to create a random sequence.
21    /// It will return the same seed if called multiple time in the same block.
22    ///
23    /// Address: `0xc104f4840573bed437190daf5d2898c2bdf928ac`
24    /// This address is computed as: `&keccak("randomSeed")[12..]`
25    pub const ADDRESS: Address = make_address(0xc104f484, 0x0573bed437190daf5d2898c2bdf928ac);
26
27    #[must_use]
28    pub const fn new(random_seed: H256) -> Self {
29        Self { random_seed }
30    }
31}
32
33impl Precompile for RandomSeed {
34    fn required_gas(_input: &[u8]) -> Result<EthGas, ExitError> {
35        Ok(costs::RANDOM_BYTES_GAS)
36    }
37
38    fn run(
39        &self,
40        input: &[u8],
41        target_gas: Option<EthGas>,
42        context: &Context,
43        _is_static: bool,
44    ) -> EvmPrecompileResult {
45        utils::validate_no_value_attached_to_precompile(context.apparent_value)?;
46        let cost = Self::required_gas(input)?;
47        if let Some(target_gas) = target_gas {
48            if cost > target_gas {
49                return Err(ExitError::OutOfGas);
50            }
51        }
52
53        Ok(PrecompileOutput::without_logs(
54            cost,
55            self.random_seed.as_bytes().to_vec(),
56        ))
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use crate::prelude::sdk::types::near_account_to_evm_address;
63    use crate::random::RandomSeed;
64
65    #[test]
66    fn test_precompile_id() {
67        assert_eq!(
68            RandomSeed::ADDRESS,
69            near_account_to_evm_address(b"randomSeed")
70        );
71    }
72}