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_C2Tuple_OutPointCVec_MonitorEventZZZ 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_C2Tuple_OutPointCVec_MonitorEventZZZ {
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 LDK::CVec_MonitorEventZ events = ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
193 LDK::C2Tuple_OutPointScriptZ funding_info = ChannelMonitor_get_funding_txo(&arg->mons[0].second);
194 LDK::OutPoint outpoint = std::move(funding_info->a);
195 LDK::C2Tuple_OutPointCVec_MonitorEventZZ pair = C2Tuple_OutPointCVec_MonitorEventZZ_new(std::move(outpoint), std::move(events));
196 auto vec = LDKCVec_C2Tuple_OutPointCVec_MonitorEventZZZ {
197 .data = (LDKC2Tuple_OutPointCVec_MonitorEventZZ*)malloc(sizeof(LDKC2Tuple_OutPointCVec_MonitorEventZZ)),
200 vec.data[0] = std::move(pair);
206 std::vector<LDK::Event> events;
208 void handle_event(const void *this_arg, const LDKEvent *event) {
209 EventQueue* arg = (EventQueue*) this_arg;
210 arg->events.push_back(Event_clone(event));
214 class PeersConnection {
219 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
220 node1_handler = init_socket_handling(&net1);
221 node2_handler = init_socket_handling(&net2);
223 struct sockaddr_in listen_addr;
224 listen_addr.sin_family = AF_INET;
225 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
226 listen_addr.sin_port = htons(10042);
227 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
229 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
232 // Wait for the initial handshakes to complete...
233 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
234 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
235 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
236 std::this_thread::yield();
239 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
240 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
241 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
243 // Then disconnect the "main" connection, while another connection is being made.
244 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
245 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
247 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
249 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
250 // Wait for the peers to disconnect...
251 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
252 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
253 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
254 std::this_thread::yield();
256 // Note that the above is somewhat race-y, as node 2 may still think its connected.
257 // Thus, make sure any connections are disconnected on its end as well.
258 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1), false);
260 // Finally make an actual connection and keep it this time
261 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
264 // Wait for the initial handshakes to complete...
265 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
266 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
267 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
268 std::this_thread::yield();
272 interrupt_socket_handling(node1_handler);
273 interrupt_socket_handling(node2_handler);
279 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
280 return write((int)((long)this_arg), data.data, data.datalen);
282 void sock_disconnect_socket(void *this_arg) {
283 close((int)((long)this_arg));
285 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
286 return this_arg == other_arg->this_arg;
288 uint64_t sock_hash(const void *this_arg) {
289 return (uint64_t)this_arg;
291 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
292 unsigned char buf[1024];
296 while ((readlen = read(rdfd, buf, 1024)) > 0) {
297 data.datalen = readlen;
298 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
299 if (!res->result_ok) {
300 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
303 PeerManager_process_events(pm);
305 PeerManager_socket_disconnected(&*pm, peer_descriptor);
308 class PeersConnection {
309 int pipefds_1_to_2[2];
310 int pipefds_2_to_1[2];
312 LDKSocketDescriptor sock1, sock2;
315 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
316 assert(!pipe(pipefds_1_to_2));
317 assert(!pipe(pipefds_2_to_1));
319 sock1 = LDKSocketDescriptor {
320 .this_arg = (void*)(long)pipefds_1_to_2[1],
321 .send_data = sock_send_data,
322 .disconnect_socket = sock_disconnect_socket,
329 sock2 = LDKSocketDescriptor {
330 .this_arg = (void*)(long)pipefds_2_to_1[1],
331 .send_data = sock_send_data,
332 .disconnect_socket = sock_disconnect_socket,
339 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
340 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
342 // Note that we have to bind the result to a C++ class to make sure it gets free'd
343 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_NetAddressZ_none());
344 assert(con_res->result_ok);
345 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_NetAddressZ_none());
346 assert(con_res2->result_ok);
348 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
349 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
352 // Wait for the initial handshakes to complete...
353 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
354 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
355 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
356 std::this_thread::yield();
361 close(pipefds_1_to_2[0]);
362 close(pipefds_2_to_1[0]);
363 close(pipefds_1_to_2[1]);
364 close(pipefds_2_to_1[1]);
371 struct CustomMsgQueue {
372 std::vector<LDK::Type> msgs;
375 uint16_t custom_msg_type_id(const void *this_arg) {
378 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
379 uint8_t *bytes = (uint8_t *) malloc(1024);
380 memset(bytes, 42, 1024);
382 .data = bytes, .datalen = 1024
385 LDKStr custom_msg_debug(const void *this_arg) {
387 .chars = NULL, .len = 0, .chars_is_owned = false
391 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
392 assert(type_id == 8888);
393 assert(buf.datalen == 1024);
395 memset(cmp, 42, 1024);
396 assert(!memcmp(cmp, buf.data, 1024));
397 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
399 .type_id = custom_msg_type_id,
400 .debug_str = custom_msg_debug,
405 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
406 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
407 arg->msgs.push_back(std::move(msg));
408 return CResult_NoneLightningErrorZ_ok();
410 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
411 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
412 .data = NULL, .datalen = 0
416 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
417 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
418 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
419 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
422 ret.data[0].a = *counterparty_node_id;
423 ret.data[0].b = LDKType {
425 .type_id = custom_msg_type_id,
426 .debug_str = custom_msg_debug,
427 .write = custom_msg_bytes,
433 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst, LDKChannelUsage usage_in) {
434 LDK::ChannelUsage usage(std::move(usage_in));
438 struct CustomRouteFinderParams {
440 LDKNetworkGraph *graph_ref;
441 LDKThirtyTwoBytes random_seed_bytes;
443 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) {
444 const struct CustomRouteFinderParams *params = (struct CustomRouteFinderParams *)this_arg;
445 assert(first_hops->datalen == 1);
446 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
447 return find_route(payer, route_params, params->graph_ref, first_hops, *params->logger, scorer, ¶ms->random_seed_bytes.data);
451 uint8_t channel_open_header[80];
452 uint8_t header_1[80];
453 uint8_t header_2[80];
454 memcpy(channel_open_header, channel_open_block, 80);
455 memcpy(header_1, block_1, 80);
456 memcpy(header_2, block_2, 80);
458 LDKPublicKey null_pk;
459 memset(&null_pk, 0, sizeof(null_pk));
461 LDKThirtyTwoBytes random_bytes;
462 LDKThirtyTwoBytes chain_tip;
463 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
465 LDKNetwork network = LDKNetwork_Testnet;
467 // Trait implementations:
468 LDKBroadcasterInterface broadcast {
470 .broadcast_transaction = broadcast_tx,
474 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
476 .this_arg = (void*)1,
482 mons1.logger = &logger1;
485 .watch_channel = add_channel_monitor,
486 .update_channel = update_channel_monitor,
487 .release_pending_monitor_events = monitors_pending_monitor_events,
491 LDK::NetworkGraph net_graph1 = NetworkGraph_new(genesis_hash, logger1);
492 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_AccessZ_none(), logger1);
493 LDKSecretKey node_secret1;
496 .this_arg = (void*)2,
502 mons2.logger = &logger2;
505 .watch_channel = add_channel_monitor,
506 .update_channel = update_channel_monitor,
507 .release_pending_monitor_events = monitors_pending_monitor_events,
511 LDK::NetworkGraph net_graph2 = NetworkGraph_new(genesis_hash, logger2);
512 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_AccessZ_none(), logger2);
513 LDKSecretKey node_secret2;
515 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
516 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
518 { // Scope for the ser-des reload
519 // Instantiate classes for node 1:
520 uint8_t node_seed[32];
521 memset(&node_seed, 0, 32);
522 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
523 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
524 LDK::CResult_SecretKeyNoneZ node_secret1_res = keys_source1->get_node_secret(keys_source1->this_arg, LDKRecipient_Node);
525 assert(node_secret1_res->result_ok);
526 node_secret1 = *node_secret1_res->contents.result;
528 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
530 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
531 assert(channels->datalen == 0);
533 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1));
535 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
536 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
538 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
539 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
541 // Demo getting a channel key and check that its returning real pubkeys:
542 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
543 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
544 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
545 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
547 // Instantiate classes for node 2:
548 memset(&node_seed, 1, 32);
549 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
550 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
551 LDK::CResult_SecretKeyNoneZ node_secret2_res = keys_source2->get_node_secret(keys_source2->this_arg, LDKRecipient_Node);
552 assert(node_secret2_res->result_ok);
553 node_secret2 = *node_secret2_res->contents.result;
555 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
556 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
557 LDK::UserConfig config2 = UserConfig_default();
558 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
560 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)));
562 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
563 assert(channels2->datalen == 0);
565 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
566 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
567 assert(chan_ann->result_ok);
568 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
569 assert(ann_res->result_ok);
571 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
573 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
574 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
576 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
577 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
579 // Open a connection!
580 PeersConnection conn(cm1, cm2, net1, net2);
582 // Note that we have to bind the result to a C++ class to make sure it gets free'd
583 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
584 assert(res->result_ok);
585 PeerManager_process_events(&net1);
587 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
588 assert(new_channels->datalen == 1);
589 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
590 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
591 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
594 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
595 if (new_channels_2->datalen == 1) {
596 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
597 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
598 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
599 assert(init_feats->inner != NULL);
602 std::this_thread::yield();
605 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
608 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
609 ev1.process_pending_events(ev1.this_arg, handler);
610 if (queue.events.size() == 1) {
611 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
612 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
613 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
614 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
615 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
616 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
618 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, queue.events[0]->funding_generation_ready.counterparty_node_id, funding_transaction);
619 assert(fund_res->result_ok);
622 std::this_thread::yield();
625 // We observe when the funding signed messages have been exchanged by
626 // waiting for two monitors to be registered.
627 assert(num_txs_broadcasted == 0);
628 PeerManager_process_events(&net1);
629 while (num_txs_broadcasted != 1) {
630 std::this_thread::yield();
633 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
634 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
636 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
637 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
639 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
640 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
641 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
643 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
644 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
645 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
647 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
648 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
649 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
650 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
652 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
653 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
654 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
655 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
657 PeerManager_process_events(&net1);
658 PeerManager_process_events(&net2);
660 // Now send funds from 1 to 2!
661 uint64_t channel_scid;
663 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
664 if (outbound_channels->datalen == 1) {
665 const LDKChannelDetails *channel = &outbound_channels->data[0];
666 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
667 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
668 uint8_t expected_chan_id[32];
669 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
670 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
672 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
673 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
674 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
675 // We opened the channel with 1000 push_msat:
676 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
677 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
678 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
679 if (inbound_capacity < 0) inbound_capacity = 0;
680 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
681 assert(ChannelDetails_get_is_usable(channel));
682 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
683 assert(scid_opt->some);
684 channel_scid = scid_opt->some;
687 std::this_thread::yield();
690 LDKCOption_u64Z min_value = {
691 .tag = LDKCOption_u64Z_Some,
694 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
695 KeysManager_as_KeysInterface(&keys2),
696 LDKCurrency_Bitcoin, min_value,
698 .chars = (const uint8_t *)"Invoice Description",
699 .len = strlen("Invoice Description"),
700 .chars_is_owned = false
702 assert(invoice->result_ok);
703 LDKThirtyTwoBytes payment_hash;
704 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
707 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
708 LDK::Score chan_scorer = LDKScore {
709 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
711 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
712 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
713 .inner = NULL, .is_owned = false
714 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff),
715 5000, Invoice_min_final_cltv_expiry(invoice->contents.result));
716 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
718 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
720 assert(route->result_ok);
721 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
722 assert(paths->datalen == 1);
723 assert(paths->data[0].datalen == 1);
724 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
725 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
726 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
727 LDKThirtyTwoBytes payment_secret;
728 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
729 LDK::CResult_PaymentIdPaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret);
730 assert(send_res->result_ok);
734 PeerManager_process_events(&net1);
735 while (mons_updated != 4) {
736 std::this_thread::yield();
739 // Check that we received the payment!
740 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
743 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
744 ev2.process_pending_events(handler);
745 if (queue.events.size() == 1) {
746 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
749 std::this_thread::yield();
751 ChannelManager_process_pending_htlc_forwards(&cm2);
752 PeerManager_process_events(&net2);
755 LDKThirtyTwoBytes payment_preimage;
758 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
759 ev2.process_pending_events(handler);
760 assert(queue.events.size() == 1);
761 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
762 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
763 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
764 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
765 Invoice_payment_secret(invoice->contents.result), 32));
766 assert(queue.events[0]->payment_received.amount_msat == 5000);
767 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
768 ChannelManager_claim_funds(&cm2, payment_preimage);
770 queue.events.clear();
771 ev2.process_pending_events(handler);
772 assert(queue.events.size() == 1);
773 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
774 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
775 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
777 PeerManager_process_events(&net2);
778 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
779 while (mons_updated != 5) {
780 std::this_thread::yield();
784 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
785 while (queue.events.size() < 2)
786 ev1.process_pending_events(ev1.this_arg, handler);
787 assert(queue.events.size() == 2);
788 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
789 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
790 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
791 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
796 cm1_ser = ChannelManager_write(&cm1);
797 cm2_ser = ChannelManager_write(&cm2);
800 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
801 assert(mons1.mons.size() == 1);
802 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
803 mons_list1->data[0].is_owned = false; // XXX: God this sucks
804 uint8_t node_seed[32];
805 memset(&node_seed, 0, 32);
806 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
807 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
809 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
810 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
811 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
812 assert(cm1_read->result_ok);
813 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
815 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
816 assert(mons2.mons.size() == 1);
817 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
818 mons_list2->data[0].is_owned = false; // XXX: God this sucks
819 memset(&node_seed, 1, 32);
820 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
822 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
823 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
824 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
825 assert(cm2_read->result_ok);
826 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
828 // Attempt to close the channel...
830 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
831 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
832 assert(!close_res->result_ok); // Note that we can't close while disconnected!
834 // Open a connection!
835 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1));
836 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
838 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
839 LDKCustomMessageHandler custom_msg_handler1 = {
840 .this_arg = &chan_2_node_id,
841 .handle_custom_message = NULL, // We only create custom messages, not handle them
842 .get_and_clear_pending_msg = create_custom_msg,
843 .CustomMessageReader = LDKCustomMessageReader {
845 .read = read_custom_message,
850 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
852 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2));
853 CustomMsgQueue peer_2_custom_messages;
854 LDKCustomMessageHandler custom_msg_handler2 = {
855 .this_arg = &peer_2_custom_messages,
856 .handle_custom_message = handle_custom_message,
857 .get_and_clear_pending_msg = never_send_custom_msgs,
858 .CustomMessageReader = LDKCustomMessageReader {
860 .read = read_custom_message,
865 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
866 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
868 PeersConnection conn(cm1, cm2, net1, net2);
871 // Wait for the channels to be considered up once the reestablish messages are processed
872 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
873 if (outbound_channels->datalen == 1) {
878 // Send another payment, this time via the InvoicePayer
879 struct CustomRouteFinderParams router_params = {
881 .graph_ref = &net_graph1,
882 .random_seed_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg),
884 LDKRouter sending_router = {
885 .this_arg = &router_params,
886 .find_route = custom_find_route,
889 LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1);
890 LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(ProbabilisticScorer_as_Score(&scorer));
892 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
893 LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, &scorer_mtx, logger1, handler1, Retry_attempts(0));
895 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
896 KeysManager_as_KeysInterface(&keys2),
897 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
899 .chars = (const uint8_t *)"Invoice 2 Description",
900 .len = strlen("Invoice 2 Description"),
901 .chars_is_owned = false
903 assert(invoice_res2->result_ok);
904 const LDKInvoice *invoice2 = invoice_res2->contents.result;
905 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = InvoicePayer_pay_invoice(&payer, invoice2);
906 assert(invoice_pay_res->result_ok);
907 PeerManager_process_events(&net1);
909 // Check that we received the payment!
912 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
913 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
914 ev2.process_pending_events(handler2);
915 if (queue2.events.size() == 1) {
916 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
919 std::this_thread::yield();
921 ChannelManager_process_pending_htlc_forwards(&cm2);
922 PeerManager_process_events(&net2);
926 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
927 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
928 ev2.process_pending_events(handler2);
929 if (queue2.events.size() == 1) {
930 assert(queue2.events[0]->tag == LDKEvent_PaymentReceived);
931 const struct LDKEvent_LDKPaymentReceived_Body *event_data = &queue2.events[0]->payment_received;
932 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
933 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
934 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
935 Invoice_payment_secret(invoice2), 32));
936 assert(event_data->amount_msat == 10000);
937 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage);
939 queue2.events.clear();
940 ev2.process_pending_events(handler2);
941 assert(queue2.events.size() == 1);
942 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
943 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Invoice_payment_hash(invoice2), 32));
944 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
948 std::this_thread::yield();
951 while (queue1.events.size() < 2) {
952 PeerManager_process_events(&net2);
953 PeerManager_process_events(&net1);
955 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
956 LDK::EventHandler evh1 = InvoicePayer_as_EventHandler(&payer);
957 ev1.process_pending_events(std::move(evh1));
959 assert(queue1.events.size() == 2);
960 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
961 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
963 // Actually close the channel
964 num_txs_broadcasted = 0;
965 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
966 assert(close_res->result_ok);
967 PeerManager_process_events(&net1);
968 while (num_txs_broadcasted != 2) {
969 std::this_thread::yield();
971 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
972 assert(chans_after_close1->datalen == 0);
973 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
974 assert(chans_after_close2->datalen == 0);
978 assert(peer_2_custom_messages.msgs.size() != 0);
980 // Few extra random tests:
983 LDKThirtyTwoBytes kdiv_params;
984 memset(&kdiv_params, 43, 32);
985 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);