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,
423 uint8_t channel_open_header[80];
424 uint8_t header_1[80];
425 uint8_t header_2[80];
426 memcpy(channel_open_header, channel_open_block, 80);
427 memcpy(header_1, block_1, 80);
428 memcpy(header_2, block_2, 80);
430 LDKPublicKey null_pk;
431 memset(&null_pk, 0, sizeof(null_pk));
433 LDKThirtyTwoBytes random_bytes;
434 LDKThirtyTwoBytes chain_tip;
435 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
437 LDKNetwork network = LDKNetwork_Testnet;
439 // Trait implementations:
440 LDKBroadcasterInterface broadcast {
442 .broadcast_transaction = broadcast_tx,
446 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
448 .this_arg = (void*)1,
454 mons1.logger = &logger1;
457 .watch_channel = add_channel_monitor,
458 .update_channel = update_channel_monitor,
459 .release_pending_monitor_events = monitors_pending_monitor_events,
463 LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger1);
464 LDKSecretKey node_secret1;
467 .this_arg = (void*)2,
473 mons2.logger = &logger2;
476 .watch_channel = add_channel_monitor,
477 .update_channel = update_channel_monitor,
478 .release_pending_monitor_events = monitors_pending_monitor_events,
482 LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger2);
483 LDKSecretKey node_secret2;
485 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
486 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
488 { // Scope for the ser-des reload
489 // Instantiate classes for node 1:
490 uint8_t node_seed[32];
491 memset(&node_seed, 0, 32);
492 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
493 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
494 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
496 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
498 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
499 assert(channels->datalen == 0);
501 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
503 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
504 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
506 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
507 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
509 // Demo getting a channel key and check that its returning real pubkeys:
510 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
511 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
512 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
513 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
515 // Instantiate classes for node 2:
516 memset(&node_seed, 1, 32);
517 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
518 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
519 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
521 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
522 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
523 LDK::UserConfig config2 = UserConfig_default();
524 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
526 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)));
528 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
529 assert(channels2->datalen == 0);
531 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
532 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
533 assert(chan_ann->result_ok);
534 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
535 assert(ann_res->result_ok);
537 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
539 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
540 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
542 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
543 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
545 // Open a connection!
546 PeersConnection conn(cm1, cm2, net1, net2);
548 // Note that we have to bind the result to a C++ class to make sure it gets free'd
549 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
550 assert(res->result_ok);
551 PeerManager_process_events(&net1);
553 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
554 assert(new_channels->datalen == 1);
555 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
556 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
557 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
560 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
561 if (new_channels_2->datalen == 1) {
562 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
563 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
564 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
565 assert(init_feats->inner != NULL);
568 std::this_thread::yield();
571 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
574 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
575 ev1.process_pending_events(ev1.this_arg, handler);
576 if (queue.events.size() == 1) {
577 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
578 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
579 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
580 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
581 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
582 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
584 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
585 assert(fund_res->result_ok);
588 std::this_thread::yield();
591 // We observe when the funding signed messages have been exchanged by
592 // waiting for two monitors to be registered.
593 assert(num_txs_broadcasted == 0);
594 PeerManager_process_events(&net1);
595 while (num_txs_broadcasted != 1) {
596 std::this_thread::yield();
599 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
600 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
602 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
603 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
605 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
606 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
607 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
609 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
610 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
611 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
613 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
614 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
615 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
616 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
618 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
619 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
620 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
621 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
623 PeerManager_process_events(&net1);
624 PeerManager_process_events(&net2);
626 // Now send funds from 1 to 2!
627 uint64_t channel_scid;
629 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
630 if (outbound_channels->datalen == 1) {
631 const LDKChannelDetails *channel = &outbound_channels->data[0];
632 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
633 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
634 uint8_t expected_chan_id[32];
635 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
636 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
638 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
639 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
640 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
641 // We opened the channel with 1000 push_msat:
642 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
643 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
644 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
645 if (inbound_capacity < 0) inbound_capacity = 0;
646 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
647 assert(ChannelDetails_get_is_usable(channel));
648 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
649 assert(scid_opt->some);
650 channel_scid = scid_opt->some;
653 std::this_thread::yield();
656 LDKCOption_u64Z min_value = {
657 .tag = LDKCOption_u64Z_Some,
660 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
661 KeysManager_as_KeysInterface(&keys2),
662 LDKCurrency_Bitcoin, min_value,
664 .chars = (const uint8_t *)"Invoice Description",
665 .len = strlen("Invoice Description"),
666 .chars_is_owned = false
668 assert(invoice->result_ok);
669 LDKThirtyTwoBytes payment_hash;
670 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
673 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
674 LDK::NetworkGraph graph_2_ref = NetGraphMsgHandler_get_network_graph(&net_graph2);
675 LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
676 .inner = NULL, .is_owned = false
677 }, &outbound_channels, Invoice_route_hints(invoice->contents.result),
678 5000, Invoice_min_final_cltv_expiry(invoice->contents.result), logger1);
679 assert(route->result_ok);
680 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
681 assert(paths->datalen == 1);
682 assert(paths->data[0].datalen == 1);
683 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
684 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
685 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
686 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, Invoice_payment_secret(invoice->contents.result));
687 assert(send_res->result_ok);
691 PeerManager_process_events(&net1);
692 while (mons_updated != 4) {
693 std::this_thread::yield();
696 // Check that we received the payment!
697 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
700 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
701 ev2.process_pending_events(ev2.this_arg, handler);
702 if (queue.events.size() == 1) {
703 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
706 std::this_thread::yield();
708 ChannelManager_process_pending_htlc_forwards(&cm2);
709 PeerManager_process_events(&net2);
712 LDKThirtyTwoBytes payment_preimage;
715 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
716 ev2.process_pending_events(ev2.this_arg, handler);
717 assert(queue.events.size() == 1);
718 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
719 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
720 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
721 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
722 Invoice_payment_secret(invoice->contents.result).data, 32));
723 assert(queue.events[0]->payment_received.amt == 5000);
724 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
725 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
727 PeerManager_process_events(&net2);
728 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
729 while (mons_updated != 5) {
730 std::this_thread::yield();
734 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
735 ev1.process_pending_events(ev1.this_arg, handler);
736 assert(queue.events.size() == 1);
737 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
738 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
743 cm1_ser = ChannelManager_write(&cm1);
744 cm2_ser = ChannelManager_write(&cm2);
747 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
748 assert(mons1.mons.size() == 1);
749 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
750 mons_list1->data[0].is_owned = false; // XXX: God this sucks
751 uint8_t node_seed[32];
752 memset(&node_seed, 0, 32);
753 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
754 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
756 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
757 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
758 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
759 assert(cm1_read->result_ok);
760 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
762 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
763 assert(mons2.mons.size() == 1);
764 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
765 mons_list2->data[0].is_owned = false; // XXX: God this sucks
766 memset(&node_seed, 1, 32);
767 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
769 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
770 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
771 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
772 assert(cm2_read->result_ok);
773 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
775 // Attempt to close the channel...
777 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
778 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
779 assert(!close_res->result_ok); // Note that we can't close while disconnected!
781 // Open a connection!
782 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
783 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
785 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
786 LDKCustomMessageHandler custom_msg_handler1 = {
787 .this_arg = &chan_2_node_id,
788 .handle_custom_message = NULL, // We only create custom messages, not handle them
789 .get_and_clear_pending_msg = create_custom_msg,
790 .CustomMessageReader = LDKCustomMessageReader {
792 .read = read_custom_message,
797 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
799 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
800 CustomMsgQueue peer_2_custom_messages;
801 LDKCustomMessageHandler custom_msg_handler2 = {
802 .this_arg = &peer_2_custom_messages,
803 .handle_custom_message = handle_custom_message,
804 .get_and_clear_pending_msg = never_send_custom_msgs,
805 .CustomMessageReader = LDKCustomMessageReader {
807 .read = read_custom_message,
812 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
813 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
815 PeersConnection conn(cm1, cm2, net1, net2);
818 // Wait for the channels to be considered up once the reestablish messages are processed
819 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
820 if (outbound_channels->datalen == 1) {
825 // Actually close the channel
826 num_txs_broadcasted = 0;
827 close_res = ChannelManager_close_channel(&cm1, &chan_id);
828 assert(close_res->result_ok);
829 PeerManager_process_events(&net1);
830 while (num_txs_broadcasted != 2) {
831 std::this_thread::yield();
833 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
834 assert(chans_after_close1->datalen == 0);
835 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
836 assert(chans_after_close2->datalen == 0);
840 assert(peer_2_custom_messages.msgs.size() != 0);
842 // Few extra random tests:
845 LDKThirtyTwoBytes kdiv_params;
846 memset(&kdiv_params, 43, 32);
847 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);