Skip to content

Commit f8942bb

Browse files
authored
SECURITY FIX: do not cancel hodl invoice on payment error
Under some unusual circumstances the `PayInvoice` function can return an error when the payment has been settled. In these cases it is extremely important not to cancel the hodl invoice since manual recovery is not possible if the hodl invoice is canceled. Also increases the default `CltvDeltaAlpha` to allow a longer window for manual recovery in the case of an error.
1 parent 7ccf669 commit f8942bb

File tree

1 file changed

+9
-14
lines changed

1 file changed

+9
-14
lines changed

relay.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ func NewRelay(ln lnc.LN) *Relay {
5050
RoutingBudgetBeta: 1_500_000,
5151
RoutingFeeBaseMsat: 1000,
5252
RoutingFeePPM: 1000,
53-
CltvDeltaAlpha: 3,
53+
CltvDeltaAlpha: 144,
5454
CltvDeltaBeta: 1_500_000,
5555
// Should be set to at most the node's `--max-cltv-expiry` setting (default: 2016)
5656
MaxCltvDelta: 1800,
5757
MinCltvDelta: 120,
5858
// Should be set so that CltvDeltaAlpha blocks are very unlikely to be added before timeout
59-
PaymentTimeout: 120,
59+
PaymentTimeout: 600,
6060
PaymentTimePreference: 0.9,
6161
},
6262
LN: ln,
@@ -194,21 +194,23 @@ func (relay *Relay) OpenCircuit(x ProxyParameters) (string, error) {
194194
func (relay *Relay) circuitSwitch(hash []byte, invoice string, fee_budget_msat, cltv_limit uint64) {
195195
defer relay.WaitGroup.Done()
196196
log.Println("opened circuit for:", invoice, hex.EncodeToString(hash))
197-
var preimage []byte
198197
_, err := relay.LN.WatchInvoice(hash)
199198
if err != nil {
200199
log.Println("error while watching wrapped invoice:", hex.EncodeToString(hash), err)
201-
goto cleanup
200+
err = relay.LN.CancelInvoice(hash)
201+
if err != nil {
202+
log.Println("error while canceling invoice:", hash, err)
203+
}
204+
return
202205
}
203-
preimage, err = relay.LN.PayInvoice(lnc.PaymentParameters{
206+
preimage, err := relay.LN.PayInvoice(lnc.PaymentParameters{
204207
Invoice: invoice,
205208
TimeoutSeconds: relay.PaymentTimeout,
206209
FeeLimitMsat: fee_budget_msat,
207210
CltvLimit: cltv_limit,
208211
})
209212
if err != nil {
210-
log.Println("error paying original invoice:", hex.EncodeToString(hash), err)
211-
goto cleanup
213+
log.Panicln("error paying original invoice:", hex.EncodeToString(hash), err)
212214
}
213215
log.Println("preimage:", hex.EncodeToString(preimage), hex.EncodeToString(hash))
214216
err = relay.LN.SettleInvoice(preimage)
@@ -217,11 +219,4 @@ func (relay *Relay) circuitSwitch(hash []byte, invoice string, fee_budget_msat,
217219
}
218220
log.Println("circuit settled")
219221
return
220-
221-
cleanup:
222-
err = relay.LN.CancelInvoice(hash)
223-
if err != nil {
224-
log.Println("error while canceling invoice:", hash, err)
225-
}
226-
return
227222
}

0 commit comments

Comments
 (0)