mirror of
https://github.com/pezkuwichain/revive-differential-tests.git
synced 2026-04-29 17:08:00 +00:00
fixes
This commit is contained in:
@@ -13,5 +13,3 @@ resolc-compiler-tests
|
||||
workdir
|
||||
|
||||
!/schema.json
|
||||
!/dev-genesis.json
|
||||
geth-dev/
|
||||
|
||||
@@ -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<S>(value: &PrivateKeySigner, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -48,16 +48,6 @@ RUST_LOG=trace ./ml-test-runner path/to/tests/ --start-platform
|
||||
- `--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
|
||||
|
||||
@@ -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<dyn revive_dt_node_interaction::EthereumNode> = 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)
|
||||
|
||||
@@ -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<Self> {
|
||||
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.
|
||||
|
||||
@@ -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<Self> {
|
||||
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> {
|
||||
|
||||
Reference in New Issue
Block a user