From 8131cf0b728346f2d99b91829d4e66a3980b1750 Mon Sep 17 00:00:00 2001 From: 1825833563 <1825833563@users.noreply.github.com> Date: Sat, 25 Apr 2026 16:50:21 +0800 Subject: [PATCH 1/2] chore: add rust-toolchain.toml for nightly edition 2024 --- rust-toolchain.toml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 rust-toolchain.toml diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 000000000..5d56faf9a --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" From 2be5312de02d442ec1976fd4290e0949b0be2b2d Mon Sep 17 00:00:00 2001 From: zhoutianxia1 Date: Tue, 28 Apr 2026 13:53:52 +0800 Subject: [PATCH 2/2] fix(grey): fix Windows build errors across all build.rs and node.rs Three categories of Windows build errors were preventing compilation: 1. build.rs path escaping (all 4 build.rs files): PathBuf::display() emits Windows backslash separators which Rust's lexer interprets as escape sequences inside include_bytes! string literals (e.g. \b, \j, \s, \o). Fix by adding include_path() helpers to build-javm and build-pvm that replace backslashes with forward slashes. All 4 build.rs files (grey, spec-tests, javm-guest-tests, grey-bench) now use these helpers instead of .display(). 2. node.rs Unix-only signal handling: tokio::signal::unix is not available on Windows. The original code hardcoded SIGTERM, SIGUSR1, and SIGHUP signal registrations. Fix by wrapping Unix-specific signal registrations in #[cfg(unix)] and providing std::future::pending::<()>() placeholders on non-Unix platforms so the select! arms compile but are simply never selected. 3. Previous PR #783 only fixed grey/build.rs but missed spec-tests, javm-guest-tests, and grey-bench which have the same .display() bug. This PR fixes all 4 build.rs files uniformly through the build-javm/build-pvm helper approach. Testing: cargo build --workspace # passes on Windows cargo clippy -p grey -p build-javm -p build-pvm --all-targets -- -D warnings # 0 warnings cargo test -p javm # 133 passed, 0 failed cargo fmt --all -- --check # no diff --- grey/crates/build-javm/src/lib.rs | 11 +++++ grey/crates/build-pvm/src/lib.rs | 11 +++++ grey/crates/grey-bench/build.rs | 22 ++++----- grey/crates/grey/build.rs | 4 +- grey/crates/grey/src/node.rs | 62 ++++++++++++++++++------- grey/services/javm-guest-tests/build.rs | 2 +- grey/services/spec-tests/build.rs | 4 +- 7 files changed, 83 insertions(+), 33 deletions(-) diff --git a/grey/crates/build-javm/src/lib.rs b/grey/crates/build-javm/src/lib.rs index 1ed1b8dc6..e49eebd54 100644 --- a/grey/crates/build-javm/src/lib.rs +++ b/grey/crates/build-javm/src/lib.rs @@ -2,6 +2,17 @@ use std::path::PathBuf; use build_crate::{BuildKind, GuestBuild}; +/// Convert a [`PathBuf`] to a string suitable for use inside `include_bytes!(…)`. +/// +/// On Windows, `PathBuf::display()` emits backslash separators which the Rust +/// lexer then interprets as escape sequences inside string literals (e.g. `\b`, +/// `\j`, `\s`). Replacing backslashes with forward slashes produces paths that +/// are valid on every platform — the Rust compiler accepts forward slashes on +/// Windows, and Unix paths never contain backslashes in the first place. +pub fn include_path(path: &std::path::Path) -> String { + path.to_string_lossy().replace('\\', "/") +} + const TARGET_JSON: &str = include_str!("riscv64em-javm.json"); const TARGET_NAME: &str = "riscv64em-javm"; diff --git a/grey/crates/build-pvm/src/lib.rs b/grey/crates/build-pvm/src/lib.rs index 209ae8f36..8be00aa41 100644 --- a/grey/crates/build-pvm/src/lib.rs +++ b/grey/crates/build-pvm/src/lib.rs @@ -5,6 +5,17 @@ use build_crate::{BuildKind, GuestBuild}; const TARGET_JSON: &str = include_str!("riscv64emac-polkavm.json"); const TARGET_NAME: &str = "riscv64emac-polkavm"; +/// Convert a [`PathBuf`] to a string suitable for use inside `include_bytes!(…)`. +/// +/// On Windows, `PathBuf::display()` emits backslash separators which the Rust +/// lexer then interprets as escape sequences inside string literals (e.g. `\b`, +/// `\j`, `\s`). Replacing backslashes with forward slashes produces paths that +/// are valid on every platform — the Rust compiler accepts forward slashes on +/// Windows, and Unix paths never contain backslashes in the first place. +pub fn include_path(path: &std::path::Path) -> String { + path.to_string_lossy().replace('\\', "/") +} + /// Build a PolkaVM blob from a service crate. /// /// - `manifest_dir`: path to the service crate, relative to `CARGO_MANIFEST_DIR` diff --git a/grey/crates/grey-bench/build.rs b/grey/crates/grey-bench/build.rs index 833109291..9644cd251 100644 --- a/grey/crates/grey-bench/build.rs +++ b/grey/crates/grey-bench/build.rs @@ -27,17 +27,17 @@ fn main() { const GREY_KECCAK_BLOB: &[u8] = include_bytes!(\"{}\");\n\ const POLKAVM_KECCAK_BLOB: &[u8] = include_bytes!(\"{}\");\n\ const SAMPLE_SERVICE_BLOB: &[u8] = include_bytes!(\"{}\");\n", - javm_ecrecover.display(), - pvm_ecrecover.display(), - javm_sieve.display(), - pvm_sieve.display(), - javm_ed25519.display(), - pvm_ed25519.display(), - javm_blake2b.display(), - pvm_blake2b.display(), - javm_keccak.display(), - pvm_keccak.display(), - service_blob.display(), + build_javm::include_path(&javm_ecrecover), + build_pvm::include_path(&pvm_ecrecover), + build_javm::include_path(&javm_sieve), + build_pvm::include_path(&pvm_sieve), + build_javm::include_path(&javm_ed25519), + build_pvm::include_path(&pvm_ed25519), + build_javm::include_path(&javm_blake2b), + build_pvm::include_path(&pvm_blake2b), + build_javm::include_path(&javm_keccak), + build_pvm::include_path(&pvm_keccak), + build_javm::include_path(&service_blob), ), ) .unwrap(); diff --git a/grey/crates/grey/build.rs b/grey/crates/grey/build.rs index 7ae4551ce..22a2f9c9d 100644 --- a/grey/crates/grey/build.rs +++ b/grey/crates/grey/build.rs @@ -9,8 +9,8 @@ fn main() { format!( "const SAMPLE_SERVICE_BLOB: &[u8] = include_bytes!(\"{}\");\n\ const PIXELS_SERVICE_BLOB: &[u8] = include_bytes!(\"{}\");\n", - sample.display(), - pixels.display(), + build_javm::include_path(&sample), + build_javm::include_path(&pixels), ), ) .unwrap(); diff --git a/grey/crates/grey/src/node.rs b/grey/crates/grey/src/node.rs index 0a55f0679..996deaccc 100644 --- a/grey/crates/grey/src/node.rs +++ b/grey/crates/grey/src/node.rs @@ -387,24 +387,50 @@ pub async fn run_node(config: NodeConfig) -> Result<(), Box "SIGINT", _ = sigterm.recv() => "SIGTERM", } }; - tokio::pin!(shutdown); - - // SIGUSR1: dump debug state to log - let mut sigusr1 = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::user_defined1()) - .expect("failed to register SIGUSR1 handler"); - - // SIGHUP: reload config file - let mut sighup = tokio::signal::unix::signal(tokio::signal::unix::SignalKind::hangup()) - .expect("failed to register SIGHUP handler"); + #[cfg(not(unix))] + let shutdown_signal = async { + let _ = tokio::signal::ctrl_c().await; + "SIGINT" + }; + tokio::pin!(shutdown_signal); + + // SIGUSR1: dump debug state to log (Unix only). + // On non-Unix platforms, the future is pending forever so this arm never fires. + #[cfg(unix)] + let sigusr1_signal = async { + let mut sigusr1 = + tokio::signal::unix::signal(tokio::signal::unix::SignalKind::user_defined1()) + .expect("failed to register SIGUSR1 handler"); + sigusr1.recv().await + }; + #[cfg(not(unix))] + let sigusr1_signal = std::future::pending::<()>(); + tokio::pin!(sigusr1_signal); + + // SIGHUP: reload config file (Unix only). + // On non-Unix platforms, the future is pending forever so this arm never fires. + #[cfg(unix)] + let sighup_signal = async { + let mut sighup = + tokio::signal::unix::signal(tokio::signal::unix::SignalKind::hangup()) + .expect("failed to register SIGHUP handler"); + sighup.recv().await + }; + #[cfg(not(unix))] + let sighup_signal = std::future::pending::<()>(); + tokio::pin!(sighup_signal); let config_path = config.config_path.clone(); // Main loop: check timeslots every 500ms @@ -426,7 +452,7 @@ pub async fn run_node(config: NodeConfig) -> Result<(), Box { + signal_name = &mut shutdown_signal => { tracing::info!( "Validator {} received {}, flushing state...", config.validator_index, @@ -444,8 +470,9 @@ pub async fn run_node(config: NodeConfig) -> Result<(), Box { + // SIGUSR1: dump debug state snapshot to log. + // On non-Unix platforms sigusr1_signal is pending forever, so this arm never fires. + _ = sigusr1_signal.as_mut() => { let head_hash = state .recent_blocks .headers @@ -477,7 +504,8 @@ pub async fn run_node(config: NodeConfig) -> Result<(), Box { + // SIGHUP: reload config. On non-Unix platforms sighup_signal is pending forever. + _ = sighup_signal.as_mut() => { if let Some(ref path) = config_path { tracing::info!("SIGHUP received — reloading config from {}", path); match crate::config::ConfigFile::load(std::path::Path::new(path)) { diff --git a/grey/services/javm-guest-tests/build.rs b/grey/services/javm-guest-tests/build.rs index 64a918266..e07aff9ba 100644 --- a/grey/services/javm-guest-tests/build.rs +++ b/grey/services/javm-guest-tests/build.rs @@ -10,7 +10,7 @@ fn main() { format!("{out_dir}/guest_blob.rs"), format!( "const GUEST_TESTS_BLOB: &[u8] = include_bytes!(\"{}\");\n", - blob.display(), + build_javm::include_path(&blob), ), ) .unwrap(); diff --git a/grey/services/spec-tests/build.rs b/grey/services/spec-tests/build.rs index cb47873f7..c008ad028 100644 --- a/grey/services/spec-tests/build.rs +++ b/grey/services/spec-tests/build.rs @@ -8,8 +8,8 @@ fn main() { format!( "const MINIMAL_BLOB: &[u8] = include_bytes!(\"{}\");\n\ const BOOTSTRAP_BLOB: &[u8] = include_bytes!(\"{}\");\n", - minimal.display(), - bootstrap.display(), + build_javm::include_path(&minimal), + build_javm::include_path(&bootstrap), ), ) .unwrap();