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 char *record) {
102 printf("%p - %s\n", this_arg, record);
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 LDKCResult_NoneChannelMonitorUpdateErrZ 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 CResult_NoneChannelMonitorUpdateErrZ_ok();
151 static std::atomic_int mons_updated(0);
152 LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
153 // First bind the args to C++ objects so they auto-free
154 LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
155 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
157 NodeMonitors* arg = (NodeMonitors*) this_arg;
158 std::unique_lock<std::mutex> l(arg->mut);
160 bool updated = false;
161 for (auto& mon : arg->mons) {
162 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
163 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
165 LDKBroadcasterInterface broadcaster = {
166 .broadcast_transaction = broadcast_tx,
168 LDK::CResult_NoneMonitorUpdateErrorZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, &fee_est, arg->logger);
169 assert(res->result_ok);
175 return CResult_NoneChannelMonitorUpdateErrZ_ok();
177 LDKCVec_MonitorEventZ monitors_pending_monitor_events(const void *this_arg) {
178 NodeMonitors* arg = (NodeMonitors*) this_arg;
179 std::unique_lock<std::mutex> l(arg->mut);
181 if (arg->mons.size() == 0) {
182 return LDKCVec_MonitorEventZ {
187 // We only ever actually have one channel per node, plus concatenating two
188 // Rust Vecs to each other from C++ will require a bit of effort.
189 assert(arg->mons.size() == 1);
190 return ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
195 std::vector<LDK::Event> events;
197 void handle_event(const void *this_arg, const LDKEvent *event) {
198 EventQueue* arg = (EventQueue*) this_arg;
199 arg->events.push_back(Event_clone(event));
203 class PeersConnection {
208 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
209 node1_handler = init_socket_handling(&net1);
210 node2_handler = init_socket_handling(&net2);
212 struct sockaddr_in listen_addr;
213 listen_addr.sin_family = AF_INET;
214 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
215 listen_addr.sin_port = htons(10042);
216 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
218 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
221 // Wait for the initial handshakes to complete...
222 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
223 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
224 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
225 std::this_thread::yield();
228 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
229 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
230 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
232 // Then disconnect the "main" connection, while another connection is being made.
233 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
234 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
236 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
238 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
239 // Wait for the peers to disconnect...
240 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
241 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
242 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
243 std::this_thread::yield();
245 // Note that the above is somewhat race-y, as node 2 may still think its connected.
246 // Thus, make sure any connections are disconnected on its end as well.
247 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1), false);
249 // Finally make an actual connection and keep it this time
250 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
253 // Wait for the initial handshakes to complete...
254 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
255 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
256 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
257 std::this_thread::yield();
261 interrupt_socket_handling(node1_handler);
262 interrupt_socket_handling(node2_handler);
268 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
269 return write((int)((long)this_arg), data.data, data.datalen);
271 void sock_disconnect_socket(void *this_arg) {
272 close((int)((long)this_arg));
274 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
275 return this_arg == other_arg->this_arg;
277 uint64_t sock_hash(const void *this_arg) {
278 return (uint64_t)this_arg;
280 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
281 unsigned char buf[1024];
285 while ((readlen = read(rdfd, buf, 1024)) > 0) {
286 data.datalen = readlen;
287 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
288 if (!res->result_ok) {
289 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
292 PeerManager_process_events(pm);
294 PeerManager_socket_disconnected(&*pm, peer_descriptor);
297 class PeersConnection {
298 int pipefds_1_to_2[2];
299 int pipefds_2_to_1[2];
301 LDKSocketDescriptor sock1, sock2;
304 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
305 assert(!pipe(pipefds_1_to_2));
306 assert(!pipe(pipefds_2_to_1));
308 sock1 = LDKSocketDescriptor {
309 .this_arg = (void*)(long)pipefds_1_to_2[1],
310 .send_data = sock_send_data,
311 .disconnect_socket = sock_disconnect_socket,
318 sock2 = LDKSocketDescriptor {
319 .this_arg = (void*)(long)pipefds_2_to_1[1],
320 .send_data = sock_send_data,
321 .disconnect_socket = sock_disconnect_socket,
328 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
329 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
331 // Note that we have to bind the result to a C++ class to make sure it gets free'd
332 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
333 assert(con_res->result_ok);
334 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
335 assert(con_res2->result_ok);
337 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
338 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
341 // Wait for the initial handshakes to complete...
342 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
343 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
344 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
345 std::this_thread::yield();
350 close(pipefds_1_to_2[0]);
351 close(pipefds_2_to_1[0]);
352 close(pipefds_1_to_2[1]);
353 close(pipefds_2_to_1[1]);
360 struct CustomMsgQueue {
361 std::vector<LDK::Type> msgs;
364 uint16_t custom_msg_type_id(const void *this_arg) {
367 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
368 uint8_t *bytes = (uint8_t *) malloc(1024);
369 memset(bytes, 42, 1024);
371 .data = bytes, .datalen = 1024
374 LDKStr custom_msg_debug(const void *this_arg) {
376 .chars = NULL, .len = 0, .chars_is_owned = false
380 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
381 assert(type_id == 8888);
382 assert(buf.datalen == 1024);
384 memset(cmp, 42, 1024);
385 assert(!memcmp(cmp, buf.data, 1024));
386 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
388 .type_id = custom_msg_type_id,
389 .debug_str = custom_msg_debug,
394 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
395 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
396 arg->msgs.push_back(std::move(msg));
397 return CResult_NoneLightningErrorZ_ok();
399 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
400 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
401 .data = NULL, .datalen = 0
405 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
406 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
407 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
408 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
411 ret.data[0].a = *counterparty_node_id;
412 ret.data[0].b = LDKType {
414 .type_id = custom_msg_type_id,
415 .debug_str = custom_msg_debug,
416 .write = custom_msg_bytes,
422 uint64_t get_chan_score(const void *this_arg, uint64_t scid) { return 42; }
425 uint8_t channel_open_header[80];
426 uint8_t header_1[80];
427 uint8_t header_2[80];
428 memcpy(channel_open_header, channel_open_block, 80);
429 memcpy(header_1, block_1, 80);
430 memcpy(header_2, block_2, 80);
432 LDKPublicKey null_pk;
433 memset(&null_pk, 0, sizeof(null_pk));
435 LDKThirtyTwoBytes random_bytes;
436 LDKThirtyTwoBytes chain_tip;
437 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
439 LDKNetwork network = LDKNetwork_Testnet;
441 // Trait implementations:
442 LDKBroadcasterInterface broadcast {
444 .broadcast_transaction = broadcast_tx,
448 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
450 .this_arg = (void*)1,
456 mons1.logger = &logger1;
459 .watch_channel = add_channel_monitor,
460 .update_channel = update_channel_monitor,
461 .release_pending_monitor_events = monitors_pending_monitor_events,
465 LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger1);
466 LDKSecretKey node_secret1;
469 .this_arg = (void*)2,
475 mons2.logger = &logger2;
478 .watch_channel = add_channel_monitor,
479 .update_channel = update_channel_monitor,
480 .release_pending_monitor_events = monitors_pending_monitor_events,
484 LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger2);
485 LDKSecretKey node_secret2;
487 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
488 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
490 { // Scope for the ser-des reload
491 // Instantiate classes for node 1:
492 uint8_t node_seed[32];
493 memset(&node_seed, 0, 32);
494 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
495 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
496 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
498 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
500 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
501 assert(channels->datalen == 0);
503 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
505 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
506 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
508 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
509 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
511 // Demo getting a channel key and check that its returning real pubkeys:
512 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
513 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
514 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
515 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
517 // Instantiate classes for node 2:
518 memset(&node_seed, 1, 32);
519 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
520 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
521 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
523 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
524 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
525 LDK::UserConfig config2 = UserConfig_default();
526 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
528 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)));
530 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
531 assert(channels2->datalen == 0);
533 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
534 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
535 assert(chan_ann->result_ok);
536 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
537 assert(ann_res->result_ok);
539 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
541 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
542 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
544 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
545 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
547 // Open a connection!
548 PeersConnection conn(cm1, cm2, net1, net2);
550 // Note that we have to bind the result to a C++ class to make sure it gets free'd
551 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
552 assert(res->result_ok);
553 PeerManager_process_events(&net1);
555 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
556 assert(new_channels->datalen == 1);
557 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
558 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
559 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
562 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
563 if (new_channels_2->datalen == 1) {
564 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
565 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
566 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
567 assert(init_feats->inner != NULL);
570 std::this_thread::yield();
573 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
576 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
577 ev1.process_pending_events(ev1.this_arg, handler);
578 if (queue.events.size() == 1) {
579 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
580 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
581 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
582 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
583 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
584 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
586 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
587 assert(fund_res->result_ok);
590 std::this_thread::yield();
593 // We observe when the funding signed messages have been exchanged by
594 // waiting for two monitors to be registered.
595 assert(num_txs_broadcasted == 0);
596 PeerManager_process_events(&net1);
597 while (num_txs_broadcasted != 1) {
598 std::this_thread::yield();
601 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
602 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
604 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
605 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
607 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
608 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
609 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
611 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
612 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
613 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
615 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
616 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
617 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
618 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
620 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
621 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
622 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
623 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
625 PeerManager_process_events(&net1);
626 PeerManager_process_events(&net2);
628 // Now send funds from 1 to 2!
629 uint64_t channel_scid;
631 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
632 if (outbound_channels->datalen == 1) {
633 const LDKChannelDetails *channel = &outbound_channels->data[0];
634 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
635 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
636 uint8_t expected_chan_id[32];
637 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
638 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
640 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
641 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
642 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
643 // We opened the channel with 1000 push_msat:
644 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
645 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
646 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
647 if (inbound_capacity < 0) inbound_capacity = 0;
648 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
649 assert(ChannelDetails_get_is_usable(channel));
650 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
651 assert(scid_opt->some);
652 channel_scid = scid_opt->some;
655 std::this_thread::yield();
658 LDKCOption_u64Z min_value = {
659 .tag = LDKCOption_u64Z_Some,
662 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
663 KeysManager_as_KeysInterface(&keys2),
664 LDKCurrency_Bitcoin, min_value,
666 .chars = (const uint8_t *)"Invoice Description",
667 .len = strlen("Invoice Description"),
668 .chars_is_owned = false
670 assert(invoice->result_ok);
671 LDKThirtyTwoBytes payment_hash;
672 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
675 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
676 LDK::NetworkGraph graph_2_ref = NetGraphMsgHandler_get_network_graph(&net_graph2);
677 LDK::Score chan_scorer = LDKScore {
678 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
680 LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
681 .inner = NULL, .is_owned = false
682 }, &outbound_channels, Invoice_route_hints(invoice->contents.result),
683 5000, Invoice_min_final_cltv_expiry(invoice->contents.result), logger1, &chan_scorer);
684 assert(route->result_ok);
685 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
686 assert(paths->datalen == 1);
687 assert(paths->data[0].datalen == 1);
688 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
689 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
690 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
691 LDK::CResult_PaymentIdPaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, Invoice_payment_secret(invoice->contents.result));
692 assert(send_res->result_ok);
696 PeerManager_process_events(&net1);
697 while (mons_updated != 4) {
698 std::this_thread::yield();
701 // Check that we received the payment!
702 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
705 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
706 ev2.process_pending_events(ev2.this_arg, handler);
707 if (queue.events.size() == 1) {
708 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
711 std::this_thread::yield();
713 ChannelManager_process_pending_htlc_forwards(&cm2);
714 PeerManager_process_events(&net2);
717 LDKThirtyTwoBytes payment_preimage;
720 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
721 ev2.process_pending_events(ev2.this_arg, handler);
722 assert(queue.events.size() == 1);
723 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
724 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
725 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
726 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
727 Invoice_payment_secret(invoice->contents.result).data, 32));
728 assert(queue.events[0]->payment_received.amt == 5000);
729 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
730 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
732 PeerManager_process_events(&net2);
733 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
734 while (mons_updated != 5) {
735 std::this_thread::yield();
739 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
740 ev1.process_pending_events(ev1.this_arg, handler);
741 assert(queue.events.size() == 1);
742 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
743 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
748 cm1_ser = ChannelManager_write(&cm1);
749 cm2_ser = ChannelManager_write(&cm2);
752 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
753 assert(mons1.mons.size() == 1);
754 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
755 mons_list1->data[0].is_owned = false; // XXX: God this sucks
756 uint8_t node_seed[32];
757 memset(&node_seed, 0, 32);
758 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
759 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
761 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
762 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
763 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
764 assert(cm1_read->result_ok);
765 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
767 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
768 assert(mons2.mons.size() == 1);
769 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
770 mons_list2->data[0].is_owned = false; // XXX: God this sucks
771 memset(&node_seed, 1, 32);
772 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
774 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
775 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
776 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
777 assert(cm2_read->result_ok);
778 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
780 // Attempt to close the channel...
782 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
783 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
784 assert(!close_res->result_ok); // Note that we can't close while disconnected!
786 // Open a connection!
787 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
788 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
790 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
791 LDKCustomMessageHandler custom_msg_handler1 = {
792 .this_arg = &chan_2_node_id,
793 .handle_custom_message = NULL, // We only create custom messages, not handle them
794 .get_and_clear_pending_msg = create_custom_msg,
795 .CustomMessageReader = LDKCustomMessageReader {
797 .read = read_custom_message,
802 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
804 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
805 CustomMsgQueue peer_2_custom_messages;
806 LDKCustomMessageHandler custom_msg_handler2 = {
807 .this_arg = &peer_2_custom_messages,
808 .handle_custom_message = handle_custom_message,
809 .get_and_clear_pending_msg = never_send_custom_msgs,
810 .CustomMessageReader = LDKCustomMessageReader {
812 .read = read_custom_message,
817 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
818 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
820 PeersConnection conn(cm1, cm2, net1, net2);
823 // Wait for the channels to be considered up once the reestablish messages are processed
824 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
825 if (outbound_channels->datalen == 1) {
830 // Actually close the channel
831 num_txs_broadcasted = 0;
832 close_res = ChannelManager_close_channel(&cm1, &chan_id);
833 assert(close_res->result_ok);
834 PeerManager_process_events(&net1);
835 while (num_txs_broadcasted != 2) {
836 std::this_thread::yield();
838 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
839 assert(chans_after_close1->datalen == 0);
840 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
841 assert(chans_after_close2->datalen == 0);
845 assert(peer_2_custom_messages.msgs.size() != 0);
847 // Few extra random tests:
850 LDKThirtyTwoBytes kdiv_params;
851 memset(&kdiv_params, 43, 32);
852 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);