Skip to content

Commit ede08a8

Browse files
funding: persist ConfirmationHeight upon first funding confirmation
This change ensures that a channel's ConfirmationHeight is recorded in the database once its funding transaction receives its initial confirmation. By doing so, we establish a reliable reference point to monitor the channel's progress toward the required confirmation depth. Signed-off-by: Nishant Bansal <[email protected]>
1 parent 222f49c commit ede08a8

File tree

2 files changed

+325
-105
lines changed

2 files changed

+325
-105
lines changed

funding/manager.go

Lines changed: 128 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,7 +3064,8 @@ func makeFundingScript(channel *channeldb.OpenChannel) ([]byte, error) {
30643064
// process once the funding transaction has been broadcast. The primary
30653065
// function of waitForFundingConfirmation is to wait for blockchain
30663066
// confirmation, and then to notify the other systems that must be notified
3067-
// when a channel has become active for lightning transactions.
3067+
// when a channel has become active for lightning transactions. It also updates
3068+
// the channel’s opening transaction block height in the database.
30683069
// The wait can be canceled by closing the cancelChan. In case of success,
30693070
// a *lnwire.ShortChannelID will be passed to confChan.
30703071
//
@@ -3108,34 +3109,135 @@ func (f *Manager) waitForFundingConfirmation(
31083109
log.Infof("Waiting for funding tx (%v) to reach %v confirmations",
31093110
txid, numConfs)
31103111

3111-
var confDetails *chainntnfs.TxConfirmation
3112-
var ok bool
3113-
31143112
// Wait until the specified number of confirmations has been reached,
31153113
// we get a cancel signal, or the wallet signals a shutdown.
3116-
select {
3117-
case confDetails, ok = <-confNtfn.Confirmed:
3118-
// fallthrough
3114+
for {
3115+
select {
3116+
case updDetails, ok := <-confNtfn.Updates:
3117+
if !ok {
3118+
log.Warnf("ChainNotifier shutting down, "+
3119+
"cannot process updates for "+
3120+
"ChannelPoint(%v)",
3121+
completeChan.FundingOutpoint)
31193122

3120-
case <-cancelChan:
3121-
log.Warnf("canceled waiting for funding confirmation, "+
3122-
"stopping funding flow for ChannelPoint(%v)",
3123-
completeChan.FundingOutpoint)
3124-
return
3123+
return
3124+
}
31253125

3126-
case <-f.quit:
3127-
log.Warnf("fundingManager shutting down, stopping funding "+
3128-
"flow for ChannelPoint(%v)",
3129-
completeChan.FundingOutpoint)
3130-
return
3131-
}
3126+
log.Debugf("funding tx %s received confirmation in "+
3127+
"block %d, %d confirmations left", txid,
3128+
updDetails.BlockHeight, updDetails.NumConfsLeft)
31323129

3133-
if !ok {
3134-
log.Warnf("ChainNotifier shutting down, cannot complete "+
3135-
"funding flow for ChannelPoint(%v)",
3136-
completeChan.FundingOutpoint)
3137-
return
3130+
// Only update the ConfirmationHeight the first time a
3131+
// confirmation is received, since on subsequent
3132+
// confirmations the block height will remain the same.
3133+
if completeChan.ConfirmationHeight == 0 {
3134+
err := completeChan.MarkConfirmationHeight(
3135+
updDetails.BlockHeight,
3136+
)
3137+
if err != nil {
3138+
log.Errorf("failed to update "+
3139+
"confirmed state for "+
3140+
"ChannelPoint(%v): %v",
3141+
completeChan.FundingOutpoint,
3142+
err)
3143+
3144+
return
3145+
}
3146+
}
3147+
3148+
case _, ok := <-confNtfn.NegativeConf:
3149+
if !ok {
3150+
log.Warnf("ChainNotifier shutting down, "+
3151+
"cannot track negative confirmations "+
3152+
"for ChannelPoint(%v)",
3153+
completeChan.FundingOutpoint)
3154+
3155+
return
3156+
}
3157+
3158+
log.Warnf("funding tx %s was reorged out; channel "+
3159+
"point: %s", txid, completeChan.FundingOutpoint)
3160+
3161+
// Reset the confirmation height to 0 because the
3162+
// funding transaction was reorged out.
3163+
err := completeChan.MarkConfirmationHeight(uint32(0))
3164+
if err != nil {
3165+
log.Errorf("failed to update state for "+
3166+
"ChannelPoint(%v): %v",
3167+
completeChan.FundingOutpoint, err)
3168+
3169+
return
3170+
}
3171+
3172+
case confDetails, ok := <-confNtfn.Confirmed:
3173+
if !ok {
3174+
log.Warnf("ChainNotifier shutting down, "+
3175+
"cannot complete funding flow for "+
3176+
"ChannelPoint(%v)",
3177+
completeChan.FundingOutpoint)
3178+
3179+
return
3180+
}
3181+
3182+
log.Debugf("funding tx %s for ChannelPoint(%v) "+
3183+
"confirmed in block %d", txid,
3184+
completeChan.FundingOutpoint,
3185+
confDetails.BlockHeight)
3186+
3187+
// In the case of requiring a single confirmation, it
3188+
// can happen that the `Confirmed` channel is read
3189+
// from first, in which case the confirmation height
3190+
// will not be set. If this happens, we take the
3191+
// confirmation height from the `Confirmed` channel.
3192+
if completeChan.ConfirmationHeight == 0 {
3193+
err := completeChan.MarkConfirmationHeight(
3194+
confDetails.BlockHeight,
3195+
)
3196+
if err != nil {
3197+
log.Errorf("failed to update "+
3198+
"confirmed state for "+
3199+
"ChannelPoint(%v): %v",
3200+
completeChan.FundingOutpoint,
3201+
err)
3202+
3203+
return
3204+
}
3205+
}
3206+
3207+
err := f.handleConfirmation(
3208+
confDetails, completeChan, confChan,
3209+
)
3210+
if err != nil {
3211+
log.Errorf("Error handling confirmation for "+
3212+
"ChannelPoint(%v), txid=%v: %v",
3213+
completeChan.FundingOutpoint, txid, err)
3214+
}
3215+
3216+
return
3217+
3218+
case <-cancelChan:
3219+
log.Warnf("canceled waiting for funding confirmation, "+
3220+
"stopping funding flow for ChannelPoint(%v)",
3221+
completeChan.FundingOutpoint)
3222+
3223+
return
3224+
3225+
case <-f.quit:
3226+
log.Warnf("fundingManager shutting down, stopping "+
3227+
"funding flow for ChannelPoint(%v)",
3228+
completeChan.FundingOutpoint)
3229+
3230+
return
3231+
}
31383232
}
3233+
}
3234+
3235+
// handleConfirmation is a helper function that constructs a ShortChannelID
3236+
// based on the confirmation details and sends this information, along with the
3237+
// funding transaction, to the provided confirmation channel.
3238+
func (f *Manager) handleConfirmation(confDetails *chainntnfs.TxConfirmation,
3239+
completeChan *channeldb.OpenChannel,
3240+
confChan chan<- *confirmedChannel) error {
31393241

31403242
fundingPoint := completeChan.FundingOutpoint
31413243
log.Infof("ChannelPoint(%v) is now active: ChannelID(%v)",
@@ -3156,8 +3258,10 @@ func (f *Manager) waitForFundingConfirmation(
31563258
fundingTx: confDetails.Tx,
31573259
}:
31583260
case <-f.quit:
3159-
return
3261+
return fmt.Errorf("manager shutting down")
31603262
}
3263+
3264+
return nil
31613265
}
31623266

31633267
// waitForTimeout will close the timeout channel if MaxWaitNumBlocksFundingConf

0 commit comments

Comments
 (0)