paid-services 3.6.0 → 3.7.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 +4 -0
- package/capacity/accept_capacity_change.js +2 -0
- package/capacity/ask_for_change_details.js +9 -10
- package/capacity/ask_for_decrease.js +167 -49
- package/capacity/fee_for_replacement.js +3 -7
- package/capacity/get_capacity_replacement.js +56 -7
- package/capacity/propose_capacity_change.js +207 -92
- package/capacity/propose_channel_open.js +54 -0
- package/package.json +2 -2
- package/test/integration/test_accept_capacity_change.js +3 -3
- package/test/integration/test_change_channel_capacity.js +4 -0
- package/test/integration/test_decrease_channel_capacity.js +7 -1
- package/test/integration/test_split_channel_capacity.js +241 -0
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
const asyncAuto = require('async/auto');
|
|
2
|
-
const
|
|
2
|
+
const asyncEach = require('async/each');
|
|
3
3
|
const asyncReflect = require('async/reflect');
|
|
4
4
|
const {broadcastChainTransaction} = require('ln-service');
|
|
5
5
|
const {cancelPendingChannel} = require('ln-service');
|
|
6
|
+
const {deletePendingChannel} = require('ln-service');
|
|
6
7
|
const {fundPendingChannels} = require('ln-service');
|
|
7
|
-
const {getChainTransactions} = require('ln-service');
|
|
8
8
|
const {getChannels} = require('ln-service');
|
|
9
9
|
const {getClosedChannels} = require('ln-service');
|
|
10
10
|
const {getHeight} = require('ln-service');
|
|
11
|
+
const {getPendingChannels} = require('ln-service');
|
|
11
12
|
const {returnResult} = require('asyncjs-util');
|
|
12
13
|
const {signTransaction} = require('ln-service');
|
|
14
|
+
const {subscribeToBlocks} = require('ln-service');
|
|
13
15
|
const {Transaction} = require('bitcoinjs-lib');
|
|
14
16
|
const {transactionAsPsbt} = require('psbt');
|
|
15
17
|
|
|
@@ -21,6 +23,7 @@ const {serviceTypeSignCapacityChange} = require('./../service_types');
|
|
|
21
23
|
|
|
22
24
|
const capacityChangeIdType = '0';
|
|
23
25
|
const findSignatureRecord = records => records.find(n => n.type === '1');
|
|
26
|
+
const {fromHex} = Transaction;
|
|
24
27
|
const fuzzHeight = 3;
|
|
25
28
|
const maxSigHexLength = 146;
|
|
26
29
|
const peerRequestTimeoutMs = 1000 * 60 * 10;
|
|
@@ -35,9 +38,10 @@ const unsignedTransactionType = '1';
|
|
|
35
38
|
bitcoinjs_network: <BitcoinJS Network Name String>
|
|
36
39
|
channel: <Channel to Change Standard Format Channel Id String>
|
|
37
40
|
decrease: [{
|
|
38
|
-
address: <
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
[address]: <Decrease Address String>
|
|
42
|
+
[node]: <Create Channel with Node With Public Key Hex String>
|
|
43
|
+
[output]: <Output Script Hex String>
|
|
44
|
+
tokens: <Decrease Tokens Number>
|
|
41
45
|
}]
|
|
42
46
|
id: <Capacity Change Request Id Hex String>
|
|
43
47
|
is_private: <Channel is Private Bool>
|
|
@@ -109,10 +113,7 @@ module.exports = (args, cbk) => {
|
|
|
109
113
|
return cbk();
|
|
110
114
|
},
|
|
111
115
|
|
|
112
|
-
//
|
|
113
|
-
getHeight: ['validate', ({}, cbk) => getHeight({lnd: args.lnd}, cbk)],
|
|
114
|
-
|
|
115
|
-
// Close the current channal and get the unsigned replacement
|
|
116
|
+
// Close the current channel and get the unsigned replacement
|
|
116
117
|
getReplacement: ['validate', ({}, cbk) => {
|
|
117
118
|
return getCapacityReplacement({
|
|
118
119
|
add_funds_transaction_id: args.increase_transaction_id,
|
|
@@ -131,9 +132,9 @@ module.exports = (args, cbk) => {
|
|
|
131
132
|
cbk);
|
|
132
133
|
}],
|
|
133
134
|
|
|
134
|
-
//
|
|
135
|
+
// The replacement channel outpoint will be returned as a result
|
|
135
136
|
replacement: ['getReplacement', ({getReplacement}, cbk) => {
|
|
136
|
-
args.logger.info({
|
|
137
|
+
args.logger.info({proposal_id: getReplacement.pending_channel_id});
|
|
137
138
|
|
|
138
139
|
return cbk(null, {
|
|
139
140
|
transaction_id: getReplacement.transaction_id,
|
|
@@ -164,8 +165,8 @@ module.exports = (args, cbk) => {
|
|
|
164
165
|
cbk);
|
|
165
166
|
}],
|
|
166
167
|
|
|
167
|
-
//
|
|
168
|
-
|
|
168
|
+
// Derive the funding PSBT to use for funding
|
|
169
|
+
funding: [
|
|
169
170
|
'getReplacement',
|
|
170
171
|
'signAddFunds',
|
|
171
172
|
({getReplacement, signAddFunds}, cbk) =>
|
|
@@ -183,10 +184,22 @@ module.exports = (args, cbk) => {
|
|
|
183
184
|
witness_script: getReplacement.witness_script,
|
|
184
185
|
});
|
|
185
186
|
|
|
186
|
-
|
|
187
|
+
return cbk(null, psbt);
|
|
188
|
+
}],
|
|
189
|
+
|
|
190
|
+
// Use the unsigned replacement transaction to "fund" the pending channel
|
|
191
|
+
fundWithReplacement: [
|
|
192
|
+
'funding',
|
|
193
|
+
'getReplacement',
|
|
194
|
+
({funding, getReplacement}, cbk) =>
|
|
195
|
+
{
|
|
196
|
+
const replacement = getReplacement.unsigned_transaction;
|
|
197
|
+
|
|
198
|
+
args.logger.info({funding_with_replacement_tx: replacement});
|
|
199
|
+
|
|
187
200
|
return fundPendingChannels({
|
|
201
|
+
funding,
|
|
188
202
|
channels: [getReplacement.pending_channel_id],
|
|
189
|
-
funding: psbt,
|
|
190
203
|
lnd: args.lnd,
|
|
191
204
|
},
|
|
192
205
|
cbk);
|
|
@@ -194,8 +207,8 @@ module.exports = (args, cbk) => {
|
|
|
194
207
|
|
|
195
208
|
// Send the final go ahead signal now that a proposal is made
|
|
196
209
|
getPeerSignature: [
|
|
197
|
-
'getReplacement',
|
|
198
210
|
'fundWithReplacement',
|
|
211
|
+
'getReplacement',
|
|
199
212
|
asyncReflect(({getReplacement}, cbk) =>
|
|
200
213
|
{
|
|
201
214
|
return makePeerRequest({
|
|
@@ -229,49 +242,86 @@ module.exports = (args, cbk) => {
|
|
|
229
242
|
return cbk([503, 'ExpectedSignatureRecordFromPeerForChange']);
|
|
230
243
|
}
|
|
231
244
|
|
|
245
|
+
args.logger.info({peer_cosigned_capacity_change: true});
|
|
246
|
+
|
|
232
247
|
return cbk(null, record.value);
|
|
233
248
|
});
|
|
234
249
|
})],
|
|
235
250
|
|
|
236
|
-
//
|
|
251
|
+
// Fund the additional other channel opens if present
|
|
252
|
+
fundAdditionalOpens: [
|
|
253
|
+
'funding',
|
|
254
|
+
'getPeerSignature',
|
|
255
|
+
'getReplacement',
|
|
256
|
+
asyncReflect(({funding, getPeerSignature, getReplacement}, cbk) =>
|
|
257
|
+
{
|
|
258
|
+
// Exit early when there was an error getting the peer signature
|
|
259
|
+
if (!!getPeerSignature.error) {
|
|
260
|
+
return cbk();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Exit early when there is nothing else to fund
|
|
264
|
+
if (!getReplacement.open_pending_ids.length) {
|
|
265
|
+
return cbk();
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Funding for the additional opens is separated for smoother canceling
|
|
269
|
+
return fundPendingChannels({
|
|
270
|
+
funding,
|
|
271
|
+
channels: getReplacement.open_pending_ids,
|
|
272
|
+
lnd: args.lnd,
|
|
273
|
+
},
|
|
274
|
+
cbk);
|
|
275
|
+
})],
|
|
276
|
+
|
|
277
|
+
// Cancel the unfunded channel opens when there is an error
|
|
237
278
|
cancelFunding: [
|
|
238
279
|
'getPeerSignature',
|
|
239
280
|
'getReplacement',
|
|
240
281
|
({getPeerSignature, getReplacement}, cbk) =>
|
|
241
282
|
{
|
|
242
|
-
// Exit early when there
|
|
283
|
+
// Exit early when there was an error getting the peer signature
|
|
243
284
|
if (!getPeerSignature.error) {
|
|
244
285
|
return cbk();
|
|
245
286
|
}
|
|
246
287
|
|
|
247
|
-
|
|
248
|
-
id: getReplacement.pending_channel_id,
|
|
249
|
-
lnd: args.lnd,
|
|
250
|
-
},
|
|
251
|
-
err => {
|
|
252
|
-
if (!!err) {
|
|
253
|
-
return cbk([503, 'FailedToCancelPendingChannel', {err}]);
|
|
254
|
-
}
|
|
288
|
+
const ids = getReplacement.open_pending_ids;
|
|
255
289
|
|
|
256
|
-
|
|
257
|
-
return
|
|
258
|
-
})
|
|
290
|
+
return asyncEach(ids, asyncReflect((id, cbk) => {
|
|
291
|
+
return cancelPendingChannel({id, lnd: args.lnd}, cbk);
|
|
292
|
+
}),
|
|
293
|
+
cbk);
|
|
259
294
|
}],
|
|
260
295
|
|
|
261
296
|
// Broadcast the new funding transaction using the peer's signature
|
|
262
297
|
confirmFunding: [
|
|
263
|
-
'
|
|
298
|
+
'fundAdditionalOpens',
|
|
264
299
|
'getPeerSignature',
|
|
265
300
|
'getReplacement',
|
|
266
301
|
'signAddFunds',
|
|
267
|
-
({
|
|
302
|
+
({
|
|
303
|
+
fundAdditionalOpens,
|
|
304
|
+
getPeerSignature,
|
|
305
|
+
getReplacement,
|
|
306
|
+
signAddFunds,
|
|
307
|
+
},
|
|
308
|
+
cbk) =>
|
|
268
309
|
{
|
|
269
|
-
//
|
|
310
|
+
// When there is no peer signature, the force close must confirm
|
|
270
311
|
if (!!getPeerSignature.error) {
|
|
271
|
-
return cbk();
|
|
312
|
+
return cbk(null, {is_success: false});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Do not broadcast a replacement when additional opens fail
|
|
316
|
+
if (!!fundAdditionalOpens.error) {
|
|
317
|
+
return cbk(null, {is_success: false});
|
|
272
318
|
}
|
|
273
319
|
|
|
274
320
|
const [addFundsSignature] = signAddFunds.signatures || [];
|
|
321
|
+
const openOutputs = fromHex(args.open_transaction).outs;
|
|
322
|
+
const txId = fromHex(getReplacement.unsigned_transaction).getId();
|
|
323
|
+
|
|
324
|
+
const outScript = openOutputs[args.transaction_vout].script;
|
|
275
325
|
|
|
276
326
|
// Insert the peer signature to get the final signed funding tx
|
|
277
327
|
const {transaction} = finalizeCapacityReplacement({
|
|
@@ -288,75 +338,140 @@ module.exports = (args, cbk) => {
|
|
|
288
338
|
|
|
289
339
|
args.logger.info({publishing_new_channel_transaction: transaction});
|
|
290
340
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
// Try and override the force close tx using the replacement
|
|
294
|
-
return broadcastChainTransaction({
|
|
295
|
-
transaction,
|
|
296
|
-
after: getHeight.current_block_height - fuzzHeight,
|
|
297
|
-
lnd: args.lnd,
|
|
298
|
-
},
|
|
299
|
-
cbk);
|
|
300
|
-
},
|
|
301
|
-
(broadcast, cbk) => {
|
|
302
|
-
args.logger.info({waiting_for_confirmation: broadcast.id});
|
|
341
|
+
// Listen to new blocks to wait for the channel change confirmation
|
|
342
|
+
const sub = subscribeToBlocks({lnd: args.lnd});
|
|
303
343
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
344
|
+
// Fail with error when the blocks subscription is lost
|
|
345
|
+
sub.on('error', err => {
|
|
346
|
+
sub.removeAllListeners();
|
|
347
|
+
|
|
348
|
+
return cbk([503, 'LostBlockchainSubscription', {err}]);
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// Publish the new channel transaction when a block is received
|
|
352
|
+
sub.on('block', async () => {
|
|
353
|
+
// Broadcast the channel replacement tx
|
|
354
|
+
try {
|
|
355
|
+
await broadcastChainTransaction({transaction, lnd: args.lnd});
|
|
356
|
+
|
|
357
|
+
args.logger.info({published_new_channel_tx: txId});
|
|
358
|
+
} catch (err) {
|
|
359
|
+
args.logger.error({err});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Look for the new channel to see if the change succeeded
|
|
363
|
+
try {
|
|
364
|
+
const {channels} = await getChannels({lnd: args.lnd});
|
|
309
365
|
|
|
310
|
-
|
|
366
|
+
const channel = channels.find(n => n.transaction_id === txId);
|
|
311
367
|
|
|
312
|
-
|
|
313
|
-
|
|
368
|
+
// Replacement is present but not yet active
|
|
369
|
+
if (!!channel && !channel.is_active) {
|
|
370
|
+
args.logger.info({waiting_for_channel_to_activate: true});
|
|
371
|
+
}
|
|
314
372
|
|
|
315
|
-
|
|
316
|
-
|
|
373
|
+
// The new channel confirmed successfully and so the change worked
|
|
374
|
+
if (!!channel && !!channel.is_active) {
|
|
375
|
+
sub.removeAllListeners();
|
|
376
|
+
|
|
377
|
+
return cbk(null, {is_success: true});
|
|
378
|
+
}
|
|
379
|
+
} catch (err) {
|
|
380
|
+
args.logger.error({err});
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Also look for a force closed channel to see if the change failed
|
|
384
|
+
try {
|
|
385
|
+
const {channels} = await getClosedChannels({lnd: args.lnd});
|
|
386
|
+
const chainTip = await getHeight({lnd: args.lnd});
|
|
387
|
+
|
|
388
|
+
const currentHeight = chainTip.current_block_height;
|
|
389
|
+
|
|
390
|
+
const channel = channels.find(channel => {
|
|
391
|
+
// The closed channel must have a closed tx id
|
|
392
|
+
if (!channel.close_transaction_id) {
|
|
393
|
+
return false;
|
|
317
394
|
}
|
|
318
395
|
|
|
319
|
-
//
|
|
320
|
-
|
|
321
|
-
return
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
// Cancel the pending channel if the force close confirms
|
|
325
|
-
if (!!replacing) {
|
|
326
|
-
return cancelPendingChannel({
|
|
327
|
-
id: getReplacement.pending_channel_id,
|
|
328
|
-
lnd: args.lnd,
|
|
329
|
-
},
|
|
330
|
-
() => {
|
|
331
|
-
return cbk([503, 'FailedToReplaceForceCloseTransaction']);
|
|
332
|
-
});
|
|
396
|
+
// Only consider channels that are conclusively closed
|
|
397
|
+
if (currentHeight - channel.close_confirm_height < fuzzHeight) {
|
|
398
|
+
return false;
|
|
333
399
|
}
|
|
334
400
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
return cbk(err);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
const channel = res.channels.find(channel => {
|
|
345
|
-
return channel.transaction_id === broadcast.id
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
// Stop broadcasting when a channel shows up
|
|
349
|
-
if (!!channel) {
|
|
350
|
-
return cbk(null, true);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
// Rebroadcast after a delay
|
|
354
|
-
return setTimeout(() => cbk(null, false), rebroadcastDelayMs);
|
|
355
|
-
});
|
|
401
|
+
// Find close channel matching the channel outpoint
|
|
402
|
+
if (channel.transaction_id !== args.transaction_id) {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return channel.transaction_vout === args.transaction_vout;
|
|
356
407
|
});
|
|
408
|
+
|
|
409
|
+
// The old channel force closed and so the change fully failed
|
|
410
|
+
if (!!channel && channel.close_transaction_id !== txId) {
|
|
411
|
+
sub.removeAllListeners();
|
|
412
|
+
|
|
413
|
+
return cbk(null, {is_success: false});
|
|
414
|
+
}
|
|
415
|
+
} catch (err) {
|
|
416
|
+
args.logger.error({err});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return;
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
return;
|
|
423
|
+
}],
|
|
424
|
+
|
|
425
|
+
// Get pending channels to clean up if there was a failure
|
|
426
|
+
getPending: ['confirmFunding', ({confirmFunding}, cbk) => {
|
|
427
|
+
// Exit early when there was no failure
|
|
428
|
+
if (!!confirmFunding.is_success) {
|
|
429
|
+
return cbk();
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return getPendingChannels({lnd: args.lnd}, cbk);
|
|
433
|
+
}],
|
|
434
|
+
|
|
435
|
+
// Clean up pending channels that will never confirm
|
|
436
|
+
cleanPendingChannels: [
|
|
437
|
+
'confirmFunding',
|
|
438
|
+
'getPending',
|
|
439
|
+
'getReplacement',
|
|
440
|
+
({confirmFunding, getPending, getReplacement}, cbk) =>
|
|
441
|
+
{
|
|
442
|
+
// Exit early when the channel activated
|
|
443
|
+
if (!!confirmFunding.is_success) {
|
|
444
|
+
args.logger.info({channel_capacity_changed: true});
|
|
445
|
+
|
|
446
|
+
return cbk();
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const replaceId = fromHex(getReplacement.unsigned_transaction).getId();
|
|
450
|
+
|
|
451
|
+
// Collect all the pending channels that depend on the replacement
|
|
452
|
+
const pending = getPending.pending_channels
|
|
453
|
+
.filter(n => !!n.is_opening)
|
|
454
|
+
.filter(n => n.transaction_id === replaceId);
|
|
455
|
+
|
|
456
|
+
// Delete the pending channels that can never confirm
|
|
457
|
+
return asyncEach(pending, (channel, cbk) => {
|
|
458
|
+
return deletePendingChannel({
|
|
459
|
+
confirmed_transaction: getReplacement.force_close_tx,
|
|
460
|
+
lnd: args.lnd,
|
|
461
|
+
pending_transaction: getReplacement.unsigned_transaction,
|
|
462
|
+
pending_transaction_vout: channel.transaction_vout,
|
|
357
463
|
},
|
|
358
|
-
|
|
359
|
-
|
|
464
|
+
err => {
|
|
465
|
+
if (!!err) {
|
|
466
|
+
args.logger.error({err});
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
return cbk();
|
|
470
|
+
});
|
|
471
|
+
},
|
|
472
|
+
() => {
|
|
473
|
+
return cbk([503, 'FailedToChangeChannelCapacity']);
|
|
474
|
+
});
|
|
360
475
|
}],
|
|
361
476
|
},
|
|
362
477
|
returnResult({reject, resolve, of: 'replacement'}, cbk));
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const {acceptsChannelOpen} = require('ln-sync');
|
|
2
|
+
const asyncAuto = require('async/auto');
|
|
3
|
+
const {connectPeer} = require('ln-sync');
|
|
4
|
+
const {returnResult} = require('asyncjs-util');
|
|
5
|
+
|
|
6
|
+
/** Check that a channel open would be accepted by a node
|
|
7
|
+
|
|
8
|
+
{
|
|
9
|
+
capacity: <Capacity Tokens Number>
|
|
10
|
+
id: <Node Identity Public Key Hex String>
|
|
11
|
+
lnd: <Authenticated LND API Object>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@returns via cbk or Promise
|
|
15
|
+
{
|
|
16
|
+
is_accepted: <Channel Proposal Is Accepted Bool>
|
|
17
|
+
}
|
|
18
|
+
*/
|
|
19
|
+
module.exports = ({capacity, id, lnd}, cbk) => {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
return asyncAuto({
|
|
22
|
+
// Check arguments
|
|
23
|
+
validate: cbk => {
|
|
24
|
+
if (!capacity) {
|
|
25
|
+
return cbk([400, 'ExpectedCapacityTokensToProposeChannelOpen']);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!id) {
|
|
29
|
+
return cbk([400, 'ExpectedNodePublicKeyToProposeChannelOpen']);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (!lnd) {
|
|
33
|
+
return cbk([400, 'ExpectedAuthenticatedLndToProposeChannelOpen']);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return cbk();
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
// Connect to the peer
|
|
40
|
+
connect: ['validate', ({}, cbk) => connectPeer({id, lnd}, cbk)],
|
|
41
|
+
|
|
42
|
+
// Propose a channel open to check acceptance
|
|
43
|
+
checkAccept: ['connect', ({}, cbk) => {
|
|
44
|
+
return acceptsChannelOpen({
|
|
45
|
+
capacity,
|
|
46
|
+
lnd,
|
|
47
|
+
partner_public_key: id,
|
|
48
|
+
},
|
|
49
|
+
cbk);
|
|
50
|
+
}],
|
|
51
|
+
},
|
|
52
|
+
returnResult({reject, resolve, of: 'checkAccept'}, cbk));
|
|
53
|
+
});
|
|
54
|
+
};
|
package/package.json
CHANGED
|
@@ -37,8 +37,8 @@
|
|
|
37
37
|
"url": "https://github.com/alexbosworth/paid-services.git"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
|
-
"integration-tests": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t
|
|
40
|
+
"integration-tests": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 180 test/integration/*.js",
|
|
41
41
|
"test": "tap --branches=1 --functions=1 --lines=1 --statements=1 -t 60 test/actions/*.js test/capacity/*.js test/client/*.js test/config/*.js test/p2p/*.js test/records/*.js test/respond/*.js test/server/*.js test/server/*.js test/services/*.js test/trades/*.js"
|
|
42
42
|
},
|
|
43
|
-
"version": "3.
|
|
43
|
+
"version": "3.7.0"
|
|
44
44
|
}
|
|
@@ -60,15 +60,15 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
60
60
|
|
|
61
61
|
// Wait for the channel to be active
|
|
62
62
|
const channel = await asyncRetry({interval, times}, async () => {
|
|
63
|
-
const [channel] = (await getChannels({lnd
|
|
63
|
+
const [channel] = (await getChannels({lnd})).channels;
|
|
64
64
|
|
|
65
|
-
if (!!channel) {
|
|
65
|
+
if (!!channel && !!channel.is_active) {
|
|
66
66
|
return channel;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
await generate({});
|
|
70
70
|
|
|
71
|
-
throw new Error('
|
|
71
|
+
throw new Error('ExpectedInitialChannelActivation');
|
|
72
72
|
});
|
|
73
73
|
|
|
74
74
|
// Find the open tx
|
|
@@ -87,6 +87,10 @@ test(`Accept capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
87
87
|
return cbk({amount: '0'});
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
+
if (args.name === 'decrease') {
|
|
91
|
+
return cbk({decrease: 'internal_spend_funds'});
|
|
92
|
+
}
|
|
93
|
+
|
|
90
94
|
if (args.name === 'direction') {
|
|
91
95
|
return cbk({direction: 'decrease'});
|
|
92
96
|
}
|
|
@@ -89,6 +89,10 @@ test(`Decrease capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
89
89
|
return cbk({amount: '200000'});
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
if (args.name === 'decrease') {
|
|
93
|
+
return cbk({decrease: 'internal_spend_funds'});
|
|
94
|
+
}
|
|
95
|
+
|
|
92
96
|
if (args.name === 'direction') {
|
|
93
97
|
return cbk({direction: 'decrease'});
|
|
94
98
|
}
|
|
@@ -129,7 +133,9 @@ test(`Decrease capacity replacement`, async ({end, equal, strictSame}) => {
|
|
|
129
133
|
// Wait to see the inbound proposal
|
|
130
134
|
waitForProposal: async () => {
|
|
131
135
|
await asyncRetry({interval, times}, async () => {
|
|
132
|
-
const {requests} = await getCapacityChangeRequests({
|
|
136
|
+
const {requests} = await getCapacityChangeRequests({
|
|
137
|
+
lnd: target.lnd,
|
|
138
|
+
});
|
|
133
139
|
|
|
134
140
|
if (!requests.length) {
|
|
135
141
|
throw new Error('FailedToFindChangeRequest');
|