Skip to content

Merge pre-v0.5.0 into v0.5.x - #507

Merged
RetricSu merged 3 commits into
v0.5.xfrom
develop
Aug 24, 2026
Merged

Merge pre-v0.5.0 into v0.5.x#507
RetricSu merged 3 commits into
v0.5.xfrom
develop

Conversation

@RetricSu

Copy link
Copy Markdown
Collaborator

No description provided.

humble-little-bear and others added 3 commits August 24, 2026 10:31
* 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
@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (5)
  • master
  • dev
  • releases/.*
  • develop
  • next-major

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e06605eb-3ac9-43c3-92c0-9a11d0ace840

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@RetricSu
RetricSu merged commit 339f885 into v0.5.x Aug 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants