mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-09-28 23:52:31 +02:00
htlcswitch+lnwallet: add malformed payment descriptor
This commit is contained in:
committed by
Olaoluwa Osuntokun
parent
e29193d550
commit
a10ed36e8f
@@ -1513,7 +1513,9 @@ func (l *channelLink) sendHTLCError(rHash [32]byte, failure lnwire.FailureMessag
|
|||||||
// to the payment sender.
|
// to the payment sender.
|
||||||
func (l *channelLink) sendMalformedHTLCError(rHash [32]byte, code lnwire.FailCode,
|
func (l *channelLink) sendMalformedHTLCError(rHash [32]byte, code lnwire.FailCode,
|
||||||
onionBlob []byte) {
|
onionBlob []byte) {
|
||||||
index, err := l.channel.FailHTLC(rHash)
|
|
||||||
|
shaOnionBlob := sha256.Sum256(onionBlob)
|
||||||
|
index, err := l.channel.MalformedFailHTLC(rHash, code, shaOnionBlob)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unable cancel htlc: %v", err)
|
log.Errorf("unable cancel htlc: %v", err)
|
||||||
return
|
return
|
||||||
@@ -1522,7 +1524,7 @@ func (l *channelLink) sendMalformedHTLCError(rHash [32]byte, code lnwire.FailCod
|
|||||||
l.cfg.Peer.SendMessage(&lnwire.UpdateFailMalformedHTLC{
|
l.cfg.Peer.SendMessage(&lnwire.UpdateFailMalformedHTLC{
|
||||||
ChanID: l.ChanID(),
|
ChanID: l.ChanID(),
|
||||||
ID: index,
|
ID: index,
|
||||||
ShaOnionBlob: sha256.Sum256(onionBlob),
|
ShaOnionBlob: shaOnionBlob,
|
||||||
FailureCode: code,
|
FailureCode: code,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@@ -107,6 +107,13 @@ const (
|
|||||||
// which contains the Fail entry.
|
// which contains the Fail entry.
|
||||||
Fail
|
Fail
|
||||||
|
|
||||||
|
// MalformedFail is an update type which removes a prior HTLC entry from the
|
||||||
|
// log. Adding a MalformedFail entry to ones log will modify the _remote_
|
||||||
|
// parties update log once a new commitment view has been evaluated which
|
||||||
|
// contains the MalformedFail entry. The difference from Fail type lie in
|
||||||
|
// the different data we have to store.
|
||||||
|
MalformedFail
|
||||||
|
|
||||||
// Settle is an update type which settles a prior HTLC crediting the
|
// Settle is an update type which settles a prior HTLC crediting the
|
||||||
// balance of the receiving node. Adding a Settle entry to a log will
|
// balance of the receiving node. Adding a Settle entry to a log will
|
||||||
// result in the settle entry being removed on the log as well as the
|
// result in the settle entry being removed on the log as well as the
|
||||||
@@ -123,6 +130,8 @@ func (u updateType) String() string {
|
|||||||
return "Add"
|
return "Add"
|
||||||
case Fail:
|
case Fail:
|
||||||
return "Fail"
|
return "Fail"
|
||||||
|
case MalformedFail:
|
||||||
|
return "MalformedFail"
|
||||||
case Settle:
|
case Settle:
|
||||||
return "Settle"
|
return "Settle"
|
||||||
default:
|
default:
|
||||||
@@ -214,11 +223,21 @@ type PaymentDescriptor struct {
|
|||||||
// NOTE: Populated only on add payment descriptor entry types.
|
// NOTE: Populated only on add payment descriptor entry types.
|
||||||
OnionBlob []byte
|
OnionBlob []byte
|
||||||
|
|
||||||
|
// ShaOnionBlob is a sha of the onion blob.
|
||||||
|
//
|
||||||
|
// NOTE: Populated only in payment descriptor with MalfromedFail type.
|
||||||
|
ShaOnionBlob [sha256.Size]byte
|
||||||
|
|
||||||
// FailReason stores the reason why a particular payment was cancelled.
|
// FailReason stores the reason why a particular payment was cancelled.
|
||||||
//
|
//
|
||||||
// NOTE: Populate only in fail payment descriptor entry types.
|
// NOTE: Populate only in fail payment descriptor entry types.
|
||||||
FailReason []byte
|
FailReason []byte
|
||||||
|
|
||||||
|
// FailCode stores the code why a particular payment was cancelled.
|
||||||
|
//
|
||||||
|
// NOTE: Populated only in payment descriptor with MalfromedFail type.
|
||||||
|
FailCode lnwire.FailCode
|
||||||
|
|
||||||
// [our|their|]PkScript are the raw public key scripts that encodes the
|
// [our|their|]PkScript are the raw public key scripts that encodes the
|
||||||
// redemption rules for this particular HTLC. These fields will only be
|
// redemption rules for this particular HTLC. These fields will only be
|
||||||
// populated iff the EntryType of this PaymentDescriptor is Add.
|
// populated iff the EntryType of this PaymentDescriptor is Add.
|
||||||
@@ -2153,7 +2172,7 @@ func processRemoveEntry(htlc *PaymentDescriptor, ourBalance,
|
|||||||
|
|
||||||
// Otherwise, this HTLC is being failed out, therefore the value of the
|
// Otherwise, this HTLC is being failed out, therefore the value of the
|
||||||
// HTLC should return to the remote party.
|
// HTLC should return to the remote party.
|
||||||
case isIncoming && htlc.EntryType == Fail:
|
case isIncoming && (htlc.EntryType == Fail || htlc.EntryType == MalformedFail):
|
||||||
*theirBalance += htlc.Amount
|
*theirBalance += htlc.Amount
|
||||||
|
|
||||||
// If an outgoing HTLC is being settled, then this means that the
|
// If an outgoing HTLC is being settled, then this means that the
|
||||||
@@ -2165,7 +2184,7 @@ func processRemoveEntry(htlc *PaymentDescriptor, ourBalance,
|
|||||||
|
|
||||||
// Otherwise, one of our outgoing HTLC's has timed out, so the value of
|
// Otherwise, one of our outgoing HTLC's has timed out, so the value of
|
||||||
// the HTLC should be returned to our settled balance.
|
// the HTLC should be returned to our settled balance.
|
||||||
case !isIncoming && htlc.EntryType == Fail:
|
case !isIncoming && (htlc.EntryType == Fail || htlc.EntryType == MalformedFail):
|
||||||
*ourBalance += htlc.Amount
|
*ourBalance += htlc.Amount
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2510,6 +2529,13 @@ func (lc *LightningChannel) ReceiveReestablish(msg *lnwire.ChannelReestablish) (
|
|||||||
ID: htlc.Index,
|
ID: htlc.Index,
|
||||||
Reason: lnwire.OpaqueReason([]byte{}),
|
Reason: lnwire.OpaqueReason([]byte{}),
|
||||||
})
|
})
|
||||||
|
case MalformedFail:
|
||||||
|
updates = append(updates, &lnwire.UpdateFailMalformedHTLC{
|
||||||
|
ChanID: chanID,
|
||||||
|
ID: htlc.Index,
|
||||||
|
ShaOnionBlob: htlc.ShaOnionBlob,
|
||||||
|
FailureCode: htlc.FailCode,
|
||||||
|
})
|
||||||
case Settle:
|
case Settle:
|
||||||
updates = append(updates, &lnwire.UpdateFufillHTLC{
|
updates = append(updates, &lnwire.UpdateFufillHTLC{
|
||||||
ChanID: chanID,
|
ChanID: chanID,
|
||||||
@@ -3253,7 +3279,43 @@ func (lc *LightningChannel) FailHTLC(rHash [32]byte, reason []byte) (uint64, err
|
|||||||
return addEntry.HtlcIndex, nil
|
return addEntry.HtlcIndex, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReceiveFailHTLC attempts to cancel a targeted HTLC by its log htlc,
|
// MalformedFailHTLC attempts to fail a targeted HTLC by its payment hash,
|
||||||
|
// inserting an entry which will remove the target log entry within the next
|
||||||
|
// commitment update. This method is intended to be called in order to cancel
|
||||||
|
// in _incoming_ HTLC.
|
||||||
|
func (lc *LightningChannel) MalformedFailHTLC(rHash [32]byte,
|
||||||
|
failCode lnwire.FailCode, shaOnionBlob [sha256.Size]byte) (uint64, error) {
|
||||||
|
lc.Lock()
|
||||||
|
defer lc.Unlock()
|
||||||
|
|
||||||
|
addEntries, ok := lc.rHashMap[rHash]
|
||||||
|
if !ok {
|
||||||
|
return 0, fmt.Errorf("unable to find HTLC to fail")
|
||||||
|
}
|
||||||
|
addEntry := addEntries[0]
|
||||||
|
|
||||||
|
pd := &PaymentDescriptor{
|
||||||
|
Amount: addEntry.Amount,
|
||||||
|
RHash: addEntry.RHash,
|
||||||
|
ParentIndex: addEntry.HtlcIndex,
|
||||||
|
LogIndex: lc.localUpdateLog.logIndex,
|
||||||
|
EntryType: MalformedFail,
|
||||||
|
FailCode: failCode,
|
||||||
|
ShaOnionBlob: shaOnionBlob,
|
||||||
|
}
|
||||||
|
|
||||||
|
lc.localUpdateLog.appendUpdate(pd)
|
||||||
|
|
||||||
|
lc.rHashMap[rHash][0] = nil
|
||||||
|
lc.rHashMap[rHash] = lc.rHashMap[rHash][1:]
|
||||||
|
if len(lc.rHashMap[rHash]) == 0 {
|
||||||
|
delete(lc.rHashMap, rHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
return addEntry.HtlcIndex, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReceiveFailHTLC attempts to cancel a targeted HTLC by its log index,
|
||||||
// inserting an entry which will remove the target log entry within the next
|
// inserting an entry which will remove the target log entry within the next
|
||||||
// commitment update. This method should be called in response to the upstream
|
// commitment update. This method should be called in response to the upstream
|
||||||
// party cancelling an outgoing HTLC. The value of the failed HTLC is returned
|
// party cancelling an outgoing HTLC. The value of the failed HTLC is returned
|
||||||
|
Reference in New Issue
Block a user