• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 12301186252

12 Dec 2024 05:01PM UTC coverage: 48.92% (-9.7%) from 58.642%
12301186252

push

github

web-flow
Merge pull request #9309 from yyforyongyu/fix-unit-test

chainntnfs: fix `TestHistoricalConfDetailsTxIndex`

99121 of 202617 relevant lines covered (48.92%)

1.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.6
/lnwallet/btcwallet/blockchain.go
1
package btcwallet
2

3
import (
4
        "encoding/hex"
5
        "errors"
6
        "fmt"
7

8
        "github.com/btcsuite/btcd/btcutil"
9
        "github.com/btcsuite/btcd/chaincfg/chainhash"
10
        "github.com/btcsuite/btcd/wire"
11
        "github.com/btcsuite/btcwallet/chain"
12
        "github.com/lightninglabs/neutrino"
13
        "github.com/lightninglabs/neutrino/headerfs"
14
        "github.com/lightningnetwork/lnd/lntypes"
15
        "github.com/lightningnetwork/lnd/lnwallet"
16
)
17

18
var (
19
        // ErrOutputSpent is returned by the GetUtxo method if the target output
20
        // for lookup has already been spent.
21
        ErrOutputSpent = errors.New("target output has been spent")
22

23
        // ErrOutputNotFound signals that the desired output could not be
24
        // located.
25
        ErrOutputNotFound = errors.New("target output was not found")
26
)
27

28
// GetBestBlock returns the current height and hash of the best known block
29
// within the main chain.
30
//
31
// This method is a part of the lnwallet.BlockChainIO interface.
32
func (b *BtcWallet) GetBestBlock() (*chainhash.Hash, int32, error) {
3✔
33
        return b.chain.GetBestBlock()
3✔
34
}
3✔
35

36
// GetUtxo returns the original output referenced by the passed outpoint that
37
// creates the target pkScript.
38
//
39
// This method is a part of the lnwallet.BlockChainIO interface.
40
func (b *BtcWallet) GetUtxo(op *wire.OutPoint, pkScript []byte,
41
        heightHint uint32, cancel <-chan struct{}) (*wire.TxOut, error) {
3✔
42

3✔
43
        switch backend := b.chain.(type) {
3✔
44

45
        case *chain.NeutrinoClient:
×
46
                spendReport, err := backend.CS.GetUtxo(
×
47
                        neutrino.WatchInputs(neutrino.InputWithScript{
×
48
                                OutPoint: *op,
×
49
                                PkScript: pkScript,
×
50
                        }),
×
51
                        neutrino.StartBlock(&headerfs.BlockStamp{
×
52
                                Height: int32(heightHint),
×
53
                        }),
×
54
                        neutrino.QuitChan(cancel),
×
55
                )
×
56
                if err != nil {
×
57
                        return nil, err
×
58
                }
×
59

60
                // If the spend report is nil, then the output was not found in
61
                // the rescan.
62
                if spendReport == nil {
×
63
                        return nil, ErrOutputNotFound
×
64
                }
×
65

66
                // If the spending transaction is populated in the spend report,
67
                // this signals that the output has already been spent.
68
                if spendReport.SpendingTx != nil {
×
69
                        return nil, ErrOutputSpent
×
70
                }
×
71

72
                // Otherwise, the output is assumed to be in the UTXO.
73
                return spendReport.Output, nil
×
74

75
        case *chain.RPCClient:
1✔
76
                txout, err := backend.GetTxOut(&op.Hash, op.Index, false)
1✔
77
                if err != nil {
1✔
78
                        return nil, err
×
79
                } else if txout == nil {
1✔
80
                        return nil, ErrOutputSpent
×
81
                }
×
82

83
                pkScript, err := hex.DecodeString(txout.ScriptPubKey.Hex)
1✔
84
                if err != nil {
1✔
85
                        return nil, err
×
86
                }
×
87

88
                // We'll ensure we properly convert the amount given in BTC to
89
                // satoshis.
90
                amt, err := btcutil.NewAmount(txout.Value)
1✔
91
                if err != nil {
1✔
92
                        return nil, err
×
93
                }
×
94

95
                return &wire.TxOut{
1✔
96
                        Value:    int64(amt),
1✔
97
                        PkScript: pkScript,
1✔
98
                }, nil
1✔
99

100
        case *chain.BitcoindClient:
2✔
101
                txout, err := backend.GetTxOut(&op.Hash, op.Index, false)
2✔
102
                if err != nil {
2✔
103
                        return nil, err
×
104
                } else if txout == nil {
2✔
105
                        return nil, ErrOutputSpent
×
106
                }
×
107

108
                pkScript, err := hex.DecodeString(txout.ScriptPubKey.Hex)
2✔
109
                if err != nil {
2✔
110
                        return nil, err
×
111
                }
×
112

113
                // Sadly, gettxout returns the output value in BTC instead of
114
                // satoshis.
115
                amt, err := btcutil.NewAmount(txout.Value)
2✔
116
                if err != nil {
2✔
117
                        return nil, err
×
118
                }
×
119

120
                return &wire.TxOut{
2✔
121
                        Value:    int64(amt),
2✔
122
                        PkScript: pkScript,
2✔
123
                }, nil
2✔
124

125
        default:
×
126
                return nil, fmt.Errorf("unknown backend")
×
127
        }
128
}
129

130
// GetBlock returns a raw block from the server given its hash. For the Neutrino
131
// implementation of the lnwallet.BlockChainIO interface, the Neutrino GetBlock
132
// method is called directly. For other implementations, the block cache is used
133
// to wrap the call to GetBlock.
134
//
135
// This method is a part of the lnwallet.BlockChainIO interface.
136
func (b *BtcWallet) GetBlock(blockHash *chainhash.Hash) (*wire.MsgBlock, error) {
3✔
137
        _, ok := b.chain.(*chain.NeutrinoClient)
3✔
138
        if !ok {
6✔
139
                return b.blockCache.GetBlock(blockHash, b.chain.GetBlock)
3✔
140
        }
3✔
141

142
        // For the neutrino implementation of lnwallet.BlockChainIO the neutrino
143
        // GetBlock function can be called directly since it uses the same block
144
        // cache. However, it does not lock the block cache mutex for the given
145
        // block hash and so that is done here.
146
        b.blockCache.HashMutex.Lock(lntypes.Hash(*blockHash))
×
147
        defer b.blockCache.HashMutex.Unlock(lntypes.Hash(*blockHash))
×
148

×
149
        return b.chain.GetBlock(blockHash)
×
150
}
151

152
// GetBlockHeader returns a block header for the block with the given hash.
153
//
154
// This method is a part of the lnwallet.BlockChainIO interface.
155
func (b *BtcWallet) GetBlockHeader(
156
        blockHash *chainhash.Hash) (*wire.BlockHeader, error) {
3✔
157

3✔
158
        return b.chain.GetBlockHeader(blockHash)
3✔
159
}
3✔
160

161
// GetBlockHash returns the hash of the block in the best blockchain at the
162
// given height.
163
//
164
// This method is a part of the lnwallet.BlockChainIO interface.
165
func (b *BtcWallet) GetBlockHash(blockHeight int64) (*chainhash.Hash, error) {
3✔
166
        return b.chain.GetBlockHash(blockHeight)
3✔
167
}
3✔
168

169
// A compile time check to ensure that BtcWallet implements the BlockChainIO
170
// interface.
171
var _ lnwallet.WalletController = (*BtcWallet)(nil)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc