8 #include "include/lightningpp.hpp"
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
24 const uint8_t valid_node_announcement[] = {
25 0x94, 0xe4, 0xf5, 0x61, 0x41, 0x24, 0x7d, 0x90, 0x23, 0xa0, 0xc8, 0x34, 0x8c, 0xc4, 0xca, 0x51,
26 0xd8, 0x17, 0x59, 0xff, 0x7d, 0xac, 0x8c, 0x9b, 0x63, 0x29, 0x1c, 0xe6, 0x12, 0x12, 0x93, 0xbd,
27 0x66, 0x4d, 0x6b, 0x9c, 0xfb, 0x35, 0xda, 0x16, 0x06, 0x3d, 0xf0, 0x8f, 0x8a, 0x39, 0x99, 0xa2,
28 0xf2, 0x5d, 0x12, 0x0f, 0x2b, 0x42, 0x1b, 0x8b, 0x9a, 0xfe, 0x33, 0x0c, 0xeb, 0x33, 0x5e, 0x52,
29 0xee, 0x99, 0xa1, 0x07, 0x06, 0xed, 0xf8, 0x48, 0x7a, 0xc6, 0xe5, 0xf5, 0x5e, 0x01, 0x3a, 0x41,
30 0x2f, 0x18, 0x94, 0x8a, 0x3b, 0x0a, 0x52, 0x3f, 0xbf, 0x61, 0xa9, 0xc5, 0x4f, 0x70, 0xee, 0xb8,
31 0x79, 0x23, 0xbb, 0x1a, 0x44, 0x7d, 0x91, 0xe6, 0x2a, 0xbc, 0xa1, 0x07, 0xbc, 0x65, 0x3b, 0x02,
32 0xd9, 0x1d, 0xb2, 0xf2, 0x3a, 0xcb, 0x75, 0x79, 0xc6, 0x66, 0xd8, 0xc1, 0x71, 0x29, 0xdf, 0x04,
33 0x60, 0xf4, 0xbf, 0x07, 0x7b, 0xb9, 0xc2, 0x11, 0x94, 0x6a, 0x28, 0xc2, 0xdd, 0xd8, 0x7b, 0x44,
34 0x8f, 0x08, 0xe3, 0xc8, 0xd8, 0xf4, 0x81, 0xb0, 0x9f, 0x94, 0xcb, 0xc8, 0xc1, 0x3c, 0xc2, 0x6e,
35 0x31, 0x26, 0xfc, 0x33, 0x16, 0x3b, 0xe0, 0xde, 0xa1, 0x16, 0x21, 0x9f, 0x89, 0xdd, 0x97, 0xa4,
36 0x41, 0xf2, 0x9f, 0x19, 0xb1, 0xae, 0x82, 0xf7, 0x85, 0x9a, 0xb7, 0x8f, 0xb7, 0x52, 0x7a, 0x72,
37 0xf1, 0x5e, 0x89, 0xe1, 0x8a, 0xcd, 0x40, 0xb5, 0x8e, 0xc3, 0xca, 0x42, 0x76, 0xa3, 0x6e, 0x1b,
38 0xf4, 0x87, 0x35, 0x30, 0x58, 0x43, 0x04, 0xd9, 0x2c, 0x50, 0x54, 0x55, 0x47, 0x6f, 0x70, 0x9b,
39 0x42, 0x1f, 0x91, 0xfc, 0xa1, 0xdb, 0x72, 0x53, 0x96, 0xc8, 0xe5, 0xcd, 0x0e, 0xcb, 0xa0, 0xfe,
40 0x6b, 0x08, 0x77, 0x48, 0xb7, 0xad, 0x4a, 0x69, 0x7c, 0xdc, 0xd8, 0x04, 0x28, 0x35, 0x9b, 0x73,
41 0x00, 0x00, 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce,
42 0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82,
44 0x09, 0x67, 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa,
45 0x1d, 0x64, 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, 0x2c, 0x03, 0x5c, 0x4e, 0x0d, 0xec,
46 0x72, 0x15, 0xe2, 0x68, 0x33, 0x93, 0x87, 0x30, 0xe5, 0xe5, 0x05, 0xaa, 0x62, 0x50, 0x4d, 0xa8,
47 0x5b, 0xa5, 0x71, 0x06, 0xa4, 0x6b, 0x5a, 0x24, 0x04, 0xfc, 0x9d, 0x8e, 0x02, 0xba, 0x72, 0xa6,
48 0xe8, 0xba, 0x53, 0xe8, 0xb9, 0x71, 0xad, 0x0c, 0x98, 0x23, 0x96, 0x8a, 0xef, 0x4d, 0x78, 0xce,
49 0x8a, 0xf2, 0x55, 0xab, 0x43, 0xdf, 0xf8, 0x30, 0x03, 0xc9, 0x02, 0xfb, 0x8d, 0x02, 0x16, 0x34,
50 0x5b, 0xf8, 0x31, 0x16, 0x4a, 0x03, 0x75, 0x8e, 0xae, 0xa5, 0xe8, 0xb6, 0x6f, 0xee, 0x2b, 0xe7,
51 0x71, 0x0b, 0x8f, 0x19, 0x0e, 0xe8, 0x80, 0x24, 0x90, 0x32, 0xa2, 0x9e, 0xd6, 0x6e
54 // A simple block containing only one transaction (which is the channel-open transaction for the
55 // channel we'll create). This was originally created by printing additional data in a simple
56 // rust-lightning unit test.
57 const uint8_t channel_open_block[] = {
58 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0xa2, 0x47, 0xd2, 0xf8, 0xd4, 0xe0, 0x6a, 0x3f, 0xf9, 0x7a, 0x9a, 0x34,
61 0xbb, 0xa9, 0x96, 0xde, 0x63, 0x84, 0x5a, 0xce, 0xcf, 0x98, 0xb8, 0xbb, 0x75, 0x4c, 0x4f, 0x7d,
62 0xee, 0x4c, 0xa9, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x01, // transaction count
64 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0xd1, 0xd9, 0x13, 0xa9,
68 0x76, 0x09, 0x05, 0xa3, 0x4d, 0x13, 0x5b, 0x69, 0xaa, 0xe7, 0x79, 0x71, 0xb9, 0x75, 0xa1, 0xd0,
69 0x77, 0xcb, 0xa2, 0xf6, 0x6a, 0x25, 0x37, 0x3a, 0xaf, 0xdc, 0x11, 0x09, 0x01, 0x00, 0x00, 0x00,
73 // The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data.
74 const uint8_t channel_open_txid[] = {
75 0x02, 0xe0, 0x50, 0x05, 0x33, 0xd3, 0x29, 0x66, 0x0c, 0xb2, 0xcb, 0x1e, 0x7a, 0x4a, 0xc7, 0xc7,
76 0x8b, 0x02, 0x46, 0x7e, 0x30, 0x2c, 0xe6, 0x19, 0xce, 0x43, 0x3e, 0xdf, 0x43, 0x65, 0xae, 0xf9,
79 // Two blocks built on top of channel_open_block:
80 const uint8_t block_1[81] = {
81 0x01, 0x00, 0x00, 0x00, 0x0c, 0x7a, 0xc2, 0xdc, 0x08, 0xaf, 0x40, 0x7d, 0x58, 0x81, 0x9b, 0x44,
82 0xc7, 0xe0, 0x0f, 0x78, 0xc0, 0xd1, 0x01, 0xa2, 0x03, 0x16, 0x4a, 0x8d, 0x92, 0x66, 0x4e, 0xaf,
83 0x7f, 0xfc, 0x6e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, // transaction count
88 const uint8_t block_2[81] = {
89 0x01, 0x00, 0x00, 0x00, 0x36, 0x0b, 0xf5, 0x46, 0x4a, 0xc7, 0x26, 0x4c, 0x4b, 0x36, 0xa6, 0x9d,
90 0x0e, 0xf0, 0x14, 0xfb, 0x8a, 0xcb, 0x20, 0x84, 0x18, 0xf3, 0xaa, 0x77, 0x32, 0x2d, 0xf7, 0x48,
91 0x62, 0x92, 0xb1, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, // transaction count
97 const LDKThirtyTwoBytes genesis_hash = { // We don't care particularly if this is "right"
98 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }
101 void print_log(const void *this_arg, const LDKRecord *record) {
102 LDK::Str mod = Record_get_module_path(record);
103 LDK::Str str = Record_get_args(record);
104 printf("%p - %.*s:%d - %.*s\n", this_arg, (int)mod->len, mod->chars, Record_get_line(record), (int)str->len, str->chars);
107 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
108 if (target == LDKConfirmationTarget_Background) {
113 // Note that we don't call _free() on target, but that's OK, its unitary
115 // We use the same fee estimator globally:
116 const LDKFeeEstimator fee_est {
118 .get_est_sat_per_1000_weight = get_fee,
122 static std::atomic_int num_txs_broadcasted(0);
123 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
124 num_txs_broadcasted += 1;
126 Transaction_free(tx);
129 struct NodeMonitors {
131 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
134 void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
135 std::unique_lock<std::mutex> l(mut);
136 for (auto& mon : mons) {
137 LDK::CVec_TransactionOutputsZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
142 LDKChannelMonitorUpdateStatus add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
143 // First bind the args to C++ objects so they auto-free
144 LDK::ChannelMonitor mon(std::move(monitor_arg));
145 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
147 NodeMonitors* arg = (NodeMonitors*) this_arg;
148 std::unique_lock<std::mutex> l(arg->mut);
150 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
151 return ChannelMonitorUpdateStatus_completed();
153 static std::atomic_int mons_updated(0);
154 LDKChannelMonitorUpdateStatus update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
155 // First bind the args to C++ objects so they auto-free
156 LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
157 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
159 NodeMonitors* arg = (NodeMonitors*) this_arg;
160 std::unique_lock<std::mutex> l(arg->mut);
162 bool updated = false;
163 for (auto& mon : arg->mons) {
164 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
165 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
167 LDKBroadcasterInterface broadcaster = {
168 .broadcast_transaction = broadcast_tx,
170 LDK::CResult_NoneNoneZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, fee_est, arg->logger);
171 assert(res->result_ok);
177 return ChannelMonitorUpdateStatus_completed();
179 LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ monitors_pending_monitor_events(const void *this_arg) {
180 NodeMonitors* arg = (NodeMonitors*) this_arg;
181 std::unique_lock<std::mutex> l(arg->mut);
183 if (arg->mons.size() == 0) {
184 return LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
189 // We only ever actually have one channel per node, plus concatenating two
190 // Rust Vecs to each other from C++ will require a bit of effort.
191 assert(arg->mons.size() == 1);
192 LDK::CVec_MonitorEventZ events = ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
193 LDK::C2Tuple_OutPointScriptZ funding_info = ChannelMonitor_get_funding_txo(&arg->mons[0].second);
194 LDK::OutPoint outpoint = std::move(funding_info->a);
195 LDKPublicKey counterparty_node_id = ChannelMonitor_get_counterparty_node_id(&arg->mons[0].second);
196 LDK::C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ tuple = C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_new(std::move(outpoint), std::move(events), std::move(counterparty_node_id));
197 auto vec = LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
198 .data = (LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ*)malloc(sizeof(LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ)),
201 vec.data[0] = std::move(tuple);
207 std::vector<LDK::Event> events;
209 void handle_event(const void *this_arg, const LDKEvent *event) {
210 EventQueue* arg = (EventQueue*) this_arg;
211 arg->events.push_back(Event_clone(event));
215 class PeersConnection {
220 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
221 node1_handler = init_socket_handling(&net1);
222 node2_handler = init_socket_handling(&net2);
224 struct sockaddr_in listen_addr;
225 listen_addr.sin_family = AF_INET;
226 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
227 listen_addr.sin_port = htons(10042);
228 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
230 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
233 // Wait for the initial handshakes to complete...
234 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
235 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
236 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
237 std::this_thread::yield();
240 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
241 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
242 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
244 // Then disconnect the "main" connection, while another connection is being made.
245 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
246 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
248 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
250 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
251 // Wait for the peers to disconnect...
252 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
253 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
254 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
255 std::this_thread::yield();
257 // Note that the above is somewhat race-y, as node 2 may still think its connected.
258 // Thus, make sure any connections are disconnected on its end as well.
259 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1), false);
261 // Finally make an actual connection and keep it this time
262 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
265 // Wait for the initial handshakes to complete...
266 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
267 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
268 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
269 std::this_thread::yield();
273 interrupt_socket_handling(node1_handler);
274 interrupt_socket_handling(node2_handler);
280 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
281 return write((int)((long)this_arg), data.data, data.datalen);
283 void sock_disconnect_socket(void *this_arg) {
284 close((int)((long)this_arg));
286 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
287 return this_arg == other_arg->this_arg;
289 uint64_t sock_hash(const void *this_arg) {
290 return (uint64_t)this_arg;
292 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
293 unsigned char buf[1024];
297 while ((readlen = read(rdfd, buf, 1024)) > 0) {
298 data.datalen = readlen;
299 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
300 if (!res->result_ok) {
301 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
304 PeerManager_process_events(pm);
306 PeerManager_socket_disconnected(&*pm, peer_descriptor);
309 class PeersConnection {
310 int pipefds_1_to_2[2];
311 int pipefds_2_to_1[2];
313 LDKSocketDescriptor sock1, sock2;
316 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
317 assert(!pipe(pipefds_1_to_2));
318 assert(!pipe(pipefds_2_to_1));
320 sock1 = LDKSocketDescriptor {
321 .this_arg = (void*)(long)pipefds_1_to_2[1],
322 .send_data = sock_send_data,
323 .disconnect_socket = sock_disconnect_socket,
330 sock2 = LDKSocketDescriptor {
331 .this_arg = (void*)(long)pipefds_2_to_1[1],
332 .send_data = sock_send_data,
333 .disconnect_socket = sock_disconnect_socket,
340 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
341 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
343 // Note that we have to bind the result to a C++ class to make sure it gets free'd
344 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_NetAddressZ_none());
345 assert(con_res->result_ok);
346 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_NetAddressZ_none());
347 assert(con_res2->result_ok);
349 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
350 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
353 // Wait for the initial handshakes to complete...
354 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
355 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
356 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
357 std::this_thread::yield();
362 close(pipefds_1_to_2[0]);
363 close(pipefds_2_to_1[0]);
364 close(pipefds_1_to_2[1]);
365 close(pipefds_2_to_1[1]);
372 struct CustomOnionMsgQueue {
374 std::vector<LDK::CustomOnionMessageContents> msgs;
377 uint64_t custom_onion_msg_type_id(const void *this_arg) {
380 LDKCVec_u8Z custom_onion_msg_bytes(const void *this_arg) {
381 uint8_t *bytes = (uint8_t *) malloc(1024);
382 memset(bytes, 43, 1024);
384 .data = bytes, .datalen = 1024
388 void handle_custom_onion_message(const void* this_arg, struct LDKCustomOnionMessageContents msg) {
389 CustomOnionMsgQueue* arg = (CustomOnionMsgQueue*) this_arg;
390 std::unique_lock<std::mutex> lck(arg->mtx);
391 arg->msgs.push_back(std::move(msg));
394 LDKCustomOnionMessageContents build_custom_onion_message() {
395 return LDKCustomOnionMessageContents {
397 .tlv_type = custom_onion_msg_type_id,
398 .write = custom_onion_msg_bytes,
403 LDKCResult_COption_CustomOnionMessageContentsZDecodeErrorZ read_custom_onion_message(const void* this_arg, uint64_t type, LDKu8slice buf) {
404 assert(type == 8888);
405 assert(buf.datalen == 1024);
407 memset(cmp, 43, 1024);
408 assert(!memcmp(cmp, buf.data, 1024));
409 return CResult_COption_CustomOnionMessageContentsZDecodeErrorZ_ok(COption_CustomOnionMessageContentsZ_some(build_custom_onion_message()));
413 struct CustomMsgQueue {
414 std::vector<LDK::Type> msgs;
417 uint16_t custom_msg_type_id(const void *this_arg) {
420 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
421 uint8_t *bytes = (uint8_t *) malloc(1024);
422 memset(bytes, 42, 1024);
424 .data = bytes, .datalen = 1024
427 LDKStr custom_msg_debug(const void *this_arg) {
429 .chars = NULL, .len = 0, .chars_is_owned = false
433 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
434 assert(type_id == 8888);
435 assert(buf.datalen == 1024);
437 memset(cmp, 42, 1024);
438 assert(!memcmp(cmp, buf.data, 1024));
439 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
441 .type_id = custom_msg_type_id,
442 .debug_str = custom_msg_debug,
447 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
448 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
449 arg->msgs.push_back(std::move(msg));
450 return CResult_NoneLightningErrorZ_ok();
452 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
453 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
454 .data = NULL, .datalen = 0
458 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
459 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
460 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
461 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
464 ret.data[0].a = *counterparty_node_id;
465 ret.data[0].b = LDKType {
467 .type_id = custom_msg_type_id,
468 .debug_str = custom_msg_debug,
469 .write = custom_msg_bytes,
475 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst, LDKChannelUsage usage_in) {
476 LDK::ChannelUsage usage(std::move(usage_in));
480 struct LDKCResult_RouteLightningErrorZ custom_find_route(const void *this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, const uint8_t (*payment_hash)[32], struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKInFlightHtlcs in_flights) {
481 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
482 assert(first_hops->datalen == 1);
483 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
484 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
485 return router_impl->find_route(router_impl->this_arg, payer, route_params, payment_hash, first_hops, in_flights);
488 void custom_notify_payment_path_failed(const void *this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
489 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
490 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
491 return router_impl->notify_payment_path_failed(router_impl->this_arg, path, short_channel_id);
493 void custom_notify_payment_path_successful(const void *this_arg, struct LDKCVec_RouteHopZ path) {
494 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
495 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
496 return router_impl->notify_payment_path_successful(router_impl->this_arg, path);
500 uint8_t channel_open_header[80];
501 uint8_t header_1[80];
502 uint8_t header_2[80];
503 memcpy(channel_open_header, channel_open_block, 80);
504 memcpy(header_1, block_1, 80);
505 memcpy(header_2, block_2, 80);
507 LDKPublicKey null_pk;
508 memset(&null_pk, 0, sizeof(null_pk));
510 LDKThirtyTwoBytes random_bytes;
511 LDKThirtyTwoBytes chain_tip;
512 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
514 LDKNetwork network = LDKNetwork_Testnet;
516 // Trait implementations:
517 LDKBroadcasterInterface broadcast {
519 .broadcast_transaction = broadcast_tx,
523 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
525 .this_arg = (void*)1,
531 mons1.logger = &logger1;
534 .watch_channel = add_channel_monitor,
535 .update_channel = update_channel_monitor,
536 .release_pending_monitor_events = monitors_pending_monitor_events,
540 LDK::NetworkGraph net_graph1 = NetworkGraph_new(genesis_hash, logger1);
541 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_AccessZ_none(), logger1);
542 LDKSecretKey node_secret1;
545 .this_arg = (void*)2,
551 mons2.logger = &logger2;
554 .watch_channel = add_channel_monitor,
555 .update_channel = update_channel_monitor,
556 .release_pending_monitor_events = monitors_pending_monitor_events,
560 LDK::NetworkGraph net_graph2 = NetworkGraph_new(genesis_hash, logger2);
561 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_AccessZ_none(), logger2);
562 LDKSecretKey node_secret2;
564 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
565 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
567 { // Scope for the ser-des reload
568 // Instantiate classes for node 1:
569 uint8_t node_seed[32];
570 memset(&node_seed, 0, 32);
571 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
572 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
573 LDK::CResult_SecretKeyNoneZ node_secret1_res = keys_source1->get_node_secret(keys_source1->this_arg, LDKRecipient_Node);
574 assert(node_secret1_res->result_ok);
575 node_secret1 = *node_secret1_res->contents.result;
577 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
579 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
580 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
581 LDK::CustomOnionMessageHandler custom_onion_msg_handler1 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler1);
583 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys1), logger1, std::move(custom_onion_msg_handler1));
585 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
586 assert(channels->datalen == 0);
588 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
590 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
591 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1));
593 // Demo getting a channel key and check that its returning real pubkeys:
594 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
595 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
596 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.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::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
603 LDK::CResult_SecretKeyNoneZ node_secret2_res = keys_source2->get_node_secret(keys_source2->this_arg, LDKRecipient_Node);
604 assert(node_secret2_res->result_ok);
605 node_secret2 = *node_secret2_res->contents.result;
607 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
608 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
609 LDK::UserConfig config2 = UserConfig_default();
610 UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2));
612 LDK::ChannelManager cm2 = ChannelManager_new(fee_est, mon2, broadcast, logger2, KeysManager_as_KeysInterface(&keys2), std::move(config2), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
614 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
615 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
616 LDK::CustomOnionMessageHandler custom_onion_msg_handler2 = IgnoringMessageHandler_as_CustomOnionMessageHandler(&ignoring_handler2);
618 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys2), logger2, std::move(custom_onion_msg_handler2));
620 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
621 assert(channels2->datalen == 0);
623 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
624 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
625 assert(chan_ann->result_ok);
626 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
627 assert(ann_res->result_ok);
629 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2), OnionMessenger_as_OnionMessageHandler(&om1));
631 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
632 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2));
634 // Open a connection!
635 PeersConnection conn(cm1, cm2, net1, net2);
637 // Note that we have to bind the result to a C++ class to make sure it gets free'd
638 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
639 assert(res->result_ok);
640 PeerManager_process_events(&net1);
642 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
643 assert(new_channels->datalen == 1);
644 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
645 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
646 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
649 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
650 if (new_channels_2->datalen == 1) {
651 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
652 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
653 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
654 assert(init_feats->inner != NULL);
657 std::this_thread::yield();
660 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
663 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
664 ev1.process_pending_events(ev1.this_arg, handler);
665 if (queue.events.size() == 1) {
666 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
667 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
668 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
669 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
670 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
671 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
673 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);
674 assert(fund_res->result_ok);
677 std::this_thread::yield();
680 // We observe when the funding signed messages have been exchanged by
681 // waiting for two monitors to be registered.
682 assert(num_txs_broadcasted == 0);
683 PeerManager_process_events(&net1);
684 while (num_txs_broadcasted != 1) {
685 std::this_thread::yield();
688 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
689 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
691 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
692 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
694 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
695 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
696 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
698 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
699 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
700 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
702 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
703 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
704 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
705 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
707 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
708 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
709 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
710 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
712 PeerManager_process_events(&net1);
713 PeerManager_process_events(&net2);
715 // Now send funds from 1 to 2!
716 uint64_t channel_scid;
718 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
719 if (outbound_channels->datalen == 1) {
720 const LDKChannelDetails *channel = &outbound_channels->data[0];
721 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
722 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
723 uint8_t expected_chan_id[32];
724 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
725 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
727 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
728 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
729 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
730 // We opened the channel with 1000 push_msat:
731 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
732 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
733 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
734 if (inbound_capacity < 0) inbound_capacity = 0;
735 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
736 assert(ChannelDetails_get_is_usable(channel));
737 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
738 assert(scid_opt->some);
739 channel_scid = scid_opt->some;
742 std::this_thread::yield();
745 LDKCOption_u64Z min_value = {
746 .tag = LDKCOption_u64Z_Some,
749 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
750 KeysManager_as_KeysInterface(&keys2), logger2,
751 LDKCurrency_Bitcoin, min_value,
753 .chars = (const uint8_t *)"Invoice Description",
754 .len = strlen("Invoice Description"),
755 .chars_is_owned = false
757 assert(invoice->result_ok);
758 LDKThirtyTwoBytes payment_hash;
759 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
762 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
763 LDK::Score chan_scorer = LDKScore {
764 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
766 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
767 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
768 .inner = NULL, .is_owned = false
769 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff,
770 1, 2, LDKCVec_u64Z { .data = NULL, .datalen = 0 }),
771 5000, Invoice_min_final_cltv_expiry(invoice->contents.result));
772 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
774 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
776 assert(route->result_ok);
777 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
778 assert(paths->datalen == 1);
779 assert(paths->data[0].datalen == 1);
780 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
781 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
782 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
783 LDKThirtyTwoBytes payment_secret;
784 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
785 LDK::CResult_PaymentIdPaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret);
786 assert(send_res->result_ok);
790 PeerManager_process_events(&net1);
791 while (mons_updated != 4) {
792 std::this_thread::yield();
795 // Check that we received the payment!
796 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
799 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
800 ev2.process_pending_events(handler);
801 if (queue.events.size() == 1) {
802 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
805 std::this_thread::yield();
807 ChannelManager_process_pending_htlc_forwards(&cm2);
808 PeerManager_process_events(&net2);
811 LDKThirtyTwoBytes payment_preimage;
814 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
815 ev2.process_pending_events(handler);
816 assert(queue.events.size() == 1);
817 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
818 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
819 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
820 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
821 Invoice_payment_secret(invoice->contents.result), 32));
822 assert(queue.events[0]->payment_received.amount_msat == 5000);
823 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
824 ChannelManager_claim_funds(&cm2, payment_preimage);
826 queue.events.clear();
827 ev2.process_pending_events(handler);
828 assert(queue.events.size() == 1);
829 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
830 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
831 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
833 PeerManager_process_events(&net2);
834 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
835 while (mons_updated != 5) {
836 std::this_thread::yield();
840 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
841 while (queue.events.size() < 2)
842 ev1.process_pending_events(ev1.this_arg, handler);
843 assert(queue.events.size() == 2);
844 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
845 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
846 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
847 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
852 cm1_ser = ChannelManager_write(&cm1);
853 cm2_ser = ChannelManager_write(&cm2);
856 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
857 assert(mons1.mons.size() == 1);
858 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
859 mons_list1->data[0].is_owned = false; // XXX: God this sucks
860 uint8_t node_seed[32];
861 memset(&node_seed, 0, 32);
862 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
863 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
865 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
866 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
867 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
868 assert(cm1_read->result_ok);
869 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
871 LDKCustomOnionMessageHandler custom_onion_msg_handler1 = {
873 .handle_custom_message = NULL, // We only create custom messages, not handle them
874 .read_custom_message = NULL, // We only create custom messages, not handle them
877 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys1), logger1, custom_onion_msg_handler1);
879 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
880 assert(mons2.mons.size() == 1);
881 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
882 mons_list2->data[0].is_owned = false; // XXX: God this sucks
883 memset(&node_seed, 1, 32);
884 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
886 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
887 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
888 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
889 assert(cm2_read->result_ok);
890 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
892 CustomOnionMsgQueue peer_2_custom_onion_messages;
893 LDKCustomOnionMessageHandler custom_onion_msg_handler2 = {
894 .this_arg = &peer_2_custom_onion_messages,
895 .handle_custom_message = handle_custom_onion_message,
896 .read_custom_message = read_custom_onion_message,
899 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys2), logger2, custom_onion_msg_handler2);
901 // Attempt to close the channel...
903 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
904 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
905 assert(!close_res->result_ok); // Note that we can't close while disconnected!
907 // Open a connection!
908 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
909 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
911 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
912 LDKCustomMessageHandler custom_msg_handler1 = {
913 .this_arg = &chan_2_node_id,
914 .handle_custom_message = NULL, // We only create custom messages, not handle them
915 .get_and_clear_pending_msg = create_custom_msg,
916 .CustomMessageReader = LDKCustomMessageReader {
918 .read = read_custom_message,
923 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1));
925 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2));
926 CustomMsgQueue peer_2_custom_messages;
927 LDKCustomMessageHandler custom_msg_handler2 = {
928 .this_arg = &peer_2_custom_messages,
929 .handle_custom_message = handle_custom_message,
930 .get_and_clear_pending_msg = never_send_custom_msgs,
931 .CustomMessageReader = LDKCustomMessageReader {
933 .read = read_custom_message,
938 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
939 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2));
941 PeersConnection conn(cm1, cm2, net1, net2);
944 // Wait for the channels to be considered up once the reestablish messages are processed
945 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
946 if (outbound_channels->datalen == 1) {
951 // Send another payment, this time via the InvoicePayer
952 LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1);
953 LDK::Score scorer_trait = ProbabilisticScorer_as_Score(&scorer);
954 LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(std::move(scorer_trait));
955 LDK::LockableScore scorer_mtx_trait = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx);
956 const LDK::DefaultRouter router = DefaultRouter_new(&net_graph1, logger1, keys_source1->get_secure_random_bytes(keys_source1->this_arg), std::move(scorer_mtx_trait));
957 LDKRouter sending_router = {
958 .this_arg = (void*)&router,
959 .find_route = custom_find_route,
960 .notify_payment_path_failed = custom_notify_payment_path_failed,
961 .notify_payment_path_successful = custom_notify_payment_path_successful,
962 // We don't probe, so we opt to crash if the probe functions are called.
963 .notify_payment_probe_successful = NULL,
964 .notify_payment_probe_failed = NULL,
968 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
969 LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, logger1, handler1, Retry_attempts(0));
971 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
972 KeysManager_as_KeysInterface(&keys2), logger1,
973 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
975 .chars = (const uint8_t *)"Invoice 2 Description",
976 .len = strlen("Invoice 2 Description"),
977 .chars_is_owned = false
979 assert(invoice_res2->result_ok);
980 const LDKInvoice *invoice2 = invoice_res2->contents.result;
981 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = InvoicePayer_pay_invoice(&payer, invoice2);
982 assert(invoice_pay_res->result_ok);
983 PeerManager_process_events(&net1);
985 // Check that we received the payment!
988 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
989 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
990 ev2.process_pending_events(handler2);
991 if (queue2.events.size() == 1) {
992 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
995 std::this_thread::yield();
997 ChannelManager_process_pending_htlc_forwards(&cm2);
998 PeerManager_process_events(&net2);
1002 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
1003 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
1004 ev2.process_pending_events(handler2);
1005 if (queue2.events.size() == 1) {
1006 assert(queue2.events[0]->tag == LDKEvent_PaymentReceived);
1007 const struct LDKEvent_LDKPaymentReceived_Body *event_data = &queue2.events[0]->payment_received;
1008 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
1009 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
1010 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
1011 Invoice_payment_secret(invoice2), 32));
1012 assert(event_data->amount_msat == 10000);
1013 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage);
1015 queue2.events.clear();
1016 ev2.process_pending_events(handler2);
1017 assert(queue2.events.size() == 1);
1018 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
1019 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Invoice_payment_hash(invoice2), 32));
1020 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
1024 std::this_thread::yield();
1027 while (queue1.events.size() < 2) {
1028 PeerManager_process_events(&net2);
1029 PeerManager_process_events(&net1);
1031 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
1032 LDK::EventHandler evh1 = InvoicePayer_as_EventHandler(&payer);
1033 ev1.process_pending_events(std::move(evh1));
1035 assert(queue1.events.size() == 2);
1036 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
1037 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
1039 // Actually close the channel
1040 num_txs_broadcasted = 0;
1041 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
1042 assert(close_res->result_ok);
1043 PeerManager_process_events(&net1);
1044 while (num_txs_broadcasted != 2) {
1045 std::this_thread::yield();
1047 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
1048 assert(chans_after_close1->datalen == 0);
1049 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
1050 assert(chans_after_close2->datalen == 0);
1052 assert(OnionMessenger_send_custom_onion_message(&om1,
1053 LDKCVec_PublicKeyZ { .data = NULL, .datalen = 0, },
1054 Destination_node(ChannelManager_get_our_node_id(&cm2)),
1055 build_custom_onion_message(), LDKBlindedRoute { .inner = NULL, .is_owned = true })
1057 PeerManager_process_events(&net1);
1059 std::this_thread::yield();
1060 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1061 if (peer_2_custom_onion_messages.msgs.size() != 0) break;
1066 std::unique_lock<std::mutex> lck(peer_2_custom_onion_messages.mtx);
1067 assert(peer_2_custom_onion_messages.msgs.size() == 1);
1068 assert(peer_2_custom_onion_messages.msgs[0].tlv_type() == 8888);
1069 assert(peer_2_custom_messages.msgs.size() != 0);
1071 // Few extra random tests:
1073 memset(&sk, 42, 32);
1074 LDKThirtyTwoBytes kdiv_params;
1075 memset(&kdiv_params, 43, 32);
1076 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);