@@ -15,11 +15,13 @@ enum InvalidSerializedDataError: Error {
15
15
public class ChannelManagerConstructor {
16
16
17
17
public let channelManager : ChannelManager
18
+
18
19
/**
19
20
* The latest block has the channel manager saw. If this is non-null it is a 32-byte block hash.
20
21
* You should sync the blockchain starting with the block that builds on this block.
21
22
*/
22
23
public let channel_manager_latest_block_hash : [ UInt8 ] ?
24
+
23
25
/**
24
26
* A list of ChannelMonitors and the last block they each saw. You should sync the blockchain on each individually
25
27
* starting with the block that builds on the hash given.
@@ -67,7 +69,7 @@ public class ChannelManagerConstructor {
67
69
68
70
}
69
71
70
- /*
72
+ /**
71
73
* Constructs a channel manager from the given interface implementations
72
74
*/
73
75
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 {
78
80
let chainParameters = ChainParameters ( network_arg: network, best_block_arg: block)
79
81
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)
80
82
}
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
+ }
81
159
160
+ public protocol ChannelManagerPersister {
161
+ func handle_events( events: [ Event ] ) -> Void ;
162
+ func persist_manager( channel_manager_bytes: [ UInt8 ] ) -> Void ;
82
163
}
0 commit comments