htlcswitch: bounce packets when quiescent
This commit is contained in:
1 file changed
+38
-11
+38
-11
@@ -643,20 +643,37 @@ func (l *channelLink) WaitForShutdown() {
|
|||||||
// actively accept requests to forward HTLC's. We're able to forward HTLC's if
|
// actively accept requests to forward HTLC's. We're able to forward HTLC's if
|
||||||
// we are eligible to update AND the channel isn't currently flushing the
|
// we are eligible to update AND the channel isn't currently flushing the
|
||||||
// outgoing half of the channel.
|
// outgoing half of the channel.
|
||||||
|
//
|
||||||
|
// NOTE: MUST NOT be called from the main event loop.
|
||||||
func (l *channelLink) EligibleToForward() bool {
|
func (l *channelLink) EligibleToForward() bool {
|
||||||
return l.EligibleToUpdate() &&
|
l.RLock()
|
||||||
!l.IsFlushing(Outgoing)
|
defer l.RUnlock()
|
||||||
|
|
||||||
|
return l.eligibleToForward()
|
||||||
}
|
}
|
||||||
|
|
||||||
// EligibleToUpdate returns a bool indicating if the channel is able to update
|
// eligibleToForward returns a bool indicating if the channel is able to
|
||||||
|
// actively accept requests to forward HTLC's. We're able to forward HTLC's if
|
||||||
|
// we are eligible to update AND the channel isn't currently flushing the
|
||||||
|
// outgoing half of the channel.
|
||||||
|
//
|
||||||
|
// NOTE: MUST be called from the main event loop.
|
||||||
|
func (l *channelLink) eligibleToForward() bool {
|
||||||
|
return l.eligibleToUpdate() && !l.IsFlushing(Outgoing)
|
||||||
|
}
|
||||||
|
|
||||||
|
// eligibleToUpdate returns a bool indicating if the channel is able to update
|
||||||
// channel state. We're able to update channel state if we know the remote
|
// channel state. We're able to update channel state if we know the remote
|
||||||
// party's next revocation point. Otherwise, we can't initiate new channel
|
// party's next revocation point. Otherwise, we can't initiate new channel
|
||||||
// state. We also require that the short channel ID not be the all-zero source
|
// state. We also require that the short channel ID not be the all-zero source
|
||||||
// ID, meaning that the channel has had its ID finalized.
|
// ID, meaning that the channel has had its ID finalized.
|
||||||
func (l *channelLink) EligibleToUpdate() bool {
|
//
|
||||||
|
// NOTE: MUST be called from the main event loop.
|
||||||
|
func (l *channelLink) eligibleToUpdate() bool {
|
||||||
return l.channel.RemoteNextRevocation() != nil &&
|
return l.channel.RemoteNextRevocation() != nil &&
|
||||||
l.ShortChanID() != hop.Source &&
|
l.channel.ShortChanID() != hop.Source &&
|
||||||
l.isReestablished()
|
l.isReestablished() &&
|
||||||
|
l.quiescer.CanSendUpdates()
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnableAdds sets the ChannelUpdateHandler state to allow UpdateAddHtlc's in
|
// EnableAdds sets the ChannelUpdateHandler state to allow UpdateAddHtlc's in
|
||||||
@@ -1599,13 +1616,14 @@ func (l *channelLink) handleDownstreamUpdateAdd(pkt *htlcPacket) error {
|
|||||||
return errors.New("not an UpdateAddHTLC packet")
|
return errors.New("not an UpdateAddHTLC packet")
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are flushing the link in the outgoing direction we can't add
|
// If we are flushing the link in the outgoing direction or we have
|
||||||
// new htlcs to the link and we need to bounce it
|
// already sent Stfu, then we can't add new htlcs to the link and we
|
||||||
if l.IsFlushing(Outgoing) {
|
// need to bounce it.
|
||||||
|
if l.IsFlushing(Outgoing) || !l.quiescer.CanSendUpdates() {
|
||||||
l.mailBox.FailAdd(pkt)
|
l.mailBox.FailAdd(pkt)
|
||||||
|
|
||||||
return NewDetailedLinkError(
|
return NewDetailedLinkError(
|
||||||
&lnwire.FailPermanentChannelFailure{},
|
&lnwire.FailTemporaryChannelFailure{},
|
||||||
OutgoingFailureLinkNotEligible,
|
OutgoingFailureLinkNotEligible,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1708,6 +1726,15 @@ func (l *channelLink) handleDownstreamUpdateAdd(pkt *htlcPacket) error {
|
|||||||
//
|
//
|
||||||
// TODO(roasbeef): add sync ntfn to ensure switch always has consistent view?
|
// TODO(roasbeef): add sync ntfn to ensure switch always has consistent view?
|
||||||
func (l *channelLink) handleDownstreamPkt(pkt *htlcPacket) {
|
func (l *channelLink) handleDownstreamPkt(pkt *htlcPacket) {
|
||||||
|
if pkt.htlc.MsgType().IsChannelUpdate() &&
|
||||||
|
!l.quiescer.CanSendUpdates() {
|
||||||
|
|
||||||
|
l.log.Warnf("unable to process channel update. "+
|
||||||
|
"ChannelID=%v is quiescent.", l.ChanID)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch htlc := pkt.htlc.(type) {
|
switch htlc := pkt.htlc.(type) {
|
||||||
case *lnwire.UpdateAddHTLC:
|
case *lnwire.UpdateAddHTLC:
|
||||||
// Handle add message. The returned error can be ignored,
|
// Handle add message. The returned error can be ignored,
|
||||||
@@ -3364,7 +3391,7 @@ func (l *channelLink) updateChannelFee(feePerKw chainfee.SatPerKWeight) error {
|
|||||||
|
|
||||||
// We skip sending the UpdateFee message if the channel is not
|
// We skip sending the UpdateFee message if the channel is not
|
||||||
// currently eligible to forward messages.
|
// currently eligible to forward messages.
|
||||||
if !l.EligibleToUpdate() {
|
if !l.eligibleToUpdate() {
|
||||||
l.log.Debugf("skipping fee update for inactive channel")
|
l.log.Debugf("skipping fee update for inactive channel")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user