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)));
246 // Wait for the new connection handshake...
247 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
248 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
249 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
250 std::this_thread::yield();
253 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
255 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2));
256 // Wait for the peers to disconnect...
257 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
258 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
259 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
260 std::this_thread::yield();
262 // Note that the above is somewhat race-y, as node 2 may still think its connected.
263 // Thus, make sure any connections are disconnected on its end as well.
264 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1));
266 // Finally make an actual connection and keep it this time
267 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
270 // Wait for the initial handshakes to complete...
271 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
272 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
273 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
274 std::this_thread::yield();
278 interrupt_socket_handling(node1_handler);
279 interrupt_socket_handling(node2_handler);
285 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
286 return write((int)((long)this_arg), data.data, data.datalen);
288 void sock_disconnect_socket(void *this_arg) {
289 close((int)((long)this_arg));
291 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
292 return this_arg == other_arg->this_arg;
294 uint64_t sock_hash(const void *this_arg) {
295 return (uint64_t)this_arg;
297 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
298 unsigned char buf[1024];
302 while ((readlen = read(rdfd, buf, 1024)) > 0) {
303 data.datalen = readlen;
304 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
305 if (!res->result_ok) {
306 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
309 PeerManager_process_events(pm);
311 PeerManager_socket_disconnected(&*pm, peer_descriptor);
314 class PeersConnection {
315 int pipefds_1_to_2[2];
316 int pipefds_2_to_1[2];
318 LDKSocketDescriptor sock1, sock2;
321 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
322 assert(!pipe(pipefds_1_to_2));
323 assert(!pipe(pipefds_2_to_1));
325 sock1 = LDKSocketDescriptor {
326 .this_arg = (void*)(long)pipefds_1_to_2[1],
327 .send_data = sock_send_data,
328 .disconnect_socket = sock_disconnect_socket,
335 sock2 = LDKSocketDescriptor {
336 .this_arg = (void*)(long)pipefds_2_to_1[1],
337 .send_data = sock_send_data,
338 .disconnect_socket = sock_disconnect_socket,
345 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
346 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
348 // Note that we have to bind the result to a C++ class to make sure it gets free'd
349 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_NetAddressZ_none());
350 assert(con_res->result_ok);
351 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_NetAddressZ_none());
352 assert(con_res2->result_ok);
354 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
355 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
358 // Wait for the initial handshakes to complete...
359 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_1 = PeerManager_get_peer_node_ids(&net1);
360 LDK::CVec_C2Tuple_PublicKeyCOption_NetAddressZZZ peers_2 = PeerManager_get_peer_node_ids(&net2);
361 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
362 std::this_thread::yield();
367 close(pipefds_1_to_2[0]);
368 close(pipefds_2_to_1[0]);
369 close(pipefds_1_to_2[1]);
370 close(pipefds_2_to_1[1]);
377 struct CustomOnionMsgQueue {
379 std::vector<LDK::CustomOnionMessageContents> msgs;
382 uint64_t custom_onion_msg_type_id(const void *this_arg) {
385 LDKCVec_u8Z custom_onion_msg_bytes(const void *this_arg) {
386 uint8_t *bytes = (uint8_t *) malloc(1024);
387 memset(bytes, 43, 1024);
389 .data = bytes, .datalen = 1024
393 void handle_custom_onion_message(const void* this_arg, struct LDKCustomOnionMessageContents msg) {
394 CustomOnionMsgQueue* arg = (CustomOnionMsgQueue*) this_arg;
395 std::unique_lock<std::mutex> lck(arg->mtx);
396 arg->msgs.push_back(std::move(msg));
399 LDKCustomOnionMessageContents build_custom_onion_message() {
400 return LDKCustomOnionMessageContents {
402 .tlv_type = custom_onion_msg_type_id,
403 .write = custom_onion_msg_bytes,
408 LDKCResult_COption_CustomOnionMessageContentsZDecodeErrorZ read_custom_onion_message(const void* this_arg, uint64_t type, LDKu8slice buf) {
409 assert(type == 8888);
410 assert(buf.datalen == 1024);
412 memset(cmp, 43, 1024);
413 assert(!memcmp(cmp, buf.data, 1024));
414 return CResult_COption_CustomOnionMessageContentsZDecodeErrorZ_ok(COption_CustomOnionMessageContentsZ_some(build_custom_onion_message()));
418 struct CustomMsgQueue {
419 std::vector<LDK::Type> msgs;
422 uint16_t custom_msg_type_id(const void *this_arg) {
425 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
426 uint8_t *bytes = (uint8_t *) malloc(1024);
427 memset(bytes, 42, 1024);
429 .data = bytes, .datalen = 1024
432 LDKStr custom_msg_debug(const void *this_arg) {
434 .chars = (const unsigned char*) "Custom Message", .len = 14, .chars_is_owned = false
438 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
439 assert(type_id == 8888);
440 assert(buf.datalen == 1024);
442 memset(cmp, 42, 1024);
443 assert(!memcmp(cmp, buf.data, 1024));
444 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
446 .type_id = custom_msg_type_id,
447 .debug_str = custom_msg_debug,
452 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
453 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
454 arg->msgs.push_back(std::move(msg));
455 return CResult_NoneLightningErrorZ_ok();
457 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
458 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
459 .data = NULL, .datalen = 0
463 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
464 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
465 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
466 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
469 ret.data[0].a = *counterparty_node_id;
470 ret.data[0].b = LDKType {
472 .type_id = custom_msg_type_id,
473 .debug_str = custom_msg_debug,
474 .write = custom_msg_bytes,
480 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst, LDKChannelUsage usage_in) {
481 LDK::ChannelUsage usage(std::move(usage_in));
485 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, LDKThirtyTwoBytes payment_id, LDKThirtyTwoBytes payment_hash) {
486 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
487 assert(first_hops->datalen == 1);
488 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
489 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
490 return router_impl->find_route(router_impl->this_arg, payer, route_params, first_hops, in_flights);
494 uint8_t channel_open_header[80];
495 uint8_t header_1[80];
496 uint8_t header_2[80];
497 memcpy(channel_open_header, channel_open_block, 80);
498 memcpy(header_1, block_1, 80);
499 memcpy(header_2, block_2, 80);
501 LDKPublicKey null_pk;
502 memset(&null_pk, 0, sizeof(null_pk));
504 LDKThirtyTwoBytes random_bytes;
505 LDKThirtyTwoBytes chain_tip;
506 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
508 LDKNetwork network = LDKNetwork_Testnet;
510 // Trait implementations:
511 LDKBroadcasterInterface broadcast {
513 .broadcast_transaction = broadcast_tx,
517 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
519 .this_arg = (void*)1,
525 mons1.logger = &logger1;
528 .watch_channel = add_channel_monitor,
529 .update_channel = update_channel_monitor,
530 .release_pending_monitor_events = monitors_pending_monitor_events,
534 LDK::NetworkGraph net_graph1 = NetworkGraph_new(network, logger1);
535 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_UtxoLookupZ_none(), logger1);
538 .this_arg = (void*)2,
544 mons2.logger = &logger2;
547 .watch_channel = add_channel_monitor,
548 .update_channel = update_channel_monitor,
549 .release_pending_monitor_events = monitors_pending_monitor_events,
553 LDKRouter panic_router = {
555 .find_route = NULL, // Segfault if we ever try to find a route
556 .find_route_with_id = NULL, // Segfault if we ever try to find a route
560 LDK::NetworkGraph net_graph2 = NetworkGraph_new(network, logger2);
561 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_UtxoLookupZ_none(), logger2);
563 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
564 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
566 { // Scope for the ser-des reload
567 // Instantiate classes for node 1:
568 uint8_t node_seed[32];
569 memset(&node_seed, 0, 32);
570 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
571 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
572 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
573 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
575 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)));
577 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
578 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
579 LDK::CustomOnionMessageHandler custom_onion_msg_handler1 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler1);
581 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), logger1, std::move(custom_onion_msg_handler1));
583 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
584 assert(channels->datalen == 0);
586 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
588 random_bytes = entropy_source1.get_secure_random_bytes();
589 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1), std::move(node_signer1));
591 // Demo getting a channel key and check that its returning real pubkeys:
592 LDKSixteenBytes user_id_1 { .data = {45, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0} };
593 LDKThirtyTwoBytes chan_signer_id1 = signer_provider1.generate_channel_keys_id(false, 42, U128_new(user_id_1));
594 LDK::WriteableEcdsaChannelSigner chan_signer1 = signer_provider1.derive_channel_signer(42, chan_signer_id1);
595 chan_signer1->EcdsaChannelSigner.ChannelSigner.set_pubkeys(&chan_signer1->EcdsaChannelSigner.ChannelSigner); // Make sure pubkeys is defined
596 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->EcdsaChannelSigner.ChannelSigner.pubkeys);
597 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
599 // Instantiate classes for node 2:
600 memset(&node_seed, 1, 32);
601 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
602 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
603 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
604 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
606 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
607 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
608 LDK::UserConfig config2 = UserConfig_default();
609 UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2));
611 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)));
613 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
614 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
615 LDK::CustomOnionMessageHandler custom_onion_msg_handler2 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler2);
617 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), logger2, std::move(custom_onion_msg_handler2));
619 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
620 assert(channels2->datalen == 0);
622 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
623 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
624 assert(chan_ann->result_ok);
625 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
626 assert(ann_res->result_ok);
628 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2), OnionMessenger_as_OnionMessageHandler(&om1));
630 random_bytes = entropy_source2.get_secure_random_bytes();
631 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2), std::move(node_signer2));
633 // Open a connection!
634 PeersConnection conn(cm1, cm2, net1, net2);
636 // Note that we have to bind the result to a C++ class to make sure it gets free'd
637 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, U128_new(user_id_1), UserConfig_default());
638 assert(res->result_ok);
639 PeerManager_process_events(&net1);
641 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
642 assert(new_channels->datalen == 1);
643 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
644 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
645 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
648 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
649 if (new_channels_2->datalen == 1) {
650 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
651 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
652 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
653 assert(init_feats->inner != NULL);
656 std::this_thread::yield();
659 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
662 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
663 ev1.process_pending_events(handler);
664 if (queue.events.size() == 1) {
665 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
666 LDKSixteenBytes event_id = U128_le_bytes(queue.events[0]->funding_generation_ready.user_channel_id);
667 assert(!memcmp(&event_id, &user_id_1, 16));
668 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
669 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
671 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
672 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
674 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);
675 assert(fund_res->result_ok);
678 std::this_thread::yield();
681 // We observe when the funding signed messages have been exchanged by
682 // waiting for two monitors to be registered.
683 assert(num_txs_broadcasted == 0);
684 PeerManager_process_events(&net1);
685 while (num_txs_broadcasted != 1) {
686 std::this_thread::yield();
689 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
690 uint8_t expected_chan_id[32];
691 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
695 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
696 ev1.process_pending_events(handler);
697 if (queue.events.size() == 1) {
698 assert(queue.events[0]->tag == LDKEvent_ChannelPending);
699 assert(!memcmp(queue.events[0]->channel_pending.channel_id.data, expected_chan_id, 32));
702 std::this_thread::yield();
705 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
708 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
709 ev2.process_pending_events(handler);
710 if (queue.events.size() == 1) {
711 assert(queue.events[0]->tag == LDKEvent_ChannelPending);
712 assert(!memcmp(queue.events[0]->channel_pending.channel_id.data, expected_chan_id, 32));
715 std::this_thread::yield();
718 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
719 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
721 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
722 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
724 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
725 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
726 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
728 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
729 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
730 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
732 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
733 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
734 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
735 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
737 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
738 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
739 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
740 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
742 PeerManager_process_events(&net1);
743 PeerManager_process_events(&net2);
747 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
748 ev2.process_pending_events(handler);
749 if (queue.events.size() == 1) {
750 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
751 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
754 std::this_thread::yield();
759 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
760 ev1.process_pending_events(handler);
761 if (queue.events.size() == 1) {
762 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
763 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
766 std::this_thread::yield();
769 // Now send funds from 1 to 2!
770 uint64_t channel_scid;
772 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
773 if (outbound_channels->datalen == 1) {
774 const LDKChannelDetails *channel = &outbound_channels->data[0];
775 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
777 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
779 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
780 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
781 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
782 // We opened the channel with 1000 push_msat:
783 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
784 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
785 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
786 if (inbound_capacity < 0) inbound_capacity = 0;
787 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
788 assert(ChannelDetails_get_is_usable(channel));
789 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
790 assert(scid_opt->some);
791 channel_scid = scid_opt->some;
794 std::this_thread::yield();
797 LDKCOption_u64Z min_value = {
798 .tag = LDKCOption_u64Z_Some,
801 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
802 KeysManager_as_NodeSigner(&keys2), logger2,
803 LDKCurrency_Bitcoin, min_value,
805 .chars = (const uint8_t *)"Invoice Description",
806 .len = strlen("Invoice Description"),
807 .chars_is_owned = false
808 }, 3600, COption_u16Z_none());
809 assert(invoice->result_ok);
810 LDKThirtyTwoBytes payment_hash;
811 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
814 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
815 LDK::Score chan_scorer = LDKScore {
816 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
818 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
819 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
820 .inner = NULL, .is_owned = false
821 }, Hints_clear(Invoice_route_hints(invoice->contents.result)), COption_u64Z_none(),
822 0xffffffff, 1, 2, LDKCVec_u64Z { .data = NULL, .datalen = 0 },
823 Invoice_min_final_cltv_expiry_delta(invoice->contents.result)),
825 random_bytes = entropy_source1.get_secure_random_bytes();
827 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
829 assert(route->result_ok);
830 LDK::CVec_PathZ paths = Route_get_paths(route->contents.result);
831 assert(paths->datalen == 1);
832 LDK::CVec_RouteHopZ hops = Path_get_hops(&paths->data[0]);
833 assert(hops->datalen == 1);
834 assert(!memcmp(RouteHop_get_pubkey(&hops->data[0]).compressed_form,
835 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
836 assert(RouteHop_get_short_channel_id(&hops->data[0]) == channel_scid);
837 LDKThirtyTwoBytes payment_secret;
838 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
839 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment_with_route(&cm1,
840 route->contents.result, payment_hash, RecipientOnionFields_secret_only(payment_secret), payment_hash);
841 assert(send_res->result_ok);
845 PeerManager_process_events(&net1);
846 while (mons_updated != 4) {
847 std::this_thread::yield();
850 // Check that we received the payment!
853 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
854 ev2.process_pending_events(handler);
855 if (queue.events.size() == 1) {
856 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
859 std::this_thread::yield();
861 ChannelManager_process_pending_htlc_forwards(&cm2);
862 PeerManager_process_events(&net2);
865 LDKThirtyTwoBytes payment_preimage;
868 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
869 ev2.process_pending_events(handler);
870 assert(queue.events.size() == 1);
871 assert(queue.events[0]->tag == LDKEvent_PaymentClaimable);
872 assert(!memcmp(queue.events[0]->payment_claimable.payment_hash.data, payment_hash.data, 32));
873 assert(queue.events[0]->payment_claimable.purpose.tag == LDKPaymentPurpose_InvoicePayment);
874 assert(!memcmp(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_secret.data,
875 Invoice_payment_secret(invoice->contents.result), 32));
876 assert(queue.events[0]->payment_claimable.amount_msat == 5000);
877 memcpy(payment_preimage.data, queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.data, 32);
878 ChannelManager_claim_funds(&cm2, payment_preimage);
880 queue.events.clear();
881 ev2.process_pending_events(handler);
882 assert(queue.events.size() == 1);
883 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
884 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
885 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
887 PeerManager_process_events(&net2);
888 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
889 while (mons_updated != 5) {
890 std::this_thread::yield();
894 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
895 while (queue.events.size() < 2)
896 ev1.process_pending_events(handler);
897 assert(queue.events.size() == 2);
898 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
899 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
900 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
901 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
906 cm1_ser = ChannelManager_write(&cm1);
907 cm2_ser = ChannelManager_write(&cm2);
910 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
911 assert(mons1.mons.size() == 1);
912 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
913 mons_list1->data[0].is_owned = false; // XXX: God this sucks
914 uint8_t node_seed[32];
915 memset(&node_seed, 0, 32);
916 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
917 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
918 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
919 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
921 LDK::ProbabilisticScorer scorer1 = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1);
922 LDK::Score scorer_trait1 = ProbabilisticScorer_as_Score(&scorer1);
923 LDK::MultiThreadedLockableScore scorer_mtx1 = MultiThreadedLockableScore_new(std::move(scorer_trait1));
924 LDK::LockableScore scorer_mtx_trait1 = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx1);
925 const LDK::DefaultRouter default_router_1 = DefaultRouter_new(&net_graph1, logger1, entropy_source1.get_secure_random_bytes(), std::move(scorer_mtx_trait1));
926 LDKRouter router1 = {
927 .this_arg = (void*)&default_router_1,
928 .find_route = NULL, // LDK currently doesn't use this, its just a default-impl
929 .find_route_with_id = custom_find_route,
933 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));
934 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
935 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
936 assert(cm1_read->result_ok);
937 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
939 LDKCustomOnionMessageHandler custom_onion_msg_handler1 = {
941 .handle_custom_message = NULL, // We only create custom messages, not handle them
942 .read_custom_message = NULL, // We only create custom messages, not handle them
945 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), logger1, custom_onion_msg_handler1);
947 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
948 assert(mons2.mons.size() == 1);
949 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
950 mons_list2->data[0].is_owned = false; // XXX: God this sucks
951 memset(&node_seed, 1, 32);
952 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
953 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
954 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
955 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
957 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));
958 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
959 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
960 assert(cm2_read->result_ok);
961 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
963 CustomOnionMsgQueue peer_2_custom_onion_messages;
964 LDKCustomOnionMessageHandler custom_onion_msg_handler2 = {
965 .this_arg = &peer_2_custom_onion_messages,
966 .handle_custom_message = handle_custom_onion_message,
967 .read_custom_message = read_custom_onion_message,
970 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), logger2, custom_onion_msg_handler2);
972 // Attempt to close the channel...
974 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
975 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
976 assert(!close_res->result_ok); // Note that we can't close while disconnected!
978 // Open a connection!
979 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
980 random_bytes = entropy_source1.get_secure_random_bytes();
982 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
983 LDKCustomMessageHandler custom_msg_handler1 = {
984 .this_arg = &chan_2_node_id,
985 .handle_custom_message = NULL, // We only create custom messages, not handle them
986 .get_and_clear_pending_msg = create_custom_msg,
987 .CustomMessageReader = LDKCustomMessageReader {
989 .read = read_custom_message,
994 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1), std::move(node_signer1));
996 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2));
997 CustomMsgQueue peer_2_custom_messages;
998 LDKCustomMessageHandler custom_msg_handler2 = {
999 .this_arg = &peer_2_custom_messages,
1000 .handle_custom_message = handle_custom_message,
1001 .get_and_clear_pending_msg = never_send_custom_msgs,
1002 .CustomMessageReader = LDKCustomMessageReader {
1004 .read = read_custom_message,
1009 random_bytes = entropy_source1.get_secure_random_bytes();
1010 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2), std::move(node_signer2));
1012 PeersConnection conn(cm1, cm2, net1, net2);
1015 // Wait for the channels to be considered up once the reestablish messages are processed
1016 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
1017 if (outbound_channels->datalen == 1) {
1020 std::this_thread::yield();
1023 // Send another payment, this time via the retires path
1024 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
1025 KeysManager_as_NodeSigner(&keys2), logger1,
1026 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
1028 .chars = (const uint8_t *)"Invoice 2 Description",
1029 .len = strlen("Invoice 2 Description"),
1030 .chars_is_owned = false
1031 }, 3600, COption_u16Z_none());
1032 assert(invoice_res2->result_ok);
1033 const LDKInvoice *invoice2 = invoice_res2->contents.result;
1034 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = pay_invoice(invoice2, Retry_attempts(0), &cm1);
1035 assert(invoice_pay_res->result_ok);
1036 PeerManager_process_events(&net1);
1038 // Check that we received the payment!
1041 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1042 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1043 ev2.process_pending_events(handler2);
1044 if (queue2.events.size() == 1) {
1045 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
1048 std::this_thread::yield();
1050 ChannelManager_process_pending_htlc_forwards(&cm2);
1051 PeerManager_process_events(&net2);
1055 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1056 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1057 ev2.process_pending_events(handler2);
1058 if (queue2.events.size() == 1) {
1059 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimable);
1060 const struct LDKEvent_LDKPaymentClaimable_Body *event_data = &queue2.events[0]->payment_claimable;
1061 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
1062 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
1063 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
1064 Invoice_payment_secret(invoice2), 32));
1065 assert(event_data->amount_msat == 10000);
1066 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage);
1068 queue2.events.clear();
1069 ev2.process_pending_events(handler2);
1070 assert(queue2.events.size() == 1);
1071 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
1072 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Invoice_payment_hash(invoice2), 32));
1073 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
1077 std::this_thread::yield();
1081 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
1082 while (queue1.events.size() < 2) {
1083 PeerManager_process_events(&net2);
1084 PeerManager_process_events(&net1);
1086 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
1087 ev1.process_pending_events(handler1);
1089 assert(queue1.events.size() == 2);
1090 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
1091 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
1093 // Actually close the channel
1094 num_txs_broadcasted = 0;
1095 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1096 assert(close_res->result_ok);
1097 PeerManager_process_events(&net1);
1098 while (num_txs_broadcasted != 2) {
1099 std::this_thread::yield();
1101 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
1102 assert(chans_after_close1->datalen == 0);
1103 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
1104 assert(chans_after_close2->datalen == 0);
1106 assert(OnionMessenger_send_onion_message(&om1,
1107 LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, },
1108 Destination_node(ChannelManager_get_our_node_id(&cm2)),
1109 LDKOnionMessageContents {
1110 .tag = LDKOnionMessageContents_Custom,
1111 .custom = build_custom_onion_message()
1112 }, LDKBlindedPath { .inner = NULL, .is_owned = true })
1114 PeerManager_process_events(&net1);
1116 std::this_thread::yield();
1117 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1118 if (peer_2_custom_onion_messages.msgs.size() != 0) break;
1123 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1124 assert(peer_2_custom_onion_messages.msgs.size() == 1);
1125 assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888);
1126 assert(peer_2_custom_messages.msgs.size() != 0);
1128 // Few extra random tests:
1130 memset(&sk, 42, 32);
1131 LDKThirtyTwoBytes kdiv_params;
1132 memset(&kdiv_params, 43, 32);
1133 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params, kdiv_params);