Skip to content

feat!(cch): CCH multi-asset swap#1257

Open
doitian wants to merge 1 commit into
nervosnetwork:developfrom
doitian:feat/cch-multi-asset-swap
Open

feat!(cch): CCH multi-asset swap#1257
doitian wants to merge 1 commit into
nervosnetwork:developfrom
doitian:feat/cch-multi-asset-swap

Conversation

@doitian

@doitian doitian commented Apr 8, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR delivers CCH multi-asset swap: a protocol specification plus the implementation that follows it. The cross-chain hub now swaps Lightning BTC against native CKB and allowlisted UDTs (not just a single wrapped-BTC UDT), and the operator-mediated proposal flow is asynchronous / fire-and-forget.

BREAKING: This PR contains database migration for CCH orders. Once merged and a new version is released, the migration should depend on the new version instead of the version in the workspace.

Specification

docs/specs/cch-multi-asset-swap.md:

  • Scope: HTLC flow unchanged; Fiber leg covers native CKB (shannons) and UDTs with type script; Lightning remains BTC-denominated.
  • Economics: swap rate from invoice pair + hub fees (BTC-side fee basis); no hard-coded 1:1 wrapped-BTC mapping.
  • Hub policy: asset allowlist and per-UDT decimals/metadata.
  • Swap acceptor: WebSocket JSON-RPC subscription with binary accept/reject, configurable timeout, explicit RPC errors on reject/timeout.
  • Async proposal model: client submits and polls; workflow resumes on the operator's response.

Implementation

Multi-asset CchOrder

  • Generalized config and actor beyond a single wrapped-BTC UDT to native CKB and allowlisted UDTs (cch/config.rs).
  • CchOrder reshaped (fiber-types, fiber-json-types): fiber_type_script: Option<Script>, separate BTC and Fiber amount fields (btc_amount_msat, btc_fee_msat, fiber_amount_smallest_unit). The counterparty invoice (incoming_invoice: CchInvoice) is always present — the order is only created once the counterparty leg has been priced and its invoice minted.
  • CchPendingProposal is a separate store record (not a CchOrderStatus variant). It holds the SwapProposal plus the scaffolding needed to build a CchOrder when the operator accepts. No CchOrder exists during the proposal phase.

Async / fire-and-forget proposal flow

  • send_btc / receive_btc validate, persist a CchPendingProposal record, broadcast the SwapProposal to operator subscribers, and return immediately with a NewOrderResult::PendingProposal(SwapProposal). The client polls get_cch_order.
  • The workflow resumes when the operator calls submit_swap_proposal_response: the actor mints the counterparty invoice, creates a new CchOrder with status Pending, deletes the CchPendingProposal record, and starts the action flow. Reject/timeout deletes the proposal record — no CchOrder is ever created.
  • On restart, every persisted CchPendingProposal record is re-broadcast and its timeout rescheduled to its deadline. Orders are resumed as usual via ResumeOrder.
  • Removed the Arc<Mutex<HashSet<Hash256>>> inflight-hash mutex (the tokio shared-state antipattern). All order creation runs inline in the single-threaded actor mailbox, which naturally serializes same-hash requests. The swap acceptor is reduced to a pure pub/sub broadcaster; blocking call_t! is replaced with fire-and-forget message passing.
  • Fiber-leg outgoing payment fee budgets are converted from the BTC-denominated fee to the Fiber asset's smallest unit using the order's net exchange rate (excluding the hub fee), so the invariant "outgoing route fee never exceeds collected fee" holds regardless of which leg carries the outgoing payment.

RPC

  • cch.rs: async/poll doc semantics; submit_swap_proposal_response is now the resume path; reverted the inflated proposal-timeout mailbox window.
  • Regenerated rpc/README.md.

Migration

  • crates/fiber-store/src/migrations/mig_20260610_cch_multi_asset.rs: migrates legacy single-asset CchOrder to the multi-asset shape in the new migration system (auto-registered via build.rs). Legacy orders are never PendingProposal (that variant doesn't exist in CchOrderStatus).

Tests / docs

  • Reworked cch actor/dispatcher/scheduler/state-machine tests to the async model (immediate PendingProposal return, operator response, poll for resolution, timeout → deleted, restart re-broadcast).
  • Regenerated store/.schema.json.

Validation

  • cargo build -p fnn -p fiber-bin --features rocksdb
  • cargo check --target wasm32-unknown-unknown -p fiber-store
  • fiber-store tests, cch tests, make check-migrate, fmt/clippy/typos ✓

@doitian doitian added this to Kanban Apr 8, 2026
@doitian doitian changed the title docs: add CCH multi-asset swap specification feat: CCH multi-asset swap Apr 8, 2026
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch 2 times, most recently from 75583f0 to f55b11f Compare April 21, 2026 04:35
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch from 2bdf38b to 8f188f6 Compare May 5, 2026 07:46
@doitian doitian marked this pull request as ready for review May 6, 2026 00:59
@doitian doitian requested a review from Copilot May 6, 2026 01:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR moves CCH from a single wrapped-BTC assumption to a multi-asset swap model for native CKB and allowlisted UDTs. Although the PR description says “spec only,” the diff already includes the first implementation slice across CCH runtime logic, RPC/API types, persistence, and test/deploy tooling.

Changes:

  • Generalizes CCH config, domain types, and actor logic around fiber_type_script, asset allowlists, fixed-rate assets, and operator-approved proposal flows.
  • Adds operator-facing swap proposal RPC/subscription endpoints, auth rules, JSON conversions, and CCH tests for the new flow.
  • Introduces persisted CchOrder shape changes, a migration/schema update, and supporting deploy/Bruno/doc updates.

Reviewed changes

Copilot reviewed 25 out of 26 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
tests/nodes/deployer/config.yml Replaces single-asset CCH test config with allowlist/fixed-rate asset config.
tests/deploy/udt-init/src/main.rs Patches deployed UDT code hashes into generated CCH node configs.
tests/bruno/e2e/cross-chain-hub/02-create-send-btc-order.bru Adds fiber_type_script to integrated CCH Bruno send_btc request.
tests/bruno/e2e/cross-chain-hub-separate/02-create-send-btc-order.bru Adds fiber_type_script to standalone CCH Bruno send_btc request.
migrate/src/migrations/mod.rs Registers the new CCH multi-asset migration module.
migrate/src/migrations/mig_20260421_cch_multi_asset.rs Migrates stored CCH orders to the new multi-asset layout.
migrate/Cargo.toml Adds migration-only serde/CKB dependencies for the new order shape.
migrate/Cargo.lock Locks the added migration dependencies.
docs/specs/cch-multi-asset-swap.md Adds the multi-asset CCH spec and swap-acceptor protocol.
crates/fiber-types/src/lib.rs Re-exports new CCH proposal-related types.
crates/fiber-types/src/cch.rs Redefines CCH order/proposal domain types for multi-asset swaps.
crates/fiber-lib/src/store/.schema.json Updates persisted schema fingerprints for CCH type changes.
crates/fiber-lib/src/rpc/README.md Regenerates RPC docs for the new CCH APIs.
crates/fiber-lib/src/rpc/cch.rs Adds swap proposal RPC/subscription methods and CCH RPC timeout changes.
crates/fiber-lib/src/rpc/biscuit.rs Adds biscuit auth rules for operator acceptor RPCs.
crates/fiber-lib/src/cch/tests/state_machine_tests.rs Updates state-machine tests for the new CCH order fields.
crates/fiber-lib/src/cch/tests/scheduler_tests.rs Updates scheduler tests for the new CCH order layout.
crates/fiber-lib/src/cch/tests/dispatcher_tests.rs Updates dispatcher tests for the new CCH order layout.
crates/fiber-lib/src/cch/tests/actor_tests.rs Adds actor coverage for fixed-rate and proposal-path CCH behavior.
crates/fiber-lib/src/cch/mod.rs Exports new CCH acceptor/config types.
crates/fiber-lib/src/cch/error.rs Adds proposal-flow-specific CCH errors.
crates/fiber-lib/src/cch/config.rs Replaces single-asset config with allowlist, fixed-rate, and proposal-timeout config.
crates/fiber-lib/src/cch/actor.rs Implements multi-asset send/receive flows and operator proposal handling.
crates/fiber-lib/src/cch/acceptor.rs Implements proposal broadcast, response handling, and timeout logic.
crates/fiber-json-types/src/convert.rs Adds JSON conversion support for new CCH/proposal types.
crates/fiber-json-types/src/cch.rs Defines new JSON-RPC params/responses for multi-asset CCH.

Comment thread crates/fiber-lib/src/cch/actor.rs Outdated
Comment thread crates/fiber-lib/src/cch/actor.rs Outdated
Comment thread crates/fiber-lib/src/cch/actor.rs Outdated
Comment thread crates/fiber-lib/src/cch/actor.rs Outdated
Comment thread crates/fiber-lib/src/cch/actor.rs Outdated
Comment thread migrate/src/migrations/mig_20260421_cch_multi_asset.rs Outdated
Comment thread crates/fiber-lib/src/cch/acceptor.rs Outdated
Comment thread crates/fiber-lib/src/cch/actor.rs Outdated
Comment thread crates/fiber-lib/src/cch/actor.rs Outdated
Comment thread docs/specs/cch-multi-asset-swap.md
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch 4 times, most recently from fe29f52 to f88f69a Compare June 3, 2026 00:14
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch 2 times, most recently from 761dcef to 6e4691b Compare June 10, 2026 07:03
@doitian doitian marked this pull request as draft June 10, 2026 07:03
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch from 6e4691b to 528c50a Compare June 10, 2026 07:13
@chainTe

chainTe commented Jun 11, 2026

Copy link
Copy Markdown

Security Review

Result: 1 confirmed finding
Reviewed range: 3bbf5ea0ed7debd83a707b5f28264bee2fd7371f..528c50a074a4ecde3df5335daccaa685d93ecb07

Validation:

  • Existing broad tests were not run locally; CI is expected to cover them.
  • Performed a diff-focused review of the CCH multi-asset flow, RPC authorization, CCH migration, watchtower change, and in-flight CKB transaction handling.

Notes:

  • crates/fiber-lib/src/fiber/in_flight_ckb_tx_actor.rs now treats CKB RPC -301 TransactionFailedToResolve as a permanent rejection and reports ReportRejected without first checking whether the tx is already committed. The previous guard documented that rebroadcasting an already-committed tx can return -301 because its inputs are spent. For funding txs, this can flow to FundingTransactionFailed and abort_funding, so an already-committed funding tx can be locally abandoned before the committed trace is processed.
  • Suggested fix: before converting -301 into rejection, query get_transaction(tx_hash) and defer to the tracer or report committed status when the tx is already committed.

@doitian doitian force-pushed the feat/cch-multi-asset-swap branch 7 times, most recently from b35547a to 6a3af83 Compare June 15, 2026 11:03
@doitian doitian marked this pull request as ready for review June 15, 2026 11:07
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch 4 times, most recently from 8ba6f6b to d8de227 Compare June 16, 2026 04:48
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch 8 times, most recently from 8c2e4ea to e775bc7 Compare June 18, 2026 11:29
@doitian doitian changed the title feat: CCH multi-asset swap feat!(cch): CCH multi-asset swap Jun 18, 2026
- Reshape CchOrder struct to support multiple Fiber-side assets
  * Replace `wrapped_btc_type_script: Script` with `fiber_type_script: Option<Script>`
  * Support both native CKB and allowlisted UDT assets
  * Separate BTC and Fiber amount fields with proper units
- Implement per-asset fixed exchange rates
- Add fiber-asset allowlist validation
- Add CCH swap acceptor protocol implementation
- Update RPC types and APIs to expose multi-asset swap capabilities
- Update configuration to support multi-asset allowlist
@doitian doitian force-pushed the feat/cch-multi-asset-swap branch from e775bc7 to 8f6064a Compare June 22, 2026 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants