htlcswitch+channel: remove cancel reasons from channel link

This commit is contained in:
Andrey Samokhvalov 2017-07-10 13:48:43 +03:00 committed by Olaoluwa Osuntokun
parent 1b4e723a5d
commit e29193d550
3 changed files with 31 additions and 40 deletions

@ -157,15 +157,6 @@ type channelLink struct {
started int32 started int32
shutdown int32 shutdown int32
// cancelReasons stores the reason why a particular HTLC was cancelled.
// The index of the HTLC within the log is mapped to the cancellation
// reason. This value is used to thread the proper error through to the
// htlcSwitch, or subsystem that initiated the HTLC.
//
// TODO(andrew.shvv) remove after payment descriptor start store
// htlc cancel reasons.
cancelReasons map[uint64]lnwire.OpaqueReason
// batchCounter is the number of updates which we received from remote // batchCounter is the number of updates which we received from remote
// side, but not include in commitment transaction yet and plus the // side, but not include in commitment transaction yet and plus the
// current number of settles that have been sent, but not yet committed // current number of settles that have been sent, but not yet committed
@ -236,7 +227,6 @@ func NewChannelLink(cfg ChannelLinkConfig, channel *lnwallet.LightningChannel,
linkControl: make(chan interface{}), linkControl: make(chan interface{}),
// TODO(roasbeef): just do reserve here? // TODO(roasbeef): just do reserve here?
availableBandwidth: uint64(channel.StateSnapshot().LocalBalance), availableBandwidth: uint64(channel.StateSnapshot().LocalBalance),
cancelReasons: make(map[uint64]lnwire.OpaqueReason),
logCommitTimer: time.NewTimer(300 * time.Millisecond), logCommitTimer: time.NewTimer(300 * time.Millisecond),
overflowQueue: newPacketQueue(lnwallet.MaxHTLCNumber / 2), overflowQueue: newPacketQueue(lnwallet.MaxHTLCNumber / 2),
bestHeight: currentHeight, bestHeight: currentHeight,
@ -664,7 +654,7 @@ func (l *channelLink) handleDownStreamPkt(pkt *htlcPacket, isReProcess bool) {
case *lnwire.UpdateFailHTLC: case *lnwire.UpdateFailHTLC:
// An HTLC cancellation has been triggered somewhere upstream, // An HTLC cancellation has been triggered somewhere upstream,
// we'll remove then HTLC from our local state machine. // we'll remove then HTLC from our local state machine.
logIndex, err := l.channel.FailHTLC(pkt.payHash) logIndex, err := l.channel.FailHTLC(pkt.payHash, htlc.Reason)
if err != nil { if err != nil {
log.Errorf("unable to cancel HTLC: %v", err) log.Errorf("unable to cancel HTLC: %v", err)
return return
@ -749,20 +739,6 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
// repeated r-values // repeated r-values
case *lnwire.UpdateFailMalformedHTLC: case *lnwire.UpdateFailMalformedHTLC:
// If remote side have been unable to parse the onion blob we
// have sent to it, than we should transform the malformed HTLC
// message to the usual HTLC fail message.
idx := msg.ID
amt, err := l.channel.ReceiveFailHTLC(idx)
if err != nil {
l.fail("unable to handle upstream fail HTLC: %v", err)
return
}
// Increment the available bandwidth as they've removed our
// HTLC.
atomic.AddUint64(&l.availableBandwidth, uint64(amt))
// Convert the failure type encoded within the HTLC fail // Convert the failure type encoded within the HTLC fail
// message to the proper generic lnwire error code. // message to the proper generic lnwire error code.
var failure lnwire.FailureMessage var failure lnwire.FailureMessage
@ -795,11 +771,10 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
return return
} }
l.cancelReasons[idx] = lnwire.OpaqueReason(b.Bytes()) // If remote side have been unable to parse the onion blob we
// have sent to it, than we should transform the malformed HTLC
case *lnwire.UpdateFailHTLC: // message to the usual HTLC fail message.
idx := msg.ID amt, err := l.channel.ReceiveFailHTLC(idx, b.Bytes())
amt, err := l.channel.ReceiveFailHTLC(idx)
if err != nil { if err != nil {
l.fail("unable to handle upstream fail HTLC: %v", err) l.fail("unable to handle upstream fail HTLC: %v", err)
return return
@ -809,7 +784,17 @@ func (l *channelLink) handleUpstreamMsg(msg lnwire.Message) {
// HTLC. // HTLC.
atomic.AddUint64(&l.availableBandwidth, uint64(amt)) atomic.AddUint64(&l.availableBandwidth, uint64(amt))
l.cancelReasons[idx] = msg.Reason case *lnwire.UpdateFailHTLC:
idx := msg.ID
amt, err := l.channel.ReceiveFailHTLC(idx, msg.Reason[:])
if err != nil {
l.fail("unable to handle upstream fail HTLC: %v", err)
return
}
// Increment the available bandwidth as they've removed our
// HTLC.
atomic.AddUint64(&l.availableBandwidth, uint64(amt))
case *lnwire.CommitSig: case *lnwire.CommitSig:
// We just received a new updates to our local commitment chain, // We just received a new updates to our local commitment chain,
@ -1105,10 +1090,8 @@ func (l *channelLink) processLockedInHtlcs(
case lnwallet.Fail: case lnwallet.Fail:
// Fetch the reason the HTLC was cancelled so we can // Fetch the reason the HTLC was cancelled so we can
// continue to propagate it. // continue to propagate it.
opaqueReason := l.cancelReasons[pd.ParentIndex]
failUpdate := &lnwire.UpdateFailHTLC{ failUpdate := &lnwire.UpdateFailHTLC{
Reason: opaqueReason, Reason: lnwire.OpaqueReason(pd.FailReason),
ChanID: l.ChanID(), ChanID: l.ChanID(),
} }
failPacket := newFailPacket(l.ShortChanID(), failUpdate, failPacket := newFailPacket(l.ShortChanID(), failUpdate,
@ -1513,7 +1496,7 @@ func (l *channelLink) sendHTLCError(rHash [32]byte, failure lnwire.FailureMessag
return return
} }
index, err := l.channel.FailHTLC(rHash) index, err := l.channel.FailHTLC(rHash, reason)
if err != nil { if err != nil {
log.Errorf("unable cancel htlc: %v", err) log.Errorf("unable cancel htlc: %v", err)
return return

@ -214,6 +214,11 @@ 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
// FailReason stores the reason why a particular payment was cancelled.
//
// NOTE: Populate only in fail payment descriptor entry types.
FailReason []byte
// [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.
@ -1691,7 +1696,6 @@ func (lc *LightningChannel) restoreStateLogs() error {
EntryType: Add, EntryType: Add,
addCommitHeightRemote: pastHeight, addCommitHeightRemote: pastHeight,
addCommitHeightLocal: pastHeight, addCommitHeightLocal: pastHeight,
OnionBlob: htlc.OnionBlob,
ourPkScript: ourP2WSH, ourPkScript: ourP2WSH,
ourWitnessScript: ourWitnessScript, ourWitnessScript: ourWitnessScript,
theirPkScript: theirP2WSH, theirPkScript: theirP2WSH,
@ -3219,7 +3223,7 @@ func (lc *LightningChannel) ReceiveHTLCSettle(preimage [32]byte, htlcIndex uint6
// _incoming_ HTLC. // _incoming_ HTLC.
// //
// TODO(roasbeef): add value as well? // TODO(roasbeef): add value as well?
func (lc *LightningChannel) FailHTLC(rHash [32]byte) (uint64, error) { func (lc *LightningChannel) FailHTLC(rHash [32]byte, reason []byte) (uint64, error) {
lc.Lock() lc.Lock()
defer lc.Unlock() defer lc.Unlock()
@ -3235,6 +3239,7 @@ func (lc *LightningChannel) FailHTLC(rHash [32]byte) (uint64, error) {
ParentIndex: addEntry.HtlcIndex, ParentIndex: addEntry.HtlcIndex,
LogIndex: lc.localUpdateLog.logIndex, LogIndex: lc.localUpdateLog.logIndex,
EntryType: Fail, EntryType: Fail,
FailReason: reason,
} }
lc.localUpdateLog.appendUpdate(pd) lc.localUpdateLog.appendUpdate(pd)
@ -3253,7 +3258,9 @@ func (lc *LightningChannel) FailHTLC(rHash [32]byte) (uint64, error) {
// 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
// along with an error indicating success. // along with an error indicating success.
func (lc *LightningChannel) ReceiveFailHTLC(htlcIndex uint64) (lnwire.MilliSatoshi, error) { func (lc *LightningChannel) ReceiveFailHTLC(htlcIndex uint64,
reason []byte) (lnwire.MilliSatoshi, error) {
lc.Lock() lc.Lock()
defer lc.Unlock() defer lc.Unlock()
@ -3268,6 +3275,7 @@ func (lc *LightningChannel) ReceiveFailHTLC(htlcIndex uint64) (lnwire.MilliSatos
ParentIndex: htlc.HtlcIndex, ParentIndex: htlc.HtlcIndex,
LogIndex: lc.remoteUpdateLog.logIndex, LogIndex: lc.remoteUpdateLog.logIndex,
EntryType: Fail, EntryType: Fail,
FailReason: reason,
} }
lc.remoteUpdateLog.appendUpdate(pd) lc.remoteUpdateLog.appendUpdate(pd)

@ -1648,11 +1648,11 @@ func TestCancelHTLC(t *testing.T) {
// Now, with the HTLC committed on both sides, trigger a cancellation // Now, with the HTLC committed on both sides, trigger a cancellation
// from Bob to Alice, removing the HTLC. // from Bob to Alice, removing the HTLC.
htlcCancelIndex, err := bobChannel.FailHTLC(paymentHash) htlcCancelIndex, err := bobChannel.FailHTLC(paymentHash, []byte("failreason"))
if err != nil { if err != nil {
t.Fatalf("unable to cancel HTLC: %v", err) t.Fatalf("unable to cancel HTLC: %v", err)
} }
if _, err := aliceChannel.ReceiveFailHTLC(htlcCancelIndex); err != nil { if _, err := aliceChannel.ReceiveFailHTLC(htlcCancelIndex, []byte("bad")); err != nil {
t.Fatalf("unable to recv htlc cancel: %v", err) t.Fatalf("unable to recv htlc cancel: %v", err)
} }