aurora_engine_precompiles/bls12_381/
g2_add.rs1use aurora_engine_sdk::bls12_381;
2use aurora_engine_types::types::{Address, EthGas, make_address};
3use aurora_evm::{Context, ExitError};
4
5use crate::prelude::{Borrowed, Vec};
6use crate::{EvmPrecompileResult, Precompile, PrecompileOutput};
7
8const BASE_GAS_FEE: u64 = 600;
10
11const INPUT_LENGTH: usize = 512;
13
14pub struct BlsG2Add;
16
17impl BlsG2Add {
18 pub const ADDRESS: Address = make_address(0, 0xD);
19
20 fn execute(input: &[u8]) -> Result<Vec<u8>, ExitError> {
21 bls12_381::g2_add(input).map_err(|e| ExitError::Other(Borrowed(e.as_ref())))
22 }
23}
24
25impl Precompile for BlsG2Add {
26 fn required_gas(_input: &[u8]) -> Result<EthGas, ExitError>
27 where
28 Self: Sized,
29 {
30 Ok(EthGas::new(BASE_GAS_FEE))
31 }
32
33 fn run(
40 &self,
41 input: &[u8],
42 target_gas: Option<EthGas>,
43 _context: &Context,
44 _is_static: bool,
45 ) -> EvmPrecompileResult {
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 if input.len() != INPUT_LENGTH {
54 return Err(ExitError::Other(Borrowed("ERR_BLS_G2ADD_INPUT_LEN")));
55 }
56
57 let output = Self::execute(input)?;
58 Ok(PrecompileOutput::without_logs(cost, output))
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65 use aurora_engine_types::H160;
66
67 #[test]
68 fn bls12_381_g2_add() {
69 let precompile = BlsG2Add;
70 let ctx = Context {
71 address: H160::zero(),
72 caller: H160::zero(),
73 apparent_value: 0.into(),
74 };
75 let input = hex::decode("\
76 00000000000000000000000000000000161c595d151a765c7dee03c9210414cdffab84b9078b4b98f9df09be5ec299b8f6322c692214f00ede97958f235c352b\
77 00000000000000000000000000000000106883e0937cb869e579b513bde8f61020fcf26be38f8b98eae3885cedec2e028970415fc653cf10e64727b7f6232e06\
78 000000000000000000000000000000000f351a82b733af31af453904874b7ca6252957a1ab51ec7f7b6fff85bbf3331f870a7e72a81594a9930859237e7a154d\
79 0000000000000000000000000000000012fcf20d1750901f2cfed64fd362f010ee64fafe9ddab406cc352b65829b929881a50514d53247d1cca7d6995d0bc9b2\
80 00000000000000000000000000000000148b7dfc21521d79ff817c7a0305f1048851e283be13c07d5c04d28b571d48172838399ba539529e8d037ffd1f729558\
81 0000000000000000000000000000000003015abea326c15098f5205a8b2d3cd74d72dac59d60671ca6ef8c9c714ea61ffdacd46d1024b5b4f7e6b3b569fabaf2\
82 0000000000000000000000000000000011f0c512fe7dc2dd8abdc1d22c2ecd2e7d1b84f8950ab90fc93bf54badf7bb9a9bad8c355d52a5efb110dca891e4cc3d\
83 0000000000000000000000000000000019774010814d1d94caf3ecda3ef4f5c5986e966eaf187c32a8a5a4a59452af0849690cf71338193f2d8435819160bcfb")
84 .expect("hex decoding failed");
85
86 let res = precompile
87 .run(&input, None, &ctx, false)
88 .expect("precompile run should not fail");
89 let expected = hex::decode("\
90 000000000000000000000000000000000383ab7a17cc57e239e874af3f1aaabba0e64625b848676712f05f56132dbbd1cadfabeb3fe1f461daba3f1720057ddd\
91 00000000000000000000000000000000096967e9b3747f1b8e344535eaa0c51e70bc77412bfaa2a7ce76f11f570c9febb8f4227316866a416a50436d098e6f9a\
92 000000000000000000000000000000001079452b7519a7b090d668d54c266335b1cdd1080ed867dd17a2476b11c2617da829bf740e51cb7dfd60d73ed02c0c67\
93 00000000000000000000000000000000015fc3a972e05cbd9014882cfe6f2f16d0291c403bf28b05056ac625e4f71dfb1295c85d73145ef554614e6eb2d5bf02")
94 .expect("hex decoding failed");
95
96 assert_eq!(res.output, expected);
97 }
98}