Skip to content

Commit b01f99c

Browse files
committed
htlcswitch+lnwallet: persist UpdateFailHTLC extra data
When propagating a failure backwards along a route we want to persist the received ExtraData of the downstream link so that any handling can occur on our node before returning the updated ExtraData to our upstream link.
1 parent 6ad7e4e commit b01f99c

File tree

3 files changed

+63
-48
lines changed

3 files changed

+63
-48
lines changed

htlcswitch/link.go

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3579,7 +3579,7 @@ func (l *channelLink) sendHTLCError(add lnwire.UpdateAddHTLC,
35793579
return
35803580
}
35813581

3582-
err = l.channel.FailHTLC(add.ID, reason, &sourceRef, nil, nil)
3582+
err = l.channel.FailHTLC(add.ID, reason, nil, &sourceRef, nil, nil)
35833583
if err != nil {
35843584
l.log.Errorf("unable cancel htlc: %v", err)
35853585
return
@@ -3588,7 +3588,7 @@ func (l *channelLink) sendHTLCError(add lnwire.UpdateAddHTLC,
35883588
// Send the appropriate failure message depending on whether we're
35893589
// in a blinded route or not.
35903590
if err := l.sendIncomingHTLCFailureMsg(
3591-
add.ID, e, reason,
3591+
add.ID, e, reason, nil,
35923592
); err != nil {
35933593
l.log.Errorf("unable to send HTLC failure: %v", err)
35943594
return
@@ -3632,8 +3632,8 @@ func (l *channelLink) sendHTLCError(add lnwire.UpdateAddHTLC,
36323632
// used if we are the introduction node and need to present an error as if
36333633
// we're the failing party.
36343634
func (l *channelLink) sendIncomingHTLCFailureMsg(htlcIndex uint64,
3635-
e hop.ErrorEncrypter,
3636-
originalFailure lnwire.OpaqueReason) error {
3635+
e hop.ErrorEncrypter, originalFailure lnwire.OpaqueReason,
3636+
extraData lnwire.ExtraOpaqueData) error {
36373637

36383638
var msg lnwire.Message
36393639
switch {
@@ -3646,9 +3646,10 @@ func (l *channelLink) sendIncomingHTLCFailureMsg(htlcIndex uint64,
36463646
// code.
36473647
case e == nil:
36483648
msg = &lnwire.UpdateFailHTLC{
3649-
ChanID: l.ChanID(),
3650-
ID: htlcIndex,
3651-
Reason: originalFailure,
3649+
ChanID: l.ChanID(),
3650+
ID: htlcIndex,
3651+
Reason: originalFailure,
3652+
ExtraData: extraData,
36523653
}
36533654

36543655
l.log.Errorf("Unexpected blinded failure when "+
@@ -3659,9 +3660,10 @@ func (l *channelLink) sendIncomingHTLCFailureMsg(htlcIndex uint64,
36593660
// transformation on the error message and can just send the original.
36603661
case !e.Type().IsBlinded():
36613662
msg = &lnwire.UpdateFailHTLC{
3662-
ChanID: l.ChanID(),
3663-
ID: htlcIndex,
3664-
Reason: originalFailure,
3663+
ChanID: l.ChanID(),
3664+
ID: htlcIndex,
3665+
Reason: originalFailure,
3666+
ExtraData: extraData,
36653667
}
36663668

36673669
// When we're the introduction node, we need to convert the error to
@@ -4196,7 +4198,7 @@ func (l *channelLink) processRemoteUpdateFailMalformedHTLC(
41964198
// If remote side have been unable to parse the onion blob we have sent
41974199
// to it, than we should transform the malformed HTLC message to the
41984200
// usual HTLC fail message.
4199-
err := l.channel.ReceiveFailHTLC(msg.ID, b.Bytes())
4201+
err := l.channel.ReceiveFailHTLC(msg.ID, b.Bytes(), msg.ExtraData)
42004202
if err != nil {
42014203
l.failf(LinkFailureError{code: ErrInvalidUpdate},
42024204
"unable to handle upstream fail HTLC: %v", err)
@@ -4237,7 +4239,7 @@ func (l *channelLink) processRemoteUpdateFailHTLC(
42374239

42384240
// Add fail to the update log.
42394241
idx := msg.ID
4240-
err := l.channel.ReceiveFailHTLC(idx, msg.Reason[:])
4242+
err := l.channel.ReceiveFailHTLC(idx, msg.Reason[:], msg.ExtraData)
42414243
if err != nil {
42424244
l.failf(LinkFailureError{code: ErrInvalidUpdate},
42434245
"unable to handle upstream fail HTLC: %v", err)
@@ -4677,8 +4679,8 @@ func (l *channelLink) processLocalUpdateFailHTLC(ctx context.Context,
46774679
// remove then HTLC from our local state machine.
46784680
inKey := pkt.inKey()
46794681
err := l.channel.FailHTLC(
4680-
pkt.incomingHTLCID, htlc.Reason, pkt.sourceRef, pkt.destRef,
4681-
&inKey,
4682+
pkt.incomingHTLCID, htlc.Reason, htlc.ExtraData, pkt.sourceRef,
4683+
pkt.destRef, &inKey,
46824684
)
46834685
if err != nil {
46844686
l.log.Errorf("unable to cancel incoming HTLC for "+
@@ -4714,7 +4716,9 @@ func (l *channelLink) processLocalUpdateFailHTLC(ctx context.Context,
47144716
// HTLC. If the incoming blinding point is non-nil, we know that we are
47154717
// a relaying node in a blinded path. Otherwise, we're either an
47164718
// introduction node or not part of a blinded path at all.
4717-
err = l.sendIncomingHTLCFailureMsg(htlc.ID, pkt.obfuscator, htlc.Reason)
4719+
err = l.sendIncomingHTLCFailureMsg(
4720+
htlc.ID, pkt.obfuscator, htlc.Reason, htlc.ExtraData,
4721+
)
47184722
if err != nil {
47194723
l.log.Errorf("unable to send HTLC failure: %v", err)
47204724

lnwallet/channel.go

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,13 +1152,14 @@ func (lc *LightningChannel) logUpdateToPayDesc(logUpdate *channeldb.LogUpdate,
11521152
ogHTLC := remoteUpdateLog.lookupHtlc(wireMsg.ID)
11531153

11541154
pd = &paymentDescriptor{
1155-
ChanID: wireMsg.ChanID,
1156-
Amount: ogHTLC.Amount,
1157-
RHash: ogHTLC.RHash,
1158-
ParentIndex: ogHTLC.HtlcIndex,
1159-
LogIndex: logUpdate.LogIndex,
1160-
EntryType: Fail,
1161-
FailReason: wireMsg.Reason[:],
1155+
ChanID: wireMsg.ChanID,
1156+
Amount: ogHTLC.Amount,
1157+
RHash: ogHTLC.RHash,
1158+
ParentIndex: ogHTLC.HtlcIndex,
1159+
LogIndex: logUpdate.LogIndex,
1160+
EntryType: Fail,
1161+
FailReason: wireMsg.Reason[:],
1162+
FailExtraData: wireMsg.ExtraData,
11621163
removeCommitHeights: lntypes.Dual[uint64]{
11631164
Remote: commitHeight,
11641165
},
@@ -1252,13 +1253,14 @@ func (lc *LightningChannel) localLogUpdateToPayDesc(logUpdate *channeldb.LogUpda
12521253
ogHTLC := remoteUpdateLog.lookupHtlc(wireMsg.ID)
12531254

12541255
return &paymentDescriptor{
1255-
ChanID: wireMsg.ChanID,
1256-
Amount: ogHTLC.Amount,
1257-
RHash: ogHTLC.RHash,
1258-
ParentIndex: ogHTLC.HtlcIndex,
1259-
LogIndex: logUpdate.LogIndex,
1260-
EntryType: Fail,
1261-
FailReason: wireMsg.Reason[:],
1256+
ChanID: wireMsg.ChanID,
1257+
Amount: ogHTLC.Amount,
1258+
RHash: ogHTLC.RHash,
1259+
ParentIndex: ogHTLC.HtlcIndex,
1260+
LogIndex: logUpdate.LogIndex,
1261+
EntryType: Fail,
1262+
FailReason: wireMsg.Reason[:],
1263+
FailExtraData: wireMsg.ExtraData,
12621264
removeCommitHeights: lntypes.Dual[uint64]{
12631265
Remote: commitHeight,
12641266
},
@@ -1367,13 +1369,14 @@ func (lc *LightningChannel) remoteLogUpdateToPayDesc(logUpdate *channeldb.LogUpd
13671369
ogHTLC := localUpdateLog.lookupHtlc(wireMsg.ID)
13681370

13691371
return &paymentDescriptor{
1370-
ChanID: wireMsg.ChanID,
1371-
Amount: ogHTLC.Amount,
1372-
RHash: ogHTLC.RHash,
1373-
ParentIndex: ogHTLC.HtlcIndex,
1374-
LogIndex: logUpdate.LogIndex,
1375-
EntryType: Fail,
1376-
FailReason: wireMsg.Reason[:],
1372+
ChanID: wireMsg.ChanID,
1373+
Amount: ogHTLC.Amount,
1374+
RHash: ogHTLC.RHash,
1375+
ParentIndex: ogHTLC.HtlcIndex,
1376+
LogIndex: logUpdate.LogIndex,
1377+
EntryType: Fail,
1378+
FailReason: wireMsg.Reason[:],
1379+
FailExtraData: wireMsg.ExtraData,
13771380
removeCommitHeights: lntypes.Dual[uint64]{
13781381
Local: commitHeight,
13791382
},
@@ -6298,7 +6301,8 @@ func (lc *LightningChannel) ReceiveHTLCSettle(preimage [32]byte, htlcIndex uint6
62986301
// NOTE: It is okay for sourceRef, destRef, and closeKey to be nil when unit
62996302
// testing the wallet.
63006303
func (lc *LightningChannel) FailHTLC(htlcIndex uint64, reason []byte,
6301-
sourceRef *channeldb.AddRef, destRef *channeldb.SettleFailRef,
6304+
extraData lnwire.ExtraOpaqueData, sourceRef *channeldb.AddRef,
6305+
destRef *channeldb.SettleFailRef,
63026306
closeKey *models.CircuitKey) error {
63036307

63046308
lc.Lock()
@@ -6326,6 +6330,7 @@ func (lc *LightningChannel) FailHTLC(htlcIndex uint64, reason []byte,
63266330
SourceRef: sourceRef,
63276331
DestRef: destRef,
63286332
ClosedCircuitKey: closeKey,
6333+
FailExtraData: extraData,
63296334
}
63306335

63316336
lc.updateLogs.Local.appendUpdate(pd)
@@ -6393,7 +6398,7 @@ func (lc *LightningChannel) MalformedFailHTLC(htlcIndex uint64,
63936398
// commitment update. This method should be called in response to the upstream
63946399
// party cancelling an outgoing HTLC.
63956400
func (lc *LightningChannel) ReceiveFailHTLC(htlcIndex uint64, reason []byte,
6396-
) error {
6401+
extraData lnwire.ExtraOpaqueData) error {
63976402

63986403
lc.Lock()
63996404
defer lc.Unlock()
@@ -6410,13 +6415,14 @@ func (lc *LightningChannel) ReceiveFailHTLC(htlcIndex uint64, reason []byte,
64106415
}
64116416

64126417
pd := &paymentDescriptor{
6413-
ChanID: lc.ChannelID(),
6414-
Amount: htlc.Amount,
6415-
RHash: htlc.RHash,
6416-
ParentIndex: htlc.HtlcIndex,
6417-
LogIndex: lc.updateLogs.Remote.logIndex,
6418-
EntryType: Fail,
6419-
FailReason: reason,
6418+
ChanID: lc.ChannelID(),
6419+
Amount: htlc.Amount,
6420+
RHash: htlc.RHash,
6421+
ParentIndex: htlc.HtlcIndex,
6422+
LogIndex: lc.updateLogs.Remote.logIndex,
6423+
EntryType: Fail,
6424+
FailReason: reason,
6425+
FailExtraData: extraData,
64206426
}
64216427

64226428
lc.updateLogs.Remote.appendUpdate(pd)

lnwallet/payment_descriptor.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ type paymentDescriptor struct {
229229
// CustomRecords also stores the set of optional custom records that
230230
// may have been attached to a sent HTLC.
231231
CustomRecords lnwire.CustomRecords
232+
233+
// FailExtraData stores any extra opaque data that may have been present
234+
// when receiving an UpdateFailHTLC message.
235+
FailExtraData lnwire.ExtraOpaqueData
232236
}
233237

234238
// toLogUpdate recovers the underlying LogUpdate from the paymentDescriptor.
@@ -257,9 +261,10 @@ func (pd *paymentDescriptor) toLogUpdate() channeldb.LogUpdate {
257261
}
258262
case Fail:
259263
msg = &lnwire.UpdateFailHTLC{
260-
ChanID: pd.ChanID,
261-
ID: pd.ParentIndex,
262-
Reason: pd.FailReason,
264+
ChanID: pd.ChanID,
265+
ID: pd.ParentIndex,
266+
Reason: pd.FailReason,
267+
ExtraData: pd.FailExtraData,
263268
}
264269
case MalformedFail:
265270
msg = &lnwire.UpdateFailMalformedHTLC{

0 commit comments

Comments
 (0)