the solc github releases downloader

Signed-off-by: xermicus <bigcyrill@hotmail.com>
This commit is contained in:
xermicus
2025-03-21 15:20:50 +01:00
parent 84a5647a8b
commit 11bd08df4e
7 changed files with 113 additions and 24 deletions
Generated
+2
View File
@@ -2877,10 +2877,12 @@ name = "revive-dt-solc-binaries"
version = "0.1.0"
dependencies = [
"anyhow",
"hex",
"once_cell",
"reqwest",
"semver 1.0.26",
"serde",
"sha2",
]
[[package]]
+1
View File
@@ -29,6 +29,7 @@ once_cell = "1.21"
semver = {version = "1.0", features = ["serde"] }
serde = { version = "1.0", default-features = false, features = ["derive"] }
serde_json = { version = "1.0", default-features = false, features = ["arbitrary_precision", "std"] }
sha2 = { version = "0.10.8" }
tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] }
# revive compiler
+1 -1
View File
@@ -1,2 +1,2 @@
//! Implements the [SolidityCompiler] trait with revive Wasm for
//! Implements the [crate::SolidityCompiler] trait with revive Wasm for
//! compiling contracts to PVM bytecode (via Wasm).
+1 -1
View File
@@ -1,2 +1,2 @@
//! Implements the [SolidityCompiler] trait with resolc for
//! Implements the [crate::SolidityCompiler] trait with resolc for
//! compiling contracts to PVM bytecode.
+2
View File
@@ -14,7 +14,9 @@ download = ["reqwest"]
[dependencies]
anyhow = { workspace = true }
hex = { workspace = true }
once_cell = { workspace = true }
reqwest = { workspace = true, optional = true }
semver = { workspace = true }
serde = { workspace = true }
sha2 = { workspace = true }
+103 -19
View File
@@ -3,6 +3,8 @@
use std::{collections::HashMap, sync::Mutex};
use once_cell::sync::Lazy;
use semver::Version;
use sha2::{Digest, Sha256};
use crate::list::List;
@@ -31,31 +33,113 @@ impl List {
}
}
#[cfg(test)]
mod tests {
use crate::list::List;
/// Download solc binaries from GitHub releases (IPFS links aren't reliable).
pub struct GHDownloader {
version: Version,
target: &'static str,
list: &'static str,
}
#[test]
fn try_get_windows_list() {
List::download(List::WINDOWS_URL).unwrap();
List::download(List::WINDOWS_URL).unwrap();
impl GHDownloader {
pub const BASE_URL: &str = "https://github.com/ethereum/solidity/releases/download";
pub const LINUX_NAME: &str = "solc-static-linux";
pub const MACOSX_NAME: &str = "solc-macos";
pub const WINDOWS_NAME: &str = "solc-windows.exe";
pub const WASM_NAME: &str = "soljson.js";
pub fn linux(version: Version) -> Self {
Self {
version,
target: Self::LINUX_NAME,
list: List::LINUX_URL,
}
}
#[test]
fn try_get_macosx_list() {
List::download(List::MACOSX_URL).unwrap();
List::download(List::MACOSX_URL).unwrap();
pub fn macosx(version: Version) -> Self {
Self {
version,
target: Self::MACOSX_NAME,
list: List::MACOSX_URL,
}
}
#[test]
fn try_get_linux_list() {
List::download(List::LINUX_URL).unwrap();
List::download(List::LINUX_URL).unwrap();
pub fn windows(version: Version) -> Self {
Self {
version,
target: Self::WINDOWS_NAME,
list: List::WINDOWS_URL,
}
}
#[test]
fn try_get_wasm_list() {
List::download(List::WASM_URL).unwrap();
List::download(List::WASM_URL).unwrap();
pub fn wasm(version: Version) -> Self {
Self {
version,
target: Self::WASM_NAME,
list: List::WASM_URL,
}
}
/// Download the solc binary.
///
/// Errors out if the download fails or the digest of the downloaded file
/// mismatches the expected digest from the release [List].
pub fn download(&self) -> anyhow::Result<Vec<u8>> {
let expected_digest = List::download(self.list)?
.builds
.iter()
.find(|build| build.version == self.version)
.ok_or_else(|| anyhow::anyhow!("solc v{} not found builds", self.version))
.map(|b| b.sha256.strip_prefix("0x").unwrap_or(&b.sha256).to_string())?;
let url = format!("{}/v{}/{}", Self::BASE_URL, self.version, self.target);
let file = reqwest::blocking::get(&url)?.bytes()?.to_vec();
if hex::encode(Sha256::digest(&file)) != expected_digest {
anyhow::bail!("sha256 mismatch for solc version {}", self.version);
}
Ok(file)
}
}
#[cfg(test)]
mod tests {
use crate::{download::GHDownloader, list::List};
#[test]
fn try_get_windows() {
let version = List::download(List::WINDOWS_URL)
.unwrap()
.latest_release
.into();
GHDownloader::windows(version).download().unwrap();
}
#[test]
fn try_get_macosx() {
let version = List::download(List::MACOSX_URL)
.unwrap()
.latest_release
.into();
GHDownloader::macosx(version).download().unwrap();
}
#[test]
fn try_get_linux() {
let version = List::download(List::LINUX_URL)
.unwrap()
.latest_release
.into();
GHDownloader::linux(version).download().unwrap();
}
#[test]
fn try_get_wasm() {
let version = List::download(List::WASM_URL)
.unwrap()
.latest_release
.into();
GHDownloader::wasm(version).download().unwrap();
}
}
+3 -3
View File
@@ -20,7 +20,7 @@ pub struct Build {
pub build: String,
#[serde(rename = "longVersion")]
pub long_version: String,
keccak256: String,
sha256: String,
urls: Vec<String>,
pub keccak256: String,
pub sha256: String,
pub urls: Vec<String>,
}