Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

funding: remove dead code and sanity check pending chan ID #7887

Merged
merged 3 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 26 additions & 47 deletions funding/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,12 +609,6 @@ type Manager struct {
// requests from a local subsystem within the daemon.
fundingRequests chan *InitFundingMsg

// newChanBarriers is a map from a channel ID to a 'barrier' which will
// be signalled once the channel is fully open. This barrier acts as a
// synchronization point for any incoming/outgoing HTLCs before the
// channel has been fully opened.
newChanBarriers *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]

localDiscoverySignals *lnutils.SyncMap[lnwire.ChannelID, chan struct{}]

handleChannelReadyBarriers *lnutils.SyncMap[lnwire.ChannelID, struct{}]
Expand Down Expand Up @@ -671,9 +665,6 @@ func NewFundingManager(cfg Config) (*Manager, error) {
signedReservations: make(
map[lnwire.ChannelID][32]byte,
),
newChanBarriers: &lnutils.SyncMap[
lnwire.ChannelID, chan struct{},
]{},
fundingMsgs: make(
chan *fundingMsg, msgBufferSize,
),
Expand Down Expand Up @@ -728,7 +719,6 @@ func (f *Manager) start() error {
"creating chan barrier",
channel.FundingOutpoint)

f.newChanBarriers.Store(chanID, make(chan struct{}))
f.localDiscoverySignals.Store(
chanID, make(chan struct{}),
)
Expand Down Expand Up @@ -992,16 +982,16 @@ func (f *Manager) reservationCoordinator() {
case fmsg := <-f.fundingMsgs:
switch msg := fmsg.msg.(type) {
case *lnwire.OpenChannel:
f.handleFundingOpen(fmsg.peer, msg)
f.fundeeProcessOpenChannel(fmsg.peer, msg)

case *lnwire.AcceptChannel:
f.handleFundingAccept(fmsg.peer, msg)
f.funderProcessAcceptChannel(fmsg.peer, msg)

case *lnwire.FundingCreated:
f.handleFundingCreated(fmsg.peer, msg)
f.fundeeProcessFundingCreated(fmsg.peer, msg)

case *lnwire.FundingSigned:
f.handleFundingSigned(fmsg.peer, msg)
f.funderProcessFundingSigned(fmsg.peer, msg)

case *lnwire.ChannelReady:
f.wg.Add(1)
Expand Down Expand Up @@ -1311,13 +1301,15 @@ func (f *Manager) ProcessFundingMsg(msg lnwire.Message, peer lnpeer.Peer) {
}
}

// handleFundingOpen creates an initial 'ChannelReservation' within the wallet,
// then responds to the source peer with an accept channel message progressing
// the funding workflow.
// fundeeProcessOpenChannel creates an initial 'ChannelReservation' within the
// wallet, then responds to the source peer with an accept channel message
// progressing the funding workflow.
//
// TODO(roasbeef): add error chan to all, let channelManager handle
// error+propagate.
func (f *Manager) handleFundingOpen(peer lnpeer.Peer,
//
//nolint:funlen
func (f *Manager) fundeeProcessOpenChannel(peer lnpeer.Peer,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice renames 👍

msg *lnwire.OpenChannel) {

// Check number of pending channels to be smaller than maximum allowed
Expand Down Expand Up @@ -1840,10 +1832,12 @@ func (f *Manager) handleFundingOpen(peer lnpeer.Peer,
}
}

// handleFundingAccept processes a response to the workflow initiation sent by
// the remote peer. This message then queues a message with the funding
// funderProcessAcceptChannel processes a response to the workflow initiation
// sent by the remote peer. This message then queues a message with the funding
// outpoint, and a commitment signature to the remote peer.
func (f *Manager) handleFundingAccept(peer lnpeer.Peer,
//
//nolint:funlen
func (f *Manager) funderProcessAcceptChannel(peer lnpeer.Peer,
msg *lnwire.AcceptChannel) {

pendingChanID := msg.PendingChannelID
Expand Down Expand Up @@ -2192,7 +2186,6 @@ func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
// fully open.
channelID := lnwire.NewChanIDFromOutPoint(outPoint)
log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
f.newChanBarriers.Store(channelID, make(chan struct{}))

// The next message that advances the funding flow will reference the
// channel via its permanent channel ID, so we'll set up this mapping
Expand Down Expand Up @@ -2255,11 +2248,14 @@ func (f *Manager) continueFundingAccept(resCtx *reservationWithCtx,
}
}

// handleFundingCreated progresses the funding workflow when the daemon is on
// the responding side of a single funder workflow. Once this message has been
// processed, a signature is sent to the remote peer allowing it to broadcast
// the funding transaction, progressing the workflow into the final stage.
func (f *Manager) handleFundingCreated(peer lnpeer.Peer,
// fundeeProcessFundingCreated progresses the funding workflow when the daemon
// is on the responding side of a single funder workflow. Once this message has
// been processed, a signature is sent to the remote peer allowing it to
// broadcast the funding transaction, progressing the workflow into the final
// stage.
//
//nolint:funlen
func (f *Manager) fundeeProcessFundingCreated(peer lnpeer.Peer,
msg *lnwire.FundingCreated) {

peerKey := peer.IdentityKey()
Expand Down Expand Up @@ -2362,7 +2358,6 @@ func (f *Manager) handleFundingCreated(peer lnpeer.Peer,
// fully open.
channelID := lnwire.NewChanIDFromOutPoint(&fundingOut)
log.Debugf("Creating chan barrier for ChanID(%v)", channelID)
f.newChanBarriers.Store(channelID, make(chan struct{}))

fundingSigned := &lnwire.FundingSigned{}

Expand Down Expand Up @@ -2465,12 +2460,12 @@ func (f *Manager) handleFundingCreated(peer lnpeer.Peer,
go f.advanceFundingState(completeChan, pendingChanID, nil)
}

// handleFundingSigned processes the final message received in a single funder
// workflow. Once this message is processed, the funding transaction is
// funderProcessFundingSigned processes the final message received in a single
// funder workflow. Once this message is processed, the funding transaction is
// broadcast. Once the funding transaction reaches a sufficient number of
// confirmations, a message is sent to the responding peer along with a compact
// encoding of the location of the channel within the blockchain.
func (f *Manager) handleFundingSigned(peer lnpeer.Peer,
func (f *Manager) funderProcessFundingSigned(peer lnpeer.Peer,
msg *lnwire.FundingSigned) {

// As the funding signed message will reference the reservation by its
Expand Down Expand Up @@ -3870,20 +3865,6 @@ func (f *Manager) handleChannelReady(peer lnpeer.Peer, //nolint:funlen
return
}

// Launch a defer so we _ensure_ that the channel barrier is properly
// closed even if the target peer is no longer online at this point.
defer func() {
// Close the active channel barrier signaling the readHandler
// that commitment related modifications to this channel can
// now proceed.
chanBarrier, ok := f.newChanBarriers.LoadAndDelete(chanID)
if ok {
log.Tracef("Closing chan barrier for ChanID(%v)",
chanID)
close(chanBarrier)
}
}()

// Before we can add the channel to the peer, we'll need to ensure that
// we have an initial forwarding policy set.
if err := f.ensureInitialForwardingPolicy(chanID, channel); err != nil {
Expand Down Expand Up @@ -4889,8 +4870,6 @@ func (f *Manager) cancelReservationCtx(peerKey *btcec.PublicKey,
func (f *Manager) deleteReservationCtx(peerKey *btcec.PublicKey,
pendingChanID [32]byte) {

// TODO(roasbeef): possibly cancel funding barrier in peer's
// channelManager?
peerIDKey := newSerializedKey(peerKey)
f.resMtx.Lock()
defer f.resMtx.Unlock()
Expand Down
7 changes: 4 additions & 3 deletions lnwallet/test/test_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ func testReservationInitiatorBalanceBelowDustCancel(miner *rpctest.Harness,
PushMSat: 0,
Flags: lnwire.FFAnnounceChannel,
CommitType: lnwallet.CommitmentTypeTweakless,
PendingChanID: [32]byte{1},
}
_, err = alice.InitChannelReservation(req)
switch {
Expand Down Expand Up @@ -2744,7 +2745,7 @@ var walletTests = []walletTestCase{
testSingleFunderReservationWorkflow(
miner, alice, bob, t,
lnwallet.CommitmentTypeLegacy, nil,
nil, [32]byte{}, 0,
nil, [32]byte{1}, 0,
)
},
},
Expand All @@ -2756,7 +2757,7 @@ var walletTests = []walletTestCase{
testSingleFunderReservationWorkflow(
miner, alice, bob, t,
lnwallet.CommitmentTypeTweakless, nil,
nil, [32]byte{}, 0,
nil, [32]byte{1}, 0,
)
},
},
Expand All @@ -2768,7 +2769,7 @@ var walletTests = []walletTestCase{
testSingleFunderReservationWorkflow(
miner, alice, bob, t,
lnwallet.CommitmentTypeSimpleTaproot, nil,
nil, [32]byte{}, 0,
nil, [32]byte{1}, 0,
)
},
},
Expand Down
18 changes: 16 additions & 2 deletions lnwallet/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,14 @@ var (
ErrReservedValueInvalidated = errors.New("reserved wallet balance " +
"invalidated: transaction would leave insufficient funds for " +
"fee bumping anchor channel closings (see debug log for details)")

// ErrEmptyPendingChanID is returned when an empty value is used for
// the pending channel ID.
ErrEmptyPendingChanID = errors.New("pending channel ID is empty")

// ErrDuplicatePendingChanID is returned when an existing pending
// channel ID is registered again.
ErrDuplicatePendingChanID = errors.New("duplicate pending channel ID")
)

// PsbtFundingRequired is a type that implements the error interface and
Expand Down Expand Up @@ -670,9 +678,15 @@ func (l *LightningWallet) RegisterFundingIntent(expectedID [32]byte,
l.intentMtx.Lock()
defer l.intentMtx.Unlock()

// Sanity check the pending channel ID is not empty.
var zeroID [32]byte
if expectedID == zeroID {
return ErrEmptyPendingChanID
}

if _, ok := l.fundingIntents[expectedID]; ok {
return fmt.Errorf("pendingChanID(%x) already has intent "+
"registered", expectedID[:])
return fmt.Errorf("%w: already has intent registered: %v",
ErrDuplicatePendingChanID, expectedID[:])
}

l.fundingIntents[expectedID] = shimIntent
Expand Down
34 changes: 34 additions & 0 deletions lnwallet/wallet_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package lnwallet

import (
"testing"

"github.com/stretchr/testify/require"
)

// TestRegisterFundingIntent checks RegisterFundingIntent behaves as expected.
func TestRegisterFundingIntent(t *testing.T) {
t.Parallel()

require := require.New(t)

// Create a testing wallet.
lw, err := NewLightningWallet(Config{})
require.NoError(err)

// Init an empty testing channel ID.
var testID [32]byte

// Call the method with empty ID should give us an error.
err = lw.RegisterFundingIntent(testID, nil)
require.ErrorIs(err, ErrEmptyPendingChanID)

// Modify the ID and call the method again should result in no error.
testID[0] = 1
err = lw.RegisterFundingIntent(testID, nil)
require.NoError(err)

// Call the method using the same ID should give us an error.
err = lw.RegisterFundingIntent(testID, nil)
require.ErrorIs(err, ErrDuplicatePendingChanID)
}
Loading