라이트닝 여러 홉 결제에서 각 channel은 같은 payment hash에 묶인 incoming·outgoing HTLC를 추가합니다. 수신자가 preimage를 공개하면 마지막 hop부터 거꾸로 각 중간 node가 outgoing HTLC를 청구하고 그 preimage로 incoming HTLC를 청구합니다. Preimage가 없으면 expiry 뒤 timeout됩니다. 각 upstream expiry는 downstream보다 길고 incoming amount는 forwarding fee만큼 커야 중간 node가 downstream을 지급하고도 upstream을 회수할 시간과 금액을 확보합니다.
Hash lock이 지급 조건을 연결합니다
수신자는 32바이트 payment preimage R을 만들고 H=SHA256(R)을 invoice에 포함합니다. Sender가 만든 각 update_add_htlc는 amount_msat, payment_hash H, cltv_expiry와 onion packet을 담습니다. 중간 node는 R을 모르므로 조건 없이 outgoing 자금을 가져갈 수 없습니다.
수신자가 유효한 R을 제시하면 SHA256(R)=H를 각 hop이 확인합니다. update_fulfill_htlc가 역방향으로 전파되면서 R은 되돌릴 수 없는 지식이 됩니다. BOLT2는 outgoing fulfill을 받은 node가 대응 incoming HTLC도 fulfill해야 한다고 규정합니다.
HTLC의 원자성은 한 번 공개된 같은 preimage가 경로 전체의 청구 조건을 동시에 풀어 주는 데서 나옵니다.
JOBCOIN 해설

그림은 이 주제의 공통 개념을 단순화한 설명입니다. 아래 항목에서 이 글의 구체적인 조건과 예외를 함께 읽어보세요.
- Hash lock이 지급 조건을 연결합니다
수신자는 32바이트 payment preimage R을 만들고 H=SHA256(R)을 invoice에 포함합니다.
- 시간 잠금은 홉마다 계단처럼 줄어듭니다
A→B→C 경로에서 B가 C에게 준 outgoing HTLC expiry는 A에게 받은 incoming expiry보다 이릅니다.
- Commitment 반영 전에는 forward하지 않습니다
Message를 받았다는 사실만으로 channel state가 확정된 것은 아닙니다.
AI로 제작한 개념도 · 실제 가격·거래 내역·통계가 아닙니다.
시간 잠금은 홉마다 계단처럼 줄어듭니다
A→B→C 경로에서 B가 C에게 준 outgoing HTLC expiry는 A에게 받은 incoming expiry보다 이릅니다. C가 마지막 순간 on-chain으로 R을 공개해도 B가 이를 보고 A 쪽 HTLC를 청구할 시간이 남아야 합니다. 차이는 B가 outgoing channel에 광고한 cltv_expiry_delta를 반영합니다.
BOLT2는 incoming expiry와 current height 차이가 outgoing delta보다 작으면 forward하지 말라고 요구합니다. Recipient도 min_final_cltv_expiry_delta를 요구합니다. Block interval·reorg·on-chain confirmation 지연 때문에 단순 wall-clock 초로 바꾸지 않습니다.
| 항목 | Incoming A→B | Outgoing B→C |
|---|---|---|
| Payment hash | H | 같은 H |
| Amount | 더 큼 | fee를 뺀 금액 |
| Expiry | 더 늦음 | 더 이름 |
| 성공 조건 | R로 청구 | R로 지급 |
| Timeout | A가 환불 가능 | B가 환불 가능 |
Commitment 반영 전에는 forward하지 않습니다
Message를 받았다는 사실만으로 channel state가 확정된 것은 아닙니다. HTLC 추가는 양쪽 commitment transactions에 반영되고 이전 상태가 revoked되는 update dance를 거쳐 irrevocably committed가 됩니다. BOLT2는 incoming HTLC가 확정되기 전 대응 outgoing HTLC를 offer하지 말라고 합니다.
이 순서를 어기면 중간 node가 upstream에서 받을 권리를 확보하기 전에 downstream에 지급할 수 있습니다. 구현은 update_add_htlc, commitment_signed, revoke_and_ack 상태를 channel별로 영속화하고 crash recovery 후 중복 fulfill·fail을 막습니다.
- Invoice의 payment hash·amount·expiry를 확인합니다.
- Route 각 hop의 fee와 CLTV delta를 누적합니다.
- Incoming HTLC commitment 확정을 기다립니다.
- Onion payload대로 outgoing HTLC를 제안합니다.
- Preimage 또는 timeout을 역방향으로 정산합니다.
On-chain 전환은 원자성을 강제하는 최후 수단입니다
Peer가 응답하지 않으면 최신 commitment transaction을 broadcast하고 HTLC-success 또는 HTLC-timeout path를 사용합니다. Preimage가 chain witness에 나타나면 upstream node도 이를 추출해 청구할 수 있습니다. Deadline 전에 transaction이 충분히 confirm될 fee와 안전 margin이 필요합니다.
작은 HTLC는 commitment에서 dust로 trimmed되어 별도 output이 없을 수 있습니다. Force close 때 miner fee로 처리될 exposure를 max_dust_htlc_exposure_msat 같은 local policy로 제한합니다. 모든 HTLC가 독립 on-chain output으로 보장된다고 설명하지 않습니다.
결제 실패는 어느 조건에서 막혔는지 분류합니다
Temporary channel failure, insufficient liquidity, fee·CLTV mismatch, malformed onion, expiry too soon은 서로 다른 재시도 의미를 가집니다. Sender는 encrypted failure를 복호화해 실패 hop을 추정하고 route를 바꾸지만 반복 probing이 privacy를 누설할 수 있습니다.
MPP는 같은 payment secret과 total amount 조건 아래 여러 HTLC parts를 모을 수 있지만 각 part의 성공·timeout 상태를 추적해야 합니다. UI는 payment pending, succeeded, failed와 개별 attempts를 구분하고 invoice가 만료됐다고 이미 committed HTLC를 즉시 취소된 것으로 처리하지 않습니다.
자주 묻는 질문
중간 노드는 수신자의 preimage를 미리 아나요?
아닙니다. 수신자가 fulfill할 때 공개되고 역방향으로 전달됩니다.
모든 hop의 CLTV expiry가 같아도 되나요?
안 됩니다. 중간 node가 downstream 청구 후 upstream을 회수할 안전 delta가 필요합니다.
HTLC는 항상 on-chain output으로 남나요?
작은 HTLC는 dust threshold와 fee에 따라 commitment transaction에서 trimmed될 수 있습니다.
더 깊이 읽기
본문에서 다룬 개념과 확인 절차를 다음 글에서 이어서 살펴보세요.



