@@ -61,6 +61,7 @@ import {
6161import {
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 = [ ] ;
0 commit comments