funding: cleanup of 6 conf and 'private' channel logic
This commits slightly rewrites the newly introduced logic for private channels. Instead of keeping the channel announce preference in a database within fundingManager, it is stored as part of the OpenChannel struct. In addition, the ChanOpenStatus_Open update is now sent after the channel is added to the router, instead of waiting until the 6 blocks confirmation has passed.
This commit is contained in:
parent
fffe15f0fd
commit
9af7cc9b99
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/lnrpc"
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwire"
|
"github.com/lightningnetwork/lnd/lnwire"
|
||||||
|
"github.com/lightningnetwork/lnd/routing"
|
||||||
"github.com/roasbeef/btcd/btcec"
|
"github.com/roasbeef/btcd/btcec"
|
||||||
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
||||||
"github.com/roasbeef/btcd/wire"
|
"github.com/roasbeef/btcd/wire"
|
||||||
@ -182,10 +183,10 @@ type fundingConfig struct {
|
|||||||
// announcement from the backing Lighting Network node.
|
// announcement from the backing Lighting Network node.
|
||||||
CurrentNodeAnnouncement func() (lnwire.NodeAnnouncement, error)
|
CurrentNodeAnnouncement func() (lnwire.NodeAnnouncement, error)
|
||||||
|
|
||||||
// SendLocalAnnouncement is used by the FundingManager to send
|
// SendAnnouncement is used by the FundingManager to send
|
||||||
// announcement messages to the Gossiper to possibly broadcast
|
// announcement messages to the Gossiper to possibly broadcast
|
||||||
// to the greater network.
|
// to the greater network.
|
||||||
SendLocalAnnouncement func(msg lnwire.Message) error
|
SendAnnouncement func(msg lnwire.Message) error
|
||||||
|
|
||||||
// SendToPeer allows the FundingManager to send messages to the peer
|
// SendToPeer allows the FundingManager to send messages to the peer
|
||||||
// node during the multiple steps involved in the creation of the
|
// node during the multiple steps involved in the creation of the
|
||||||
@ -261,10 +262,6 @@ type fundingManager struct {
|
|||||||
// funding workflows.
|
// funding workflows.
|
||||||
activeReservations map[serializedPubKey]pendingChannels
|
activeReservations map[serializedPubKey]pendingChannels
|
||||||
|
|
||||||
// pendingChanAnnPrefs is a map which stores a pending channel's id
|
|
||||||
// along with its announcement preference.
|
|
||||||
pendingChanAnnPrefs map[[32]byte]bool
|
|
||||||
|
|
||||||
// signedReservations is a utility map that maps the permanent channel
|
// signedReservations is a utility map that maps the permanent channel
|
||||||
// ID of a funding reservation to its temporary channel ID. This is
|
// ID of a funding reservation to its temporary channel ID. This is
|
||||||
// required as mid funding flow, we switch to referencing the channel
|
// required as mid funding flow, we switch to referencing the channel
|
||||||
@ -334,12 +331,6 @@ var (
|
|||||||
// of being opened.
|
// of being opened.
|
||||||
channelOpeningStateBucket = []byte("channelOpeningState")
|
channelOpeningStateBucket = []byte("channelOpeningState")
|
||||||
|
|
||||||
// openChanAnnPrefBucket is the database bucket used to store each
|
|
||||||
// channel's announcement preference signalled by the LSB of
|
|
||||||
// channel_flags of the open_channel message in the funding workflow.
|
|
||||||
// It only stores open channels' announcement preferences.
|
|
||||||
openChanAnnPrefBucket = []byte("open_chan_ann")
|
|
||||||
|
|
||||||
// ErrChannelNotFound is returned when we are looking for a specific
|
// ErrChannelNotFound is returned when we are looking for a specific
|
||||||
// channel opening state in the FundingManager's internal database, but
|
// channel opening state in the FundingManager's internal database, but
|
||||||
// the channel in question is not considered being in an opening state.
|
// the channel in question is not considered being in an opening state.
|
||||||
@ -359,7 +350,6 @@ func newFundingManager(cfg fundingConfig) (*fundingManager, error) {
|
|||||||
fundingRequests: make(chan *initFundingMsg, msgBufferSize),
|
fundingRequests: make(chan *initFundingMsg, msgBufferSize),
|
||||||
localDiscoverySignals: make(map[lnwire.ChannelID]chan struct{}),
|
localDiscoverySignals: make(map[lnwire.ChannelID]chan struct{}),
|
||||||
handleFundingLockedBarriers: make(map[lnwire.ChannelID]struct{}),
|
handleFundingLockedBarriers: make(map[lnwire.ChannelID]struct{}),
|
||||||
pendingChanAnnPrefs: make(map[[32]byte]bool),
|
|
||||||
queries: make(chan interface{}, 1),
|
queries: make(chan interface{}, 1),
|
||||||
quit: make(chan struct{}),
|
quit: make(chan struct{}),
|
||||||
}, nil
|
}, nil
|
||||||
@ -505,40 +495,22 @@ func (f *fundingManager) Start() error {
|
|||||||
go func(dbChan *channeldb.OpenChannel) {
|
go func(dbChan *channeldb.OpenChannel) {
|
||||||
defer f.wg.Done()
|
defer f.wg.Done()
|
||||||
|
|
||||||
// Retrieve channel announcement preference
|
err = f.addToRouterGraph(dbChan, shortChanID)
|
||||||
private, err := f.getOpenChanAnnPref(
|
|
||||||
&dbChan.FundingOutpoint)
|
|
||||||
if err != nil {
|
|
||||||
fndgLog.Errorf("unable to retrieve channel "+
|
|
||||||
"announcement preference: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lnChannel, err := lnwallet.NewLightningChannel(
|
|
||||||
nil, nil, f.cfg.FeeEstimator, dbChan)
|
|
||||||
if err != nil {
|
|
||||||
fndgLog.Errorf("error creating "+
|
|
||||||
"lightning channel: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer lnChannel.Stop()
|
|
||||||
|
|
||||||
err = f.addToRouterGraph(dbChan, lnChannel,
|
|
||||||
shortChanID, private)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Errorf("failed adding to "+
|
fndgLog.Errorf("failed adding to "+
|
||||||
"router graph: %v", err)
|
"router graph: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !private {
|
// TODO(halseth): should create a state machine
|
||||||
err = f.annAfterSixConfs(dbChan,
|
// that can more easily be resumed from
|
||||||
lnChannel, shortChanID)
|
// different states, to avoid this code
|
||||||
if err != nil {
|
// duplication.
|
||||||
fndgLog.Errorf("error sending channel "+
|
err = f.annAfterSixConfs(dbChan, shortChanID)
|
||||||
"announcement: %v", err)
|
if err != nil {
|
||||||
return
|
fndgLog.Errorf("error sending channel "+
|
||||||
}
|
"announcements: %v", err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}(channel)
|
}(channel)
|
||||||
|
|
||||||
@ -548,43 +520,13 @@ func (f *fundingManager) Start() error {
|
|||||||
f.wg.Add(1)
|
f.wg.Add(1)
|
||||||
go func(dbChan *channeldb.OpenChannel) {
|
go func(dbChan *channeldb.OpenChannel) {
|
||||||
defer f.wg.Done()
|
defer f.wg.Done()
|
||||||
// Retrieve channel announcement preference
|
|
||||||
private, err := f.getOpenChanAnnPref(
|
|
||||||
&dbChan.FundingOutpoint)
|
|
||||||
if err != nil {
|
|
||||||
fndgLog.Errorf("unable to retrieve channel "+
|
|
||||||
"announcement preference: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
lnChannel, err := lnwallet.NewLightningChannel(
|
err = f.annAfterSixConfs(channel, shortChanID)
|
||||||
nil, nil, f.cfg.FeeEstimator, dbChan)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Errorf("error creating "+
|
fndgLog.Errorf("error sending channel "+
|
||||||
"lightning channel: %v", err)
|
"announcement: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer lnChannel.Stop()
|
|
||||||
|
|
||||||
if private {
|
|
||||||
// We delete the channel from our internal
|
|
||||||
// database.
|
|
||||||
err := f.deleteChannelOpeningState(
|
|
||||||
&channel.FundingOutpoint)
|
|
||||||
if err != nil {
|
|
||||||
fndgLog.Errorf("error deleting "+
|
|
||||||
"channel state: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = f.annAfterSixConfs(channel,
|
|
||||||
lnChannel, shortChanID)
|
|
||||||
if err != nil {
|
|
||||||
fndgLog.Errorf("error sending channel "+
|
|
||||||
"announcement: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}(channel)
|
}(channel)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -729,7 +671,6 @@ func (f *fundingManager) failFundingFlow(peer *btcec.PublicKey,
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(f.pendingChanAnnPrefs, tempChanID)
|
|
||||||
f.cancelReservationCtx(peer, tempChanID)
|
f.cancelReservationCtx(peer, tempChanID)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -826,6 +767,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
|||||||
// number and send ErrorGeneric to remote peer if condition is
|
// number and send ErrorGeneric to remote peer if condition is
|
||||||
// violated.
|
// violated.
|
||||||
peerIDKey := newSerializedKey(fmsg.peerAddress.IdentityKey)
|
peerIDKey := newSerializedKey(fmsg.peerAddress.IdentityKey)
|
||||||
|
|
||||||
msg := fmsg.msg
|
msg := fmsg.msg
|
||||||
amt := msg.FundingAmount
|
amt := msg.FundingAmount
|
||||||
|
|
||||||
@ -883,7 +825,7 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
|||||||
reservation, err := f.cfg.Wallet.InitChannelReservation(amt, 0,
|
reservation, err := f.cfg.Wallet.InitChannelReservation(amt, 0,
|
||||||
msg.PushAmount, btcutil.Amount(msg.FeePerKiloWeight), 0,
|
msg.PushAmount, btcutil.Amount(msg.FeePerKiloWeight), 0,
|
||||||
fmsg.peerAddress.IdentityKey, fmsg.peerAddress.Address,
|
fmsg.peerAddress.IdentityKey, fmsg.peerAddress.Address,
|
||||||
&chainHash)
|
&chainHash, msg.ChannelFlags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fndgLog.Errorf("Unable to initialize reservation: %v", err)
|
fndgLog.Errorf("Unable to initialize reservation: %v", err)
|
||||||
f.failFundingFlow(fmsg.peerAddress.IdentityKey,
|
f.failFundingFlow(fmsg.peerAddress.IdentityKey,
|
||||||
@ -934,16 +876,6 @@ func (f *fundingManager) handleFundingOpen(fmsg *fundingOpenMsg) {
|
|||||||
}
|
}
|
||||||
f.resMtx.Unlock()
|
f.resMtx.Unlock()
|
||||||
|
|
||||||
// Save the announcement preference of this pending channel
|
|
||||||
if msg.ChannelFlags&1 == 0 {
|
|
||||||
// This channel WILL be announced to the greater network later.
|
|
||||||
f.pendingChanAnnPrefs[msg.PendingChannelID] = false
|
|
||||||
} else {
|
|
||||||
// This channel WILL NOT be announced to the greater network
|
|
||||||
// later.
|
|
||||||
f.pendingChanAnnPrefs[msg.PendingChannelID] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Using the RequiredRemoteDelay closure, we'll compute the remote CSV
|
// Using the RequiredRemoteDelay closure, we'll compute the remote CSV
|
||||||
// delay we require given the total amount of funds within the channel.
|
// delay we require given the total amount of funds within the channel.
|
||||||
remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt)
|
remoteCsvDelay := f.cfg.RequiredRemoteDelay(amt)
|
||||||
@ -1178,12 +1110,6 @@ func (f *fundingManager) handleFundingCreated(fmsg *fundingCreatedMsg) {
|
|||||||
peerKey, pendingChanID[:])
|
peerKey, pendingChanID[:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
private, ok := f.pendingChanAnnPrefs[pendingChanID]
|
|
||||||
if !ok {
|
|
||||||
fndgLog.Warnf("can't find channel announcement preference for"+
|
|
||||||
"chanID:%x", pendingChanID[:])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// The channel initiator has responded with the funding outpoint of the
|
// The channel initiator has responded with the funding outpoint of the
|
||||||
// final funding transaction, as well as a signature for our version of
|
// final funding transaction, as well as a signature for our version of
|
||||||
@ -1210,32 +1136,10 @@ func (f *fundingManager) handleFundingCreated(fmsg *fundingCreatedMsg) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// A new channel has almost finished the funding process. In order to
|
|
||||||
// properly synchronize with the writeHandler goroutine, we add a new
|
|
||||||
// channel to the barriers map which will be closed once the channel is
|
|
||||||
// fully open.
|
|
||||||
f.barrierMtx.Lock()
|
|
||||||
channelID := lnwire.NewChanIDFromOutPoint(&fundingOut)
|
|
||||||
fndgLog.Debugf("Creating chan barrier for ChanID(%v)", channelID)
|
|
||||||
f.newChanBarriers[channelID] = make(chan struct{})
|
|
||||||
f.barrierMtx.Unlock()
|
|
||||||
|
|
||||||
// Store channel announcement preference in boltdb
|
|
||||||
if err = f.saveOpenChanAnnPref(&fundingOut, private); err != nil {
|
|
||||||
fndgLog.Errorf("unable to save channel announcement preference "+
|
|
||||||
"to db for chanID:%x", channelID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If something goes wrong before the funding transaction is confirmed,
|
// If something goes wrong before the funding transaction is confirmed,
|
||||||
// we use this convenience method to delete the pending OpenChannel
|
// we use this convenience method to delete the pending OpenChannel
|
||||||
// from the database.
|
// from the database.
|
||||||
deleteFromDatabase := func() {
|
deleteFromDatabase := func() {
|
||||||
err := f.deleteOpenChanAnnPref(&completeChan.FundingOutpoint)
|
|
||||||
if err != nil {
|
|
||||||
fndgLog.Errorf("Failed to delete channel announcement "+
|
|
||||||
"preference: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
closeInfo := &channeldb.ChannelCloseSummary{
|
closeInfo := &channeldb.ChannelCloseSummary{
|
||||||
ChanPoint: completeChan.FundingOutpoint,
|
ChanPoint: completeChan.FundingOutpoint,
|
||||||
ChainHash: completeChan.ChainHash,
|
ChainHash: completeChan.ChainHash,
|
||||||
@ -1318,31 +1222,36 @@ func (f *fundingManager) handleFundingCreated(fmsg *fundingCreatedMsg) {
|
|||||||
go f.waitForFundingWithTimeout(completeChan, confChan,
|
go f.waitForFundingWithTimeout(completeChan, confChan,
|
||||||
timeoutChan)
|
timeoutChan)
|
||||||
|
|
||||||
|
var shortChanID *lnwire.ShortChannelID
|
||||||
|
var ok bool
|
||||||
select {
|
select {
|
||||||
case <-timeoutChan:
|
case <-timeoutChan:
|
||||||
// We did not see the funding confirmation before
|
// We did not see the funding confirmation before
|
||||||
// timeout, so we forget the channel.
|
// timeout, so we forget the channel.
|
||||||
deleteFromDatabase()
|
deleteFromDatabase()
|
||||||
|
return
|
||||||
case <-f.quit:
|
case <-f.quit:
|
||||||
// The fundingManager is shutting down, will resume
|
// The fundingManager is shutting down, will resume
|
||||||
// wait for funding transaction on startup.
|
// wait for funding transaction on startup.
|
||||||
case shortChanID, ok := <-confChan:
|
return
|
||||||
|
case shortChanID, ok = <-confChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
fndgLog.Errorf("waiting for funding confirmation" +
|
fndgLog.Errorf("waiting for funding confirmation" +
|
||||||
" failed")
|
" failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Fallthrough.
|
||||||
|
}
|
||||||
|
|
||||||
f.deleteReservationCtx(peerKey, fmsg.msg.PendingChannelID)
|
// Success, funding transaction was confirmed.
|
||||||
|
f.deleteReservationCtx(peerKey, fmsg.msg.PendingChannelID)
|
||||||
|
|
||||||
// Success, funding transaction was confirmed.
|
err := f.handleFundingConfirmation(completeChan,
|
||||||
err := f.handleFundingConfirmation(completeChan,
|
shortChanID)
|
||||||
shortChanID)
|
if err != nil {
|
||||||
if err != nil {
|
fndgLog.Errorf("failed to handle funding"+
|
||||||
fndgLog.Errorf("failed to handle funding"+
|
"confirmation: %v", err)
|
||||||
"confirmation: %v", err)
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -1391,12 +1300,6 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||||||
pendingChanID, []byte(err.Error()))
|
pendingChanID, []byte(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
private, ok := f.pendingChanAnnPrefs[pendingChanID]
|
|
||||||
if !ok {
|
|
||||||
fndgLog.Warnf("can't find channel announcement preference for"+
|
|
||||||
"chanID:%x", pendingChanID[:])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an entry in the local discovery map so we can ensure that we
|
// Create an entry in the local discovery map so we can ensure that we
|
||||||
// process the channel confirmation fully before we receive a funding
|
// process the channel confirmation fully before we receive a funding
|
||||||
@ -1407,12 +1310,6 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||||||
f.localDiscoverySignals[permChanID] = make(chan struct{})
|
f.localDiscoverySignals[permChanID] = make(chan struct{})
|
||||||
f.localDiscoveryMtx.Unlock()
|
f.localDiscoveryMtx.Unlock()
|
||||||
|
|
||||||
// Store channel announcement preference in boltdb
|
|
||||||
if err = f.saveOpenChanAnnPref(fundingPoint, private); err != nil {
|
|
||||||
fndgLog.Errorf("unable to save channel announcement preference "+
|
|
||||||
"to db for chanID:%x", permChanID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The remote peer has responded with a signature for our commitment
|
// The remote peer has responded with a signature for our commitment
|
||||||
// transaction. We'll verify the signature for validity, then commit
|
// transaction. We'll verify the signature for validity, then commit
|
||||||
// the state to disk as we can now open the channel.
|
// the state to disk as we can now open the channel.
|
||||||
@ -1459,29 +1356,55 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||||||
confChan)
|
confChan)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
var shortChanID *lnwire.ShortChannelID
|
||||||
|
var ok bool
|
||||||
select {
|
select {
|
||||||
case <-f.quit:
|
case <-f.quit:
|
||||||
return
|
return
|
||||||
case shortChanID, ok := <-confChan:
|
case shortChanID, ok = <-confChan:
|
||||||
if !ok {
|
if !ok {
|
||||||
fndgLog.Errorf("waiting for funding confirmation" +
|
fndgLog.Errorf("waiting for funding confirmation" +
|
||||||
" failed")
|
" failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
f.deleteReservationCtx(peerKey, pendingChanID)
|
|
||||||
|
|
||||||
// Success, funding transaction was confirmed
|
|
||||||
err := f.handleFundingConfirmation(completeChan,
|
|
||||||
shortChanID)
|
|
||||||
if err != nil {
|
|
||||||
fndgLog.Errorf("failed to handle funding"+
|
|
||||||
"confirmation: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally give the caller a final update notifying them that
|
// Success, funding transaction was confirmed.
|
||||||
|
fndgLog.Debugf("Channel with ShortChanID %v now confirmed",
|
||||||
|
shortChanID.ToUint64())
|
||||||
|
|
||||||
|
// Go on adding the channel to the channel graph, and crafting
|
||||||
|
// channel announcements.
|
||||||
|
|
||||||
|
// We create the state-machine object which wraps the database state.
|
||||||
|
lnChannel, err := lnwallet.NewLightningChannel(nil, nil, f.cfg.FeeEstimator,
|
||||||
|
completeChan)
|
||||||
|
if err != nil {
|
||||||
|
fndgLog.Errorf("failed creating lnChannel: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
lnChannel.Stop()
|
||||||
|
lnChannel.CancelObserver()
|
||||||
|
}()
|
||||||
|
|
||||||
|
err = f.sendFundingLocked(completeChan, lnChannel, shortChanID)
|
||||||
|
if err != nil {
|
||||||
|
fndgLog.Errorf("failed sending fundingLocked: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fndgLog.Debugf("FundingLocked for channel with ShortChanID "+
|
||||||
|
"%v sent", shortChanID.ToUint64())
|
||||||
|
|
||||||
|
err = f.addToRouterGraph(completeChan, shortChanID)
|
||||||
|
if err != nil {
|
||||||
|
fndgLog.Errorf("failed adding to router graph: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fndgLog.Debugf("Channel with ShortChanID %v added to "+
|
||||||
|
"router graph", shortChanID.ToUint64())
|
||||||
|
|
||||||
|
// Give the caller a final update notifying them that
|
||||||
// the channel is now open.
|
// the channel is now open.
|
||||||
// TODO(roasbeef): only notify after recv of funding locked?
|
// TODO(roasbeef): only notify after recv of funding locked?
|
||||||
resCtx.updates <- &lnrpc.OpenStatusUpdate{
|
resCtx.updates <- &lnrpc.OpenStatusUpdate{
|
||||||
@ -1494,6 +1417,15 @@ func (f *fundingManager) handleFundingSigned(fmsg *fundingSignedMsg) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f.deleteReservationCtx(peerKey, pendingChanID)
|
||||||
|
|
||||||
|
err = f.annAfterSixConfs(completeChan, shortChanID)
|
||||||
|
if err != nil {
|
||||||
|
fndgLog.Errorf("failed sending channel announcement: %v",
|
||||||
|
err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1672,8 +1604,9 @@ func (f *fundingManager) waitForFundingConfirmation(completeChan *channeldb.Open
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// This closes the discoverySignal channel, indicating to a separate
|
// Close the discoverySignal channel, indicating to a separate
|
||||||
// goroutine that it is acceptable to process funding locked messages
|
// goroutine that the channel now is marked as open in the database
|
||||||
|
// and that it is acceptable to process funding locked messages
|
||||||
// from the peer.
|
// from the peer.
|
||||||
f.localDiscoveryMtx.Lock()
|
f.localDiscoveryMtx.Lock()
|
||||||
if discoverySignal, ok := f.localDiscoverySignals[chanID]; ok {
|
if discoverySignal, ok := f.localDiscoverySignals[chanID]; ok {
|
||||||
@ -1689,13 +1622,6 @@ func (f *fundingManager) waitForFundingConfirmation(completeChan *channeldb.Open
|
|||||||
func (f *fundingManager) handleFundingConfirmation(completeChan *channeldb.OpenChannel,
|
func (f *fundingManager) handleFundingConfirmation(completeChan *channeldb.OpenChannel,
|
||||||
shortChanID *lnwire.ShortChannelID) error {
|
shortChanID *lnwire.ShortChannelID) error {
|
||||||
|
|
||||||
// Retrieve channel announcement preference
|
|
||||||
private, err := f.getOpenChanAnnPref(&completeChan.FundingOutpoint)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("unable to retrieve channel announcement "+
|
|
||||||
"preference: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// We create the state-machine object which wraps the database state.
|
// We create the state-machine object which wraps the database state.
|
||||||
lnChannel, err := lnwallet.NewLightningChannel(nil, nil, f.cfg.FeeEstimator,
|
lnChannel, err := lnwallet.NewLightningChannel(nil, nil, f.cfg.FeeEstimator,
|
||||||
completeChan)
|
completeChan)
|
||||||
@ -1715,23 +1641,14 @@ func (f *fundingManager) handleFundingConfirmation(completeChan *channeldb.OpenC
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed sending fundingLocked: %v", err)
|
return fmt.Errorf("failed sending fundingLocked: %v", err)
|
||||||
}
|
}
|
||||||
err = f.addToRouterGraph(completeChan, lnChannel, shortChanID, private)
|
err = f.addToRouterGraph(completeChan, shortChanID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed adding to router graph: %v", err)
|
return fmt.Errorf("failed adding to router graph: %v", err)
|
||||||
}
|
}
|
||||||
|
err = f.annAfterSixConfs(completeChan, shortChanID)
|
||||||
if private {
|
if err != nil {
|
||||||
// We delete the channel from our internal database.
|
return fmt.Errorf("failed sending channel announcement: %v",
|
||||||
err := f.deleteChannelOpeningState(&completeChan.FundingOutpoint)
|
err)
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error deleting channel state: %v", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
err = f.annAfterSixConfs(completeChan, lnChannel, shortChanID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed sending channel announcement: %v",
|
|
||||||
err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -1813,19 +1730,26 @@ func (f *fundingManager) sendFundingLocked(completeChan *channeldb.OpenChannel,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// addToRouterGraph sends a private ChannelAnnouncement and a private
|
// addToRouterGraph sends a ChannelAnnouncement and a ChannelUpdate to the
|
||||||
// ChannelUpdate to the gossiper so that it is added to the Router's internal
|
// gossiper so that the channel is added to the Router's internal graph.
|
||||||
// graph before the announcement_signatures is sent in
|
// These announcement messages are NOT broadcasted to the greater network,
|
||||||
// annAfterSixConfs. These private announcement messages are NOT
|
// only to the channel counter party. The proofs required to announce the
|
||||||
// broadcasted to the greater network.
|
// channel to the greater network will be created and sent in annAfterSixConfs.
|
||||||
func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
|
func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
|
||||||
shortChanID *lnwire.ShortChannelID, private bool) error {
|
shortChanID *lnwire.ShortChannelID) error {
|
||||||
|
|
||||||
chanID := lnwire.NewChanIDFromOutPoint(&completeChan.FundingOutpoint)
|
chanID := lnwire.NewChanIDFromOutPoint(&completeChan.FundingOutpoint)
|
||||||
|
|
||||||
|
// We'll obtain their min HTLC as we'll use this value within our
|
||||||
|
// ChannelUpdate. We use this value isn't of ours, as the remote party
|
||||||
|
// will be the one that's carrying the HTLC towards us.
|
||||||
|
remoteMinHTLC := completeChan.RemoteChanCfg.MinHTLC
|
||||||
|
|
||||||
ann, err := f.newChanAnnouncement(f.cfg.IDKey, completeChan.IdentityPub,
|
ann, err := f.newChanAnnouncement(f.cfg.IDKey, completeChan.IdentityPub,
|
||||||
completeChan.LocalChanCfg.MultiSigKey,
|
completeChan.LocalChanCfg.MultiSigKey,
|
||||||
completeChan.RemoteChanCfg.MultiSigKey, *shortChanID, chanID)
|
completeChan.RemoteChanCfg.MultiSigKey, *shortChanID, chanID,
|
||||||
|
remoteMinHTLC,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error generating channel "+
|
return fmt.Errorf("error generating channel "+
|
||||||
"announcement: %v", err)
|
"announcement: %v", err)
|
||||||
@ -1833,21 +1757,30 @@ func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
|
|||||||
|
|
||||||
// Send ChannelAnnouncement and ChannelUpdate to the gossiper to add
|
// Send ChannelAnnouncement and ChannelUpdate to the gossiper to add
|
||||||
// to the Router's topology.
|
// to the Router's topology.
|
||||||
if err = f.cfg.SendLocalAnnouncement(ann.chanAnn); err != nil {
|
if err = f.cfg.SendAnnouncement(ann.chanAnn); err != nil {
|
||||||
return fmt.Errorf("error sending private channel "+
|
if routing.IsError(err, routing.ErrOutdated, routing.ErrIgnored) {
|
||||||
"announcement: %v", err)
|
fndgLog.Debugf("Router rejected ChannelAnnouncement: %v",
|
||||||
|
err)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("error sending channel "+
|
||||||
|
"announcement: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err = f.cfg.SendLocalAnnouncement(ann.chanUpdateAnn); err != nil {
|
if err = f.cfg.SendAnnouncement(ann.chanUpdateAnn); err != nil {
|
||||||
return fmt.Errorf("error sending private channel "+
|
if routing.IsError(err, routing.ErrOutdated, routing.ErrIgnored) {
|
||||||
"update: %v", err)
|
fndgLog.Debugf("Router rejected ChannelUpdate: %v", err)
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("error sending channel "+
|
||||||
|
"update: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// As the channel is now added to the ChannelRouter's topology, the
|
// As the channel is now added to the ChannelRouter's topology, the
|
||||||
// channel is moved to the next state of the state machine. It will be
|
// channel is moved to the next state of the state machine. It will be
|
||||||
// moved to the last state (actually deleted from the database) after
|
// moved to the last state (actually deleted from the database) after
|
||||||
// the channel is finally announced.
|
// the channel is finally announced.
|
||||||
err = f.saveChannelOpeningState(&completeChan.FundingOutpoint, addedToRouterGraph,
|
err = f.saveChannelOpeningState(&completeChan.FundingOutpoint,
|
||||||
shortChanID)
|
addedToRouterGraph, shortChanID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error setting channel state to"+
|
return fmt.Errorf("error setting channel state to"+
|
||||||
" addedToRouterGraph: %v", err)
|
" addedToRouterGraph: %v", err)
|
||||||
@ -1859,61 +1792,86 @@ func (f *fundingManager) addToRouterGraph(completeChan *channeldb.OpenChannel,
|
|||||||
// annAfterSixConfs broadcasts the necessary channel announcement messages to
|
// annAfterSixConfs broadcasts the necessary channel announcement messages to
|
||||||
// the network after 6 confs. Should be called after the fundingLocked message
|
// the network after 6 confs. Should be called after the fundingLocked message
|
||||||
// is sent and the channel is added to the router graph (channelState is
|
// is sent and the channel is added to the router graph (channelState is
|
||||||
// 'addedToRouterGraph') and the channel is ready to be used.
|
// 'addedToRouterGraph') and the channel is ready to be used. This is the last
|
||||||
|
// step in the channel opening process, and the opening state will be deleted
|
||||||
|
// from the database if successful.
|
||||||
func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
|
func (f *fundingManager) annAfterSixConfs(completeChan *channeldb.OpenChannel,
|
||||||
shortChanID *lnwire.ShortChannelID) error {
|
shortChanID *lnwire.ShortChannelID) error {
|
||||||
|
|
||||||
// Register with the ChainNotifier for a notification once the
|
// If this channel is meant to be announced to the greater network,
|
||||||
// funding transaction reaches 6 confirmations.
|
// wait until the funding tx has reached 6 confirmations before
|
||||||
txid := completeChan.FundingOutpoint.Hash
|
// announcing it.
|
||||||
confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(&txid, 6,
|
announceChan := completeChan.ChannelFlags&lnwire.FFAnnounceChannel != 0
|
||||||
completeChan.FundingBroadcastHeight)
|
if !announceChan {
|
||||||
if err != nil {
|
fndgLog.Debugf("Will not announce private channel %v.",
|
||||||
return fmt.Errorf("Unable to register for confirmation of "+
|
shortChanID.ToUint64())
|
||||||
"ChannelPoint(%v): %v", completeChan.FundingOutpoint, err)
|
} else {
|
||||||
}
|
// Register with the ChainNotifier for a notification once the
|
||||||
|
// funding transaction reaches at least 6 confirmations.
|
||||||
// Wait until 6 confirmations has been reached or the wallet signals
|
numConfs := uint32(completeChan.NumConfsRequired)
|
||||||
// a shutdown.
|
if numConfs < 6 {
|
||||||
select {
|
numConfs = 6
|
||||||
case _, ok := <-confNtfn.Confirmed:
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("ChainNotifier shutting down, cannot "+
|
|
||||||
"complete funding flow for ChannelPoint(%v)",
|
|
||||||
completeChan.FundingOutpoint)
|
|
||||||
}
|
}
|
||||||
case <-f.quit:
|
txid := completeChan.FundingOutpoint.Hash
|
||||||
return fmt.Errorf("fundingManager shutting down, stopping funding "+
|
fndgLog.Debugf("Will announce channel %v after ChannelPoint"+
|
||||||
"flow for ChannelPoint(%v)", completeChan.FundingOutpoint)
|
"(%v) has gotten %d confirmations",
|
||||||
|
shortChanID.ToUint64(), completeChan.FundingOutpoint,
|
||||||
|
numConfs)
|
||||||
|
|
||||||
|
confNtfn, err := f.cfg.Notifier.RegisterConfirmationsNtfn(&txid,
|
||||||
|
numConfs, completeChan.FundingBroadcastHeight)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("Unable to register for confirmation of "+
|
||||||
|
"ChannelPoint(%v): %v", completeChan.FundingOutpoint, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until 6 confirmations has been reached or the wallet signals
|
||||||
|
// a shutdown.
|
||||||
|
select {
|
||||||
|
case _, ok := <-confNtfn.Confirmed:
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("ChainNotifier shutting down, cannot "+
|
||||||
|
"complete funding flow for ChannelPoint(%v)",
|
||||||
|
completeChan.FundingOutpoint)
|
||||||
|
}
|
||||||
|
// Fallthrough.
|
||||||
|
|
||||||
|
case <-f.quit:
|
||||||
|
return fmt.Errorf("fundingManager shutting down, stopping funding "+
|
||||||
|
"flow for ChannelPoint(%v)", completeChan.FundingOutpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
fundingPoint := completeChan.FundingOutpoint
|
||||||
|
chanID := lnwire.NewChanIDFromOutPoint(&fundingPoint)
|
||||||
|
|
||||||
|
fndgLog.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
|
||||||
|
&fundingPoint, spew.Sdump(shortChanID))
|
||||||
|
|
||||||
|
// We'll obtain their min HTLC as we'll use this value within our
|
||||||
|
// ChannelUpdate. We use this value isn't of ours, as the remote party
|
||||||
|
// will be the one that's carrying the HTLC towards us.
|
||||||
|
remoteMinHTLC := completeChan.RemoteChanCfg.MinHTLC
|
||||||
|
|
||||||
|
// Create and broadcast the proofs required to make this channel
|
||||||
|
// public and usable for other nodes for routing.
|
||||||
|
err = f.announceChannel(f.cfg.IDKey, completeChan.IdentityPub,
|
||||||
|
completeChan.LocalChanCfg.MultiSigKey,
|
||||||
|
completeChan.RemoteChanCfg.MultiSigKey, *shortChanID, chanID,
|
||||||
|
remoteMinHTLC,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("channel announcement failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fndgLog.Debugf("Channel with ChannelPoint(%v), short_chan_id=%v "+
|
||||||
|
"announced", &fundingPoint, spew.Sdump(shortChanID))
|
||||||
}
|
}
|
||||||
|
|
||||||
fundingPoint := completeChan.FundingOutpoint
|
// We delete the channel opening state from our internal database
|
||||||
chanID := lnwire.NewChanIDFromOutPoint(&fundingPoint)
|
// as the opening process has succeeded. We can do this because we
|
||||||
|
// assume the AuthenticatedGossiper queues the announcement messages,
|
||||||
fndgLog.Infof("Announcing ChannelPoint(%v), short_chan_id=%v",
|
// and persists them in case of a daemon shutdown.
|
||||||
&fundingPoint, spew.Sdump(shortChanID))
|
err := f.deleteChannelOpeningState(&completeChan.FundingOutpoint)
|
||||||
|
|
||||||
// We'll obtain their min HTLC as we'll use this value within our
|
|
||||||
// ChannelUpdate. We use this value isn't of ours, as the remote party
|
|
||||||
// will be the one that's carrying the HTLC towards us.
|
|
||||||
remoteMinHTLC := completeChan.RemoteChanCfg.MinHTLC
|
|
||||||
|
|
||||||
// Register the new link with the L3 routing manager so this new
|
|
||||||
// channel can be utilized during path finding.
|
|
||||||
err := f.announceChannel(f.cfg.IDKey, completeChan.IdentityPub,
|
|
||||||
completeChan.LocalChanCfg.MultiSigKey,
|
|
||||||
completeChan.RemoteChanCfg.MultiSigKey, *shortChanID, chanID,
|
|
||||||
remoteMinHTLC,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("channel announcement failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// After the channel is successfully announced from the fundingManager,
|
|
||||||
// we delete the channel from our internal database. We can do this
|
|
||||||
// because we assume the AuthenticatedGossiper queues the announcement
|
|
||||||
// messages, and persists them in case of a daemon shutdown.
|
|
||||||
err = f.deleteChannelOpeningState(&fundingPoint)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error deleting channel state: %v", err)
|
return fmt.Errorf("error deleting channel state: %v", err)
|
||||||
}
|
}
|
||||||
@ -2240,8 +2198,13 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
|
|||||||
// the ChannelUpdate announcement messages. The channel proof and node
|
// the ChannelUpdate announcement messages. The channel proof and node
|
||||||
// announcements are broadcast to the greater network.
|
// announcements are broadcast to the greater network.
|
||||||
if err = f.cfg.SendAnnouncement(ann.chanProof); err != nil {
|
if err = f.cfg.SendAnnouncement(ann.chanProof); err != nil {
|
||||||
fndgLog.Errorf("Unable to send channel proof: %v", err)
|
if routing.IsError(err, routing.ErrOutdated, routing.ErrIgnored) {
|
||||||
return err
|
fndgLog.Debugf("Router rejected AnnounceSignatures: %v",
|
||||||
|
err)
|
||||||
|
} else {
|
||||||
|
fndgLog.Errorf("Unable to send channel proof: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that the channel is announced to the network, we will also
|
// Now that the channel is announced to the network, we will also
|
||||||
@ -2254,9 +2217,14 @@ func (f *fundingManager) announceChannel(localIDKey, remoteIDKey, localFundingKe
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = f.cfg.SendAnnouncement(&nodeAnn); err != nil {
|
if err := f.cfg.SendAnnouncement(&nodeAnn); err != nil {
|
||||||
fndgLog.Errorf("Unable to send node announcement: %v", err)
|
if routing.IsError(err, routing.ErrOutdated, routing.ErrIgnored) {
|
||||||
return err
|
fndgLog.Debugf("Router rejected NodeAnnouncement: %v",
|
||||||
|
err)
|
||||||
|
} else {
|
||||||
|
fndgLog.Errorf("Unable to send node announcement: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -2305,12 +2273,20 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
|
|||||||
// multiply the computed sat/weight by 1000 to arrive at fee-per-kw.
|
// multiply the computed sat/weight by 1000 to arrive at fee-per-kw.
|
||||||
commitFeePerKw := feePerWeight * 1000
|
commitFeePerKw := feePerWeight * 1000
|
||||||
|
|
||||||
|
// We set the channel flags to indicate whether we want this channel
|
||||||
|
// to be announced to the network.
|
||||||
|
var channelFlags lnwire.FundingFlag
|
||||||
|
if !msg.openChanReq.private {
|
||||||
|
// This channel will be announced.
|
||||||
|
channelFlags = lnwire.FFAnnounceChannel
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize a funding reservation with the local wallet. If the
|
// Initialize a funding reservation with the local wallet. If the
|
||||||
// wallet doesn't have enough funds to commit to this channel, then the
|
// wallet doesn't have enough funds to commit to this channel, then the
|
||||||
// request will fail, and be aborted.
|
// request will fail, and be aborted.
|
||||||
reservation, err := f.cfg.Wallet.InitChannelReservation(capacity,
|
reservation, err := f.cfg.Wallet.InitChannelReservation(capacity,
|
||||||
localAmt, msg.pushAmt, commitFeePerKw, msg.fundingFeePerWeight,
|
localAmt, msg.pushAmt, commitFeePerKw, msg.fundingFeePerWeight,
|
||||||
peerKey, msg.peerAddress.Address, &msg.chainHash)
|
peerKey, msg.peerAddress.Address, &msg.chainHash, channelFlags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg.err <- err
|
msg.err <- err
|
||||||
return
|
return
|
||||||
@ -2358,18 +2334,6 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
|
|||||||
fndgLog.Infof("Starting funding workflow with %v for pendingID(%x)",
|
fndgLog.Infof("Starting funding workflow with %v for pendingID(%x)",
|
||||||
msg.peerAddress.Address, chanID)
|
msg.peerAddress.Address, chanID)
|
||||||
|
|
||||||
// Save the announcement preference of this pending channel
|
|
||||||
var channelFlags byte
|
|
||||||
if msg.openChanReq.private {
|
|
||||||
// This channel will be private
|
|
||||||
channelFlags = 1
|
|
||||||
f.pendingChanAnnPrefs[chanID] = true
|
|
||||||
} else {
|
|
||||||
// This channel will be publicly announced to the greater network.
|
|
||||||
channelFlags = 0
|
|
||||||
f.pendingChanAnnPrefs[chanID] = false
|
|
||||||
}
|
|
||||||
|
|
||||||
fundingOpen := lnwire.OpenChannel{
|
fundingOpen := lnwire.OpenChannel{
|
||||||
ChainHash: *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
|
ChainHash: *f.cfg.Wallet.Cfg.NetParams.GenesisHash,
|
||||||
PendingChannelID: chanID,
|
PendingChannelID: chanID,
|
||||||
@ -2388,7 +2352,7 @@ func (f *fundingManager) handleInitFundingMsg(msg *initFundingMsg) {
|
|||||||
HtlcPoint: ourContribution.HtlcBasePoint,
|
HtlcPoint: ourContribution.HtlcBasePoint,
|
||||||
DelayedPaymentPoint: ourContribution.DelayBasePoint,
|
DelayedPaymentPoint: ourContribution.DelayBasePoint,
|
||||||
FirstCommitmentPoint: ourContribution.FirstCommitmentPoint,
|
FirstCommitmentPoint: ourContribution.FirstCommitmentPoint,
|
||||||
ChannelFlags: lnwire.FFAnnounceChannel,
|
ChannelFlags: channelFlags,
|
||||||
}
|
}
|
||||||
if err := f.cfg.SendToPeer(peerKey, &fundingOpen); err != nil {
|
if err := f.cfg.SendToPeer(peerKey, &fundingOpen); err != nil {
|
||||||
fndgLog.Errorf("Unable to send funding request message: %v", err)
|
fndgLog.Errorf("Unable to send funding request message: %v", err)
|
||||||
@ -2470,7 +2434,6 @@ func (f *fundingManager) handleErrorMsg(fmsg *fundingErrorMsg) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(f.pendingChanAnnPrefs, chanID)
|
|
||||||
if _, err := f.cancelReservationCtx(peerKey, chanID); err != nil {
|
if _, err := f.cancelReservationCtx(peerKey, chanID); err != nil {
|
||||||
fndgLog.Warnf("unable to delete reservation: %v", err)
|
fndgLog.Warnf("unable to delete reservation: %v", err)
|
||||||
return
|
return
|
||||||
@ -2539,86 +2502,6 @@ func copyPubKey(pub *btcec.PublicKey) *btcec.PublicKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// saveOpenChanAnnPref saves an open channel's announcement preference.
|
|
||||||
func (f *fundingManager) saveOpenChanAnnPref(chanPoint *wire.OutPoint,
|
|
||||||
pref bool) error {
|
|
||||||
return f.cfg.Wallet.Cfg.Database.Update(func(tx *bolt.Tx) error {
|
|
||||||
|
|
||||||
bucket, err := tx.CreateBucketIfNotExists(openChanAnnPrefBucket)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var outpointBytes bytes.Buffer
|
|
||||||
if err = writeOutpoint(&outpointBytes, chanPoint); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
scratch := make([]byte, 0)
|
|
||||||
var b byte
|
|
||||||
if pref {
|
|
||||||
b = 1
|
|
||||||
} else {
|
|
||||||
b = 0
|
|
||||||
}
|
|
||||||
scratch = append(scratch[:], b)
|
|
||||||
|
|
||||||
return bucket.Put(outpointBytes.Bytes(), scratch[:])
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// getOpenChanAnnPref retrives an open channel's announcement preference.
|
|
||||||
func (f *fundingManager) getOpenChanAnnPref(chanPoint *wire.OutPoint) (bool, error) {
|
|
||||||
|
|
||||||
var pref bool
|
|
||||||
err := f.cfg.Wallet.Cfg.Database.View(func(tx *bolt.Tx) error {
|
|
||||||
|
|
||||||
bucket := tx.Bucket(openChanAnnPrefBucket)
|
|
||||||
if bucket == nil {
|
|
||||||
return fmt.Errorf("Channel announcement preference " +
|
|
||||||
"not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
var outpointBytes bytes.Buffer
|
|
||||||
if err := writeOutpoint(&outpointBytes, chanPoint); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
value := bucket.Get(outpointBytes.Bytes())
|
|
||||||
if value == nil {
|
|
||||||
return fmt.Errorf("Channel announcement preference " +
|
|
||||||
"not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
if value[0] == 1 {
|
|
||||||
pref = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return pref, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// deleteOpenChanAnnPref deletes an open channel's announcement preference.
|
|
||||||
func (f *fundingManager) deleteOpenChanAnnPref(chanPoint *wire.OutPoint) error {
|
|
||||||
return f.cfg.Wallet.Cfg.Database.Update(func(tx *bolt.Tx) error {
|
|
||||||
bucket := tx.Bucket(openChanAnnPrefBucket)
|
|
||||||
if bucket == nil {
|
|
||||||
return fmt.Errorf("Bucket not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
var outpointBytes bytes.Buffer
|
|
||||||
if err := writeOutpoint(&outpointBytes, chanPoint); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bucket.Delete(outpointBytes.Bytes())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// saveChannelOpeningState saves the channelOpeningState for the provided
|
// saveChannelOpeningState saves the channelOpeningState for the provided
|
||||||
// chanPoint to the channelOpeningStateBucket.
|
// chanPoint to the channelOpeningStateBucket.
|
||||||
func (f *fundingManager) saveChannelOpeningState(chanPoint *wire.OutPoint,
|
func (f *fundingManager) saveChannelOpeningState(chanPoint *wire.OutPoint,
|
||||||
|
Loading…
Reference in New Issue
Block a user