ln-service 52.16.1 → 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.
Files changed (119) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -8
  3. package/package.json +4 -12
  4. package/test/autopilotrpc-integration/test_autopilot.js +9 -15
  5. package/test/chainrpc-integration/test_get_height.js +7 -10
  6. package/test/chainrpc-integration/test_subscribe_to_blocks.js +52 -31
  7. package/test/chainrpc-integration/test_subscribe_to_chain_address.js +72 -66
  8. package/test/chainrpc-integration/test_subscribe_to_chain_spend.js +47 -16
  9. package/test/{integration → extra-integration}/test_recover_funds_from_channel.js +0 -0
  10. package/test/{integration → extra-integration}/test_recover_funds_from_channels.js +0 -0
  11. package/test/{integration → extra-integration}/test_restrict_macaroon.js +0 -0
  12. package/test/{integration → extra-integration}/test_revoke_access.js +0 -0
  13. package/test/{integration → extra-integration}/test_subscribe_to_rpc_requests.js +1 -1
  14. package/test/integration/test_add_peer.js +16 -12
  15. package/test/integration/test_cancel_pending_channel.js +20 -6
  16. package/test/integration/test_close_channel.js +15 -10
  17. package/test/integration/test_create_chain_address.js +3 -6
  18. package/test/integration/test_create_invoice.js +27 -23
  19. package/test/integration/test_decode_payment_request.js +30 -29
  20. package/test/integration/test_delete_payment.js +11 -8
  21. package/test/integration/test_delete_payments.js +13 -16
  22. package/test/integration/test_get_access_ids.js +4 -7
  23. package/test/integration/test_get_backup.js +12 -8
  24. package/test/integration/test_get_backups.js +8 -10
  25. package/test/integration/test_get_chain_balance.js +9 -53
  26. package/test/integration/test_get_chain_fee_estimate.js +21 -10
  27. package/test/integration/test_get_chain_transactions.js +30 -52
  28. package/test/integration/test_get_channel.js +7 -7
  29. package/test/integration/test_get_channel_balance.js +5 -6
  30. package/test/integration/test_get_channels.js +11 -10
  31. package/test/integration/test_get_closed_channels.js +169 -139
  32. package/test/integration/test_get_failed_payments.js +36 -39
  33. package/test/integration/test_get_fee_rates.js +6 -9
  34. package/test/integration/test_get_forwards.js +34 -35
  35. package/test/integration/test_get_invoice.js +7 -11
  36. package/test/integration/test_get_invoices.js +33 -30
  37. package/test/integration/test_get_methods.js +4 -7
  38. package/test/integration/test_get_network_centrality.js +14 -17
  39. package/test/integration/test_get_network_graph.js +12 -15
  40. package/test/integration/test_get_network_info.js +5 -6
  41. package/test/integration/test_get_node.js +15 -31
  42. package/test/integration/test_get_payments.js +10 -10
  43. package/test/integration/test_get_peers.js +10 -13
  44. package/test/integration/test_get_pending_coop.js +13 -18
  45. package/test/integration/test_get_pending_force.js +29 -21
  46. package/test/integration/test_get_route_to_destination.js +47 -40
  47. package/test/integration/test_get_utxos.js +17 -42
  48. package/test/integration/test_get_wallet_info.js +5 -12
  49. package/test/integration/test_open_channel.js +16 -9
  50. package/test/integration/test_open_channels.js +66 -66
  51. package/test/integration/test_pay.js +39 -36
  52. package/test/integration/test_pay_private_invoice.js +78 -71
  53. package/test/integration/test_payment_errors.js +13 -11
  54. package/test/integration/test_propose_channel.js +74 -53
  55. package/test/integration/test_push_funds.js +11 -15
  56. package/test/integration/test_rebalance.js +11 -22
  57. package/test/integration/test_remove_peer.js +13 -48
  58. package/test/integration/test_send_message_to_peer.js +20 -14
  59. package/test/integration/test_send_to_chain_address.js +60 -51
  60. package/test/integration/test_send_to_chain_addresses.js +30 -18
  61. package/test/integration/test_sign_message.js +3 -6
  62. package/test/integration/test_stop_daemon.js +3 -9
  63. package/test/integration/test_subscribe_to_backups.js +19 -11
  64. package/test/integration/test_subscribe_to_channels.js +28 -20
  65. package/test/integration/test_subscribe_to_graph.js +43 -22
  66. package/test/integration/test_subscribe_to_invoices.js +89 -103
  67. package/test/integration/test_subscribe_to_open_requests.js +47 -31
  68. package/test/integration/test_subscribe_to_peer_messages.js +51 -21
  69. package/test/integration/test_subscribe_to_peers.js +11 -16
  70. package/test/integration/test_subscribe_to_transactions.js +49 -45
  71. package/test/integration/test_update_routing_fees.js +12 -16
  72. package/test/integration/test_verify_access.js +5 -10
  73. package/test/integration/test_verify_backup.js +10 -8
  74. package/test/integration/test_verify_backups.js +11 -16
  75. package/test/integration/test_verify_message.js +6 -9
  76. package/test/invoicesrpc-integration/test_cancel_invoice.js +15 -22
  77. package/test/invoicesrpc-integration/test_get_sweep_transactions.js +15 -11
  78. package/test/invoicesrpc-integration/test_push_payment.js +53 -55
  79. package/test/invoicesrpc-integration/test_settle_invoice.js +25 -19
  80. package/test/invoicesrpc-integration/test_subscribe_cancel_invoice.js +13 -11
  81. package/test/invoicesrpc-integration/test_subscribe_settle_invoice.js +20 -15
  82. package/test/macros/change_password.js +14 -12
  83. package/test/macros/generate_blocks.js +23 -28
  84. package/test/macros/rpc.js +1 -0
  85. package/test/macros/setup_channel.js +23 -9
  86. package/test/macros/spawn_lnd.js +2 -0
  87. package/test/macros/wait_for_channel.js +8 -3
  88. package/test/macros/wait_for_route.js +2 -2
  89. package/test/routerrpc-integration/test_delete_forwarding_reputations.js +15 -22
  90. package/test/routerrpc-integration/test_disable_channel.js +8 -12
  91. package/test/routerrpc-integration/test_get_forwarding_confidence.js +17 -37
  92. package/test/routerrpc-integration/test_get_forwarding_reputations.js +26 -23
  93. package/test/routerrpc-integration/test_get_pathfinding_settings.js +6 -12
  94. package/test/routerrpc-integration/test_get_payment.js +19 -26
  95. package/test/routerrpc-integration/test_get_route_confidence.js +15 -21
  96. package/test/routerrpc-integration/test_get_route_through_hops.js +29 -32
  97. package/test/routerrpc-integration/test_multipath_payment.js +18 -20
  98. package/test/routerrpc-integration/test_pay_via_payment_details.js +19 -34
  99. package/test/routerrpc-integration/test_pay_via_payment_request.js +17 -27
  100. package/test/routerrpc-integration/test_pay_via_routes.js +37 -37
  101. package/test/routerrpc-integration/test_probe_for_route.js +27 -33
  102. package/test/routerrpc-integration/test_subscribe_to_forward_requests.js +39 -44
  103. package/test/routerrpc-integration/test_subscribe_to_forwards.js +83 -77
  104. package/test/routerrpc-integration/test_subscribe_to_past_payments.js +34 -28
  105. package/test/routerrpc-integration/test_update_pathfinding_settings.js +7 -10
  106. package/test/signerrpc-integration/test_diffie_hellman_compute_secret.js +15 -14
  107. package/test/signerrpc-integration/test_sign_bytes.js +11 -15
  108. package/test/signerrpc-integration/test_sign_transaction.js +6 -7
  109. package/test/signerrpc-integration/test_verify_bytes_signature.js +11 -12
  110. package/test/versionrpc-integration/test_get_wallet_version.js +6 -7
  111. package/test/walletrpc-integration/test_fund_psbt.js +13 -12
  112. package/test/walletrpc-integration/test_get_chain_fee_rate.js +4 -8
  113. package/test/walletrpc-integration/test_get_locked_utxos.js +11 -27
  114. package/test/walletrpc-integration/test_get_public_key.js +5 -13
  115. package/test/walletrpc-integration/test_lock_utxo.js +16 -23
  116. package/test/walletrpc-integration/test_send_to_chain_output_scripts.js +25 -6
  117. package/test/walletrpc-integration/test_sign_psbt.js +28 -19
  118. package/test/walletrpc-integration/test_unlock_utxo.js +16 -27
  119. package/test/walletrpc-integration/test_update_chain_transaction.js +6 -31
@@ -1,4 +1,5 @@
1
1
  const asyncRetry = require('async/retry');
2
+ const {spawnLightningCluster} = require('ln-docker-daemons');
2
3
  const {test} = require('@alexbosworth/tap');
3
4
 
4
5
  const {closeChannel} = require('./../../');
@@ -19,30 +20,34 @@ const {sendToChainAddress} = require('./../../');
19
20
  const {settleHodlInvoice} = require('./../../');
20
21
  const {setupChannel} = require('./../macros');
21
22
  const {subscribeToInvoice} = require('./../../');
23
+ const {subscribeToPayViaRequest} = require('./../../');
22
24
 
23
25
  const all = promise => Promise.all(promise);
24
26
  const confirmationCount = 6;
25
27
  const defaultFee = 1e3;
26
28
  const interval = 125;
27
29
  const maxChanTokens = Math.pow(2, 24) - 1;
30
+ const size = 2;
28
31
  const times = 1000;
29
32
 
30
33
  // Getting closed channels should return closed channels
31
34
  test(`Get closed channels`, async ({end, equal}) => {
32
- const cluster = await createCluster({is_remote_skipped: true});
35
+ const {kill, nodes} = await spawnLightningCluster({size});
33
36
 
34
- const {lnd} = cluster.control;
37
+ const [control, target] = nodes;
38
+
39
+ const {generate, lnd} = control;
35
40
 
36
41
  const channelOpen = await setupChannel({
42
+ generate,
37
43
  lnd,
38
44
  capacity: maxChanTokens,
39
- generate: cluster.generate,
40
45
  partner_csv_delay: 20,
41
- to: cluster.target,
46
+ to: target,
42
47
  });
43
48
 
44
49
  const closing = await closeChannel({
45
- lnd: cluster.control.lnd,
50
+ lnd,
46
51
  tokens_per_vbyte: defaultFee,
47
52
  transaction_id: channelOpen.transaction_id,
48
53
  transaction_vout: channelOpen.transaction_vout,
@@ -54,7 +59,7 @@ test(`Get closed channels`, async ({end, equal}) => {
54
59
 
55
60
  // Wait for channel to close
56
61
  await asyncRetry({interval, times}, async () => {
57
- await cluster.generate({});
62
+ await generate({});
58
63
 
59
64
  const {channels} = await getClosedChannels({lnd});
60
65
 
@@ -63,46 +68,43 @@ test(`Get closed channels`, async ({end, equal}) => {
63
68
  }
64
69
  });
65
70
 
66
- const {channels} = await getClosedChannels({lnd: cluster.control.lnd});
71
+ const {channels} = await getClosedChannels({lnd});
67
72
 
68
73
  const [channel] = channels;
69
74
 
70
75
  equal(channels.length, [channelOpen].length, 'Channel close listed');
71
76
 
72
- if (!!channel) {
73
- // LND 0.11.1 and below do not use anchors
74
- if (isAnchors) {
75
- equal(maxChanTokens - channel.final_local_balance, 2810, 'Final');
76
- } else {
77
- equal(maxChanTokens - channel.final_local_balance, 9050, 'Final');
78
- }
79
-
80
- equal(channel.capacity, maxChanTokens, 'Channel capacity reflected');
81
- equal(!!channel.close_confirm_height, true, 'Channel close height');
82
- equal(channel.close_transaction_id, closing.transaction_id, 'Close tx id');
83
- equal(channel.final_time_locked_balance, 0, 'Final locked balance');
84
- equal(!!channel.id, true, 'Channel id');
85
- equal(channel.is_breach_close, false, 'Not breach close');
86
- equal(channel.is_cooperative_close, true, 'Is cooperative close');
87
- equal(channel.is_funding_cancel, false, 'Not funding cancel');
88
- equal(channel.is_local_force_close, false, 'Not local force close');
89
- equal(channel.is_remote_force_close, false, 'Not remote force close');
90
- equal(channel.partner_public_key, cluster.target_node_public_key, 'Pubkey');
91
- equal(channel.transaction_id, channelOpen.transaction_id, 'Channel tx id');
92
- equal(channel.transaction_vout, channelOpen.transaction_vout, 'Chan vout');
77
+ // LND 0.11.1 and below do not use anchors
78
+ if (isAnchors) {
79
+ equal(maxChanTokens - channel.final_local_balance, 2810, 'Final');
80
+ } else {
81
+ equal(maxChanTokens - channel.final_local_balance, 9050, 'Final');
93
82
  }
94
83
 
84
+ equal(channel.capacity, maxChanTokens, 'Channel capacity reflected');
85
+ equal(!!channel.close_confirm_height, true, 'Channel close height');
86
+ equal(channel.close_transaction_id, closing.transaction_id, 'Close tx id');
87
+ equal(channel.final_time_locked_balance, 0, 'Final locked balance');
88
+ equal(!!channel.id, true, 'Channel id');
89
+ equal(channel.is_breach_close, false, 'Not breach close');
90
+ equal(channel.is_cooperative_close, true, 'Is cooperative close');
91
+ equal(channel.is_funding_cancel, false, 'Not funding cancel');
92
+ equal(channel.is_local_force_close, false, 'Not local force close');
95
93
  equal(channel.is_partner_closed, false, 'Partner did not close the chan');
96
94
  equal(channel.is_partner_initiated, false, 'Partner did not open channel');
95
+ equal(channel.is_remote_force_close, false, 'Not remote force close');
96
+ equal(channel.partner_public_key, target.id, 'Pubkey');
97
+ equal(channel.transaction_id, channelOpen.transaction_id, 'Channel tx id');
98
+ equal(channel.transaction_vout, channelOpen.transaction_vout, 'Chan vout');
97
99
 
98
100
  // Setup a force close to show force close channel output
99
101
  const toForceClose = await setupChannel({
102
+ generate,
100
103
  lnd,
101
104
  capacity: 7e5,
102
- generate: cluster.generate,
103
105
  give: 3e5,
104
106
  partner_csv_delay: 20,
105
- to: cluster.target,
107
+ to: target,
106
108
  });
107
109
 
108
110
  const cancelInvoice = await createHodlInvoice({
@@ -111,141 +113,169 @@ test(`Get closed channels`, async ({end, equal}) => {
111
113
  tokens: 1e5,
112
114
  });
113
115
 
114
- const claimInvoice = await createHodlInvoice({
116
+ const settleInvoice = await createHodlInvoice({
115
117
  lnd,
116
- cltv_delta: 18,
118
+ cltv_delta: 144,
117
119
  tokens: 1e5,
118
120
  });
119
121
 
120
- [cancelInvoice, claimInvoice].forEach(({request}) => {
121
- return payViaPaymentRequest({request, lnd: cluster.target.lnd}, () => {});
122
- });
122
+ const subCancelInvoice = subscribeToInvoice({lnd, id: cancelInvoice.id});
123
+ const subSettleInvoice = subscribeToInvoice({lnd, id: settleInvoice.id});
123
124
 
124
- const waitForHold = id => new Promise((resolve, reject) => {
125
- const subInvoice = subscribeToInvoice({id, lnd});
125
+ const cancelInvoiceUpdates = [];
126
+ const settleInvoiceUpdates = [];
126
127
 
127
- subInvoice.on('invoice_updated', n => !n.is_held ? null : resolve());
128
+ subCancelInvoice.on('invoice_updated', n => cancelInvoiceUpdates.push(n));
129
+ subSettleInvoice.on('invoice_updated', n => settleInvoiceUpdates.push(n));
128
130
 
129
- return;
131
+ // Kick off a payment to the cancel invoice
132
+ const payToCancel = subscribeToPayViaRequest({
133
+ lnd: target.lnd,
134
+ request: cancelInvoice.request,
130
135
  });
131
136
 
132
- await all([cancelInvoice, claimInvoice].map(({id}) => waitForHold(id)));
133
-
134
- await closeChannel({
135
- lnd,
136
- is_force_close: true,
137
- transaction_id: toForceClose.transaction_id,
138
- transaction_vout: toForceClose.transaction_vout,
137
+ // Kick off a payment to the settle invoice
138
+ const payToSettle = subscribeToPayViaRequest({
139
+ lnd: target.lnd,
140
+ request: settleInvoice.request,
139
141
  });
140
142
 
141
- await settleHodlInvoice({lnd, secret: claimInvoice.secret});
142
-
143
- // LND 0.12.0 requires a delay before sweeps start
144
- await delay(1000 * 35);
145
-
146
- // Wait for channel to close
147
143
  await asyncRetry({interval, times}, async () => {
148
- const closedChannels = await getClosedChannels({lnd});
149
-
150
- await cluster.generate({count: 1});
151
-
152
- if (closedChannels.channels.length < 2) {
153
- throw new Error('ExpectedClosedChannel');
144
+ if (!cancelInvoiceUpdates.filter(n => !!n.is_held).length) {
145
+ throw new Error('WaitingForLockToCancelInvoice');
154
146
  }
155
- });
156
147
 
157
- const targetChannels = await getClosedChannels({lnd: cluster.target.lnd});
158
-
159
- const [, control] = (await getClosedChannels({lnd})).channels;
160
-
161
- // Wait for target channel
162
- await asyncRetry({interval, times}, async () => {
163
- const targetChans = await getClosedChannels({lnd: cluster.target.lnd});
164
-
165
- if (targetChans.channels.length < 2) {
166
- throw new Error('ExpectedClosedTargetChannel');
148
+ if (!settleInvoiceUpdates.filter(n => !!n.is_held).length) {
149
+ throw new Error('WaitingForLockToSettleInvoice');
167
150
  }
168
- });
169
151
 
170
- const [, target] = targetChannels.channels;
152
+ // Push the held HTLCs to chain
153
+ await closeChannel({
154
+ lnd: target.lnd,
155
+ is_force_close: true,
156
+ transaction_id: toForceClose.transaction_id,
157
+ transaction_vout: toForceClose.transaction_vout,
158
+ });
159
+ });
171
160
 
172
- equal(control.close_balance_vout !== undefined, true, 'Has balance vout');
173
- equal(!!control.close_balance_spent_by, true, 'Has close balance spend');
174
- equal(control.close_payments.length, 3, 'Has all close payments');
161
+ // Use the preimage to sweep the settle invoice on chain
162
+ await settleHodlInvoice({lnd, secret: settleInvoice.secret});
175
163
 
176
- if (!!target) {
177
- equal(target.close_balance_vout !== undefined, true, 'target vout coins');
178
- equal(!!target.close_balance_spent_by, true, 'Target close balance spend');
179
- equal(target.close_payments.length, 2, 'Target close payments present');
180
- }
164
+ // LND 0.12.0 requires a delay before sweeps start
165
+ const deadChans = await asyncRetry({interval: 1000, times: 99}, async () => {
166
+ const {channels} = await getClosedChannels({lnd});
181
167
 
182
- const controlCloseId = control.close_transaction_id;
168
+ if (channels.length === [toForceClose, channelOpen].length) {
169
+ return channels;
170
+ }
183
171
 
184
- const controlTimedOut = control.close_payments.find(n => n.is_refunded);
185
- const controlPending = control.close_payments.find(n => n.is_pending);
172
+ await target.generate({});
173
+ await generate({});
186
174
 
187
- const controlPaid = control.close_payments.find(payment => {
188
- return payment.transaction_id === controlPending.spent_by;
175
+ throw new Error('WaitingForForceClose');
189
176
  });
190
177
 
191
- // LND 0.11.1 and below do not use anchors
192
- if (!isAnchors) {
193
- equal(controlTimedOut.tokens, 91213, 'Timed out has token count');
194
- equal(controlTimedOut.is_outgoing, false, 'Timeout is incoming payment');
195
- equal(controlTimedOut.is_paid, false, 'Timed out payment is not paid');
196
- equal(controlTimedOut.is_pending, false, 'Timed out payment is not paid');
197
- equal(controlTimedOut.is_refunded, true, 'Timed out payment is refunded');
198
- equal(controlTimedOut.spent_by, undefined, 'Timed out has no spent by');
199
- equal(!!controlTimedOut.transaction_id, true, 'Timed out has tx id');
200
- equal(controlTimedOut.transaction_vout !== undefined, true, 'Refund vout');
201
- }
178
+ const forced = deadChans.find(n => !!n.is_remote_force_close);
179
+
180
+ equal(forced.capacity, 7e5, 'Got force close capacity');
181
+ equal(!!forced.close_balance_spent_by, true, 'Got a spend id');
182
+ equal(forced.close_balance_vout !== undefined, true, 'Got a spend vout');
183
+ equal(!!forced.close_confirm_height !== undefined, true, 'Confirm height');
184
+ equal(forced.close_payments.length, 2, '2 pending payments');
185
+ equal(!!forced.close_transaction_id, true, 'Got closed tx id');
186
+ equal(!!forced.final_local_balance, true, 'Got final balance');
187
+ equal(forced.final_time_locked_balance, 0, 'Got timelock balance');
188
+ equal(forced.id, toForceClose.id, 'Got closed channel id');
189
+ equal(forced.is_breach_close, false, 'Not a breach');
190
+ equal(forced.is_cooperative_close, false, 'Not a coop close');
191
+ equal(forced.is_funding_cancel, false, 'Not a cancel');
192
+ equal(forced.is_local_force_close, false, 'Not a local force close');
193
+ equal(forced.is_partner_closed, true, 'The remote closed');
194
+ equal(forced.is_partner_initiated, false, 'Local initiated');
195
+ equal(forced.is_remote_force_close, true, 'Remote force closed');
196
+ equal(forced.partner_public_key, target.id, 'Got remote public key');
197
+ equal(forced.transaction_id, toForceClose.transaction_id, 'Got txid');
198
+ equal(forced.transaction_vout, toForceClose.transaction_vout, 'Got vout');
199
+
200
+ const cancelHtlc = forced.close_payments.find(n => !n.is_paid);
201
+
202
+ equal(cancelHtlc.is_outgoing, false, 'HTLC is incoming');
203
+ equal(cancelHtlc.is_paid, false, 'HTLC is not settled');
204
+ equal(cancelHtlc.is_pending, false, 'HTLC cannot be settled');
205
+ equal(cancelHtlc.is_refunded, false, 'HTLC has not been refunded');
206
+ equal(cancelHtlc.spent_by, undefined, 'HTLC has no sweep tx');
207
+ equal(cancelHtlc.tokens, 1e5, 'HTLC has invoice value');
208
+ equal(!!cancelHtlc.transaction_id, true, 'HTLC has tx id');
209
+ equal(cancelHtlc.transaction_vout !== undefined, true, 'HTLC has tx vout');
210
+
211
+ const settleHtlc = forced.close_payments.find(n => !!n.is_paid);
212
+
213
+ equal(settleHtlc.is_outgoing, false, 'Settle is incoming');
214
+ equal(settleHtlc.is_paid, true, 'Settle is paid');
215
+ equal(settleHtlc.is_pending, false, 'Already settled');
216
+ equal(settleHtlc.is_refunded, false, 'No refund available');
217
+ equal(!!settleHtlc.spent_by, true, 'Swept with preimage tx');
218
+ equal(settleHtlc.tokens, 1e5, 'Settled with invoice value');
219
+ equal(!!settleHtlc.transaction_id, true, 'Output tx id');
220
+ equal(settleHtlc.transaction_vout !== undefined, true, 'Output tx vout');
221
+
222
+ const alsoDead = await asyncRetry({interval: 2000, times: 99}, async () => {
223
+ const {channels} = await getClosedChannels({lnd: target.lnd});
224
+
225
+ if (channels.length === [toForceClose, channelOpen].length) {
226
+ return channels;
227
+ }
202
228
 
203
- equal(controlPending.is_outgoing, false, 'Pending is incoming payment');
204
- equal(controlPending.is_paid, false, 'Pending is not yet paid');
205
- equal(controlPending.is_pending, true, 'Pending is marked pending');
206
- equal(controlPending.is_refunded, false, 'Pending is not marked refunded');
207
- equal(!!controlPending.spent_by, true, 'Pending has spent by');
208
- equal(controlPending.tokens, 100000, 'Pending payment has tokens');
209
- equal(controlPending.transaction_id, controlCloseId, 'Pending off close');
210
- equal(controlPending.transaction_vout !== undefined, true, 'Pending vout');
229
+ await target.generate({count: 100});
211
230
 
212
- // LND 0.11.1 and below do not use anchors
213
- if (!isAnchors) {
214
- equal(controlTimedOut.tokens, 91213, 'Paid payment has token count');
215
- }
231
+ throw new Error('WaitingForTargetForceClose');
232
+ });
216
233
 
217
- equal(controlPaid.is_outgoing, false, 'Paid is incoming payment');
218
- equal(controlPaid.is_paid, true, 'Paid payment is paid');
219
- equal(controlPaid.is_pending, false, 'Paid payment is not pending');
220
- equal(controlPaid.is_refunded, false, 'Paid payment is not refunded');
221
- equal(!!controlPaid.spent_by, true, 'Paid payment has spent by');
222
- equal(!!controlPaid.transaction_id, true, 'Paid payment has tx id');
223
- equal(controlPaid.transaction_vout !== undefined, true, 'Paid tx vout');
224
-
225
- const targetCloseId = target.close_transaction_id;
226
-
227
- const targetTimedOut = target.close_payments.find(n => n.is_refunded);
228
- const targetPaid = target.close_payments.find(n => n.is_paid);
229
-
230
- equal(targetTimedOut.is_outgoing, true, 'Target refund is outgoing');
231
- equal(targetTimedOut.is_paid, false, 'Target refund is not paid');
232
- equal(targetTimedOut.is_pending, false, 'Target refund is not pending');
233
- equal(targetTimedOut.is_refunded, true, 'Target refund is refunded');
234
- equal(!!targetTimedOut.spent_by, true, 'Target refund has spent by');
235
- equal(targetTimedOut.tokens, 100000, 'Target refund has tokens');
236
- equal(targetTimedOut.transaction_id, targetCloseId, 'Target refund spend');
237
- equal(targetTimedOut.transaction_vout !== undefined, true, 'T Refund vout');
238
-
239
- equal(targetPaid.is_outgoing, true, 'Target paid is outgoing');
240
- equal(targetPaid.is_paid, true, 'Target paid is not paid');
241
- equal(targetPaid.is_pending, false, 'Target paid is not pending');
242
- equal(targetPaid.is_refunded, false, 'Target paid is refunded');
243
- equal(!!targetPaid.spent_by, true, 'Target paid has spent by');
244
- equal(targetPaid.tokens, 100000, 'Target paid has tokens');
245
- equal(targetPaid.transaction_id, targetCloseId, 'Target paid spend');
246
- equal(targetPaid.transaction_vout !== undefined, true, 'Target paid vout');
247
-
248
- await cluster.kill({});
234
+ const forceClosed = alsoDead.find(n => !!n.is_local_force_close);
235
+
236
+ equal(forceClosed.capacity, 7e5, 'Target capacity reflected');
237
+ equal(!!forceClosed.close_balance_spent_by, true, 'Target spent by');
238
+ equal(forceClosed.close_balance_vout !== undefined, true, 'Has balance out');
239
+ equal(!!forceClosed.close_confirm_height, true, 'Has confirm height');
240
+ equal(!!forceClosed.close_payments.length, true, 'Has close payments');
241
+ equal(!!forceClosed.close_transaction_id, true, 'Has close id');
242
+ equal(forceClosed.final_local_balance, 1e5, 'Has local balance');
243
+ equal(forceClosed.final_time_locked_balance, 3e5, 'Has timelock balance');
244
+ equal(forceClosed.id, toForceClose.id, 'Has channel id');
245
+ equal(forceClosed.is_breach_close, false, 'Not breach close');
246
+ equal(forceClosed.is_cooperative_close, false, 'Not coop close');
247
+ equal(forceClosed.is_funding_cancel, false, 'Not funding cancel');
248
+ equal(forceClosed.is_local_force_close, true, 'Locally forced closed');
249
+ equal(forceClosed.is_partner_closed, false, 'Not remote closed');
250
+ equal(forceClosed.is_partner_initiated, true, 'Remote created channel');
251
+ equal(forceClosed.is_remote_force_close, false, 'Remote not force closed');
252
+ equal(forceClosed.partner_public_key, control.id, 'Got peer key');
253
+ equal(forceClosed.transaction_id, toForceClose.transaction_id, 'Got tx id');
254
+ equal(forceClosed.transaction_vout, toForceClose.transaction_vout, 'Vout');
255
+
256
+ const forcePay = forceClosed.close_payments.find(n => !!n.is_paid);
257
+
258
+ equal(forcePay.is_outgoing, true, 'Payment was outgoing');
259
+ equal(forcePay.is_paid, true, 'Payment was sent');
260
+ equal(forcePay.is_pending, false, 'Payment is settled');
261
+ equal(forcePay.is_refunded, false, 'Payment completed successfully');
262
+ equal(!!forcePay.spent_by, true, 'Payment was swept with preimage');
263
+ equal(forcePay.tokens, 1e5, 'Payment tokens amount');
264
+ equal(!!forcePay.transaction_id, true, 'Got payment transaction id');
265
+ equal(forcePay.transaction_vout !== undefined, true, 'Got payment vout');
266
+
267
+ const refundedHtlc = forceClosed.close_payments.find(n => !!n.is_refunded);
268
+
269
+ equal(refundedHtlc.is_outgoing, true, 'Payment was outgoing');
270
+ equal(refundedHtlc.is_paid, false, 'Payment was not paid');
271
+ equal(refundedHtlc.is_pending, false, 'Payment is resolved back');
272
+ equal(refundedHtlc.is_refunded, true, 'Payment refunded successfully');
273
+ equal(!!refundedHtlc.spent_by, true, 'Payment was swept with preimage');
274
+ equal(refundedHtlc.tokens, 1e5, 'Payment refund tokens amount');
275
+ equal(!!refundedHtlc.transaction_id, true, 'Got refund transaction id');
276
+ equal(refundedHtlc.transaction_vout !== undefined, true, 'Got refund vout');
277
+
278
+ await kill({});
249
279
 
250
280
  return end();
251
281
  });
@@ -1,11 +1,13 @@
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
6
  const {createChainAddress} = require('./../../');
5
7
  const {createCluster} = require('./../macros');
6
8
  const {createInvoice} = require('./../../');
7
- const {delay} = require('./../macros');
8
9
  const {deleteForwardingReputations} = require('./../../');
10
+ const {getChainBalance} = require('./../../');
9
11
  const {getFailedPayments} = require('./../../');
10
12
  const {getPayment} = require('./../../');
11
13
  const {getPayments} = require('./../../');
@@ -15,56 +17,53 @@ const {setupChannel} = require('./../macros');
15
17
 
16
18
  const channelCapacityTokens = 1e6;
17
19
  const confirmationCount = 20;
20
+ const count = 100;
21
+ const size = 3;
22
+ const times = 1000;
18
23
  const tokens = 1e6 / 2;
19
24
 
20
25
  // Getting failed payments should return failed payments
21
26
  test('Get failed payments', async ({end, equal, strictSame}) => {
22
- const cluster = await createCluster({});
27
+ const {kill, nodes} = await spawnLightningCluster({size});
23
28
 
24
- const {lnd} = cluster.control;
29
+ const [{generate, lnd}, target, remote] = nodes;
25
30
 
26
- const {address} = await createChainAddress({
27
- format: 'p2wpkh',
28
- lnd: cluster.remote.lnd,
29
- });
31
+ const {address} = await createChainAddress({lnd: remote.lnd});
32
+
33
+ await generate({count});
30
34
 
31
35
  // Send coins to remote so that it can accept the channel
32
- await sendToChainAddress({lnd, address, tokens: channelCapacityTokens})
36
+ await sendToChainAddress({lnd, address, tokens: channelCapacityTokens});
37
+
33
38
  // Generate to confirm the tx
34
- await cluster.generate({count: confirmationCount, node: cluster.control});
35
- await cluster.generate({count: confirmationCount, node: cluster.remote});
39
+ await generate({count: confirmationCount});
40
+ await remote.generate({count: confirmationCount});
36
41
 
37
42
  await setupChannel({
43
+ generate,
38
44
  lnd,
39
45
  capacity: channelCapacityTokens + channelCapacityTokens,
40
- generate: cluster.generate,
41
- to: cluster.target,
46
+ to: target,
42
47
  });
43
48
 
44
49
  await setupChannel({
45
50
  capacity: channelCapacityTokens,
46
- lnd: cluster.target.lnd,
47
- generate: cluster.generate,
48
- generator: cluster.target,
51
+ lnd: target.lnd,
52
+ generate: target.generate,
53
+ generator: target,
49
54
  give: Math.round(channelCapacityTokens / 2),
50
- to: cluster.remote,
55
+ to: remote,
51
56
  });
52
57
 
53
- await addPeer({
54
- lnd,
55
- public_key: cluster.remote.public_key,
56
- socket: cluster.remote.socket,
57
- });
58
+ await addPeer({lnd, public_key: remote.id, socket: remote.socket});
58
59
 
59
- const invoice = await createInvoice({tokens, lnd: cluster.remote.lnd});
60
+ const invoice = await createInvoice({tokens, lnd: remote.lnd});
60
61
 
61
62
  const bigInvoice = await createInvoice({
62
63
  tokens: (channelCapacityTokens / 2) + (channelCapacityTokens / 4),
63
- lnd: cluster.remote.lnd,
64
+ lnd: remote.lnd,
64
65
  });
65
66
 
66
- await delay(1000);
67
-
68
67
  try {
69
68
  await pay({lnd, request: bigInvoice.request});
70
69
  } catch (err) {
@@ -73,26 +72,24 @@ test('Get failed payments', async ({end, equal, strictSame}) => {
73
72
  // Create a new channel to increase total edge liquidity
74
73
  await setupChannel({
75
74
  capacity: channelCapacityTokens,
76
- lnd: cluster.target.lnd,
77
- generate: cluster.generate,
78
- generator: cluster.target,
79
- to: cluster.remote,
75
+ lnd: target.lnd,
76
+ generate: target.generate,
77
+ generator: target,
78
+ to: remote,
80
79
  });
81
80
 
82
81
  await deleteForwardingReputations({lnd});
83
82
 
84
- try {
85
- const {secret} = await pay({lnd, request: invoice.request});
86
- } catch (err) {
87
- equal(err, null, 'No error when probing for route');
88
- }
83
+ await asyncRetry({times}, async () => {
84
+ await pay({lnd, request: invoice.request});
85
+ });
89
86
 
90
87
  {
91
88
  const {payments} = await getFailedPayments({lnd});
92
89
 
93
- const [payment] = payments;
90
+ const [payment] = payments.filter(n => n.mtokens === bigInvoice.mtokens);
94
91
 
95
- equal(payment.destination, cluster.remote.public_key, 'Payment to');
92
+ equal(payment.destination, remote.id, 'Payment to');
96
93
  equal(payment.confirmed_at, undefined, 'No confirmation date');
97
94
  equal(!!payment.created_at, true, 'Got payment created date');
98
95
  equal(payment.fee, undefined, 'No fee when not paid');
@@ -134,12 +131,12 @@ test('Get failed payments', async ({end, equal, strictSame}) => {
134
131
 
135
132
  const [payment] = payments;
136
133
 
137
- equal(payment.destination, cluster.remote.public_key, 'Paid to');
134
+ equal(payment.destination, remote.id, 'Paid to');
138
135
  equal(!!payment.confirmed_at, true, 'Got confirmation date');
139
136
  equal(!!payment.created_at, true, 'Got payment start date');
140
137
  equal(payment.fee, 1, 'Got fee paid');
141
138
  equal(payment.fee_mtokens, '1500', 'Got fee mtokens paid');
142
- strictSame(payment.hops, [cluster.target.public_key], 'Got hops');
139
+ strictSame(payment.hops, [target.id], 'Got hops');
143
140
  equal(!!payment.id, true, 'Got a payment id');
144
141
  equal(!!payment.index, true, 'Got payment index');
145
142
  equal(payment.is_confirmed, true, 'Failed payment is not confirmed');
@@ -152,7 +149,7 @@ test('Get failed payments', async ({end, equal, strictSame}) => {
152
149
  equal(payment.tokens, invoice.tokens, 'Failed has tokens');
153
150
  }
154
151
 
155
- await cluster.kill({});
152
+ await kill({});
156
153
 
157
154
  return end();
158
155
  });
@@ -1,23 +1,20 @@
1
+ const {spawnLightningCluster} = require('ln-docker-daemons');
1
2
  const {test} = require('@alexbosworth/tap');
2
3
 
3
- const {createCluster} = require('./../macros');
4
4
  const {getFeeRates} = require('./../../');
5
5
  const {setupChannel} = require('./../macros');
6
6
 
7
7
  const defaultBaseFee = 1;
8
8
  const defaultFeeRate = 1;
9
+ const size = 2;
9
10
 
10
11
  // Getting fee rates should return the fee rates of nodes in the channel graph
11
12
  test(`Get fee rates`, async ({end, equal}) => {
12
- const cluster = await createCluster({is_remote_skipped: true});
13
+ const {kill, nodes} = await spawnLightningCluster({size});
13
14
 
14
- const {lnd} = cluster.control;
15
+ const [{generate, lnd}, to] = nodes;
15
16
 
16
- const channelOpen = await setupChannel({
17
- lnd,
18
- generate: cluster.generate,
19
- to: cluster.target,
20
- });
17
+ const channelOpen = await setupChannel({generate, lnd, to});
21
18
 
22
19
  const {channels} = await getFeeRates({lnd});
23
20
 
@@ -35,7 +32,7 @@ test(`Get fee rates`, async ({end, equal}) => {
35
32
  equal(channel.transaction_id, channelOpen.transaction_id, 'Channel tx id');
36
33
  equal(channel.transaction_vout, channelOpen.transaction_vout, 'Tx vout');
37
34
 
38
- await cluster.kill({});
35
+ await kill({});
39
36
 
40
37
  return end();
41
38
  });