htlcswitch: use LinkError for internal errors

Update the ChannelLink interface to specifically
return the LinkError struct. This error implements
the ClearTextError interface, so will be picked
up as a routing realted error by the router.

With LinkErrors implemented, the switch now
returns a LinkError for all failures on our
incoming/outgoing link and ForwardingError when
the failure occurs down the line.
This commit is contained in:
carla committed 2020-01-14 15:21:15 +02:00
1 parent b5a2d75465
commit f430fd50c5
8 files changed
+185 -79

No files matched your search

+28 -21
View File
@@ -2135,16 +2135,17 @@ func (l *channelLink) UpdateForwardingPolicy(newPolicy ForwardingPolicy) {
l.cfg.FwrdingPolicy = newPolicy
}
// CheckHtlcForward should return a nil error if the passed HTLC details satisfy
// the current forwarding policy fo the target link. Otherwise, a valid
// protocol failure message should be returned in order to signal to the source
// of the HTLC, the policy consistency issue.
// CheckHtlcForward should return a nil error if the passed HTLC details
// satisfy the current forwarding policy fo the target link. Otherwise,
// a LinkError with a valid protocol failure message should be returned
// in order to signal to the source of the HTLC, the policy consistency
// issue.
//
// NOTE: Part of the ChannelLink interface.
func (l *channelLink) CheckHtlcForward(payHash [32]byte,
incomingHtlcAmt, amtToForward lnwire.MilliSatoshi,
incomingTimeout, outgoingTimeout uint32,
heightNow uint32) lnwire.FailureMessage {
heightNow uint32) *LinkError {
l.RLock()
policy := l.cfg.FwrdingPolicy
@@ -2176,14 +2177,14 @@ func (l *channelLink) CheckHtlcForward(payHash [32]byte,
// As part of the returned error, we'll send our latest routing
// policy so the sending node obtains the most up to date data.
return l.createFailureWithUpdate(
failure := l.createFailureWithUpdate(
func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage {
return lnwire.NewFeeInsufficient(
amtToForward, *upd,
)
},
)
return NewLinkError(failure)
}
// Finally, we'll ensure that the time-lock on the outgoing HTLC meets
@@ -2198,26 +2199,27 @@ func (l *channelLink) CheckHtlcForward(payHash [32]byte,
// Grab the latest routing policy so the sending node is up to
// date with our current policy.
return l.createFailureWithUpdate(
failure := l.createFailureWithUpdate(
func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage {
return lnwire.NewIncorrectCltvExpiry(
incomingTimeout, *upd,
)
},
)
return NewLinkError(failure)
}
return nil
}
// CheckHtlcTransit should return a nil error if the passed HTLC details satisfy the
// current channel policy. Otherwise, a valid protocol failure message should
// be returned in order to signal the violation. This call is intended to be
// used for locally initiated payments for which there is no corresponding
// incoming htlc.
// CheckHtlcTransit should return a nil error if the passed HTLC details
// satisfy the current channel policy. Otherwise, a LinkError with a
// valid protocol failure message should be returned in order to signal
// the violation. This call is intended to be used for locally initiated
// payments for which there is no corresponding incoming htlc.
func (l *channelLink) CheckHtlcTransit(payHash [32]byte,
amt lnwire.MilliSatoshi, timeout uint32,
heightNow uint32) lnwire.FailureMessage {
heightNow uint32) *LinkError {
l.RLock()
policy := l.cfg.FwrdingPolicy
@@ -2232,7 +2234,7 @@ func (l *channelLink) CheckHtlcTransit(payHash [32]byte,
// the channel's amount and time lock constraints.
func (l *channelLink) canSendHtlc(policy ForwardingPolicy,
payHash [32]byte, amt lnwire.MilliSatoshi, timeout uint32,
heightNow uint32) lnwire.FailureMessage {
heightNow uint32) *LinkError {
// As our first sanity check, we'll ensure that the passed HTLC isn't
// too small for the next hop. If so, then we'll cancel the HTLC
@@ -2244,13 +2246,14 @@ func (l *channelLink) canSendHtlc(policy ForwardingPolicy,
// As part of the returned error, we'll send our latest routing
// policy so the sending node obtains the most up to date data.
return l.createFailureWithUpdate(
failure := l.createFailureWithUpdate(
func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage {
return lnwire.NewAmountBelowMinimum(
amt, *upd,
)
},
)
return NewLinkError(failure)
}
// Next, ensure that the passed HTLC isn't too large. If so, we'll
@@ -2261,11 +2264,12 @@ func (l *channelLink) canSendHtlc(policy ForwardingPolicy,
// As part of the returned error, we'll send our latest routing
// policy so the sending node obtains the most up-to-date data.
return l.createFailureWithUpdate(
failure := l.createFailureWithUpdate(
func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage {
return lnwire.NewTemporaryChannelFailure(upd)
},
)
return NewDetailedLinkError(failure, FailureDetailHTLCExceedsMax)
}
// We want to avoid offering an HTLC which will expire in the near
@@ -2275,12 +2279,12 @@ func (l *channelLink) canSendHtlc(policy ForwardingPolicy,
l.log.Errorf("htlc(%x) has an expiry that's too soon: "+
"outgoing_expiry=%v, best_height=%v", payHash[:],
timeout, heightNow)
return l.createFailureWithUpdate(
failure := l.createFailureWithUpdate(
func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage {
return lnwire.NewExpiryTooSoon(*upd)
},
)
return NewLinkError(failure)
}
// Check absolute max delta.
@@ -2289,16 +2293,19 @@ func (l *channelLink) canSendHtlc(policy ForwardingPolicy,
"the future: got %v, but maximum is %v", payHash[:],
timeout-heightNow, l.cfg.MaxOutgoingCltvExpiry)
return &lnwire.FailExpiryTooFar{}
return NewLinkError(&lnwire.FailExpiryTooFar{})
}
// Check to see if there is enough balance in this channel.
if amt > l.Bandwidth() {
return l.createFailureWithUpdate(
failure := l.createFailureWithUpdate(
func(upd *lnwire.ChannelUpdate) lnwire.FailureMessage {
return lnwire.NewTemporaryChannelFailure(upd)
},
)
return NewDetailedLinkError(
failure, FailureDetailInsufficientBalance,
)
}
return nil