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.
- package/CHANGELOG.md +12 -0
- package/README.md +1 -8
- package/package.json +4 -12
- 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 +36 -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 -71
- 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 +20 -14
- 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/change_password.js +14 -12
- package/test/macros/generate_blocks.js +23 -28
- package/test/macros/rpc.js +1 -0
- package/test/macros/setup_channel.js +23 -9
- package/test/macros/spawn_lnd.js +2 -0
- 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 -23
- 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 +39 -44
- 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
|
@@ -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
|
|
35
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
33
36
|
|
|
34
|
-
const
|
|
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:
|
|
46
|
+
to: target,
|
|
42
47
|
});
|
|
43
48
|
|
|
44
49
|
const closing = await closeChannel({
|
|
45
|
-
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
|
|
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
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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:
|
|
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
|
|
116
|
+
const settleInvoice = await createHodlInvoice({
|
|
115
117
|
lnd,
|
|
116
|
-
cltv_delta:
|
|
118
|
+
cltv_delta: 144,
|
|
117
119
|
tokens: 1e5,
|
|
118
120
|
});
|
|
119
121
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
});
|
|
122
|
+
const subCancelInvoice = subscribeToInvoice({lnd, id: cancelInvoice.id});
|
|
123
|
+
const subSettleInvoice = subscribeToInvoice({lnd, id: settleInvoice.id});
|
|
123
124
|
|
|
124
|
-
const
|
|
125
|
-
|
|
125
|
+
const cancelInvoiceUpdates = [];
|
|
126
|
+
const settleInvoiceUpdates = [];
|
|
126
127
|
|
|
127
|
-
|
|
128
|
+
subCancelInvoice.on('invoice_updated', n => cancelInvoiceUpdates.push(n));
|
|
129
|
+
subSettleInvoice.on('invoice_updated', n => settleInvoiceUpdates.push(n));
|
|
128
130
|
|
|
129
|
-
|
|
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
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
173
|
-
|
|
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
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
168
|
+
if (channels.length === [toForceClose, channelOpen].length) {
|
|
169
|
+
return channels;
|
|
170
|
+
}
|
|
183
171
|
|
|
184
|
-
|
|
185
|
-
|
|
172
|
+
await target.generate({});
|
|
173
|
+
await generate({});
|
|
186
174
|
|
|
187
|
-
|
|
188
|
-
return payment.transaction_id === controlPending.spent_by;
|
|
175
|
+
throw new Error('WaitingForForceClose');
|
|
189
176
|
});
|
|
190
177
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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
|
-
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
equal(controlTimedOut.tokens, 91213, 'Paid payment has token count');
|
|
215
|
-
}
|
|
231
|
+
throw new Error('WaitingForTargetForceClose');
|
|
232
|
+
});
|
|
216
233
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
equal(
|
|
220
|
-
equal(
|
|
221
|
-
equal(
|
|
222
|
-
equal(!!
|
|
223
|
-
equal(
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
equal(
|
|
231
|
-
equal(
|
|
232
|
-
equal(
|
|
233
|
-
equal(
|
|
234
|
-
equal(
|
|
235
|
-
equal(
|
|
236
|
-
equal(
|
|
237
|
-
equal(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
equal(
|
|
242
|
-
equal(
|
|
243
|
-
equal(
|
|
244
|
-
equal(
|
|
245
|
-
equal(
|
|
246
|
-
equal(
|
|
247
|
-
|
|
248
|
-
|
|
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
|
|
27
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
23
28
|
|
|
24
|
-
const {lnd} =
|
|
29
|
+
const [{generate, lnd}, target, remote] = nodes;
|
|
25
30
|
|
|
26
|
-
const {address} = await createChainAddress({
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
35
|
-
await
|
|
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
|
-
|
|
41
|
-
to: cluster.target,
|
|
46
|
+
to: target,
|
|
42
47
|
});
|
|
43
48
|
|
|
44
49
|
await setupChannel({
|
|
45
50
|
capacity: channelCapacityTokens,
|
|
46
|
-
lnd:
|
|
47
|
-
generate:
|
|
48
|
-
generator:
|
|
51
|
+
lnd: target.lnd,
|
|
52
|
+
generate: target.generate,
|
|
53
|
+
generator: target,
|
|
49
54
|
give: Math.round(channelCapacityTokens / 2),
|
|
50
|
-
to:
|
|
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:
|
|
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:
|
|
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:
|
|
77
|
-
generate:
|
|
78
|
-
generator:
|
|
79
|
-
to:
|
|
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
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
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,
|
|
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,
|
|
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, [
|
|
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
|
|
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
|
|
13
|
+
const {kill, nodes} = await spawnLightningCluster({size});
|
|
13
14
|
|
|
14
|
-
const {lnd} =
|
|
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
|
|
35
|
+
await kill({});
|
|
39
36
|
|
|
40
37
|
return end();
|
|
41
38
|
});
|