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.
58 // Note that the merkle root is incorrect, but it isn't ever checked by LDK, so should be fine.
59 const uint8_t channel_open_block[] = {
60 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0xa2, 0x47, 0xd2, 0xf8, 0xd4, 0xe0, 0x6a, 0x3f, 0xf9, 0x7a, 0x9a, 0x34,
63 0xbb, 0xa9, 0x96, 0xde, 0x63, 0x84, 0x5a, 0xce, 0xcf, 0x98, 0xb8, 0xbb, 0x75, 0x4c, 0x4f, 0x7d,
64 0xee, 0x4c, 0xa9, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x01, // transaction count
66 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0xc5, 0x1c, 0xad, 0x5e,
70 0x51, 0x11, 0xb0, 0x11, 0xa1, 0x14, 0xf4, 0xda, 0x02, 0x3d, 0xbc, 0xc1, 0x44, 0x3c, 0x67, 0x31,
71 0xec, 0x6f, 0x10, 0x2f, 0x89, 0xc1, 0x05, 0x80, 0xfe, 0xfc, 0xd6, 0xc7, 0x01, 0x00, 0x00, 0x00,
75 // The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data.
76 const uint8_t channel_open_txid[] = {
77 0x7a, 0x14, 0x8f, 0xb4, 0x08, 0x49, 0x9b, 0x51, 0x2e, 0xff, 0xf9, 0x46, 0x73, 0xca, 0xc6, 0x48,
78 0xfd, 0x95, 0x0e, 0x72, 0xd4, 0xd3, 0xdb, 0x79, 0xc9, 0x20, 0xed, 0x83, 0xb2, 0xde, 0xed, 0x41,
81 // Two blocks built on top of channel_open_block:
82 const uint8_t block_1[81] = {
83 0x01, 0x00, 0x00, 0x00, 0x0c, 0x7a, 0xc2, 0xdc, 0x08, 0xaf, 0x40, 0x7d, 0x58, 0x81, 0x9b, 0x44,
84 0xc7, 0xe0, 0x0f, 0x78, 0xc0, 0xd1, 0x01, 0xa2, 0x03, 0x16, 0x4a, 0x8d, 0x92, 0x66, 0x4e, 0xaf,
85 0x7f, 0xfc, 0x6e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x00, // transaction count
90 const uint8_t block_2[81] = {
91 0x01, 0x00, 0x00, 0x00, 0x36, 0x0b, 0xf5, 0x46, 0x4a, 0xc7, 0x26, 0x4c, 0x4b, 0x36, 0xa6, 0x9d,
92 0x0e, 0xf0, 0x14, 0xfb, 0x8a, 0xcb, 0x20, 0x84, 0x18, 0xf3, 0xaa, 0x77, 0x32, 0x2d, 0xf7, 0x48,
93 0x62, 0x92, 0xb1, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, // transaction count
99 void print_log(const void *this_arg, const LDKRecord *record) {
100 LDK::Str mod = Record_get_module_path(record);
101 LDK::Str str = Record_get_args(record);
102 printf("%p - %.*s:%d - %.*s\n", this_arg, (int)mod->len, mod->chars, Record_get_line(record), (int)str->len, str->chars);
105 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
106 if (target == LDKConfirmationTarget_Background) {
111 // Note that we don't call _free() on target, but that's OK, its unitary
113 // We use the same fee estimator globally:
114 const LDKFeeEstimator fee_est {
116 .get_est_sat_per_1000_weight = get_fee,
120 static std::atomic_int num_txs_broadcasted(0);
121 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
122 num_txs_broadcasted += 1;
124 Transaction_free(tx);
127 struct NodeMonitors {
129 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
132 void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
133 std::unique_lock<std::mutex> l(mut);
134 for (auto& mon : mons) {
135 LDK::CVec_TransactionOutputsZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
140 LDKChannelMonitorUpdateStatus add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
141 // First bind the args to C++ objects so they auto-free
142 LDK::ChannelMonitor mon(std::move(monitor_arg));
143 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
145 NodeMonitors* arg = (NodeMonitors*) this_arg;
146 std::unique_lock<std::mutex> l(arg->mut);
148 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
149 return ChannelMonitorUpdateStatus_completed();
151 static std::atomic_int mons_updated(0);
152 LDKChannelMonitorUpdateStatus update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, const LDKChannelMonitorUpdate *update) {
153 // First bind the args to C++ objects so they auto-free
154 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
156 NodeMonitors* arg = (NodeMonitors*) this_arg;
157 std::unique_lock<std::mutex> l(arg->mut);
159 bool updated = false;
160 for (auto& mon : arg->mons) {
161 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
162 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
164 LDKBroadcasterInterface broadcaster = {
165 .broadcast_transaction = broadcast_tx,
167 LDK::CResult_NoneNoneZ res = ChannelMonitor_update_monitor(&mon.second, update, &broadcaster, fee_est, arg->logger);
168 assert(res->result_ok);
174 return ChannelMonitorUpdateStatus_completed();
176 LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ monitors_pending_monitor_events(const void *this_arg) {
177 NodeMonitors* arg = (NodeMonitors*) this_arg;
178 std::unique_lock<std::mutex> l(arg->mut);
180 if (arg->mons.size() == 0) {
181 return LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
186 // We only ever actually have one channel per node, plus concatenating two
187 // Rust Vecs to each other from C++ will require a bit of effort.
188 assert(arg->mons.size() == 1);
189 LDK::CVec_MonitorEventZ events = ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
190 LDK::C2Tuple_OutPointScriptZ funding_info = ChannelMonitor_get_funding_txo(&arg->mons[0].second);
191 LDK::OutPoint outpoint = std::move(funding_info->a);
192 LDKPublicKey counterparty_node_id = ChannelMonitor_get_counterparty_node_id(&arg->mons[0].second);
193 LDK::C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ tuple = C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_new(std::move(outpoint), std::move(events), std::move(counterparty_node_id));
194 auto vec = LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
195 .data = (LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ*)malloc(sizeof(LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ)),
198 vec.data[0] = std::move(tuple);
204 std::vector<LDK::Event> events;
206 void handle_event(const void *this_arg, LDKEvent event) {
207 EventQueue* arg = (EventQueue*) this_arg;
208 arg->events.push_back(std::move(event));
212 class PeersConnection {
217 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
218 node1_handler = init_socket_handling(&net1);
219 node2_handler = init_socket_handling(&net2);
221 struct sockaddr_in listen_addr;
222 listen_addr.sin_family = AF_INET;
223 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
224 listen_addr.sin_port = htons(10042);
225 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
227 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
230 // Wait for the initial handshakes to complete...
231 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
232 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
233 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
234 std::this_thread::yield();
237 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
238 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
239 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
241 // Then disconnect the "main" connection, while another connection is being made.
242 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2));
243 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
245 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
247 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2));
248 // Wait for the peers to disconnect...
249 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
250 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
251 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
252 std::this_thread::yield();
254 // Note that the above is somewhat race-y, as node 2 may still think its connected.
255 // Thus, make sure any connections are disconnected on its end as well.
256 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1));
258 // Finally make an actual connection and keep it this time
259 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
262 // Wait for the initial handshakes to complete...
263 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
264 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
265 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
266 std::this_thread::yield();
270 interrupt_socket_handling(node1_handler);
271 interrupt_socket_handling(node2_handler);
277 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
278 return write((int)((long)this_arg), data.data, data.datalen);
280 void sock_disconnect_socket(void *this_arg) {
281 close((int)((long)this_arg));
283 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
284 return this_arg == other_arg->this_arg;
286 uint64_t sock_hash(const void *this_arg) {
287 return (uint64_t)this_arg;
289 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
290 unsigned char buf[1024];
294 while ((readlen = read(rdfd, buf, 1024)) > 0) {
295 data.datalen = readlen;
296 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
297 if (!res->result_ok) {
298 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
301 PeerManager_process_events(pm);
303 PeerManager_socket_disconnected(&*pm, peer_descriptor);
306 class PeersConnection {
307 int pipefds_1_to_2[2];
308 int pipefds_2_to_1[2];
310 LDKSocketDescriptor sock1, sock2;
313 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
314 assert(!pipe(pipefds_1_to_2));
315 assert(!pipe(pipefds_2_to_1));
317 sock1 = LDKSocketDescriptor {
318 .this_arg = (void*)(long)pipefds_1_to_2[1],
319 .send_data = sock_send_data,
320 .disconnect_socket = sock_disconnect_socket,
327 sock2 = LDKSocketDescriptor {
328 .this_arg = (void*)(long)pipefds_2_to_1[1],
329 .send_data = sock_send_data,
330 .disconnect_socket = sock_disconnect_socket,
337 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
338 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
340 // Note that we have to bind the result to a C++ class to make sure it gets free'd
341 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_NetAddressZ_none());
342 assert(con_res->result_ok);
343 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_NetAddressZ_none());
344 assert(con_res2->result_ok);
346 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
347 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
350 // Wait for the initial handshakes to complete...
351 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
352 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
353 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
354 std::this_thread::yield();
359 close(pipefds_1_to_2[0]);
360 close(pipefds_2_to_1[0]);
361 close(pipefds_1_to_2[1]);
362 close(pipefds_2_to_1[1]);
369 struct CustomOnionMsgQueue {
371 std::vector<LDK::CustomOnionMessageContents> msgs;
374 uint64_t custom_onion_msg_type_id(const void *this_arg) {
377 LDKCVec_u8Z custom_onion_msg_bytes(const void *this_arg) {
378 uint8_t *bytes = (uint8_t *) malloc(1024);
379 memset(bytes, 43, 1024);
381 .data = bytes, .datalen = 1024
385 void handle_custom_onion_message(const void* this_arg, struct LDKCustomOnionMessageContents msg) {
386 CustomOnionMsgQueue* arg = (CustomOnionMsgQueue*) this_arg;
387 std::unique_lock<std::mutex> lck(arg->mtx);
388 arg->msgs.push_back(std::move(msg));
391 LDKCustomOnionMessageContents build_custom_onion_message() {
392 return LDKCustomOnionMessageContents {
394 .tlv_type = custom_onion_msg_type_id,
395 .write = custom_onion_msg_bytes,
400 LDKCResult_COption_CustomOnionMessageContentsZDecodeErrorZ read_custom_onion_message(const void* this_arg, uint64_t type, LDKu8slice buf) {
401 assert(type == 8888);
402 assert(buf.datalen == 1024);
404 memset(cmp, 43, 1024);
405 assert(!memcmp(cmp, buf.data, 1024));
406 return CResult_COption_CustomOnionMessageContentsZDecodeErrorZ_ok(COption_CustomOnionMessageContentsZ_some(build_custom_onion_message()));
410 struct CustomMsgQueue {
411 std::vector<LDK::Type> msgs;
414 uint16_t custom_msg_type_id(const void *this_arg) {
417 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
418 uint8_t *bytes = (uint8_t *) malloc(1024);
419 memset(bytes, 42, 1024);
421 .data = bytes, .datalen = 1024
424 LDKStr custom_msg_debug(const void *this_arg) {
426 .chars = NULL, .len = 0, .chars_is_owned = false
430 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
431 assert(type_id == 8888);
432 assert(buf.datalen == 1024);
434 memset(cmp, 42, 1024);
435 assert(!memcmp(cmp, buf.data, 1024));
436 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
438 .type_id = custom_msg_type_id,
439 .debug_str = custom_msg_debug,
444 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
445 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
446 arg->msgs.push_back(std::move(msg));
447 return CResult_NoneLightningErrorZ_ok();
449 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
450 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
451 .data = NULL, .datalen = 0
455 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
456 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
457 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
458 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
461 ret.data[0].a = *counterparty_node_id;
462 ret.data[0].b = LDKType {
464 .type_id = custom_msg_type_id,
465 .debug_str = custom_msg_debug,
466 .write = custom_msg_bytes,
472 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst, LDKChannelUsage usage_in) {
473 LDK::ChannelUsage usage(std::move(usage_in));
477 struct LDKCResult_RouteLightningErrorZ custom_find_route(const void *this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKInFlightHtlcs *in_flights) {
478 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
479 assert(first_hops->datalen == 1);
480 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
481 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
482 return router_impl->find_route(router_impl->this_arg, payer, route_params, first_hops, in_flights);
486 uint8_t channel_open_header[80];
487 uint8_t header_1[80];
488 uint8_t header_2[80];
489 memcpy(channel_open_header, channel_open_block, 80);
490 memcpy(header_1, block_1, 80);
491 memcpy(header_2, block_2, 80);
493 LDKPublicKey null_pk;
494 memset(&null_pk, 0, sizeof(null_pk));
496 LDKThirtyTwoBytes random_bytes;
497 LDKThirtyTwoBytes chain_tip;
498 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
500 LDKNetwork network = LDKNetwork_Testnet;
502 // Trait implementations:
503 LDKBroadcasterInterface broadcast {
505 .broadcast_transaction = broadcast_tx,
509 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
511 .this_arg = (void*)1,
517 mons1.logger = &logger1;
520 .watch_channel = add_channel_monitor,
521 .update_channel = update_channel_monitor,
522 .release_pending_monitor_events = monitors_pending_monitor_events,
526 LDK::NetworkGraph net_graph1 = NetworkGraph_new(network, logger1);
527 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_UtxoLookupZ_none(), logger1);
530 .this_arg = (void*)2,
536 mons2.logger = &logger2;
539 .watch_channel = add_channel_monitor,
540 .update_channel = update_channel_monitor,
541 .release_pending_monitor_events = monitors_pending_monitor_events,
545 LDKRouter panic_router = {
547 .find_route = NULL, // Segfault if we ever try to find a route
551 LDK::NetworkGraph net_graph2 = NetworkGraph_new(network, logger2);
552 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_UtxoLookupZ_none(), logger2);
554 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
555 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
557 { // Scope for the ser-des reload
558 // Instantiate classes for node 1:
559 uint8_t node_seed[32];
560 memset(&node_seed, 0, 32);
561 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
562 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
563 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
564 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
566 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, panic_router, logger1, KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), KeysManager_as_SignerProvider(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
568 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
569 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
570 LDK::CustomOnionMessageHandler custom_onion_msg_handler1 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler1);
572 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), logger1, std::move(custom_onion_msg_handler1));
574 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
575 assert(channels->datalen == 0);
577 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
579 random_bytes = entropy_source1.get_secure_random_bytes();
580 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1), std::move(node_signer1));
582 // Demo getting a channel key and check that its returning real pubkeys:
583 LDKSixteenBytes user_id_1 { .data = {45, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0} };
584 LDKThirtyTwoBytes chan_signer_id1 = signer_provider1.generate_channel_keys_id(false, 42, U128_new(user_id_1));
585 LDK::WriteableEcdsaChannelSigner chan_signer1 = signer_provider1.derive_channel_signer(42, chan_signer_id1);
586 chan_signer1->EcdsaChannelSigner.ChannelSigner.set_pubkeys(&chan_signer1->EcdsaChannelSigner.ChannelSigner); // Make sure pubkeys is defined
587 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->EcdsaChannelSigner.ChannelSigner.pubkeys);
588 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
590 // Instantiate classes for node 2:
591 memset(&node_seed, 1, 32);
592 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
593 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
594 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
595 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
597 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
598 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
599 LDK::UserConfig config2 = UserConfig_default();
600 UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2));
602 LDK::ChannelManager cm2 = ChannelManager_new(fee_est, mon2, broadcast, panic_router, logger2, KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), KeysManager_as_SignerProvider(&keys2), std::move(config2), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
604 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
605 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
606 LDK::CustomOnionMessageHandler custom_onion_msg_handler2 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler2);
608 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), logger2, std::move(custom_onion_msg_handler2));
610 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
611 assert(channels2->datalen == 0);
613 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
614 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
615 assert(chan_ann->result_ok);
616 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
617 assert(ann_res->result_ok);
619 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2), OnionMessenger_as_OnionMessageHandler(&om1));
621 random_bytes = entropy_source2.get_secure_random_bytes();
622 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2), std::move(node_signer2));
624 // Open a connection!
625 PeersConnection conn(cm1, cm2, net1, net2);
627 // Note that we have to bind the result to a C++ class to make sure it gets free'd
628 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, U128_new(user_id_1), UserConfig_default());
629 assert(res->result_ok);
630 PeerManager_process_events(&net1);
632 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
633 assert(new_channels->datalen == 1);
634 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
635 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
636 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
639 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
640 if (new_channels_2->datalen == 1) {
641 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
642 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
643 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
644 assert(init_feats->inner != NULL);
647 std::this_thread::yield();
650 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
653 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
654 ev1.process_pending_events(handler);
655 if (queue.events.size() == 1) {
656 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
657 LDKSixteenBytes event_id = U128_le_bytes(queue.events[0]->funding_generation_ready.user_channel_id);
658 assert(!memcmp(&event_id, &user_id_1, 16));
659 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
660 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
662 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
663 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
665 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);
666 assert(fund_res->result_ok);
669 std::this_thread::yield();
672 // We observe when the funding signed messages have been exchanged by
673 // waiting for two monitors to be registered.
674 assert(num_txs_broadcasted == 0);
675 PeerManager_process_events(&net1);
676 while (num_txs_broadcasted != 1) {
677 std::this_thread::yield();
680 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
681 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
683 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
684 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
686 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
687 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
688 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
690 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
691 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
692 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
694 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
695 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
696 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
697 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
699 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
700 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
701 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
702 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
704 PeerManager_process_events(&net1);
705 PeerManager_process_events(&net2);
707 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
708 uint8_t expected_chan_id[32];
709 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
711 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
714 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
715 ev2.process_pending_events(handler);
716 if (queue.events.size() == 1) {
717 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
718 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
721 std::this_thread::yield();
726 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
727 ev1.process_pending_events(handler);
728 if (queue.events.size() == 1) {
729 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
730 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
733 std::this_thread::yield();
736 // Now send funds from 1 to 2!
737 uint64_t channel_scid;
739 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
740 if (outbound_channels->datalen == 1) {
741 const LDKChannelDetails *channel = &outbound_channels->data[0];
742 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
744 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
746 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
747 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
748 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
749 // We opened the channel with 1000 push_msat:
750 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
751 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
752 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
753 if (inbound_capacity < 0) inbound_capacity = 0;
754 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
755 assert(ChannelDetails_get_is_usable(channel));
756 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
757 assert(scid_opt->some);
758 channel_scid = scid_opt->some;
761 std::this_thread::yield();
764 LDKCOption_u64Z min_value = {
765 .tag = LDKCOption_u64Z_Some,
768 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
769 KeysManager_as_NodeSigner(&keys2), logger2,
770 LDKCurrency_Bitcoin, min_value,
772 .chars = (const uint8_t *)"Invoice Description",
773 .len = strlen("Invoice Description"),
774 .chars_is_owned = false
775 }, 3600, COption_u16Z_none());
776 assert(invoice->result_ok);
777 LDKThirtyTwoBytes payment_hash;
778 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
781 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
782 LDK::Score chan_scorer = LDKScore {
783 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
785 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
786 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
787 .inner = NULL, .is_owned = false
788 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff,
789 1, 2, LDKCVec_u64Z { .data = NULL, .datalen = 0 },
790 Invoice_min_final_cltv_expiry_delta(invoice->contents.result)),
792 random_bytes = entropy_source1.get_secure_random_bytes();
794 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
796 assert(route->result_ok);
797 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
798 assert(paths->datalen == 1);
799 assert(paths->data[0].datalen == 1);
800 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
801 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
802 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
803 LDKThirtyTwoBytes payment_secret;
804 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
805 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret, payment_hash);
806 assert(send_res->result_ok);
810 PeerManager_process_events(&net1);
811 while (mons_updated != 4) {
812 std::this_thread::yield();
815 // Check that we received the payment!
818 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
819 ev2.process_pending_events(handler);
820 if (queue.events.size() == 1) {
821 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
824 std::this_thread::yield();
826 ChannelManager_process_pending_htlc_forwards(&cm2);
827 PeerManager_process_events(&net2);
830 LDKThirtyTwoBytes payment_preimage;
833 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
834 ev2.process_pending_events(handler);
835 assert(queue.events.size() == 1);
836 assert(queue.events[0]->tag == LDKEvent_PaymentClaimable);
837 assert(!memcmp(queue.events[0]->payment_claimable.payment_hash.data, payment_hash.data, 32));
838 assert(queue.events[0]->payment_claimable.purpose.tag == LDKPaymentPurpose_InvoicePayment);
839 assert(!memcmp(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_secret.data,
840 Invoice_payment_secret(invoice->contents.result), 32));
841 assert(queue.events[0]->payment_claimable.amount_msat == 5000);
842 memcpy(payment_preimage.data, queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.data, 32);
843 ChannelManager_claim_funds(&cm2, payment_preimage);
845 queue.events.clear();
846 ev2.process_pending_events(handler);
847 assert(queue.events.size() == 1);
848 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
849 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
850 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
852 PeerManager_process_events(&net2);
853 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
854 while (mons_updated != 5) {
855 std::this_thread::yield();
859 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
860 while (queue.events.size() < 2)
861 ev1.process_pending_events(handler);
862 assert(queue.events.size() == 2);
863 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
864 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
865 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
866 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
871 cm1_ser = ChannelManager_write(&cm1);
872 cm2_ser = ChannelManager_write(&cm2);
875 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
876 assert(mons1.mons.size() == 1);
877 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
878 mons_list1->data[0].is_owned = false; // XXX: God this sucks
879 uint8_t node_seed[32];
880 memset(&node_seed, 0, 32);
881 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
882 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
883 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
884 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
886 LDK::ProbabilisticScorer scorer1 = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1);
887 LDK::Score scorer_trait1 = ProbabilisticScorer_as_Score(&scorer1);
888 LDK::MultiThreadedLockableScore scorer_mtx1 = MultiThreadedLockableScore_new(std::move(scorer_trait1));
889 LDK::LockableScore scorer_mtx_trait1 = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx1);
890 const LDK::DefaultRouter default_router_1 = DefaultRouter_new(&net_graph1, logger1, entropy_source1.get_secure_random_bytes(), std::move(scorer_mtx_trait1));
891 LDKRouter router1 = {
892 .this_arg = (void*)&default_router_1,
893 .find_route = custom_find_route,
897 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), KeysManager_as_SignerProvider(&keys1), fee_est, mon1, broadcast, router1, logger1, UserConfig_default(), std::move(mons_list1));
898 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
899 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
900 assert(cm1_read->result_ok);
901 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
903 LDKCustomOnionMessageHandler custom_onion_msg_handler1 = {
905 .handle_custom_message = NULL, // We only create custom messages, not handle them
906 .read_custom_message = NULL, // We only create custom messages, not handle them
909 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), logger1, custom_onion_msg_handler1);
911 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
912 assert(mons2.mons.size() == 1);
913 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
914 mons_list2->data[0].is_owned = false; // XXX: God this sucks
915 memset(&node_seed, 1, 32);
916 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
917 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
918 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
919 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
921 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), KeysManager_as_SignerProvider(&keys2), fee_est, mon2, broadcast, panic_router, logger2, UserConfig_default(), std::move(mons_list2));
922 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
923 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
924 assert(cm2_read->result_ok);
925 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
927 CustomOnionMsgQueue peer_2_custom_onion_messages;
928 LDKCustomOnionMessageHandler custom_onion_msg_handler2 = {
929 .this_arg = &peer_2_custom_onion_messages,
930 .handle_custom_message = handle_custom_onion_message,
931 .read_custom_message = read_custom_onion_message,
934 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), logger2, custom_onion_msg_handler2);
936 // Attempt to close the channel...
938 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
939 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
940 assert(!close_res->result_ok); // Note that we can't close while disconnected!
942 // Open a connection!
943 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
944 random_bytes = entropy_source1.get_secure_random_bytes();
946 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
947 LDKCustomMessageHandler custom_msg_handler1 = {
948 .this_arg = &chan_2_node_id,
949 .handle_custom_message = NULL, // We only create custom messages, not handle them
950 .get_and_clear_pending_msg = create_custom_msg,
951 .CustomMessageReader = LDKCustomMessageReader {
953 .read = read_custom_message,
958 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1), std::move(node_signer1));
960 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2));
961 CustomMsgQueue peer_2_custom_messages;
962 LDKCustomMessageHandler custom_msg_handler2 = {
963 .this_arg = &peer_2_custom_messages,
964 .handle_custom_message = handle_custom_message,
965 .get_and_clear_pending_msg = never_send_custom_msgs,
966 .CustomMessageReader = LDKCustomMessageReader {
968 .read = read_custom_message,
973 random_bytes = entropy_source1.get_secure_random_bytes();
974 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2), std::move(node_signer2));
976 PeersConnection conn(cm1, cm2, net1, net2);
979 // Wait for the channels to be considered up once the reestablish messages are processed
980 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
981 if (outbound_channels->datalen == 1) {
986 // Send another payment, this time via the retires path
987 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
988 KeysManager_as_NodeSigner(&keys2), logger1,
989 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
991 .chars = (const uint8_t *)"Invoice 2 Description",
992 .len = strlen("Invoice 2 Description"),
993 .chars_is_owned = false
994 }, 3600, COption_u16Z_none());
995 assert(invoice_res2->result_ok);
996 const LDKInvoice *invoice2 = invoice_res2->contents.result;
997 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = pay_invoice(invoice2, Retry_attempts(0), &cm1);
998 assert(invoice_pay_res->result_ok);
999 PeerManager_process_events(&net1);
1001 // Check that we received the payment!
1004 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1005 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1006 ev2.process_pending_events(handler2);
1007 if (queue2.events.size() == 1) {
1008 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
1011 std::this_thread::yield();
1013 ChannelManager_process_pending_htlc_forwards(&cm2);
1014 PeerManager_process_events(&net2);
1018 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1019 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1020 ev2.process_pending_events(handler2);
1021 if (queue2.events.size() == 1) {
1022 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimable);
1023 const struct LDKEvent_LDKPaymentClaimable_Body *event_data = &queue2.events[0]->payment_claimable;
1024 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
1025 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
1026 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
1027 Invoice_payment_secret(invoice2), 32));
1028 assert(event_data->amount_msat == 10000);
1029 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage);
1031 queue2.events.clear();
1032 ev2.process_pending_events(handler2);
1033 assert(queue2.events.size() == 1);
1034 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
1035 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Invoice_payment_hash(invoice2), 32));
1036 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
1040 std::this_thread::yield();
1044 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
1045 while (queue1.events.size() < 2) {
1046 PeerManager_process_events(&net2);
1047 PeerManager_process_events(&net1);
1049 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
1050 ev1.process_pending_events(handler1);
1052 assert(queue1.events.size() == 2);
1053 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
1054 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
1056 // Actually close the channel
1057 num_txs_broadcasted = 0;
1058 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1059 assert(close_res->result_ok);
1060 PeerManager_process_events(&net1);
1061 while (num_txs_broadcasted != 2) {
1062 std::this_thread::yield();
1064 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
1065 assert(chans_after_close1->datalen == 0);
1066 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
1067 assert(chans_after_close2->datalen == 0);
1069 assert(OnionMessenger_send_onion_message(&om1,
1070 LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, },
1071 Destination_node(ChannelManager_get_our_node_id(&cm2)),
1072 LDKOnionMessageContents {
1073 .tag = LDKOnionMessageContents_Custom,
1074 .custom = build_custom_onion_message()
1075 }, LDKBlindedPath { .inner = NULL, .is_owned = true })
1077 PeerManager_process_events(&net1);
1079 std::this_thread::yield();
1080 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1081 if (peer_2_custom_onion_messages.msgs.size() != 0) break;
1086 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1087 assert(peer_2_custom_onion_messages.msgs.size() == 1);
1088 assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888);
1089 assert(peer_2_custom_messages.msgs.size() != 0);
1091 // Few extra random tests:
1093 memset(&sk, 42, 32);
1094 LDKThirtyTwoBytes kdiv_params;
1095 memset(&kdiv_params, 43, 32);
1096 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);