lnwallet/btcwallet/blockchain: properly handle nil spend report

This commit adds an additional check in GetUtxo that
tests for the nil-ness of the spend report returned by
the neutrino backend. Previously, a nil error and
spend report could be returned if the rescan did not
find the output at or above the start height. This
was observed to have cause a nil pointer dereference
when the returning line attempted to access the output.
This case is now handled by returning a distinct error
signaling that the output was not found.
This commit is contained in:
Conner Fromknecht 2018-01-09 18:14:25 -08:00
parent beeb75cb5f
commit c17b695128
No known key found for this signature in database
GPG Key ID: 39DE78FBE6ACB0EF
1 changed files with 14 additions and 1 deletions

View File

@ -18,6 +18,10 @@ var (
// ErrOutputSpent is returned by the GetUtxo method if the target output // ErrOutputSpent is returned by the GetUtxo method if the target output
// for lookup has already been spent. // for lookup has already been spent.
ErrOutputSpent = errors.New("target output has been spent") ErrOutputSpent = errors.New("target output has been spent")
// ErrOutputNotFound signals that the desired output could not be
// located.
ErrOutputNotFound = errors.New("target output was not found")
) )
// GetBestBlock returns the current height and hash of the best known block // GetBestBlock returns the current height and hash of the best known block
@ -61,10 +65,19 @@ func (b *BtcWallet) GetUtxo(op *wire.OutPoint, heightHint uint32) (*wire.TxOut,
return nil, err return nil, err
} }
if spendReport != nil && spendReport.SpendingTx != nil { // If the spend report is nil, then the output was not found in
// the rescan.
if spendReport == nil {
return nil, ErrOutputNotFound
}
// If the spending transaction is populated in the spend report,
// this signals that the output has already been spent.
if spendReport.SpendingTx != nil {
return nil, ErrOutputSpent return nil, ErrOutputSpent
} }
// Otherwise, the output is assumed to be in the UTXO.
return spendReport.Output, nil return spendReport.Output, nil
case *chain.RPCClient: case *chain.RPCClient: