跳至主要內容
高級

Pathfinding 路徑搜索

深入了解閃電網路的路徑搜索演算法,如何在去中心化網路中找到最佳支付路徑。

15 分鐘

什麼是路徑搜索?

路徑搜索(Pathfinding)是在閃電網路中找到從發送方到接收方的支付路徑的過程。 由於網路是去中心化的,每個節點只知道公開的網路圖和自己的私有通道信息, 必須使用演算法在有限信息下找到可行且低成本的路徑。

挑戰: 路徑搜索不只是找到最短路徑。需要考慮費用、容量限制、可靠性、時間鎖等多個因素, 且通道餘額是動態變化且部分未知的。

網路圖結構

Lightning Network Graph Structure:

Nodes (Vertices):
  - Each Lightning node is a vertex
  - Identified by 33-byte public key
  - Announced via node_announcement message

Edges:
  - Each public channel is an edge
  - Actually bidirectional (each direction independent)
  - Announced via channel_announcement
  - Updated via channel_update

Edge Properties:
  short_channel_id: channel identifier
  capacity: total capacity (known)
  balance: each party's balance (unknown!)

  Per-direction parameters:
    - base_fee: base fee
    - fee_rate: proportional fee (ppm)
    - cltv_delta: timelock delta
    - htlc_min: minimum HTLC
    - htlc_max: maximum HTLC

Typical Network Size (2024):
  - Nodes: ~15,000
  - Channels: ~50,000
  - Total capacity: ~5,000 BTC
  - Graph size: ~10MB

基礎演算法

Dijkstra Algorithm Variant:

Basic Idea:
Find lowest "cost" path from source to target

Cost Function Design:
cost(edge) = f(fee, probability, time_lock, ...)

LND Cost Function Example:
cost = fee
     + amount * risk_factor * cltv_delta
     + amount * (1 - success_probability) * penalty

Parameters:
  - fee: direct fee cost
  - risk_factor: time value (fund locking cost)
  - cltv_delta: timelock increase for this hop
  - success_probability: historical success estimate
  - penalty: failure penalty factor

Algorithm Flow:
  1. Search backwards from target (more efficient)
  2. Maintain priority queue (sorted by cost)
  3. Pop lowest cost node each time
  4. Update optimal path for neighbor nodes
  5. Until reaching source node

Pseudocode:
function dijkstra(source, target, amount):
  dist[target] = 0
  queue.add(target, 0)

  while queue not empty:
    node = queue.pop_min()

    for edge in node.incoming_edges:
      if can_forward(edge, amount):
        new_cost = dist[node] + edge_cost(edge, amount)
        if new_cost < dist[edge.source]:
          dist[edge.source] = new_cost
          prev[edge.source] = edge
          queue.update(edge.source, new_cost)

  return reconstruct_path(prev, source, target)

容量不確定性

Channel Balance Uncertainty:

Problem:
  - Only know total capacity, not individual balances
  - Balances change in real-time
  - Selected path may fail due to insufficient balance

Example:
Channel capacity: 1 BTC
Possible balance distributions:
  - Alice: 0.0 BTC, Bob: 1.0 BTC
  - Alice: 0.3 BTC, Bob: 0.7 BTC
  - Alice: 0.5 BTC, Bob: 0.5 BTC
  - Alice: 1.0 BTC, Bob: 0.0 BTC
  - Any value in between...

Probability Model:
Assume balance uniformly distributed in [0, capacity]

P(can_forward amount) = (capacity - amount) / capacity

amount = 0.1 BTC, capacity = 1 BTC
P(success) = 0.9 (90%)

amount = 0.9 BTC, capacity = 1 BTC
P(success) = 0.1 (10%)

Multi-hop Success Rate:
P(path success) = P(hop1) * P(hop2) * ... * P(hopN)

3-hop path, 90% success rate each hop:
P(success) = 0.9^3 = 0.729 (73%)

This is why large payments often fail!

任務控制

Mission Control (LND's Learning Mechanism):

Concept: Learn path reliability from payment history

Recording Each Attempt:

  Payment Attempt #1:
    Path: A -> B -> C -> D
    Result: Failed at B->C (TEMPORARY_CHANNEL_FAILURE)
    Learned: B->C may have insufficient balance

  Payment Attempt #2:
    Path: A -> E -> F -> D (avoiding B->C)
    Result: Success
    Learned: E->F->D path is reliable

Mission Control Data Structure:
{
  "node_pairs": {
    "B->C": {
      "last_fail_time": "2024-01-01T12:00:00Z",
      "fail_amount": 100000,
      "success_amount": 50000
    }
  }
}

Success Rate Estimation Update:
if (amount > fail_amount):
  P(success) = 0  // will definitely fail
else if (amount <= success_amount):
  P(success) = high  // likely to succeed
else:
  P(success) = interpolate(...)

Decay Mechanism:
  - Old data weight decreases (balances change)
  - Retry failed paths after some time
  - Typical decay time: 1-24 hours

多路徑搜索

MPP Path Finding:

Problem: How to find multiple paths that work together?

Method 1: Greedy Split
  1. Find best single path, allocate max possible amount
  2. Repeat on residual graph
  3. Until total amount satisfied

Method 2: Min-Cost Flow
  - Model as network flow problem
  - Capacity = estimated available balance
  - Cost = fee + risk
  - Solve minimum cost maximum flow

Method 3: Opportunistic
  1. Try single path for full amount
  2. If fails, halve amount and retry
  3. Recursively split until success or give up

LND's Approach:
  1. Compute multiple candidate paths (K shortest paths)
  2. Evaluate success probability and cost for each path
  3. Select optimal combination (lowest total cost with
     sufficient probability)
  4. Send shards in parallel
  5. Re-route failed shards

優化技術

圖剪枝

移除明顯不可行的邊(容量太小、費率太高、節點離線)。 減少搜索空間,加速計算。

A* 啟發式

使用啟發式函數估計剩餘成本,優先探索更有前途的路徑。 適用於大型網路。

路徑緩存

緩存常用目的地的路徑。定期刷新以反映網路變化。 注意緩存失效策略。

雙向搜索

如果知道接收方的私有通道信息(route hints),可以從兩端同時搜索, 在中間相遇。

Trampoline 路由

How Trampoline Routing Changes Path Finding:

Traditional Mode:
  - Sender maintains complete network graph
  - Sender computes full path
  - High computation cost, not mobile-friendly

Trampoline Mode:
  - Sender only knows a few Trampoline nodes
  - Sender computes path to Trampoline
  - Trampoline nodes compute subsequent paths
  - Greatly reduces sender's computation and storage

Path Finding Responsibility Distribution:

  Sender:
    -> Finds path to first Trampoline

  Trampoline 1:
    -> Finds path to Trampoline 2 (or destination)

  Trampoline 2:
    -> Finds path to final destination

See: /tech/lightning/trampoline

實現差異

LND

使用 Mission Control 學習機制,Dijkstra + A* 混合,支持 MPP 分片。 成本函數考慮費用、時間鎖、歷史成功率。

CLN

使用概率模型估計成功率,Dijkstra 變體,插件可擴展路徑選擇。 renepay 插件提供高級路徑搜索。

LDK

概率評分器(Probabilistic Scorer),可定制成本函數, 適合集成到各種應用中。

相關資源

下一步: 了解 多路徑支付 如何利用多條路徑提高大額支付的成功率。

已複製連結
已複製到剪貼簿