@@ -15,11 +15,13 @@ enum InvalidSerializedDataError: Error {
1515public class ChannelManagerConstructor {
1616
1717 public let channelManager : ChannelManager
18+
1819 /**
1920 * The latest block has the channel manager saw. If this is non-null it is a 32-byte block hash.
2021 * You should sync the blockchain starting with the block that builds on this block.
2122 */
2223 public let channel_manager_latest_block_hash : [ UInt8 ] ?
24+
2325 /**
2426 * A list of ChannelMonitors and the last block they each saw. You should sync the blockchain on each individually
2527 * starting with the block that builds on the hash given.
@@ -67,7 +69,7 @@ public class ChannelManagerConstructor {
6769
6870 }
6971
70- /*
72+ /**
7173 * Constructs a channel manager from the given interface implementations
7274 */
7375 public init ( network: LDKNetwork , config: UserConfig , current_blockchain_tip_hash: [ UInt8 ] , current_blockchain_tip_height: UInt32 , keys_interface: KeysInterface , fee_estimator: FeeEstimator , chain_monitor: ChainMonitor , tx_broadcaster: BroadcasterInterface , logger: Logger ) {
@@ -78,5 +80,84 @@ public class ChannelManagerConstructor {
7880 let chainParameters = ChainParameters ( network_arg: network, best_block_arg: block)
7981 self . channelManager = ChannelManager ( fee_est: fee_estimator, chain_monitor: chain_monitor. as_Watch ( ) , tx_broadcaster: tx_broadcaster, logger: logger, keys_manager: keys_interface, config: config, params: chainParameters)
8082 }
83+
84+ var persisterWorkItem : DispatchWorkItem ?
85+ var shutdown = false
86+
87+ /**
88+ * Utility which adds all of the deserialized ChannelMonitors to the chain watch so that further updates from the
89+ * ChannelManager are processed as normal.
90+ *
91+ * This also spawns a background thread which will call the appropriate methods on the provided
92+ * ChannelManagerPersister as required.
93+ */
94+ public func chain_sync_completed( persister: ChannelManagerPersister ) {
95+ if self . persisterWorkItem != nil {
96+ return
97+ }
98+
99+ for (currentChannelMonitor, _) in self . channel_monitors {
100+ let chainMonitorWatch = self . chain_monitor. as_Watch ( )
101+ let fundingTxo = currentChannelMonitor. get_funding_txo ( )
102+ let outPoint = OutPoint ( pointer: fundingTxo. cOpaqueStruct!. a)
103+ chainMonitorWatch. watch_channel ( funding_txo: outPoint, monitor: currentChannelMonitor)
104+ }
105+
106+ self . persisterWorkItem = DispatchWorkItem {
107+ var lastTimerTick = NSDate ( ) . timeIntervalSince1970
108+ while !self . shutdown {
109+ var needsPersist = self . channelManager. await_persistable_update_timeout ( max_wait: 1 )
110+
111+ let rawManagerEvents = self . channelManager. as_EventsProvider ( ) . get_and_clear_pending_events ( )
112+ let managerEvents = rawManagerEvents. map { ( e: LDKEvent ) -> Event in
113+ Event ( pointer: e)
114+ }
115+ if managerEvents. count != 0 {
116+ persister. handle_events ( events: managerEvents)
117+ needsPersist = true
118+ }
119+
120+ let rawMonitorEvents = self . chain_monitor. as_EventsProvider ( ) . get_and_clear_pending_events ( ) ;
121+ let monitorEvents = rawMonitorEvents. map { ( e: LDKEvent ) -> Event in
122+ Event ( pointer: e)
123+ }
124+ if monitorEvents. count != 0 {
125+ persister. handle_events ( events: monitorEvents)
126+ needsPersist = true
127+ }
128+
129+ if needsPersist {
130+ persister. persist_manager ( channel_manager_bytes: self . channelManager. write ( obj: self . channelManager) )
131+ }
132+
133+ if self . shutdown {
134+ return
135+ }
136+
137+ let currentTimerTick = NSDate ( ) . timeIntervalSince1970
138+ if lastTimerTick < ( currentTimerTick- 60 ) { // more than 60 seconds have passed since the last timer tick
139+ self . channelManager. timer_tick_occurred ( )
140+ lastTimerTick = currentTimerTick
141+ }
142+
143+ Thread . sleep ( forTimeInterval: 1 ) // this should hopefully not suspend the main application
144+ }
145+ }
146+
147+ let backgroundQueue = DispatchQueue ( label: " org.ldk.ChannelManagerConstructor.persisterThread " , qos: . background)
148+ backgroundQueue. async ( execute: self . persisterWorkItem!)
149+ }
150+
151+ public func interrupt( ) {
152+ self . shutdown = true
153+ if let workItem = self . persisterWorkItem {
154+ workItem. wait ( )
155+ }
156+ }
157+
158+ }
81159
160+ public protocol ChannelManagerPersister {
161+ func handle_events( events: [ Event ] ) -> Void ;
162+ func persist_manager( channel_manager_bytes: [ UInt8 ] ) -> Void ;
82163}
0 commit comments