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:
- 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
- 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
- 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 2 | Phase 3 |
|---|---|
| Internal test suite | Cross-implementation testing with CLN & LND |
| RGB-to-RGB channels | RGB node β standard LN nodes (BTC channels) |
| Protocol correctness | BOLT wire format compliance |
| Edge case safety | Gossip, multi-hop routing, MPP interop |
| Single codebase validation | 1,002 LDK state machine tests restored (1,019 total) |
| Happy-path reliability | Fuzzing + 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 theseWhen 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:
| Message | RGB Field | TLV Type |
|---|---|---|
| OpenChannel / OpenChannelV2 | rgb_context_data | 827167 |
| UpdateAddHTLC | rgb_amount | 827167 |
| Onion Payload (Forward / Receive) | rgb_amount_to_forward | 827167 |
| ChannelAnnouncement | rgb_asset_id | 827167 |
| ChannelUpdate | rgb_htlc_maximum | 827167 |
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
getinfofeatures hex (byte position 103, bit 3) - LND:
describegraphshowsbit 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
| Test | Direction | Verification |
|---|---|---|
peer_connect_rgb_to_cln | RGB β CLN | Noise handshake + Init exchange + feature negotiation |
peer_connect_rgb_to_lnd | RGB β LND | Same, with feature bit 827 acknowledged |
P1 β Channel Layer (Pure BTC)
| Test | Direction | Verification |
|---|---|---|
btc_channel_open_rgb_to_cln | RGB opens β CLN | OpenChannel β AcceptChannel β FundingTx β ChannelReady |
btc_channel_open_rgb_to_lnd | RGB opens β LND | Same flow, LND as acceptor |
P2 β Payment Layer (Pure BTC)
| Test | Direction | Verification |
|---|---|---|
btc_pay_rgb_to_cln | RGB β CLN | Bidirectional: RGBβCLN send + CLNβRGB receive |
btc_pay_rgb_to_lnd | RGB β LND | Bidirectional: RGBβLND send + LNDβRGB receive |
keysend_rgb_to_lnd | RGB β LND | Spontaneous payment (no invoice) |
P3 β Gossip Layer
| Test | Verification |
|---|---|
gossip_channel_announcement_rgb_to_cln | Channel announcement propagation + channel_update exchange |
P4 β Advanced Routing
| Test | Topology | Verification |
|---|---|---|
multihop_rgb_via_lnd_to_cln | RGB β LND β CLN | Three-node routing with gossip propagation |
mpp_rgb_to_lnd_2paths | RGB β LND (direct) + RGB β CLN β LND | Multi-path payment splitting across 2 routes |
P5 β Fault Tolerance
| Test | Verification |
|---|---|
reconnect_after_disconnect_cln | channel_reestablish after TCP disconnect |
force_close_rgb_then_sweep_cln | Unilateral 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
| Metric | Value |
|---|---|
| LDK state machine tests restored | 1,002 (1,019 total passing) |
| Bugs found and fixed | 6 |
| Interop test scenarios | 12 |
| Cross-implementation pass rate | 100% (consecutive rounds, same environment) |
| Implementations tested | CLN v23.08, LND v0.18.5 |
| Wire format changes | 5 messages migrated to TLV 827167 (odd) |
| Feature bits registered | 826/827 (rgb_channel) |
| Fuzz sequences executed | 1,000+ (zero asset conservation violations) |
What Phase 3 Proved
- 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
- Zero regression: 1,019 LDK tests pass (1,002 restored) with RGB modifications β native Lightning functionality is fully intact
- Feature isolation: RGB-specific data travels in odd TLV extensions that standard nodes silently ignore, ensuring forward compatibility
- Production topology: Multi-hop routing and MPP work across heterogeneous node implementations (LDK, CLN, LND)
- 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.