Merge pull request #1905 from halseth/fundinglocked-htlc-mismatch
Defer channel restoration until after channel active check.
This commit is contained in:
commit
c508365bcc
@ -26,7 +26,6 @@ import (
|
||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnpeer"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/routing"
|
||||
)
|
||||
@ -2315,7 +2314,7 @@ func (p *mockPeer) SendMessage(_ bool, msgs ...lnwire.Message) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
func (p *mockPeer) AddNewChannel(_ *lnwallet.LightningChannel, _ <-chan struct{}) error {
|
||||
func (p *mockPeer) AddNewChannel(_ *channeldb.OpenChannel, _ <-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
func (p *mockPeer) WipeChannel(_ *wire.OutPoint) error { return nil }
|
||||
|
@ -267,7 +267,7 @@ type fundingConfig struct {
|
||||
|
||||
// FindChannel queries the database for the channel with the given
|
||||
// channel ID.
|
||||
FindChannel func(chanID lnwire.ChannelID) (*lnwallet.LightningChannel, error)
|
||||
FindChannel func(chanID lnwire.ChannelID) (*channeldb.OpenChannel, error)
|
||||
|
||||
// TempChanIDSeed is a cryptographically random string of bytes that's
|
||||
// used as a seed to generate pending channel ID's.
|
||||
@ -2323,10 +2323,9 @@ func (f *fundingManager) handleFundingLocked(fmsg *fundingLockedMsg) {
|
||||
|
||||
// If the RemoteNextRevocation is non-nil, it means that we have
|
||||
// already processed fundingLocked for this channel, so ignore.
|
||||
if channel.RemoteNextRevocation() != nil {
|
||||
if channel.RemoteNextRevocation != nil {
|
||||
fndgLog.Infof("Received duplicate fundingLocked for "+
|
||||
"ChannelID(%v), ignoring.", chanID)
|
||||
channel.Stop()
|
||||
return
|
||||
}
|
||||
|
||||
@ -2334,10 +2333,9 @@ func (f *fundingManager) handleFundingLocked(fmsg *fundingLockedMsg) {
|
||||
// need to create the next commitment state for the remote party. So
|
||||
// we'll insert that into the channel now before passing it along to
|
||||
// other sub-systems.
|
||||
err = channel.InitNextRevocation(fmsg.msg.NextPerCommitmentPoint)
|
||||
err = channel.InsertNextRevocation(fmsg.msg.NextPerCommitmentPoint)
|
||||
if err != nil {
|
||||
fndgLog.Errorf("unable to insert next commitment point: %v", err)
|
||||
channel.Stop()
|
||||
return
|
||||
}
|
||||
|
||||
@ -2361,8 +2359,7 @@ func (f *fundingManager) handleFundingLocked(fmsg *fundingLockedMsg) {
|
||||
if err := fmsg.peer.AddNewChannel(channel, f.quit); err != nil {
|
||||
fndgLog.Errorf("Unable to add new channel %v with peer %x: %v",
|
||||
fmsg.peer.IdentityKey().SerializeCompressed(),
|
||||
*channel.ChanPoint, err)
|
||||
channel.Stop()
|
||||
channel.FundingOutpoint, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,13 +178,13 @@ func (n *testNode) QuitSignal() <-chan struct{} {
|
||||
return n.shutdownChannel
|
||||
}
|
||||
|
||||
func (n *testNode) AddNewChannel(channel *lnwallet.LightningChannel,
|
||||
func (n *testNode) AddNewChannel(channel *channeldb.OpenChannel,
|
||||
quit <-chan struct{}) error {
|
||||
|
||||
done := make(chan struct{})
|
||||
errChan := make(chan error)
|
||||
msg := &newChannelMsg{
|
||||
channel: channel,
|
||||
done: done,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
select {
|
||||
@ -194,12 +194,11 @@ func (n *testNode) AddNewChannel(channel *lnwallet.LightningChannel,
|
||||
}
|
||||
|
||||
select {
|
||||
case <-done:
|
||||
case err := <-errChan:
|
||||
return err
|
||||
case <-quit:
|
||||
return ErrFundingManagerShuttingDown
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -304,7 +303,8 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
|
||||
return lnwire.NodeAnnouncement{}, nil
|
||||
},
|
||||
TempChanIDSeed: chanIDSeed,
|
||||
FindChannel: func(chanID lnwire.ChannelID) (*lnwallet.LightningChannel, error) {
|
||||
FindChannel: func(chanID lnwire.ChannelID) (
|
||||
*channeldb.OpenChannel, error) {
|
||||
dbChannels, err := cdb.FetchAllChannels()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -312,10 +312,7 @@ func createTestFundingManager(t *testing.T, privKey *btcec.PrivateKey,
|
||||
|
||||
for _, channel := range dbChannels {
|
||||
if chanID.IsChanPoint(&channel.FundingOutpoint) {
|
||||
return lnwallet.NewLightningChannel(
|
||||
signer,
|
||||
nil,
|
||||
channel)
|
||||
return channel, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -992,14 +989,14 @@ func assertHandleFundingLocked(t *testing.T, alice, bob *testNode) {
|
||||
// They should both send the new channel state to their peer.
|
||||
select {
|
||||
case c := <-alice.newChannels:
|
||||
close(c.done)
|
||||
close(c.err)
|
||||
case <-time.After(time.Second * 15):
|
||||
t.Fatalf("alice did not send new channel to peer")
|
||||
}
|
||||
|
||||
select {
|
||||
case c := <-bob.newChannels:
|
||||
close(c.done)
|
||||
close(c.err)
|
||||
case <-time.After(time.Second * 15):
|
||||
t.Fatalf("bob did not send new channel to peer")
|
||||
}
|
||||
|
@ -1477,7 +1477,8 @@ func (m *mockPeer) SendMessage(sync bool, msgs ...lnwire.Message) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (m *mockPeer) AddNewChannel(_ *lnwallet.LightningChannel, _ <-chan struct{}) error {
|
||||
func (m *mockPeer) AddNewChannel(_ *channeldb.OpenChannel,
|
||||
_ <-chan struct{}) error {
|
||||
return nil
|
||||
}
|
||||
func (m *mockPeer) WipeChannel(*wire.OutPoint) error {
|
||||
|
@ -543,7 +543,7 @@ func (s *mockServer) Address() net.Addr {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *mockServer) AddNewChannel(channel *lnwallet.LightningChannel,
|
||||
func (s *mockServer) AddNewChannel(channel *channeldb.OpenChannel,
|
||||
cancel <-chan struct{}) error {
|
||||
|
||||
return nil
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/btcsuite/btcd/btcec"
|
||||
"github.com/btcsuite/btcd/wire"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
)
|
||||
|
||||
@ -19,7 +19,7 @@ type Peer interface {
|
||||
|
||||
// AddNewChannel adds a new channel to the peer. The channel should fail
|
||||
// to be added if the cancel channel is closed.
|
||||
AddNewChannel(channel *lnwallet.LightningChannel, cancel <-chan struct{}) error
|
||||
AddNewChannel(channel *channeldb.OpenChannel, cancel <-chan struct{}) error
|
||||
|
||||
// WipeChannel removes the channel uniquely identified by its channel
|
||||
// point from all indexes associated with the peer.
|
||||
|
74
peer.go
74
peer.go
@ -59,12 +59,12 @@ type outgoingMsg struct {
|
||||
errChan chan error // MUST be buffered.
|
||||
}
|
||||
|
||||
// newChannelMsg packages an lnwallet.LightningChannel with a channel that
|
||||
// allows the receiver of the request to report when the funding transaction
|
||||
// has been confirmed and the channel creation process completed.
|
||||
// newChannelMsg packages a channeldb.OpenChannel with a channel that allows
|
||||
// the receiver of the request to report when the funding transaction has been
|
||||
// confirmed and the channel creation process completed.
|
||||
type newChannelMsg struct {
|
||||
channel *lnwallet.LightningChannel
|
||||
done chan struct{}
|
||||
channel *channeldb.OpenChannel
|
||||
err chan error
|
||||
}
|
||||
|
||||
// closeMsgs is a wrapper struct around any wire messages that deal with the
|
||||
@ -1522,9 +1522,9 @@ out:
|
||||
// funding workflow. We'll initialize the necessary local
|
||||
// state, and notify the htlc switch of a new link.
|
||||
case newChanReq := <-p.newChannels:
|
||||
chanPoint := newChanReq.channel.ChannelPoint()
|
||||
chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
|
||||
newChan := newChanReq.channel
|
||||
chanPoint := &newChan.FundingOutpoint
|
||||
chanID := lnwire.NewChanIDFromOutPoint(chanPoint)
|
||||
|
||||
// Make sure this channel is not already active.
|
||||
p.activeChanMtx.Lock()
|
||||
@ -1533,8 +1533,7 @@ out:
|
||||
"ignoring.", chanPoint)
|
||||
|
||||
p.activeChanMtx.Unlock()
|
||||
close(newChanReq.done)
|
||||
newChanReq.channel.Stop()
|
||||
close(newChanReq.err)
|
||||
|
||||
// If we're being sent a new channel, and our
|
||||
// existing channel doesn't have the next
|
||||
@ -1548,7 +1547,7 @@ out:
|
||||
"FundingLocked for ChannelPoint(%v)",
|
||||
chanPoint)
|
||||
|
||||
nextRevoke := newChan.RemoteNextRevocation()
|
||||
nextRevoke := newChan.RemoteNextRevocation
|
||||
err := currentChan.InitNextRevocation(nextRevoke)
|
||||
if err != nil {
|
||||
peerLog.Errorf("unable to init chan "+
|
||||
@ -1562,7 +1561,21 @@ out:
|
||||
// If not already active, we'll add this channel to the
|
||||
// set of active channels, so we can look it up later
|
||||
// easily according to its channel ID.
|
||||
p.activeChannels[chanID] = newChan
|
||||
lnChan, err := lnwallet.NewLightningChannel(
|
||||
p.server.cc.signer, p.server.witnessBeacon,
|
||||
newChan,
|
||||
)
|
||||
if err != nil {
|
||||
p.activeChanMtx.Unlock()
|
||||
err := fmt.Errorf("unable to create "+
|
||||
"LightningChannel: %v", err)
|
||||
peerLog.Errorf(err.Error())
|
||||
|
||||
newChanReq.err <- err
|
||||
continue
|
||||
}
|
||||
|
||||
p.activeChannels[chanID] = lnChan
|
||||
p.activeChanMtx.Unlock()
|
||||
|
||||
peerLog.Infof("New channel active ChannelPoint(%v) "+
|
||||
@ -1574,15 +1587,24 @@ out:
|
||||
// TODO(roasbeef): panic on below?
|
||||
_, currentHeight, err := p.server.cc.chainIO.GetBestBlock()
|
||||
if err != nil {
|
||||
peerLog.Errorf("unable to get best block: %v", err)
|
||||
err := fmt.Errorf("unable to get best "+
|
||||
"block: %v", err)
|
||||
peerLog.Errorf(err.Error())
|
||||
|
||||
lnChan.Stop()
|
||||
newChanReq.err <- err
|
||||
continue
|
||||
}
|
||||
chainEvents, err := p.server.chainArb.SubscribeChannelEvents(
|
||||
*chanPoint,
|
||||
)
|
||||
if err != nil {
|
||||
peerLog.Errorf("unable to subscribe to chain "+
|
||||
"events: %v", err)
|
||||
err := fmt.Errorf("unable to subscribe to "+
|
||||
"chain events: %v", err)
|
||||
peerLog.Errorf(err.Error())
|
||||
|
||||
lnChan.Stop()
|
||||
newChanReq.err <- err
|
||||
continue
|
||||
}
|
||||
|
||||
@ -1591,7 +1613,7 @@ out:
|
||||
// forwarded. For fees we'll use the default values, as
|
||||
// they currently are always set to the default values
|
||||
// at initial channel creation.
|
||||
fwdMinHtlc := newChan.FwdMinHtlc()
|
||||
fwdMinHtlc := lnChan.FwdMinHtlc()
|
||||
defaultPolicy := p.server.cc.routingPolicy
|
||||
forwardingPolicy := &htlcswitch.ForwardingPolicy{
|
||||
MinHTLC: fwdMinHtlc,
|
||||
@ -1602,16 +1624,21 @@ out:
|
||||
|
||||
// Create the link and add it to the switch.
|
||||
err = p.addLink(
|
||||
chanPoint, newChan, forwardingPolicy,
|
||||
chanPoint, lnChan, forwardingPolicy,
|
||||
chainEvents, currentHeight, false,
|
||||
)
|
||||
if err != nil {
|
||||
peerLog.Errorf("can't register new channel "+
|
||||
err := fmt.Errorf("can't register new channel "+
|
||||
"link(%v) with NodeKey(%x)", chanPoint,
|
||||
p.PubKey())
|
||||
peerLog.Errorf(err.Error())
|
||||
|
||||
lnChan.Stop()
|
||||
newChanReq.err <- err
|
||||
continue
|
||||
}
|
||||
|
||||
close(newChanReq.done)
|
||||
close(newChanReq.err)
|
||||
|
||||
// We've just received a local request to close an active
|
||||
// channel. If will either kick of a cooperative channel
|
||||
@ -2171,13 +2198,13 @@ func (p *peer) Address() net.Addr {
|
||||
// added if the cancel channel is closed.
|
||||
//
|
||||
// NOTE: Part of the lnpeer.Peer interface.
|
||||
func (p *peer) AddNewChannel(channel *lnwallet.LightningChannel,
|
||||
func (p *peer) AddNewChannel(channel *channeldb.OpenChannel,
|
||||
cancel <-chan struct{}) error {
|
||||
|
||||
newChanDone := make(chan struct{})
|
||||
errChan := make(chan error, 1)
|
||||
newChanMsg := &newChannelMsg{
|
||||
channel: channel,
|
||||
done: newChanDone,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
select {
|
||||
@ -2191,12 +2218,11 @@ func (p *peer) AddNewChannel(channel *lnwallet.LightningChannel,
|
||||
// We pause here to wait for the peer to recognize the new channel
|
||||
// before we close the channel barrier corresponding to the channel.
|
||||
select {
|
||||
case <-newChanDone:
|
||||
case err := <-errChan:
|
||||
return err
|
||||
case <-p.quit:
|
||||
return ErrPeerExiting
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartTime returns the time at which the connection was established if the
|
||||
|
@ -743,7 +743,9 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
|
||||
},
|
||||
NotifyWhenOnline: s.NotifyWhenOnline,
|
||||
TempChanIDSeed: chanIDSeed,
|
||||
FindChannel: func(chanID lnwire.ChannelID) (*lnwallet.LightningChannel, error) {
|
||||
FindChannel: func(chanID lnwire.ChannelID) (
|
||||
*channeldb.OpenChannel, error) {
|
||||
|
||||
dbChannels, err := chanDB.FetchAllChannels()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -751,10 +753,7 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
|
||||
|
||||
for _, channel := range dbChannels {
|
||||
if chanID.IsChanPoint(&channel.FundingOutpoint) {
|
||||
return lnwallet.NewLightningChannel(
|
||||
cc.signer, s.witnessBeacon,
|
||||
channel,
|
||||
)
|
||||
return channel, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user