mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-04-29 22:57:59 +00:00
Compute transaction input for executing transactions (#28)
* Parsed ABI field in order to get method parameter * Added logic for ABI * Refactored dependencies * Small refactoring * Added unit tests for ABI parameter extraction logic * Fixed format issues * Fixed format * Added new changes to format * Added bail to stop execution when we have an error during deployment
This commit is contained in:
+104
-22
@@ -1,12 +1,14 @@
|
||||
//! The test driver handles the compilation and execution of the test cases.
|
||||
|
||||
use alloy::json_abi::JsonAbi;
|
||||
use alloy::primitives::Bytes;
|
||||
use alloy::rpc::types::TransactionInput;
|
||||
use alloy::rpc::types::trace::geth::GethTrace;
|
||||
use alloy::rpc::types::{TransactionInput, TransactionReceipt};
|
||||
use alloy::{
|
||||
primitives::{Address, TxKind, map::HashMap},
|
||||
rpc::types::{
|
||||
TransactionReceipt, TransactionRequest,
|
||||
trace::geth::{AccountState, DiffMode, GethTrace},
|
||||
TransactionRequest,
|
||||
trace::geth::{AccountState, DiffMode},
|
||||
},
|
||||
};
|
||||
use revive_dt_compiler::{Compiler, CompilerInput, SolidityCompiler};
|
||||
@@ -15,6 +17,8 @@ use revive_dt_format::{input::Input, metadata::Metadata, mode::SolcMode};
|
||||
use revive_dt_node_interaction::EthereumNode;
|
||||
use revive_dt_report::reporter::{CompilationTask, Report, Span};
|
||||
use revive_solc_json_interface::SolcStandardJsonOutput;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap as StdHashMap;
|
||||
|
||||
use crate::Platform;
|
||||
|
||||
@@ -27,7 +31,8 @@ pub struct State<'a, T: Platform> {
|
||||
config: &'a Arguments,
|
||||
span: Span,
|
||||
contracts: Contracts<T>,
|
||||
deployed_contracts: HashMap<String, Address>,
|
||||
deployed_contracts: StdHashMap<String, Address>,
|
||||
deployed_abis: StdHashMap<String, JsonAbi>,
|
||||
}
|
||||
|
||||
impl<'a, T> State<'a, T>
|
||||
@@ -40,6 +45,7 @@ where
|
||||
span,
|
||||
contracts: Default::default(),
|
||||
deployed_contracts: Default::default(),
|
||||
deployed_abis: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,15 +132,21 @@ where
|
||||
std::any::type_name::<T>()
|
||||
);
|
||||
|
||||
let tx =
|
||||
match input.legacy_transaction(self.config.network_id, nonce, &self.deployed_contracts)
|
||||
{
|
||||
Ok(tx) => tx,
|
||||
Err(err) => {
|
||||
log::error!("Failed to construct legacy transaction: {err:?}");
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
let tx = match input.legacy_transaction(
|
||||
self.config.network_id,
|
||||
nonce,
|
||||
&self.deployed_contracts,
|
||||
&self.deployed_abis,
|
||||
) {
|
||||
Ok(tx) => {
|
||||
log::debug!("Legacy transaction data: {tx:#?}");
|
||||
tx
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("Failed to construct legacy transaction: {err:?}");
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
|
||||
log::trace!("Executing transaction for input: {input:?}");
|
||||
|
||||
@@ -191,9 +203,6 @@ where
|
||||
&contract_name,
|
||||
&input.instance
|
||||
);
|
||||
if contract_name != &input.instance {
|
||||
continue;
|
||||
}
|
||||
|
||||
let bytecode = contract
|
||||
.evm
|
||||
@@ -270,6 +279,52 @@ where
|
||||
address,
|
||||
std::any::type_name::<T>()
|
||||
);
|
||||
|
||||
if let Some(Value::String(metadata_json_str)) = &contract.metadata {
|
||||
log::trace!(
|
||||
"metadata found for contract {contract_name}, {metadata_json_str}"
|
||||
);
|
||||
|
||||
match serde_json::from_str::<serde_json::Value>(metadata_json_str) {
|
||||
Ok(metadata_json) => {
|
||||
if let Some(abi_value) =
|
||||
metadata_json.get("output").and_then(|o| o.get("abi"))
|
||||
{
|
||||
match serde_json::from_value::<JsonAbi>(abi_value.clone()) {
|
||||
Ok(parsed_abi) => {
|
||||
log::trace!(
|
||||
"ABI found in metadata for contract {}",
|
||||
&contract_name
|
||||
);
|
||||
self.deployed_abis
|
||||
.insert(contract_name.clone(), parsed_abi);
|
||||
}
|
||||
Err(err) => {
|
||||
anyhow::bail!(
|
||||
"Failed to parse ABI from metadata for contract {}: {}",
|
||||
contract_name,
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -343,14 +398,41 @@ where
|
||||
for case in &self.metadata.cases {
|
||||
for input in &case.inputs {
|
||||
log::debug!("Starting deploying contract {}", &input.instance);
|
||||
leader_state.deploy_contracts(input, self.leader_node)?;
|
||||
follower_state.deploy_contracts(input, self.follower_node)?;
|
||||
if let Err(err) = leader_state.deploy_contracts(input, self.leader_node) {
|
||||
log::error!("Leader deployment failed for {}: {err}", input.instance);
|
||||
continue;
|
||||
} else {
|
||||
log::debug!("Leader deployment succeeded for {}", &input.instance);
|
||||
}
|
||||
|
||||
if let Err(err) = follower_state.deploy_contracts(input, self.follower_node) {
|
||||
log::error!("Follower deployment failed for {}: {err}", input.instance);
|
||||
continue;
|
||||
} else {
|
||||
log::debug!("Follower deployment succeeded for {}", &input.instance);
|
||||
}
|
||||
|
||||
log::debug!("Starting executing contract {}", &input.instance);
|
||||
let (leader_receipt, _, leader_diff) =
|
||||
leader_state.execute_input(input, self.leader_node)?;
|
||||
let (follower_receipt, _, follower_diff) =
|
||||
follower_state.execute_input(input, self.follower_node)?;
|
||||
|
||||
let (leader_receipt, _, leader_diff) = match leader_state
|
||||
.execute_input(input, self.leader_node)
|
||||
{
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
log::error!("Leader execution failed for {}: {err}", input.instance);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let (follower_receipt, _, follower_diff) = match follower_state
|
||||
.execute_input(input, self.follower_node)
|
||||
{
|
||||
Ok(result) => result,
|
||||
Err(err) => {
|
||||
log::error!("Follower execution failed for {}: {err}", input.instance);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if leader_diff == follower_diff {
|
||||
log::debug!("State diffs match between leader and follower.");
|
||||
|
||||
Reference in New Issue
Block a user