htlcswitch+peer: CreateAndAddLink in switch, add messageSwitch to peer

This commit allows the peer to be tested without relying on a raw
htlcswitch.Switch pointer. This is accomplished by using a messageSwitch
interface and adding the CreateAndAddLink method to the
htlcswitch.Switch.
This commit is contained in:
eugene 2021-08-03 15:18:37 -04:00
parent e72468646c
commit 23a4fad4ac
No known key found for this signature in database
GPG Key ID: 118759E83439A9B1
4 changed files with 74 additions and 30 deletions

View File

@ -1956,6 +1956,15 @@ func (s *Switch) Stop() error {
return nil
}
// CreateAndAddLink will create a link and then add it to the internal maps
// when given a ChannelLinkConfig and LightningChannel.
func (s *Switch) CreateAndAddLink(linkCfg ChannelLinkConfig,
lnChan *lnwallet.LightningChannel) error {
link := NewChannelLink(linkCfg, lnChan)
return s.AddLink(link)
}
// AddLink is used to initiate the handling of the add link command. The
// request will be propagated and handled in the main goroutine.
func (s *Switch) AddLink(link ChannelLink) error {

View File

@ -177,7 +177,7 @@ type Config struct {
// Switch is a pointer to the htlcswitch. It is used to setup, get, and
// tear-down ChannelLinks.
Switch *htlcswitch.Switch
Switch messageSwitch
// InterceptSwitch is a pointer to the InterceptableSwitch, a wrapper around
// the regular Switch. We only export it here to pass ForwardPackets to the
@ -841,18 +841,17 @@ func (p *Brontide) addLink(chanPoint *wire.OutPoint,
HtlcNotifier: p.cfg.HtlcNotifier,
}
link := htlcswitch.NewChannelLink(linkCfg, lnChan)
// Before adding our new link, purge the switch of any pending or live
// links going by the same channel id. If one is found, we'll shut it
// down to ensure that the mailboxes are only ever under the control of
// one link.
p.cfg.Switch.RemoveLink(link.ChanID())
chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
p.cfg.Switch.RemoveLink(chanID)
// With the channel link created, we'll now notify the htlc switch so
// this channel can be used to dispatch local payments and also
// passively forward payments.
return p.cfg.Switch.AddLink(link)
return p.cfg.Switch.CreateAndAddLink(linkCfg, lnChan)
}
// maybeSendNodeAnn sends our node announcement to the remote peer if at least

View File

@ -4,9 +4,36 @@ import (
"net"
"time"
"github.com/lightningnetwork/lnd/htlcswitch"
"github.com/lightningnetwork/lnd/lnwallet"
"github.com/lightningnetwork/lnd/lnwire"
)
// messageSwitch is an interface that abstracts managing the lifecycle of
// abstract links. This is intended for peer package usage only.
type messageSwitch interface {
// BestHeight returns the best height known to the messageSwitch.
BestHeight() uint32
// CircuitModifier returns a reference to the messageSwitch's internal
// CircuitModifier which abstracts the paths payments take and allows
// modifying them.
CircuitModifier() htlcswitch.CircuitModifier
// RemoveLink removes an abstract link given a ChannelID.
RemoveLink(cid lnwire.ChannelID)
// CreateAndAddLink creates an abstract link in the messageSwitch given
// a ChannelLinkConfig and raw LightningChannel pointer.
CreateAndAddLink(cfg htlcswitch.ChannelLinkConfig,
lnChan *lnwallet.LightningChannel) error
// GetLinksByInterface retrieves abstract links (represented by the
// ChannelUpdateHandler interface) based on the provided public key.
GetLinksByInterface(pub [33]byte) ([]htlcswitch.ChannelUpdateHandler,
error)
}
// LinkUpdater is an interface implemented by most messages in BOLT 2 that are
// allowed to update the channel state.
type LinkUpdater interface {

View File

@ -29,7 +29,6 @@ import (
"github.com/lightningnetwork/lnd/netann"
"github.com/lightningnetwork/lnd/queue"
"github.com/lightningnetwork/lnd/shachain"
"github.com/lightningnetwork/lnd/ticker"
"github.com/stretchr/testify/require"
)
@ -307,28 +306,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
},
}
_, currentHeight, err := chainIO.GetBestBlock()
if err != nil {
return nil, nil, nil, err
}
htlcSwitch, err := htlcswitch.New(htlcswitch.Config{
DB: dbAlice,
SwitchPackager: channeldb.NewSwitchPackager(),
Notifier: notifier,
FwdEventTicker: ticker.New(
htlcswitch.DefaultFwdEventInterval),
LogEventTicker: ticker.New(
htlcswitch.DefaultLogInterval),
AckEventTicker: ticker.New(
htlcswitch.DefaultAckInterval),
}, uint32(currentHeight))
if err != nil {
return nil, nil, nil, err
}
if err = htlcSwitch.Start(); err != nil {
return nil, nil, nil, err
}
htlcSwitch := &mockMessageSwitch{}
nodeSignerAlice := netann.NewNodeSigner(aliceKeySigner)
@ -342,7 +320,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
Graph: dbAlice.ChannelGraph(),
MessageSigner: nodeSignerAlice,
OurPubKey: aliceKeyPub,
IsChannelActive: htlcSwitch.HasActiveLink,
IsChannelActive: func(lnwire.ChannelID) bool { return true },
ApplyChannelUpdate: func(*lnwire.ChannelUpdate) error { return nil },
})
if err != nil {
@ -374,7 +352,7 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
Switch: htlcSwitch,
ChanActiveTimeout: chanActiveTimeout,
InterceptSwitch: htlcswitch.NewInterceptableSwitch(htlcSwitch),
InterceptSwitch: htlcswitch.NewInterceptableSwitch(nil),
ChannelDB: dbAlice,
FeeEstimator: estimator,
@ -395,6 +373,37 @@ func createTestPeer(notifier chainntnfs.ChainNotifier,
return alicePeer, channelBob, cleanUpFunc, nil
}
// mockMessageSwitch is a mock implementation of the messageSwitch interface
// used for testing without relying on a *htlcswitch.Switch in unit tests.
type mockMessageSwitch struct{}
// BestHeight currently returns a dummy value.
func (m *mockMessageSwitch) BestHeight() uint32 {
return 0
}
// CircuitModifier currently returns a dummy value.
func (m *mockMessageSwitch) CircuitModifier() htlcswitch.CircuitModifier {
return nil
}
// RemoveLink currently does nothing.
func (m *mockMessageSwitch) RemoveLink(cid lnwire.ChannelID) {}
// CreateAndAddLink currently returns a dummy value.
func (m *mockMessageSwitch) CreateAndAddLink(cfg htlcswitch.ChannelLinkConfig,
lnChan *lnwallet.LightningChannel) error {
return nil
}
// GetLinksByInterface currently returns dummy values.
func (m *mockMessageSwitch) GetLinksByInterface(pub [33]byte) (
[]htlcswitch.ChannelUpdateHandler, error) {
return nil, nil
}
type mockMessageConn struct {
t *testing.T