Skip to content

Conversation

@doitian
Copy link
Member

@doitian doitian commented Dec 9, 2025

Summary

Add comprehensive verification and validation for CCH cross-chain swaps to ensure swap safety and prevent failures due to expiry timing, hash mismatches, or incompatible invoice configurations.

Changes

Expiry Verification

  • Added validation in both send_btc and receive_btc flows to check that outgoing invoices have sufficient remaining expiry time
  • Introduced min_outgoing_invoice_expiry_delta_seconds config option (default: 6 hours) to control the minimum acceptable invoice expiry
  • Returns OutgoingInvoiceExpiryTooShort error when validation fails

Final Expiry Safety Validation

  • Ensures the outgoing invoice's final CLTV/TLC expiry is less than half of the incoming invoice's configured expiry, giving the CCH operator sufficient time to settle the incoming side before the outgoing side expires

Preimage and Hash Validation

  • Validates preimage matches payment hash when settling CCH orders
  • Validates wrapped BTC type script matches the invoice UDT type script
  • Validates hash algorithm is SHA256 for LND compatibility

Config Improvements

  • Renamed config fields with explicit units for clarity:
    • order_expiryorder_expiry_delta_seconds
    • btc_final_tlc_expirybtc_final_tlc_expiry_delta_blocks
    • ckb_final_tlc_expiry_deltackb_final_tlc_expiry_delta_seconds
  • Updated default values:
    • BTC final TLC expiry: 180 blocks (~30 hours)
    • CKB final TLC expiry: 30 hours

Order Structure

  • Simplified CchOrder by removing ckb_final_tlc_expiry_delta field
  • Renamed expires_after to expiry_delta_seconds for consistency

New Error Types

  • OutgoingInvoiceExpiryTooShort
  • CKBInvoiceExpired
  • BTCInvoiceFinalTlcExpiryDeltaTooSmall
  • CKBInvoiceFinalTlcExpiryDeltaTooSmall
  • PreimagePaymentHashMismatch
  • WrappedBtcTypeScriptMismatch
  • IncompatibleHashAlgorithm

Documentation

  • Added docs/specs/cch-expiry-dependency.md explaining CCH expiry configuration and default behavior

@doitian doitian force-pushed the feature/cch-verifications branch from 1fa8070 to 380ecd4 Compare December 15, 2025 04:31
@doitian doitian mentioned this pull request Dec 17, 2025
9 tasks
@doitian doitian force-pushed the feature/cch-verifications branch 3 times, most recently from a131964 to 9f536e9 Compare December 29, 2025 03:47
doitian added 10 commits January 6, 2026 13:22
- Implement a state machine for CCH orders to manage transitions based on incoming invoice and outgoing payment events.
- Introduce action dispatchers for handling various order actions, such as sending payments and settling invoices.
- Refactor existing code to improve modularity and maintainability, including the separation of event handling and order state management.
- For sending BTC from fiber to lnd, check the fiber payment has been settled successfully.
- For receiving BTC from lnd to fiber, check the lnd payment has been settled successfully.

Closes nervosnetwork#952
This change improves error handling in CCH (Cross-Chain Hub) actions by
distinguishing between permanent and transient errors when sending
payments or settling invoices. Permanent failures now result in order
state transitions with detailed failure reasons, while transient errors
are retried. Additionally, the `tonic` crate is added as a dependency to
handle gRPC status codes from LND.

The tracking events and state machine are updated to carry optional
failure reasons, enabling better diagnostics and more precise order
status management. Orders in final states now skip redundant tracking
events to avoid unnecessary processing.
Replaces the fixed 1-second retry delay with exponential backoff to
reduce load during persistent failures and improve recovery behavior.
Delays start at 1 second and double on each retry, capped at 10 minutes.
- Make cch order db operations synchronous
- Added helper methods `get_order_or_none `and
  `get_active_order_or_none` to CchState to reduce code duplication and
  centralize the common pattern of handling NotFound errors vs other
  errors. This also eliminates redundant final status checks.
Introduce a 1-second delay after detecting successful payment receipt in
end-to-end tests to ensure downstream processes have sufficient time to
stabilize before proceeding.
- CCH now validates that outgoing invoices have sufficient remaining expiry
time before accepting swaps, preventing swaps that might fail due to
invoice expiration during settlement.
- The minimal final hot TLC expiry is correctly set on incoming invoice.
- Config fields are renamed with explicit units (seconds/blocks) for clarity.
Ensures the outgoing invoice's final CLTV/TLC expiry is less than half of
the incoming invoice's configured expiry, giving the CCH operator sufficient
time to settle the incoming side before the outgoing side expires.
- Introduced a new error variant for incompatible preimage and payment hash
- Implemented preimage hash verification in the CchOrderStateMachine to ensure the computed hash matches the expected payment hash, enhancing the integrity of payment processing
- Introduced new error variants for wrapped BTC type script mismatch and incompatible hash algorithm.
- Added checks to ensure the wrapped BTC type script matches the invoice UDT type script.
- Validated that the hash algorithm used in invoices is SHA256 for compatibility with LND.
The assertions should verify that the receiver has received the payment.
It is incorrect to check the sender's balance, as the payment may still
be in flight and thus not yet reflected in either the sender's or the
receiver's balance.
Added an additional error return for wrapped BTC typescript mismatch to ensure the invoice must have a configured typescript.
@doitian doitian force-pushed the feature/cch-verifications branch from 9f536e9 to d63b09d Compare January 6, 2026 05:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants