mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-06-11 16:41:01 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 83af9b750c | |||
| 3bce1b1545 |
@@ -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>,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user