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, LDKEvent event) {
198 EventQueue* arg = (EventQueue*) this_arg;
199 arg->events.push_back(std::move(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]);
358 uint8_t channel_open_header[80];
359 uint8_t header_1[80];
360 uint8_t header_2[80];
361 memcpy(channel_open_header, channel_open_block, 80);
362 memcpy(header_1, block_1, 80);
363 memcpy(header_2, block_2, 80);
365 LDKPublicKey null_pk;
366 memset(&null_pk, 0, sizeof(null_pk));
368 LDKThirtyTwoBytes random_bytes;
369 LDKThirtyTwoBytes chain_tip;
370 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
372 LDKNetwork network = LDKNetwork_Testnet;
374 // Trait implementations:
375 LDKBroadcasterInterface broadcast {
377 .broadcast_transaction = broadcast_tx,
381 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
383 .this_arg = (void*)1,
389 mons1.logger = &logger1;
392 .watch_channel = add_channel_monitor,
393 .update_channel = update_channel_monitor,
394 .release_pending_monitor_events = monitors_pending_monitor_events,
398 LDK::NetGraphMsgHandler net_graph1 = NetGraphMsgHandler_new(genesis_hash, NULL, logger1);
399 LDKSecretKey node_secret1;
402 .this_arg = (void*)2,
408 mons2.logger = &logger2;
411 .watch_channel = add_channel_monitor,
412 .update_channel = update_channel_monitor,
413 .release_pending_monitor_events = monitors_pending_monitor_events,
417 LDK::NetGraphMsgHandler net_graph2 = NetGraphMsgHandler_new(genesis_hash, NULL, logger2);
418 LDKSecretKey node_secret2;
420 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
421 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
423 { // Scope for the ser-des reload
424 // Instantiate classes for node 1:
425 uint8_t node_seed[32];
426 memset(&node_seed, 0, 32);
427 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
428 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
429 node_secret1 = keys_source1->get_node_secret(keys_source1->this_arg);
431 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
433 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
434 assert(channels->datalen == 0);
436 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
438 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
439 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
441 // Demo getting a channel key and check that its returning real pubkeys:
442 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
443 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
444 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
445 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
447 // Instantiate classes for node 2:
448 memset(&node_seed, 1, 32);
449 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
450 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
451 node_secret2 = keys_source2->get_node_secret(keys_source2->this_arg);
453 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
454 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
455 LDK::UserConfig config2 = UserConfig_default();
456 UserConfig_set_own_channel_config(&config2, std::move(handshake_config2));
458 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)));
460 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
461 assert(channels2->datalen == 0);
463 LDK::RoutingMessageHandler net_msgs2 = NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2);
464 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
465 assert(chan_ann->result_ok);
466 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
467 assert(ann_res->result_ok);
469 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
471 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
472 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
474 // Open a connection!
475 PeersConnection conn(cm1, cm2, net1, net2);
477 // Note that we have to bind the result to a C++ class to make sure it gets free'd
478 LDK::CResult_NoneAPIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
479 assert(res->result_ok);
480 PeerManager_process_events(&net1);
482 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
483 assert(new_channels->datalen == 1);
484 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
485 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
486 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
489 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
490 if (new_channels_2->datalen == 1) {
491 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
492 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
493 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
494 assert(init_feats->inner != NULL);
497 std::this_thread::yield();
500 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
503 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
504 ev1.process_pending_events(ev1.this_arg, handler);
505 if (queue.events.size() == 1) {
506 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
507 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
508 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
509 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
510 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
511 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
513 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, funding_transaction);
514 assert(fund_res->result_ok);
517 std::this_thread::yield();
520 // We observe when the funding signed messages have been exchanged by
521 // waiting for two monitors to be registered.
522 assert(num_txs_broadcasted == 0);
523 PeerManager_process_events(&net1);
524 while (num_txs_broadcasted != 1) {
525 std::this_thread::yield();
528 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
529 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
531 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
532 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
534 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
535 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
536 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
538 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
539 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
540 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
542 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
543 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
544 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
545 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
547 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
548 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
549 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
550 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
552 PeerManager_process_events(&net1);
553 PeerManager_process_events(&net2);
555 // Now send funds from 1 to 2!
557 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
558 if (outbound_channels->datalen == 1) {
559 const LDKChannelDetails *channel = &outbound_channels->data[0];
560 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
561 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
562 uint8_t expected_chan_id[32];
563 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
564 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
566 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
567 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
568 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
569 // We opened the channel with 1000 push_msat:
570 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
571 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
572 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
573 if (inbound_capacity < 0) inbound_capacity = 0;
574 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
575 assert(ChannelDetails_get_is_usable(channel));
578 std::this_thread::yield();
581 LDKCOption_u64Z min_value = {
582 .tag = LDKCOption_u64Z_Some,
585 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
586 KeysManager_as_KeysInterface(&keys2),
587 LDKCurrency_Bitcoin, min_value,
589 .chars = (const uint8_t *)"Invoice Description",
590 .len = strlen("Invoice Description"),
591 .chars_is_owned = false
593 assert(invoice->result_ok);
594 LDKThirtyTwoBytes payment_hash;
595 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
598 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
599 LDK::LockedNetworkGraph graph_2_locked = NetGraphMsgHandler_read_locked_graph(&net_graph2);
600 LDK::NetworkGraph graph_2_ref = LockedNetworkGraph_graph(&graph_2_locked);
601 LDK::CResult_RouteLightningErrorZ route = get_route(ChannelManager_get_our_node_id(&cm1), &graph_2_ref, ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
602 .inner = NULL, .is_owned = false
603 }, &outbound_channels, Invoice_route_hints(invoice->contents.result),
604 5000, Invoice_min_final_cltv_expiry(invoice->contents.result), logger1);
605 assert(route->result_ok);
606 LDK::CResult_NonePaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, Invoice_payment_secret(invoice->contents.result));
607 assert(send_res->result_ok);
611 PeerManager_process_events(&net1);
612 while (mons_updated != 4) {
613 std::this_thread::yield();
616 // Check that we received the payment!
617 LDKEventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
620 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
621 ev2.process_pending_events(ev2.this_arg, handler);
622 if (queue.events.size() == 1) {
623 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
626 std::this_thread::yield();
628 ChannelManager_process_pending_htlc_forwards(&cm2);
629 PeerManager_process_events(&net2);
632 LDKThirtyTwoBytes payment_preimage;
635 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
636 ev2.process_pending_events(ev2.this_arg, handler);
637 assert(queue.events.size() == 1);
638 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
639 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
640 assert(!memcmp(queue.events[0]->payment_received.payment_secret.data, Invoice_payment_secret(invoice->contents.result).data, 32));
641 assert(queue.events[0]->payment_received.amt == 5000);
642 memcpy(payment_preimage.data, queue.events[0]->payment_received.payment_preimage.data, 32);
643 assert(ChannelManager_claim_funds(&cm2, payment_preimage));
645 PeerManager_process_events(&net2);
646 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
647 while (mons_updated != 5) {
648 std::this_thread::yield();
652 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
653 ev1.process_pending_events(ev1.this_arg, handler);
654 assert(queue.events.size() == 1);
655 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
656 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
661 cm1_ser = ChannelManager_write(&cm1);
662 cm2_ser = ChannelManager_write(&cm2);
665 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
666 assert(mons1.mons.size() == 1);
667 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
668 mons_list1->data[0].is_owned = false; // XXX: God this sucks
669 uint8_t node_seed[32];
670 memset(&node_seed, 0, 32);
671 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
672 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
674 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
675 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
676 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
677 assert(cm1_read->result_ok);
678 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
680 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
681 assert(mons2.mons.size() == 1);
682 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
683 mons_list2->data[0].is_owned = false; // XXX: God this sucks
684 memset(&node_seed, 1, 32);
685 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
687 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
688 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
689 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
690 assert(cm2_read->result_ok);
691 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
693 // Attempt to close the channel...
695 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
696 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id);
697 assert(!close_res->result_ok); // Note that we can't close while disconnected!
699 // Open a connection!
700 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph1));
701 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
702 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1);
704 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), NetGraphMsgHandler_as_RoutingMessageHandler(&net_graph2));
705 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
706 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2);
708 PeersConnection conn(cm1, cm2, net1, net2);
711 // Wait for the channels to be considered up once the reestablish messages are processed
712 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
713 if (outbound_channels->datalen == 1) {
718 // Actually close the channel
719 num_txs_broadcasted = 0;
720 close_res = ChannelManager_close_channel(&cm1, &chan_id);
721 assert(close_res->result_ok);
722 PeerManager_process_events(&net1);
723 while (num_txs_broadcasted != 2) {
724 std::this_thread::yield();
726 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
727 assert(chans_after_close1->datalen == 0);
728 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
729 assert(chans_after_close2->datalen == 0);
733 // Few extra random tests:
736 LDKThirtyTwoBytes kdiv_params;
737 memset(&kdiv_params, 43, 32);
738 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);