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 LDKRecord *record) {
102 LDK::Str mod = Record_get_module_path(record);
103 LDK::Str str = Record_get_args(record);
104 printf("%p - %.*s:%d - %.*s\n", this_arg, (int)mod->len, mod->chars, Record_get_line(record), (int)str->len, str->chars);
107 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
108 if (target == LDKConfirmationTarget_Background) {
113 // Note that we don't call _free() on target, but that's OK, its unitary
115 // We use the same fee estimator globally:
116 const LDKFeeEstimator fee_est {
118 .get_est_sat_per_1000_weight = get_fee,
122 static std::atomic_int num_txs_broadcasted(0);
123 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
124 num_txs_broadcasted += 1;
126 Transaction_free(tx);
129 struct NodeMonitors {
131 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
134 void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
135 std::unique_lock<std::mutex> l(mut);
136 for (auto& mon : mons) {
137 LDK::CVec_TransactionOutputsZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
142 LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
143 // First bind the args to C++ objects so they auto-free
144 LDK::ChannelMonitor mon(std::move(monitor_arg));
145 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
147 NodeMonitors* arg = (NodeMonitors*) this_arg;
148 std::unique_lock<std::mutex> l(arg->mut);
150 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
151 return CResult_NoneChannelMonitorUpdateErrZ_ok();
153 static std::atomic_int mons_updated(0);
154 LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
155 // First bind the args to C++ objects so they auto-free
156 LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
157 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
159 NodeMonitors* arg = (NodeMonitors*) this_arg;
160 std::unique_lock<std::mutex> l(arg->mut);
162 bool updated = false;
163 for (auto& mon : arg->mons) {
164 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
165 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
167 LDKBroadcasterInterface broadcaster = {
168 .broadcast_transaction = broadcast_tx,
170 LDK::CResult_NoneNoneZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger);
171 assert(res->result_ok);
177 return CResult_NoneChannelMonitorUpdateErrZ_ok();
179 LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
180 NodeMonitors* arg = (NodeMonitors*) this_arg;
181 std::unique_lock<std::mutex> l(arg->mut);
183 if (arg->mons.size() == 0) {
184 return LDKCVec_MonitorEventZ {
189 // We only ever actually have one channel per node, plus concatenating two
190 // Rust Vecs to each other from C++ will require a bit of effort.
191 assert(arg->mons.size() == 1);
192 return ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
197 std::vector<LDK::Event> events;
199 void handle_event(const void *this_arg, const LDKEvent *event) {
200 EventQueue* arg = (EventQueue*) this_arg;
201 arg->events.push_back(Event_clone(event));
205 class PeersConnection {
210 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
211 node1_handler = init_socket_handling(&net1);
212 node2_handler = init_socket_handling(&net2);
214 struct sockaddr_in listen_addr;
215 listen_addr.sin_family = AF_INET;
216 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
217 listen_addr.sin_port = htons(10042);
218 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
220 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
223 // Wait for the initial handshakes to complete...
224 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
225 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
226 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
227 std::this_thread::yield();
230 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
231 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
232 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
234 // Then disconnect the "main" connection, while another connection is being made.
235 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
236 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
238 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
240 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
241 // Wait for the peers to disconnect...
242 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
243 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
244 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
245 std::this_thread::yield();
247 // Note that the above is somewhat race-y, as node 2 may still think its connected.
248 // Thus, make sure any connections are disconnected on its end as well.
249 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1), false);
251 // Finally make an actual connection and keep it this time
252 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
255 // Wait for the initial handshakes to complete...
256 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
257 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
258 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
259 std::this_thread::yield();
263 interrupt_socket_handling(node1_handler);
264 interrupt_socket_handling(node2_handler);
270 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
271 return write((int)((long)this_arg), data.data, data.datalen);
273 void sock_disconnect_socket(void *this_arg) {
274 close((int)((long)this_arg));
276 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
277 return this_arg == other_arg->this_arg;
279 uint64_t sock_hash(const void *this_arg) {
280 return (uint64_t)this_arg;
282 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
283 unsigned char buf[1024];
287 while ((readlen = read(rdfd, buf, 1024)) > 0) {
288 data.datalen = readlen;
289 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
290 if (!res->result_ok) {
291 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
294 PeerManager_process_events(pm);
296 PeerManager_socket_disconnected(&*pm, peer_descriptor);
299 class PeersConnection {
300 int pipefds_1_to_2[2];
301 int pipefds_2_to_1[2];
303 LDKSocketDescriptor sock1, sock2;
306 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
307 assert(!pipe(pipefds_1_to_2));
308 assert(!pipe(pipefds_2_to_1));
310 sock1 = LDKSocketDescriptor {
311 .this_arg = (void*)(long)pipefds_1_to_2[1],
312 .send_data = sock_send_data,
313 .disconnect_socket = sock_disconnect_socket,
320 sock2 = LDKSocketDescriptor {
321 .this_arg = (void*)(long)pipefds_2_to_1[1],
322 .send_data = sock_send_data,
323 .disconnect_socket = sock_disconnect_socket,
330 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
331 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
333 // Note that we have to bind the result to a C++ class to make sure it gets free'd
334 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_NetAddressZ_none());
335 assert(con_res->result_ok);
336 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_NetAddressZ_none());
337 assert(con_res2->result_ok);
339 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
340 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
343 // Wait for the initial handshakes to complete...
344 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
345 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
346 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
347 std::this_thread::yield();
352 close(pipefds_1_to_2[0]);
353 close(pipefds_2_to_1[0]);
354 close(pipefds_1_to_2[1]);
355 close(pipefds_2_to_1[1]);
362 struct CustomMsgQueue {
363 std::vector<LDK::Type> msgs;
366 uint16_t custom_msg_type_id(const void *this_arg) {
369 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
370 uint8_t *bytes = (uint8_t *) malloc(1024);
371 memset(bytes, 42, 1024);
373 .data = bytes, .datalen = 1024
376 LDKStr custom_msg_debug(const void *this_arg) {
378 .chars = NULL, .len = 0, .chars_is_owned = false
382 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
383 assert(type_id == 8888);
384 assert(buf.datalen == 1024);
386 memset(cmp, 42, 1024);
387 assert(!memcmp(cmp, buf.data, 1024));
388 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
390 .type_id = custom_msg_type_id,
391 .debug_str = custom_msg_debug,
396 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
397 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
398 arg->msgs.push_back(std::move(msg));
399 return CResult_NoneLightningErrorZ_ok();
401 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
402 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
403 .data = NULL, .datalen = 0
407 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
408 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
409 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
410 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
413 ret.data[0].a = *counterparty_node_id;
414 ret.data[0].b = LDKType {
416 .type_id = custom_msg_type_id,
417 .debug_str = custom_msg_debug,
418 .write = custom_msg_bytes,
424 uint64_t get_chan_score(const void *this_arg, uint64_t scid, uint64_t htlc_amt, uint64_t chan_capacity, const LDKNodeId *src, const LDKNodeId *dst) {
428 struct CustomRouteFinderParams {
430 LDKNetworkGraph *graph_ref;
431 LDKThirtyTwoBytes random_seed_bytes;
433 struct LDKCResult_RouteLightningErrorZ custom_find_route(const void *this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, const uint8_t (*payment_hash)[32], struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKScore *NONNULL_PTR scorer) {
434 const struct CustomRouteFinderParams *params = (struct CustomRouteFinderParams *)this_arg;
435 assert(first_hops->datalen == 1);
436 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
437 return find_route(payer, route_params, params->graph_ref, first_hops, *params->logger, scorer, ¶ms->random_seed_bytes.data);
441 uint8_t channel_open_header[80];
442 uint8_t header_1[80];
443 uint8_t header_2[80];
444 memcpy(channel_open_header, channel_open_block, 80);
445 memcpy(header_1, block_1, 80);
446 memcpy(header_2, block_2, 80);
448 LDKPublicKey null_pk;
449 memset(&null_pk, 0, sizeof(null_pk));
451 LDKThirtyTwoBytes random_bytes;
452 LDKThirtyTwoBytes chain_tip;
453 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
455 LDKNetwork network = LDKNetwork_Testnet;
457 // Trait implementations:
458 LDKBroadcasterInterface broadcast {
460 .broadcast_transaction = broadcast_tx,
464 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
466 .this_arg = (void*)1,
472 mons1.logger = &logger1;
475 .watch_channel = add_channel_monitor,
476 .update_channel = update_channel_monitor,
477 .release_pending_monitor_events = monitors_pending_monitor_events,
481 LDK::NetworkGraph net_graph1 = NetworkGraph_new(genesis_hash);
482 LDK::NetGraphMsgHandler graph_msg_handler1 = NetGraphMsgHandler_new(&net_graph1, COption_AccessZ_none(), logger1);
483 LDKSecretKey node_secret1;
486 .this_arg = (void*)2,
492 mons2.logger = &logger2;
495 .watch_channel = add_channel_monitor,
496 .update_channel = update_channel_monitor,
497 .release_pending_monitor_events = monitors_pending_monitor_events,
501 LDK::NetworkGraph net_graph2 = NetworkGraph_new(genesis_hash);
502 LDK::NetGraphMsgHandler graph_msg_handler2 = NetGraphMsgHandler_new(&net_graph2, COption_AccessZ_none(), logger2);
503 LDKSecretKey node_secret2;
505 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
506 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
508 { // Scope for the ser-des reload
509 // Instantiate classes for node 1:
510 uint8_t node_seed[32];
511 memset(&node_seed, 0, 32);
512 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
513 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
514 LDK::CResult_SecretKeyNoneZ node_secret1_res = keys_source1->get_node_secret(keys_source1->this_arg, LDKRecipient_Node);
515 assert(node_secret1_res->result_ok);
516 node_secret1 = *node_secret1_res->contents.result;
518 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
520 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
521 assert(channels->datalen == 0);
523 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler1));
525 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
526 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
528 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
529 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
531 // Demo getting a channel key and check that its returning real pubkeys:
532 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
533 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
534 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
535 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
537 // Instantiate classes for node 2:
538 memset(&node_seed, 1, 32);
539 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
540 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
541 LDK::CResult_SecretKeyNoneZ node_secret2_res = keys_source2->get_node_secret(keys_source2->this_arg, LDKRecipient_Node);
542 assert(node_secret2_res->result_ok);
543 node_secret2 = *node_secret2_res->contents.result;
545 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
546 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
547 LDK::UserConfig config2 = UserConfig_default();
548 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
550 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)));
552 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
553 assert(channels2->datalen == 0);
555 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler2);
556 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
557 assert(chan_ann->result_ok);
558 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
559 assert(ann_res->result_ok);
561 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
563 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
564 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
566 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
567 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
569 // Open a connection!
570 PeersConnection conn(cm1, cm2, net1, net2);
572 // Note that we have to bind the result to a C++ class to make sure it gets free'd
573 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
574 assert(res->result_ok);
575 PeerManager_process_events(&net1);
577 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
578 assert(new_channels->datalen == 1);
579 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
580 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
581 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
584 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
585 if (new_channels_2->datalen == 1) {
586 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
587 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
588 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
589 assert(init_feats->inner != NULL);
592 std::this_thread::yield();
595 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
598 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
599 ev1.process_pending_events(ev1.this_arg, handler);
600 if (queue.events.size() == 1) {
601 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
602 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
603 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
604 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
605 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
606 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
608 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
609 assert(fund_res->result_ok);
612 std::this_thread::yield();
615 // We observe when the funding signed messages have been exchanged by
616 // waiting for two monitors to be registered.
617 assert(num_txs_broadcasted == 0);
618 PeerManager_process_events(&net1);
619 while (num_txs_broadcasted != 1) {
620 std::this_thread::yield();
623 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
624 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
626 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
627 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
629 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
630 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
631 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
633 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
634 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
635 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
637 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
638 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
639 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
640 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
642 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
643 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
644 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
645 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
647 PeerManager_process_events(&net1);
648 PeerManager_process_events(&net2);
650 // Now send funds from 1 to 2!
651 uint64_t channel_scid;
653 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
654 if (outbound_channels->datalen == 1) {
655 const LDKChannelDetails *channel = &outbound_channels->data[0];
656 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
657 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
658 uint8_t expected_chan_id[32];
659 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
660 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
662 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
663 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
664 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
665 // We opened the channel with 1000 push_msat:
666 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
667 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
668 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
669 if (inbound_capacity < 0) inbound_capacity = 0;
670 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
671 assert(ChannelDetails_get_is_usable(channel));
672 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
673 assert(scid_opt->some);
674 channel_scid = scid_opt->some;
677 std::this_thread::yield();
680 LDKCOption_u64Z min_value = {
681 .tag = LDKCOption_u64Z_Some,
684 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
685 KeysManager_as_KeysInterface(&keys2),
686 LDKCurrency_Bitcoin, min_value,
688 .chars = (const uint8_t *)"Invoice Description",
689 .len = strlen("Invoice Description"),
690 .chars_is_owned = false
692 assert(invoice->result_ok);
693 LDKThirtyTwoBytes payment_hash;
694 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
697 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
698 LDK::Score chan_scorer = LDKScore {
699 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
701 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
702 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
703 .inner = NULL, .is_owned = false
704 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff),
705 5000, Invoice_min_final_cltv_expiry(invoice->contents.result));
706 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
707 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
708 assert(route->result_ok);
709 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
710 assert(paths->datalen == 1);
711 assert(paths->data[0].datalen == 1);
712 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
713 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
714 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
715 LDKThirtyTwoBytes payment_secret;
716 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
717 LDK::CResult_PaymentIdPaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret);
718 assert(send_res->result_ok);
722 PeerManager_process_events(&net1);
723 while (mons_updated != 4) {
724 std::this_thread::yield();
727 // Check that we received the payment!
728 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
731 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
732 ev2.process_pending_events(handler);
733 if (queue.events.size() == 1) {
734 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
737 std::this_thread::yield();
739 ChannelManager_process_pending_htlc_forwards(&cm2);
740 PeerManager_process_events(&net2);
743 LDKThirtyTwoBytes payment_preimage;
746 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
747 ev2.process_pending_events(handler);
748 assert(queue.events.size() == 1);
749 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
750 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
751 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
752 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
753 Invoice_payment_secret(invoice->contents.result), 32));
754 assert(queue.events[0]->payment_received.amt == 5000);
755 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
756 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
758 PeerManager_process_events(&net2);
759 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
760 while (mons_updated != 5) {
761 std::this_thread::yield();
765 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
766 while (queue.events.size() < 2)
767 ev1.process_pending_events(ev1.this_arg, handler);
768 assert(queue.events.size() == 2);
769 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
770 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
771 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
772 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
777 cm1_ser = ChannelManager_write(&cm1);
778 cm2_ser = ChannelManager_write(&cm2);
781 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
782 assert(mons1.mons.size() == 1);
783 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
784 mons_list1->data[0].is_owned = false; // XXX: God this sucks
785 uint8_t node_seed[32];
786 memset(&node_seed, 0, 32);
787 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
788 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
790 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
791 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
792 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
793 assert(cm1_read->result_ok);
794 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
796 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
797 assert(mons2.mons.size() == 1);
798 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
799 mons_list2->data[0].is_owned = false; // XXX: God this sucks
800 memset(&node_seed, 1, 32);
801 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
803 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
804 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
805 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
806 assert(cm2_read->result_ok);
807 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
809 // Attempt to close the channel...
811 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
812 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
813 assert(!close_res->result_ok); // Note that we can't close while disconnected!
815 // Open a connection!
816 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler1));
817 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
819 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
820 LDKCustomMessageHandler custom_msg_handler1 = {
821 .this_arg = &chan_2_node_id,
822 .handle_custom_message = NULL, // We only create custom messages, not handle them
823 .get_and_clear_pending_msg = create_custom_msg,
824 .CustomMessageReader = LDKCustomMessageReader {
826 .read = read_custom_message,
831 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
833 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler2));
834 CustomMsgQueue peer_2_custom_messages;
835 LDKCustomMessageHandler custom_msg_handler2 = {
836 .this_arg = &peer_2_custom_messages,
837 .handle_custom_message = handle_custom_message,
838 .get_and_clear_pending_msg = never_send_custom_msgs,
839 .CustomMessageReader = LDKCustomMessageReader {
841 .read = read_custom_message,
846 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
847 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
849 PeersConnection conn(cm1, cm2, net1, net2);
852 // Wait for the channels to be considered up once the reestablish messages are processed
853 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
854 if (outbound_channels->datalen == 1) {
859 // Send another payment, this time via the InvoicePayer
860 struct CustomRouteFinderParams router_params = {
862 .graph_ref = &net_graph1,
863 .random_seed_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg),
865 LDKRouter sending_router = {
866 .this_arg = &router_params,
867 .find_route = custom_find_route,
870 LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1);
871 LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(ProbabilisticScorer_as_Score(&scorer));
873 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
874 LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, &scorer_mtx, logger1, handler1, RetryAttempts_new(0));
876 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
877 KeysManager_as_KeysInterface(&keys2),
878 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
880 .chars = (const uint8_t *)"Invoice 2 Description",
881 .len = strlen("Invoice 2 Description"),
882 .chars_is_owned = false
884 assert(invoice_res2->result_ok);
885 const LDKInvoice *invoice2 = invoice_res2->contents.result;
886 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = InvoicePayer_pay_invoice(&payer, invoice2);
887 assert(invoice_pay_res->result_ok);
888 PeerManager_process_events(&net1);
890 // Check that we received the payment!
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_PendingHTLCsForwardable);
900 std::this_thread::yield();
902 ChannelManager_process_pending_htlc_forwards(&cm2);
903 PeerManager_process_events(&net2);
907 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
908 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
909 ev2.process_pending_events(handler2);
910 if (queue2.events.size() == 1) {
911 assert(queue2.events[0]->tag == LDKEvent_PaymentReceived);
912 const struct LDKEvent_LDKPaymentReceived_Body *event_data = &queue2.events[0]->payment_received;
913 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
914 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
915 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
916 Invoice_payment_secret(invoice2), 32));
917 assert(event_data->amt == 10000);
918 assert(ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage));
921 std::this_thread::yield();
924 while (queue1.events.size() < 2) {
925 PeerManager_process_events(&net2);
926 PeerManager_process_events(&net1);
928 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
929 LDK::EventHandler evh1 = InvoicePayer_as_EventHandler(&payer);
930 ev1.process_pending_events(std::move(evh1));
932 assert(queue1.events.size() == 2);
933 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
934 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
936 // Actually close the channel
937 num_txs_broadcasted = 0;
938 close_res = ChannelManager_close_channel(&cm1, &chan_id);
939 assert(close_res->result_ok);
940 PeerManager_process_events(&net1);
941 while (num_txs_broadcasted != 2) {
942 std::this_thread::yield();
944 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
945 assert(chans_after_close1->datalen == 0);
946 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
947 assert(chans_after_close2->datalen == 0);
951 assert(peer_2_custom_messages.msgs.size() != 0);
953 // Few extra random tests:
956 LDKThirtyTwoBytes kdiv_params;
957 memset(&kdiv_params, 43, 32);
958 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);