diff --git a/Cargo.lock b/Cargo.lock index 9b39bd2..189c268 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1449,6 +1449,7 @@ dependencies = [ "parity-scale-codec", "polkavm", "revive-solidity", + "sha1", ] [[package]] @@ -1698,6 +1699,17 @@ dependencies = [ "stacker", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + [[package]] name = "sha2" version = "0.10.8" diff --git a/Cargo.toml b/Cargo.toml index 762df99..eaad105 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,7 @@ serde_json = { version = "1.0", features = [ "arbitrary_precision" ] } regex = "1.10" once_cell = "1.19" num = "0.4" +sha1 = "0.10" sha2 = "0.10" sha3 = "0.10" md5 = "0.7" diff --git a/crates/integration/Cargo.toml b/crates/integration/Cargo.toml index 210e510..eb53734 100644 --- a/crates/integration/Cargo.toml +++ b/crates/integration/Cargo.toml @@ -16,3 +16,4 @@ env_logger = { workspace = true } [dev-dependencies] alloy-sol-types = { workspace = true } +sha1 = { workspace = true } diff --git a/crates/integration/src/lib.rs b/crates/integration/src/lib.rs index 49819f0..8aa59d5 100644 --- a/crates/integration/src/lib.rs +++ b/crates/integration/src/lib.rs @@ -41,6 +41,7 @@ pub fn compile_blob_with_options( mod tests { use alloy_primitives::{FixedBytes, Keccak256, I256, U256}; use alloy_sol_types::{sol, SolCall}; + use sha1::Digest; use crate::mock_runtime::{self, State}; @@ -244,7 +245,6 @@ mod tests { contract MStore8 { function mStore8(uint value) public pure returns (uint256 word); } - ); let code = crate::compile_blob_with_options( "MStore8", @@ -329,4 +329,31 @@ mod tests { assert(parameter, expected); } } + + #[test] + fn sha1() { + sol!( + contract SHA1 { + function sha1(bytes memory data) public pure returns (bytes20); + } + ); + + let code = + crate::compile_blob_with_options("SHA1", include_str!("../contracts/sha1.sol"), false); + let (mut instance, export) = mock_runtime::prepare(&code, None); + + let pre = vec![0xffu8; 512]; + let mut hasher = sha1::Sha1::new(); + hasher.update(&pre); + let hash = hasher.finalize(); + + let input = SHA1::sha1Call::new((pre,)).abi_encode(); + let state = crate::mock_runtime::call(State::new(input), &mut instance, export); + + assert_eq!(state.output.flags, 0); + + let expected = FixedBytes::<20>::from_slice(&hash[..]); + let received = FixedBytes::<20>::from_slice(&state.output.data[..20]); + assert_eq!(received, expected); + } } diff --git a/crates/integration/src/mock_runtime.rs b/crates/integration/src/mock_runtime.rs index c803ad3..dacb388 100644 --- a/crates/integration/src/mock_runtime.rs +++ b/crates/integration/src/mock_runtime.rs @@ -58,7 +58,7 @@ fn link_host_functions(engine: &Engine) -> Linker { |caller: Caller, out_ptr: u32, out_len_ptr: u32| -> Result<(), Trap> { let (mut caller, state) = caller.split(); - assert_ne!(0, caller.read_u32(out_len_ptr)?); + assert!(state.input.len() <= caller.read_u32(out_len_ptr).unwrap() as usize); caller.write_memory(out_ptr, &state.input)?; caller.write_memory(out_len_ptr, &(state.input.len() as u32).encode())?; diff --git a/crates/llvm-context/src/eravm/context/function/runtime/entry.rs b/crates/llvm-context/src/eravm/context/function/runtime/entry.rs index 8bbd38e..c37a813 100644 --- a/crates/llvm-context/src/eravm/context/function/runtime/entry.rs +++ b/crates/llvm-context/src/eravm/context/function/runtime/entry.rs @@ -28,13 +28,16 @@ impl Entry { /// The number of mandatory arguments. pub const MANDATORY_ARGUMENTS_COUNT: usize = 2; + /// Reserve 1kb for calldata. + pub const MAX_CALLDATA_SIZE: usize = 1024; + /// Initializes the global variables. /// The pointers are not initialized, because it's not possible to create a null pointer. pub fn initialize_globals(context: &mut Context) -> anyhow::Result<()> where D: Dependency + Clone, { - let calldata_type = context.array_type(context.byte_type(), 1024); + let calldata_type = context.array_type(context.byte_type(), Self::MAX_CALLDATA_SIZE); context.set_global( crate::eravm::GLOBAL_CALLDATA_POINTER, calldata_type, @@ -112,7 +115,10 @@ impl Entry { "length_pointer_casted", )?; - context.build_store(length_pointer, context.integer_const(32, 1024))?; + context.build_store( + length_pointer, + context.integer_const(32, Self::MAX_CALLDATA_SIZE as u64), + )?; context.builder().build_call( context.module().get_function("input").expect("is declared"), &[input_pointer_casted.into(), length_pointer_casted.into()],