implement calldatacopy

Signed-off-by: xermicus <cyrill@parity.io>
This commit is contained in:
xermicus
2024-03-19 10:49:47 +01:00
parent 6d058a42ed
commit 2b9e40225d
12 changed files with 210 additions and 43 deletions
+39 -9
View File
@@ -27,7 +27,8 @@ pub fn compile_blob(contract_name: &str, source_code: &str) -> Vec<u8> {
#[cfg(test)]
mod tests {
use alloy_primitives::U256;
use alloy_primitives::{FixedBytes, Keccak256, I256, U256};
use alloy_sol_types::{sol, SolCall};
use crate::mock_runtime::{self, State};
@@ -46,6 +47,37 @@ mod tests {
assert_eq!(state.storage[&U256::ZERO], U256::ZERO);
}
#[test]
fn hash_keccak_256() {
sol!(
#[derive(Debug, PartialEq, Eq)]
contract TestSha3 {
function test(string memory _pre) external payable returns (bytes32);
}
);
let source = r#"contract TestSha3 {
function test(string memory _pre) external payable returns (bytes32 hash) {
hash = keccak256(bytes(_pre));
}
}"#;
let code = crate::compile_blob("TestSha3", source);
let param = "hello";
let input = TestSha3::testCall::new((param.to_string(),)).abi_encode();
let state = State::new(input);
let (instance, export) = mock_runtime::prepare(&code);
let state = crate::mock_runtime::call(state, &instance, export);
assert_eq!(state.output.flags, 0);
let mut hasher = Keccak256::new();
hasher.update(param);
let expected = hasher.finalize();
let received = FixedBytes::<32>::from_slice(&state.output.data);
assert_eq!(expected, received);
}
#[test]
fn erc20() {
let _ = crate::compile_blob("ERC20", include_str!("../contracts/ERC20.sol"));
@@ -54,8 +86,8 @@ mod tests {
#[test]
fn triangle_number() {
let code = crate::compile_blob("Computation", include_str!("../contracts/Computation.sol"));
let param = alloy_primitives::U256::try_from(13).unwrap();
let expected = alloy_primitives::U256::try_from(91).unwrap();
let param = U256::try_from(13).unwrap();
let expected = U256::try_from(91).unwrap();
// function triangle_number(int64)
let mut input = 0x0f760610u32.to_be_bytes().to_vec();
@@ -67,16 +99,15 @@ mod tests {
assert_eq!(state.output.flags, 0);
let received =
alloy_primitives::U256::from_be_bytes::<32>(state.output.data.try_into().unwrap());
let received = U256::from_be_bytes::<32>(state.output.data.try_into().unwrap());
assert_eq!(received, expected);
}
#[test]
fn odd_product() {
let code = crate::compile_blob("Computation", include_str!("../contracts/Computation.sol"));
let param = alloy_primitives::I256::try_from(5i32).unwrap();
let expected = alloy_primitives::I256::try_from(945i64).unwrap();
let param = I256::try_from(5i32).unwrap();
let expected = I256::try_from(945i64).unwrap();
// function odd_product(int32)
let mut input = 0x00261b66u32.to_be_bytes().to_vec();
@@ -88,8 +119,7 @@ mod tests {
assert_eq!(state.output.flags, 0);
let received =
alloy_primitives::I256::from_be_bytes::<32>(state.output.data.try_into().unwrap());
let received = I256::from_be_bytes::<32>(state.output.data.try_into().unwrap());
assert_eq!(received, expected);
}
}
+22 -1
View File
@@ -2,7 +2,7 @@
//! TODO: Switch to drink! once RISCV is ready in polkadot-sdk
use std::collections::HashMap;
use alloy_primitives::U256;
use alloy_primitives::{Keccak256, U256};
use parity_scale_codec::Encode;
use polkavm::{
Caller, Config, Engine, ExportIndex, GasMeteringKind, InstancePre, Linker, Module,
@@ -168,6 +168,27 @@ fn link_host_functions(engine: &Engine) -> Linker<State> {
)
.unwrap();
linker
.func_wrap(
"hash_keccak_256",
|caller: Caller<State>,
input_ptr: u32,
input_len: u32,
out_ptr: u32|
-> Result<(), Trap> {
let (mut caller, _) = caller.split();
let pre = caller.read_memory_into_vec(input_ptr, input_len)?;
let mut hasher = Keccak256::new();
hasher.update(&pre);
caller.write_memory(out_ptr, &hasher.finalize()[..])?;
Ok(())
},
)
.unwrap();
linker
}