Compare commits

..

2 Commits

Author SHA1 Message Date
Omar Abdulla 83af9b750c Remove unneeded code 2025-07-16 19:35:32 +03:00
Omar Abdulla 3bce1b1545 Log certain errors better 2025-07-16 19:08:22 +03:00
4 changed files with 71 additions and 93 deletions
-1
View File
@@ -49,7 +49,6 @@ pub struct CompilerInput<T: PartialEq + Eq + Hash> {
} }
/// The generic compilation output configuration. /// The generic compilation output configuration.
#[derive(Debug)]
pub struct CompilerOutput<T: PartialEq + Eq + Hash> { pub struct CompilerOutput<T: PartialEq + Eq + Hash> {
/// The solc standard JSON input. /// The solc standard JSON input.
pub input: CompilerInput<T>, pub input: CompilerInput<T>,
+6 -51
View File
@@ -11,7 +11,6 @@ use revive_dt_config::Arguments;
use revive_solc_json_interface::SolcStandardJsonOutput; use revive_solc_json_interface::SolcStandardJsonOutput;
/// A wrapper around the `resolc` binary, emitting PVM-compatible bytecode. /// A wrapper around the `resolc` binary, emitting PVM-compatible bytecode.
#[derive(Debug)]
pub struct Resolc { pub struct Resolc {
/// Path to the `resolc` executable /// Path to the `resolc` executable
resolc_path: PathBuf, resolc_path: PathBuf,
@@ -20,7 +19,6 @@ pub struct Resolc {
impl SolidityCompiler for Resolc { impl SolidityCompiler for Resolc {
type Options = Vec<String>; type Options = Vec<String>;
#[tracing::instrument(level = "debug", ret)]
fn build( fn build(
&self, &self,
input: CompilerInput<Self::Options>, input: CompilerInput<Self::Options>,
@@ -71,13 +69,12 @@ impl SolidityCompiler for Resolc {
}); });
} }
let mut parsed = let parsed = serde_json::from_slice::<SolcStandardJsonOutput>(&stdout).map_err(|e| {
serde_json::from_slice::<SolcStandardJsonOutput>(&stdout).map_err(|e| { anyhow::anyhow!(
anyhow::anyhow!( "failed to parse resolc JSON output: {e}\nstderr: {}",
"failed to parse resolc JSON output: {e}\nstderr: {}", String::from_utf8_lossy(&stderr)
String::from_utf8_lossy(&stderr) )
) })?;
})?;
// Detecting if the compiler output contained errors and reporting them through logs and // Detecting if the compiler output contained errors and reporting them through logs and
// errors instead of returning the compiler output that might contain errors. // errors instead of returning the compiler output that might contain errors.
@@ -88,48 +85,6 @@ impl SolidityCompiler for Resolc {
} }
} }
// We need to do some post processing on the output to make it in the same format that solc
// outputs. More specifically, for each contract, the `.metadata` field should be replaced
// with the `.metadata.solc_metadata` field which contains the ABI and other information
// about the compiled contracts. We do this because we do not want any downstream logic to
// need to differentiate between which compiler is being used when extracting the ABI of the
// contracts.
if let Some(ref mut contracts) = parsed.contracts {
for (contract_path, contracts_map) in contracts.iter_mut() {
for (contract_name, contract_info) in contracts_map.iter_mut() {
let Some(metadata) = contract_info.metadata.take() else {
continue;
};
// Get the `solc_metadata` in the metadata of the contract.
let Some(solc_metadata) = metadata
.get("solc_metadata")
.and_then(|metadata| metadata.as_str())
else {
tracing::error!(
contract_path,
contract_name,
metadata = serde_json::to_string(&metadata).unwrap(),
"Encountered a contract compiled with resolc that has no solc_metadata"
);
anyhow::bail!(
"Contract {} compiled with resolc that has no solc_metadata",
contract_name
);
};
// Replace the original metadata with the new solc_metadata.
contract_info.metadata =
Some(serde_json::Value::String(solc_metadata.to_string()));
}
}
}
tracing::debug!(
output = %serde_json::to_string(&parsed).unwrap(),
"Compiled successfully"
);
Ok(CompilerOutput { Ok(CompilerOutput {
input, input,
output: parsed, output: parsed,
-7
View File
@@ -11,7 +11,6 @@ use revive_dt_config::Arguments;
use revive_dt_solc_binaries::download_solc; use revive_dt_solc_binaries::download_solc;
use revive_solc_json_interface::SolcStandardJsonOutput; use revive_solc_json_interface::SolcStandardJsonOutput;
#[derive(Debug)]
pub struct Solc { pub struct Solc {
solc_path: PathBuf, solc_path: PathBuf,
} }
@@ -19,7 +18,6 @@ pub struct Solc {
impl SolidityCompiler for Solc { impl SolidityCompiler for Solc {
type Options = (); type Options = ();
#[tracing::instrument(level = "debug", ret)]
fn build( fn build(
&self, &self,
input: CompilerInput<Self::Options>, input: CompilerInput<Self::Options>,
@@ -77,11 +75,6 @@ impl SolidityCompiler for Solc {
} }
} }
tracing::debug!(
output = %String::from_utf8_lossy(&output.stdout).to_string(),
"Compiled successfully"
);
Ok(CompilerOutput { Ok(CompilerOutput {
input, input,
output: parsed, output: parsed,
+65 -34
View File
@@ -219,7 +219,17 @@ where
continue; continue;
}; };
let nonce = node.fetch_add_nonce(input.caller)?; let nonce = match node.fetch_add_nonce(input.caller) {
Ok(nonce) => nonce,
Err(error) => {
tracing::error!(
caller = ?input.caller,
?error,
"Failed to get the nonce for the caller"
);
return Err(error);
}
};
tracing::debug!( tracing::debug!(
"Calculated nonce {}, for contract {}, having address {} on node: {}", "Calculated nonce {}, for contract {}, having address {} on node: {}",
@@ -232,7 +242,17 @@ where
// We are using alloy for building and submitting the transactions and it will // We are using alloy for building and submitting the transactions and it will
// automatically fill in all of the missing fields from the provider that we // automatically fill in all of the missing fields from the provider that we
// are using. // are using.
let code = alloy::hex::decode(&code)?; let code = match alloy::hex::decode(&code) {
Ok(code) => code,
Err(error) => {
tracing::error!(
code,
?error,
"Failed to hex-decode the code of the contract. (This could possibly mean that it contains '_' and therefore it requires linking to be performed)"
);
return Err(error.into());
}
};
let tx = TransactionRequest::default() let tx = TransactionRequest::default()
.nonce(nonce) .nonce(nonce)
.from(input.caller) .from(input.caller)
@@ -282,40 +302,51 @@ where
std::any::type_name::<T>() std::any::type_name::<T>()
); );
let Some(Value::String(metadata)) = &contract.metadata else { if let Some(Value::String(metadata_json_str)) = &contract.metadata {
tracing::error!(?contract, "Contract does not have a metadata field"); tracing::trace!(
anyhow::bail!("Contract does not have a metadata field: {contract:?}"); "metadata found for contract {contract_name}, {metadata_json_str}"
};
// Deserialize the solc metadata into a JSON object so we can get the ABI of the
// contracts. If we fail to perform the deserialization then we return an error
// as there's no other way to handle this.
let Ok(metadata) = serde_json::from_str::<Value>(metadata) else {
tracing::error!(%metadata, "Failed to parse solc metadata into a structured value");
anyhow::bail!(
"Failed to parse solc metadata into a structured value {metadata}"
); );
};
// Accessing the ABI on the solc metadata and erroring if the accessing failed match serde_json::from_str::<serde_json::Value>(metadata_json_str) {
let Some(abi) = metadata.get("output").and_then(|value| value.get("abi")) Ok(metadata_json) => {
else { if let Some(abi_value) =
tracing::error!(%metadata, "Failed to access the .output.abi field of the solc metadata"); metadata_json.get("output").and_then(|o| o.get("abi"))
anyhow::bail!( {
"Failed to access the .output.abi field of the solc metadata {metadata}" match serde_json::from_value::<JsonAbi>(abi_value.clone()) {
); Ok(parsed_abi) => {
}; tracing::trace!(
"ABI found in metadata for contract {}",
// Deserialize the ABI object that we got from the unstructured JSON into a &contract_name
// structured ABI object and error out if we fail. );
let Ok(abi) = serde_json::from_value::<JsonAbi>(abi.clone()) else { self.deployed_abis
tracing::error!(%metadata, "Failed to deserialize ABI into a structured format"); .insert(contract_name.clone(), parsed_abi);
anyhow::bail!( }
"Failed to deserialize ABI into a structured format {metadata}" Err(err) => {
); anyhow::bail!(
}; "Failed to parse ABI from metadata for contract {}: {}",
contract_name,
self.deployed_abis.insert(contract_name.clone(), abi); err
);
}
}
} else {
anyhow::bail!(
"No ABI found in metadata for contract {}",
contract_name
);
}
}
Err(err) => {
anyhow::bail!(
"Failed to parse metadata JSON string for contract {}: {}",
contract_name,
err
);
}
}
} else {
anyhow::bail!("No metadata found for contract {}", contract_name);
}
} }
} }
} }