aurora_engine_precompiles/
identity.rs1use crate::prelude::types::{make_address, Address, EthGas};
2use crate::{utils, EvmPrecompileResult, Precompile, PrecompileOutput};
3use aurora_evm::{Context, ExitError};
4
5mod costs {
7 use aurora_engine_types::types::EthGas;
8
9 pub(super) const IDENTITY_BASE: EthGas = EthGas::new(15);
11
12 pub(super) const IDENTITY_PER_WORD: EthGas = EthGas::new(3);
14}
15
16mod consts {
17 pub(super) const IDENTITY_WORD_LEN: u64 = 32;
19}
20
21pub struct Identity;
22
23impl Identity {
24 pub const ADDRESS: Address = make_address(0, 4);
25}
26
27impl Precompile for Identity {
28 fn required_gas(input: &[u8]) -> Result<EthGas, ExitError> {
31 let input_len = u64::try_from(input.len()).map_err(utils::err_usize_conv)?;
32 Ok(
33 (input_len + consts::IDENTITY_WORD_LEN - 1) / consts::IDENTITY_WORD_LEN
34 * costs::IDENTITY_PER_WORD
35 + costs::IDENTITY_BASE,
36 )
37 }
38
39 fn run(
44 &self,
45 input: &[u8],
46 target_gas: Option<EthGas>,
47 _context: &Context,
48 _is_static: bool,
49 ) -> EvmPrecompileResult {
50 let cost = Self::required_gas(input)?;
51 if let Some(target_gas) = target_gas {
52 if cost > target_gas {
53 return Err(ExitError::OutOfGas);
54 }
55 }
56
57 Ok(PrecompileOutput::without_logs(cost, input.to_vec()))
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use aurora_evm::ExitError;
64
65 use crate::utils::new_context;
66
67 use super::*;
68
69 #[test]
70 fn test_identity() {
71 let input = [0u8, 1, 2, 3];
72
73 let expected = input[0..2].to_vec();
74 let res = Identity
75 .run(&input[0..2], Some(EthGas::new(18)), &new_context(), false)
76 .unwrap()
77 .output;
78 assert_eq!(res, expected);
79
80 let expected = input.to_vec();
81 let res = Identity
82 .run(&input, Some(EthGas::new(18)), &new_context(), false)
83 .unwrap()
84 .output;
85 assert_eq!(res, expected);
86
87 let res = Identity.run(&input[0..2], Some(EthGas::new(17)), &new_context(), false);
89
90 assert!(matches!(res, Err(ExitError::OutOfGas)));
91
92 let input = [
94 0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
95 24, 25, 26, 27, 28, 29, 30, 31, 32,
96 ];
97 let res = Identity
98 .run(&input, Some(EthGas::new(21)), &new_context(), false)
99 .unwrap()
100 .output;
101 assert_eq!(res, input.to_vec());
102 }
103}