高級
TLV Streams TLV 編碼
了解閃電網路中廣泛使用的 Type-Length-Value 編碼格式,實現協議的可擴展性。
8 分鐘
什麼是 TLV?
TLV(Type-Length-Value)是閃電網路訊息中使用的可擴展編碼格式。 它允許在不破壞向後相容性的情況下添加新欄位,是協議演進的基礎。
可擴展性: TLV 讓新版本可以添加欄位,舊版本會忽略不認識的 type。 這是閃電網路平滑升級的關鍵。
TLV 格式
TLV 記錄結構: 單個 TLV 記錄: +-------------+-------------+-----------------------------+ | Type | Length | Value | | (BigSize) | (BigSize) | (Length bytes) | +-------------+-------------+-----------------------------+ Type:識別這是什麼欄位 Length:Value 的位元組長度 Value:實際資料 TLV Stream(多個記錄): +---------+ +---------+ +---------+ +---------+ | TLV 1 | | TLV 2 | | TLV 3 | | ... | +---------+ +---------+ +---------+ +---------+ 規則: • Type 必須嚴格遞增 • 不允許重複的 Type • 未知 Type 的處理取決於奇偶性
BigSize 編碼
BigSize 變長整數編碼: Encoding Rules: Range Format 0x00 - 0xFC 1 byte: direct value 0xFD - 0xFFFF 3 bytes: 0xFD + 2 bytes (big-endian) 0x10000 - 0xFFFFFFFF 5 bytes: 0xFE + 4 bytes (big-endian) > 0xFFFFFFFF 9 bytes: 0xFF + 8 bytes (big-endian) Encoding Examples: Value Encoding (hex) 0 00 252 FC 253 FD 00 FD 65535 FD FF FF 65536 FE 00 01 00 00 4294967295 FE FF FF FF FF 4294967296 FF 00 00 00 01 00 00 00 00 最小編碼規則: • 必須使用能表示該值的最短形式 • 非最小編碼是無效的 • 這防止了編碼歧義
Type 規則
Type 奇偶規則: 未知 Type 處理: 偶數 Type(even): • 「必須理解」 • 如果不認識,必須拒絕整個訊息 • 用於關鍵欄位 奇數 Type(odd): • 「可以忽略」 • 如果不認識,可以安全忽略 • 用於可選欄位 範例: Type 2(偶數):payment_hash -> 必須理解,否則無法處理支付 Type 3(奇數):payment_metadata -> 可選,舊版本可以忽略 Type 8(偶數):payment_secret -> MPP 必需,不認識就拒絕 Type 排序: • 所有 Type 必須嚴格遞增 • 確保解析效率 • 允許快速跳過不需要的欄位
洋蔥 Payload TLV
洋蔥路由 payload 中的 TLV: Standard TLV Types: Type Name Description 2 amt_to_forward 轉發金額(msat) 4 outgoing_cltv_value 出站 CLTV 6 short_channel_id 下一跳通道 ID 8 payment_data 支付資料(最終跳) 10 encrypted_recipient_data 盲化路徑加密資料 12 blinding_point 盲化點 16 payment_metadata 支付元資料 18 total_amount_msat MPP 總金額 payment_data 結構(Type 8): • payment_secret: 32 bytes • total_msat: 8 bytes(TU64) 用於 MPP 支付的最終跳 中繼 vs 最終跳: 中繼節點 payload: • amt_to_forward(必需) • outgoing_cltv_value(必需) • short_channel_id(必需) 最終節點 payload: • amt_to_forward(必需) • outgoing_cltv_value(必需) • payment_data(MPP 必需) • payment_metadata(可選)
訊息中的 TLV
常見訊息的 TLV 欄位: open_channel2 TLV: Type Name Description 0 upfront_shutdown_script 預設關閉腳本 1 channel_type 通道類型 2 require_confirmed_inputs 要求確認輸入 node_announcement TLV: Type Name Description 1 will_fund 流動性廣告條款 invoice TLV (BOLT 12): Type Name Description 0 chains 支援的區塊鏈 2 offer_id Offer 識別符 4 amount 金額 6 description 描述 8 features 功能位 10 paths 盲化路徑 ... ... ...
解析範例
TLV 解析示範:
原始資料(十六進位):
02 08 00000000000003E8
04 04 00028F5C
06 08 018A8B0000040000
解析過程:
TLV 1:
Type: 02(amt_to_forward)
Length: 08(8 bytes)
Value: 00000000000003E8(1000 msat)
TLV 2:
Type: 04(outgoing_cltv_value)
Length: 04(4 bytes)
Value: 00028F5C(167772)
TLV 3:
Type: 06(short_channel_id)
Length: 08(8 bytes)
Value: 018A8B0000040000(block:tx:output 編碼)
JavaScript 解析:
function parseTLV(buffer) {
const records = [];
let offset = 0;
while (offset < buffer.length) {
const type = readBigSize(buffer, offset);
offset += bigSizeLength(type);
const length = readBigSize(buffer, offset);
offset += bigSizeLength(length);
const value = buffer.slice(offset, offset + length);
offset += length;
records.push({ type, length, value });
}
return records;
} 向後相容
奇數 Type 可被舊版本忽略,新功能可以安全添加 而不破壞現有實現。
高效解析
Type 遞增順序允許單次掃描解析, BigSize 編碼最小化開銷。
驗證重要: 解析 TLV 時必須驗證 Type 嚴格遞增、BigSize 使用最小編碼、 偶數未知 Type 必須拒絕。
相關資源
- • BOLT 1 TLV 規範
- • BOLT 訊息協議
- • 洋蔥路由
下一步: 了解 Onion Messages 如何使用 TLV 傳遞任意訊息。
已複製連結