Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cancel long-running Neutrino GetUTXO calls on quit #2716

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions chainntnfs/neutrinonotify/neutrino.go
Expand Up @@ -764,6 +764,7 @@ func (n *NeutrinoNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
neutrino.EndBlock(&waddrmgr.BlockStamp{
Height: int32(historicalDispatch.EndHeight),
}),
neutrino.QuitChan(n.quit),
)
if err != nil && !strings.Contains(err.Error(), "not found") {
return nil, err
Expand Down
4 changes: 3 additions & 1 deletion contractcourt/channel_arbitrator_test.go
Expand Up @@ -124,12 +124,14 @@ func (b *mockArbitratorLog) WipeHistory() error {

type mockChainIO struct{}

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

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

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

Expand Down
3 changes: 2 additions & 1 deletion lnwallet/btcwallet/blockchain.go
Expand Up @@ -38,7 +38,7 @@ func (b *BtcWallet) GetBestBlock() (*chainhash.Hash, int32, error) {
//
// This method is a part of the lnwallet.BlockChainIO interface.
func (b *BtcWallet) GetUtxo(op *wire.OutPoint, pkScript []byte,
heightHint uint32) (*wire.TxOut, error) {
heightHint uint32, cancel <-chan struct{}) (*wire.TxOut, error) {

switch backend := b.chain.(type) {

Expand All @@ -51,6 +51,7 @@ func (b *BtcWallet) GetUtxo(op *wire.OutPoint, pkScript []byte,
neutrino.StartBlock(&waddrmgr.BlockStamp{
Height: int32(heightHint),
}),
neutrino.QuitChan(cancel),
)
if err != nil {
return nil, err
Expand Down
3 changes: 2 additions & 1 deletion lnwallet/btcwallet/btcwallet.go
Expand Up @@ -67,8 +67,9 @@ type BtcWallet struct {
}

// A compile time check to ensure that BtcWallet implements the
// WalletController interface.
// WalletController and BlockChainIO interfaces.
var _ lnwallet.WalletController = (*BtcWallet)(nil)
var _ lnwallet.BlockChainIO = (*BtcWallet)(nil)

// New returns a new fully initialized instance of BtcWallet given a valid
// configuration struct.
Expand Down
6 changes: 4 additions & 2 deletions lnwallet/interface.go
Expand Up @@ -268,8 +268,10 @@ type BlockChainIO interface {
// script that the outpoint creates. In the case that the output is in
// the UTXO set, then the output corresponding to that output is
// returned. Otherwise, a non-nil error will be returned.
GetUtxo(op *wire.OutPoint, pkScript []byte,
heightHint uint32) (*wire.TxOut, error)
// As for some backends this call can initiate a rescan, the passed
// cancel channel can be closed to abort the call.
GetUtxo(op *wire.OutPoint, pkScript []byte, heightHint uint32,
cancel <-chan struct{}) (*wire.TxOut, error)

// GetBlockHash returns the hash of the block in the best blockchain
// at the given height.
Expand Down
7 changes: 6 additions & 1 deletion lnwallet/wallet.go
Expand Up @@ -971,10 +971,15 @@ func (l *LightningWallet) handleFundingCounterPartySigs(msg *addCounterPartySigs
txin.Witness[len(txin.Witness)-1],
)
if err != nil {
msg.err <- fmt.Errorf("cannot create script: "+
"%v", err)
msg.completeChan <- nil
return
}

output, err := l.Cfg.ChainIO.GetUtxo(
&txin.PreviousOutPoint,
pkScript, 0,
pkScript, 0, l.quit,
)
if output == nil {
msg.err <- fmt.Errorf("input to funding tx "+
Expand Down
4 changes: 3 additions & 1 deletion mock.go
Expand Up @@ -205,12 +205,14 @@ type mockChainIO struct {
bestHeight int32
}

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

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

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

Expand Down
3 changes: 2 additions & 1 deletion routing/notifications_test.go
Expand Up @@ -181,7 +181,8 @@ func (m *mockChain) addUtxo(op wire.OutPoint, out *wire.TxOut) {
m.utxos[op] = *out
m.Unlock()
}
func (m *mockChain) GetUtxo(op *wire.OutPoint, _ []byte, _ uint32) (*wire.TxOut, error) {
func (m *mockChain) GetUtxo(op *wire.OutPoint, _ []byte, _ uint32,
_ <-chan struct{}) (*wire.TxOut, error) {
m.RLock()
defer m.RUnlock()

Expand Down
1 change: 1 addition & 0 deletions routing/router.go
Expand Up @@ -1113,6 +1113,7 @@ func (r *ChannelRouter) processUpdate(msg interface{}) error {
// been closed so we'll ignore it.
chanUtxo, err := r.cfg.Chain.GetUtxo(
fundingPoint, fundingPkScript, channelID.BlockHeight,
r.quit,
)
if err != nil {
r.rejectMtx.Lock()
Expand Down
5 changes: 4 additions & 1 deletion sweep/test_utils.go
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/btcsuite/btcd/wire"
"github.com/lightningnetwork/lnd/chainntnfs"
"github.com/lightningnetwork/lnd/input"
"github.com/lightningnetwork/lnd/lnwallet"
)

var (
Expand Down Expand Up @@ -237,12 +238,14 @@ func (m *MockNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,

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) (*wire.TxOut, error) {
heightHint uint32, _ <-chan struct{}) (*wire.TxOut, error) {

return nil, nil
}
Expand Down