add runner crate (#34)

Signed-off-by: xermicus <cyrill@parity.io>
Co-authored-by: xermicus <cyrill@parity.io>
Co-authored-by: pgherveou <pgherveou@gmail.com>
This commit is contained in:
Cyrill Leutwiler
2024-08-24 03:20:52 +02:00
committed by GitHub
parent 0903718f07
commit 7844bbb604
10 changed files with 8664 additions and 224 deletions
+64 -62
View File
@@ -1,6 +1,8 @@
use alloy_primitives::{Address, I256, U256};
use alloy_sol_types::{sol, SolCall, SolConstructor};
use revive_solidity::test_utils::*;
use crate::mock_runtime::{CallOutput, State};
#[derive(Clone)]
@@ -193,8 +195,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Baseline::baselineCall::new(()).abi_encode(),
}
}
@@ -205,8 +207,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Computation::odd_productCall::new((n,)).abi_encode(),
}
}
@@ -217,8 +219,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Computation::triangle_numberCall::new((n,)).abi_encode(),
}
}
@@ -229,8 +231,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: FibonacciRecursive::fib3Call::new((U256::from(n),)).abi_encode(),
}
}
@@ -241,8 +243,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: FibonacciIterative::fib3Call::new((U256::from(n),)).abi_encode(),
}
}
@@ -253,8 +255,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: FibonacciBinet::fib3Call::new((U256::from(n),)).abi_encode(),
}
}
@@ -265,8 +267,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: SHA1::sha1Call::new((pre,)).abi_encode(),
}
}
@@ -277,8 +279,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Flipper::flipCall::new(()).abi_encode(),
}
}
@@ -289,8 +291,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Flipper::constructorCall::new((coin,)).abi_encode(),
}
}
@@ -301,8 +303,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: IERC20::totalSupplyCall::new(()).abi_encode(),
}
}
@@ -313,8 +315,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Block::numberCall::new(()).abi_encode(),
}
}
@@ -325,8 +327,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Block::timestampCall::new(()).abi_encode(),
}
}
@@ -337,8 +339,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Context::address_thisCall::new(()).abi_encode(),
}
}
@@ -349,8 +351,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Context::callerCall::new(()).abi_encode(),
}
}
@@ -361,8 +363,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: DivisionArithmetics::divCall::new((n, d)).abi_encode(),
}
}
@@ -373,8 +375,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: DivisionArithmetics::sdivCall::new((n, d)).abi_encode(),
}
}
@@ -385,8 +387,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: DivisionArithmetics::modCall::new((n, d)).abi_encode(),
}
}
@@ -397,8 +399,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: DivisionArithmetics::smodCall::new((n, d)).abi_encode(),
}
}
@@ -409,8 +411,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: MStore8::mStore8Call::new((value,)).abi_encode(),
}
}
@@ -421,8 +423,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Events::emitEventCall::new((topics,)).abi_encode(),
}
}
@@ -433,8 +435,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: vec![0; 4],
}
}
@@ -445,8 +447,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: vec![0; 4],
}
}
@@ -457,8 +459,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: ExtCode::ExtCodeSizeCall::new((address,)).abi_encode(),
}
}
@@ -469,8 +471,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: ExtCode::CodeSizeCall::new(()).abi_encode(),
}
}
@@ -481,8 +483,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: MCopy::memcpyCall::new((payload,)).abi_encode(),
}
}
@@ -493,8 +495,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Call::value_transferCall::new((destination,)).abi_encode(),
}
}
@@ -505,8 +507,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Call::callCall::new((callee, payload)).abi_encode(),
}
}
@@ -517,8 +519,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Default::default(),
}
}
@@ -529,8 +531,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Value::balance_ofCall::new((address,)).abi_encode(),
}
}
@@ -541,8 +543,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Bitwise::opByteCall::new((index, value)).abi_encode(),
}
}
@@ -553,8 +555,8 @@ impl Contract {
Self {
name,
evm_runtime: crate::compile_evm_bin_runtime(name, code),
pvm_runtime: crate::compile_blob(name, code),
evm_runtime: compile_evm_bin_runtime(name, code),
pvm_runtime: compile_blob(name, code),
calldata: Storage::transientCall::new((value,)).abi_encode(),
}
}
-108
View File
@@ -4,120 +4,12 @@ use mock_runtime::{CallOutput, State};
use crate::mock_runtime::{Event, ReturnFlags};
use once_cell::sync::Lazy;
use std::{collections::HashMap, sync::Mutex};
pub mod cases;
pub mod mock_runtime;
#[cfg(test)]
mod tests;
pub(crate) static PVM_BLOB_CACHE: Lazy<Mutex<HashMap<CompiledBlobId, Vec<u8>>>> =
Lazy::new(Default::default);
pub(crate) static EVM_BLOB_CACHE: Lazy<Mutex<HashMap<CompiledBlobId, Vec<u8>>>> =
Lazy::new(Default::default);
#[derive(Hash, PartialEq, Eq)]
struct CompiledBlobId {
contract_name: String,
solc_optimizer_enabled: bool,
pipeline: revive_solidity::SolcPipeline,
}
/// Compile the blob of `contract_name` found in given `source_code`.
/// The `solc` optimizer will be enabled
pub fn compile_blob(contract_name: &str, source_code: &str) -> Vec<u8> {
compile_blob_with_options(
contract_name,
source_code,
true,
revive_solidity::SolcPipeline::Yul,
)
}
/// Compile the EVM bin-runtime of `contract_name` found in given `source_code`.
/// The `solc` optimizer will be enabled
pub fn compile_evm_bin_runtime(contract_name: &str, source_code: &str) -> Vec<u8> {
let pipeline = revive_solidity::SolcPipeline::Yul;
let solc_optimizer_enabled = true;
let id = CompiledBlobId {
contract_name: contract_name.to_owned(),
pipeline,
solc_optimizer_enabled,
};
if let Some(blob) = EVM_BLOB_CACHE.lock().unwrap().get(&id) {
return blob.clone();
}
let file_name = "contract.sol";
let contracts = revive_solidity::test_utils::build_solidity_with_options_evm(
[(file_name.into(), source_code.into())].into(),
Default::default(),
None,
pipeline,
solc_optimizer_enabled,
)
.expect("source should compile");
let bin_runtime = &contracts
.get(contract_name)
.unwrap_or_else(|| panic!("contract '{}' didn't produce bin-runtime", contract_name))
.object;
let blob = hex::decode(bin_runtime).expect("bin-runtime shold be hex encoded");
EVM_BLOB_CACHE.lock().unwrap().insert(id, blob.clone());
blob
}
/// Compile the blob of `contract_name` found in given `source_code`.
pub fn compile_blob_with_options(
contract_name: &str,
source_code: &str,
solc_optimizer_enabled: bool,
pipeline: revive_solidity::SolcPipeline,
) -> Vec<u8> {
let id = CompiledBlobId {
contract_name: contract_name.to_owned(),
solc_optimizer_enabled,
pipeline,
};
if let Some(blob) = PVM_BLOB_CACHE.lock().unwrap().get(&id) {
return blob.clone();
}
let file_name = "contract.sol";
let contracts = revive_solidity::test_utils::build_solidity_with_options(
[(file_name.into(), source_code.into())].into(),
Default::default(),
None,
pipeline,
revive_llvm_context::OptimizerSettings::cycles(),
solc_optimizer_enabled,
)
.expect("source should compile")
.contracts
.expect("source should contain at least one contract");
let bytecode = contracts[file_name][contract_name]
.evm
.as_ref()
.expect("source should produce EVM output")
.bytecode
.as_ref()
.expect("source should produce assembly text")
.object
.as_str();
let blob = hex::decode(bytecode).expect("hex encoding should always be valid");
PVM_BLOB_CACHE.lock().unwrap().insert(id, blob.clone());
blob
}
pub fn assert_success(contract: &Contract, differential: bool) -> (State, CallOutput) {
let (state, output) = contract.execute();
assert_eq!(output.flags, ReturnFlags::Success);
+7 -5
View File
@@ -5,6 +5,8 @@ use alloy_sol_types::{sol, SolCall, SolValue};
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use sha1::Digest;
use revive_solidity::test_utils::*;
use crate::{
assert_success,
cases::Contract,
@@ -62,7 +64,7 @@ fn hash_keccak_256() {
hash = keccak256(bytes(_pre));
}
}"#;
let code = crate::compile_blob("TestSha3", source);
let code = compile_blob("TestSha3", source);
let param = "hello";
let input = TestSha3::testCall::new((param.to_string(),)).abi_encode();
@@ -82,7 +84,7 @@ fn hash_keccak_256() {
#[test]
fn erc20() {
let _ = crate::compile_blob("ERC20", include_str!("../contracts/ERC20.sol"));
let _ = compile_blob("ERC20", include_str!("../contracts/ERC20.sol"));
}
#[test]
@@ -109,7 +111,7 @@ fn msize_plain() {
function mSize() public pure returns (uint);
}
);
let code = crate::compile_blob_with_options(
let code = compile_blob_with_options(
"MSize",
include_str!("../contracts/MSize.sol"),
false,
@@ -138,7 +140,7 @@ fn transferred_value() {
function value() public payable returns (uint);
}
);
let code = crate::compile_blob("Value", include_str!("../contracts/Value.sol"));
let code = compile_blob("Value", include_str!("../contracts/Value.sol"));
let (_, output) = State::default()
.transaction()
@@ -162,7 +164,7 @@ fn msize_non_word_sized_access() {
function mStore100() public pure returns (uint);
}
);
let code = crate::compile_blob_with_options(
let code = compile_blob_with_options(
"MSize",
include_str!("../contracts/MSize.sol"),
false,