ln-service 59.3.2 → 59.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,441 +0,0 @@
1
- const {join} = require('path');
2
- const {readFile} = require('fs');
3
- const {readFileSync} = require('fs');
4
- const {spawn} = require('child_process');
5
-
6
- const asyncAuto = require('async/auto');
7
- const asyncMapSeries = require('async/mapSeries');
8
- const asyncRetry = require('async/retry');
9
- const {networks} = require('bitcoinjs-lib');
10
- const openPortFinder = require('portfinder');
11
- const tinysecp = require('tiny-secp256k1');
12
-
13
- const {changePassword} = require('./../../');
14
- const {createSeed} = require('./../../');
15
- const {createWallet} = require('./../../');
16
- const generateBlocks = require('./generate_blocks');
17
- const {authenticatedLndGrpc} = require('./../../');
18
- const spawnChainDaemon = require('./spawn_chain_daemon');
19
- const {stopDaemon} = require('./../../');
20
- const {unauthenticatedLndGrpc} = require('./../../');
21
- const {unlockWallet} = require('./../../');
22
-
23
- const adminMacaroonFileName = 'admin.macaroon';
24
- const chainPass = '0k39BVOdg4uuS7qNCG2jbIXNpwU7d3Ft87PpHPPoCfk=';
25
- const chainRpcCertName = 'rpc.cert';
26
- const chainUser = 'bitcoinrpc';
27
- const interval = 100;
28
- const invoiceMacaroonFileName = 'invoice.macaroon';
29
- const lightningDaemonExecFileName = 'lnd';
30
- const lightningDaemonLogPath = 'logs/';
31
- const lightningSeedPassphrase = 'passphrase';
32
- const lightningTlsCertFileName = 'tls.cert';
33
- const lightningTlsKeyFileName = 'tls.key';
34
- const lightningWalletPassword = 'password';
35
- const lndWalletUnlockerService = 'WalletUnlocker';
36
- const localhost = '127.0.0.1';
37
- const maxSpawnChainDaemonAttempts = 3;
38
- const readMacaroonFileName = 'readonly.macaroon';
39
- const retryCreateSeedCount = 500;
40
- const startPortRange = 7593;
41
- const startWalletTimeoutMs = 4500;
42
- const times = 200;
43
-
44
- /** Run a change password test
45
-
46
- {}
47
-
48
- @returns via cbk
49
- {
50
- kill: <Stop Function> ({}, err => {})
51
- lnd: <Authenticated LND gRPC API Object>
52
- }
53
- */
54
- module.exports = ({network}, cbk) => {
55
- return asyncAuto({
56
- // Import ECPair library
57
- ecp: async () => (await import('ecpair')).ECPairFactory(tinysecp),
58
-
59
- // Find open ports for the listen, REST and RPC ports
60
- getPorts: cbk => {
61
- return asyncMapSeries(['listen', 'rest', 'rpc'], (_, cbk) => {
62
- const port = startPortRange + Math.round(Math.random() * 2000);
63
-
64
- const stopPort = port + 20000;
65
-
66
- return setTimeout(() => {
67
- return openPortFinder.getPort({port, stopPort}, cbk);
68
- },
69
- 50);
70
- },
71
- (err, ports) => {
72
- if (!!err || !Array.isArray(ports) || !ports.length) {
73
- return cbk([500, 'FailedToFindOpenPorts', err]);
74
- }
75
-
76
- const [listen, rest, rpc] = ports;
77
-
78
- return cbk(null, {listen, rest, rpc});
79
- });
80
- },
81
-
82
- // Make a private key for mining rewards
83
- miningKey: ['ecp', ({ecp}, cbk) => {
84
- const keyPair = ecp.makeRandom({network: networks.testnet});
85
-
86
- return cbk(null, {
87
- private_key: keyPair.toWIF(),
88
- public_key: keyPair.publicKey.toString('hex'),
89
- });
90
- }],
91
-
92
- // Spawn a backing chain daemon for lnd
93
- spawnChainDaemon: ['miningKey', ({miningKey}, cbk) => {
94
- return asyncRetry(maxSpawnChainDaemonAttempts, cbk => {
95
- return spawnChainDaemon({
96
- daemon: 'btcd',
97
- is_tls: true,
98
- mining_public_key: miningKey.public_key,
99
- },
100
- cbk);
101
- },
102
- cbk);
103
- }],
104
-
105
- // Get the chain daemon cert
106
- getChainDaemonCert: ['spawnChainDaemon', ({spawnChainDaemon}, cbk) => {
107
- return asyncRetry({interval, times}, cbk => {
108
- return readFile(spawnChainDaemon.rpc_cert, (err, data) => {
109
- if (!!err) {
110
- return cbk([503, 'FailedToGetChainDaemonRpcCert', {err}]);
111
- }
112
-
113
- return cbk(null, data);
114
- });
115
- },
116
- cbk);
117
- }],
118
-
119
- // Generate a block to prevent lnd from getting stuck
120
- generateBlock: [
121
- 'getChainDaemonCert',
122
- 'miningKey',
123
- 'spawnChainDaemon',
124
- ({getChainDaemonCert, miningKey, spawnChainDaemon}, cbk) =>
125
- {
126
- return asyncRetry({interval, times}, cbk => {
127
- try {
128
- return generateBlocks({
129
- cert: getChainDaemonCert,
130
- count: 1,
131
- host: localhost,
132
- key: miningKey.public_key,
133
- pass: chainPass,
134
- port: spawnChainDaemon.rpc_port,
135
- user: chainUser,
136
- },
137
- cbk);
138
- } catch (err) {
139
- return cbk([503, 'FailedToGenerateBlockWhenSpawningLnd', {err}]);
140
- }
141
- },
142
- cbk);
143
- }],
144
-
145
- // Spawn LND
146
- spawnLightningDaemon: [
147
- 'generateBlock',
148
- 'getPorts',
149
- 'spawnChainDaemon',
150
- ({getPorts, spawnChainDaemon}, cbk) =>
151
- {
152
- const {dir} = spawnChainDaemon;
153
-
154
- const daemon = spawn(lightningDaemonExecFileName, [
155
- '--adminmacaroonpath', join(dir, adminMacaroonFileName),
156
- '--bitcoin.active',
157
- '--bitcoin.chaindir', dir,
158
- '--bitcoin.node', 'btcd',
159
- '--bitcoin.regtest',
160
- '--btcd.dir', dir,
161
- '--btcd.rpccert', join(dir, chainRpcCertName),
162
- '--btcd.rpchost', `${localhost}:${spawnChainDaemon.rpc_port}`,
163
- '--btcd.rpcpass', chainPass,
164
- '--btcd.rpcuser', chainUser,
165
- '--datadir', dir,
166
- '--debuglevel', 'trace',
167
- '--externalip', `${localhost}:${getPorts.listen}`,
168
- '--invoicemacaroonpath', join(dir, invoiceMacaroonFileName),
169
- '--listen', `${localhost}:${getPorts.listen}`,
170
- '--logdir', join(dir, lightningDaemonLogPath),
171
- '--nobootstrap',
172
- '--readonlymacaroonpath', join(dir, readMacaroonFileName),
173
- '--restlisten', `${localhost}:${getPorts.rest}`,
174
- '--rpclisten', `${localhost}:${getPorts.rpc}`,
175
- '--tlscertpath', join(dir, lightningTlsCertFileName),
176
- '--tlskeypath', join(dir, lightningTlsKeyFileName),
177
- ]);
178
-
179
- daemon.stderr.on('data', data => {});
180
-
181
- let isReady = false;
182
-
183
- daemon.stdout.on('data', data => {
184
- if (!isReady && /gRPC.proxy.started/.test(data+'')) {
185
- isReady = true;
186
-
187
- return cbk();
188
- };
189
-
190
- return;
191
- });
192
-
193
- return;
194
- }],
195
-
196
- // Get connection to the no-wallet lnd
197
- nonAuthenticatedLnd: [
198
- 'getPorts',
199
- 'spawnChainDaemon',
200
- 'spawnLightningDaemon',
201
- ({getPorts, spawnChainDaemon}, cbk) =>
202
- {
203
- const {dir} = spawnChainDaemon;
204
-
205
- const cert = readFileSync(join(dir, lightningTlsCertFileName));
206
-
207
- try {
208
- return cbk(null, unauthenticatedLndGrpc({
209
- cert: cert.toString('base64'),
210
- socket: `localhost:${getPorts.rpc}`,
211
- }).lnd);
212
- } catch (err) {
213
- return cbk([503, 'FailedToInstantiateNonAuthenticatedLnd', {err}]);
214
- }
215
- }],
216
-
217
- // Create seed
218
- createSeed: [
219
- 'getPorts',
220
- 'nonAuthenticatedLnd',
221
- 'spawnChainDaemon',
222
- ({getPorts, nonAuthenticatedLnd, spawnChainDaemon}, cbk) =>
223
- {
224
- return asyncRetry({interval, times: retryCreateSeedCount}, cbk => {
225
- const {dir} = spawnChainDaemon;
226
-
227
- const cert = readFileSync(join(dir, lightningTlsCertFileName));
228
-
229
- const {lnd} = unauthenticatedLndGrpc({
230
- cert: cert.toString('base64'),
231
- socket: `localhost:${getPorts.rpc}`,
232
- });
233
-
234
- return createSeed({lnd, passphrase: lightningSeedPassphrase}, cbk);
235
- },
236
- cbk);
237
- }],
238
-
239
- // Create wallet
240
- createWallet: [
241
- 'createSeed',
242
- 'nonAuthenticatedLnd',
243
- ({createSeed, nonAuthenticatedLnd}, cbk) =>
244
- {
245
- return createWallet({
246
- lnd: nonAuthenticatedLnd,
247
- passphrase: lightningSeedPassphrase,
248
- password: lightningWalletPassword,
249
- seed: createSeed.seed,
250
- },
251
- err => {
252
- if (!!err) {
253
- return cbk(err);
254
- }
255
-
256
- return cbk();
257
- });
258
- }],
259
-
260
- // Get admin macaroon
261
- macaroon: [
262
- 'createWallet',
263
- 'spawnChainDaemon',
264
- ({spawnChainDaemon}, cbk) =>
265
- {
266
- const {dir} = spawnChainDaemon;
267
- const interval = retryCount => 50 * Math.pow(2, retryCount);
268
- const times = 15;
269
-
270
- const macaroonPath = join(dir, adminMacaroonFileName);
271
-
272
- return asyncRetry({interval, times}, cbk => {
273
- try {
274
- return cbk(null, readFileSync(macaroonPath).toString('base64'));
275
- } catch (err) {
276
- return cbk([503, 'FailedToGetAdminMacaroon', err]);
277
- }
278
- },
279
- cbk);
280
- }],
281
-
282
- // Wallet details
283
- wallet: [
284
- 'macaroon',
285
- 'spawnChainDaemon',
286
- 'getPorts',
287
- ({getPorts, macaroon, spawnChainDaemon}, cbk) =>
288
- {
289
- const {dir} = spawnChainDaemon;
290
- const certPath = join(dir, lightningTlsCertFileName);
291
-
292
- return cbk(null, {
293
- macaroon,
294
- cert: readFileSync(certPath).toString('base64'),
295
- host: `localhost:${getPorts.rpc}`,
296
- });
297
- }],
298
-
299
- // Wallet LND GRPC API
300
- lnd: ['wallet', ({wallet}, cbk) => {
301
- try {
302
- return cbk(null, authenticatedLndGrpc({
303
- cert: wallet.cert,
304
- macaroon: wallet.macaroon,
305
- socket: wallet.host,
306
- }).lnd);
307
- } catch (err) {
308
- return cbk([503, 'FailedToInstantiateWalletLnd', err]);
309
- }
310
- }],
311
-
312
- // Stop LND
313
- stopLnd: ['lnd', async ({lnd}) => {
314
- const interval = 200;
315
- const times = 15;
316
-
317
- return await asyncRetry({interval, times}, async () => {
318
- return await stopDaemon({lnd});
319
- });
320
- }],
321
-
322
- // Restart LND (locked)
323
- restartLnd: [
324
- 'getPorts',
325
- 'spawnChainDaemon',
326
- 'stopLnd',
327
- ({getPorts, spawnChainDaemon}, cbk) =>
328
- {
329
- const {dir} = spawnChainDaemon;
330
-
331
- const daemon = spawn(lightningDaemonExecFileName, [
332
- '--adminmacaroonpath', join(dir, adminMacaroonFileName),
333
- '--bitcoin.active',
334
- '--bitcoin.chaindir', dir,
335
- '--bitcoin.node', 'btcd',
336
- '--bitcoin.regtest',
337
- '--btcd.dir', dir,
338
- '--btcd.rpccert', join(dir, chainRpcCertName),
339
- '--btcd.rpchost', `${localhost}:${spawnChainDaemon.rpc_port}`,
340
- '--btcd.rpcpass', chainPass,
341
- '--btcd.rpcuser', chainUser,
342
- '--datadir', dir,
343
- '--debuglevel', 'trace',
344
- '--externalip', `${localhost}:${getPorts.listen}`,
345
- '--invoicemacaroonpath', join(dir, invoiceMacaroonFileName),
346
- '--listen', `${localhost}:${getPorts.listen}`,
347
- '--logdir', join(dir, lightningDaemonLogPath),
348
- '--nobootstrap',
349
- '--readonlymacaroonpath', join(dir, readMacaroonFileName),
350
- '--restlisten', `${localhost}:${getPorts.rest}`,
351
- '--rpclisten', `${localhost}:${getPorts.rpc}`,
352
- '--tlscertpath', join(dir, lightningTlsCertFileName),
353
- '--tlskeypath', join(dir, lightningTlsKeyFileName),
354
- ]);
355
-
356
- daemon.stderr.on('data', data => {});
357
-
358
- let isReady = false;
359
-
360
- daemon.stdout.on('data', data => {
361
- if (!isReady && /gRPC.proxy.started/.test(data+'')) {
362
- isReady = true;
363
-
364
- return cbk(null, {daemon});
365
- };
366
-
367
- return;
368
- });
369
-
370
- return;
371
- }],
372
-
373
- // Get tls cert
374
- cert: [
375
- 'restartLnd',
376
- 'spawnChainDaemon',
377
- ({spawnChainDaemon}, cbk) =>
378
- {
379
- const {dir} = spawnChainDaemon;
380
- const times = 150;
381
-
382
- const certPath = join(dir, lightningTlsCertFileName);
383
-
384
- return asyncRetry({interval, times}, cbk => {
385
- try {
386
- return cbk(null, readFileSync(certPath).toString('base64'));
387
- } catch (err) {
388
- return cbk([503, 'FailedToGetCertAfterRestart', err]);
389
- }
390
- },
391
- cbk);
392
- }],
393
-
394
- // Get locked restarted lnd
395
- restartedLnd: ['cert', 'getPorts', ({cert, getPorts}, cbk) => {
396
- try {
397
- return cbk(null, unauthenticatedLndGrpc({
398
- cert,
399
- socket: `localhost:${getPorts.rpc}`,
400
- }).lnd);
401
- } catch (err) {
402
- return cbk([503, 'FailedToLaunchLightningDaemon', err]);
403
- }
404
- }],
405
-
406
- // Change password
407
- changePassword: ['restartedLnd', ({restartedLnd}, cbk) => {
408
- return asyncRetry({interval, times}, cbk => {
409
- return changePassword({
410
- current_password: lightningWalletPassword,
411
- lnd: restartedLnd,
412
- new_password: 'changed_passphrase',
413
- },
414
- cbk);
415
- },
416
- cbk);
417
- }],
418
- },
419
- (err, res) => {
420
- if (!!err) {
421
- return cbk(err);
422
- }
423
-
424
- const {lnd} = res;
425
-
426
- const kill = () => {
427
- res.spawnChainDaemon.daemon.kill(9);
428
- res.restartLnd.daemon.kill(9);
429
-
430
- return;
431
- };
432
-
433
- process.on('uncaughtException', err => {
434
- kill();
435
-
436
- setTimeout(() => process.exit(1), 1000);
437
- });
438
-
439
- return cbk(null, {lnd, kill});
440
- });
441
- };
@@ -1,27 +0,0 @@
1
- const rpc = require('./rpc');
2
-
3
- const addFlag = 'add';
4
- const cmd = 'addnode';
5
-
6
- /** Connect to node
7
-
8
- {
9
- [cert]: <TLS Cert For RPC Connection Buffer Object>
10
- connect: <Socket To Connect To String>
11
- host: <Chain Daemon IP String>
12
- pass: <RPC Password String>
13
- port: <RPC Port Number>
14
- user: <RPC Username String>
15
- }
16
- */
17
- module.exports = ({cert, connect, host, pass, port, user}, cbk) => {
18
- const params = [connect, addFlag];
19
-
20
- return rpc({cert, cmd, host, params, pass, port, user}, err => {
21
- if (!!err) {
22
- return cbk([503, 'UnexpectedErrorAddingNode', {err}]);
23
- }
24
-
25
- return cbk();
26
- });
27
- };