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