Skip to content

Commit e8d92c6

Browse files
committed
update channelmanagerconstructor with chain sync complete method
1 parent 4168503 commit e8d92c6

File tree

1 file changed

+82
-1
lines changed

1 file changed

+82
-1
lines changed

bindings/batteries/ChannelManagerConstructor.swift

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ enum InvalidSerializedDataError: Error {
1515
public 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

Comments
 (0)