Merge pull request #45 from TheBlueMatt/main
[ldk-c-bindings] / lightning-c-bindings / demo.cpp
1 extern "C" {
2 #include <lightning.h>
3
4 #ifdef REAL_NET
5 #include <ldk_net.h>
6 #endif
7 }
8 #include "include/lightningpp.hpp"
9
10 #include <assert.h>
11 #include <stdio.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
15 #include <unistd.h>
16
17 #include <atomic>
18 #include <chrono>
19 #include <functional>
20 #include <thread>
21 #include <mutex>
22 #include <vector>
23
24 const uint8_t valid_node_announcement[] = {
25         0x94, 0xe4, 0xf5, 0x61, 0x41, 0x24, 0x7d, 0x90, 0x23, 0xa0, 0xc8, 0x34, 0x8c, 0xc4, 0xca, 0x51,
26         0xd8, 0x17, 0x59, 0xff, 0x7d, 0xac, 0x8c, 0x9b, 0x63, 0x29, 0x1c, 0xe6, 0x12, 0x12, 0x93, 0xbd,
27         0x66, 0x4d, 0x6b, 0x9c, 0xfb, 0x35, 0xda, 0x16, 0x06, 0x3d, 0xf0, 0x8f, 0x8a, 0x39, 0x99, 0xa2,
28         0xf2, 0x5d, 0x12, 0x0f, 0x2b, 0x42, 0x1b, 0x8b, 0x9a, 0xfe, 0x33, 0x0c, 0xeb, 0x33, 0x5e, 0x52,
29         0xee, 0x99, 0xa1, 0x07, 0x06, 0xed, 0xf8, 0x48, 0x7a, 0xc6, 0xe5, 0xf5, 0x5e, 0x01, 0x3a, 0x41,
30         0x2f, 0x18, 0x94, 0x8a, 0x3b, 0x0a, 0x52, 0x3f, 0xbf, 0x61, 0xa9, 0xc5, 0x4f, 0x70, 0xee, 0xb8,
31         0x79, 0x23, 0xbb, 0x1a, 0x44, 0x7d, 0x91, 0xe6, 0x2a, 0xbc, 0xa1, 0x07, 0xbc, 0x65, 0x3b, 0x02,
32         0xd9, 0x1d, 0xb2, 0xf2, 0x3a, 0xcb, 0x75, 0x79, 0xc6, 0x66, 0xd8, 0xc1, 0x71, 0x29, 0xdf, 0x04,
33         0x60, 0xf4, 0xbf, 0x07, 0x7b, 0xb9, 0xc2, 0x11, 0x94, 0x6a, 0x28, 0xc2, 0xdd, 0xd8, 0x7b, 0x44,
34         0x8f, 0x08, 0xe3, 0xc8, 0xd8, 0xf4, 0x81, 0xb0, 0x9f, 0x94, 0xcb, 0xc8, 0xc1, 0x3c, 0xc2, 0x6e,
35         0x31, 0x26, 0xfc, 0x33, 0x16, 0x3b, 0xe0, 0xde, 0xa1, 0x16, 0x21, 0x9f, 0x89, 0xdd, 0x97, 0xa4,
36         0x41, 0xf2, 0x9f, 0x19, 0xb1, 0xae, 0x82, 0xf7, 0x85, 0x9a, 0xb7, 0x8f, 0xb7, 0x52, 0x7a, 0x72,
37         0xf1, 0x5e, 0x89, 0xe1, 0x8a, 0xcd, 0x40, 0xb5, 0x8e, 0xc3, 0xca, 0x42, 0x76, 0xa3, 0x6e, 0x1b,
38         0xf4, 0x87, 0x35, 0x30, 0x58, 0x43, 0x04, 0xd9, 0x2c, 0x50, 0x54, 0x55, 0x47, 0x6f, 0x70, 0x9b,
39         0x42, 0x1f, 0x91, 0xfc, 0xa1, 0xdb, 0x72, 0x53, 0x96, 0xc8, 0xe5, 0xcd, 0x0e, 0xcb, 0xa0, 0xfe,
40         0x6b, 0x08, 0x77, 0x48, 0xb7, 0xad, 0x4a, 0x69, 0x7c, 0xdc, 0xd8, 0x04, 0x28, 0x35, 0x9b, 0x73,
41         0x00, 0x00, 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce,
42         0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00,
43         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82,
44         0x09, 0x67, 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa,
45         0x1d, 0x64, 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, 0x2c, 0x03, 0x5c, 0x4e, 0x0d, 0xec,
46         0x72, 0x15, 0xe2, 0x68, 0x33, 0x93, 0x87, 0x30, 0xe5, 0xe5, 0x05, 0xaa, 0x62, 0x50, 0x4d, 0xa8,
47         0x5b, 0xa5, 0x71, 0x06, 0xa4, 0x6b, 0x5a, 0x24, 0x04, 0xfc, 0x9d, 0x8e, 0x02, 0xba, 0x72, 0xa6,
48         0xe8, 0xba, 0x53, 0xe8, 0xb9, 0x71, 0xad, 0x0c, 0x98, 0x23, 0x96, 0x8a, 0xef, 0x4d, 0x78, 0xce,
49         0x8a, 0xf2, 0x55, 0xab, 0x43, 0xdf, 0xf8, 0x30, 0x03, 0xc9, 0x02, 0xfb, 0x8d, 0x02, 0x16, 0x34,
50         0x5b, 0xf8, 0x31, 0x16, 0x4a, 0x03, 0x75, 0x8e, 0xae, 0xa5, 0xe8, 0xb6, 0x6f, 0xee, 0x2b, 0xe7,
51         0x71, 0x0b, 0x8f, 0x19, 0x0e, 0xe8, 0x80, 0x24, 0x90, 0x32, 0xa2, 0x9e, 0xd6, 0x6e
52 };
53
54 // A simple block containing only one transaction (which is the channel-open transaction for the
55 // channel we'll create). This was originally created by printing additional data in a simple
56 // rust-lightning unit test.
57 const uint8_t channel_open_block[] = {
58         0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60         0x00, 0x00, 0x00, 0x00, 0xa2, 0x47, 0xd2, 0xf8, 0xd4, 0xe0, 0x6a, 0x3f, 0xf9, 0x7a, 0x9a, 0x34,
61         0xbb, 0xa9, 0x96, 0xde, 0x63, 0x84, 0x5a, 0xce, 0xcf, 0x98, 0xb8, 0xbb, 0x75, 0x4c, 0x4f, 0x7d,
62         0xee, 0x4c, 0xa9, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63         0x01, // transaction count
64         0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67         0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0xd1, 0xd9, 0x13, 0xa9,
68         0x76, 0x09, 0x05, 0xa3, 0x4d, 0x13, 0x5b, 0x69, 0xaa, 0xe7, 0x79, 0x71, 0xb9, 0x75, 0xa1, 0xd0,
69         0x77, 0xcb, 0xa2, 0xf6, 0x6a, 0x25, 0x37, 0x3a, 0xaf, 0xdc, 0x11, 0x09, 0x01, 0x00, 0x00, 0x00,
70         0x00, 0x00
71 };
72
73 // The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data.
74 const uint8_t channel_open_txid[] = {
75         0x02, 0xe0, 0x50, 0x05, 0x33, 0xd3, 0x29, 0x66, 0x0c, 0xb2, 0xcb, 0x1e, 0x7a, 0x4a, 0xc7, 0xc7,
76         0x8b, 0x02, 0x46, 0x7e, 0x30, 0x2c, 0xe6, 0x19, 0xce, 0x43, 0x3e, 0xdf, 0x43, 0x65, 0xae, 0xf9,
77 };
78
79 // Two blocks built on top of channel_open_block:
80 const uint8_t block_1[81] = {
81         0x01, 0x00, 0x00, 0x00, 0x0c, 0x7a, 0xc2, 0xdc, 0x08, 0xaf, 0x40, 0x7d, 0x58, 0x81, 0x9b, 0x44,
82         0xc7, 0xe0, 0x0f, 0x78, 0xc0, 0xd1, 0x01, 0xa2, 0x03, 0x16, 0x4a, 0x8d, 0x92, 0x66, 0x4e, 0xaf,
83         0x7f, 0xfc, 0x6e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86         0x00, // transaction count
87 };
88 const uint8_t block_2[81] = {
89         0x01, 0x00, 0x00, 0x00, 0x36, 0x0b, 0xf5, 0x46, 0x4a, 0xc7, 0x26, 0x4c, 0x4b, 0x36, 0xa6, 0x9d,
90         0x0e, 0xf0, 0x14, 0xfb, 0x8a, 0xcb, 0x20, 0x84, 0x18, 0xf3, 0xaa, 0x77, 0x32, 0x2d, 0xf7, 0x48,
91         0x62, 0x92, 0xb1, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94         0x00, // transaction count
95 };
96
97 const LDKThirtyTwoBytes genesis_hash = { // We don't care particularly if this is "right"
98         .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }
99 };
100
101 void print_log(const void *this_arg, const char *record) {
102         printf("%p - %s\n", this_arg, record);
103 }
104
105 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
106         if (target == LDKConfirmationTarget_Background) {
107                 return 253;
108         } else {
109                 return 507;
110         }
111         // Note that we don't call _free() on target, but that's OK, its unitary
112 }
113 // We use the same fee estimator globally:
114 const LDKFeeEstimator fee_est {
115         .this_arg = NULL,
116         .get_est_sat_per_1000_weight = get_fee,
117         .free = NULL,
118 };
119
120 static std::atomic_int num_txs_broadcasted(0);
121 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
122         num_txs_broadcasted += 1;
123         //TODO
124         Transaction_free(tx);
125 }
126
127 struct NodeMonitors {
128         std::mutex mut;
129         std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
130         LDKLogger* logger;
131
132         void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
133                 std::unique_lock<std::mutex> l(mut);
134                 for (auto& mon : mons) {
135                         LDK::CVec_TransactionOutputsZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
136                 }
137         }
138 };
139
140 LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
141         // First bind the args to C++ objects so they auto-free
142         LDK::ChannelMonitor mon(std::move(monitor_arg));
143         LDK::OutPoint funding_txo(std::move(funding_txo_arg));
144
145         NodeMonitors* arg = (NodeMonitors*) this_arg;
146         std::unique_lock<std::mutex> l(arg->mut);
147
148         arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
149         return CResult_NoneChannelMonitorUpdateErrZ_ok();
150 }
151 static std::atomic_int mons_updated(0);
152 LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
153         // First bind the args to C++ objects so they auto-free
154         LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
155         LDK::OutPoint funding_txo(std::move(funding_txo_arg));
156
157         NodeMonitors* arg = (NodeMonitors*) this_arg;
158         std::unique_lock<std::mutex> l(arg->mut);
159
160         bool updated = false;
161         for (auto& mon : arg->mons) {
162                 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
163                                 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
164                         updated = true;
165                         LDKBroadcasterInterface broadcaster = {
166                                 .broadcast_transaction = broadcast_tx,
167                         };
168                         LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger);
169                         assert(res->result_ok);
170                 }
171         }
172         assert(updated);
173
174         mons_updated += 1;
175         return CResult_NoneChannelMonitorUpdateErrZ_ok();
176 }
177 LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
178         NodeMonitors* arg = (NodeMonitors*) this_arg;
179         std::unique_lock<std::mutex> l(arg->mut);
180
181         if (arg->mons.size() == 0) {
182                 return LDKCVec_MonitorEventZ {
183                         .data = NULL,
184                         .datalen = 0,
185                 };
186         } else {
187                 // We only ever actually have one channel per node, plus concatenating two
188                 // Rust Vecs to each other from C++ will require a bit of effort.
189                 assert(arg->mons.size() == 1);
190                 return ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
191         }
192 }
193
194 struct EventQueue {
195         std::vector<LDK::Event> events;
196 };
197 void handle_event(const void *this_arg, const LDKEvent *event) {
198         EventQueue* arg = (EventQueue*) this_arg;
199         arg->events.push_back(Event_clone(event));
200 }
201
202 #ifdef REAL_NET
203 class PeersConnection {
204         void* node1_handler;
205         void* node2_handler;
206
207 public:
208         PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
209                 node1_handler = init_socket_handling(&net1);
210                 node2_handler = init_socket_handling(&net2);
211
212                 struct sockaddr_in listen_addr;
213                 listen_addr.sin_family = AF_INET;
214                 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
215                 listen_addr.sin_port = htons(10042);
216                 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
217
218                 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
219
220                 while (true) {
221                         // Wait for the initial handshakes to complete...
222                         LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
223                         LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
224                         if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
225                         std::this_thread::yield();
226                 }
227
228                 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
229                 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
230                 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
231
232                 // Then disconnect the "main" connection, while another connection is being made.
233                 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
234                 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
235
236                 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
237                 while (true) {
238                         PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
239                         // Wait for the peers to disconnect...
240                         LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
241                         LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
242                         if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
243                         std::this_thread::yield();
244                 }
245                 // Note that the above is somewhat race-y, as node 2 may still think its connected.
246                 // Thus, make sure any connections are disconnected on its end as well.
247                 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1), false);
248
249                 // Finally make an actual connection and keep it this time
250                 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
251
252                 while (true) {
253                         // Wait for the initial handshakes to complete...
254                         LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
255                         LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
256                         if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
257                         std::this_thread::yield();
258                 }
259         }
260         void stop() {
261                 interrupt_socket_handling(node1_handler);
262                 interrupt_socket_handling(node2_handler);
263         }
264 };
265
266 #else // REAL_NET
267
268 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
269         return write((int)((long)this_arg), data.data, data.datalen);
270 }
271 void sock_disconnect_socket(void *this_arg) {
272         close((int)((long)this_arg));
273 }
274 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
275         return this_arg == other_arg->this_arg;
276 }
277 uint64_t sock_hash(const void *this_arg) {
278         return (uint64_t)this_arg;
279 }
280 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
281         unsigned char buf[1024];
282         LDKu8slice data;
283         data.data = buf;
284         ssize_t readlen = 0;
285         while ((readlen = read(rdfd, buf, 1024)) > 0) {
286                 data.datalen = readlen;
287                 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
288                 if (!res->result_ok) {
289                         peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
290                         return;
291                 }
292                 PeerManager_process_events(pm);
293         }
294         PeerManager_socket_disconnected(&*pm, peer_descriptor);
295 }
296
297 class PeersConnection {
298         int pipefds_1_to_2[2];
299         int pipefds_2_to_1[2];
300         std::thread t1, t2;
301         LDKSocketDescriptor sock1, sock2;
302
303 public:
304         PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
305                 assert(!pipe(pipefds_1_to_2));
306                 assert(!pipe(pipefds_2_to_1));
307
308                 sock1 = LDKSocketDescriptor {
309                         .this_arg = (void*)(long)pipefds_1_to_2[1],
310                         .send_data = sock_send_data,
311                         .disconnect_socket = sock_disconnect_socket,
312                         .eq = sock_eq,
313                         .hash = sock_hash,
314                         .cloned = NULL,
315                         .free = NULL,
316                 };
317
318                 sock2 = LDKSocketDescriptor {
319                         .this_arg = (void*)(long)pipefds_2_to_1[1],
320                         .send_data = sock_send_data,
321                         .disconnect_socket = sock_disconnect_socket,
322                         .eq = sock_eq,
323                         .hash = sock_hash,
324                         .cloned = NULL,
325                         .free = NULL,
326                 };
327
328                 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
329                 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
330
331                 // Note that we have to bind the result to a C++ class to make sure it gets free'd
332                 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
333                 assert(con_res->result_ok);
334                 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
335                 assert(con_res2->result_ok);
336
337                 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
338                 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
339
340                 while (true) {
341                         // Wait for the initial handshakes to complete...
342                         LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
343                         LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
344                         if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
345                         std::this_thread::yield();
346                 }
347         }
348
349         void stop() {
350                 close(pipefds_1_to_2[0]);
351                 close(pipefds_2_to_1[0]);
352                 close(pipefds_1_to_2[1]);
353                 close(pipefds_2_to_1[1]);
354                 t1.join();
355                 t2.join();
356         }
357 };
358 #endif // !REAL_NET
359
360 struct CustomMsgQueue {
361         std::vector<LDK::Type> msgs;
362 };
363
364 uint16_t custom_msg_type_id(const void *this_arg) {
365         return 8888;
366 }
367 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
368         uint8_t *bytes = (uint8_t *) malloc(1024);
369         memset(bytes, 42, 1024);
370         return LDKCVec_u8Z {
371                 .data = bytes, .datalen = 1024
372         };
373 }
374 LDKStr custom_msg_debug(const void *this_arg) {
375         return LDKStr {
376                 .chars = NULL, .len = 0, .chars_is_owned = false
377         };
378 }
379
380 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
381         assert(type_id == 8888);
382         assert(buf.datalen == 1024);
383         uint8_t cmp[1024];
384         memset(cmp, 42, 1024);
385         assert(!memcmp(cmp, buf.data, 1024));
386         return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
387                 .this_arg = NULL,
388                 .type_id = custom_msg_type_id,
389                 .debug_str = custom_msg_debug,
390                 .free = NULL,
391         }));
392 }
393
394 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
395         CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
396         arg->msgs.push_back(std::move(msg));
397         return CResult_NoneLightningErrorZ_ok();
398 }
399 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
400         return LDKCVec_C2Tuple_PublicKeyTypeZZ {
401                 .data = NULL, .datalen = 0
402         };
403 }
404
405 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
406         const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
407         LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
408                 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
409                 .datalen = 1
410         };
411         ret.data[0].a = *counterparty_node_id;
412         ret.data[0].b = LDKType {
413                 .this_arg = NULL,
414                 .type_id = custom_msg_type_id,
415                 .debug_str = custom_msg_debug,
416                 .write = custom_msg_bytes,
417                 .free = NULL,
418         };
419         return ret;
420 }
421
422 int main() {
423         uint8_t channel_open_header[80];
424         uint8_t header_1[80];
425         uint8_t header_2[80];
426         memcpy(channel_open_header, channel_open_block, 80);
427         memcpy(header_1, block_1, 80);
428         memcpy(header_2, block_2, 80);
429
430         LDKPublicKey null_pk;
431         memset(&null_pk, 0, sizeof(null_pk));
432
433         LDKThirtyTwoBytes random_bytes;
434         LDKThirtyTwoBytes chain_tip;
435         memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
436
437         LDKNetwork network = LDKNetwork_Testnet;
438
439         // Trait implementations:
440         LDKBroadcasterInterface broadcast {
441                 .this_arg = NULL,
442                 .broadcast_transaction = broadcast_tx,
443                 .free = NULL,
444         };
445
446         // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
447         LDKLogger logger1 {
448                 .this_arg = (void*)1,
449                 .log = print_log,
450                 .free = NULL,
451         };
452
453         NodeMonitors mons1;
454         mons1.logger = &logger1;
455         LDKWatch mon1 {
456                 .this_arg = &mons1,
457                 .watch_channel = add_channel_monitor,
458                 .update_channel = update_channel_monitor,
459                 .release_pending_monitor_events = monitors_pending_monitor_events,
460                 .free = NULL,
461         };
462
463         LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger1);
464         LDKSecretKey node_secret1;
465
466         LDKLogger logger2 {
467                 .this_arg = (void*)2,
468                 .log = print_log,
469                 .free = NULL,
470         };
471
472         NodeMonitors mons2;
473         mons2.logger = &logger2;
474         LDKWatch mon2 {
475                 .this_arg = &mons2,
476                 .watch_channel = add_channel_monitor,
477                 .update_channel = update_channel_monitor,
478                 .release_pending_monitor_events = monitors_pending_monitor_events,
479                 .free = NULL,
480         };
481
482         LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger2);
483         LDKSecretKey node_secret2;
484
485         LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
486         LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
487
488         { // Scope for the ser-des reload
489                 // Instantiate classes for node 1:
490                 uint8_t node_seed[32];
491                 memset(&node_seed, 0, 32);
492                 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
493                 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
494                 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
495
496                 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
497
498                 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
499                 assert(channels->datalen == 0);
500
501                 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
502
503                 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
504                 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
505
506                 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
507                 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
508
509                 // Demo getting a channel key and check that its returning real pubkeys:
510                 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
511                 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
512                 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
513                 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
514
515                 // Instantiate classes for node 2:
516                 memset(&node_seed, 1, 32);
517                 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
518                 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
519                 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
520
521                 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
522                 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
523                 LDK::UserConfig config2 = UserConfig_default();
524                 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
525
526                 LDK::ChannelManager cm2 = ChannelManager_new(fee_est, mon2, broadcast, logger2, KeysManager_as_KeysInterface(&keys2), std::move(config2), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
527
528                 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
529                 assert(channels2->datalen == 0);
530
531                 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
532                 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
533                 assert(chan_ann->result_ok);
534                 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
535                 assert(ann_res->result_ok);
536
537                 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
538
539                 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
540                 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
541
542                 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
543                 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
544
545                 // Open a connection!
546                 PeersConnection conn(cm1, cm2, net1, net2);
547
548                 // Note that we have to bind the result to a C++ class to make sure it gets free'd
549                 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
550                 assert(res->result_ok);
551                 PeerManager_process_events(&net1);
552
553                 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
554                 assert(new_channels->datalen == 1);
555                 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
556                 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
557                 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
558
559                 while (true) {
560                         LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
561                         if (new_channels_2->datalen == 1) {
562                                 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
563                                 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
564                                 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
565                                 assert(init_feats->inner != NULL);
566                                 break;
567                         }
568                         std::this_thread::yield();
569                 }
570
571                 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
572                 while (true) {
573                         EventQueue queue;
574                         LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
575                         ev1.process_pending_events(ev1.this_arg, handler);
576                         if (queue.events.size() == 1) {
577                                 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
578                                 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
579                                 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
580                                 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
581                                 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
582                                 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
583
584                                 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
585                                 assert(fund_res->result_ok);
586                                 break;
587                         }
588                         std::this_thread::yield();
589                 }
590
591                 // We observe when the funding signed messages have been exchanged by
592                 // waiting for two monitors to be registered.
593                 assert(num_txs_broadcasted == 0);
594                 PeerManager_process_events(&net1);
595                 while (num_txs_broadcasted != 1) {
596                         std::this_thread::yield();
597                 }
598
599                 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
600                 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
601
602                 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
603                 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
604
605                 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
606                 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
607                 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
608
609                 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
610                 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
611                 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
612
613                 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
614                 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
615                 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
616                 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
617
618                 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
619                 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
620                 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
621                 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
622
623                 PeerManager_process_events(&net1);
624                 PeerManager_process_events(&net2);
625
626                 // Now send funds from 1 to 2!
627                 uint64_t channel_scid;
628                 while (true) {
629                         LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
630                         if (outbound_channels->datalen == 1) {
631                                 const LDKChannelDetails *channel = &outbound_channels->data[0];
632                                 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
633                                 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
634                                 uint8_t expected_chan_id[32];
635                                 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
636                                 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
637                                 assert(!memcmp(
638                                         ChannelCounterparty_get_node_id(&counterparty).compressed_form,
639                                         ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
640                                 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
641                                 // We opened the channel with 1000 push_msat:
642                                 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
643                                         40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
644                                 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
645                                 if (inbound_capacity < 0) inbound_capacity = 0;
646                                 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
647                                 assert(ChannelDetails_get_is_usable(channel));
648                                 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
649                                 assert(scid_opt->some);
650                                 channel_scid = scid_opt->some;
651                                 break;
652                         }
653                         std::this_thread::yield();
654                 }
655
656                 LDKCOption_u64Z min_value = {
657                         .tag = LDKCOption_u64Z_Some,
658                         .some = 5000,
659                 };
660                 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
661                         KeysManager_as_KeysInterface(&keys2),
662                         LDKCurrency_Bitcoin, min_value,
663                         LDKStr {
664                                 .chars = (const uint8_t *)"Invoice Description",
665                                 .len =             strlen("Invoice Description"),
666                                 .chars_is_owned = false
667                         });
668                 assert(invoice->result_ok);
669                 LDKThirtyTwoBytes payment_hash;
670                 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
671
672                 {
673                         LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
674                         LDK::NetworkGraph graph_2_ref = NetGraphMsgHandler_get_network_graph(&net_graph2);
675                         LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
676                                         .inner = NULL, .is_owned = false
677                                 }, &outbound_channels, Invoice_route_hints(invoice->contents.result),
678                                 5000, Invoice_min_final_cltv_expiry(invoice->contents.result), logger1);
679                         assert(route->result_ok);
680                         LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
681                         assert(paths->datalen == 1);
682                         assert(paths->data[0].datalen == 1);
683                         assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
684                                 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
685                         assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
686                         LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, Invoice_payment_secret(invoice->contents.result));
687                         assert(send_res->result_ok);
688                 }
689
690                 mons_updated = 0;
691                 PeerManager_process_events(&net1);
692                 while (mons_updated != 4) {
693                         std::this_thread::yield();
694                 }
695
696                 // Check that we received the payment!
697                 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
698                 while (true) {
699                         EventQueue queue;
700                         LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
701                         ev2.process_pending_events(ev2.this_arg, handler);
702                         if (queue.events.size() == 1) {
703                                 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
704                                 break;
705                         }
706                         std::this_thread::yield();
707                 }
708                 ChannelManager_process_pending_htlc_forwards(&cm2);
709                 PeerManager_process_events(&net2);
710
711                 mons_updated = 0;
712                 LDKThirtyTwoBytes payment_preimage;
713                 {
714                         EventQueue queue;
715                         LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
716                         ev2.process_pending_events(ev2.this_arg, handler);
717                         assert(queue.events.size() == 1);
718                         assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
719                         assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
720                         assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
721                         assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
722                                         Invoice_payment_secret(invoice->contents.result).data, 32));
723                         assert(queue.events[0]->payment_received.amt == 5000);
724                         memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
725                         assert(ChannelManager_claim_funds(&cm2, payment_preimage));
726                 }
727                 PeerManager_process_events(&net2);
728                 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
729                 while (mons_updated != 5) {
730                         std::this_thread::yield();
731                 }
732                 {
733                         EventQueue queue;
734                         LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
735                         ev1.process_pending_events(ev1.this_arg, handler);
736                         assert(queue.events.size() == 1);
737                         assert(queue.events[0]->tag == LDKEvent_PaymentSent);
738                         assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
739                 }
740
741                 conn.stop();
742
743                 cm1_ser = ChannelManager_write(&cm1);
744                 cm2_ser = ChannelManager_write(&cm2);
745         }
746
747         LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
748         assert(mons1.mons.size() == 1);
749         mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
750         mons_list1->data[0].is_owned = false; // XXX: God this sucks
751         uint8_t node_seed[32];
752         memset(&node_seed, 0, 32);
753         LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
754         LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
755
756         LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
757         LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
758                 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
759         assert(cm1_read->result_ok);
760         LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
761
762         LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
763         assert(mons2.mons.size() == 1);
764         mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
765         mons_list2->data[0].is_owned = false; // XXX: God this sucks
766         memset(&node_seed, 1, 32);
767         LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
768
769         LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
770         LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
771                 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
772         assert(cm2_read->result_ok);
773         LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
774
775         // Attempt to close the channel...
776         uint8_t chan_id[32];
777         for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
778         LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
779         assert(!close_res->result_ok); // Note that we can't close while disconnected!
780
781         // Open a connection!
782         LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
783         random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
784
785         LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
786         LDKCustomMessageHandler custom_msg_handler1 = {
787                 .this_arg = &chan_2_node_id,
788                 .handle_custom_message = NULL, // We only create custom messages, not handle them
789                 .get_and_clear_pending_msg = create_custom_msg,
790                 .CustomMessageReader = LDKCustomMessageReader {
791                         .this_arg = NULL,
792                         .read = read_custom_message,
793                         .free = NULL,
794                 },
795                 .free = NULL,
796         };
797         LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
798
799         LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
800         CustomMsgQueue peer_2_custom_messages;
801         LDKCustomMessageHandler custom_msg_handler2 = {
802                 .this_arg = &peer_2_custom_messages,
803                 .handle_custom_message = handle_custom_message,
804                 .get_and_clear_pending_msg = never_send_custom_msgs,
805                 .CustomMessageReader = LDKCustomMessageReader {
806                         .this_arg = NULL,
807                         .read = read_custom_message,
808                         .free = NULL,
809                 },
810                 .free = NULL,
811         };
812         random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
813         LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
814
815         PeersConnection conn(cm1, cm2, net1, net2);
816
817         while (true) {
818                 // Wait for the channels to be considered up once the reestablish messages are processed
819                 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
820                 if (outbound_channels->datalen == 1) {
821                         break;
822                 }
823         }
824
825         // Actually close the channel
826         num_txs_broadcasted = 0;
827         close_res = ChannelManager_close_channel(&cm1, &chan_id);
828         assert(close_res->result_ok);
829         PeerManager_process_events(&net1);
830         while (num_txs_broadcasted != 2) {
831                 std::this_thread::yield();
832         }
833         LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
834         assert(chans_after_close1->datalen == 0);
835         LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
836         assert(chans_after_close2->datalen == 0);
837
838         conn.stop();
839
840         assert(peer_2_custom_messages.msgs.size() != 0);
841
842         // Few extra random tests:
843         LDKSecretKey sk;
844         memset(&sk, 42, 32);
845         LDKThirtyTwoBytes kdiv_params;
846         memset(&kdiv_params, 43, 32);
847         LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);
848 }