Skip to content

Commit 0c08abb

Browse files
committed
fix: network grapth staleness check
1 parent 781ebf0 commit 0c08abb

File tree

1 file changed

+72
-0
lines changed

1 file changed

+72
-0
lines changed

src/utils/lightning/index.ts

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,67 @@ export const checkRgsHealth = async (): Promise<
300300
}
301301
};
302302

303+
/**
304+
* Checks if the network graph needs to be refreshed before making a payment.
305+
* Considers the graph stale if RGS data is older than the specified threshold.
306+
* @param {number} maxAgeHours - Maximum acceptable age in hours (default: 6)
307+
* @returns {Promise<boolean>} - True if refresh is needed
308+
*/
309+
export const shouldRefreshNetworkGraph = async (
310+
maxAgeHours: number = 6,
311+
): Promise<boolean> => {
312+
const healthCheck = await checkRgsHealth();
313+
314+
if (healthCheck.isErr()) {
315+
// If we can't check RGS health, assume refresh is needed
316+
console.warn(
317+
`Network graph health check failed: ${healthCheck.error.message}`,
318+
);
319+
return true;
320+
}
321+
322+
const { ageHours } = healthCheck.value;
323+
324+
if (ageHours > maxAgeHours) {
325+
console.log(
326+
`Network graph is stale (${ageHours.toFixed(1)}h old), refresh needed`,
327+
);
328+
return true;
329+
}
330+
331+
return false;
332+
};
333+
334+
/**
335+
* Forces a network graph refresh by calling syncLdk.
336+
* This ensures we have the latest routing information before attempting payments.
337+
* @returns {Promise<Result<string>>}
338+
*/
339+
export const forceNetworkGraphRefresh = async (): Promise<Result<string>> => {
340+
try {
341+
console.log('Forcing network graph refresh for payment routing...');
342+
343+
// Sync LDK to get latest network graph
344+
const syncResult = await lm.syncLdk();
345+
if (syncResult.isErr()) {
346+
return err(`Network graph refresh failed: ${syncResult.error.message}`);
347+
}
348+
349+
// Optionally download fresh scorer data
350+
const scorerResult = await ldk.downloadScorer();
351+
if (scorerResult.isErr()) {
352+
console.warn(
353+
`Scorer download failed: ${scorerResult.error.message}, continuing with cached scorer`,
354+
);
355+
}
356+
357+
console.log('Network graph refresh completed successfully');
358+
return ok('Network graph refreshed');
359+
} catch (e) {
360+
return err(`Network graph refresh error: ${e.message}`);
361+
}
362+
};
363+
303364
/**
304365
* Fetch fees from mempool.space and blocktank.to, prioritizing mempool.space.
305366
* Multiple attempts are made to fetch the fees from each provider
@@ -1702,6 +1763,17 @@ export const payLightningInvoice = async ({
17021763
try {
17031764
await waitForLdkChannels();
17041765

1766+
// Check if network graph needs refresh before attempting payment
1767+
const needsRefresh = await shouldRefreshNetworkGraph(6); // 6 hour threshold
1768+
if (needsRefresh) {
1769+
console.log('Network graph is stale, forcing refresh before payment...');
1770+
const refreshResult = await forceNetworkGraphRefresh();
1771+
if (refreshResult.isErr()) {
1772+
console.warn(`Failed to refresh network graph: ${refreshResult.error.message}`);
1773+
// Continue anyway - better to try with stale data than fail immediately
1774+
}
1775+
}
1776+
17051777
const addPeersResponse = await addPeers();
17061778
if (addPeersResponse.isErr()) {
17071779
return err(addPeersResponse.error.message);

0 commit comments

Comments
 (0)