Bitlight Labs Blog
Lightning RGB Phase 3: From Feature Complete to Production Interoperability

Phase 3: RGB Lightning Integration Testing - From Feature Complete to Production Interoperability

1. Overview

Phase 3 marks the transition from internal validation to real-world network participation. We addressed three core objectives:

  1. BOLT-Compliant Interoperability: Prove that RGB-LDK nodes are not isolated β€” they follow BOLT standards, speak the same wire protocol, and can open channels, route payments, and exchange gossip with any standard Lightning node on the network
  2. Zero Regression: Ensure that RGB protocol extensions introduce no regressions to the underlying Lightning implementation β€” validated by restoring 1,002 previously disabled LDK state machine tests, bringing the total to 1,019 passing
  3. Reliability Under Stress: Evaluate system behavior under adversarial conditions through fuzzing (randomized payment sequences) and chaos testing (node crashes during in-flight HTLCs)

Through TDD methodology, we discovered and fixed 6 bugs in the RGB integration layer, migrated all RGB wire fields to BOLT-compliant TLV extensions, and built a Docker-based interop framework validating 12 cross-implementation scenarios against CLN v23.08 and LND v0.18.5.


2. Phase 2 Recap and Phase 3 Objectives

Phase 2 Achievements

Phase 2 validated RGB safety in edge cases:

  • All RGB edge case tests passed: Force close recovery, HTLC fail/timeout asset safety
  • RGB_OFFSET_V2: Dynamic balance calculation mechanism solving state asymmetry
  • RGB↔BTC Swap: Atomic exchange feature with full lifecycle validation
  • Native LN compatibility: 9 BTC baseline tests + advanced features (BOLT 12, BIP 21, LSPS2, Anchor Outputs)

Phase 3 Focus Shift

Phase 2 answered "is it safe?", Phase 3 answers "can it participate in the real Lightning Network?":

Phase 2Phase 3
Internal test suiteCross-implementation testing with CLN & LND
RGB-to-RGB channelsRGB node ↔ standard LN nodes (BTC channels)
Protocol correctnessBOLT wire format compliance
Edge case safetyGossip, multi-hop routing, MPP interop
Single codebase validation1,002 LDK state machine tests restored (1,019 total)
Happy-path reliabilityFuzzing + chaos engineering

3. LDK State Machine Test Restoration

RGB integration modifies LDK core code across commitment transactions, HTLC processing, channel state management, and wire serialization. Before claiming interoperability, we must prove these modifications introduce zero regression to existing Lightning behavior.

Scale of Validation

We restored and executed the complete LDK test suite across 4 crates:

1,002 previously disabled tests restored and passing, bringing the total to 1,019 tests passed, 0 failed, 0 ignored.

This covers the full spectrum of LDK's protocol state machine: channel lifecycle, HTLC forwarding, commitment revocation, persistence recovery, background processing, and DNS resolution.

Issues Discovered Through TDD

The test restoration process uncovered 6 issues in the RGB integration layer, falling into three categories:

Serialization gaps β€” RGB-specific fields (HTLC amounts, channel context) were not persisted correctly, causing data loss on node restart and deserialization failures on channel restore.

Routing calculation errors β€” RGB fee accumulation was skipped for blinded paths, MPP splits used the total payment amount instead of per-path values, and retry paths calculated HTLC amounts as zero.

TLV type conflicts β€” RGB TLV types initially overlapped with BOLT-reserved ranges, producing onion packets that standard nodes would reject.

These weren't bugs in working features β€” they were protocol capabilities that hadn't been implemented yet. The TDD approach identified all 6 before they could reach production.


4. Wire Format TLV Migration

The Compatibility Problem

The original RGB implementation embedded asset fields inline in Lightning wire messages:

Original: OpenChannel { ..., asset_id: Option<AssetId>, color_context_data: Option<...> }
                              ^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^
                              Inline fields β€” standard nodes reject these

When Option::None is serialized, it writes 0x00, which standard nodes interpret as TLV type 0 (even type = must-understand β†’ connection rejected).

The Solution: Odd TLV Types

All RGB fields were migrated to odd TLV types (β‰₯ 827167), derived from SLIP-0044 coin type for RGB:

MessageRGB FieldTLV Type
OpenChannel / OpenChannelV2rgb_context_data827167
UpdateAddHTLCrgb_amount827167
Onion Payload (Forward / Receive)rgb_amount_to_forward827167
ChannelAnnouncementrgb_asset_id827167
ChannelUpdatergb_htlc_maximum827167

All RGB extensions share a single TLV type 827167 (odd), derived from SLIP-0044. Per BOLT #1, odd TLV types are "unknown but okay" β€” standard nodes silently ignore them instead of disconnecting.

Feature Bit Registration

RGB channel support is advertised via Feature Bit 826/827:

  • Bit 826 (even): Required β€” "I require RGB channel support"
  • Bit 827 (odd): Optional β€” "I support RGB channels, but don't require peers to"

Verification confirmed both CLN and LND correctly handle bit 827:

  • CLN: Visible in getinfo features hex (byte position 103, bit 3)
  • LND: describegraph shows bit 827: name=unknown, known=False β€” acknowledged but ignored

Breaking Change Notice

The TLV migration introduces a wire-incompatible change with previously released versions. Nodes running the old inline format cannot communicate with nodes running the new TLV format β€” channel opens will fail.

Users upgrading from pre-TLV releases must:

  • Deploy all nodes with the latest image simultaneously
  • Do not mix old and new versions in the same channel network
  • Existing channels opened with the old format need to be closed and re-opened after upgrade

5. Cross-Implementation Interoperability Testing

Docker Test Environment

We built a unified Docker Compose environment for reproducible interop testing:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Docker regtest network        β”‚
β”‚                172.30.0.0/24               β”‚
β”‚                                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚ bitcoind β”‚  β”‚  electrs β”‚  β”‚  miner   β”‚  β”‚
β”‚  β”‚  :18443  β”‚  β”‚  :3000   β”‚  β”‚(one-shot)β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   CLN    β”‚  β”‚   LND    β”‚  β”‚ rgb-ldk  β”‚  β”‚
β”‚  β”‚ v23.08   β”‚  β”‚ v0.18.5  β”‚  β”‚  node    β”‚  β”‚
β”‚  β”‚  :9735   β”‚  β”‚  :9735   β”‚  β”‚  :9735   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Test Matrix: 12 Scenarios, 100% Pass Rate

P0 β€” Peer Layer

TestDirectionVerification
peer_connect_rgb_to_clnRGB β†’ CLNNoise handshake + Init exchange + feature negotiation
peer_connect_rgb_to_lndRGB β†’ LNDSame, with feature bit 827 acknowledged

P1 β€” Channel Layer (Pure BTC)

TestDirectionVerification
btc_channel_open_rgb_to_clnRGB opens β†’ CLNOpenChannel β†’ AcceptChannel β†’ FundingTx β†’ ChannelReady
btc_channel_open_rgb_to_lndRGB opens β†’ LNDSame flow, LND as acceptor

P2 β€” Payment Layer (Pure BTC)

TestDirectionVerification
btc_pay_rgb_to_clnRGB ↔ CLNBidirectional: RGBβ†’CLN send + CLNβ†’RGB receive
btc_pay_rgb_to_lndRGB ↔ LNDBidirectional: RGBβ†’LND send + LNDβ†’RGB receive
keysend_rgb_to_lndRGB β†’ LNDSpontaneous payment (no invoice)

P3 β€” Gossip Layer

TestVerification
gossip_channel_announcement_rgb_to_clnChannel announcement propagation + channel_update exchange

P4 β€” Advanced Routing

TestTopologyVerification
multihop_rgb_via_lnd_to_clnRGB β†’ LND β†’ CLNThree-node routing with gossip propagation
mpp_rgb_to_lnd_2pathsRGB β†’ LND (direct) + RGB β†’ CLN β†’ LNDMulti-path payment splitting across 2 routes

P5 β€” Fault Tolerance

TestVerification
reconnect_after_disconnect_clnchannel_reestablish after TCP disconnect
force_close_rgb_then_sweep_clnUnilateral close + on-chain sweep recovery

All 12 scenarios pass consistently across consecutive test rounds in the same Docker environment, with proper channel lifecycle management ensuring no state leakage between tests.


6. Reliability Engineering: Fuzzing and Chaos Testing

Beyond functional correctness, Phase 3 evaluated system behavior under stress and adversarial conditions.

Fuzzing: Randomized Payment Sequences

We implemented seed-based fuzz testing for the RGB multi-hop payment path, randomizing:

  • Payment amounts (boundary values: minimum dust, near-channel-capacity)
  • Payment outcomes (success / fail / timeout interleaving)
  • Multi-hop routing paths (3-node topology with random forwarding)

Key invariant: Asset conservation β€” sum(all_rgb_balances) == initial_rgb_total must hold after every operation sequence, regardless of intermediate failures.

Over 1,000+ randomized sequences executed with zero asset conservation violations.

Chaos Testing: Node Crash Recovery

We conducted controlled chaos experiments simulating node crashes during in-flight HTLCs β€” the most dangerous moment for state consistency, as both BTC commitments and RGB overlay data must remain synchronized.

Chaos testing revealed that abrupt node termination can lead to persistence layer inconsistencies between the Lightning channel state and RGB overlay data. This is a known challenge shared across Lightning implementations β€” the fundamental tension between performance (batched writes) and durability (immediate persistence) under crash scenarios.

This finding has been documented and is tracked as a long-term reliability engineering effort, requiring careful coordination between LDK's persistence model and RGB state management. The value of chaos testing is precisely in surfacing these risks under controlled conditions, establishing clear boundaries of what the system can and cannot guarantee today.


7. Technical Summary

Validation Results

MetricValue
LDK state machine tests restored1,002 (1,019 total passing)
Bugs found and fixed6
Interop test scenarios12
Cross-implementation pass rate100% (consecutive rounds, same environment)
Implementations testedCLN v23.08, LND v0.18.5
Wire format changes5 messages migrated to TLV 827167 (odd)
Feature bits registered826/827 (rgb_channel)
Fuzz sequences executed1,000+ (zero asset conservation violations)

What Phase 3 Proved

  1. BOLT compliance: RGB-LDK nodes follow the Lightning wire protocol standard. They are not isolated β€” they can join the existing network, open channels, route payments, and exchange gossip with any BOLT-compliant node
  2. Zero regression: 1,019 LDK tests pass (1,002 restored) with RGB modifications β€” native Lightning functionality is fully intact
  3. Feature isolation: RGB-specific data travels in odd TLV extensions that standard nodes silently ignore, ensuring forward compatibility
  4. Production topology: Multi-hop routing and MPP work across heterogeneous node implementations (LDK, CLN, LND)
  5. Known boundaries: Chaos testing established clear reliability boundaries, identifying persistence consistency under crash scenarios as a long-term engineering focus

8. What's Next

Phase 3's completion marks RGB Lightning integration's transition from "feature complete" to "network compatible". RGB-LDK nodes can now participate in the real Lightning Network alongside CLN and LND.

Going forward, development enters a continuous iteration cycle:

  • Community feedback: Collecting and addressing issues from early adopters and integration partners
  • Feature development: Continued RGB protocol enhancements driven by real-world usage patterns
  • Upstream compatibility: Maintaining alignment with LDK, CLN, and LND upstream releases as the Lightning ecosystem evolves

The foundation is in place for bringing tokenized assets to Lightning's global payment network.