mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-06-22 21:51:03 +00:00
complete the M-L format parser
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
This commit is contained in:
@@ -1,46 +0,0 @@
|
|||||||
//! The compiler driver builds the test case contracts for selected compilers.
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use revive_dt_compiler::{Compiler, CompilerInput, SolidityCompiler};
|
|
||||||
use revive_dt_format::{
|
|
||||||
metadata::Metadata,
|
|
||||||
mode::{Mode, SolcMode},
|
|
||||||
};
|
|
||||||
use revive_solc_json_interface::SolcStandardJsonOutput;
|
|
||||||
use semver::Version;
|
|
||||||
|
|
||||||
pub fn build<T: SolidityCompiler>(
|
|
||||||
metadata: &Metadata,
|
|
||||||
) -> anyhow::Result<HashMap<CompilerInput<T::Options>, SolcStandardJsonOutput>> {
|
|
||||||
let sources = metadata.contract_sources()?;
|
|
||||||
let base_path = metadata.directory()?.display().to_string();
|
|
||||||
let modes = metadata
|
|
||||||
.modes
|
|
||||||
.to_owned()
|
|
||||||
.unwrap_or_else(|| vec![Mode::Solidity(Default::default())]);
|
|
||||||
|
|
||||||
let mut result = HashMap::new();
|
|
||||||
for mode in modes {
|
|
||||||
let mut compiler = Compiler::<T>::new().base_path(base_path.clone());
|
|
||||||
for (file, _contract) in sources.values() {
|
|
||||||
compiler = compiler.with_source(file)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
match mode {
|
|
||||||
Mode::Solidity(SolcMode {
|
|
||||||
solc_version: _,
|
|
||||||
solc_optimize,
|
|
||||||
llvm_optimizer_settings: _,
|
|
||||||
}) => {
|
|
||||||
let optimizer = solc_optimize.unwrap_or(true);
|
|
||||||
let version = Version::new(0, 8, 29);
|
|
||||||
let output = compiler.solc_optimizer(optimizer).try_build(&version)?;
|
|
||||||
result.insert(output.input, output.output);
|
|
||||||
}
|
|
||||||
Mode::Unknown(mode) => log::debug!("compiler: ignoring unknown mode '{mode}'"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
//! The input driver executes the test cases differentially against selected nodes.
|
|
||||||
@@ -1,55 +1,99 @@
|
|||||||
//! The test driver handles the compilation and execution of the test cases.
|
//! The test driver handles the compilation and execution of the test cases.
|
||||||
|
|
||||||
use alloy::primitives::map::HashMap;
|
use alloy::primitives::{Address, map::HashMap};
|
||||||
use compiler::build;
|
use revive_dt_compiler::{Compiler, CompilerInput, SolidityCompiler};
|
||||||
use revive_dt_compiler::{CompilerInput, SolidityCompiler};
|
|
||||||
use revive_dt_config::Arguments;
|
use revive_dt_config::Arguments;
|
||||||
use revive_dt_format::metadata::Metadata;
|
use revive_dt_format::{
|
||||||
|
metadata::Metadata,
|
||||||
|
mode::{Mode, SolcMode},
|
||||||
|
};
|
||||||
use revive_dt_node::Node;
|
use revive_dt_node::Node;
|
||||||
use revive_solc_json_interface::SolcStandardJsonOutput;
|
use revive_solc_json_interface::SolcStandardJsonOutput;
|
||||||
|
use semver::Version;
|
||||||
|
|
||||||
use crate::Platform;
|
use crate::Platform;
|
||||||
|
|
||||||
pub mod compiler;
|
|
||||||
pub mod input;
|
|
||||||
|
|
||||||
type Contracts<T> = HashMap<
|
type Contracts<T> = HashMap<
|
||||||
CompilerInput<<<T as Platform>::Compiler as SolidityCompiler>::Options>,
|
CompilerInput<<<T as Platform>::Compiler as SolidityCompiler>::Options>,
|
||||||
SolcStandardJsonOutput,
|
SolcStandardJsonOutput,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
pub struct State<T: Platform> {
|
||||||
|
contracts: Contracts<T>,
|
||||||
|
deployed_contracts: HashMap<String, Address>,
|
||||||
|
node: T::Blockchain,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> State<T>
|
||||||
|
where
|
||||||
|
T: Platform,
|
||||||
|
{
|
||||||
|
fn new(config: &Arguments) -> Self {
|
||||||
|
Self {
|
||||||
|
contracts: Default::default(),
|
||||||
|
deployed_contracts: Default::default(),
|
||||||
|
node: <T::Blockchain as Node>::new(config),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_contracts(&mut self, metadata: &Metadata) -> anyhow::Result<()> {
|
||||||
|
let sources = metadata.contract_sources()?;
|
||||||
|
let base_path = metadata.directory()?.display().to_string();
|
||||||
|
let modes = metadata
|
||||||
|
.modes
|
||||||
|
.to_owned()
|
||||||
|
.unwrap_or_else(|| vec![Mode::Solidity(Default::default())]);
|
||||||
|
|
||||||
|
let mut result = HashMap::new();
|
||||||
|
for mode in modes {
|
||||||
|
let mut compiler = Compiler::<T::Compiler>::new().base_path(base_path.clone());
|
||||||
|
for (file, _contract) in sources.values() {
|
||||||
|
compiler = compiler.with_source(file)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
match mode {
|
||||||
|
Mode::Solidity(SolcMode {
|
||||||
|
solc_version: _,
|
||||||
|
solc_optimize,
|
||||||
|
llvm_optimizer_settings: _,
|
||||||
|
}) => {
|
||||||
|
let optimizer = solc_optimize.unwrap_or(true);
|
||||||
|
let version = Version::new(0, 8, 29);
|
||||||
|
let output = compiler.solc_optimizer(optimizer).try_build(&version)?;
|
||||||
|
result.insert(output.input, output.output);
|
||||||
|
}
|
||||||
|
Mode::Unknown(mode) => log::debug!("compiler: ignoring unknown mode '{mode}'"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Driver<'a, Leader: Platform, Follower: Platform> {
|
pub struct Driver<'a, Leader: Platform, Follower: Platform> {
|
||||||
metadata: &'a Metadata,
|
metadata: &'a Metadata,
|
||||||
config: &'a Arguments,
|
config: &'a Arguments,
|
||||||
|
leader: State<Leader>,
|
||||||
leader_contracts: Contracts<Leader>,
|
follower: State<Follower>,
|
||||||
leader_node: <Leader as Platform>::Blockchain,
|
|
||||||
|
|
||||||
follower_contracts: Contracts<Follower>,
|
|
||||||
follower_node: <Follower as Platform>::Blockchain,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, L, F> Driver<'a, L, F>
|
impl<'a, L, F> Driver<'a, L, F>
|
||||||
where
|
where
|
||||||
L: Platform + Default,
|
L: Platform,
|
||||||
F: Platform + Default,
|
F: Platform,
|
||||||
{
|
{
|
||||||
pub fn new(metadata: &'a Metadata, config: &'a Arguments) -> Driver<'a, L, F> {
|
pub fn new(metadata: &'a Metadata, config: &'a Arguments) -> Driver<'a, L, F> {
|
||||||
Self {
|
Self {
|
||||||
metadata,
|
metadata,
|
||||||
config,
|
config,
|
||||||
|
leader: State::new(config),
|
||||||
leader_node: <<L as Platform>::Blockchain as Node>::new(config),
|
follower: State::new(config),
|
||||||
leader_contracts: Default::default(),
|
|
||||||
|
|
||||||
follower_node: <<F as Platform>::Blockchain as Node>::new(config),
|
|
||||||
follower_contracts: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&mut self) -> anyhow::Result<()> {
|
pub fn execute(&mut self) -> anyhow::Result<()> {
|
||||||
self.leader_contracts = build::<L::Compiler>(self.metadata)?;
|
self.leader.build_contracts(self.metadata)?;
|
||||||
self.follower_contracts = build::<F::Compiler>(self.metadata)?;
|
self.follower.build_contracts(self.metadata)?;
|
||||||
|
|
||||||
if self.config.compile_only {
|
if self.config.compile_only {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|||||||
+28
-26
@@ -1,15 +1,38 @@
|
|||||||
use alloy::json_abi::Function;
|
use alloy::json_abi::Function;
|
||||||
use alloy::primitives::U256;
|
use semver::VersionReq;
|
||||||
use serde::{Deserialize, de::Deserializer};
|
use serde::{Deserialize, de::Deserializer};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
|
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
|
||||||
pub struct Input {
|
pub struct Input {
|
||||||
pub instance: String,
|
pub instance: Option<String>,
|
||||||
#[serde(deserialize_with = "deserialize_method")]
|
#[serde(deserialize_with = "deserialize_method")]
|
||||||
pub method: Method,
|
pub method: Method,
|
||||||
#[serde(deserialize_with = "deserialize_calldata")]
|
pub calldata: Option<Calldata>,
|
||||||
pub calldata: Vec<u8>,
|
pub expected: Option<Expected>,
|
||||||
pub expected: Option<Vec<String>>,
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Expected {
|
||||||
|
Calldata(Calldata),
|
||||||
|
Expected(ExpectedOutput),
|
||||||
|
ExpectedMany(Vec<ExpectedOutput>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
|
||||||
|
pub struct ExpectedOutput {
|
||||||
|
compiler_version: Option<VersionReq>,
|
||||||
|
return_data: Option<Calldata>,
|
||||||
|
events: Option<Value>,
|
||||||
|
exception: Option<bool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum Calldata {
|
||||||
|
Single(String),
|
||||||
|
Compound(Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specify how the contract is called.
|
/// Specify how the contract is called.
|
||||||
@@ -30,27 +53,6 @@ pub enum Method {
|
|||||||
Function([u8; 4]),
|
Function([u8; 4]),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_calldata<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
|
||||||
where
|
|
||||||
D: Deserializer<'de>,
|
|
||||||
{
|
|
||||||
let calldata_strings: Vec<String> = Vec::deserialize(deserializer)?;
|
|
||||||
let mut result = Vec::with_capacity(calldata_strings.len() * 32);
|
|
||||||
|
|
||||||
for calldata_string in &calldata_strings {
|
|
||||||
match calldata_string.parse::<U256>() {
|
|
||||||
Ok(parsed) => result.extend_from_slice(&parsed.to_be_bytes::<32>()),
|
|
||||||
Err(error) => {
|
|
||||||
return Err(serde::de::Error::custom(format!(
|
|
||||||
"parsing U256 {calldata_string} error: {error}"
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_method<'de, D>(deserializer: D) -> Result<Method, D::Error>
|
fn deserialize_method<'de, D>(deserializer: D) -> Result<Method, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
|
|||||||
Reference in New Issue
Block a user