diff --git a/AGENTS.md b/AGENTS.md index df9f2a63..0c198061 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,7 +59,7 @@ Toolchain uses the `stable` channel via `rust-toolchain.toml` (+ rustfmt + clipp | `storage` | KvStore, witness pruner, settled-source index | | `consensus` | wPoA engine, validator set, slashing | | `genesis` | Genesis block construction | -| `evm` | revm-backed PQVM execution adapter, parallel scheduler | +| `pqvm` | revm-backed PQVM execution adapter, parallel scheduler | | `mempool` | Transaction pool | | `network` | libp2p gossipsub | | `rpc` | JSON-RPC, TLS, three-RPC fanout | diff --git a/CHANGELOG.md b/CHANGELOG.md index 1af42a3d..f994bf66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -331,12 +331,12 @@ All notable changes to this project will be documented in this file. `expiry_block`, `root_signature`, and `session_signature`. RLP encodes as a 5-field list. Breaking change vs v0.18.x wire format. See `docs/AA_PHASE2_SPEC.md`. -- **AA Phase 2 contract paymaster** (`crates/evm`): `validatePaymasterOp` ABI call +- **AA Phase 2 contract paymaster** (`crates/pqvm`): `validatePaymasterOp` ABI call dispatched when `paymaster_context` is present. Call runs in a world-state snapshot (mutations discarded). Gas cap 50k. Bool return decoded from 32-byte ABI word. -- **AA Phase 2 session keys** (`crates/evm`): Session-key-signed AA bundles now +- **AA Phase 2 session keys** (`crates/pqvm`): Session-key-signed AA bundles now validated via two-step PQ verification: (1) root key authorizes the session key via `session_auth_hash`; (2) session key signs the tx via `sender_signing_hash`. Constraint checks: expiry block, value cap (Σ inner call values), optional target @@ -344,7 +344,7 @@ All notable changes to this project will be documented in this file. `SessionTargetMismatch`, `SessionRootSignatureInvalid`, `SessionKeySignatureInvalid`, `SessionKeyDisallowedAlgorithm`. -- **AA Phase 2 guardian recovery** (`crates/evm`, `crates/storage`): `AccountManager` +- **AA Phase 2 guardian recovery** (`crates/pqvm`, `crates/storage`): `AccountManager` system contract gains 4 new entry points: `setGuardians(address[],uint8,uint64)`, `submitRecovery(address,bytes,uint8)`, `executeRecovery(address)`, `cancelRecovery(address)`. `GuardianConfig` and `RecoveryProposal` persisted in @@ -355,7 +355,7 @@ All notable changes to this project will be documented in this file. ### Fixed -- **Double PQ signature verification** (`crates/evm`): `validate_tx()` and +- **Double PQ signature verification** (`crates/pqvm`): `validate_tx()` and `validate_tx_for_import()` both previously called `verify_paymaster_signature()` after already invoking `validate_aa_tx()` which performs the same check internally. The redundant second call is now removed; PQ (Dilithium) sig verification is @@ -591,16 +591,16 @@ All notable changes to this project will be documented in this file. ### Added -- **Parallel EVM executor** (`crates/evm`): `ConflictMetric` type with `ReadWrite`, `WriteWrite`, and `Incomplete` variants for tracking inter-transaction state conflicts. +- **Parallel PQVM executor** (`crates/pqvm`): `ConflictMetric` type with `ReadWrite`, `WriteWrite`, and `Incomplete` variants for tracking inter-transaction state conflicts. - `plan_with_metrics()`: transaction dependency graph builder that returns a `Vec` alongside the execution plan. -- CLI flag `--parallel-evm` (default: **OFF**) to opt-in to the parallel execution path. -- CLI flag `--parallel-evm-workers ` to control the Rayon worker-pool size (default: number of logical CPUs). -- `config/node.example.toml` updated with a `[parallel_evm]` section documenting both flags. -- State validation tests: 11 unit tests in `crates/evm`, 3 benchmarks in `crates/bench` (`parallel_evm_throughput`, `conflict_detection_overhead`, `sequential_baseline`). +- CLI flag `--parallel-pqvm` (default: **OFF**) to opt-in to the parallel execution path. +- CLI flag `--parallel-pqvm-workers ` to control the Rayon worker-pool size (default: number of logical CPUs). +- `config/node.example.toml` updated with a `[parallel_pqvm]` section documenting both flags. +- State validation tests: 11 unit tests in `crates/pqvm`, 3 benchmarks in `crates/bench` (`parallel_pqvm_throughput`, `conflict_detection_overhead`, `sequential_baseline`). ### Changed -- `parallel-evm` feature is gated behind the CLI flag and disabled on production nodes until further notice. +- `parallel-pqvm` feature is gated behind the CLI flag and disabled on production nodes until further notice. ### Previous release: [0.13.0] @@ -629,7 +629,7 @@ All notable changes to this project will be documented in this file. **Batch 4 — Operations & Observability** - Structured JSON logging with `--log-format json|text` and sensitive-field filtering -- Extended Prometheus metrics: `shell_aa_tx_total`, `shell_key_rotation_total`, `shell_validator_weight`, `shell_consensus_slot_miss`, `shell_evm_gas_used_total`, `shell_snapshot_size_bytes` +- Extended Prometheus metrics: `shell_aa_tx_total`, `shell_key_rotation_total`, `shell_validator_weight`, `shell_consensus_slot_miss`, `shell_pqvm_gas_used_total`, `shell_snapshot_size_bytes` - Admin RPC namespace (`admin_nodeInfo`, `admin_peers`, `admin_addPeer`, `admin_removePeer`, `admin_datadir`); requires `--admin-api` flag (loopback-only by default) - Hot backup / restore CLI: `shell-node backup create|restore|schedule` @@ -696,11 +696,11 @@ All notable changes to this project will be documented in this file. ### Added - Upgrade from Shanghai to Cancun EVM specification -- EIP-2930 access list support in transactions, EVM execution, and RPC +- EIP-2930 access list support in transactions, PQVM execution, and RPC - EIP-4844 basic blob transaction type and gas pricing - `debug_traceTransaction` and trace API for transaction debugging - Missing standard Ethereum JSON-RPC methods (full eth_* coverage) -- Comprehensive EVM compatibility verification tests +- Comprehensive Ethereum tooling compatibility verification tests - State pruning with configurable retention policy - Batch parallel signature verification with Rayon - RLP serialization replacing JSON in chain store for performance @@ -783,7 +783,7 @@ All notable changes to this project will be documented in this file. - PoA consensus engine with pluggable trait - Genesis block initialization from config - Code storage and PQ public key registry in ChainStore -- EVM executor with revm integration +- PQVM executor with revm integration - PQ precompiles — disabled `ecrecover`, added Dilithium3 verify - Transaction validation pipeline with hybrid pubkey registration - JSON-RPC server with `eth_*` and `shell_*` endpoints diff --git a/Cargo.lock b/Cargo.lock index 9e3b4d94..8a6ae360 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5861,12 +5861,12 @@ dependencies = [ "shell-consensus", "shell-core", "shell-crypto", - "shell-evm", "shell-genesis", "shell-keystore", "shell-mempool", "shell-network", "shell-node", + "shell-pqvm", "shell-primitives", "shell-rpc", "shell-storage", @@ -5942,27 +5942,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "shell-evm" -version = "0.23.0" -dependencies = [ - "alloy-primitives", - "alloy-rlp", - "blake3", - "criterion", - "hex", - "rayon", - "revm", - "serde", - "serde_json", - "sha3", - "shell-core", - "shell-crypto", - "shell-primitives", - "shell-storage", - "thiserror 2.0.18", -] - [[package]] name = "shell-genesis" version = "0.23.0" @@ -6024,7 +6003,7 @@ dependencies = [ "serde_json", "shell-core", "shell-crypto", - "shell-evm", + "shell-pqvm", "shell-primitives", "shell-storage", "thiserror 2.0.18", @@ -6083,10 +6062,10 @@ dependencies = [ "shell-consensus", "shell-core", "shell-crypto", - "shell-evm", "shell-genesis", "shell-mempool", "shell-network", + "shell-pqvm", "shell-primitives", "shell-rpc", "shell-stark-prover", @@ -6096,6 +6075,27 @@ dependencies = [ "tracing", ] +[[package]] +name = "shell-pqvm" +version = "0.23.0" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "blake3", + "criterion", + "hex", + "rayon", + "revm", + "serde", + "serde_json", + "sha3", + "shell-core", + "shell-crypto", + "shell-primitives", + "shell-storage", + "thiserror 2.0.18", +] + [[package]] name = "shell-primitives" version = "0.23.0" @@ -6130,8 +6130,8 @@ dependencies = [ "shell-consensus", "shell-core", "shell-crypto", - "shell-evm", "shell-mempool", + "shell-pqvm", "shell-primitives", "shell-stark-prover", "shell-storage", diff --git a/Cargo.toml b/Cargo.toml index 06b83e19..c38a324b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ members = [ "crates/storage", "crates/consensus", "crates/genesis", - "crates/evm", + "crates/pqvm", "crates/mempool", "crates/rpc", "crates/network", @@ -63,7 +63,7 @@ async-trait = "0.1" # --- storage (trie) --- eth_trie = "0.4" -# --- evm --- +# --- pqvm --- revm = { version = "36", default-features = false, features = ["std", "optional_no_base_fee", "optional_balance_check"] } # --- rpc --- diff --git a/README.md b/README.md index 982e35c7..191aad57 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Accounts are identified by `0x`-prefixed 64-character lowercase hex addresses the full 32-byte BLAKE3 hash of `algo_id ‖ public_key`. At the **canonical layer** (RPC, storage, consensus, signing), addresses are always -the full 32 bytes. At the **EVM execution boundary**, Shell-Chain maintains a +the full 32 bytes. At the **revm adapter boundary**, Shell-Chain maintains a 20-byte mapping layer: `Address::to_alloy()` takes the last 20 bytes of the 32-byte canonical address for use with revm, and `Address::from_alloy()` zero-pads left back to 32 bytes. This boundary is internal — external callers (SDK, CLI, explorer) @@ -79,7 +79,7 @@ For the full design and current implementation status, see │ shell-core │ │ (Block, Transaction, Account) │ ├──────────┬──────────────┼───────────────────┤ -│ shell-evm│ shell-crypto │ shell-storage │ +│ shell-pqvm│ shell-crypto │ shell-storage │ │(PQVM/revm│ (PQ Crypto) │ (RocksDB) │ │ adapter) │ │ │ ├──────────┴──────────────┴───────────────────┤ @@ -97,7 +97,7 @@ For the full design and current implementation status, see | `shell-core` | Block, Transaction (AA-native), Account, Receipt, EIP-1559 gas model | | `shell-storage` | RocksDB backend, Merkle Patricia Trie, RLP serialization, state pruning, storage profiles | | `shell-consensus` | PoA engine (default); optional wPoA extension: weight-based fork choice, BFT finality, slashing | -| `shell-evm` | PQVM execution adapter over revm for retained Cancun-style semantics, PQ precompiles, EIP-2930/4844 fields, system contracts | +| `shell-pqvm` | PQVM execution adapter over revm for retained Cancun-style semantics, PQ precompiles, EIP-2930/4844 fields, system contracts | | `shell-mempool` | Transaction pool with PQ validation, fee-priority ordering, Replace-by-Fee | | `shell-network` | libp2p P2P: GossipSub, Kademlia DHT, NAT traversal, peer scoring, tx gossip | | `shell-rpc` | JSON-RPC (HTTP + WebSocket), CORS, rate limiting, filters, subscriptions, debug/trace APIs | @@ -117,7 +117,7 @@ shell-chain/ │ ├── consensus/ # Weighted PoA consensus engine and slashing │ ├── core/ # Block, Transaction, Account │ ├── crypto/ # Post-quantum cryptography -│ ├── evm/ # PQVM/revm execution adapter and precompiles +│ ├── pqvm/ # PQVM/revm execution adapter and precompiles │ ├── genesis/ # Genesis configuration │ ├── keystore/ # Encrypted key storage │ ├── mempool/ # Transaction pool diff --git a/UPGRADE.md b/UPGRADE.md index 6b395757..7050a6a7 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -432,7 +432,7 @@ New Prometheus metrics added in v0.13.0: | `shell_key_rotation_total` | Counter | PQ key rotations | | `shell_validator_weight{address}` | Gauge | Current validator weight | | `shell_consensus_slot_miss` | Counter | Empty slots (missed proposer) | -| `shell_evm_gas_used_total` | Counter | Cumulative gas used | +| `shell_pqvm_gas_used_total` | Counter | Cumulative gas used | | `shell_snapshot_size_bytes` | Gauge | Latest backup snapshot size | Update your Grafana dashboards by importing the updated JSON from `docker/grafana/`. diff --git a/blog/why-native-account-abstraction.md b/blog/why-native-account-abstraction.md index dbad790f..0e93846b 100644 --- a/blog/why-native-account-abstraction.md +++ b/blog/why-native-account-abstraction.md @@ -34,10 +34,10 @@ Layer 1: Protocol-level signature check (Dilithium3 or SPHINCS+) ↓ Layer 2: Account-specific validation contract (if set via AccountManager) ↓ -Layer 3: EVM execution +Layer 3: PQVM execution ``` -The critical difference: validation happens **before** the EVM sees the +The critical difference: validation happens **before** the PQVM sees the transaction. No bundler. No `UserOperation` mempool. No `EntryPoint` contract to re-enter. The chain itself is the bundler. diff --git a/config/node.example.toml b/config/node.example.toml index e68165f8..1e30f71b 100644 --- a/config/node.example.toml +++ b/config/node.example.toml @@ -36,9 +36,10 @@ # level = "info" # trace | debug | info | warn | error # format = "text" # text | compact | json -# ── Parallel-EVM scheduler ──────────────────────────────────────────────────── +# ── Parallel-PQVM scheduler ──────────────────────────────────────────────────── # Enables conflict-graph-based parallel transaction scheduling. -# Equivalent CLI flags: --parallel-evm --parallel-evm-workers -[parallel_evm] +# Preferred CLI flags: --parallel-pqvm --parallel-pqvm-workers +# Deprecated aliases still accepted: --parallel-evm --parallel-evm-workers +[parallel_pqvm] # enabled = false # worker_threads = 4 diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 0f2f5360..b31c4bc8 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -21,7 +21,7 @@ shell-core.workspace = true shell-storage.workspace = true shell-consensus = { path = "../consensus" } shell-genesis = { path = "../genesis" } -shell-evm = { path = "../evm" } +shell-pqvm = { path = "../pqvm" } shell-mempool = { path = "../mempool" } shell-rpc = { path = "../rpc" } shell-network = { path = "../network" } diff --git a/crates/cli/src/commands/run.rs b/crates/cli/src/commands/run.rs index be14f98f..829f689c 100644 --- a/crates/cli/src/commands/run.rs +++ b/crates/cli/src/commands/run.rs @@ -62,10 +62,10 @@ pub struct RunArgs { pub mempool_price_bump: Option, /// Account LRU cache size for the world-state trie, in MiB (default: 64). pub state_cache_size_mb: Option, - /// Enable the parallel-EVM conflict-graph scheduler. - pub parallel_evm: bool, - /// Number of worker threads for the parallel-EVM scheduler (default: logical CPUs). - pub parallel_evm_workers: Option, + /// Enable the parallel-PQVM conflict-graph scheduler. + pub parallel_pqvm: bool, + /// Number of worker threads for the parallel-PQVM scheduler (default: logical CPUs). + pub parallel_pqvm_workers: Option, /// Override witness bundle retention from the storage profile. /// `0` = keep forever. Omit to use the storage profile default. pub witness_retention: Option, @@ -658,14 +658,14 @@ async fn run_with_store( }, max_idle_interval_ms: args.max_idle_interval * 1000, state_cache_size_mb: args.state_cache_size_mb.unwrap_or(64), - parallel_evm: shell_node::config::ParallelEvmConfig { - enabled: args.parallel_evm, - max_workers: args.parallel_evm_workers.unwrap_or_else(|| { + parallel_pqvm: shell_node::config::ParallelPqvmConfig { + enabled: args.parallel_pqvm, + max_workers: args.parallel_pqvm_workers.unwrap_or_else(|| { std::thread::available_parallelism() .map(usize::from) .unwrap_or(1) }), - ..shell_node::config::ParallelEvmConfig::default() + ..shell_node::config::ParallelPqvmConfig::default() }, enable_stark_aggregation: args.enable_stark_aggregation, l2_stark_mode: args @@ -840,14 +840,14 @@ mod tests { use super::*; use shell_core::BlockHeader; use shell_genesis::initialize_genesis; - use shell_node::config::ParallelEvmConfig; + use shell_node::config::ParallelPqvmConfig; use shell_primitives::{Bytes, U256}; use shell_storage::{MemoryDb, DEFAULT_BODY_RETENTION, DEFAULT_WITNESS_RETENTION}; use std::collections::HashMap; - /// Verify that `--parallel-evm --parallel-evm-workers 4` produces the correct config. + /// Verify that `--parallel-pqvm --parallel-pqvm-workers 4` produces the correct config. #[test] - fn parallel_evm_args_produce_correct_config() { + fn parallel_pqvm_args_produce_correct_config() { let args = RunArgs { datadir: std::path::PathBuf::from("shell-data"), rpc_addr: "127.0.0.1:8545".into(), @@ -875,8 +875,8 @@ mod tests { mempool_max_size: None, mempool_price_bump: None, state_cache_size_mb: None, - parallel_evm: true, - parallel_evm_workers: Some(4), + parallel_pqvm: true, + parallel_pqvm_workers: Some(4), witness_retention: Some(DEFAULT_WITNESS_RETENTION), body_retention: Some(DEFAULT_BODY_RETENTION), storage_profile: "full".into(), @@ -892,16 +892,16 @@ mod tests { }, }; - let expected = ParallelEvmConfig { - enabled: args.parallel_evm, - max_workers: args.parallel_evm_workers.unwrap(), - ..ParallelEvmConfig::default() + let expected = ParallelPqvmConfig { + enabled: args.parallel_pqvm, + max_workers: args.parallel_pqvm_workers.unwrap(), + ..ParallelPqvmConfig::default() }; - assert!(expected.enabled, "--parallel-evm must set enabled = true"); + assert!(expected.enabled, "--parallel-pqvm must set enabled = true"); assert_eq!( expected.max_workers, 4, - "--parallel-evm-workers 4 must set max_workers = 4" + "--parallel-pqvm-workers 4 must set max_workers = 4" ); } diff --git a/crates/cli/src/config.rs b/crates/cli/src/config.rs index 43770f96..1b407377 100644 --- a/crates/cli/src/config.rs +++ b/crates/cli/src/config.rs @@ -15,7 +15,8 @@ pub struct ShellConfig { pub consensus: ConsensusSection, pub metrics: MetricsSection, pub logging: LoggingSection, - pub parallel_evm: ParallelEvmSection, + #[serde(alias = "parallel_evm")] + pub parallel_pqvm: ParallelPqvmSection, } #[derive(Debug, Default, Deserialize)] @@ -72,10 +73,10 @@ pub struct LoggingSection { pub format: Option, } -/// Parallel-EVM scheduling configuration. +/// Parallel-PQVM scheduling configuration. #[derive(Debug, Default, Deserialize)] #[serde(default)] -pub struct ParallelEvmSection { +pub struct ParallelPqvmSection { /// Enable conflict-graph scheduling. pub enabled: Option, /// Maximum worker threads for parallelizable waves. diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index da43347a..cf437204 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -192,13 +192,13 @@ enum Commands { #[arg(long)] state_cache_size_mb: Option, - /// Enable the parallel-EVM conflict-graph scheduler. - #[arg(long)] - parallel_evm: bool, + /// Enable the parallel-PQVM conflict-graph scheduler. + #[arg(long, alias = "parallel-evm")] + parallel_pqvm: bool, - /// Worker threads for the parallel-EVM scheduler (default: logical CPUs). - #[arg(long)] - parallel_evm_workers: Option, + /// Worker threads for the parallel-PQVM scheduler (default: logical CPUs). + #[arg(long, alias = "parallel-evm-workers")] + parallel_pqvm_workers: Option, /// High-level storage classification for this node. /// @@ -487,8 +487,8 @@ async fn main() { mempool_max_size, mempool_price_bump, state_cache_size_mb, - parallel_evm, - parallel_evm_workers, + parallel_pqvm, + parallel_pqvm_workers, storage_profile, witness_retention, body_retention, @@ -609,10 +609,10 @@ async fn main() { .or(file_config.metrics.listen_addr) .unwrap_or_else(|| "127.0.0.1:9090".to_string()); - let effective_parallel_evm = - parallel_evm || file_config.parallel_evm.enabled.unwrap_or(false); - let effective_parallel_evm_workers = - parallel_evm_workers.or(file_config.parallel_evm.worker_threads); + let effective_parallel_pqvm = + parallel_pqvm || file_config.parallel_pqvm.enabled.unwrap_or(false); + let effective_parallel_pqvm_workers = + parallel_pqvm_workers.or(file_config.parallel_pqvm.worker_threads); commands::run(commands::run::RunArgs { datadir, @@ -642,8 +642,8 @@ async fn main() { mempool_max_size, mempool_price_bump, state_cache_size_mb, - parallel_evm: effective_parallel_evm, - parallel_evm_workers: effective_parallel_evm_workers, + parallel_pqvm: effective_parallel_pqvm, + parallel_pqvm_workers: effective_parallel_pqvm_workers, storage_profile, witness_retention, body_retention, diff --git a/crates/mempool/Cargo.toml b/crates/mempool/Cargo.toml index e2a1b44e..25d1beb3 100644 --- a/crates/mempool/Cargo.toml +++ b/crates/mempool/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace = true shell-primitives.workspace = true shell-crypto.workspace = true shell-core.workspace = true -shell-evm = { path = "../evm" } +shell-pqvm = { path = "../pqvm" } shell-storage = { path = "../storage" } thiserror.workspace = true parking_lot = { workspace = true } diff --git a/crates/mempool/src/pool.rs b/crates/mempool/src/pool.rs index f10a9305..9adbe9f3 100644 --- a/crates/mempool/src/pool.rs +++ b/crates/mempool/src/pool.rs @@ -6,7 +6,7 @@ use parking_lot::RwLock; use shell_core::SignedTransaction; use shell_crypto::Verifier; -use shell_evm::{ +use shell_pqvm::{ compute_intrinsic_gas, validate_aa_bundle_structure, validate_aa_tx, AaValidationError, AaValidationOutcome, TxValidationError, }; diff --git a/crates/node/Cargo.toml b/crates/node/Cargo.toml index 9a4a5c68..adaf6558 100644 --- a/crates/node/Cargo.toml +++ b/crates/node/Cargo.toml @@ -13,7 +13,7 @@ shell-storage.workspace = true shell-genesis = { path = "../genesis" } shell-stark-prover = { path = "../stark-prover" } shell-consensus = { path = "../consensus" } -shell-evm = { path = "../evm" } +shell-pqvm = { path = "../pqvm" } shell-mempool = { path = "../mempool" } shell-rpc = { path = "../rpc" } shell-network = { path = "../network" } diff --git a/crates/node/src/config.rs b/crates/node/src/config.rs index c0e483d3..cda3b896 100644 --- a/crates/node/src/config.rs +++ b/crates/node/src/config.rs @@ -3,10 +3,10 @@ use std::net::SocketAddr; use shell_consensus::{PoaConfig, WPoaConfig}; -pub use shell_evm::ParallelEvmConfig; use shell_genesis::NetworkType; use shell_mempool::MempoolConfig; use shell_network::NetworkConfig; +pub use shell_pqvm::ParallelPqvmConfig; use shell_primitives::Address; use shell_rpc::RpcConfig; @@ -228,8 +228,8 @@ pub struct NodeConfig { /// Account cache size in MiB for the world state LRU trie cache. /// Default: 64 MiB. Higher values reduce state trie decode overhead. pub state_cache_size_mb: usize, - /// Parallel-EVM PoC configuration. Disabled by default until promoted. - pub parallel_evm: ParallelEvmConfig, + /// Parallel-PQVM PoC configuration. Disabled by default until promoted. + pub parallel_pqvm: ParallelPqvmConfig, /// Enable STARK aggregate proof generation during block production. /// When true, `produce_block` calls `prove_sig_batch()` over all transaction /// entries and stores the result in `BlockHeader::sig_aggregate_proof`. @@ -294,7 +294,7 @@ impl NodeConfig { metrics: MetricsConfig::default(), max_idle_interval_ms: 600_000, state_cache_size_mb: 64, - parallel_evm: ParallelEvmConfig::default(), + parallel_pqvm: ParallelPqvmConfig::default(), enable_stark_aggregation: params.stark_aggregation, l2_stark_mode: L2StarkMode::Disabled, node_role: NodeRole::default(), diff --git a/crates/node/src/error.rs b/crates/node/src/error.rs index c1a9bca8..6f0843da 100644 --- a/crates/node/src/error.rs +++ b/crates/node/src/error.rs @@ -10,8 +10,8 @@ pub enum NodeError { #[error("consensus error: {0}")] Consensus(#[from] shell_consensus::ConsensusError), - #[error("evm error: {0}")] - Evm(#[from] shell_evm::ExecutorError), + #[error("pqvm error: {0}")] + Pqvm(#[from] shell_pqvm::ExecutorError), #[error("network error: {0}")] Network(#[from] shell_network::NetworkError), diff --git a/crates/node/src/node/block_importer.rs b/crates/node/src/node/block_importer.rs index 216123da..0394068b 100644 --- a/crates/node/src/node/block_importer.rs +++ b/crates/node/src/node/block_importer.rs @@ -347,7 +347,7 @@ impl Node { } let (state_db, _) = block_store.isolated_state_db()?; - let mut evm = ShellEvm::new(state_db, self.config.chain_id); + let mut evm = ShellPqvm::new(state_db, self.config.chain_id); // Non-signature validation (chain-id, gas, sender binding). // Uses PreVerified to skip redundant individual @@ -426,7 +426,7 @@ impl Node { &result.system_contract_effects, )?; } else { - commit_evm_state( + commit_pqvm_state( &result, evm.state_db_mut().world_state_mut(), &self.chain_store, diff --git a/crates/node/src/node/block_producer.rs b/crates/node/src/node/block_producer.rs index eef4e428..94adee90 100644 --- a/crates/node/src/node/block_producer.rs +++ b/crates/node/src/node/block_producer.rs @@ -34,7 +34,7 @@ impl Node { // Create an isolated EVM instance at the current state root. let (state_db, current_root) = block_store.isolated_state_db()?; - let mut evm = ShellEvm::new(state_db, self.config.chain_id); + let mut evm = ShellPqvm::new(state_db, self.config.chain_id); let now = self.current_block_timestamp(head.header.timestamp); @@ -127,8 +127,8 @@ impl Node { &result.system_contract_effects, )?; } else { - // Normal EVM tx: commit EvmState changeset. - commit_evm_state( + // Normal PQVM tx: commit the revm state changeset. + commit_pqvm_state( &result, evm.state_db_mut().world_state_mut(), &self.chain_store, @@ -137,7 +137,7 @@ impl Node { // Commit to the node's persistent WorldState. { let mut ws = self.world_state.write(); - commit_evm_state(&result, &mut ws, &self.chain_store)?; + commit_pqvm_state(&result, &mut ws, &self.chain_store)?; } } total_effective_fees = total_effective_fees.saturating_add( @@ -273,17 +273,17 @@ impl Node { // Compute block-level logs bloom by OR-ing all receipt blooms. { - let receipt_blooms: Vec = receipts + let receipt_blooms: Vec = receipts .iter() .map(|r| { - let mut bloom = [0u8; shell_evm::bloom::BLOOM_SIZE]; + let mut bloom = [0u8; shell_pqvm::bloom::BLOOM_SIZE]; let bytes = r.logs_bloom.as_ref(); - let len = bytes.len().min(shell_evm::bloom::BLOOM_SIZE); + let len = bytes.len().min(shell_pqvm::bloom::BLOOM_SIZE); bloom[..len].copy_from_slice(&bytes[..len]); bloom }) .collect(); - let block_bloom = shell_evm::bloom::bloom_union(&receipt_blooms); + let block_bloom = shell_pqvm::bloom::bloom_union(&receipt_blooms); header.logs_bloom = Bytes::from(block_bloom.to_vec()); } diff --git a/crates/node/src/node/mod.rs b/crates/node/src/node/mod.rs index e94a78f3..a9a1ec4e 100644 --- a/crates/node/src/node/mod.rs +++ b/crates/node/src/node/mod.rs @@ -33,9 +33,9 @@ pub(crate) use shell_core::{ pub(crate) use shell_crypto::{ BatchVerifier, MultiVerifier, PreVerified, Signer, Verifier, VerifyItem, }; -pub(crate) use shell_evm::{commit_evm_state, validate_tx_for_import, ShellEvm, ShellStateDb}; pub(crate) use shell_mempool::TxPool; pub(crate) use shell_network::{NetworkMessage, NetworkService}; +pub(crate) use shell_pqvm::{commit_pqvm_state, validate_tx_for_import, ShellPqvm, ShellStateDb}; pub(crate) use shell_primitives::{Address, Bytes, ShellHash, U256}; pub(crate) use shell_rpc::DevRpcControl; pub(crate) use shell_storage::{ @@ -833,7 +833,7 @@ impl Node { fn sync_system_contract_state( &self, local_ws: &mut WorldState, - effects: &shell_evm::SystemContractEffects, + effects: &shell_pqvm::SystemContractEffects, ) -> Result<(), NodeError> { let registry_account = if effects.validator_set_changed { let validators = local_ws.get_validators()?; @@ -3123,9 +3123,9 @@ mod tests { let tx = Transaction { chain_id: 1337, nonce: 0, - to: Some(shell_evm::account_manager_address()), + to: Some(shell_pqvm::account_manager_address()), value: U256::ZERO, - data: shell_primitives::Bytes::from(shell_evm::encode_rotate_key_calldata( + data: shell_primitives::Bytes::from(shell_pqvm::encode_rotate_key_calldata( &new_pubkey, tx_signer.sig_type().as_u8(), )), @@ -3172,7 +3172,7 @@ mod tests { assert_eq!( account.balance, initial_balance - - U256::from(shell_evm::SYSTEM_CALL_BASE_GAS + shell_evm::SYSTEM_CALL_OP_GAS) + - U256::from(shell_pqvm::SYSTEM_CALL_BASE_GAS + shell_pqvm::SYSTEM_CALL_OP_GAS) * U256::from(shell_core::INITIAL_BASE_FEE) ); assert_eq!( @@ -3462,9 +3462,9 @@ mod tests { let add_tx = Transaction { chain_id: 1337, nonce: 0, - to: Some(shell_evm::registry_address()), + to: Some(shell_pqvm::registry_address()), value: U256::ZERO, - data: Bytes::copy_from_slice(&shell_evm::encode_add_validator_calldata(&target)), + data: Bytes::copy_from_slice(&shell_pqvm::encode_add_validator_calldata(&target)), gas_limit: 100_000, max_fee_per_gas: shell_core::INITIAL_BASE_FEE, max_priority_fee_per_gas: 0, diff --git a/crates/evm/Cargo.toml b/crates/pqvm/Cargo.toml similarity index 97% rename from crates/evm/Cargo.toml rename to crates/pqvm/Cargo.toml index 85a9b2dd..075d4bb6 100644 --- a/crates/evm/Cargo.toml +++ b/crates/pqvm/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "shell-evm" +name = "shell-pqvm" version.workspace = true edition.workspace = true license.workspace = true diff --git a/crates/evm/benches/parallel_bench.rs b/crates/pqvm/benches/parallel_bench.rs similarity index 91% rename from crates/evm/benches/parallel_bench.rs rename to crates/pqvm/benches/parallel_bench.rs index 185e080c..443acb8b 100644 --- a/crates/evm/benches/parallel_bench.rs +++ b/crates/pqvm/benches/parallel_bench.rs @@ -1,12 +1,12 @@ -//! Benchmarks for the parallel-EVM scheduling and rwset layer. +//! Benchmarks for the parallel-PQVM scheduling and rwset layer. //! //! These benchmarks exercise the conflict-graph and wave-planning paths using -//! mock transactions — no real EVM execution is required. +//! mock transactions — no real PQVM execution is required. use criterion::{black_box, criterion_group, criterion_main, Criterion}; use shell_core::{SignedTransaction, Transaction}; use shell_crypto::{PQSignature, SignatureType}; -use shell_evm::{HeuristicRwSetExtractor, ParallelEvmConfig, ParallelScheduler}; +use shell_pqvm::{HeuristicRwSetExtractor, ParallelPqvmConfig, ParallelScheduler}; use shell_primitives::{Address, Bytes, U256}; fn make_tx(nonce: u64, to: Address) -> SignedTransaction { @@ -33,7 +33,7 @@ fn make_tx(nonce: u64, to: Address) -> SignedTransaction { } fn scheduler() -> ParallelScheduler { - ParallelScheduler::new(ParallelEvmConfig { + ParallelScheduler::new(ParallelPqvmConfig { enabled: true, max_workers: 4, fallback_on_incomplete: true, diff --git a/crates/evm/benches/parallel_poc.rs b/crates/pqvm/benches/parallel_poc.rs similarity index 94% rename from crates/evm/benches/parallel_poc.rs rename to crates/pqvm/benches/parallel_poc.rs index c6775ca9..56bf8cf2 100644 --- a/crates/evm/benches/parallel_poc.rs +++ b/crates/pqvm/benches/parallel_poc.rs @@ -1,11 +1,11 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; use shell_core::{SignedTransaction, Transaction}; use shell_crypto::{PQSignature, SignatureType}; -use shell_evm::{HeuristicRwSetExtractor, ParallelEvmConfig, ParallelScheduler}; +use shell_pqvm::{HeuristicRwSetExtractor, ParallelPqvmConfig, ParallelScheduler}; use shell_primitives::{Address, Bytes, U256}; fn bench_parallel_poc(c: &mut Criterion) { - let scheduler = ParallelScheduler::new(ParallelEvmConfig { + let scheduler = ParallelScheduler::new(ParallelPqvmConfig { enabled: true, max_workers: 4, fallback_on_incomplete: true, diff --git a/crates/evm/benches/evm_bench.rs b/crates/pqvm/benches/pqvm_bench.rs similarity index 93% rename from crates/evm/benches/evm_bench.rs rename to crates/pqvm/benches/pqvm_bench.rs index 476c2233..868caf37 100644 --- a/crates/evm/benches/evm_bench.rs +++ b/crates/pqvm/benches/pqvm_bench.rs @@ -1,19 +1,19 @@ -//! Benchmarks for shell-evm: transfer, contract creation. +//! Benchmarks for shell-pqvm: transfer, contract creation. use criterion::{black_box, criterion_group, criterion_main, Criterion}; use std::sync::Arc; use shell_core::{Account, BlockHeader, SignedTransaction, Transaction}; use shell_crypto::{PQSignature, SignatureType}; -use shell_evm::{ShellEvm, ShellStateDb}; +use shell_pqvm::{ShellPqvm, ShellStateDb}; use shell_primitives::{Address, Bytes, ShellHash, U256}; use shell_storage::{ChainStore, MemoryDb, WorldState}; -fn setup_evm() -> ShellEvm { +fn setup_evm() -> ShellPqvm { let ws = WorldState::new(Arc::new(MemoryDb::new())); let cs = ChainStore::new(Arc::new(MemoryDb::new())); let state_db = ShellStateDb::new(ws, cs); - ShellEvm::new(state_db, 1337) + ShellPqvm::new(state_db, 1337) } fn sample_header() -> BlockHeader { @@ -39,7 +39,7 @@ fn sample_header() -> BlockHeader { } } -fn fund_account(evm: &mut ShellEvm, addr: &Address, balance: U256) { +fn fund_account(evm: &mut ShellPqvm, addr: &Address, balance: U256) { let account = Account { pq_pubkey_hash: ShellHash::ZERO, nonce: 0, @@ -101,7 +101,7 @@ fn minimal_init_code() -> Vec { // ── Simple transfer ────────────────────────────────────────── fn bench_simple_transfer(c: &mut Criterion) { - c.bench_function("evm/simple_transfer", |b| { + c.bench_function("pqvm/simple_transfer", |b| { let mut evm = setup_evm(); let sender = Address::from([0x01; 20]); let receiver = Address::from([0x02; 20]); @@ -121,7 +121,7 @@ fn bench_simple_transfer(c: &mut Criterion) { // ── Contract creation ──────────────────────────────────────── fn bench_contract_creation(c: &mut Criterion) { - c.bench_function("evm/contract_creation", |b| { + c.bench_function("pqvm/contract_creation", |b| { let mut evm = setup_evm(); let deployer = Address::from([0x42; 20]); fund_account(&mut evm, &deployer, U256::from(1_000_000_000_000u64)); diff --git a/crates/evm/src/aa_validation.rs b/crates/pqvm/src/aa_validation.rs similarity index 100% rename from crates/evm/src/aa_validation.rs rename to crates/pqvm/src/aa_validation.rs diff --git a/crates/evm/src/bloom.rs b/crates/pqvm/src/bloom.rs similarity index 100% rename from crates/evm/src/bloom.rs rename to crates/pqvm/src/bloom.rs diff --git a/crates/evm/src/executor.rs b/crates/pqvm/src/executor.rs similarity index 98% rename from crates/evm/src/executor.rs rename to crates/pqvm/src/executor.rs index 03918bad..1441c102 100644 --- a/crates/evm/src/executor.rs +++ b/crates/pqvm/src/executor.rs @@ -1,6 +1,6 @@ //! PQVM/revm execution adapter: executes transactions via revm and produces receipts. //! -//! [`ShellEvm`] wraps revm with shell-chain's state bridge and +//! [`ShellPqvm`] wraps revm with shell-chain's state bridge and //! provides a high-level API for executing individual transactions and //! full blocks. @@ -30,8 +30,8 @@ use crate::system_contracts::{ /// Errors returned during PQVM/revm execution. #[derive(Debug, thiserror::Error)] pub enum ExecutorError { - #[error("evm: {0}")] - Evm(String), + #[error("pqvm/revm: {0}")] + Revm(String), #[error("state db: {0}")] StateDb(#[from] StateDbError), @@ -50,11 +50,11 @@ pub struct TxExecutionResult { /// State changes produced by this transaction (for committing). pub state_changes: EvmState, /// Maps 20-byte revm bridge address → full 32-byte PQ Shell address for accounts - /// whose upper 12 bytes are non-zero. Required by `commit_evm_state` to + /// whose upper 12 bytes are non-zero. Required by `commit_pqvm_state` to /// write state to the correct canonical key in world_state. pub pq_addr_map: std::collections::HashMap, /// The sender's nonce after this transaction (= tx.nonce + 1). Used by - /// `commit_evm_state` to ensure the nonce is always advanced correctly even + /// `commit_pqvm_state` to ensure the nonce is always advanced correctly even /// when revm's `disable_nonce_check = true` suppresses the normal increment. pub sender_shell_addr: ShellAddress, /// Expected nonce of `sender_shell_addr` after tx (= tx.nonce + 1). @@ -75,7 +75,7 @@ pub struct TxExecutionResult { /// Wraps revm and provides: /// - `execute_tx()`: execute a single validated transaction → receipt + state /// - Block-level gas tracking for cumulative_gas_used -pub struct ShellEvm { +pub struct ShellPqvm { state_db: ShellStateDb, chain_id: u64, } @@ -101,7 +101,7 @@ where ); } -impl ShellEvm { +impl ShellPqvm { pub fn new(state_db: ShellStateDb, chain_id: u64) -> Self { Self { state_db, chain_id } } @@ -153,7 +153,7 @@ impl ShellEvm { } } - // ── Normal EVM execution path ────────────────────────── + // ── Normal PQVM/revm execution path ────────────────────────── let tx = &signed_tx.tx; let sender_shell_addr = signed_tx.from; let sender_nonce_after = tx.nonce.saturating_add(1); @@ -222,12 +222,12 @@ impl ShellEvm { // Execute let result_and_state = evm .transact(tx_env) - .map_err(|e| ExecutorError::Evm(format!("{e:?}")))?; + .map_err(|e| ExecutorError::Revm(format!("{e:?}")))?; let exec_result = result_and_state.result; let state = result_and_state.state; - // Capture PQ address hints for commit_evm_state so it writes to the + // Capture PQ address hints for commit_pqvm_state so it writes to the // canonical Shell address rather than the zero-padded EVM address. let pq_addr_map = self.state_db.pq_hints.clone(); @@ -335,7 +335,7 @@ impl ShellEvm { ) -> Result { let bundle = signed_tx .aa_bundle() - .ok_or_else(|| ExecutorError::Evm("execute_aa_bundle called on non-AA tx".into()))?; + .ok_or_else(|| ExecutorError::Revm("execute_aa_bundle called on non-AA tx".into()))?; let tx = &signed_tx.tx; let sender = signed_tx.from; let payer = bundle.paymaster.unwrap_or(sender); @@ -344,7 +344,7 @@ impl ShellEvm { let declared_value = tx.value; let inner_value_sum = bundle.inner_value_sum(); if inner_value_sum > declared_value { - return Err(ExecutorError::Evm(format!( + return Err(ExecutorError::Revm(format!( "aa bundle inner value sum ({inner_value_sum}) exceeds outer value ({declared_value})" ))); } @@ -484,7 +484,7 @@ impl ShellEvm { successful_values_sum = successful_values_sum.saturating_add(inner.value); let cs_arc = std::sync::Arc::clone(self.state_db.chain_store().store()); let cs_view = ChainStore::new(cs_arc); - // Build a minimal result for commit_evm_state; no PQ addresses in AA + // Build a minimal result for commit_pqvm_state; no PQ addresses in AA // inner calls (they use EVM-canonical addresses), no nonce advance here // as outer tx handles it. let inner_result = TxExecutionResult { @@ -498,7 +498,7 @@ impl ShellEvm { is_system_tx: false, system_contract_effects: SystemContractEffects::default(), }; - commit_evm_state(&inner_result, self.state_db.world_state_mut(), &cs_view)?; + commit_pqvm_state(&inner_result, self.state_db.world_state_mut(), &cs_view)?; } ExecutionResult::Revert { output, .. } => { atomic_failure = true; @@ -823,14 +823,14 @@ fn empty_receipt() -> TransactionReceipt { /// Iterates the revm `EvmState` (address → account) and for each touched /// account, updates balance, nonce, contract code, and storage slots. /// -/// Call this after `ShellEvm::execute_tx()` to persist the computed state +/// Call this after `ShellPqvm::execute_tx()` to persist the computed state /// diff. For multi-transaction blocks, call after **each** transaction so /// subsequent transactions see prior state updates. /// /// Uses `result.pq_addr_map` to write PQ-derived accounts to the correct /// 32-byte canonical key, and `result.sender_nonce_after` to ensure the /// sender's nonce advances even when revm's `disable_nonce_check = true`. -pub fn commit_evm_state( +pub fn commit_pqvm_state( result: &TxExecutionResult, world_state: &mut WorldState, chain_store: &ChainStore, @@ -907,11 +907,11 @@ mod tests { use shell_storage::{ChainStore, MemoryDb, WorldState}; use std::sync::Arc; - fn setup_evm() -> ShellEvm { + fn setup_evm() -> ShellPqvm { let ws = WorldState::new(Arc::new(MemoryDb::new())); let cs = ChainStore::new(Arc::new(MemoryDb::new())); let state_db = ShellStateDb::new(ws, cs); - ShellEvm::new(state_db, 1337) + ShellPqvm::new(state_db, 1337) } fn sample_header() -> BlockHeader { @@ -937,7 +937,7 @@ mod tests { } } - fn fund_account(evm: &mut ShellEvm, addr: &ShellAddress, balance: U256) { + fn fund_account(evm: &mut ShellPqvm, addr: &ShellAddress, balance: U256) { let account = Account { pq_pubkey_hash: ShellHash::ZERO, nonce: 0, @@ -1452,7 +1452,7 @@ mod tests { // ── Helpers for advanced EVM tests ──────────────────────── - fn commit_state(evm: &mut ShellEvm, state: &EvmState) { + fn commit_state(evm: &mut ShellPqvm, state: &EvmState) { let (ws, cs) = evm.state_db_mut().world_state_and_chain_store(); let fake_result = TxExecutionResult { receipt: empty_receipt(), @@ -1465,11 +1465,11 @@ mod tests { is_system_tx: false, system_contract_effects: SystemContractEffects::default(), }; - commit_evm_state(&fake_result, ws, cs).unwrap(); + commit_pqvm_state(&fake_result, ws, cs).unwrap(); } fn deploy_contract( - evm: &mut ShellEvm, + evm: &mut ShellPqvm, from: &ShellAddress, init_code: Vec, value: U256, @@ -1499,7 +1499,7 @@ mod tests { } fn call_contract( - evm: &mut ShellEvm, + evm: &mut ShellPqvm, from: &ShellAddress, to: &ShellAddress, calldata: Vec, @@ -3490,7 +3490,7 @@ mod tests { .unwrap() } - fn get_balance(evm: &mut ShellEvm, addr: &ShellAddress) -> U256 { + fn get_balance(evm: &mut ShellPqvm, addr: &ShellAddress) -> U256 { evm.state_db_mut() .world_state_mut() .get_account(addr) @@ -3499,7 +3499,7 @@ mod tests { .unwrap_or(U256::ZERO) } - fn get_nonce(evm: &mut ShellEvm, addr: &ShellAddress) -> u64 { + fn get_nonce(evm: &mut ShellPqvm, addr: &ShellAddress) -> u64 { evm.state_db_mut() .world_state_mut() .get_account(addr) @@ -3691,7 +3691,9 @@ mod tests { let header = sample_header(); let res = evm.execute_aa_bundle(&signed, &header, 0, 0); - assert!(matches!(res, Err(ExecutorError::Evm(msg)) if msg.contains("exceeds outer value"))); + assert!( + matches!(res, Err(ExecutorError::Revm(msg)) if msg.contains("exceeds outer value")) + ); assert_eq!(get_balance(&mut evm, &dst), U256::ZERO); assert_eq!(get_nonce(&mut evm, &sender), 0); } diff --git a/crates/evm/src/lib.rs b/crates/pqvm/src/lib.rs similarity index 87% rename from crates/evm/src/lib.rs rename to crates/pqvm/src/lib.rs index 926fd3da..01a6db3e 100644 --- a/crates/evm/src/lib.rs +++ b/crates/pqvm/src/lib.rs @@ -1,10 +1,10 @@ -//! Shell-chain EVM integration layer. +//! Shell-chain PQVM execution layer. //! //! This crate bridges the shell-chain storage layer (WorldState + ChainStore) //! with revm, providing: //! //! - [`ShellStateDb`]: implements `revm::Database` over WorldState + ChainStore -//! - [`ShellEvm`]: transaction executor (Shanghai spec) +//! - [`ShellPqvm`]: transaction executor backed by retained Cancun-style semantics //! - [`ShellPrecompiles`]: PQ precompile provider (6-precompile suite at 0x0001-0x0006) //! - [`pqvm_opcodes`]: Native PQ opcodes (0xB0 PQVERIFY, 0xB1 PQHASH, 0xB2 PQADDR) //! - [`validate_tx`]: PQ signature verification + hybrid pubkey registration @@ -24,9 +24,9 @@ mod tx_validation; pub use aa_validation::{ validate_aa_tx, AaValidationError, AaValidationOutcome, VALIDATION_GAS_CAP, }; -pub use executor::{commit_evm_state, ExecutorError, ShellEvm, TxExecutionResult}; +pub use executor::{commit_pqvm_state, ExecutorError, ShellPqvm, TxExecutionResult}; pub use parallel::{ - ConflictMetric, ConflictReason, ExecutionWave, ParallelEvmConfig, ParallelExecutionPlan, + ConflictMetric, ConflictReason, ExecutionWave, ParallelExecutionPlan, ParallelPqvmConfig, ParallelScheduler, TxConflict, TxConflictGraph, }; pub use pqvm_opcodes::{OPCODE_PQADDR, OPCODE_PQHASH, OPCODE_PQVERIFY}; diff --git a/crates/evm/src/parallel.rs b/crates/pqvm/src/parallel.rs similarity index 95% rename from crates/evm/src/parallel.rs rename to crates/pqvm/src/parallel.rs index 4b9f6d46..3ee0928b 100644 --- a/crates/evm/src/parallel.rs +++ b/crates/pqvm/src/parallel.rs @@ -1,8 +1,8 @@ -//! Parallel EVM PoC scheduling primitives. +//! Parallel PQVM PoC scheduling primitives. //! //! This module intentionally stays additive: it builds conflict graphs and //! execution waves from transaction read/write sets without changing the -//! production executor path. Callers can opt in via [`ParallelEvmConfig`] +//! production executor path. Callers can opt in via [`ParallelPqvmConfig`] //! and either inspect the plan or execute wave-local work with rayon. use rayon::prelude::*; @@ -10,9 +10,9 @@ use shell_core::SignedTransaction; use crate::rwset::{ReadWriteSetExtractor, TxAccessPath, TxReadWriteSet}; -/// Feature flag and scheduler knobs for the parallel-EVM PoC. +/// Feature flag and scheduler knobs for the parallel-PQVM PoC. #[derive(Debug, Clone, PartialEq, Eq)] -pub struct ParallelEvmConfig { +pub struct ParallelPqvmConfig { /// Enables conflict-graph scheduling. pub enabled: bool, /// Maximum worker threads used for parallelizable waves. @@ -21,7 +21,7 @@ pub struct ParallelEvmConfig { pub fallback_on_incomplete: bool, } -impl Default for ParallelEvmConfig { +impl Default for ParallelPqvmConfig { fn default() -> Self { Self { enabled: false, @@ -102,18 +102,18 @@ pub struct ParallelExecutionPlan { pub fallback_serial: bool, } -/// Conflict-aware scheduler for the parallel-EVM PoC. +/// Conflict-aware scheduler for the parallel-PQVM PoC. #[derive(Debug, Clone)] pub struct ParallelScheduler { - config: ParallelEvmConfig, + config: ParallelPqvmConfig, } impl ParallelScheduler { - pub fn new(config: ParallelEvmConfig) -> Self { + pub fn new(config: ParallelPqvmConfig) -> Self { Self { config } } - pub fn config(&self) -> &ParallelEvmConfig { + pub fn config(&self) -> &ParallelPqvmConfig { &self.config } @@ -460,9 +460,9 @@ mod parallel_validation { txs.iter().map(|tx| extractor.extract(tx)).collect(); // Parallel: build graph, which extracts rwsets internally. - let scheduler_parallel = ParallelScheduler::new(ParallelEvmConfig { + let scheduler_parallel = ParallelScheduler::new(ParallelPqvmConfig { enabled: true, - ..ParallelEvmConfig::default() + ..ParallelPqvmConfig::default() }); let graph = scheduler_parallel.build_graph(&txs, &extractor); @@ -524,7 +524,7 @@ mod parallel_validation { assert!(graph.rwsets.is_empty(), "rwsets should be empty"); assert!(graph.conflicts.is_empty(), "conflicts should be empty"); - let scheduler = ParallelScheduler::new(ParallelEvmConfig::default()); + let scheduler = ParallelScheduler::new(ParallelPqvmConfig::default()); let plan = scheduler.plan_from_graph(&graph); assert!( plan.waves.is_empty(), @@ -610,9 +610,9 @@ mod tests { signed_tx(shared, 1, Vec::new()), signed_tx(shared, 2, Vec::new()), ]; - let scheduler = ParallelScheduler::new(ParallelEvmConfig { + let scheduler = ParallelScheduler::new(ParallelPqvmConfig { enabled: true, - ..ParallelEvmConfig::default() + ..ParallelPqvmConfig::default() }); let graph = scheduler.build_graph(&txs, &HeuristicRwSetExtractor); @@ -628,9 +628,9 @@ mod tests { signed_tx(Address::from([0x31; 20]), 1, Vec::new()), signed_tx(Address::from([0x32; 20]), 2, Vec::new()), ]; - let scheduler = ParallelScheduler::new(ParallelEvmConfig { + let scheduler = ParallelScheduler::new(ParallelPqvmConfig { enabled: true, - ..ParallelEvmConfig::default() + ..ParallelPqvmConfig::default() }); let (_, plan) = scheduler.plan(&txs, &HeuristicRwSetExtractor); @@ -662,10 +662,10 @@ mod tests { PQSignature::new(SignatureType::Dilithium3, vec![0x77; 32]), )]; - let scheduler = ParallelScheduler::new(ParallelEvmConfig { + let scheduler = ParallelScheduler::new(ParallelPqvmConfig { enabled: true, fallback_on_incomplete: true, - ..ParallelEvmConfig::default() + ..ParallelPqvmConfig::default() }); let (_, plan) = scheduler.plan(&txs, &HeuristicRwSetExtractor); @@ -680,10 +680,10 @@ mod tests { signed_tx(Address::from([0x51; 20]), 1, Vec::new()), signed_tx(Address::from([0x52; 20]), 2, Vec::new()), ]; - let scheduler = ParallelScheduler::new(ParallelEvmConfig { + let scheduler = ParallelScheduler::new(ParallelPqvmConfig { enabled: true, max_workers: 2, - ..ParallelEvmConfig::default() + ..ParallelPqvmConfig::default() }); let (_, plan) = scheduler.plan(&txs, &HeuristicRwSetExtractor); let outputs = scheduler @@ -703,10 +703,10 @@ mod tests { signed_tx(shared, 4, Vec::new()), signed_tx(Address::from([0x33; 20]), 5, Vec::new()), ]; - let scheduler = ParallelScheduler::new(ParallelEvmConfig { + let scheduler = ParallelScheduler::new(ParallelPqvmConfig { enabled: true, max_workers: 4, - ..ParallelEvmConfig::default() + ..ParallelPqvmConfig::default() }); let (_, plan) = scheduler.plan(&txs, &HeuristicRwSetExtractor); let outputs = scheduler @@ -746,9 +746,9 @@ mod tests { signed_tx(shared, 1, Vec::new()), signed_tx(shared, 2, Vec::new()), ]; - let scheduler = ParallelScheduler::new(ParallelEvmConfig { + let scheduler = ParallelScheduler::new(ParallelPqvmConfig { enabled: true, - ..ParallelEvmConfig::default() + ..ParallelPqvmConfig::default() }); let (graph, _, metric) = scheduler.plan_with_metrics(&txs_conflict, &HeuristicRwSetExtractor); diff --git a/crates/evm/src/pqvm_opcodes.rs b/crates/pqvm/src/pqvm_opcodes.rs similarity index 100% rename from crates/evm/src/pqvm_opcodes.rs rename to crates/pqvm/src/pqvm_opcodes.rs diff --git a/crates/evm/src/precompiles.rs b/crates/pqvm/src/precompiles.rs similarity index 100% rename from crates/evm/src/precompiles.rs rename to crates/pqvm/src/precompiles.rs diff --git a/crates/evm/src/rwset.rs b/crates/pqvm/src/rwset.rs similarity index 99% rename from crates/evm/src/rwset.rs rename to crates/pqvm/src/rwset.rs index c0f0b844..f78ec640 100644 --- a/crates/evm/src/rwset.rs +++ b/crates/pqvm/src/rwset.rs @@ -83,7 +83,7 @@ pub trait ReadWriteSetExtractor { fn extract(&self, tx: &SignedTransaction) -> TxReadWriteSet; } -/// Heuristic extractor used by the M11 parallel-EVM PoC. +/// Heuristic extractor used by the M11 parallel-PQVM PoC. #[derive(Debug, Clone, Copy, Default)] pub struct HeuristicRwSetExtractor; diff --git a/crates/evm/src/state_db.rs b/crates/pqvm/src/state_db.rs similarity index 100% rename from crates/evm/src/state_db.rs rename to crates/pqvm/src/state_db.rs diff --git a/crates/evm/src/system_contracts.rs b/crates/pqvm/src/system_contracts.rs similarity index 100% rename from crates/evm/src/system_contracts.rs rename to crates/pqvm/src/system_contracts.rs diff --git a/crates/evm/src/tracer.rs b/crates/pqvm/src/tracer.rs similarity index 99% rename from crates/evm/src/tracer.rs rename to crates/pqvm/src/tracer.rs index a218cfa5..81198379 100644 --- a/crates/evm/src/tracer.rs +++ b/crates/pqvm/src/tracer.rs @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize}; use shell_primitives::{Address, Bytes, U256}; -/// A single call frame in an EVM execution trace. +/// A single call frame in an PQVM/revm execution trace. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct CallFrame { diff --git a/crates/evm/src/tx_validation.rs b/crates/pqvm/src/tx_validation.rs similarity index 100% rename from crates/evm/src/tx_validation.rs rename to crates/pqvm/src/tx_validation.rs diff --git a/crates/evm/tests/aa_integration.rs b/crates/pqvm/tests/aa_integration.rs similarity index 99% rename from crates/evm/tests/aa_integration.rs rename to crates/pqvm/tests/aa_integration.rs index a74cc801..9452fc22 100644 --- a/crates/evm/tests/aa_integration.rs +++ b/crates/pqvm/tests/aa_integration.rs @@ -4,7 +4,7 @@ use alloy_primitives::U256; use common::{apply_tx, deploy_runtime_contract, fund_account, setup, sign_tx, CHAIN_ID}; use shell_core::{SignedTransaction, Transaction}; use shell_crypto::{DilithiumSigner, MultiVerifier, PQSignature, SignatureType, Signer}; -use shell_evm::{ +use shell_pqvm::{ account_manager_address, encode_clear_validation_code_calldata, encode_set_validation_code_calldata, validate_tx, TxValidationError, }; diff --git a/crates/evm/tests/common/mod.rs b/crates/pqvm/tests/common/mod.rs similarity index 91% rename from crates/evm/tests/common/mod.rs rename to crates/pqvm/tests/common/mod.rs index f71cb15e..43d52e58 100644 --- a/crates/evm/tests/common/mod.rs +++ b/crates/pqvm/tests/common/mod.rs @@ -1,20 +1,20 @@ use alloy_primitives::U256; use shell_core::{Account, BlockHeader, SignedTransaction, Transaction}; use shell_crypto::{Signer, Verifier}; -use shell_evm::{commit_evm_state, validate_tx, ShellEvm, ShellStateDb, TxExecutionResult}; +use shell_pqvm::{commit_pqvm_state, validate_tx, ShellPqvm, ShellStateDb, TxExecutionResult}; use shell_primitives::{Address as ShellAddress, Bytes as ShellBytes, ShellHash}; use shell_storage::{ChainStore, MemoryDb, WorldState}; use std::sync::Arc; pub const CHAIN_ID: u64 = 1337; -pub fn setup() -> (ShellEvm, ChainStore) { +pub fn setup() -> (ShellPqvm, ChainStore) { let world_state = WorldState::new(Arc::new(MemoryDb::new())); let chain_store_db = Arc::new(MemoryDb::new()); let chain_store_for_evm = ChainStore::new(chain_store_db.clone()); let chain_store_for_tests = ChainStore::new(chain_store_db); let state_db = ShellStateDb::new(world_state, chain_store_for_evm); - let evm = ShellEvm::new(state_db, CHAIN_ID); + let evm = ShellPqvm::new(state_db, CHAIN_ID); (evm, chain_store_for_tests) } @@ -41,7 +41,7 @@ pub fn sample_header(number: u64) -> BlockHeader { } } -pub fn fund_account(evm: &mut ShellEvm, addr: &ShellAddress, balance: U256) { +pub fn fund_account(evm: &mut ShellPqvm, addr: &ShellAddress, balance: U256) { let account = Account { pq_pubkey_hash: ShellHash::ZERO, nonce: 0, @@ -72,7 +72,7 @@ pub fn sign_tx( } pub fn apply_tx( - evm: &mut ShellEvm, + evm: &mut ShellPqvm, chain_store: &ChainStore, verifier: &V, signed_tx: &SignedTransaction, @@ -99,8 +99,8 @@ pub fn apply_tx( .expect("execute_tx failed"); if !result.is_system_tx { - commit_evm_state(&result, evm.state_db_mut().world_state_mut(), chain_store) - .expect("commit_evm_state failed"); + commit_pqvm_state(&result, evm.state_db_mut().world_state_mut(), chain_store) + .expect("commit_pqvm_state failed"); } result @@ -109,7 +109,7 @@ pub fn apply_tx( #[allow(dead_code)] #[allow(clippy::too_many_arguments)] pub fn deploy_runtime_contract( - evm: &mut ShellEvm, + evm: &mut ShellPqvm, chain_store: &ChainStore, verifier: &V, signer: &S, diff --git a/crates/evm/tests/integration.rs b/crates/pqvm/tests/integration.rs similarity index 95% rename from crates/evm/tests/integration.rs rename to crates/pqvm/tests/integration.rs index ce53942b..5f7d9e4b 100644 --- a/crates/evm/tests/integration.rs +++ b/crates/pqvm/tests/integration.rs @@ -1,12 +1,12 @@ //! End-to-end EVM integration tests. //! -//! These tests exercise the full pipeline: tx validation → EVM execution → receipt, +//! These tests exercise the full pipeline: tx validation → PQVM execution → receipt, //! using real Dilithium3 signatures and the Shell PQ precompile suite (0x0001–0x0006). use alloy_primitives::U256; use shell_core::{Account, BlockHeader, SignedTransaction, Transaction}; use shell_crypto::{DilithiumSigner, DilithiumVerifier, PQSignature, SignatureType, Signer}; -use shell_evm::{validate_tx, ShellEvm, ShellStateDb, TxValidationError}; +use shell_pqvm::{validate_tx, ShellPqvm, ShellStateDb, TxValidationError}; use shell_primitives::{Address as ShellAddress, Bytes as ShellBytes, ShellHash}; use shell_storage::{ChainStore, MemoryDb, WorldState}; use std::sync::Arc; @@ -15,13 +15,13 @@ use std::sync::Arc; const CHAIN_ID: u64 = 1337; -fn setup() -> (ShellEvm, ChainStore) { +fn setup() -> (ShellPqvm, ChainStore) { let ws = WorldState::new(Arc::new(MemoryDb::new())); let cs_db = Arc::new(MemoryDb::new()); let cs_for_evm = ChainStore::new(cs_db.clone()); let cs_for_test = ChainStore::new(cs_db); let state_db = ShellStateDb::new(ws, cs_for_evm); - let evm = ShellEvm::new(state_db, CHAIN_ID); + let evm = ShellPqvm::new(state_db, CHAIN_ID); (evm, cs_for_test) } @@ -48,7 +48,7 @@ fn sample_header(number: u64) -> BlockHeader { } } -fn fund_account(evm: &mut ShellEvm, addr: &ShellAddress, balance: U256) { +fn fund_account(evm: &mut ShellPqvm, addr: &ShellAddress, balance: U256) { let account = Account { pq_pubkey_hash: ShellHash::ZERO, nonce: 0, @@ -261,9 +261,9 @@ fn e2e_hybrid_pubkey_second_tx_from_registry() { let r1 = evm.execute_tx(&signed1, &header, 0, 0).unwrap(); assert_eq!(r1.receipt.status, 1); - // Commit the nonce change from execution using commit_evm_state so PQ + // Commit the nonce change from execution using commit_pqvm_state so PQ // addresses are correctly resolved via the pq_addr_map. - shell_evm::commit_evm_state(&r1, evm.state_db_mut().world_state_mut(), &cs) + shell_pqvm::commit_pqvm_state(&r1, evm.state_db_mut().world_state_mut(), &cs) .expect("commit r1 failed"); // Second tx: NO pubkey attached — should read from registry @@ -306,7 +306,7 @@ fn e2e_hybrid_pubkey_second_tx_from_registry() { fn e2e_precompile_addresses() { use alloy_primitives::address; use revm::primitives::hardfork::SpecId; - use shell_evm::ShellPrecompiles; + use shell_pqvm::ShellPrecompiles; let sp = ShellPrecompiles::new(SpecId::CANCUN); diff --git a/crates/evm/tests/key_rotation.rs b/crates/pqvm/tests/key_rotation.rs similarity index 99% rename from crates/evm/tests/key_rotation.rs rename to crates/pqvm/tests/key_rotation.rs index bb260937..86e78010 100644 --- a/crates/evm/tests/key_rotation.rs +++ b/crates/pqvm/tests/key_rotation.rs @@ -4,7 +4,7 @@ use alloy_primitives::U256; use common::{apply_tx, fund_account, setup, sign_tx, CHAIN_ID}; use shell_core::Transaction; use shell_crypto::{DilithiumSigner, MultiVerifier, Signer, SphincsSigner}; -use shell_evm::{ +use shell_pqvm::{ account_manager_address, encode_rotate_key_calldata, validate_tx, TxValidationError, }; use shell_primitives::{blake3_hash, Address as ShellAddress, Bytes as ShellBytes}; diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml index 7bed9242..cfdf9d5c 100644 --- a/crates/rpc/Cargo.toml +++ b/crates/rpc/Cargo.toml @@ -12,7 +12,7 @@ shell-core.workspace = true shell-storage.workspace = true shell-stark-prover = { path = "../stark-prover" } shell-mempool = { path = "../mempool" } -shell-evm = { path = "../evm" } +shell-pqvm = { path = "../pqvm" } shell-consensus = { path = "../consensus" } jsonrpsee.workspace = true tokio.workspace = true diff --git a/crates/rpc/src/api.rs b/crates/rpc/src/api.rs index efbe2262..8411e69a 100644 --- a/crates/rpc/src/api.rs +++ b/crates/rpc/src/api.rs @@ -284,8 +284,11 @@ pub trait TraceApi { } /// Hardhat/Foundry-compatible dev RPCs. +/// +/// The `evm` namespace name is retained as an Ethereum tooling compatibility +/// surface; it is not the Shell-Chain execution model name. #[rpc(server, namespace = "evm")] -pub trait EvmApi { +pub trait LegacyEvmApi { /// Mine one or more blocks immediately. #[method(name = "mine")] async fn mine( diff --git a/crates/rpc/src/filter.rs b/crates/rpc/src/filter.rs index d04e93b8..2a7eb55f 100644 --- a/crates/rpc/src/filter.rs +++ b/crates/rpc/src/filter.rs @@ -1,7 +1,7 @@ //! Log filter for `eth_getLogs` — supports address, topic, and bloom-based filtering. use serde::Deserialize; -use shell_evm::bloom::{bloom_contains, Bloom, BLOOM_SIZE}; +use shell_pqvm::bloom::{bloom_contains, Bloom, BLOOM_SIZE}; use shell_primitives::{Address, ShellHash}; /// Maximum number of blocks that can be queried in a single `eth_getLogs` call. @@ -215,7 +215,7 @@ impl RawLogFilter { #[cfg(test)] mod tests { use super::*; - use shell_evm::bloom::logs_bloom; + use shell_pqvm::bloom::logs_bloom; use shell_primitives::Bytes; fn make_log(addr: Address, topics: Vec, data: &[u8]) -> shell_core::Log { diff --git a/crates/rpc/src/handler/evm.rs b/crates/rpc/src/handler/evm.rs index cf566894..e5670698 100644 --- a/crates/rpc/src/handler/evm.rs +++ b/crates/rpc/src/handler/evm.rs @@ -1,13 +1,12 @@ use super::*; #[jsonrpsee::core::async_trait] -impl EvmApiServer for RpcHandler { +impl LegacyEvmApiServer for RpcHandler { async fn mine(&self, blocks: Option) -> Result { let count = blocks.unwrap_or(1).max(1); - let dev = self - .dev_control - .as_ref() - .ok_or_else(|| feature_not_enabled("evm namespace not enabled on this node"))?; + let dev = self.dev_control.as_ref().ok_or_else(|| { + feature_not_enabled("legacy evm dev namespace not enabled on this node") + })?; dev.mine_blocks(count).map_err(internal_err)?; Ok(serde_json::json!({ "blocksMined": hex_u64(count), @@ -18,10 +17,9 @@ impl EvmApiServer for RpcHandler { &self, timestamp: u64, ) -> Result { - let dev = self - .dev_control - .as_ref() - .ok_or_else(|| feature_not_enabled("evm namespace not enabled on this node"))?; + let dev = self.dev_control.as_ref().ok_or_else(|| { + feature_not_enabled("legacy evm dev namespace not enabled on this node") + })?; let applied = dev .set_next_block_timestamp(timestamp) .map_err(internal_err)?; @@ -29,27 +27,24 @@ impl EvmApiServer for RpcHandler { } async fn increase_time(&self, seconds: u64) -> Result { - let dev = self - .dev_control - .as_ref() - .ok_or_else(|| feature_not_enabled("evm namespace not enabled on this node"))?; + let dev = self.dev_control.as_ref().ok_or_else(|| { + feature_not_enabled("legacy evm dev namespace not enabled on this node") + })?; let total = dev.increase_time(seconds).map_err(internal_err)?; Ok(serde_json::json!(hex_u64(total))) } async fn snapshot(&self) -> Result { - let dev = self - .dev_control - .as_ref() - .ok_or_else(|| feature_not_enabled("evm namespace not enabled on this node"))?; + let dev = self.dev_control.as_ref().ok_or_else(|| { + feature_not_enabled("legacy evm dev namespace not enabled on this node") + })?; dev.snapshot().map_err(internal_err) } async fn revert(&self, snapshot_id: String) -> Result { - let dev = self - .dev_control - .as_ref() - .ok_or_else(|| feature_not_enabled("evm namespace not enabled on this node"))?; + let dev = self.dev_control.as_ref().ok_or_else(|| { + feature_not_enabled("legacy evm dev namespace not enabled on this node") + })?; dev.revert(&snapshot_id).map_err(internal_err) } } diff --git a/crates/rpc/src/handler/mod.rs b/crates/rpc/src/handler/mod.rs index ac4eb721..45997a90 100644 --- a/crates/rpc/src/handler/mod.rs +++ b/crates/rpc/src/handler/mod.rs @@ -12,15 +12,15 @@ pub(crate) use shell_core::{ Block, BlockHeader, SignedTransaction, SystemTransaction, Transaction, INITIAL_BASE_FEE, }; pub(crate) use shell_crypto::{MultiVerifier, Signer}; -pub(crate) use shell_evm::bloom::BLOOM_SIZE; -pub(crate) use shell_evm::{ShellEvm, ShellStateDb}; pub(crate) use shell_mempool::TxPool; +pub(crate) use shell_pqvm::bloom::BLOOM_SIZE; +pub(crate) use shell_pqvm::{ShellPqvm, ShellStateDb}; pub(crate) use shell_primitives::{Address, Bytes, ShellHash, U256}; pub(crate) use shell_storage::{ChainStore, KvStore, WitnessStore, WorldState}; pub(crate) use crate::admin::{AdminApiServer, NodeInfo, PeerInfo}; pub(crate) use crate::api::{ - DebugApiServer, EthApiServer, EvmApiServer, NetApiServer, ShellApiServer, TraceApiServer, + DebugApiServer, EthApiServer, LegacyEvmApiServer, NetApiServer, ShellApiServer, TraceApiServer, Web3ApiServer, }; pub(crate) use crate::dev_control::DynDevRpcControl; @@ -420,7 +420,7 @@ impl RpcHandler { let tx = Transaction { chain_id: self.chain_id, nonce, - to: Some(shell_evm::registry_address()), + to: Some(shell_pqvm::registry_address()), value: U256::ZERO, data: Bytes::copy_from_slice(&calldata), gas_limit: 100_000, @@ -459,7 +459,7 @@ impl RpcHandler { let world_state = WorldState::at_root(store.clone(), &state_root).map_err(internal_err)?; let chain_store = ChainStore::new(store); let state_db = ShellStateDb::new(world_state, chain_store); - let mut evm = ShellEvm::new(state_db, self.chain_id); + let mut evm = ShellPqvm::new(state_db, self.chain_id); let from = req.from.unwrap_or(Address::ZERO); // Cap gas to prevent DoS via unbounded simulated execution. @@ -549,7 +549,7 @@ impl RpcHandler { let result = evm .execute_tx(&signed, &header, 0, 0) - .map_err(|e| internal_err(format!("EVM execution failed: {e}")))?; + .map_err(|e| internal_err(format!("PQVM execution failed: {e}")))?; Ok((result.output.clone(), result.gas_used)) } @@ -1302,22 +1302,28 @@ mod tests { let dev = Arc::new(MockDevControl::default()); let handler = setup().with_dev_control(dev.clone()); - let mined = EvmApiServer::mine(&handler, Some(2)).await.unwrap(); + let mined = LegacyEvmApiServer::mine(&handler, Some(2)).await.unwrap(); assert_eq!(mined["blocksMined"], "0x2"); assert_eq!(dev.mined.load(Ordering::Relaxed), 2); - let next = EvmApiServer::set_next_block_timestamp(&handler, 1_700_000_123) + let next = LegacyEvmApiServer::set_next_block_timestamp(&handler, 1_700_000_123) .await .unwrap(); assert_eq!(next, serde_json::json!("0x6553f17b")); - let increased = EvmApiServer::increase_time(&handler, 30).await.unwrap(); + let increased = LegacyEvmApiServer::increase_time(&handler, 30) + .await + .unwrap(); assert_eq!(increased, serde_json::json!("0x1e")); - let snapshot = EvmApiServer::snapshot(&handler).await.unwrap(); + let snapshot = LegacyEvmApiServer::snapshot(&handler).await.unwrap(); assert_eq!(snapshot, "0x1"); - assert!(EvmApiServer::revert(&handler, "0x1".into()).await.unwrap()); - assert!(!EvmApiServer::revert(&handler, "0x2".into()).await.unwrap()); + assert!(LegacyEvmApiServer::revert(&handler, "0x1".into()) + .await + .unwrap()); + assert!(!LegacyEvmApiServer::revert(&handler, "0x2".into()) + .await + .unwrap()); } #[tokio::test] @@ -2235,7 +2241,7 @@ mod tests { let signer = DilithiumSigner::generate(); let pubkey = signer.public_key().to_vec(); let addr = signer_address(&signer); - let gas_limit = shell_evm::compute_intrinsic_gas(&[], true, &None); + let gas_limit = shell_pqvm::compute_intrinsic_gas(&[], true, &None); // Fund the sender so balance check passes. { @@ -2283,7 +2289,7 @@ mod tests { let signer = DilithiumSigner::generate(); let pubkey = signer.public_key().to_vec(); let addr = signer_address(&signer); - let gas_limit = shell_evm::compute_intrinsic_gas(&[], true, &None); + let gas_limit = shell_pqvm::compute_intrinsic_gas(&[], true, &None); { let mut ws = handler.world_state.write(); @@ -2467,7 +2473,7 @@ mod tests { number: u64, logs_per_receipt: Vec>, ) -> ShellHash { - let bloom = shell_evm::bloom::logs_bloom( + let bloom = shell_pqvm::bloom::logs_bloom( &logs_per_receipt .iter() .flatten() @@ -2510,7 +2516,7 @@ mod tests { .into_iter() .enumerate() .map(|(i, logs)| { - let receipt_bloom = shell_evm::bloom::logs_bloom(&logs); + let receipt_bloom = shell_pqvm::bloom::logs_bloom(&logs); cumulative_gas += 21_000; TransactionReceipt { tx_hash: ShellHash::from_slice(&[i as u8 + 1; 32]), @@ -2795,11 +2801,11 @@ mod tests { // Verify the transaction has the correct calldata. let target_addr = parse_address(&target).unwrap(); - let expected_calldata = shell_evm::encode_add_validator_calldata(&target_addr); + let expected_calldata = shell_pqvm::encode_add_validator_calldata(&target_addr); let pending = handler.tx_pool.pending(100); assert_eq!(pending.len(), 1); assert_eq!(pending[0].tx.data.as_ref(), expected_calldata.as_slice()); - assert_eq!(pending[0].tx.to, Some(shell_evm::registry_address())); + assert_eq!(pending[0].tx.to, Some(shell_pqvm::registry_address())); assert_eq!(pending[0].tx.value, U256::ZERO); assert_eq!(pending[0].tx.chain_id, 42); assert_eq!(pending[0].tx.nonce, 0); @@ -2820,7 +2826,7 @@ mod tests { assert_eq!(handler.tx_pool.len(), 1); let target_addr = parse_address(&target).unwrap(); - let expected_calldata = shell_evm::encode_remove_validator_calldata(&target_addr); + let expected_calldata = shell_pqvm::encode_remove_validator_calldata(&target_addr); let pending = handler.tx_pool.pending(100); assert_eq!(pending[0].tx.data.as_ref(), expected_calldata.as_slice()); } @@ -3097,7 +3103,7 @@ mod tests { .await .unwrap(); - let expected = shell_evm::encode_add_validator_calldata(&target); + let expected = shell_pqvm::encode_add_validator_calldata(&target); assert_eq!(result, format!("0x{}", hex::encode(expected))); // Must start with the selector assert!(result.starts_with("0x")); @@ -3115,7 +3121,7 @@ mod tests { .await .unwrap(); - let expected = shell_evm::encode_remove_validator_calldata(&target); + let expected = shell_pqvm::encode_remove_validator_calldata(&target); assert_eq!(result, format!("0x{}", hex::encode(expected))); assert_eq!(result.len(), 74); } @@ -3125,7 +3131,7 @@ mod tests { let handler = setup(); let result = ShellApiServer::get_governance_info(&handler).await.unwrap(); let addr_str = result["systemContractAddress"].as_str().unwrap(); - let expected = format!("{}", shell_evm::registry_address()); + let expected = format!("{}", shell_pqvm::registry_address()); assert_eq!(addr_str, expected); } @@ -4253,7 +4259,7 @@ mod tests { let signer = DilithiumSigner::generate(); let pubkey = signer.public_key().to_vec(); let addr = signer_address(&signer); - let gas_limit = shell_evm::compute_intrinsic_gas(&[], true, &None); + let gas_limit = shell_pqvm::compute_intrinsic_gas(&[], true, &None); // Fund the sender and register pubkey so mempool can verify. { @@ -4301,7 +4307,7 @@ mod tests { let signer = DilithiumSigner::generate(); let pubkey = signer.public_key().to_vec(); let addr = signer_address(&signer); - let gas_limit = shell_evm::compute_intrinsic_gas(&[], true, &None); + let gas_limit = shell_pqvm::compute_intrinsic_gas(&[], true, &None); { let mut ws = handler.world_state.write(); @@ -4347,7 +4353,7 @@ mod tests { let signer = DilithiumSigner::generate(); let pubkey = signer.public_key().to_vec(); let addr = signer_address(&signer); - let gas_limit = shell_evm::compute_intrinsic_gas(&[], true, &None); + let gas_limit = shell_pqvm::compute_intrinsic_gas(&[], true, &None); { let mut ws = handler.world_state.write(); diff --git a/crates/rpc/src/handler/net.rs b/crates/rpc/src/handler/net.rs index 9ed0305a..18477674 100644 --- a/crates/rpc/src/handler/net.rs +++ b/crates/rpc/src/handler/net.rs @@ -52,7 +52,7 @@ impl DebugApiServer for RpcHandler { let to_addr = tx.tx.to.unwrap_or(Address::ZERO); let call_type = if tx.tx.to.is_none() { "CREATE" } else { "CALL" }; - let mut frame = shell_evm::CallFrame::new( + let mut frame = shell_pqvm::CallFrame::new( call_type, tx.sender(), to_addr, @@ -77,7 +77,7 @@ impl DebugApiServer for RpcHandler { } } - let trace = shell_evm::TraceResult { + let trace = shell_pqvm::TraceResult { frame, failed: !receipt.succeeded(), }; @@ -109,7 +109,7 @@ impl DebugApiServer for RpcHandler { let to_addr = tx.tx.to.unwrap_or(Address::ZERO); let call_type = if tx.tx.to.is_none() { "CREATE" } else { "CALL" }; - let mut frame = shell_evm::CallFrame::new( + let mut frame = shell_pqvm::CallFrame::new( call_type, tx.sender(), to_addr, @@ -135,7 +135,7 @@ impl DebugApiServer for RpcHandler { } let failed = receipt.map(|r| !r.succeeded()).unwrap_or(true); - let trace = shell_evm::TraceResult { frame, failed }; + let trace = shell_pqvm::TraceResult { frame, failed }; traces.push(trace); } diff --git a/crates/rpc/src/handler/shell_api.rs b/crates/rpc/src/handler/shell_api.rs index 7cd8189c..5763f373 100644 --- a/crates/rpc/src/handler/shell_api.rs +++ b/crates/rpc/src/handler/shell_api.rs @@ -101,26 +101,26 @@ impl ShellApiServer for RpcHandler { async fn encode_add_validator(&self, address: String) -> Result { let addr = parse_address(&address)?; - let calldata = shell_evm::encode_add_validator_calldata(&addr); + let calldata = shell_pqvm::encode_add_validator_calldata(&addr); Ok(format!("0x{}", hex::encode(calldata))) } async fn encode_remove_validator(&self, address: String) -> Result { let addr = parse_address(&address)?; - let calldata = shell_evm::encode_remove_validator_calldata(&addr); + let calldata = shell_pqvm::encode_remove_validator_calldata(&addr); Ok(format!("0x{}", hex::encode(calldata))) } async fn propose_add_validator(&self, address: String) -> Result { let addr = parse_address(&address)?; - let calldata = shell_evm::encode_add_validator_calldata(&addr); + let calldata = shell_pqvm::encode_add_validator_calldata(&addr); let hash = self.propose_validator_tx(calldata)?; Ok(format!("0x{}", hex::encode(hash.0))) } async fn propose_remove_validator(&self, address: String) -> Result { let addr = parse_address(&address)?; - let calldata = shell_evm::encode_remove_validator_calldata(&addr); + let calldata = shell_pqvm::encode_remove_validator_calldata(&addr); let hash = self.propose_validator_tx(calldata)?; Ok(format!("0x{}", hex::encode(hash.0))) } @@ -131,7 +131,7 @@ impl ShellApiServer for RpcHandler { weight: u64, ) -> Result { let addr = parse_address(&address)?; - let calldata = shell_evm::encode_set_validator_weight_calldata(&addr, weight); + let calldata = shell_pqvm::encode_set_validator_weight_calldata(&addr, weight); let hash = self.propose_validator_tx(calldata)?; Ok(format!("0x{}", hex::encode(hash.0))) } @@ -155,7 +155,7 @@ impl ShellApiServer for RpcHandler { Ok(serde_json::json!({ "validatorCount": validators.len(), "validators": validators, - "systemContractAddress": shell_evm::registry_address(), + "systemContractAddress": shell_pqvm::registry_address(), "proposalGasLimit": 100_000, })) } @@ -163,9 +163,9 @@ impl ShellApiServer for RpcHandler { async fn estimate_governance_gas(&self, operation: String) -> Result { let gas = match operation.as_str() { "addValidator" | "removeValidator" => { - shell_evm::SYSTEM_CALL_BASE_GAS + shell_evm::SYSTEM_CALL_OP_GAS + shell_pqvm::SYSTEM_CALL_BASE_GAS + shell_pqvm::SYSTEM_CALL_OP_GAS } - "getValidators" | "isValidator" => shell_evm::SYSTEM_CALL_BASE_GAS, + "getValidators" | "isValidator" => shell_pqvm::SYSTEM_CALL_BASE_GAS, _ => { return Err(invalid_params(format!( "unknown governance operation: {operation}" diff --git a/crates/rpc/src/server.rs b/crates/rpc/src/server.rs index e39f431b..2ba52541 100644 --- a/crates/rpc/src/server.rs +++ b/crates/rpc/src/server.rs @@ -19,7 +19,7 @@ use shell_storage::{ChainStore, KvStore, WitnessStore, WorldState}; use crate::admin::AdminApiServer; use crate::api::{ - DebugApiServer, EthApiServer, EvmApiServer, NetApiServer, ShellApiServer, TraceApiServer, + DebugApiServer, EthApiServer, LegacyEvmApiServer, NetApiServer, ShellApiServer, TraceApiServer, Web3ApiServer, }; use crate::dev_control::DynDevRpcControl; @@ -299,7 +299,7 @@ pub async fn start_rpc_server( module.merge(EthPubSubServer::into_rpc(handler.clone()))?; } if ns.iter().any(|n| n == "evm") { - module.merge(EvmApiServer::into_rpc(handler.clone()))?; + module.merge(LegacyEvmApiServer::into_rpc(handler.clone()))?; } if ns.iter().any(|n| n == "shell") { module.merge(ShellApiServer::into_rpc(handler.clone()))?; diff --git a/docs/ACCOUNT_ABSTRACTION_GUIDE.md b/docs/ACCOUNT_ABSTRACTION_GUIDE.md index b44274de..e5ea53bf 100644 --- a/docs/ACCOUNT_ABSTRACTION_GUIDE.md +++ b/docs/ACCOUNT_ABSTRACTION_GUIDE.md @@ -157,8 +157,8 @@ Current node logic accepts the common "magic valid" encodings: This call path is implemented in: -- `crates/evm/src/aa_validation.rs` -- `crates/evm/src/tx_validation.rs` +- `crates/pqvm/src/aa_validation.rs` +- `crates/pqvm/src/tx_validation.rs` - `contracts/DefaultPQValidator.sol` --- @@ -227,8 +227,8 @@ Ethereum add-on AA layer. If you want to trace the implementation in code: - `crates/primitives/src/address.rs` — address derivation (`BLAKE3(algo_id || pubkey)`, 32-byte output, `0x` hex encoding) -- `crates/evm/src/aa_validation.rs` — native AA dispatcher and custom-validator path -- `crates/evm/src/tx_validation.rs` — transaction validation entry points +- `crates/pqvm/src/aa_validation.rs` — native AA dispatcher and custom-validator path +- `crates/pqvm/src/tx_validation.rs` — transaction validation entry points - `crates/mempool/src/pool.rs` — mempool-side validation integration --- diff --git a/docs/SYSTEM_CONTRACTS.md b/docs/SYSTEM_CONTRACTS.md index 7bc13939..62791d5d 100644 --- a/docs/SYSTEM_CONTRACTS.md +++ b/docs/SYSTEM_CONTRACTS.md @@ -230,7 +230,7 @@ System contract calls use a flat base gas charge: | `setValidationCode` | `SYSTEM_CALL_BASE_GAS` + hash write | | `clearValidationCode` | `SYSTEM_CALL_BASE_GAS` + delete | -`SYSTEM_CALL_BASE_GAS` is a constant defined in `shell-evm` — use +`SYSTEM_CALL_BASE_GAS` is a constant defined in `shell-pqvm` — use `shell_estimateGovernanceGas` to get accurate estimates before submitting. --- diff --git a/docs/node-cli.md b/docs/node-cli.md index cdc9631d..ab2a1010 100644 --- a/docs/node-cli.md +++ b/docs/node-cli.md @@ -77,8 +77,8 @@ shell-node [GLOBAL FLAGS] run [OPTIONS] | `--mempool-max-size ` | `4096` | Maximum pending transactions in mempool | | `--mempool-price-bump ` | `10` | Minimum gas-price bump % to replace a pending tx | | `--state-cache-size-mb ` | `64` | Account LRU cache size for world-state trie | -| `--parallel-evm` | `false` | Enable parallel-EVM conflict-graph scheduler | -| `--parallel-evm-workers ` | logical CPUs | Worker threads for parallel-EVM | +| `--parallel-pqvm` | `false` | Enable parallel-PQVM conflict-graph scheduler (`--parallel-evm` remains a deprecated alias) | +| `--parallel-pqvm-workers ` | logical CPUs | Worker threads for parallel-PQVM (`--parallel-evm-workers` remains a deprecated alias) | | `--storage-profile ` | `full` | Storage classification: `archive`, `full`, or `light` | | `--witness-retention ` | profile default | Override witness bundle retention (0 = keep forever) | | `--body-retention ` | profile default | Override TX body retention (0 = keep forever) | diff --git a/tools/tx-generator/Cargo.lock b/tools/tx-generator/Cargo.lock index 3d0f1a45..def974b6 100644 --- a/tools/tx-generator/Cargo.lock +++ b/tools/tx-generator/Cargo.lock @@ -3351,7 +3351,7 @@ dependencies = [ [[package]] name = "shell-core" -version = "0.22.2" +version = "0.23.0" dependencies = [ "alloy-rlp", "serde", @@ -3364,7 +3364,7 @@ dependencies = [ [[package]] name = "shell-crypto" -version = "0.22.2" +version = "0.23.0" dependencies = [ "alloy-rlp", "fips204", @@ -3381,8 +3381,8 @@ dependencies = [ ] [[package]] -name = "shell-evm" -version = "0.22.2" +name = "shell-pqvm" +version = "0.23.0" dependencies = [ "alloy-primitives", "blake3", @@ -3401,7 +3401,7 @@ dependencies = [ [[package]] name = "shell-primitives" -version = "0.22.2" +version = "0.23.0" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -3414,7 +3414,7 @@ dependencies = [ [[package]] name = "shell-storage" -version = "0.22.2" +version = "0.23.0" dependencies = [ "alloy-rlp", "base64", @@ -3423,6 +3423,7 @@ dependencies = [ "hex", "lru", "parking_lot", + "rlp", "serde", "serde_json", "sha2", @@ -3444,7 +3445,7 @@ dependencies = [ "serde_json", "shell-core", "shell-crypto", - "shell-evm", + "shell-pqvm", "shell-primitives", "tokio", ] diff --git a/tools/tx-generator/Cargo.toml b/tools/tx-generator/Cargo.toml index 5403b46e..7a5db83e 100644 --- a/tools/tx-generator/Cargo.toml +++ b/tools/tx-generator/Cargo.toml @@ -14,7 +14,7 @@ path = "src/main.rs" [dependencies] shell-crypto = { path = "../../crates/crypto", default-features = false, features = [] } shell-core = { path = "../../crates/core" } -shell-evm = { path = "../../crates/evm" } +shell-pqvm = { path = "../../crates/pqvm" } shell-primitives = { path = "../../crates/primitives" } tokio = { version = "1", features = ["full"] } diff --git a/tools/tx-generator/src/bin/shell-aa-injector.rs b/tools/tx-generator/src/bin/shell-aa-injector.rs index af7dca62..efff96c5 100644 --- a/tools/tx-generator/src/bin/shell-aa-injector.rs +++ b/tools/tx-generator/src/bin/shell-aa-injector.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use serde_json::json; use shell_core::{SignedTransaction, Transaction}; use shell_crypto::{DilithiumSigner, Signer}; -use shell_evm::{account_manager_address, encode_rotate_key_calldata}; +use shell_pqvm::{account_manager_address, encode_rotate_key_calldata}; use shell_primitives::{Address, Bytes, U256}; use shell_tx_generator::load_dev_authority;