aurora_engine_precompiles/
random.rs

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