Skip to content

Commit

Permalink
Compilance fix 7 (#229)
Browse files Browse the repository at this point in the history
* Compilance fix 7

* Fix an issue in memory gas panic
  • Loading branch information
sorpaas authored Nov 23, 2023
1 parent dc364d7 commit c239c9c
Show file tree
Hide file tree
Showing 12 changed files with 593 additions and 578 deletions.
1 change: 1 addition & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ jobs:
- name: Run tests
run: |
cargo run --release --verbose -p jsontests -- \
jsontests/res/ethtests/GeneralStateTests/stArgsZeroOneBalance/ \
jsontests/res/ethtests/GeneralStateTests/stCodeCopyTest/ \
jsontests/res/ethtests/GeneralStateTests/stExample/ \
jsontests/res/ethtests/GeneralStateTests/stSelfBalance \
Expand Down
6 changes: 3 additions & 3 deletions jsontests/src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use evm::backend::in_memory::{
use evm::standard::{Config, Etable, Gasometer, Invoker, TransactArgs};
use evm::utils::u256_to_h256;
use evm::Capture;
use precompiles::StandardPrecompileSet;
use precompiles::StandardResolver;
use primitive_types::U256;
use std::collections::{BTreeMap, BTreeSet};

Expand Down Expand Up @@ -60,8 +60,8 @@ pub fn run_test(_filename: &str, _test_name: &str, test: Test, debug: bool) -> R
.collect::<BTreeMap<_, _>>();

let etable = Etable::runtime();
let precompiles = StandardPrecompileSet::new(&config);
let invoker = Invoker::<_, Gasometer, _, _, _, _>::new(&config, &precompiles, &etable);
let resolver = StandardResolver::new(&config);
let invoker = Invoker::<_, Gasometer, _, _, _, _>::new(&config, &resolver, &etable);
let args = TransactArgs::Call {
caller: test.transaction.sender,
address: test.transaction.to,
Expand Down
137 changes: 65 additions & 72 deletions precompiles/src/blake2/mod.rs
Original file line number Diff line number Diff line change
@@ -1,98 +1,91 @@
mod eip152;

use crate::{address, PurePrecompileSet};
use crate::PurePrecompile;
use evm::{ExitException, ExitResult, ExitSucceed, RuntimeState, StaticGasometer};
use primitive_types::H160;

pub struct Blake2F;

impl Blake2F {
const GAS_COST_PER_ROUND: u64 = 1; // https://eips.ethereum.org/EIPS/eip-152#gas-costs-and-benchmarks
}

impl<G: StaticGasometer> PurePrecompileSet<G> for Blake2F {
impl<G: StaticGasometer> PurePrecompile<G> for Blake2F {
/// Format of `input`:
/// [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f]
fn execute(
&self,
input: &[u8],
state: &RuntimeState,
_state: &RuntimeState,
gasometer: &mut G,
) -> Option<(ExitResult, Vec<u8>)> {
const ADDRESS: H160 = address(9);

if state.context.address == ADDRESS {
const BLAKE2_F_ARG_LEN: usize = 213;

if input.len() != BLAKE2_F_ARG_LEN {
return Some((
ExitException::Other(
"input length for Blake2 F precompile should be exactly 213 bytes".into(),
)
.into(),
Vec::new(),
));
}

let mut rounds_buf: [u8; 4] = [0; 4];
rounds_buf.copy_from_slice(&input[0..4]);
let rounds: u32 = u32::from_be_bytes(rounds_buf);

let gas_cost: u64 = (rounds as u64) * Blake2F::GAS_COST_PER_ROUND;
try_some!(gasometer.record_cost(gas_cost.into()));

// we use from_le_bytes below to effectively swap byte order to LE if architecture is BE
let mut h_buf: [u8; 64] = [0; 64];
h_buf.copy_from_slice(&input[4..68]);
let mut h = [0u64; 8];
let mut ctr = 0;
for state_word in &mut h {
let mut temp: [u8; 8] = Default::default();
temp.copy_from_slice(&h_buf[(ctr * 8)..(ctr + 1) * 8]);
*state_word = u64::from_le_bytes(temp);
ctr += 1;
}
) -> (ExitResult, Vec<u8>) {
const BLAKE2_F_ARG_LEN: usize = 213;

if input.len() != BLAKE2_F_ARG_LEN {
return (
ExitException::Other(
"input length for Blake2 F precompile should be exactly 213 bytes".into(),
)
.into(),
Vec::new(),
);
}

let mut m_buf: [u8; 128] = [0; 128];
m_buf.copy_from_slice(&input[68..196]);
let mut m = [0u64; 16];
ctr = 0;
for msg_word in &mut m {
let mut temp: [u8; 8] = Default::default();
temp.copy_from_slice(&m_buf[(ctr * 8)..(ctr + 1) * 8]);
*msg_word = u64::from_le_bytes(temp);
ctr += 1;
}
let mut rounds_buf: [u8; 4] = [0; 4];
rounds_buf.copy_from_slice(&input[0..4]);
let rounds: u32 = u32::from_be_bytes(rounds_buf);

let gas_cost: u64 = (rounds as u64) * Blake2F::GAS_COST_PER_ROUND;
try_some!(gasometer.record_cost(gas_cost.into()));

// we use from_le_bytes below to effectively swap byte order to LE if architecture is BE
let mut h_buf: [u8; 64] = [0; 64];
h_buf.copy_from_slice(&input[4..68]);
let mut h = [0u64; 8];
let mut ctr = 0;
for state_word in &mut h {
let mut temp: [u8; 8] = Default::default();
temp.copy_from_slice(&h_buf[(ctr * 8)..(ctr + 1) * 8]);
*state_word = u64::from_le_bytes(temp);
ctr += 1;
}

let mut t_0_buf: [u8; 8] = [0; 8];
t_0_buf.copy_from_slice(&input[196..204]);
let t_0 = u64::from_le_bytes(t_0_buf);
let mut m_buf: [u8; 128] = [0; 128];
m_buf.copy_from_slice(&input[68..196]);
let mut m = [0u64; 16];
ctr = 0;
for msg_word in &mut m {
let mut temp: [u8; 8] = Default::default();
temp.copy_from_slice(&m_buf[(ctr * 8)..(ctr + 1) * 8]);
*msg_word = u64::from_le_bytes(temp);
ctr += 1;
}

let mut t_1_buf: [u8; 8] = [0; 8];
t_1_buf.copy_from_slice(&input[204..212]);
let t_1 = u64::from_le_bytes(t_1_buf);
let mut t_0_buf: [u8; 8] = [0; 8];
t_0_buf.copy_from_slice(&input[196..204]);
let t_0 = u64::from_le_bytes(t_0_buf);

let f = if input[212] == 1 {
true
} else if input[212] == 0 {
false
} else {
return Some((
ExitException::Other("incorrect final block indicator flag".into()).into(),
Vec::new(),
));
};
let mut t_1_buf: [u8; 8] = [0; 8];
t_1_buf.copy_from_slice(&input[204..212]);
let t_1 = u64::from_le_bytes(t_1_buf);

eip152::compress(&mut h, m, [t_0, t_1], f, rounds as usize);
let f = if input[212] == 1 {
true
} else if input[212] == 0 {
false
} else {
return (
ExitException::Other("incorrect final block indicator flag".into()).into(),
Vec::new(),
);
};

let mut output_buf = [0u8; u64::BITS as usize];
for (i, state_word) in h.iter().enumerate() {
output_buf[i * 8..(i + 1) * 8].copy_from_slice(&state_word.to_le_bytes());
}
eip152::compress(&mut h, m, [t_0, t_1], f, rounds as usize);

Some((ExitSucceed::Returned.into(), output_buf.to_vec()))
} else {
None
let mut output_buf = [0u8; u64::BITS as usize];
for (i, state_word) in h.iter().enumerate() {
output_buf[i * 8..(i + 1) * 8].copy_from_slice(&state_word.to_le_bytes());
}

(ExitSucceed::Returned.into(), output_buf.to_vec())
}
}
Loading

0 comments on commit c239c9c

Please sign in to comment.