mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-04-28 08:28:00 +00:00
initialize geth via the standard json
Signed-off-by: xermicus <bigcyrill@hotmail.com>
This commit is contained in:
Generated
+15
-6
@@ -1441,7 +1441,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2862,16 +2862,23 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "revive-dt-config"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "revive-dt-core"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"log",
|
||||
"rayon",
|
||||
"revive-dt-compiler",
|
||||
"revive-dt-config",
|
||||
"revive-dt-format",
|
||||
"revive-solc-json-interface",
|
||||
"semver 1.0.26",
|
||||
@@ -2897,6 +2904,9 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"alloy",
|
||||
"anyhow",
|
||||
"revive-dt-config",
|
||||
"revive-dt-node-interaction",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2908,7 +2918,6 @@ dependencies = [
|
||||
"hex",
|
||||
"log",
|
||||
"once_cell",
|
||||
"revive-dt-node",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
]
|
||||
@@ -3051,7 +3060,7 @@ dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3392,7 +3401,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"psm",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3526,7 +3535,7 @@ dependencies = [
|
||||
"getrandom 0.3.2",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
+6
-5
@@ -14,6 +14,7 @@ rust-version = "1.85.0"
|
||||
|
||||
[workspace.dependencies]
|
||||
revive-dt-compiler = { version = "0.1.0", path = "crates/compiler" }
|
||||
revive-dt-config = { version = "0.1.0", path = "crates/config" }
|
||||
revive-dt-core = { version = "0.1.0", path = "crates/core" }
|
||||
revive-dt-format = { version = "0.1.0", path = "crates/format" }
|
||||
revive-dt-node = { version = "0.1.0", path = "crates/node" }
|
||||
@@ -43,13 +44,13 @@ revive-differential = { git = "https://github.com/paritytech/revive", rev = "497
|
||||
version = "0.12.6"
|
||||
default-features = false
|
||||
features = [
|
||||
"providers",
|
||||
"rpc-types",
|
||||
"json-abi",
|
||||
"reqwest",
|
||||
"std",
|
||||
"genesis",
|
||||
"provider-debug-api"
|
||||
"providers",
|
||||
"provider-debug-api",
|
||||
"reqwest",
|
||||
"rpc-types",
|
||||
"std",
|
||||
]
|
||||
|
||||
[profile.bench]
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "revive-dt-config"
|
||||
description = "global configuration for the revive differential tester"
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
edition.workspace = true
|
||||
repository.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
clap = { workspace = true }
|
||||
@@ -0,0 +1,39 @@
|
||||
//! The global configuration used accross all revive differential testing crates.
|
||||
|
||||
use std::{path::PathBuf, sync::OnceLock};
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
static ARGUMENTS: OnceLock<Arguments> = OnceLock::new();
|
||||
|
||||
/// Get the command line arguments.
|
||||
pub fn get_args() -> &'static Arguments {
|
||||
ARGUMENTS.get_or_init(Arguments::parse)
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser, Clone)]
|
||||
#[command(
|
||||
name = "revive compiler differential tester utility",
|
||||
arg_required_else_help = true
|
||||
)]
|
||||
pub struct Arguments {
|
||||
/// The path to the `resolc` executable to be tested.
|
||||
///
|
||||
/// By default it uses the `resolc` binary found in `$PATH`.
|
||||
#[arg(long = "resolc", short, default_value = "resolc")]
|
||||
pub resolc: PathBuf,
|
||||
|
||||
/// A list of test corpus JSON files to be tested.
|
||||
#[arg(long = "corpus", short)]
|
||||
pub corpus: Vec<PathBuf>,
|
||||
|
||||
/// A place to store temporary artifacts during test execution.
|
||||
#[arg(long = "workdir", short)]
|
||||
pub working_directory: PathBuf,
|
||||
|
||||
/// The path to the `geth` executable.
|
||||
///
|
||||
/// By default it uses `geth` binary found in `$PATH`.
|
||||
#[arg(short, long = "geth", default_value = "geth")]
|
||||
pub geth: PathBuf,
|
||||
}
|
||||
@@ -16,9 +16,9 @@ path = "src/main.rs"
|
||||
revive-dt-compiler = { workspace = true }
|
||||
revive-dt-format = { workspace = true }
|
||||
revive-solc-json-interface = { workspace = true }
|
||||
revive-dt-config = { workspace = true }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
log = { workspace = true }
|
||||
env_logger = { workspace = true }
|
||||
rayon = { workspace = true }
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[command(name = "The PolkaVM Solidity compiler", arg_required_else_help = true)]
|
||||
pub struct Arguments {
|
||||
/// The path where the `resolc` executable to be tested is found at.
|
||||
///
|
||||
/// By default it uses the `resolc` found in `$PATH`
|
||||
#[arg(long = "resolc")]
|
||||
pub resolc: Option<PathBuf>,
|
||||
|
||||
/// A list of test corpus JSON files to be tested.
|
||||
#[arg(long = "corpus")]
|
||||
pub corpus: Vec<PathBuf>,
|
||||
}
|
||||
@@ -3,5 +3,4 @@
|
||||
//! This crate defines the testing configuration and
|
||||
//! provides a helper utilty to execute tests.
|
||||
|
||||
pub mod arguments;
|
||||
pub mod driver;
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use clap::Parser;
|
||||
|
||||
use rayon::prelude::*;
|
||||
use revive_dt_core::{arguments::Arguments, driver::compiler::build_evm};
|
||||
|
||||
use revive_dt_config::*;
|
||||
use revive_dt_core::driver::compiler::build_evm;
|
||||
use revive_dt_format::corpus::Corpus;
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
env_logger::init();
|
||||
|
||||
let args = Arguments::try_parse()?;
|
||||
|
||||
for path in args.corpus.iter().collect::<BTreeSet<_>>() {
|
||||
for path in get_args().corpus.iter().collect::<BTreeSet<_>>() {
|
||||
log::trace!("attempting corpus {path:?}");
|
||||
let corpus = Corpus::try_from_path(path)?;
|
||||
log::info!("found corpus: {corpus:?}");
|
||||
|
||||
@@ -16,5 +16,3 @@ log = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
|
||||
revive-dt-node = { workspace = true }
|
||||
|
||||
@@ -2,15 +2,14 @@
|
||||
|
||||
use alloy::rpc::types::trace::geth::GethTrace;
|
||||
use alloy::rpc::types::{TransactionReceipt, TransactionRequest};
|
||||
use revive_dt_node::Node;
|
||||
use tokio_runtime::TO_TOKIO;
|
||||
|
||||
mod tokio_runtime;
|
||||
pub mod trace;
|
||||
pub mod transaction;
|
||||
|
||||
/// An interface for all node interactions.
|
||||
pub trait NodeInteraction: Node {
|
||||
/// An interface for all interactions with Ethereum compatible nodes.
|
||||
pub trait EthereumNode {
|
||||
/// Execute the [TransactionRequest] and return a [TransactionReceipt].
|
||||
fn execute_transaction(
|
||||
&self,
|
||||
|
||||
@@ -5,7 +5,6 @@ use alloy::providers::ProviderBuilder;
|
||||
use alloy::providers::ext::DebugApi;
|
||||
use alloy::rpc::types::TransactionReceipt;
|
||||
use alloy::rpc::types::trace::geth::{GethDebugTracingOptions, GethTrace};
|
||||
use revive_dt_node::Node;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::TO_TOKIO;
|
||||
@@ -37,10 +36,10 @@ impl AsyncNodeInteraction for Trace {
|
||||
|
||||
/// Trace the transaction in [TransactionReceipt] against the `node`,
|
||||
/// using the provided [GethDebugTracingOptions].
|
||||
pub fn trace_transaction<T: Node>(
|
||||
pub fn trace_transaction(
|
||||
transaction_receipt: TransactionReceipt,
|
||||
options: GethDebugTracingOptions,
|
||||
node: &T,
|
||||
connection_string: String,
|
||||
) -> anyhow::Result<GethTrace> {
|
||||
let trace_sender = TO_TOKIO.lock().unwrap().trace_sender.clone();
|
||||
let (geth_trace_sender, mut geth_trace_receiver) = mpsc::channel(1);
|
||||
@@ -49,7 +48,7 @@ pub fn trace_transaction<T: Node>(
|
||||
transaction_hash: transaction_receipt.transaction_hash,
|
||||
options,
|
||||
geth_trace_sender,
|
||||
connection_string: node.connection_string(),
|
||||
connection_string,
|
||||
})?;
|
||||
|
||||
geth_trace_receiver
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
use alloy::providers::{Provider, ProviderBuilder};
|
||||
use alloy::rpc::types::{TransactionReceipt, TransactionRequest};
|
||||
use revive_dt_node::Node;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
use crate::TO_TOKIO;
|
||||
@@ -34,9 +33,9 @@ impl AsyncNodeInteraction for Transaction {
|
||||
}
|
||||
|
||||
/// Execute the [TransactionRequest] against the `node`.
|
||||
pub fn execute_transaction<T: Node>(
|
||||
pub fn execute_transaction(
|
||||
transaction_request: TransactionRequest,
|
||||
node: &T,
|
||||
connection_string: String,
|
||||
) -> anyhow::Result<TransactionReceipt> {
|
||||
let request_sender = TO_TOKIO.lock().unwrap().transaction_sender.clone();
|
||||
let (receipt_sender, mut receipt_receiver) = mpsc::channel(1);
|
||||
@@ -44,7 +43,7 @@ pub fn execute_transaction<T: Node>(
|
||||
request_sender.blocking_send(Transaction {
|
||||
transaction_request,
|
||||
receipt_sender,
|
||||
connection_string: node.connection_string(),
|
||||
connection_string,
|
||||
})?;
|
||||
|
||||
receipt_receiver
|
||||
|
||||
@@ -11,3 +11,7 @@ rust-version.workspace = true
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
alloy = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
revive-dt-node-interaction = { workspace = true }
|
||||
revive-dt-config = { workspace = true }
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
//! The go-ethereum node implementation.
|
||||
|
||||
use std::{
|
||||
fs::{File, create_dir, exists},
|
||||
path::PathBuf,
|
||||
process::{Command, Stdio},
|
||||
sync::atomic::{AtomicU32, Ordering},
|
||||
};
|
||||
|
||||
use alloy::{
|
||||
genesis::Genesis,
|
||||
rpc::types::trace::geth::{DiffMode, PreStateFrame},
|
||||
};
|
||||
use revive_dt_config::get_args;
|
||||
use revive_dt_node_interaction::{
|
||||
EthereumNode, trace::trace_transaction, transaction::execute_transaction,
|
||||
};
|
||||
|
||||
use crate::Node;
|
||||
|
||||
static NODE_COUNT: AtomicU32 = AtomicU32::new(0);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Instance {
|
||||
connection_string: String,
|
||||
directory: PathBuf,
|
||||
geth: PathBuf,
|
||||
id: u32,
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
pub fn new() -> anyhow::Result<Self> {
|
||||
let args = get_args();
|
||||
|
||||
let geth_directory = args.working_directory.join("geth");
|
||||
if !exists(&geth_directory)? {
|
||||
create_dir(&geth_directory)?;
|
||||
}
|
||||
|
||||
let id = NODE_COUNT.fetch_add(1, Ordering::SeqCst);
|
||||
let directory = geth_directory.join(id.to_string());
|
||||
|
||||
let connection_string = directory.join("geth.ipc").display().to_string();
|
||||
|
||||
Ok(Self {
|
||||
connection_string,
|
||||
directory,
|
||||
geth: args.geth.clone(),
|
||||
id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Instance {
|
||||
/// Call `init` on the node to configure it's genesis.
|
||||
fn init(&mut self, genesis: Genesis) -> anyhow::Result<()> {
|
||||
let genesis_path = self.directory.join("genesis.json");
|
||||
|
||||
let mut file = File::create(&genesis_path)?;
|
||||
serde_json::to_writer_pretty(&mut file, &genesis)?;
|
||||
|
||||
if !Command::new(&self.geth)
|
||||
.arg("--datadir")
|
||||
.arg(self.directory.join("data"))
|
||||
.stderr(Stdio::null())
|
||||
.stdout(Stdio::null())
|
||||
.spawn()?
|
||||
.wait()?
|
||||
.success()
|
||||
{
|
||||
anyhow::bail!("failed to initialize geth node {:?}", &self);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl EthereumNode for Instance {
|
||||
fn execute_transaction(
|
||||
&self,
|
||||
transaction_request: alloy::rpc::types::TransactionRequest,
|
||||
) -> anyhow::Result<alloy::rpc::types::TransactionReceipt> {
|
||||
execute_transaction(transaction_request, self.connection_string())
|
||||
}
|
||||
|
||||
fn trace_transaction(
|
||||
&self,
|
||||
transaction_receipt: alloy::rpc::types::TransactionReceipt,
|
||||
) -> anyhow::Result<alloy::rpc::types::trace::geth::GethTrace> {
|
||||
trace_transaction(
|
||||
transaction_receipt,
|
||||
Default::default(),
|
||||
self.connection_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Node for Instance {
|
||||
fn connection_string(&self) -> String {
|
||||
self.connection_string.clone()
|
||||
}
|
||||
|
||||
fn shutdown(self) -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn spawn(&mut self, genesis: Genesis) -> anyhow::Result<&mut Self> {
|
||||
self.init(genesis)?;
|
||||
|
||||
Ok(self)
|
||||
}
|
||||
|
||||
fn state_diff(
|
||||
&self,
|
||||
transaction: alloy::rpc::types::TransactionReceipt,
|
||||
) -> anyhow::Result<DiffMode> {
|
||||
match self
|
||||
.trace_transaction(transaction)?
|
||||
.try_into_pre_state_frame()?
|
||||
{
|
||||
PreStateFrame::Diff(diff) => Ok(diff),
|
||||
_ => anyhow::bail!("expected a diff mode trace"),
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
-15
@@ -1,29 +1,28 @@
|
||||
//! An abstract interface for testing nodes.
|
||||
//! This crate implements the testing nodes.
|
||||
|
||||
use alloy::{
|
||||
genesis::Genesis,
|
||||
rpc::types::{TransactionReceipt, TransactionRequest, trace::parity::StateDiff},
|
||||
rpc::types::{TransactionReceipt, trace::geth::DiffMode},
|
||||
};
|
||||
use revive_dt_node_interaction::EthereumNode;
|
||||
|
||||
pub trait Node {
|
||||
/// Configures the node with the given genesis configuration.
|
||||
fn with_genesis(&mut self, genesis: &Genesis) -> anyhow::Result<&mut Self>;
|
||||
pub mod geth;
|
||||
|
||||
/// Spawns the node, blocking until it's ready to accept transactions.
|
||||
fn spawn(&mut self) -> anyhow::Result<&mut Self>;
|
||||
/// An abstract interface for testing nodes.
|
||||
pub trait Node: EthereumNode {
|
||||
/// Spawns a node configured according to the [Genesis].
|
||||
///
|
||||
/// Blocking until it's ready to accept transactions.
|
||||
fn spawn(&mut self, genesis: Genesis) -> anyhow::Result<&mut Self>;
|
||||
|
||||
/// Prune the node, blocking until it's completely stopped.
|
||||
/// Prune the node instance and related data.
|
||||
///
|
||||
/// Blocking until it's completely stopped.
|
||||
fn shutdown(self) -> anyhow::Result<()>;
|
||||
|
||||
/// Returns the nodes connection string.
|
||||
fn connection_string(&self) -> String;
|
||||
|
||||
/// Execute the [TransactionRequest], blocking until the transaction is mined.
|
||||
fn execute_transaction(
|
||||
&self,
|
||||
transaction: &TransactionRequest,
|
||||
) -> anyhow::Result<TransactionReceipt>;
|
||||
|
||||
/// Returns the state diff of the transaction hash in the [TransactionReceipt].
|
||||
fn state_diff(&self, transaction: &TransactionReceipt) -> anyhow::Result<StateDiff>;
|
||||
fn state_diff(&self, transaction: TransactionReceipt) -> anyhow::Result<DiffMode>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user