Conversation
* feat: add Fiber (FNN) support to the local devnet Add a local Fiber development environment to offckb: - Genesis: the devnet now carries the Fiber contracts auth, funding_lock and commitment_lock, copied from the new ckb/fiber submodule pinned to the FNN v0.9.0-rc7 commit (bc361aa). They are appended after the existing system cells so existing script type ids (accounts, sudt, xudt, ...) stay unchanged; the genesis tx hash changes, so cell dep out points are always read from a fresh `ckb list-hashes` at start. - FNN install: download/cache of the tested FNN release (0.9.0-rc7, portable tarballs), keeping the bundled config/testnet/config.yml as the devnet config template; --binary-path/--fnn-binary-path run a locally built FNN, using its sibling testnet config or the shipped fallback. - offckb node --fiber: start CKB, miner, RPC proxy and FNN nodes with one command (daemon mode included). Plain local devnet only: mainnet/testnet and forked devnets (any fork.json) are rejected before any daemon respawn. - offckb fiber start/stop/status/logs/clean: manage FNNs on an already-running devnet. Node N uses built-in account N+2, RPC port 21713+N and P2P port 8343+N (1-16 nodes). Each node writes only to its own fnn.log; per-node FNN config overrides live in fiber/nodes.yml; config.yml is regenerated every start from the FNN testnet config with unknown fields preserved. - Startup checks: genesis hash agreement between list-hashes, CKB RPC and every FNN node_info, node identity key vs fiber/sk, funding account vs the expected built-in account, and available balance; then node 1 connects to the other nodes (verified via list_peers). - Process management: a shared .offckb-devnet.lock, runtime.json for manager/node records, daemon PID files with identity checks, stop only ever signals recorded managers (never per-FNN kills), store LOCK verification before cleans; offckb clean removes fiber stores with --data and refuses while a daemon or live store lock is confirmed. - fiber status reports CKB and per-node state (starting/running/stopped/unknown/conflict) plus an OFFCKB-managed column, as a table or --json. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(fiber): address PR #483 review feedback - Sanitize builder home paths (/Users/quake, /home/quake) embedded in the committed funding_lock/commitment_lock binaries with equal-length replacements; make fiber reproduces the sanitized copies and fails with a clear message when the ckb/fiber submodule is missing - Keep already-spawned FNNs from being orphaned when a later spawn fails - Treat signal-terminated children as exited (exitCode is null there) - Capture store lock files before signaling the manager; it removes runtime.json during its own shutdown - isStoreLockHeld: only lsof exit 1 means 'no holder'; any other exit status or a timeout kill now reports 'unknown' instead of 'free' - Align the node --fiber --daemon readiness wait with the fiber daemon's 10-minute budget (first run may download FNN) - Mark ckb.udt_whitelist as a managed nodes.yml field so per-node overrides cannot silently break UDT payments - Replace deprecated wmic with PowerShell Get-CimInstance for Windows process command-line lookup - Give requireScript a full contextual error instead of raw missing:<name> - Warn that shrinking nodes.yml discards the removed nodes' config overrides - Share helpers: fiberAccountIndex in the start summary, lockMatches between status and manager, nodeDaemonPaths across cmd/fiber modules, fiberNodeIds for node enumeration, SystemScriptName for script lookup - Delete the downloaded FNN tarball after install (also on failure) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(fiber): fail-closed daemon identity, startup signal window, lifecycle tests Address the PR #483 test-squad review gates: - J1 (Critical): verifyDaemonIdentity no longer trusts the pid file's scriptPath/scriptDir and no longer matches "node"/"index.js" substrings anywhere in the command line. Identity now comes from the live process: the executable must be this Node runtime (exact process.execPath match or an exact node/nodejs basename), its first argument must equal this installation's CLI entry after realpath normalization, and its start time must match the pid file's startedAt within 30s — the PID-reuse guard, finally reading the field that was always written but never checked. Inspection prefers /proc (exact argv, tick-precision start time) and falls back to ps lstart/args, or one CIM JSON call returning CommandLine + CreationDate on Windows. Every unverifiable step fails closed: stop refuses without signaling. - J2 (High): startFiberEnvironment installs SIGINT/SIGTERM handlers before the first FNN spawn; a signal inside the startup window runs the same cleanup as a post-ready stop (SIGTERM, SIGKILL after the grace period, runtime.json dropped) and exits 130/143. The handlers are removed once the environment is ready so supervision handlers take over. - J3 (High): lifecycle-layer tests cover the verifyDaemonIdentity true/false matrix (forged scriptPath, basename-only match, non-node executable with "node" substrings, start-time mismatch, legacy record), the isStoreLockHeld missing/held/free/unavailable/error states, assertFiberFullyStopped fail-closed paths, stopFiberNodes SIGTERM-to-SIGKILL escalation and signal-exited children (null exitCode), and the startup signal window. - J7: fiber.store_path joins the nodes.yml managed fields so a per-node override cannot relocate the store away from clean's RocksDB LOCK check. stopFiberNodes and isStoreLockHeld take optional grace-period/command parameters for deterministic tests; the ps/CIM probes now run with a 5s timeout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(fiber): address remaining PR #483 review items beyond the merge gates - J6: `node stop` now refuses while a foreground fiber environment is live instead of orphaning its FNNs on a stopped chain; `--force` overrides with a warning - J8: isRuntimeStale fails closed — an unverifiable manager (EPERM) keeps its runtime record instead of being discarded, matching the environment lock's philosophy - S1: FNN downloads are verified against SHA-256 digests pinned in source (all five v0.9.0-rc7 packages, cross-checked against the GitHub release API and a local re-download); missing pins fail closed - S5: jest coverage ratchet for src/fiber/** and src/util/daemon.ts - S2: FiberContractsMissingError now carries the full migration guidance itself, so `node --fiber` on a pre-Fiber devnet prints the same rebuild instructions as `fiber start` - clean: re-verify fully-stopped after the confirmation prompt, closing the prompt-window race; fiberClean locks the env lock of the settings it was given instead of the default - docs: single-instance/fixed-ports caveat (F9/J4), pre-Fiber devnet migration note, node stop --force - tests: +24 — isRuntimeStale fail-closed, node-stop guard matrix, stopFiber stale/foreign-daemon paths, fiberClean refusal/deletion, checksum verify matrix, assertPlainDevnet, lockMatches list-hashes verification (merge-base 4f27ae9 vs PR head): all 19 pre-existing system cells keep identical index/data_hash/type_hash; fiber auth/funding_lock/commitment_lock are appended at 20-22; dep groups unchanged; genesis b15fa8a5.. -> 334344de.. * fix(fiber): address latest CodeRabbit review round on PR #483 - node stop: verify fiber daemon identity before refusing, honor --force - node foreground: share one shutdown latch between component-exit and signal handlers so cleanup cannot race itself - fiber daemon start: keep live unverifiable PID metadata instead of replacing it and stranding the real daemon - fiber stop: keep pid/runtime records when manager exit is unconfirmed; bound 'starting' records by the startup grace window so an interrupted launcher no longer deadlocks stop/clean - install: private per-run temp dir (mkdtemp) for download+extract, reject unsupported linux/darwin architectures instead of mapping to x86_64, parameterize and export buildFnnPackageName - nodes.yml: reject an empty stored node list - fiber status: verify daemon identity for the OFFCKB column, probe all FNNs concurrently - tests: isolate ps lstart answers in foreign-process mocks, drop the obsolete wmic mock branch, park a rejection handler in the startup-window test, cover the new behaviors * fix(fiber): don't let EPIPE truncate a graceful shutdown in progress With piped output (`offckb node --fiber 2>&1 | tee log`), Ctrl+C kills the pipeline reader together with the CLI; the first log line of the shutdown cleanup then hits EPIPE and installBrokenPipeHandlers exits the process with 0 in the middle of teardown — runtime.json is left behind and the 130 exit code is lost. Add a process-wide graceful-shutdown marker (util/shutdown.ts): the signal handlers and the component-exit teardown enter it before their first log line, and the broken-pipe handler swallows EPIPE while a shutdown is running so the cleanup completes and exits 130/143 itself. Normal broken-pipe behavior (quiet exit 0 for `| head` etc.) is unchanged. Also document the UDT channel gotchas found in the same test round: UDT channels need a manual accept_channel with funding_amount 0x0, both sides must hold the UDT first, and `udt issue` amounts are base units. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
… identity probe timeout) (#506) * test: stop broken-pipe test from crashing jest worker on macOS/Windows * fix: raise daemon-identity probe timeout to stop Windows CI flake * test: stub stream.on with mockReturnThis so broken-pipe handlers never touch live streams
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (5)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Your free Security trial is over. An organization admin can activate billing to continue. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
No description provided.