Compare commits

..

14 Commits

Author SHA1 Message Date
Omar Abdulla 9aa26a99d6 Update the release profile 2025-07-15 14:06:53 +03:00
Omar Abdulla 02f853699e Improve the comments 2025-07-15 13:43:33 +03:00
Omar fde303f549 Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:23:56 +03:00
Omar e5a751f507 Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:23:50 +03:00
Omar d9d62b1038 Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:23:15 +03:00
Omar 71ae3b0f9a Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:23:03 +03:00
Omar 8cda6a9726 Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:22:54 +03:00
Omar a43d94ea7d Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:22:45 +03:00
Omar 6960298438 Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:22:36 +03:00
Omar 62cf57d39e Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:22:23 +03:00
Omar 3fc26eb03b Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:22:15 +03:00
Omar 268437b4d9 Update crates/node-interaction/src/blocking_executor.rs
Co-authored-by: xermicus <cyrill@parity.io>
2025-07-15 13:22:03 +03:00
Omar Abdulla 27a0a0de0b Fix doc test 2025-07-14 21:33:57 +03:00
Omar Abdulla 331705134a Update the async runtime with syntactic sugar. 2025-07-14 21:13:58 +03:00
5 changed files with 27 additions and 168 deletions
+4 -8
View File
@@ -44,8 +44,6 @@ pub trait SolidityCompiler {
pub struct CompilerInput<T: PartialEq + Eq + Hash> {
pub extra_options: T,
pub input: SolcStandardJsonInput,
pub allow_paths: Vec<PathBuf>,
pub base_path: Option<PathBuf>,
}
/// The generic compilation output configuration.
@@ -85,8 +83,8 @@ where
pub struct Compiler<T: SolidityCompiler> {
input: SolcStandardJsonInput,
extra_options: T::Options,
allow_paths: Vec<PathBuf>,
base_path: Option<PathBuf>,
allow_paths: Vec<String>,
base_path: Option<String>,
}
impl Default for Compiler<solc::Solc> {
@@ -147,12 +145,12 @@ where
self
}
pub fn allow_path(mut self, path: PathBuf) -> Self {
pub fn allow_path(mut self, path: String) -> Self {
self.allow_paths.push(path);
self
}
pub fn base_path(mut self, base_path: PathBuf) -> Self {
pub fn base_path(mut self, base_path: String) -> Self {
self.base_path = Some(base_path);
self
}
@@ -161,8 +159,6 @@ where
T::new(solc_path).build(CompilerInput {
extra_options: self.extra_options,
input: self.input,
allow_paths: self.allow_paths,
base_path: self.base_path,
})
}
+5 -28
View File
@@ -23,27 +23,13 @@ impl SolidityCompiler for Resolc {
&self,
input: CompilerInput<Self::Options>,
) -> anyhow::Result<CompilerOutput<Self::Options>> {
let mut command = Command::new(&self.resolc_path);
command
let mut child = Command::new(&self.resolc_path)
.arg("--standard-json")
.args(&input.extra_options)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.arg("--standard-json");
if let Some(ref base_path) = input.base_path {
command.arg("--base-path").arg(base_path);
}
if !input.allow_paths.is_empty() {
command.arg("--allow-paths").arg(
input
.allow_paths
.iter()
.map(|path| path.display().to_string())
.collect::<Vec<_>>()
.join(","),
);
}
let mut child = command.spawn()?;
.spawn()?;
let stdin_pipe = child.stdin.as_mut().expect("stdin must be piped");
serde_json::to_writer(stdin_pipe, &input.input)?;
@@ -69,22 +55,13 @@ impl SolidityCompiler for Resolc {
});
}
let parsed = serde_json::from_slice::<SolcStandardJsonOutput>(&stdout).map_err(|e| {
let parsed: SolcStandardJsonOutput = serde_json::from_slice(&stdout).map_err(|e| {
anyhow::anyhow!(
"failed to parse resolc JSON output: {e}\nstderr: {}",
String::from_utf8_lossy(&stderr)
)
})?;
// Detecting if the compiler output contained errors and reporting them through logs and
// errors instead of returning the compiler output that might contain errors.
for error in parsed.errors.iter().flatten() {
if error.severity == "error" {
tracing::error!(?error, ?input, "Encountered an error in the compilation");
anyhow::bail!("Encountered an error in the compilation: {error}")
}
}
Ok(CompilerOutput {
input,
output: parsed,
+4 -37
View File
@@ -9,7 +9,6 @@ use std::{
use crate::{CompilerInput, CompilerOutput, SolidityCompiler};
use revive_dt_config::Arguments;
use revive_dt_solc_binaries::download_solc;
use revive_solc_json_interface::SolcStandardJsonOutput;
pub struct Solc {
solc_path: PathBuf,
@@ -22,27 +21,12 @@ impl SolidityCompiler for Solc {
&self,
input: CompilerInput<Self::Options>,
) -> anyhow::Result<CompilerOutput<Self::Options>> {
let mut command = Command::new(&self.solc_path);
command
let mut child = Command::new(&self.solc_path)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.arg("--standard-json");
if let Some(ref base_path) = input.base_path {
command.arg("--base-path").arg(base_path);
}
if !input.allow_paths.is_empty() {
command.arg("--allow-paths").arg(
input
.allow_paths
.iter()
.map(|path| path.display().to_string())
.collect::<Vec<_>>()
.join(","),
);
}
let mut child = command.spawn()?;
.arg("--standard-json")
.spawn()?;
let stdin = child.stdin.as_mut().expect("should be piped");
serde_json::to_writer(stdin, &input.input)?;
@@ -58,26 +42,9 @@ impl SolidityCompiler for Solc {
});
}
let parsed =
serde_json::from_slice::<SolcStandardJsonOutput>(&output.stdout).map_err(|e| {
anyhow::anyhow!(
"failed to parse resolc JSON output: {e}\nstderr: {}",
String::from_utf8_lossy(&output.stdout)
)
})?;
// Detecting if the compiler output contained errors and reporting them through logs and
// errors instead of returning the compiler output that might contain errors.
for error in parsed.errors.iter().flatten() {
if error.severity == "error" {
tracing::error!(?error, ?input, "Encountered an error in the compilation");
anyhow::bail!("Encountered an error in the compilation: {error}")
}
}
Ok(CompilerOutput {
input,
output: parsed,
output: serde_json::from_slice(&output.stdout)?,
error: None,
})
}
+11 -87
View File
@@ -69,13 +69,14 @@ where
anyhow::bail!("unsupported solc version: {:?}", &mode.solc_version);
};
let compiler = Compiler::<T::Compiler>::new()
.allow_path(metadata.directory()?)
let mut compiler = Compiler::<T::Compiler>::new()
.base_path(metadata.directory()?.display().to_string())
.solc_optimizer(mode.solc_optimize());
let compiler = FilesWithExtensionIterator::new(metadata.directory()?)
.with_allowed_extension("sol")
.try_fold(compiler, |compiler, path| compiler.with_source(&path))?;
for (file, _contract) in metadata.contract_sources()?.values() {
tracing::debug!("contract source {}", file.display());
compiler = compiler.with_source(file)?;
}
let mut task = CompilationTask {
json_input: compiler.input(),
@@ -179,15 +180,12 @@ where
}
pub fn deploy_contracts(&mut self, input: &Input, node: &T::Blockchain) -> anyhow::Result<()> {
let tracing_span = tracing::debug_span!(
"Deploying contracts",
?input,
node = std::any::type_name::<T>()
tracing::debug!(
"Deploying contracts {}, having address {} on node: {}",
&input.instance,
&input.caller,
std::any::type_name::<T>()
);
let _guard = tracing_span.enter();
tracing::debug!(number_of_contracts_to_deploy = self.contracts.len());
for output in self.contracts.values() {
let Some(contract_map) = &output.contracts else {
tracing::debug!(
@@ -478,77 +476,3 @@ where
Ok(())
}
}
/// An iterator that finds files of a certain extension in the provided directory. You can think of
/// this a glob pattern similar to: `${path}/**/*.md`
struct FilesWithExtensionIterator {
/// The set of allowed extensions that that match the requirement and that should be returned
/// when found.
allowed_extensions: std::collections::HashSet<std::borrow::Cow<'static, str>>,
/// The set of directories to visit next. This iterator does BFS and so these directories will
/// only be visited if we can't find any files in our state.
directories_to_search: Vec<std::path::PathBuf>,
/// The set of files matching the allowed extensions that were found. If there are entries in
/// this vector then they will be returned when the [`Iterator::next`] method is called. If not
/// then we visit one of the next directories to visit.
///
/// [`Iterator`]: std::iter::Iterator
files_matching_allowed_extensions: Vec<std::path::PathBuf>,
}
impl FilesWithExtensionIterator {
fn new(root_directory: std::path::PathBuf) -> Self {
Self {
allowed_extensions: Default::default(),
directories_to_search: vec![root_directory],
files_matching_allowed_extensions: Default::default(),
}
}
fn with_allowed_extension(
mut self,
allowed_extension: impl Into<std::borrow::Cow<'static, str>>,
) -> Self {
self.allowed_extensions.insert(allowed_extension.into());
self
}
}
impl Iterator for FilesWithExtensionIterator {
type Item = std::path::PathBuf;
fn next(&mut self) -> Option<Self::Item> {
if let Some(file_path) = self.files_matching_allowed_extensions.pop() {
return Some(file_path);
};
let directory_to_search = self.directories_to_search.pop()?;
// Read all of the entries in the directory. If we failed to read this dir's entires then we
// elect to just ignore it and look in the next directory, we do that by calling the next
// method again on the iterator, which is an intentional decision that we made here instead
// of panicking.
let Ok(dir_entries) = std::fs::read_dir(directory_to_search) else {
return self.next();
};
for entry in dir_entries.flatten() {
let entry_path = entry.path();
if entry_path.is_dir() {
self.directories_to_search.push(entry_path)
} else if entry_path.is_file()
&& entry_path.extension().is_some_and(|ext| {
self.allowed_extensions
.iter()
.any(|allowed| ext.eq_ignore_ascii_case(allowed.as_ref()))
})
{
self.files_matching_allowed_extensions.push(entry_path)
}
}
self.next()
}
}
+3 -8
View File
@@ -123,14 +123,9 @@ impl Input {
return Ok(Bytes::default()); // fallback or deployer — no input
};
let Some(abi) = deployed_abis.get(&self.instance) else {
tracing::error!(
contract_name = self.instance,
available_abis = ?deployed_abis.keys().collect::<Vec<_>>(),
"Attempted to lookup ABI of contract but it wasn't found"
);
anyhow::bail!("ABI for instance '{}' not found", &self.instance);
};
let abi = deployed_abis
.get(&self.instance)
.ok_or_else(|| anyhow::anyhow!("ABI for instance '{}' not found", &self.instance))?;
tracing::trace!("ABI found for instance: {}", &self.instance);