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 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 LDKInFlightHtlcs in_flights) {
440 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
441 assert(first_hops->datalen == 1);
442 assert(ChannelDetails_get_is_usable(&first_hops->data[0]));
443 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
444 return router_impl->find_route(router_impl->this_arg, payer, route_params, payment_hash, first_hops, in_flights);
447 void custom_notify_payment_path_failed(const void *this_arg, struct LDKCVec_RouteHopZ path, uint64_t short_channel_id) {
448 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
449 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
450 return router_impl->notify_payment_path_failed(router_impl->this_arg, path, short_channel_id);
452 void custom_notify_payment_path_successful(const void *this_arg, struct LDKCVec_RouteHopZ path) {
453 const LDK::DefaultRouter *router = (LDK::DefaultRouter *)this_arg;
454 const LDK::Router router_impl = DefaultRouter_as_Router(&*router);
455 return router_impl->notify_payment_path_successful(router_impl->this_arg, path);
459 uint8_t channel_open_header[80];
460 uint8_t header_1[80];
461 uint8_t header_2[80];
462 memcpy(channel_open_header, channel_open_block, 80);
463 memcpy(header_1, block_1, 80);
464 memcpy(header_2, block_2, 80);
466 LDKPublicKey null_pk;
467 memset(&null_pk, 0, sizeof(null_pk));
469 LDKThirtyTwoBytes random_bytes;
470 LDKThirtyTwoBytes chain_tip;
471 memset(&chain_tip, 0, sizeof(chain_tip)); // channel_open_header's prev_blockhash is all-0s
473 LDKNetwork network = LDKNetwork_Testnet;
475 // Trait implementations:
476 LDKBroadcasterInterface broadcast {
478 .broadcast_transaction = broadcast_tx,
482 // Instantiate classes for the nodes that don't get reloaded on a ser-des reload
484 .this_arg = (void*)1,
490 mons1.logger = &logger1;
493 .watch_channel = add_channel_monitor,
494 .update_channel = update_channel_monitor,
495 .release_pending_monitor_events = monitors_pending_monitor_events,
499 LDK::NetworkGraph net_graph1 = NetworkGraph_new(genesis_hash, logger1);
500 LDK::P2PGossipSync graph_msg_handler1 = P2PGossipSync_new(&net_graph1, COption_AccessZ_none(), logger1);
501 LDKSecretKey node_secret1;
504 .this_arg = (void*)2,
510 mons2.logger = &logger2;
513 .watch_channel = add_channel_monitor,
514 .update_channel = update_channel_monitor,
515 .release_pending_monitor_events = monitors_pending_monitor_events,
519 LDK::NetworkGraph net_graph2 = NetworkGraph_new(genesis_hash, logger2);
520 LDK::P2PGossipSync graph_msg_handler2 = P2PGossipSync_new(&net_graph2, COption_AccessZ_none(), logger2);
521 LDKSecretKey node_secret2;
523 LDK::CVec_u8Z cm1_ser = LDKCVec_u8Z {}; // ChannelManager 1 serialization at the end of the ser-des scope
524 LDK::CVec_u8Z cm2_ser = LDKCVec_u8Z {}; // ChannelManager 2 serialization at the end of the ser-des scope
526 { // Scope for the ser-des reload
527 // Instantiate classes for node 1:
528 uint8_t node_seed[32];
529 memset(&node_seed, 0, 32);
530 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 0, 0);
531 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
532 LDK::CResult_SecretKeyNoneZ node_secret1_res = keys_source1->get_node_secret(keys_source1->this_arg, LDKRecipient_Node);
533 assert(node_secret1_res->result_ok);
534 node_secret1 = *node_secret1_res->contents.result;
536 LDK::ChannelManager cm1 = ChannelManager_new(fee_est, mon1, broadcast, logger1, KeysManager_as_KeysInterface(&keys1), UserConfig_default(), ChainParameters_new(network, BestBlock_new(chain_tip, 0)));
537 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys1), logger1);
539 LDK::CVec_ChannelDetailsZ channels = ChannelManager_list_channels(&cm1);
540 assert(channels->datalen == 0);
542 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
544 LDK::IgnoringMessageHandler ignoring_handler1 = IgnoringMessageHandler_new();
545 LDK::CustomMessageHandler custom_msg_handler1 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler1);
547 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
548 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1));
550 // Demo getting a channel key and check that its returning real pubkeys:
551 LDK::Sign chan_signer1 = keys_source1->get_channel_signer(keys_source1->this_arg, false, 42);
552 chan_signer1->BaseSign.set_pubkeys(&chan_signer1->BaseSign); // Make sure pubkeys is defined
553 LDKPublicKey payment_point = ChannelPublicKeys_get_payment_point(&chan_signer1->BaseSign.pubkeys);
554 assert(memcmp(&payment_point, &null_pk, sizeof(null_pk)));
556 // Instantiate classes for node 2:
557 memset(&node_seed, 1, 32);
558 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 0, 0);
559 LDK::KeysInterface keys_source2 = KeysManager_as_KeysInterface(&keys2);
560 LDK::CResult_SecretKeyNoneZ node_secret2_res = keys_source2->get_node_secret(keys_source2->this_arg, LDKRecipient_Node);
561 assert(node_secret2_res->result_ok);
562 node_secret2 = *node_secret2_res->contents.result;
564 LDK::ChannelHandshakeConfig handshake_config2 = ChannelHandshakeConfig_default();
565 ChannelHandshakeConfig_set_minimum_depth(&handshake_config2, 2);
566 LDK::UserConfig config2 = UserConfig_default();
567 UserConfig_set_channel_handshake_config(&config2, std::move(handshake_config2));
569 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)));
570 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys2), logger2);
572 LDK::CVec_ChannelDetailsZ channels2 = ChannelManager_list_channels(&cm2);
573 assert(channels2->datalen == 0);
575 LDK::RoutingMessageHandler net_msgs2 = P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2);
576 LDK::CResult_ChannelAnnouncementDecodeErrorZ chan_ann = ChannelAnnouncement_read(LDKu8slice { .data = valid_node_announcement, .datalen = sizeof(valid_node_announcement) });
577 assert(chan_ann->result_ok);
578 LDK::CResult_boolLightningErrorZ ann_res = net_msgs2->handle_channel_announcement(net_msgs2->this_arg, chan_ann->contents.result);
579 assert(ann_res->result_ok);
581 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), std::move(net_msgs2), OnionMessenger_as_OnionMessageHandler(&om1));
583 LDK::IgnoringMessageHandler ignoring_handler2 = IgnoringMessageHandler_new();
584 LDK::CustomMessageHandler custom_msg_handler2 = IgnoringMessageHandler_as_CustomMessageHandler(&ignoring_handler2);
586 random_bytes = keys_source2->get_secure_random_bytes(keys_source2->this_arg);
587 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2));
589 // Open a connection!
590 PeersConnection conn(cm1, cm2, net1, net2);
592 // Note that we have to bind the result to a C++ class to make sure it gets free'd
593 LDK::CResult__u832APIErrorZ res = ChannelManager_create_channel(&cm1, ChannelManager_get_our_node_id(&cm2), 40000, 1000, 42, UserConfig_default());
594 assert(res->result_ok);
595 PeerManager_process_events(&net1);
597 LDK::CVec_ChannelDetailsZ new_channels = ChannelManager_list_channels(&cm1);
598 assert(new_channels->datalen == 1);
599 LDK::ChannelCounterparty new_channels_counterparty = ChannelDetails_get_counterparty(&new_channels->data[0]);
600 LDKPublicKey chan_open_pk = ChannelCounterparty_get_node_id(&new_channels_counterparty);
601 assert(!memcmp(chan_open_pk.compressed_form, ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
604 LDK::CVec_ChannelDetailsZ new_channels_2 = ChannelManager_list_channels(&cm2);
605 if (new_channels_2->datalen == 1) {
606 // Sample getting our counterparty's init features (which used to be hard to do without a memory leak):
607 LDK::ChannelCounterparty new_channels_2_counterparty = ChannelDetails_get_counterparty(&new_channels_2->data[0]);
608 const LDK::InitFeatures init_feats = ChannelCounterparty_get_features(&new_channels_2_counterparty);
609 assert(init_feats->inner != NULL);
612 std::this_thread::yield();
615 LDKEventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
618 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
619 ev1.process_pending_events(ev1.this_arg, handler);
620 if (queue.events.size() == 1) {
621 assert(queue.events[0]->tag == LDKEvent_FundingGenerationReady);
622 assert(queue.events[0]->funding_generation_ready.user_channel_id == 42);
623 assert(queue.events[0]->funding_generation_ready.channel_value_satoshis == 40000);
624 assert(queue.events[0]->funding_generation_ready.output_script.datalen == 34);
625 assert(!memcmp(queue.events[0]->funding_generation_ready.output_script.data, channel_open_block + 58 + 81, 34));
626 LDKTransaction funding_transaction { .data = const_cast<uint8_t*>(channel_open_block + 81), .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false };
628 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);
629 assert(fund_res->result_ok);
632 std::this_thread::yield();
635 // We observe when the funding signed messages have been exchanged by
636 // waiting for two monitors to be registered.
637 assert(num_txs_broadcasted == 0);
638 PeerManager_process_events(&net1);
639 while (num_txs_broadcasted != 1) {
640 std::this_thread::yield();
643 LDK::Listen listener1 = ChannelManager_as_Listen(&cm1);
644 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
646 LDK::Listen listener2 = ChannelManager_as_Listen(&cm2);
647 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = channel_open_block, .datalen = sizeof(channel_open_block) }, 1);
649 LDKCVec_C2Tuple_usizeTransactionZZ txdata { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
650 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
651 mons1.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
653 txdata = LDKCVec_C2Tuple_usizeTransactionZZ { .data = (LDKC2Tuple_usizeTransactionZ*)malloc(sizeof(LDKC2Tuple_usizeTransactionZ)), .datalen = 1 };
654 *txdata.data = C2Tuple_usizeTransactionZ_new(0, LDKTransaction { .data = (uint8_t*)channel_open_block + 81, .datalen = sizeof(channel_open_block) - 81, .data_is_owned = false });
655 mons2.ConnectBlock(&channel_open_header, 1, txdata, broadcast, fee_est);
657 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
658 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_1, .datalen = sizeof(block_1) }, 2);
659 mons1.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
660 mons2.ConnectBlock(&header_1, 2, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
662 listener1->block_connected(listener1->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
663 listener2->block_connected(listener2->this_arg, LDKu8slice { .data = block_2, .datalen = sizeof(block_1) }, 3);
664 mons1.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
665 mons2.ConnectBlock(&header_2, 3, LDKCVec_C2Tuple_usizeTransactionZZ { .data = NULL, .datalen = 0 }, broadcast, fee_est);
667 PeerManager_process_events(&net1);
668 PeerManager_process_events(&net2);
670 // Now send funds from 1 to 2!
671 uint64_t channel_scid;
673 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
674 if (outbound_channels->datalen == 1) {
675 const LDKChannelDetails *channel = &outbound_channels->data[0];
676 LDK::ChannelCounterparty counterparty = ChannelDetails_get_counterparty(channel);
677 // Note that the channel ID is the same as the channel txid reversed as the output index is 0
678 uint8_t expected_chan_id[32];
679 for (int i = 0; i < 32; i++) { expected_chan_id[i] = channel_open_txid[31-i]; }
680 assert(!memcmp(ChannelDetails_get_channel_id(channel), expected_chan_id, 32));
682 ChannelCounterparty_get_node_id(&counterparty).compressed_form,
683 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
684 assert(ChannelDetails_get_channel_value_satoshis(channel) == 40000);
685 // We opened the channel with 1000 push_msat:
686 assert(ChannelDetails_get_outbound_capacity_msat(channel) ==
687 40000*1000 - 1000 - 1000 * ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty));
688 int64_t inbound_capacity = ((int64_t)1000) - ChannelCounterparty_get_unspendable_punishment_reserve(&counterparty);
689 if (inbound_capacity < 0) inbound_capacity = 0;
690 assert(ChannelDetails_get_inbound_capacity_msat(channel) == (uint64_t)inbound_capacity);
691 assert(ChannelDetails_get_is_usable(channel));
692 LDK::COption_u64Z scid_opt = ChannelDetails_get_short_channel_id(channel);
693 assert(scid_opt->some);
694 channel_scid = scid_opt->some;
697 std::this_thread::yield();
700 LDKCOption_u64Z min_value = {
701 .tag = LDKCOption_u64Z_Some,
704 LDK::CResult_InvoiceSignOrCreationErrorZ invoice = create_invoice_from_channelmanager(&cm2,
705 KeysManager_as_KeysInterface(&keys2),
706 LDKCurrency_Bitcoin, min_value,
708 .chars = (const uint8_t *)"Invoice Description",
709 .len = strlen("Invoice Description"),
710 .chars_is_owned = false
712 assert(invoice->result_ok);
713 LDKThirtyTwoBytes payment_hash;
714 memcpy(payment_hash.data, Invoice_payment_hash(invoice->contents.result), 32);
717 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
718 LDK::Score chan_scorer = LDKScore {
719 .this_arg = NULL, .channel_penalty_msat = get_chan_score, .free = NULL
721 LDK::RouteParameters route_params = RouteParameters_new(PaymentParameters_new(
722 ChannelManager_get_our_node_id(&cm2), LDKInvoiceFeatures {
723 .inner = NULL, .is_owned = false
724 }, Invoice_route_hints(invoice->contents.result), COption_u64Z_none(), 0xffffffff,
725 1, 2, LDKCVec_u64Z { .data = NULL, .datalen = 0 }),
726 5000, Invoice_min_final_cltv_expiry(invoice->contents.result));
727 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
729 LDK::CResult_RouteLightningErrorZ route = find_route(ChannelManager_get_our_node_id(&cm1), &route_params, &net_graph2, &outbound_channels, logger1, &chan_scorer, &random_bytes.data);
731 assert(route->result_ok);
732 LDK::CVec_CVec_RouteHopZZ paths = Route_get_paths(route->contents.result);
733 assert(paths->datalen == 1);
734 assert(paths->data[0].datalen == 1);
735 assert(!memcmp(RouteHop_get_pubkey(&paths->data[0].data[0]).compressed_form,
736 ChannelManager_get_our_node_id(&cm2).compressed_form, 33));
737 assert(RouteHop_get_short_channel_id(&paths->data[0].data[0]) == channel_scid);
738 LDKThirtyTwoBytes payment_secret;
739 memcpy(payment_secret.data, Invoice_payment_secret(invoice->contents.result), 32);
740 LDK::CResult_PaymentIdPaymentSendFailureZ send_res = ChannelManager_send_payment(&cm1, route->contents.result, payment_hash, payment_secret);
741 assert(send_res->result_ok);
745 PeerManager_process_events(&net1);
746 while (mons_updated != 4) {
747 std::this_thread::yield();
750 // Check that we received the payment!
751 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
754 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
755 ev2.process_pending_events(handler);
756 if (queue.events.size() == 1) {
757 assert(queue.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
760 std::this_thread::yield();
762 ChannelManager_process_pending_htlc_forwards(&cm2);
763 PeerManager_process_events(&net2);
766 LDKThirtyTwoBytes payment_preimage;
769 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
770 ev2.process_pending_events(handler);
771 assert(queue.events.size() == 1);
772 assert(queue.events[0]->tag == LDKEvent_PaymentReceived);
773 assert(!memcmp(queue.events[0]->payment_received.payment_hash.data, payment_hash.data, 32));
774 assert(queue.events[0]->payment_received.purpose.tag == LDKPaymentPurpose_InvoicePayment);
775 assert(!memcmp(queue.events[0]->payment_received.purpose.invoice_payment.payment_secret.data,
776 Invoice_payment_secret(invoice->contents.result), 32));
777 assert(queue.events[0]->payment_received.amount_msat == 5000);
778 memcpy(payment_preimage.data, queue.events[0]->payment_received.purpose.invoice_payment.payment_preimage.data, 32);
779 ChannelManager_claim_funds(&cm2, payment_preimage);
781 queue.events.clear();
782 ev2.process_pending_events(handler);
783 assert(queue.events.size() == 1);
784 assert(queue.events[0]->tag == LDKEvent_PaymentClaimed);
785 assert(!memcmp(queue.events[0]->payment_claimed.payment_hash.data, payment_hash.data, 32));
786 assert(queue.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
788 PeerManager_process_events(&net2);
789 // Wait until we've passed through a full set of monitor updates (ie new preimage + CS/RAA messages)
790 while (mons_updated != 5) {
791 std::this_thread::yield();
795 LDKEventHandler handler = { .this_arg = &queue, .handle_event = handle_event, .free = NULL };
796 while (queue.events.size() < 2)
797 ev1.process_pending_events(ev1.this_arg, handler);
798 assert(queue.events.size() == 2);
799 assert(queue.events[0]->tag == LDKEvent_PaymentSent);
800 assert(!memcmp(queue.events[0]->payment_sent.payment_preimage.data, payment_preimage.data, 32));
801 assert(queue.events[1]->tag == LDKEvent_PaymentPathSuccessful);
802 assert(!memcmp(queue.events[1]->payment_path_successful.payment_hash.data, payment_hash.data, 32));
807 cm1_ser = ChannelManager_write(&cm1);
808 cm2_ser = ChannelManager_write(&cm2);
811 LDK::CVec_ChannelMonitorZ mons_list1 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
812 assert(mons1.mons.size() == 1);
813 mons_list1->data[0] = *& std::get<1>(mons1.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
814 mons_list1->data[0].is_owned = false; // XXX: God this sucks
815 uint8_t node_seed[32];
816 memset(&node_seed, 0, 32);
817 LDK::KeysManager keys1 = KeysManager_new(&node_seed, 1, 0);
818 LDK::KeysInterface keys_source1 = KeysManager_as_KeysInterface(&keys1);
820 LDK::ChannelManagerReadArgs cm1_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys1), fee_est, mon1, broadcast, logger1, UserConfig_default(), std::move(mons_list1));
821 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm1_read =
822 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm1_ser->data, .datalen = cm1_ser -> datalen}, std::move(cm1_args));
823 assert(cm1_read->result_ok);
824 LDK::ChannelManager cm1(std::move(cm1_read->contents.result->b));
826 LDK::OnionMessenger om1 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys1), logger1);
828 LDK::CVec_ChannelMonitorZ mons_list2 = LDKCVec_ChannelMonitorZ { .data = (LDKChannelMonitor*)malloc(sizeof(LDKChannelMonitor)), .datalen = 1 };
829 assert(mons2.mons.size() == 1);
830 mons_list2->data[0] = *& std::get<1>(mons2.mons[0]); // Note that we need a reference, thus need a raw clone here, which *& does.
831 mons_list2->data[0].is_owned = false; // XXX: God this sucks
832 memset(&node_seed, 1, 32);
833 LDK::KeysManager keys2 = KeysManager_new(&node_seed, 1, 0);
835 LDK::ChannelManagerReadArgs cm2_args = ChannelManagerReadArgs_new(KeysManager_as_KeysInterface(&keys2), fee_est, mon2, broadcast, logger2, UserConfig_default(), std::move(mons_list2));
836 LDK::CResult_C2Tuple_BlockHashChannelManagerZDecodeErrorZ cm2_read =
837 C2Tuple_BlockHashChannelManagerZ_read(LDKu8slice { .data = cm2_ser->data, .datalen = cm2_ser -> datalen}, std::move(cm2_args));
838 assert(cm2_read->result_ok);
839 LDK::ChannelManager cm2(std::move(cm2_read->contents.result->b));
841 LDK::OnionMessenger om2 = OnionMessenger_new(KeysManager_as_KeysInterface(&keys2), logger2);
843 // Attempt to close the channel...
845 for (int i = 0; i < 32; i++) { chan_id[i] = channel_open_txid[31-i]; }
846 LDK::CResult_NoneAPIErrorZ close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
847 assert(!close_res->result_ok); // Note that we can't close while disconnected!
849 // Open a connection!
850 LDK::MessageHandler msg_handler1 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm1), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler1), OnionMessenger_as_OnionMessageHandler(&om1));
851 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
853 LDKPublicKey chan_2_node_id = ChannelManager_get_our_node_id(&cm2);
854 LDKCustomMessageHandler custom_msg_handler1 = {
855 .this_arg = &chan_2_node_id,
856 .handle_custom_message = NULL, // We only create custom messages, not handle them
857 .get_and_clear_pending_msg = create_custom_msg,
858 .CustomMessageReader = LDKCustomMessageReader {
860 .read = read_custom_message,
865 LDK::PeerManager net1 = PeerManager_new(std::move(msg_handler1), node_secret1, 0xdeadbeef, &random_bytes.data, logger1, std::move(custom_msg_handler1));
867 LDK::MessageHandler msg_handler2 = MessageHandler_new(ChannelManager_as_ChannelMessageHandler(&cm2), P2PGossipSync_as_RoutingMessageHandler(&graph_msg_handler2), OnionMessenger_as_OnionMessageHandler(&om2));
868 CustomMsgQueue peer_2_custom_messages;
869 LDKCustomMessageHandler custom_msg_handler2 = {
870 .this_arg = &peer_2_custom_messages,
871 .handle_custom_message = handle_custom_message,
872 .get_and_clear_pending_msg = never_send_custom_msgs,
873 .CustomMessageReader = LDKCustomMessageReader {
875 .read = read_custom_message,
880 random_bytes = keys_source1->get_secure_random_bytes(keys_source1->this_arg);
881 LDK::PeerManager net2 = PeerManager_new(std::move(msg_handler2), node_secret2, 0xdeadbeef, &random_bytes.data, logger2, std::move(custom_msg_handler2));
883 PeersConnection conn(cm1, cm2, net1, net2);
886 // Wait for the channels to be considered up once the reestablish messages are processed
887 LDK::CVec_ChannelDetailsZ outbound_channels = ChannelManager_list_usable_channels(&cm1);
888 if (outbound_channels->datalen == 1) {
893 // Send another payment, this time via the InvoicePayer
894 LDK::ProbabilisticScorer scorer = ProbabilisticScorer_new(ProbabilisticScoringParameters_default(), &net_graph1, logger1);
895 LDK::Score scorer_trait = ProbabilisticScorer_as_Score(&scorer);
896 LDK::MultiThreadedLockableScore scorer_mtx = MultiThreadedLockableScore_new(std::move(scorer_trait));
897 LDK::LockableScore scorer_mtx_trait = MultiThreadedLockableScore_as_LockableScore(&scorer_mtx);
898 const LDK::DefaultRouter router = DefaultRouter_new(&net_graph1, logger1, keys_source1->get_secure_random_bytes(keys_source1->this_arg), std::move(scorer_mtx_trait));
899 LDKRouter sending_router = {
900 .this_arg = (void*)&router,
901 .find_route = custom_find_route,
902 .notify_payment_path_failed = custom_notify_payment_path_failed,
903 .notify_payment_path_successful = custom_notify_payment_path_successful,
904 // We don't probe, so we opt to crash if the probe functions are called.
905 .notify_payment_probe_successful = NULL,
906 .notify_payment_probe_failed = NULL,
910 LDKEventHandler handler1 = { .this_arg = &queue1, .handle_event = handle_event, .free = NULL };
911 LDK::InvoicePayer payer = InvoicePayer_new(ChannelManager_as_Payer(&cm1), sending_router, logger1, handler1, Retry_attempts(0));
913 LDK::CResult_InvoiceSignOrCreationErrorZ invoice_res2 = create_invoice_from_channelmanager(&cm2,
914 KeysManager_as_KeysInterface(&keys2),
915 LDKCurrency_Bitcoin, COption_u64Z_some(10000),
917 .chars = (const uint8_t *)"Invoice 2 Description",
918 .len = strlen("Invoice 2 Description"),
919 .chars_is_owned = false
921 assert(invoice_res2->result_ok);
922 const LDKInvoice *invoice2 = invoice_res2->contents.result;
923 LDK::CResult_PaymentIdPaymentErrorZ invoice_pay_res = InvoicePayer_pay_invoice(&payer, invoice2);
924 assert(invoice_pay_res->result_ok);
925 PeerManager_process_events(&net1);
927 // Check that we received the payment!
930 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
931 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
932 ev2.process_pending_events(handler2);
933 if (queue2.events.size() == 1) {
934 assert(queue2.events[0]->tag == LDKEvent_PendingHTLCsForwardable);
937 std::this_thread::yield();
939 ChannelManager_process_pending_htlc_forwards(&cm2);
940 PeerManager_process_events(&net2);
944 LDKEventHandler handler2 = { .this_arg = &queue2, .handle_event = handle_event, .free = NULL };
945 LDK::EventsProvider ev2 = ChannelManager_as_EventsProvider(&cm2);
946 ev2.process_pending_events(handler2);
947 if (queue2.events.size() == 1) {
948 assert(queue2.events[0]->tag == LDKEvent_PaymentReceived);
949 const struct LDKEvent_LDKPaymentReceived_Body *event_data = &queue2.events[0]->payment_received;
950 assert(!memcmp(event_data->payment_hash.data, Invoice_payment_hash(invoice2), 32));
951 assert(event_data->purpose.tag == LDKPaymentPurpose_InvoicePayment);
952 assert(!memcmp(event_data->purpose.invoice_payment.payment_secret.data,
953 Invoice_payment_secret(invoice2), 32));
954 assert(event_data->amount_msat == 10000);
955 ChannelManager_claim_funds(&cm2, event_data->purpose.invoice_payment.payment_preimage);
957 queue2.events.clear();
958 ev2.process_pending_events(handler2);
959 assert(queue2.events.size() == 1);
960 assert(queue2.events[0]->tag == LDKEvent_PaymentClaimed);
961 assert(!memcmp(queue2.events[0]->payment_claimed.payment_hash.data, Invoice_payment_hash(invoice2), 32));
962 assert(queue2.events[0]->payment_claimed.purpose.tag == LDKPaymentPurpose_InvoicePayment);
966 std::this_thread::yield();
969 while (queue1.events.size() < 2) {
970 PeerManager_process_events(&net2);
971 PeerManager_process_events(&net1);
973 LDK::EventsProvider ev1 = ChannelManager_as_EventsProvider(&cm1);
974 LDK::EventHandler evh1 = InvoicePayer_as_EventHandler(&payer);
975 ev1.process_pending_events(std::move(evh1));
977 assert(queue1.events.size() == 2);
978 assert(queue1.events[0]->tag == LDKEvent_PaymentSent);
979 assert(queue1.events[1]->tag == LDKEvent_PaymentPathSuccessful);
981 // Actually close the channel
982 num_txs_broadcasted = 0;
983 close_res = ChannelManager_close_channel(&cm1, &chan_id, ChannelManager_get_our_node_id(&cm2));
984 assert(close_res->result_ok);
985 PeerManager_process_events(&net1);
986 while (num_txs_broadcasted != 2) {
987 std::this_thread::yield();
989 LDK::CVec_ChannelDetailsZ chans_after_close1 = ChannelManager_list_channels(&cm1);
990 assert(chans_after_close1->datalen == 0);
991 LDK::CVec_ChannelDetailsZ chans_after_close2 = ChannelManager_list_channels(&cm2);
992 assert(chans_after_close2->datalen == 0);
996 assert(peer_2_custom_messages.msgs.size() != 0);
998 // Few extra random tests:
1000 memset(&sk, 42, 32);
1001 LDKThirtyTwoBytes kdiv_params;
1002 memset(&kdiv_params, 43, 32);
1003 LDK::InMemorySigner signer = InMemorySigner_new(sk, sk, sk, sk, sk, sk, random_bytes, 42, kdiv_params);