Merge pull request #43 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
246                 // Finally make an actual connection and keep it this time
247                 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
248
249                 while (true) {
250                         // Wait for the initial handshakes to complete...
251                         LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
252                         LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
253                         if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
254                         std::this_thread::yield();
255                 }
256         }
257         void stop() {
258                 interrupt_socket_handling(node1_handler);
259                 interrupt_socket_handling(node2_handler);
260         }
261 };
262
263 #else // REAL_NET
264
265 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
266         return write((int)((long)this_arg), data.data, data.datalen);
267 }
268 void sock_disconnect_socket(void *this_arg) {
269         close((int)((long)this_arg));
270 }
271 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
272         return this_arg == other_arg->this_arg;
273 }
274 uint64_t sock_hash(const void *this_arg) {
275         return (uint64_t)this_arg;
276 }
277 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
278         unsigned char buf[1024];
279         LDKu8slice data;
280         data.data = buf;
281         ssize_t readlen = 0;
282         while ((readlen = read(rdfd, buf, 1024)) > 0) {
283                 data.datalen = readlen;
284                 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
285                 if (!res->result_ok) {
286                         peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
287                         return;
288                 }
289                 PeerManager_process_events(pm);
290         }
291         PeerManager_socket_disconnected(&*pm, peer_descriptor);
292 }
293
294 class PeersConnection {
295         int pipefds_1_to_2[2];
296         int pipefds_2_to_1[2];
297         std::thread t1, t2;
298         LDKSocketDescriptor sock1, sock2;
299
300 public:
301         PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
302                 assert(!pipe(pipefds_1_to_2));
303                 assert(!pipe(pipefds_2_to_1));
304
305                 sock1 = LDKSocketDescriptor {
306                         .this_arg = (void*)(long)pipefds_1_to_2[1],
307                         .send_data = sock_send_data,
308                         .disconnect_socket = sock_disconnect_socket,
309                         .eq = sock_eq,
310                         .hash = sock_hash,
311                         .cloned = NULL,
312                         .free = NULL,
313                 };
314
315                 sock2 = LDKSocketDescriptor {
316                         .this_arg = (void*)(long)pipefds_2_to_1[1],
317                         .send_data = sock_send_data,
318                         .disconnect_socket = sock_disconnect_socket,
319                         .eq = sock_eq,
320                         .hash = sock_hash,
321                         .cloned = NULL,
322                         .free = NULL,
323                 };
324
325                 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
326                 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
327
328                 // Note that we have to bind the result to a C++ class to make sure it gets free'd
329                 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
330                 assert(con_res->result_ok);
331                 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
332                 assert(con_res2->result_ok);
333
334                 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
335                 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
336
337                 while (true) {
338                         // Wait for the initial handshakes to complete...
339                         LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
340                         LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
341                         if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
342                         std::this_thread::yield();
343                 }
344         }
345
346         void stop() {
347                 close(pipefds_1_to_2[0]);
348                 close(pipefds_2_to_1[0]);
349                 close(pipefds_1_to_2[1]);
350                 close(pipefds_2_to_1[1]);
351                 t1.join();
352                 t2.join();
353         }
354 };
355 #endif // !REAL_NET
356
357 struct CustomMsgQueue {
358         std::vector<LDK::Type> msgs;
359 };
360
361 uint16_t custom_msg_type_id(const void *this_arg) {
362         return 8888;
363 }
364 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
365         uint8_t *bytes = (uint8_t *) malloc(1024);
366         memset(bytes, 42, 1024);
367         return LDKCVec_u8Z {
368                 .data = bytes, .datalen = 1024
369         };
370 }
371 LDKStr custom_msg_debug(const void *this_arg) {
372         return LDKStr {
373                 .chars = NULL, .len = 0, .chars_is_owned = false
374         };
375 }
376
377 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
378         assert(type_id == 8888);
379         assert(buf.datalen == 1024);
380         uint8_t cmp[1024];
381         memset(cmp, 42, 1024);
382         assert(!memcmp(cmp, buf.data, 1024));
383         return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
384                 .this_arg = NULL,
385                 .type_id = custom_msg_type_id,
386                 .debug_str = custom_msg_debug,
387                 .free = NULL,
388         }));
389 }
390
391 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
392         CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
393         arg->msgs.push_back(std::move(msg));
394         return CResult_NoneLightningErrorZ_ok();
395 }
396 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
397         return LDKCVec_C2Tuple_PublicKeyTypeZZ {
398                 .data = NULL, .datalen = 0
399         };
400 }
401
402 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
403         const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
404         LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
405                 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
406                 .datalen = 1
407         };
408         ret.data[0].a = *counterparty_node_id;
409         ret.data[0].b = LDKType {
410                 .this_arg = NULL,
411                 .type_id = custom_msg_type_id,
412                 .debug_str = custom_msg_debug,
413                 .write = custom_msg_bytes,
414                 .free = NULL,
415         };
416         return ret;
417 }
418
419 int main() {
420         uint8_t channel_open_header[80];
421         uint8_t header_1[80];
422         uint8_t header_2[80];
423         memcpy(channel_open_header, channel_open_block, 80);
424         memcpy(header_1, block_1, 80);
425         memcpy(header_2, block_2, 80);
426
427         LDKPublicKey null_pk;
428         memset(&null_pk, 0, sizeof(null_pk));
429
430         LDKThirtyTwoBytes random_bytes;
431         LDKThirtyTwoBytes chain_tip;
432         memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
433
434         LDKNetwork network = LDKNetwork_Testnet;
435
436         // Trait implementations:
437         LDKBroadcasterInterface broadcast {
438                 .this_arg = NULL,
439                 .broadcast_transaction = broadcast_tx,
440                 .free = NULL,
441         };
442
443         // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
444         LDKLogger logger1 {
445                 .this_arg = (void*)1,
446                 .log = print_log,
447                 .free = NULL,
448         };
449
450         NodeMonitors mons1;
451         mons1.logger = &logger1;
452         LDKWatch mon1 {
453                 .this_arg = &mons1,
454                 .watch_channel = add_channel_monitor,
455                 .update_channel = update_channel_monitor,
456                 .release_pending_monitor_events = monitors_pending_monitor_events,
457                 .free = NULL,
458         };
459
460         LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger1);
461         LDKSecretKey node_secret1;
462
463         LDKLogger logger2 {
464                 .this_arg = (void*)2,
465                 .log = print_log,
466                 .free = NULL,
467         };
468
469         NodeMonitors mons2;
470         mons2.logger = &logger2;
471         LDKWatch mon2 {
472                 .this_arg = &mons2,
473                 .watch_channel = add_channel_monitor,
474                 .update_channel = update_channel_monitor,
475                 .release_pending_monitor_events = monitors_pending_monitor_events,
476                 .free = NULL,
477         };
478
479         LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger2);
480         LDKSecretKey node_secret2;
481
482         LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
483         LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
484
485         { // Scope for the ser-des reload
486                 // Instantiate classes for node 1:
487                 uint8_t node_seed[32];
488                 memset(&node_seed, 0, 32);
489                 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
490                 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
491                 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
492
493                 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
494
495                 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
496                 assert(channels->datalen == 0);
497
498                 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
499
500                 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
501                 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
502
503                 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
504                 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
505
506                 // Demo getting a channel key and check that its returning real pubkeys:
507                 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
508                 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
509                 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
510                 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
511
512                 // Instantiate classes for node 2:
513                 memset(&node_seed, 1, 32);
514                 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
515                 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
516                 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
517
518                 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
519                 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
520                 LDK::UserConfig config2 = UserConfig_default();
521                 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
522
523                 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)));
524
525                 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
526                 assert(channels2->datalen == 0);
527
528                 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
529                 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
530                 assert(chan_ann->result_ok);
531                 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
532                 assert(ann_res->result_ok);
533
534                 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
535
536                 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
537                 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
538
539                 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
540                 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
541
542                 // Open a connection!
543                 PeersConnection conn(cm1, cm2, net1, net2);
544
545                 // Note that we have to bind the result to a C++ class to make sure it gets free'd
546                 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
547                 assert(res->result_ok);
548                 PeerManager_process_events(&net1);
549
550                 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
551                 assert(new_channels->datalen == 1);
552                 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
553                 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
554                 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
555
556                 while (true) {
557                         LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
558                         if (new_channels_2->datalen == 1) {
559                                 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
560                                 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
561                                 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
562                                 assert(init_feats->inner != NULL);
563                                 break;
564                         }
565                         std::this_thread::yield();
566                 }
567
568                 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
569                 while (true) {
570                         EventQueue queue;
571                         LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
572                         ev1.process_pending_events(ev1.this_arg, handler);
573                         if (queue.events.size() == 1) {
574                                 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
575                                 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
576                                 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
577                                 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
578                                 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
579                                 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
580
581                                 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
582                                 assert(fund_res->result_ok);
583                                 break;
584                         }
585                         std::this_thread::yield();
586                 }
587
588                 // We observe when the funding signed messages have been exchanged by
589                 // waiting for two monitors to be registered.
590                 assert(num_txs_broadcasted == 0);
591                 PeerManager_process_events(&net1);
592                 while (num_txs_broadcasted != 1) {
593                         std::this_thread::yield();
594                 }
595
596                 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
597                 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
598
599                 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
600                 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
601
602                 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
603                 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
604                 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
605
606                 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
607                 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
608                 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
609
610                 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
611                 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
612                 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
613                 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
614
615                 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
616                 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
617                 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
618                 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
619
620                 PeerManager_process_events(&net1);
621                 PeerManager_process_events(&net2);
622
623                 // Now send funds from 1 to 2!
624                 uint64_t channel_scid;
625                 while (true) {
626                         LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
627                         if (outbound_channels->datalen == 1) {
628                                 const LDKChannelDetails *channel = &outbound_channels->data[0];
629                                 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
630                                 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
631                                 uint8_t expected_chan_id[32];
632                                 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
633                                 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
634                                 assert(!memcmp(
635                                         ChannelCounterparty_get_node_id(&counterparty).compressed_form,
636                                         ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
637                                 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
638                                 // We opened the channel with 1000 push_msat:
639                                 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
640                                         40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
641                                 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
642                                 if (inbound_capacity < 0) inbound_capacity = 0;
643                                 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
644                                 assert(ChannelDetails_get_is_usable(channel));
645                                 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
646                                 assert(scid_opt->some);
647                                 channel_scid = scid_opt->some;
648                                 break;
649                         }
650                         std::this_thread::yield();
651                 }
652
653                 LDKCOption_u64Z min_value = {
654                         .tag = LDKCOption_u64Z_Some,
655                         .some = 5000,
656                 };
657                 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
658                         KeysManager_as_KeysInterface(&keys2),
659                         LDKCurrency_Bitcoin, min_value,
660                         LDKStr {
661                                 .chars = (const uint8_t *)"Invoice Description",
662                                 .len =             strlen("Invoice Description"),
663                                 .chars_is_owned = false
664                         });
665                 assert(invoice->result_ok);
666                 LDKThirtyTwoBytes payment_hash;
667                 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
668
669                 {
670                         LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
671                         LDK::NetworkGraph graph_2_ref = NetGraphMsgHandler_get_network_graph(&net_graph2);
672                         LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
673                                         .inner = NULL, .is_owned = false
674                                 }, &outbound_channels, Invoice_route_hints(invoice->contents.result),
675                                 5000, Invoice_min_final_cltv_expiry(invoice->contents.result), logger1);
676                         assert(route->result_ok);
677                         LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
678                         assert(paths->datalen == 1);
679                         assert(paths->data[0].datalen == 1);
680                         assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
681                                 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
682                         assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
683                         LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, Invoice_payment_secret(invoice->contents.result));
684                         assert(send_res->result_ok);
685                 }
686
687                 mons_updated = 0;
688                 PeerManager_process_events(&net1);
689                 while (mons_updated != 4) {
690                         std::this_thread::yield();
691                 }
692
693                 // Check that we received the payment!
694                 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
695                 while (true) {
696                         EventQueue queue;
697                         LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
698                         ev2.process_pending_events(ev2.this_arg, handler);
699                         if (queue.events.size() == 1) {
700                                 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
701                                 break;
702                         }
703                         std::this_thread::yield();
704                 }
705                 ChannelManager_process_pending_htlc_forwards(&cm2);
706                 PeerManager_process_events(&net2);
707
708                 mons_updated = 0;
709                 LDKThirtyTwoBytes payment_preimage;
710                 {
711                         EventQueue queue;
712                         LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
713                         ev2.process_pending_events(ev2.this_arg, handler);
714                         assert(queue.events.size() == 1);
715                         assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
716                         assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
717                         assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
718                         assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
719                                         Invoice_payment_secret(invoice->contents.result).data, 32));
720                         assert(queue.events[0]->payment_received.amt == 5000);
721                         memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
722                         assert(ChannelManager_claim_funds(&cm2, payment_preimage));
723                 }
724                 PeerManager_process_events(&net2);
725                 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
726                 while (mons_updated != 5) {
727                         std::this_thread::yield();
728                 }
729                 {
730                         EventQueue queue;
731                         LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
732                         ev1.process_pending_events(ev1.this_arg, handler);
733                         assert(queue.events.size() == 1);
734                         assert(queue.events[0]->tag == LDKEvent_PaymentSent);
735                         assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
736                 }
737
738                 conn.stop();
739
740                 cm1_ser = ChannelManager_write(&cm1);
741                 cm2_ser = ChannelManager_write(&cm2);
742         }
743
744         LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
745         assert(mons1.mons.size() == 1);
746         mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
747         mons_list1->data[0].is_owned = false; // XXX: God this sucks
748         uint8_t node_seed[32];
749         memset(&node_seed, 0, 32);
750         LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
751         LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
752
753         LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
754         LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
755                 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
756         assert(cm1_read->result_ok);
757         LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
758
759         LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
760         assert(mons2.mons.size() == 1);
761         mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
762         mons_list2->data[0].is_owned = false; // XXX: God this sucks
763         memset(&node_seed, 1, 32);
764         LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
765
766         LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
767         LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
768                 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
769         assert(cm2_read->result_ok);
770         LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
771
772         // Attempt to close the channel...
773         uint8_t chan_id[32];
774         for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
775         LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
776         assert(!close_res->result_ok); // Note that we can't close while disconnected!
777
778         // Open a connection!
779         LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
780         random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
781
782         LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
783         LDKCustomMessageHandler custom_msg_handler1 = {
784                 .this_arg = &chan_2_node_id,
785                 .handle_custom_message = NULL, // We only create custom messages, not handle them
786                 .get_and_clear_pending_msg = create_custom_msg,
787                 .CustomMessageReader = LDKCustomMessageReader {
788                         .this_arg = NULL,
789                         .read = read_custom_message,
790                         .free = NULL,
791                 },
792                 .free = NULL,
793         };
794         LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
795
796         LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
797         CustomMsgQueue peer_2_custom_messages;
798         LDKCustomMessageHandler custom_msg_handler2 = {
799                 .this_arg = &peer_2_custom_messages,
800                 .handle_custom_message = handle_custom_message,
801                 .get_and_clear_pending_msg = never_send_custom_msgs,
802                 .CustomMessageReader = LDKCustomMessageReader {
803                         .this_arg = NULL,
804                         .read = read_custom_message,
805                         .free = NULL,
806                 },
807                 .free = NULL,
808         };
809         random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
810         LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
811
812         PeersConnection conn(cm1, cm2, net1, net2);
813
814         while (true) {
815                 // Wait for the channels to be considered up once the reestablish messages are processed
816                 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
817                 if (outbound_channels->datalen == 1) {
818                         break;
819                 }
820         }
821
822         // Actually close the channel
823         num_txs_broadcasted = 0;
824         close_res = ChannelManager_close_channel(&cm1, &chan_id);
825         assert(close_res->result_ok);
826         PeerManager_process_events(&net1);
827         while (num_txs_broadcasted != 2) {
828                 std::this_thread::yield();
829         }
830         LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
831         assert(chans_after_close1->datalen == 0);
832         LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
833         assert(chans_after_close2->datalen == 0);
834
835         conn.stop();
836
837         assert(peer_2_custom_messages.msgs.size() != 0);
838
839         // Few extra random tests:
840         LDKSecretKey sk;
841         memset(&sk, 42, 32);
842         LDKThirtyTwoBytes kdiv_params;
843         memset(&kdiv_params, 43, 32);
844         LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);
845 }