mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-04-22 16:07:59 +00:00
Scaffold utility and library (#3)
Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com> Signed-off-by: xermicus <bigcyrill@hotmail.com>
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use alloy::{
|
||||
json_abi::Function, network::TransactionBuilder, primitives::Address,
|
||||
rpc::types::TransactionRequest,
|
||||
};
|
||||
use semver::VersionReq;
|
||||
use serde::{Deserialize, de::Deserializer};
|
||||
use serde_json::Value;
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq)]
|
||||
pub struct Input {
|
||||
#[serde(default = "default_caller")]
|
||||
pub caller: Address,
|
||||
pub comment: Option<String>,
|
||||
#[serde(default = "default_instance")]
|
||||
pub instance: String,
|
||||
#[serde(deserialize_with = "deserialize_method")]
|
||||
pub method: Method,
|
||||
pub calldata: Option<Calldata>,
|
||||
pub expected: Option<Expected>,
|
||||
pub value: Option<String>,
|
||||
pub storage: Option<HashMap<String, Calldata>>,
|
||||
}
|
||||
|
||||
#[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.
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||
pub enum Method {
|
||||
/// Initiate a deploy transaction, calling contracts constructor.
|
||||
///
|
||||
/// Indicated by `#deployer`.
|
||||
Deployer,
|
||||
/// Does not calculate and insert a function selector.
|
||||
///
|
||||
/// Indicated by `#fallback`.
|
||||
#[default]
|
||||
Fallback,
|
||||
/// Call the public function with this selector.
|
||||
///
|
||||
/// Calculates the selector if neither deployer or fallback matches.
|
||||
Function([u8; 4]),
|
||||
}
|
||||
|
||||
fn deserialize_method<'de, D>(deserializer: D) -> Result<Method, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
Ok(match String::deserialize(deserializer)?.as_str() {
|
||||
"#deployer" => Method::Deployer,
|
||||
"#fallback" => Method::Fallback,
|
||||
signature => {
|
||||
let signature = if signature.ends_with(')') {
|
||||
signature.to_string()
|
||||
} else {
|
||||
format!("{signature}()")
|
||||
};
|
||||
match Function::parse(&signature) {
|
||||
Ok(function) => Method::Function(function.selector().0),
|
||||
Err(error) => {
|
||||
return Err(serde::de::Error::custom(format!(
|
||||
"parsing function signature '{signature}' error: {error}"
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
impl Input {
|
||||
fn instance_to_address(
|
||||
&self,
|
||||
instance: &str,
|
||||
deployed_contracts: &HashMap<String, Address>,
|
||||
) -> anyhow::Result<Address> {
|
||||
deployed_contracts
|
||||
.get(instance)
|
||||
.copied()
|
||||
.ok_or_else(|| anyhow::anyhow!("instance {instance} not deployed"))
|
||||
}
|
||||
|
||||
/// Parse this input into a legacy transaction.
|
||||
pub fn legacy_transaction(
|
||||
&self,
|
||||
chain_id: u64,
|
||||
nonce: u64,
|
||||
deployed_contracts: &HashMap<String, Address>,
|
||||
) -> anyhow::Result<TransactionRequest> {
|
||||
let to = match self.method {
|
||||
Method::Deployer => Address::ZERO,
|
||||
_ => self.instance_to_address(&self.instance, deployed_contracts)?,
|
||||
};
|
||||
|
||||
Ok(TransactionRequest::default()
|
||||
.with_from(self.caller)
|
||||
.with_to(to)
|
||||
.with_nonce(nonce)
|
||||
.with_chain_id(chain_id)
|
||||
.with_gas_price(20_000_000_000)
|
||||
.with_gas_limit(20_000_000_000))
|
||||
}
|
||||
}
|
||||
|
||||
fn default_instance() -> String {
|
||||
"Test".to_string()
|
||||
}
|
||||
|
||||
fn default_caller() -> Address {
|
||||
"90F8bf6A479f320ead074411a4B0e7944Ea8c9C1".parse().unwrap()
|
||||
}
|
||||
Reference in New Issue
Block a user