diff --git a/Cargo.lock b/Cargo.lock index 5638ea5..0ba64ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1734,6 +1734,7 @@ dependencies = [ "env_logger", "hex", "log", + "once_cell", "polkavm", "rayon", "revive-common", diff --git a/crates/integration/Cargo.toml b/crates/integration/Cargo.toml index 70bbf24..c19e8ae 100644 --- a/crates/integration/Cargo.toml +++ b/crates/integration/Cargo.toml @@ -12,6 +12,7 @@ alloy-sol-types = { workspace = true } hex = { workspace = true } env_logger = { workspace = true } log = { workspace = true } +once_cell = { workspace = true } revive-solidity = { path = "../solidity" } revive-differential = { path = "../differential" } diff --git a/crates/integration/src/lib.rs b/crates/integration/src/lib.rs index 8e58e61..98b200e 100644 --- a/crates/integration/src/lib.rs +++ b/crates/integration/src/lib.rs @@ -4,12 +4,27 @@ 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>>> = + Lazy::new(Default::default); +pub(crate) static EVM_BLOB_CACHE: Lazy>>> = + 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 { @@ -24,14 +39,25 @@ pub fn compile_blob(contract_name: &str, source_code: &str) -> Vec { /// 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 { - let file_name = "contract.sol"; + 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, - revive_solidity::SolcPipeline::Yul, - true, + pipeline, + solc_optimizer_enabled, ) .expect("source should compile"); let bin_runtime = &contracts @@ -39,7 +65,11 @@ pub fn compile_evm_bin_runtime(contract_name: &str, source_code: &str) -> Vec Vec { - let file_name = "contract.sol"; + 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(), @@ -72,8 +111,11 @@ pub fn compile_blob_with_options( .expect("source should produce assembly text") .object .as_str(); + let blob = hex::decode(bytecode).expect("hex encoding should always be valid"); - 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) {