Merge pull request #663 from cfromknecht/utxn-height-hint

Fix UtxoNursery Commit Sweep Height-Hint
This commit is contained in:
Olaoluwa Osuntokun 2018-01-27 15:57:03 -08:00 committed by GitHub
commit 28f782b156
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 65 additions and 3 deletions

@ -9,6 +9,7 @@ import (
"sync"
"github.com/boltdb/bolt"
"github.com/go-errors/errors"
"github.com/roasbeef/btcd/btcec"
"github.com/roasbeef/btcd/wire"
)
@ -434,6 +435,42 @@ func (d *DB) FetchClosedChannels(pendingOnly bool) ([]*ChannelCloseSummary, erro
return chanSummaries, nil
}
// ErrClosedChannelNotFound signals that a closed channel could not be found in
// the channeldb.
var ErrClosedChannelNotFound = errors.New("unable to find closed channel summary")
// FetchClosedChannel queries for a channel close summary using the channel
// point of the channel in question.
func (d *DB) FetchClosedChannel(chanID *wire.OutPoint) (*ChannelCloseSummary, error) {
var chanSummary *ChannelCloseSummary
if err := d.View(func(tx *bolt.Tx) error {
closeBucket := tx.Bucket(closedChannelBucket)
if closeBucket == nil {
return ErrClosedChannelNotFound
}
var b bytes.Buffer
var err error
if err = writeOutpoint(&b, chanID); err != nil {
return err
}
summaryBytes := closeBucket.Get(b.Bytes())
if summaryBytes == nil {
return ErrClosedChannelNotFound
}
summaryReader := bytes.NewReader(summaryBytes)
chanSummary, err = deserializeCloseChannelSummary(summaryReader)
return err
}); err != nil {
return nil, err
}
return chanSummary, nil
}
// MarkChanFullyClosed marks a channel as fully closed within the database. A
// channel should be marked as fully closed if the channel was initially
// cooperatively closed and it's reach a single confirmation, or after all the

@ -302,7 +302,7 @@ func (u *utxoNursery) Start() error {
// NOTE: The next two steps *may* spawn go routines, thus from this
// point forward, we must close the nursery's quit channel if we detect
// any failures during startup to ensure they terminate.
if err := u.reloadPreschool(lastGraduatedHeight); err != nil {
if err := u.reloadPreschool(); err != nil {
newBlockChan.Cancel()
close(u.quit)
return err
@ -608,14 +608,39 @@ func (u *utxoNursery) NurseryReport(
// reloadPreschool re-initializes the chain notifier with all of the outputs
// that had been saved to the "preschool" database bucket prior to shutdown.
func (u *utxoNursery) reloadPreschool(heightHint uint32) error {
func (u *utxoNursery) reloadPreschool() error {
psclOutputs, err := u.cfg.Store.FetchPreschools()
if err != nil {
return err
}
// For each of the preschool outputs stored in the nursery store, load
// it's close summary from disk so that we can get an accurate height
// hint from which to start our range for spend notifications.
for i := range psclOutputs {
err := u.registerPreschoolConf(&psclOutputs[i], heightHint)
kid := &psclOutputs[i]
chanPoint := kid.OriginChanPoint()
// Load the close summary for this output's channel point.
closeSummary, err := u.cfg.DB.FetchClosedChannel(chanPoint)
if err == channeldb.ErrClosedChannelNotFound {
// This should never happen since the close summary
// should only be removed after the channel has been
// swept completely.
utxnLog.Warnf("Close summary not found for "+
"chan_point=%v, can't determine height hint"+
"to sweep commit txn", chanPoint)
continue
} else if err != nil {
return err
}
// Use the close height from the channel summary as our height
// hint to drive our spend notifications, with our confirmation
// depth as a buffer for reorgs.
heightHint := closeSummary.CloseHeight - u.cfg.ConfDepth
err = u.registerPreschoolConf(kid, heightHint)
if err != nil {
return err
}