Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 59 additions & 2 deletions crates/core/src/driver/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
//! The test driver handles the compilation and execution of the test cases.

use alloy::{
primitives::{Address, map::HashMap},
rpc::types::trace::geth::{AccountState, DiffMode, GethTrace},
network::TransactionBuilder,
primitives::{Address, bytes::Bytes, map::HashMap},
rpc::types::{
TransactionRequest,
trace::geth::{AccountState, DiffMode, GethTrace},
},
};
use revive_dt_compiler::{Compiler, CompilerInput, SolidityCompiler};
use revive_dt_config::Arguments;
Expand Down Expand Up @@ -109,6 +113,56 @@ where

Ok((trace, diff))
}

pub fn deploy_contracts(&mut self, input: &Input, node: &T::Blockchain) -> anyhow::Result<()> {
for output in self.contracts.values() {
let Some(contract_map) = &output.contracts else {
log::debug!("No contracts in output — skipping deployment for this input.");
continue;
};

for contracts in contract_map.values() {
for (contract_name, contract) in contracts {
if contract_name != &input.instance {
continue;
}

let bytecode = contract
.evm
.as_ref()
.and_then(|evm| evm.bytecode.as_ref())
.map(|b| b.object.clone());

let Some(code) = bytecode else {
anyhow::bail!("no bytecode for contract `{}`", contract_name);
};

let tx = TransactionRequest::default()
.with_from(input.caller)
.with_to(Address::ZERO)
.with_input(Bytes::from(code.clone()))
.with_gas_price(20_000_000_000)
.with_gas_limit(20_000_000_000)
.with_chain_id(self.config.network_id)
.with_nonce(0);

let receipt = node.execute_transaction(tx)?;
let Some(address) = receipt.contract_address else {
anyhow::bail!(
"contract `{}` deployment did not return an address",
contract_name
);
};

self.deployed_contracts
.insert(contract_name.clone(), address);
log::info!("deployed contract `{}` at {:?}", contract_name, address);
}
}
}

Ok(())
}
}

pub struct Driver<'a, Leader: Platform, Follower: Platform> {
Expand Down Expand Up @@ -173,6 +227,9 @@ where

for case in &self.metadata.cases {
for input in &case.inputs {
leader_state.deploy_contracts(input, self.leader_node)?;
follower_state.deploy_contracts(input, self.follower_node)?;

let (_, leader_diff) = leader_state.execute_input(input, self.leader_node)?;
let (_, follower_diff) =
follower_state.execute_input(input, self.follower_node)?;
Expand Down
46 changes: 31 additions & 15 deletions crates/core/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rayon::{ThreadPoolBuilder, prelude::*};

use revive_dt_config::*;
use revive_dt_core::{
Geth, Kitchensink,
Geth, Kitchensink, Platform,
driver::{Driver, State},
};
use revive_dt_format::{corpus::Corpus, metadata::Metadata};
Expand Down Expand Up @@ -74,28 +74,30 @@ fn collect_corpora(args: &Arguments) -> anyhow::Result<HashMap<Corpus, Vec<Metad
Ok(corpora)
}

fn execute_corpus(args: &Arguments, tests: &[Metadata], span: Span) -> anyhow::Result<()> {
let leader_nodes = NodePool::new(args)?;
let follower_nodes = NodePool::new(args)?;
fn run_driver<L, F>(args: &Arguments, tests: &[Metadata], span: Span) -> anyhow::Result<()>
where
L: Platform,
F: Platform,
L::Blockchain: revive_dt_node::Node + Send + Sync + 'static,
F::Blockchain: revive_dt_node::Node + Send + Sync + 'static,
{
let leader_nodes = NodePool::<L::Blockchain>::new(args)?;
let follower_nodes = NodePool::<F::Blockchain>::new(args)?;

tests.par_iter().for_each(|metadata| {
let mut driver = match (&args.leader, &args.follower) {
(TestingPlatform::Geth, TestingPlatform::Kitchensink) => Driver::<Geth, Geth>::new(
metadata,
args,
leader_nodes.round_robbin(),
follower_nodes.round_robbin(),
),
_ => unimplemented!(),
};
let mut driver = Driver::<L, F>::new(
metadata,
args,
leader_nodes.round_robbin(),
follower_nodes.round_robbin(),
);

match driver.execute(span) {
Ok(build) => {
Ok(_) => {
log::info!(
"metadata {} success",
metadata.directory().as_ref().unwrap().display()
);
build
}
Err(error) => {
log::warn!(
Expand All @@ -109,6 +111,20 @@ fn execute_corpus(args: &Arguments, tests: &[Metadata], span: Span) -> anyhow::R
Ok(())
}

fn execute_corpus(args: &Arguments, tests: &[Metadata], span: Span) -> anyhow::Result<()> {
match (&args.leader, &args.follower) {
(TestingPlatform::Geth, TestingPlatform::Kitchensink) => {
run_driver::<Geth, Kitchensink>(args, tests, span)?
}
(TestingPlatform::Geth, TestingPlatform::Geth) => {
run_driver::<Geth, Geth>(args, tests, span)?
}
_ => unimplemented!(),
}

Ok(())
}

fn compile_corpus(config: &Arguments, tests: &[Metadata], platform: &TestingPlatform, span: Span) {
tests.par_iter().for_each(|metadata| {
for mode in &metadata.solc_modes() {
Expand Down