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