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 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
690 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
692 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
693 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
695 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
696 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
697 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
699 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
700 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
701 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
703 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
704 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
705 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
706 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
708 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
709 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
710 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
711 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
713 PeerManager_process_events(&net1);
714 PeerManager_process_events(&net2);
716 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
717 uint8_t expected_chan_id[32];
718 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
720 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
723 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
724 ev2.process_pending_events(handler);
725 if (queue.events.size() == 1) {
726 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
727 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
730 std::this_thread::yield();
735 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
736 ev1.process_pending_events(handler);
737 if (queue.events.size() == 1) {
738 assert(queue.events[0]->tag == LDKEvent_ChannelReady);
739 assert(!memcmp(queue.events[0]->channel_ready.channel_id.data, expected_chan_id, 32));
742 std::this_thread::yield();
745 // Now send funds from 1 to 2!
746 uint64_t channel_scid;
748 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
749 if (outbound_channels->datalen == 1) {
750 const LDKChannelDetails *channel = &outbound_channels->data[0];
751 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
753 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
755 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
756 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
757 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
758 // We opened the channel with 1000 push_msat:
759 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
760 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
761 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
762 if (inbound_capacity < 0) inbound_capacity = 0;
763 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
764 assert(ChannelDetails_get_is_usable(channel));
765 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
766 assert(scid_opt->some);
767 channel_scid = scid_opt->some;
770 std::this_thread::yield();
773 LDKCOption_u64Z min_value = {
774 .tag = LDKCOption_u64Z_Some,
777 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
778 KeysManager_as_NodeSigner(&keys2), logger2,
779 LDKCurrency_Bitcoin, min_value,
781 .chars = (const uint8_t *)"Invoice Description",
782 .len = strlen("Invoice Description"),
783 .chars_is_owned = false
784 }, 3600, COption_u16Z_none());
785 assert(invoice->result_ok);
786 LDKThirtyTwoBytes payment_hash;
787 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
790 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
791 LDK::Score chan_scorer = LDKScore {
792 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
794 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
795 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
796 .inner = NULL, .is_owned = false
797 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff,
798 1, 2, LDKCVec_u64Z { .data = NULL, .datalen = 0 },
799 Invoice_min_final_cltv_expiry_delta(invoice->contents.result)),
801 random_bytes = entropy_source1.get_secure_random_bytes();
803 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
805 assert(route->result_ok);
806 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
807 assert(paths->datalen == 1);
808 assert(paths->data[0].datalen == 1);
809 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
810 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
811 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
812 LDKThirtyTwoBytes payment_secret;
813 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
814 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret, payment_hash);
815 assert(send_res->result_ok);
819 PeerManager_process_events(&net1);
820 while (mons_updated != 4) {
821 std::this_thread::yield();
824 // Check that we received the payment!
827 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
828 ev2.process_pending_events(handler);
829 if (queue.events.size() == 1) {
830 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
833 std::this_thread::yield();
835 ChannelManager_process_pending_htlc_forwards(&cm2);
836 PeerManager_process_events(&net2);
839 LDKThirtyTwoBytes payment_preimage;
842 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
843 ev2.process_pending_events(handler);
844 assert(queue.events.size() == 1);
845 assert(queue.events[0]->tag == LDKEvent_PaymentClaimable);
846 assert(!memcmp(queue.events[0]->payment_claimable.payment_hash.data, payment_hash.data, 32));
847 assert(queue.events[0]->payment_claimable.purpose.tag == LDKPaymentPurpose_InvoicePayment);
848 assert(!memcmp(queue.events[0]->payment_claimable.purpose.invoice_payment.payment_secret.data,
849 Invoice_payment_secret(invoice->contents.result), 32));
850 assert(queue.events[0]->payment_claimable.amount_msat == 5000);
851 memcpy(payment_preimage.data, queue.events[0]->payment_claimable.purpose.invoice_payment.payment_preimage.data, 32);
852 ChannelManager_claim_funds(&cm2, payment_preimage);
854 queue.events.clear();
855 ev2.process_pending_events(handler);
856 assert(queue.events.size() == 1);
857 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
858 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
859 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
861 PeerManager_process_events(&net2);
862 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
863 while (mons_updated != 5) {
864 std::this_thread::yield();
868 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
869 while (queue.events.size() < 2)
870 ev1.process_pending_events(handler);
871 assert(queue.events.size() == 2);
872 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
873 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
874 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
875 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
880 cm1_ser = ChannelManager_write(&cm1);
881 cm2_ser = ChannelManager_write(&cm2);
884 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
885 assert(mons1.mons.size() == 1);
886 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
887 mons_list1->data[0].is_owned = false; // XXX: God this sucks
888 uint8_t node_seed[32];
889 memset(&node_seed, 0, 32);
890 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
891 LDK::NodeSigner node_signer1 = KeysManager_as_NodeSigner(&keys1);
892 LDK::EntropySource entropy_source1 = KeysManager_as_EntropySource(&keys1);
893 LDK::SignerProvider signer_provider1 = KeysManager_as_SignerProvider(&keys1);
895 LDK::ProbabilisticScorer scorer1 = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1);
896 LDK::Score scorer_trait1 = ProbabilisticScorer_as_Score(&scorer1);
897 LDK::MultiThreadedLockableScore scorer_mtx1 = MultiThreadedLockableScore_new(std::move(scorer_trait1));
898 LDK::LockableScore scorer_mtx_trait1 = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx1);
899 const LDK::DefaultRouter default_router_1 = DefaultRouter_new(&net_graph1, logger1, entropy_source1.get_secure_random_bytes(), std::move(scorer_mtx_trait1));
900 LDKRouter router1 = {
901 .this_arg = (void*)&default_router_1,
902 .find_route = NULL, // LDK currently doesn't use this, its just a default-impl
903 .find_route_with_id = custom_find_route,
907 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));
908 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
909 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
910 assert(cm1_read->result_ok);
911 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
913 LDKCustomOnionMessageHandler custom_onion_msg_handler1 = {
915 .handle_custom_message = NULL, // We only create custom messages, not handle them
916 .read_custom_message = NULL, // We only create custom messages, not handle them
919 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_EntropySource(&keys1), KeysManager_as_NodeSigner(&keys1), logger1, custom_onion_msg_handler1);
921 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
922 assert(mons2.mons.size() == 1);
923 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
924 mons_list2->data[0].is_owned = false; // XXX: God this sucks
925 memset(&node_seed, 1, 32);
926 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
927 LDK::NodeSigner node_signer2 = KeysManager_as_NodeSigner(&keys2);
928 LDK::EntropySource entropy_source2 = KeysManager_as_EntropySource(&keys2);
929 LDK::SignerProvider signer_provider2 = KeysManager_as_SignerProvider(&keys2);
931 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));
932 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
933 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
934 assert(cm2_read->result_ok);
935 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
937 CustomOnionMsgQueue peer_2_custom_onion_messages;
938 LDKCustomOnionMessageHandler custom_onion_msg_handler2 = {
939 .this_arg = &peer_2_custom_onion_messages,
940 .handle_custom_message = handle_custom_onion_message,
941 .read_custom_message = read_custom_onion_message,
944 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_EntropySource(&keys2), KeysManager_as_NodeSigner(&keys2), logger2, custom_onion_msg_handler2);
946 // Attempt to close the channel...
948 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
949 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
950 assert(!close_res->result_ok); // Note that we can't close while disconnected!
952 // Open a connection!
953 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
954 random_bytes = entropy_source1.get_secure_random_bytes();
956 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
957 LDKCustomMessageHandler custom_msg_handler1 = {
958 .this_arg = &chan_2_node_id,
959 .handle_custom_message = NULL, // We only create custom messages, not handle them
960 .get_and_clear_pending_msg = create_custom_msg,
961 .CustomMessageReader = LDKCustomMessageReader {
963 .read = read_custom_message,
968 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1), std::move(node_signer1));
970 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2));
971 CustomMsgQueue peer_2_custom_messages;
972 LDKCustomMessageHandler custom_msg_handler2 = {
973 .this_arg = &peer_2_custom_messages,
974 .handle_custom_message = handle_custom_message,
975 .get_and_clear_pending_msg = never_send_custom_msgs,
976 .CustomMessageReader = LDKCustomMessageReader {
978 .read = read_custom_message,
983 random_bytes = entropy_source1.get_secure_random_bytes();
984 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2), std::move(node_signer2));
986 PeersConnection conn(cm1, cm2, net1, net2);
989 // Wait for the channels to be considered up once the reestablish messages are processed
990 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
991 if (outbound_channels->datalen == 1) {
996 // Send another payment, this time via the retires path
997 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
998 KeysManager_as_NodeSigner(&keys2), logger1,
999 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
1001 .chars = (const uint8_t *)"Invoice 2 Description",
1002 .len = strlen("Invoice 2 Description"),
1003 .chars_is_owned = false
1004 }, 3600, COption_u16Z_none());
1005 assert(invoice_res2->result_ok);
1006 const LDKInvoice *invoice2 = invoice_res2->contents.result;
1007 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = pay_invoice(invoice2, Retry_attempts(0), &cm1);
1008 assert(invoice_pay_res->result_ok);
1009 PeerManager_process_events(&net1);
1011 // Check that we received the payment!
1014 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1015 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1016 ev2.process_pending_events(handler2);
1017 if (queue2.events.size() == 1) {
1018 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
1021 std::this_thread::yield();
1023 ChannelManager_process_pending_htlc_forwards(&cm2);
1024 PeerManager_process_events(&net2);
1028 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1029 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1030 ev2.process_pending_events(handler2);
1031 if (queue2.events.size() == 1) {
1032 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimable);
1033 const struct LDKEvent_LDKPaymentClaimable_Body *event_data = &queue2.events[0]->payment_claimable;
1034 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
1035 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
1036 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
1037 Invoice_payment_secret(invoice2), 32));
1038 assert(event_data->amount_msat == 10000);
1039 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage);
1041 queue2.events.clear();
1042 ev2.process_pending_events(handler2);
1043 assert(queue2.events.size() == 1);
1044 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
1045 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Invoice_payment_hash(invoice2), 32));
1046 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
1050 std::this_thread::yield();
1054 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
1055 while (queue1.events.size() < 2) {
1056 PeerManager_process_events(&net2);
1057 PeerManager_process_events(&net1);
1059 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
1060 ev1.process_pending_events(handler1);
1062 assert(queue1.events.size() == 2);
1063 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
1064 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
1066 // Actually close the channel
1067 num_txs_broadcasted = 0;
1068 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1069 assert(close_res->result_ok);
1070 PeerManager_process_events(&net1);
1071 while (num_txs_broadcasted != 2) {
1072 std::this_thread::yield();
1074 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
1075 assert(chans_after_close1->datalen == 0);
1076 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
1077 assert(chans_after_close2->datalen == 0);
1079 assert(OnionMessenger_send_onion_message(&om1,
1080 LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, },
1081 Destination_node(ChannelManager_get_our_node_id(&cm2)),
1082 LDKOnionMessageContents {
1083 .tag = LDKOnionMessageContents_Custom,
1084 .custom = build_custom_onion_message()
1085 }, LDKBlindedPath { .inner = NULL, .is_owned = true })
1087 PeerManager_process_events(&net1);
1089 std::this_thread::yield();
1090 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1091 if (peer_2_custom_onion_messages.msgs.size() != 0) break;
1096 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1097 assert(peer_2_custom_onion_messages.msgs.size() == 1);
1098 assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888);
1099 assert(peer_2_custom_messages.msgs.size() != 0);
1101 // Few extra random tests:
1103 memset(&sk, 42, 32);
1104 LDKThirtyTwoBytes kdiv_params;
1105 memset(&kdiv_params, 43, 32);
1106 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);