Skip to content
This repository was archived by the owner on Feb 9, 2026. It is now read-only.

Commit 50b625d

Browse files
authored
Merge pull request #182 from synonymdev/limit-lm-start-calls
fix(lightning): Limit lm.start Calls
2 parents 60de3c5 + bd610af commit 50b625d

1 file changed

Lines changed: 65 additions & 14 deletions

File tree

lib/src/lightning-manager.ts

Lines changed: 65 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ class LightningManager {
141141
private forceSync: boolean = false;
142142
private pendingSyncPromises: Array<(result: Result<string>) => void> = [];
143143

144+
private isStarting: boolean = false;
145+
private pendingStartPromises: Array<(result: Result<string>) => void> = [];
146+
private previousAccountName: string = '';
147+
144148
constructor() {
145149
// Step 0: Subscribe to all events
146150
ldk.onEvent(EEventTypes.native_log, (line) => {
@@ -236,6 +240,33 @@ class LightningManager {
236240
return ok('Storage set');
237241
}
238242

243+
/**
244+
* Resolves all pending start promises with the provided result.
245+
* @private
246+
* @param {Result<string>} result
247+
* @returns {void}
248+
*/
249+
private resolveAllPendingStartPromises(result: Result<string>): void {
250+
while (this.pendingStartPromises.length > 0) {
251+
const resolve = this.pendingStartPromises.shift();
252+
if (resolve) {
253+
resolve(result);
254+
}
255+
}
256+
}
257+
258+
/**
259+
* Sets isStarting to false, resolves all start promises and returns error.
260+
* @private
261+
* @param {Err<string>} e
262+
* @returns {Promise<Result<string>>}
263+
*/
264+
private handleStartError = (e: Err<string>): Result<string> => {
265+
this.isStarting = false;
266+
this.resolveAllPendingStartPromises(e);
267+
return e;
268+
};
269+
239270
/**
240271
* Spins up and syncs all processes
241272
* @param {string} seed
@@ -281,6 +312,19 @@ class LightningManager {
281312
return err('getTransactionPosition is not set in start method.');
282313
}
283314

315+
// Retry start method if presented with a new account name.
316+
if (this.previousAccountName !== account.name) {
317+
this.isStarting = false;
318+
this.previousAccountName = account.name;
319+
}
320+
321+
if (this.isStarting) {
322+
return new Promise<Result<string>>((resolve) => {
323+
this.pendingStartPromises.push(resolve);
324+
});
325+
}
326+
this.isStarting = true;
327+
284328
// Ensure the start params function as expected.
285329
const paramCheckResponse = await startParamCheck({
286330
account,
@@ -294,7 +338,7 @@ class LightningManager {
294338
network,
295339
});
296340
if (paramCheckResponse.isErr()) {
297-
return err(paramCheckResponse.error.message);
341+
return this.handleStartError(paramCheckResponse);
298342
}
299343

300344
this.getBestBlock = getBestBlock;
@@ -313,14 +357,16 @@ class LightningManager {
313357
this.trustedZeroConfPeers = trustedZeroConfPeers;
314358

315359
if (!this.baseStoragePath) {
316-
return err(
317-
'baseStoragePath required for wallet persistence. Call setBaseStoragePath(path) first.',
360+
return this.handleStartError(
361+
err(
362+
'baseStoragePath required for wallet persistence. Call setBaseStoragePath(path) first.',
363+
),
318364
);
319365
}
320366

321367
const storageSetRes = await this.setStorage(account);
322368
if (storageSetRes.isErr()) {
323-
return err(storageSetRes.error);
369+
return this.handleStartError(storageSetRes);
324370
}
325371

326372
//Validate we didn't change the seed for this account if one exists
@@ -338,15 +384,17 @@ class LightningManager {
338384
remotePersist: false,
339385
});
340386
if (writeRes.isErr()) {
341-
return err(writeRes.error);
387+
return this.handleStartError(err(writeRes.error));
342388
}
343389
} else {
344-
return err(readSeed.error);
390+
return this.handleStartError(err(readSeed.error));
345391
}
346392
} else {
347393
//Cannot start an existing node with a different seed
348394
if (readSeed.value.content !== account.seed) {
349-
return err('Seed for current node cannot be changed.');
395+
return this.handleStartError(
396+
err('Seed for current node cannot be changed.'),
397+
);
350398
}
351399
}
352400

@@ -358,7 +406,7 @@ class LightningManager {
358406
details: backupServerDetails,
359407
});
360408
if (backupSetupRes.isErr()) {
361-
return err(backupSetupRes.error);
409+
return this.handleStartError(err(backupSetupRes.error));
362410
}
363411
}
364412

@@ -390,13 +438,13 @@ class LightningManager {
390438
// Step 5: Initialize the ChainMonitor
391439
const chainMonitorRes = await ldk.initChainMonitor();
392440
if (chainMonitorRes.isErr()) {
393-
return chainMonitorRes;
441+
return this.handleStartError(chainMonitorRes);
394442
}
395443

396444
// Step 6: Initialize the KeysManager
397445
const keysManager = await ldk.initKeysManager(this.account.seed);
398446
if (keysManager.isErr()) {
399-
return keysManager;
447+
return this.handleStartError(keysManager);
400448
}
401449

402450
// Step 7: Read ChannelMonitors state from disk
@@ -413,22 +461,22 @@ class LightningManager {
413461
rapidGossipSyncUrl,
414462
});
415463
if (networkGraphRes.isErr()) {
416-
return networkGraphRes;
464+
return this.handleStartError(networkGraphRes);
417465
}
418466

419467
// Step 8: Initialize the UserConfig ChannelManager
420468
const confRes = await ldk.initUserConfig(userConfig);
421469

422470
if (confRes.isErr()) {
423-
return confRes;
471+
return this.handleStartError(confRes);
424472
}
425473

426474
const channelManagerRes = await ldk.initChannelManager({
427475
network: this.network,
428476
bestBlock,
429477
});
430478
if (channelManagerRes.isErr()) {
431-
return channelManagerRes;
479+
return this.handleStartError(channelManagerRes);
432480
}
433481

434482
// Attempt to abandon any stored payment ids.
@@ -468,7 +516,10 @@ class LightningManager {
468516
//Writes node state to log files
469517
ldk.nodeStateDump().catch(console.error);
470518

471-
return ok('Node running');
519+
this.isStarting = false;
520+
const result = ok('Node started');
521+
this.resolveAllPendingStartPromises(result);
522+
return result;
472523
}
473524

474525
async setStorage(account: TAccount): Promise<Result<string>> {

0 commit comments

Comments
 (0)