From 8ae994f9de654250161d397f2c40a2e9fa0ad01a Mon Sep 17 00:00:00 2001 From: pgherveou Date: Wed, 8 Oct 2025 09:43:36 +0200 Subject: [PATCH] fixes --- .gitignore | 2 - crates/config/src/lib.rs | 14 ------ crates/core/src/differential_tests/driver.rs | 1 - crates/ml-test-runner/README.md | 50 ------------------- crates/ml-test-runner/src/main.rs | 8 ++- crates/node/src/node_implementations/geth.rs | 27 ++++++++-- .../src/node_implementations/substrate.rs | 27 ++++++++-- 7 files changed, 50 insertions(+), 79 deletions(-) diff --git a/.gitignore b/.gitignore index 5d06954..8688a3c 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,3 @@ resolc-compiler-tests workdir !/schema.json -!/dev-genesis.json -geth-dev/ diff --git a/crates/config/src/lib.rs b/crates/config/src/lib.rs index 87ce15a..47cfc65 100644 --- a/crates/config/src/lib.rs +++ b/crates/config/src/lib.rs @@ -777,20 +777,6 @@ impl WalletConfiguration { } } -impl Default for WalletConfiguration { - fn default() -> Self { - let mut config = Self::parse_from::<[&str; 0], &str>([]); - config.additional_keys = 0; - config - // config.default_key = PrivateKeySigner::from_bytes( - // &FixedBytes::from_hex_str( - // "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d", - // ) - // .unwrap(), - // ) - } -} - fn serialize_private_key(value: &PrivateKeySigner, serializer: S) -> Result where S: Serializer, diff --git a/crates/core/src/differential_tests/driver.rs b/crates/core/src/differential_tests/driver.rs index ae73063..e65c102 100644 --- a/crates/core/src/differential_tests/driver.rs +++ b/crates/core/src/differential_tests/driver.rs @@ -846,7 +846,6 @@ where Ok((*address, abi.clone(), None)) } else { info!("Contract instance requires deployment."); - let (address, abi, receipt) = self .deploy_contract(contract_instance, deployer, calldata, value) .await diff --git a/crates/ml-test-runner/README.md b/crates/ml-test-runner/README.md index f115388..e76a833 100644 --- a/crates/ml-test-runner/README.md +++ b/crates/ml-test-runner/README.md @@ -48,16 +48,6 @@ RUST_LOG=trace ./ml-test-runner path/to/tests/ --start-platform - `--platform ` - Platform to test against (`geth`, `kitchensink`, or `zombienet`, default: `geth`) - `--start-platform` - Start the platform and execute tests (default: `false`, compile-only mode) -## Logging - -The ml-test-runner uses the `tracing` crate for logging. Set the `RUST_LOG` environment variable to control log output: - -- `RUST_LOG=info` - Shows high-level progress (file discovery, node startup, test execution) -- `RUST_LOG=debug` - Shows detailed execution flow (compilation, driver creation, step execution) -- `RUST_LOG=trace` - Shows very detailed tracing (mostly from dependencies) - -Logs are written to stderr, while test results are written to stdout for easy filtering. - ## Output Format The runner produces cargo-test-style output: @@ -75,46 +65,6 @@ Error: ... test result: FAILED. 1 passed; 1 failed; 1 cached; finished in 2.34s ``` -## Implementation Status - -### ✅ Completed -- CLI argument parsing with full configuration options -- File discovery (single file, corpus, recursive directory walk) -- Cached-passed tracking system -- Cargo-test-style output formatting -- Contract compilation with caching -- Platform node management and spawning -- Library deployment and linking -- Full case execution using Driver pattern -- Test file discovery and metadata loading -- Pass/fail tracking and caching -- Output formatting and summary generation -- Error handling and bail behavior -- Optional node startup with `--start-platform` flag -- Compile-only mode (default) for fast validation -- Full execution mode (with `--start-platform`) for actual testing -- Tracing/logging support via `RUST_LOG` - -### 🚧 TODO -- Additional optimizations and performance tuning -- Support for custom working directories - -## Implementation Details - -The ml-test-runner is a **simplified, single-platform test runner** that shares core components with the main differential testing tool: - -- **Compilation**: Uses the shared `CachedCompiler` from `revive-dt-core` that stores compilation artifacts to avoid recompiling -- **Library Deployment**: Automatically deploys library contracts when needed and links them -- **Test Execution**: Uses the shared `Driver` from `revive-dt-core::differential_tests` to execute test cases on the configured platform -- **Node Management**: Optionally spawns and manages blockchain nodes (when `--start-platform` is used) -- **Single Platform**: Unlike the main tool which does differential testing (comparing multiple platforms), `ml-test-runner` executes against a single platform -- **Two Modes**: - - **Compile-only mode** (default): Fast validation that contracts compile correctly, no node required - - **Full execution mode** (`--start-platform`): Spawns a node and executes all test steps with assertions -- **Tracing**: Full logging support via `tracing` and `tracing-subscriber` crates - -The implementation is clean, focused code that reuses battle-tested components from `revive-dt-core`. This ensures consistency while maintaining a lean codebase optimized for ML pipeline integration. - ## Building ```bash diff --git a/crates/ml-test-runner/src/main.rs b/crates/ml-test-runner/src/main.rs index cc02ded..262e4c2 100644 --- a/crates/ml-test-runner/src/main.rs +++ b/crates/ml-test-runner/src/main.rs @@ -48,6 +48,10 @@ struct MlTestRunnerArgs { /// Start the platform and wait for RPC readiness #[arg(long = "start-platform", default_value = "false")] start_platform: bool, + + /// Private key to use for wallet initialization (hex string with or without 0x prefix) + #[arg(long = "private-key", default_value = "0x4f3edf983ac636a65a842ce7c78d9aa706d3b113bce9c46f30d7d21715b23b1d")] + private_key: String, } fn main() -> anyhow::Result<()> { @@ -308,9 +312,9 @@ async fn execute_test_file( info!("Using existing node"); let existing_node: Box = match args.platform { TestingPlatform::Geth => - Box::new(revive_dt_node::node_implementations::geth::GethNode::new_existing()), + Box::new(revive_dt_node::node_implementations::geth::GethNode::new_existing(&args.private_key)?), TestingPlatform::Kitchensink | TestingPlatform::Zombienet => Box::new( - revive_dt_node::node_implementations::substrate::SubstrateNode::new_existing(), + revive_dt_node::node_implementations::substrate::SubstrateNode::new_existing(&args.private_key)?, ), }; Box::leak(existing_node) diff --git a/crates/node/src/node_implementations/geth.rs b/crates/node/src/node_implementations/geth.rs index eacce5f..d809d08 100644 --- a/crates/node/src/node_implementations/geth.rs +++ b/crates/node/src/node_implementations/geth.rs @@ -130,9 +130,26 @@ impl GethNode { } } - pub fn new_existing() -> Self { - let wallet_config = revive_dt_config::WalletConfiguration::default(); - Self { + pub fn new_existing(private_key: &str) -> anyhow::Result { + use alloy::{primitives::FixedBytes, signers::local::PrivateKeySigner}; + + let key_str = private_key.trim().strip_prefix("0x").unwrap_or(private_key.trim()); + let key_bytes = alloy::hex::decode(key_str) + .map_err(|e| anyhow::anyhow!("Failed to decode private key hex: {}", e))?; + + if key_bytes.len() != 32 { + anyhow::bail!("Private key must be 32 bytes (64 hex characters), got {}", key_bytes.len()); + } + + let mut bytes = [0u8; 32]; + bytes.copy_from_slice(&key_bytes); + + let signer = PrivateKeySigner::from_bytes(&FixedBytes(bytes)) + .map_err(|e| anyhow::anyhow!("Failed to create signer from private key: {}", e))?; + + let wallet = Arc::new(EthereumWallet::new(signer)); + + Ok(Self { connection_string: "http://localhost:8545".to_string(), base_directory: PathBuf::new(), data_directory: PathBuf::new(), @@ -142,10 +159,10 @@ impl GethNode { chain_id: 1337, handle: None, start_timeout: Duration::from_secs(0), - wallet: wallet_config.wallet(), + wallet, nonce_manager: Default::default(), provider: Default::default(), - } + }) } /// Create the node directory and call `geth init` to configure the genesis. diff --git a/crates/node/src/node_implementations/substrate.rs b/crates/node/src/node_implementations/substrate.rs index 97377b3..e08c5f1 100644 --- a/crates/node/src/node_implementations/substrate.rs +++ b/crates/node/src/node_implementations/substrate.rs @@ -132,9 +132,26 @@ impl SubstrateNode { } } - pub fn new_existing() -> Self { - let wallet_config = revive_dt_config::WalletConfiguration::default(); - Self { + pub fn new_existing(private_key: &str) -> anyhow::Result { + use alloy::{primitives::FixedBytes, signers::local::PrivateKeySigner}; + + let key_str = private_key.trim().strip_prefix("0x").unwrap_or(private_key.trim()); + let key_bytes = alloy::hex::decode(key_str) + .map_err(|e| anyhow::anyhow!("Failed to decode private key hex: {}", e))?; + + if key_bytes.len() != 32 { + anyhow::bail!("Private key must be 32 bytes (64 hex characters), got {}", key_bytes.len()); + } + + let mut bytes = [0u8; 32]; + bytes.copy_from_slice(&key_bytes); + + let signer = PrivateKeySigner::from_bytes(&FixedBytes(bytes)) + .map_err(|e| anyhow::anyhow!("Failed to create signer from private key: {}", e))?; + + let wallet = Arc::new(EthereumWallet::new(signer)); + + Ok(Self { id: 0, node_binary: PathBuf::new(), eth_proxy_binary: PathBuf::new(), @@ -144,10 +161,10 @@ impl SubstrateNode { logs_directory: PathBuf::new(), substrate_process: None, eth_proxy_process: None, - wallet: wallet_config.wallet(), + wallet, nonce_manager: Default::default(), provider: Default::default(), - } + }) } fn init(&mut self, mut genesis: Genesis) -> anyhow::Result<&mut Self> {