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 LDKCOption_NetAddressZ remote_network_address = {
335 .tag = LDKCOption_NetAddressZ_None,
337 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, remote_network_address);
338 assert(con_res->result_ok);
339 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, remote_network_address);
340 assert(con_res2->result_ok);
342 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
343 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
346 // Wait for the initial handshakes to complete...
347 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
348 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
349 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
350 std::this_thread::yield();
355 close(pipefds_1_to_2[0]);
356 close(pipefds_2_to_1[0]);
357 close(pipefds_1_to_2[1]);
358 close(pipefds_2_to_1[1]);
365 struct CustomMsgQueue {
366 std::vector<LDK::Type> msgs;
369 uint16_t custom_msg_type_id(const void *this_arg) {
372 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
373 uint8_t *bytes = (uint8_t *) malloc(1024);
374 memset(bytes, 42, 1024);
376 .data = bytes, .datalen = 1024
379 LDKStr custom_msg_debug(const void *this_arg) {
381 .chars = NULL, .len = 0, .chars_is_owned = false
385 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
386 assert(type_id == 8888);
387 assert(buf.datalen == 1024);
389 memset(cmp, 42, 1024);
390 assert(!memcmp(cmp, buf.data, 1024));
391 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
393 .type_id = custom_msg_type_id,
394 .debug_str = custom_msg_debug,
399 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
400 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
401 arg->msgs.push_back(std::move(msg));
402 return CResult_NoneLightningErrorZ_ok();
404 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
405 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
406 .data = NULL, .datalen = 0
410 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
411 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
412 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
413 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
416 ret.data[0].a = *counterparty_node_id;
417 ret.data[0].b = LDKType {
419 .type_id = custom_msg_type_id,
420 .debug_str = custom_msg_debug,
421 .write = custom_msg_bytes,
427 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) {
431 struct CustomRouteFinderParams {
433 LDKNetworkGraph *graph_ref;
434 LDKThirtyTwoBytes random_seed_bytes;
436 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) {
437 const struct CustomRouteFinderParams *params = (struct CustomRouteFinderParams *)this_arg;
438 assert(first_hops->datalen == 1);
439 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
440 return find_route(payer, route_params, params->graph_ref, first_hops, *params->logger, scorer, ¶ms->random_seed_bytes.data);
444 uint8_t channel_open_header[80];
445 uint8_t header_1[80];
446 uint8_t header_2[80];
447 memcpy(channel_open_header, channel_open_block, 80);
448 memcpy(header_1, block_1, 80);
449 memcpy(header_2, block_2, 80);
451 LDKPublicKey null_pk;
452 memset(&null_pk, 0, sizeof(null_pk));
454 LDKThirtyTwoBytes random_bytes;
455 LDKThirtyTwoBytes chain_tip;
456 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
458 LDKNetwork network = LDKNetwork_Testnet;
460 // Trait implementations:
461 LDKBroadcasterInterface broadcast {
463 .broadcast_transaction = broadcast_tx,
467 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
469 .this_arg = (void*)1,
475 mons1.logger = &logger1;
478 .watch_channel = add_channel_monitor,
479 .update_channel = update_channel_monitor,
480 .release_pending_monitor_events = monitors_pending_monitor_events,
484 LDK::NetworkGraph net_graph1 = NetworkGraph_new(genesis_hash);
485 LDK::NetGraphMsgHandler graph_msg_handler1 = NetGraphMsgHandler_new(&net_graph1, COption_AccessZ_none(), logger1);
486 LDKSecretKey node_secret1;
489 .this_arg = (void*)2,
495 mons2.logger = &logger2;
498 .watch_channel = add_channel_monitor,
499 .update_channel = update_channel_monitor,
500 .release_pending_monitor_events = monitors_pending_monitor_events,
504 LDK::NetworkGraph net_graph2 = NetworkGraph_new(genesis_hash);
505 LDK::NetGraphMsgHandler graph_msg_handler2 = NetGraphMsgHandler_new(&net_graph2, COption_AccessZ_none(), logger2);
506 LDKSecretKey node_secret2;
508 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
509 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
511 { // Scope for the ser-des reload
512 // Instantiate classes for node 1:
513 uint8_t node_seed[32];
514 memset(&node_seed, 0, 32);
515 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
516 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
517 LDK::CResult_SecretKeyNoneZ node_secret1_res = keys_source1->get_node_secret(keys_source1->this_arg, LDKRecipient_Node);
518 assert(node_secret1_res->result_ok);
519 node_secret1 = *node_secret1_res->contents.result;
521 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
523 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
524 assert(channels->datalen == 0);
526 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler1));
528 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
529 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
531 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
532 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
534 // Demo getting a channel key and check that its returning real pubkeys:
535 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
536 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
537 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
538 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
540 // Instantiate classes for node 2:
541 memset(&node_seed, 1, 32);
542 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
543 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
544 LDK::CResult_SecretKeyNoneZ node_secret2_res = keys_source2->get_node_secret(keys_source2->this_arg, LDKRecipient_Node);
545 assert(node_secret2_res->result_ok);
546 node_secret2 = *node_secret2_res->contents.result;
548 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
549 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
550 LDK::UserConfig config2 = UserConfig_default();
551 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
553 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)));
555 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
556 assert(channels2->datalen == 0);
558 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler2);
559 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
560 assert(chan_ann->result_ok);
561 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
562 assert(ann_res->result_ok);
564 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
566 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
567 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
569 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
570 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
572 // Open a connection!
573 PeersConnection conn(cm1, cm2, net1, net2);
575 // Note that we have to bind the result to a C++ class to make sure it gets free'd
576 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
577 assert(res->result_ok);
578 PeerManager_process_events(&net1);
580 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
581 assert(new_channels->datalen == 1);
582 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
583 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
584 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
587 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
588 if (new_channels_2->datalen == 1) {
589 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
590 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
591 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
592 assert(init_feats->inner != NULL);
595 std::this_thread::yield();
598 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
601 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
602 ev1.process_pending_events(ev1.this_arg, handler);
603 if (queue.events.size() == 1) {
604 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
605 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
606 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
607 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
608 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
609 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
611 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
612 assert(fund_res->result_ok);
615 std::this_thread::yield();
618 // We observe when the funding signed messages have been exchanged by
619 // waiting for two monitors to be registered.
620 assert(num_txs_broadcasted == 0);
621 PeerManager_process_events(&net1);
622 while (num_txs_broadcasted != 1) {
623 std::this_thread::yield();
626 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
627 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
629 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
630 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
632 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
633 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
634 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
636 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
637 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
638 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
640 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
641 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
642 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
643 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
645 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
646 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
647 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
648 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
650 PeerManager_process_events(&net1);
651 PeerManager_process_events(&net2);
653 // Now send funds from 1 to 2!
654 uint64_t channel_scid;
656 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
657 if (outbound_channels->datalen == 1) {
658 const LDKChannelDetails *channel = &outbound_channels->data[0];
659 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
660 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
661 uint8_t expected_chan_id[32];
662 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
663 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
665 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
666 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
667 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
668 // We opened the channel with 1000 push_msat:
669 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
670 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
671 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
672 if (inbound_capacity < 0) inbound_capacity = 0;
673 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
674 assert(ChannelDetails_get_is_usable(channel));
675 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
676 assert(scid_opt->some);
677 channel_scid = scid_opt->some;
680 std::this_thread::yield();
683 LDKCOption_u64Z min_value = {
684 .tag = LDKCOption_u64Z_Some,
687 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
688 KeysManager_as_KeysInterface(&keys2),
689 LDKCurrency_Bitcoin, min_value,
691 .chars = (const uint8_t *)"Invoice Description",
692 .len = strlen("Invoice Description"),
693 .chars_is_owned = false
695 assert(invoice->result_ok);
696 LDKThirtyTwoBytes payment_hash;
697 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
700 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
701 LDK::Score chan_scorer = LDKScore {
702 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
704 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
705 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
706 .inner = NULL, .is_owned = false
707 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff),
708 5000, Invoice_min_final_cltv_expiry(invoice->contents.result));
709 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
710 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
711 assert(route->result_ok);
712 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
713 assert(paths->datalen == 1);
714 assert(paths->data[0].datalen == 1);
715 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
716 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
717 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
718 LDKThirtyTwoBytes payment_secret;
719 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
720 LDK::CResult_PaymentIdPaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret);
721 assert(send_res->result_ok);
725 PeerManager_process_events(&net1);
726 while (mons_updated != 4) {
727 std::this_thread::yield();
730 // Check that we received the payment!
731 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
734 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
735 ev2.process_pending_events(handler);
736 if (queue.events.size() == 1) {
737 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
740 std::this_thread::yield();
742 ChannelManager_process_pending_htlc_forwards(&cm2);
743 PeerManager_process_events(&net2);
746 LDKThirtyTwoBytes payment_preimage;
749 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
750 ev2.process_pending_events(handler);
751 assert(queue.events.size() == 1);
752 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
753 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
754 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
755 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
756 Invoice_payment_secret(invoice->contents.result), 32));
757 assert(queue.events[0]->payment_received.amt == 5000);
758 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
759 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
761 PeerManager_process_events(&net2);
762 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
763 while (mons_updated != 5) {
764 std::this_thread::yield();
768 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
769 while (queue.events.size() < 2)
770 ev1.process_pending_events(ev1.this_arg, handler);
771 assert(queue.events.size() == 2);
772 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
773 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
774 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
775 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
780 cm1_ser = ChannelManager_write(&cm1);
781 cm2_ser = ChannelManager_write(&cm2);
784 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
785 assert(mons1.mons.size() == 1);
786 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
787 mons_list1->data[0].is_owned = false; // XXX: God this sucks
788 uint8_t node_seed[32];
789 memset(&node_seed, 0, 32);
790 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
791 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
793 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
794 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
795 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
796 assert(cm1_read->result_ok);
797 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
799 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
800 assert(mons2.mons.size() == 1);
801 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
802 mons_list2->data[0].is_owned = false; // XXX: God this sucks
803 memset(&node_seed, 1, 32);
804 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
806 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
807 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
808 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
809 assert(cm2_read->result_ok);
810 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
812 // Attempt to close the channel...
814 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
815 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
816 assert(!close_res->result_ok); // Note that we can't close while disconnected!
818 // Open a connection!
819 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler1));
820 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
822 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
823 LDKCustomMessageHandler custom_msg_handler1 = {
824 .this_arg = &chan_2_node_id,
825 .handle_custom_message = NULL, // We only create custom messages, not handle them
826 .get_and_clear_pending_msg = create_custom_msg,
827 .CustomMessageReader = LDKCustomMessageReader {
829 .read = read_custom_message,
834 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
836 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&graph_msg_handler2));
837 CustomMsgQueue peer_2_custom_messages;
838 LDKCustomMessageHandler custom_msg_handler2 = {
839 .this_arg = &peer_2_custom_messages,
840 .handle_custom_message = handle_custom_message,
841 .get_and_clear_pending_msg = never_send_custom_msgs,
842 .CustomMessageReader = LDKCustomMessageReader {
844 .read = read_custom_message,
849 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
850 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
852 PeersConnection conn(cm1, cm2, net1, net2);
855 // Wait for the channels to be considered up once the reestablish messages are processed
856 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
857 if (outbound_channels->datalen == 1) {
862 // Send another payment, this time via the InvoicePayer
863 struct CustomRouteFinderParams router_params = {
865 .graph_ref = &net_graph1,
866 .random_seed_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg),
868 LDKRouter sending_router = {
869 .this_arg = &router_params,
870 .find_route = custom_find_route,
873 LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1);
874 LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(ProbabilisticScorer_as_Score(&scorer));
876 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
877 LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, &scorer_mtx, logger1, handler1, RetryAttempts_new(0));
879 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
880 KeysManager_as_KeysInterface(&keys2),
881 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
883 .chars = (const uint8_t *)"Invoice 2 Description",
884 .len = strlen("Invoice 2 Description"),
885 .chars_is_owned = false
887 assert(invoice_res2->result_ok);
888 const LDKInvoice *invoice2 = invoice_res2->contents.result;
889 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = InvoicePayer_pay_invoice(&payer, invoice2);
890 assert(invoice_pay_res->result_ok);
891 PeerManager_process_events(&net1);
893 // Check that we received the payment!
896 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
897 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
898 ev2.process_pending_events(handler2);
899 if (queue2.events.size() == 1) {
900 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
903 std::this_thread::yield();
905 ChannelManager_process_pending_htlc_forwards(&cm2);
906 PeerManager_process_events(&net2);
910 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
911 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
912 ev2.process_pending_events(handler2);
913 if (queue2.events.size() == 1) {
914 assert(queue2.events[0]->tag == LDKEvent_PaymentReceived);
915 const struct LDKEvent_LDKPaymentReceived_Body *event_data = &queue2.events[0]->payment_received;
916 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
917 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
918 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
919 Invoice_payment_secret(invoice2), 32));
920 assert(event_data->amt == 10000);
921 assert(ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage));
924 std::this_thread::yield();
927 while (queue1.events.size() < 2) {
928 PeerManager_process_events(&net2);
929 PeerManager_process_events(&net1);
931 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
932 LDK::EventHandler evh1 = InvoicePayer_as_EventHandler(&payer);
933 ev1.process_pending_events(std::move(evh1));
935 assert(queue1.events.size() == 2);
936 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
937 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
939 // Actually close the channel
940 num_txs_broadcasted = 0;
941 close_res = ChannelManager_close_channel(&cm1, &chan_id);
942 assert(close_res->result_ok);
943 PeerManager_process_events(&net1);
944 while (num_txs_broadcasted != 2) {
945 std::this_thread::yield();
947 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
948 assert(chans_after_close1->datalen == 0);
949 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
950 assert(chans_after_close2->datalen == 0);
954 assert(peer_2_custom_messages.msgs.size() != 0);
956 // Few extra random tests:
959 LDKThirtyTwoBytes kdiv_params;
960 memset(&kdiv_params, 43, 32);
961 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);