8 #include "include/lightningpp.hpp"
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
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
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,
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,
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
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
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 }
101 void print_log(const void *this_arg, const char *record) {
102 printf("%p - %s\n", this_arg, record);
105 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
106 if (target == LDKConfirmationTarget_Background) {
111 // Note that we don't call _free() on target, but that's OK, its unitary
113 // We use the same fee estimator globally:
114 const LDKFeeEstimator fee_est {
116 .get_est_sat_per_1000_weight = get_fee,
120 static std::atomic_int num_txs_broadcasted(0);
121 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
122 num_txs_broadcasted += 1;
124 Transaction_free(tx);
127 struct NodeMonitors {
129 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
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);
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));
145 NodeMonitors* arg = (NodeMonitors*) this_arg;
146 std::unique_lock<std::mutex> l(arg->mut);
148 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
149 return CResult_NoneChannelMonitorUpdateErrZ_ok();
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));
157 NodeMonitors* arg = (NodeMonitors*) this_arg;
158 std::unique_lock<std::mutex> l(arg->mut);
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)) {
165 LDKBroadcasterInterface broadcaster = {
166 .broadcast_transaction = broadcast_tx,
168 LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger);
169 assert(res->result_ok);
175 return CResult_NoneChannelMonitorUpdateErrZ_ok();
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);
181 if (arg->mons.size() == 0) {
182 return LDKCVec_MonitorEventZ {
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);
195 std::vector<LDK::Event> events;
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));
203 class PeersConnection {
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);
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)));
218 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
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();
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)));
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)));
236 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
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();
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);
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)));
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();
261 interrupt_socket_handling(node1_handler);
262 interrupt_socket_handling(node2_handler);
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);
271 void sock_disconnect_socket(void *this_arg) {
272 close((int)((long)this_arg));
274 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
275 return this_arg == other_arg->this_arg;
277 uint64_t sock_hash(const void *this_arg) {
278 return (uint64_t)this_arg;
280 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
281 unsigned char buf[1024];
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);
292 PeerManager_process_events(pm);
294 PeerManager_socket_disconnected(&*pm, peer_descriptor);
297 class PeersConnection {
298 int pipefds_1_to_2[2];
299 int pipefds_2_to_1[2];
301 LDKSocketDescriptor sock1, sock2;
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));
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,
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,
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);
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);
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);
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();
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]);
360 struct CustomMsgQueue {
361 std::vector<LDK::Type> msgs;
364 uint16_t custom_msg_type_id(const void *this_arg) {
367 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
368 uint8_t *bytes = (uint8_t *) malloc(1024);
369 memset(bytes, 42, 1024);
371 .data = bytes, .datalen = 1024
374 LDKStr custom_msg_debug(const void *this_arg) {
376 .chars = NULL, .len = 0, .chars_is_owned = false
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);
384 memset(cmp, 42, 1024);
385 assert(!memcmp(cmp, buf.data, 1024));
386 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
388 .type_id = custom_msg_type_id,
389 .debug_str = custom_msg_debug,
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();
399 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
400 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
401 .data = NULL, .datalen = 0
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))),
411 ret.data[0].a = *counterparty_node_id;
412 ret.data[0].b = LDKType {
414 .type_id = custom_msg_type_id,
415 .debug_str = custom_msg_debug,
416 .write = custom_msg_bytes,
422 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst) { return 42; }
424 struct CustomRouteFinderParams {
426 LDKNetworkGraph *graph_ref;
428 struct LDKCResult_RouteLightningErrorZ custom_find_route(const void *this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKScore *NONNULL_PTR scorer) {
429 const struct CustomRouteFinderParams *params = (struct CustomRouteFinderParams *)this_arg;
430 assert(first_hops->datalen == 1);
431 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
432 return find_route(payer, route_params, params->graph_ref, first_hops, *params->logger, scorer);
436 uint8_t channel_open_header[80];
437 uint8_t header_1[80];
438 uint8_t header_2[80];
439 memcpy(channel_open_header, channel_open_block, 80);
440 memcpy(header_1, block_1, 80);
441 memcpy(header_2, block_2, 80);
443 LDKPublicKey null_pk;
444 memset(&null_pk, 0, sizeof(null_pk));
446 LDKThirtyTwoBytes random_bytes;
447 LDKThirtyTwoBytes chain_tip;
448 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
450 LDKNetwork network = LDKNetwork_Testnet;
452 // Trait implementations:
453 LDKBroadcasterInterface broadcast {
455 .broadcast_transaction = broadcast_tx,
459 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
461 .this_arg = (void*)1,
467 mons1.logger = &logger1;
470 .watch_channel = add_channel_monitor,
471 .update_channel = update_channel_monitor,
472 .release_pending_monitor_events = monitors_pending_monitor_events,
476 LDK::NetworkGraph net_graph1 = NetworkGraph_new(genesis_hash);
477 LDK::NetGraphMsgHandler graph_msg_handler1 = NetGraphMsgHandler_new(&net_graph1, COption_AccessZ_none(), logger1);
478 LDKSecretKey node_secret1;
481 .this_arg = (void*)2,
487 mons2.logger = &logger2;
490 .watch_channel = add_channel_monitor,
491 .update_channel = update_channel_monitor,
492 .release_pending_monitor_events = monitors_pending_monitor_events,
496 LDK::NetworkGraph net_graph2 = NetworkGraph_new(genesis_hash);
497 LDK::NetGraphMsgHandler graph_msg_handler2 = NetGraphMsgHandler_new(&net_graph2, COption_AccessZ_none(), logger2);
498 LDKSecretKey node_secret2;
500 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
501 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
503 { // Scope for the ser-des reload
504 // Instantiate classes for node 1:
505 uint8_t node_seed[32];
506 memset(&node_seed, 0, 32);
507 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
508 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
509 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
511 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
513 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
514 assert(channels->datalen == 0);
516 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler1));
518 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
519 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
521 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
522 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
524 // Demo getting a channel key and check that its returning real pubkeys:
525 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
526 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
527 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
528 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
530 // Instantiate classes for node 2:
531 memset(&node_seed, 1, 32);
532 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
533 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
534 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
536 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
537 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
538 LDK::UserConfig config2 = UserConfig_default();
539 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
541 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)));
543 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
544 assert(channels2->datalen == 0);
546 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler2);
547 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
548 assert(chan_ann->result_ok);
549 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
550 assert(ann_res->result_ok);
552 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
554 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
555 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
557 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
558 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
560 // Open a connection!
561 PeersConnection conn(cm1, cm2, net1, net2);
563 // Note that we have to bind the result to a C++ class to make sure it gets free'd
564 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
565 assert(res->result_ok);
566 PeerManager_process_events(&net1);
568 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
569 assert(new_channels->datalen == 1);
570 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
571 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
572 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
575 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
576 if (new_channels_2->datalen == 1) {
577 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
578 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
579 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
580 assert(init_feats->inner != NULL);
583 std::this_thread::yield();
586 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
589 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
590 ev1.process_pending_events(ev1.this_arg, handler);
591 if (queue.events.size() == 1) {
592 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
593 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
594 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
595 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
596 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
597 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
599 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
600 assert(fund_res->result_ok);
603 std::this_thread::yield();
606 // We observe when the funding signed messages have been exchanged by
607 // waiting for two monitors to be registered.
608 assert(num_txs_broadcasted == 0);
609 PeerManager_process_events(&net1);
610 while (num_txs_broadcasted != 1) {
611 std::this_thread::yield();
614 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
615 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
617 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
618 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
620 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
621 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
622 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
624 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
625 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
626 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
628 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
629 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
630 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
631 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
633 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
634 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
635 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
636 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
638 PeerManager_process_events(&net1);
639 PeerManager_process_events(&net2);
641 // Now send funds from 1 to 2!
642 uint64_t channel_scid;
644 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
645 if (outbound_channels->datalen == 1) {
646 const LDKChannelDetails *channel = &outbound_channels->data[0];
647 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
648 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
649 uint8_t expected_chan_id[32];
650 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
651 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
653 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
654 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
655 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
656 // We opened the channel with 1000 push_msat:
657 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
658 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
659 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
660 if (inbound_capacity < 0) inbound_capacity = 0;
661 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
662 assert(ChannelDetails_get_is_usable(channel));
663 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
664 assert(scid_opt->some);
665 channel_scid = scid_opt->some;
668 std::this_thread::yield();
671 LDKCOption_u64Z min_value = {
672 .tag = LDKCOption_u64Z_Some,
675 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
676 KeysManager_as_KeysInterface(&keys2),
677 LDKCurrency_Bitcoin, min_value,
679 .chars = (const uint8_t *)"Invoice Description",
680 .len = strlen("Invoice Description"),
681 .chars_is_owned = false
683 assert(invoice->result_ok);
684 LDKThirtyTwoBytes payment_hash;
685 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
688 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
689 LDK::Score chan_scorer = LDKScore {
690 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
692 LDK::RouteParameters route_params = RouteParameters_new(Payee_new(
693 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
694 .inner = NULL, .is_owned = false
695 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none()),
696 5000, Invoice_min_final_cltv_expiry(invoice->contents.result));
697 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer);
698 assert(route->result_ok);
699 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
700 assert(paths->datalen == 1);
701 assert(paths->data[0].datalen == 1);
702 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
703 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
704 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
705 LDKThirtyTwoBytes payment_secret;
706 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
707 LDK::CResult_PaymentIdPaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret);
708 assert(send_res->result_ok);
712 PeerManager_process_events(&net1);
713 while (mons_updated != 4) {
714 std::this_thread::yield();
717 // Check that we received the payment!
718 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
721 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
722 ev2.process_pending_events(handler);
723 if (queue.events.size() == 1) {
724 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
727 std::this_thread::yield();
729 ChannelManager_process_pending_htlc_forwards(&cm2);
730 PeerManager_process_events(&net2);
733 LDKThirtyTwoBytes payment_preimage;
736 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
737 ev2.process_pending_events(handler);
738 assert(queue.events.size() == 1);
739 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
740 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
741 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
742 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
743 Invoice_payment_secret(invoice->contents.result), 32));
744 assert(queue.events[0]->payment_received.amt == 5000);
745 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
746 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
748 PeerManager_process_events(&net2);
749 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
750 while (mons_updated != 5) {
751 std::this_thread::yield();
755 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
756 ev1.process_pending_events(ev1.this_arg, handler);
757 assert(queue.events.size() == 1);
758 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
759 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
764 cm1_ser = ChannelManager_write(&cm1);
765 cm2_ser = ChannelManager_write(&cm2);
768 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
769 assert(mons1.mons.size() == 1);
770 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
771 mons_list1->data[0].is_owned = false; // XXX: God this sucks
772 uint8_t node_seed[32];
773 memset(&node_seed, 0, 32);
774 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
775 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
777 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
778 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
779 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
780 assert(cm1_read->result_ok);
781 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
783 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
784 assert(mons2.mons.size() == 1);
785 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
786 mons_list2->data[0].is_owned = false; // XXX: God this sucks
787 memset(&node_seed, 1, 32);
788 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
790 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
791 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
792 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
793 assert(cm2_read->result_ok);
794 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
796 // Attempt to close the channel...
798 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
799 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
800 assert(!close_res->result_ok); // Note that we can't close while disconnected!
802 // Open a connection!
803 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler1));
804 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
806 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
807 LDKCustomMessageHandler custom_msg_handler1 = {
808 .this_arg = &chan_2_node_id,
809 .handle_custom_message = NULL, // We only create custom messages, not handle them
810 .get_and_clear_pending_msg = create_custom_msg,
811 .CustomMessageReader = LDKCustomMessageReader {
813 .read = read_custom_message,
818 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
820 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler2));
821 CustomMsgQueue peer_2_custom_messages;
822 LDKCustomMessageHandler custom_msg_handler2 = {
823 .this_arg = &peer_2_custom_messages,
824 .handle_custom_message = handle_custom_message,
825 .get_and_clear_pending_msg = never_send_custom_msgs,
826 .CustomMessageReader = LDKCustomMessageReader {
828 .read = read_custom_message,
833 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
834 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
836 PeersConnection conn(cm1, cm2, net1, net2);
839 // Wait for the channels to be considered up once the reestablish messages are processed
840 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
841 if (outbound_channels->datalen == 1) {
846 // Send another payment, this time via the InvoicePayer
847 struct CustomRouteFinderParams router_params = {
849 .graph_ref = &net_graph1,
851 LDKRouter sending_router = {
852 .this_arg = &router_params,
853 .find_route = custom_find_route,
856 LDK::Scorer scorer = Scorer_default();
857 LDK::LockableScore scorer_mtx = LockableScore_new(Scorer_as_Score(&scorer));
859 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
860 LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, &scorer_mtx, logger1, handler1, RetryAttempts_new(0));
862 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
863 KeysManager_as_KeysInterface(&keys2),
864 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
866 .chars = (const uint8_t *)"Invoice 2 Description",
867 .len = strlen("Invoice 2 Description"),
868 .chars_is_owned = false
870 assert(invoice_res2->result_ok);
871 const LDKInvoice *invoice2 = invoice_res2->contents.result;
872 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = InvoicePayer_pay_invoice(&payer, invoice2);
873 assert(invoice_pay_res->result_ok);
874 PeerManager_process_events(&net1);
876 // Check that we received the payment!
879 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
880 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
881 ev2.process_pending_events(handler2);
882 if (queue2.events.size() == 1) {
883 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
886 std::this_thread::yield();
888 ChannelManager_process_pending_htlc_forwards(&cm2);
889 PeerManager_process_events(&net2);
893 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
894 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
895 ev2.process_pending_events(handler2);
896 if (queue2.events.size() == 1) {
897 assert(queue2.events[0]->tag == LDKEvent_PaymentReceived);
898 const struct LDKEvent_LDKPaymentReceived_Body *event_data = &queue2.events[0]->payment_received;
899 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
900 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
901 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
902 Invoice_payment_secret(invoice2), 32));
903 assert(event_data->amt == 10000);
904 assert(ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage));
907 std::this_thread::yield();
910 while (queue1.events.size() == 0) {
911 PeerManager_process_events(&net2);
912 PeerManager_process_events(&net1);
914 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
915 LDK::EventHandler evh1 = InvoicePayer_as_EventHandler(&payer);
916 ev1.process_pending_events(std::move(evh1));
918 assert(queue1.events.size() == 1);
919 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
921 // Actually close the channel
922 num_txs_broadcasted = 0;
923 close_res = ChannelManager_close_channel(&cm1, &chan_id);
924 assert(close_res->result_ok);
925 PeerManager_process_events(&net1);
926 while (num_txs_broadcasted != 2) {
927 std::this_thread::yield();
929 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
930 assert(chans_after_close1->datalen == 0);
931 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
932 assert(chans_after_close2->datalen == 0);
936 assert(peer_2_custom_messages.msgs.size() != 0);
938 // Few extra random tests:
941 LDKThirtyTwoBytes kdiv_params;
942 memset(&kdiv_params, 43, 32);
943 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);