mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-06-19 05:11:25 +02:00
htlcswitch+peer: remove ShutdownIfChannelClean
This commit is contained in:
parent
64fda6ca65
commit
ec55831229
@ -134,11 +134,6 @@ type ChannelUpdateHandler interface {
|
|||||||
// parameter.
|
// parameter.
|
||||||
MayAddOutgoingHtlc(lnwire.MilliSatoshi) error
|
MayAddOutgoingHtlc(lnwire.MilliSatoshi) error
|
||||||
|
|
||||||
// ShutdownIfChannelClean shuts the link down if the channel state is
|
|
||||||
// clean. This can be used with dynamic commitment negotiation or coop
|
|
||||||
// close negotiation which require a clean channel state.
|
|
||||||
ShutdownIfChannelClean() error
|
|
||||||
|
|
||||||
// EnableAdds sets the ChannelUpdateHandler state to allow
|
// EnableAdds sets the ChannelUpdateHandler state to allow
|
||||||
// UpdateAddHtlc's in the specified direction. It returns an error if
|
// UpdateAddHtlc's in the specified direction. It returns an error if
|
||||||
// the state already allowed those adds.
|
// the state already allowed those adds.
|
||||||
|
@ -273,13 +273,6 @@ type ChannelLinkConfig struct {
|
|||||||
GetAliases func(base lnwire.ShortChannelID) []lnwire.ShortChannelID
|
GetAliases func(base lnwire.ShortChannelID) []lnwire.ShortChannelID
|
||||||
}
|
}
|
||||||
|
|
||||||
// shutdownReq contains an error channel that will be used by the channelLink
|
|
||||||
// to send an error if shutdown failed. If shutdown succeeded, the channel will
|
|
||||||
// be closed.
|
|
||||||
type shutdownReq struct {
|
|
||||||
err chan error
|
|
||||||
}
|
|
||||||
|
|
||||||
// channelLink is the service which drives a channel's commitment update
|
// channelLink is the service which drives a channel's commitment update
|
||||||
// state-machine. In the event that an HTLC needs to be propagated to another
|
// state-machine. In the event that an HTLC needs to be propagated to another
|
||||||
// link, the forward handler from config is used which sends HTLC to the
|
// link, the forward handler from config is used which sends HTLC to the
|
||||||
@ -340,10 +333,6 @@ type channelLink struct {
|
|||||||
// by the HTLC switch.
|
// by the HTLC switch.
|
||||||
downstream chan *htlcPacket
|
downstream chan *htlcPacket
|
||||||
|
|
||||||
// shutdownRequest is a channel that the channelLink will listen on to
|
|
||||||
// service shutdown requests from ShutdownIfChannelClean calls.
|
|
||||||
shutdownRequest chan *shutdownReq
|
|
||||||
|
|
||||||
// updateFeeTimer is the timer responsible for updating the link's
|
// updateFeeTimer is the timer responsible for updating the link's
|
||||||
// commitment fee every time it fires.
|
// commitment fee every time it fires.
|
||||||
updateFeeTimer *time.Timer
|
updateFeeTimer *time.Timer
|
||||||
@ -458,7 +447,6 @@ func NewChannelLink(cfg ChannelLinkConfig,
|
|||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
channel: channel,
|
channel: channel,
|
||||||
shortChanID: channel.ShortChanID(),
|
shortChanID: channel.ShortChanID(),
|
||||||
shutdownRequest: make(chan *shutdownReq),
|
|
||||||
hodlMap: make(map[models.CircuitKey]hodlHtlc),
|
hodlMap: make(map[models.CircuitKey]hodlHtlc),
|
||||||
hodlQueue: queue.NewConcurrentQueue(10),
|
hodlQueue: queue.NewConcurrentQueue(10),
|
||||||
log: build.NewPrefixLog(logPrefix, log),
|
log: build.NewPrefixLog(logPrefix, log),
|
||||||
@ -1446,24 +1434,6 @@ func (l *channelLink) htlcManager() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
case req := <-l.shutdownRequest:
|
|
||||||
// If the channel is clean, we send nil on the err chan
|
|
||||||
// and return to prevent the htlcManager goroutine from
|
|
||||||
// processing any more updates. The full link shutdown
|
|
||||||
// will be triggered by RemoveLink in the peer.
|
|
||||||
if l.channel.IsChannelClean() {
|
|
||||||
req.err <- nil
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
l.log.Infof("Channel is in an unclean state " +
|
|
||||||
"(lingering updates), graceful shutdown of " +
|
|
||||||
"channel link not possible")
|
|
||||||
|
|
||||||
// Otherwise, the channel has lingering updates, send
|
|
||||||
// an error and continue.
|
|
||||||
req.err <- ErrLinkFailedShutdown
|
|
||||||
|
|
||||||
case <-l.quit:
|
case <-l.quit:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -3020,29 +2990,6 @@ func (l *channelLink) HandleChannelUpdate(message lnwire.Message) {
|
|||||||
l.mailBox.AddMessage(message)
|
l.mailBox.AddMessage(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ShutdownIfChannelClean triggers a link shutdown if the channel is in a clean
|
|
||||||
// state and errors if the channel has lingering updates.
|
|
||||||
//
|
|
||||||
// NOTE: Part of the ChannelUpdateHandler interface.
|
|
||||||
func (l *channelLink) ShutdownIfChannelClean() error {
|
|
||||||
errChan := make(chan error, 1)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case l.shutdownRequest <- &shutdownReq{
|
|
||||||
err: errChan,
|
|
||||||
}:
|
|
||||||
case <-l.quit:
|
|
||||||
return ErrLinkShuttingDown
|
|
||||||
}
|
|
||||||
|
|
||||||
select {
|
|
||||||
case err := <-errChan:
|
|
||||||
return err
|
|
||||||
case <-l.quit:
|
|
||||||
return ErrLinkShuttingDown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateChannelFee updates the commitment fee-per-kw on this channel by
|
// updateChannelFee updates the commitment fee-per-kw on this channel by
|
||||||
// committing to an update_fee message.
|
// committing to an update_fee message.
|
||||||
func (l *channelLink) updateChannelFee(feePerKw chainfee.SatPerKWeight) error {
|
func (l *channelLink) updateChannelFee(feePerKw chainfee.SatPerKWeight) error {
|
||||||
|
@ -6666,94 +6666,6 @@ func TestPendingCommitTicker(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestShutdownIfChannelClean tests that a link will exit the htlcManager loop
|
|
||||||
// if and only if the underlying channel state is clean.
|
|
||||||
func TestShutdownIfChannelClean(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
const chanAmt = btcutil.SatoshiPerBitcoin * 5
|
|
||||||
const chanReserve = btcutil.SatoshiPerBitcoin * 1
|
|
||||||
aliceLink, bobChannel, batchTicker, start, _, err :=
|
|
||||||
newSingleLinkTestHarness(t, chanAmt, chanReserve)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
var (
|
|
||||||
coreLink = aliceLink.(*channelLink)
|
|
||||||
aliceMsgs = coreLink.cfg.Peer.(*mockPeer).sentMsgs
|
|
||||||
)
|
|
||||||
|
|
||||||
shutdownAssert := func(expectedErr error) {
|
|
||||||
err = aliceLink.ShutdownIfChannelClean()
|
|
||||||
if expectedErr != nil {
|
|
||||||
require.Error(t, err, expectedErr)
|
|
||||||
} else {
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err = start()
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
ctx := linkTestContext{
|
|
||||||
t: t,
|
|
||||||
aliceLink: aliceLink,
|
|
||||||
bobChannel: bobChannel,
|
|
||||||
aliceMsgs: aliceMsgs,
|
|
||||||
}
|
|
||||||
|
|
||||||
// First send an HTLC from Bob to Alice and assert that the link can't
|
|
||||||
// be shutdown while the update is outstanding.
|
|
||||||
htlc := generateHtlc(t, coreLink, 0)
|
|
||||||
|
|
||||||
// <---add-----
|
|
||||||
ctx.sendHtlcBobToAlice(htlc)
|
|
||||||
// <---sig-----
|
|
||||||
ctx.sendCommitSigBobToAlice(1)
|
|
||||||
// ----rev---->
|
|
||||||
ctx.receiveRevAndAckAliceToBob()
|
|
||||||
shutdownAssert(ErrLinkFailedShutdown)
|
|
||||||
|
|
||||||
// ----sig---->
|
|
||||||
ctx.receiveCommitSigAliceToBob(1)
|
|
||||||
shutdownAssert(ErrLinkFailedShutdown)
|
|
||||||
|
|
||||||
// <---rev-----
|
|
||||||
ctx.sendRevAndAckBobToAlice()
|
|
||||||
shutdownAssert(ErrLinkFailedShutdown)
|
|
||||||
|
|
||||||
// ---settle-->
|
|
||||||
ctx.receiveSettleAliceToBob()
|
|
||||||
shutdownAssert(ErrLinkFailedShutdown)
|
|
||||||
|
|
||||||
// ----sig---->
|
|
||||||
ctx.receiveCommitSigAliceToBob(0)
|
|
||||||
shutdownAssert(ErrLinkFailedShutdown)
|
|
||||||
|
|
||||||
// <---rev-----
|
|
||||||
ctx.sendRevAndAckBobToAlice()
|
|
||||||
shutdownAssert(ErrLinkFailedShutdown)
|
|
||||||
|
|
||||||
// There is currently no controllable breakpoint between Alice
|
|
||||||
// receiving the CommitSig and her sending out the RevokeAndAck. As
|
|
||||||
// soon as the RevokeAndAck is generated, the channel becomes clean.
|
|
||||||
// This can happen right after the CommitSig is received, so there is
|
|
||||||
// no shutdown assertion here.
|
|
||||||
// <---sig-----
|
|
||||||
ctx.sendCommitSigBobToAlice(0)
|
|
||||||
|
|
||||||
// ----rev---->
|
|
||||||
ctx.receiveRevAndAckAliceToBob()
|
|
||||||
shutdownAssert(nil)
|
|
||||||
|
|
||||||
// Now that the link has exited the htlcManager loop, attempt to
|
|
||||||
// trigger the batch ticker. It should not be possible.
|
|
||||||
select {
|
|
||||||
case batchTicker <- time.Now():
|
|
||||||
t.Fatalf("expected batch ticker to be inactive")
|
|
||||||
case <-time.After(5 * time.Second):
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TestPipelineSettle tests that a link should only pipeline a settle if the
|
// TestPipelineSettle tests that a link should only pipeline a settle if the
|
||||||
// related add is fully locked-in meaning it is on both sides' commitment txns.
|
// related add is fully locked-in meaning it is on both sides' commitment txns.
|
||||||
func TestPipelineSettle(t *testing.T) {
|
func TestPipelineSettle(t *testing.T) {
|
||||||
|
@ -899,7 +899,6 @@ func (f *mockChannelLink) ChannelPoint() *wire.OutPoint { return
|
|||||||
func (f *mockChannelLink) Stop() {}
|
func (f *mockChannelLink) Stop() {}
|
||||||
func (f *mockChannelLink) EligibleToForward() bool { return f.eligible }
|
func (f *mockChannelLink) EligibleToForward() bool { return f.eligible }
|
||||||
func (f *mockChannelLink) MayAddOutgoingHtlc(lnwire.MilliSatoshi) error { return nil }
|
func (f *mockChannelLink) MayAddOutgoingHtlc(lnwire.MilliSatoshi) error { return nil }
|
||||||
func (f *mockChannelLink) ShutdownIfChannelClean() error { return nil }
|
|
||||||
func (f *mockChannelLink) setLiveShortChanID(sid lnwire.ShortChannelID) { f.shortChanID = sid }
|
func (f *mockChannelLink) setLiveShortChanID(sid lnwire.ShortChannelID) { f.shortChanID = sid }
|
||||||
func (f *mockChannelLink) IsUnadvertised() bool { return f.unadvertised }
|
func (f *mockChannelLink) IsUnadvertised() bool { return f.unadvertised }
|
||||||
func (f *mockChannelLink) UpdateShortChanID() (lnwire.ShortChannelID, error) {
|
func (f *mockChannelLink) UpdateShortChanID() (lnwire.ShortChannelID, error) {
|
||||||
|
@ -485,9 +485,6 @@ func (m *mockUpdateHandler) EligibleToForward() bool { return false }
|
|||||||
// MayAddOutgoingHtlc currently returns nil.
|
// MayAddOutgoingHtlc currently returns nil.
|
||||||
func (m *mockUpdateHandler) MayAddOutgoingHtlc(lnwire.MilliSatoshi) error { return nil }
|
func (m *mockUpdateHandler) MayAddOutgoingHtlc(lnwire.MilliSatoshi) error { return nil }
|
||||||
|
|
||||||
// ShutdownIfChannelClean currently returns nil.
|
|
||||||
func (m *mockUpdateHandler) ShutdownIfChannelClean() error { return nil }
|
|
||||||
|
|
||||||
type mockMessageConn struct {
|
type mockMessageConn struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user