Skip to content

Commit

Permalink
add identity precompile
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuajbouw committed Apr 21, 2021
1 parent dda3038 commit 9f09002
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 8 deletions.
7 changes: 5 additions & 2 deletions src/precompiles/blake2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ mod tests {
0300000000000000\
0000000000000000\
00",
).unwrap();
)
.unwrap();
blake2f(&input, Some(12)).unwrap().1
}

Expand Down Expand Up @@ -259,7 +260,9 @@ mod tests {

let expected = hex::decode(
"75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d28752\
98743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735").unwrap();
98743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735",
)
.unwrap();
assert_eq!(test_blake2f_final_block_false(), expected);
}
}
7 changes: 5 additions & 2 deletions src/precompiles/bn128.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::precompiles::util::check_gas;
use crate::precompiles::PrecompileResult;
use crate::prelude::*;
use evm::{ExitError, ExitSucceed};
use crate::precompiles::util::check_gas;

/// bn128 costs.
mod costs {
Expand Down Expand Up @@ -105,7 +105,10 @@ pub(crate) fn alt_bn128_mul(input: &[u8], target_gas: Option<u64>) -> Precompile
pub(crate) fn alt_bn128_pair(input: &[u8], target_gas: Option<u64>) -> PrecompileResult {
use bn::{arith::U256, AffineG1, AffineG2, Fq, Fq2, Group, Gt, G1, G2};

check_gas(target_gas, costs::PAIR_PER_POINT * input.len() as u64 / 192u64 + costs::PAIR)?;
check_gas(
target_gas,
costs::PAIR_PER_POINT * input.len() as u64 / 192u64 + costs::PAIR,
)?;

if input.len() % 192 != 0 {
return Err(ExitError::Other(Borrowed(
Expand Down
35 changes: 31 additions & 4 deletions src/precompiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ pub fn istanbul_precompiles(
hash::ripemd160(input).as_bytes().to_vec(),
0,
))),
4 => Some(Ok((ExitSucceed::Returned, identity(input).to_vec(), 0))),
4 => Some(identity(input, target_gas)),
5 => match modexp::modexp(input, target_gas) {
Ok(r) => Some(Ok((ExitSucceed::Returned, r, 0))),
Err(e) => Some(Err(e)),
Expand All @@ -58,10 +58,21 @@ pub fn istanbul_precompiles(
}
}

mod costs {
pub(super) const IDENTITY_BASE: u64 = 15;

pub(super) const IDENTITY_PER_WORD: u64 = 3;
}

/// Takes the input bytes, copies them, and returns it as the output.
///
/// See: https://ethereum.github.io/yellowpaper/paper.pdf
/// See: https://etherscan.io/address/0000000000000000000000000000000000000004
fn identity(input: &[u8]) -> &[u8] {
input
fn identity(input: &[u8], target_gas: Option<u64>) -> PrecompileResult {
let cost = (input.len() + 31) as u64 / 32 * costs::IDENTITY_PER_WORD + costs::IDENTITY_BASE;
util::check_gas(target_gas, cost)?;

Ok((ExitSucceed::Returned, input.to_vec(), 0))
}

#[cfg(test)]
Expand All @@ -70,6 +81,22 @@ mod tests {

#[test]
fn test_identity() {
assert_eq!(identity(b""), b"")
let input = [0u8, 1, 2, 3];

let expected = input[0..2].to_vec();
let res = identity(&input[0..2], Some(18)).unwrap().1;
assert_eq!(res, expected);

let expected = input.to_vec();
let res = identity(&input, Some(18)).unwrap().1;

// gas fail
let res = identity(&input[0..2], Some(17));
assert!(matches!(res, Err(ExitError::OutOfGas)));

// larger input
let input = [0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32];
let res = identity(&input, Some(21)).unwrap().1;
assert_eq!(res, input.to_vec());
}
}

0 comments on commit 9f09002

Please sign in to comment.