fix(solc): add timeout and error detection for releases lookup (#759)

* fix(solc): add timeout and error detection for releases lookup

* bump tokio cargo update

* fix: move timeout in async block
This commit is contained in:
Matthias Seitz 2022-01-05 19:42:07 +01:00 committed by GitHub
parent 2ca8f99e87
commit 3da5a419fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 14 deletions

9
Cargo.lock generated
View File

@ -3419,11 +3419,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.14.0" version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838"
dependencies = [ dependencies = [
"autocfg",
"bytes", "bytes",
"libc", "libc",
"memchr", "memchr",
@ -3439,9 +3438,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "1.6.0" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e" checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@ -19,7 +19,7 @@ serde_json = "1.0.68"
serde = { version = "1.0.130", features = ["derive"] } serde = { version = "1.0.130", features = ["derive"] }
semver = "1.0.4" semver = "1.0.4"
walkdir = "2.3.2" walkdir = "2.3.2"
tokio = { version = "1.12.0", default-features = false, features = ["process", "io-util", "fs"], optional = true } tokio = { version = "1.15.0", default-features = false, features = ["process", "io-util", "fs", "time"], optional = true }
futures-util = { version = "^0.3", optional = true } futures-util = { version = "^0.3", optional = true }
once_cell = "1.8.0" once_cell = "1.8.0"
regex = "1.5.4" regex = "1.5.4"
@ -50,7 +50,7 @@ getrandom = { version = "0.2", features = ["js"] }
criterion = { version = "0.3", features = ["async_tokio"] } criterion = { version = "0.3", features = ["async_tokio"] }
pretty_assertions = "1.0.0" pretty_assertions = "1.0.0"
tempdir = "0.3.7" tempdir = "0.3.7"
tokio = { version = "1.12.0", features = ["full"] } tokio = { version = "1.15.0", features = ["full"] }
[[bench]] [[bench]]
name = "compile_many" name = "compile_many"

View File

@ -48,20 +48,33 @@ static LOCK: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
#[cfg(all(feature = "svm", feature = "async"))] #[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.
pub static RELEASES: Lazy<(svm::Releases, Vec<Version>)> = Lazy::new(|| { /// The boolean value marks whether there was an error.
pub static RELEASES: Lazy<(svm::Releases, Vec<Version>, bool)> = Lazy::new(|| {
// Try to download the releases, if it fails default to empty // Try to download the releases, if it fails default to empty
match tokio::runtime::Runtime::new() match tokio::runtime::Runtime::new()
.expect("could not create tokio rt to get remote releases") .expect("could not create tokio rt to get remote releases")
// TODO: Can we make this future timeout at a small time amount so that
// we do not degrade startup performance if the consumer has a weak network? // we do not degrade startup performance if the consumer has a weak network?
.block_on(svm::all_releases(svm::platform())) // use a 3 sec timeout for the request which should still be fine for slower connections
{ .block_on(async {
Ok(releases) => { tokio::time::timeout(
std::time::Duration::from_millis(3000),
svm::all_releases(svm::platform()),
)
.await
}) {
Ok(Ok(releases)) => {
let mut sorted_releases = releases.releases.keys().cloned().collect::<Vec<Version>>(); let mut sorted_releases = releases.releases.keys().cloned().collect::<Vec<Version>>();
sorted_releases.sort(); sorted_releases.sort();
(releases, sorted_releases) (releases, sorted_releases, true)
}
Ok(Err(err)) => {
tracing::error!("{:?}", err);
(svm::Releases::default(), Vec::new(), false)
}
Err(err) => {
tracing::error!("Releases request timed out: {:?}", err);
(svm::Releases::default(), Vec::new(), false)
} }
Err(_) => (svm::Releases::default(), Vec::new()),
} }
}); });
@ -281,6 +294,12 @@ impl Solc {
let content = let content =
std::fs::read(&version_path).map_err(|err| SolcError::io(err, version_path))?; std::fs::read(&version_path).map_err(|err| SolcError::io(err, version_path))?;
if !RELEASES.2 {
// we skip checksum verification because the underlying request to fetch release info
// failed so we have nothing to compare against
return Ok(())
}
use sha2::Digest; use sha2::Digest;
let mut hasher = sha2::Sha256::new(); let mut hasher = sha2::Sha256::new();
hasher.update(&content); hasher.update(&content);