ln-service 52.14.4 → 53.0.0
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.
- package/CHANGELOG.md +21 -0
- package/README.md +163 -11
- package/package.json +7 -14
- package/test/autopilotrpc-integration/test_autopilot.js +9 -15
- package/test/chainrpc-integration/test_get_height.js +7 -10
- package/test/chainrpc-integration/test_subscribe_to_blocks.js +52 -31
- package/test/chainrpc-integration/test_subscribe_to_chain_address.js +72 -66
- package/test/chainrpc-integration/test_subscribe_to_chain_spend.js +47 -16
- package/test/{integration → extra-integration}/test_recover_funds_from_channel.js +0 -0
- package/test/{integration → extra-integration}/test_recover_funds_from_channels.js +0 -0
- package/test/{integration → extra-integration}/test_restrict_macaroon.js +0 -0
- package/test/{integration → extra-integration}/test_revoke_access.js +0 -0
- package/test/{integration → extra-integration}/test_subscribe_to_rpc_requests.js +1 -1
- package/test/integration/test_add_peer.js +16 -12
- package/test/integration/test_cancel_pending_channel.js +20 -6
- package/test/integration/test_close_channel.js +15 -10
- package/test/integration/test_create_chain_address.js +3 -6
- package/test/integration/test_create_invoice.js +27 -23
- package/test/integration/test_decode_payment_request.js +30 -29
- package/test/integration/test_delete_payment.js +11 -8
- package/test/integration/test_delete_payments.js +13 -16
- package/test/integration/test_get_access_ids.js +4 -7
- package/test/integration/test_get_backup.js +12 -8
- package/test/integration/test_get_backups.js +8 -10
- package/test/integration/test_get_chain_balance.js +9 -53
- package/test/integration/test_get_chain_fee_estimate.js +21 -10
- package/test/integration/test_get_chain_transactions.js +30 -52
- package/test/integration/test_get_channel.js +7 -7
- package/test/integration/test_get_channel_balance.js +5 -6
- package/test/integration/test_get_channels.js +11 -10
- package/test/integration/test_get_closed_channels.js +169 -139
- package/test/integration/test_get_failed_payments.js +37 -39
- package/test/integration/test_get_fee_rates.js +6 -9
- package/test/integration/test_get_forwards.js +34 -35
- package/test/integration/test_get_invoice.js +7 -11
- package/test/integration/test_get_invoices.js +33 -30
- package/test/integration/test_get_methods.js +4 -7
- package/test/integration/test_get_network_centrality.js +14 -17
- package/test/integration/test_get_network_graph.js +12 -15
- package/test/integration/test_get_network_info.js +5 -6
- package/test/integration/test_get_node.js +15 -31
- package/test/integration/test_get_payments.js +10 -10
- package/test/integration/test_get_peers.js +10 -13
- package/test/integration/test_get_pending_coop.js +13 -18
- package/test/integration/test_get_pending_force.js +29 -21
- package/test/integration/test_get_route_to_destination.js +47 -40
- package/test/integration/test_get_utxos.js +17 -42
- package/test/integration/test_get_wallet_info.js +5 -12
- package/test/integration/test_open_channel.js +16 -9
- package/test/integration/test_open_channels.js +66 -66
- package/test/integration/test_pay.js +39 -36
- package/test/integration/test_pay_private_invoice.js +78 -72
- package/test/integration/test_payment_errors.js +13 -11
- package/test/integration/test_propose_channel.js +74 -53
- package/test/integration/test_push_funds.js +11 -15
- package/test/integration/test_rebalance.js +11 -22
- package/test/integration/test_remove_peer.js +13 -48
- package/test/integration/test_send_message_to_peer.js +25 -17
- package/test/integration/test_send_to_chain_address.js +60 -51
- package/test/integration/test_send_to_chain_addresses.js +30 -18
- package/test/integration/test_sign_message.js +3 -6
- package/test/integration/test_stop_daemon.js +3 -9
- package/test/integration/test_subscribe_to_backups.js +19 -11
- package/test/integration/test_subscribe_to_channels.js +28 -20
- package/test/integration/test_subscribe_to_graph.js +43 -22
- package/test/integration/test_subscribe_to_invoices.js +89 -103
- package/test/integration/test_subscribe_to_open_requests.js +47 -31
- package/test/integration/test_subscribe_to_peer_messages.js +51 -21
- package/test/integration/test_subscribe_to_peers.js +11 -16
- package/test/integration/test_subscribe_to_transactions.js +49 -45
- package/test/integration/test_update_routing_fees.js +12 -16
- package/test/integration/test_verify_access.js +5 -10
- package/test/integration/test_verify_backup.js +10 -8
- package/test/integration/test_verify_backups.js +11 -16
- package/test/integration/test_verify_message.js +6 -9
- package/test/invoicesrpc-integration/test_cancel_invoice.js +15 -22
- package/test/invoicesrpc-integration/test_get_sweep_transactions.js +15 -11
- package/test/invoicesrpc-integration/test_push_payment.js +53 -55
- package/test/invoicesrpc-integration/test_settle_invoice.js +25 -19
- package/test/invoicesrpc-integration/test_subscribe_cancel_invoice.js +13 -11
- package/test/invoicesrpc-integration/test_subscribe_settle_invoice.js +20 -15
- package/test/macros/btcsuite_type_daemon.js +1 -1
- package/test/macros/chain_send_transaction.js +1 -1
- package/test/macros/change_password.js +15 -13
- package/test/macros/generate_blocks.js +24 -29
- package/test/macros/rpc.js +1 -0
- package/test/macros/setup_channel.js +23 -9
- package/test/macros/spawn_lnd.js +3 -1
- package/test/macros/wait_for_channel.js +8 -3
- package/test/macros/wait_for_route.js +2 -2
- package/test/routerrpc-integration/test_delete_forwarding_reputations.js +15 -22
- package/test/routerrpc-integration/test_disable_channel.js +8 -12
- package/test/routerrpc-integration/test_get_forwarding_confidence.js +17 -37
- package/test/routerrpc-integration/test_get_forwarding_reputations.js +26 -25
- package/test/routerrpc-integration/test_get_pathfinding_settings.js +6 -12
- package/test/routerrpc-integration/test_get_payment.js +19 -26
- package/test/routerrpc-integration/test_get_route_confidence.js +15 -21
- package/test/routerrpc-integration/test_get_route_through_hops.js +29 -32
- package/test/routerrpc-integration/test_multipath_payment.js +18 -20
- package/test/routerrpc-integration/test_pay_via_payment_details.js +19 -34
- package/test/routerrpc-integration/test_pay_via_payment_request.js +17 -27
- package/test/routerrpc-integration/test_pay_via_routes.js +37 -37
- package/test/routerrpc-integration/test_probe_for_route.js +27 -33
- package/test/routerrpc-integration/test_subscribe_to_forward_requests.js +138 -32
- package/test/routerrpc-integration/test_subscribe_to_forwards.js +83 -77
- package/test/routerrpc-integration/test_subscribe_to_past_payments.js +34 -28
- package/test/routerrpc-integration/test_update_pathfinding_settings.js +7 -10
- package/test/signerrpc-integration/test_diffie_hellman_compute_secret.js +15 -14
- package/test/signerrpc-integration/test_sign_bytes.js +11 -15
- package/test/signerrpc-integration/test_sign_transaction.js +6 -7
- package/test/signerrpc-integration/test_verify_bytes_signature.js +11 -12
- package/test/versionrpc-integration/test_get_wallet_version.js +6 -7
- package/test/walletrpc-integration/test_fund_psbt.js +13 -12
- package/test/walletrpc-integration/test_get_chain_fee_rate.js +4 -8
- package/test/walletrpc-integration/test_get_locked_utxos.js +11 -27
- package/test/walletrpc-integration/test_get_public_key.js +5 -13
- package/test/walletrpc-integration/test_lock_utxo.js +16 -23
- package/test/walletrpc-integration/test_send_to_chain_output_scripts.js +25 -6
- package/test/walletrpc-integration/test_sign_psbt.js +28 -19
- package/test/walletrpc-integration/test_unlock_utxo.js +16 -27
- package/test/walletrpc-integration/test_update_chain_transaction.js +6 -31
|
@@ -8,14 +8,16 @@ const {networks} = require('bitcoinjs-lib');
|
|
|
8
8
|
const {payments} = require('bitcoinjs-lib');
|
|
9
9
|
const {script} = require('bitcoinjs-lib');
|
|
10
10
|
const signPsbtWithKey = require('psbt').signPsbt;
|
|
11
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
11
12
|
const {test} = require('@alexbosworth/tap');
|
|
12
13
|
const {Transaction} = require('bitcoinjs-lib');
|
|
13
14
|
const {updatePsbt} = require('psbt');
|
|
14
15
|
|
|
16
|
+
const {addPeer} = require('./../../');
|
|
15
17
|
const {broadcastChainTransaction} = require('./../../');
|
|
16
18
|
const {createChainAddress} = require('./../../');
|
|
17
|
-
const {createCluster} = require('./../macros');
|
|
18
19
|
const {fundPsbt} = require('./../../');
|
|
20
|
+
const {getChainBalance} = require('./../../');
|
|
19
21
|
const {getChannels} = require('./../../');
|
|
20
22
|
const {getPendingChannels} = require('./../../');
|
|
21
23
|
const {getPublicKey} = require('./../../');
|
|
@@ -26,6 +28,7 @@ const {proposeChannel} = require('./../../');
|
|
|
26
28
|
const {signPsbt} = require('./../../');
|
|
27
29
|
const {signTransaction} = require('./../../');
|
|
28
30
|
|
|
31
|
+
const anchorFeatureBit = 23;
|
|
29
32
|
const capacity = 1e6;
|
|
30
33
|
const {ceil} = Math;
|
|
31
34
|
const cooperativeCloseDelay = 2016;
|
|
@@ -40,41 +43,70 @@ const {p2ms} = payments;
|
|
|
40
43
|
const {p2pkh} = payments;
|
|
41
44
|
const {regtest} = networks;
|
|
42
45
|
const reserveRatio = 0.01;
|
|
46
|
+
const size = 2;
|
|
43
47
|
const temporaryFamily = 805;
|
|
44
48
|
const times = 300;
|
|
45
49
|
|
|
46
50
|
// Proposing a cooperative delay channel should open a cooperative delay chan
|
|
47
51
|
test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
48
|
-
const
|
|
52
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
49
53
|
|
|
50
|
-
const
|
|
54
|
+
const [control, target] = nodes;
|
|
55
|
+
|
|
56
|
+
const {lnd, generate} = control;
|
|
57
|
+
|
|
58
|
+
const {version} = await getWalletVersion({lnd});
|
|
51
59
|
|
|
52
60
|
switch (version) {
|
|
53
61
|
case '0.11.0-beta':
|
|
54
62
|
case '0.11.1-beta':
|
|
55
63
|
// Exit early when funding PSBTs is not supported
|
|
56
|
-
await
|
|
64
|
+
await kill({});
|
|
65
|
+
|
|
57
66
|
return end();
|
|
58
|
-
break;
|
|
59
67
|
|
|
60
68
|
default:
|
|
61
69
|
break;
|
|
62
70
|
}
|
|
63
71
|
|
|
64
|
-
|
|
72
|
+
// Generate some funds for LND
|
|
73
|
+
await asyncRetry({times}, async () => {
|
|
74
|
+
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
75
|
+
|
|
76
|
+
await generate({});
|
|
77
|
+
|
|
78
|
+
const wallet = await getChainBalance({lnd});
|
|
79
|
+
|
|
80
|
+
if (!wallet.chain_balance) {
|
|
81
|
+
throw new Error('ExpectedChainBalanceForNode');
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Generate some funds for LND
|
|
86
|
+
await asyncRetry({times}, async () => {
|
|
87
|
+
await target.generate({});
|
|
65
88
|
|
|
66
|
-
|
|
89
|
+
const wallet = await getChainBalance({lnd: target.lnd});
|
|
90
|
+
|
|
91
|
+
if (!wallet.chain_balance) {
|
|
92
|
+
throw new Error('ExpectedChainBalanceForNode');
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const {features} = await getWalletInfo({lnd});
|
|
97
|
+
|
|
98
|
+
const isAnchors = !!features.find(n => n.bit === anchorFeatureBit);
|
|
67
99
|
|
|
68
100
|
// Derive a temporary key for control to pay into
|
|
69
101
|
const controlDerivedKey = await getPublicKey({
|
|
102
|
+
lnd,
|
|
70
103
|
family: temporaryFamily,
|
|
71
|
-
lnd: cluster.control.lnd,
|
|
72
104
|
});
|
|
73
105
|
|
|
74
106
|
// Derive a temporary key for target to pay into
|
|
75
107
|
const targetDerivedKey = await getPublicKey({
|
|
76
108
|
family: temporaryFamily,
|
|
77
|
-
lnd:
|
|
109
|
+
lnd: target.lnd,
|
|
78
110
|
});
|
|
79
111
|
|
|
80
112
|
// Control should fund and sign a transaction going to the control temp key
|
|
@@ -95,7 +127,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
95
127
|
|
|
96
128
|
// Control can now fund a transaction to pay to the temp address
|
|
97
129
|
const controlFundPsbt = await fundPsbt({
|
|
98
|
-
lnd
|
|
130
|
+
lnd,
|
|
99
131
|
fee_tokens_per_vbyte: feeRate,
|
|
100
132
|
outputs: [{
|
|
101
133
|
address: controlDerivedAddress.address,
|
|
@@ -105,7 +137,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
105
137
|
|
|
106
138
|
// Target can now fund a transaction to pay to the temp address
|
|
107
139
|
const targetFundPsbt = await fundPsbt({
|
|
108
|
-
lnd:
|
|
140
|
+
lnd: target.lnd,
|
|
109
141
|
fee_tokens_per_vbyte: feeRate,
|
|
110
142
|
outputs: [{
|
|
111
143
|
address: targetDerivedAddress.address,
|
|
@@ -114,14 +146,11 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
114
146
|
});
|
|
115
147
|
|
|
116
148
|
// Control can sign the funding to the temporary address
|
|
117
|
-
const controlSignPsbt = await signPsbt({
|
|
118
|
-
lnd: cluster.control.lnd,
|
|
119
|
-
psbt: controlFundPsbt.psbt,
|
|
120
|
-
});
|
|
149
|
+
const controlSignPsbt = await signPsbt({lnd, psbt: controlFundPsbt.psbt});
|
|
121
150
|
|
|
122
151
|
// Target can sign the funding to the temporary address
|
|
123
152
|
const targetSignPsbt = await signPsbt({
|
|
124
|
-
lnd:
|
|
153
|
+
lnd: target.lnd,
|
|
125
154
|
psbt: targetFundPsbt.psbt,
|
|
126
155
|
});
|
|
127
156
|
|
|
@@ -138,16 +167,10 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
138
167
|
const targetId = fromHex(targetPsbt.unsigned_transaction).getId();
|
|
139
168
|
|
|
140
169
|
// Derive a new control key for a 2:2 multisig
|
|
141
|
-
const controlMultiSigKey = await getPublicKey({
|
|
142
|
-
family,
|
|
143
|
-
lnd: cluster.control.lnd,
|
|
144
|
-
});
|
|
170
|
+
const controlMultiSigKey = await getPublicKey({family, lnd});
|
|
145
171
|
|
|
146
172
|
// Derive a new target key for a 2:2 multisig
|
|
147
|
-
const targetMultiSigKey = await getPublicKey({
|
|
148
|
-
family,
|
|
149
|
-
lnd: cluster.target.lnd,
|
|
150
|
-
});
|
|
173
|
+
const targetMultiSigKey = await getPublicKey({family, lnd: target.lnd});
|
|
151
174
|
|
|
152
175
|
const fundingMultiSigKeys = [
|
|
153
176
|
controlMultiSigKey.public_key,
|
|
@@ -223,8 +246,11 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
223
246
|
return hash.equals(targetTxHash);
|
|
224
247
|
});
|
|
225
248
|
|
|
249
|
+
const decodePayout = decodePsbt({psbt: psbtWithSpending.psbt});
|
|
250
|
+
|
|
226
251
|
// Call signTransaction on the unsigned tx that pays from temp -> multisig
|
|
227
252
|
const controlSignDerivedKey = await signTransaction({
|
|
253
|
+
lnd,
|
|
228
254
|
inputs: [{
|
|
229
255
|
key_family: temporaryFamily,
|
|
230
256
|
key_index: controlDerivedKey.index,
|
|
@@ -234,8 +260,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
234
260
|
vin: controlVin,
|
|
235
261
|
witness_script: p2pkh({hash: controlDerivedAddress.hash}).output,
|
|
236
262
|
}],
|
|
237
|
-
|
|
238
|
-
transaction: decodePsbt({psbt: psbtWithSpending.psbt}).unsigned_transaction,
|
|
263
|
+
transaction: decodePayout.unsigned_transaction,
|
|
239
264
|
});
|
|
240
265
|
|
|
241
266
|
const [controlDerivedSignature] = controlSignDerivedKey.signatures;
|
|
@@ -266,7 +291,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
266
291
|
vin: targetVin,
|
|
267
292
|
witness_script: p2pkh({hash: targetDerivedAddress.hash}).output,
|
|
268
293
|
}],
|
|
269
|
-
lnd:
|
|
294
|
+
lnd: target.lnd,
|
|
270
295
|
transaction: decodePsbt({psbt: psbtWithSpending.psbt}).unsigned_transaction,
|
|
271
296
|
});
|
|
272
297
|
|
|
@@ -292,7 +317,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
292
317
|
cooperative_close_delay: cooperativeCloseDelay,
|
|
293
318
|
id: pendingChannelId.toString('hex'),
|
|
294
319
|
key_index: targetMultiSigKey.index,
|
|
295
|
-
lnd:
|
|
320
|
+
lnd: target.lnd,
|
|
296
321
|
remote_key: controlMultiSigKey.public_key,
|
|
297
322
|
transaction_id: fundingTxId,
|
|
298
323
|
transaction_vout: fundingTxVout,
|
|
@@ -300,7 +325,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
300
325
|
|
|
301
326
|
const coopCloseAddress = await createChainAddress({
|
|
302
327
|
format: 'np2wpkh',
|
|
303
|
-
lnd:
|
|
328
|
+
lnd: control.lnd,
|
|
304
329
|
});
|
|
305
330
|
|
|
306
331
|
// Propose the channel to the target
|
|
@@ -312,14 +337,14 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
312
337
|
id: pendingChannelId.toString('hex'),
|
|
313
338
|
is_private: true,
|
|
314
339
|
key_index: controlMultiSigKey.index,
|
|
315
|
-
lnd:
|
|
316
|
-
partner_public_key:
|
|
340
|
+
lnd: control.lnd,
|
|
341
|
+
partner_public_key: target.id,
|
|
317
342
|
remote_key: targetMultiSigKey.public_key,
|
|
318
343
|
transaction_id: fundingTxId,
|
|
319
344
|
transaction_vout: fundingTxVout,
|
|
320
345
|
});
|
|
321
346
|
|
|
322
|
-
const pendingTarget = await getPendingChannels({lnd:
|
|
347
|
+
const pendingTarget = await getPendingChannels({lnd: target.lnd});
|
|
323
348
|
|
|
324
349
|
const [incoming] = pendingTarget.pending_channels;
|
|
325
350
|
|
|
@@ -341,7 +366,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
341
366
|
equal(incoming.is_partner_initiated, true, 'Peer initiated the channel');
|
|
342
367
|
equal(incoming.local_balance, giveTokens, 'The incoming channel is split');
|
|
343
368
|
equal(incoming.local_reserve, capacity * reserveRatio, 'Reserve ratio');
|
|
344
|
-
equal(incoming.partner_public_key,
|
|
369
|
+
equal(incoming.partner_public_key, control.id, 'Peer key');
|
|
345
370
|
equal(incoming.pending_balance, undefined, 'No tokens pending');
|
|
346
371
|
equal(incoming.pending_payments, undefined, 'No HTLCs active');
|
|
347
372
|
equal(incoming.received, 0, 'Nothing received');
|
|
@@ -370,27 +395,27 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
370
395
|
|
|
371
396
|
// Broadcast the transaction to fund the control side
|
|
372
397
|
await broadcastChainTransaction({
|
|
398
|
+
lnd,
|
|
373
399
|
transaction: controlSignPsbt.transaction,
|
|
374
|
-
lnd: cluster.control.lnd,
|
|
375
400
|
});
|
|
376
401
|
|
|
377
402
|
// Broadcast the transaction to fund the target side
|
|
378
403
|
await broadcastChainTransaction({
|
|
404
|
+
lnd,
|
|
379
405
|
transaction: targetSignPsbt.transaction,
|
|
380
|
-
lnd: cluster.control.lnd,
|
|
381
406
|
});
|
|
382
407
|
|
|
383
408
|
// Broadcast the transaction to fund the channel
|
|
384
409
|
await broadcastChainTransaction({
|
|
410
|
+
lnd,
|
|
385
411
|
transaction: finalTempTx.transaction,
|
|
386
|
-
lnd: cluster.control.lnd,
|
|
387
412
|
});
|
|
388
413
|
|
|
389
414
|
// Mine the funding transactions into a block
|
|
390
415
|
await asyncRetry({interval, times}, async () => {
|
|
391
|
-
await
|
|
416
|
+
await control.generate({});
|
|
392
417
|
|
|
393
|
-
const {channels} = await getChannels({lnd
|
|
418
|
+
const {channels} = await getChannels({lnd});
|
|
394
419
|
|
|
395
420
|
if (!channels.find(n => n.is_active)) {
|
|
396
421
|
throw new Error('ExpectedActiveChannel');
|
|
@@ -399,7 +424,7 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
399
424
|
return;
|
|
400
425
|
});
|
|
401
426
|
|
|
402
|
-
const controlChannels = await getChannels({lnd
|
|
427
|
+
const controlChannels = await getChannels({lnd});
|
|
403
428
|
|
|
404
429
|
const [controlChannel] = controlChannels.channels;
|
|
405
430
|
|
|
@@ -409,32 +434,30 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
409
434
|
if (isAnchors) {
|
|
410
435
|
equal(controlChannel.commit_transaction_fee, 2810, 'Regular tx fee');
|
|
411
436
|
equal(controlChannel.commit_transaction_weight, 1116, 'Regular tx size');
|
|
412
|
-
equal(controlChannel.is_static_remote_key, false, 'Not static remote key');
|
|
413
437
|
} else {
|
|
414
438
|
equal(controlChannel.commit_transaction_fee, 9050, 'Regular tx fee');
|
|
415
439
|
equal(controlChannel.commit_transaction_weight, 724, 'Regular tx size');
|
|
416
|
-
equal(controlChannel.is_static_remote_key, true, 'Regular remote key');
|
|
417
440
|
}
|
|
418
441
|
|
|
419
442
|
equal(controlChannel.capacity, capacity, 'Channel with capacity created');
|
|
420
|
-
equal(controlChannel.cooperative_close_address, closeAddr, 'Got
|
|
421
|
-
equal(controlChannel.cooperative_close_delay_height,
|
|
422
|
-
equal(controlChannel.id,
|
|
443
|
+
equal(controlChannel.cooperative_close_address, closeAddr, 'Got closeaddr');
|
|
444
|
+
equal(!!controlChannel.cooperative_close_delay_height, true, 'Thaw height');
|
|
445
|
+
equal(!!controlChannel.id, true, 'Got channel id');
|
|
423
446
|
equal(controlChannel.is_active, true, 'Channel is active and ready');
|
|
424
447
|
equal(controlChannel.is_closing, false, 'Channel is not closing');
|
|
425
448
|
equal(controlChannel.is_opening, false, 'Channel is already opened');
|
|
426
449
|
equal(controlChannel.is_partner_initiated, false, 'Control opened');
|
|
427
450
|
equal(controlChannel.is_private, true, 'Channel is private');
|
|
428
|
-
equal(controlChannel.local_balance, incoming.remote_balance, 'Control
|
|
451
|
+
equal(controlChannel.local_balance, incoming.remote_balance, 'Control tok');
|
|
429
452
|
equal(controlChannel.local_csv, 144, 'Channel CSV');
|
|
430
453
|
ok(controlChannel.local_dust >= 354, 'Channel dust');
|
|
431
454
|
equal(controlChannel.local_given, giveTokens, 'Channel tokens given over');
|
|
432
455
|
equal(controlChannel.local_max_htlcs, 483, 'Channel HTLCs max set');
|
|
433
|
-
equal(controlChannel.partner_public_key,
|
|
456
|
+
equal(controlChannel.partner_public_key, target.id, 'R-key');
|
|
434
457
|
equal(controlChannel.transaction_id, fundingTxId, 'Funding tx id');
|
|
435
458
|
equal(controlChannel.transaction_vout, fundingTxVout, 'Funding tx vout');
|
|
436
459
|
|
|
437
|
-
const targetChannels = await getChannels({lnd:
|
|
460
|
+
const targetChannels = await getChannels({lnd: target.lnd});
|
|
438
461
|
|
|
439
462
|
const [targetChannel] = targetChannels.channels;
|
|
440
463
|
|
|
@@ -442,17 +465,15 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
442
465
|
if (isAnchors) {
|
|
443
466
|
equal(targetChannel.commit_transaction_fee, 2810, 'Regular tx commit fee');
|
|
444
467
|
equal(targetChannel.commit_transaction_weight, 1116, 'Regular tx size');
|
|
445
|
-
equal(targetChannel.is_static_remote_key, false, 'Anchor channel');
|
|
446
468
|
} else {
|
|
447
469
|
equal(targetChannel.commit_transaction_fee, 9050, 'Regular tx commit fee');
|
|
448
470
|
equal(targetChannel.commit_transaction_weight, 724, 'Regular tx size');
|
|
449
|
-
equal(targetChannel.is_static_remote_key, true, 'Regular remote key');
|
|
450
471
|
}
|
|
451
472
|
|
|
452
473
|
equal(targetChannel.capacity, capacity, 'Channel with capacity created');
|
|
453
474
|
equal(targetChannel.cooperative_close_address, undefined, 'No close addr');
|
|
454
|
-
equal(targetChannel.cooperative_close_delay_height,
|
|
455
|
-
equal(targetChannel.id,
|
|
475
|
+
equal(!!targetChannel.cooperative_close_delay_height, true, 'Thaw height');
|
|
476
|
+
equal(!!targetChannel.id, true, 'Got channel id');
|
|
456
477
|
equal(targetChannel.is_active, true, 'Channel is active and ready');
|
|
457
478
|
equal(targetChannel.is_closing, false, 'Channel is not closing');
|
|
458
479
|
equal(targetChannel.is_opening, false, 'Channel is already opened');
|
|
@@ -463,11 +484,11 @@ test(`Propose a channel with a coop delay`, async ({end, equal, ok}) => {
|
|
|
463
484
|
ok(targetChannel.local_dust >= 354, 'Channel dust');
|
|
464
485
|
equal(targetChannel.local_given, 0, 'No tokens given');
|
|
465
486
|
equal(targetChannel.local_max_htlcs, 483, 'Channel HTLCs max set');
|
|
466
|
-
equal(targetChannel.partner_public_key,
|
|
487
|
+
equal(targetChannel.partner_public_key, control.id, 'R-key');
|
|
467
488
|
equal(targetChannel.transaction_id, fundingTxId, 'Funding tx id');
|
|
468
489
|
equal(targetChannel.transaction_vout, fundingTxVout, 'Funding tx vout');
|
|
469
490
|
|
|
470
|
-
await
|
|
491
|
+
await kill({});
|
|
471
492
|
|
|
472
493
|
return end();
|
|
473
494
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const asyncRetry = require('async/retry');
|
|
2
2
|
const {decodeChanId} = require('bolt07');
|
|
3
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
3
4
|
const {test} = require('@alexbosworth/tap');
|
|
4
5
|
|
|
5
6
|
const {createCluster} = require('./../macros');
|
|
@@ -7,6 +8,7 @@ const {createInvoice} = require('./../../');
|
|
|
7
8
|
const {getChannel} = require('./../../');
|
|
8
9
|
const {getChannelBalance} = require('./../../');
|
|
9
10
|
const {getChannels} = require('./../../');
|
|
11
|
+
const {getHeight} = require('./../../');
|
|
10
12
|
const {getPendingChannels} = require('./../../');
|
|
11
13
|
const {getWalletInfo} = require('./../../');
|
|
12
14
|
const {pay} = require('./../../');
|
|
@@ -18,33 +20,27 @@ const {floor} = Math;
|
|
|
18
20
|
const interval = 1000;
|
|
19
21
|
const mtokPerTok = 1e3;
|
|
20
22
|
const reserveRatio = 0.02;
|
|
23
|
+
const size = 2;
|
|
21
24
|
const times = 100;
|
|
22
25
|
const tokens = 1e3;
|
|
23
26
|
|
|
24
27
|
// Pushing funds via a fee bump should result in the destination getting funds
|
|
25
28
|
test('Push funds', async ({end, equal}) => {
|
|
26
|
-
|
|
29
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
cluster = await createCluster({
|
|
30
|
-
is_circular_enabled: true,
|
|
31
|
-
is_remote_skipped: true,
|
|
32
|
-
});
|
|
33
|
-
} catch (err) {
|
|
34
|
-
cluster = await createCluster({is_remote_skipped: true});
|
|
35
|
-
}
|
|
31
|
+
const [control, target] = nodes;
|
|
36
32
|
|
|
37
|
-
const {lnd} =
|
|
33
|
+
const {lnd} = control;
|
|
38
34
|
|
|
39
35
|
await setupChannel({
|
|
40
36
|
lnd,
|
|
41
|
-
generate:
|
|
37
|
+
generate: control.generate,
|
|
42
38
|
give: floor(channelCapacityTokens * reserveRatio),
|
|
43
|
-
to:
|
|
39
|
+
to: target,
|
|
44
40
|
});
|
|
45
41
|
|
|
46
|
-
const destination =
|
|
47
|
-
const height = (await
|
|
42
|
+
const destination = control.id;
|
|
43
|
+
const height = (await getHeight({lnd})).current_block_height;
|
|
48
44
|
const initialBalance = (await getChannelBalance({lnd})).channel_balance;
|
|
49
45
|
const invoice = await createInvoice({lnd});
|
|
50
46
|
const mtokens = '1000';
|
|
@@ -82,7 +78,7 @@ test('Push funds', async ({end, equal}) => {
|
|
|
82
78
|
equal(initialBalance - finalBalance, tokens, 'Funds pushed to peer');
|
|
83
79
|
});
|
|
84
80
|
|
|
85
|
-
await
|
|
81
|
+
await kill({});
|
|
86
82
|
|
|
87
83
|
return end();
|
|
88
84
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
1
2
|
const {test} = require('@alexbosworth/tap');
|
|
2
3
|
|
|
3
4
|
const {createCluster} = require('./../macros');
|
|
@@ -14,36 +15,24 @@ const {waitForPendingChannel} = require('./../macros');
|
|
|
14
15
|
const channelCapacityTokens = 1e6;
|
|
15
16
|
const confirmationCount = 20;
|
|
16
17
|
const defaultFee = 1e3;
|
|
18
|
+
const size = 2;
|
|
17
19
|
const tokens = 1e3;
|
|
18
20
|
|
|
19
21
|
// Rebalancing channels should result in balanced channels
|
|
20
22
|
test('Rebalance', async ({end, equal}) => {
|
|
21
|
-
|
|
23
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
cluster = await createCluster({
|
|
25
|
-
is_circular_enabled: true,
|
|
26
|
-
is_remote_skipped: true,
|
|
27
|
-
});
|
|
28
|
-
} catch (err) {
|
|
29
|
-
cluster = await createCluster({is_remote_skipped: true});
|
|
30
|
-
}
|
|
25
|
+
const [control, target] = nodes;
|
|
31
26
|
|
|
32
|
-
const {lnd} =
|
|
27
|
+
const {generate, lnd} = control;
|
|
33
28
|
|
|
34
|
-
await setupChannel({
|
|
35
|
-
lnd,
|
|
36
|
-
generate: cluster.generate,
|
|
37
|
-
give: 1e5,
|
|
38
|
-
to: cluster.target,
|
|
39
|
-
});
|
|
29
|
+
await setupChannel({generate, lnd, give: 1e5, to: target});
|
|
40
30
|
|
|
41
31
|
await setupChannel({
|
|
42
|
-
generate:
|
|
43
|
-
generator: cluster.target,
|
|
32
|
+
generate: target.generate,
|
|
44
33
|
give: 1e5,
|
|
45
|
-
lnd:
|
|
46
|
-
to:
|
|
34
|
+
lnd: target.lnd,
|
|
35
|
+
to: control,
|
|
47
36
|
});
|
|
48
37
|
|
|
49
38
|
const invoice = await createInvoice({lnd, tokens});
|
|
@@ -53,7 +42,7 @@ test('Rebalance', async ({end, equal}) => {
|
|
|
53
42
|
const {route} = await getRouteToDestination({
|
|
54
43
|
lnd,
|
|
55
44
|
tokens,
|
|
56
|
-
destination:
|
|
45
|
+
destination: control.id,
|
|
57
46
|
outgoing_channel: inChannelId,
|
|
58
47
|
payment: invoice.payment,
|
|
59
48
|
total_mtokens: !!invoice.payment ? invoice.mtokens : undefined,
|
|
@@ -63,7 +52,7 @@ test('Rebalance', async ({end, equal}) => {
|
|
|
63
52
|
|
|
64
53
|
equal(selfPay.secret, invoice.secret, 'Payment made to self');
|
|
65
54
|
|
|
66
|
-
await
|
|
55
|
+
await kill({});
|
|
67
56
|
|
|
68
57
|
return end();
|
|
69
58
|
});
|
|
@@ -1,71 +1,36 @@
|
|
|
1
|
+
const asyncRetry = require('async/retry');
|
|
2
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
1
3
|
const {test} = require('@alexbosworth/tap');
|
|
2
4
|
|
|
3
5
|
const {addPeer} = require('./../../');
|
|
4
|
-
const {connectChainNode} = require('./../macros');
|
|
5
|
-
const {delay} = require('./../macros');
|
|
6
|
-
const {generateBlocks} = require('./../macros');
|
|
7
6
|
const {getPeers} = require('./../../');
|
|
8
|
-
const {getWalletInfo} = require('./../../');
|
|
9
7
|
const {removePeer} = require('./../../');
|
|
10
|
-
const {spawnLnd} = require('./../macros');
|
|
11
|
-
const {waitForTermination} = require('./../macros');
|
|
12
8
|
|
|
13
|
-
const
|
|
9
|
+
const size = 2;
|
|
14
10
|
|
|
15
11
|
// Removing peers should result in a removed peer
|
|
16
12
|
test(`Remove a peer`, async ({end, equal}) => {
|
|
17
|
-
const
|
|
13
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
18
14
|
|
|
19
|
-
const [
|
|
15
|
+
const [{id, lnd}, target] = nodes;
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const host = control.listen_ip;
|
|
24
|
-
const pass = control.chain_rpc_pass;
|
|
25
|
-
const port = control.chain_rpc_port;
|
|
26
|
-
const targetNode = await getWalletInfo({lnd: target.lnd});
|
|
27
|
-
const user = control.chain_rpc_user;
|
|
28
|
-
|
|
29
|
-
await connectChainNode({cert, connect, host, pass, port, user});
|
|
30
|
-
|
|
31
|
-
await control.generate({count: maturityCount});
|
|
32
|
-
|
|
33
|
-
const controlWallet = await getWalletInfo({lnd: control.lnd});
|
|
34
|
-
const targetWallet = await getWalletInfo({lnd: target.lnd});
|
|
35
|
-
|
|
36
|
-
equal(controlWallet.is_synced_to_chain, true, 'Control syncs to chain');
|
|
37
|
-
equal(targetWallet.is_synced_to_chain, true, 'Target syncs to chain');
|
|
38
|
-
|
|
39
|
-
await delay(1000);
|
|
40
|
-
|
|
41
|
-
await addPeer({
|
|
42
|
-
lnd: control.lnd,
|
|
43
|
-
public_key: targetNode.public_key,
|
|
44
|
-
socket: `127.0.0.1:${target.listen_port}`,
|
|
17
|
+
await asyncRetry({interval: 10, times: 2000}, async () => {
|
|
18
|
+
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
45
19
|
});
|
|
46
20
|
|
|
47
|
-
await
|
|
48
|
-
|
|
49
|
-
const {peers} = await getPeers({lnd: control.lnd});
|
|
50
|
-
|
|
51
|
-
await delay(1000);
|
|
21
|
+
const {peers} = await getPeers({lnd});
|
|
52
22
|
|
|
53
23
|
const [targetPeer] = peers;
|
|
54
24
|
|
|
55
|
-
equal(targetPeer.public_key,
|
|
56
|
-
|
|
57
|
-
await removePeer({lnd: control.lnd, public_key: targetPeer.public_key});
|
|
58
|
-
|
|
59
|
-
await delay(1000);
|
|
25
|
+
equal(targetPeer.public_key, target.id, 'Peer is added');
|
|
60
26
|
|
|
61
|
-
|
|
27
|
+
await removePeer({lnd, public_key: targetPeer.public_key});
|
|
62
28
|
|
|
63
|
-
|
|
29
|
+
const postRemovalPeers = await getPeers({lnd});
|
|
64
30
|
|
|
65
|
-
|
|
31
|
+
equal(postRemovalPeers.peers.length, [].length, 'Peer is removed');
|
|
66
32
|
|
|
67
|
-
await
|
|
68
|
-
await waitForTermination({lnd: target.lnd});
|
|
33
|
+
await kill({});
|
|
69
34
|
|
|
70
35
|
return end();
|
|
71
36
|
});
|
|
@@ -1,65 +1,73 @@
|
|
|
1
1
|
const asyncRetry = require('async/retry');
|
|
2
|
+
const {spawnLightningCluster} = require('ln-docker-daemons');
|
|
2
3
|
const {test} = require('@alexbosworth/tap');
|
|
3
4
|
|
|
4
|
-
const {
|
|
5
|
+
const {addPeer} = require('./../../');
|
|
5
6
|
const {sendMessageToPeer} = require('./../../');
|
|
6
7
|
const {subscribeToPeerMessages} = require('./../../');
|
|
7
8
|
|
|
8
9
|
const interval = 10;
|
|
10
|
+
const size = 2;
|
|
9
11
|
const times = 1000;
|
|
10
12
|
|
|
11
13
|
// Sending a message to a peer should result in the message received
|
|
12
14
|
test(`Send peer message`, async ({end, equal, strictSame}) => {
|
|
13
|
-
const
|
|
15
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
14
16
|
|
|
15
|
-
const {lnd} =
|
|
17
|
+
const [{id, lnd}, target] = nodes;
|
|
16
18
|
|
|
17
19
|
try {
|
|
18
20
|
await sendMessageToPeer({
|
|
19
21
|
lnd,
|
|
20
22
|
message: Buffer.from('message').toString('hex'),
|
|
21
|
-
public_key:
|
|
23
|
+
public_key: target.id,
|
|
22
24
|
});
|
|
23
25
|
} catch (err) {
|
|
24
26
|
const [code] = err;
|
|
25
27
|
|
|
26
28
|
// Send message to peer is not supported on LND 0.13.4 or lower
|
|
27
29
|
if (code === 501) {
|
|
28
|
-
await
|
|
30
|
+
await kill({});
|
|
29
31
|
|
|
30
32
|
return end();
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
await asyncRetry({interval, times}, async () => {
|
|
37
|
+
await addPeer({lnd, public_key: target.id, socket: target.socket});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const sub = subscribeToPeerMessages({lnd: target.lnd});
|
|
35
41
|
|
|
36
42
|
const messages = [];
|
|
37
43
|
|
|
38
44
|
sub.on('message_received', message => messages.push(message));
|
|
39
45
|
|
|
40
|
-
await sendMessageToPeer({
|
|
41
|
-
lnd,
|
|
42
|
-
message: Buffer.from('message').toString('hex'),
|
|
43
|
-
public_key: cluster.target.public_key,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
46
|
await asyncRetry({interval, times}, async () => {
|
|
47
|
+
await sendMessageToPeer({
|
|
48
|
+
lnd,
|
|
49
|
+
message: Buffer.from('message').toString('hex'),
|
|
50
|
+
public_key: target.id,
|
|
51
|
+
});
|
|
52
|
+
|
|
47
53
|
if (!messages.length) {
|
|
48
54
|
throw new Error('ExpectedMessage');
|
|
49
55
|
}
|
|
50
56
|
});
|
|
51
57
|
|
|
58
|
+
const [message] = messages;
|
|
59
|
+
|
|
52
60
|
strictSame(
|
|
53
|
-
|
|
54
|
-
|
|
61
|
+
message,
|
|
62
|
+
{
|
|
55
63
|
message: Buffer.from('message').toString('hex'),
|
|
56
|
-
public_key:
|
|
64
|
+
public_key: id,
|
|
57
65
|
type: 32768,
|
|
58
|
-
}
|
|
66
|
+
},
|
|
59
67
|
'Message successfully sent to peer'
|
|
60
68
|
);
|
|
61
69
|
|
|
62
|
-
await
|
|
70
|
+
await kill({});
|
|
63
71
|
|
|
64
72
|
return end();
|
|
65
73
|
});
|