|
| 1 | +// |
| 2 | +// HumanObjectPeerTestInstance.swift |
| 3 | +// LDKConsumerExperiment |
| 4 | +// |
| 5 | +// Created by Arik Sosman on 7/22/21. |
| 6 | +// |
| 7 | + |
| 8 | +import Foundation |
| 9 | +import LDKSwift |
| 10 | +import LDKCHeaders |
| 11 | + |
| 12 | +public class HumanObjectPeerTestInstance { |
| 13 | + |
| 14 | + private let nice_close: Bool; |
| 15 | + private let use_km_wrapper: Bool; |
| 16 | + private let use_manual_watch: Bool; |
| 17 | + private let reload_peers: Bool; |
| 18 | + private let break_cross_peer_refs: Bool; |
| 19 | + private let use_nio_peer_handler: Bool; |
| 20 | + private let use_filter: Bool; |
| 21 | + private let use_chan_manager_constructor: Bool; |
| 22 | + |
| 23 | + |
| 24 | + public init(nice_close: Bool, use_km_wrapper: Bool, use_manual_watch: Bool, reload_peers: Bool, break_cross_peer_refs: Bool, use_nio_peer_handler: Bool, use_filter: Bool, use_chan_manager_constructor: Bool) { |
| 25 | + self.nice_close = nice_close |
| 26 | + self.use_km_wrapper = use_km_wrapper |
| 27 | + self.use_manual_watch = use_manual_watch |
| 28 | + self.reload_peers = reload_peers |
| 29 | + self.break_cross_peer_refs = break_cross_peer_refs |
| 30 | + self.use_nio_peer_handler = use_nio_peer_handler |
| 31 | + self.use_filter = use_filter |
| 32 | + self.use_chan_manager_constructor = use_chan_manager_constructor |
| 33 | + } |
| 34 | + |
| 35 | + fileprivate class Peer { |
| 36 | + |
| 37 | + private(set) var txBroadcaster: BroadcasterInterface! |
| 38 | + let master: HumanObjectPeerTestInstance |
| 39 | + let logger: Logger |
| 40 | + let feeEstimator: FeeEstimator |
| 41 | + let seed: UInt8 |
| 42 | + var filterAdditions: Set<String> |
| 43 | + let monitors: [String: ChannelMonitor] |
| 44 | + private(set) var filter: Filter! |
| 45 | + private(set) var keysInterface: KeysInterface! |
| 46 | + private(set) var explicitKeysManager: KeysManager? |
| 47 | + private(set) var router: NetGraphMsgHandler! |
| 48 | + private(set) var channelManager: ChannelManager! |
| 49 | + private(set) var peerManager: PeerManager! |
| 50 | + |
| 51 | + |
| 52 | + private(set) var constructor: ChannelManagerConstructor? |
| 53 | + private(set) var tcpSocketHandler: TCPPeerHandler? |
| 54 | + private(set) var tcpPort: UInt16? |
| 55 | + |
| 56 | + private(set) var pendingManagerEvents: [Event] = [] |
| 57 | + private(set) var nodeId: [UInt8]? |
| 58 | + |
| 59 | + var chainWatch: Watch? |
| 60 | + var chainMonitor: ChainMonitor? |
| 61 | + |
| 62 | + fileprivate class TestBroadcaster: BroadcasterInterface { |
| 63 | + let master: Peer |
| 64 | + fileprivate init(master: Peer){ |
| 65 | + self.master = master |
| 66 | + super.init() |
| 67 | + } |
| 68 | + } |
| 69 | + |
| 70 | + fileprivate class TestFilter: Filter { |
| 71 | + |
| 72 | + let master: Peer |
| 73 | + |
| 74 | + fileprivate init(master: Peer) { |
| 75 | + self.master = master |
| 76 | + super.init() |
| 77 | + } |
| 78 | + override func register_output(output: WatchedOutput) -> Option_C2Tuple_usizeTransactionZZ { |
| 79 | + self.master.filterAdditions.insert("\(output.get_outpoint().get_txid()):\(output.get_outpoint().get_index())") |
| 80 | + return Option_C2Tuple_usizeTransactionZZ(value: nil) |
| 81 | + } |
| 82 | + override func register_tx(txid: [UInt8]?, script_pubkey: [UInt8]) { |
| 83 | + self.master.filterAdditions.insert("\(txid)") |
| 84 | + } |
| 85 | + } |
| 86 | + |
| 87 | + fileprivate class TestKeysInterface: KeysInterface { |
| 88 | + |
| 89 | + let master: Peer |
| 90 | + let interface: KeysInterface |
| 91 | + |
| 92 | + fileprivate init(master: Peer, underlyingInterface: KeysInterface){ |
| 93 | + self.master = master |
| 94 | + self.interface = underlyingInterface |
| 95 | + super.init() |
| 96 | + } |
| 97 | + |
| 98 | + override func get_channel_signer(inbound: Bool, channel_value_satoshis: UInt64) -> Sign { |
| 99 | + let ck = self.interface.get_channel_signer(inbound: inbound, channel_value_satoshis: channel_value_satoshis) |
| 100 | + // add to must free objects |
| 101 | + return ck |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + fileprivate class TestChannelManagerPersister: ChannelManagerPersister, ExtendedChannelManagerPersister { |
| 106 | + |
| 107 | + let master: Peer |
| 108 | + |
| 109 | + fileprivate init(master: Peer) { |
| 110 | + self.master = master |
| 111 | + super.init() |
| 112 | + } |
| 113 | + |
| 114 | + func handle_event(event: Event) { |
| 115 | + master.pendingManagerEvents.append(event) |
| 116 | + } |
| 117 | + |
| 118 | + } |
| 119 | + |
| 120 | + fileprivate class TestPersister: Persist { |
| 121 | + override func persist_new_channel(id: OutPoint, data: ChannelMonitor) -> Result_NoneChannelMonitorUpdateErrZ { |
| 122 | + return Result_NoneChannelMonitorUpdateErrZ() |
| 123 | + } |
| 124 | + override func update_persisted_channel(id: OutPoint, update: ChannelMonitorUpdate, data: ChannelMonitor) -> Result_NoneChannelMonitorUpdateErrZ { |
| 125 | + return Result_NoneChannelMonitorUpdateErrZ() |
| 126 | + } |
| 127 | + } |
| 128 | + |
| 129 | + fileprivate init(master: HumanObjectPeerTestInstance, _dummy: Any, seed: UInt8) { |
| 130 | + |
| 131 | + self.master = master |
| 132 | + self.logger = MyLogger() |
| 133 | + self.feeEstimator = MyFeeEstimator() |
| 134 | + self.monitors = [String: ChannelMonitor]() |
| 135 | + self.seed = seed |
| 136 | + let persister = TestPersister() |
| 137 | + self.filterAdditions = Set<String>() |
| 138 | + |
| 139 | + self.txBroadcaster = TestBroadcaster(master: self) |
| 140 | + |
| 141 | + if master.use_filter { |
| 142 | + self.filter = TestFilter(master: self) |
| 143 | + } |
| 144 | + |
| 145 | + if master.use_manual_watch || false { // don't support manual watch yet |
| 146 | + // self.chainMonitor |
| 147 | + }else{ |
| 148 | + self.chainMonitor = ChainMonitor(chain_source: self.filter, broadcaster: self.txBroadcaster, logger: self.logger, feeest: self.feeEstimator, persister: persister) |
| 149 | + self.chainWatch = self.chainMonitor!.as_Watch() |
| 150 | + } |
| 151 | + |
| 152 | + var keySeed = [UInt8](repeating: 0, count: 32) |
| 153 | + for i in 0..<32 { |
| 154 | + keySeed[i] = UInt8(i) ^ seed |
| 155 | + } |
| 156 | + |
| 157 | + let timestamp_seconds = UInt64(NSDate().timeIntervalSince1970) |
| 158 | + let timestamp_nanos = UInt32(truncating: NSNumber(value: timestamp_seconds * 1000 * 1000)) |
| 159 | + let keysManager = KeysManager(seed: keySeed, starting_time_secs: timestamp_seconds, starting_time_nanos: timestamp_nanos) |
| 160 | + |
| 161 | + if master.use_km_wrapper { |
| 162 | + // self.keysInterface = manual_ |
| 163 | + }else { |
| 164 | + self.keysInterface = keysManager.as_KeysInterface() |
| 165 | + self.explicitKeysManager = keysManager |
| 166 | + } |
| 167 | + |
| 168 | + self.router = NetGraphMsgHandler(chain_access: nil, logger: self.logger, network_graph: NetworkGraph(genesis_hash: [UInt8](repeating: 0, count: 32))) |
| 169 | + |
| 170 | + } |
| 171 | + |
| 172 | + fileprivate convenience init (master: HumanObjectPeerTestInstance, seed: UInt8) { |
| 173 | + self.init(master: master, _dummy: (), seed: seed) |
| 174 | + |
| 175 | + if master.use_chan_manager_constructor { |
| 176 | + self.constructor = ChannelManagerConstructor(network: LDKNetwork_Bitcoin, config: UserConfig(), current_blockchain_tip_hash: [UInt8](repeating: 0, count: 32), current_blockchain_tip_height: 0, keys_interface: self.keysInterface, fee_estimator: self.feeEstimator, chain_monitor: self.chainMonitor!, router: self.router, tx_broadcaster: self.txBroadcaster, logger: self.logger) |
| 177 | + self.constructor?.chain_sync_completed(persister: TestChannelManagerPersister(master: self)) |
| 178 | + self.channelManager = self.constructor!.channelManager |
| 179 | + self.peerManager = self.constructor!.peerManager |
| 180 | + } else { |
| 181 | + let chainParameters = ChainParameters(network_arg: LDKNetwork_Bitcoin, best_block_arg: BestBlock(block_hash: [UInt8](repeating: 0, count: 32), height: 0)) |
| 182 | + self.channelManager = ChannelManager(fee_est: self.feeEstimator, chain_monitor: self.chainWatch!, tx_broadcaster: self.txBroadcaster, logger: self.logger, keys_manager: self.keysInterface, config: UserConfig(), params: chainParameters) |
| 183 | + let randomData = self.keysInterface.get_secure_random_bytes() |
| 184 | + let messageHandler = MessageHandler(chan_handler_arg: self.channelManager.as_ChannelMessageHandler(), route_handler_arg: self.router.as_RoutingMessageHandler()) |
| 185 | + PeerManager(message_handler: messageHandler, our_node_secret: self.keysInterface.get_node_secret(), ephemeral_random_data: randomData, logger: self.logger) |
| 186 | + } |
| 187 | + self.nodeId = self.channelManager.get_our_node_id() |
| 188 | + self.bindSocketHandler() |
| 189 | + } |
| 190 | + |
| 191 | + fileprivate convenience init (original: Peer) { |
| 192 | + self.init(master: original.master, _dummy: (), seed: original.seed) |
| 193 | + |
| 194 | + if master.use_chan_manager_constructor { |
| 195 | + self.constructor = ChannelManagerConstructor(network: LDKNetwork_Bitcoin, config: UserConfig(), current_blockchain_tip_hash: [UInt8](repeating: 0, count: 32), current_blockchain_tip_height: 0, keys_interface: self.keysInterface, fee_estimator: self.feeEstimator, chain_monitor: self.chainMonitor!, router: self.router, tx_broadcaster: self.txBroadcaster, logger: self.logger) |
| 196 | + self.constructor?.chain_sync_completed(persister: TestChannelManagerPersister(master: self)) |
| 197 | + self.channelManager = self.constructor!.channelManager |
| 198 | + self.peerManager = self.constructor!.peerManager |
| 199 | + self.pendingManagerEvents.append(contentsOf: original.pendingManagerEvents) |
| 200 | + } else { |
| 201 | + var monitors: [ChannelMonitor] = [] |
| 202 | + var nativeMonitors: [LDKChannelMonitor] = [] |
| 203 | + // let serialized = original.monitors[0].wr |
| 204 | + let serializedManager = original.channelManager.write(obj: original.channelManager) |
| 205 | + let managerResult = UtilMethods.constructor_BlockHashChannelManagerZ_read(ser: serializedManager, arg_keys_manager: self.keysInterface, arg_fee_estimator: self.feeEstimator, arg_chain_monitor: self.chainWatch!, arg_tx_broadcaster: self.txBroadcaster, arg_logger: self.logger, arg_default_config: UserConfig(), arg_channel_monitors: nativeMonitors) |
| 206 | + assert(managerResult.isOk()) |
| 207 | + managerResult.getValue()! |
| 208 | + } |
| 209 | + self.nodeId = self.channelManager.get_our_node_id() |
| 210 | + self.bindSocketHandler() |
| 211 | + } |
| 212 | + |
| 213 | + private func bindSocketHandler() { |
| 214 | + if !self.master.use_nio_peer_handler { |
| 215 | + return |
| 216 | + } |
| 217 | + self.tcpSocketHandler = TCPPeerHandler(peerManager: self.peerManager) |
| 218 | + for i in 0...10000 { |
| 219 | + let port = UInt16(i) |
| 220 | + let bound = self.tcpSocketHandler!.bind(address: "127.0.0.1", port: port) |
| 221 | + if bound { |
| 222 | + self.tcpPort = port |
| 223 | + return |
| 224 | + } |
| 225 | + } |
| 226 | + } |
| 227 | + |
| 228 | + fileprivate func getManualWatch() { |
| 229 | + |
| 230 | + } |
| 231 | + |
| 232 | + } |
| 233 | + |
| 234 | + func do_read_event(pm: PeerManager, descriptor: SocketDescriptor, data: [UInt8]) { |
| 235 | + let res = pm.read_event(peer_descriptor: descriptor, data: data) |
| 236 | + assert(res.isOk()) |
| 237 | + } |
| 238 | + |
| 239 | + |
| 240 | + fileprivate func connectPeers(peerA: Peer, peerB: Peer) { |
| 241 | + if self.use_nio_peer_handler { |
| 242 | + let connectionResult = peerA.tcpSocketHandler?.connect(address: "127.0.0.1", port: peerB.tcpPort!, theirNodeId: peerB.nodeId!) |
| 243 | + print("connection result: \(connectionResult)") |
| 244 | + }else{ |
| 245 | + // not currently relevant; we need the TCP connection simulation |
| 246 | + } |
| 247 | + } |
| 248 | + |
| 249 | + func do_test_message_handler() { |
| 250 | + let peer1 = Peer(master: self, seed: 1) |
| 251 | + let peer2 = Peer(master: self, seed: 2) |
| 252 | + |
| 253 | + connectPeers(peerA: peer1, peerB: peer2) |
| 254 | + } |
| 255 | + |
| 256 | +} |
0 commit comments