8 #include "include/lightningpp.hpp"
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
24 const uint8_t valid_node_announcement[] = {
25 0x94, 0xe4, 0xf5, 0x61, 0x41, 0x24, 0x7d, 0x90, 0x23, 0xa0, 0xc8, 0x34, 0x8c, 0xc4, 0xca, 0x51,
26 0xd8, 0x17, 0x59, 0xff, 0x7d, 0xac, 0x8c, 0x9b, 0x63, 0x29, 0x1c, 0xe6, 0x12, 0x12, 0x93, 0xbd,
27 0x66, 0x4d, 0x6b, 0x9c, 0xfb, 0x35, 0xda, 0x16, 0x06, 0x3d, 0xf0, 0x8f, 0x8a, 0x39, 0x99, 0xa2,
28 0xf2, 0x5d, 0x12, 0x0f, 0x2b, 0x42, 0x1b, 0x8b, 0x9a, 0xfe, 0x33, 0x0c, 0xeb, 0x33, 0x5e, 0x52,
29 0xee, 0x99, 0xa1, 0x07, 0x06, 0xed, 0xf8, 0x48, 0x7a, 0xc6, 0xe5, 0xf5, 0x5e, 0x01, 0x3a, 0x41,
30 0x2f, 0x18, 0x94, 0x8a, 0x3b, 0x0a, 0x52, 0x3f, 0xbf, 0x61, 0xa9, 0xc5, 0x4f, 0x70, 0xee, 0xb8,
31 0x79, 0x23, 0xbb, 0x1a, 0x44, 0x7d, 0x91, 0xe6, 0x2a, 0xbc, 0xa1, 0x07, 0xbc, 0x65, 0x3b, 0x02,
32 0xd9, 0x1d, 0xb2, 0xf2, 0x3a, 0xcb, 0x75, 0x79, 0xc6, 0x66, 0xd8, 0xc1, 0x71, 0x29, 0xdf, 0x04,
33 0x60, 0xf4, 0xbf, 0x07, 0x7b, 0xb9, 0xc2, 0x11, 0x94, 0x6a, 0x28, 0xc2, 0xdd, 0xd8, 0x7b, 0x44,
34 0x8f, 0x08, 0xe3, 0xc8, 0xd8, 0xf4, 0x81, 0xb0, 0x9f, 0x94, 0xcb, 0xc8, 0xc1, 0x3c, 0xc2, 0x6e,
35 0x31, 0x26, 0xfc, 0x33, 0x16, 0x3b, 0xe0, 0xde, 0xa1, 0x16, 0x21, 0x9f, 0x89, 0xdd, 0x97, 0xa4,
36 0x41, 0xf2, 0x9f, 0x19, 0xb1, 0xae, 0x82, 0xf7, 0x85, 0x9a, 0xb7, 0x8f, 0xb7, 0x52, 0x7a, 0x72,
37 0xf1, 0x5e, 0x89, 0xe1, 0x8a, 0xcd, 0x40, 0xb5, 0x8e, 0xc3, 0xca, 0x42, 0x76, 0xa3, 0x6e, 0x1b,
38 0xf4, 0x87, 0x35, 0x30, 0x58, 0x43, 0x04, 0xd9, 0x2c, 0x50, 0x54, 0x55, 0x47, 0x6f, 0x70, 0x9b,
39 0x42, 0x1f, 0x91, 0xfc, 0xa1, 0xdb, 0x72, 0x53, 0x96, 0xc8, 0xe5, 0xcd, 0x0e, 0xcb, 0xa0, 0xfe,
40 0x6b, 0x08, 0x77, 0x48, 0xb7, 0xad, 0x4a, 0x69, 0x7c, 0xdc, 0xd8, 0x04, 0x28, 0x35, 0x9b, 0x73,
41 0x00, 0x00, 0x43, 0x49, 0x7f, 0xd7, 0xf8, 0x26, 0x95, 0x71, 0x08, 0xf4, 0xa3, 0x0f, 0xd9, 0xce,
42 0xc3, 0xae, 0xba, 0x79, 0x97, 0x20, 0x84, 0xe9, 0x0e, 0xad, 0x01, 0xea, 0x33, 0x09, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x5b, 0xe5, 0xe9, 0x47, 0x82,
44 0x09, 0x67, 0x4a, 0x96, 0xe6, 0x0f, 0x1f, 0x03, 0x7f, 0x61, 0x76, 0x54, 0x0f, 0xd0, 0x01, 0xfa,
45 0x1d, 0x64, 0x69, 0x47, 0x70, 0xc5, 0x6a, 0x77, 0x09, 0xc4, 0x2c, 0x03, 0x5c, 0x4e, 0x0d, 0xec,
46 0x72, 0x15, 0xe2, 0x68, 0x33, 0x93, 0x87, 0x30, 0xe5, 0xe5, 0x05, 0xaa, 0x62, 0x50, 0x4d, 0xa8,
47 0x5b, 0xa5, 0x71, 0x06, 0xa4, 0x6b, 0x5a, 0x24, 0x04, 0xfc, 0x9d, 0x8e, 0x02, 0xba, 0x72, 0xa6,
48 0xe8, 0xba, 0x53, 0xe8, 0xb9, 0x71, 0xad, 0x0c, 0x98, 0x23, 0x96, 0x8a, 0xef, 0x4d, 0x78, 0xce,
49 0x8a, 0xf2, 0x55, 0xab, 0x43, 0xdf, 0xf8, 0x30, 0x03, 0xc9, 0x02, 0xfb, 0x8d, 0x02, 0x16, 0x34,
50 0x5b, 0xf8, 0x31, 0x16, 0x4a, 0x03, 0x75, 0x8e, 0xae, 0xa5, 0xe8, 0xb6, 0x6f, 0xee, 0x2b, 0xe7,
51 0x71, 0x0b, 0x8f, 0x19, 0x0e, 0xe8, 0x80, 0x24, 0x90, 0x32, 0xa2, 0x9e, 0xd6, 0x6e
54 // A simple block containing only one transaction (which is the channel-open transaction for the
55 // channel we'll create). This was originally created by printing additional data in a simple
56 // rust-lightning unit test.
57 const uint8_t channel_open_block[] = {
58 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0xa2, 0x47, 0xd2, 0xf8, 0xd4, 0xe0, 0x6a, 0x3f, 0xf9, 0x7a, 0x9a, 0x34,
61 0xbb, 0xa9, 0x96, 0xde, 0x63, 0x84, 0x5a, 0xce, 0xcf, 0x98, 0xb8, 0xbb, 0x75, 0x4c, 0x4f, 0x7d,
62 0xee, 0x4c, 0xa9, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x01, // transaction count
64 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x01, 0x40, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x20, 0xd1, 0xd9, 0x13, 0xa9,
68 0x76, 0x09, 0x05, 0xa3, 0x4d, 0x13, 0x5b, 0x69, 0xaa, 0xe7, 0x79, 0x71, 0xb9, 0x75, 0xa1, 0xd0,
69 0x77, 0xcb, 0xa2, 0xf6, 0x6a, 0x25, 0x37, 0x3a, 0xaf, 0xdc, 0x11, 0x09, 0x01, 0x00, 0x00, 0x00,
73 // The first transaction in the block is header (80 bytes) + transaction count (1 byte) into the block data.
74 const uint8_t channel_open_txid[] = {
75 0x02, 0xe0, 0x50, 0x05, 0x33, 0xd3, 0x29, 0x66, 0x0c, 0xb2, 0xcb, 0x1e, 0x7a, 0x4a, 0xc7, 0xc7,
76 0x8b, 0x02, 0x46, 0x7e, 0x30, 0x2c, 0xe6, 0x19, 0xce, 0x43, 0x3e, 0xdf, 0x43, 0x65, 0xae, 0xf9,
79 // Two blocks built on top of channel_open_block:
80 const uint8_t block_1[81] = {
81 0x01, 0x00, 0x00, 0x00, 0x0c, 0x7a, 0xc2, 0xdc, 0x08, 0xaf, 0x40, 0x7d, 0x58, 0x81, 0x9b, 0x44,
82 0xc7, 0xe0, 0x0f, 0x78, 0xc0, 0xd1, 0x01, 0xa2, 0x03, 0x16, 0x4a, 0x8d, 0x92, 0x66, 0x4e, 0xaf,
83 0x7f, 0xfc, 0x6e, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, // transaction count
88 const uint8_t block_2[81] = {
89 0x01, 0x00, 0x00, 0x00, 0x36, 0x0b, 0xf5, 0x46, 0x4a, 0xc7, 0x26, 0x4c, 0x4b, 0x36, 0xa6, 0x9d,
90 0x0e, 0xf0, 0x14, 0xfb, 0x8a, 0xcb, 0x20, 0x84, 0x18, 0xf3, 0xaa, 0x77, 0x32, 0x2d, 0xf7, 0x48,
91 0x62, 0x92, 0xb1, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, // transaction count
97 const LDKThirtyTwoBytes genesis_hash = { // We don't care particularly if this is "right"
98 .data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1 }
101 void print_log(const void *this_arg, const LDKRecord *record) {
102 LDK::Str mod = Record_get_module_path(record);
103 LDK::Str str = Record_get_args(record);
104 printf("%p - %.*s:%d - %.*s\n", this_arg, (int)mod->len, mod->chars, Record_get_line(record), (int)str->len, str->chars);
107 uint32_t get_fee(const void *this_arg, LDKConfirmationTarget target) {
108 if (target == LDKConfirmationTarget_Background) {
113 // Note that we don't call _free() on target, but that's OK, its unitary
115 // We use the same fee estimator globally:
116 const LDKFeeEstimator fee_est {
118 .get_est_sat_per_1000_weight = get_fee,
122 static std::atomic_int num_txs_broadcasted(0);
123 void broadcast_tx(const void *this_arg, LDKTransaction tx) {
124 num_txs_broadcasted += 1;
126 Transaction_free(tx);
129 struct NodeMonitors {
131 std::vector<std::pair<LDK::OutPoint, LDK::ChannelMonitor>> mons;
134 void ConnectBlock(const uint8_t (*header)[80], uint32_t height, LDKCVec_C2Tuple_usizeTransactionZZ tx_data, LDKBroadcasterInterface broadcast, LDKFeeEstimator fee_est) {
135 std::unique_lock<std::mutex> l(mut);
136 for (auto& mon : mons) {
137 LDK::CVec_TransactionOutputsZ res = ChannelMonitor_block_connected(&mon.second, header, tx_data, height, broadcast, fee_est, *logger);
142 LDKCResult_NoneChannelMonitorUpdateErrZ add_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitor monitor_arg) {
143 // First bind the args to C++ objects so they auto-free
144 LDK::ChannelMonitor mon(std::move(monitor_arg));
145 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
147 NodeMonitors* arg = (NodeMonitors*) this_arg;
148 std::unique_lock<std::mutex> l(arg->mut);
150 arg->mons.push_back(std::make_pair(std::move(funding_txo), std::move(mon)));
151 return CResult_NoneChannelMonitorUpdateErrZ_ok();
153 static std::atomic_int mons_updated(0);
154 LDKCResult_NoneChannelMonitorUpdateErrZ update_channel_monitor(const void *this_arg, LDKOutPoint funding_txo_arg, LDKChannelMonitorUpdate monitor_arg) {
155 // First bind the args to C++ objects so they auto-free
156 LDK::ChannelMonitorUpdate update(std::move(monitor_arg));
157 LDK::OutPoint funding_txo(std::move(funding_txo_arg));
159 NodeMonitors* arg = (NodeMonitors*) this_arg;
160 std::unique_lock<std::mutex> l(arg->mut);
162 bool updated = false;
163 for (auto& mon : arg->mons) {
164 if (OutPoint_get_index(&mon.first) == OutPoint_get_index(&funding_txo) &&
165 !memcmp(OutPoint_get_txid(&mon.first), OutPoint_get_txid(&funding_txo), 32)) {
167 LDKBroadcasterInterface broadcaster = {
168 .broadcast_transaction = broadcast_tx,
170 LDK::CResult_NoneNoneZ res = ChannelMonitor_update_monitor(&mon.second, &update, &broadcaster, fee_est, arg->logger);
171 assert(res->result_ok);
177 return CResult_NoneChannelMonitorUpdateErrZ_ok();
179 LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ monitors_pending_monitor_events(const void *this_arg) {
180 NodeMonitors* arg = (NodeMonitors*) this_arg;
181 std::unique_lock<std::mutex> l(arg->mut);
183 if (arg->mons.size() == 0) {
184 return LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
189 // We only ever actually have one channel per node, plus concatenating two
190 // Rust Vecs to each other from C++ will require a bit of effort.
191 assert(arg->mons.size() == 1);
192 LDK::CVec_MonitorEventZ events = ChannelMonitor_get_and_clear_pending_monitor_events(&arg->mons[0].second);
193 LDK::C2Tuple_OutPointScriptZ funding_info = ChannelMonitor_get_funding_txo(&arg->mons[0].second);
194 LDK::OutPoint outpoint = std::move(funding_info->a);
195 LDKPublicKey counterparty_node_id = ChannelMonitor_get_counterparty_node_id(&arg->mons[0].second);
196 LDK::C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ tuple = C3Tuple_OutPointCVec_MonitorEventZPublicKeyZ_new(std::move(outpoint), std::move(events), std::move(counterparty_node_id));
197 auto vec = LDKCVec_C3Tuple_OutPointCVec_MonitorEventZPublicKeyZZ {
198 .data = (LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ*)malloc(sizeof(LDKC3Tuple_OutPointCVec_MonitorEventZPublicKeyZ)),
201 vec.data[0] = std::move(tuple);
207 std::vector<LDK::Event> events;
209 void handle_event(const void *this_arg, const LDKEvent *event) {
210 EventQueue* arg = (EventQueue*) this_arg;
211 arg->events.push_back(Event_clone(event));
215 class PeersConnection {
220 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
221 node1_handler = init_socket_handling(&net1);
222 node2_handler = init_socket_handling(&net2);
224 struct sockaddr_in listen_addr;
225 listen_addr.sin_family = AF_INET;
226 listen_addr.sin_addr.s_addr = htonl((127 << 8*3) | 1);
227 listen_addr.sin_port = htons(10042);
228 assert(!socket_bind(node2_handler, (sockaddr*)&listen_addr, sizeof(listen_addr)));
230 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
233 // Wait for the initial handshakes to complete...
234 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
235 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
236 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
237 std::this_thread::yield();
240 // Connect twice, which should auto-disconnect, and is a good test of our disconnect pipeline
241 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
242 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
244 // Then disconnect the "main" connection, while another connection is being made.
245 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
246 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
248 // Wait for all our sockets to disconnect (making sure we disconnect any new connections)...
250 PeerManager_disconnect_by_node_id(&net1, ChannelManager_get_our_node_id(&cm2), false);
251 // Wait for the peers to disconnect...
252 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
253 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
254 if (peers_1->datalen == 0 && peers_2->datalen == 0) { break; }
255 std::this_thread::yield();
257 // Note that the above is somewhat race-y, as node 2 may still think its connected.
258 // Thus, make sure any connections are disconnected on its end as well.
259 PeerManager_disconnect_by_node_id(&net2, ChannelManager_get_our_node_id(&cm1), false);
261 // Finally make an actual connection and keep it this time
262 assert(!socket_connect(node1_handler, ChannelManager_get_our_node_id(&cm2), (sockaddr*)&listen_addr, sizeof(listen_addr)));
265 // Wait for the initial handshakes to complete...
266 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
267 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
268 if (peers_1->datalen == 1 && peers_2->datalen == 1) { break; }
269 std::this_thread::yield();
273 interrupt_socket_handling(node1_handler);
274 interrupt_socket_handling(node2_handler);
280 uintptr_t sock_send_data(void *this_arg, LDKu8slice data, bool resume_read) {
281 return write((int)((long)this_arg), data.data, data.datalen);
283 void sock_disconnect_socket(void *this_arg) {
284 close((int)((long)this_arg));
286 bool sock_eq(const void *this_arg, const LDKSocketDescriptor *other_arg) {
287 return this_arg == other_arg->this_arg;
289 uint64_t sock_hash(const void *this_arg) {
290 return (uint64_t)this_arg;
292 void sock_read_data_thread(int rdfd, LDKSocketDescriptor *peer_descriptor, LDKPeerManager *pm) {
293 unsigned char buf[1024];
297 while ((readlen = read(rdfd, buf, 1024)) > 0) {
298 data.datalen = readlen;
299 LDK::CResult_boolPeerHandleErrorZ res = PeerManager_read_event(&*pm, peer_descriptor, data);
300 if (!res->result_ok) {
301 peer_descriptor->disconnect_socket(peer_descriptor->this_arg);
304 PeerManager_process_events(pm);
306 PeerManager_socket_disconnected(&*pm, peer_descriptor);
309 class PeersConnection {
310 int pipefds_1_to_2[2];
311 int pipefds_2_to_1[2];
313 LDKSocketDescriptor sock1, sock2;
316 PeersConnection(LDK::ChannelManager& cm1, LDK::ChannelManager& cm2, LDK::PeerManager& net1, LDK::PeerManager& net2) {
317 assert(!pipe(pipefds_1_to_2));
318 assert(!pipe(pipefds_2_to_1));
320 sock1 = LDKSocketDescriptor {
321 .this_arg = (void*)(long)pipefds_1_to_2[1],
322 .send_data = sock_send_data,
323 .disconnect_socket = sock_disconnect_socket,
330 sock2 = LDKSocketDescriptor {
331 .this_arg = (void*)(long)pipefds_2_to_1[1],
332 .send_data = sock_send_data,
333 .disconnect_socket = sock_disconnect_socket,
340 t1 = std::thread(&sock_read_data_thread, pipefds_2_to_1[0], &sock1, &net1);
341 t2 = std::thread(&sock_read_data_thread, pipefds_1_to_2[0], &sock2, &net2);
343 // Note that we have to bind the result to a C++ class to make sure it gets free'd
344 LDK::CResult_CVec_u8ZPeerHandleErrorZ con_res = PeerManager_new_outbound_connection(&net1, ChannelManager_get_our_node_id(&cm2), sock1, COption_NetAddressZ_none());
345 assert(con_res->result_ok);
346 LDK::CResult_NonePeerHandleErrorZ con_res2 = PeerManager_new_inbound_connection(&net2, sock2, COption_NetAddressZ_none());
347 assert(con_res2->result_ok);
349 auto writelen = write(pipefds_1_to_2[1], con_res->contents.result->data, con_res->contents.result->datalen);
350 assert(writelen > 0 && uint64_t(writelen) == con_res->contents.result->datalen);
353 // Wait for the initial handshakes to complete...
354 LDK::CVec_PublicKeyZ peers_1 = PeerManager_get_peer_node_ids(&net1);
355 LDK::CVec_PublicKeyZ peers_2 = PeerManager_get_peer_node_ids(&net2);
356 if (peers_1->datalen == 1 && peers_2->datalen ==1) { break; }
357 std::this_thread::yield();
362 close(pipefds_1_to_2[0]);
363 close(pipefds_2_to_1[0]);
364 close(pipefds_1_to_2[1]);
365 close(pipefds_2_to_1[1]);
372 struct CustomMsgQueue {
373 std::vector<LDK::Type> msgs;
376 uint16_t custom_msg_type_id(const void *this_arg) {
379 LDKCVec_u8Z custom_msg_bytes(const void *this_arg) {
380 uint8_t *bytes = (uint8_t *) malloc(1024);
381 memset(bytes, 42, 1024);
383 .data = bytes, .datalen = 1024
386 LDKStr custom_msg_debug(const void *this_arg) {
388 .chars = NULL, .len = 0, .chars_is_owned = false
392 LDKCResult_COption_TypeZDecodeErrorZ read_custom_message(const void* this_arg, uint16_t type_id, LDKu8slice buf) {
393 assert(type_id == 8888);
394 assert(buf.datalen == 1024);
396 memset(cmp, 42, 1024);
397 assert(!memcmp(cmp, buf.data, 1024));
398 return CResult_COption_TypeZDecodeErrorZ_ok(COption_TypeZ_some(LDKType {
400 .type_id = custom_msg_type_id,
401 .debug_str = custom_msg_debug,
406 LDKCResult_NoneLightningErrorZ handle_custom_message(const void* this_arg, struct LDKType msg, struct LDKPublicKey _sender_node_id) {
407 CustomMsgQueue* arg = (CustomMsgQueue*) this_arg;
408 arg->msgs.push_back(std::move(msg));
409 return CResult_NoneLightningErrorZ_ok();
411 LDKCVec_C2Tuple_PublicKeyTypeZZ never_send_custom_msgs(const void* this_arg) {
412 return LDKCVec_C2Tuple_PublicKeyTypeZZ {
413 .data = NULL, .datalen = 0
417 LDKCVec_C2Tuple_PublicKeyTypeZZ create_custom_msg(const void* this_arg) {
418 const LDKPublicKey *counterparty_node_id = (const LDKPublicKey *)this_arg;
419 LDKCVec_C2Tuple_PublicKeyTypeZZ ret = {
420 .data = ((LDKC2Tuple_PublicKeyTypeZ*)malloc(sizeof(LDKC2Tuple_PublicKeyTypeZ))),
423 ret.data[0].a = *counterparty_node_id;
424 ret.data[0].b = LDKType {
426 .type_id = custom_msg_type_id,
427 .debug_str = custom_msg_debug,
428 .write = custom_msg_bytes,
434 uint64_t get_chan_score(const void *this_arg, uint64_t scid, const LDKNodeId *src, const LDKNodeId *dst, LDKChannelUsage usage_in) {
435 LDK::ChannelUsage usage(std::move(usage_in));
439 struct CustomRouteFinderParams {
441 LDKNetworkGraph *graph_ref;
442 LDKThirtyTwoBytes random_seed_bytes;
444 struct LDKCResult_RouteLightningErrorZ custom_find_route(const void *this_arg, struct LDKPublicKey payer, const struct LDKRouteParameters *NONNULL_PTR route_params, const uint8_t (*payment_hash)[32], struct LDKCVec_ChannelDetailsZ *first_hops, const struct LDKScore *NONNULL_PTR scorer) {
445 const struct CustomRouteFinderParams *params = (struct CustomRouteFinderParams *)this_arg;
446 assert(first_hops->datalen == 1);
447 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
448 return find_route(payer, route_params, params->graph_ref, first_hops, *params->logger, scorer, ¶ms->random_seed_bytes.data);
452 uint8_t channel_open_header[80];
453 uint8_t header_1[80];
454 uint8_t header_2[80];
455 memcpy(channel_open_header, channel_open_block, 80);
456 memcpy(header_1, block_1, 80);
457 memcpy(header_2, block_2, 80);
459 LDKPublicKey null_pk;
460 memset(&null_pk, 0, sizeof(null_pk));
462 LDKThirtyTwoBytes random_bytes;
463 LDKThirtyTwoBytes chain_tip;
464 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
466 LDKNetwork network = LDKNetwork_Testnet;
468 // Trait implementations:
469 LDKBroadcasterInterface broadcast {
471 .broadcast_transaction = broadcast_tx,
475 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
477 .this_arg = (void*)1,
483 mons1.logger = &logger1;
486 .watch_channel = add_channel_monitor,
487 .update_channel = update_channel_monitor,
488 .release_pending_monitor_events = monitors_pending_monitor_events,
492 LDK::NetworkGraph net_graph1 = NetworkGraph_new(genesis_hash, logger1);
493 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_AccessZ_none(), logger1);
494 LDKSecretKey node_secret1;
497 .this_arg = (void*)2,
503 mons2.logger = &logger2;
506 .watch_channel = add_channel_monitor,
507 .update_channel = update_channel_monitor,
508 .release_pending_monitor_events = monitors_pending_monitor_events,
512 LDK::NetworkGraph net_graph2 = NetworkGraph_new(genesis_hash, logger2);
513 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_AccessZ_none(), logger2);
514 LDKSecretKey node_secret2;
516 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
517 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
519 { // Scope for the ser-des reload
520 // Instantiate classes for node 1:
521 uint8_t node_seed[32];
522 memset(&node_seed, 0, 32);
523 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
524 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
525 LDK::CResult_SecretKeyNoneZ node_secret1_res = keys_source1->get_node_secret(keys_source1->this_arg, LDKRecipient_Node);
526 assert(node_secret1_res->result_ok);
527 node_secret1 = *node_secret1_res->contents.result;
529 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
531 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
532 assert(channels->datalen == 0);
534 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1));
536 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
537 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
539 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
540 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
542 // Demo getting a channel key and check that its returning real pubkeys:
543 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
544 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
545 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
546 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
548 // Instantiate classes for node 2:
549 memset(&node_seed, 1, 32);
550 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
551 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
552 LDK::CResult_SecretKeyNoneZ node_secret2_res = keys_source2->get_node_secret(keys_source2->this_arg, LDKRecipient_Node);
553 assert(node_secret2_res->result_ok);
554 node_secret2 = *node_secret2_res->contents.result;
556 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
557 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
558 LDK::UserConfig config2 = UserConfig_default();
559 UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2));
561 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)));
563 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
564 assert(channels2->datalen == 0);
566 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
567 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
568 assert(chan_ann->result_ok);
569 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
570 assert(ann_res->result_ok);
572 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2));
574 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
575 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
577 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
578 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
580 // Open a connection!
581 PeersConnection conn(cm1, cm2, net1, net2);
583 // Note that we have to bind the result to a C++ class to make sure it gets free'd
584 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
585 assert(res->result_ok);
586 PeerManager_process_events(&net1);
588 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
589 assert(new_channels->datalen == 1);
590 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
591 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
592 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
595 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
596 if (new_channels_2->datalen == 1) {
597 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
598 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
599 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
600 assert(init_feats->inner != NULL);
603 std::this_thread::yield();
606 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
609 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
610 ev1.process_pending_events(ev1.this_arg, handler);
611 if (queue.events.size() == 1) {
612 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
613 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
614 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
615 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
616 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
617 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
619 LDK::CResult_NoneAPIErrorZ fund_res = ChannelManager_funding_transaction_generated(&cm1, &queue.events[0]->funding_generation_ready.temporary_channel_id.data, queue.events[0]->funding_generation_ready.counterparty_node_id, funding_transaction);
620 assert(fund_res->result_ok);
623 std::this_thread::yield();
626 // We observe when the funding signed messages have been exchanged by
627 // waiting for two monitors to be registered.
628 assert(num_txs_broadcasted == 0);
629 PeerManager_process_events(&net1);
630 while (num_txs_broadcasted != 1) {
631 std::this_thread::yield();
634 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
635 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
637 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
638 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
640 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
641 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
642 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
644 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
645 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
646 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
648 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
649 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
650 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
651 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
653 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
654 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
655 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
656 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
658 PeerManager_process_events(&net1);
659 PeerManager_process_events(&net2);
661 // Now send funds from 1 to 2!
662 uint64_t channel_scid;
664 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
665 if (outbound_channels->datalen == 1) {
666 const LDKChannelDetails *channel = &outbound_channels->data[0];
667 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
668 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
669 uint8_t expected_chan_id[32];
670 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
671 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
673 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
674 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
675 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
676 // We opened the channel with 1000 push_msat:
677 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
678 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
679 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
680 if (inbound_capacity < 0) inbound_capacity = 0;
681 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
682 assert(ChannelDetails_get_is_usable(channel));
683 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
684 assert(scid_opt->some);
685 channel_scid = scid_opt->some;
688 std::this_thread::yield();
691 LDKCOption_u64Z min_value = {
692 .tag = LDKCOption_u64Z_Some,
695 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
696 KeysManager_as_KeysInterface(&keys2),
697 LDKCurrency_Bitcoin, min_value,
699 .chars = (const uint8_t *)"Invoice Description",
700 .len = strlen("Invoice Description"),
701 .chars_is_owned = false
703 assert(invoice->result_ok);
704 LDKThirtyTwoBytes payment_hash;
705 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
708 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
709 LDK::Score chan_scorer = LDKScore {
710 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
712 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
713 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
714 .inner = NULL, .is_owned = false
715 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff,
716 1, 2, LDKCVec_u64Z { .data = NULL, .datalen = 0 }),
717 5000, Invoice_min_final_cltv_expiry(invoice->contents.result));
718 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
720 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
722 assert(route->result_ok);
723 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
724 assert(paths->datalen == 1);
725 assert(paths->data[0].datalen == 1);
726 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
727 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
728 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
729 LDKThirtyTwoBytes payment_secret;
730 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
731 LDK::CResult_PaymentIdPaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret);
732 assert(send_res->result_ok);
736 PeerManager_process_events(&net1);
737 while (mons_updated != 4) {
738 std::this_thread::yield();
741 // Check that we received the payment!
742 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
745 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
746 ev2.process_pending_events(handler);
747 if (queue.events.size() == 1) {
748 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
751 std::this_thread::yield();
753 ChannelManager_process_pending_htlc_forwards(&cm2);
754 PeerManager_process_events(&net2);
757 LDKThirtyTwoBytes payment_preimage;
760 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
761 ev2.process_pending_events(handler);
762 assert(queue.events.size() == 1);
763 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
764 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
765 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
766 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
767 Invoice_payment_secret(invoice->contents.result), 32));
768 assert(queue.events[0]->payment_received.amount_msat == 5000);
769 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
770 ChannelManager_claim_funds(&cm2, payment_preimage);
772 queue.events.clear();
773 ev2.process_pending_events(handler);
774 assert(queue.events.size() == 1);
775 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
776 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
777 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
779 PeerManager_process_events(&net2);
780 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
781 while (mons_updated != 5) {
782 std::this_thread::yield();
786 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
787 while (queue.events.size() < 2)
788 ev1.process_pending_events(ev1.this_arg, handler);
789 assert(queue.events.size() == 2);
790 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
791 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
792 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
793 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
798 cm1_ser = ChannelManager_write(&cm1);
799 cm2_ser = ChannelManager_write(&cm2);
802 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
803 assert(mons1.mons.size() == 1);
804 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
805 mons_list1->data[0].is_owned = false; // XXX: God this sucks
806 uint8_t node_seed[32];
807 memset(&node_seed, 0, 32);
808 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
809 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
811 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
812 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
813 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
814 assert(cm1_read->result_ok);
815 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
817 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
818 assert(mons2.mons.size() == 1);
819 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
820 mons_list2->data[0].is_owned = false; // XXX: God this sucks
821 memset(&node_seed, 1, 32);
822 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
824 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
825 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
826 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
827 assert(cm2_read->result_ok);
828 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
830 // Attempt to close the channel...
832 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
833 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
834 assert(!close_res->result_ok); // Note that we can't close while disconnected!
836 // Open a connection!
837 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1));
838 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
840 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
841 LDKCustomMessageHandler custom_msg_handler1 = {
842 .this_arg = &chan_2_node_id,
843 .handle_custom_message = NULL, // We only create custom messages, not handle them
844 .get_and_clear_pending_msg = create_custom_msg,
845 .CustomMessageReader = LDKCustomMessageReader {
847 .read = read_custom_message,
852 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, &random_bytes.data, logger1, std::move(custom_msg_handler1));
854 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2));
855 CustomMsgQueue peer_2_custom_messages;
856 LDKCustomMessageHandler custom_msg_handler2 = {
857 .this_arg = &peer_2_custom_messages,
858 .handle_custom_message = handle_custom_message,
859 .get_and_clear_pending_msg = never_send_custom_msgs,
860 .CustomMessageReader = LDKCustomMessageReader {
862 .read = read_custom_message,
867 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
868 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, &random_bytes.data, logger2, std::move(custom_msg_handler2));
870 PeersConnection conn(cm1, cm2, net1, net2);
873 // Wait for the channels to be considered up once the reestablish messages are processed
874 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
875 if (outbound_channels->datalen == 1) {
880 // Send another payment, this time via the InvoicePayer
881 struct CustomRouteFinderParams router_params = {
883 .graph_ref = &net_graph1,
884 .random_seed_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg),
886 LDKRouter sending_router = {
887 .this_arg = &router_params,
888 .find_route = custom_find_route,
891 LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1);
892 LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(ProbabilisticScorer_as_Score(&scorer));
894 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
895 LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, &scorer_mtx, logger1, handler1, Retry_attempts(0));
897 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
898 KeysManager_as_KeysInterface(&keys2),
899 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
901 .chars = (const uint8_t *)"Invoice 2 Description",
902 .len = strlen("Invoice 2 Description"),
903 .chars_is_owned = false
905 assert(invoice_res2->result_ok);
906 const LDKInvoice *invoice2 = invoice_res2->contents.result;
907 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = InvoicePayer_pay_invoice(&payer, invoice2);
908 assert(invoice_pay_res->result_ok);
909 PeerManager_process_events(&net1);
911 // Check that we received the payment!
914 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
915 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
916 ev2.process_pending_events(handler2);
917 if (queue2.events.size() == 1) {
918 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
921 std::this_thread::yield();
923 ChannelManager_process_pending_htlc_forwards(&cm2);
924 PeerManager_process_events(&net2);
928 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
929 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
930 ev2.process_pending_events(handler2);
931 if (queue2.events.size() == 1) {
932 assert(queue2.events[0]->tag == LDKEvent_PaymentReceived);
933 const struct LDKEvent_LDKPaymentReceived_Body *event_data = &queue2.events[0]->payment_received;
934 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
935 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
936 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
937 Invoice_payment_secret(invoice2), 32));
938 assert(event_data->amount_msat == 10000);
939 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage);
941 queue2.events.clear();
942 ev2.process_pending_events(handler2);
943 assert(queue2.events.size() == 1);
944 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
945 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Invoice_payment_hash(invoice2), 32));
946 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
950 std::this_thread::yield();
953 while (queue1.events.size() < 2) {
954 PeerManager_process_events(&net2);
955 PeerManager_process_events(&net1);
957 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
958 LDK::EventHandler evh1 = InvoicePayer_as_EventHandler(&payer);
959 ev1.process_pending_events(std::move(evh1));
961 assert(queue1.events.size() == 2);
962 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
963 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
965 // Actually close the channel
966 num_txs_broadcasted = 0;
967 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
968 assert(close_res->result_ok);
969 PeerManager_process_events(&net1);
970 while (num_txs_broadcasted != 2) {
971 std::this_thread::yield();
973 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
974 assert(chans_after_close1->datalen == 0);
975 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
976 assert(chans_after_close2->datalen == 0);
980 assert(peer_2_custom_messages.msgs.size() != 0);
982 // Few extra random tests:
985 LDKThirtyTwoBytes kdiv_params;
986 memset(&kdiv_params, 43, 32);
987 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);