mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-04-22 23:07:58 +00:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa2053de6f | |||
| 3ed8a1ca1c |
@@ -10,6 +10,10 @@ use crate::{CompilerInput, CompilerOutput, SolidityCompiler};
|
||||
use revive_dt_config::Arguments;
|
||||
use revive_solc_json_interface::SolcStandardJsonOutput;
|
||||
|
||||
// TODO: I believe that we need to also pass the solc compiler to resolc so that resolc uses the
|
||||
// specified solc compiler. I believe that currently we completely ignore the specified solc binary
|
||||
// when invoking resolc which doesn't seem right if we're using solc as a compiler frontend.
|
||||
|
||||
/// A wrapper around the `resolc` binary, emitting PVM-compatible bytecode.
|
||||
#[derive(Debug)]
|
||||
pub struct Resolc {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
use std::str::FromStr;
|
||||
|
||||
use alloy::json_abi::JsonAbi;
|
||||
use alloy::network::{Ethereum, TransactionBuilder};
|
||||
@@ -200,12 +201,13 @@ where
|
||||
case_idx: CaseIdx,
|
||||
input: &Input,
|
||||
node: &T::Blockchain,
|
||||
mode: &SolcMode,
|
||||
) -> anyhow::Result<(TransactionReceipt, GethTrace, DiffMode)> {
|
||||
let deployment_receipts =
|
||||
self.handle_contract_deployment(metadata, case_idx, input, node)?;
|
||||
let execution_receipt =
|
||||
self.handle_input_execution(case_idx, input, deployment_receipts, node)?;
|
||||
self.handle_input_expectations(case_idx, input, &execution_receipt, node)?;
|
||||
self.handle_input_expectations(case_idx, input, &execution_receipt, node, mode)?;
|
||||
self.handle_input_diff(case_idx, execution_receipt, node)
|
||||
}
|
||||
|
||||
@@ -312,6 +314,7 @@ where
|
||||
input: &Input,
|
||||
execution_receipt: &TransactionReceipt,
|
||||
node: &T::Blockchain,
|
||||
mode: &SolcMode,
|
||||
) -> anyhow::Result<()> {
|
||||
let span = tracing::info_span!("Handling input expectations");
|
||||
let _guard = span.enter();
|
||||
@@ -367,6 +370,7 @@ where
|
||||
node,
|
||||
expectation,
|
||||
&tracing_result,
|
||||
mode,
|
||||
)?;
|
||||
}
|
||||
|
||||
@@ -380,11 +384,16 @@ where
|
||||
node: &T::Blockchain,
|
||||
expectation: &ExpectedOutput,
|
||||
tracing_result: &CallFrame,
|
||||
mode: &SolcMode,
|
||||
) -> anyhow::Result<()> {
|
||||
// TODO: We want to respect the compiler version filter on the expected output but would
|
||||
// require some changes to the interfaces of the compiler and such. So, we add it later.
|
||||
// Additionally, what happens if the compiler filter doesn't match? Do we consider that the
|
||||
// transaction should succeed? Do we just ignore the expectation?
|
||||
if let Some(ref version_requirement) = expectation.compiler_version {
|
||||
let Some(compiler_version) = mode.last_patch_version(&self.config.solc) else {
|
||||
anyhow::bail!("unsupported solc version: {:?}", &mode.solc_version);
|
||||
};
|
||||
if !version_requirement.matches(&compiler_version) {
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let deployed_contracts = self.deployed_contracts(case_idx);
|
||||
let chain_state_provider = node;
|
||||
@@ -431,8 +440,18 @@ where
|
||||
expected_events.iter().zip(execution_receipt.logs())
|
||||
{
|
||||
// Handling the emitter assertion.
|
||||
if let Some(expected_address) = expected_event.address {
|
||||
let expected = expected_address;
|
||||
if let Some(ref expected_address) = expected_event.address {
|
||||
let expected = if let Some(contract_instance) = expected_address
|
||||
.strip_suffix(".address")
|
||||
.map(ContractInstance::new)
|
||||
{
|
||||
deployed_contracts
|
||||
.get(&contract_instance)
|
||||
.map(|(address, _)| *address)
|
||||
} else {
|
||||
Address::from_str(expected_address).ok()
|
||||
}
|
||||
.context("Failed to get the address of the event")?;
|
||||
let actual = actual_event.address();
|
||||
if actual != expected {
|
||||
tracing::error!(
|
||||
@@ -865,8 +884,13 @@ where
|
||||
tracing::info_span!("Executing input", contract_name = ?input.instance)
|
||||
.in_scope(|| {
|
||||
let (leader_receipt, _, leader_diff) = match leader_state
|
||||
.handle_input(self.metadata, case_idx, &input, self.leader_node)
|
||||
{
|
||||
.handle_input(
|
||||
self.metadata,
|
||||
case_idx,
|
||||
&input,
|
||||
self.leader_node,
|
||||
&mode,
|
||||
) {
|
||||
Ok(result) => result,
|
||||
Err(error) => {
|
||||
tracing::error!(
|
||||
@@ -895,6 +919,7 @@ where
|
||||
case_idx,
|
||||
&input,
|
||||
self.follower_node,
|
||||
&mode,
|
||||
) {
|
||||
Ok(result) => result,
|
||||
Err(error) => {
|
||||
|
||||
@@ -51,7 +51,7 @@ pub struct ExpectedOutput {
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
|
||||
pub struct Event {
|
||||
pub address: Option<Address>,
|
||||
pub address: Option<String>,
|
||||
pub topics: Vec<String>,
|
||||
pub values: Calldata,
|
||||
}
|
||||
@@ -1010,4 +1010,53 @@ mod tests {
|
||||
// Assert
|
||||
assert!(resolved.is_err())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expected_json_can_be_deserialized1() {
|
||||
// Arrange
|
||||
let str = r#"
|
||||
{
|
||||
"return_data": [
|
||||
"1"
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"topics": [],
|
||||
"values": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
|
||||
// Act
|
||||
let expected = serde_json::from_str::<Expected>(str);
|
||||
|
||||
// Assert
|
||||
expected.expect("Failed to deserialize");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expected_json_can_be_deserialized2() {
|
||||
// Arrange
|
||||
let str = r#"
|
||||
{
|
||||
"return_data": [
|
||||
"1"
|
||||
],
|
||||
"events": [
|
||||
{
|
||||
"address": "Main.address",
|
||||
"topics": [],
|
||||
"values": []
|
||||
}
|
||||
]
|
||||
}
|
||||
"#;
|
||||
|
||||
// Act
|
||||
let expected = serde_json::from_str::<Expected>(str);
|
||||
|
||||
// Assert
|
||||
expected.expect("Failed to deserialize");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user