Skip to content

Commit

Permalink
feat(precompile): add a bool to bytes32 helper function (#1170)
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes committed Mar 8, 2024
1 parent 93557e9 commit 2aa0cd2
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 11 deletions.
8 changes: 3 additions & 5 deletions crates/precompile/src/bn128.rs
@@ -1,5 +1,6 @@
use crate::{
utilities::right_pad, Address, Error, Precompile, PrecompileResult, PrecompileWithAddress,
utilities::{bool_to_bytes32, right_pad},
Address, Error, Precompile, PrecompileResult, PrecompileWithAddress,
};
use bn::{AffineG1, AffineG2, Fq, Fq2, Group, Gt, G1, G2};
use revm_primitives::Bytes;
Expand Down Expand Up @@ -222,10 +223,7 @@ fn run_pair(

mul == Gt::one()
};

let mut out = [0u8; 32];
out[31] = success as u8;
Ok((gas_used, out.into()))
Ok((gas_used, bool_to_bytes32(success)))
}

/*
Expand Down
45 changes: 39 additions & 6 deletions crates/precompile/src/utilities.rs
@@ -1,25 +1,26 @@
use revm_primitives::{b256, Bytes, B256};
use std::borrow::Cow;

/// Right-pads the given slice at `offset` with zeroes until `LEN`.
///
/// Returns the first `LEN` bytes if it does not need padding.
#[inline(always)]
#[inline]
pub fn right_pad_with_offset<const LEN: usize>(data: &[u8], offset: usize) -> Cow<'_, [u8; LEN]> {
right_pad(data.get(offset..).unwrap_or_default())
}

/// Right-pads the given slice at `offset` with zeroes until `len`.
///
/// Returns the first `len` bytes if it does not need padding.
#[inline(always)]
#[inline]
pub fn right_pad_with_offset_vec(data: &[u8], offset: usize, len: usize) -> Cow<'_, [u8]> {
right_pad_vec(data.get(offset..).unwrap_or_default(), len)
}

/// Right-pads the given slice with zeroes until `LEN`.
///
/// Returns the first `LEN` bytes if it does not need padding.
#[inline(always)]
#[inline]
pub fn right_pad<const LEN: usize>(data: &[u8]) -> Cow<'_, [u8; LEN]> {
if let Some(data) = data.get(..LEN) {
Cow::Borrowed(data.try_into().unwrap())
Expand All @@ -33,7 +34,7 @@ pub fn right_pad<const LEN: usize>(data: &[u8]) -> Cow<'_, [u8; LEN]> {
/// Right-pads the given slice with zeroes until `len`.
///
/// Returns the first `len` bytes if it does not need padding.
#[inline(always)]
#[inline]
pub fn right_pad_vec(data: &[u8], len: usize) -> Cow<'_, [u8]> {
if let Some(data) = data.get(..len) {
Cow::Borrowed(data)
Expand All @@ -47,7 +48,7 @@ pub fn right_pad_vec(data: &[u8], len: usize) -> Cow<'_, [u8]> {
/// Left-pads the given slice with zeroes until `LEN`.
///
/// Returns the first `LEN` bytes if it does not need padding.
#[inline(always)]
#[inline]
pub fn left_pad<const LEN: usize>(data: &[u8]) -> Cow<'_, [u8; LEN]> {
if let Some(data) = data.get(..LEN) {
Cow::Borrowed(data.try_into().unwrap())
Expand All @@ -61,7 +62,7 @@ pub fn left_pad<const LEN: usize>(data: &[u8]) -> Cow<'_, [u8; LEN]> {
/// Left-pads the given slice with zeroes until `len`.
///
/// Returns the first `len` bytes if it does not need padding.
#[inline(always)]
#[inline]
pub fn left_pad_vec(data: &[u8], len: usize) -> Cow<'_, [u8]> {
if let Some(data) = data.get(..len) {
Cow::Borrowed(data)
Expand All @@ -72,6 +73,28 @@ pub fn left_pad_vec(data: &[u8], len: usize) -> Cow<'_, [u8]> {
}
}

/// Converts a boolean to a left-padded 32-byte `Bytes` value.
///
/// This is optimized to not allocate at runtime by using 2 static arrays.
#[inline]
pub const fn bool_to_bytes32(value: bool) -> Bytes {
Bytes::from_static(&bool_to_b256(value).0)
}

/// Converts a boolean to a left-padded `B256` value.
///
/// This is optimized to not allocate at runtime by using 2 static arrays.
#[inline]
pub const fn bool_to_b256(value: bool) -> &'static B256 {
const TRUE: &B256 = &b256!("0000000000000000000000000000000000000000000000000000000000000001");
const FALSE: &B256 = &b256!("0000000000000000000000000000000000000000000000000000000000000000");
if value {
TRUE
} else {
FALSE
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -140,4 +163,14 @@ mod tests {
assert!(matches!(padded, Cow::Borrowed(_)));
assert_eq!(padded[..], [1, 2, 3, 4, 5, 6, 7, 8]);
}

#[test]
fn bool2bytes() {
let f = bool_to_bytes32(false);
assert_eq!(f[..], [0; 32]);
let t = bool_to_bytes32(true);
assert_eq!(t.len(), 32);
assert_eq!(t[..31], [0; 31]);
assert_eq!(t[31], 1);
}
}

0 comments on commit 2aa0cd2

Please sign in to comment.