Skip to content

Commit

Permalink
sweep: use chain notifier instead of chain IO for best block
Browse files Browse the repository at this point in the history
Because the BestBlock method of ChainIO is not exposed through any
RPC we want to get rid of it so we can use the sweeper outside of
lnd too. Since the chain notifier now also delivers the current best
block we don't need the BestBlock method any more.
  • Loading branch information
guggero committed Oct 14, 2019
1 parent b6dda14 commit 8e4a897
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 58 deletions.
1 change: 0 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,6 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
return time.NewTimer(sweep.DefaultBatchWindowDuration).C
},
Notifier: cc.chainNotifier,
ChainIO: cc.chainIO,
Store: sweeperStore,
MaxInputsPerTx: sweep.DefaultMaxInputsPerTx,
MaxSweepAttempts: sweep.DefaultMaxSweepAttempts,
Expand Down
44 changes: 19 additions & 25 deletions sweep/sweeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,6 @@ type UtxoSweeperConfig struct {
// certain on-chain events.
Notifier chainntnfs.ChainNotifier

// ChainIO is used to determine the current block height.
ChainIO lnwallet.BlockChainIO

// Store stores the published sweeper txes.
Store SweeperStore

Expand Down Expand Up @@ -323,20 +320,10 @@ func (s *UtxoSweeper) Start() error {
// not change from here on.
s.relayFeeRate = s.cfg.FeeEstimator.RelayFeePerKW()

// Register for block epochs to retry sweeping every block.
bestHash, bestHeight, err := s.cfg.ChainIO.GetBestBlock()
if err != nil {
return fmt.Errorf("get best block: %v", err)
}

log.Debugf("Best height: %v", bestHeight)

blockEpochs, err := s.cfg.Notifier.RegisterBlockEpochNtfn(
&chainntnfs.BlockEpoch{
Height: bestHeight,
Hash: bestHash,
},
)
// We need to register for block epochs and retry sweeping every block.
// We should get a notification with the current best block immediately
// if we don't provide any epoch. We'll wait for that in the collector.
blockEpochs, err := s.cfg.Notifier.RegisterBlockEpochNtfn(nil)
if err != nil {
return fmt.Errorf("register block epoch ntfn: %v", err)
}
Expand All @@ -347,10 +334,7 @@ func (s *UtxoSweeper) Start() error {
defer blockEpochs.Cancel()
defer s.wg.Done()

err := s.collector(blockEpochs.Epochs, bestHeight)
if err != nil {
log.Errorf("sweeper stopped: %v", err)
}
s.collector(blockEpochs.Epochs)
}()

return nil
Expand Down Expand Up @@ -445,8 +429,18 @@ func (s *UtxoSweeper) feeRateForPreference(

// collector is the sweeper main loop. It processes new inputs, spend
// notifications and counts down to publication of the sweep tx.
func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch,
bestHeight int32) error {
func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch) {
// We registered for the block epochs with a nil request. The notifier
// should send us the current best block immediately. So we need to wait
// for it here because we need to know the current best height.
var bestHeight int32
select {
case bestBlock := <-blockEpochs:
bestHeight = bestBlock.Height

case <-s.quit:
return
}

for {
select {
Expand Down Expand Up @@ -622,7 +616,7 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch,
// sweep.
case epoch, ok := <-blockEpochs:
if !ok {
return nil
return
}

bestHeight = epoch.Height
Expand All @@ -635,7 +629,7 @@ func (s *UtxoSweeper) collector(blockEpochs <-chan *chainntnfs.BlockEpoch,
}

case <-s.quit:
return nil
return
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions sweep/sweeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,8 @@ func createSweeperTestContext(t *testing.T) *sweeperTestContext {
ctx.timeoutChan <- c
return c
},
Store: store,
Signer: &mockSigner{},
ChainIO: &mockChainIO{},
Store: store,
Signer: &mockSigner{},
GenSweepScript: func() ([]byte, error) {
script := []byte{outputScriptCount}
outputScriptCount++
Expand Down
46 changes: 17 additions & 29 deletions sweep/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwallet"
)

var (
defaultTestTimeout = 5 * time.Second
mockChainIOHeight = int32(100)
mockChainHash, _ = chainhash.NewHashFromStr("00aabbccddeeff")
mockChainHeight = int32(100)
)

type mockSigner struct {
Expand Down Expand Up @@ -155,12 +155,22 @@ func (m *MockNotifier) RegisterBlockEpochNtfn(
log.Tracef("Mock block ntfn registered")

m.mutex.Lock()
epochChan := make(chan *chainntnfs.BlockEpoch, 0)
bestHeight := int32(0)
if bestBlock != nil {
bestHeight = bestBlock.Height
epochChan := make(chan *chainntnfs.BlockEpoch, 1)

// The real notifier returns a notification with the current block hash
// and height immediately if no best block hash or height is specified
// in the request. We want to emulate this behaviour as well for the
// mock.
switch {
case bestBlock == nil:
epochChan <- &chainntnfs.BlockEpoch{
Hash: mockChainHash,
Height: mockChainHeight,
}
m.epochChan[epochChan] = mockChainHeight
default:
m.epochChan[epochChan] = bestBlock.Height
}
m.epochChan[epochChan] = bestHeight
m.mutex.Unlock()

return &chainntnfs.BlockEpochEvent{
Expand Down Expand Up @@ -235,25 +245,3 @@ func (m *MockNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
},
}, nil
}

type mockChainIO struct{}

var _ lnwallet.BlockChainIO = (*mockChainIO)(nil)

func (m *mockChainIO) GetBestBlock() (*chainhash.Hash, int32, error) {
return nil, mockChainIOHeight, nil
}

func (m *mockChainIO) GetUtxo(op *wire.OutPoint, pkScript []byte,
heightHint uint32, _ <-chan struct{}) (*wire.TxOut, error) {

return nil, nil
}

func (m *mockChainIO) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
return nil, nil
}

func (m *mockChainIO) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) {
return nil, nil
}

0 comments on commit 8e4a897

Please sign in to comment.