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

Commit c42e73e

Browse files
authored
Merge pull request #242 from synonymdev/broadcast-tx-cleanup
Broadcasted transactions cleanup
2 parents 4125f00 + a146e9e commit c42e73e

5 files changed

Lines changed: 107 additions & 2 deletions

File tree

lib/android/src/main/java/com/reactnativeldk/LdkModule.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,7 @@ class LdkModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaMod
12441244
logDump.add("Open channel:")
12451245

12461246
channel._funding_txo?._txid?.let { txId ->
1247-
logDump.add("Funding txid: ${txId.hexEncodedString()}")
1247+
logDump.add("Funding txid: ${txId.reversedArray().hexEncodedString()}")
12481248
}
12491249

12501250
logDump.add("Ready: ${if (channel._is_channel_ready) "YES" else "NO"}")

lib/ios/Helpers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ extension ChannelDetails {
127127
"confirmations_required": getConfirmationsRequired() as Any, // Optional number
128128
"short_channel_id": shortChannelId,
129129
"inbound_scid_alias": getInboundScidAlias() != nil ? String(getInboundScidAlias()!) : shortChannelId, //String
130-
"inbound_payment_scid": getInboundPaymentScid() as Any, //Optional number,
130+
"inbound_payment_scid": getInboundPaymentScid() != nil ? String(getInboundPaymentScid()!) : "", //String,
131131
"inbound_capacity_sat": getInboundCapacityMsat() / 1000,
132132
"outbound_capacity_sat": getOutboundCapacityMsat() / 1000,
133133
"channel_value_satoshis": getChannelValueSatoshis(),

lib/src/lightning-manager.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ import {
6161
import {
6262
appendPath,
6363
findOutputsFromRawTxs,
64+
getTxIdFromRawTx,
6465
isValidBech32mEncodedString,
6566
parseData,
6667
promiseTimeout,
@@ -510,6 +511,8 @@ class LightningManager {
510511
//Writes node state to log files
511512
ldk.nodeStateDump().catch(console.error);
512513

514+
this.cleanupBroadcastedTxs().catch(console.error);
515+
513516
this.isStarting = false;
514517
const result = ok('Node started');
515518
this.resolveAllPendingStartPromises(result);
@@ -1586,6 +1589,102 @@ class LightningManager {
15861589
return [];
15871590
}
15881591

1592+
async cleanupBroadcastedTxs(): Promise<void> {
1593+
const savedTxs = await this.getLdkBroadcastedTxs();
1594+
if (savedTxs.length === 0) {
1595+
await ldk.writeToLogFile(
1596+
'debug',
1597+
'No broadcasted transactions found to cleanup.',
1598+
);
1599+
return;
1600+
}
1601+
1602+
const txsToCleanup: string[] = [];
1603+
for (const rawTx of savedTxs) {
1604+
const txid = getTxIdFromRawTx(rawTx);
1605+
const txData = await this.getTransactionData(txid);
1606+
if (!txData) {
1607+
await ldk.writeToLogFile(
1608+
'error',
1609+
`No txData found for tx: ${txid}. Skip cleanup.`,
1610+
);
1611+
//TODO maybe try broadcast and depending on the error, remove it if invalid inputs or something we expect from an invalid tx.
1612+
continue;
1613+
}
1614+
1615+
if (!txData.height) {
1616+
await ldk.writeToLogFile(
1617+
'error',
1618+
`Tx: ${txid} has no height (not in block). Skipping cleanup.`,
1619+
);
1620+
continue;
1621+
}
1622+
1623+
const numberOfConfirmations =
1624+
this.currentBlock.height - txData.height + 1;
1625+
if (numberOfConfirmations >= 6) {
1626+
await ldk.writeToLogFile(
1627+
'debug',
1628+
`Cleaning up tx: ${txid} with ${numberOfConfirmations} confirmations.`,
1629+
);
1630+
txsToCleanup.push(rawTx);
1631+
} else {
1632+
await ldk.writeToLogFile(
1633+
'debug',
1634+
`Tx: ${txid} with ${numberOfConfirmations} confirmations. Skipping cleanup.`,
1635+
);
1636+
}
1637+
}
1638+
1639+
if (txsToCleanup.length === 0) {
1640+
await ldk.writeToLogFile(
1641+
'debug',
1642+
'No broadcasted transactions found to cleanup.',
1643+
);
1644+
return;
1645+
}
1646+
1647+
//Fetch again in case of another process writing to the file since last lookup.
1648+
const latestSavedTxs = await this.getLdkBroadcastedTxs();
1649+
const txsToKeep = latestSavedTxs.filter((tx) => !txsToCleanup.includes(tx));
1650+
1651+
const saveRes = await ldk.writeToFile({
1652+
fileName: ELdkFiles.broadcasted_transactions,
1653+
content: JSON.stringify(txsToKeep),
1654+
remotePersist: false,
1655+
});
1656+
if (saveRes.isErr()) {
1657+
await ldk.writeToLogFile(
1658+
'error',
1659+
`Failed saving cleaned up txs: ${saveRes.error}`,
1660+
);
1661+
return;
1662+
}
1663+
1664+
//Save the cleanup up txs just in case. They won't ever be loaded automatically.
1665+
let currentConfirmedRawTxs: string[] = [];
1666+
const currentConfirmedRawTxsRes = await ldk.readFromFile({
1667+
fileName: ELdkFiles.confirmed_broadcasted_transactions,
1668+
});
1669+
if (currentConfirmedRawTxsRes.isOk()) {
1670+
currentConfirmedRawTxs = parseData(
1671+
currentConfirmedRawTxsRes.value.content,
1672+
[],
1673+
);
1674+
}
1675+
1676+
await ldk.writeToFile({
1677+
fileName: ELdkFiles.confirmed_broadcasted_transactions,
1678+
content: JSON.stringify(currentConfirmedRawTxs.concat(txsToCleanup)),
1679+
remotePersist: false,
1680+
});
1681+
1682+
await ldk.writeToLogFile(
1683+
'info',
1684+
`Cleaned up ${txsToCleanup.length} broadcasted transactions.`,
1685+
);
1686+
}
1687+
15891688
async rebroadcastAllKnownTransactions(): Promise<any[]> {
15901689
const broadcastedTransactions = await this.getLdkBroadcastedTxs();
15911690
const results = [];

lib/src/utils/helpers.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ export const findOutputsFromRawTxs = (
301301
return result;
302302
};
303303

304+
export const getTxIdFromRawTx = (rawTx: string): string => {
305+
const tx = bitcoin.Transaction.fromHex(rawTx);
306+
return tx.getId();
307+
};
308+
304309
/**
305310
* Pauses execution of a function.
306311
* @param {number} ms The time to wait in milliseconds.

lib/src/utils/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,7 @@ export enum ELdkFiles {
481481
peers = 'peers.json', //File saved from JS
482482
unconfirmed_transactions = 'unconfirmed_transactions.json',
483483
broadcasted_transactions = 'broadcasted_transactions.json',
484+
confirmed_broadcasted_transactions = 'confirmed_broadcasted_transactions.json',
484485
payment_ids = 'payment_ids.json',
485486
spendable_outputs = 'spendable_outputs.json',
486487
payments_claimed = 'payments_claimed.json', // Written in swift/kotlin and read from JS

0 commit comments

Comments
 (0)