htlcswitch: add new CloseType enum to account for all closure types
This commit is contained in:
parent
a5d9ce2fac
commit
93cbfdbd60
@ -7,18 +7,18 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
"github.com/lightningnetwork/lnd/routing"
|
||||
"github.com/lightningnetwork/lnd/routing/rt/graph"
|
||||
"github.com/btcsuite/fastsha256"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lightning-onion"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/routing"
|
||||
"github.com/lightningnetwork/lnd/routing/rt/graph"
|
||||
"github.com/roasbeef/btcd/btcec"
|
||||
"github.com/roasbeef/btcd/wire"
|
||||
"github.com/roasbeef/btcutil"
|
||||
"golang.org/x/crypto/ripemd160"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -184,6 +184,8 @@ func (h *htlcSwitch) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
hswcLog.Tracef("Starting HTLC switch")
|
||||
|
||||
h.wg.Add(2)
|
||||
go h.networkAdmin()
|
||||
go h.htlcForwarder()
|
||||
@ -198,6 +200,8 @@ func (h *htlcSwitch) Stop() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
hswcLog.Infof("HLTC switch shutting down")
|
||||
|
||||
close(h.quit)
|
||||
h.wg.Wait()
|
||||
|
||||
@ -480,7 +484,7 @@ func (h *htlcSwitch) handleRegisterLink(req *registerLinkMsg) {
|
||||
// this link leaves the interface empty, then the interface entry itself is
|
||||
// also deleted.
|
||||
func (h *htlcSwitch) handleUnregisterLink(req *unregisterLinkMsg) {
|
||||
hswcLog.Infof("unregistering active link, interface=%v, chan_point=%v",
|
||||
hswcLog.Debugf("unregistering active link, interface=%v, chan_point=%v",
|
||||
hex.EncodeToString(req.chanInterface[:]), req.chanPoint)
|
||||
|
||||
chanInterface := req.chanInterface
|
||||
@ -493,7 +497,7 @@ func (h *htlcSwitch) handleUnregisterLink(req *unregisterLinkMsg) {
|
||||
// links for this channel should be cleared.
|
||||
chansRemoved := make([]*wire.OutPoint, 0, len(links))
|
||||
if req.chanPoint == nil {
|
||||
hswcLog.Infof("purging all active links for interface %v",
|
||||
hswcLog.Debugf("purging all active links for interface %v",
|
||||
hex.EncodeToString(chanInterface[:]))
|
||||
|
||||
for _, link := range links {
|
||||
@ -550,7 +554,7 @@ func (h *htlcSwitch) handleUnregisterLink(req *unregisterLinkMsg) {
|
||||
// * just have the interfaces index be keyed on hash160?
|
||||
|
||||
if len(links) == 0 {
|
||||
hswcLog.Infof("interface %v has no active links, destroying",
|
||||
hswcLog.Debugf("interface %v has no active links, destroying",
|
||||
hex.EncodeToString(chanInterface[:]))
|
||||
h.interfaceMtx.Lock()
|
||||
delete(h.interfaces, chanInterface)
|
||||
@ -574,7 +578,7 @@ func (h *htlcSwitch) handleCloseLink(req *closeLinkReq) {
|
||||
return
|
||||
}
|
||||
|
||||
hswcLog.Infof("requesting interface %v to close link %v",
|
||||
hswcLog.Debugf("requesting interface %v to close link %v",
|
||||
hex.EncodeToString(targetLink.peer.lightningID[:]), req.chanPoint)
|
||||
targetLink.peer.localCloseChanReqs <- req
|
||||
}
|
||||
@ -650,11 +654,30 @@ func (h *htlcSwitch) UnregisterLink(remotePub *btcec.PublicKey, chanPoint *wire.
|
||||
<-done
|
||||
}
|
||||
|
||||
// closeChanReq represents a request to close a particular channel specified
|
||||
// by its outpoint.
|
||||
// LinkCloseType is a enum which signals the type of channel closure the switch
|
||||
// should execute.
|
||||
type LinkCloseType uint8
|
||||
|
||||
const (
|
||||
// CloseRegular indicates a regular cooperative channel closure should be attempted.
|
||||
CloseRegular LinkCloseType = iota
|
||||
|
||||
// CloseForce indicates that the channel should be forcefully closed.
|
||||
// This entails the broadcast of the commitment transaction directly on
|
||||
// chain unilaterally.
|
||||
CloseForce
|
||||
|
||||
// CloseBreach indicates that a channel breach has been dtected, and
|
||||
// the link should immediately be marked as unavailable.
|
||||
CloseBreach
|
||||
)
|
||||
|
||||
// closeChanReq represents a request to close a particular channel specified by
|
||||
// its outpoint.
|
||||
type closeLinkReq struct {
|
||||
chanPoint *wire.OutPoint
|
||||
forceClose bool
|
||||
CloseType LinkCloseType
|
||||
|
||||
chanPoint *wire.OutPoint
|
||||
|
||||
updates chan *lnrpc.CloseStatusUpdate
|
||||
err chan error
|
||||
@ -663,18 +686,18 @@ type closeLinkReq struct {
|
||||
// CloseLink closes an active link targetted by it's channel point. Closing the
|
||||
// link initiates a cooperative channel closure iff forceClose is false. If
|
||||
// forceClose is true, then a unilateral channel closure is executed.
|
||||
// TODO(roabeef): bool flag for timeout
|
||||
// TODO(roasbeef): consolidate with UnregisterLink?
|
||||
func (h *htlcSwitch) CloseLink(chanPoint *wire.OutPoint,
|
||||
forceClose bool) (chan *lnrpc.CloseStatusUpdate, chan error) {
|
||||
closeType LinkCloseType) (chan *lnrpc.CloseStatusUpdate, chan error) {
|
||||
|
||||
updateChan := make(chan *lnrpc.CloseStatusUpdate, 1)
|
||||
errChan := make(chan error, 1)
|
||||
|
||||
h.linkControl <- &closeLinkReq{
|
||||
chanPoint: chanPoint,
|
||||
forceClose: forceClose,
|
||||
updates: updateChan,
|
||||
err: errChan,
|
||||
CloseType: closeType,
|
||||
chanPoint: chanPoint,
|
||||
updates: updateChan,
|
||||
err: errChan,
|
||||
}
|
||||
|
||||
return updateChan, errChan
|
||||
|
2
lnd.go
2
lnd.go
@ -68,7 +68,7 @@ func lndMain() error {
|
||||
defer chanDB.Close()
|
||||
|
||||
// Next load btcd's TLS cert for the RPC connection. If a raw cert was
|
||||
// specified in the config, then we'll se that directly. Otherwise, we
|
||||
// specified in the config, then we'll set that directly. Otherwise, we
|
||||
// attempt to read the cert from the path specified in the config.
|
||||
var rpcCert []byte
|
||||
if cfg.RawRPCCert != "" {
|
||||
|
58
peer.go
58
peer.go
@ -11,7 +11,6 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/lightningnetwork/lnd/routing/rt/graph"
|
||||
"github.com/btcsuite/fastsha256"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lightning-onion"
|
||||
@ -19,6 +18,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/routing/rt/graph"
|
||||
"github.com/roasbeef/btcd/btcec"
|
||||
"github.com/roasbeef/btcd/txscript"
|
||||
"github.com/roasbeef/btcd/wire"
|
||||
@ -778,15 +778,35 @@ func (p *peer) handleLocalClose(req *closeLinkReq) {
|
||||
channel := p.activeChannels[*req.chanPoint]
|
||||
p.activeChanMtx.RUnlock()
|
||||
|
||||
if req.forceClose {
|
||||
switch req.CloseType {
|
||||
// A type of CloseForce indicates that the user has opted for
|
||||
// unilaterally close the channel on-chain.
|
||||
case CloseForce:
|
||||
closingTxid, err = p.executeForceClose(channel)
|
||||
peerLog.Infof("Force closing ChannelPoint(%v) with txid: %v",
|
||||
req.chanPoint, closingTxid)
|
||||
} else {
|
||||
|
||||
// A type of CloseRegular indicates that the user has opted to close
|
||||
// out this channel on-chian, so we execute the cooperative channel
|
||||
// closre workflow.
|
||||
case CloseRegular:
|
||||
closingTxid, err = p.executeCooperativeClose(channel)
|
||||
peerLog.Infof("Attempting cooperative close of "+
|
||||
"ChannelPoint(%v) with txid: %v", req.chanPoint,
|
||||
closingTxid)
|
||||
|
||||
// A type of CloseBreach indicates that the counter-party has breached
|
||||
// the cahnnel therefore we need to clean up our local state.
|
||||
case CloseBreach:
|
||||
peerLog.Infof("ChannelPoint(%v) has been breached, wiping "+
|
||||
"channel", req.chanPoint)
|
||||
if err := wipeChannel(p, channel); err != nil {
|
||||
peerLog.Infof("Unable to wipe channel after detected "+
|
||||
"breach: %v", err)
|
||||
req.err <- err
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
req.err <- err
|
||||
@ -817,11 +837,10 @@ func (p *peer) handleLocalClose(req *closeLinkReq) {
|
||||
|
||||
select {
|
||||
case height, ok := <-confNtfn.Confirmed:
|
||||
// In the case that the ChainNotifier is shutting
|
||||
// down, all subscriber notification channels will be
|
||||
// closed, generating a nil receive.
|
||||
// In the case that the ChainNotifier is shutting down,
|
||||
// all subscriber notification channels will be closed,
|
||||
// generating a nil receive.
|
||||
if !ok {
|
||||
// TODO(roasbeef): check for nil elsewhere
|
||||
return
|
||||
}
|
||||
|
||||
@ -877,10 +896,12 @@ func (p *peer) handleRemoteClose(req *lnwire.CloseRequest) {
|
||||
return
|
||||
}
|
||||
|
||||
peerLog.Infof("Broadcasting cooperative close tx: %v",
|
||||
newLogClosure(func() string {
|
||||
return spew.Sdump(closeTx)
|
||||
}))
|
||||
|
||||
// Finally, broadcast the closure transaction, to the network.
|
||||
peerLog.Infof("Broadcasting cooperative close tx: %v", newLogClosure(func() string {
|
||||
return spew.Sdump(closeTx)
|
||||
}))
|
||||
if err := p.server.lnwallet.PublishTransaction(closeTx); err != nil {
|
||||
peerLog.Errorf("channel close tx from "+
|
||||
"ChannelPoint(%v) rejected: %v",
|
||||
@ -910,20 +931,33 @@ func wipeChannel(p *peer, channel *lnwallet.LightningChannel) error {
|
||||
// longer active.
|
||||
p.server.htlcSwitch.UnregisterLink(p.addr.IdentityKey, chanID)
|
||||
|
||||
// Additionally, close up "down stream" link for the htlcManager which
|
||||
// has been assigned to this channel. This servers the link between the
|
||||
// htlcManager and the switch, signalling that the channel is no longer
|
||||
// active.
|
||||
p.htlcManMtx.RLock()
|
||||
|
||||
// If the channel can't be found in the map, then this channel has
|
||||
// already been wiped.
|
||||
htlcWireLink, ok := p.htlcManagers[*chanID]
|
||||
if !ok {
|
||||
p.htlcManMtx.RUnlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
close(htlcWireLink)
|
||||
|
||||
p.htlcManMtx.RUnlock()
|
||||
|
||||
// Next, we remove the htlcManager from our internal map as the
|
||||
// goroutine should have exited gracefully due to the channel closure
|
||||
// above.
|
||||
p.htlcManMtx.RLock()
|
||||
delete(p.htlcManagers, *chanID)
|
||||
p.htlcManMtx.RUnlock()
|
||||
|
||||
close(htlcWireLink)
|
||||
|
||||
// Finally, we purge the channel's state from the database, leaving a
|
||||
// small summary for historical records.
|
||||
if err := channel.DeleteState(); err != nil {
|
||||
peerLog.Errorf("Unable to delete ChannelPoint(%v) "+
|
||||
"from db %v", chanID, err)
|
||||
|
12
rpcserver.go
12
rpcserver.go
@ -12,7 +12,6 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/lightningnetwork/lnd/routing/rt/graph"
|
||||
"github.com/btcsuite/fastsha256"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/lightningnetwork/lightning-onion"
|
||||
@ -20,6 +19,7 @@ import (
|
||||
"github.com/lightningnetwork/lnd/lnrpc"
|
||||
"github.com/lightningnetwork/lnd/lnwallet"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
"github.com/lightningnetwork/lnd/routing/rt/graph"
|
||||
"github.com/roasbeef/btcd/btcec"
|
||||
"github.com/roasbeef/btcd/txscript"
|
||||
"github.com/roasbeef/btcd/wire"
|
||||
@ -367,7 +367,15 @@ func (r *rpcServer) CloseChannel(in *lnrpc.CloseChannelRequest,
|
||||
rpcsLog.Tracef("[closechannel] request for ChannelPoint(%v)",
|
||||
targetChannelPoint)
|
||||
|
||||
updateChan, errChan := r.server.htlcSwitch.CloseLink(targetChannelPoint, force)
|
||||
var closeType LinkCloseType
|
||||
switch force {
|
||||
case true:
|
||||
closeType = CloseForce
|
||||
case false:
|
||||
closeType = CloseRegular
|
||||
}
|
||||
|
||||
updateChan, errChan := r.server.htlcSwitch.CloseLink(targetChannelPoint, closeType)
|
||||
|
||||
out:
|
||||
for {
|
||||
|
Loading…
Reference in New Issue
Block a user