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();
246 // Finally make an actual connection and keep it this time
247 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
250 // Wait for the initial handshakes to complete...
251 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
252 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
253 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
254 std::this_thread::yield();
258 interrupt_socket_handling(node1_handler);
259 interrupt_socket_handling(node2_handler);
265 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
266 return write((int)((long)this_arg), data.data, data.datalen);
268 void sock_disconnect_socket(void *this_arg) {
269 close((int)((long)this_arg));
271 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
272 return this_arg == other_arg->this_arg;
274 uint64_t sock_hash(const void *this_arg) {
275 return (uint64_t)this_arg;
277 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
278 unsigned char buf[1024];
282 while ((readlen = read(rdfd, buf, 1024)) > 0) {
283 data.datalen = readlen;
284 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
285 if (!res->result_ok) {
286 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
289 PeerManager_process_events(pm);
291 PeerManager_socket_disconnected(&*pm, peer_descriptor);
294 class PeersConnection {
295 int pipefds_1_to_2[2];
296 int pipefds_2_to_1[2];
298 LDKSocketDescriptor sock1, sock2;
301 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
302 assert(!pipe(pipefds_1_to_2));
303 assert(!pipe(pipefds_2_to_1));
305 sock1 = LDKSocketDescriptor {
306 .this_arg = (void*)(long)pipefds_1_to_2[1],
307 .send_data = sock_send_data,
308 .disconnect_socket = sock_disconnect_socket,
315 sock2 = LDKSocketDescriptor {
316 .this_arg = (void*)(long)pipefds_2_to_1[1],
317 .send_data = sock_send_data,
318 .disconnect_socket = sock_disconnect_socket,
325 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
326 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
328 // Note that we have to bind the result to a C++ class to make sure it gets free'd
329 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1);
330 assert(con_res->result_ok);
331 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2);
332 assert(con_res2->result_ok);
334 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
335 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
338 // Wait for the initial handshakes to complete...
339 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
340 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
341 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
342 std::this_thread::yield();
347 close(pipefds_1_to_2[0]);
348 close(pipefds_2_to_1[0]);
349 close(pipefds_1_to_2[1]);
350 close(pipefds_2_to_1[1]);
357 struct CustomMsgQueue {
358 std::vector<LDK::Type> msgs;
361 uint16_t custom_msg_type_id(const void *this_arg) {
364 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
365 uint8_t *bytes = (uint8_t *) malloc(1024);
366 memset(bytes, 42, 1024);
368 .data = bytes, .datalen = 1024
371 LDKStr custom_msg_debug(const void *this_arg) {
373 .chars = NULL, .len = 0, .chars_is_owned = false
377 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
378 assert(type_id == 8888);
379 assert(buf.datalen == 1024);
381 memset(cmp, 42, 1024);
382 assert(!memcmp(cmp, buf.data, 1024));
383 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
385 .type_id = custom_msg_type_id,
386 .debug_str = custom_msg_debug,
391 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
392 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
393 arg->msgs.push_back(std::move(msg));
394 return CResult_NoneLightningErrorZ_ok();
396 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
397 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
398 .data = NULL, .datalen = 0
402 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
403 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
404 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
405 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
408 ret.data[0].a = *counterparty_node_id;
409 ret.data[0].b = LDKType {
411 .type_id = custom_msg_type_id,
412 .debug_str = custom_msg_debug,
413 .write = custom_msg_bytes,
420 uint8_t channel_open_header[80];
421 uint8_t header_1[80];
422 uint8_t header_2[80];
423 memcpy(channel_open_header, channel_open_block, 80);
424 memcpy(header_1, block_1, 80);
425 memcpy(header_2, block_2, 80);
427 LDKPublicKey null_pk;
428 memset(&null_pk, 0, sizeof(null_pk));
430 LDKThirtyTwoBytes random_bytes;
431 LDKThirtyTwoBytes chain_tip;
432 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
434 LDKNetwork network = LDKNetwork_Testnet;
436 // Trait implementations:
437 LDKBroadcasterInterface broadcast {
439 .broadcast_transaction = broadcast_tx,
443 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
445 .this_arg = (void*)1,
451 mons1.logger = &logger1;
454 .watch_channel = add_channel_monitor,
455 .update_channel = update_channel_monitor,
456 .release_pending_monitor_events = monitors_pending_monitor_events,
460 LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger1);
461 LDKSecretKey node_secret1;
464 .this_arg = (void*)2,
470 mons2.logger = &logger2;
473 .watch_channel = add_channel_monitor,
474 .update_channel = update_channel_monitor,
475 .release_pending_monitor_events = monitors_pending_monitor_events,
479 LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(NetworkGraph_new(genesis_hash), COption_AccessZ_none(), logger2);
480 LDKSecretKey node_secret2;
482 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
483 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
485 { // Scope for the ser-des reload
486 // Instantiate classes for node 1:
487 uint8_t node_seed[32];
488 memset(&node_seed, 0, 32);
489 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
490 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
491 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
493 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
495 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
496 assert(channels->datalen == 0);
498 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
500 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
501 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
503 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
504 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
506 // Demo getting a channel key and check that its returning real pubkeys:
507 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
508 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
509 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
510 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
512 // Instantiate classes for node 2:
513 memset(&node_seed, 1, 32);
514 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
515 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
516 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
518 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
519 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
520 LDK::UserConfig config2 = UserConfig_default();
521 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
523 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)));
525 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
526 assert(channels2->datalen == 0);
528 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
529 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
530 assert(chan_ann->result_ok);
531 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
532 assert(ann_res->result_ok);
534 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
536 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
537 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
539 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
540 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
542 // Open a connection!
543 PeersConnection conn(cm1, cm2, net1, net2);
545 // Note that we have to bind the result to a C++ class to make sure it gets free'd
546 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
547 assert(res->result_ok);
548 PeerManager_process_events(&net1);
550 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
551 assert(new_channels->datalen == 1);
552 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
553 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
554 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
557 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
558 if (new_channels_2->datalen == 1) {
559 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
560 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
561 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
562 assert(init_feats->inner != NULL);
565 std::this_thread::yield();
568 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
571 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
572 ev1.process_pending_events(ev1.this_arg, handler);
573 if (queue.events.size() == 1) {
574 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
575 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
576 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
577 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
578 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
579 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
581 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
582 assert(fund_res->result_ok);
585 std::this_thread::yield();
588 // We observe when the funding signed messages have been exchanged by
589 // waiting for two monitors to be registered.
590 assert(num_txs_broadcasted == 0);
591 PeerManager_process_events(&net1);
592 while (num_txs_broadcasted != 1) {
593 std::this_thread::yield();
596 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
597 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
599 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
600 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
602 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
603 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
604 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
606 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
607 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
608 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
610 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
611 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
612 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
613 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
615 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
616 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
617 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
618 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
620 PeerManager_process_events(&net1);
621 PeerManager_process_events(&net2);
623 // Now send funds from 1 to 2!
624 uint64_t channel_scid;
626 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
627 if (outbound_channels->datalen == 1) {
628 const LDKChannelDetails *channel = &outbound_channels->data[0];
629 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
630 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
631 uint8_t expected_chan_id[32];
632 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
633 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
635 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
636 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
637 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
638 // We opened the channel with 1000 push_msat:
639 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
640 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
641 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
642 if (inbound_capacity < 0) inbound_capacity = 0;
643 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
644 assert(ChannelDetails_get_is_usable(channel));
645 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
646 assert(scid_opt->some);
647 channel_scid = scid_opt->some;
650 std::this_thread::yield();
653 LDKCOption_u64Z min_value = {
654 .tag = LDKCOption_u64Z_Some,
657 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
658 KeysManager_as_KeysInterface(&keys2),
659 LDKCurrency_Bitcoin, min_value,
661 .chars = (const uint8_t *)"Invoice Description",
662 .len = strlen("Invoice Description"),
663 .chars_is_owned = false
665 assert(invoice->result_ok);
666 LDKThirtyTwoBytes payment_hash;
667 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
670 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
671 LDK::NetworkGraph graph_2_ref = NetGraphMsgHandler_get_network_graph(&net_graph2);
672 LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
673 .inner = NULL, .is_owned = false
674 }, &outbound_channels, Invoice_route_hints(invoice->contents.result),
675 5000, Invoice_min_final_cltv_expiry(invoice->contents.result), logger1);
676 assert(route->result_ok);
677 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
678 assert(paths->datalen == 1);
679 assert(paths->data[0].datalen == 1);
680 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
681 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
682 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
683 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, Invoice_payment_secret(invoice->contents.result));
684 assert(send_res->result_ok);
688 PeerManager_process_events(&net1);
689 while (mons_updated != 4) {
690 std::this_thread::yield();
693 // Check that we received the payment!
694 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
697 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
698 ev2.process_pending_events(ev2.this_arg, handler);
699 if (queue.events.size() == 1) {
700 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
703 std::this_thread::yield();
705 ChannelManager_process_pending_htlc_forwards(&cm2);
706 PeerManager_process_events(&net2);
709 LDKThirtyTwoBytes payment_preimage;
712 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
713 ev2.process_pending_events(ev2.this_arg, handler);
714 assert(queue.events.size() == 1);
715 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
716 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
717 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
718 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
719 Invoice_payment_secret(invoice->contents.result).data, 32));
720 assert(queue.events[0]->payment_received.amt == 5000);
721 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
722 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
724 PeerManager_process_events(&net2);
725 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
726 while (mons_updated != 5) {
727 std::this_thread::yield();
731 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
732 ev1.process_pending_events(ev1.this_arg, handler);
733 assert(queue.events.size() == 1);
734 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
735 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
740 cm1_ser = ChannelManager_write(&cm1);
741 cm2_ser = ChannelManager_write(&cm2);
744 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
745 assert(mons1.mons.size() == 1);
746 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
747 mons_list1->data[0].is_owned = false; // XXX: God this sucks
748 uint8_t node_seed[32];
749 memset(&node_seed, 0, 32);
750 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
751 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
753 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
754 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
755 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
756 assert(cm1_read->result_ok);
757 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
759 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
760 assert(mons2.mons.size() == 1);
761 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
762 mons_list2->data[0].is_owned = false; // XXX: God this sucks
763 memset(&node_seed, 1, 32);
764 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
766 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
767 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
768 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
769 assert(cm2_read->result_ok);
770 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
772 // Attempt to close the channel...
774 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
775 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
776 assert(!close_res->result_ok); // Note that we can't close while disconnected!
778 // Open a connection!
779 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
780 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
782 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
783 LDKCustomMessageHandler custom_msg_handler1 = {
784 .this_arg = &chan_2_node_id,
785 .handle_custom_message = NULL, // We only create custom messages, not handle them
786 .get_and_clear_pending_msg = create_custom_msg,
787 .CustomMessageReader = LDKCustomMessageReader {
789 .read = read_custom_message,
794 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
796 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
797 CustomMsgQueue peer_2_custom_messages;
798 LDKCustomMessageHandler custom_msg_handler2 = {
799 .this_arg = &peer_2_custom_messages,
800 .handle_custom_message = handle_custom_message,
801 .get_and_clear_pending_msg = never_send_custom_msgs,
802 .CustomMessageReader = LDKCustomMessageReader {
804 .read = read_custom_message,
809 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
810 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
812 PeersConnection conn(cm1, cm2, net1, net2);
815 // Wait for the channels to be considered up once the reestablish messages are processed
816 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
817 if (outbound_channels->datalen == 1) {
822 // Actually close the channel
823 num_txs_broadcasted = 0;
824 close_res = ChannelManager_close_channel(&cm1, &chan_id);
825 assert(close_res->result_ok);
826 PeerManager_process_events(&net1);
827 while (num_txs_broadcasted != 2) {
828 std::this_thread::yield();
830 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
831 assert(chans_after_close1->datalen == 0);
832 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
833 assert(chans_after_close2->datalen == 0);
837 assert(peer_2_custom_messages.msgs.size() != 0);
839 // Few extra random tests:
842 LDKThirtyTwoBytes kdiv_params;
843 memset(&kdiv_params, 43, 32);
844 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);