feat(solc): use svm blocking feature (#904)

* feat(solc): use svm blocking feature

* chore: bump ethers

* fix: enable svm blocking feature

Co-authored-by: Georgios Konstantopoulos <me@gakonst.com>
This commit is contained in:
Matthias Seitz 2022-02-12 17:40:09 +01:00 committed by GitHub
parent 1f0eb725a7
commit c8d8b66d0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 18 additions and 77 deletions

10
Cargo.lock generated
View File

@ -3475,8 +3475,9 @@ dependencies = [
[[package]] [[package]]
name = "solang-parser" name = "solang-parser"
version = "0.1.1" version = "0.1.2"
source = "git+https://github.com/hyperledger-labs/solang#b286b63d8003a17092e0ae54d89898970df6d6fa" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec12f31165397a3b145b0b06bc47470226ac9bf52b9aa8ea1ab7aa6e74809b39"
dependencies = [ dependencies = [
"lalrpop", "lalrpop",
"lalrpop-util", "lalrpop-util",
@ -3536,9 +3537,8 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
[[package]] [[package]]
name = "svm-rs" name = "svm-rs"
version = "0.2.6" version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/roynalnaruto/svm-rs#9b3627cfde2763fdc35afa9cbcea8ebc2926938d"
checksum = "01ebb94785ad8eecc53c119257322f72afd3e3ab5016e74b2b2b143449107135"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"cfg-if 1.0.0", "cfg-if 1.0.0",

View File

@ -35,13 +35,14 @@ tempfile = { version = "3.3.0", optional = true }
fs_extra = { version = "1.2.0", optional = true } fs_extra = { version = "1.2.0", optional = true }
sha2 = { version = "0.9.8", default-features = false } sha2 = { version = "0.9.8", default-features = false }
dunce = "1.0.2" dunce = "1.0.2"
solang-parser = { git = "https://github.com/hyperledger-labs/solang", default-features = false } solang-parser = { default-features = false, version = "0.1.2" }
rayon = "1.5.1" rayon = "1.5.1"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
home = "0.5.3" home = "0.5.3"
# SVM is not WASM compatible yet. # SVM is not WASM compatible yet.
svm = { package = "svm-rs", default-features = false, version = "0.2.6", optional = true } # svm = { package = "svm-rs", default-features = false, version = "0.2.7", optional = true }
svm = { package = "svm-rs", default-features = false, git = "https://github.com/roynalnaruto/svm-rs", optional = true, features = ["blocking"] }
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
# NOTE: this enables wasm compatibility for getrandom indirectly # NOTE: this enables wasm compatibility for getrandom indirectly
@ -72,7 +73,7 @@ required-features = ["project-util"]
[features] [features]
default = ["rustls"] default = ["rustls"]
async = ["tokio", "futures-util"] async = ["tokio", "futures-util"]
full = ["async", "svm"] full = ["async", "svm", "svm/blocking"]
# Utilities for creating and testing project workspaces # Utilities for creating and testing project workspaces
project-util = ["tempfile", "fs_extra"] project-util = ["tempfile", "fs_extra"]
tests = [] tests = []

View File

@ -52,32 +52,6 @@ use std::sync::Mutex;
#[allow(unused)] #[allow(unused)]
static LOCK: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(())); static LOCK: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
#[cfg(all(feature = "svm", feature = "async"))]
#[allow(clippy::large_enum_variant)]
pub enum RuntimeOrHandle {
Runtime(tokio::runtime::Runtime),
Handle(tokio::runtime::Handle),
}
#[cfg(all(feature = "svm", feature = "async"))]
impl Default for RuntimeOrHandle {
fn default() -> Self {
Self::new()
}
}
#[cfg(all(feature = "svm", feature = "async"))]
impl RuntimeOrHandle {
pub fn new() -> RuntimeOrHandle {
match tokio::runtime::Handle::try_current() {
Ok(handle) => RuntimeOrHandle::Handle(handle),
Err(_) => RuntimeOrHandle::Runtime(
tokio::runtime::Runtime::new().expect("Failed to start runtime"),
),
}
}
}
/// take the lock in tests, we use this to enforce that /// take the lock in tests, we use this to enforce that
/// a test does not run while a compiler version is being installed /// a test does not run while a compiler version is being installed
/// ///
@ -90,55 +64,21 @@ pub(crate) fn take_solc_installer_lock() -> std::sync::MutexGuard<'static, ()> {
LOCK.lock().unwrap() LOCK.lock().unwrap()
} }
#[cfg(all(feature = "svm", feature = "async"))]
/// A list of upstream Solc releases, used to check which version /// A list of upstream Solc releases, used to check which version
/// we should download. /// we should download.
/// The boolean value marks whether there was an error. /// The boolean value marks whether there was an error.
pub static RELEASES: Lazy<(svm::Releases, Vec<Version>, bool)> = Lazy::new(|| { #[cfg(all(feature = "svm"))]
// Try to download the releases, if it fails default to empty pub static RELEASES: once_cell::sync::Lazy<(svm::Releases, Vec<Version>, bool)> =
let releases_result = match RuntimeOrHandle::new() { once_cell::sync::Lazy::new(|| match svm::blocking_all_releases(svm::platform()) {
RuntimeOrHandle::Runtime(runtime) => Ok(releases) => {
// we do not degrade startup performance if the consumer has a weak network? let sorted_versions = releases.clone().into_versions();
// use a 3 sec timeout for the request which should still be fine for slower connections (releases, sorted_versions, true)
{
runtime.block_on(async {
tokio::time::timeout(
std::time::Duration::from_millis(3000),
svm::all_releases(svm::platform()),
)
.await
})
} }
RuntimeOrHandle::Handle(handle) => Err(err) => {
// we do not degrade startup performance if the consumer has a weak network?
// use a 3 sec timeout for the request which should still be fine for slower connections
{
handle.block_on(async {
tokio::time::timeout(
std::time::Duration::from_millis(3000),
svm::all_releases(svm::platform()),
)
.await
})
}
};
match releases_result {
Ok(Ok(releases)) => {
let mut sorted_releases = releases.releases.keys().cloned().collect::<Vec<Version>>();
sorted_releases.sort();
(releases, sorted_releases, true)
}
Ok(Err(err)) => {
tracing::error!("{:?}", err); tracing::error!("{:?}", err);
(svm::Releases::default(), Vec::new(), false) (svm::Releases::default(), Vec::new(), false)
} }
Err(err) => { });
tracing::error!("Releases request timed out: {:?}", err);
(svm::Releases::default(), Vec::new(), false)
}
}
});
/// A `Solc` version is either installed (available locally) or can be downloaded, from the remote /// A `Solc` version is either installed (available locally) or can be downloaded, from the remote
/// endpoint /// endpoint
@ -434,7 +374,7 @@ impl Solc {
pub fn blocking_install(version: &Version) -> std::result::Result<(), svm::SolcVmError> { pub fn blocking_install(version: &Version) -> std::result::Result<(), svm::SolcVmError> {
tracing::trace!("blocking installing solc version \"{}\"", version); tracing::trace!("blocking installing solc version \"{}\"", version);
crate::report::solc_installation_start(version); crate::report::solc_installation_start(version);
tokio::runtime::Runtime::new().unwrap().block_on(svm::install(version))?; svm::blocking_install(version)?;
crate::report::solc_installation_success(version); crate::report::solc_installation_success(version);
Ok(()) Ok(())
} }