diff --git a/crates/compiler/src/solc.rs b/crates/compiler/src/solc.rs index f296e3e..a07cdb9 100644 --- a/crates/compiler/src/solc.rs +++ b/crates/compiler/src/solc.rs @@ -238,4 +238,25 @@ mod test { Version::new(0, 7, 6) ) } + + #[tokio::test] + async fn compiler_version_can_be_obtained1() { + // Arrange + let args = Arguments::default(); + println!("Getting compiler path"); + let path = Solc::get_compiler_executable(&args, Version::new(0, 4, 21)) + .await + .unwrap(); + println!("Got compiler path"); + let compiler = Solc::new(path); + + // Act + let version = compiler.version(); + + // Assert + assert_eq!( + version.expect("Failed to get version"), + Version::new(0, 4, 21) + ) + } } diff --git a/crates/solc-binaries/src/cache.rs b/crates/solc-binaries/src/cache.rs index 0b7daaf..b2d8846 100644 --- a/crates/solc-binaries/src/cache.rs +++ b/crates/solc-binaries/src/cache.rs @@ -11,14 +11,14 @@ use std::{ use tokio::sync::Mutex; -use crate::download::GHDownloader; +use crate::download::SolcDownloader; pub const SOLC_CACHE_DIRECTORY: &str = "solc"; pub(crate) static SOLC_CACHER: LazyLock>> = LazyLock::new(Default::default); pub(crate) async fn get_or_download( working_directory: &Path, - downloader: &GHDownloader, + downloader: &SolcDownloader, ) -> anyhow::Result { let target_directory = working_directory .join(SOLC_CACHE_DIRECTORY) @@ -38,7 +38,7 @@ pub(crate) async fn get_or_download( Ok(target_file) } -async fn download_to_file(path: &Path, downloader: &GHDownloader) -> anyhow::Result<()> { +async fn download_to_file(path: &Path, downloader: &SolcDownloader) -> anyhow::Result<()> { tracing::info!("caching file: {}", path.display()); let Ok(file) = File::create_new(path) else { diff --git a/crates/solc-binaries/src/download.rs b/crates/solc-binaries/src/download.rs index 93ee451..119c4dd 100644 --- a/crates/solc-binaries/src/download.rs +++ b/crates/solc-binaries/src/download.rs @@ -38,21 +38,21 @@ impl List { } } -/// Download solc binaries from GitHub releases (IPFS links aren't reliable). +/// Download solc binaries from the official SolidityLang site #[derive(Clone, Debug)] -pub struct GHDownloader { +pub struct SolcDownloader { pub version: Version, pub target: &'static str, pub list: &'static str, } -impl GHDownloader { - pub const BASE_URL: &str = "https://github.com/ethereum/solidity/releases/download"; +impl SolcDownloader { + pub const BASE_URL: &str = "https://binaries.soliditylang.org"; - 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 const LINUX_NAME: &str = "linux-amd64"; + pub const MACOSX_NAME: &str = "macosx-amd64"; + pub const WINDOWS_NAME: &str = "windows-amd64"; + pub const WASM_NAME: &str = "wasm"; async fn new( version: impl Into, @@ -102,26 +102,27 @@ impl GHDownloader { Self::new(version, Self::WASM_NAME, List::WASM_URL).await } - /// Returns the download link. - pub fn url(&self) -> String { - format!("{}/v{}/{}", Self::BASE_URL, &self.version, &self.target) - } - /// 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 async fn download(&self) -> anyhow::Result> { tracing::info!("downloading solc: {self:?}"); - let expected_digest = List::download(self.list) - .await? - .builds + let builds = List::download(self.list).await?.builds; + let build = 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())?; + .ok_or_else(|| anyhow::anyhow!("solc v{} not found builds", self.version))?; - let file = reqwest::get(self.url()).await?.bytes().await?.to_vec(); + let path = build.path.clone(); + let expected_digest = build + .sha256 + .strip_prefix("0x") + .unwrap_or(&build.sha256) + .to_string(); + let url = format!("{}/{}/{}", Self::BASE_URL, self.target, path.display()); + + let file = reqwest::get(url).await?.bytes().await?.to_vec(); if hex::encode(Sha256::digest(&file)) != expected_digest { anyhow::bail!("sha256 mismatch for solc version {}", self.version); @@ -133,7 +134,7 @@ impl GHDownloader { #[cfg(test)] mod tests { - use crate::{download::GHDownloader, list::List}; + use crate::{download::SolcDownloader, list::List}; #[tokio::test] async fn try_get_windows() { @@ -141,7 +142,7 @@ mod tests { .await .unwrap() .latest_release; - GHDownloader::windows(version) + SolcDownloader::windows(version) .await .unwrap() .download() @@ -155,7 +156,7 @@ mod tests { .await .unwrap() .latest_release; - GHDownloader::macosx(version) + SolcDownloader::macosx(version) .await .unwrap() .download() @@ -169,7 +170,7 @@ mod tests { .await .unwrap() .latest_release; - GHDownloader::linux(version) + SolcDownloader::linux(version) .await .unwrap() .download() @@ -180,7 +181,7 @@ mod tests { #[tokio::test] async fn try_get_wasm() { let version = List::download(List::WASM_URL).await.unwrap().latest_release; - GHDownloader::wasm(version) + SolcDownloader::wasm(version) .await .unwrap() .download() diff --git a/crates/solc-binaries/src/lib.rs b/crates/solc-binaries/src/lib.rs index 7251c7c..05d0de5 100644 --- a/crates/solc-binaries/src/lib.rs +++ b/crates/solc-binaries/src/lib.rs @@ -6,7 +6,7 @@ use std::path::{Path, PathBuf}; use cache::get_or_download; -use download::GHDownloader; +use download::SolcDownloader; use revive_dt_common::types::VersionOrRequirement; @@ -25,13 +25,13 @@ pub async fn download_solc( wasm: bool, ) -> anyhow::Result { let downloader = if wasm { - GHDownloader::wasm(version).await + SolcDownloader::wasm(version).await } else if cfg!(target_os = "linux") { - GHDownloader::linux(version).await + SolcDownloader::linux(version).await } else if cfg!(target_os = "macos") { - GHDownloader::macosx(version).await + SolcDownloader::macosx(version).await } else if cfg!(target_os = "windows") { - GHDownloader::windows(version).await + SolcDownloader::windows(version).await } else { unimplemented!() }?;