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

lightningnetwork / lnd / 13517582158

25 Feb 2025 09:11AM UTC coverage: 49.382% (-9.5%) from 58.835%
13517582158

Pull #9549

github

yyforyongyu
docs: update release notes re flake fix
Pull Request #9549: Fix unit test flake `TestHistoricalConfDetailsTxIndex`

0 of 76 new or added lines in 1 file covered. (0.0%)

27171 existing lines in 435 files now uncovered.

100986 of 204500 relevant lines covered (49.38%)

1.54 hits per line

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

3.38
/lntest/unittest/backend.go
1
package unittest
2

3
import (
4
        "fmt"
5
        "os/exec"
6
        "path/filepath"
7
        "strings"
8
        "testing"
9
        "time"
10

11
        "github.com/btcsuite/btcd/chaincfg"
12
        "github.com/btcsuite/btcd/integration/rpctest"
13
        "github.com/btcsuite/btcd/rpcclient"
14
        "github.com/btcsuite/btcwallet/chain"
15
        "github.com/btcsuite/btcwallet/walletdb"
16
        "github.com/lightninglabs/neutrino"
17
        "github.com/lightningnetwork/lnd/kvdb"
18
        "github.com/lightningnetwork/lnd/lntest/port"
19
        "github.com/lightningnetwork/lnd/lntest/wait"
20
        "github.com/stretchr/testify/require"
21
)
22

23
var (
24
        // TrickleInterval is the interval at which the miner should trickle
25
        // transactions to its peers. We'll set it small to ensure the miner
26
        // propagates transactions quickly in the tests.
27
        TrickleInterval = 10 * time.Millisecond
28
)
29

30
var (
31
        // NetParams are the default network parameters for the tests.
32
        NetParams = &chaincfg.RegressionNetParams
33
)
34

35
// NewMiner spawns testing harness backed by a btcd node that can serve as a
36
// miner.
37
func NewMiner(t *testing.T, netParams *chaincfg.Params, extraArgs []string,
UNCOV
38
        createChain bool, spendableOutputs uint32) *rpctest.Harness {
×
UNCOV
39

×
UNCOV
40
        t.Helper()
×
UNCOV
41

×
NEW
42
        args := []string{
×
NEW
43
                "--nobanning",
×
NEW
44
                "--debuglevel=debug",
×
NEW
45
                fmt.Sprintf("--trickleinterval=%v", TrickleInterval),
×
NEW
46

×
NEW
47
                // Don't disconnect if a reply takes too long.
×
NEW
48
                "--nostalldetect",
×
NEW
49
        }
×
NEW
50
        extraArgs = append(extraArgs, args...)
×
UNCOV
51

×
UNCOV
52
        node, err := rpctest.New(netParams, nil, extraArgs, "")
×
UNCOV
53
        require.NoError(t, err, "unable to create backend node")
×
UNCOV
54
        t.Cleanup(func() {
×
UNCOV
55
                require.NoError(t, node.TearDown())
×
UNCOV
56
        })
×
57

58
        // We want to overwrite some of the connection settings to make the
59
        // tests more robust. We might need to restart the backend while there
60
        // are already blocks present, which will take a bit longer than the
61
        // 1 second the default settings amount to. Doubling both values will
62
        // give us retries up to 4 seconds.
UNCOV
63
        node.MaxConnRetries = rpctest.DefaultMaxConnectionRetries * 2
×
UNCOV
64
        node.ConnectionRetryTimeout = rpctest.DefaultConnectionRetryTimeout * 2
×
UNCOV
65

×
UNCOV
66
        if err := node.SetUp(createChain, spendableOutputs); err != nil {
×
67
                t.Fatalf("unable to set up backend node: %v", err)
×
68
        }
×
69

70
        // Next mine enough blocks in order for segwit and the CSV package
71
        // soft-fork to activate.
UNCOV
72
        numBlocks := netParams.MinerConfirmationWindow*2 + 17
×
UNCOV
73
        _, err = node.Client.Generate(numBlocks)
×
UNCOV
74
        require.NoError(t, err, "failed to generate blocks")
×
UNCOV
75

×
UNCOV
76
        return node
×
77
}
78

79
// NewBitcoindBackend spawns a new bitcoind node that connects to a miner at the
80
// specified address. The txindex boolean can be set to determine whether the
81
// backend node should maintain a transaction index. The rpcpolling boolean
82
// can be set to determine whether bitcoind's RPC polling interface should be
83
// used for block and tx notifications or if its ZMQ interface should be used.
84
// A connection to the newly spawned bitcoind node is returned.
85
func NewBitcoindBackend(t *testing.T, netParams *chaincfg.Params,
UNCOV
86
        minerAddr string, txindex, rpcpolling bool) *chain.BitcoindConn {
×
UNCOV
87

×
UNCOV
88
        t.Helper()
×
UNCOV
89

×
UNCOV
90
        tempBitcoindDir := t.TempDir()
×
UNCOV
91

×
UNCOV
92
        rpcPort := port.NextAvailablePort()
×
UNCOV
93
        torBindPort := port.NextAvailablePort()
×
UNCOV
94
        zmqBlockPort := port.NextAvailablePort()
×
UNCOV
95
        zmqTxPort := port.NextAvailablePort()
×
UNCOV
96
        zmqBlockHost := fmt.Sprintf("tcp://127.0.0.1:%d", zmqBlockPort)
×
UNCOV
97
        zmqTxHost := fmt.Sprintf("tcp://127.0.0.1:%d", zmqTxPort)
×
UNCOV
98

×
NEW
99
        // TODO(yy): Make this configurable via `chain.BitcoindConfig` and
×
NEW
100
        // replace the default P2P port when set.
×
NEW
101
        p2pPort := port.NextAvailablePort()
×
NEW
102
        netParams.DefaultPort = fmt.Sprintf("%d", p2pPort)
×
NEW
103

×
UNCOV
104
        args := []string{
×
UNCOV
105
                "-datadir=" + tempBitcoindDir,
×
UNCOV
106
                "-regtest",
×
UNCOV
107
                "-rpcauth=weks:469e9bb14ab2360f8e226efed5ca6fd$507c670e800a95" +
×
UNCOV
108
                        "284294edb5773b05544b220110063096c221be9933c82d38e1",
×
UNCOV
109
                fmt.Sprintf("-rpcport=%d", rpcPort),
×
UNCOV
110
                fmt.Sprintf("-bind=127.0.0.1:%d=onion", torBindPort),
×
NEW
111
                fmt.Sprintf("-port=%d", p2pPort),
×
UNCOV
112
                "-disablewallet",
×
UNCOV
113
                "-zmqpubrawblock=" + zmqBlockHost,
×
UNCOV
114
                "-zmqpubrawtx=" + zmqTxHost,
×
NEW
115

×
NEW
116
                // whitelist localhost to speed up relay.
×
NEW
117
                "-whitelist=127.0.0.1",
×
NEW
118

×
NEW
119
                // Disable v2 transport as btcd doesn't support it yet.
×
NEW
120
                //
×
NEW
121
                // TODO(yy): Remove this line once v2 conn is supported in
×
NEW
122
                // `btcd`.
×
NEW
123
                "-v2transport=0",
×
UNCOV
124
        }
×
UNCOV
125
        if txindex {
×
UNCOV
126
                args = append(args, "-txindex")
×
UNCOV
127
        }
×
128

UNCOV
129
        bitcoind := exec.Command("bitcoind", args...)
×
NEW
130
        err := bitcoind.Start()
×
NEW
131
        require.NoError(t, err, "unable to start bitcoind")
×
NEW
132

×
UNCOV
133
        t.Cleanup(func() {
×
NEW
134
                // Kill `bitcoind` and assert there's no error.
×
NEW
135
                err = bitcoind.Process.Kill()
×
NEW
136
                require.NoError(t, err)
×
NEW
137

×
NEW
138
                err = bitcoind.Wait()
×
NEW
139
                if strings.Contains(err.Error(), "signal: killed") {
×
NEW
140
                        return
×
NEW
141
                }
×
142

NEW
143
                require.NoError(t, err)
×
144
        })
145

146
        // Wait for the bitcoind instance to start up.
UNCOV
147
        time.Sleep(time.Second)
×
UNCOV
148

×
UNCOV
149
        host := fmt.Sprintf("127.0.0.1:%d", rpcPort)
×
UNCOV
150
        cfg := &chain.BitcoindConfig{
×
UNCOV
151
                ChainParams: netParams,
×
UNCOV
152
                Host:        host,
×
UNCOV
153
                User:        "weks",
×
UNCOV
154
                Pass:        "weks",
×
UNCOV
155
                // Fields only required for pruned nodes, not needed for these
×
UNCOV
156
                // tests.
×
UNCOV
157
                Dialer:             nil,
×
UNCOV
158
                PrunedModeMaxPeers: 0,
×
UNCOV
159
        }
×
UNCOV
160

×
UNCOV
161
        if rpcpolling {
×
UNCOV
162
                cfg.PollingConfig = &chain.PollingConfig{
×
UNCOV
163
                        BlockPollingInterval: time.Millisecond * 20,
×
UNCOV
164
                        TxPollingInterval:    time.Millisecond * 20,
×
UNCOV
165
                }
×
UNCOV
166
        } else {
×
UNCOV
167
                cfg.ZMQConfig = &chain.ZMQConfig{
×
UNCOV
168
                        ZMQBlockHost:    zmqBlockHost,
×
UNCOV
169
                        ZMQTxHost:       zmqTxHost,
×
UNCOV
170
                        ZMQReadDeadline: 5 * time.Second,
×
UNCOV
171
                }
×
UNCOV
172
        }
×
173

UNCOV
174
        var conn *chain.BitcoindConn
×
NEW
175
        err = wait.NoError(func() error {
×
UNCOV
176
                var err error
×
UNCOV
177
                conn, err = chain.NewBitcoindConn(cfg)
×
UNCOV
178
                if err != nil {
×
179
                        return err
×
180
                }
×
181

UNCOV
182
                return conn.Start()
×
183
        }, 10*time.Second)
UNCOV
184
        if err != nil {
×
185
                t.Fatalf("unable to establish connection to bitcoind at %v: "+
×
186
                        "%v", tempBitcoindDir, err)
×
187
        }
×
UNCOV
188
        t.Cleanup(conn.Stop)
×
UNCOV
189

×
NEW
190
        // Assert that the connection with the miner is made.
×
NEW
191
        //
×
NEW
192
        // Create a new RPC client.
×
NEW
193
        rpcCfg := rpcclient.ConnConfig{
×
NEW
194
                Host:                 cfg.Host,
×
NEW
195
                User:                 cfg.User,
×
NEW
196
                Pass:                 cfg.Pass,
×
NEW
197
                DisableConnectOnNew:  true,
×
NEW
198
                DisableAutoReconnect: false,
×
NEW
199
                DisableTLS:           true,
×
NEW
200
                HTTPPostMode:         true,
×
NEW
201
        }
×
NEW
202

×
NEW
203
        rpcClient, err := rpcclient.New(&rpcCfg, nil)
×
NEW
204
        require.NoError(t, err, "failed to create RPC client")
×
NEW
205

×
NEW
206
        // Connect to the miner node.
×
NEW
207
        err = rpcClient.AddNode(minerAddr, rpcclient.ANAdd)
×
NEW
208
        require.NoError(t, err, "failed to connect to miner")
×
NEW
209

×
NEW
210
        // Get the network info and assert the num of outbound connections is 1.
×
NEW
211
        err = wait.NoError(func() error {
×
NEW
212
                result, err := rpcClient.GetNetworkInfo()
×
NEW
213
                require.NoError(t, err)
×
NEW
214

×
NEW
215
                if int(result.Connections) != 1 {
×
NEW
216
                        return fmt.Errorf("want 1 conn, got %d",
×
NEW
217
                                result.Connections)
×
NEW
218
                }
×
219

NEW
220
                if int(result.ConnectionsOut) != 1 {
×
NEW
221
                        return fmt.Errorf("want 1 outbound conn, got %d",
×
NEW
222
                                result.Connections)
×
NEW
223
                }
×
224

NEW
225
                return nil
×
226
        }, wait.DefaultTimeout)
NEW
227
        require.NoError(t, err, "timeout connecting to the miner")
×
NEW
228

×
NEW
229
        // Tear down the rpc client.
×
NEW
230
        rpcClient.Shutdown()
×
NEW
231

×
UNCOV
232
        return conn
×
233
}
234

235
// NewNeutrinoBackend spawns a new neutrino node that connects to a miner at
236
// the specified address.
237
func NewNeutrinoBackend(t *testing.T, netParams *chaincfg.Params,
UNCOV
238
        minerAddr string) *neutrino.ChainService {
×
UNCOV
239

×
UNCOV
240
        t.Helper()
×
UNCOV
241

×
UNCOV
242
        spvDir := t.TempDir()
×
UNCOV
243

×
UNCOV
244
        dbName := filepath.Join(spvDir, "neutrino.db")
×
UNCOV
245
        spvDatabase, err := walletdb.Create(
×
UNCOV
246
                "bdb", dbName, true, kvdb.DefaultDBTimeout,
×
UNCOV
247
        )
×
UNCOV
248
        if err != nil {
×
249
                t.Fatalf("unable to create walletdb: %v", err)
×
250
        }
×
UNCOV
251
        t.Cleanup(func() {
×
UNCOV
252
                spvDatabase.Close()
×
UNCOV
253
        })
×
254

255
        // Create an instance of neutrino connected to the running btcd
256
        // instance.
UNCOV
257
        spvConfig := neutrino.Config{
×
UNCOV
258
                DataDir:      spvDir,
×
UNCOV
259
                Database:     spvDatabase,
×
UNCOV
260
                ChainParams:  *netParams,
×
UNCOV
261
                ConnectPeers: []string{minerAddr},
×
UNCOV
262
        }
×
UNCOV
263
        spvNode, err := neutrino.NewChainService(spvConfig)
×
UNCOV
264
        if err != nil {
×
265
                t.Fatalf("unable to create neutrino: %v", err)
×
266
        }
×
267

268
        // We'll also wait for the instance to sync up fully to the chain
269
        // generated by the btcd instance.
UNCOV
270
        _ = spvNode.Start()
×
UNCOV
271
        for !spvNode.IsCurrent() {
×
UNCOV
272
                time.Sleep(time.Millisecond * 100)
×
UNCOV
273
        }
×
UNCOV
274
        t.Cleanup(func() {
×
UNCOV
275
                _ = spvNode.Stop()
×
UNCOV
276
        })
×
277

UNCOV
278
        return spvNode
×
279
}
280

281
func init() {
3✔
282
        // Before we start any node, we need to make sure that any btcd or
3✔
283
        // bitcoind node that is started through the RPC harness uses a unique
3✔
284
        // port as well to avoid any port collisions.
3✔
285
        rpctest.ListenAddressGenerator =
3✔
286
                port.GenerateSystemUniqueListenerAddresses
3✔
287
}
3✔
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